# TZif Engine 总体架构

## 1. 模块与目录结构

| 目录/package | 职责 |
|---|---|
| `types/` | 公共 concrete types、POSIX AST、resolution/diagnostic 类型、checked errors |
| `parser/` | header、size、body、metadata、footer 的严格 TZif v2/v3 解析 |
| `posix/` | Int64 Gregorian calendar、POSIX rule transition 计算与 offset 选择 |
| `converter/` | active offset、UTC→local、候选收集、gap/overlap 与 local→UTC |
| `text/` | local/UTC/numeric-offset ISO-8601 严格适配 |
| 根 `*.mbt` | 公共 facade、完整模型 validation、diagnostics 与 transition queries |
| `test/fixtures/`、`test/*`、`golden/` | 原创 fixture、真实 golden、conformance、interop、mutation 证据 |
| `cli/` | 十六进制输入 CLI、诊断输出和退出码 |
| `examples/`、`bench/`、`.github/`、交付文档 | 端到端示例、可复现基准、CI 与发布/验收材料 |

实际 package 还包括 `test/conformance`、`test/interop`、`test/mutation`、`examples` 和 `bench`。
`.mooncakes/`、`_build/` 是本地缓存/产物，不属于源码架构。

## 2. 公开类型所有权与 API

`types/` 拥有调用者需要构造、匹配或检查的 `TimeType`、`Transition`、`TzifData`、
`LocalDateTime`、`OffsetDateTime`、`LocalTimeResolution`、`OffsetSource`、
`TransitionDetail`、POSIX AST 和 `TzifError`。parser/converter/posix/text 不拥有 facade
用户可见的第三方具体类型。

根 facade 拥有稳定调用路径：

```moonbit
load(Bytes) -> TzifResult[TzifData]
validate(TzifData) -> TzifResult[Unit]
utc_to_local(TzifData, Int64) -> TzifResult[LocalDateTime]
resolve_local(TzifData, LocalDateTime) -> TzifResult[LocalTimeResolution]
local_to_utc(TzifData, LocalDateTime, AmbiguityStrategy) -> TzifResult[Int64]
diagnostics / transition_at / previous_transition / next_transition
transition_detail / transition_details_between
parse_iso_* / format_iso_* / info
```

最终 `pkg.generated.mbti` 只能由 `moon info` 生成。是否增加 `pub using @types` 要以外部调用体验和
接口清晰度决定，不能通过 re-export 改变 `types` 的所有权。

## 3. 核心数据流

读取：

```text
Bytes
→ header #1 + checked v1 size
→ exact header #2 position
→ 64-bit body + designation/leap/indicator validation
→ newline-framed POSIX footer
→ final-transition/footer consistency
→ TzifData
→ public validate()
```

UTC→local：

```text
utc seconds → binary search explicit transitions
→ initial type / explicit type / POSIX rule source
→ checked offset → Int64 calendar decomposition
→ LocalDateTime + OffsetSource
```

local→UTC：

```text
validated civil fields → collect distinct explicit/footer offsets
→ candidate UTC = local epoch - offset
→ utc_to_local round trip
→ sorted unique candidates → Unique / Gap / Ambiguous
→ optional earlier/later policy
```

## 4. 错误边界与资源限制

- 所有公开不可信输入路径返回 `TzifResult`；CLI 在边界把错误转换为消息和退出码。
- header counts、乘加尺寸、剩余长度、索引、NUL、ASCII、flag、transition order 在分配/解码前检查。
- `Int64` 保存 epoch、transition 和日数，禁止通过 `Int` 缩窄 2038/2100。
- parser 不读取文件系统；宿主负责 I/O 和最大输入策略。测试用 mutation corpus 验证无 panic。
- `validate` 保护调用方手工构造或跨信任边界得到的公开 `TzifData`。

## 5. Target 与并发模型

核心为同步纯计算或只读数组查询，支持 native、wasm、wasm-gc、JavaScript。CLI 只通过
`moonbitlang/x/sys` 读取 argv/设置退出码，不把文件 I/O 引入核心。

并发不适用：当前 API 不含全局可变缓存和后台任务；解析结果由调用者持有，只读查询可由宿主按
自身并发模型隔离。若未来加入缓存，必须重新定义共享状态和同步语义。

## 6. 复杂度

- parse：`O(file length + transition count + type count)`。
- UTC offset lookup：显式 transitions 上 `O(log n)`；POSIX 规则为常数个相邻年度事件。
- local resolution：`O(number of distinct candidate offsets × log n)`。
- transition range：`O(log n + k)`，`k` 为返回条数。
- 内存：与 transitions、types、metadata 和 designation 大小线性相关。

## 7. 关键设计决策

| ADR | 选择 | 备选 | 理由 | 代价/重审条件 |
|---|---|---|---|---|
| `ADR-001` | 核心接收 `Bytes` | 核心接收路径/zone name | 四 target、可嵌入、I/O 策略分离 | 宿主需自行读取或嵌入 |
| `ADR-002` | 公开模型由 `types` 拥有 | internal type 后 re-export | 构造、匹配、方法和 mbti 所有权清晰 | 消费者当前需导入 `types` |
| `ADR-003` | local→UTC 反向验证候选 | 对 local transition 边界排序 | 兼容历史非整时、非单调 offset 变化 | 候选数与类型数相关 |
| `ADR-004` | leap 只解析/验证 | leap-aware civil time | 与 POSIX 秒 API 边界一致 | 不适合 leap-aware 应用 |
| `ADR-005` | v2 reader 接受 tzcode 扩展时刻 | 严格拒绝 v2 扩展 | 兼容真实 IANA/tzcode 产物 | writer 若实现必须按版本约束 |
| `ADR-006` | 对标而不依赖 `x/time` | 包装 `x/time` | 当前 strict parser/local resolution 是独立贡献 | 上游能力变化时重新评估 |

## 8. 当前实现状态

所有模块已有真实目录和独立组件，没有 placeholder。开发阶段已按追踪矩阵逐项审查、
补测试并重跑完整门禁。
