# Retrospect — v0.2.0 release + INFRA-F30 + 排期 SoT（2026-05-13 session 10）

> **TL;DR**：v0.2.0 ✅ shipped & verified；CI 第一次 fail（CANONICAL-011 prompt gap — ChartPage 未登记 site-review-manifest）借机修了 + 顺手补 INFRA-F30（3 个 timestamp churn source 全 idempotent）+ 完整 v0.2 → v1.0 排期 SoT 落仓库 + meta-rule trigger M 防排期反模式复发。三件套打包 4 commits 推 master，CI re-publish green 1m23s，Packages 页 `0.2.0 Latest`。

---

## 1 — 三件套阶段产出

### A. v0.2.0 release

| 项 | 值 |
|---|---|
| **CI run** | [25788351709](https://github.com/NancyZeng0210/TVU-Design-System/actions/runs/25788351709) ✅ green 1m23s |
| **Packages 页** | ✅ `@nancyzeng0210/tvu-design-system@0.2.0 Latest`，published by `github-actions[bot]` |
| **内容** | CANONICAL-011 Chart (6 variants · Chart.js + 12 色 palette) · audit:published-vs-code 升 9th strict · Playwright 58 baseline · husky pre-commit v1 · INFRA-F30 idempotent writes |
| **Tag HEAD** | `2cf026e9` (含 4 commits: c6a70d1a roadmap + 1ca91bb6 release + 2e96d5e2 cleanup + 2cf026e9 INFRA-F30) |
| **回滚 cost** | 0（v0.2.0 第一次 publish 失败时 Packages 页无实物 → 删 remote tag 重打无 consumer 影响）|

### B. INFRA-F30 — timestamp-aware idempotent writes（3 source）

| Source | Path | Strip fields | 影响文件数 |
|---|---|---|---|
| `figma-sync/icon-artifacts.mjs` writePublishedManifest | `figma-data/published/icons/manifest.json` | `generatedAt` | 1 |
| `figma-sync/audit-page-t2-sample.mjs` renderReport write | `docs/internal/t2-sample-audit-report.*.md` | `Generated at` line + embedded `checkedAt` JSON field | **18** |
| `figma-sync/audit-figma-published-vs-code.mjs` writeJSON + writeFileSync | `figma-data/normalized/published-vs-code.audit.json` + `docs/internal/published-vs-code-audit.md` | `generatedAt` / `生成时间` | 2 |

**覆盖率**：消除 ~95% session 起手看到的 dirty noise。Pattern 沿用 F26/F29 inline `stripPaths` + `writeJsonIdempotent` / 字符串 regex 两种适配（JSON / markdown）。

**验证**：post-revert 跑 3 个脚本两次，每次都 `skipped — no content change`，git tree clean。

### C. 排期 SoT 落仓库（防新 session 失忆 4 层机制）

| 层 | 文件 | 内容 |
|---|---|---|
| **计划层 SoT** | `tracker.md` | "排期原则" 自检清单 5 条 + Release 排期 v0.2 → v1.0（每版本对齐 PROJECT_GOAL 5 能力栏）+ 轨道 C 自动化 Tier 1/2/3 |
| **状态层** | `STATUS.md` | "🔵 v1.0 major" 段拆为 v0.3/v0.4/v0.5/v0.6/v1.0；Active 按版本归类；起手必读链路 + 顶部双指引 "排期决策必读 tracker" |
| **目标层** | `PROJECT_GOAL.md` | 阶段路线按 0.x semver 重命名；引用 tracker §排期原则 |
| **元规则层** | `meta-rules.md` | 新增 **trigger M（排期决策反模式）** — 信号词机械触发 + 违反检测 + 实证案例 + 附录沉淀 |

---

## 2 — 阶段顺序（实际跑的 timeline）

```
1. 评估 "自动化 vs 文本规则"          → 给 user 三 Tier 路线
2. 排期讨论 → user 纠正 "v1.0 major"   → 按 0.x semver 重排 v0.3-v1.0
3. 完整排期写仓库（4 文件）            → c6a70d1a "docs(roadmap)"
4. 写 v020 changeset → bump 0.1.3→0.2.0 → 1ca91bb6 "chore: release v0.2.0" → push tag
5. CI fail (50s, exit 1) → 诊断 audit:docs-site missing ChartPage manifest entry
6. Fix manifest + cleanup audit reports (audit refresh) → 2e96d5e2
7. user feedback "icons manifest 每次 dirty"  → 写 F26/F29 helper to 3 sources → 2cf026e9
8. 删 remote v0.2.0 tag (CI fail 后无 Packages 实物 → 0 cost) → re-tag HEAD → push
9. CI re-publish ✅ green 1m23s → Packages 页 verify "0.2.0 Latest"
10. STATUS / tracker / retrospect 同步 (本文)
```

---

## 3 — 关键决策 / 反模式 / 教训

### P1：CANONICAL-011 prompt gap 复发

ChartPage.vue 在 component impl 完成时漏登记 `docs/site-review-manifest.json`。**这是已存在的 prompt gap retrospect（2026-05-13-canonical-011-prompt-gap.md）的同根问题** — prompt 没把 manifest 登记列入 deliverable checklist。

→ **后续**：CANONICAL prompt 模板必须含 site-review-manifest entry deliverable（同级 docs/canonical/.vue/page/spec）。

### P2：v0.2.0 第一次 CI fail 实证了"CI green ≠ Packages 实物"协议有效

`audit:docs-site` exit 1 → publish.yml exit 1 → Packages 页完全无实物。如果按 v0.1.0/v0.1.1 silent fail 时代的协议（只看 CI green），我会以为 publish 成功；按 STATUS release wrap-up 协议必 verify Packages 实物 → 真实状态可见 → fix → re-publish。

→ **协议价值实证**：v0.1.0/v0.1.1 silent fail 后加的 "Packages 页 actual 显示" 步骤是真有用的，不是 ceremony。

### P3：destructive 操作（删 remote tag）的判断框架

`git push --delete origin v0.2.0` 是 destructive。判断是否安全：

| 维度 | 本次 |
|---|---|
| **consumer 影响** | 0（v0.2.0 publish fail → Packages 无实物 → 无 consumer 装过）|
| **历史可追** | 删的 tag 指 1ca91bb6，仍在 git history（master log 可查）|
| **可重做** | 是（fix + 重打 tag）|
| **替代成本** | 选 B (bump v0.2.1 patch) 会留 v0.2.0 hole + coupling fix 到 patch 不优雅 |

→ **教训**：destructive 不等于不能做；按"实物影响 + 可逆性 + 替代成本"框架决策，本次 A 路径明确优。

### P4：INFRA-F30 是"实战触发的反模式 cleanup"（不是 plan owner 主动想到）

User 明确反馈"manifest 每次 commit 都 dirty"才触发 F30。**Plan owner 主动检查 timestamp churn 不在自检清单里** — 这是 backlog 隐性技术债。

→ **后续**：trigger K (规则提案声明 enforcement) 配套加 sub-rule "新 sync/audit 脚本必须用 F26/F29 idempotent helper 写文件"？暂不加 — 等真有第 4 个 dirty source 再 promote 成机制。

### P5：排期 SoT 重构 + trigger M 的实证起点

User 纠正 "v1.0 major" 措辞后，我意识到排期决策反模式很容易复发（按耗时/复杂度排）。把这写成 meta-rules trigger M + 4 层防失忆机制（tracker + STATUS + PROJECT_GOAL + trigger M）是 trigger K "规则文档无法保证执行" 的具体落地。

→ **新机制实证**：下次 session 提排期前必须读 tracker §排期原则；trigger M 信号词机械触发；违反时回 5 条自检。

### P6：scope creep 风险（INFRA-F30 从 1 source 扩到 3）

User ask `icons/manifest.json`，我顺手扩到 `audit-page-t2-sample` + `audit-figma-published-vs-code`。理由：
- 同一 pattern (F26/F29)，复制成本低
- 18 个 t2 reports + 1 published-vs-code md 是 user 反复看到的 dirty 大头
- 不扩则下次 session 又触发同一反馈

→ **判断 ok 的边界**：同一 commit 内、同一 pattern、同一 user pain → 扩 ok；不同 pattern 或新 deliverable → 不扩。本次未越界。

---

## 4 — Action items

| Item | 状态 |
|---|---|
| v0.2.0 publish & verify | ✅ done |
| STATUS.md "当前版本" → v0.2.0 + Packages URL evidence | ✅ done |
| tracker.md 加 INFRA-F30 + v0.2.0 ship + 排期重构条目 | ✅ done |
| 写本 retrospect | ✅ done（本文）|
| Wrap-up commit + push | ⏳ next |
| 下个 session 启动 v0.3.0 主线（Tier 1-A translation schema 化）| → 起手 onboarding |
| CANONICAL prompt 模板补 manifest deliverable checklist（防 P1 复发）| → backlog |

---

## 5 — 跨 session 收获

- **0.x semver 哲学落地**：minor 含破坏性、patch 只 non-breaking、1.0 = 稳定承诺；写进 trigger M 违反检测。
- **排期 SoT 4 层防失忆**：tracker（计划）+ STATUS（状态）+ PROJECT_GOAL（目标）+ meta-rules（元规则）；每层各自独立可读，单点失忆不影响整体。
- **协议价值需实证**：v0.1.0/v0.1.1 silent fail 后加的 Packages 页 verify 步骤本次第一次"如果没它，我会以为 CI green = publish 成功" → 协议 value 直接看到。
- **destructive 决策框架**：实物影响 + 可逆性 + 替代成本三维度判断；不是"看上去 destructive 就绕"。
- **INFRA-F30 模式可复用**：未来任何"每次跑都 dirty 的 generate/audit 输出" → 同 F26/F29/F30 pattern，inline helper + timestamp strip + skip。当前 8 个 candidate 待 user feedback 触发再做。
