21 KiB
U3 r0.3 有依据的阶段判断 Implementation Plan
For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (
- [ ]) syntax for tracking. 本计划已于 2026-10-13 获用户阶段5批准,授权在现有任务工作区内做零付费实施与验证;新付费样本仍须单独批准。
Goal: 保留同一任务卡中有用的阶段判断;数字、集合归属和决定状态没有可核对依据时,只显示待确认问题,不把模型的肯定句当成事实。
Architecture: Core 为材料检查点候选增加可选结构化依据;Backend 沿既有来源注册表校验短引与有限数量关系,把可复算结论或未定关系归一化,再用现有 CAS 一次提交。UI 仍消费原有 material_record、analysis、needs_user;不增页面、按钮、数据库表或模型回合。真实模型质量仍须另行授权验证。
Tech Stack: Go、Core Go/TypeScript 契约、Backend runmgr/runtime、SQLite/PostgreSQL、React/TypeScript、Vitest、Playwright、Dev make evidence 与 Gitea CI。
Spec: U3 r0.3 书面设计;失败依据在U2/U3 核验报告。初始工作区沿用已登记的 Dev feature/fast-slow-u2-u3-plan,不重做本任务 precheck、不创建第二份任务卡。r0.2 唯一 A01 的 46,154 Usage、语义 FAIL 和原始文件均不改判。书面设计与本计划均已获用户批准;付费资源未获新授权。
Global Constraints
- 阶段边界: 本计划获人工批准后才改 r0.3 语义代码;真实模型样本仍须另外固定 run/Usage/在途风险并单独批准。旧授权已用尽,不自动重试。新样本任一语义或停止规则失败,六 PR 保持草稿,不合入或部署。
- 既有能力: 不改 TaskSnapshot 数据表、事件序号、owner/project/attempt/epoch 权限、连续原文引用、历史更正与最终正文所有者。来源无效/版本漂移仍整批拒绝;依据不足但来源有效则安全归一化,并将同批结果一次 CAS 保存。
- 界面: 左侧上下文、中间对话、右侧工作/文件不变;默认最多三项普通发现,关键
needs_user可见,历史和依据仍用@uiCollapsible。颜色/字号/圆角仅用@ui/tokens.css,动效仅用@ui/motion.css;异步状态唯一所有者仍是 Frontend store,旧 seq 丢弃。 - 成本: 不增摘要/审核模型回合,不改生产路由或默许提高预算;依据字段增加 token 的影响必须离线量化,最终答复预留按真实返回 Usage 继续生效。
- 治理: 实施首步先核对并同步已推进的权威 main,组件各自提交后推进 Dev gitlink;已有任务不重复
make precheck。验收、请求审核和合入前分别以CMD='make task-sync' make evidence同步;组合make test && make build的完整 SELF 收据由工具导入任务卡。独立 REVIEW/REPLAY 与精确 HEAD GATE 分开标记,禁止用旧 SHA CI 放行。
File Map and Interfaces
| 单元 | 文件 | 职责 |
|---|---|---|
| 候选契约 | modules/core/task_snapshot.go、task_snapshot_test.go、ts/types.ts |
可选 WorkFindingEvidence,只约束候选,不改持久 TaskFinding;sourceIndex 指向同条现有 sources |
| 原文计数 | modules/backend/internal/runmgr/material_evidence.go、material_evidence_test.go |
在已校验来源短引中识别有限的总量/首期/依赖数量,算差额和可能交集,未知降级 |
| 提交与提示 | modules/backend/internal/runmgr/task_checkpoint.go、material.go、material_sources.go、相关测试;internal/runtime/work_checkpoint.go |
全字段风险检查、单批归一化/CAS、工具 JSON、归一化回执与 v9 处理配方 |
| 类型镜像/展示 | modules/frontend/src/contracts.ts、modules/ui/src/contracts.ts(make contracts 生成);modules/ui/test/progressive-cards.test.tsx、modules/frontend/test/work-state.test.ts |
消费相同现有卡片类别,待确认默认可见、历史/阅读无回退;无新页面 |
| 组合和记录 | Dev gitlinks、.task/feature-fast-slow-u2-u3-plan.md、Documents 核验报告 |
精确 SHA、SQLite/PG/浏览器、独立评审、草稿 PR 和结果出口 |
候选新增的内部契约固定为:
type WorkEvidencePremise struct {
Role string `json:"role"` // total, phase, dependent, direct_relation
SourceIndex int `json:"sourceIndex"` // index into this finding's Sources
Value *int `json:"value,omitempty"`
}
type WorkFindingEvidence struct {
Mode string `json:"mode"` // direct_relation, difference, unresolved_relation
Premises []WorkEvidencePremise `json:"premises"`
Result *int `json:"result,omitempty"` // only difference
}
// Add to existing WorkFindingCandidate only:
Evidence *WorkFindingEvidence `json:"evidence,omitempty"`
Core 只验证枚举、数量、索引、字段组合和现有 16KiB 候选上限。Backend 的 normalizeMaterialEvidence(candidate core.WorkCheckpointCandidate, sources materialSourceRegistry) (core.WorkCheckpointCandidate, []string, error) 对已验短引、数值角色和关系作安全归一化:返回归一化候选、给工具结果看的简短说明、或必须整批拒绝的错误。实现时用 TaskFinding 原有类别和 Sources/Assumptions 保存输出,不引入新表。direct_relation 仅允许 material_record,只在短引本身明确写出关系时按现有宿主路径展示原文;difference 由宿主生成 analysis 和 total-phase 算式及“推算”;unresolved_relation 对可验证的三个计数计算交集范围,范围不唯一时由宿主生成 needs_user,范围唯一时也只由宿主生成有前提的判断,均不复制模型肯定归属句。现有无依据的 material_record 原文路径继续有效。
有限识别只接受短引中明确的“总/包含 N 项”“第一期 N 项”“其中 N 项依赖外部接口”等受支持中文数量语法及直接关系原句;超过已提供前缀、单位不一致、多个无法消歧的数字、陌生表述均走待确认。不声称通用自然语言蕴含证明。风险检查同时覆盖 findings 的 text/impact/assumptions 和 focus/remaining/nextStep;后者不能携带未经证明的归属或决定肯定句,必要时由宿主替换为中性进度/待核对说明。结构合法但原文不能证明的依据按“待确认”处理;sourceId/版本/权限不合法仍整批拒绝。
Review Focus
- 数字同句多义: “第一期8项、第二期4项”不能把第二个数字当首期;单位“万元/项”不得交叉计算。Task 2 的多数字/混合单位 RED 用例必须保守降级。
- 来源重复与截断: 相同文字在两个文件、无 Origin、或来源只提供了首段时,
sourceIndex不得越权引用另一个块。Task 2 的来源映射与版本 RED 用例必须整批拒绝伪造来源。 - 旁路字段: findings 正确但 focus/remaining/nextStep 称“已决定第二期含3项”时,默认卡不能泄露该肯定句。Task 3 的全字段投影测试必须验证中性替换。
- 混合批次: 一条有效差额、一条归属未定、一条来源无效:前两者可在来源均合法时原子归一化;来源无效时全部不提交,且没有后继付费请求。Task 3 的 CAS/拒绝/幂等测试覆盖。
- 预算和阅读回归: 结构化依据扩大提示后,final-only 仍为最终正文留额度;待确认发现刷新/窄屏/来源跳转不抢文件和焦点。Task 4 的 fake-stream、UI/Frontend 与真实 HTTP 浏览器测试覆盖。
Task 1:Core 候选依据契约
Files: Modify modules/core/task_snapshot.go、task_snapshot_test.go、ts/types.ts;不改 TaskSnapshot/TaskFinding 和数据库。
Interfaces: WorkFindingCandidate.Evidence *WorkFindingEvidence;SourceIndex 只引用同一 finding 的 Sources。Core 的 ValidateWorkCheckpoint 验证 direct_relation 恰一条关系前提且无 Result;difference 恰有 total/phase 两项且有 Result;unresolved_relation 恰有 total/phase/dependent 三项且无 Result。整数范围 0..1,000,000,同一模式不允许重复 role,索引须 0 <= index < len(Sources);计算与原文语义交给 Backend。
-
Step 0: 在现有任务工作区同步基线。 确认当前 Root/组件提交及任务卡收据已保存,使用
RECEIPT=/tmp/fast-slow-u3-r03-first-sync-20261013.json CMD='make task-sync' make evidence;导入原始收据。先核对最新 main 的项目成员/公开契约差异,遇到需改变本设计的冲突停在计划阶段。组件分支随后以同一权威主干处理各自合并;不得用旧 r0.2 组合假定兼容。 -
Step 1: 写 RED。 在
task_snapshot_test.go用现有合法候选加Evidence,表驱动覆盖三个模式的合法组合、索引越界、负数、重复 role、未知 mode、difference 缺结果、unresolved 偷带结果以及候选 JSON 不超过现有16KiB工具上限。TStypes.ts增加同名可选字段后,构建期校验生成镜像一致。candidate.Findings[0].Evidence = &WorkFindingEvidence{Mode: "difference", Premises: []WorkEvidencePremise{ {Role: "total", SourceIndex: 0, Value: intPtr(12)}, {Role: "phase", SourceIndex: 1, Value: intPtr(8)}, }, Result: intPtr(4)} if err := ValidateWorkCheckpoint(candidate); err != nil { t.Fatal(err) } -
Step 2: 跑 RED。
cd modules/core && go test ./... -run 'TestWorkCheckpointEvidence' -count=1;预期新类型/校验缺失。 -
Step 3: 实现 Core 类型与结构校验。 仅增加上述候选字段及
ValidateWorkCheckpoint的有限模式检查;TS 权威镜像同步,不增加状态枚举或前端行为。 -
Step 4: 跑 GREEN。
cd modules/core && go test ./... -count=1;检查git diff --check和 Go/TS 字段名一致。 -
Step 5: 独立提交 Core。 主题行英文祈使,body 写
Why:/Evidence:/Impact:/Refs:;Dev 指针留到 Task 4 统一绑定。
Task 2:Backend 纯依据判定与保守降级
Files: Create modules/backend/internal/runmgr/material_evidence.go、material_evidence_test.go;Backend 内嵌 deps/agent-system-core 指向 Task 1 精确 SHA。组件同步若涉及权限/公开契约取舍,暂停并交人工决定。
Interfaces: normalizeMaterialEvidence(core.WorkCheckpointCandidate, materialSourceRegistry) (core.WorkCheckpointCandidate, []string, error) 不写库、不调用模型;调用方先对全部 sources 执行 registry.validate 与持久原件校验,函数只使用已提供前缀和候选中的同条来源短引。parseCountPremise(quote, role, value) bool 只识别受支持数量模式。difference 由宿主重新计算 result;unresolved_relation 用 remaining=total-phase、low=max(0,dependent-phase)、high=min(dependent,remaining),low!=high 时把对应 finding 改为 needs_user、清空模型肯定 text/impact、填入宿主文字与真实来源;low==high 时也只发布宿主生成的、附前提的确定数量关系。前提数值超出总量安全降级,绝不输出伪算式。
-
Step 1: 写 RED。 用 r0.2 A01 的三份首段构造来源注册表及候选:错误
phase-list-gap不得保存“剩余4项包含3项”;12−8=4可保留为带“推算”的判断;明确原句“第二期包含3项依赖外部接口”可展示原文;0–3的未定交集转待确认。另覆盖12项/8万元、同句两个阶段数字、来源重复、无 Origin、截断块、旧 parserRevision 和陌生数词。normalized, notes, err := normalizeMaterialEvidence(candidate, sources) if err != nil { t.Fatal(err) } if normalized.Findings[0].Kind != "needs_user" || strings.Contains(normalized.Findings[0].Text, "其中包含3项") { t.Fatal("unsupported phase membership escaped", normalized.Findings[0]) } if len(notes) == 0 { t.Fatal("model was not told that the claim became pending") } -
Step 2: 跑 RED。
cd modules/backend && go test ./internal/runmgr -run 'TestMaterialEvidence|TestMaterialSetBounds' -count=1;预期未实现或错误断言失败。 -
Step 3: 实现最小纯函数。 原文直接关系优先保留 quote 的字面展示;仅支持
total/phase/dependent的有限角色和一致单位。自由文本中已决定/已批准/其中/包含/属于/剩余/第一期/第二期与数量或归属共现、却无可验证依据时,产出通用待确认句,不原样回显风险词句;不认识的表达也走保守路径。 -
Step 4: 跑 GREEN 与现有审批边界。
go test ./internal/runmgr -run 'TestMaterialEvidence|TestMaterialSetBounds|TestMaterialApprovalClaims|TestMaterialSource' -count=1;测试未触发的普通分析仍带“待核对”,否定/疑问审批表达不误拒。 -
Step 5: 自审并提交 Backend 独立提交。 记录识别语言的有限范围及未知降级成本,不声称通用语义正确性。
Task 3:一次提交、提示与预算兼容
Files: Modify modules/backend/internal/runmgr/task_checkpoint.go、task_checkpoint_test.go、material.go、material_sources.go、material_sources_test.go;modify modules/backend/internal/runtime/work_checkpoint.go、work_checkpoint_test.go。不改已经落盘的 r0.2 样本、数据库表或 SSE 契约。
Interfaces: PublishWorkCheckpoint 先结构校验和全部来源合法性,再调用 Task 2 纯函数归一化与审批/全字段风险守卫,最后沿现有 CommitTaskSources 做一次 CAS。Backend 对所有模型文本和结果文本都做守卫;有明确原文的 material_record 沿现有宿主引用路径显示。有效来源但不唯一的关系提交 needs_user;来源伪造、hash/版本漂移、JSON未知字段或越权依旧整个检查点失败。runtime.WorkCheckpointSink.PublishWorkCheckpoint 从 error 改为 (string,error),runCtx 在 CAS 成功后才返回简短归一化回执;publishCheckpoint 将回执附在既有成功消息,供正常下一轮模型看见,不新增 provider 调用。处理配方从 material-recipe.v8 到 material-recipe.v9。
-
Step 1: 写 RED。
task_checkpoint_test.go用 SQLite 断言“有效差额+未定关系”同批一次提交、无伪造肯定句;同批再加非法 sourceId 后整个批次零提交且已保存旧成果不丢;幂等同 ID 不重复计数,更正旧 finding 保留历史。work_checkpoint_test.go的假 stream 断言工具成功消息说明“转待确认”,仍只有既有最终答复请求;focus/remaining/nextStep 注入无依据决定句会被中性化。before := card.Task.Revision receipt, err := ctx.PublishWorkCheckpoint(mixedCandidate) if err != nil { t.Fatal(err) } if !strings.Contains(receipt, "待确认") { t.Fatal(receipt) } after, _ := store.GetCard(owner, card.ID) if after.Task.Revision != before+1 || after.Task.Findings[len(after.Task.Findings)-1].Kind != "needs_user" { t.Fatal("mixed batch was not normalized atomically") } -
Step 2: 跑 RED。
cd modules/backend && go test ./internal/runmgr ./internal/runtime -run 'TestWorkCheckpointEvidence|TestMaterialFinalReserve' -count=1。 -
Step 3: 连接校验与工具说明。 更新严格 JSON schema 的可选 evidence;将
WorkCheckpointSink、runCtx与现有单测调用点一起迁移到(string,error),使同一 checkpointId 幂等重发也能返回同一安全说明。材料任务提示只说明三种依据及未知归属要转待确认,不重复整份来源索引;工具结果回报归一化原因但不向默认UI暴露 sourceId。完整来源/阶段状态仍由宿主唯一拥有。 -
Step 4: 跑 GREEN 与失败恢复。
go test ./internal/runmgr ./internal/runtime -count=1,加go test -tags live ./internal/server -run 'TestMechanismSourceExtractionAfterSourceOnce|TestEvaluationStops' -count=1;离线比对 A01 输入与工具 schema 字符数/估算 token,若最终预留明显不足,停下来重新评审预算策略,不能私自提高额度。 -
Step 5: 提交 Backend。 精确记录 Core gitlink、新配方版本、RED/GREEN、正常/拒绝路径,不把假 stream 称为模型质量证明。
Task 4:组合、真实数据库与既有阅读界面
Files: Update generated modules/frontend/src/contracts.ts、modules/ui/src/contracts.ts only through make contracts;add/adjust modules/ui/test/progressive-cards.test.tsx and modules/frontend/test/work-state.test.ts if the current behavior is not already covered;update Dev component gitlinks and task card。任何新视觉令牌、页面、store 所有权或公开 TaskSnapshot 字段需求须回设计评审。
- Step 1: 同步后的组件核对。 复查 Task 1 的权威 main 同步记录和 Core/Backend 分支来源;组件各自与最新权威 main 核对,解决不改变设计的冲突。当前主干已含项目成员相关 Backend/Frontend/Documents 变化,不能用旧 r0.2 组合声称兼容。
- Step 2: 类型镜像 RED→GREEN。 固定 Core SHA 后先运行
make contracts,用git diff --exit-code检查生成镜像与 Core 类型一致;该命令预期在两个镜像尚未提交时指出差异,随后按生成结果提交。UI 断言材料记载优先、待核对判断限量、needs_user在“需要留意”默认可见;Frontend 断言刷新/迟到来源响应不抢文件/焦点,旧 seq 丢弃。cd modules/ui && npm test && npm run typecheck、cd modules/frontend && npm test && npm run build。 - Step 3: PostgreSQL 与 SQLite。 Backend 全量
go test ./... -count=1;用任务自有新数据目录/端口启动隔离 PostgreSQL,AGENT_PG_TEST_DSN仅指向该测试库,运行go test ./internal/runmgr ./internal/cardsvc ./internal/store -count=1并停止任务进程;来源CAS、混合批次和预算路径须在两档一致。输出经make evidence记录。 - Step 4: Dev 组合与真实浏览器。 组件都提交后推进 gitlink,干净 HEAD 上用
CMD='make test && make build' make evidence捕获完整输出并导入任务卡。启动带 PID/二进制 SHA/数据目录/组件 SHA manifest 的新任务自有 mechanism 实例;PLAYWRIGHT_BASE_URL、WORK_CHECKPOINT_HTTP_MANIFEST均从本轮 manifest 验证后传入e2e/work-checkpoints.playwright.ts。用真实 HTTP 验证待确认卡、来源跳转、版本变化、刷新和后台不抢阅读;仅停止本任务进程,保留 trace。 - Step 5: 独立代码复审与草稿 PR。 审阅者用准确 Core/Backend/Frontend/UI/Docs/Dev SHA 重放五类 Review Focus;修复 Important 后按影响补测。六个 PR 继续草稿,推送当前 HEAD,核验 Dev
test/test-pg/svc-realcombo、Backendvet-and-test、UItest的受信 runner、SHA、所有必需步骤;Core/Frontend/Documents 无独立工作流时由 Dev 组合 CI 覆盖其 gitlink。真实模型仍NOT_RUN,不合入。
Task 5:真实模型质量出口(另行资源审批)
Files: 只在受控评测入口确有缺口时改 modules/backend/eval/live/work_checkpoints_test.go/internal/server/work_checkpoint_eval_test.go;结果写 Dev 任务卡与 Documents 核验报告。旧 r0.2 A01 的原始 exit0、46,154 Usage 和语义 FAIL 不改写。
- Step 1: 准备可审查、一次性的资源提案。 固定新 Dev/Backend/UI/Frontend/Docs SHA、同一 A01 材料哈希、受保护路由来源(不输出 key)、新结果文件名、最多 run 数、单 run 与整批返回 Usage 目标、输出上限/300秒、缺 Usage/检查点拒绝/超额停止规则;明确在途调用可越过目标,无法凭源码承诺货币硬上限。
- Step 2: 等待用户明确批准。 没有新授权则
NOT_RUN,六 PR 草稿且不合入;r0.2 的“授权”只覆盖已经执行的一次,不能复用标签或重跑。 - Step 3: 获批后只运行一次。 全新隔离数据/manifest/输出,启动前重验 PID、二进制哈希、路由权限、零既有 run;逐调用核对实际 paid run ID、工具次数、Usage、持久阶段窗口、每条原文与逻辑归属、最终正文;任何工具拒绝后不再发 provider 请求。结果与失败用
make evidence原样保存,不补写或重试。 - Step 4: 独立 REPLAY 与交付裁决。 两个实质阶段、数字/决定/归属语义、完整最终答复及停止边界全部 PASS 后提交阶段 6/7 产物供人工评审;人工通过后才进入
policy/delivery.md的重新同步、独立代码复审、精确 HEAD CI 和智能体 PR 合入。任一 FAIL 保留真实证据与草稿,修订设计/资源后再单独评审。部署不在本计划范围;合入成功后按已授权的任务卡归档和安全工作区回收规则收尾。