Files
Jyotisha/docs/tasks/TASK-round2-cost-and-delivery-20260831.md
T
Jesse_ChenandClaude Fable 5.1 8db71aaf81 docs: product-level README, AGENTS.md split into code/reading parts, add CLAUDE.md, move task briefs to docs/tasks
- README.md is now the product/repo front door (architecture, repo map,
  local dev, test tiers, delivery flow, doc map). Engine positioning,
  VedAstro/Codex setup and the oracle/benchmark command reference move
  verbatim to docs/engine/README.md, docs/engine/vedastro-gateway.md and
  docs/benchmark/README.md. Capability badges realigned with the registry
  (91/78/8/0); tests/test_readme_badges.py was red on staging.
- AGENTS.md: Part A (environment truth, delivery, worktrees, record
  placement, bug workflow, growth freeze, frontend red lines, privacy,
  pre-work check, test tiers) and Part B (reading-rigor constraints).
  GitHub issue-tracker/triage boilerplate removed: GitHub is a read-only
  mirror. All strings locked by tests/ are preserved.
- CLAUDE.md added: roles, three working modes, task-brief sections,
  acceptance criteria, session discipline; imports AGENTS.md.
- 50 tracked TASK-*/PROGRESS-* files and 3 never-committed briefs move to
  docs/tasks/ with an index; REPO_LAYOUT.md merged into README.

Docs-only change (no gated path touched).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0193vBv6w5MV2cifdTUu9H5P
2026-09-03 06:56:06 +00:00

13 KiB
Raw Blame History

任务书 · 第二轮:真实成本与交付物(2026-08-31)

基线:origin/staging @ 3a4396a4

下面所有行号只是线索,请按选择器/函数名定位。

为什么要做

前两份任务书(TASK-billing-pricing-20260830.mdTASK-rectification-convergence-20260830.md)已完成大部分实现。按代码逐条核对后,剩余缺口集中在两类:

A 类 · 卡在缺真实数据,不是实现问题。 计费任务 0 的聚合端点已就绪,但 staging 没有跑出真实单位成本,于是会员参数不敢动、缓存降幅无法验证、定价测算页只能显示估算。上一轮拒绝凭估算改参数是对的,本轮负责把这个输入补上

B 类 · 交付物本身还是空的。 校正任务 7(逐条回答 → 区间收窄归因表)是 P0,且不依赖任何外部数据,但排在 8/9/10 后面一起没做。用户为一次校正付的钱,买的就是这张表。

还有一个上一轮遗留的阻塞项:上下文缓存目前只对 Anthropic 生效,若生产 provider 不是 Anthropic,则「随便聊」会员档的毛利模型不成立。

已完成,不要重做

计费任务 0/1/2/3/6,校正任务 0/1/2/3/6。核对依据见两份 PROGRESS 末尾的「外部核对(2026-08-31)」。


