# Tier 1-A Sprint 4 — audit:translation-completeness 实现 + 10th strict gate + wrap-up

> **触发方式**：用户对 executor 说 `请按 docs/internal/_prompts/tier1a-sprint4-audit-impl.prompt.md 执行`
> **角色**：executor
> **依赖**：
> - [`docs/internal/_plans/tier1a-translation-schema-spec.md`](../_plans/tier1a-translation-schema-spec.md) §3 + §4 Sprint 4
> - Sprint 1-3 全 ship（HEAD = `859c2ba5` Sprint 3）
> **完成后 STOP**，列改动 + 未解决项给 plan owner 复审

> ⚠️ **本 sprint 复杂度高于前 3 个**（前 3 是数据迁移，本 sprint 是 audit 逻辑实现 + 10th strict gate + wrap-up 7 deliverable）。spec 估 2-3 day，实跑可能更长。**遇任何歧义先 STOP 报告**，不要硬猜。

---

## 0. 起手 Pre-flight check（mandatory 顺序）

**Pre-flight 判断规则**（同 Sprint 3 范式）：

只有当**以下任意一项**为真时才 STOP：

1. 本 sprint 输出路径已 dirty / exists：
   - `figma-sync/audit-translation-completeness.mjs` exists / modified
   - `figma-sync/audit-allowlist/translation-completeness.json` exists
   - `docs/internal/retrospection/2026-05-14-tier1a-translation-schema.md` exists

2. 已 ship sprint 产物被改动（回归风险）：
   - `src/design-system/translation/axis-implementation-map.json` / `.schema.json` modified
   - `src/design-system/translation/prop-aliases.json` / `.schema.json` / `.md` modified
   - `src/design-system/translation/divergences.md` / `divergences-decisions.json` / `.schema.json` modified

3. 本 sprint 明示不动文件被改动：
   - `src/design-system/translation/icon-aliases.ts` modified
   - `src/design-system/translation/token-aliases.ts` modified
   - `src/design-system/translation/figma-extract-rules.draft.md` modified（D1：留 draft）
   - 其它 `figma-sync/audit-*.mjs` modified（本 sprint 只**新建**一个 audit，不动既有 9 个）

4. baseline 不绿（见下）

**其它 dirty / untracked**（如 `.claude/settings.json`、`docs/STATUS.md`、本 prompt 文件 untracked）与本 sprint 无关，正常继续。

```bash
git status --short
git log --oneline -3
# 顶部应是 859c2ba5 feat(tier1a-sprint3): ...

pnpm test                       # 应 105 passed | 1 skipped
pnpm exec vue-tsc --noEmit      # 应 0 错

# Sprint 1+2+3 baseline 全绿
node -e "
  const Ajv2020 = require('ajv/dist/2020.js').default;
  const ajv = new Ajv2020({ strict: true });
  const v1 = ajv.compile(require('./src/design-system/translation/schemas/axis-implementation-map.schema.json'));
  const v2 = ajv.compile(require('./src/design-system/translation/schemas/prop-aliases.schema.json'));
  const v3 = ajv.compile(require('./src/design-system/translation/schemas/divergences-decisions.schema.json'));
  const d1 = require('./src/design-system/translation/axis-implementation-map.json');
  const d2 = require('./src/design-system/translation/prop-aliases.json');
  const d3 = require('./src/design-system/translation/divergences-decisions.json');
  if (!v1(d1) || !v2(d2) || !v3(d3)) process.exit(1);
  console.log('All 3 baseline OK:', d1.instances.length, 'instances /', d2.entries.length, 'entries /', d3.decisions.length, 'decisions');
"
# 预期：All 3 baseline OK: 16 instances / 102 entries / 26 decisions
```

---

## 1. 任务摘要

实现 **`audit:translation-completeness`** L5 strict gate（10th in pipeline），完成 Tier 1-A 收尾。

**5 维 audit**（spec §3）+ **7 个 deliverable**。

**关键边界**：
- 本 sprint **不改** 既有 9 个 audit 脚本逻辑（只新增 1 个 `audit-translation-completeness.mjs`）
- 本 sprint **不改** translation 6 个真源（Sprint 1-3 已 ship，本 sprint 只**读**它们做 audit）
- 本 sprint **不改** Figma plan / consumer code
- 升 10th strict gate 时 audit **必须先跑通**（即跑出来 finding 数能合理 allowlist 化 → 实际 fail rate 控制到 0），否则 publish 全 block

