Repository navigation
refactor(quota): compose quota summary in one TypeScript planning crossing - #7881
Conversation
…ssing Extend the existing todo.quota_planning.project request so TypeScript selects sources, composes lanes, counts, limits, warnings and display projection for user and project-asset quota summaries. Python gathers compatibility facts and dereferences owner-selected source references so original values survive the JSON transport. Pinned complete-output fixtures stay byte-identical; matrix paths drop from 1-5 crossings to one, non-dict input stays at zero and owner refusal stays at one without fallback. No handler, authority or persisted format is added. Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com> Signed-off-by: hhyykk <4408344+hhyykk@users.noreply.github.com>
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 99facff915
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if ((legacy || unknownSchema) && typeof payload.index === "number" && Number.isInteger(payload.index) && payload.index >= 0) { | ||
| presentation[1] = payload.index; presentation[2] = ""; presentation[3] = ""; | ||
| } | ||
| return {...fact, presentation, payload, display_source: {record: payload}}; |
There was a problem hiding this comment.
Recompute actionability after applying handoff readiness
When a successor has resume_when but no explicit resume_ready, and its handoff gate is cleared_with_successor, projectTodoSummaryDisplay adds resume_ready: true to the projected payload. However, the returned row retains fact.actionable, which Python computed from the unprojected source as false. Previously, actionability was computed after display projection. Comparing the parent implementation against this commit reproduces a successor disappearing from first_executable_items and executable_backlog_items, with its advancement count dropping from 1 to 0 despite the returned payload showing it as ready. Recompute the affected selection facts from the projected payload so cleared handoffs can resume execution.
Useful? React with 👍 / 👎.
loopx-agent
left a comment
There was a problem hiding this comment.
1) 问题定义(为什么改、要解决什么)
- 将用户与项目资产配额摘要(quota summary)的来源选择、泳道组合、计数与展示投影收敛至单次
todo.quota_planning.project跨运行时调用,并通过来源引用保留原始 Python 标量/对象精度。
2) 改动摘要(按模块分组)
- 单次跨运行时配额摘要组合 (
loopx/control_plane/todos/quota_selection.py,loopx/control_plane/todos/quota_selection.ts,loopx/control_plane/todos/quota_summary.py):在project_quota_planning中新增summary_kind与summary_request,由 TypeScriptprepareQuotaSummary与composeQuotaSummary组合完整配额摘要,再由 Python_decode_quota_summary_wire解引用还原。 - 快照与来源引用测试 (
tests/control_plane/**,tests/control_plane_ts/**):新增事务快照等价性测试与来源引用保真测试。
3) 逐点审阅结论(架构、语义、正确性、测试、风险)
- 架构方向:单次跨运行时边界收敛方向清晰,大幅精简了
quota_summary.py的重复泳道拼装逻辑。 - 正确性缺陷(Handoff 放行后的 Actionability 失步):在切换前,
todo_summary_open_items先运行projectTodoSummaryDisplay(将cleared_with_successorhandoff 门控对应的后继 Todo 注入resume_ready: True),随后才调用encode(item)计算todo_item_is_actionable_open(item)。切换后,quota_selection.py:182对未经过projectTodoSummaryDisplay的原始value.get(key, [])预先执行encode(row, include_payload=False),此时携带resume_when但尚未显式落盘resume_ready: True的已放行 handoff 后继项的fact.actionable被计算为False;而在quota_selection.ts:532中,prepareQuotaSummary虽然通过projectTodoSummaryDisplay得到了含resume_ready: true的payload,却直接沿用了旧的fact.actionable(return {...fact, presentation, payload, display_source: {record: payload}}),导致该就绪后继项从first_executable_items与executable_backlog_items中丢失。
4) 建议修改项(分 P0/P1/P2,带文件路径和行号)
- [P1]
loopx/control_plane/todos/quota_selection.py:182&loopx/control_plane/todos/quota_selection.ts:532:当projectTodoSummaryDisplay因cleared_with_successorhandoff 门控为条目注入resume_ready: true时,需同步按投影后的payload(或在 Python 端encode时结合handoff_gates)重算actionable与相关可执行性事实,并补充一条携带resume_when+cleared_with_successor的回归测试。
5) 最终结论(Verdict)
Changes requested (P1 actionability desync for cleared handoff successors with resume_when at exact head 99facff915f8ec3fc350bad835f9af179a635e7b).
loopx-agent
left a comment
There was a problem hiding this comment.
Reviewer: model_agent; gpt-6.1-sol; OpenAI; runtime_reported; reasoning_effort=max
动机 / Motivation
读取 quota/status 的 Agent 和维护摘要逻辑的开发者。 原来普通完整来源有 2 次 succession、1 次 context 和 1 次 planning 调用;现在仍有一次 succession 来源读取,另一次 planning 内完成组合,输出保持完整一致。 独立的 24 个输入/摘要组合,完整输出逐字节一致;底层 transport 计数显示普通路径 4→2,含 user-action 的路径 7→2。64 个 Python tests、5 个 TS tests 与真实 File/SQLite integrated canary 通过。 本次不删除仍有消费者的 planning-only codec,不宣称总 transport 恒为一次、installed/latency 或长程效果已资格化。
改动思路 / Approach
已有 quota_selection.ts 是 scope、claim、resume、deadline 的 typed owner,把最终组合放在同一事务内符合其职责;source reference 是为保留既有值类型的明确 codec。 两类摘要完整迁入现有 TS owner,复用 display/source selection;Python 保留源类型事实和引用 transport,不增加 handler 或第二个 authority。 保持 Python 组合保留重复跨界;另建 quota_summary.ts 会增加 Python/TS 同名双份结构;普通 JSON 全量搬运会改变大整数、float 和 metadata。当前方案复用现有 owner,付出的 source-reference 验证成本有实际 lossless 回归覆盖。 正向路径从 summarize_user_todos_for_quota / summarize_project_asset_todos_for_quota → project_quota_planning → projectTodoQuotaPlanning 进入既有 owner,24 个完整输出全部一致;9007199254740993、1.0、嵌套 proof 与 warning 类型均保留;异常路径保留 现有 EffectRuntimeRejected 与 codec RuntimeError,负向测试通过;无第二次 Python planning fallback;非 dict 输入保持零调用。本次完整审查当前 head,没有继承先前模板审查的通过结论。
具体改动 / Changes
13 paths +887/-309;旧 Python 组合删除、现有 TS owner 扩展、transport decoder 与独立完整快照/负向测试、双语 ledger。 lane/count/limit/warning 在 quota_selection.ts;context_projection.ts 只报告已有选择的源坐标;Python codec 不选择允许工作。 新增 todo_quota_summary_wire_v1 是当前同版本内部 transport;没有 persisted schema、权限、provider 选择或第二个状态 owner。v0-v4 planning 历史 reader 仍有当前消费者,保留合理。
关键代码讲解
-
prepareQuotaSummary:复用 display owner 选源并准备摘要事务。 把旧 Python 选择移入已有 typed 边界。 输入为summary_request/source_rows 与 typed selection,关键条件是kind 仅 user/project_asset;缺失 source lane 明确拒绝。EffectRuntimeRequestError,不静默回退 -
composeQuotaSummary:完成所有 lane、count、limit 与 warning 组合。 保留原字段与限制,引用保留 Python 原值。 输入为planning lanes 与 source facts,关键条件是deadline 使用完整 source;展示限制不改变候选全集。非法必需 lane 拒绝 -
_decode_quota_summary_wire:验证源/目标坐标并恢复原始值类型。 先验证全部 patch、大小和唯一目标,再写入 summary。 输入为wire summary/source_copies/integer_copies 与原 source,关键条件是坐标只允许 str/非负 int,目标必须 null;越界/重复/过大拒绝。RuntimeError,不把损坏 wire 当成空摘要
规格为 docs/architecture/rfcs/typescript-control-plane-migration-v0.md,spec_revision 867615e2c3aa2a32516a71d46f11a20d6fcb3289;按真实生产 caller 迁移中性决策、保留必要 Python I/O/codec;当前 ledger 对应这一个完整替换边界。
- replacement-first:implemented。两个公开摘要入口均复用同一 typed 组合 owner;旧 Python 组合与 _QuotaTodoLanes 退役。 对应
quota_summary.py → quota_selection.ts;源码对照 + 24-case paired execution。 - lossless transport:implemented。保留源数值类型、完整 metadata、proof、warning,非法引用在应用 patch 前拒绝。 对应
_decode_quota_summary_wire;source-reference negative tests + full output parity。 - real-path qualification:implemented。真实入口覆盖 File/SQLite;不以 unit/mock 替代 canary。 对应
examples/control-plane-integrated-canary-smoke.py;reviewer executed PASS on both backends。
对主干的风险 / Risks
最强风险是源码组合看似等价却悄悄改变原始 Python 数字/metadata,或限制展示时损失 scope、重试时钟和 closure proof。 为区分修复与无效测试,我对不可变 base/head 执行相同输入:base 24 完整输出为对照;普通 4 次 transport,user-actions 7 次;head 24 输出与 base 字节一致;对应路径降至 2 次 transport,其中组合仅一次。我在 effect_runtime_request 层计数,覆盖调用别名:旧测量忽略 succession preread 会低估完整调用数。因此这里明确区分一次组合调用与完整 transport 次数。 验证了 agent scope、other-agent user actions、legacy source、监测与 closure/successor proof;display cap 不裁剪 deadline 原始候选,source-reference 在展开前计预算。
- PASSED:
24-case paired corpus; 64 selected Python tests— PASS:24 outputs byte-identical;Python64 passed - PASSED:
source-reference suite + 5 TS quota summary tests— PASS:无部分 patch、无拒绝回退 - PASSED:
examples/control-plane-integrated-canary-smoke.py— PASS:File 和 SQLite - PASSED:
check_rfc_bilingual.py --base 867615e2c3aa2a32516a71d46f11a20d6fcb3289 --head HEAD; git diff --check— PASS,当前 head 日志保留
语义与 CI 对齐
沿用现有 typed Todo/display vocabulary;新 wire 是内部 transport。原 metadata 的真实性来自独立 source 坐标,不依赖 prose substring 分类。 没有新开关或默认启用变化;对 source 空/非法、legacy、非 dict、无 capability、owner refusal 均做完整对照,状态和权限没有旁路。 独立证据覆盖当前 changed invariant;远端 CI 的其他状态与合并 readiness 另行保留,没有把检查颜色当作正确性证明。 真实 source CLI 与 File/SQLite 已验证;没有 isolated PostgreSQL store 变更,无该后端新增持久化义务;未运行 installed/latency 或真实模型实验。作者大范围 119 个基线失败未作为本次独立验证结论。 作者文档“1–5→1”描述组合相关调用,若解读成完整 transport 总数就会低估仍存在的 succession preread;建议把这个计数边界写清。此表述修正不改变当前无损迁移结论。
我的整体评价 / Verdict
APPROVE:当前完整 diff 在所声明边界内达到 goal_achieved;long_horizon 为 preserved,配额、scope、阻塞、监测与 successor 的决策和回读保持;减少跨 runtime 次数是局部执行成本证据,并非任务效果或端到端延迟结论。 user_experience 为 preserved,现有 quota/status 消费者得到同一完整摘要,不需要迁移设置或操作流程。 quota/status payload 完整一致;未改变渲染/入口/设置,visual_review not_applicable。 已有 quota_selection.ts 是 scope、claim、resume、deadline 的 typed owner,把最终组合放在同一事务内符合其职责;source reference 是为保留既有值类型的明确 codec。 两类摘要完整迁入现有 TS owner,复用 display/source selection;Python 保留源类型事实和引用 transport,不增加 handler 或第二个 authority。 已删除旧 Python 组合,避免新建同名 TS 模块;仍活跃的 compaction/source helper 与 planning codec 暂留,最后 caller 迁出再退役。 不把本次 review 当作合并授权。
English verdict: APPROVE — 99facff915f8ec3fc350bad835f9af179a635e7b; both quota summaries now compose under the existing typed owner with byte-identical output; the complete ordinary transport path drops from four calls to two. 64 Python tests, 5 TypeScript tests, 24 paired cases and real File/SQLite integrated canary pass.
Goal And Delivered Outcome
todo.quota_planning.projectplus up to 4todo.context.page). A plain JSON move to TypeScript was blocked: a characterization pass showed that source counts, metadata, Vision proofs and warning fields would lose their original Python values in JSON transport._QuotaTodoLanes) → TypeScript owns source selection, lane composition, counts, limits, warnings and display projection inside the existingtodo.quota_planning.projectrequest. Python gathers compatibility facts and dereferences source references that the owner selected, so original values come back unchanged. Every pinned complete output is byte-identical.loopx-project/loopx:main. No issue closure claimed.Author Declaration
Implemented against
tests/control_plane/test_quota_summary_transaction_characterization.py,quota_summary_transaction_snapshots.json(27 cases, both summary kinds, call counts)quota_selection.tsprepareQuotaSummary/composeQuotaSummaryinside the existing planning request;context_projection.tsreports selected source coordinates through a callback and reuses the existing display selectorquota_summary_transaction.test.tsquota_selection.py_decode_quota_summary_wire: validates reference coordinates, null targets, paths and expanded size before attaching source valuestest_quota_summary_source_references.py(malformed refs, bounds, mutable-row independence)quota_selection.ts(already paired), not a newquota_summary.ts; twin count stays 45/45semantic-vocabulary-drift-smoke.pyledger/typescript-control-plane-migration-v0/2026-11-02-quota-summary-transaction{,.zh-CN}.md, linked from both RFC filescheck_rfc_bilingual.pyquota_selection.tsis code-identical apart from local helper renames.Migration economics receipt
loopx/control_plane/todos/quota_selection.ts(existingtodo.quota_planning.projectowner)_QuotaTodoLanesNo latency or long-horizon benefit is claimed.
Scope And Continuation
Validation
staticpassedruff checkon changed Python;npm run typecheck:control-plane;git diff --check.unitpassedunitpassedintegrationpassedcontrol-plane-integrated-canary-smoke.py: File and SQLite providers passed (real synthetic quota should-run journey).canarypassedloopx canary premerge --from-git-diff --git-diff-base origin/main: direct checks (diff, bilingual, compile, module ceilings), 10/10 catalog canaries, 8/8 risk-profile smokes and public-boundary scan passed; 0 manual holds.unitfailed (pre-existing)origin/main(867615e), and the failure sets match exactly. A 10-test sample was rerun on this head and on main: 10/10 fail on both. They involve CLI capture argument requirements, monitor settlement expectations, periodic-report successors and steward configuration. None involve the changed code.Frontend / Visual Evidence
Type of Change
LoopX Area
Technical Direction
Shared-authority RFC fixture impact
Boundary Checklist
none.Signed-off-bytrailer (git commit -s).Merge requires explicit maintainer authorization (quota rules under
loopx/**).