docs(tasks): 校正状态板 + 状态下沉第二批 + 后门单 + 对账清单
① 状态板校正:09-15~16 这 10 份任务书的实现早已合入 staging 并经逐单 验收,状态板却仍写「待领取 / 待验收」。改成「已验收」并补上落点 SHA 与验收要点;顺带补齐 8 个 PROGRESS 列。防复发写进「命名与归档」: 实现合入的同一次推送必须同时改状态板那一行。 ② 新增 TASK-home-state-lowering-batch2-20260916(不占 BUG 号): 第一批f8e607c2已验收(useState 66→52、useRef 41→39、散装 rectification* 归零)。本单搬剩下三簇 session*10 / profile*6 / synastry*4,目标 52→≤36;并修第一批尾巴—— createRectificationShellSetters 每帧新身份多出的那条 exhaustive-deps warning(119→120),正解是稳住 setter 身份而不是塞进 deps。 ③ 新增 TASK-api-server-backdoor-close-20260916(不占 BUG 号): 实测四处 __new__ 的传递闭包只有 8 方法 / 314 行且 0 个碰 HTTP 上下文, 占全类 4%。所以关后门不必捆绑 2,000+ 行体量搬运。产品拍板阶段 2/3 不立单,由3b17c1b2换好的门禁长期推进。原 decomposition 单标为已取代。 ④ 新增 RECONCILE-20260916:另外 7 份 09-10~14 的单没有 PROGRESS、但 引用的 BUG 号都是 resolved,无法从 README 判断,列成一页纸让执行方 回填;另附三条确定没做的证据、两条未闭环状态、BLK-001 仍红。 纯文档推送,不触发门禁、不发布镜像、不部署。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JUei7K13cYxLHE3Axe4A45
This commit is contained in:
co-authored by
Claude Opus 5
parent
4f643aa095
commit
37e6c519f7
+16
-12
@@ -83,7 +83,7 @@
|
|||||||
| `TASK-rectification-candidate-compare-columns-20260908.md` | `PROGRESS-rectification-candidate-compare-columns-20260908.md` | 产品决定交付卡改一行三列:每列相对可能性、D9/D10/月宿性格处事、经历对照计数、往后 12 个月事件窗、「更像这个」即采用;引擎按候选分钟各算 ledger 与窗口;顺带 BUG-598 点选题成年下限在 inspect 回退路径缺失(需核对)、采集题「没有」按钮(产品可否决);Skill 10.0.18 | 已验收通过(「没有」按钮等产品答复) | `a43a6db8`(BUG-597~598,Skill 10.0.18) |
|
| `TASK-rectification-candidate-compare-columns-20260908.md` | `PROGRESS-rectification-candidate-compare-columns-20260908.md` | 产品决定交付卡改一行三列:每列相对可能性、D9/D10/月宿性格处事、经历对照计数、往后 12 个月事件窗、「更像这个」即采用;引擎按候选分钟各算 ledger 与窗口;顺带 BUG-598 点选题成年下限在 inspect 回退路径缺失(需核对)、采集题「没有」按钮(产品可否决);Skill 10.0.18 | 已验收通过(「没有」按钮等产品答复) | `a43a6db8`(BUG-597~598,Skill 10.0.18) |
|
||||||
| `TASK-api-not-configured-mislabel-20260904.md` | `PROGRESS-api-not-configured-mislabel-20260904.md` | 16 处路由把数据库瞬断(部署切换窗口)兜底翻译成 503「服务尚未配置」;改为仅配置错误用该文案,其余 `service_unavailable`,收敛为共享 helper | 已验收 | `5483649b`(BUG-542);2 条子进程测试留 CI Node 22 复核 |
|
| `TASK-api-not-configured-mislabel-20260904.md` | `PROGRESS-api-not-configured-mislabel-20260904.md` | 16 处路由把数据库瞬断(部署切换窗口)兜底翻译成 503「服务尚未配置」;改为仅配置错误用该文案,其余 `service_unavailable`,收敛为共享 helper | 已验收 | `5483649b`(BUG-542);2 条子进程测试留 CI Node 22 复核 |
|
||||||
| `TASK-rectification-ux-20260902.md` | `PROGRESS-rectification-ux-20260903.md` | 会话面空白假死与交互摩擦 | 已验收 | `d159f08e`(09-03 在新基线重做后合入,BUG-505~509) |
|
| `TASK-rectification-ux-20260902.md` | `PROGRESS-rectification-ux-20260903.md` | 会话面空白假死与交互摩擦 | 已验收 | `d159f08e`(09-03 在新基线重做后合入,BUG-505~509) |
|
||||||
| `TASK-rectification-timeline-20260909.md` | — | 常驻吸顶时间轴:轴锁**当前**搜索窗口并随放宽缩放、时段/分钟两套标记、候选点二元编码不分置信度(BUG-560 blocked)、无 hover(BUG-575)、只读不可采用。实现用第三个 grid 行而非 `position: sticky`,`useConversationScrollAnchor` 一行不改;条高固定是正确性要求;吸顶条只留区间与宽度两个元素 | 已验收通过;宽度口径与空心点两处未通过→修复单 | `ce91a0d2` |
|
| `TASK-rectification-timeline-20260909.md` | `PROGRESS-rectification-timeline-20260909.md` | 常驻吸顶时间轴:轴锁**当前**搜索窗口并随放宽缩放、时段/分钟两套标记、候选点二元编码不分置信度(BUG-560 blocked)、无 hover(BUG-575)、只读不可采用。实现用第三个 grid 行而非 `position: sticky`,`useConversationScrollAnchor` 一行不改;条高固定是正确性要求;吸顶条只留区间与宽度两个元素 | 已验收通过;宽度口径与空心点两处未通过→修复单 | `ce91a0d2` |
|
||||||
| `TASK-rectification-timeline-fix-20260909.md` | `PROGRESS-rectification-timeline-fix-20260909.md` | 时间轴修复单:宽度读数改含两端分钟数(与 BUG-593 报告/卡片一致);标记改读推断层候选全集,被淘汰分钟留在原地变空心(客户端投影只含 active,DESIGN §10 描述在真实数据下画不出) | 已验收通过 | `92e3d5e7`(BUG-602~603) |
|
| `TASK-rectification-timeline-fix-20260909.md` | `PROGRESS-rectification-timeline-fix-20260909.md` | 时间轴修复单:宽度读数改含两端分钟数(与 BUG-593 报告/卡片一致);标记改读推断层候选全集,被淘汰分钟留在原地变空心(客户端投影只含 active,DESIGN §10 描述在真实数据下画不出) | 已验收通过 | `92e3d5e7`(BUG-602~603) |
|
||||||
| `TASK-rectification-conversation-economy-20260909.md` | `PROGRESS-rectification-conversation-economy-20260909.md` | 对照竞品后产品拍板三条:开场三句讲做法 + 一次收多件(推翻 opening brief「不要一次说完/不举例」与 SKILL L52);采集题「没有 / 记不清」按钮(不做示例骨架条);每轮只留一句(方法句进活动记录、点选旁白去领先落后、证据轮正文一句复述 + 服务端裁剪);Skill 10.0.19 | 已验收通过(2 条 P3 备注) | `aa7ccb30` + `1453fb16`(BUG-604~606,Skill 10.0.19) |
|
| `TASK-rectification-conversation-economy-20260909.md` | `PROGRESS-rectification-conversation-economy-20260909.md` | 对照竞品后产品拍板三条:开场三句讲做法 + 一次收多件(推翻 opening brief「不要一次说完/不举例」与 SKILL L52);采集题「没有 / 记不清」按钮(不做示例骨架条);每轮只留一句(方法句进活动记录、点选旁白去领先落后、证据轮正文一句复述 + 服务端裁剪);Skill 10.0.19 | 已验收通过(2 条 P3 备注) | `aa7ccb30` + `1453fb16`(BUG-604~606,Skill 10.0.19) |
|
||||||
| `TASK-consultation-daily-empty-answer-20260909.md` | `PROGRESS-consultation-daily-empty-answer-20260909.md` | 首页「深入看今日」计算完成却 `empty_answer`:入口定的 `timing` 被模型改成 `general`(`canonicalDomainPlan` 以模型为准),分段写作标题与今日格式错位,分段 `maxSteps=1` 且工具仍可调 → 模型在分段里再调工具、零正文;思考流按 chunk 过滤漏出缺词英文 | 已验收通过 | `17b36f3a`(BUG-612~613) |
|
| `TASK-consultation-daily-empty-answer-20260909.md` | `PROGRESS-consultation-daily-empty-answer-20260909.md` | 首页「深入看今日」计算完成却 `empty_answer`:入口定的 `timing` 被模型改成 `general`(`canonicalDomainPlan` 以模型为准),分段写作标题与今日格式错位,分段 `maxSteps=1` 且工具仍可调 → 模型在分段里再调工具、零正文;思考流按 chunk 过滤漏出缺词英文 | 已验收通过 | `17b36f3a`(BUG-612~613) |
|
||||||
@@ -231,23 +231,27 @@
|
|||||||
| `TASK-rectification-title-repair-migration-20260915.md` | — | BUG-699 / 704 的数据修补写成了 Node 脚本(要 `SCHEMA_DATABASE_URL`),但 `Migrate Staging Database` 只跑 `migrator` 应用 SQL 迁移、不执行任意脚本——产品没有任何按钮能修自己那批错名字的会话。脚本里本来就是纯 SQL,搬进一次性迁移即可复用现成按钮。生产停在 `7b620c7a`(无 `use-rectification-surface.ts`),where 自然匹配 0 行,是 no-op | 待领取 | `codex/rectification-title-repair-migration-20260915` |
|
| `TASK-rectification-title-repair-migration-20260915.md` | — | BUG-699 / 704 的数据修补写成了 Node 脚本(要 `SCHEMA_DATABASE_URL`),但 `Migrate Staging Database` 只跑 `migrator` 应用 SQL 迁移、不执行任意脚本——产品没有任何按钮能修自己那批错名字的会话。脚本里本来就是纯 SQL,搬进一次性迁移即可复用现成按钮。生产停在 `7b620c7a`(无 `use-rectification-surface.ts`),where 自然匹配 0 行,是 no-op | 待领取 | `codex/rectification-title-repair-migration-20260915` |
|
||||||
| `TASK-staging-dispatch-autofill-sha-20260915.md` | `PROGRESS-staging-dispatch-autofill-sha-20260915.md` | `Migrate Staging Database` 每次都要手抄 40 位 SHA,而那个值恰恰是「最新一个过门禁的 staging 提交」——机器能自己算,查询代码那一步里就有。改成留空自动解析、填了仍走原路径(回滚用),三条安全属性一条不丢。**产品 2026-09-15 明确授权修改该 workflow,执行方不得以 AGENTS.md §2.7 拒改**;生产两个按钮保持手填,那是护栏不是麻烦 | 待验收 | `codex/staging-dispatch-autofill-sha-20260915` |
|
| `TASK-staging-dispatch-autofill-sha-20260915.md` | `PROGRESS-staging-dispatch-autofill-sha-20260915.md` | `Migrate Staging Database` 每次都要手抄 40 位 SHA,而那个值恰恰是「最新一个过门禁的 staging 提交」——机器能自己算,查询代码那一步里就有。改成留空自动解析、填了仍走原路径(回滚用),三条安全属性一条不丢。**产品 2026-09-15 明确授权修改该 workflow,执行方不得以 AGENTS.md §2.7 拒改**;生产两个按钮保持手填,那是护栏不是麻烦 | 待验收 | `codex/staging-dispatch-autofill-sha-20260915` |
|
||||||
| `TASK-staging-auto-migrate-on-deploy-20260915.md` | `PROGRESS-staging-auto-migrate-on-deploy-20260915.md` | 门禁通过后自动先跑 staging 迁移再部署,不再手点(迁移幂等、无挂起时是 no-op,`db-migrate.mjs --check` 挂起返 3 可用于日志)。今天 `deploy-staging.yml` 完全不提迁移,忘点就让新代码跑在旧 schema 上且无人拦。**产品再次授权改 workflow,范围限 `backend-quality-gate.yml` 的 dispatch 段**;迁移失败必须阻断部署;回滚不自动迁移;生产完全不动。⚠️ 同轮必须把「迁移须对已部署代码向后兼容、破坏性变更拆两轮」写进 AGENTS.md §7.6 | 待验收 | `codex/staging-auto-migrate-on-deploy-20260915` |
|
| `TASK-staging-auto-migrate-on-deploy-20260915.md` | `PROGRESS-staging-auto-migrate-on-deploy-20260915.md` | 门禁通过后自动先跑 staging 迁移再部署,不再手点(迁移幂等、无挂起时是 no-op,`db-migrate.mjs --check` 挂起返 3 可用于日志)。今天 `deploy-staging.yml` 完全不提迁移,忘点就让新代码跑在旧 schema 上且无人拦。**产品再次授权改 workflow,范围限 `backend-quality-gate.yml` 的 dispatch 段**;迁移失败必须阻断部署;回滚不自动迁移;生产完全不动。⚠️ 同轮必须把「迁移须对已部署代码向后兼容、破坏性变更拆两轮」写进 AGENTS.md §7.6 | 待验收 | `codex/staging-auto-migrate-on-deploy-20260915` |
|
||||||
| `TASK-api-server-decomposition-20260916.md` | `PROGRESS-api-server-decomposition-20260916.md` | **重构单(串行在 qizheng 单之后;2026-09-15 又加两条前置:C1 外网缓存单先做、freeze-metric-change 先落地)**:把业务逻辑搬出 `JyotishAPIHandler`。核心不是行数,是 3 个文件 **4 处**靠 `JyotishAPIHandler.__new__` 伪造空壳 handler 借方法(`consultation_workflow_service` ×2、`capture_report_blocked_repairs_golden`、`local_accuracy_report`,MCP 也走这条),依赖方向反了、handler 没有 `headers`/`wfile` 随时可炸——实测佐证:**225 个类方法里只有 12 处真的碰 HTTP 上下文**。四阶段:拆 `__new__` 后门 → 抽 ≥150 行业务方法 → `do_POST`/`do_GET` 改路由表 → **阶段 4 已改写**:收尾不再是「行数 baseline + 余量 300→50」(那只是把问题推到三个月后),改成主门 `__new__` 计数必须为 0 + 类方法数不得增长,行数退为粗护栏保持 300 余量。纯搬运不改行为,`test_api_server_security.py` 3841 行断言一条不许改。预计 11,334 → 约 9,230 行。BUG 段 710+ | 待领取 | — |
|
| `TASK-api-server-decomposition-20260916.md` | `PROGRESS-api-server-decomposition-20260916.md` | **已取代:阶段 1 由 `TASK-api-server-backdoor-close-20260916` 完成(实测只需 8 方法 / 314 行);阶段 2/3 产品拍板不立单,由新门禁长期推进。以下为原文** · 重构单(串行在 qizheng 单之后;2026-09-15 又加两条前置:C1 外网缓存单先做、freeze-metric-change 先落地)**:把业务逻辑搬出 `JyotishAPIHandler`。核心不是行数,是 3 个文件 **4 处**靠 `JyotishAPIHandler.__new__` 伪造空壳 handler 借方法(`consultation_workflow_service` ×2、`capture_report_blocked_repairs_golden`、`local_accuracy_report`,MCP 也走这条),依赖方向反了、handler 没有 `headers`/`wfile` 随时可炸——实测佐证:**225 个类方法里只有 12 处真的碰 HTTP 上下文**。四阶段:拆 `__new__` 后门 → 抽 ≥150 行业务方法 → `do_POST`/`do_GET` 改路由表 → **阶段 4 已改写**:收尾不再是「行数 baseline + 余量 300→50」(那只是把问题推到三个月后),改成主门 `__new__` 计数必须为 0 + 类方法数不得增长,行数退为粗护栏保持 300 余量。纯搬运不改行为,`test_api_server_security.py` 3841 行断言一条不许改。预计 11,334 → 约 9,230 行。BUG 段 710+ | 已取代 | 见 `TASK-api-server-backdoor-close-20260916.md` |
|
||||||
| `TASK-chart-vedastro-decouple-20260915.md` | `PROGRESS-chart-vedastro-decouple-20260915.md` | **P0**:星盘页首屏那一发 `/api/chart` 没传 `skip_vedastro_main_entry_overview`,实测冷算 0.40–0.66 秒里约 0.36 秒是 VedAstro 空转(本机连 endpoint 都没配);生产 env 开着 network + fanout,等于首屏同步等 24 个外部请求 + 3 次领域扫描,而 `chart-view-mapper.ts` / `chart-view-contract.ts` 根本不读这份证据。星历页同端点传了标志,两页策略相反。BUG-718,**复发自 BUG-161**(前台请求不得同步串联可选外部证据)。串行在 chart-page-blocking-open 之后 | 待验收 | `codex/chart-vedastro-decouple-20260915` |
|
| `TASK-chart-vedastro-decouple-20260915.md` | `PROGRESS-chart-vedastro-decouple-20260915.md` | **P0**:星盘页首屏那一发 `/api/chart` 没传 `skip_vedastro_main_entry_overview`,实测冷算 0.40–0.66 秒里约 0.36 秒是 VedAstro 空转(本机连 endpoint 都没配);生产 env 开着 network + fanout,等于首屏同步等 24 个外部请求 + 3 次领域扫描,而 `chart-view-mapper.ts` / `chart-view-contract.ts` 根本不读这份证据。星历页同端点传了标志,两页策略相反。BUG-718,**复发自 BUG-161**(前台请求不得同步串联可选外部证据)。串行在 chart-page-blocking-open 之后 | 待验收 | `codex/chart-vedastro-decouple-20260915` |
|
||||||
| `TASK-vedastro-runtime-ops-20260915.md` | `PROGRESS-vedastro-runtime-ops-20260915.md` | 运行期真相单(与上单并行,文件不重叠;**不得改 `jyotish_api_server.py`**):官方 `vedastro==1.23.25` 其实是 REST 客户端(46 KB,全打 `api.vedastro.org`),且 import 时请求 pypi 并 `pip install --upgrade` 自升级——本机实测 pin 装完一 import 就变 1.23.26,`requirements.txt` 的锁在运行期是假的(BUG-719);无 key 时免费层排队是同步 sleep + 全局锁,24 个请求 ≈ 4.8 分钟堵住前台线程(BUG-720,定级依赖生产 key 是否配置)。生产 env 核对清单在 `docs/testing/vedastro-runtime-20260915.md`,**只能由产品负责人执行**。台账 ERR-107 / ERR-108 | 待验收 | `codex/vedastro-runtime-ops-20260915` |
|
| `TASK-vedastro-runtime-ops-20260915.md` | `PROGRESS-vedastro-runtime-ops-20260915.md` | 运行期真相单(与上单并行,文件不重叠;**不得改 `jyotish_api_server.py`**):官方 `vedastro==1.23.25` 其实是 REST 客户端(46 KB,全打 `api.vedastro.org`),且 import 时请求 pypi 并 `pip install --upgrade` 自升级——本机实测 pin 装完一 import 就变 1.23.26,`requirements.txt` 的锁在运行期是假的(BUG-719);无 key 时免费层排队是同步 sleep + 全局锁,24 个请求 ≈ 4.8 分钟堵住前台线程(BUG-720,定级依赖生产 key 是否配置)。生产 env 核对清单在 `docs/testing/vedastro-runtime-20260915.md`,**只能由产品负责人执行**。台账 ERR-107 / ERR-108 | 待验收 | `codex/vedastro-runtime-ops-20260915` |
|
||||||
| `TASK-rectification-engine-memoization-20260915.md` | — | **性能单(纯 Python,独占引擎三文件,可并行)**:一次重算 45% 的 CPU 是重复算同一份 Shadbala——`build_candidate_static_context` 每个候选分钟已算过一次却只留哈希、丢掉结果,`_candidate_row` 在「候选 × 事件 × 采样日期」最内层再算 36 遍(实测 2196 次 vs 应 61 次)。过境盘只依赖事件日期却按候选算 2196 次(应 36);鉴别探针一次请求算两遍;`_cached_rows` 是死代码。本机等价实验 3358 → 1604 ms(**快 53%**),`candidate_scores` 与 `decision_receipt` 逐字相同(唯一差异是计时字段)。**只做记忆化,不改算法**;year 精度采满 12 个月**产品 2026-09-15 决定不改、研究单也不立**。BUG 段 721 | 待领取 | — |
|
| `TASK-rectification-engine-memoization-20260915.md` | `PROGRESS-rectification-engine-memoization-20260915.md` | **性能单(纯 Python,独占引擎三文件,可并行)**:一次重算 45% 的 CPU 是重复算同一份 Shadbala——`build_candidate_static_context` 每个候选分钟已算过一次却只留哈希、丢掉结果,`_candidate_row` 在「候选 × 事件 × 采样日期」最内层再算 36 遍(实测 2196 次 vs 应 61 次)。过境盘只依赖事件日期却按候选算 2196 次(应 36);鉴别探针一次请求算两遍;`_cached_rows` 是死代码。本机等价实验 3358 → 1604 ms(**快 53%**),`candidate_scores` 与 `decision_receipt` 逐字相同(唯一差异是计时字段)。**只做记忆化,不改算法**;year 精度采满 12 个月**产品 2026-09-15 决定不改、研究单也不立**。BUG 段 721 | 已验收(带修复单) | `53a37ce9`(BUG-721)。实现等价性由改前/改后同机对比独立证实;等价 golden 跨机不稳另出修复单 |
|
||||||
| `TASK-rectification-failure-attribution-20260915.md` | — | **三处把系统故障说成别的东西(独占 `route.ts`)**:意图分类器两次异常返回的 `null` 与用户真的「说不清」共用一条分支,回一句「我不太确定这句是不是在回答上面的问题」,**用户这句里的经历直接丢弃且不写证据**(BUG-722,采集题分支早已改对、点选题分支没跟上);引擎 429(`ERR_COMPUTE_BUSY` + `Retry-After`)被压成 `engine_request_failed`,不重试不打日志,证据记下了但范围不动、模型照说「记下了」(BUG-723,**复发自 BUG-715**);attempt 210s × 2 = 420s > 路由 `maxDuration` 240s,重试必超预算(BUG-724,**复发自 BUG-059**,BUG-388 的防复发只写了单次尝试)。超时改成整轮一个预算,不砍 attempt 也不提 240。**产品 2026-09-15 决定:意图分类继续用会话选定的贵模型,不新增「工具模型」角色** | 待领取 | — |
|
| `TASK-rectification-failure-attribution-20260915.md` | `PROGRESS-rectification-failure-attribution-20260915.md` | **三处把系统故障说成别的东西(独占 `route.ts`)**:意图分类器两次异常返回的 `null` 与用户真的「说不清」共用一条分支,回一句「我不太确定这句是不是在回答上面的问题」,**用户这句里的经历直接丢弃且不写证据**(BUG-722,采集题分支早已改对、点选题分支没跟上);引擎 429(`ERR_COMPUTE_BUSY` + `Retry-After`)被压成 `engine_request_failed`,不重试不打日志,证据记下了但范围不动、模型照说「记下了」(BUG-723,**复发自 BUG-715**);attempt 210s × 2 = 420s > 路由 `maxDuration` 240s,重试必超预算(BUG-724,**复发自 BUG-059**,BUG-388 的防复发只写了单次尝试)。超时改成整轮一个预算,不砍 attempt 也不提 240。**产品 2026-09-15 决定:意图分类继续用会话选定的贵模型,不新增「工具模型」角色** | 已验收 | `8b982baf`(BUG-722~724)。`RECTIFICATION_RUN_BUDGET_MS=225_000` 与 `210_000` 收敛到一处,测试从两条路由模块读出 `maxDuration` 做 `<` 断言 |
|
||||||
| `TASK-rectification-settled-render-split-20260915.md` | — | **前端性能单(独占校正会话组件,可并行)**:`rectification-agentic-chat.tsx` 1973 行、`useMemo` 0 个、`memo` 0 个,`messages.map` 内联在组件体里且逐条新建时间轴数组与 choice card,`ChatMessageRow` 无 memo、结算态 Markdown 走没有缓存的 `renderProse`。流式每帧(~60/s)重渲整条会话并重跑每条已结算消息的 Markdown。BUG-473 在本文件只落地了 `stream-frame-buffer`,咨询面的 `SettledMessageList` + `HistoryMessageEntry` 拆分没有跟过来。**零行为变化**;验收必须有按帧驱动的渲染计数断言(照 `home-streaming-render-split.test.ts`)。BUG 段 725 | 待领取 | — |
|
| `TASK-rectification-settled-render-split-20260915.md` | `PROGRESS-rectification-settled-render-split-20260915.md` | **前端性能单(独占校正会话组件,可并行)**:`rectification-agentic-chat.tsx` 1973 行、`useMemo` 0 个、`memo` 0 个,`messages.map` 内联在组件体里且逐条新建时间轴数组与 choice card,`ChatMessageRow` 无 memo、结算态 Markdown 走没有缓存的 `renderProse`。流式每帧(~60/s)重渲整条会话并重跑每条已结算消息的 Markdown。BUG-473 在本文件只落地了 `stream-frame-buffer`,咨询面的 `SettledMessageList` + `HistoryMessageEntry` 拆分没有跟过来。**零行为变化**;验收必须有按帧驱动的渲染计数断言(照 `home-streaming-render-split.test.ts`)。BUG 段 725 | 已验收 | `58ccafb6`(BUG-725)。新建 `rectification-message-entry.tsx`;渲染计数测试做了拆分/未拆分对照与严格不等式 |
|
||||||
| `TASK-rectification-request-dossier-cache-20260915.md` | — | **低风险单,串行在 failure-attribution 之后(同改 `route.ts`)**:一轮 Agent 对话实测取 3.44 次整份 Case 档案(点选题 2.07 次),全仓约 40 个调用点、请求内零缓存;档案是「最近 50 轮 turns + 全部 evidence + 合成收据」的大 jsonb。做法是包装 `accounting` 客户端做**写即失效**的请求作用域缓存(两个只读投影命中缓存,其余任何 RPC 先清空再转发),**零调用点改动**。不得做成「请求内只读一次」——档案在请求内会变。BUG 段 726 | 待领取 | — |
|
| `TASK-rectification-request-dossier-cache-20260915.md` | `PROGRESS-rectification-request-dossier-cache-20260915.md` | **低风险单,串行在 failure-attribution 之后(同改 `route.ts`)**:一轮 Agent 对话实测取 3.44 次整份 Case 档案(点选题 2.07 次),全仓约 40 个调用点、请求内零缓存;档案是「最近 50 轮 turns + 全部 evidence + 合成收据」的大 jsonb。做法是包装 `accounting` 客户端做**写即失效**的请求作用域缓存(两个只读投影命中缓存,其余任何 RPC 先清空再转发),**零调用点改动**。不得做成「请求内只读一次」——档案在请求内会变。BUG 段 726 | 已验收 | `b9c05377`(BUG-726)。Proxy 包装,读投影合并、其余 RPC 与属性访问一律失效;五条路由各一处接线,零调用点改动 |
|
||||||
| `TASK-consultation-external-evidence-cache-20260915.md` | `PROGRESS-consultation-external-evidence-cache-20260915.md` | **普通聊天性能单(Python;2026-09-15 产品拍板改为排在 api-server-decomposition 之前)**:每轮每域同步等外网,cProfile 前三名全是 `api.vedastro.org` 的 HTTPS 往返(0.801 + 0.786 + 0.206 s),本地 swisseph 只有 0.022 s。三个护栏数字凑不齐:前台等 1.5 s、后台跑 8 s、线程池只有 2 个 worker,且超时**不 cancel** → 每 4 秒一轮就长期饱和,之后每轮白等再拿 `official_blocked`(BUG-727)。另 `western_evidence_packet` 122 KB 前端零读取点(BUG-728)。**产品定案**:按「出生数据+岁差+交点+UTC 日期」缓存(与引擎 `_official_snapshot_reference_date` 同键,否决自定 TTL),同日 0 等待 / 跨日先用旧的(≤7 天)后台刷新 / `daily_starlanguage` 要求当天 / 冷启动才走 1.5 s。**不许「干脆不调」——那会重开 BUG-301。** 另含 staging 单域耗时实测单(代码注释里的 21 s 与本机 0.5 s 差 40 倍,三域上限就是从它推的)。BUG 段 727–728 | 待验收 | `codex/consultation-external-evidence-cache-20260915` |
|
| `TASK-consultation-external-evidence-cache-20260915.md` | `PROGRESS-consultation-external-evidence-cache-20260915.md` | **普通聊天性能单(Python;2026-09-15 产品拍板改为排在 api-server-decomposition 之前)**:每轮每域同步等外网,cProfile 前三名全是 `api.vedastro.org` 的 HTTPS 往返(0.801 + 0.786 + 0.206 s),本地 swisseph 只有 0.022 s。三个护栏数字凑不齐:前台等 1.5 s、后台跑 8 s、线程池只有 2 个 worker,且超时**不 cancel** → 每 4 秒一轮就长期饱和,之后每轮白等再拿 `official_blocked`(BUG-727)。另 `western_evidence_packet` 122 KB 前端零读取点(BUG-728)。**产品定案**:按「出生数据+岁差+交点+UTC 日期」缓存(与引擎 `_official_snapshot_reference_date` 同键,否决自定 TTL),同日 0 等待 / 跨日先用旧的(≤7 天)后台刷新 / `daily_starlanguage` 要求当天 / 冷启动才走 1.5 s。**不许「干脆不调」——那会重开 BUG-301。** 另含 staging 单域耗时实测单(代码注释里的 21 s 与本机 0.5 s 差 40 倍,三域上限就是从它推的)。BUG 段 727–728 | 已验收 | `e61535f4`(BUG-727/728)。缓存目录与 `_api_chart_cache` 分开、超时 `pending.cancel()`、`daily_starlanguage` 拒隔夜;`jyotish_api_server.py` 反而净降 43 行 |
|
||||||
| `TASK-consultation-context-memory-20260915.md` | `PROGRESS-consultation-context-memory-20260915.md` | **记忆三缺口(TS,可并行)**:历史超预算时从最老整轮丢弃,`droppedCount` 算了却**全仓零读取点**,模型不知道少看了几轮——单条截断有「省略 N 字」标记,整轮丢弃没有(BUG-729,BUG-555 防复发只写了「头部截断」所以漏网);写摘要阈值写死 16,000,历史预算却是 `clamp((窗口−60k)×1.5, 4k, 40k)`,窗口 < **70,667** 时预算低于阈值 → 每轮静默丢(BUG-730,后台上架中等窗口模型即触发);写满时服务端存着摘要,`continueInNewChat` 只带问题不带摘要,而 `context_summary` 根本不在任何会话接口的列里(BUG-731)。**产品定案:静默继承**,且摘要文本永远不许由客户端提供(`chatSessionCreateSchema` 只收来源会话 uuid)。BUG 段 729–731 | 待验收 | `codex/consultation-context-memory-20260915` |
|
| `TASK-consultation-context-memory-20260915.md` | `PROGRESS-consultation-context-memory-20260915.md` | **记忆三缺口(TS,可并行)**:历史超预算时从最老整轮丢弃,`droppedCount` 算了却**全仓零读取点**,模型不知道少看了几轮——单条截断有「省略 N 字」标记,整轮丢弃没有(BUG-729,BUG-555 防复发只写了「头部截断」所以漏网);写摘要阈值写死 16,000,历史预算却是 `clamp((窗口−60k)×1.5, 4k, 40k)`,窗口 < **70,667** 时预算低于阈值 → 每轮静默丢(BUG-730,后台上架中等窗口模型即触发);写满时服务端存着摘要,`continueInNewChat` 只带问题不带摘要,而 `context_summary` 根本不在任何会话接口的列里(BUG-731)。**产品定案:静默继承**,且摘要文本永远不许由客户端提供(`chatSessionCreateSchema` 只收来源会话 uuid)。BUG 段 729–731 | 已验收 | `149e1ec4`(BUG-729~731)。丢整轮有两种诚实措辞;阈值由预算派生且越界直接 throw;静默继承只收来源会话 uuid,schema 仍 `.strict()` 无 `context_summary` |
|
||||||
| `TASK-consultation-session-capacity-20260915.md` | `PROGRESS-consultation-session-capacity-20260915.md` | **对话上限单(一份迁移,可并行;不碰 route.ts)**:`append_consultation_question` 的 200,000 字符额度里,`thinkingText`(≤4,000) + `thinkingSections`(实测 1,521/2,243/2,977) 占一半以上,而 `techniqueTruth`/`workflowReceipt`/`agentExecutionReceipt` 照样入库却不计入——同一条上限身兼二职且两职都没做好,约 **19 轮** 就「已写满」(200 条那档永远碰不到)。**产品定案:思考文本不计入**,额度只数用户读得到的正文(约 19 → 约 50 轮),另设一条按 `length(elem::text)` 把全部字段算全的物理上限(算式取 1,000,000,写进迁移注释)护住数据库行;两档都返回同一个 `session_full`。保留 advisory lock / 幂等 / 满员拒绝(BUG-464 防复发)。BUG 段 732 | 待验收 | `codex/consultation-session-capacity-20260915`(BUG-732);`test:db` 环境缺口 |
|
| `TASK-consultation-session-capacity-20260915.md` | `PROGRESS-consultation-session-capacity-20260915.md` | **对话上限单(一份迁移,可并行;不碰 route.ts)**:`append_consultation_question` 的 200,000 字符额度里,`thinkingText`(≤4,000) + `thinkingSections`(实测 1,521/2,243/2,977) 占一半以上,而 `techniqueTruth`/`workflowReceipt`/`agentExecutionReceipt` 照样入库却不计入——同一条上限身兼二职且两职都没做好,约 **19 轮** 就「已写满」(200 条那档永远碰不到)。**产品定案:思考文本不计入**,额度只数用户读得到的正文(约 19 → 约 50 轮),另设一条按 `length(elem::text)` 把全部字段算全的物理上限(算式取 1,000,000,写进迁移注释)护住数据库行;两档都返回同一个 `session_full`。保留 advisory lock / 幂等 / 满员拒绝(BUG-464 防复发)。BUG 段 732 | 已验收 | `dcfc2f15` / `51a65d92`(BUG-732) |
|
||||||
| `TASK-freeze-metric-change-20260915.md` | — | **规则单(后面两单的前置,无 BUG 号)**:两条增长冻结余量都用完(`page.tsx` 1,951/1,951 余 **0**;`jyotish_api_server.py` 11,334/11,363 余 **29**),冻结从「逼新代码往外走」退化成「拦路」。实证:`page.tsx` 行数砍 59% 但 `Home()` 的 `useState` 从 56 涨到 **66**(拆的是代码不是状态);api server **225 个类方法只有 12 处真碰 HTTP 上下文**,4 处 `__new__` 伪造空壳就是这么来的。**产品拍板换口径**:主门改成「`Home()` 的 useState/useRef 不得增长」与「类方法数 + `__new__` 计数不得增长」,行数降级为粗护栏;**同时推翻 §6「参数式 hook 内部保持 0 个 React hook」**(那正是状态搬不走的原因)。改 `AGENTS.md` §6 + 两个合同测试,不碰业务代码 | 待领取 | — |
|
| `TASK-freeze-metric-change-20260915.md` | `PROGRESS-freeze-metric-change-20260915.md` | **规则单(后面两单的前置,无 BUG 号)**:两条增长冻结余量都用完(`page.tsx` 1,951/1,951 余 **0**;`jyotish_api_server.py` 11,334/11,363 余 **29**),冻结从「逼新代码往外走」退化成「拦路」。实证:`page.tsx` 行数砍 59% 但 `Home()` 的 `useState` 从 56 涨到 **66**(拆的是代码不是状态);api server **225 个类方法只有 12 处真碰 HTTP 上下文**,4 处 `__new__` 伪造空壳就是这么来的。**产品拍板换口径**:主门改成「`Home()` 的 useState/useRef 不得增长」与「类方法数 + `__new__` 计数不得增长」,行数降级为粗护栏;**同时推翻 §6「参数式 hook 内部保持 0 个 React hook」**(那正是状态搬不走的原因)。改 `AGENTS.md` §6 + 两个合同测试,不碰业务代码 | 已验收 | `3b17c1b2`。`AGENTS.md` §6 已按新口径改写,两个合同测试到位 |
|
||||||
| `TASK-home-state-lowering-20260915.md` | — | **page.tsx 状态下沉第一簇(串行在 freeze-metric-change + C2 + R3 之后)**:66 个 state 里 `rectification*` 占 **15** 个,而它们服务的 `<ConversationalBirthTimeRectification>` 本来就是 `dynamic()` 懒加载子树、挂着 24 个 props;`useRectificationSurface` 要解构约 56 个参数。把这簇搬进子树,`Home()` 的 useState 从 66 降到 ≤ 53。**零行为变化**;第一步必须先把 15 个逐个分类(只服务子树 / 外壳也要读)。产品否决了 Context Provider 与外部 store 两条路。不占 BUG 号 | 待领取 | — |
|
| `TASK-home-state-lowering-20260915.md` | `PROGRESS-home-state-lowering-20260915.md` | **page.tsx 状态下沉第一簇(串行在 freeze-metric-change + C2 + R3 之后)**:66 个 state 里 `rectification*` 占 **15** 个,而它们服务的 `<ConversationalBirthTimeRectification>` 本来就是 `dynamic()` 懒加载子树、挂着 24 个 props;`useRectificationSurface` 要解构约 56 个参数。把这簇搬进子树,`Home()` 的 useState 从 66 降到 ≤ 53。**零行为变化**;第一步必须先把 15 个逐个分类(只服务子树 / 外壳也要读)。产品否决了 Context Provider 与外部 store 两条路。不占 BUG 号 | 已验收 | `f8e607c2`。实测 useState 66→52、useRef 41→39、残留散装 `rectification*` state 0;冻结基线**往紧里收**;全量套件两侧完全相同(3329/fail 31)。遗留:`createRectificationShellSetters` 身份不稳多 1 条 warning,已披露,并进第二批 |
|
||||||
| `TASK-rectification-engine-memoization-fix-20260915.md` | — | **验收修复单(只改测试,一行实现不许动)**:BUG-721 的实现**等价性成立**(我在改前 `6b3248bf` / 改后 `e4788dfc` 同机跑同一 payload,`candidate_scores` 逐字相同),9 条计数断言全过;但等价 golden 在本机复现不出来——4 处浮点尾数差(score 1.0e-4 ×2、`margin_percent` 1.1e-3 ×2)。**复发自 BUG-712**(「不得对全精度浮点做整体 `==`」,那一单只落在 ephemeris 一处)。而 `tests/test_rectification_*.py` 在 `CORE_PYTEST_TARGETS` 里,**staging 门禁靠机器舍入碰巧一致才是绿的**。修法:主证据换成**同进程差分**(把 static context 的四个缓存键置 `None` 即可回退旧路径,A/B 严格相等),golden 降为离散字段严格相等 + 浮点带容差(容差按实测 1.1e-3 推);**禁止重建 golden 来「修」**。另含六份 golden 的仓库级排查。BUG-733 | 待领取 | — |
|
| `TASK-rectification-engine-memoization-fix-20260915.md` | `PROGRESS-rectification-engine-memoization-fix-20260915.md` | **验收修复单(只改测试,一行实现不许动)**:BUG-721 的实现**等价性成立**(我在改前 `6b3248bf` / 改后 `e4788dfc` 同机跑同一 payload,`candidate_scores` 逐字相同),9 条计数断言全过;但等价 golden 在本机复现不出来——4 处浮点尾数差(score 1.0e-4 ×2、`margin_percent` 1.1e-3 ×2)。**复发自 BUG-712**(「不得对全精度浮点做整体 `==`」,那一单只落在 ephemeris 一处)。而 `tests/test_rectification_*.py` 在 `CORE_PYTEST_TARGETS` 里,**staging 门禁靠机器舍入碰巧一致才是绿的**。修法:主证据换成**同进程差分**(把 static context 的四个缓存键置 `None` 即可回退旧路径,A/B 严格相等),golden 降为离散字段严格相等 + 浮点带容差(容差按实测 1.1e-3 推);**禁止重建 golden 来「修」**。另含六份 golden 的仓库级排查。BUG-733 | 已验收 | `2b7b4565`(BUG-733)。同进程差分立为主证据,golden 降为离散严格+浮点容差;本机 14 条全绿 |
|
||||||
| `TASK-consultation-residual-hotspots-20260916.md` | — | **性能单(与拆解单文件不重叠,可并行)**:BUG-727 的快照缓存已验收生效(逐轮 trace 确认每轮 hit、响应体 52 万→40 万字符),但耗时没降——重测 6 次调用 5.30 s 里**网络仍占 70 %**(poll 2.42 + ssl read 0.76 + 握手 0.56),本地占星计算只剩 **2.4 %**。剩下那一次外网是 `gateway_status → probe_official_rest_health → probe_calculate_health`:**它不是 ping,是把一份虚构排盘 POST 给 `api.vedastro.org`**,而且 `consume_rate_token()` 会**烧掉对方一个业务限流令牌**,还不复用连接(6 次调用 3 次 TLS 握手,单次 0.186 s),结果零 TTL(BUG-734)。另 `yoga_engine._eval_custom` 对静态规则表的 192 条表达式**每请求重新编译 102 次**(多语句的还要先抛一次 SyntaxError 再 parse+改写 AST+compile),占 9.4 %(BUG-735)。修法:探测加 TTL(成功 60 s / 失败 10 s,配置变即失效,**诊断端点必须 force_refresh 保持实时**)+ 共享 opener;表达式缓存 code object。**硬红线:绝不缓存 yoga 求值结果**(会跨用户串盘)。等价证明用 BUG-733 的同进程差分,不再写跨机 golden。BUG 段 734–735 | 待领取 | — |
|
| `TASK-consultation-residual-hotspots-20260916.md` | — | **性能单(与拆解单文件不重叠,可并行)**:BUG-727 的快照缓存已验收生效(逐轮 trace 确认每轮 hit、响应体 52 万→40 万字符),但耗时没降——重测 6 次调用 5.30 s 里**网络仍占 70 %**(poll 2.42 + ssl read 0.76 + 握手 0.56),本地占星计算只剩 **2.4 %**。剩下那一次外网是 `gateway_status → probe_official_rest_health → probe_calculate_health`:**它不是 ping,是把一份虚构排盘 POST 给 `api.vedastro.org`**,而且 `consume_rate_token()` 会**烧掉对方一个业务限流令牌**,还不复用连接(6 次调用 3 次 TLS 握手,单次 0.186 s),结果零 TTL(BUG-734)。另 `yoga_engine._eval_custom` 对静态规则表的 192 条表达式**每请求重新编译 102 次**(多语句的还要先抛一次 SyntaxError 再 parse+改写 AST+compile),占 9.4 %(BUG-735)。修法:探测加 TTL(成功 60 s / 失败 10 s,配置变即失效,**诊断端点必须 force_refresh 保持实时**)+ 共享 opener;表达式缓存 code object。**硬红线:绝不缓存 yoga 求值结果**(会跨用户串盘)。等价证明用 BUG-733 的同进程差分,不再写跨机 golden。BUG 段 734–735 | 待领取 | — |
|
||||||
|
| `TASK-home-state-lowering-batch2-20260916.md` | — | **状态下沉第二批(纯前端,与另两单可并行)**:第一批 `f8e607c2` 已验收(useState 66→52、useRef 41→39、散装 `rectification*` 归零、全量套件两侧完全相同)。本单照同一套做法搬剩下三簇:`session*` **10** 个(`useSessionManagement` 仍要解构约 40 个参数)、`profile*` **6** 个、`synastry*` **4** 个(无 hook,散在 `Home()`),目标 useState 52 → **≤36**。另修第一批留下的尾巴:`createRectificationShellSetters` 在 render 体里无记忆化 → 每帧新身份 → 多一条 `exhaustive-deps` warning(119→**120**),**正解是稳住 setter 身份、不是塞进 deps**(塞进去会每帧重拉入口摘要),本单要把 warning 降回 119。零行为变化;先分类再动手。不占 BUG 号 | 待领取 | — |
|
||||||
|
| `TASK-api-server-backdoor-close-20260916.md` | — | **取代 decomposition 单的阶段 1(纯 Python,与另两单可并行)**:实测四处 `__new__` 的**传递闭包只有 8 个方法 / 314 行,且 0 个碰 HTTP 上下文**(占全类 4%)。所以「关后门」是一次 314 行纯搬运,不需要捆绑 2,000+ 行的体量搬运。产品拍板:**阶段 2/3 不立单**,由 `3b17c1b2` 换好的门禁(类方法数 + `__new__` 计数只许降)长期推进。唯一成功判据:`grep -c "JyotishAPIHandler.__new__"` **收到 0** 并写进合同测试。`test_api_server_security.py` 的 3,841 行断言一条不许改。不占 BUG 号 | 待领取 | — |
|
||||||
|
| `RECONCILE-20260916.md` | — | **对账清单(不是任务书)**:状态板与现实脱节(09-15~16 那 10 份早已合入却仍写「待领取/待验收」,本轮已修正),所以另外 7 份 09-10~14 的单**不能拿 README 当证据**——它们没有 `PROGRESS-*.md`,但引用的 BUG 号都是 `resolved`。要么被别的单顺带修了没留记录,要么压根没做。每行回一个「做了/没做」即可。另附三条我已查到确定没做的证据、两条状态未闭环的、以及 BLK-001 仍红(2026-09-16 在 `4f643aa0` 复跑确认) | 待产品负责人 / 执行方回填 | — |
|
||||||
|
|
||||||
## 命名与归档
|
## 命名与归档
|
||||||
|
|
||||||
- 文件名:`TASK-<kebab-主题>-<YYYYMMDD>.md`;同主题的修复单加 `-fix`;进度记录同名换前缀。
|
- 文件名:`TASK-<kebab-主题>-<YYYYMMDD>.md`;同主题的修复单加 `-fix`;进度记录同名换前缀。
|
||||||
- 一轮结束后不删除文件;结论沉淀到 `docs/BUG_HISTORY.md`(Bug)、`CHANGELOG.md`(行为/skill 变化)、`frontend/DESIGN.md`(视觉与交互合同)。
|
- 一轮结束后不删除文件;结论沉淀到 `docs/BUG_HISTORY.md`(Bug)、`CHANGELOG.md`(行为/skill 变化)、`frontend/DESIGN.md`(视觉与交互合同)。
|
||||||
- 任务书里的行号会随代码漂移,定位以符号名为准。
|
- 任务书里的行号会随代码漂移,定位以符号名为准。
|
||||||
|
- **实现合入 `staging` 的同一次推送里,必须同时把状态板那一行改掉。** 2026-09-16 的对账发现 10 份早已合入的单仍写着「待领取 / 待验收」,会导致重复派活。
|
||||||
|
|||||||
@@ -0,0 +1,64 @@
|
|||||||
|
# 对账清单 · 这 7 份任务书到底做了没(2026-09-16)
|
||||||
|
|
||||||
|
给执行方 / 产品负责人的一页纸。**不是任务书,不需要实现任何东西**,只需要每行回一个「做了 / 没做」,并把做了的补一份 `PROGRESS-*.md`。
|
||||||
|
|
||||||
|
## 为什么要对账
|
||||||
|
|
||||||
|
`docs/tasks/README.md` 的状态板已被证明不可靠:2026-09-15~16 这一批共 **10 份**任务书,实现早就合进 staging 并经我逐单验收,状态板却仍然写着「待领取 / 待验收」(本轮已修正)。
|
||||||
|
|
||||||
|
所以对下面这 7 份,**我不能拿 README 的状态当证据**。我用的判据是两条客观事实:
|
||||||
|
|
||||||
|
1. `docs/tasks/` 下**没有**对应的 `PROGRESS-*.md`;
|
||||||
|
2. 但它们引用的 `BUG-NNN` 在 `docs/BUG_HISTORY.md` 里**都是 `resolved`**。
|
||||||
|
|
||||||
|
两条合起来有两种可能:**(a)** 被别的单顺带修了、执行方没单独留记录;**(b)** 压根没做,而那些 BUG 号是被更早的单闭环的。**只有做过的人分得清。**
|
||||||
|
|
||||||
|
## 要回答的 7 行
|
||||||
|
|
||||||
|
| # | 任务书 | 引用的 BUG | 做了没?(请填) | 若做了,落在哪个 commit |
|
||||||
|
| --- | --- | --- | --- | --- |
|
||||||
|
| 1 | `TASK-rectification-after-pool-empty-decision-20260913.md` | 见文内 | | |
|
||||||
|
| 2 | `TASK-rectification-delivery-vs-collect-split-20260914.md` | 见文内 | | |
|
||||||
|
| 3 | `TASK-rectification-invite-copy-and-assertions-fix-20260915.md` | 见文内 | | |
|
||||||
|
| 4 | `TASK-rectification-precision-adaptive-boundary-research-20260914.md` | 研究单 | | |
|
||||||
|
| 5 | `TASK-rectification-spoken-orphan-and-engine-representative-20260914.md` | 见文内 | | |
|
||||||
|
| 6 | `TASK-rectification-tiebreak-hold-exit-fix-20260914.md` | 见文内 | | |
|
||||||
|
| 7 | `TASK-rectification-probe-supply-research-20260913.md` | 无 BUG 号(研究单) | | |
|
||||||
|
|
||||||
|
填法:
|
||||||
|
|
||||||
|
- **做了** → 补一份 `docs/tasks/PROGRESS-<同名>.md`,哪怕只有三行(做了什么、落在哪个 commit、有没有让步),并在状态板上把该行改成实际状态。
|
||||||
|
- **没做** → 在状态板上写明「待领取」,并说一句它现在还成不成立(有些旧单可能已被后来的轮次取代)。
|
||||||
|
- **已被取代** → 写明被哪一份取代,参照 `TASK-rectification-exhausted-gate-exit-20260910.md` 那行的写法(「已被取代(并入采集重设计单)」)。
|
||||||
|
|
||||||
|
## 顺带确认的三件事
|
||||||
|
|
||||||
|
这三条我已经查到**确定没做**的证据,不需要对账,直接派活即可:
|
||||||
|
|
||||||
|
| 任务书 | 我的证据 |
|
||||||
|
| --- | --- |
|
||||||
|
| `TASK-rectification-title-repair-migration-20260915.md` | `frontend/supabase/migrations/` 下**没有**对应的迁移文件 |
|
||||||
|
| `TASK-settings-dialog-size-and-nav-20260915.md` | BUG-698 在 `docs/BUG_HISTORY.md` 里**查无此号** |
|
||||||
|
| `TASK-rectification-record-conflict-copy-20260914.md` | BUG-691 **查无此号** |
|
||||||
|
|
||||||
|
另两条状态未闭环,也不需要对账:
|
||||||
|
|
||||||
|
| 任务书 | 状态 |
|
||||||
|
| --- | --- |
|
||||||
|
| `TASK-rectification-tied-first-premature-delivery-fix-20260914.md` | BUG-684 仍是 `investigating` |
|
||||||
|
| `TASK-rectification-unstampable-probe-and-naked-card-20260914.md` | BUG-559 只到 `mitigated`,记录里自注「点选同年复发见 BUG-592」 |
|
||||||
|
|
||||||
|
## 还有一条长期红
|
||||||
|
|
||||||
|
`BLOCKED.md` 的 **BLK-001** 我 2026-09-16 在 `4f643aa0` 上复跑,**仍然红**:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
.venv/bin/python -m pytest -q \
|
||||||
|
"tests/test_active_rectification_api.py::test_long_real_conversation_reaches_vedastro_after_local_range_is_narrow"
|
||||||
|
```
|
||||||
|
|
||||||
|
当初的处置是「只记录,不改引擎、不改门槛、不改断言让它变绿」。它从 2026-09-06 挂到今天。**这一条需要产品决定**:继续挂着,还是立一份单去查(查的是 BUG-560 那条根因——分钟级原始分的区分力≈随机)。
|
||||||
|
|
||||||
|
## 防复发
|
||||||
|
|
||||||
|
状态板与现实脱节这件事本身要治:**任务书合入 staging 的同一次推送里,必须同时把状态板那一行改掉**。这条建议加进 `docs/tasks/README.md` 的「命名与归档」一节。
|
||||||
@@ -0,0 +1,143 @@
|
|||||||
|
# TASK · 关掉 `JyotishAPIHandler.__new__` 后门(314 行纯搬运)
|
||||||
|
|
||||||
|
- 日期:2026-09-16
|
||||||
|
- 基线 commit:`origin/staging` @ `4f643aa0`
|
||||||
|
- 执行分支:`codex/api-server-backdoor-close-20260916`
|
||||||
|
- 落点:`scripts/jyotish_api_server.py`、新建的 `scripts/` 下模块、`scripts/consultation_workflow_service.py`、`scripts/capture_report_blocked_repairs_golden.py`、`scripts/local_accuracy_report.py`、`tests/test_api_server_growth_contract.py`
|
||||||
|
- **取代 `TASK-api-server-decomposition-20260916` 的阶段 1**;该单其余阶段的处置见 §3.2
|
||||||
|
- 与 `TASK-consultation-residual-hotspots-20260916`(`vedastro_*` / `yoga_engine`)、`TASK-home-state-lowering-batch2-20260916`(纯前端)**无文件重叠,三单可并行**
|
||||||
|
- 规模:8 个方法 / 314 行搬进独立模块。**纯搬运,零行为变化。**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. 为什么把范围缩到 314 行
|
||||||
|
|
||||||
|
原任务书四个阶段(拆 `__new__` → 抽 ≥150 行方法 → `do_POST` 改路由表 → 重新冻结)方向是对的,但它把「关后门」和「体量搬运」捆在了一起。我按调用链实测算了阶段 1 的**传递闭包**(从四处伪造实际借用的方法出发,跟着 `self._x()` 一路追):
|
||||||
|
|
||||||
|
| | 数量 |
|
||||||
|
| --- | ---: |
|
||||||
|
| 需要搬的方法 | **8 个** |
|
||||||
|
| 合计行数 | **314 行** |
|
||||||
|
| 其中真的碰 HTTP 上下文(`self.headers` / `wfile` / `rfile` / `path` / `client_address`) | **0 个** |
|
||||||
|
| 占 `JyotishAPIHandler` 全类(225 方法 / 8,219 行)的比例 | **4 % / 4 %** |
|
||||||
|
|
||||||
|
**关后门只需要一次 314 行的纯搬运,而且这 8 个方法一个都不碰 HTTP,没有隐藏耦合。**
|
||||||
|
|
||||||
|
四处伪造实际借用的入口方法只有 5 个:
|
||||||
|
|
||||||
|
| 位置 | 借用的方法 |
|
||||||
|
| --- | --- |
|
||||||
|
| `scripts/consultation_workflow_service.py:20` / `:27` | `_compute_vedastro_gateway_archives`、`_high_rigor_vedastro_official_summary`、`_interpretation_source_runtime_coverage` |
|
||||||
|
| `scripts/capture_report_blocked_repairs_golden.py:59` | `_compute_consultation_workflow` |
|
||||||
|
| `scripts/local_accuracy_report.py:141` | `_compute_synastry` |
|
||||||
|
|
||||||
|
## 2. 事故实证
|
||||||
|
|
||||||
|
```python
|
||||||
|
handler = JyotishAPIHandler.__new__(JyotishAPIHandler) # 不跑 __init__ 的空壳
|
||||||
|
```
|
||||||
|
|
||||||
|
`__new__` 绕过 `BaseHTTPRequestHandler.__init__`,造出来的对象**没有 `headers` / `wfile` / `rfile` / `client_address`**。今天能跑,只是因为被借用的这 8 个方法碰巧没碰它们——我逐个查过,`0` 个碰。
|
||||||
|
|
||||||
|
**这是一颗类型检查看不见的地雷**:任何人往这 8 个方法(或它们调用的任何方法)里加一行 `self.headers.get(...)`,MCP 与两个离线脚本就会在运行时 `AttributeError`,而单元测试与 `tsc` 都发现不了。
|
||||||
|
|
||||||
|
更根本的是依赖方向反了:`consultation_workflow_service.py` 的 docstring 自称是「shared consultation workflow boundary for API and MCP callers」,实际却**反过来依赖 HTTP 单体文件**,只为借它身上的方法。
|
||||||
|
|
||||||
|
全仓依赖该模块的文件有 **43 个**(`scripts/`、`tests/`、`mcp_server.py`)。
|
||||||
|
|
||||||
|
## 3. 决策记录
|
||||||
|
|
||||||
|
产品 2026-09-16 拍板:
|
||||||
|
|
||||||
|
1. **只做「关后门」这一件事,不做体量搬运。** 原任务书的阶段 2(抽 7 个 ≥150 行方法,2,073 行)与阶段 3(78 个 `elif` 改路由表)**本轮不做**。理由:那是 2,000+ 行的大搬运、零用户价值,而 `tests/test_api_server_security.py` 有 3,841 行断言绑在这个类上——风险与收益不匹配。
|
||||||
|
2. **阶段 2/3 不另立单,改由门禁长期推进。** `3b17c1b2` 已把增长冻结的主门从行数换成「**类方法数不得增长 + `__new__` 计数不得增长**」。这意味着以后任何想往这个类里加方法的改动都会被拦,只能往外搬——**换口径本身已经替代了一次性大搬运的必要性**。这条写进 `docs/tasks/README.md` 的状态板备注,避免下一轮有人又提。
|
||||||
|
3. **纯搬运,零行为变化。** `tests/test_api_server_security.py` 的 3,841 行断言**一条不许改**。
|
||||||
|
4. **收尾把 `__new__` 计数基线收到 0。** 这是本单唯一不可伪造的成功判据。
|
||||||
|
|
||||||
|
## 4. 硬红线
|
||||||
|
|
||||||
|
1. **`grep -rn "JyotishAPIHandler.__new__" --include=*.py .`(排除 `skills/*/versions/**`)必须零命中**,并且这条断言要写进 `tests/test_api_server_growth_contract.py`,基线从 4 收到 **0**。
|
||||||
|
2. **`tests/test_api_server_security.py` 一条断言不许改。** 若它红了,说明不是纯搬运——回去改实现,不是改断言。
|
||||||
|
3. **不得顺手搬阶段 2/3 的方法。** 类方法数会因本单下降,把新值写进合同测试即可;**不得**为了多降一点而扩大范围。
|
||||||
|
4. 搬出去的模块**不得**再反向 import `jyotish_api_server`——那等于把后门换了个地方开。要有一条断言钉住这个方向。
|
||||||
|
5. 本单会与 `TASK-consultation-external-evidence-cache-20260915`(已合入 `e61535f4`)的改动共处同一文件:它在 `execute_consultation_workflow` 里加了走缓存模块的分支。**照常搬运,不得把它改回去。**
|
||||||
|
6. 不得顺手升级依赖、不得顺手修不在本单里的 warning。
|
||||||
|
|
||||||
|
## 5. 任务分解
|
||||||
|
|
||||||
|
### 5.1 先自己把闭包算一遍
|
||||||
|
|
||||||
|
不要抄本任务书的 8 个方法。开工时用同样的方法重算(从 5 个入口方法出发,跟着 `self._x()` 追传递闭包,并标出哪些碰 HTTP 上下文),结果写进进度记录。代码可能已经漂移。
|
||||||
|
|
||||||
|
- 验收:进度记录里有闭包清单、行数、以及「碰 HTTP 上下文的有几个」。
|
||||||
|
- 验收:若重算出来**有**方法碰 HTTP 上下文,**停手**,把那几个列出来先问——本单的前提是它们都不碰。
|
||||||
|
|
||||||
|
### 5.2 把闭包搬进独立模块
|
||||||
|
|
||||||
|
按职责放进 `scripts/` 下的新模块(建议按 vedastro 证据 / 咨询工作流 / 合盘分组,不要一股脑塞一个文件)。`JyotishAPIHandler` 里对应位置改成薄调用。
|
||||||
|
|
||||||
|
- 验收:`scripts/jyotish_api_server.py` 的类方法数下降,新值写进合同测试。
|
||||||
|
- 验收:新模块不 import `jyotish_api_server`,有断言。
|
||||||
|
|
||||||
|
### 5.3 三个调用方改成直接 import
|
||||||
|
|
||||||
|
`consultation_workflow_service.py`(两处)、`capture_report_blocked_repairs_golden.py`、`local_accuracy_report.py` 改成直接 import 新模块,删掉 `JyotishAPIHandler.__new__` 与对 `jyotish_api_server` 的 import。
|
||||||
|
|
||||||
|
- 验收:三个文件都不再 import `jyotish_api_server`。
|
||||||
|
- 验收:MCP 侧(`mcp_server.py:741` / `:4749` 经由 `consultation_workflow_service`)仍然可用——至少一条端到端断言。
|
||||||
|
|
||||||
|
### 5.4 合同测试收基线
|
||||||
|
|
||||||
|
`tests/test_api_server_growth_contract.py`:`__new__` 计数基线 4 → **0**;类方法数基线更新为收尾实测值;行数粗护栏 baseline 重设为收尾实测 + 300。同步更新文件顶部 docstring 的日期与说明。
|
||||||
|
|
||||||
|
- 验收:人为加回一处 `JyotishAPIHandler.__new__` 必须让测试变红(贴反向验证)。
|
||||||
|
- 验收:人为加一个类方法必须变红(贴反向验证)。
|
||||||
|
- 验收:该文件既有的三条断言(`AGENTS.md` 必须含 `must not grow` / `thinly registered`、该测试必须在 `CORE_PYTEST_TARGETS` 与快速门里)仍绿。
|
||||||
|
|
||||||
|
### 5.5 记录
|
||||||
|
|
||||||
|
本单不产生 Bug 记录(结构改造,不是缺陷),不进 `CHANGELOG.md`(无用户可感知变化)。进度记录里必须有:闭包清单、搬前/搬后的类方法数与行数、两次反向验证结果。
|
||||||
|
|
||||||
|
同轮把原 `TASK-api-server-decomposition-20260916` 在状态板上标成**已取代(阶段 1 由本单完成;阶段 2/3 不立单,由门禁长期推进)**。
|
||||||
|
|
||||||
|
## 6. 让步顺序
|
||||||
|
|
||||||
|
1. 5.1 **不得砍**——闭包没重算就动手,等于拿本任务书的旧数字赌代码没漂。
|
||||||
|
2. 5.2 + 5.3 是主体,必须一起做(只搬不改调用方,后门还在)。
|
||||||
|
3. 5.4 不得砍——`__new__` 计数收到 0 是本单唯一的成功判据。
|
||||||
|
4. 5.5 不得砍。
|
||||||
|
|
||||||
|
## 7. 开工前置命令
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git fetch origin --prune
|
||||||
|
git worktree add -b codex/api-server-backdoor-close-20260916 \
|
||||||
|
.worktrees/api-server-backdoor-close-20260916 origin/staging
|
||||||
|
cd .worktrees/api-server-backdoor-close-20260916
|
||||||
|
git status -sb | head -1
|
||||||
|
# 重算基线
|
||||||
|
grep -rn "JyotishAPIHandler.__new__" --include=*.py . | grep -v "skills/.*/versions/"
|
||||||
|
grep -cE '^ (async )?def ' scripts/jyotish_api_server.py
|
||||||
|
wc -l scripts/jyotish_api_server.py
|
||||||
|
python3 scripts/pre_work_check.py --remote-timeout 8 --command-timeout 45 # AGENTS §9
|
||||||
|
```
|
||||||
|
|
||||||
|
开工前必读:`docs/research/pre_work_error_ledger.md`(AGENTS §9);原 `TASK-api-server-decomposition-20260916.md`(它对根因的分析仍然有效,只是范围被本单收窄)。
|
||||||
|
|
||||||
|
验收命令:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
.venv/bin/python -m pytest tests/test_api_server_security.py tests/test_api_server_growth_contract.py \
|
||||||
|
tests/test_consultation_consumer_context.py tests/test_vedastro_gateway.py
|
||||||
|
.venv/bin/python scripts/run_quality_gate.py --profile quick
|
||||||
|
```
|
||||||
|
|
||||||
|
## 8. BUG 编号起点
|
||||||
|
|
||||||
|
本单不占 BUG 号。基线 `4f643aa0` 上最大号 **BUG-733**;734/735 已被 `TASK-consultation-residual-hotspots-20260916` 预占。
|
||||||
|
|
||||||
|
## 9. 不在本单范围
|
||||||
|
|
||||||
|
- 阶段 2(抽 ≥150 行业务方法)与阶段 3(`do_POST` 路由表)——**不立单,由门禁长期推进**
|
||||||
|
- `execute_consultation_workflow` 里的任何业务逻辑改动
|
||||||
|
- 外网探测与 yoga 编译缓存(见 `TASK-consultation-residual-hotspots-20260916`)
|
||||||
@@ -0,0 +1,149 @@
|
|||||||
|
# TASK · page.tsx 状态下沉第二批:session / profile / synastry 三簇 + 稳住外壳 setter
|
||||||
|
|
||||||
|
- 日期:2026-09-16
|
||||||
|
- 基线 commit:`origin/staging` @ `4f643aa0`(开工时以最新 `origin/staging` 为准,数字全部重测)
|
||||||
|
- 执行分支:`codex/home-state-lowering-batch2-20260916`
|
||||||
|
- 落点:`frontend/src/app/page.tsx`、`frontend/src/hooks/use-session-management.ts`、`frontend/src/hooks/use-profile-onboarding.ts`、`frontend/src/hooks/use-rectification-surface.ts`、以及为合盘新建的 hook
|
||||||
|
- **串行在 `f8e607c2`(第一批)之后**,已满足
|
||||||
|
- 与 `TASK-consultation-residual-hotspots-20260916`(纯 Python)、`TASK-api-server-backdoor-close-20260916`(纯 Python)**无文件重叠,三单可并行**
|
||||||
|
- 规模:照第一批的成方再搬三簇。**零行为变化、零文案变化。**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. 第一批已经证明这条路走得通
|
||||||
|
|
||||||
|
`f8e607c2` 把 15 个 `rectification*` 状态搬走,我验收实测:
|
||||||
|
|
||||||
|
| 指标 | 第一批前 | 第一批后 |
|
||||||
|
| --- | ---: | ---: |
|
||||||
|
| `Home()` 的 `useState` | 66 | **52** |
|
||||||
|
| `Home()` 的 `useRef` | 41 | **39** |
|
||||||
|
| `page.tsx` 行数 | 1,951 | 1,931 |
|
||||||
|
| 残留散装 `rectification*` state | 15 | **0** |
|
||||||
|
|
||||||
|
做法是:先把 15 个逐条分类成「只服务子树」与「外壳也要读」,前者搬进 `useRectificationSurface`,后者合并成**一个**对象 state。全量前端套件两侧完全相同(3329 tests / fail 31,失败清单逐条一致),首屏 gzip 0.00 % 变化,`/` 仍 `○ Static`。增长冻结基线**往紧里收**(66/41/1951 → 52/39/1931)。
|
||||||
|
|
||||||
|
本单把同一套做法用在剩下的三簇上。
|
||||||
|
|
||||||
|
## 2. 事故实证:剩下的 52 个里还有 20 个是成簇的
|
||||||
|
|
||||||
|
`Home()` 现在 52 个 `useState`,按前缀分群:
|
||||||
|
|
||||||
|
| 群 | 个数 | 已经有的抽取点 |
|
||||||
|
| --- | ---: | --- |
|
||||||
|
| `session*` | **10** | `use-session-management.ts`(参数式,解构约 40 个参数) |
|
||||||
|
| `profile*` | **6** | `use-profile-onboarding.ts` |
|
||||||
|
| `synastry*` | **4** | 无,散在 `Home()` 里 |
|
||||||
|
| 其余分散 | 32 | — |
|
||||||
|
|
||||||
|
`useSessionManagement(params)` 的第一件事仍然是解构约 40 个参数——第一批没有碰它。这就是「代码搬走了、状态没搬」的残留部分。
|
||||||
|
|
||||||
|
另有第一批留下的一个小尾巴(执行方已在进度记录里主动披露,判断正确):
|
||||||
|
|
||||||
|
`createRectificationShellSetters(setRectification)` 在 render 体里**无记忆化调用**,每帧返回新的函数身份,于是入口摘要那个 `useEffect` 多了一条 `react-hooks/exhaustive-deps` warning(全仓 119 → **120**)。进度记录写明「不能把它们放进 deps,否则每帧重拉摘要」——这个判断是对的,我核过:那几个 setter 都只是 `setRectification(prev => ...)` 的包装,任何身份行为都一样,**当前是安全的**。但它是个陷阱:后面任何人为了消除 warning 把它们塞进 deps,就会造成每帧重新拉取入口摘要。
|
||||||
|
|
||||||
|
## 3. 决策记录
|
||||||
|
|
||||||
|
产品 2026-09-16 授权本单,口径与第一批一致:
|
||||||
|
|
||||||
|
1. **继续走「状态下沉」**,不引外部 store、不铺全局 Context Provider(第一批已否决这两条,本单不重开)。
|
||||||
|
2. **抽出去的 hook 与子组件持有自己的状态**——`AGENTS.md` §6 已于 `3b17c1b2` 改写,「参数式 hook 内部保持 0 个 React hook」那条红线已经推翻。执行方不得以旧 AGENTS 为由拒改。
|
||||||
|
3. **零行为变化。** 本单不修任何已知交互缺陷,发现了写进进度记录。
|
||||||
|
4. **那条 warning 要在本单里消掉**,做法是稳住 setter 身份,**不是**把它们加进 deps。
|
||||||
|
|
||||||
|
## 4. 硬红线
|
||||||
|
|
||||||
|
1. **先分类再动手。** 三簇共 20 个状态,每一个都要归到「只服务子树 → 搬下去」或「外壳也要读 → 合并成一个对象」,分类表连同「谁在读」写进进度记录,一个不漏。第一批的分类表是格式范本。
|
||||||
|
2. **零行为变化**是唯一成败判据。逐条对照:会话列表加载/翻页/切换/归档/置顶/重命名/删除、模型切换与同步失败、资料引导各步、头像上传、合盘发起与历史、写满后开新对话。
|
||||||
|
3. `next build` 后 `/` 仍须 `○ Static`;首屏 gzip 变化在 ±2 % 内(第一批实测 130,872 B,同一种量法)。
|
||||||
|
4. 测试总数不得低于开工时 `origin/staging` 的实测;改任何既有断言必须写「原值 / 新值 / 原因」三栏(AGENTS §7.3)。第一批那批源码正则合同(`foo={bar}` → `foo: bar`)是可接受的改法范本:**主语不许变**。
|
||||||
|
5. **`npm run lint` 的 warning 数不得上升**,并且本单要把 120 降回 **119**(消掉 §2 那条)。
|
||||||
|
6. 不得新写第二个聊天输入框、第二套滚动跟随、第二套加载动画(§6 第三条原样有效)。
|
||||||
|
7. 不得顺手升级依赖、不得顺手修不在本单里的 warning。
|
||||||
|
|
||||||
|
## 5. 任务分解
|
||||||
|
|
||||||
|
### 5.1 稳住外壳 setter,消掉那条 warning(先做,最小)
|
||||||
|
|
||||||
|
把 `createRectificationShellSetters(setRectification)` 的结果记忆化(`useMemo`,依赖只有 `setRectification`,而它是 React 的稳定 setter),使四个 setter 身份跨帧稳定;然后把它们按 eslint 的要求补进那个 `useEffect` 的 deps。
|
||||||
|
|
||||||
|
- 验收:`npm run lint` 从 120 warning 回到 **119**,且**没有新增任何其它 warning**(按规则+信息归一化比对,不要只比数字)。
|
||||||
|
- 验收:入口摘要的 effect 仍然只在 `accountId` / `bootstrapPhase` 变化时触发——新增一条断言或在进度记录里给出证明,**不得靠肉眼**。
|
||||||
|
|
||||||
|
### 5.2 `synastry*` 四个下沉(第二小,边界最清楚)
|
||||||
|
|
||||||
|
`synastryRelationshipType` / `synastryPendingId` / `synastryReportCard` / `synastryHistory` 目前散在 `Home()` 里,没有对应 hook。新建一个 hook 或直接让合盘子树持有。
|
||||||
|
|
||||||
|
- 验收:`Home()` 里 `const [synastry` 的出现次数为 **0**。
|
||||||
|
- 验收:合盘发起、失败、历史列表三条路径行为不变。
|
||||||
|
|
||||||
|
### 5.3 `profile*` 六个下沉
|
||||||
|
|
||||||
|
`use-profile-onboarding.ts` 已存在(445 行,参数式)。改成持有自己的状态。注意资料引导与 `bootstrapPhase`、揭幕门耦合较深,分类时要特别小心哪些是外壳要读的。
|
||||||
|
|
||||||
|
- 验收:分类表里每个 `profile*` 都写明谁在读。
|
||||||
|
- 验收:`Home()` 里散装 `profile*` state ≤ **1**(合并对象),多留必须逐个说明理由。
|
||||||
|
|
||||||
|
### 5.4 `session*` 十个下沉(最大、最后做)
|
||||||
|
|
||||||
|
`use-session-management.ts` 是三簇里耦合最深的(约 40 个参数,522 行),而且它和校正面有交叉(第一批的进度记录写明:`useSessionManagement` 必须在 surface hook 之前调用,用 `rectificationSessionOpenerRef` 把 opener 递过去)。**这条交叉关系不得破坏**。
|
||||||
|
|
||||||
|
- 验收:`useSessionManagement` 的参数个数显著下降,新值写进进度记录(改前约 40)。
|
||||||
|
- 验收:`Home()` 里散装 `session*` state ≤ **2**。
|
||||||
|
- 验收:`rectificationSessionOpenerRef` 那条调用顺序约束仍然成立,并有一条断言钉住。
|
||||||
|
|
||||||
|
### 5.5 收口指标
|
||||||
|
|
||||||
|
- 验收:`Home()` 的 `useState` 从 **52** 降到 **≤ 36**(三簇共 20 个,允许留 ≤ 4 个在外壳);`useRef` 不得上升(改前 39)。
|
||||||
|
- 验收:`frontend/tests/home-shell-growth-contract.test.ts` 更新为新基线(**只许往紧里收**),并贴一次反向验证(人为加一个 `useState` 必须变红)。
|
||||||
|
- 验收:全量前端套件失败清单与开工基线逐条一致。
|
||||||
|
|
||||||
|
### 5.6 真人清单
|
||||||
|
|
||||||
|
照 `docs/testing/home-state-lowering-20260915.md` 的格式,为本单三簇补一份可照做的走查条目(本仓无浏览器与登录态)。
|
||||||
|
|
||||||
|
## 6. 让步顺序
|
||||||
|
|
||||||
|
1. 5.1 必须做,它是第一批留下的尾巴,最小。
|
||||||
|
2. 5.2 → 5.3 → 5.4 按由易到难推进。**做不完可以只交前两簇**,砍掉的簇在进度记录里写明,并把 5.5 的目标值按实际达成调整(**只许往紧里收,不许放松**)。
|
||||||
|
3. 5.5、5.6 不得砍。
|
||||||
|
|
||||||
|
## 7. 开工前置命令
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git fetch origin --prune
|
||||||
|
git worktree add -b codex/home-state-lowering-batch2-20260916 \
|
||||||
|
.worktrees/home-state-lowering-batch2-20260916 origin/staging
|
||||||
|
cd .worktrees/home-state-lowering-batch2-20260916/frontend
|
||||||
|
git status -sb | head -1
|
||||||
|
npm ci
|
||||||
|
# 重测基线,不要抄本任务书里的数
|
||||||
|
grep -cE '\buseState[<(]' src/app/page.tsx
|
||||||
|
grep -cE '\buseRef[<(]' src/app/page.tsx
|
||||||
|
for p in session profile synastry; do printf "%s: %s\n" "$p" "$(grep -cE "const \[$p" src/app/page.tsx)"; done
|
||||||
|
npm run lint 2>&1 | tail -2
|
||||||
|
```
|
||||||
|
|
||||||
|
开工前必读:`docs/tasks/PROGRESS-home-state-lowering-20260915.md`(第一批的分类表与收尾实测,是本单的格式范本)。
|
||||||
|
|
||||||
|
验收命令:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./node_modules/.bin/tsc --noEmit
|
||||||
|
npm run lint # 0 error,warning 必须 ≤ 119
|
||||||
|
npx tsx --test tests/home-shell-growth-contract.test.ts tests/rectification-*.test.ts \
|
||||||
|
tests/chat-session-*.test.ts tests/session-*.test.ts
|
||||||
|
npx tsx --test tests/*.test.ts # 与基线逐条比对失败清单
|
||||||
|
npm run build # `/` 仍须 ○ Static
|
||||||
|
```
|
||||||
|
|
||||||
|
## 8. BUG 编号起点
|
||||||
|
|
||||||
|
本单不占 BUG 号(结构改造,不是缺陷)。基线 `4f643aa0` 上最大号 **BUG-733**;734/735 已被 `TASK-consultation-residual-hotspots-20260916` 预占。
|
||||||
|
|
||||||
|
## 9. 不在本单范围
|
||||||
|
|
||||||
|
- 其余 32 个分散状态(没有成簇,逐个搬性价比低)
|
||||||
|
- Context Provider 或外部 store
|
||||||
|
- 任何交互缺陷(本单零行为变化)
|
||||||
|
- API server 一侧(另一条线)
|
||||||
Reference in New Issue
Block a user