**预计实跑路径**：先 implement audit 不接 strict → 跑出 baseline finding 数 → review finding 分类（real bug / acceptable / allowlist 范围）→ allowlist 种子写 → 跑到 0 fail → 升 strict → wrap-up docs。

---

## 2. 5 维 audit 实现指导

### 2.1 输入数据源（read-only）

| 数据 | 路径 | 用法 |
|---|---|---|
| translation SoT 1 | `src/design-system/translation/axis-implementation-map.json` | instances[] 的 figmaComponent / figmaAxis / codeFile / verifyHint |
| translation SoT 2 | `src/design-system/translation/prop-aliases.json` | entries[] 的 scope / component / codeName / figmaName |
| translation SoT 3 | `src/design-system/translation/divergences-decisions.json` | decisions[] 的 category=resolved / verifyHint |
| translation SoT 4 | `src/design-system/translation/icon-aliases.ts` | 用 `pnpm tsx` 或 dynamic import；export `ICON_ALIAS_TO_FIGMA_NAME` + `COMPONENT_ICON_OVERRIDES` |
| translation SoT 5 | `src/design-system/translation/token-aliases.ts` | export `FIGMA_TOKEN_TO_CODE_TOKEN` + `CODE_TOKEN_TO_FIGMA_TOKEN` |
| figma 真源 1 | `figma-data/raw/components.index.json` | figma 全量 component 列表（参考 `audit-figma-published-vs-code.mjs` path） |
| figma 真源 2 | `figma-data/normalized/variables.json` | figma token 列表（color / dimension Variables） |
| figma 真源 3 | `figma-data/published/icons/manifest.json` | 已发布图标列表 |
| figma 真源 4 | `figma-data/normalized/figma-styles.json` | Text / Effect / Fill / Grid Styles |
| code 锚点 | `src/canonical/<Component>.vue` | defineProps grep 验证 |

### 2.2 维度 1: figma-data → translation 覆盖率（forward）

对每个 figma component / axis / token：

```js
// Pseudo-code
for (const component of figmaComponents) {
  // axis-implementation-map 覆盖
  const hasInstance = axisImplMap.instances.some(i => i.figmaComponent === component.name)
  if (!hasInstance) findings.push({ type: 'unmapped-figma-source', source: 'axis-impl-map', name: component.name })

  // prop-aliases 覆盖（对该 component 的每个 axis / property）
  for (const axis of component.axes) {
    const hasEntry = propAliases.entries.some(e =>
      (e.component === component.name || (e.components && e.components.includes(component.name)))
      && e.figmaName === axis.name
    )
    if (!hasEntry) findings.push({ type: 'unmapped-figma-source', source: 'prop-aliases', name: `${component.name}.${axis.name}` })
  }
}

// token 覆盖
for (const tokenName of figmaTokenNames) {
  if (!(tokenName in FIGMA_TOKEN_TO_CODE_TOKEN)) {
    findings.push({ type: 'unmapped-figma-token', name: tokenName })
  }
}
```

**实证检查**：先跑一次看 finding 总数。如果 finding 数 > 50，先 STOP 报告给 plan owner — 数太多说明 allowlist 范围决策需要 plan owner 拍板（不是 executor 自决 50 个 entry 进 allowlist）。

### 2.3 维度 2: translation → code 反向一致（backward）

```js
// prop-aliases.json component-prop entry → defineProps
for (const entry of propAliases.entries.filter(e => e.scope === 'component-prop')) {
  const canonicalPath = `src/canonical/${entry.component}.vue`
  if (!existsSync(canonicalPath)) continue  // skip if canonical doesn't exist (some components only in src/components)
  const source = readFileSync(canonicalPath, 'utf8')
  const definePropsRe = /defineProps[\s\S]*?\{[\s\S]*?\}/
  const propsBlock = source.match(definePropsRe)?.[0] ?? ''
  if (!new RegExp(`\\b${entry.codeName}\\b`).test(propsBlock)) {
    findings.push({ type: 'stale-code-anchor', entry: entry.id, prop: entry.codeName, file: canonicalPath })
  }
}

// axis-impl-map verifyHint
for (const instance of axisImplMap.instances) {
  if (!instance.verifyHint || !instance.verifyHint.startsWith('grep')) continue
  // safety: 只允许 grep 命令，不让 audit 执行任意 shell
  const result = execGrep(instance.verifyHint)
  if (result.lines === 0) findings.push({ type: 'stale-anchor', instance: instance.id })
}

// icon-aliases.ts values → figma-icons manifest
for (const figmaName of Object.values(ICON_ALIAS_TO_FIGMA_NAME)) {
  if (!iconManifest.icons.some(i => i.name === figmaName)) {
    findings.push({ type: 'icon-not-in-figma', name: figmaName })
  }
}

// token-aliases.ts keys → figma variables
for (const figmaToken of Object.keys(FIGMA_TOKEN_TO_CODE_TOKEN)) {
  // figma token 名匹配规则需 verify — 可能 normalize.json 里是 collection/name 复合 ID
  // 起手 read figma-data/normalized/variables.json + figma-styles.json 看 schema 再写匹配
  if (!figmaTokenSet.has(figmaToken)) {
    findings.push({ type: 'token-not-in-figma', name: figmaToken })
  }
}
```

