Files
codex-app-server/docs/chv-muse-p11-gap.md
T
host 60c371d9d5 feat(chv): 对齐 Muse P11 用量计量与配额执行——四项计量 + 三档档位门 + 哈希链账本
- cloud/usage.py(新):TIER_LIMITS 三档提案(Free $0/Paid $19/Heavy $99,
  提案非定价,payload 带 proposal 标注)、TierStore(无档位行不受档位门
  约束)、UsageLedger(追加写哈希链,篡改可发现)、UsageMeter(token 读
  cost_records、消息读账本、并发/存储注入实测)、QuotaGate(纯准入判定,
  402,不碰在跑任务)、80% 提醒每维度每窗口一次
- cloud/server.py:_reject_if_over_quota 内加档位门(同一漏斗,双人门
  自动覆盖;查询异常 fail-closed 503)、GET /users/me/usage、
  GET/POST /admin/tiers、存储实测复用 _task_worktree_for_files
- docs/chv-muse-p11-gap.md:差距表(先写表再动手)+ 诚实边界(USD 路径
  30 秒轮询掐断与“不掐断”语义不一致是已知待决;并发即拒与设计文档
  排队不同;cloud 任务存储量不到;Heavy 消息/天提案未给,本轨定不限)
- 测试 22/22,全量 1889 OK(skipped=8);mypy 在 usage.py 上干净,
  server.py 5 错均为基线旧错(marker_tools/sub2api/_row_get,与本轨无关)
- 真机验证排队在 round-11 与 P4~P9 之后;不接真实计费
2026-11-06 22:42:30 +00:00

9.6 KiB
Raw Blame History

对齐 Muse P11 差距表:用量计量与配额执行

依据:~/workspace/research_notes/meta-muse-ai-architecture-20261101-0755/report.md (官方帮助中心 / 新闻室 2026-09-08 为准;第三方转述只作参考,不得把 第三方转述的价格写成官方定价)。基线:06c3e17。先写表再动手。

§1 要求(官方 + 本项目提案)

# 要求 来源
1 免费但有使用上限;达到上限可升级付费订阅,或等免费额度刷新 官方帮助中心(报告 §1.5/§6)
2 免费额度具体数字、付费档价格未出现在首发新闻稿中;Power/Maximum 等价格是第三方转述的帮助中心内容,不得写成官方定价 报告 §1.5、§5 表
3 三档档位与价格沿用本项目提案(用户 2026-11-06 委托“按市场定”,未确认为定价):Free $0 / Paid $19/月 / Heavy $99/月 本项目提案,见 §2
4 四项计量:token 数、消息数、并发任务数、存储量 本轨任务书 + 设计文档 §6.2
5 超限回 402;进行中回合不掐断,跑完才拦下一回合 本轨任务书 + 设计文档 §6.2
6 用量展示:用户可查当期用量与剩余额度;接近上限提醒一次(阈值默认 80%,本项目自定) 本轨任务书
7 账本追加写、不可篡改;账本里绝不含对话原文、文件内容、密钥 本轨任务书
8 不接真实计费、不碰真实钱;计费对接(Stripe 等)待用户另行批准 本轨任务书

档位提案数值(提案,非用户确认定价,非官方定价):

档位 价格 消息/天 tokens/月 并发任务 存储
Free $0 50 200,000 1 1 GB
Paid $19/月 500 2,000,000 5 10 GB
Heavy $99/月 不限(见 §5 第 4 条) 20,000,000 20 100 GB

§2 现状(基线 06c3e17 已有,可复用)

  • cloud/cost.py:CostStore:cost_records(task_id, project_id, model, tokens, usd_micros, source, day),actual(模型真实用量事件)与 estimated(字符估算)永不混算;价格表是 OpenAI 挂牌价,注释明言 “不是 relay 的账单”;report_by_task/project/day,无 report_by_user。
  • cloud/db.py:user_quotas(user_id PK, quota_usd_micros, updated_at)。
  • cloud/server.py:_quota_status(USD 月度配额,UTC 自然月)、 _check_quota / _reject_if_over_quota(超限回 402 quota_exceeded, 查询异常 fail-closed 回 503 quota_check_unavailable)、 _check_unpriced_token_cap(无价 token 上限,默认 20M/月,可配)、 GET /users/me/quota、GET/POST /admin/quotas。 准入点是建任务 / 分支 / 重试 / 续跑 / goal-resume,均为权限校验通过后、 写库之前;_reject_if_over_quota_for_task 双人门(触发人 + 原任务创建人)。
  • 全仓 grep 确认:cost_records 没有任何 UPDATE / DELETE 路径, token 账本已是追加写;本轨不再为 token 另建一套账本(见 §3 第 2 条)。

缺失:消息数计量、并发任务门、存储门、三档档位表、用量展示端点、 80% 提醒、账本防篡改校验、report_by_user。

