Repository navigation
Conversation
Signed-off-by: song <liusongstep@gmail.com>
Signed-off-by: song <liusongstep@gmail.com>
songoow
left a comment
There was a problem hiding this comment.
Reviewer: model_agent; model=GPT-6 family (Codex); provider=OpenAI; self_reported (runtime observation unavailable).
动机
维护者或 Agent 在已写回工作后读取扣费失败原因,需要区分配额用尽和其他拒绝。此前普通传输错误只要提到 budget 就会被归为预算拒绝,真正的限额拒绝没有这个词反而丢失分类;本次使用实际拒绝分支传来的类型化事实区分两者。同一错误更换说明文案不会改变分类,原有回执、重放和重试效果保持不变。本批仅修结算失败分类,不实现新的扣费策略、执行授权或完整 Goal 验收。全量词表来源验收仍由 #4447 的既有阶段负责,本 PR 不关闭该 tracker。
改动思路
拒绝事实由现有 quota 分支产生,TypeScript 结算 owner 负责唯一分类,Python 仅传输已有 action 值。当前 PR 只增加一项拒绝事实并删除文本分类,不新增运行时调用、存储或决策框架。我核对了真实 quota 入口、callback 传输、TS reducer 和 Python 解码:仅准入本身拒绝扣费时才附带 quota_rejection_action,其他先发生的绑定或工作区失败不会借用嵌套快照中的限额状态。说明文字继续完整传递,成功、拒绝和恢复仍由原有结算边界控制。
具体改动
评审 head:c773edef89273ccf4240b54da1f166667963d64e;基线:125db4201982a4bf1a10a330ba573ea52bf85096。规格依据为 docs/architecture/rfcs/agent-loop-effect-interpreter-v0.md,spec_revision 125db4201982a4bf1a10a330ba573ea52bf85096,使用修改前的已接受契约判断本次行为,而非让新文档自证正确。
关键代码讲解
build_quota_slot_preview_for_decision:仅在真实准入拒绝分支携带已有 action;无效决策不给出该事实。分配、检查及成功扣费规则不变。callbackFailureKind/commitStepPayload:复用EffectiveAction.THROTTLED_SKIP与SettlementFailureKind;预算拒绝只适用于 quota-spend 阶段。缺失、未知、格式错误或其他 action 保持阶段级失败,不再按文案猜测。execute_turn_driver_settlement:原有 caller 无需改动,完整传输 provider payload,由 TS 返回保留原始 receipts 的结果。executor 回归使用真实spend_quota_slot拒绝,并验证失败重放与恢复。
规格映射:M7.1 的预算失败区分与部分执行/重试 characterization 在本次受影响路径实现;M7.2 的原始 effect identity、receipt 链与不重复 writeback/spend 保留并验证。全部 M7 和 #4447 的其他来源闭合不属于此批。英中文档同步披露新的 transient callback 分类规则与历史回执读取边界。
对主干的风险
行为变化是明确的:新输入只有说明文字、没有结构化拒绝事实时,保留 quota_spend_rejected,不会再因 budget 字样提升为预算分类。此前已保存的失败回执保持原样;旧 callback 若需要预算分类应提供现有 action 事实。不存在新的 opt-in 或默认关闭宣称,也没有新的用户确认步骤或权限来源。frontend/Lark 源码搜索未找到按该失败 kind 分支的消费者,CLI/Turn 的现有输出仍承载结果。
语义与 CI 对齐
相同四类输入经真实 Turn API、TS bridge 和隔离文件 journal 运行:基线将真实 throttle 分成普通拒绝,将误导文案分成预算拒绝;head 修正两者。逐字段比较只有这两类首次失败及其重放的 failure.kind 共四处改变,完整失败说明、receipts、effects 和调用次数一致;恢复均为 host/writeback 各一次、spend 两次。独立 oracle 在基线失败、head 通过,未用当前实现输出生成预期。
最终 head 上 283 项 Python、205 项 TypeScript、TS typecheck、Ruff 与完整语义检查通过;开发期 advisory 未发现支持形式的新词表,但不证明所有语义等价。premerge 在同一补丁的 rebase 前版本通过 7 个 catalog canary、8 个 risk smoke、公开边界、diff 与编译检查;rebase 后已重跑上述受影响测试与完整语义检查。远端当前为 1 success / 6 queued,没有已报告失败;排队是合并准备度的保留项。未做安装态 App、真实模型或外部 provider 验收,不据此声称全量上线资格。
我的整体评价
Approval conclusion (author-owned PR; GitHub blocks formal self-approval).
这个增量有完整真实调用方、独立反例及恢复读回,规模与诊断缺陷相称。long_horizon 判断为 preserved:失败后的原回执与恢复顺序未变;user_experience 判断为 improved:失败分类能反映结构化原因,未增加操作步骤。未来导向检查已应用于该分类边界:复用既有词表与 TS owner、删除 substring 规则;更广状态机迁移留给其既有 owner,不绑入此批。语义选择为 reuse_existing。CI 与维护者合并授权仍单独保留,评审不代表整个 Goal 已完成。
English verdict: APPROVE - c773ede; typed quota refusal fixes both diagnostic misclassifications while preserving receipts and retry effects; 283 Python and 205 TypeScript tests pass, remote CI remains queued.
Quota-spend callback failures were classified by whether their message contained
budget: an unrelated transport error mentioning the budget becamebudget_rejected, while a real throttled quota refusal without that word remained generic.The quota admission-refusal branch now transports its existing action as
quota_rejection_action. The TypeScript settlement owner mapsEffectiveAction.THROTTLED_SKIPto the existing budget failure kind. Missing, malformed, unknown or unrelated facts retain the stage-specific rejection. Previously persisted failure receipts remain unchanged; new callback results no longer infer their category from prose. The English and Chinese effect RFCs disclose this behavior change.Refs #4447 for the bounded settlement source-evidence follow-up; this does not close the tracker. The source value reuses the existing effective-action owner, and the result reuses
SettlementFailureKind. No new vocabulary or runtime bridge is introduced. The related refactor removes the text classifier within its current owner; a broader decision migration is deferred.Validation:
Changed entrypoints are quota refusal output and the existing Turn settlement result. No frontend or Lark consumer branches on this failure kind; no new interaction or authority is introduced. This is source-checkout and isolated synthetic validation, not installed-App or live-provider qualification. Remote CI and maintainer merge remain separate gates.