**注意**：`figma-styles.json` 路径 figma 真源 4 — 含 Text / Effect / Fill Styles（token-aliases.ts 末尾段有 L1 shadow / Roboto / spacing / radius 这些是 Styles 不是 Variables）。

### 2.4 维度 3: JSON Schema 验证

对 3 个 JSON 用 AJV 2020 validate（spec §3 dialect note）：

```js
import Ajv2020 from 'ajv/dist/2020.js'
const ajv = new Ajv2020({ strict: true })

for (const { data, schema, name } of [
  { data: axisImplMap, schema: axisImplSchema, name: 'axis-implementation-map' },
  { data: propAliases, schema: propAliasesSchema, name: 'prop-aliases' },
  { data: divergencesDecisions, schema: divergencesSchema, name: 'divergences-decisions' },
]) {
  const validate = ajv.compile(schema)
  if (!validate(data)) {
    findings.push({ type: 'schema-violation', source: name, errors: validate.errors })
  }
}
```

### 2.5 维度 4: divergences resolved 实证

```js
for (const decision of divergencesDecisions.decisions.filter(d => d.category === 'resolved')) {
  if (!decision.verifyHint || !decision.verifyHint.includes('grep')) continue
  const result = execGrep(decision.verifyHint)
  // verifyHint 形如 "grep -rE \"['\\\"]success['\\\"]\" src/components/Notification/ → 0 hits"
  // 期望 0 hits；若有 hits → regression
  if (result.lines > 0) {
    findings.push({ type: 'regression', decision: decision.id, hits: result.lines })
  }
}
```

**Sprint 3 已暴露问题**：`Notification.type` verifyHint 太宽（`grep -n "type"`）会大量假阳性。**Sprint 4 处理策略**：
- 若 `decision.verifyHint` 太宽（如包含 `"type"` 这种 token 单词），audit 跑出 hits 但**不**标 regression
- 改标 `weak-verify-hint` finding，作 plan owner 复审项不阻断 publish
- 收窄 verifyHint 是 Sprint 4 后续任务（如果跑出来发现），但**不**在本 sprint scope（fidelity 1:1 不修 Sprint 1-3 数据）

### 2.6 维度 5: token-aliases 双向一致性

```js
for (const [figmaName, codeToken] of Object.entries(FIGMA_TOKEN_TO_CODE_TOKEN)) {
  if (CODE_TOKEN_TO_FIGMA_TOKEN[codeToken] !== figmaName) {
    findings.push({ type: 'bidirectional-inconsistency', forward: { figmaName, codeToken }, reverse: { codeToken, expected: figmaName, actual: CODE_TOKEN_TO_FIGMA_TOKEN[codeToken] } })
  }
}
for (const [codeToken, figmaName] of Object.entries(CODE_TOKEN_TO_FIGMA_TOKEN)) {
  if (FIGMA_TOKEN_TO_CODE_TOKEN[figmaName] !== codeToken) {
    findings.push({ type: 'bidirectional-inconsistency', reverse: { codeToken, figmaName }, forward: { figmaName, expected: codeToken, actual: FIGMA_TOKEN_TO_CODE_TOKEN[figmaName] } })
  }
}
```

### 2.7 Allowlist 机制

**路径**：`figma-sync/audit-allowlist/translation-completeness.json`（**不**在 figma-data 下；同 `dimension-tokens.json` 同目录）

**格式**：按 finding 类型分组