§3 改动清单(本轨)

  1. cloud/usage.py(新,标准库 + cloud.db / cloud.cost 的常量口径, 不引 server):
    • TIER_LIMITS:三档提案数值,模块 docstring 与每个返回 payload 都标注 proposal: true(提案,非定价)。
    • TierStore:user_tiers(user_id PK, tier, updated_at),get_tier / set_tier(非法档位名拒绝);无档位行的用户不受档位门约束, 只受既有 USD 配额约束——定档是管理员显式操作,不给存量用户 默认套 Free(否则上线即拦住所有人)。
    • UsageLedger:usage_ledger 追加写哈希链账本(prev_hash + entry_hash = sha256(规范 JSON)),record / sum_kind / verify_chain(篡改返回首个坏行 id)。记消息、任务起止、存储 快照、提醒事件;token 事件不重复记(见第 2 条)。
    • UsageMeter:月度 token(读 cost_records JOIN tasks,与 _quota_status 同款查询,actual / estimated 分开列)、当日消息 (读账本)、并发(注入 running_task_count,状态 queued / running)、存储(注入 storage_bytes,磁盘实测)。 summary(user_id):四项 used / limit / remaining + 提醒 + 账本 校验结果。
    • QuotaGate:check_task_admission(token + 并发 + 存储)、 check_message_admission(消息/天 + token/月)。返回 None 放行, 否则否决 dict(error: quota_exceeded + dimension + limit / used + 可读 detail);纯准入判定,无任何终止在跑任务的 API(进行中回合不掐断,见 §5 第 1 条)。
    • disk_usage_bytes(path):递归求和,不跟随符号链接,读错跳过 (尽力而为,调用方在 payload 里标明实测范围)。
    • 提醒阈值默认 0.8,环境变量 CLOUD_USAGE_WARN_RATIO 可配; 每维度每窗口只记一次提醒(账本 kind="warning" 去重)。
  2. token 计量口径:以模型方返回为准(source="actual");无返回时 字符估算(source="estimated",payload 标注为估算)。档位门只计 actual——与 cost.py 的 P1 决定一致(“Estimated rows are never real spend and must not trip the cap”);estimated 只展示、不拦人。 但 payload 同时列出 estimated 数,让用户看得见估算占比。
  3. cloud/server.py 接线(只动配额漏斗,不新增调用点):
    • _reject_if_over_quota 内、USD 门与无价 cap 通过后,加档位门 (同一 quota_user_id);档位查询异常同样 fail-closed 回 503。 _reject_if_over_quota_for_task 不动(它已委托给前者,双人门 自动覆盖)。
    • GET /users/me/usage(_user_usage_self):当期用量与剩余额度
      • USD 配额合并返回 + 提醒 + 账本校验结果。
    • GET/POST /admin/tiers(_admin_tiers_get/set,_is_global_admin 同款鉴权):管理员定档 / 查档。
    • 存储实测:复用 _task_worktree_for_files 逐任务解析本机 worktree 求和;cloud / cloud-hypervisor 任务不在本机,量不到,计 0 并在 payload 里标明 storage_measured_tasks / storage_total_tasks。
  4. cloud/tests/test_usage_quota.py(新):档位数值钉住提案、非法档位 拒绝、无档位行不限档位门、token actual/estimated 口径、消息固定 UTC 日窗口、并发门、存储门与清理指引、账本哈希链与篡改发现、提醒 只发一次、准入纯判定不碰在跑任务、服务端点(/users/me/usage、 /admin/tiers、档位门 402)。
  5. docs/chv-production-readiness.md:补 P11 一节。

§4 真机待验证清单(未做,排队在 round-11 与 P4~P9 之后)

  • 真实 token 回传下的月度累计与 402(actual 行累计、无价模型走 既有 cap 不走美元门)。
  • 并发门在真实多任务下(建第 N+1 个任务被拒,在跑任务不受影响)。
  • 存储门在真实 worktree 下(本机任务目录求和、cloud 任务不计入)。
  • 80% 提醒在真实使用下只发一次、跨窗口重置。
  • 账本在真实写入压力下的链完整性(并发写不丢链不断)。

§5 诚实边界(本轨内不解决,写清不冒充)

  1. 进行中回合的语义不一致(已知待决):设计文档 §6.2 与本轨 任务书说“进行中的回合不中途掐断”;但基线 _check_quota 的 docstring 与 worker 实现是另一套——Local popen 与 Docker 路径的 worker 轮询每 30 秒查一次 USD 配额,超限杀进程组/容器(掐断粒度 是轮次边界 + 30 秒检查)。本轨新增的四项档位门只做准入, 不改既有 USD 路径的轮询掐断;两处语义不一致是已知待决项, 不在本轨内悄悄统一,须由父级另行裁决。
  2. 并发超限的处理与设计文档不同:设计文档 §6.2 说并发超限 “新任务排队,不立即拒绝”;本轨任务书(父级指令)说“即拒并 给出可读原因”。本轨按任务书即拒,差异记在此。
  3. 存储计量不完整:cloud / cloud-hypervisor 任务的 worktree 不在本机,量不到;本机也只能按任务 worktree 求和,用户在 VM 内或其它路径的占用不在计量内。payload 标明实测范围, 不冒充全量。
  4. Heavy 消息/天提案未给:提案原文只给了 Heavy 的 tokens / 并发 / 存储,未给消息/天。本轨定为不限,并标注为本项目决定, 不是提案原文、不是官方口径。
  5. 窗口口径:token 按 UTC 自然月(与既有 USD 配额一致); 消息按 UTC 自然日(固定窗口,非滑动);并发与存储是瞬时值。 固定窗口边界存在少量跨窗毛刺,文档写清,不冒充滑动窗口。
  6. 价格与计费:档位价格是助手提案(用户委托按市场定,未确认), 不是用户确认定价,更不是 Meta 官方定价;payload 与文档都带 proposal 标注。真实计费(Stripe/支付/开票/充值)不在本轨, 待用户另行批准;任何把“记账”等同于“收费”的说法都是错的。
  7. token 价格:USD 换算沿用 cost.py 的 OpenAI 挂牌价表, 注释明言不是 relay 账单;无价模型(无价格表项)的 token 只 计量、不折算美元,仍走既有无价 token cap。