硬红线

  1. 任务 0 是门控。 会员参数、售价、公平使用上限的任何调整,必须在任务 0 产出真实单位成本之后。不得凭估算改数——上一轮正确地拒绝了这件事,本轮不得倒退。
  2. 不得用生产用户数据做压测。 任务 0 的数据采集用真实调用,但必须是可控账号,且不得为了凑数据而批量刷接口造成成本与容量浪费。
  3. 归因表的收窄贡献必须来自服务端打分,不得由模型叙述生成。 一张看起来专业、实则模型编的归因表比没有更糟。
  4. 零贡献证据必须显式标注,不得静默丢弃。这是诚实性的一部分。
  5. 禁止答案回流(沿用上一轮红线 3):任何以已知答案调出来的规则不得进入生产打分链路。
  6. 上游同步必须过污染审查(沿用上一轮红线 4):不得同步带 pl9_1993observed_*_case_onlytarget_minute 标记的打分逻辑。
  7. 诚实性不可让渡:不得放宽 confirmation-gate.ts 的 blocker,不得降低 sealed holdout 门槛。
  8. 不得修改既有测试断言 —— 除非该断言锁的正是本轮要改的缺陷本身;那种情况必须在断言上方注明原值与原因,并在 PROGRESS 单列。
  9. 推 staging 前必须 ./node_modules/.bin/tsc --noEmit 通过。不要用 npx tsc,本仓库环境下会装到空包 tsc@2.0.4
  10. 数据库测试必须真跑。 npm run test:db 需要 Docker。没有 Docker 就不要推 —— 写进 BLOCKED.md 并停下。
  11. 不得改 .gitea/workflows/**。不得在有未提交改动的工作树上切分支。不得自行把 staging 提升到 main。

让步顺序:诚实性不回退 > 数据不损坏 > 功能与测试不回归 > 可验证的改进 > 成本 > 代码整洁

开工前置

git fetch origin --prune
git worktree add -b codex/round2-cost-delivery-20260831 \
  ../.worktrees/round2-cost-delivery-20260831 origin/staging

pre_work_error_ledger.md,跑 scripts/pre_work_check.py,读 frontend/AGENTS.md。改前在 docs/BUG_HISTORY.md 检索同类记录。

先读这些:

  • 两份 PROGRESS 末尾的「外部核对(2026-08-31)」——本轮范围的依据
  • frontend/src/app/api/admin/usage/aggregate/route.ts —— 任务 0 的现成入口
  • frontend/src/lib/agent-generation-settings.ts —— cachedSystemMessage() 的 provider 分支
  • frontend/src/lib/rectification-agentic/v9/evidence-model.tscore/rectification-decision.ts —— 任务 2 要接归因的地方
  • references/upstream/1993-session-correction-rerun.txt —— 归因表的目标形态就在这份记录里

任务 0(P0,门控)· 在 staging 采到真实单位成本

事实

计费任务 0 已交付聚合端点,但 report.full 从未有过真实行(上一轮才接上计费),chat.standardrectification 也缺分叉后的新数据。没有这批数据,任务 3(会员参数)与任务 1 的降幅验证都无法进行。

要做什么

  1. 把当前 staging 部署起来,确认 /api/health 的 SHA 与 origin/staging 一致,并在 PROGRESS 记录。
  2. 用可控账号跑出每类功能的真实调用,每类至少 5 次、覆盖典型与偏长两种形态
    • chat.standard:含多领域计算的完整咨询
    • rectification:至少一个跑到证据停止或预算耗尽的完整 case
    • report.full:至少一份分章节完整生成
  3. 用聚合端点导出 per-feature 的 runs / p50 / p95 / maxcost_microusdinput_tokensoutput_tokensduration_ms,以及 metadata.cache 的命中情况。
  4. 结果写进 PROGRESS,形成一张表:功能 → p50 成本 → p95 成本 → 缓存命中率

验收

  • 三类功能各有不少于 5 条真实 usage_ledger 记录。
  • PROGRESS 里有上述表格,数值可复核到 request_id(脱敏,只列聚合值)。
  • 明确记录当前生产/staging 实际使用的 provider 与 model_id —— 任务 1 依赖这个结论

停止条件

若 staging 无法部署或无法产生真实调用,写进 BLOCKED.md 并停下。任务 2 不受影响,可并行开工;任务 1、3 必须等本任务。


任务 1P0,依赖任务 0 的 provider 结论)· 让上下文缓存对生产 provider 真正生效

事实

frontend/src/lib/agent-generation-settings.ts

/** Adds only Anthropic's message-level cache marker; other providers keep current behavior. */
export function cachedSystemMessage(content: string, model?: unknown) {
  if (modelProviderId(model) !== "anthropic") return null;
  ...
}

用量解析覆盖全 provider,但缓存标记只对 Anthropic 下发。同文件顶部注释与 api/daily-starlanguage/route.ts:105deepseek-v4-flash)都指向 DeepSeek 系。

会员「随便聊」档的毛利模型完全依赖这项降本,因此这是上线阻塞项。

要做什么

  1. 按任务 0 确认的生产 provider,查清其上下文缓存契约——以 provider 官方文档为准,不要凭记忆写。要弄清:怎么声明、命中如何计价、最小可缓存长度、前缀稳定性要求。
  2. 为该 provider 实现缓存声明,保证 system + skill 前缀落在缓存边界内。校正的 system message 内嵌绑定 Skill 全文(v9/agent-run.tsbootstrap),是最值得缓存的稳定前缀。
  3. 不支持缓存的 provider 保持现有行为,返回 null,不报错、不改变请求形状。
  4. 降幅必须实测:用任务 0 的同一批 case 形态再跑一轮,对比 p50 cost_microusd。没有前后对比就不许在 PROGRESS 声称降本。

验收

  • 生产 provider 的请求能在账本 metadata.cache 看到非零命中。
  • 对话与校正的 p50 cost_microusd 相对任务 0 基线有可测量下降,降幅写进 PROGRESS。
  • 非目标 provider 行为不变,既有测试全绿。

任务 2(P0,无依赖,可立即开工)· 逐条回答 → 区间收窄归因表

这是 TASK-rectification-convergence-20260830.md 的任务 7,原文保留有效,本节为可独立执行的展开。

事实

references/upstream/1993-session-correction-rerun.txt 里,整场真实会话最有价值的产物是用户主动索要的那张表:

你的回答 压缩后的分钟区间 作用
2017 入职,岗位内容不合 14:4814:50 很强的收窄点
2023 末起量,一改风格就稳 14:4814:50 最接近最终分钟的一条