```json
{
  "unmapped-figma-source": [
    "Account Name",
    "Time Zone",
    "Logo & Service Name",
    "...layout container 名称..."
  ],
  "unmapped-figma-token": [],
  "stale-anchor": [],
  "stale-code-anchor": [],
  "icon-not-in-figma": [],
  "token-not-in-figma": [],
  "regression": [],
  "weak-verify-hint": [],
  "schema-violation": [],
  "bidirectional-inconsistency": []
}
```

**初始内容**：先跑 audit 不带 allowlist，看 finding 总数 + 分类；plan owner 复审后填初始 allowlist。

### 2.8 退出码 + 输出

```js
// audit-translation-completeness.mjs 末尾
if (filteredFindings.length === 0) {
  console.log('✅ audit:translation-completeness PASS')
  process.exit(0)
} else {
  console.error(`❌ audit:translation-completeness FAIL — ${filteredFindings.length} findings`)
  console.error(JSON.stringify(filteredFindings, null, 2))
  process.exit(1)
}
```

**JSON 输出**：`figma-data/normalized/translation-completeness.audit.json`（同 `published-vs-code.audit.json` 范式）

含 idempotent write（按 audit-figma-published-vs-code.mjs 的 `writeJSON` + `stripPaths(['generatedAt'])` 范式，避免 git churn）。

---

## 3. 任务输出（7 个 deliverable）

### D1: `figma-sync/audit-translation-completeness.mjs`

实现 5 维 audit（§2 详述）。参考 `figma-sync/audit-figma-published-vs-code.mjs` 范式：
- ESM imports
- ROOT/path resolve
- idempotent writes（INFRA-F30 pattern）
- exit 0 / 1
- console summary

**首次跑要点**：
- 先跑**不接 allowlist** 版本，看 finding 总数 + 分类
- 如总数 > 50 → **STOP** 报告 finding 分类给 plan owner，**不要**自决 50 个 allowlist
- 如总数 ≤ 50 → 把明显应 allowlist 的（layout container 等）放进 D2，跑到 0 fail

### D2: `figma-sync/audit-allowlist/translation-completeness.json`

按 §2.7 格式建初始 allowlist。

### D3: `package.json` 加 script + 升 10th strict gate

```json
{
  "scripts": {
    "audit:translation-completeness": "node figma-sync/audit-translation-completeness.mjs",
    "prepublishOnly": "pnpm run audit:icon-fill-currentcolor && pnpm run audit:no-hardcoded-design-tokens && pnpm run audit:component-no-inline-svg && pnpm run audit:figma-conformance && pnpm run audit:docs-site && pnpm run audit:component-tokens && pnpm run audit:tokenized-diff && pnpm run audit:design-system && pnpm run audit:published-vs-code && pnpm run audit:translation-completeness"
  }
}
```

**注意**：10th gate 必须 audit 跑通 (exit 0) 后才能升 strict。先 D1+D2 跑到 0 fail，再 D3 改 `prepublishOnly`。

### D4: `docs/RELEASING.md` gate 表更新

read 现有 file（168 行）找 audit gate 表 / "strict gate" 段，加 10th gate 行。fidelity 保持原格式。

### D5: `docs/STATUS.md` 更新

- 顶部 "Last updated" → 2026-05-14
- "当前版本" 段：v0.2.0 不变（仍是 published version）
- "Active 后续工作" 段：v0.3.0 active 项减 1（Tier 1-A 完成 → 剩 Phase 6.3 / 6.4 / BRIDGE-005）
- "🛠️ Infrastructure" 段（如有 audit gate 计数）：9→10 strict

### D6: `docs/internal/retrospection/design-spec-canonical-alignment-tracker.md` 更新

- "已完成" table 加 4 行（Tier 1-A Sprint 1/2/3/4）
- v0.3.0 段把 Tier 1-A 去掉（已完成）
- 大图段（§大图剩余工作量）v0.3.0 估时更新

### D7: `docs/internal/retrospection/2026-05-14-tier1a-translation-schema.md` 复盘

格式参考 `docs/internal/retrospection/2026-05-13-v020-release-and-infra-f30.md`：

