Repository navigation
Conversation
Signed-off-by: shangzh0 <97216392+shangzh0@users.noreply.github.com>
songoow
left a comment
There was a problem hiding this comment.
Reviewer: model_agent | GPT-6 Astra Pro | OpenAI | self_reported
审阅固定在 c66ece1790a1da680cc9a673122dc16221d4bf90,基线 21367015cce45294dcf99f54a3211d66f5d842c5。发现 1 个新 P2,结论 REQUEST_CHANGES:明确退休步骤之后,初始旧读依据会再次有效,延迟写入可以恢复被否定的步骤。 这是实际 journal append 与独立 CLI 状态读回验证的回归,不是因为 CI pending 或缺少原生 provider 环境而保留结论。当前没有既有 review/comment 需要重复。
动机 / Motivation
受影响的是使用 LoopX 记录任务内下一步、随后根据新证据改写指导的 Agent,以及读取其状态的维护者。 Agent 先记录旧实验步骤,后来明确说明该实验已失效;旧读取器跳过这条没有 step_revision 的新决策,状态和后续派生观察仍显示旧实验。 本补丁能让新明确指导阻止旧步骤被读取,并保留原 Todo;但当前实现使读依据回到初始值,持有初始旧依据的延迟写入可以重新提交被否定的步骤。 范围是已有 journal 的推荐读取与步骤写回,不改变 Todo 选择、claim、lease、Goal 意图或配额,也不保证实验方案优劣。
这个问题值得修:后续工作不能不断拿到已经否定的实验建议。核心退休效果在本轮确实成立,普通观察和其他 Agent 也没有误退休本人的步骤;尚缺的是保持纠偏以后的写入新鲜度,让延迟客户端必须重新读取和判断。
改动思路 / Approach
Python 继续只解码既有 journal 和 typed source,TypeScript 继续拥有任务绑定、步骤复用及写入依据校验;修复应在该 owner 内保留可区分的明确决策版本,不增加并行状态机。 当前 PR 的边界是同一 Agent 的历史推荐到状态投影和下一次步骤写回,既要退休旧步骤,也要维持旧读取不能覆盖新决策的约束。 现有完整 journal 按时间与追加位置倒序读取,本补丁只在同一 actor 内把 explicit_arg 加入停止查找的条件。这样 TypeScript 收到明确指导而非更旧步骤,就不会继续附加 next_step。派生观察仍跳过、不生成新 step receipt;peer 的记录也不参与本 actor 的查找。
该分工与代码规模合理,没有必要新增任务状态表或重写 Todo selector。问题在于读 barrier 和写 fence 是相连的:TS 把 explicit 当作“不能复用步骤”是对的,但把它当作“从未有过步骤”的空版本会让过去的 basis 重现。修复应复用当前 decision owner,为最近明确决策保留可区分版本,同时保持步骤不可复用。
具体改动 / Changes
关键代码讲解
latest_bound_recommendation(recommendation_source_io.py:67,新增分支:75–80)在遇到同 actor 的 explicit receipt 时停止扫描;这修复了跳过新决策、恢复旧实验的原缺陷。resolveLaneRecommendation(refresh_recommendation.ts:67)仍校验 actor、Goal、Todo、task/source facts,只允许agent_lane_step被附到当前任务。但 86–88 行也仅从该种 receipt 取priorRevision;新 explicit 输入落到null,basis 因而可以回到初始值。128 行的字符串相等校验随后错误接受旧 B0。resolve_refresh_recommendation(refresh_recommendation.py:112)让显式参数优先;普通派生刷新才选择当前任务并尝试复用有效 bound step。生产 producer 已检查:CLI 原样传入显式--recommended-action,turn_run_once写 host 的明确 follow-up 推荐;普通派生刷新没有该显式参数,demo 也传 None。没有按自然语言判断“旧/新实验”。project_agent_next_actions(recommendation_source_io.py:108)从当前 canonical 任务按 actor 投影,并调用同一 TS owner。独立 source API 和新进程status --include-task-graph读回一致;展示--limit 1与50不改变完整 journal 的步骤结论。
书面依据是基线 21367015cce45294dcf99f54a3211d66f5d842c5 的 docs/quota-allocation.md(Next Action writeback)及 docs/project-agent-todo-contract.md。本审查给未编号要求添加三个引用名:step-read-fence 要求旧读取冲突后重读重判,当前 head not_met;task-authority-preserved 要求不改 Todo/claim/lease/Markdown,当前 implemented;full-history-read 要求展示窗口不决定最新有效步骤,当前 implemented。本PR新增的 explicit 退休段落说明其预期行为,不被循环当成独立旧规范。
验证与实际对照
本轮运行 next-action writeback、receipt/CLI、settlement 三组测试,PASS:39 passed,205.14 秒,exit0;Ruff、diff hygiene、base/head bilingual check 同样 PASS。独立 harness 使用相同 synthetic fixture、真实 FileAuthorityStore 与 TS Effect Runtime,在两个不可变 revision 上走 source API、durable journal 和 CLI,没有 mock reducer 或手改 journal。
| 同一场景 | 基线 | 当前 head |
|---|---|---|
| bound step 后普通 derived、peer explicit | 保留原步骤 | 保留原步骤 |
| 本人 explicit 后再 3 次 derived | 仍复活旧实验 | 无旧 next_step,派生指导回到当前任务 |
| fresh basis 写新 S2 后再 2 次 derived | 持久化并保留 S2 | 持久化并保留 S2 |
| 初始 B0 缓存,在中间 bound + explicit 后延迟写入 | exit1,basis conflict,无追加 | exit0,追加 1 行,旧实验重新可见 |
每一步都核对 source Markdown、canonical provider revision/cursor/Todos 不变。对最后一行另做实际写入后的独立 CLI status,排除仅 dry-run 成功、仅内部字段变化或旧历史回放。固定 fixture 指纹一致;比较只去除路径和不透明 hash 字节,保留 basis 是否回到初始值的关系、完整推荐文字/source/authority、退出码和追加数量。没有把相同枚举当成语义一致。
对主干的风险 / Risks
[P2] 明确退休后旧 B0 再次有效
触发者是同一 Agent 的延迟命令、并发会话或重试:早先读了没有步骤时的 B0,另一轮已经写过步骤并明确否定,再把旧 B0 发回来。新 Python 分支返回 explicit,TS 的 priorRevision=null 使 basis 与最初相等;现有 expected !== basis 守卫失效。实际 head 返回 appended=true、journal 增加一行,独立 status 显示 Continue the old experiment.;base 同输入返回 next_action_basis_conflict、不增加 journal。Todo 没变不能证明外部规划仍新鲜,提供 basis 的调用者本来就是要检查这层更新。
让最近同 actor 明确决策的稳定、可区分 receipt/decision revision 参与既有 TS read basis,同时继续禁止旧 step 复用;不能把所有 explicit barrier 都退化为 null/同一常量,也不能复用旧 step 的 token。 先读 B0,再写 S1,再明确退休,最后用旧 B0 提交下一步:必须 next_action_basis_conflict 且 journal 不增长;重新读取新 basis 后写 S2 成功,peer 和多次 derived 仍保持既有隔离。 这项新反例解释了为何现有39项全过仍不能批准:新增测试覆盖了读退休,却没有保留最初 B0 并在退休后重新提交它。修复时应继续保留已有 peer/derived 行为与 fresh 恢复,不增加平行 state 或让 explicit 获得 Todo 权限。
语义与 CI 对齐
补丁复用现有 explicit_arg、agent_lane_step 和 refresh_recommendation_v0 词汇,没有新增领域分类;需修复的是现有 source-facts fence 的语义一致性。最新采样的同 head CI 没有失败,仍有跳过及未完成项;跳过项未计为通过,也不因 pending 额外否决。本轮没有独立重跑全树 premerge 或 installed-wheel,不把作者报告列为已验证。代码判断已有明确 P2,后续合并仍要执行配置要求的 readiness 检查。
我的整体评价 / Verdict
这是一项真实且范围合理的小修,核心“明确指导之后旧步骤不再被读取”已经通过正反对照。长期纠偏与调用者体验仍存在具体 regression:持有旧依据的延迟写入错误成功,能撤销刚完成的指导纠正;因此当前交付不能视为完整。fresh basis 建立新步骤的合法恢复路径已验证,不需要为此引入额外人工确认或新任务协议。
检查的变更路径只影响 journal 解码、CLI 推荐与既有状态数据,没有页面或渲染布局变化,因此视觉截图不适用。 未测试模型实际采纳或长期实验收益;本次没有渲染页面改动。修复唯一 P2 后,应重复旧 B0 拒绝、新 basis 恢复和现有 peer/derived 矩阵,再刷新 exact head 与 CI;本轮没有提交修复或执行合并。
English verdict: REQUEST_CHANGES — exact head c66ece1; explicit supersession works, but its null prior revision recreates the initial basis and allows a stale write to append and resurrect a retired step. Preserve a distinct decision revision in the existing basis owner and rerun the paired stale-write/fresh-recovery regression.
| if row.get("agent_id") == agent_id and isinstance(resolution, dict) and resolution.get("step_revision"): | ||
| if row.get("agent_id") == agent_id and isinstance(resolution, dict) and ( | ||
| resolution.get("step_revision") | ||
| or resolution.get("recommended_action_source") == RECOMMENDED_ACTION_SOURCE_EXPLICIT |
There was a problem hiding this comment.
[P2] 保留明确退休决策的版本,避免旧 basis 再次有效
这里开始把没有 step_revision 的 explicit receipt 返回给既有 TS owner,但 resolveLaneRecommendation 的 86–88 行只为 agent_lane_step 取 prior revision,explicit 会回到 null,使 basis 等于第一次尚无步骤时的 B0。可重现序列是:先缓存 B0 → 写 bound step → 同一 Agent 明确退休 → 用缓存 B0 的延迟 --next-action 写回。当前 head 真实 CLI 返回 0、appended=true、journal 增加一行,独立 status 又显示刚否定的 Continue the old experiment.;相同 fixture 在 base 21367015cce4 返回 next_action_basis_conflict 且不追加。
请让最近明确决策的稳定、可区分 revision 参与同一 TS read basis,同时继续禁止旧 step 复用。不要把所有 explicit barrier 都视为 null/同一常量或沿用旧 step token。补充上述旧 B0 应拒绝、fresh basis 写 S2 应成功的公共路径回归;现有 39 项测试全过但未覆盖该 ABA 情况。
Signed-off-by: shangzh0 <97216392+shangzh0@users.noreply.github.com>
|
Reproduced and fixed the stale-B0 P2 in 2baba90. The existing TS read-basis owner now hashes the explicit decision's existing journal identity, transported by the reader. No new persisted decision/step field or permission was added. Explicit guidance remains non-reusable; repeated same-text/same-clock committed records remain distinct. New regression: read B0 → write S1 → explicit retirement → stale B0 API/CLI rejection with no journal append → separate CLI route read → fresh S2 accepted and retained through derived observations. Canonical provider revision/cursor/Todos and source Markdown stay unchanged. The CLI status assertion preserves the existing minimal fixture's health exit1 and verifies its complete, error-free read projection, not health or execution authority. Peer/derived cases remain covered. Validation: 40 Python suite tests passed; final expanded CLI regression rerun passed (1 passed, 25 deselected). 20 TS owner tests, typecheck/Ruff, standard canary and isolated installed-wheel real decoder/typed-owner checks passed. Updated the PR description for this exact head and retained the original regression finding. Re-review is pending; no merge performed. |
Goal And Delivered Outcome
After an Agent writes a bound next-step and later explicitly replaces its recommended action, status can resurrect the old step: journal lookup skips the newer explicit decision because it has no
step_revision. Retain that newer actor-scoped decision as the lookup barrier so the existing TypeScript owner declines to reuse the retired step.中文:Agent 明确改写后续指导后,状态读取不能跳过这次决策、恢复更旧的 next-step。
Author Declaration
Written by: model_agent — OpenAI GPT-6 family.
Implemented against the existing Todo/Next Action authoring and typed recommendation contract at main
21367015cce45294dcf99f54a3211d66f5d842c5. Python only decodes the existing journal, source marker and committed source identity; the shared TypeScript owner still decides task binding, eligibility and the read fence. Derived progress observations retain valid bound steps, another Agent cannot retire this Agent's step, and a fresh next-action remains required to establish a new bound step.Complete for reproduced explicit-decision supersession. This does not rank experimental hypotheses, guarantee a better action or establish that every historical stale recommendation had this cause. No Todo selection, source Markdown, permission, scoring or defaults changed.
Self-check: exercised the real source API, durable journal and CLI status path; no independent review is claimed.
Validation
Tested revision:
2baba90005466298b89735cee30791768ff971c6; synthetic inputs only.next_step.No native benchmark, model or evaluator runs launched. Remote CI, independent review and long-horizon outcome gains remain unproven.
Frontend And Boundaries
Existing status projection only; no new screen or rendering change, visual evidence N/A. Synthetic fixtures and public-safe contract text; no raw trajectories, private paths or secrets. Dedicated branch, explicit staging, DCO signoff; no merge performed.
Review Follow-up
The first head fixed stale reading but introduced a freshness regression: explicit retirement had no prior step revision, so the read basis could become identical to its initial B0 and admit a delayed old write. This was reproduced before repair.
Follow-up 2baba90 keeps the existing explicit journal source identity in the TypeScript-owned basis. Python transports the recorded Goal/Agent identity and source reference only; it does not mint a decision revision or persist a new receipt field. The explicit record still cannot become a reusable step. Distinct committed records remain distinct even with identical text and timestamp; ordinary derived observations and peer decisions retain their existing behavior.
The regression reads B0, writes S1, explicitly retires it, rejects B0 through both the real API and CLI with no index append, verifies the retired route through a separate CLI status read, then accepts a fresh S2 and preserves it through derived observations. The existing minimal fixture lacks a complete Goal health brief, so that status read explicitly retains health exit1 with a complete, error-free read projection; it is not reported as a healthy Goal or execution grant. Source Markdown, canonical provider revision/cursor/Todos remain unchanged. The initial success-only status test helper was corrected for this fixture boundary without changing product health rules.
40 Python tests passed before the final CLI assertion expansion; that expanded regression was then rerun and passed. 20 TypeScript owner tests, final standard canary and isolated installed-wheel checks passed. Original review evidence is retained and independent re-review remains pending.