本仓没有这个概念:v9/evidence-model.tscore/*.ts 中不存在 narrow / contribution / attribution 语义,只有「这条证据支持哪个候选」,没有「这条回答把区间从 X 压到了 Y」。

同一份记录也证明了产品价值的真实边界:用户的 8 条生平锚点把窗口从 30 分钟压到 3 分钟,收窄是真的。归因表就是把这件事变得可见。

要做什么

  1. 每次证据写入后记录区间快照:写入前宽度、写入后宽度、该条证据的归属贡献。持久化,不靠事后重算(重算会因候选集变化而不可复现)。沿用既有 receipt / SQL 函数模式,状态留在 Postgres。
  2. 报告(校正任务 3 的产物)新增归因表:用户原话(走 display_date_label 口径)→ 收窄前后区间 → 一句作用说明。
  3. 收窄贡献由服务端打分产出,模型只做措辞(红线 3)。
  4. 无贡献的证据也要列出并标注「未产生收窄」(红线 4)。
  5. 归因表要能回答用户那句真实提问:「这个结论有多少来自我的回答?」 ——若最终区间主要由声明窗口或先验决定,必须说出来。

验收

  • 报告含归因表,条目数等于已确认证据数。
  • 每条的收窄前后宽度与该轮实际候选集一致,可复核。
  • 零贡献证据被显式标注,不被静默丢弃。
  • 归因数据来自持久化快照,重开页面结果一致。

任务 3(P1,依赖任务 0 与任务 1)· 会员参数与售价重设

这是 TASK-billing-pricing-20260830.md 的任务 5,上一轮正确地保留未改,本轮在有数据后执行。

事实

product_entitlements 的公平使用参数仍为种子值(20260806020000_billing_products_subscriptions.sql:146-155):月卡 billingLimit 2000、年卡 24000、Pro 月卡 5000、Pro 年卡 60000。上一轮已完成语义澄清与文案约束,只差参数本身。

要做什么

  1. 用任务 0 / 任务 1 的实测 p50、p95 成本重设 minuteLimit / dayLimit / billingLimit按 p95 定,不按均值——公平使用要挡的是尾部。
  2. billingLimit 的定位是熔断,不是对用户承诺的配额;「随便聊」靠 minuteLimit + dayLimit 保护真人容量。语义已在上一轮写入 admin 文案,本轮只改数。
  3. 按产品已定规则,移除 standard 月卡/年卡的 rectificationreport.full 权益(改为单独计费)。移除前必须核查存量订阅依赖,有在期会员依赖这些配额时给出兼容处理,不得让权益凭空消失。
  4. 售价(billing_products.price_cents)改动需产品确认后再执行,本任务只准备迁移,不擅自调价。
  5. 全部走幂等迁移或既有 admin_save_product_draft 审计路径,不得手改生产库

验收

  • 迁移幂等,npm run db:migrate:check 在隔离 Docker PostgreSQL 里 apply / check / reapply 三次退出码均为 0。
  • 新参数下,按 p95 成本估算的会员毛利写进 PROGRESS。
  • 存量订阅的兼容路径有明确记录。
  • 定价测算页读到新参数后,输出表与 PROGRESS 的数字一致。

任务 4(P1)· 「为什么是这个结论」的质疑通道

TASK-rectification-convergence-20260830.md 的任务 8,原文有效。

真实会话里用户问「你是信息记忆联想了吗?还是靠印度占星专业技术推理出来的?」——这一问是全部真相的来源。本仓没有任何「为什么」入口(v9/choice-card.tswhy 是每个选项的说明,不是结论来源)。

内容全部来自服务端已有的 claimCards / evidenceRefs / confirmation-gate blocker不得由模型即兴生成。与任务 2 的归因表共用同一份服务端数据,不要建第二套。


任务 5(P1)· 中途改窗口与保留证据重跑

TASK-rectification-convergence-20260830.md 的任务 9,原文有效。

要点重申:同一 case 内重跑不重复扣费(沿用 rectification:case:<caseId> 幂等键);重跑必须留痕;新窗口与既有证据冲突时如实呈现,不得静默丢弃。


任务 6P1)· 首轮批量出题

TASK-rectification-convergence-20260830.md 的任务 10,原文有效。

src/mastra/agentic-rectification.ts 中「一次一问」仍在。上游手册的节奏是第 1 轮 3–5 道 A/B/C/D 一起出。批量轮在轮次预算里记为一轮


建议执行顺序

  1. 任务 2 —— 无依赖,交付物核心,立即开工
  2. 任务 0 —— 与任务 2 并行,它是任务 1、3 的输入
  3. 任务 1 —— 拿到 provider 结论后立即做,它是「随便聊」上线的阻塞项
  4. 任务 3 —— 有成本数据后执行
  5. 任务 4 / 5 / 6 —— 依次

交付

  • PROGRESS 写进 PROGRESS-round2-cost-delivery-20260831.md,任务 0 的成本表与任务 1 的降幅对比单列。
  • 每个任务一个提交。
  • 推 staging 前:./node_modules/.bin/tsc --noEmit 通过、npm run lint 无新增 error、npm run test:db 在 Docker 下 fail=0、npm run build 通过。
  • 全量 ./node_modules/.bin/tsx --test tests/*.test.ts 的失败清单与基线逐条比对,确认无新增。