- **TL;DR** — 1-2 段
- **§1 阶段产出** — 4 sprint 摘要表（commit / 内容 / 实际耗时）
- **§2 阶段顺序** — timeline
- **§3 关键决策 / 反模式 / 教训** — 至少含：
  - spec §0 关键发现（5 SoT 实际 6 文件，"split" 路径）
  - Sprint 1 实际 1h vs 估 1 day（4-8x under）
  - Sprint 2 1h vs 估 2-3 day
  - Sprint 3 1h vs 估 2-3 day
  - Sprint 4 实际 vs 估 2-3 day
  - Sprint 3 pre-flight gate 措辞 oversight + 修正
  - 新加 status enum（`approved` / `bridge-tier3-dep`）/ 新 category（`component-level-translation`）
  - allowlist 路径修正（`figma-sync/` 不是 `figma-data/`）
  - Notification.type verifyHint 太宽 → `weak-verify-hint` finding（Sprint 4 处理）
  - Alert ❓ unconfirmed（Sprint 3 报告，未解决项进 backlog）
- **§4 解锁的后续工作** — Phase 6.6 / 6.7 / 6.8 / BRIDGE-005 / Tier 1-B / 1-C / T4b AI manifest
- **§5 验证证据** — 全 10 audit pass，3 schema validate，pre-commit hook green

---

## 4. 执行步骤（按顺序）

1. 起手 §0 pre-flight 全绿
2. Read 5 个 translation SoT + 4 个 figma 真源（建立全貌）
3. **先 implement audit D1 — 不接 allowlist + 不升 strict**
4. 跑一次 audit，输出 finding 总数 + 分类（console.log）
5. **如 finding 总数 > 50 → STOP，报告给 plan owner，等拍板 allowlist 范围**
6. 如 finding 总数 ≤ 50 → 按 §2.7 写 D2 allowlist（layout container 等明显项）
7. 再跑 audit，验证 0 fail
8. D3 改 `prepublishOnly` 升 10th strict gate
9. 跑 `pnpm run prepublishOnly` 全 10 audit 全绿
10. D4-D7 docs 更新
11. 跑 §5 验收命令
12. STOP + 报告

---

## 5. 验收命令

```bash
# D1 + D2 — 文件存在
test -f figma-sync/audit-translation-completeness.mjs
test -f figma-sync/audit-allowlist/translation-completeness.json

# audit 单跑 0 fail
pnpm run audit:translation-completeness
# 预期：✅ audit:translation-completeness PASS

# D3 — 10th gate 接入
grep "audit:translation-completeness" package.json
# 预期：至少 2 处命中（一处 scripts 定义，一处 prepublishOnly 末尾）

# 全 10 audit prepublishOnly 跑通
pnpm run prepublishOnly
# 预期：每个 audit ✅ PASS，整体 exit 0

# Sprint 1+2+3 baseline 仍 OK
node -e "
  const Ajv2020 = require('ajv/dist/2020.js').default;
  const ajv = new Ajv2020({ strict: true });
  const v1 = ajv.compile(require('./src/design-system/translation/schemas/axis-implementation-map.schema.json'));
  const v2 = ajv.compile(require('./src/design-system/translation/schemas/prop-aliases.schema.json'));
  const v3 = ajv.compile(require('./src/design-system/translation/schemas/divergences-decisions.schema.json'));
  if (!v1(require('./src/design-system/translation/axis-implementation-map.json'))) process.exit(1);
  if (!v2(require('./src/design-system/translation/prop-aliases.json'))) process.exit(1);
  if (!v3(require('./src/design-system/translation/divergences-decisions.json'))) process.exit(1);
  console.log('Sprint 1+2+3 baseline still OK');
"

# D4 — RELEASING.md 含 10th gate
grep "translation-completeness" docs/RELEASING.md
# 预期：>=1 命中

# D5 — STATUS.md last updated 今天
head -3 docs/STATUS.md | grep "2026-05-14"
# 预期：1 命中

# D6 — tracker 含 Tier 1-A Sprint
grep "Tier 1-A\|tier1a-sprint" docs/internal/retrospection/design-spec-canonical-alignment-tracker.md | head
# 预期：>=4 命中（4 sprint 各一）

# D7 — retrospect 文件存在
test -f docs/internal/retrospection/2026-05-14-tier1a-translation-schema.md

# 全套测试 + typecheck 0 回归
pnpm test                                       # 105 passed | 1 skipped
pnpm exec vue-tsc --noEmit                      # 0 错

# idempotent write 验证（INFRA-F30 pattern）
pnpm run audit:translation-completeness         # 跑两次
pnpm run audit:translation-completeness
git status figma-data/normalized/translation-completeness.audit.json
# 预期：clean（idempotent 不触发 dirty）
```

