№ · 任务清单 CH.07.03
主页 · 📃 任务清单 · Day 4 R6 字段净化 — 短工 Input Spec v1.0

Day 4 R6 字段净化 — 短工 Input Spec v1.0

📅 2026-07-03 · 📦 12.2 KB · 📃 任务清单 · 📝 MD 文档 🏷️ 装备🏷️ 主链🏷️ 短工🏷️ 剧情🏷️ 计划🏷️ 时间

整理时间:2026-07-03 16:58 +08:00 整理人:Mavis(PM / 制作人视角) 本 spec 用途:Day 4 R6 短工([短工]#story-tracking-字段净化@v1.2)接到本任务时的 input spec;短工按 spec 一条条对着改,需要再读全 剧情追踪-字段净化与输出规则-v1.md 真相源:docs/design/active/剧情追踪-字段净化与输出规则-v1.md(2026-07-02 落盘) 5 日计划出处:docs/plans/active/2026-07-06-5日开发计划-v1.md § Day 4 主任务 R6(v1.2 新增) 本次校对的真值偏差:5 处改动位置部分行号与 v1.2 计划写的有偏差,本 spec 用 grep 实勘的真行号;同时发现 1 处 v1.2 未列的开发者字段(下文 § 1.6)


0. TL;DR(60 秒版)

| 项 | 内容 | | :--- | :--- | | 总改动文件数 | 4 代码文件 + 1 文档 | | 总改动 JSX / Data 行数 | ~25 行(精确行号见 § 1) | | 不动什么 | src/utils/failureEndgame.ts / src/utils/jianghuBriefing.ts / 16 件装备数据 / 任何 lane 外代码 | | 预估工时 | 3 - 4h(短工) | | 风险等级 | 中(动了玩家界面文案 + JSX,需 build + lint + 截图对照) |


1. 精确真行号清单(grep 实勘,2026-07-03 16:55)

1.1 src/components/StoryTrackingCard.tsx(3 处)

改动 A:line 501 - 505 — 删除 bridge?.mainchainLine 渲染块(主链紫色小条)

// 当前(line 501-505):
{bridge?.mainchainLine && (
  <div className="mt-2 rounded-lg border border-[#e6d8c8] bg-white/80 px-2.5 py-1.5 text-[9.5px] font-semibold leading-5 text-[#7a4f2b]">
    主链:{bridge.mainchainLine}
  </div>
)}

目标:整个 if 块删除(包括 501 - 505 共 5 行)。

注意:不要删 bridge 变量本身或 bridge 数据来源(只删渲染块),因为 bridge.trackingJumpTarget 等其他字段还要用。

grep 引用:bridge?.mainchainLine 在文件 line 501(line 137 还有一处声明,line 97 还有 comparison,这些都是声明 / 比较位置,不是渲染块,不删)

改动 B:line 516 — 删除 属性:

// 当前(line 516):
<span>属性:{storyTracking.year1Plan.attributeLine}</span>

目标:删除整行(line 516)。

注意:不要删 attributeLine 数据来源(src/data/year1Plan.ts:353-356 的属性拼接代码),只删 UI 层渲染。如果之后场景还要用,数据层保留。

改动 C:line 519 - 521 — 改写 验收:

// 当前(line 519-521):
<div className="mt-1 truncate" title={storyTracking.year1Plan.checklistLine}>
  验收:{storyTracking.year1Plan.checklistLine}
</div>

改写目标(依据 truth source § 4 阶段平铺规则):

  • 删除 truncate + title 整段(line 519 整行 line 520 整行 line 521 整行共 3 行)
  • 替换为 只显示 checklistStage.label + passSignal + mustNodes 进度(✓ / ○,如果数据支持)
  • 数据来源:storyTracking.year1Plan.checklistStage(注意:真值字段名是 checklistLine 拼字符串,不是 checklistStage 对象) — 短工需要确认 Year1PlanSnapshot.checklistStage 在 types 里是否存在,如果没有,短工可决定是否新建字段(本 spec 范围内 Year1PlanChecklistStage 应已存在于 src/data/year1Plan.ts:45-53,可直接对接)

真值偏差提醒:v1.2 计划写的是 checklistStage.label + passSignal + mustNodes,真值 grep 显示当前只有 checklistLine(字符串拼)。短工需先读 src/data/year1Plan.ts:45-72Year1PlanChecklistStage 类型定义,确认是否真有 passSignal + mustNodes 字段,如有就直接对接使用;如无,本 spec 不要求新建类型(留 v1.1)。

改动 D(line 517 — v1.2 计划未列出,真值发现):删除 投放:

// 当前(line 517):
<span>投放:{storyTracking.year1Plan.itemLine}</span>

是否删除判断依据:itemLine 来源是 src/data/year1Plan.ts:357:const itemLine = '${itemBand.focus} · ${itemBand.storyItems.slice(0, 2).join(' / ')}'; —— 这里有 · 拼接符号 + storyItems 数组,是开发者字段(看 storyItems 像内部 ID 列表)。

短工处理选项:

  • 选项 B.1 ✅ 推荐:删除整行(line 517),让玩家只看验收 / 阶段 / 阶段进度。如果认为"投放"对玩家有意义,可改写为更直观的中文。
  • 选项 B.2:保留 line 517 + line 357 简化:const itemLine = itemBand.focus;(只保留 focus,丢 storyItems 切片)
  • 选项 B.3:保留原状

默认:走 选项 B.1(最干净,与"删开发者字段"主线一致)

1.2 src/data/year1Plan.ts — line 357 — itemLine 简化(只动 line 357,其他不动)

前提:走 § 1.1 改动 D 的 选项 B.2 而不是 B.1 时,才动这一处。如果走 B.1,这一处不改

// 当前(line 357):
const itemLine = '${itemBand.focus} · ${itemBand.storyItems.slice(0, 2).join(' / ')}';

目标改写(选项 B.2 时):

const itemLine = itemBand.focus;

配套:line 40 的 storyItems: string[]; 字段不动(数据层保留,Phase 2 + 可能用)。

1.3 src/App.tsx — line 3044 - 3050 — nextHint 加长度截断(≤ 24 字)

// 当前(line 3044-3050):
const nextHint =
  primaryBond?.unlockEffects[0] ??
  briefingLead?.detail ??
  briefingLead?.summary ??
  (yearTracking ? `下一章:${yearTracking.nextChapterTitle}` : undefined) ??
  jianghuBriefingReport.sections.upcoming[0]?.summary ??
  "先触发剧情事件或打开江湖简报。";

目标改写(在 line 3050 后插入截断逻辑):

// 新增 line 3050b(在 const nextHint 块后,line 3051 前):
const nextHintSafe =
  nextHint && nextHint.length > 24
    ? nextHint.slice(0, 24).trimEnd() + '…'
    : nextHint;
// 把后续所有 nextHint 用法(line 3117 等)改为 nextHintSafe

注意:

  • nextHint 用法不止 line 3117 一处。短工需要 grep src/App.tsx -n 'nextHint' 全扫,然后把所有引用统一改为 nextHintSafe
  • 如果扫出的引用大于 1 处,需确认变量重命名不冲突;如有冲突,可保留 nextHint 原变量,新增 nextHintSafe 变量,然后在每个引用点改用 nextHintSafe
  • "叙事化过滤(去掉 :xxx 后超 20 字的列表段)" 这条 v1.2 R6 提到,本 spec 范围内做长度截断;叙事化过滤留 v1.1(如需实现,需新建工具函数,扩大范围不在本 spec)。

1.4 AGENTS.md — 第 4 节新增「玩家文案 vs 开发者字段」段落

真值现状:AGENTS.md 是项目根目录,落到 AGENTS.md。第 4 节是「命名约定」,目前在第 4 节末尾(看主题文档)。短工需先读 AGENTS.md 第 4 节,确认其结构,然后追加一段。

新增段落内容(按 剧情追踪-字段净化与输出规则-v1.md § 4 复刻):

### 玩家文案 vs 开发者字段(5 日计划 v1.2 R6 引入,2026-07-04)

- 玩家能看到的 UI 文案**不**应出现 `tax_reported` / `brief=risk-tax_reported` / `主语:...・压 ...` / `属性:服务 / 厨艺 / 账房 / 巡防` / `验收:xxx -> xxx ->` 等开发者 / 调试字段。
- 阶段平铺规则:阶段验收区只显示 `checklistStage.label` + `passSignal` + mustNodes 进度(✓ / ○),不展开 6 段完整流水线。
- 数据层 `src/data/year1Plan.ts` 的 `attributeLine` / `itemLine` / `checklistLine` 是**数据层拼接 helper**,**不**要直接进 UI(只保留 `focus` 等**对玩家有意义**的字段)。
- 如果场景需要调试信息,加 `?dev=1` 入口(留 v1.1),本 5 日不实现。

2. 文件边界(短工只动这 4 + 1 文件)

| 文件 | 改动位置 | 改动性质 | | :--- | :--- | :--- | | src/components/StoryTrackingCard.tsx | line 501 - 505 / 516 / 517 / 519 - 521(选) | JSX 删除 + 改写 | | src/data/year1Plan.ts | line 357(选,跟 § 1.2 选项 B.2 配套) | Data 简化 | | src/App.tsx | line 3050 后插入 + 所有 nextHint 用法引用点 | 长度截断 | | AGENTS.md | 第 4 节末尾新增段落 | 文档 | | docs/handoff/index.md(可选) | 同步 Update 段 | 文档 |

完全不动:

  • src/utils/failureEndgame.ts(任何既有 ID / 规则)
  • src/utils/jianghuBriefing.ts mainchainLine 构造逻辑(逻辑保留,UI 层不用即可)
  • src/data/items/**(16 件装备数据)
  • src/App.tsx 壳层 / 主导航 / bridge 跨模块跳转(tasklineFailureJump / briefingJump 跳功能)

3. 验收

  • [ ] (a) npm run build 通过 + npm run lint新增错误
  • [ ] (b) 截图对照:剧情追踪面板再有 tax_reported / brief=risk-tax_reported / 主语:...・压 ... / 属性:服务 / 厨艺... / 验收:xxx -> xxx -> 等开发者字段
  • [ ] (c) bridge 跨模块跳转(tasklineFailureJump)功能受影响 — 测试一次终局解释层跳转 + 一次江湖简报跳转
  • [ ] (d) AGENTS.md 第 4 节新增段落落盘
  • [ ] (e) nextHint 截断生效:取一个长度 ≥ 24 字的 hint 来源(比如 jianghuBriefingReport.sections.upcoming[0]?.summary 如果有),验证渲染 ≤ 24 字 + 末尾有
  • [ ] (f) Day 5 短工 phase1-roll-regression 的视觉对照 checklist 加 1 条「剧情追踪面板字段净化对照」(依赖本 lane 落盘)

4. 不做什么

  • ❌ 不实现 ?dev=1 调试入口(留 v1.1)
  • ❌ 不重做 StoryTrackingCard 整体组件架构(留 W28+)
  • ❌ 不动 failureEndgame.ts 任何既有 ID / 规则
  • ❌ 不动 jianghuBriefing.ts mainchainLine 构造逻辑
  • ❌ 不动 16 件装备数据
  • ❌ 不实现"叙事化过滤(去掉 :xxx 后超 20 字的列表段)"(留 v1.1)
  • ❌ 不动 5 日计划核心路径(R2 → R1.0 → R1.1 → R1.3 → R1.4 → R1.5 → R1.6)
  • ❌ 不实现 bridge 数据层重构(只删渲染块 + 简化 itemLine)

5. 风险与回退

| 风险 | 触发条件 | 回退方案 | | :--- | :--- | :--- | | 改动打回归,撞 bridge 跨模块跳转 | bridge.mainchainLine 改成别处用 | 仅删渲染块(line 501-505),bridge 数据保留 | | nextHint 截断后某场景渲染出错 | nextHint 用法分布在 > 1 处,改 nextHintSafe 时漏改 | 保留 nextHint 变量,新增 nextHintSafe;或回退恢复所有引用,只 line 3050 后插入截断不动原变量 | | AGENTS.md 第 4 节结构差异 | 不同时期不同人编辑过 | 先读全 4 节,只在末尾追加,不替换既有段 | | Year1PlanSnapshot.checklistStage 在 types 里存在 | 上游 reviewer 改了类型 | 短工不动类型,只保留当前 checklistLine 渲染 + 加个注释"待 v1.1 升级" |


6. 给短工的 quick checklist(打印这页贴桌面)

□ 读 src/components/StoryTrackingCard.tsx 全文 528 行(确认 mainchainLine / attributeLine / itemLine / checklistLine 4 个字段的渲染位置)
□ 改 A:line 501-505 删除(整 5 行,包括外层 if)
□ 改 B:line 516 删除(整 1 行)
□ 改 D:line 517 删除(整 1 行)— 默认选项 B.1
   或 line 517 保留 + 改 src/data/year1Plan.ts:357(选项 B.2)
□ 改 C:line 519-521 改写(整 3 行替换为 checklistStage.label 渲染)
□ 改 src/App.tsx:line 3050 后插入 nextHintSafe + 改所有 nextHint 引用
□ 改 AGENTS.md:第 4 节末尾新增段落
□ 跑 npm run build + npm run lint(无新增错误)
□ 截图核对(用 browser / quick visual demo)
□ 跑一次跨模块跳转终局解释 + 跨模块跳转江湖简报(bridge 不受影响)
□ 回执:5 处改动 diff + 截图 + 测试结果

7. 参考入口

| 想看什么 | 去这里 | | :--- | :--- | | R6 truth source | docs/design/active/剧情追踪-字段净化与输出规则-v1.md | | 5 日计划 v1.2 R6 主任务 | docs/plans/active/2026-07-06-5日开发计划-v1.md § Day 4 主任务 R6 | | Phase 1 真值快照(不动此 spec 但相关)| docs/design/active/phase1-equipment-code-layer-snapshot-v1.md | | 当前 handoff 状态 | docs/handoff/index.md | | AGENTS.md 守则(第 4 节位置) | AGENTS.md | | StoryTrackingCard.tsx | src/components/StoryTrackingCard.tsx(528 行) | | year1Plan.ts | src/data/year1Plan.ts(371 行) | | App.tsx nextHint | src/App.tsx:3044-3117 |


8. 版本与变更记录

| 版本 | 时间 | 整理人 | 关键变更 | | :---: | :--- | :--- | :--- | | v1.0 | 2026-07-03 16:58 | Mavis(PM 视角) | 首版:Day 4 R6 字段净化短工 input spec,基于 grep 实勘真行号 + 5 处改动位置 + 1 处发现(投放:itemLine 也是开发者字段) |


(End of spec — § 0 - § 8,预计 8 - 10 KB)