**任一验收 fail → STOP，不要硬上**，报告给 plan owner。

---

## 6. 报告格式（STOP 后必交）

```markdown
## Sprint 4 完成报告

### 改动文件清单（7 deliverable）
- [ ] D1 figma-sync/audit-translation-completeness.mjs（X 行）
- [ ] D2 figma-sync/audit-allowlist/translation-completeness.json（initial allowlist Y 项）
- [ ] D3 package.json 加 script + 升 10th strict gate
- [ ] D4 docs/RELEASING.md gate 表更新
- [ ] D5 docs/STATUS.md 更新（last updated / active 段 / infra 段）
- [ ] D6 docs/internal/retrospection/design-spec-canonical-alignment-tracker.md 已完成段加 4 sprint
- [ ] D7 docs/internal/retrospection/2026-05-14-tier1a-translation-schema.md 复盘

### Audit baseline 数据
- 5 维 finding 总数（首次跑不接 allowlist）：Z
- 各维分布：
  - 维度 1 forward 覆盖率：unmapped-figma-source: A1, unmapped-figma-token: A2
  - 维度 2 backward 一致性：stale-anchor: B1, stale-code-anchor: B2, icon-not-in-figma: B3, token-not-in-figma: B4
  - 维度 3 schema 验证：schema-violation: C
  - 维度 4 resolved 实证：regression: D1, weak-verify-hint: D2
  - 维度 5 双向一致：bidirectional-inconsistency: E
- Allowlist 范围（D2）：F 项
- 最终 audit fail count（10th strict）：G（应为 0）

### 验收结果
- pnpm run audit:translation-completeness（单跑）: [PASS / FAIL details]
- pnpm run prepublishOnly（10 audit）: [全 PASS / 哪个 fail]
- Sprint 1+2+3 baseline：[OK / fail]
- pnpm test: [105 passed | 1 skipped / fail]
- vue-tsc: [0 错 / 报错]
- idempotent write 验证：[clean / dirty]
- docs 更新：[D4/D5/D6/D7 全交 / 缺哪个]

### 实际耗时
[Xh，对比 spec §4 估 2-3 day]

### Sprint 1-4 全程实际 vs 估时
[Sprint 1: 1h vs 1d / Sprint 2: 1h vs 2-3d / Sprint 3: 1h vs 2-3d / Sprint 4: Xh vs 2-3d]

### Open Issue 处理结果
- Notification.type verifyHint 太宽 → 是否 classified as `weak-verify-hint`？发现 N 项类似 weak hints？
- Alert ❓ unconfirmed → 留 backlog？还是 audit 跑出 / allowlist 覆盖？

### 未解决 / 待 plan owner 决策项
[列任何 sprint 4 中遇到的 plan owner 判断项，特别是：
- Finding 是否归 allowlist vs 真 bug
- weak-verify-hint 是 finding 还是 silent skip
- Schema validation 失败如何处理
- ...]
```

---

## 7. 严格不做的事（executor 边界）

- ❌ 改 Sprint 1-3 translation SoT 数据（fidelity 1:1，audit 是消费方）
- ❌ 改既有 9 个 audit 脚本逻辑（只新增 1 个）
- ❌ 改 Figma plan 假设 / consumer code / canonical 组件
- ❌ 自决大批量 allowlist 项（> 50 finding 时 STOP 报告，让 plan owner 拍板）
- ❌ 升 strict 前不验证 audit 0 fail
- ❌ 修 verifyHint（如 Notification.type 太宽）— 留 backlog，sprint 5+ 处理
- ❌ commit — plan owner 审完后用户决定
- ❌ 触发 changeset / release v0.3.0 — wrap-up 后 plan owner 决定 release 节奏
- ❌ 改 STATUS.md "当前版本" 段（v0.2.0 仍 latest published；Tier 1-A 只是 v0.3.0 in-progress）

---

## 8. 完成后 STOP

把报告交给 plan owner，由 plan owner 复审 + 用户决定：

- 是否 commit sprint 4
- 是否 release v0.3.0（含 Phase 6.3/6.4/BRIDGE-005 一起？还是先 Tier 1-A 独立 v0.3.0-alpha？）
- 是否进 v0.3.0 其它主线（Phase 6.3 删 Notification.success / 6.4 加 props / BRIDGE-005 boolean schema）

Tier 1-A 收尾后**重大解锁**：能力 5 溯源 schema 化落地，T4b AI manifest 前置就绪。
