#471: wakeup-plan latest-open-fresh 投影(完整版,收口 hotfix1+2)#482
Conversation
…/latest + release-rollup 仅 latest-per-sha 且 ahead>0 本地 ref 验证(止 stale 投影/graphql)
…ssue471-wakeup-plan-latest-open-fresh
🤖 架构审查 approveTL;DR
详细说明我核对了 关键架构点是新增的本地 ref probe 只读 📎 完整 codex 原始输出(存档备查)---
pr: 482
role: architect
verdict: approve
---
## Verdict
approve: no architecture compliance concerns; the PR narrows wakeup-plan release-rollup projection input while preserving #396 runner revalidation and no standalone authorization.
## Evidence
- `skills/codex-refactor-loop/scripts/codex_refactor_loop/wakeup_plan.py:1321`: `release_rollup_actions()` still emits a fixed `release-rollup-needed` action with `controller_action: "open_release_rollup_pr_from_action"`, `runner_authority`, and `no_lifecycle_authority: True`; this stays within CLAUDE.md #396 allowed actions, specifically "named helper `open_release_rollup_pr_from_action`" and "wakeup-plan closed action projection".
- `skills/codex-refactor-loop/scripts/codex_refactor_loop/wakeup_plan.py:1379`: `_release_rollup_event_is_fresh()` uses `safe_head_ref` plus read-only `git rev-parse --verify` and `git rev-list --count` against `refs/remotes/origin/<review_base>..refs/remotes/origin/<integration>`; it does not commit, push, merge, tag, release, edit labels, or mutate host config, so it does not violate the CLAUDE.md #396 forbidden generic lifecycle surface.
- `skills/codex-refactor-loop/SKILL.md:301`: the #396 contract now explicitly states that wakeup-plan may prune stale/superseded local evidence, that release-rollup freshness may use read-only local ref evidence, that probe failure fails open, and that this "does not weaken #396 revalidation or create standalone authorization"; this maps the changed concept to the CLAUDE.md rule "变更必须可验证" and the wakeup-runner carveout.
- `skills/codex-refactor-loop/scripts/test_skill_reference_anchors.py:1427` and `skills/codex-refactor-loop/scripts/test_wakeup_plan.py:1471`: source-regression and behavior tests cover the new contract, satisfying CLAUDE.md "行为变更必须配套 behavior test + source-regression test".
- Scope honesty: PR files are `SKILL.md`, `wakeup_plan.py`, `test_skill_reference_anchors.py`, and `test_wakeup_plan.py`; implement summary records `SCOPE_EXTEND` as `none`, and these files match the declared wakeup-plan + tests + SKILL anchor scope.
- Old/New pattern comment policy: `HOST_REFACTOR_COMMENT_POLICY=none` per implement summary; the diff adds no new Old/New refactor-history source comments.本机调试线索: ⟦AI:AUTO-LOOP⟧ |
|
质量审查结论:通过。 从 readability / naming / simplicity 角度看,这次改动范围集中在 release-rollup freshness projection: 未发现需要改动的质量问题。 ⟦AI:AUTO-LOOP⟧ |
|
测试视角结论: approve。 证据:
未发现新增 skip/manual、sleep pacing、断言弱化或 mock-only pseudo-coverage。 ⟦AI:AUTO-LOOP⟧ |
📊 review-gate MERGE — reject=0 approve=3,CLEAN。合并(完整 wakeup-plan 投影修复)。🤖 controller status banner |
* #471 hotfix: wakeup_plan completed-marker 投影按 open-managed 集过滤,closed/merged target 不投影(止血 graphql:消除 wakeup_runner 对已终结 target 的逐条重校验) * #410: SKILL/prompt 注释改引 durable contract anchor,不引用一次性 .refactor-loop/runs/*;新增 test_generated_artifacts_not_authority 窄 source-regression (#472) * #471 hotfix2: wakeup-plan 同一 target 只投影最新有效 marker,旧轮次不再投影 dispatchable action(止 graphql backoff 最后一刀) * skill: 强化 no-gap 规则 — 0 codex + active work 无观察模式豁免,必须当 turn 立即介入派 codex(+source-regression) * #470: direct-post prompt 渲染时 fixed-token 内联 _github-post-rules,host worktree cwd 可达(避免裸相对路径) (#479) * #478 hotfix: daemon spawn 改 launch-and-forget 独立 supervisor(start_new_session 不 wait),daemon reload 不丢 in-flight worker;daemon 每 tick 清晰状态行 * #471: wakeup-plan latest-open-fresh 投影 — completed-marker open-target/latest + release-rollup 仅 latest-per-sha 且 ahead>0 本地 ref 验证(止 stale 投影/graphql) (#482) * #481: consensus->implement readiness-dedup gate(止 daemon 重派 closed/has-PR/in-flight) (#486) * #481: consensus->implement readiness-dedup gate, closed/closing-PR/remote-branch/in-flight target 不投影 dispatchable, 止重复/race * #481 fix r1: dedup gate 复用 concurrency monitor owner surface 测量 in-flight,不重实现 daemon 算法(addr architect) * #481 fix r2: 补 controller helper guard behavior test(addr tests) * #485: consensus->implement 按 scope_paths 冲突分组串行(同组一个 executable,其余 status_only),复用 batching-heuristics,防并行冲突 PR (#489) * #475: wakeup-runner WakeupApplyBudget — spawn-worker action 按 hard_gate.dispatch_required 批量到 floor deficit(lifecycle action 仍 1/tick),修 1/tick 线性恢复 (#492) * hotfix(#475 ext): batch budget 纳入 dispatch_design_consensus —— solver triplet 一 tick 派齐(非 lifecycle,worker 派发),修 design-consensus 仍 1/tick 低并发 * hotfix: headless spawn-intent launch — skipped duplicate 不再 break 整批 spawn,stale applied ledger(log 缺失)可重试,helper_exit:3 加来源诊断事件;修 248 intent 堆积/0 并发 * hotfix r2: blocked lifecycle action 不再 dead-stop 整 tick — 跳过/抑制 stale blocked(close-drop target OPEN / publish 无 verified head)继续 launch 后续 spawn-batch,使 headless 并发拉到 floor * hotfix r3: 根治 headless 0 并发 — detached spawn-codex launch 显式传 env_for_subprocess(修 #478 decouple 丢 env 致 EXIT=127);失败 log(非0 EXIT)可重试 launch,EXIT=0/未完成仍抑制重复;tick 状态汇总后续 launch 不被首个 blocked 掩盖 * hotfix r4: run_once 通用 blocked-not-dead-stop — 任何 blocked/skipped non-spawn action 不再 dead-stop 整 tick,继续 launch 后续 spawn-batch;wakeup-plan 抑制 precondition 注定失败的 stale action;根治 headless 并发=0 * hotfix r5: wakeup-plan 投影侧 suppress stale close_managed_drop(target 实际 OPEN 的 drop-close 注定失败)为 status_only,不再占 tick 挡住后续 design-consensus spawn launch * hotfix r6: wakeup-runner run_once 不再把 no-intents 的 dispatch_design_consensus(helper_exit:3)误判为 codex launch failure dead-stop 整 tick 根因:dispatch_design_consensus 是 spawn-batch action;当 solver triplet 不完整(如 #496 minimal/structural EXIT=0 但未 emit SOLVER_DONE marker)时 helper 返回 exit 3(NO_INTENTS),_spawn_launch_failure 命中 "helper_exit:" 前缀判 True → run_once break,整 tick dead-stop,后续 reviewers/其他 design-consensus/implement 全部不派 → headless 并发=0。 修法:run_once 中 blocked 的 spawn-batch action 若 controller_action != spawn_codex_harness_background(即 dispatch_design_consensus),按 routing no-op skip-and-continue,继续 launch 后续 spawn-batch;仅真正 spawn_codex_harness_background launch failure 才走既有 retry/break。延续 r4 blocked-not-dead-stop 不变量到 design-consensus spawn-batch action。 behavior test: test_wakeup_runner_design_consensus_no_intents_does_not_dead_stop_later_spawn_batch(无修复时 later spawn 不 launch 而 FAIL)。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * hotfix r7: review head_sha binding — 打通 headless review→merge 自驱 根因:reviewer artifact frontmatter 不带 head_sha,_review_evidence_from_artifact 取不到所审 head SHA → 所有 reviewing PR(#480/#473/#402)恒判 WAIT_OR_REDISPATCH:invalid_reviewer_evidence:missing_reviewed_head_sha,且 wakeup-plan 不自动重派 reviewer → review→merge headless 永久卡死(挡住发版)。 修法(codex hotfix worker 实现,controller 验证后提交): - controller_actions 派 reviewer 时取 headRefOid,缺则 fail-closed,注入权威 HEAD_SHA 进 rendered prompt。 - reviewer-{architect,tests,quality}.md frontmatter 写 head_sha: ${HEAD_SHA}。 - wakeup_runner._review_head_sha_for:artifact 缺 head_sha 时从 controller-rendered prompt/log 回收(不依赖 worker 自报,避免 markerless 覆辙);live-head 陈旧判定与 merge 真值表语义不变。 - wakeup_plan 为 missing/stale reviewer head 的 OPEN reviewing PR 投射可执行 dispatch_reviewers 自愈动作。 验证:controller 独立重跑 test_wakeup_runner+review_gate+wakeup_plan+controller_actions 293 通过、marker/prompt 合同 30 通过;review-gate 安全语义(stale head 仍不 merge)由 13 项 review-gate 测试锁住。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * hotfix r8: 让 review-evidence-redispatch 自愈动作可执行 — 打通 headless review→merge 闭环 承接 r7:r7 让 reviewer 证据绑定 head_sha,但 wakeup_plan 投射的 review-evidence-redispatch 自愈动作被 closed-action-projection finalizer 强制 status_only(其 kind 不在 EXECUTABLE_ACTION_KINDS),runner 永不应用 → #480/#473/#402 缺 head 的 review 证据无法自动重派 → review_gate 恒 WAIT_OR_REDISPATCH → 并发耗干到 0。 修法(codex hotfix worker 实现,controller 验证后提交): - wakeup_plan EXECUTABLE_ACTION_KINDS 加 review-evidence-redispatch,finalizer 保留 runner authority 不再强制 status_only。 - controller_actions.dispatch_reviewers 读 stale_review_roles 只重派陈旧角色,且 _pending_review_spawn_exists 跳过已有在飞 dispatch-reviewers:<pr>:<role>:r1 intent(幂等不双派);仍走 r7 的 HEAD_SHA 注入,使重派 reviewer 的新证据 head-bound。 - merge-gate 真值表不变,仅让既有自愈动作可执行 + 定向到陈旧角色。 验证:controller 独立重跑 test_wakeup_plan+wakeup_runner+review_gate+controller_actions 295 通过。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * hotfix r9: reviewer 重派 bump 到下一轮 + 绝对 cd + latest-evidence-per-role — 真正打通 headless review→merge 根因(同一类:按"产物存在"而非"成功+区分维度"抑制):reviewer 重派硬编码回 r1,撞上旧 head 早先成功(EXIT=0)的 r1 log → _harness_spawn_intent_log_suppresses_retry 判"做过了"抑制 → 当前 head 该重跑的 review 永不跑 → review_gate 恒 WAIT_OR_REDISPATCH → 并发 0。且 intent cd 是相对 "." → headless 启动层不投射。 最小修法(按 maintainer directive:文件名即唯一 id,不加 wrapper --id,留在现有 r<R> 命名约定内不改公开命名): - controller_actions.dispatch_reviewers:_next_review_round 取该 PR/role 现有最大轮 +1,渲染 r<N+1> 的 prompt/log/output/intent;pending-spawn 幂等 guard 按真实轮号;_append_harness_spawn_intent 的 cd 改 str(cd.resolve()) 绝对路径,使 headless 投射+启动成立。 - wakeup_plan.latest_reviewer_heads / wakeup_runner._latest_review_evidence_by_role:改为"每 role 取各自最新轮证据"(而非全局最新单轮),使只重派陈旧 role 时不丢其它 role 已 head-bound 的有效证据;merge 仍要求每 role 证据绑定 live head,安全语义不变。 验证:controller 独立重跑 test_wakeup_plan+wakeup_runner+review_gate+controller_actions 299 通过。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * hotfix r10: review_gate action 带上 reviewed head_sha + e2e 锁死 headless review→decision 全路 根因(review path head_sha 串接的第 5 处):wakeup_plan 投影 REVIEW_DONE 的 review_gate action 时只读 log 的 head(log 无 head)→ action.head_sha 空 → wakeup_runner._review_gate 卡 WAIT_OR_REDISPATCH:missing_action_reviewed_head_sha,证据虽已 head-bound 但 gate 连比都没法比。 修法(最小、按文件名即 id 思路): - wakeup_plan.completed_marker_actions:REVIEW_DONE action 的 head_sha 改由 _review_done_action_head_sha 从权威证据面解析(latest_reviewer_heads 含 r7 prompt 注入的 head;或全 role head-bound 时取 live PR head;否则回落 log)。只从真实来源填充,不绕过 gate 的 head 比对,merge 安全语义不变。 - 新增 test_review_gate_e2e.py:从真实 wakeup_plan 投影 → WakeupRunner apply,断言 FIX(有 reject)与 MERGE(全 approve+CI 绿)两条具体决策落地——端到端锁死整条 review→decision,杜绝再冒隐藏层。 - test_wakeup_plan.py:加 prompt-bound reviewed head 的 planner 回归。 验证:controller 独立重跑 test_wakeup_plan+wakeup_runner+review_gate+controller_actions+review_gate_e2e 302 通过。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * hotfix r11: PrChecksProjection 对瞬时 gh-api 失败加 bounded retry — ready PR headless 走到 review_gate 决策 根因:review_gate 的 CI 读 PrChecksProjection.check_pr 对 gh api pulls/<n> 与 commits/<sha>/check-runs 的单次非零返回立即 fail-closed(ci_unavailable:pull_api_failure),无重试;rate limit 健康,实为瞬时 blip → 让 #473/#402(MERGEABLE+CI 绿)每 tick 被瞬时失败挡住、never reach MERGE/FIX。 修法(最小,只动 PrChecksProjection;不碰 #322 ReleaseRequiredChecksProjection): - _run_api_read:对两处 api read 最多 3 次确定性重试(无 sleep),成功即停,持续失败仍 fail-closed(安全)。happy path 无行为变化。 - starvation 结论(worker 核实):review_gate 本就被 apply,blocked ci_unavailable 行可重评估(非 terminal duplicate-suppressed),无需改 run_once。 - e2e:test_review_gate_e2e 加「首次 pulls 读瞬时失败仍 merge」用例;test_pr_checks 加 retry 覆盖。 验证:controller 独立重跑 test_pr_checks+wakeup_runner+review_gate+review_gate_e2e+wakeup_plan+controller_actions 309 通过。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * hotfix r12: run_once 不再让 spawn-batch starve drain-only lifecycle — ready PR headless merge,backlog 能 drain 根因(已核实):wakeup_plan 每 tick 把 SPAWN actions(implement intent + design-consensus #495/#496/#490/#491/#418,index 0-5)排在 lifecycle review_gate(#480/#473/#402,index 6-8)之前;run_once 旧逻辑 `if applied_spawns>0 and not is_spawn_action: break` → 只要派了任一 spawn,首个 lifecycle 即 break 整 tick。design-consensus 几乎总有 spawn 活 → review_gate/merge 永远 starve → #473(approve/approve/comment → MERGE_WITH_COMMENTS,MERGEABLE+CI 绿)永不 merge,active 数永不下降。 修法(最小,核心 dispatch loop): - 引入 consumes_spawn_budget = is_spawn_action or _uses_spawn_budget(action);超 budget 时 `continue`(不 break)以便仍能抵达后续 drain-only lifecycle。 - _uses_spawn_budget:dispatch_reviewers=True、review_gate 仅当决策为 FIX(会派 fix worker)=True;否则 review_gate(MERGE/MERGE_WITH_COMMENTS)、close 等 drain-only=False → 不占 spawn budget、floor 填满后仍被评估执行。 - 保留 r6 的 spawn launch-failure break/retry 与 dispatch_design_consensus no-intents skip-and-continue;真值表/head-binding/CI-green/mergeable 安全语义不变。 结果:每 tick 既用 spawn 填满 floor,又评估 merge/close 等 drain-only lifecycle,backlog 能 drain。 验证:controller 独立重跑 test_wakeup_runner+review_gate+review_gate_e2e+wakeup_plan+controller_actions+pr_checks 309 通过;新增 test_wakeup_runner_lifecycle_review_gate_not_starved_after_spawn_batch。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * hotfix r13: 修 WakeupRunner._run_command 把 --repo 注入到 gh 子命令前致全部 gh 调用 malformed — review→merge 根因 根因(实测确认):_run_command 对所有 gh 命令在 full[1:1] 插 --repo(子命令之前)。gh 不接受 --repo 作 pre-subcommand 全局 flag,且 gh api 根本不吃 --repo(repo 在 URL):`gh --repo O/R api repos/O/R/pulls/473` → rc=1 "unknown flag: --repo"。于是 wakeup-runner 的每个 gh 调用都 malformed:CI 读(PrChecksProjection(runner=_run_command) 的 gh api pulls/check-runs)→ ci_unavailable:pull_api_failure;mergeability(gh pr view)→ mergeability_unavailable;live-state 等同理。→ review gate 永远读不到 CI/mergeable → #473(approve/approve/comment=MERGE_WITH_COMMENTS,绿)、#402、#480 永不 headless 落地。r11 的 retry 只是重复同一 malformed 命令。直连 PrChecksProjection()/直连 gh 用的是 plain default runner(无注入)所以正常,掩盖了 bug。 最小修法:_run_command 仅对 `gh pr`/`gh issue` 注入 --repo,且放在子命令(及其 verb)之后的合法位置;`gh api` 完全不动;绝不 pre-subcommand 注入;已存在 --repo 则不重复。 验证:controller 独立重跑 test_wakeup_runner+review_gate+review_gate_e2e+pr_checks+wakeup_plan+controller_actions 312 通过;新增 argv-shape 测试 + e2e(stub subprocess.run 拒绝 malformed `gh --repo ... api`,ready PR 仍 merge)。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * hotfix r14: managed draft PR ready-then-merge — review gate 不再硬挡 pr_draft 根因(r13 修好 gh 调用后浮现):review_gate 的 _review_gate_mergeability_error 把 isDraft=True 当 WAIT_OR_REDISPATCH:pr_draft 硬挡。但本 loop draft-until-consensus:PR 开为 draft 直到 review 共识,merge_pr 在决策 MERGE/MERGE_WITH_COMMENTS 时 ready-then-merge。于是绿 gate 的 managed draft(如 #473 approve/approve/comment)永远卡 pr_draft、永不 headless 落地。 最小修法: - wakeup_runner:删除 mergeability 检查里的 isDraft→pr_draft 硬挡(仍挡 mergeable!=MERGEABLE,即 CONFLICTING/DIRTY)。 - controller_actions.merge_pr:对 live draft PR 先校验 crnd:lifecycle:managed 再 gh pr ready(非 managed draft 不 ready,写 CONTROLLER_ACTION_BLOCKED:target-not-managed 并返回 2);保留既有 ready-then-merge。 - 真值表/head-binding/CI-green/conflicting-blocks 安全语义不变;readying 仅限 managed PR。 验证:controller 独立重跑 test_wakeup_runner+review_gate+review_gate_e2e+controller_actions+wakeup_plan+pr_checks 316 通过;新增 managed-draft merge + 真实 plan→runner→controller ready-then-merge e2e + conflicting/非managed 安全用例。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * #409: 移除 .refactor-loop/host.env runtime fallback,CONSENSUS_RND_HOST_ENV 为唯一 host fact locator(缺失 fail-closed);迁移依赖 legacy fallback 的 test fixture (#473) * hotfix r15 (sshx 共识 B 之一): 统一 gh argv 构造到单一 build_gh_argv helper — 防 r13 类 --repo bug 复发 sshx 一致共识 B 的硬化第1步:把分散重复的 gh --repo 处理收口到 codex_refactor_loop/gh_invoke.py 的 build_gh_argv(slug, argv):gh api 永不加 --repo(repo 在 URL);gh pr/issue 仅在 subcommand 之后、缺失时加 --repo <slug>;绝不 pre-subcommand。wakeup_runner._run_command / ControllerActions.gh / PrChecksProjection 三处 API 调用全部改走该 helper,删除各自的内联 --repo 启发式。行为保持不变(含 r13 修复)。 验证:characterization + source-regression 锁在 test_gh_invoke.py(9 测试);controller 独立重跑 test_gh_invoke+pr_checks+wakeup_runner+review_gate+review_gate_e2e+controller_actions+wakeup_plan 326 通过;pr_checks 直跑 --help 兼容。 注:这是硬化(防复发),不直接提升并发;并发瓶颈在上游 implement→publish 阶段,接下来单独处理。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * hotfix r16 (sshx 共识): 打通 implement→publish 解锁并发瓶颈 — markerless/stale implement 重派 + 安全门控发布 sshx codex-cli triplet 共识(minimal/structural/delete + meta-judge):10 个 design-solving issue 已达成共识但卡在 implement→publish(implement 早跑过却 markerless/未提交/过期 base/没 PR;dispatch_consensus_implementation 被 local_iter_branch 抑制、publish 被 verified_pr_head_unavailable 抑制)→ 无新可派工作 → 并发 ~1。 修法(wakeup_plan/wakeup_runner/controller_actions/git.py): - success-aware 重派:implement 分支/worktree 存在但无 valid clean IMPLEMENT_DONE:ok marker(markerless/failed)或 base 过期 → 重派;fresh_safe_worktree 把 canonical worktree reset/recreate 到当前 origin/$INTEGRATION_BRANCH;仅 genuine in-flight / 已有干净 PR / 待发布 clean marker 才抑制。 - 发布门控(严防误发 stale/wrong-scope):publish_implementation_output 仅在 canonical identity(refactor/iter<issue>-<candidate> + worktree 实际分支匹配)+ fresh integration base(merge-base==origin/integration,过期 base block)+ managed open issue + 无重复 PR + 非空 scoped diff 时,commit→push→open PR→派 reviewers;否则 block。 - wakeup_plan 用 canonical_implementation_identity/single_linked_managed_issue/clean_scoped_diff 替代 verified_pr_head 抑制。 验证:controller 独立重跑 wakeup_plan+wakeup_runner+review_gate+review_gate_e2e+controller_actions+pr_checks+gh_invoke 330 通过。 已知待修(follow-up):worker 把 PR title/body/commit 文案改成英文,违反「GitHub artifact 中文」策略,下一 commit 恢复中文。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * hotfix r17: fresh consensus-implement 重派前清除 terminal 非可发布 implement log — 让卡住的 implement 真正启动 承接 r16:r16 让 markerless/stale implement 重派(reset worktree),但旧的 EXIT=1/markerless implement log 仍占 spawn 的 target_log_absent 前置 → fresh implement 不启动(同一类「按存在抑制」,implement-spawn-log 层)。 修法(controller_actions,success-aware):fresh consensus-implementation dispatch 写 spawn intent 前,仅清除 terminal 非可发布 implement log(EXIT!=0 失败 / EXIT=0 无 IMPLEMENT_DONE:ok marker);保留 genuinely in-flight(无 EXIT)与 clean publish-ready(EXIT=0 + 干净 marker)log 不动。于是卡住的 markerless/failed implement 重派后能真正 launch、跑在 fresh base、产出干净 marker → r16 门控发布。 验证:controller 独立重跑 wakeup_plan+wakeup_runner+review_gate+review_gate_e2e+controller_actions+pr_checks+gh_invoke 333 通过。 设计说明:并发瓶颈用确定性逻辑修对(ready=clean EXIT=0+marker;parallel=scope_paths 不相交),不引入 LLM-in-loop 分发判断(daemon-first;sshx codex 三人组一致 revise:LLM 最多 shadow-mode,不入决策回路)。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * hotfix r18: implement-lifecycle 收敛为单一 success-aware 谓词 + runner 路径自清陈旧 log — headless 自愈,不再需手动清 log 承接 r16/r17(r17 把清 log 放进被抑制的 dispatch 路径,从没执行)。新增 implement_lifecycle.py 单一事实源 classify_implement_attempt → in_flight | publish_ready | redispatch,plan/runner/controller 共用: - runner spawn-apply 路径 _spawn_log_suppresses_retry 仅在 in_flight|publish_ready 时抑制;redispatch(EXIT!=0/markerless/stale-base) 不抑制且 _clear_redispatchable_spawn_log 在 spawn 实际应用处清掉陈旧终态 log → fresh implement 真启动(修 r17 misplacement,免手动清)。 - publish 仅 publish_ready(clean IMPLEMENT_DONE:ok + canonical identity + fresh base + 非空 scoped diff);clean-marker 但 stale-base 改 redispatch 而非死锁(#421 edge)。 - 确定性逻辑(非 LLM-in-loop;daemon-first);merge-gate/#191/#322/#396 安全语义不变。 验证:controller 独立重跑 wakeup_plan+wakeup_runner+review_gate+review_gate_e2e+controller_actions+pr_checks+gh_invoke 339 通过。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * 修复 phase9-router triplet-evidence-invalid 误判致 headless design-consensus wedge solver prompt 注入的 issue source snapshot 含上一轮 design-consensus 的 audit-trail(peer solver log 路径)时,_peer_solver_reference_violation 扫描整个 prompt 误判为 peer-isolation 违规,fail-closed 拒派 meta-judge, 使所有 body 含历史 consensus 记录的 issue 永久 wedge。 修复:peer-isolation 扫描只覆盖 router-controlled 区域,剥离 '## Issue source snapshot' 到 '## Full solver template' 之间的 issue 作者内容;router header / solver template 注入的真实 peer 引用仍拦截。 加两个 behavior test 覆盖 snapshot-排除 与 router-区域-仍拦截。 dogfood headless 实测:reload 后 418/437/474/490/491/493/494/495 全部 恢复 solver→judge→consensus 自驱,#494 已自驱到 implement。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * CLAUDE.md: 加 consensus-rnd:foundational-invariants sentinel block dogfood bootstrap 的 check-project-rules probe 要求 PROJECT_RULES 含此 fixed-point block;缺失时 probe fail-closed 阻断 headless restart。内容 为 probe 生成的 canonical FI-001~007,镜像既有设计哲学,不引入新约束。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * 修复 markerless implement 致 publish 卡死的 headless gap implement worker 干净退出(EXIT=0)但把 IMPLEMENT_DONE marker 只写进 run artifact(runs/implement-issue-<id>.md)而非 log 末尾时(codex stdout marker 落点不可靠),completed_marker_actions 只扫 log marker → markerless → 不生成 publish action → design→implement→PR 链卡在 implement 后。实测 #421:EXIT=0 + artifact 有 IMPLEMENT_DONE:issue-421:ok + 9 文件 staged,却无 PR、label 仍 停在 design-solving。 修复:对 clean-exit 的 implement-issue log,log markerless 时 fallback 读取 run artifact 末尾的 IMPLEMENT_DONE marker,复用 review verdict 已有的 artifact-first 模式。窄作用域(仅 implement-issue + clean-exit),配 2 个 behavior test;全套 wakeup_plan 138 tests green。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * 补全 markerless implement publish:revalidation 也读 run artifact marker 8aeea89 修了 wakeup_plan detection 端,但 wakeup-runner 的 source-marker revalidation(_source_log_has_clean_marker)仍只扫 log,markerless implement publish 仍被 reject(clean_exit_marker_missing)。补全:revalidation 对 clean-exit implement-issue log 在 log markerless 时 fallback 读 runs/implement-issue-<id>.md 的 marker,与 detection 端一致;配 behavior test, 全套 wakeup_runner 76 tests green。 注:dogfood 实测确认 markerless 是系统性病根(还影响 readiness 重派、review verdict 等多处),应走系统性统一(见 #491 日志/observability 与后续 marker-reading 收口);本 commit 只补 implement publish 这条链。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * 日志详细化:wakeup-runner tick 显示全状态计数 + 被掩盖的 blocked/skipped 详情 旧 _wakeup_tick_action 只看 results[0],一个 tick 处理多 action 时 blocked(如 publish 失败)被成功的 spawn 掩盖、完全不可见;graphql-backoff 固定显示误导的 'remaining=unknown'。dogfood 调试时这逼得每次翻 ledger 才知道真实发生了什么。 改:tick log 显示 [applied=N,blocked=M,...] 全状态计数 + 被掩盖的 blocked/skipped 具体 reason+action(graphql-backoff 作整-tick 门控单独报、去掉 unknown);dispatched headline 保留。更新 test 反映可见性提升,全套 wakeup_runner 76 tests green。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * 补全 markerless implement 第三环:readiness 谓词读 run artifact marker classify_implement_attempt(r18 单一 success-aware 谓词)只扫 log 找 IMPLEMENT_DONE:ok,markerless log(marker 落 artifact)→ redispatch:markerless → readiness 不 suppress → 重派覆盖已完成工作(dogfood 实测 #421 重派 4 次、#493 IMPLEMENT_DONE:ok→重派→:partial 工作丢失)。 补全:markerless log 时 fallback 读 runs/implement-<cluster>.md 的 IMPLEMENT_DONE:ok,与 detection(8aeea89)/revalidation(dfacc64)一致。窄作用域 + r17/r18 兼容:只接受 :ok,partial/失败/真 markerless(无 artifact)仍 redispatch recovery — 现有 markerless-redispatch test(wakeup_plan/wakeup_runner/ controller_actions 共 304 tests)全绿,新增 2 behavior test。 至此 implement→PR 的 markerless 三环(detection/revalidation/readiness)打通; review 链 markerless 与系统性统一抽象交 #499 共识。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * #500: design-consensus 编排重设计 — phase9-router 唯一派发 owner,删 wakeup-runner 双重派发 落地 #500 r4 consensus(structural framing,no-new-schema): - phase9-router 成为唯一 design-consensus worker intent owner,新增 META_RESOLVED:re-design → marker.round+1 三路 solver route - 删除 wakeup-runner 的 dispatch_design_consensus(消除双重派发 helper_exit:3) - wakeup-runner 只保留 closed action apply(drop→close、consensus→implement) - dispatch_consensus_implementation readiness 后转 crnd:phase:implementing - 无新增 schema(复用 HARNESS_SPAWN_INTENT) 修复 headless P0:reflector META_RESOLVED 无 consumer + phase9-router/wakeup-runner 双重派发致 0-codex 死锁。14 文件 +207/-282;verification 471 tests 全绿。 共识由 controller 手动驱动 design-consensus r1→r4 达成(daemon 停止期间)。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * #501 fix r1: 补 dispatch_consensus_implementation label-transition failure-branch test tests reviewer reject:新增 label transition(gh issue edit→implementing)只测 success path,缺 gh issue edit 返回 nonzero 时 dispatch stop before worktree/render/intent 的 failure-branch test。本 fix 补该测试。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * 修复 headless 死锁:label 移除集只留 canonical crnd:*,删除历史 alias gh issue/pr edit --remove-label 会因仓库不存在的 label 整条 rc=1 失败。 ISSUE_LABELS_REMOVE/PR_LABELS_REMOVE 含 cleanup_aliases(emoji/legacy 名), 仓库未维护这些历史 label,导致 _move_issue_to_implementing_phase 永久失败, consensus→implement 派发卡死、wakeup_runner 0 codex 自驱死锁。 按 maintainer 指令删除历史 label 兼容(不再管历史标签):移除集只列 canonical crnd:* phase/human/stuck label。新增 source-regression 锁定 两集 canonical-only、无 alias。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * 修复 #500 回归:phase9-router 生产 ctx 丢失 GH_REPO_SLUG 致 design-consensus intake 全死 #500(e733b1a)把 Phase9Router.__init__ 的 ctx 构造从 `LoopContext.load(repo_root=repo_root)` 改成 `LoopContext.load(repo_root=repo_root, env={"REPO_ROOT": str(repo_root)})`。 受限 env 不读 os.environ,使 daemon(经 source host.env 启动)的 ctx gh_repo_slug=None → `_open_design_consensus_issues` 第一行 fail-closed 返回 [] → DesignConsensusIssueIntake 静默永不派 → headless 无法为任何 issue 启动 design-consensus;`_require_open_source_issue` 也因无 slug 失败(marker route 如 #490 redesign 卡在 phase9-source-state-unavailable)。 修复:revert 为 `LoopContext.load(repo_root=repo_root)`,读进程环境解析 host facts。 测试一律用 `Phase9Router(ctx=...)` 显式 ctx,不依赖受限 env;新增回归测试锁定 生产 repo_root 构造路径解析 GH_REPO_SLUG。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * 加 STALE_REVIVAL_HOURS:>阈值未推进的 stuck implement 自动 re-trigger(env 可配,默认 3h) headless 下 partial/failed/markerless 的 implement log 会让已排队的 dispatch-consensus-implementation spawn intent 永久卡在 runner 的 target_log_absent 前置(清 log 的 dispatch_consensus_implementation 又被 pending_implement_intent 抑制)→ stuck implement 不会自愈(如 #421/494/493/474/498 的 10h partial-wedge)。 新增 host-tunable STALE_REVIVAL_HOURS(默认 3,非正/非法回落 3h)。wakeup_plan 投影 implement spawn intent 时,若目标 implement log 是 redispatchable (partial/failed/markerless/stale-base)且 mtime 已超阈值,清掉它 → target_log_absent 通过 → implement 自动重派。安全闸:in-flight(无终止 EXIT)永不清、 publish-ready(:ok+diff)不清、age-gate 防误清刚跑完的。 env 已登记进 SKILL.md host env surface matrix + host.env.example;5 个 behavior test + matrix↔example 对称测试覆盖。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * 扩展 stale-revival 覆盖死 codex:in_flight 无 EXIT 且 >阈值 + 不在存活清单 也 re-trigger 最常见的 headless wedge 是 codex/supervisor 中途死亡(如 daemon 被 kill 截断), log 永远停在 in_flight(无终止 EXIT)→ classify 永判 in_flight → 永不 redispatch。 之前只清 redispatchable(partial/failed/markerless)log,漏了这半边。 现在 _revive_stale_redispatchable_implement_log 在 log mtime 超阈值时,先按 redispatchable 清;否则若 classify 为 in_flight 且 monitor 存活清单里无该 log 的 活进程,则判定为死 worker 清掉。安全性:spawn-codex 的 no-output stall 窗口远小于 默认 3h,故 >阈值仍 in_flight 的 log 必是死 supervisor;再加 monitor 存活校验 双保险,绝不杀活 codex。新增 3 个 behavior test(死 codex revive / fresh 不碰 / 活进程不碰)。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * 加手动 trigger:consensus-rnd-cli revive-implements(立即 re-trigger 卡住的 implement,不等阈值) _revive_stale_redispatchable_implement_log 加 force 参数:跳过 stale_revival_seconds() age gate,但 in_flight log 在 force 下必须经 monitor 存活校验证明无活进程才清(绝不杀 正在跑的 codex)。新增 force_revive_stuck_implements() 扫所有 implement-issue-*.log 强制 revive,和新 CLI 命令 revive-implements(authority delete-log)。auto 路径 force=False 不变。新增 4 个 behavior test。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * 修 env 泄漏:测试套件 import 时隔离 ambient host.env(worktree 里跑 TEST_CMD 不再假失败) daemon spawn 的 implement worker 在 worktree 里跑完整 TEST_CMD 时,继承的相对 CONSENSUS_RND_HOST_ENV=.config/consensus-rnd/host.env 泄漏进 temp-repo LoopContext.load(repo_root=tmp) → 解析成 tmp/.config/... 不存在 → 假 LoopContextError(实测 concurrency_monitor 48 + restart_daemons 23 + … ≈151 errors) → 全套永不绿 → implement 永远 :partial → 进不了 PR。 unittest discover 在 collection 阶段先 import 所有 test_*.py 再跑;新增 test_aaa_host_env_isolation.py(字母序最先)在 import 时 pop 掉 host 注入变量, 全套在任何测试 run 前即隔离。验证:full discover 设 locator 跑 → exit 0 全绿 (此前 同条件 151 errors);targeted before/after 证 48/23/1 errors → OK。 纯测试模块,不碰 production/daemon。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * 修 markerless keystone:solver/judge marker 加 companion-artifact fallback solver/judge codex 有时 EXIT=0 但 SOLVER_DONE/META_JUDGE_DONE marker 只落 run artifact、没在 log 末尾,导致 phase9-router 判 triplet 不完整、永不派 judge, design-consensus 轮卡死(实测 #505 r1 structural 214 次嵌入、0 次行首)。 把已有的 implement artifact-marker fallback 扩到 solver/judge:clean-exit log 末尾无独立 marker 时,从 companion run artifact runs/<log-stem>.md 兜底读。纯 additive(log 有 marker 时行为不变)、prefix-scoped、精确 filename regex、复用 安全的独立 marker 提取(不信嵌入/echo)。不削弱共识(仍要 3 marked solver + judge,只让 marker 来源更稳健)。phase9/router.py + wakeup_plan.py + behavior + source-regression tests;full suite 1367 green。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * 修 publish stale-base 无恢复 + 停 :ok churn:让 implementing 能发出 draft PR implement :ok 但 worktree base 落后 origin/$INTEGRATION_BRANCH 时,publish 原本硬 block(publish_implementation_stale_base)且永不恢复;stale-revival 又把 stale-base 的 :ok implement 当 redispatchable 反复重派同一 stale worktree → 无限 churn 占满 floor、长时间零正式 PR(implement→首个 PR 永远开不出)。 改为:publish 前在 worktree merge origin/$INTEGRATION_BRANCH 恢复 base(冲突则 merge --abort + 明确 reason 交既有 resolver/re-dispatch);clean `:ok` 不再被 stale-revival churn(终态成功走 publish-with-recovery,不重跑);无 open PR 的 :ok 创建 draft PR(per #300 共识前 draft)+ Closes #N。controller 仍拥有 git topology, worker 不 commit/push,不绕 review-gate/merge 真值表。controller_actions.py + wakeup_plan.py + wakeup_runner.py + behavior/source-regression tests;full suite 1374 green。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * 修 markerless implement:EXIT=0+真diff 无干净 marker 时合成 publish 候选,止 stale-revival 空重派死循环 publish build/test 闸做安全网。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * 修 publish 顺序 bug + merge 失败派 codex 兜底 resolver:先 commit worker diff 再 merge fresh base,真冲突不 wedge 改派 resolver,幂等续跑 空判据改 git diff HEAD;顺带修 wakeup_plan stale-suppression 同类 git diff 问题。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * 实现 issue #504 (#519) * 修 headless review-fix prompt 渲染不全:绑定全部 placeholder(PR_NUMBER/标题/轮次/分支/REVIEW_*_PATH 等),解锁 reject PR 的 fix→merge 之前 headless _dispatch_review_fix 只绑 FIX_OUTPUT_PATH,其余 ${} 未解析致 fix codex 读不到 reject 证据。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * 实现 issue #496 (#520) * 修 review-fix codex 派到 main 的 cd bug:改在 PR worktree 跑,worktree 缺失 fail-closed 之前 _dispatch_review_fix cd=repo_root → fix 改 main(污染 daemon checkout)且不落 PR 分支(reject PR 永不 merge)。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * 实现 issue #508 (#523) * 修 wakeup-plan action 排序:review_gate/publish 排到新工作 spawn 前,解 spawn-budget 饿死→reject PR 可被 fix→merge Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * CLAUDE.md 加宪法工程规则:异常必抛出+记可诊断日志严禁吞掉/静默;测试必断言真实行为禁无意义测试(maintainer 指令) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * 实现 issue #503 (#521) * 增加通用工程基本规则,明确面向对象设计要求及实现细则 * 实现 issue #514 (#524) * 完善通用面向对象设计准则,增加核心原则与实现层细则 * 实现 issue #494 (#526) * 实现 issue #517 (#528) * 实现 issue #505 (#510) * 实现 issue #505 * #510 fix r1:补 phase9-router 行为测试覆盖(应对 tests reviewer reject) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * 修复 headless FIX_DONE 不提交 fix 输出 gap:wakeup-runner 在 FIX_DONE re-review 前先 commit+push fix worktree headless 下 fix codex 产出 FIX_DONE 但 worker 从不 commit,FIX_DONE 直接路由 dispatch_reviewers, fix 输出永远留在 worktree 未提交,reviewers 永远审旧 head,reject 不收敛,阻断所有需 fix 轮的 PR review→merge。镜像 interactive controller:FIX_DONE 源的 dispatch_reviewers 前,若 fix worktree dirty 则 git add+commit+safe_push,clean 则 no-op。附 2 个 behavior test(dirty 提交/clean 跳过)。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * 实现 issue #491 (#531) * 实现 issue #490 (#529) * 实现 issue #490 * 实现 issue #490 * PR #529 review-fix output * 实现 issue #499 (#512) * 实现 issue #499 * PR #512 review-fix output * 实现 issue #474 (#532) * 实现 issue #474 * 实现 issue #474 * 实现 issue #474 * 实现 issue #474 * PR #532 review-fix output * 实现 issue #476 (#518) * 实现 issue #476 * PR #518 review-fix output * 实现 issue #509 (#527) * 实现 issue #509 * 实现 issue #509 * spawn-claim recycle 改用 artifact-aware terminal marker:companion log 被 24h retention 删除后,已完成任务的 claim 仍可回收(读 runs/ artifact),不再永久阻断重派;running 任务无终止 marker 仍不回收(防 double-spawn) * 实现 issue #421:发行前 clean-room 集成测试制度 (#534) * 实现 issue #421 * rebase #421 onto fresh integration:解决 test_cli_command_router 冲突 + 校验 * 实现 issue #493:测试纪律修宪(behavior-first) (#535) * 实现 issue #493 * rebase #493 onto fresh integration:解决冲突 + 校验 * PR #535 review-fix r1:addressed tests+quality reject(behavior-first test 调整) * 实现 issue #506 (#536) * 实现 issue #506 * 实现 issue #506 * 实现 issue #506 * 实现 issue #506 * PR #536 review-fix output * churn 根治:wakeup-plan 给 consensus-impl spawn-intent 套 open_closing_pr/terminal/in-flight 抑制(对齐 dispatch_consensus_implementation),已有 PR 的 issue 不再被重派 implement * 实现 issue #507 (#525) * 实现 issue #507 * 实现 issue #507 * PR #525 review-fix output * 实现 issue #516 (#530) * 实现 issue #516 * 实现 issue #516 * #530 fix r1:补 ManagedWorkSnapshot fetch-failure stale-cache fallback 行为测试(应对 tests reviewer reject) * PR #530 review-fix output * PR #530 review-fix r2:typed ManagedWorkItem projection(addresses architect 类型边界 reject + tests + contract-tests) * PR #530 review-fix r3:anchor ManagedWorkSnapshot read surface in authorization mirror + cross-artifact source-regression(addresses architect governance reject) * PR #530 review-fix r4:add canonical+legacy managed-label discovery regression test(addresses tests reject) * 修复 worker marker reader 误判相同重复 marker 为冲突 codex 常把终止 marker 回显 2-3 次(含 diff + 前缀行),导致 read_worker_terminal_marker 返回 duplicate_or_conflicting,review 真值表 永不收敛、所有 headless review→merge 卡死。改为:相同重复 marker 折叠为 有效,仅当存在 2+ 个不同 marker 值才判 duplicate_or_conflicting。 覆盖 _last_final_marker / _sentinel_adjacent_marker / _marker_from_companion_artifact,保留 malformed 与 foreign-prefix 检测。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Reserve implementation PR for issue #537 (#540) ⟦AI:AUTO-LOOP⟧ * 实现 issue #511 (#522) * 实现 issue #511 * PR #522 review-fix output * PR #522 review-fix output * 移除误入 PR 的 .refactor-loop 运行 artifact(architect r8 reject) resolve-pr522-merge.md 是一次性合并解决 summary,属生成物,不应进 durable diff (CLAUDE.md「生成物不当事实源」)。解决说明保留在 commit message / PR body。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * 修复早期 PR reservation 崩溃(#511 回归,阻断所有 implement 派发) _reserve_implementation_pr 用 worker 富正文路径开 reservation PR,但该文件在 reservation 时尚不存在 → FileNotFoundError(未被 except RuntimeError 捕获)→ wakeup-runner tick 崩溃 → 任何 consensus issue 无法 implement → loop P0 wedge。 修复:reservation 前若 body 缺失则写占位正文(## issue #N 实现 + Closes + sentinel, publish 会拒占位逼 worker 产真正文);reservation 幂等(已有 open PR 直接返回; 已有 remote head 则 reset 到 integration + force-with-lease push);捕获 OSError。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Reserve implementation PR for issue #543 (#544) ⟦AI:AUTO-LOOP⟧ * Reserve implementation PR for issue #541 (#546) ⟦AI:AUTO-LOOP⟧ * revert early-PR reservation(#507):不再开空占位 PR,publish 出真内容才开 PR dispatch_consensus_implementation 不再 reserve/开 PR;publish_implementation_output 恢复 pre-#507 行为——implement 出非空 diff 才 commit+push+open_pr_with_label(用 worker 真 title/body,验证非占位);空 diff 不开 PR、不 merge、不关 issue。删除占位机制 (_reserve_implementation_pr / _placeholder_*),改 wakeup_plan/runner 的 early_pr_missing 投影。 根因:空占位 PR 被 reviewer 在 implement publish 前空合,假性关闭 #537/#541/#543。 全量套件 1496 passed。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * 实现 issue #542:删除 redispatch payload 冗余 head_sha (#547) 移除 review redispatch 的重复 head_sha payload * hotfix: stale consensus-implement intent 指向已删 worktree 不再 suppress fresh re-dispatch consensus_implementation_suppressed_reason 的 pending_implement_intent 分支增加 worktree 存在性 守卫(接入既有 _canonical_consensus_worktree_exists):仅当 stale pending intent 的 canonical worktree 仍存在时才 suppress。revert early-PR reservation(#507)后,#537/#541/#543 的 pending implement intent 指向已删除 worktree,旧逻辑 suppress fresh re-dispatch,而 wakeup-runner 不断把 stale intent spawn 进死 cd 致 os error 2 / EXIT=1 死循环,阻断 consensus→implement 自主链路。 现 worktree 缺失即放行 fresh dispatch 重建 worktree。 补 test_wakeup_plan(worktree 缺失不 suppress / worktree 存在仍 suppress)+ 更新 test_controller_actions 锁旧行为的 subTest(pending case 建 canonical worktree 以保留 reject-before-fresh_safe_worktree 意图)。全套件 1557 passed。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * hotfix: spawn-claim lock 持有者 pid 已死即可回收(自愈,防 cleared-log 永久 HELD) _existing_claim_is_recyclable 增加 pid-liveness 回退:当 lock 记录的持有者 pid 已死(os.kill pid 0 抛 ProcessLookupError)时即可回收,保留既有 terminal-marker 回收与 live-spawn 保护 (pid 存活+无 marker 仍不回收)+ metadata-mismatch fail-closed。根因:implement 失败(EXIT=1) 留 stale lock,dispatch_consensus_implementation 重派时清掉 log → #490 spawn-claim 只在 log 有 EXIT= 时回收 → cleared log 无 marker → 死进程 lock 无法回收 → SPAWN_CLAIM_HELD 永久死锁, 阻断 consensus→implement 重派(#537/#541/#543)。补 7 个 behavior test。全套件 1560 passed。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * hotfix: publish_implementation_output 接受 worker 已 commit 的实现 diff _require_publish_implementation_diff 之前只看 git diff HEAD --quiet(未提交改动), worker 一旦自己 commit(在自己分支上,隔离无害)工作区就 clean → 误判 no_diff → 不开 PR。 现改为:有未提交改动 OR HEAD 相对 integration base 有 committed delta(merge-base..HEAD 非空) 即视为有 diff 可发;_commit_publish_implementation_diff 在工作区已 clean(worker 已 commit)时 跳过提交返回成功,不再误报 publish_commit_failed。修 #541 类 worker-commit→no_diff→无 PR+ daemon 重复 dispatch。补 behavior test。codex 全套件 DISCOVER_STATUS:0 通过。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * 实现 issue #437: .refactor-loop 历史生成物与陈旧 worktree 的有界清理机制 (#548) * #437: 新增 canonical RuntimeRetention owner,log-retention 降为一版 alias;清理覆盖 generated files+pending-events compaction+stale worktree;CLAUDE.md 加 #437 narrow carveout * PR #548 review-fix output * PR #548 review-fix output * PR #548 review-fix output * PR #548 review-fix output * PR #548 review-fix output * hotfix: CONFLICTING managed review PR 的 stale-base 冲突自主 resolve 接线既有但孤儿的 prompts/rebase-resolve.md 进 headless 路径:managed review PR mergeable=CONFLICTING(base 落后)时,controller 在 PR worktree 起 git merge --no-commit --no-ff origin/<integration>——干净则直接 commit+push,有冲突则派 rebase-resolve codex(隔离 worktree 内解+stage,禁 commit/push),收到 REBASE_RESOLVE_DONE 后 controller commit + safe_push 仅推 PR head。结果再过 CI+ review-gate 把关。新增 dispatch_pr_rebase_resolve / commit_push_resolved_pr_rebase (controller_actions)+ wakeup_plan 投影 + wakeup_runner 应用。 安全:只动 refactor/iter<N>-* PR 分支,显式 guard 拒碰 integration/review_base, diff-filter=U 验未解冲突才 commit,任何 abort 路径 git merge --abort 留干净 worktree, 幂等(已含 base / 解析在飞则 NOOP)。修 stale-base churn 致 loop 永久停滞(一个 PR 合了其它全 CONFLICTING 无人解)的根因。codex 全套件 1589 passed。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * hotfix: rebase_resolve_actions 投影前 enrich live mergeability(修生产 gap) 自主-resolve 投影读 item.mergeable 前未 enrich,但生产 GhItem 来自 snapshot mergeable 为空 → 永远 skip → CONFLICTING PR 不投影 dispatch_pr_rebase_resolve → loop 仍停滞。复用同文件 _with_live_mergeability(review_evidence_redispatch_actions 已用同模式)。补 mergeable-为空-需-live-fetch 的回归测试(原测试 mock 了 mergeable 未覆盖此生产路径)。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * hotfix: dispatch_pr_rebase_resolve kind 进 EXECUTABLE_ACTION_KINDS(end-to-end 可执行) _close_projection_action 的 else 分支默认 status_only=True;rebase action 的 kind stale-base-conflicting-pr 不在 EXECUTABLE_ACTION_KINDS → 永远 status_only,runner 不 apply,CONFLICTING PR 永不自主 resolve。加该 kind(+ commit_push completion kind 如需) 进集合;controller_action 已在 RUNNER_NAMED_HELPER_ACTIONS 故随即保持 executable。补 端到端 wakeup-plan pipeline 测试(原测试只测 rebase_resolve_actions 单函数,漏了 closed- action-projection 的 status_only 关卡)。codex 全套件 1593 passed。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * hotfix: rebase-resolve commit/dispatch 投影 gate 在实际 worktree merge 态(止 stale-marker 噪音) commit_push_resolved_pr_rebase 之前只凭持久 REBASE_RESOLVE_DONE marker 投影,worktree 已 commit+push(#549)或 abort(#550/#551)后 marker 仍在 → 每 tick fail-closed 噪音 + 反复 0-codex(zero_streak 触警)+ stale marker 挡 #550/#551 fresh resolve。现 gate:仅当 worktree 真有 merge-in-progress(MERGE_HEAD)且无 unmerged 才投 executable commit_push; 否则不投。并让 worktree clean + 仍 CONFLICTING 的 PR 重新拿 executable dispatch_pr_rebase_resolve (stale DONE marker 不再永久压制)。补端到端测试。codex 全套件通过。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * 实现 issue #502: 删除遗留 label 兼容层:purge emoji/legacy alias 全套(cleanup_aliases / per-spec (#549) * 实现 issue #502: 删除遗留 label 兼容层:purge emoji/legacy alias 全套(cleanup_aliases / per-spec * 修复 PR #549 review r3:#502 label-purge 适配当前 label 代码(contract-tests + architect/tests reject) fix codex round-3 applied-4:对齐 #502 遗留 label 兼容层 purge 与近期新增 label 代码, 修 contract-tests 失败 + architect/tests reject。改 labels.py + SKILL.md + test_wakeup_plan.py。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * 修复 headless review_gate ci_failed 死锁:reject→FIX 移到 ci/mergeability 检查前 _review_gate_decision 之前 ci_error/mergeability 检查在 reject>0→FIX 之前 → CI 红的 PR 即使 reviewer reject 也返回 WAIT_OR_REDISPATCH:ci_failed 干等,而 CI 不修不会绿 → 死锁 (#548/#549 都中,需手动派 fix 破解)。把 reject>0→FIX 移到 ci/mergeability 检查前 (仍在 reviewer-validity/head 检查之后)→ reject 时即使 CI 红也自主派 fix(fix 同解 reject+CI)。 MERGE/MERGE_WITH_COMMENTS 判定完全不变(仍需 ci-green + mergeable + reject=0 + approve>=1), 无误合并风险。补 test_wakeup_runner 端到端测试(reject+ci-red→FIX;reject=0+ci-red 仍 WAIT; happy path MERGE 不变;stale-head+reject 仍 WAIT)。full suite 1600 passed。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * 修正 review_gate 顺序:mergeability 检查移到 reject→FIX 之前(CONFLICTING 不并发 review/fix) 上一修复(a125d19)把 reject→FIX 移到 ci+mergeability 前,破了 ci_failed 死锁但也让 CONFLICTING+reject 的 PR 路由到 FIX → 与独立的 dispatch_pr_rebase_resolve 并发跑同一 worktree(#550 出现 98-file mid-merge + reviewer 并发)。把 mergeability_error 检查移到 reject→FIX 之前:CONFLICTING→WAIT(先 rebase-resolve,不并发 review/fix);MERGEABLE+ CI红+reject→FIX(死锁修复保留);ci_error 仍在 reject→FIX 后(纯 CI 红无 reject 才 WAIT)。 MERGE 判定不变。test_wakeup_runner 90 OK(+conflicting 用例)。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * 实现 issue #498: headless daemon fail-closed 点的 codex 兜底裁决/生成机制(narrow allowlist,非通用 es (#550) * 实现 issue #498 * 实现 issue #498: headless daemon fail-closed 点的 codex 兜底裁决/生成机制(narrow allowlist,非通用 es * PR #550 review-fix output * 新增 patrol-inspector 巡检 issue intake (#551) * 实现 issue #541 * PR #551 review-fix output * PR #551 review-fix output * 修复 PR #551 contract-tests:对齐 patrol 第8 daemon + safe_push/sync_dev 测试 host.env #551 patrol 新增 patrol_inspector_daemon(第8 daemon)→ test_anti_stop_restart 期望 7→8; test_controller_lib_safe_push / test_sync_dev 补 CONSENSUS_RND_HOST_ENV host.env 设置 (代码按 host-config contract 需 host.env locator,rebase-resolve 丢了 base 新测试版本)。 断言未削弱(daemon 数断言强化为8)。full discovery 1634 OK + sshx 13 OK。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * 修复 PR #551 contract-tests(clean-env):e2e fixture 设 META_ESCALATION_STUCK_HOURS 隔离 de-dup 测试 test_batch_and_per_task_lock_do_not_duplicate_spawn 在 clean env(CI)下失败:#506 meta- escalation 因 fixture mock 态被判 stuck 而 fire,产出 repository-stalled RunnerResult 污染 de-dup 断言(expected [] got [RunnerResult])。fixture host.env+env 设 META_ESCALATION_STUCK_ HOURS=999999 禁该测试的 meta-escalation,聚焦 de-dup 行为。断言未削弱。clean discovery 全过。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * 修复 publish-gap:implement readiness 用 git status --porcelain 判 staged diff 原 classify_implement_attempt / wakeup_runner publish 前用 git diff --quiet 只检测 unstaged 改动;worker 正确 git add -A 后 staged diff 被误判 empty_scoped_diff,导致完成的 implement (如 #553 干净 EXIT=0 + 885 行真实 staged diff + 有效 title/body artifacts)永远出不了 PR, wakeup_runner 对 children 反复空转 re-dispatch。改为先 git status --porcelain 判 staged/ unstaged/untracked 任一即 publish-ready,只有真干净才 fallback git diff。publish-time 建 PR 路径不变(不重蹈 #507 early-PR 空 commit/placeholder 死锁)。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * 修复 patrol_inspector daemon 启动崩溃:DaemonHeartbeatLease 用构造函数非 from_env #551 patrol.py daemon 分支调 DaemonHeartbeatLease.from_env()(不存在的方法)→ AttributeError 启动即崩,daemon 从未成功跑起来。改为 DaemonHeartbeatLease( "patrol_inspector_daemon", ctx.repo_root),与 closed_label_reconciler/wakeup_runner 一致,心跳文件名匹配 restart 助手期待的 patrol_inspector_daemon.ts。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * 修复 publish-gap 残留层:duplicate-marker log 读 companion artifact + 取代 superseded spawn intent 层2 残留:implement worker 把 IMPLEMENT_DONE:issue-N:ok 在 log 里 echo 多次→ worker_markers 返回 duplicate_or_conflicting_log_marker fail-closed→classifier 当 markerless 且不查 companion artifact→无 completed-marker action→无 publish→stale harness-spawn-intent:dispatch-consensus-implementation:N 残留致 pending_implement_intent。 修:(1) classify_implement_attempt / completed_marker_actions 遇 duplicate marker 时 narrow 读 companion .refactor-loop/runs/implement-*.md(仅 implement log,仅末 30 行恰好 1 个 IMPLEMENT_DONE:ok 才接受);(2) suppress_publish_superseded_implementation_spawn_intents: 仅当某 issue 已有 executable publish_implementation_output 才把对应 dispatch-consensus- implementation spawn intent 抑制为 status_only(implementation_ready_to_publish)。 不重蹈 #507 死锁:只在 publish 已 ready 后抑制 spawn(不漏派)、publish 仍全验证(不提前/ 重复)、wakeup-runner/publish 授权口径不变。live 验证 #553 现投影 executable publish。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * 实现 issue #555 (#557) * 修复 publish-gap 第3层:wakeup_runner clean_exit revalidation 对 duplicate-marker log 复用 artifact-fallback pubgap2 修了 plan 侧 duplicate-marker artifact-fallback,但 wakeup_runner 的 _source_log_has_clean_marker(clean_exit_source_marker 预条件 revalidation)仍用严格 reader,对 #553 duplicate IMPLEMENT_DONE echo 返回 clean_exit_marker_missing→阻 publish。 改为严格 reader 优先,仅当 duplicate_or_conflicting_log_marker + is_implement_log + _implement_run_artifact_done_marker 精确匹配 projected marker 才 fallback。复用 plan 侧 同一 helper,不弱化安全门(reviewer/release/rebase/非 implement/其它 fail reason 保持严格)。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * 接 dispatch_remote_ci_fix 进 wakeup_runner:pipeline 自主修 ci-red(#396 内) children review 通过但 contract-tests 红(改 restart/supervisor daemon 却没同步本地 TEST_CMD 屏蔽的 daemon-count 测试),wakeup_runner 缺 dispatch_remote_ci_fix 实现致 ci-red 永 status_only 不自主修。镜像既有 dispatch_reviewers + review-fix commit-push: 每失败 check 派一个 remote-ci-fix.md worker(无 commit 权),REMOTE_CI_FIX_DONE:<check>:ok 后 controller safe_push 推,:infra/:blocked 留 maintainer。durable retry cap=2 per pr:head_sha:check(state/remote-ci-fix-attempts.json),超限 RETRY_CAP 停。在 #396 'dispatch remote-ci worker' 口径内,worker 无 lifecycle/commit 权,无新授权。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * 修复 wakeup_runner 单 helper 失败饿死全 tick:仅直接 spawn launch 失败才 break run_once 对任何 spawn-budget blocked 且 reason 含 helper_exit:* 就 break 整 tick。rollup PR #560(head rollup/<sha> 无 worktree)的 review-fix helper_exit:3(WORKTREE_MISSING)→ break → 饿死 #558/#561 的独立 ci-red 派发,致 runner ~30min noop 0 派发(0 codex)。 改为:仅直接 spawn_codex_harness_background launch 失败(is_spawn_action + _spawn_launch_failure) 才停扫描;blocked named helper(review_gate FIX / dispatch_remote_ci_fix)记录后 continue, 让同 tick 后面独立 PR 的 action 仍被处理。单 PR helper 失败不再阻塞全局派发。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * 收紧无人唤醒与大 issue 分解授权测试 (#559) * 实现 issue #556 * 实现 issue #556 * PR #559 review-fix output * 修复 identical-duplicate terminal marker 被误判 conflicting:reader 容忍相同重复 remote-ci-fix worker echo REMOTE_CI_FIX_DONE:check:ok 两次→read_worker_terminal_marker 返回 duplicate_or_conflicting→runner 读不到→不 commit worker fix→撞 retry cap,#558 卡。 根因修(worker_markers._sentinel_adjacent_marker):无 sentinel-adjacent 但 tail 有 2+ standalone marker 全 identical 时返回该 marker。一次修 implement/ci-fix/未来所有 marker。 不弱化 conflicting:不同 marker 仍 fail,malformed 仍 fail,单非终止 marker 仍不终止。 不扩 #396;wakeup_runner 仍 revalidate clean_exit_source_marker 才 commit/push。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * rollup PR 自主化(maintainer-directive 2026-06-06):singleton + CI-only + 详细 body + auto-squash-merge 实现 maintainer 指令「rollup 只要ci过了就可以,不用review...绿了自动squash...默认自动,在env可配,只开一个rollup」: - Singleton:已有 open rollup(head rollup/ + base review-base)时 force-with-lease 更新其 head 到当前 integration SHA + 刷新 title/body;无则才新建,不增殖。 - CI-only:rollup PR 排除出 reviewer/review-fix/remote-ci-fix dispatch(不走 cluster 3-reviewer gate)。 - 详细 title/body:integration 领先 review-base 的 commit 数 + 范围 + commit 摘要(中文经 hex 编码守 source-EN-only)。 - Auto-squash-merge:host.env ROLLUP_AUTO_MERGE(默认 auto;manual 则等人工)。owner-gated + 仅 rollup PR narrow allowlist + exact-SHA required checks 全绿硬 gate(ReleaseRequiredChecksProjection)→ gh pr merge --squash --delete-branch;分支保护/host-policy 失败→WAIT 留人工不 force。所有失败写诊断 pending event。 - 授权双锚定:runtime-exceptions.md#rollup-autonomous-merge-2026-06-06 + SKILL.md + host.env surface matrix; durable artifact = maintainer-directives/2026-06-06。source-regression + behavior test 全覆盖。回归 1619 passed。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* #471 hotfix: wakeup_plan completed-marker 投影按 open-managed 集过滤,closed/merged target 不投影(止血 graphql:消除 wakeup_runner 对已终结 target 的逐条重校验) * #410: SKILL/prompt 注释改引 durable contract anchor,不引用一次性 .refactor-loop/runs/*;新增 test_generated_artifacts_not_authority 窄 source-regression (#472) * #471 hotfix2: wakeup-plan 同一 target 只投影最新有效 marker,旧轮次不再投影 dispatchable action(止 graphql backoff 最后一刀) * skill: 强化 no-gap 规则 — 0 codex + active work 无观察模式豁免,必须当 turn 立即介入派 codex(+source-regression) * #470: direct-post prompt 渲染时 fixed-token 内联 _github-post-rules,host worktree cwd 可达(避免裸相对路径) (#479) * #478 hotfix: daemon spawn 改 launch-and-forget 独立 supervisor(start_new_session 不 wait),daemon reload 不丢 in-flight worker;daemon 每 tick 清晰状态行 * #471: wakeup-plan latest-open-fresh 投影 — completed-marker open-target/latest + release-rollup 仅 latest-per-sha 且 ahead>0 本地 ref 验证(止 stale 投影/graphql) (#482) * #481: consensus->implement readiness-dedup gate(止 daemon 重派 closed/has-PR/in-flight) (#486) * #481: consensus->implement readiness-dedup gate, closed/closing-PR/remote-branch/in-flight target 不投影 dispatchable, 止重复/race * #481 fix r1: dedup gate 复用 concurrency monitor owner surface 测量 in-flight,不重实现 daemon 算法(addr architect) * #481 fix r2: 补 controller helper guard behavior test(addr tests) * #485: consensus->implement 按 scope_paths 冲突分组串行(同组一个 executable,其余 status_only),复用 batching-heuristics,防并行冲突 PR (#489) * #475: wakeup-runner WakeupApplyBudget — spawn-worker action 按 hard_gate.dispatch_required 批量到 floor deficit(lifecycle action 仍 1/tick),修 1/tick 线性恢复 (#492) * hotfix(#475 ext): batch budget 纳入 dispatch_design_consensus —— solver triplet 一 tick 派齐(非 lifecycle,worker 派发),修 design-consensus 仍 1/tick 低并发 * hotfix: headless spawn-intent launch — skipped duplicate 不再 break 整批 spawn,stale applied ledger(log 缺失)可重试,helper_exit:3 加来源诊断事件;修 248 intent 堆积/0 并发 * hotfix r2: blocked lifecycle action 不再 dead-stop 整 tick — 跳过/抑制 stale blocked(close-drop target OPEN / publish 无 verified head)继续 launch 后续 spawn-batch,使 headless 并发拉到 floor * hotfix r3: 根治 headless 0 并发 — detached spawn-codex launch 显式传 env_for_subprocess(修 #478 decouple 丢 env 致 EXIT=127);失败 log(非0 EXIT)可重试 launch,EXIT=0/未完成仍抑制重复;tick 状态汇总后续 launch 不被首个 blocked 掩盖 * hotfix r4: run_once 通用 blocked-not-dead-stop — 任何 blocked/skipped non-spawn action 不再 dead-stop 整 tick,继续 launch 后续 spawn-batch;wakeup-plan 抑制 precondition 注定失败的 stale action;根治 headless 并发=0 * hotfix r5: wakeup-plan 投影侧 suppress stale close_managed_drop(target 实际 OPEN 的 drop-close 注定失败)为 status_only,不再占 tick 挡住后续 design-consensus spawn launch * hotfix r6: wakeup-runner run_once 不再把 no-intents 的 dispatch_design_consensus(helper_exit:3)误判为 codex launch failure dead-stop 整 tick 根因:dispatch_design_consensus 是 spawn-batch action;当 solver triplet 不完整(如 #496 minimal/structural EXIT=0 但未 emit SOLVER_DONE marker)时 helper 返回 exit 3(NO_INTENTS),_spawn_launch_failure 命中 "helper_exit:" 前缀判 True → run_once break,整 tick dead-stop,后续 reviewers/其他 design-consensus/implement 全部不派 → headless 并发=0。 修法:run_once 中 blocked 的 spawn-batch action 若 controller_action != spawn_codex_harness_background(即 dispatch_design_consensus),按 routing no-op skip-and-continue,继续 launch 后续 spawn-batch;仅真正 spawn_codex_harness_background launch failure 才走既有 retry/break。延续 r4 blocked-not-dead-stop 不变量到 design-consensus spawn-batch action。 behavior test: test_wakeup_runner_design_consensus_no_intents_does_not_dead_stop_later_spawn_batch(无修复时 later spawn 不 launch 而 FAIL)。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * hotfix r7: review head_sha binding — 打通 headless review→merge 自驱 根因:reviewer artifact frontmatter 不带 head_sha,_review_evidence_from_artifact 取不到所审 head SHA → 所有 reviewing PR(#480/#473/#402)恒判 WAIT_OR_REDISPATCH:invalid_reviewer_evidence:missing_reviewed_head_sha,且 wakeup-plan 不自动重派 reviewer → review→merge headless 永久卡死(挡住发版)。 修法(codex hotfix worker 实现,controller 验证后提交): - controller_actions 派 reviewer 时取 headRefOid,缺则 fail-closed,注入权威 HEAD_SHA 进 rendered prompt。 - reviewer-{architect,tests,quality}.md frontmatter 写 head_sha: ${HEAD_SHA}。 - wakeup_runner._review_head_sha_for:artifact 缺 head_sha 时从 controller-rendered prompt/log 回收(不依赖 worker 自报,避免 markerless 覆辙);live-head 陈旧判定与 merge 真值表语义不变。 - wakeup_plan 为 missing/stale reviewer head 的 OPEN reviewing PR 投射可执行 dispatch_reviewers 自愈动作。 验证:controller 独立重跑 test_wakeup_runner+review_gate+wakeup_plan+controller_actions 293 通过、marker/prompt 合同 30 通过;review-gate 安全语义(stale head 仍不 merge)由 13 项 review-gate 测试锁住。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * hotfix r8: 让 review-evidence-redispatch 自愈动作可执行 — 打通 headless review→merge 闭环 承接 r7:r7 让 reviewer 证据绑定 head_sha,但 wakeup_plan 投射的 review-evidence-redispatch 自愈动作被 closed-action-projection finalizer 强制 status_only(其 kind 不在 EXECUTABLE_ACTION_KINDS),runner 永不应用 → #480/#473/#402 缺 head 的 review 证据无法自动重派 → review_gate 恒 WAIT_OR_REDISPATCH → 并发耗干到 0。 修法(codex hotfix worker 实现,controller 验证后提交): - wakeup_plan EXECUTABLE_ACTION_KINDS 加 review-evidence-redispatch,finalizer 保留 runner authority 不再强制 status_only。 - controller_actions.dispatch_reviewers 读 stale_review_roles 只重派陈旧角色,且 _pending_review_spawn_exists 跳过已有在飞 dispatch-reviewers:<pr>:<role>:r1 intent(幂等不双派);仍走 r7 的 HEAD_SHA 注入,使重派 reviewer 的新证据 head-bound。 - merge-gate 真值表不变,仅让既有自愈动作可执行 + 定向到陈旧角色。 验证:controller 独立重跑 test_wakeup_plan+wakeup_runner+review_gate+controller_actions 295 通过。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * hotfix r9: reviewer 重派 bump 到下一轮 + 绝对 cd + latest-evidence-per-role — 真正打通 headless review→merge 根因(同一类:按"产物存在"而非"成功+区分维度"抑制):reviewer 重派硬编码回 r1,撞上旧 head 早先成功(EXIT=0)的 r1 log → _harness_spawn_intent_log_suppresses_retry 判"做过了"抑制 → 当前 head 该重跑的 review 永不跑 → review_gate 恒 WAIT_OR_REDISPATCH → 并发 0。且 intent cd 是相对 "." → headless 启动层不投射。 最小修法(按 maintainer directive:文件名即唯一 id,不加 wrapper --id,留在现有 r<R> 命名约定内不改公开命名): - controller_actions.dispatch_reviewers:_next_review_round 取该 PR/role 现有最大轮 +1,渲染 r<N+1> 的 prompt/log/output/intent;pending-spawn 幂等 guard 按真实轮号;_append_harness_spawn_intent 的 cd 改 str(cd.resolve()) 绝对路径,使 headless 投射+启动成立。 - wakeup_plan.latest_reviewer_heads / wakeup_runner._latest_review_evidence_by_role:改为"每 role 取各自最新轮证据"(而非全局最新单轮),使只重派陈旧 role 时不丢其它 role 已 head-bound 的有效证据;merge 仍要求每 role 证据绑定 live head,安全语义不变。 验证:controller 独立重跑 test_wakeup_plan+wakeup_runner+review_gate+controller_actions 299 通过。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * hotfix r10: review_gate action 带上 reviewed head_sha + e2e 锁死 headless review→decision 全路 根因(review path head_sha 串接的第 5 处):wakeup_plan 投影 REVIEW_DONE 的 review_gate action 时只读 log 的 head(log 无 head)→ action.head_sha 空 → wakeup_runner._review_gate 卡 WAIT_OR_REDISPATCH:missing_action_reviewed_head_sha,证据虽已 head-bound 但 gate 连比都没法比。 修法(最小、按文件名即 id 思路): - wakeup_plan.completed_marker_actions:REVIEW_DONE action 的 head_sha 改由 _review_done_action_head_sha 从权威证据面解析(latest_reviewer_heads 含 r7 prompt 注入的 head;或全 role head-bound 时取 live PR head;否则回落 log)。只从真实来源填充,不绕过 gate 的 head 比对,merge 安全语义不变。 - 新增 test_review_gate_e2e.py:从真实 wakeup_plan 投影 → WakeupRunner apply,断言 FIX(有 reject)与 MERGE(全 approve+CI 绿)两条具体决策落地——端到端锁死整条 review→decision,杜绝再冒隐藏层。 - test_wakeup_plan.py:加 prompt-bound reviewed head 的 planner 回归。 验证:controller 独立重跑 test_wakeup_plan+wakeup_runner+review_gate+controller_actions+review_gate_e2e 302 通过。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * hotfix r11: PrChecksProjection 对瞬时 gh-api 失败加 bounded retry — ready PR headless 走到 review_gate 决策 根因:review_gate 的 CI 读 PrChecksProjection.check_pr 对 gh api pulls/<n> 与 commits/<sha>/check-runs 的单次非零返回立即 fail-closed(ci_unavailable:pull_api_failure),无重试;rate limit 健康,实为瞬时 blip → 让 #473/#402(MERGEABLE+CI 绿)每 tick 被瞬时失败挡住、never reach MERGE/FIX。 修法(最小,只动 PrChecksProjection;不碰 #322 ReleaseRequiredChecksProjection): - _run_api_read:对两处 api read 最多 3 次确定性重试(无 sleep),成功即停,持续失败仍 fail-closed(安全)。happy path 无行为变化。 - starvation 结论(worker 核实):review_gate 本就被 apply,blocked ci_unavailable 行可重评估(非 terminal duplicate-suppressed),无需改 run_once。 - e2e:test_review_gate_e2e 加「首次 pulls 读瞬时失败仍 merge」用例;test_pr_checks 加 retry 覆盖。 验证:controller 独立重跑 test_pr_checks+wakeup_runner+review_gate+review_gate_e2e+wakeup_plan+controller_actions 309 通过。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * hotfix r12: run_once 不再让 spawn-batch starve drain-only lifecycle — ready PR headless merge,backlog 能 drain 根因(已核实):wakeup_plan 每 tick 把 SPAWN actions(implement intent + design-consensus #495/#496/#490/#491/#418,index 0-5)排在 lifecycle review_gate(#480/#473/#402,index 6-8)之前;run_once 旧逻辑 `if applied_spawns>0 and not is_spawn_action: break` → 只要派了任一 spawn,首个 lifecycle 即 break 整 tick。design-consensus 几乎总有 spawn 活 → review_gate/merge 永远 starve → #473(approve/approve/comment → MERGE_WITH_COMMENTS,MERGEABLE+CI 绿)永不 merge,active 数永不下降。 修法(最小,核心 dispatch loop): - 引入 consumes_spawn_budget = is_spawn_action or _uses_spawn_budget(action);超 budget 时 `continue`(不 break)以便仍能抵达后续 drain-only lifecycle。 - _uses_spawn_budget:dispatch_reviewers=True、review_gate 仅当决策为 FIX(会派 fix worker)=True;否则 review_gate(MERGE/MERGE_WITH_COMMENTS)、close 等 drain-only=False → 不占 spawn budget、floor 填满后仍被评估执行。 - 保留 r6 的 spawn launch-failure break/retry 与 dispatch_design_consensus no-intents skip-and-continue;真值表/head-binding/CI-green/mergeable 安全语义不变。 结果:每 tick 既用 spawn 填满 floor,又评估 merge/close 等 drain-only lifecycle,backlog 能 drain。 验证:controller 独立重跑 test_wakeup_runner+review_gate+review_gate_e2e+wakeup_plan+controller_actions+pr_checks 309 通过;新增 test_wakeup_runner_lifecycle_review_gate_not_starved_after_spawn_batch。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * hotfix r13: 修 WakeupRunner._run_command 把 --repo 注入到 gh 子命令前致全部 gh 调用 malformed — review→merge 根因 根因(实测确认):_run_command 对所有 gh 命令在 full[1:1] 插 --repo(子命令之前)。gh 不接受 --repo 作 pre-subcommand 全局 flag,且 gh api 根本不吃 --repo(repo 在 URL):`gh --repo O/R api repos/O/R/pulls/473` → rc=1 "unknown flag: --repo"。于是 wakeup-runner 的每个 gh 调用都 malformed:CI 读(PrChecksProjection(runner=_run_command) 的 gh api pulls/check-runs)→ ci_unavailable:pull_api_failure;mergeability(gh pr view)→ mergeability_unavailable;live-state 等同理。→ review gate 永远读不到 CI/mergeable → #473(approve/approve/comment=MERGE_WITH_COMMENTS,绿)、#402、#480 永不 headless 落地。r11 的 retry 只是重复同一 malformed 命令。直连 PrChecksProjection()/直连 gh 用的是 plain default runner(无注入)所以正常,掩盖了 bug。 最小修法:_run_command 仅对 `gh pr`/`gh issue` 注入 --repo,且放在子命令(及其 verb)之后的合法位置;`gh api` 完全不动;绝不 pre-subcommand 注入;已存在 --repo 则不重复。 验证:controller 独立重跑 test_wakeup_runner+review_gate+review_gate_e2e+pr_checks+wakeup_plan+controller_actions 312 通过;新增 argv-shape 测试 + e2e(stub subprocess.run 拒绝 malformed `gh --repo ... api`,ready PR 仍 merge)。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * hotfix r14: managed draft PR ready-then-merge — review gate 不再硬挡 pr_draft 根因(r13 修好 gh 调用后浮现):review_gate 的 _review_gate_mergeability_error 把 isDraft=True 当 WAIT_OR_REDISPATCH:pr_draft 硬挡。但本 loop draft-until-consensus:PR 开为 draft 直到 review 共识,merge_pr 在决策 MERGE/MERGE_WITH_COMMENTS 时 ready-then-merge。于是绿 gate 的 managed draft(如 #473 approve/approve/comment)永远卡 pr_draft、永不 headless 落地。 最小修法: - wakeup_runner:删除 mergeability 检查里的 isDraft→pr_draft 硬挡(仍挡 mergeable!=MERGEABLE,即 CONFLICTING/DIRTY)。 - controller_actions.merge_pr:对 live draft PR 先校验 crnd:lifecycle:managed 再 gh pr ready(非 managed draft 不 ready,写 CONTROLLER_ACTION_BLOCKED:target-not-managed 并返回 2);保留既有 ready-then-merge。 - 真值表/head-binding/CI-green/conflicting-blocks 安全语义不变;readying 仅限 managed PR。 验证:controller 独立重跑 test_wakeup_runner+review_gate+review_gate_e2e+controller_actions+wakeup_plan+pr_checks 316 通过;新增 managed-draft merge + 真实 plan→runner→controller ready-then-merge e2e + conflicting/非managed 安全用例。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * #409: 移除 .refactor-loop/host.env runtime fallback,CONSENSUS_RND_HOST_ENV 为唯一 host fact locator(缺失 fail-closed);迁移依赖 legacy fallback 的 test fixture (#473) * hotfix r15 (sshx 共识 B 之一): 统一 gh argv 构造到单一 build_gh_argv helper — 防 r13 类 --repo bug 复发 sshx 一致共识 B 的硬化第1步:把分散重复的 gh --repo 处理收口到 codex_refactor_loop/gh_invoke.py 的 build_gh_argv(slug, argv):gh api 永不加 --repo(repo 在 URL);gh pr/issue 仅在 subcommand 之后、缺失时加 --repo <slug>;绝不 pre-subcommand。wakeup_runner._run_command / ControllerActions.gh / PrChecksProjection 三处 API 调用全部改走该 helper,删除各自的内联 --repo 启发式。行为保持不变(含 r13 修复)。 验证:characterization + source-regression 锁在 test_gh_invoke.py(9 测试);controller 独立重跑 test_gh_invoke+pr_checks+wakeup_runner+review_gate+review_gate_e2e+controller_actions+wakeup_plan 326 通过;pr_checks 直跑 --help 兼容。 注:这是硬化(防复发),不直接提升并发;并发瓶颈在上游 implement→publish 阶段,接下来单独处理。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * hotfix r16 (sshx 共识): 打通 implement→publish 解锁并发瓶颈 — markerless/stale implement 重派 + 安全门控发布 sshx codex-cli triplet 共识(minimal/structural/delete + meta-judge):10 个 design-solving issue 已达成共识但卡在 implement→publish(implement 早跑过却 markerless/未提交/过期 base/没 PR;dispatch_consensus_implementation 被 local_iter_branch 抑制、publish 被 verified_pr_head_unavailable 抑制)→ 无新可派工作 → 并发 ~1。 修法(wakeup_plan/wakeup_runner/controller_actions/git.py): - success-aware 重派:implement 分支/worktree 存在但无 valid clean IMPLEMENT_DONE:ok marker(markerless/failed)或 base 过期 → 重派;fresh_safe_worktree 把 canonical worktree reset/recreate 到当前 origin/$INTEGRATION_BRANCH;仅 genuine in-flight / 已有干净 PR / 待发布 clean marker 才抑制。 - 发布门控(严防误发 stale/wrong-scope):publish_implementation_output 仅在 canonical identity(refactor/iter<issue>-<candidate> + worktree 实际分支匹配)+ fresh integration base(merge-base==origin/integration,过期 base block)+ managed open issue + 无重复 PR + 非空 scoped diff 时,commit→push→open PR→派 reviewers;否则 block。 - wakeup_plan 用 canonical_implementation_identity/single_linked_managed_issue/clean_scoped_diff 替代 verified_pr_head 抑制。 验证:controller 独立重跑 wakeup_plan+wakeup_runner+review_gate+review_gate_e2e+controller_actions+pr_checks+gh_invoke 330 通过。 已知待修(follow-up):worker 把 PR title/body/commit 文案改成英文,违反「GitHub artifact 中文」策略,下一 commit 恢复中文。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * hotfix r17: fresh consensus-implement 重派前清除 terminal 非可发布 implement log — 让卡住的 implement 真正启动 承接 r16:r16 让 markerless/stale implement 重派(reset worktree),但旧的 EXIT=1/markerless implement log 仍占 spawn 的 target_log_absent 前置 → fresh implement 不启动(同一类「按存在抑制」,implement-spawn-log 层)。 修法(controller_actions,success-aware):fresh consensus-implementation dispatch 写 spawn intent 前,仅清除 terminal 非可发布 implement log(EXIT!=0 失败 / EXIT=0 无 IMPLEMENT_DONE:ok marker);保留 genuinely in-flight(无 EXIT)与 clean publish-ready(EXIT=0 + 干净 marker)log 不动。于是卡住的 markerless/failed implement 重派后能真正 launch、跑在 fresh base、产出干净 marker → r16 门控发布。 验证:controller 独立重跑 wakeup_plan+wakeup_runner+review_gate+review_gate_e2e+controller_actions+pr_checks+gh_invoke 333 通过。 设计说明:并发瓶颈用确定性逻辑修对(ready=clean EXIT=0+marker;parallel=scope_paths 不相交),不引入 LLM-in-loop 分发判断(daemon-first;sshx codex 三人组一致 revise:LLM 最多 shadow-mode,不入决策回路)。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * hotfix r18: implement-lifecycle 收敛为单一 success-aware 谓词 + runner 路径自清陈旧 log — headless 自愈,不再需手动清 log 承接 r16/r17(r17 把清 log 放进被抑制的 dispatch 路径,从没执行)。新增 implement_lifecycle.py 单一事实源 classify_implement_attempt → in_flight | publish_ready | redispatch,plan/runner/controller 共用: - runner spawn-apply 路径 _spawn_log_suppresses_retry 仅在 in_flight|publish_ready 时抑制;redispatch(EXIT!=0/markerless/stale-base) 不抑制且 _clear_redispatchable_spawn_log 在 spawn 实际应用处清掉陈旧终态 log → fresh implement 真启动(修 r17 misplacement,免手动清)。 - publish 仅 publish_ready(clean IMPLEMENT_DONE:ok + canonical identity + fresh base + 非空 scoped diff);clean-marker 但 stale-base 改 redispatch 而非死锁(#421 edge)。 - 确定性逻辑(非 LLM-in-loop;daemon-first);merge-gate/#191/#322/#396 安全语义不变。 验证:controller 独立重跑 wakeup_plan+wakeup_runner+review_gate+review_gate_e2e+controller_actions+pr_checks+gh_invoke 339 通过。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * 修复 phase9-router triplet-evidence-invalid 误判致 headless design-consensus wedge solver prompt 注入的 issue source snapshot 含上一轮 design-consensus 的 audit-trail(peer solver log 路径)时,_peer_solver_reference_violation 扫描整个 prompt 误判为 peer-isolation 违规,fail-closed 拒派 meta-judge, 使所有 body 含历史 consensus 记录的 issue 永久 wedge。 修复:peer-isolation 扫描只覆盖 router-controlled 区域,剥离 '## Issue source snapshot' 到 '## Full solver template' 之间的 issue 作者内容;router header / solver template 注入的真实 peer 引用仍拦截。 加两个 behavior test 覆盖 snapshot-排除 与 router-区域-仍拦截。 dogfood headless 实测:reload 后 418/437/474/490/491/493/494/495 全部 恢复 solver→judge→consensus 自驱,#494 已自驱到 implement。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * CLAUDE.md: 加 consensus-rnd:foundational-invariants sentinel block dogfood bootstrap 的 check-project-rules probe 要求 PROJECT_RULES 含此 fixed-point block;缺失时 probe fail-closed 阻断 headless restart。内容 为 probe 生成的 canonical FI-001~007,镜像既有设计哲学,不引入新约束。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * 修复 markerless implement 致 publish 卡死的 headless gap implement worker 干净退出(EXIT=0)但把 IMPLEMENT_DONE marker 只写进 run artifact(runs/implement-issue-<id>.md)而非 log 末尾时(codex stdout marker 落点不可靠),completed_marker_actions 只扫 log marker → markerless → 不生成 publish action → design→implement→PR 链卡在 implement 后。实测 #421:EXIT=0 + artifact 有 IMPLEMENT_DONE:issue-421:ok + 9 文件 staged,却无 PR、label 仍 停在 design-solving。 修复:对 clean-exit 的 implement-issue log,log markerless 时 fallback 读取 run artifact 末尾的 IMPLEMENT_DONE marker,复用 review verdict 已有的 artifact-first 模式。窄作用域(仅 implement-issue + clean-exit),配 2 个 behavior test;全套 wakeup_plan 138 tests green。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * 补全 markerless implement publish:revalidation 也读 run artifact marker 8aeea89 修了 wakeup_plan detection 端,但 wakeup-runner 的 source-marker revalidation(_source_log_has_clean_marker)仍只扫 log,markerless implement publish 仍被 reject(clean_exit_marker_missing)。补全:revalidation 对 clean-exit implement-issue log 在 log markerless 时 fallback 读 runs/implement-issue-<id>.md 的 marker,与 detection 端一致;配 behavior test, 全套 wakeup_runner 76 tests green。 注:dogfood 实测确认 markerless 是系统性病根(还影响 readiness 重派、review verdict 等多处),应走系统性统一(见 #491 日志/observability 与后续 marker-reading 收口);本 commit 只补 implement publish 这条链。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * 日志详细化:wakeup-runner tick 显示全状态计数 + 被掩盖的 blocked/skipped 详情 旧 _wakeup_tick_action 只看 results[0],一个 tick 处理多 action 时 blocked(如 publish 失败)被成功的 spawn 掩盖、完全不可见;graphql-backoff 固定显示误导的 'remaining=unknown'。dogfood 调试时这逼得每次翻 ledger 才知道真实发生了什么。 改:tick log 显示 [applied=N,blocked=M,...] 全状态计数 + 被掩盖的 blocked/skipped 具体 reason+action(graphql-backoff 作整-tick 门控单独报、去掉 unknown);dispatched headline 保留。更新 test 反映可见性提升,全套 wakeup_runner 76 tests green。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * 补全 markerless implement 第三环:readiness 谓词读 run artifact marker classify_implement_attempt(r18 单一 success-aware 谓词)只扫 log 找 IMPLEMENT_DONE:ok,markerless log(marker 落 artifact)→ redispatch:markerless → readiness 不 suppress → 重派覆盖已完成工作(dogfood 实测 #421 重派 4 次、#493 IMPLEMENT_DONE:ok→重派→:partial 工作丢失)。 补全:markerless log 时 fallback 读 runs/implement-<cluster>.md 的 IMPLEMENT_DONE:ok,与 detection(8aeea89)/revalidation(dfacc64)一致。窄作用域 + r17/r18 兼容:只接受 :ok,partial/失败/真 markerless(无 artifact)仍 redispatch recovery — 现有 markerless-redispatch test(wakeup_plan/wakeup_runner/ controller_actions 共 304 tests)全绿,新增 2 behavior test。 至此 implement→PR 的 markerless 三环(detection/revalidation/readiness)打通; review 链 markerless 与系统性统一抽象交 #499 共识。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * #500: design-consensus 编排重设计 — phase9-router 唯一派发 owner,删 wakeup-runner 双重派发 落地 #500 r4 consensus(structural framing,no-new-schema): - phase9-router 成为唯一 design-consensus worker intent owner,新增 META_RESOLVED:re-design → marker.round+1 三路 solver route - 删除 wakeup-runner 的 dispatch_design_consensus(消除双重派发 helper_exit:3) - wakeup-runner 只保留 closed action apply(drop→close、consensus→implement) - dispatch_consensus_implementation readiness 后转 crnd:phase:implementing - 无新增 schema(复用 HARNESS_SPAWN_INTENT) 修复 headless P0:reflector META_RESOLVED 无 consumer + phase9-router/wakeup-runner 双重派发致 0-codex 死锁。14 文件 +207/-282;verification 471 tests 全绿。 共识由 controller 手动驱动 design-consensus r1→r4 达成(daemon 停止期间)。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * #501 fix r1: 补 dispatch_consensus_implementation label-transition failure-branch test tests reviewer reject:新增 label transition(gh issue edit→implementing)只测 success path,缺 gh issue edit 返回 nonzero 时 dispatch stop before worktree/render/intent 的 failure-branch test。本 fix 补该测试。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * 修复 headless 死锁:label 移除集只留 canonical crnd:*,删除历史 alias gh issue/pr edit --remove-label 会因仓库不存在的 label 整条 rc=1 失败。 ISSUE_LABELS_REMOVE/PR_LABELS_REMOVE 含 cleanup_aliases(emoji/legacy 名), 仓库未维护这些历史 label,导致 _move_issue_to_implementing_phase 永久失败, consensus→implement 派发卡死、wakeup_runner 0 codex 自驱死锁。 按 maintainer 指令删除历史 label 兼容(不再管历史标签):移除集只列 canonical crnd:* phase/human/stuck label。新增 source-regression 锁定 两集 canonical-only、无 alias。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * 修复 #500 回归:phase9-router 生产 ctx 丢失 GH_REPO_SLUG 致 design-consensus intake 全死 #500(e733b1a)把 Phase9Router.__init__ 的 ctx 构造从 `LoopContext.load(repo_root=repo_root)` 改成 `LoopContext.load(repo_root=repo_root, env={"REPO_ROOT": str(repo_root)})`。 受限 env 不读 os.environ,使 daemon(经 source host.env 启动)的 ctx gh_repo_slug=None → `_open_design_consensus_issues` 第一行 fail-closed 返回 [] → DesignConsensusIssueIntake 静默永不派 → headless 无法为任何 issue 启动 design-consensus;`_require_open_source_issue` 也因无 slug 失败(marker route 如 #490 redesign 卡在 phase9-source-state-unavailable)。 修复:revert 为 `LoopContext.load(repo_root=repo_root)`,读进程环境解析 host facts。 测试一律用 `Phase9Router(ctx=...)` 显式 ctx,不依赖受限 env;新增回归测试锁定 生产 repo_root 构造路径解析 GH_REPO_SLUG。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * 加 STALE_REVIVAL_HOURS:>阈值未推进的 stuck implement 自动 re-trigger(env 可配,默认 3h) headless 下 partial/failed/markerless 的 implement log 会让已排队的 dispatch-consensus-implementation spawn intent 永久卡在 runner 的 target_log_absent 前置(清 log 的 dispatch_consensus_implementation 又被 pending_implement_intent 抑制)→ stuck implement 不会自愈(如 #421/494/493/474/498 的 10h partial-wedge)。 新增 host-tunable STALE_REVIVAL_HOURS(默认 3,非正/非法回落 3h)。wakeup_plan 投影 implement spawn intent 时,若目标 implement log 是 redispatchable (partial/failed/markerless/stale-base)且 mtime 已超阈值,清掉它 → target_log_absent 通过 → implement 自动重派。安全闸:in-flight(无终止 EXIT)永不清、 publish-ready(:ok+diff)不清、age-gate 防误清刚跑完的。 env 已登记进 SKILL.md host env surface matrix + host.env.example;5 个 behavior test + matrix↔example 对称测试覆盖。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * 扩展 stale-revival 覆盖死 codex:in_flight 无 EXIT 且 >阈值 + 不在存活清单 也 re-trigger 最常见的 headless wedge 是 codex/supervisor 中途死亡(如 daemon 被 kill 截断), log 永远停在 in_flight(无终止 EXIT)→ classify 永判 in_flight → 永不 redispatch。 之前只清 redispatchable(partial/failed/markerless)log,漏了这半边。 现在 _revive_stale_redispatchable_implement_log 在 log mtime 超阈值时,先按 redispatchable 清;否则若 classify 为 in_flight 且 monitor 存活清单里无该 log 的 活进程,则判定为死 worker 清掉。安全性:spawn-codex 的 no-output stall 窗口远小于 默认 3h,故 >阈值仍 in_flight 的 log 必是死 supervisor;再加 monitor 存活校验 双保险,绝不杀活 codex。新增 3 个 behavior test(死 codex revive / fresh 不碰 / 活进程不碰)。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * 加手动 trigger:consensus-rnd-cli revive-implements(立即 re-trigger 卡住的 implement,不等阈值) _revive_stale_redispatchable_implement_log 加 force 参数:跳过 stale_revival_seconds() age gate,但 in_flight log 在 force 下必须经 monitor 存活校验证明无活进程才清(绝不杀 正在跑的 codex)。新增 force_revive_stuck_implements() 扫所有 implement-issue-*.log 强制 revive,和新 CLI 命令 revive-implements(authority delete-log)。auto 路径 force=False 不变。新增 4 个 behavior test。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * 修 env 泄漏:测试套件 import 时隔离 ambient host.env(worktree 里跑 TEST_CMD 不再假失败) daemon spawn 的 implement worker 在 worktree 里跑完整 TEST_CMD 时,继承的相对 CONSENSUS_RND_HOST_ENV=.config/consensus-rnd/host.env 泄漏进 temp-repo LoopContext.load(repo_root=tmp) → 解析成 tmp/.config/... 不存在 → 假 LoopContextError(实测 concurrency_monitor 48 + restart_daemons 23 + … ≈151 errors) → 全套永不绿 → implement 永远 :partial → 进不了 PR。 unittest discover 在 collection 阶段先 import 所有 test_*.py 再跑;新增 test_aaa_host_env_isolation.py(字母序最先)在 import 时 pop 掉 host 注入变量, 全套在任何测试 run 前即隔离。验证:full discover 设 locator 跑 → exit 0 全绿 (此前 同条件 151 errors);targeted before/after 证 48/23/1 errors → OK。 纯测试模块,不碰 production/daemon。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * 修 markerless keystone:solver/judge marker 加 companion-artifact fallback solver/judge codex 有时 EXIT=0 但 SOLVER_DONE/META_JUDGE_DONE marker 只落 run artifact、没在 log 末尾,导致 phase9-router 判 triplet 不完整、永不派 judge, design-consensus 轮卡死(实测 #505 r1 structural 214 次嵌入、0 次行首)。 把已有的 implement artifact-marker fallback 扩到 solver/judge:clean-exit log 末尾无独立 marker 时,从 companion run artifact runs/<log-stem>.md 兜底读。纯 additive(log 有 marker 时行为不变)、prefix-scoped、精确 filename regex、复用 安全的独立 marker 提取(不信嵌入/echo)。不削弱共识(仍要 3 marked solver + judge,只让 marker 来源更稳健)。phase9/router.py + wakeup_plan.py + behavior + source-regression tests;full suite 1367 green。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * 修 publish stale-base 无恢复 + 停 :ok churn:让 implementing 能发出 draft PR implement :ok 但 worktree base 落后 origin/$INTEGRATION_BRANCH 时,publish 原本硬 block(publish_implementation_stale_base)且永不恢复;stale-revival 又把 stale-base 的 :ok implement 当 redispatchable 反复重派同一 stale worktree → 无限 churn 占满 floor、长时间零正式 PR(implement→首个 PR 永远开不出)。 改为:publish 前在 worktree merge origin/$INTEGRATION_BRANCH 恢复 base(冲突则 merge --abort + 明确 reason 交既有 resolver/re-dispatch);clean `:ok` 不再被 stale-revival churn(终态成功走 publish-with-recovery,不重跑);无 open PR 的 :ok 创建 draft PR(per #300 共识前 draft)+ Closes #N。controller 仍拥有 git topology, worker 不 commit/push,不绕 review-gate/merge 真值表。controller_actions.py + wakeup_plan.py + wakeup_runner.py + behavior/source-regression tests;full suite 1374 green。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * 修 markerless implement:EXIT=0+真diff 无干净 marker 时合成 publish 候选,止 stale-revival 空重派死循环 publish build/test 闸做安全网。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * 修 publish 顺序 bug + merge 失败派 codex 兜底 resolver:先 commit worker diff 再 merge fresh base,真冲突不 wedge 改派 resolver,幂等续跑 空判据改 git diff HEAD;顺带修 wakeup_plan stale-suppression 同类 git diff 问题。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * 实现 issue #504 (#519) * 修 headless review-fix prompt 渲染不全:绑定全部 placeholder(PR_NUMBER/标题/轮次/分支/REVIEW_*_PATH 等),解锁 reject PR 的 fix→merge 之前 headless _dispatch_review_fix 只绑 FIX_OUTPUT_PATH,其余 ${} 未解析致 fix codex 读不到 reject 证据。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * 实现 issue #496 (#520) * 修 review-fix codex 派到 main 的 cd bug:改在 PR worktree 跑,worktree 缺失 fail-closed 之前 _dispatch_review_fix cd=repo_root → fix 改 main(污染 daemon checkout)且不落 PR 分支(reject PR 永不 merge)。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * 实现 issue #508 (#523) * 修 wakeup-plan action 排序:review_gate/publish 排到新工作 spawn 前,解 spawn-budget 饿死→reject PR 可被 fix→merge Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * CLAUDE.md 加宪法工程规则:异常必抛出+记可诊断日志严禁吞掉/静默;测试必断言真实行为禁无意义测试(maintainer 指令) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * 实现 issue #503 (#521) * 增加通用工程基本规则,明确面向对象设计要求及实现细则 * 实现 issue #514 (#524) * 完善通用面向对象设计准则,增加核心原则与实现层细则 * 实现 issue #494 (#526) * 实现 issue #517 (#528) * 实现 issue #505 (#510) * 实现 issue #505 * #510 fix r1:补 phase9-router 行为测试覆盖(应对 tests reviewer reject) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * 修复 headless FIX_DONE 不提交 fix 输出 gap:wakeup-runner 在 FIX_DONE re-review 前先 commit+push fix worktree headless 下 fix codex 产出 FIX_DONE 但 worker 从不 commit,FIX_DONE 直接路由 dispatch_reviewers, fix 输出永远留在 worktree 未提交,reviewers 永远审旧 head,reject 不收敛,阻断所有需 fix 轮的 PR review→merge。镜像 interactive controller:FIX_DONE 源的 dispatch_reviewers 前,若 fix worktree dirty 则 git add+commit+safe_push,clean 则 no-op。附 2 个 behavior test(dirty 提交/clean 跳过)。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * 实现 issue #491 (#531) * 实现 issue #490 (#529) * 实现 issue #490 * 实现 issue #490 * PR #529 review-fix output * 实现 issue #499 (#512) * 实现 issue #499 * PR #512 review-fix output * 实现 issue #474 (#532) * 实现 issue #474 * 实现 issue #474 * 实现 issue #474 * 实现 issue #474 * PR #532 review-fix output * 实现 issue #476 (#518) * 实现 issue #476 * PR #518 review-fix output * 实现 issue #509 (#527) * 实现 issue #509 * 实现 issue #509 * spawn-claim recycle 改用 artifact-aware terminal marker:companion log 被 24h retention 删除后,已完成任务的 claim 仍可回收(读 runs/ artifact),不再永久阻断重派;running 任务无终止 marker 仍不回收(防 double-spawn) * 实现 issue #421:发行前 clean-room 集成测试制度 (#534) * 实现 issue #421 * rebase #421 onto fresh integration:解决 test_cli_command_router 冲突 + 校验 * 实现 issue #493:测试纪律修宪(behavior-first) (#535) * 实现 issue #493 * rebase #493 onto fresh integration:解决冲突 + 校验 * PR #535 review-fix r1:addressed tests+quality reject(behavior-first test 调整) * 实现 issue #506 (#536) * 实现 issue #506 * 实现 issue #506 * 实现 issue #506 * 实现 issue #506 * PR #536 review-fix output * churn 根治:wakeup-plan 给 consensus-impl spawn-intent 套 open_closing_pr/terminal/in-flight 抑制(对齐 dispatch_consensus_implementation),已有 PR 的 issue 不再被重派 implement * 实现 issue #507 (#525) * 实现 issue #507 * 实现 issue #507 * PR #525 review-fix output * 实现 issue #516 (#530) * 实现 issue #516 * 实现 issue #516 * #530 fix r1:补 ManagedWorkSnapshot fetch-failure stale-cache fallback 行为测试(应对 tests reviewer reject) * PR #530 review-fix output * PR #530 review-fix r2:typed ManagedWorkItem projection(addresses architect 类型边界 reject + tests + contract-tests) * PR #530 review-fix r3:anchor ManagedWorkSnapshot read surface in authorization mirror + cross-artifact source-regression(addresses architect governance reject) * PR #530 review-fix r4:add canonical+legacy managed-label discovery regression test(addresses tests reject) * 修复 worker marker reader 误判相同重复 marker 为冲突 codex 常把终止 marker 回显 2-3 次(含 diff + 前缀行),导致 read_worker_terminal_marker 返回 duplicate_or_conflicting,review 真值表 永不收敛、所有 headless review→merge 卡死。改为:相同重复 marker 折叠为 有效,仅当存在 2+ 个不同 marker 值才判 duplicate_or_conflicting。 覆盖 _last_final_marker / _sentinel_adjacent_marker / _marker_from_companion_artifact,保留 malformed 与 foreign-prefix 检测。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Reserve implementation PR for issue #537 (#540) ⟦AI:AUTO-LOOP⟧ * 实现 issue #511 (#522) * 实现 issue #511 * PR #522 review-fix output * PR #522 review-fix output * 移除误入 PR 的 .refactor-loop 运行 artifact(architect r8 reject) resolve-pr522-merge.md 是一次性合并解决 summary,属生成物,不应进 durable diff (CLAUDE.md「生成物不当事实源」)。解决说明保留在 commit message / PR body。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * 修复早期 PR reservation 崩溃(#511 回归,阻断所有 implement 派发) _reserve_implementation_pr 用 worker 富正文路径开 reservation PR,但该文件在 reservation 时尚不存在 → FileNotFoundError(未被 except RuntimeError 捕获)→ wakeup-runner tick 崩溃 → 任何 consensus issue 无法 implement → loop P0 wedge。 修复:reservation 前若 body 缺失则写占位正文(## issue #N 实现 + Closes + sentinel, publish 会拒占位逼 worker 产真正文);reservation 幂等(已有 open PR 直接返回; 已有 remote head 则 reset 到 integration + force-with-lease push);捕获 OSError。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Reserve implementation PR for issue #543 (#544) ⟦AI:AUTO-LOOP⟧ * Reserve implementation PR for issue #541 (#546) ⟦AI:AUTO-LOOP⟧ * revert early-PR reservation(#507):不再开空占位 PR,publish 出真内容才开 PR dispatch_consensus_implementation 不再 reserve/开 PR;publish_implementation_output 恢复 pre-#507 行为——implement 出非空 diff 才 commit+push+open_pr_with_label(用 worker 真 title/body,验证非占位);空 diff 不开 PR、不 merge、不关 issue。删除占位机制 (_reserve_implementation_pr / _placeholder_*),改 wakeup_plan/runner 的 early_pr_missing 投影。 根因:空占位 PR 被 reviewer 在 implement publish 前空合,假性关闭 #537/#541/#543。 全量套件 1496 passed。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * 实现 issue #542:删除 redispatch payload 冗余 head_sha (#547) 移除 review redispatch 的重复 head_sha payload * hotfix: stale consensus-implement intent 指向已删 worktree 不再 suppress fresh re-dispatch consensus_implementation_suppressed_reason 的 pending_implement_intent 分支增加 worktree 存在性 守卫(接入既有 _canonical_consensus_worktree_exists):仅当 stale pending intent 的 canonical worktree 仍存在时才 suppress。revert early-PR reservation(#507)后,#537/#541/#543 的 pending implement intent 指向已删除 worktree,旧逻辑 suppress fresh re-dispatch,而 wakeup-runner 不断把 stale intent spawn 进死 cd 致 os error 2 / EXIT=1 死循环,阻断 consensus→implement 自主链路。 现 worktree 缺失即放行 fresh dispatch 重建 worktree。 补 test_wakeup_plan(worktree 缺失不 suppress / worktree 存在仍 suppress)+ 更新 test_controller_actions 锁旧行为的 subTest(pending case 建 canonical worktree 以保留 reject-before-fresh_safe_worktree 意图)。全套件 1557 passed。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * hotfix: spawn-claim lock 持有者 pid 已死即可回收(自愈,防 cleared-log 永久 HELD) _existing_claim_is_recyclable 增加 pid-liveness 回退:当 lock 记录的持有者 pid 已死(os.kill pid 0 抛 ProcessLookupError)时即可回收,保留既有 terminal-marker 回收与 live-spawn 保护 (pid 存活+无 marker 仍不回收)+ metadata-mismatch fail-closed。根因:implement 失败(EXIT=1) 留 stale lock,dispatch_consensus_implementation 重派时清掉 log → #490 spawn-claim 只在 log 有 EXIT= 时回收 → cleared log 无 marker → 死进程 lock 无法回收 → SPAWN_CLAIM_HELD 永久死锁, 阻断 consensus→implement 重派(#537/#541/#543)。补 7 个 behavior test。全套件 1560 passed。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * hotfix: publish_implementation_output 接受 worker 已 commit 的实现 diff _require_publish_implementation_diff 之前只看 git diff HEAD --quiet(未提交改动), worker 一旦自己 commit(在自己分支上,隔离无害)工作区就 clean → 误判 no_diff → 不开 PR。 现改为:有未提交改动 OR HEAD 相对 integration base 有 committed delta(merge-base..HEAD 非空) 即视为有 diff 可发;_commit_publish_implementation_diff 在工作区已 clean(worker 已 commit)时 跳过提交返回成功,不再误报 publish_commit_failed。修 #541 类 worker-commit→no_diff→无 PR+ daemon 重复 dispatch。补 behavior test。codex 全套件 DISCOVER_STATUS:0 通过。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * 实现 issue #437: .refactor-loop 历史生成物与陈旧 worktree 的有界清理机制 (#548) * #437: 新增 canonical RuntimeRetention owner,log-retention 降为一版 alias;清理覆盖 generated files+pending-events compaction+stale worktree;CLAUDE.md 加 #437 narrow carveout * PR #548 review-fix output * PR #548 review-fix output * PR #548 review-fix output * PR #548 review-fix output * PR #548 review-fix output * hotfix: CONFLICTING managed review PR 的 stale-base 冲突自主 resolve 接线既有但孤儿的 prompts/rebase-resolve.md 进 headless 路径:managed review PR mergeable=CONFLICTING(base 落后)时,controller 在 PR worktree 起 git merge --no-commit --no-ff origin/<integration>——干净则直接 commit+push,有冲突则派 rebase-resolve codex(隔离 worktree 内解+stage,禁 commit/push),收到 REBASE_RESOLVE_DONE 后 controller commit + safe_push 仅推 PR head。结果再过 CI+ review-gate 把关。新增 dispatch_pr_rebase_resolve / commit_push_resolved_pr_rebase (controller_actions)+ wakeup_plan 投影 + wakeup_runner 应用。 安全:只动 refactor/iter<N>-* PR 分支,显式 guard 拒碰 integration/review_base, diff-filter=U 验未解冲突才 commit,任何 abort 路径 git merge --abort 留干净 worktree, 幂等(已含 base / 解析在飞则 NOOP)。修 stale-base churn 致 loop 永久停滞(一个 PR 合了其它全 CONFLICTING 无人解)的根因。codex 全套件 1589 passed。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * hotfix: rebase_resolve_actions 投影前 enrich live mergeability(修生产 gap) 自主-resolve 投影读 item.mergeable 前未 enrich,但生产 GhItem 来自 snapshot mergeable 为空 → 永远 skip → CONFLICTING PR 不投影 dispatch_pr_rebase_resolve → loop 仍停滞。复用同文件 _with_live_mergeability(review_evidence_redispatch_actions 已用同模式)。补 mergeable-为空-需-live-fetch 的回归测试(原测试 mock 了 mergeable 未覆盖此生产路径)。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * hotfix: dispatch_pr_rebase_resolve kind 进 EXECUTABLE_ACTION_KINDS(end-to-end 可执行) _close_projection_action 的 else 分支默认 status_only=True;rebase action 的 kind stale-base-conflicting-pr 不在 EXECUTABLE_ACTION_KINDS → 永远 status_only,runner 不 apply,CONFLICTING PR 永不自主 resolve。加该 kind(+ commit_push completion kind 如需) 进集合;controller_action 已在 RUNNER_NAMED_HELPER_ACTIONS 故随即保持 executable。补 端到端 wakeup-plan pipeline 测试(原测试只测 rebase_resolve_actions 单函数,漏了 closed- action-projection 的 status_only 关卡)。codex 全套件 1593 passed。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * hotfix: rebase-resolve commit/dispatch 投影 gate 在实际 worktree merge 态(止 stale-marker 噪音) commit_push_resolved_pr_rebase 之前只凭持久 REBASE_RESOLVE_DONE marker 投影,worktree 已 commit+push(#549)或 abort(#550/#551)后 marker 仍在 → 每 tick fail-closed 噪音 + 反复 0-codex(zero_streak 触警)+ stale marker 挡 #550/#551 fresh resolve。现 gate:仅当 worktree 真有 merge-in-progress(MERGE_HEAD)且无 unmerged 才投 executable commit_push; 否则不投。并让 worktree clean + 仍 CONFLICTING 的 PR 重新拿 executable dispatch_pr_rebase_resolve (stale DONE marker 不再永久压制)。补端到端测试。codex 全套件通过。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * 实现 issue #502: 删除遗留 label 兼容层:purge emoji/legacy alias 全套(cleanup_aliases / per-spec (#549) * 实现 issue #502: 删除遗留 label 兼容层:purge emoji/legacy alias 全套(cleanup_aliases / per-spec * 修复 PR #549 review r3:#502 label-purge 适配当前 label 代码(contract-tests + architect/tests reject) fix codex round-3 applied-4:对齐 #502 遗留 label 兼容层 purge 与近期新增 label 代码, 修 contract-tests 失败 + architect/tests reject。改 labels.py + SKILL.md + test_wakeup_plan.py。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * 修复 headless review_gate ci_failed 死锁:reject→FIX 移到 ci/mergeability 检查前 _review_gate_decision 之前 ci_error/mergeability 检查在 reject>0→FIX 之前 → CI 红的 PR 即使 reviewer reject 也返回 WAIT_OR_REDISPATCH:ci_failed 干等,而 CI 不修不会绿 → 死锁 (#548/#549 都中,需手动派 fix 破解)。把 reject>0→FIX 移到 ci/mergeability 检查前 (仍在 reviewer-validity/head 检查之后)→ reject 时即使 CI 红也自主派 fix(fix 同解 reject+CI)。 MERGE/MERGE_WITH_COMMENTS 判定完全不变(仍需 ci-green + mergeable + reject=0 + approve>=1), 无误合并风险。补 test_wakeup_runner 端到端测试(reject+ci-red→FIX;reject=0+ci-red 仍 WAIT; happy path MERGE 不变;stale-head+reject 仍 WAIT)。full suite 1600 passed。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * 修正 review_gate 顺序:mergeability 检查移到 reject→FIX 之前(CONFLICTING 不并发 review/fix) 上一修复(a125d19)把 reject→FIX 移到 ci+mergeability 前,破了 ci_failed 死锁但也让 CONFLICTING+reject 的 PR 路由到 FIX → 与独立的 dispatch_pr_rebase_resolve 并发跑同一 worktree(#550 出现 98-file mid-merge + reviewer 并发)。把 mergeability_error 检查移到 reject→FIX 之前:CONFLICTING→WAIT(先 rebase-resolve,不并发 review/fix);MERGEABLE+ CI红+reject→FIX(死锁修复保留);ci_error 仍在 reject→FIX 后(纯 CI 红无 reject 才 WAIT)。 MERGE 判定不变。test_wakeup_runner 90 OK(+conflicting 用例)。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * 实现 issue #498: headless daemon fail-closed 点的 codex 兜底裁决/生成机制(narrow allowlist,非通用 es (#550) * 实现 issue #498 * 实现 issue #498: headless daemon fail-closed 点的 codex 兜底裁决/生成机制(narrow allowlist,非通用 es * PR #550 review-fix output * 新增 patrol-inspector 巡检 issue intake (#551) * 实现 issue #541 * PR #551 review-fix output * PR #551 review-fix output * 修复 PR #551 contract-tests:对齐 patrol 第8 daemon + safe_push/sync_dev 测试 host.env #551 patrol 新增 patrol_inspector_daemon(第8 daemon)→ test_anti_stop_restart 期望 7→8; test_controller_lib_safe_push / test_sync_dev 补 CONSENSUS_RND_HOST_ENV host.env 设置 (代码按 host-config contract 需 host.env locator,rebase-resolve 丢了 base 新测试版本)。 断言未削弱(daemon 数断言强化为8)。full discovery 1634 OK + sshx 13 OK。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * 修复 PR #551 contract-tests(clean-env):e2e fixture 设 META_ESCALATION_STUCK_HOURS 隔离 de-dup 测试 test_batch_and_per_task_lock_do_not_duplicate_spawn 在 clean env(CI)下失败:#506 meta- escalation 因 fixture mock 态被判 stuck 而 fire,产出 repository-stalled RunnerResult 污染 de-dup 断言(expected [] got [RunnerResult])。fixture host.env+env 设 META_ESCALATION_STUCK_ HOURS=999999 禁该测试的 meta-escalation,聚焦 de-dup 行为。断言未削弱。clean discovery 全过。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * 修复 publish-gap:implement readiness 用 git status --porcelain 判 staged diff 原 classify_implement_attempt / wakeup_runner publish 前用 git diff --quiet 只检测 unstaged 改动;worker 正确 git add -A 后 staged diff 被误判 empty_scoped_diff,导致完成的 implement (如 #553 干净 EXIT=0 + 885 行真实 staged diff + 有效 title/body artifacts)永远出不了 PR, wakeup_runner 对 children 反复空转 re-dispatch。改为先 git status --porcelain 判 staged/ unstaged/untracked 任一即 publish-ready,只有真干净才 fallback git diff。publish-time 建 PR 路径不变(不重蹈 #507 early-PR 空 commit/placeholder 死锁)。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * 实现 issue #552 * PR #558 remote-ci-fix output * 移除 #552 越界加的孤立 flaky phase9-router 测试 fb2f461(#552 实现)给未改动的 phase9 router 加了 test_phase9_router_tick_summary_is_ router_local_diagnostic,与 #552「收窄 restart daemon 权威」scope 无关,且该测试 call self.router.tick() 不 mock managed-work-snapshot fetch → CI 无 GitHub 时 fetch-failed 诊断行污染输出致 anchored regex 不匹配(flaky),挡 CI。main 从无此测试。按删除优先+scope 收口移除;若 router 诊断测试有价值应在 phase9-focused PR 以 hermetic 形式正式加。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* #471 hotfix: wakeup_plan completed-marker 投影按 open-managed 集过滤,closed/merged target 不投影(止血 graphql:消除 wakeup_runner 对已终结 target 的逐条重校验) * #410: SKILL/prompt 注释改引 durable contract anchor,不引用一次性 .refactor-loop/runs/*;新增 test_generated_artifacts_not_authority 窄 source-regression (#472) * #471 hotfix2: wakeup-plan 同一 target 只投影最新有效 marker,旧轮次不再投影 dispatchable action(止 graphql backoff 最后一刀) * skill: 强化 no-gap 规则 — 0 codex + active work 无观察模式豁免,必须当 turn 立即介入派 codex(+source-regression) * #470: direct-post prompt 渲染时 fixed-token 内联 _github-post-rules,host worktree cwd 可达(避免裸相对路径) (#479) * #478 hotfix: daemon spawn 改 launch-and-forget 独立 supervisor(start_new_session 不 wait),daemon reload 不丢 in-flight worker;daemon 每 tick 清晰状态行 * #471: wakeup-plan latest-open-fresh 投影 — completed-marker open-target/latest + release-rollup 仅 latest-per-sha 且 ahead>0 本地 ref 验证(止 stale 投影/graphql) (#482) * #481: consensus->implement readiness-dedup gate(止 daemon 重派 closed/has-PR/in-flight) (#486) * #481: consensus->implement readiness-dedup gate, closed/closing-PR/remote-branch/in-flight target 不投影 dispatchable, 止重复/race * #481 fix r1: dedup gate 复用 concurrency monitor owner surface 测量 in-flight,不重实现 daemon 算法(addr architect) * #481 fix r2: 补 controller helper guard behavior test(addr tests) * #485: consensus->implement 按 scope_paths 冲突分组串行(同组一个 executable,其余 status_only),复用 batching-heuristics,防并行冲突 PR (#489) * #475: wakeup-runner WakeupApplyBudget — spawn-worker action 按 hard_gate.dispatch_required 批量到 floor deficit(lifecycle action 仍 1/tick),修 1/tick 线性恢复 (#492) * hotfix(#475 ext): batch budget 纳入 dispatch_design_consensus —— solver triplet 一 tick 派齐(非 lifecycle,worker 派发),修 design-consensus 仍 1/tick 低并发 * hotfix: headless spawn-intent launch — skipped duplicate 不再 break 整批 spawn,stale applied ledger(log 缺失)可重试,helper_exit:3 加来源诊断事件;修 248 intent 堆积/0 并发 * hotfix r2: blocked lifecycle action 不再 dead-stop 整 tick — 跳过/抑制 stale blocked(close-drop target OPEN / publish 无 verified head)继续 launch 后续 spawn-batch,使 headless 并发拉到 floor * hotfix r3: 根治 headless 0 并发 — detached spawn-codex launch 显式传 env_for_subprocess(修 #478 decouple 丢 env 致 EXIT=127);失败 log(非0 EXIT)可重试 launch,EXIT=0/未完成仍抑制重复;tick 状态汇总后续 launch 不被首个 blocked 掩盖 * hotfix r4: run_once 通用 blocked-not-dead-stop — 任何 blocked/skipped non-spawn action 不再 dead-stop 整 tick,继续 launch 后续 spawn-batch;wakeup-plan 抑制 precondition 注定失败的 stale action;根治 headless 并发=0 * hotfix r5: wakeup-plan 投影侧 suppress stale close_managed_drop(target 实际 OPEN 的 drop-close 注定失败)为 status_only,不再占 tick 挡住后续 design-consensus spawn launch * hotfix r6: wakeup-runner run_once 不再把 no-intents 的 dispatch_design_consensus(helper_exit:3)误判为 codex launch failure dead-stop 整 tick 根因:dispatch_design_consensus 是 spawn-batch action;当 solver triplet 不完整(如 #496 minimal/structural EXIT=0 但未 emit SOLVER_DONE marker)时 helper 返回 exit 3(NO_INTENTS),_spawn_launch_failure 命中 "helper_exit:" 前缀判 True → run_once break,整 tick dead-stop,后续 reviewers/其他 design-consensus/implement 全部不派 → headless 并发=0。 修法:run_once 中 blocked 的 spawn-batch action 若 controller_action != spawn_codex_harness_background(即 dispatch_design_consensus),按 routing no-op skip-and-continue,继续 launch 后续 spawn-batch;仅真正 spawn_codex_harness_background launch failure 才走既有 retry/break。延续 r4 blocked-not-dead-stop 不变量到 design-consensus spawn-batch action。 behavior test: test_wakeup_runner_design_consensus_no_intents_does_not_dead_stop_later_spawn_batch(无修复时 later spawn 不 launch 而 FAIL)。 * hotfix r7: review head_sha binding — 打通 headless review→merge 自驱 根因:reviewer artifact frontmatter 不带 head_sha,_review_evidence_from_artifact 取不到所审 head SHA → 所有 reviewing PR(#480/#473/#402)恒判 WAIT_OR_REDISPATCH:invalid_reviewer_evidence:missing_reviewed_head_sha,且 wakeup-plan 不自动重派 reviewer → review→merge headless 永久卡死(挡住发版)。 修法(codex hotfix worker 实现,controller 验证后提交): - controller_actions 派 reviewer 时取 headRefOid,缺则 fail-closed,注入权威 HEAD_SHA 进 rendered prompt。 - reviewer-{architect,tests,quality}.md frontmatter 写 head_sha: ${HEAD_SHA}。 - wakeup_runner._review_head_sha_for:artifact 缺 head_sha 时从 controller-rendered prompt/log 回收(不依赖 worker 自报,避免 markerless 覆辙);live-head 陈旧判定与 merge 真值表语义不变。 - wakeup_plan 为 missing/stale reviewer head 的 OPEN reviewing PR 投射可执行 dispatch_reviewers 自愈动作。 验证:controller 独立重跑 test_wakeup_runner+review_gate+wakeup_plan+controller_actions 293 通过、marker/prompt 合同 30 通过;review-gate 安全语义(stale head 仍不 merge)由 13 项 review-gate 测试锁住。 * hotfix r8: 让 review-evidence-redispatch 自愈动作可执行 — 打通 headless review→merge 闭环 承接 r7:r7 让 reviewer 证据绑定 head_sha,但 wakeup_plan 投射的 review-evidence-redispatch 自愈动作被 closed-action-projection finalizer 强制 status_only(其 kind 不在 EXECUTABLE_ACTION_KINDS),runner 永不应用 → #480/#473/#402 缺 head 的 review 证据无法自动重派 → review_gate 恒 WAIT_OR_REDISPATCH → 并发耗干到 0。 修法(codex hotfix worker 实现,controller 验证后提交): - wakeup_plan EXECUTABLE_ACTION_KINDS 加 review-evidence-redispatch,finalizer 保留 runner authority 不再强制 status_only。 - controller_actions.dispatch_reviewers 读 stale_review_roles 只重派陈旧角色,且 _pending_review_spawn_exists 跳过已有在飞 dispatch-reviewers:<pr>:<role>:r1 intent(幂等不双派);仍走 r7 的 HEAD_SHA 注入,使重派 reviewer 的新证据 head-bound。 - merge-gate 真值表不变,仅让既有自愈动作可执行 + 定向到陈旧角色。 验证:controller 独立重跑 test_wakeup_plan+wakeup_runner+review_gate+controller_actions 295 通过。 * hotfix r9: reviewer 重派 bump 到下一轮 + 绝对 cd + latest-evidence-per-role — 真正打通 headless review→merge 根因(同一类:按"产物存在"而非"成功+区分维度"抑制):reviewer 重派硬编码回 r1,撞上旧 head 早先成功(EXIT=0)的 r1 log → _harness_spawn_intent_log_suppresses_retry 判"做过了"抑制 → 当前 head 该重跑的 review 永不跑 → review_gate 恒 WAIT_OR_REDISPATCH → 并发 0。且 intent cd 是相对 "." → headless 启动层不投射。 最小修法(按 maintainer directive:文件名即唯一 id,不加 wrapper --id,留在现有 r<R> 命名约定内不改公开命名): - controller_actions.dispatch_reviewers:_next_review_round 取该 PR/role 现有最大轮 +1,渲染 r<N+1> 的 prompt/log/output/intent;pending-spawn 幂等 guard 按真实轮号;_append_harness_spawn_intent 的 cd 改 str(cd.resolve()) 绝对路径,使 headless 投射+启动成立。 - wakeup_plan.latest_reviewer_heads / wakeup_runner._latest_review_evidence_by_role:改为"每 role 取各自最新轮证据"(而非全局最新单轮),使只重派陈旧 role 时不丢其它 role 已 head-bound 的有效证据;merge 仍要求每 role 证据绑定 live head,安全语义不变。 验证:controller 独立重跑 test_wakeup_plan+wakeup_runner+review_gate+controller_actions 299 通过。 * hotfix r10: review_gate action 带上 reviewed head_sha + e2e 锁死 headless review→decision 全路 根因(review path head_sha 串接的第 5 处):wakeup_plan 投影 REVIEW_DONE 的 review_gate action 时只读 log 的 head(log 无 head)→ action.head_sha 空 → wakeup_runner._review_gate 卡 WAIT_OR_REDISPATCH:missing_action_reviewed_head_sha,证据虽已 head-bound 但 gate 连比都没法比。 修法(最小、按文件名即 id 思路): - wakeup_plan.completed_marker_actions:REVIEW_DONE action 的 head_sha 改由 _review_done_action_head_sha 从权威证据面解析(latest_reviewer_heads 含 r7 prompt 注入的 head;或全 role head-bound 时取 live PR head;否则回落 log)。只从真实来源填充,不绕过 gate 的 head 比对,merge 安全语义不变。 - 新增 test_review_gate_e2e.py:从真实 wakeup_plan 投影 → WakeupRunner apply,断言 FIX(有 reject)与 MERGE(全 approve+CI 绿)两条具体决策落地——端到端锁死整条 review→decision,杜绝再冒隐藏层。 - test_wakeup_plan.py:加 prompt-bound reviewed head 的 planner 回归。 验证:controller 独立重跑 test_wakeup_plan+wakeup_runner+review_gate+controller_actions+review_gate_e2e 302 通过。 * hotfix r11: PrChecksProjection 对瞬时 gh-api 失败加 bounded retry — ready PR headless 走到 review_gate 决策 根因:review_gate 的 CI 读 PrChecksProjection.check_pr 对 gh api pulls/<n> 与 commits/<sha>/check-runs 的单次非零返回立即 fail-closed(ci_unavailable:pull_api_failure),无重试;rate limit 健康,实为瞬时 blip → 让 #473/#402(MERGEABLE+CI 绿)每 tick 被瞬时失败挡住、never reach MERGE/FIX。 修法(最小,只动 PrChecksProjection;不碰 #322 ReleaseRequiredChecksProjection): - _run_api_read:对两处 api read 最多 3 次确定性重试(无 sleep),成功即停,持续失败仍 fail-closed(安全)。happy path 无行为变化。 - starvation 结论(worker 核实):review_gate 本就被 apply,blocked ci_unavailable 行可重评估(非 terminal duplicate-suppressed),无需改 run_once。 - e2e:test_review_gate_e2e 加「首次 pulls 读瞬时失败仍 merge」用例;test_pr_checks 加 retry 覆盖。 验证:controller 独立重跑 test_pr_checks+wakeup_runner+review_gate+review_gate_e2e+wakeup_plan+controller_actions 309 通过。 * hotfix r12: run_once 不再让 spawn-batch starve drain-only lifecycle — ready PR headless merge,backlog 能 drain 根因(已核实):wakeup_plan 每 tick 把 SPAWN actions(implement intent + design-consensus #495/#496/#490/#491/#418,index 0-5)排在 lifecycle review_gate(#480/#473/#402,index 6-8)之前;run_once 旧逻辑 `if applied_spawns>0 and not is_spawn_action: break` → 只要派了任一 spawn,首个 lifecycle 即 break 整 tick。design-consensus 几乎总有 spawn 活 → review_gate/merge 永远 starve → #473(approve/approve/comment → MERGE_WITH_COMMENTS,MERGEABLE+CI 绿)永不 merge,active 数永不下降。 修法(最小,核心 dispatch loop): - 引入 consumes_spawn_budget = is_spawn_action or _uses_spawn_budget(action);超 budget 时 `continue`(不 break)以便仍能抵达后续 drain-only lifecycle。 - _uses_spawn_budget:dispatch_reviewers=True、review_gate 仅当决策为 FIX(会派 fix worker)=True;否则 review_gate(MERGE/MERGE_WITH_COMMENTS)、close 等 drain-only=False → 不占 spawn budget、floor 填满后仍被评估执行。 - 保留 r6 的 spawn launch-failure break/retry 与 dispatch_design_consensus no-intents skip-and-continue;真值表/head-binding/CI-green/mergeable 安全语义不变。 结果:每 tick 既用 spawn 填满 floor,又评估 merge/close 等 drain-only lifecycle,backlog 能 drain。 验证:controller 独立重跑 test_wakeup_runner+review_gate+review_gate_e2e+wakeup_plan+controller_actions+pr_checks 309 通过;新增 test_wakeup_runner_lifecycle_review_gate_not_starved_after_spawn_batch。 * hotfix r13: 修 WakeupRunner._run_command 把 --repo 注入到 gh 子命令前致全部 gh 调用 malformed — review→merge 根因 根因(实测确认):_run_command 对所有 gh 命令在 full[1:1] 插 --repo(子命令之前)。gh 不接受 --repo 作 pre-subcommand 全局 flag,且 gh api 根本不吃 --repo(repo 在 URL):`gh --repo O/R api repos/O/R/pulls/473` → rc=1 "unknown flag: --repo"。于是 wakeup-runner 的每个 gh 调用都 malformed:CI 读(PrChecksProjection(runner=_run_command) 的 gh api pulls/check-runs)→ ci_unavailable:pull_api_failure;mergeability(gh pr view)→ mergeability_unavailable;live-state 等同理。→ review gate 永远读不到 CI/mergeable → #473(approve/approve/comment=MERGE_WITH_COMMENTS,绿)、#402、#480 永不 headless 落地。r11 的 retry 只是重复同一 malformed 命令。直连 PrChecksProjection()/直连 gh 用的是 plain default runner(无注入)所以正常,掩盖了 bug。 最小修法:_run_command 仅对 `gh pr`/`gh issue` 注入 --repo,且放在子命令(及其 verb)之后的合法位置;`gh api` 完全不动;绝不 pre-subcommand 注入;已存在 --repo 则不重复。 验证:controller 独立重跑 test_wakeup_runner+review_gate+review_gate_e2e+pr_checks+wakeup_plan+controller_actions 312 通过;新增 argv-shape 测试 + e2e(stub subprocess.run 拒绝 malformed `gh --repo ... api`,ready PR 仍 merge)。 * hotfix r14: managed draft PR ready-then-merge — review gate 不再硬挡 pr_draft 根因(r13 修好 gh 调用后浮现):review_gate 的 _review_gate_mergeability_error 把 isDraft=True 当 WAIT_OR_REDISPATCH:pr_draft 硬挡。但本 loop draft-until-consensus:PR 开为 draft 直到 review 共识,merge_pr 在决策 MERGE/MERGE_WITH_COMMENTS 时 ready-then-merge。于是绿 gate 的 managed draft(如 #473 approve/approve/comment)永远卡 pr_draft、永不 headless 落地。 最小修法: - wakeup_runner:删除 mergeability 检查里的 isDraft→pr_draft 硬挡(仍挡 mergeable!=MERGEABLE,即 CONFLICTING/DIRTY)。 - controller_actions.merge_pr:对 live draft PR 先校验 crnd:lifecycle:managed 再 gh pr ready(非 managed draft 不 ready,写 CONTROLLER_ACTION_BLOCKED:target-not-managed 并返回 2);保留既有 ready-then-merge。 - 真值表/head-binding/CI-green/conflicting-blocks 安全语义不变;readying 仅限 managed PR。 验证:controller 独立重跑 test_wakeup_runner+review_gate+review_gate_e2e+controller_actions+wakeup_plan+pr_checks 316 通过;新增 managed-draft merge + 真实 plan→runner→controller ready-then-merge e2e + conflicting/非managed 安全用例。 * #409: 移除 .refactor-loop/host.env runtime fallback,CONSENSUS_RND_HOST_ENV 为唯一 host fact locator(缺失 fail-closed);迁移依赖 legacy fallback 的 test fixture (#473) * hotfix r15 (sshx 共识 B 之一): 统一 gh argv 构造到单一 build_gh_argv helper — 防 r13 类 --repo bug 复发 sshx 一致共识 B 的硬化第1步:把分散重复的 gh --repo 处理收口到 codex_refactor_loop/gh_invoke.py 的 build_gh_argv(slug, argv):gh api 永不加 --repo(repo 在 URL);gh pr/issue 仅在 subcommand 之后、缺失时加 --repo <slug>;绝不 pre-subcommand。wakeup_runner._run_command / ControllerActions.gh / PrChecksProjection 三处 API 调用全部改走该 helper,删除各自的内联 --repo 启发式。行为保持不变(含 r13 修复)。 验证:characterization + source-regression 锁在 test_gh_invoke.py(9 测试);controller 独立重跑 test_gh_invoke+pr_checks+wakeup_runner+review_gate+review_gate_e2e+controller_actions+wakeup_plan 326 通过;pr_checks 直跑 --help 兼容。 注:这是硬化(防复发),不直接提升并发;并发瓶颈在上游 implement→publish 阶段,接下来单独处理。 * hotfix r16 (sshx 共识): 打通 implement→publish 解锁并发瓶颈 — markerless/stale implement 重派 + 安全门控发布 sshx codex-cli triplet 共识(minimal/structural/delete + meta-judge):10 个 design-solving issue 已达成共识但卡在 implement→publish(implement 早跑过却 markerless/未提交/过期 base/没 PR;dispatch_consensus_implementation 被 local_iter_branch 抑制、publish 被 verified_pr_head_unavailable 抑制)→ 无新可派工作 → 并发 ~1。 修法(wakeup_plan/wakeup_runner/controller_actions/git.py): - success-aware 重派:implement 分支/worktree 存在但无 valid clean IMPLEMENT_DONE:ok marker(markerless/failed)或 base 过期 → 重派;fresh_safe_worktree 把 canonical worktree reset/recreate 到当前 origin/$INTEGRATION_BRANCH;仅 genuine in-flight / 已有干净 PR / 待发布 clean marker 才抑制。 - 发布门控(严防误发 stale/wrong-scope):publish_implementation_output 仅在 canonical identity(refactor/iter<issue>-<candidate> + worktree 实际分支匹配)+ fresh integration base(merge-base==origin/integration,过期 base block)+ managed open issue + 无重复 PR + 非空 scoped diff 时,commit→push→open PR→派 reviewers;否则 block。 - wakeup_plan 用 canonical_implementation_identity/single_linked_managed_issue/clean_scoped_diff 替代 verified_pr_head 抑制。 验证:controller 独立重跑 wakeup_plan+wakeup_runner+review_gate+review_gate_e2e+controller_actions+pr_checks+gh_invoke 330 通过。 已知待修(follow-up):worker 把 PR title/body/commit 文案改成英文,违反「GitHub artifact 中文」策略,下一 commit 恢复中文。 * hotfix r17: fresh consensus-implement 重派前清除 terminal 非可发布 implement log — 让卡住的 implement 真正启动 承接 r16:r16 让 markerless/stale implement 重派(reset worktree),但旧的 EXIT=1/markerless implement log 仍占 spawn 的 target_log_absent 前置 → fresh implement 不启动(同一类「按存在抑制」,implement-spawn-log 层)。 修法(controller_actions,success-aware):fresh consensus-implementation dispatch 写 spawn intent 前,仅清除 terminal 非可发布 implement log(EXIT!=0 失败 / EXIT=0 无 IMPLEMENT_DONE:ok marker);保留 genuinely in-flight(无 EXIT)与 clean publish-ready(EXIT=0 + 干净 marker)log 不动。于是卡住的 markerless/failed implement 重派后能真正 launch、跑在 fresh base、产出干净 marker → r16 门控发布。 验证:controller 独立重跑 wakeup_plan+wakeup_runner+review_gate+review_gate_e2e+controller_actions+pr_checks+gh_invoke 333 通过。 设计说明:并发瓶颈用确定性逻辑修对(ready=clean EXIT=0+marker;parallel=scope_paths 不相交),不引入 LLM-in-loop 分发判断(daemon-first;sshx codex 三人组一致 revise:LLM 最多 shadow-mode,不入决策回路)。 * hotfix r18: implement-lifecycle 收敛为单一 success-aware 谓词 + runner 路径自清陈旧 log — headless 自愈,不再需手动清 log 承接 r16/r17(r17 把清 log 放进被抑制的 dispatch 路径,从没执行)。新增 implement_lifecycle.py 单一事实源 classify_implement_attempt → in_flight | publish_ready | redispatch,plan/runner/controller 共用: - runner spawn-apply 路径 _spawn_log_suppresses_retry 仅在 in_flight|publish_ready 时抑制;redispatch(EXIT!=0/markerless/stale-base) 不抑制且 _clear_redispatchable_spawn_log 在 spawn 实际应用处清掉陈旧终态 log → fresh implement 真启动(修 r17 misplacement,免手动清)。 - publish 仅 publish_ready(clean IMPLEMENT_DONE:ok + canonical identity + fresh base + 非空 scoped diff);clean-marker 但 stale-base 改 redispatch 而非死锁(#421 edge)。 - 确定性逻辑(非 LLM-in-loop;daemon-first);merge-gate/#191/#322/#396 安全语义不变。 验证:controller 独立重跑 wakeup_plan+wakeup_runner+review_gate+review_gate_e2e+controller_actions+pr_checks+gh_invoke 339 通过。 * 修复 phase9-router triplet-evidence-invalid 误判致 headless design-consensus wedge solver prompt 注入的 issue source snapshot 含上一轮 design-consensus 的 audit-trail(peer solver log 路径)时,_peer_solver_reference_violation 扫描整个 prompt 误判为 peer-isolation 违规,fail-closed 拒派 meta-judge, 使所有 body 含历史 consensus 记录的 issue 永久 wedge。 修复:peer-isolation 扫描只覆盖 router-controlled 区域,剥离 '## Issue source snapshot' 到 '## Full solver template' 之间的 issue 作者内容;router header / solver template 注入的真实 peer 引用仍拦截。 加两个 behavior test 覆盖 snapshot-排除 与 router-区域-仍拦截。 dogfood headless 实测:reload 后 418/437/474/490/491/493/494/495 全部 恢复 solver→judge→consensus 自驱,#494 已自驱到 implement。 * CLAUDE.md: 加 consensus-rnd:foundational-invariants sentinel block dogfood bootstrap 的 check-project-rules probe 要求 PROJECT_RULES 含此 fixed-point block;缺失时 probe fail-closed 阻断 headless restart。内容 为 probe 生成的 canonical FI-001~007,镜像既有设计哲学,不引入新约束。 * 修复 markerless implement 致 publish 卡死的 headless gap implement worker 干净退出(EXIT=0)但把 IMPLEMENT_DONE marker 只写进 run artifact(runs/implement-issue-<id>.md)而非 log 末尾时(codex stdout marker 落点不可靠),completed_marker_actions 只扫 log marker → markerless → 不生成 publish action → design→implement→PR 链卡在 implement 后。实测 #421:EXIT=0 + artifact 有 IMPLEMENT_DONE:issue-421:ok + 9 文件 staged,却无 PR、label 仍 停在 design-solving。 修复:对 clean-exit 的 implement-issue log,log markerless 时 fallback 读取 run artifact 末尾的 IMPLEMENT_DONE marker,复用 review verdict 已有的 artifact-first 模式。窄作用域(仅 implement-issue + clean-exit),配 2 个 behavior test;全套 wakeup_plan 138 tests green。 * 补全 markerless implement publish:revalidation 也读 run artifact marker 8aeea89 修了 wakeup_plan detection 端,但 wakeup-runner 的 source-marker revalidation(_source_log_has_clean_marker)仍只扫 log,markerless implement publish 仍被 reject(clean_exit_marker_missing)。补全:revalidation 对 clean-exit implement-issue log 在 log markerless 时 fallback 读 runs/implement-issue-<id>.md 的 marker,与 detection 端一致;配 behavior test, 全套 wakeup_runner 76 tests green。 注:dogfood 实测确认 markerless 是系统性病根(还影响 readiness 重派、review verdict 等多处),应走系统性统一(见 #491 日志/observability 与后续 marker-reading 收口);本 commit 只补 implement publish 这条链。 * 日志详细化:wakeup-runner tick 显示全状态计数 + 被掩盖的 blocked/skipped 详情 旧 _wakeup_tick_action 只看 results[0],一个 tick 处理多 action 时 blocked(如 publish 失败)被成功的 spawn 掩盖、完全不可见;graphql-backoff 固定显示误导的 'remaining=unknown'。dogfood 调试时这逼得每次翻 ledger 才知道真实发生了什么。 改:tick log 显示 [applied=N,blocked=M,...] 全状态计数 + 被掩盖的 blocked/skipped 具体 reason+action(graphql-backoff 作整-tick 门控单独报、去掉 unknown);dispatched headline 保留。更新 test 反映可见性提升,全套 wakeup_runner 76 tests green。 * 补全 markerless implement 第三环:readiness 谓词读 run artifact marker classify_implement_attempt(r18 单一 success-aware 谓词)只扫 log 找 IMPLEMENT_DONE:ok,markerless log(marker 落 artifact)→ redispatch:markerless → readiness 不 suppress → 重派覆盖已完成工作(dogfood 实测 #421 重派 4 次、#493 IMPLEMENT_DONE:ok→重派→:partial 工作丢失)。 补全:markerless log 时 fallback 读 runs/implement-<cluster>.md 的 IMPLEMENT_DONE:ok,与 detection(8aeea89)/revalidation(dfacc64)一致。窄作用域 + r17/r18 兼容:只接受 :ok,partial/失败/真 markerless(无 artifact)仍 redispatch recovery — 现有 markerless-redispatch test(wakeup_plan/wakeup_runner/ controller_actions 共 304 tests)全绿,新增 2 behavior test。 至此 implement→PR 的 markerless 三环(detection/revalidation/readiness)打通; review 链 markerless 与系统性统一抽象交 #499 共识。 * #500: design-consensus 编排重设计 — phase9-router 唯一派发 owner,删 wakeup-runner 双重派发 落地 #500 r4 consensus(structural framing,no-new-schema): - phase9-router 成为唯一 design-consensus worker intent owner,新增 META_RESOLVED:re-design → marker.round+1 三路 solver route - 删除 wakeup-runner 的 dispatch_design_consensus(消除双重派发 helper_exit:3) - wakeup-runner 只保留 closed action apply(drop→close、consensus→implement) - dispatch_consensus_implementation readiness 后转 crnd:phase:implementing - 无新增 schema(复用 HARNESS_SPAWN_INTENT) 修复 headless P0:reflector META_RESOLVED 无 consumer + phase9-router/wakeup-runner 双重派发致 0-codex 死锁。14 文件 +207/-282;verification 471 tests 全绿。 共识由 controller 手动驱动 design-consensus r1→r4 达成(daemon 停止期间)。 * #501 fix r1: 补 dispatch_consensus_implementation label-transition failure-branch test tests reviewer reject:新增 label transition(gh issue edit→implementing)只测 success path,缺 gh issue edit 返回 nonzero 时 dispatch stop before worktree/render/intent 的 failure-branch test。本 fix 补该测试。 * 修复 headless 死锁:label 移除集只留 canonical crnd:*,删除历史 alias gh issue/pr edit --remove-label 会因仓库不存在的 label 整条 rc=1 失败。 ISSUE_LABELS_REMOVE/PR_LABELS_REMOVE 含 cleanup_aliases(emoji/legacy 名), 仓库未维护这些历史 label,导致 _move_issue_to_implementing_phase 永久失败, consensus→implement 派发卡死、wakeup_runner 0 codex 自驱死锁。 按 maintainer 指令删除历史 label 兼容(不再管历史标签):移除集只列 canonical crnd:* phase/human/stuck label。新增 source-regression 锁定 两集 canonical-only、无 alias。 * 修复 #500 回归:phase9-router 生产 ctx 丢失 GH_REPO_SLUG 致 design-consensus intake 全死 #500(e733b1a)把 Phase9Router.__init__ 的 ctx 构造从 `LoopContext.load(repo_root=repo_root)` 改成 `LoopContext.load(repo_root=repo_root, env={"REPO_ROOT": str(repo_root)})`。 受限 env 不读 os.environ,使 daemon(经 source host.env 启动)的 ctx gh_repo_slug=None → `_open_design_consensus_issues` 第一行 fail-closed 返回 [] → DesignConsensusIssueIntake 静默永不派 → headless 无法为任何 issue 启动 design-consensus;`_require_open_source_issue` 也因无 slug 失败(marker route 如 #490 redesign 卡在 phase9-source-state-unavailable)。 修复:revert 为 `LoopContext.load(repo_root=repo_root)`,读进程环境解析 host facts。 测试一律用 `Phase9Router(ctx=...)` 显式 ctx,不依赖受限 env;新增回归测试锁定 生产 repo_root 构造路径解析 GH_REPO_SLUG。 * 加 STALE_REVIVAL_HOURS:>阈值未推进的 stuck implement 自动 re-trigger(env 可配,默认 3h) headless 下 partial/failed/markerless 的 implement log 会让已排队的 dispatch-consensus-implementation spawn intent 永久卡在 runner 的 target_log_absent 前置(清 log 的 dispatch_consensus_implementation 又被 pending_implement_intent 抑制)→ stuck implement 不会自愈(如 #421/494/493/474/498 的 10h partial-wedge)。 新增 host-tunable STALE_REVIVAL_HOURS(默认 3,非正/非法回落 3h)。wakeup_plan 投影 implement spawn intent 时,若目标 implement log 是 redispatchable (partial/failed/markerless/stale-base)且 mtime 已超阈值,清掉它 → target_log_absent 通过 → implement 自动重派。安全闸:in-flight(无终止 EXIT)永不清、 publish-ready(:ok+diff)不清、age-gate 防误清刚跑完的。 env 已登记进 SKILL.md host env surface matrix + host.env.example;5 个 behavior test + matrix↔example 对称测试覆盖。 * 扩展 stale-revival 覆盖死 codex:in_flight 无 EXIT 且 >阈值 + 不在存活清单 也 re-trigger 最常见的 headless wedge 是 codex/supervisor 中途死亡(如 daemon 被 kill 截断), log 永远停在 in_flight(无终止 EXIT)→ classify 永判 in_flight → 永不 redispatch。 之前只清 redispatchable(partial/failed/markerless)log,漏了这半边。 现在 _revive_stale_redispatchable_implement_log 在 log mtime 超阈值时,先按 redispatchable 清;否则若 classify 为 in_flight 且 monitor 存活清单里无该 log 的 活进程,则判定为死 worker 清掉。安全性:spawn-codex 的 no-output stall 窗口远小于 默认 3h,故 >阈值仍 in_flight 的 log 必是死 supervisor;再加 monitor 存活校验 双保险,绝不杀活 codex。新增 3 个 behavior test(死 codex revive / fresh 不碰 / 活进程不碰)。 * 加手动 trigger:consensus-rnd-cli revive-implements(立即 re-trigger 卡住的 implement,不等阈值) _revive_stale_redispatchable_implement_log 加 force 参数:跳过 stale_revival_seconds() age gate,但 in_flight log 在 force 下必须经 monitor 存活校验证明无活进程才清(绝不杀 正在跑的 codex)。新增 force_revive_stuck_implements() 扫所有 implement-issue-*.log 强制 revive,和新 CLI 命令 revive-implements(authority delete-log)。auto 路径 force=False 不变。新增 4 个 behavior test。 * 修 env 泄漏:测试套件 import 时隔离 ambient host.env(worktree 里跑 TEST_CMD 不再假失败) daemon spawn 的 implement worker 在 worktree 里跑完整 TEST_CMD 时,继承的相对 CONSENSUS_RND_HOST_ENV=.config/consensus-rnd/host.env 泄漏进 temp-repo LoopContext.load(repo_root=tmp) → 解析成 tmp/.config/... 不存在 → 假 LoopContextError(实测 concurrency_monitor 48 + restart_daemons 23 + … ≈151 errors) → 全套永不绿 → implement 永远 :partial → 进不了 PR。 unittest discover 在 collection 阶段先 import 所有 test_*.py 再跑;新增 test_aaa_host_env_isolation.py(字母序最先)在 import 时 pop 掉 host 注入变量, 全套在任何测试 run 前即隔离。验证:full discover 设 locator 跑 → exit 0 全绿 (此前 同条件 151 errors);targeted before/after 证 48/23/1 errors → OK。 纯测试模块,不碰 production/daemon。 * 修 markerless keystone:solver/judge marker 加 companion-artifact fallback solver/judge codex 有时 EXIT=0 但 SOLVER_DONE/META_JUDGE_DONE marker 只落 run artifact、没在 log 末尾,导致 phase9-router 判 triplet 不完整、永不派 judge, design-consensus 轮卡死(实测 #505 r1 structural 214 次嵌入、0 次行首)。 把已有的 implement artifact-marker fallback 扩到 solver/judge:clean-exit log 末尾无独立 marker 时,从 companion run artifact runs/<log-stem>.md 兜底读。纯 additive(log 有 marker 时行为不变)、prefix-scoped、精确 filename regex、复用 安全的独立 marker 提取(不信嵌入/echo)。不削弱共识(仍要 3 marked solver + judge,只让 marker 来源更稳健)。phase9/router.py + wakeup_plan.py + behavior + source-regression tests;full suite 1367 green。 * 修 publish stale-base 无恢复 + 停 :ok churn:让 implementing 能发出 draft PR implement :ok 但 worktree base 落后 origin/$INTEGRATION_BRANCH 时,publish 原本硬 block(publish_implementation_stale_base)且永不恢复;stale-revival 又把 stale-base 的 :ok implement 当 redispatchable 反复重派同一 stale worktree → 无限 churn 占满 floor、长时间零正式 PR(implement→首个 PR 永远开不出)。 改为:publish 前在 worktree merge origin/$INTEGRATION_BRANCH 恢复 base(冲突则 merge --abort + 明确 reason 交既有 resolver/re-dispatch);clean `:ok` 不再被 stale-revival churn(终态成功走 publish-with-recovery,不重跑);无 open PR 的 :ok 创建 draft PR(per #300 共识前 draft)+ Closes #N。controller 仍拥有 git topology, worker 不 commit/push,不绕 review-gate/merge 真值表。controller_actions.py + wakeup_plan.py + wakeup_runner.py + behavior/source-regression tests;full suite 1374 green。 * 修 markerless implement:EXIT=0+真diff 无干净 marker 时合成 publish 候选,止 stale-revival 空重派死循环 publish build/test 闸做安全网。 * 修 publish 顺序 bug + merge 失败派 codex 兜底 resolver:先 commit worker diff 再 merge fresh base,真冲突不 wedge 改派 resolver,幂等续跑 空判据改 git diff HEAD;顺带修 wakeup_plan stale-suppression 同类 git diff 问题。 * 实现 issue #504 (#519) * 修 headless review-fix prompt 渲染不全:绑定全部 placeholder(PR_NUMBER/标题/轮次/分支/REVIEW_*_PATH 等),解锁 reject PR 的 fix→merge 之前 headless _dispatch_review_fix 只绑 FIX_OUTPUT_PATH,其余 ${} 未解析致 fix codex 读不到 reject 证据。 * 实现 issue #496 (#520) * 修 review-fix codex 派到 main 的 cd bug:改在 PR worktree 跑,worktree 缺失 fail-closed 之前 _dispatch_review_fix cd=repo_root → fix 改 main(污染 daemon checkout)且不落 PR 分支(reject PR 永不 merge)。 * 实现 issue #508 (#523) * 修 wakeup-plan action 排序:review_gate/publish 排到新工作 spawn 前,解 spawn-budget 饿死→reject PR 可被 fix→merge * CLAUDE.md 加宪法工程规则:异常必抛出+记可诊断日志严禁吞掉/静默;测试必断言真实行为禁无意义测试(maintainer 指令) * 实现 issue #503 (#521) * 增加通用工程基本规则,明确面向对象设计要求及实现细则 * 实现 issue #514 (#524) * 完善通用面向对象设计准则,增加核心原则与实现层细则 * 实现 issue #494 (#526) * 实现 issue #517 (#528) * 实现 issue #505 (#510) * 实现 issue #505 * #510 fix r1:补 phase9-router 行为测试覆盖(应对 tests reviewer reject) --------- * 修复 headless FIX_DONE 不提交 fix 输出 gap:wakeup-runner 在 FIX_DONE re-review 前先 commit+push fix worktree headless 下 fix codex 产出 FIX_DONE 但 worker 从不 commit,FIX_DONE 直接路由 dispatch_reviewers, fix 输出永远留在 worktree 未提交,reviewers 永远审旧 head,reject 不收敛,阻断所有需 fix 轮的 PR review→merge。镜像 interactive controller:FIX_DONE 源的 dispatch_reviewers 前,若 fix worktree dirty 则 git add+commit+safe_push,clean 则 no-op。附 2 个 behavior test(dirty 提交/clean 跳过)。 * 实现 issue #491 (#531) * 实现 issue #490 (#529) * 实现 issue #490 * 实现 issue #490 * PR #529 review-fix output * 实现 issue #499 (#512) * 实现 issue #499 * PR #512 review-fix output * 实现 issue #474 (#532) * 实现 issue #474 * 实现 issue #474 * 实现 issue #474 * 实现 issue #474 * PR #532 review-fix output * 实现 issue #476 (#518) * 实现 issue #476 * PR #518 review-fix output * 实现 issue #509 (#527) * 实现 issue #509 * 实现 issue #509 * spawn-claim recycle 改用 artifact-aware terminal marker:companion log 被 24h retention 删除后,已完成任务的 claim 仍可回收(读 runs/ artifact),不再永久阻断重派;running 任务无终止 marker 仍不回收(防 double-spawn) * 实现 issue #421:发行前 clean-room 集成测试制度 (#534) * 实现 issue #421 * rebase #421 onto fresh integration:解决 test_cli_command_router 冲突 + 校验 * 实现 issue #493:测试纪律修宪(behavior-first) (#535) * 实现 issue #493 * rebase #493 onto fresh integration:解决冲突 + 校验 * PR #535 review-fix r1:addressed tests+quality reject(behavior-first test 调整) * 实现 issue #506 (#536) * 实现 issue #506 * 实现 issue #506 * 实现 issue #506 * 实现 issue #506 * PR #536 review-fix output * churn 根治:wakeup-plan 给 consensus-impl spawn-intent 套 open_closing_pr/terminal/in-flight 抑制(对齐 dispatch_consensus_implementation),已有 PR 的 issue 不再被重派 implement * 实现 issue #507 (#525) * 实现 issue #507 * 实现 issue #507 * PR #525 review-fix output * 实现 issue #516 (#530) * 实现 issue #516 * 实现 issue #516 * #530 fix r1:补 ManagedWorkSnapshot fetch-failure stale-cache fallback 行为测试(应对 tests reviewer reject) * PR #530 review-fix output * PR #530 review-fix r2:typed ManagedWorkItem projection(addresses architect 类型边界 reject + tests + contract-tests) * PR #530 review-fix r3:anchor ManagedWorkSnapshot read surface in authorization mirror + cross-artifact source-regression(addresses architect governance reject) * PR #530 review-fix r4:add canonical+legacy managed-label discovery regression test(addresses tests reject) * 修复 worker marker reader 误判相同重复 marker 为冲突 codex 常把终止 marker 回显 2-3 次(含 diff + 前缀行),导致 read_worker_terminal_marker 返回 duplicate_or_conflicting,review 真值表 永不收敛、所有 headless review→merge 卡死。改为:相同重复 marker 折叠为 有效,仅当存在 2+ 个不同 marker 值才判 duplicate_or_conflicting。 覆盖 _last_final_marker / _sentinel_adjacent_marker / _marker_from_companion_artifact,保留 malformed 与 foreign-prefix 检测。 * Reserve implementation PR for issue #537 (#540) ⟦AI:AUTO-LOOP⟧ * 实现 issue #511 (#522) * 实现 issue #511 * PR #522 review-fix output * PR #522 review-fix output * 移除误入 PR 的 .refactor-loop 运行 artifact(architect r8 reject) resolve-pr522-merge.md 是一次性合并解决 summary,属生成物,不应进 durable diff (CLAUDE.md「生成物不当事实源」)。解决说明保留在 commit message / PR body。 --------- * 修复早期 PR reservation 崩溃(#511 回归,阻断所有 implement 派发) _reserve_implementation_pr 用 worker 富正文路径开 reservation PR,但该文件在 reservation 时尚不存在 → FileNotFoundError(未被 except RuntimeError 捕获)→ wakeup-runner tick 崩溃 → 任何 consensus issue 无法 implement → loop P0 wedge。 修复:reservation 前若 body 缺失则写占位正文(## issue #N 实现 + Closes + sentinel, publish 会拒占位逼 worker 产真正文);reservation 幂等(已有 open PR 直接返回; 已有 remote head 则 reset 到 integration + force-with-lease push);捕获 OSError。 * Reserve implementation PR for issue #543 (#544) ⟦AI:AUTO-LOOP⟧ * Reserve implementation PR for issue #541 (#546) ⟦AI:AUTO-LOOP⟧ * revert early-PR reservation(#507):不再开空占位 PR,publish 出真内容才开 PR dispatch_consensus_implementation 不再 reserve/开 PR;publish_implementation_output 恢复 pre-#507 行为——implement 出非空 diff 才 commit+push+open_pr_with_label(用 worker 真 title/body,验证非占位);空 diff 不开 PR、不 merge、不关 issue。删除占位机制 (_reserve_implementation_pr / _placeholder_*),改 wakeup_plan/runner 的 early_pr_missing 投影。 根因:空占位 PR 被 reviewer 在 implement publish 前空合,假性关闭 #537/#541/#543。 全量套件 1496 passed。 * 实现 issue #542:删除 redispatch payload 冗余 head_sha (#547) 移除 review redispatch 的重复 head_sha payload * hotfix: stale consensus-implement intent 指向已删 worktree 不再 suppress fresh re-dispatch consensus_implementation_suppressed_reason 的 pending_implement_intent 分支增加 worktree 存在性 守卫(接入既有 _canonical_consensus_worktree_exists):仅当 stale pending intent 的 canonical worktree 仍存在时才 suppress。revert early-PR reservation(#507)后,#537/#541/#543 的 pending implement intent 指向已删除 worktree,旧逻辑 suppress fresh re-dispatch,而 wakeup-runner 不断把 stale intent spawn 进死 cd 致 os error 2 / EXIT=1 死循环,阻断 consensus→implement 自主链路。 现 worktree 缺失即放行 fresh dispatch 重建 worktree。 补 test_wakeup_plan(worktree 缺失不 suppress / worktree 存在仍 suppress)+ 更新 test_controller_actions 锁旧行为的 subTest(pending case 建 canonical worktree 以保留 reject-before-fresh_safe_worktree 意图)。全套件 1557 passed。 * hotfix: spawn-claim lock 持有者 pid 已死即可回收(自愈,防 cleared-log 永久 HELD) _existing_claim_is_recyclable 增加 pid-liveness 回退:当 lock 记录的持有者 pid 已死(os.kill pid 0 抛 ProcessLookupError)时即可回收,保留既有 terminal-marker 回收与 live-spawn 保护 (pid 存活+无 marker 仍不回收)+ metadata-mismatch fail-closed。根因:implement 失败(EXIT=1) 留 stale lock,dispatch_consensus_implementation 重派时清掉 log → #490 spawn-claim 只在 log 有 EXIT= 时回收 → cleared log 无 marker → 死进程 lock 无法回收 → SPAWN_CLAIM_HELD 永久死锁, 阻断 consensus→implement 重派(#537/#541/#543)。补 7 个 behavior test。全套件 1560 passed。 * hotfix: publish_implementation_output 接受 worker 已 commit 的实现 diff _require_publish_implementation_diff 之前只看 git diff HEAD --quiet(未提交改动), worker 一旦自己 commit(在自己分支上,隔离无害)工作区就 clean → 误判 no_diff → 不开 PR。 现改为:有未提交改动 OR HEAD 相对 integration base 有 committed delta(merge-base..HEAD 非空) 即视为有 diff 可发;_commit_publish_implementation_diff 在工作区已 clean(worker 已 commit)时 跳过提交返回成功,不再误报 publish_commit_failed。修 #541 类 worker-commit→no_diff→无 PR+ daemon 重复 dispatch。补 behavior test。codex 全套件 DISCOVER_STATUS:0 通过。 * 实现 issue #437: .refactor-loop 历史生成物与陈旧 worktree 的有界清理机制 (#548) * #437: 新增 canonical RuntimeRetention owner,log-retention 降为一版 alias;清理覆盖 generated files+pending-events compaction+stale worktree;CLAUDE.md 加 #437 narrow carveout * PR #548 review-fix output * PR #548 review-fix output * PR #548 review-fix output * PR #548 review-fix output * PR #548 review-fix output * hotfix: CONFLICTING managed review PR 的 stale-base 冲突自主 resolve 接线既有但孤儿的 prompts/rebase-resolve.md 进 headless 路径:managed review PR mergeable=CONFLICTING(base 落后)时,controller 在 PR worktree 起 git merge --no-commit --no-ff origin/<integration>——干净则直接 commit+push,有冲突则派 rebase-resolve codex(隔离 worktree 内解+stage,禁 commit/push),收到 REBASE_RESOLVE_DONE 后 controller commit + safe_push 仅推 PR head。结果再过 CI+ review-gate 把关。新增 dispatch_pr_rebase_resolve / commit_push_resolved_pr_rebase (controller_actions)+ wakeup_plan 投影 + wakeup_runner 应用。 安全:只动 refactor/iter<N>-* PR 分支,显式 guard 拒碰 integration/review_base, diff-filter=U 验未解冲突才 commit,任何 abort 路径 git merge --abort 留干净 worktree, 幂等(已含 base / 解析在飞则 NOOP)。修 stale-base churn 致 loop 永久停滞(一个 PR 合了其它全 CONFLICTING 无人解)的根因。codex 全套件 1589 passed。 * hotfix: rebase_resolve_actions 投影前 enrich live mergeability(修生产 gap) 自主-resolve 投影读 item.mergeable 前未 enrich,但生产 GhItem 来自 snapshot mergeable 为空 → 永远 skip → CONFLICTING PR 不投影 dispatch_pr_rebase_resolve → loop 仍停滞。复用同文件 _with_live_mergeability(review_evidence_redispatch_actions 已用同模式)。补 mergeable-为空-需-live-fetch 的回归测试(原测试 mock 了 mergeable 未覆盖此生产路径)。 * hotfix: dispatch_pr_rebase_resolve kind 进 EXECUTABLE_ACTION_KINDS(end-to-end 可执行) _close_projection_action 的 else 分支默认 status_only=True;rebase action 的 kind stale-base-conflicting-pr 不在 EXECUTABLE_ACTION_KINDS → 永远 status_only,runner 不 apply,CONFLICTING PR 永不自主 resolve。加该 kind(+ commit_push completion kind 如需) 进集合;controller_action 已在 RUNNER_NAMED_HELPER_ACTIONS 故随即保持 executable。补 端到端 wakeup-plan pipeline 测试(原测试只测 rebase_resolve_actions 单函数,漏了 closed- action-projection 的 status_only 关卡)。codex 全套件 1593 passed。 * hotfix: rebase-resolve commit/dispatch 投影 gate 在实际 worktree merge 态(止 stale-marker 噪音) commit_push_resolved_pr_rebase 之前只凭持久 REBASE_RESOLVE_DONE marker 投影,worktree 已 commit+push(#549)或 abort(#550/#551)后 marker 仍在 → 每 tick fail-closed 噪音 + 反复 0-codex(zero_streak 触警)+ stale marker 挡 #550/#551 fresh resolve。现 gate:仅当 worktree 真有 merge-in-progress(MERGE_HEAD)且无 unmerged 才投 executable commit_push; 否则不投。并让 worktree clean + 仍 CONFLICTING 的 PR 重新拿 executable dispatch_pr_rebase_resolve (stale DONE marker 不再永久压制)。补端到端测试。codex 全套件通过。 * 实现 issue #502: 删除遗留 label 兼容层:purge emoji/legacy alias 全套(cleanup_aliases / per-spec (#549) * 实现 issue #502: 删除遗留 label 兼容层:purge emoji/legacy alias 全套(cleanup_aliases / per-spec * 修复 PR #549 review r3:#502 label-purge 适配当前 label 代码(contract-tests + architect/tests reject) fix codex round-3 applied-4:对齐 #502 遗留 label 兼容层 purge 与近期新增 label 代码, 修 contract-tests 失败 + architect/tests reject。改 labels.py + SKILL.md + test_wakeup_plan.py。 --------- * 修复 headless review_gate ci_failed 死锁:reject→FIX 移到 ci/mergeability 检查前 _review_gate_decision 之前 ci_error/mergeability 检查在 reject>0→FIX 之前 → CI 红的 PR 即使 reviewer reject 也返回 WAIT_OR_REDISPATCH:ci_failed 干等,而 CI 不修不会绿 → 死锁 (#548/#549 都中,需手动派 fix 破解)。把 reject>0→FIX 移到 ci/mergeability 检查前 (仍在 reviewer-validity/head 检查之后)→ reject 时即使 CI 红也自主派 fix(fix 同解 reject+CI)。 MERGE/MERGE_WITH_COMMENTS 判定完全不变(仍需 ci-green + mergeable + reject=0 + approve>=1), 无误合并风险。补 test_wakeup_runner 端到端测试(reject+ci-red→FIX;reject=0+ci-red 仍 WAIT; happy path MERGE 不变;stale-head+reject 仍 WAIT)。full suite 1600 passed。 * 修正 review_gate 顺序:mergeability 检查移到 reject→FIX 之前(CONFLICTING 不并发 review/fix) 上一修复(a125d19)把 reject→FIX 移到 ci+mergeability 前,破了 ci_failed 死锁但也让 CONFLICTING+reject 的 PR 路由到 FIX → 与独立的 dispatch_pr_rebase_resolve 并发跑同一 worktree(#550 出现 98-file mid-merge + reviewer 并发)。把 mergeability_error 检查移到 reject→FIX 之前:CONFLICTING→WAIT(先 rebase-resolve,不并发 review/fix);MERGEABLE+ CI红+reject→FIX(死锁修复保留);ci_error 仍在 reject→FIX 后(纯 CI 红无 reject 才 WAIT)。 MERGE 判定不变。test_wakeup_runner 90 OK(+conflicting 用例)。 * 实现 issue #498: headless daemon fail-closed 点的 codex 兜底裁决/生成机制(narrow allowlist,非通用 es (#550) * 实现 issue #498 * 实现 issue #498: headless daemon fail-closed 点的 codex 兜底裁决/生成机制(narrow allowlist,非通用 es * PR #550 review-fix output * 新增 patrol-inspector 巡检 issue intake (#551) * 实现 issue #541 * PR #551 review-fix output * PR #551 review-fix output * 修复 PR #551 contract-tests:对齐 patrol 第8 daemon + safe_push/sync_dev 测试 host.env #551 patrol 新增 patrol_inspector_daemon(第8 daemon)→ test_anti_stop_restart 期望 7→8; test_controller_lib_safe_push / test_sync_dev 补 CONSENSUS_RND_HOST_ENV host.env 设置 (代码按 host-config contract 需 host.env locator,rebase-resolve 丢了 base 新测试版本)。 断言未削弱(daemon 数断言强化为8)。full discovery 1634 OK + sshx 13 OK。 * 修复 PR #551 contract-tests(clean-env):e2e fixture 设 META_ESCALATION_STUCK_HOURS 隔离 de-dup 测试 test_batch_and_per_task_lock_do_not_duplicate_spawn 在 clean env(CI)下失败:#506 meta- escalation 因 fixture mock 态被判 stuck 而 fire,产出 repository-stalled RunnerResult 污染 de-dup 断言(expected [] got [RunnerResult])。fixture host.env+env 设 META_ESCALATION_STUCK_ HOURS=999999 禁该测试的 meta-escalation,聚焦 de-dup 行为。断言未削弱。clean discovery 全过。 --------- * 修复 publish-gap:implement readiness 用 git status --porcelain 判 staged diff 原 classify_implement_attempt / wakeup_runner publish 前用 git diff --quiet 只检测 unstaged 改动;worker 正确 git add -A 后 staged diff 被误判 empty_scoped_diff,导致完成的 implement (如 #553 干净 EXIT=0 + 885 行真实 staged diff + 有效 title/body artifacts)永远出不了 PR, wakeup_runner 对 children 反复空转 re-dispatch。改为先 git status --porcelain 判 staged/ unstaged/untracked 任一即 publish-ready,只有真干净才 fallback git diff。publish-time 建 PR 路径不变(不重蹈 #507 early-PR 空 commit/placeholder 死锁)。 * 实现 issue #552 * PR #558 remote-ci-fix output * 移除 #552 越界加的孤立 flaky phase9-router 测试 fb2f461(#552 实现)给未改动的 phase9 router 加了 test_phase9_router_tick_summary_is_ router_local_diagnostic,与 #552「收窄 restart daemon 权威」scope 无关,且该测试 call self.router.tick() 不 mock managed-work-snapshot fetch → CI 无 GitHub 时 fetch-failed 诊断行污染输出致 anchored regex 不匹配(flaky),挡 CI。main 从无此测试。按删除优先+scope 收口移除;若 router 诊断测试有价值应在 phase9-focused PR 以 hermetic 形式正式加。 --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* #471 hotfix: wakeup_plan completed-marker 投影按 open-managed 集过滤,closed/merged target 不投影(止血 graphql:消除 wakeup_runner 对已终结 target 的逐条重校验)
* #410: SKILL/prompt 注释改引 durable contract anchor,不引用一次性 .refactor-loop/runs/*;新增 test_generated_artifacts_not_authority 窄 source-regression (#472)
* #471 hotfix2: wakeup-plan 同一 target 只投影最新有效 marker,旧轮次不再投影 dispatchable action(止 graphql backoff 最后一刀)
* skill: 强化 no-gap 规则 — 0 codex + active work 无观察模式豁免,必须当 turn 立即介入派 codex(+source-regression)
* #470: direct-post prompt 渲染时 fixed-token 内联 _github-post-rules,host worktree cwd 可达(避免裸相对路径) (#479)
* #478 hotfix: daemon spawn 改 launch-and-forget 独立 supervisor(start_new_session 不 wait),daemon reload 不丢 in-flight worker;daemon 每 tick 清晰状态行
* #471: wakeup-plan latest-open-fresh 投影 — completed-marker open-target/latest + release-rollup 仅 latest-per-sha 且 ahead>0 本地 ref 验证(止 stale 投影/graphql) (#482)
* #481: consensus->implement readiness-dedup gate(止 daemon 重派 closed/has-PR/in-flight) (#486)
* #481: consensus->implement readiness-dedup gate, closed/closing-PR/remote-branch/in-flight target 不投影 dispatchable, 止重复/race
* #481 fix r1: dedup gate 复用 concurrency monitor owner surface 测量 in-flight,不重实现 daemon 算法(addr architect)
* #481 fix r2: 补 controller helper guard behavior test(addr tests)
* #485: consensus->implement 按 scope_paths 冲突分组串行(同组一个 executable,其余 status_only),复用 batching-heuristics,防并行冲突 PR (#489)
* #475: wakeup-runner WakeupApplyBudget — spawn-worker action 按 hard_gate.dispatch_required 批量到 floor deficit(lifecycle action 仍 1/tick),修 1/tick 线性恢复 (#492)
* hotfix(#475 ext): batch budget 纳入 dispatch_design_consensus —— solver triplet 一 tick 派齐(非 lifecycle,worker 派发),修 design-consensus 仍 1/tick 低并发
* hotfix: headless spawn-intent launch — skipped duplicate 不再 break 整批 spawn,stale applied ledger(log 缺失)可重试,helper_exit:3 加来源诊断事件;修 248 intent 堆积/0 并发
* hotfix r2: blocked lifecycle action 不再 dead-stop 整 tick — 跳过/抑制 stale blocked(close-drop target OPEN / publish 无 verified head)继续 launch 后续 spawn-batch,使 headless 并发拉到 floor
* hotfix r3: 根治 headless 0 并发 — detached spawn-codex launch 显式传 env_for_subprocess(修 #478 decouple 丢 env 致 EXIT=127);失败 log(非0 EXIT)可重试 launch,EXIT=0/未完成仍抑制重复;tick 状态汇总后续 launch 不被首个 blocked 掩盖
* hotfix r4: run_once 通用 blocked-not-dead-stop — 任何 blocked/skipped non-spawn action 不再 dead-stop 整 tick,继续 launch 后续 spawn-batch;wakeup-plan 抑制 precondition 注定失败的 stale action;根治 headless 并发=0
* hotfix r5: wakeup-plan 投影侧 suppress stale close_managed_drop(target 实际 OPEN 的 drop-close 注定失败)为 status_only,不再占 tick 挡住后续 design-consensus spawn launch
* hotfix r6: wakeup-runner run_once 不再把 no-intents 的 dispatch_design_consensus(helper_exit:3)误判为 codex launch failure dead-stop 整 tick
根因:dispatch_design_consensus 是 spawn-batch action;当 solver triplet 不完整(如 #496 minimal/structural EXIT=0 但未 emit SOLVER_DONE marker)时 helper 返回 exit 3(NO_INTENTS),_spawn_launch_failure 命中 "helper_exit:" 前缀判 True → run_once break,整 tick dead-stop,后续 reviewers/其他 design-consensus/implement 全部不派 → headless 并发=0。
修法:run_once 中 blocked 的 spawn-batch action 若 controller_action != spawn_codex_harness_background(即 dispatch_design_consensus),按 routing no-op skip-and-continue,继续 launch 后续 spawn-batch;仅真正 spawn_codex_harness_background launch failure 才走既有 retry/break。延续 r4 blocked-not-dead-stop 不变量到 design-consensus spawn-batch action。
behavior test: test_wakeup_runner_design_consensus_no_intents_does_not_dead_stop_later_spawn_batch(无修复时 later spawn 不 launch 而 FAIL)。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* hotfix r7: review head_sha binding — 打通 headless review→merge 自驱
根因:reviewer artifact frontmatter 不带 head_sha,_review_evidence_from_artifact 取不到所审 head SHA → 所有 reviewing PR(#480/#473/#402)恒判 WAIT_OR_REDISPATCH:invalid_reviewer_evidence:missing_reviewed_head_sha,且 wakeup-plan 不自动重派 reviewer → review→merge headless 永久卡死(挡住发版)。
修法(codex hotfix worker 实现,controller 验证后提交):
- controller_actions 派 reviewer 时取 headRefOid,缺则 fail-closed,注入权威 HEAD_SHA 进 rendered prompt。
- reviewer-{architect,tests,quality}.md frontmatter 写 head_sha: ${HEAD_SHA}。
- wakeup_runner._review_head_sha_for:artifact 缺 head_sha 时从 controller-rendered prompt/log 回收(不依赖 worker 自报,避免 markerless 覆辙);live-head 陈旧判定与 merge 真值表语义不变。
- wakeup_plan 为 missing/stale reviewer head 的 OPEN reviewing PR 投射可执行 dispatch_reviewers 自愈动作。
验证:controller 独立重跑 test_wakeup_runner+review_gate+wakeup_plan+controller_actions 293 通过、marker/prompt 合同 30 通过;review-gate 安全语义(stale head 仍不 merge)由 13 项 review-gate 测试锁住。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* hotfix r8: 让 review-evidence-redispatch 自愈动作可执行 — 打通 headless review→merge 闭环
承接 r7:r7 让 reviewer 证据绑定 head_sha,但 wakeup_plan 投射的 review-evidence-redispatch 自愈动作被 closed-action-projection finalizer 强制 status_only(其 kind 不在 EXECUTABLE_ACTION_KINDS),runner 永不应用 → #480/#473/#402 缺 head 的 review 证据无法自动重派 → review_gate 恒 WAIT_OR_REDISPATCH → 并发耗干到 0。
修法(codex hotfix worker 实现,controller 验证后提交):
- wakeup_plan EXECUTABLE_ACTION_KINDS 加 review-evidence-redispatch,finalizer 保留 runner authority 不再强制 status_only。
- controller_actions.dispatch_reviewers 读 stale_review_roles 只重派陈旧角色,且 _pending_review_spawn_exists 跳过已有在飞 dispatch-reviewers:<pr>:<role>:r1 intent(幂等不双派);仍走 r7 的 HEAD_SHA 注入,使重派 reviewer 的新证据 head-bound。
- merge-gate 真值表不变,仅让既有自愈动作可执行 + 定向到陈旧角色。
验证:controller 独立重跑 test_wakeup_plan+wakeup_runner+review_gate+controller_actions 295 通过。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* hotfix r9: reviewer 重派 bump 到下一轮 + 绝对 cd + latest-evidence-per-role — 真正打通 headless review→merge
根因(同一类:按"产物存在"而非"成功+区分维度"抑制):reviewer 重派硬编码回 r1,撞上旧 head 早先成功(EXIT=0)的 r1 log → _harness_spawn_intent_log_suppresses_retry 判"做过了"抑制 → 当前 head 该重跑的 review 永不跑 → review_gate 恒 WAIT_OR_REDISPATCH → 并发 0。且 intent cd 是相对 "." → headless 启动层不投射。
最小修法(按 maintainer directive:文件名即唯一 id,不加 wrapper --id,留在现有 r<R> 命名约定内不改公开命名):
- controller_actions.dispatch_reviewers:_next_review_round 取该 PR/role 现有最大轮 +1,渲染 r<N+1> 的 prompt/log/output/intent;pending-spawn 幂等 guard 按真实轮号;_append_harness_spawn_intent 的 cd 改 str(cd.resolve()) 绝对路径,使 headless 投射+启动成立。
- wakeup_plan.latest_reviewer_heads / wakeup_runner._latest_review_evidence_by_role:改为"每 role 取各自最新轮证据"(而非全局最新单轮),使只重派陈旧 role 时不丢其它 role 已 head-bound 的有效证据;merge 仍要求每 role 证据绑定 live head,安全语义不变。
验证:controller 独立重跑 test_wakeup_plan+wakeup_runner+review_gate+controller_actions 299 通过。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* hotfix r10: review_gate action 带上 reviewed head_sha + e2e 锁死 headless review→decision 全路
根因(review path head_sha 串接的第 5 处):wakeup_plan 投影 REVIEW_DONE 的 review_gate action 时只读 log 的 head(log 无 head)→ action.head_sha 空 → wakeup_runner._review_gate 卡 WAIT_OR_REDISPATCH:missing_action_reviewed_head_sha,证据虽已 head-bound 但 gate 连比都没法比。
修法(最小、按文件名即 id 思路):
- wakeup_plan.completed_marker_actions:REVIEW_DONE action 的 head_sha 改由 _review_done_action_head_sha 从权威证据面解析(latest_reviewer_heads 含 r7 prompt 注入的 head;或全 role head-bound 时取 live PR head;否则回落 log)。只从真实来源填充,不绕过 gate 的 head 比对,merge 安全语义不变。
- 新增 test_review_gate_e2e.py:从真实 wakeup_plan 投影 → WakeupRunner apply,断言 FIX(有 reject)与 MERGE(全 approve+CI 绿)两条具体决策落地——端到端锁死整条 review→decision,杜绝再冒隐藏层。
- test_wakeup_plan.py:加 prompt-bound reviewed head 的 planner 回归。
验证:controller 独立重跑 test_wakeup_plan+wakeup_runner+review_gate+controller_actions+review_gate_e2e 302 通过。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* hotfix r11: PrChecksProjection 对瞬时 gh-api 失败加 bounded retry — ready PR headless 走到 review_gate 决策
根因:review_gate 的 CI 读 PrChecksProjection.check_pr 对 gh api pulls/<n> 与 commits/<sha>/check-runs 的单次非零返回立即 fail-closed(ci_unavailable:pull_api_failure),无重试;rate limit 健康,实为瞬时 blip → 让 #473/#402(MERGEABLE+CI 绿)每 tick 被瞬时失败挡住、never reach MERGE/FIX。
修法(最小,只动 PrChecksProjection;不碰 #322 ReleaseRequiredChecksProjection):
- _run_api_read:对两处 api read 最多 3 次确定性重试(无 sleep),成功即停,持续失败仍 fail-closed(安全)。happy path 无行为变化。
- starvation 结论(worker 核实):review_gate 本就被 apply,blocked ci_unavailable 行可重评估(非 terminal duplicate-suppressed),无需改 run_once。
- e2e:test_review_gate_e2e 加「首次 pulls 读瞬时失败仍 merge」用例;test_pr_checks 加 retry 覆盖。
验证:controller 独立重跑 test_pr_checks+wakeup_runner+review_gate+review_gate_e2e+wakeup_plan+controller_actions 309 通过。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* hotfix r12: run_once 不再让 spawn-batch starve drain-only lifecycle — ready PR headless merge,backlog 能 drain
根因(已核实):wakeup_plan 每 tick 把 SPAWN actions(implement intent + design-consensus #495/#496/#490/#491/#418,index 0-5)排在 lifecycle review_gate(#480/#473/#402,index 6-8)之前;run_once 旧逻辑 `if applied_spawns>0 and not is_spawn_action: break` → 只要派了任一 spawn,首个 lifecycle 即 break 整 tick。design-consensus 几乎总有 spawn 活 → review_gate/merge 永远 starve → #473(approve/approve/comment → MERGE_WITH_COMMENTS,MERGEABLE+CI 绿)永不 merge,active 数永不下降。
修法(最小,核心 dispatch loop):
- 引入 consumes_spawn_budget = is_spawn_action or _uses_spawn_budget(action);超 budget 时 `continue`(不 break)以便仍能抵达后续 drain-only lifecycle。
- _uses_spawn_budget:dispatch_reviewers=True、review_gate 仅当决策为 FIX(会派 fix worker)=True;否则 review_gate(MERGE/MERGE_WITH_COMMENTS)、close 等 drain-only=False → 不占 spawn budget、floor 填满后仍被评估执行。
- 保留 r6 的 spawn launch-failure break/retry 与 dispatch_design_consensus no-intents skip-and-continue;真值表/head-binding/CI-green/mergeable 安全语义不变。
结果:每 tick 既用 spawn 填满 floor,又评估 merge/close 等 drain-only lifecycle,backlog 能 drain。
验证:controller 独立重跑 test_wakeup_runner+review_gate+review_gate_e2e+wakeup_plan+controller_actions+pr_checks 309 通过;新增 test_wakeup_runner_lifecycle_review_gate_not_starved_after_spawn_batch。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* hotfix r13: 修 WakeupRunner._run_command 把 --repo 注入到 gh 子命令前致全部 gh 调用 malformed — review→merge 根因
根因(实测确认):_run_command 对所有 gh 命令在 full[1:1] 插 --repo(子命令之前)。gh 不接受 --repo 作 pre-subcommand 全局 flag,且 gh api 根本不吃 --repo(repo 在 URL):`gh --repo O/R api repos/O/R/pulls/473` → rc=1 "unknown flag: --repo"。于是 wakeup-runner 的每个 gh 调用都 malformed:CI 读(PrChecksProjection(runner=_run_command) 的 gh api pulls/check-runs)→ ci_unavailable:pull_api_failure;mergeability(gh pr view)→ mergeability_unavailable;live-state 等同理。→ review gate 永远读不到 CI/mergeable → #473(approve/approve/comment=MERGE_WITH_COMMENTS,绿)、#402、#480 永不 headless 落地。r11 的 retry 只是重复同一 malformed 命令。直连 PrChecksProjection()/直连 gh 用的是 plain default runner(无注入)所以正常,掩盖了 bug。
最小修法:_run_command 仅对 `gh pr`/`gh issue` 注入 --repo,且放在子命令(及其 verb)之后的合法位置;`gh api` 完全不动;绝不 pre-subcommand 注入;已存在 --repo 则不重复。
验证:controller 独立重跑 test_wakeup_runner+review_gate+review_gate_e2e+pr_checks+wakeup_plan+controller_actions 312 通过;新增 argv-shape 测试 + e2e(stub subprocess.run 拒绝 malformed `gh --repo ... api`,ready PR 仍 merge)。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* hotfix r14: managed draft PR ready-then-merge — review gate 不再硬挡 pr_draft
根因(r13 修好 gh 调用后浮现):review_gate 的 _review_gate_mergeability_error 把 isDraft=True 当 WAIT_OR_REDISPATCH:pr_draft 硬挡。但本 loop draft-until-consensus:PR 开为 draft 直到 review 共识,merge_pr 在决策 MERGE/MERGE_WITH_COMMENTS 时 ready-then-merge。于是绿 gate 的 managed draft(如 #473 approve/approve/comment)永远卡 pr_draft、永不 headless 落地。
最小修法:
- wakeup_runner:删除 mergeability 检查里的 isDraft→pr_draft 硬挡(仍挡 mergeable!=MERGEABLE,即 CONFLICTING/DIRTY)。
- controller_actions.merge_pr:对 live draft PR 先校验 crnd:lifecycle:managed 再 gh pr ready(非 managed draft 不 ready,写 CONTROLLER_ACTION_BLOCKED:target-not-managed 并返回 2);保留既有 ready-then-merge。
- 真值表/head-binding/CI-green/conflicting-blocks 安全语义不变;readying 仅限 managed PR。
验证:controller 独立重跑 test_wakeup_runner+review_gate+review_gate_e2e+controller_actions+wakeup_plan+pr_checks 316 通过;新增 managed-draft merge + 真实 plan→runner→controller ready-then-merge e2e + conflicting/非managed 安全用例。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* #409: 移除 .refactor-loop/host.env runtime fallback,CONSENSUS_RND_HOST_ENV 为唯一 host fact locator(缺失 fail-closed);迁移依赖 legacy fallback 的 test fixture (#473)
* hotfix r15 (sshx 共识 B 之一): 统一 gh argv 构造到单一 build_gh_argv helper — 防 r13 类 --repo bug 复发
sshx 一致共识 B 的硬化第1步:把分散重复的 gh --repo 处理收口到 codex_refactor_loop/gh_invoke.py 的 build_gh_argv(slug, argv):gh api 永不加 --repo(repo 在 URL);gh pr/issue 仅在 subcommand 之后、缺失时加 --repo <slug>;绝不 pre-subcommand。wakeup_runner._run_command / ControllerActions.gh / PrChecksProjection 三处 API 调用全部改走该 helper,删除各自的内联 --repo 启发式。行为保持不变(含 r13 修复)。
验证:characterization + source-regression 锁在 test_gh_invoke.py(9 测试);controller 独立重跑 test_gh_invoke+pr_checks+wakeup_runner+review_gate+review_gate_e2e+controller_actions+wakeup_plan 326 通过;pr_checks 直跑 --help 兼容。
注:这是硬化(防复发),不直接提升并发;并发瓶颈在上游 implement→publish 阶段,接下来单独处理。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* hotfix r16 (sshx 共识): 打通 implement→publish 解锁并发瓶颈 — markerless/stale implement 重派 + 安全门控发布
sshx codex-cli triplet 共识(minimal/structural/delete + meta-judge):10 个 design-solving issue 已达成共识但卡在 implement→publish(implement 早跑过却 markerless/未提交/过期 base/没 PR;dispatch_consensus_implementation 被 local_iter_branch 抑制、publish 被 verified_pr_head_unavailable 抑制)→ 无新可派工作 → 并发 ~1。
修法(wakeup_plan/wakeup_runner/controller_actions/git.py):
- success-aware 重派:implement 分支/worktree 存在但无 valid clean IMPLEMENT_DONE:ok marker(markerless/failed)或 base 过期 → 重派;fresh_safe_worktree 把 canonical worktree reset/recreate 到当前 origin/$INTEGRATION_BRANCH;仅 genuine in-flight / 已有干净 PR / 待发布 clean marker 才抑制。
- 发布门控(严防误发 stale/wrong-scope):publish_implementation_output 仅在 canonical identity(refactor/iter<issue>-<candidate> + worktree 实际分支匹配)+ fresh integration base(merge-base==origin/integration,过期 base block)+ managed open issue + 无重复 PR + 非空 scoped diff 时,commit→push→open PR→派 reviewers;否则 block。
- wakeup_plan 用 canonical_implementation_identity/single_linked_managed_issue/clean_scoped_diff 替代 verified_pr_head 抑制。
验证:controller 独立重跑 wakeup_plan+wakeup_runner+review_gate+review_gate_e2e+controller_actions+pr_checks+gh_invoke 330 通过。
已知待修(follow-up):worker 把 PR title/body/commit 文案改成英文,违反「GitHub artifact 中文」策略,下一 commit 恢复中文。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* hotfix r17: fresh consensus-implement 重派前清除 terminal 非可发布 implement log — 让卡住的 implement 真正启动
承接 r16:r16 让 markerless/stale implement 重派(reset worktree),但旧的 EXIT=1/markerless implement log 仍占 spawn 的 target_log_absent 前置 → fresh implement 不启动(同一类「按存在抑制」,implement-spawn-log 层)。
修法(controller_actions,success-aware):fresh consensus-implementation dispatch 写 spawn intent 前,仅清除 terminal 非可发布 implement log(EXIT!=0 失败 / EXIT=0 无 IMPLEMENT_DONE:ok marker);保留 genuinely in-flight(无 EXIT)与 clean publish-ready(EXIT=0 + 干净 marker)log 不动。于是卡住的 markerless/failed implement 重派后能真正 launch、跑在 fresh base、产出干净 marker → r16 门控发布。
验证:controller 独立重跑 wakeup_plan+wakeup_runner+review_gate+review_gate_e2e+controller_actions+pr_checks+gh_invoke 333 通过。
设计说明:并发瓶颈用确定性逻辑修对(ready=clean EXIT=0+marker;parallel=scope_paths 不相交),不引入 LLM-in-loop 分发判断(daemon-first;sshx codex 三人组一致 revise:LLM 最多 shadow-mode,不入决策回路)。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* hotfix r18: implement-lifecycle 收敛为单一 success-aware 谓词 + runner 路径自清陈旧 log — headless 自愈,不再需手动清 log
承接 r16/r17(r17 把清 log 放进被抑制的 dispatch 路径,从没执行)。新增 implement_lifecycle.py 单一事实源 classify_implement_attempt → in_flight | publish_ready | redispatch,plan/runner/controller 共用:
- runner spawn-apply 路径 _spawn_log_suppresses_retry 仅在 in_flight|publish_ready 时抑制;redispatch(EXIT!=0/markerless/stale-base) 不抑制且 _clear_redispatchable_spawn_log 在 spawn 实际应用处清掉陈旧终态 log → fresh implement 真启动(修 r17 misplacement,免手动清)。
- publish 仅 publish_ready(clean IMPLEMENT_DONE:ok + canonical identity + fresh base + 非空 scoped diff);clean-marker 但 stale-base 改 redispatch 而非死锁(#421 edge)。
- 确定性逻辑(非 LLM-in-loop;daemon-first);merge-gate/#191/#322/#396 安全语义不变。
验证:controller 独立重跑 wakeup_plan+wakeup_runner+review_gate+review_gate_e2e+controller_actions+pr_checks+gh_invoke 339 通过。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* 修复 phase9-router triplet-evidence-invalid 误判致 headless design-consensus wedge
solver prompt 注入的 issue source snapshot 含上一轮 design-consensus 的
audit-trail(peer solver log 路径)时,_peer_solver_reference_violation
扫描整个 prompt 误判为 peer-isolation 违规,fail-closed 拒派 meta-judge,
使所有 body 含历史 consensus 记录的 issue 永久 wedge。
修复:peer-isolation 扫描只覆盖 router-controlled 区域,剥离
'## Issue source snapshot' 到 '## Full solver template' 之间的 issue
作者内容;router header / solver template 注入的真实 peer 引用仍拦截。
加两个 behavior test 覆盖 snapshot-排除 与 router-区域-仍拦截。
dogfood headless 实测:reload 后 418/437/474/490/491/493/494/495 全部
恢复 solver→judge→consensus 自驱,#494 已自驱到 implement。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* CLAUDE.md: 加 consensus-rnd:foundational-invariants sentinel block
dogfood bootstrap 的 check-project-rules probe 要求 PROJECT_RULES 含此
fixed-point block;缺失时 probe fail-closed 阻断 headless restart。内容
为 probe 生成的 canonical FI-001~007,镜像既有设计哲学,不引入新约束。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* 修复 markerless implement 致 publish 卡死的 headless gap
implement worker 干净退出(EXIT=0)但把 IMPLEMENT_DONE marker 只写进 run
artifact(runs/implement-issue-<id>.md)而非 log 末尾时(codex stdout marker
落点不可靠),completed_marker_actions 只扫 log marker → markerless → 不生成
publish action → design→implement→PR 链卡在 implement 后。实测 #421:EXIT=0
+ artifact 有 IMPLEMENT_DONE:issue-421:ok + 9 文件 staged,却无 PR、label 仍
停在 design-solving。
修复:对 clean-exit 的 implement-issue log,log markerless 时 fallback 读取
run artifact 末尾的 IMPLEMENT_DONE marker,复用 review verdict 已有的
artifact-first 模式。窄作用域(仅 implement-issue + clean-exit),配 2 个
behavior test;全套 wakeup_plan 138 tests green。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* 补全 markerless implement publish:revalidation 也读 run artifact marker
8aeea89 修了 wakeup_plan detection 端,但 wakeup-runner 的 source-marker
revalidation(_source_log_has_clean_marker)仍只扫 log,markerless implement
publish 仍被 reject(clean_exit_marker_missing)。补全:revalidation 对
clean-exit implement-issue log 在 log markerless 时 fallback 读
runs/implement-issue-<id>.md 的 marker,与 detection 端一致;配 behavior test,
全套 wakeup_runner 76 tests green。
注:dogfood 实测确认 markerless 是系统性病根(还影响 readiness 重派、review
verdict 等多处),应走系统性统一(见 #491 日志/observability 与后续 marker-reading
收口);本 commit 只补 implement publish 这条链。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* 日志详细化:wakeup-runner tick 显示全状态计数 + 被掩盖的 blocked/skipped 详情
旧 _wakeup_tick_action 只看 results[0],一个 tick 处理多 action 时 blocked(如
publish 失败)被成功的 spawn 掩盖、完全不可见;graphql-backoff 固定显示误导的
'remaining=unknown'。dogfood 调试时这逼得每次翻 ledger 才知道真实发生了什么。
改:tick log 显示 [applied=N,blocked=M,...] 全状态计数 + 被掩盖的 blocked/skipped
具体 reason+action(graphql-backoff 作整-tick 门控单独报、去掉 unknown);dispatched
headline 保留。更新 test 反映可见性提升,全套 wakeup_runner 76 tests green。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* 补全 markerless implement 第三环:readiness 谓词读 run artifact marker
classify_implement_attempt(r18 单一 success-aware 谓词)只扫 log 找
IMPLEMENT_DONE:ok,markerless log(marker 落 artifact)→ redispatch:markerless →
readiness 不 suppress → 重派覆盖已完成工作(dogfood 实测 #421 重派 4 次、#493
IMPLEMENT_DONE:ok→重派→:partial 工作丢失)。
补全:markerless log 时 fallback 读 runs/implement-<cluster>.md 的
IMPLEMENT_DONE:ok,与 detection(8aeea89)/revalidation(dfacc64)一致。窄作用域 +
r17/r18 兼容:只接受 :ok,partial/失败/真 markerless(无 artifact)仍 redispatch
recovery — 现有 markerless-redispatch test(wakeup_plan/wakeup_runner/
controller_actions 共 304 tests)全绿,新增 2 behavior test。
至此 implement→PR 的 markerless 三环(detection/revalidation/readiness)打通;
review 链 markerless 与系统性统一抽象交 #499 共识。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* #500: design-consensus 编排重设计 — phase9-router 唯一派发 owner,删 wakeup-runner 双重派发
落地 #500 r4 consensus(structural framing,no-new-schema):
- phase9-router 成为唯一 design-consensus worker intent owner,新增
META_RESOLVED:re-design → marker.round+1 三路 solver route
- 删除 wakeup-runner 的 dispatch_design_consensus(消除双重派发 helper_exit:3)
- wakeup-runner 只保留 closed action apply(drop→close、consensus→implement)
- dispatch_consensus_implementation readiness 后转 crnd:phase:implementing
- 无新增 schema(复用 HARNESS_SPAWN_INTENT)
修复 headless P0:reflector META_RESOLVED 无 consumer + phase9-router/wakeup-runner
双重派发致 0-codex 死锁。14 文件 +207/-282;verification 471 tests 全绿。
共识由 controller 手动驱动 design-consensus r1→r4 达成(daemon 停止期间)。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* #501 fix r1: 补 dispatch_consensus_implementation label-transition failure-branch test
tests reviewer reject:新增 label transition(gh issue edit→implementing)只测 success
path,缺 gh issue edit 返回 nonzero 时 dispatch stop before worktree/render/intent 的
failure-branch test。本 fix 补该测试。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* 修复 headless 死锁:label 移除集只留 canonical crnd:*,删除历史 alias
gh issue/pr edit --remove-label 会因仓库不存在的 label 整条 rc=1 失败。
ISSUE_LABELS_REMOVE/PR_LABELS_REMOVE 含 cleanup_aliases(emoji/legacy 名),
仓库未维护这些历史 label,导致 _move_issue_to_implementing_phase 永久失败,
consensus→implement 派发卡死、wakeup_runner 0 codex 自驱死锁。
按 maintainer 指令删除历史 label 兼容(不再管历史标签):移除集只列
canonical crnd:* phase/human/stuck label。新增 source-regression 锁定
两集 canonical-only、无 alias。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* 修复 #500 回归:phase9-router 生产 ctx 丢失 GH_REPO_SLUG 致 design-consensus intake 全死
#500(e733b1a)把 Phase9Router.__init__ 的 ctx 构造从
`LoopContext.load(repo_root=repo_root)` 改成
`LoopContext.load(repo_root=repo_root, env={"REPO_ROOT": str(repo_root)})`。
受限 env 不读 os.environ,使 daemon(经 source host.env 启动)的 ctx
gh_repo_slug=None → `_open_design_consensus_issues` 第一行 fail-closed 返回 []
→ DesignConsensusIssueIntake 静默永不派 → headless 无法为任何 issue 启动
design-consensus;`_require_open_source_issue` 也因无 slug 失败(marker route
如 #490 redesign 卡在 phase9-source-state-unavailable)。
修复:revert 为 `LoopContext.load(repo_root=repo_root)`,读进程环境解析 host facts。
测试一律用 `Phase9Router(ctx=...)` 显式 ctx,不依赖受限 env;新增回归测试锁定
生产 repo_root 构造路径解析 GH_REPO_SLUG。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* 加 STALE_REVIVAL_HOURS:>阈值未推进的 stuck implement 自动 re-trigger(env 可配,默认 3h)
headless 下 partial/failed/markerless 的 implement log 会让已排队的
dispatch-consensus-implementation spawn intent 永久卡在 runner 的
target_log_absent 前置(清 log 的 dispatch_consensus_implementation 又被
pending_implement_intent 抑制)→ stuck implement 不会自愈(如 #421/494/493/474/498
的 10h partial-wedge)。
新增 host-tunable STALE_REVIVAL_HOURS(默认 3,非正/非法回落 3h)。wakeup_plan
投影 implement spawn intent 时,若目标 implement log 是 redispatchable
(partial/failed/markerless/stale-base)且 mtime 已超阈值,清掉它 →
target_log_absent 通过 → implement 自动重派。安全闸:in-flight(无终止 EXIT)永不清、
publish-ready(:ok+diff)不清、age-gate 防误清刚跑完的。
env 已登记进 SKILL.md host env surface matrix + host.env.example;5 个 behavior
test + matrix↔example 对称测试覆盖。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* 扩展 stale-revival 覆盖死 codex:in_flight 无 EXIT 且 >阈值 + 不在存活清单 也 re-trigger
最常见的 headless wedge 是 codex/supervisor 中途死亡(如 daemon 被 kill 截断),
log 永远停在 in_flight(无终止 EXIT)→ classify 永判 in_flight → 永不 redispatch。
之前只清 redispatchable(partial/failed/markerless)log,漏了这半边。
现在 _revive_stale_redispatchable_implement_log 在 log mtime 超阈值时,先按
redispatchable 清;否则若 classify 为 in_flight 且 monitor 存活清单里无该 log 的
活进程,则判定为死 worker 清掉。安全性:spawn-codex 的 no-output stall 窗口远小于
默认 3h,故 >阈值仍 in_flight 的 log 必是死 supervisor;再加 monitor 存活校验
双保险,绝不杀活 codex。新增 3 个 behavior test(死 codex revive / fresh 不碰 /
活进程不碰)。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* 加手动 trigger:consensus-rnd-cli revive-implements(立即 re-trigger 卡住的 implement,不等阈值)
_revive_stale_redispatchable_implement_log 加 force 参数:跳过 stale_revival_seconds()
age gate,但 in_flight log 在 force 下必须经 monitor 存活校验证明无活进程才清(绝不杀
正在跑的 codex)。新增 force_revive_stuck_implements() 扫所有 implement-issue-*.log
强制 revive,和新 CLI 命令 revive-implements(authority delete-log)。auto 路径
force=False 不变。新增 4 个 behavior test。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* 修 env 泄漏:测试套件 import 时隔离 ambient host.env(worktree 里跑 TEST_CMD 不再假失败)
daemon spawn 的 implement worker 在 worktree 里跑完整 TEST_CMD 时,继承的相对
CONSENSUS_RND_HOST_ENV=.config/consensus-rnd/host.env 泄漏进 temp-repo
LoopContext.load(repo_root=tmp) → 解析成 tmp/.config/... 不存在 → 假
LoopContextError(实测 concurrency_monitor 48 + restart_daemons 23 + … ≈151 errors)
→ 全套永不绿 → implement 永远 :partial → 进不了 PR。
unittest discover 在 collection 阶段先 import 所有 test_*.py 再跑;新增
test_aaa_host_env_isolation.py(字母序最先)在 import 时 pop 掉 host 注入变量,
全套在任何测试 run 前即隔离。验证:full discover 设 locator 跑 → exit 0 全绿
(此前 同条件 151 errors);targeted before/after 证 48/23/1 errors → OK。
纯测试模块,不碰 production/daemon。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* 修 markerless keystone:solver/judge marker 加 companion-artifact fallback
solver/judge codex 有时 EXIT=0 但 SOLVER_DONE/META_JUDGE_DONE marker 只落 run
artifact、没在 log 末尾,导致 phase9-router 判 triplet 不完整、永不派 judge,
design-consensus 轮卡死(实测 #505 r1 structural 214 次嵌入、0 次行首)。
把已有的 implement artifact-marker fallback 扩到 solver/judge:clean-exit log
末尾无独立 marker 时,从 companion run artifact runs/<log-stem>.md 兜底读。纯
additive(log 有 marker 时行为不变)、prefix-scoped、精确 filename regex、复用
安全的独立 marker 提取(不信嵌入/echo)。不削弱共识(仍要 3 marked solver +
judge,只让 marker 来源更稳健)。phase9/router.py + wakeup_plan.py + behavior +
source-regression tests;full suite 1367 green。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* 修 publish stale-base 无恢复 + 停 :ok churn:让 implementing 能发出 draft PR
implement :ok 但 worktree base 落后 origin/$INTEGRATION_BRANCH 时,publish 原本硬
block(publish_implementation_stale_base)且永不恢复;stale-revival 又把 stale-base
的 :ok implement 当 redispatchable 反复重派同一 stale worktree → 无限 churn 占满
floor、长时间零正式 PR(implement→首个 PR 永远开不出)。
改为:publish 前在 worktree merge origin/$INTEGRATION_BRANCH 恢复 base(冲突则
merge --abort + 明确 reason 交既有 resolver/re-dispatch);clean `:ok` 不再被
stale-revival churn(终态成功走 publish-with-recovery,不重跑);无 open PR 的 :ok
创建 draft PR(per #300 共识前 draft)+ Closes #N。controller 仍拥有 git topology,
worker 不 commit/push,不绕 review-gate/merge 真值表。controller_actions.py +
wakeup_plan.py + wakeup_runner.py + behavior/source-regression tests;full suite
1374 green。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* 修 markerless implement:EXIT=0+真diff 无干净 marker 时合成 publish 候选,止 stale-revival 空重派死循环
publish build/test 闸做安全网。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* 修 publish 顺序 bug + merge 失败派 codex 兜底 resolver:先 commit worker diff 再 merge fresh base,真冲突不 wedge 改派 resolver,幂等续跑
空判据改 git diff HEAD;顺带修 wakeup_plan stale-suppression 同类 git diff 问题。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* 实现 issue #504 (#519)
* 修 headless review-fix prompt 渲染不全:绑定全部 placeholder(PR_NUMBER/标题/轮次/分支/REVIEW_*_PATH 等),解锁 reject PR 的 fix→merge
之前 headless _dispatch_review_fix 只绑 FIX_OUTPUT_PATH,其余 ${} 未解析致 fix codex 读不到 reject 证据。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* 实现 issue #496 (#520)
* 修 review-fix codex 派到 main 的 cd bug:改在 PR worktree 跑,worktree 缺失 fail-closed
之前 _dispatch_review_fix cd=repo_root → fix 改 main(污染 daemon checkout)且不落 PR 分支(reject PR 永不 merge)。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* 实现 issue #508 (#523)
* 修 wakeup-plan action 排序:review_gate/publish 排到新工作 spawn 前,解 spawn-budget 饿死→reject PR 可被 fix→merge
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* CLAUDE.md 加宪法工程规则:异常必抛出+记可诊断日志严禁吞掉/静默;测试必断言真实行为禁无意义测试(maintainer 指令)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* 实现 issue #503 (#521)
* 增加通用工程基本规则,明确面向对象设计要求及实现细则
* 实现 issue #514 (#524)
* 完善通用面向对象设计准则,增加核心原则与实现层细则
* 实现 issue #494 (#526)
* 实现 issue #517 (#528)
* 实现 issue #505 (#510)
* 实现 issue #505
* #510 fix r1:补 phase9-router 行为测试覆盖(应对 tests reviewer reject)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* 修复 headless FIX_DONE 不提交 fix 输出 gap:wakeup-runner 在 FIX_DONE re-review 前先 commit+push fix worktree
headless 下 fix codex 产出 FIX_DONE 但 worker 从不 commit,FIX_DONE 直接路由 dispatch_reviewers,
fix 输出永远留在 worktree 未提交,reviewers 永远审旧 head,reject 不收敛,阻断所有需 fix 轮的 PR
review→merge。镜像 interactive controller:FIX_DONE 源的 dispatch_reviewers 前,若 fix worktree
dirty 则 git add+commit+safe_push,clean 则 no-op。附 2 个 behavior test(dirty 提交/clean 跳过)。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* 实现 issue #491 (#531)
* 实现 issue #490 (#529)
* 实现 issue #490
* 实现 issue #490
* PR #529 review-fix output
* 实现 issue #499 (#512)
* 实现 issue #499
* PR #512 review-fix output
* 实现 issue #474 (#532)
* 实现 issue #474
* 实现 issue #474
* 实现 issue #474
* 实现 issue #474
* PR #532 review-fix output
* 实现 issue #476 (#518)
* 实现 issue #476
* PR #518 review-fix output
* 实现 issue #509 (#527)
* 实现 issue #509
* 实现 issue #509
* spawn-claim recycle 改用 artifact-aware terminal marker:companion log 被 24h retention 删除后,已完成任务的 claim 仍可回收(读 runs/ artifact),不再永久阻断重派;running 任务无终止 marker 仍不回收(防 double-spawn)
* 实现 issue #421:发行前 clean-room 集成测试制度 (#534)
* 实现 issue #421
* rebase #421 onto fresh integration:解决 test_cli_command_router 冲突 + 校验
* 实现 issue #493:测试纪律修宪(behavior-first) (#535)
* 实现 issue #493
* rebase #493 onto fresh integration:解决冲突 + 校验
* PR #535 review-fix r1:addressed tests+quality reject(behavior-first test 调整)
* 实现 issue #506 (#536)
* 实现 issue #506
* 实现 issue #506
* 实现 issue #506
* 实现 issue #506
* PR #536 review-fix output
* churn 根治:wakeup-plan 给 consensus-impl spawn-intent 套 open_closing_pr/terminal/in-flight 抑制(对齐 dispatch_consensus_implementation),已有 PR 的 issue 不再被重派 implement
* 实现 issue #507 (#525)
* 实现 issue #507
* 实现 issue #507
* PR #525 review-fix output
* 实现 issue #516 (#530)
* 实现 issue #516
* 实现 issue #516
* #530 fix r1:补 ManagedWorkSnapshot fetch-failure stale-cache fallback 行为测试(应对 tests reviewer reject)
* PR #530 review-fix output
* PR #530 review-fix r2:typed ManagedWorkItem projection(addresses architect 类型边界 reject + tests + contract-tests)
* PR #530 review-fix r3:anchor ManagedWorkSnapshot read surface in authorization mirror + cross-artifact source-regression(addresses architect governance reject)
* PR #530 review-fix r4:add canonical+legacy managed-label discovery regression test(addresses tests reject)
* 修复 worker marker reader 误判相同重复 marker 为冲突
codex 常把终止 marker 回显 2-3 次(含 diff + 前缀行),导致
read_worker_terminal_marker 返回 duplicate_or_conflicting,review 真值表
永不收敛、所有 headless review→merge 卡死。改为:相同重复 marker 折叠为
有效,仅当存在 2+ 个不同 marker 值才判 duplicate_or_conflicting。
覆盖 _last_final_marker / _sentinel_adjacent_marker /
_marker_from_companion_artifact,保留 malformed 与 foreign-prefix 检测。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* Reserve implementation PR for issue #537 (#540)
⟦AI:AUTO-LOOP⟧
* 实现 issue #511 (#522)
* 实现 issue #511
* PR #522 review-fix output
* PR #522 review-fix output
* 移除误入 PR 的 .refactor-loop 运行 artifact(architect r8 reject)
resolve-pr522-merge.md 是一次性合并解决 summary,属生成物,不应进 durable diff
(CLAUDE.md「生成物不当事实源」)。解决说明保留在 commit message / PR body。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* 修复早期 PR reservation 崩溃(#511 回归,阻断所有 implement 派发)
_reserve_implementation_pr 用 worker 富正文路径开 reservation PR,但该文件在
reservation 时尚不存在 → FileNotFoundError(未被 except RuntimeError 捕获)→
wakeup-runner tick 崩溃 → 任何 consensus issue 无法 implement → loop P0 wedge。
修复:reservation 前若 body 缺失则写占位正文(## issue #N 实现 + Closes + sentinel,
publish 会拒占位逼 worker 产真正文);reservation 幂等(已有 open PR 直接返回;
已有 remote head 则 reset 到 integration + force-with-lease push);捕获 OSError。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* Reserve implementation PR for issue #543 (#544)
⟦AI:AUTO-LOOP⟧
* Reserve implementation PR for issue #541 (#546)
⟦AI:AUTO-LOOP⟧
* revert early-PR reservation(#507):不再开空占位 PR,publish 出真内容才开 PR
dispatch_consensus_implementation 不再 reserve/开 PR;publish_implementation_output
恢复 pre-#507 行为——implement 出非空 diff 才 commit+push+open_pr_with_label(用 worker
真 title/body,验证非占位);空 diff 不开 PR、不 merge、不关 issue。删除占位机制
(_reserve_implementation_pr / _placeholder_*),改 wakeup_plan/runner 的 early_pr_missing 投影。
根因:空占位 PR 被 reviewer 在 implement publish 前空合,假性关闭 #537/#541/#543。
全量套件 1496 passed。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* 实现 issue #542:删除 redispatch payload 冗余 head_sha (#547)
移除 review redispatch 的重复 head_sha payload
* hotfix: stale consensus-implement intent 指向已删 worktree 不再 suppress fresh re-dispatch
consensus_implementation_suppressed_reason 的 pending_implement_intent 分支增加 worktree 存在性
守卫(接入既有 _canonical_consensus_worktree_exists):仅当 stale pending intent 的 canonical
worktree 仍存在时才 suppress。revert early-PR reservation(#507)后,#537/#541/#543 的 pending
implement intent 指向已删除 worktree,旧逻辑 suppress fresh re-dispatch,而 wakeup-runner 不断把
stale intent spawn 进死 cd 致 os error 2 / EXIT=1 死循环,阻断 consensus→implement 自主链路。
现 worktree 缺失即放行 fresh dispatch 重建 worktree。
补 test_wakeup_plan(worktree 缺失不 suppress / worktree 存在仍 suppress)+ 更新
test_controller_actions 锁旧行为的 subTest(pending case 建 canonical worktree 以保留
reject-before-fresh_safe_worktree 意图)。全套件 1557 passed。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* hotfix: spawn-claim lock 持有者 pid 已死即可回收(自愈,防 cleared-log 永久 HELD)
_existing_claim_is_recyclable 增加 pid-liveness 回退:当 lock 记录的持有者 pid 已死(os.kill
pid 0 抛 ProcessLookupError)时即可回收,保留既有 terminal-marker 回收与 live-spawn 保护
(pid 存活+无 marker 仍不回收)+ metadata-mismatch fail-closed。根因:implement 失败(EXIT=1)
留 stale lock,dispatch_consensus_implementation 重派时清掉 log → #490 spawn-claim 只在 log 有
EXIT= 时回收 → cleared log 无 marker → 死进程 lock 无法回收 → SPAWN_CLAIM_HELD 永久死锁,
阻断 consensus→implement 重派(#537/#541/#543)。补 7 个 behavior test。全套件 1560 passed。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* hotfix: publish_implementation_output 接受 worker 已 commit 的实现 diff
_require_publish_implementation_diff 之前只看 git diff HEAD --quiet(未提交改动),
worker 一旦自己 commit(在自己分支上,隔离无害)工作区就 clean → 误判 no_diff → 不开 PR。
现改为:有未提交改动 OR HEAD 相对 integration base 有 committed delta(merge-base..HEAD 非空)
即视为有 diff 可发;_commit_publish_implementation_diff 在工作区已 clean(worker 已 commit)时
跳过提交返回成功,不再误报 publish_commit_failed。修 #541 类 worker-commit→no_diff→无 PR+
daemon 重复 dispatch。补 behavior test。codex 全套件 DISCOVER_STATUS:0 通过。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* 实现 issue #437: .refactor-loop 历史生成物与陈旧 worktree 的有界清理机制 (#548)
* #437: 新增 canonical RuntimeRetention owner,log-retention 降为一版 alias;清理覆盖 generated files+pending-events compaction+stale worktree;CLAUDE.md 加 #437 narrow carveout
* PR #548 review-fix output
* PR #548 review-fix output
* PR #548 review-fix output
* PR #548 review-fix output
* PR #548 review-fix output
* hotfix: CONFLICTING managed review PR 的 stale-base 冲突自主 resolve
接线既有但孤儿的 prompts/rebase-resolve.md 进 headless 路径:managed review PR
mergeable=CONFLICTING(base 落后)时,controller 在 PR worktree 起 git merge
--no-commit --no-ff origin/<integration>——干净则直接 commit+push,有冲突则派
rebase-resolve codex(隔离 worktree 内解+stage,禁 commit/push),收到
REBASE_RESOLVE_DONE 后 controller commit + safe_push 仅推 PR head。结果再过 CI+
review-gate 把关。新增 dispatch_pr_rebase_resolve / commit_push_resolved_pr_rebase
(controller_actions)+ wakeup_plan 投影 + wakeup_runner 应用。
安全:只动 refactor/iter<N>-* PR 分支,显式 guard 拒碰 integration/review_base,
diff-filter=U 验未解冲突才 commit,任何 abort 路径 git merge --abort 留干净 worktree,
幂等(已含 base / 解析在飞则 NOOP)。修 stale-base churn 致 loop 永久停滞(一个 PR
合了其它全 CONFLICTING 无人解)的根因。codex 全套件 1589 passed。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* hotfix: rebase_resolve_actions 投影前 enrich live mergeability(修生产 gap)
自主-resolve 投影读 item.mergeable 前未 enrich,但生产 GhItem 来自 snapshot
mergeable 为空 → 永远 skip → CONFLICTING PR 不投影 dispatch_pr_rebase_resolve →
loop 仍停滞。复用同文件 _with_live_mergeability(review_evidence_redispatch_actions
已用同模式)。补 mergeable-为空-需-live-fetch 的回归测试(原测试 mock 了 mergeable
未覆盖此生产路径)。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* hotfix: dispatch_pr_rebase_resolve kind 进 EXECUTABLE_ACTION_KINDS(end-to-end 可执行)
_close_projection_action 的 else 分支默认 status_only=True;rebase action 的 kind
stale-base-conflicting-pr 不在 EXECUTABLE_ACTION_KINDS → 永远 status_only,runner 不
apply,CONFLICTING PR 永不自主 resolve。加该 kind(+ commit_push completion kind 如需)
进集合;controller_action 已在 RUNNER_NAMED_HELPER_ACTIONS 故随即保持 executable。补
端到端 wakeup-plan pipeline 测试(原测试只测 rebase_resolve_actions 单函数,漏了 closed-
action-projection 的 status_only 关卡)。codex 全套件 1593 passed。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* hotfix: rebase-resolve commit/dispatch 投影 gate 在实际 worktree merge 态(止 stale-marker 噪音)
commit_push_resolved_pr_rebase 之前只凭持久 REBASE_RESOLVE_DONE marker 投影,worktree
已 commit+push(#549)或 abort(#550/#551)后 marker 仍在 → 每 tick fail-closed 噪音 +
反复 0-codex(zero_streak 触警)+ stale marker 挡 #550/#551 fresh resolve。现 gate:仅当
worktree 真有 merge-in-progress(MERGE_HEAD)且无 unmerged 才投 executable commit_push;
否则不投。并让 worktree clean + 仍 CONFLICTING 的 PR 重新拿 executable dispatch_pr_rebase_resolve
(stale DONE marker 不再永久压制)。补端到端测试。codex 全套件通过。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* 实现 issue #502: 删除遗留 label 兼容层:purge emoji/legacy alias 全套(cleanup_aliases / per-spec (#549)
* 实现 issue #502: 删除遗留 label 兼容层:purge emoji/legacy alias 全套(cleanup_aliases / per-spec
* 修复 PR #549 review r3:#502 label-purge 适配当前 label 代码(contract-tests + architect/tests reject)
fix codex round-3 applied-4:对齐 #502 遗留 label 兼容层 purge 与近期新增 label 代码,
修 contract-tests 失败 + architect/tests reject。改 labels.py + SKILL.md + test_wakeup_plan.py。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* 修复 headless review_gate ci_failed 死锁:reject→FIX 移到 ci/mergeability 检查前
_review_gate_decision 之前 ci_error/mergeability 检查在 reject>0→FIX 之前 → CI 红的 PR
即使 reviewer reject 也返回 WAIT_OR_REDISPATCH:ci_failed 干等,而 CI 不修不会绿 → 死锁
(#548/#549 都中,需手动派 fix 破解)。把 reject>0→FIX 移到 ci/mergeability 检查前
(仍在 reviewer-validity/head 检查之后)→ reject 时即使 CI 红也自主派 fix(fix 同解 reject+CI)。
MERGE/MERGE_WITH_COMMENTS 判定完全不变(仍需 ci-green + mergeable + reject=0 + approve>=1),
无误合并风险。补 test_wakeup_runner 端到端测试(reject+ci-red→FIX;reject=0+ci-red 仍 WAIT;
happy path MERGE 不变;stale-head+reject 仍 WAIT)。full suite 1600 passed。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* 修正 review_gate 顺序:mergeability 检查移到 reject→FIX 之前(CONFLICTING 不并发 review/fix)
上一修复(a125d19)把 reject→FIX 移到 ci+mergeability 前,破了 ci_failed 死锁但也让
CONFLICTING+reject 的 PR 路由到 FIX → 与独立的 dispatch_pr_rebase_resolve 并发跑同一
worktree(#550 出现 98-file mid-merge + reviewer 并发)。把 mergeability_error 检查移到
reject→FIX 之前:CONFLICTING→WAIT(先 rebase-resolve,不并发 review/fix);MERGEABLE+
CI红+reject→FIX(死锁修复保留);ci_error 仍在 reject→FIX 后(纯 CI 红无 reject 才 WAIT)。
MERGE 判定不变。test_wakeup_runner 90 OK(+conflicting 用例)。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* 实现 issue #498: headless daemon fail-closed 点的 codex 兜底裁决/生成机制(narrow allowlist,非通用 es (#550)
* 实现 issue #498
* 实现 issue #498: headless daemon fail-closed 点的 codex 兜底裁决/生成机制(narrow allowlist,非通用 es
* PR #550 review-fix output
* 新增 patrol-inspector 巡检 issue intake (#551)
* 实现 issue #541
* PR #551 review-fix output
* PR #551 review-fix output
* 修复 PR #551 contract-tests:对齐 patrol 第8 daemon + safe_push/sync_dev 测试 host.env
#551 patrol 新增 patrol_inspector_daemon(第8 daemon)→ test_anti_stop_restart 期望 7→8;
test_controller_lib_safe_push / test_sync_dev 补 CONSENSUS_RND_HOST_ENV host.env 设置
(代码按 host-config contract 需 host.env locator,rebase-resolve 丢了 base 新测试版本)。
断言未削弱(daemon 数断言强化为8)。full discovery 1634 OK + sshx 13 OK。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* 修复 PR #551 contract-tests(clean-env):e2e fixture 设 META_ESCALATION_STUCK_HOURS 隔离 de-dup 测试
test_batch_and_per_task_lock_do_not_duplicate_spawn 在 clean env(CI)下失败:#506 meta-
escalation 因 fixture mock 态被判 stuck 而 fire,产出 repository-stalled RunnerResult 污染
de-dup 断言(expected [] got [RunnerResult])。fixture host.env+env 设 META_ESCALATION_STUCK_
HOURS=999999 禁该测试的 meta-escalation,聚焦 de-dup 行为。断言未削弱。clean discovery 全过。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* 修复 publish-gap:implement readiness 用 git status --porcelain 判 staged diff
原 classify_implement_attempt / wakeup_runner publish 前用 git diff --quiet 只检测 unstaged
改动;worker 正确 git add -A 后 staged diff 被误判 empty_scoped_diff,导致完成的 implement
(如 #553 干净 EXIT=0 + 885 行真实 staged diff + 有效 title/body artifacts)永远出不了 PR,
wakeup_runner 对 children 反复空转 re-dispatch。改为先 git status --porcelain 判 staged/
unstaged/untracked 任一即 publish-ready,只有真干净才 fallback git diff。publish-time 建 PR
路径不变(不重蹈 #507 early-PR 空 commit/placeholder 死锁)。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* 修复 patrol_inspector daemon 启动崩溃:DaemonHeartbeatLease 用构造函数非 from_env
#551 patrol.py daemon 分支调 DaemonHeartbeatLease.from_env()(不存在的方法)→
AttributeError 启动即崩,daemon 从未成功跑起来。改为 DaemonHeartbeatLease(
"patrol_inspector_daemon", ctx.repo_root),与 closed_label_reconciler/wakeup_runner
一致,心跳文件名匹配 restart 助手期待的 patrol_inspector_daemon.ts。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* 修复 publish-gap 残留层:duplicate-marker log 读 companion artifact + 取代 superseded spawn intent
层2 残留:implement worker 把 IMPLEMENT_DONE:issue-N:ok 在 log 里 echo 多次→
worker_markers 返回 duplicate_or_conflicting_log_marker fail-closed→classifier 当
markerless 且不查 companion artifact→无 completed-marker action→无 publish→stale
harness-spawn-intent:dispatch-consensus-implementation:N 残留致 pending_implement_intent。
修:(1) classify_implement_attempt / completed_marker_actions 遇 duplicate marker 时
narrow 读 companion .refactor-loop/runs/implement-*.md(仅 implement log,仅末 30 行恰好
1 个 IMPLEMENT_DONE:ok 才接受);(2) suppress_publish_superseded_implementation_spawn_intents:
仅当某 issue 已有 executable publish_implementation_output 才把对应 dispatch-consensus-
implementation spawn intent 抑制为 status_only(implementation_ready_to_publish)。
不重蹈 #507 死锁:只在 publish 已 ready 后抑制 spawn(不漏派)、publish 仍全验证(不提前/
重复)、wakeup-runner/publish 授权口径不变。live 验证 #553 现投影 executable publish。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* 实现 issue #555 (#557)
* 修复 publish-gap 第3层:wakeup_runner clean_exit revalidation 对 duplicate-marker log 复用 artifact-fallback
pubgap2 修了 plan 侧 duplicate-marker artifact-fallback,但 wakeup_runner 的
_source_log_has_clean_marker(clean_exit_source_marker 预条件 revalidation)仍用严格
reader,对 #553 duplicate IMPLEMENT_DONE echo 返回 clean_exit_marker_missing→阻 publish。
改为严格 reader 优先,仅当 duplicate_or_conflicting_log_marker + is_implement_log +
_implement_run_artifact_done_marker 精确匹配 projected marker 才 fallback。复用 plan 侧
同一 helper,不弱化安全门(reviewer/release/rebase/非 implement/其它 fail reason 保持严格)。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* 实现 issue #553
* PR #561 review-fix output
* PR #561 remote-ci-fix output
* PR #561 review-fix output
* 收窄 restart daemon 权威到 owner-local 命令面 (#558)
* #471 hotfix: wakeup_plan completed-marker 投影按 open-managed 集过滤,closed/merged target 不投影(止血 graphql:消除 wakeup_runner 对已终结 target 的逐条重校验)
* #410: SKILL/prompt 注释改引 durable contract anchor,不引用一次性 .refactor-loop/runs/*;新增 test_generated_artifacts_not_authority 窄 source-regression (#472)
* #471 hotfix2: wakeup-plan 同一 target 只投影最新有效 marker,旧轮次不再投影 dispatchable action(止 graphql backoff 最后一刀)
* skill: 强化 no-gap 规则 — 0 codex + active work 无观察模式豁免,必须当 turn 立即介入派 codex(+source-regression)
* #470: direct-post prompt 渲染时 fixed-token 内联 _github-post-rules,host worktree cwd 可达(避免裸相对路径) (#479)
* #478 hotfix: daemon spawn 改 launch-and-forget 独立 supervisor(start_new_session 不 wait),daemon reload 不丢 in-flight worker;daemon 每 tick 清晰状态行
* #471: wakeup-plan latest-open-fresh 投影 — completed-marker open-target/latest + release-rollup 仅 latest-per-sha 且 ahead>0 本地 ref 验证(止 stale 投影/graphql) (#482)
* #481: consensus->implement readiness-dedup gate(止 daemon 重派 closed/has-PR/in-flight) (#486)
* #481: consensus->implement readiness-dedup gate, closed/closing-PR/remote-branch/in-flight target 不投影 dispatchable, 止重复/race
* #481 fix r1: dedup gate 复用 concurrency monitor owner surface 测量 in-flight,不重实现 daemon 算法(addr architect)
* #481 fix r2: 补 controller helper guard behavior test(addr tests)
* #485: consensus->implement 按 scope_paths 冲突分组串行(同组一个 executable,其余 status_only),复用 batching-heuristics,防并行冲突 PR (#489)
* #475: wakeup-runner WakeupApplyBudget — spawn-worker action 按 hard_gate.dispatch_required 批量到 floor deficit(lifecycle action 仍 1/tick),修 1/tick 线性恢复 (#492)
* hotfix(#475 ext): batch budget 纳入 dispatch_design_consensus —— solver triplet 一 tick 派齐(非 lifecycle,worker 派发),修 design-consensus 仍 1/tick 低并发
* hotfix: headless spawn-intent launch — skipped duplicate 不再 break 整批 spawn,stale applied ledger(log 缺失)可重试,helper_exit:3 加来源诊断事件;修 248 intent 堆积/0 并发
* hotfix r2: blocked lifecycle action 不再 dead-stop 整 tick — 跳过/抑制 stale blocked(close-drop target OPEN / publish 无 verified head)继续 launch 后续 spawn-batch,使 headless 并发拉到 floor
* hotfix r3: 根治 headless 0 并发 — detached spawn-codex launch 显式传 env_for_subprocess(修 #478 decouple 丢 env 致 EXIT=127);失败 log(非0 EXIT)可重试 launch,EXIT=0/未完成仍抑制重复;tick 状态汇总后续 launch 不被首个 blocked 掩盖
* hotfix r4: run_once 通用 blocked-not-dead-stop — 任何 blocked/skipped non-spawn action 不再 dead-stop 整 tick,继续 launch 后续 spawn-batch;wakeup-plan 抑制 precondition 注定失败的 stale action;根治 headless 并发=0
* hotfix r5: wakeup-plan 投影侧 suppress stale close_managed_drop(target 实际 OPEN 的 drop-close 注定失败)为 status_only,不再占 tick 挡住后续 design-consensus spawn launch
* hotfix r6: wakeup-runner run_once 不再把 no-intents 的 dispatch_design_consensus(helper_exit:3)误判为 codex launch failure dead-stop 整 tick
根因:dispatch_design_consensus 是 spawn-batch action;当 solver triplet 不完整(如 #496 minimal/structural EXIT=0 但未 emit SOLVER_DONE marker)时 helper 返回 exit 3(NO_INTENTS),_spawn_launch_failure 命中 "helper_exit:" 前缀判 True → run_once break,整 tick dead-stop,后续 reviewers/其他 design-consensus/implement 全部不派 → headless 并发=0。
修法:run_once 中 blocked 的 spawn-batch action 若 controller_action != spawn_codex_harness_background(即 dispatch_design_consensus),按 routing no-op skip-and-continue,继续 launch 后续 spawn-batch;仅真正 spawn_codex_harness_background launch failure 才走既有 retry/break。延续 r4 blocked-not-dead-stop 不变量到 design-consensus spawn-batch action。
behavior test: test_wakeup_runner_design_consensus_no_intents_does_not_dead_stop_later_spawn_batch(无修复时 later spawn 不 launch 而 FAIL)。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* hotfix r7: review head_sha binding — 打通 headless review→merge 自驱
根因:reviewer artifact frontmatter 不带 head_sha,_review_evidence_from_artifact 取不到所审 head SHA → 所有 reviewing PR(#480/#473/#402)恒判 WAIT_OR_REDISPATCH:invalid_reviewer_evidence:missing_reviewed_head_sha,且 wakeup-plan 不自动重派 reviewer → review→merge headless 永久卡死(挡住发版)。
修法(codex hotfix worker 实现,controller 验证后提交):
- controller_actions 派 reviewer 时取 headRefOid,缺则 fail-closed,注入权威 HEAD_SHA 进 rendered prompt。
- reviewer-{architect,tests,quality}.md frontmatter 写 head_sha: ${HEAD_SHA}。
- wakeup_runner._review_head_sha_for:artifact 缺 head_sha 时从 controller-rendered prompt/log 回收(不依赖 worker 自报,避免 markerless 覆辙);live-head 陈旧判定与 merge 真值表语义不变。
- wakeup_plan 为 missing/stale reviewer head 的 OPEN reviewing PR 投射可执行 dispatch_reviewers 自愈动作。
验证:controller 独立重跑 test_wakeup_runner+review_gate+wakeup_plan+controller_actions 293 通过、marker/prompt 合同 30 通过;review-gate 安全语义(stale head 仍不 merge)由 13 项 review-gate 测试锁住。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* hotfix r8: 让 review-evidence-redispatch 自愈动作可执行 — 打通 headless review→merge 闭环
承接 r7:r7 让 reviewer 证据绑定 head_sha,但 wakeup_plan 投射的 review-evidence-redispatch 自愈动作被 closed-action-projection finalizer 强制 status_only(其 kind 不在 EXECUTABLE_ACTION_KINDS),runner 永不应用 → #480/#473/#402 缺 head 的 review 证据无法自动重派 → review_gate 恒 WAIT_OR_REDISPATCH → 并发耗干到 0。
修法(codex hotfix worker 实现,controller 验证后提交):
- wakeup_plan EXECUTABLE_ACTION_KINDS 加 review-evidence-redispatch,finalizer 保留 runner authority 不再强制 status_only。
- controller_actions.dispatch_reviewers 读 stale_review_roles 只重派陈旧角色,且 _pending_review_spawn_exists 跳过已有在飞 dispatch-reviewers:<pr>:<role>:r1 intent(幂等不双派);仍走 r7 的 HEAD_SHA 注入,使重派 reviewer 的新证据 head-bound。
- merge-gate 真值表不变,仅让既有自愈动作可执行 + 定向到陈旧角色。
验证:controller 独立重跑 test_wakeup_plan+wakeup_runner+review_gate+controller_actions 295 通过。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* hotfix r9: reviewer 重派 bump 到下一轮 + 绝对 cd + latest-evidence-per-role — 真正打通 headless review→merge
根因(同一类:按"产物存在"而非"成功+区分维度"抑制):reviewer 重派硬编码回 r1,撞上旧 head 早先成功(EXIT=0)的 r1 log → _harness_spawn_intent_log_suppresses_retry 判"做过了"抑制 → 当前 head 该重跑的 review 永不跑 → review_gate 恒 WAIT_OR_REDISPATCH → 并发 0。且 intent cd 是相对 "." → headless 启动层不投射。
最小修法(按 maintainer directive:文件名即唯一 id,不加 wrapper --id,留在现有 r<R> 命名约定内不改公开命名):
- controller_actions.dispatch_reviewers:_next_review_round 取该 PR/role 现有最大轮 +1,渲染 r<N+1> 的 prompt/log/output/intent;pending-spawn 幂等 guard 按真实轮号;_append_harness_spawn_intent 的 cd 改 str(cd.resolve()) 绝对路径,使 headless 投射+启动成立。
- wakeup_plan.latest_reviewer_heads / wakeup_runner._latest_review_evidence_by_role:改为"每 role 取各自最新轮证据"(而非全局最新单轮),使只重派陈旧 role 时不丢其它 role 已 head-bound 的有效证据;merge 仍要求每 role 证据绑定 live head,安全语义不变。
验证:controller 独立重跑 test_wakeup_plan+wakeup_runner+review_gate+controller_actions 299 通过。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* hotfix r10: review_gate action 带上 reviewed head_sha + e2e 锁死 headless review→decision 全路
根因(review path head_sha 串接的第 5 处):wakeup_plan 投影 REVIEW_DONE 的 review_gate action 时只读 log 的 head(log 无 head)→ action.head_sha 空 → wakeup_runner._review_gate 卡 WAIT_OR_REDISPATCH:missing_action_reviewed_head_sha,证据虽已 head-bound 但 gate 连比都没法比。
修法(最小、按文件名即 id 思路):
- wakeup_plan.completed_marker_actions:REVIEW_DONE action 的 head_sha 改由 _review_done_action_head_sha 从权威证据面解析(latest_reviewer_heads 含 r7 prompt 注入的 head;或全 role head-bound 时取 live PR head;否则回落 log)。只从真实来源填充,不绕过 gate 的 head 比对,merge 安全语义不变。
- 新增 test_review_gate_e2e.py:从真实 wakeup_plan 投影 → WakeupRunner apply,断言 FIX(有 reject)与 MERGE(全 approve+CI 绿)两条具体决策落地——端到端锁死整条 review→decision,杜绝再冒隐藏层。
- test_wakeup_plan.py:加 prompt-bound reviewed head 的 planner 回归。
验证:controller 独立重跑 test_wakeup_plan+wakeup_runner+review_gate+controller_actions+review_gate_e2e 302 通过。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* hotfix r11: PrChecksProjection 对瞬时 gh-api 失败加 bounded retry — ready PR headless 走到 review_gate 决策
根因:review_gate 的 CI 读 PrChecksProjection.check_pr 对 gh api pulls/<n> 与 commits/<sha>/check-runs 的单次非零返回立即 fail-closed(ci_unavailable:pull_api_failure),无重试;rate limit 健康,实为瞬时 blip → 让 #473/#402(MERGEABLE+CI 绿)每 tick 被瞬时失败挡住、never reach MERGE/FIX。
修法(最小,只动 PrChecksProjection;不碰 #322 ReleaseRequiredChecksProjection):
- _run_api_read:对两处 api read 最多 3 次确定性重试(无 sleep),成功即停,持续失败仍 fail-closed(安全)。happy path 无行为变化。
- starvation 结论(worker 核实):review_gate 本就被 apply,blocked ci_unavailable 行可重评估(非 terminal duplicate-suppressed),无需改 run_once。
- e2e:test_review_gate_e2e 加「首次 pulls 读瞬时失败仍 merge」用例;test_pr_checks 加 retry 覆盖。
验证:controller 独立重跑 test_pr_checks+wakeup_runner+review_gate+review_gate_e2e+wakeup_plan+co…
* #471 hotfix: wakeup_plan completed-marker 投影按 open-managed 集过滤,closed/merged target 不投影(止血 graphql:消除 wakeup_runner 对已终结 target 的逐条重校验) * #410: SKILL/prompt 注释改引 durable contract anchor,不引用一次性 .refactor-loop/runs/*;新增 test_generated_artifacts_not_authority 窄 source-regression (#472) * #471 hotfix2: wakeup-plan 同一 target 只投影最新有效 marker,旧轮次不再投影 dispatchable action(止 graphql backoff 最后一刀) * skill: 强化 no-gap 规则 — 0 codex + active work 无观察模式豁免,必须当 turn 立即介入派 codex(+source-regression) * #470: direct-post prompt 渲染时 fixed-token 内联 _github-post-rules,host worktree cwd 可达(避免裸相对路径) (#479) * #478 hotfix: daemon spawn 改 launch-and-forget 独立 supervisor(start_new_session 不 wait),daemon reload 不丢 in-flight worker;daemon 每 tick 清晰状态行 * #471: wakeup-plan latest-open-fresh 投影 — completed-marker open-target/latest + release-rollup 仅 latest-per-sha 且 ahead>0 本地 ref 验证(止 stale 投影/graphql) (#482) * #481: consensus->implement readiness-dedup gate(止 daemon 重派 closed/has-PR/in-flight) (#486) * #481: consensus->implement readiness-dedup gate, closed/closing-PR/remote-branch/in-flight target 不投影 dispatchable, 止重复/race * #481 fix r1: dedup gate 复用 concurrency monitor owner surface 测量 in-flight,不重实现 daemon 算法(addr architect) * #481 fix r2: 补 controller helper guard behavior test(addr tests) * #485: consensus->implement 按 scope_paths 冲突分组串行(同组一个 executable,其余 status_only),复用 batching-heuristics,防并行冲突 PR (#489) * #475: wakeup-runner WakeupApplyBudget — spawn-worker action 按 hard_gate.dispatch_required 批量到 floor deficit(lifecycle action 仍 1/tick),修 1/tick 线性恢复 (#492) * hotfix(#475 ext): batch budget 纳入 dispatch_design_consensus —— solver triplet 一 tick 派齐(非 lifecycle,worker 派发),修 design-consensus 仍 1/tick 低并发 * hotfix: headless spawn-intent launch — skipped duplicate 不再 break 整批 spawn,stale applied ledger(log 缺失)可重试,helper_exit:3 加来源诊断事件;修 248 intent 堆积/0 并发 * hotfix r2: blocked lifecycle action 不再 dead-stop 整 tick — 跳过/抑制 stale blocked(close-drop target OPEN / publish 无 verified head)继续 launch 后续 spawn-batch,使 headless 并发拉到 floor * hotfix r3: 根治 headless 0 并发 — detached spawn-codex launch 显式传 env_for_subprocess(修 #478 decouple 丢 env 致 EXIT=127);失败 log(非0 EXIT)可重试 launch,EXIT=0/未完成仍抑制重复;tick 状态汇总后续 launch 不被首个 blocked 掩盖 * hotfix r4: run_once 通用 blocked-not-dead-stop — 任何 blocked/skipped non-spawn action 不再 dead-stop 整 tick,继续 launch 后续 spawn-batch;wakeup-plan 抑制 precondition 注定失败的 stale action;根治 headless 并发=0 * hotfix r5: wakeup-plan 投影侧 suppress stale close_managed_drop(target 实际 OPEN 的 drop-close 注定失败)为 status_only,不再占 tick 挡住后续 design-consensus spawn launch * hotfix r6: wakeup-runner run_once 不再把 no-intents 的 dispatch_design_consensus(helper_exit:3)误判为 codex launch failure dead-stop 整 tick 根因:dispatch_design_consensus 是 spawn-batch action;当 solver triplet 不完整(如 #496 minimal/structural EXIT=0 但未 emit SOLVER_DONE marker)时 helper 返回 exit 3(NO_INTENTS),_spawn_launch_failure 命中 "helper_exit:" 前缀判 True → run_once break,整 tick dead-stop,后续 reviewers/其他 design-consensus/implement 全部不派 → headless 并发=0。 修法:run_once 中 blocked 的 spawn-batch action 若 controller_action != spawn_codex_harness_background(即 dispatch_design_consensus),按 routing no-op skip-and-continue,继续 launch 后续 spawn-batch;仅真正 spawn_codex_harness_background launch failure 才走既有 retry/break。延续 r4 blocked-not-dead-stop 不变量到 design-consensus spawn-batch action。 behavior test: test_wakeup_runner_design_consensus_no_intents_does_not_dead_stop_later_spawn_batch(无修复时 later spawn 不 launch 而 FAIL)。 * hotfix r7: review head_sha binding — 打通 headless review→merge 自驱 根因:reviewer artifact frontmatter 不带 head_sha,_review_evidence_from_artifact 取不到所审 head SHA → 所有 reviewing PR(#480/#473/#402)恒判 WAIT_OR_REDISPATCH:invalid_reviewer_evidence:missing_reviewed_head_sha,且 wakeup-plan 不自动重派 reviewer → review→merge headless 永久卡死(挡住发版)。 修法(codex hotfix worker 实现,controller 验证后提交): - controller_actions 派 reviewer 时取 headRefOid,缺则 fail-closed,注入权威 HEAD_SHA 进 rendered prompt。 - reviewer-{architect,tests,quality}.md frontmatter 写 head_sha: ${HEAD_SHA}。 - wakeup_runner._review_head_sha_for:artifact 缺 head_sha 时从 controller-rendered prompt/log 回收(不依赖 worker 自报,避免 markerless 覆辙);live-head 陈旧判定与 merge 真值表语义不变。 - wakeup_plan 为 missing/stale reviewer head 的 OPEN reviewing PR 投射可执行 dispatch_reviewers 自愈动作。 验证:controller 独立重跑 test_wakeup_runner+review_gate+wakeup_plan+controller_actions 293 通过、marker/prompt 合同 30 通过;review-gate 安全语义(stale head 仍不 merge)由 13 项 review-gate 测试锁住。 * hotfix r8: 让 review-evidence-redispatch 自愈动作可执行 — 打通 headless review→merge 闭环 承接 r7:r7 让 reviewer 证据绑定 head_sha,但 wakeup_plan 投射的 review-evidence-redispatch 自愈动作被 closed-action-projection finalizer 强制 status_only(其 kind 不在 EXECUTABLE_ACTION_KINDS),runner 永不应用 → #480/#473/#402 缺 head 的 review 证据无法自动重派 → review_gate 恒 WAIT_OR_REDISPATCH → 并发耗干到 0。 修法(codex hotfix worker 实现,controller 验证后提交): - wakeup_plan EXECUTABLE_ACTION_KINDS 加 review-evidence-redispatch,finalizer 保留 runner authority 不再强制 status_only。 - controller_actions.dispatch_reviewers 读 stale_review_roles 只重派陈旧角色,且 _pending_review_spawn_exists 跳过已有在飞 dispatch-reviewers:<pr>:<role>:r1 intent(幂等不双派);仍走 r7 的 HEAD_SHA 注入,使重派 reviewer 的新证据 head-bound。 - merge-gate 真值表不变,仅让既有自愈动作可执行 + 定向到陈旧角色。 验证:controller 独立重跑 test_wakeup_plan+wakeup_runner+review_gate+controller_actions 295 通过。 * hotfix r9: reviewer 重派 bump 到下一轮 + 绝对 cd + latest-evidence-per-role — 真正打通 headless review→merge 根因(同一类:按"产物存在"而非"成功+区分维度"抑制):reviewer 重派硬编码回 r1,撞上旧 head 早先成功(EXIT=0)的 r1 log → _harness_spawn_intent_log_suppresses_retry 判"做过了"抑制 → 当前 head 该重跑的 review 永不跑 → review_gate 恒 WAIT_OR_REDISPATCH → 并发 0。且 intent cd 是相对 "." → headless 启动层不投射。 最小修法(按 maintainer directive:文件名即唯一 id,不加 wrapper --id,留在现有 r<R> 命名约定内不改公开命名): - controller_actions.dispatch_reviewers:_next_review_round 取该 PR/role 现有最大轮 +1,渲染 r<N+1> 的 prompt/log/output/intent;pending-spawn 幂等 guard 按真实轮号;_append_harness_spawn_intent 的 cd 改 str(cd.resolve()) 绝对路径,使 headless 投射+启动成立。 - wakeup_plan.latest_reviewer_heads / wakeup_runner._latest_review_evidence_by_role:改为"每 role 取各自最新轮证据"(而非全局最新单轮),使只重派陈旧 role 时不丢其它 role 已 head-bound 的有效证据;merge 仍要求每 role 证据绑定 live head,安全语义不变。 验证:controller 独立重跑 test_wakeup_plan+wakeup_runner+review_gate+controller_actions 299 通过。 * hotfix r10: review_gate action 带上 reviewed head_sha + e2e 锁死 headless review→decision 全路 根因(review path head_sha 串接的第 5 处):wakeup_plan 投影 REVIEW_DONE 的 review_gate action 时只读 log 的 head(log 无 head)→ action.head_sha 空 → wakeup_runner._review_gate 卡 WAIT_OR_REDISPATCH:missing_action_reviewed_head_sha,证据虽已 head-bound 但 gate 连比都没法比。 修法(最小、按文件名即 id 思路): - wakeup_plan.completed_marker_actions:REVIEW_DONE action 的 head_sha 改由 _review_done_action_head_sha 从权威证据面解析(latest_reviewer_heads 含 r7 prompt 注入的 head;或全 role head-bound 时取 live PR head;否则回落 log)。只从真实来源填充,不绕过 gate 的 head 比对,merge 安全语义不变。 - 新增 test_review_gate_e2e.py:从真实 wakeup_plan 投影 → WakeupRunner apply,断言 FIX(有 reject)与 MERGE(全 approve+CI 绿)两条具体决策落地——端到端锁死整条 review→decision,杜绝再冒隐藏层。 - test_wakeup_plan.py:加 prompt-bound reviewed head 的 planner 回归。 验证:controller 独立重跑 test_wakeup_plan+wakeup_runner+review_gate+controller_actions+review_gate_e2e 302 通过。 * hotfix r11: PrChecksProjection 对瞬时 gh-api 失败加 bounded retry — ready PR headless 走到 review_gate 决策 根因:review_gate 的 CI 读 PrChecksProjection.check_pr 对 gh api pulls/<n> 与 commits/<sha>/check-runs 的单次非零返回立即 fail-closed(ci_unavailable:pull_api_failure),无重试;rate limit 健康,实为瞬时 blip → 让 #473/#402(MERGEABLE+CI 绿)每 tick 被瞬时失败挡住、never reach MERGE/FIX。 修法(最小,只动 PrChecksProjection;不碰 #322 ReleaseRequiredChecksProjection): - _run_api_read:对两处 api read 最多 3 次确定性重试(无 sleep),成功即停,持续失败仍 fail-closed(安全)。happy path 无行为变化。 - starvation 结论(worker 核实):review_gate 本就被 apply,blocked ci_unavailable 行可重评估(非 terminal duplicate-suppressed),无需改 run_once。 - e2e:test_review_gate_e2e 加「首次 pulls 读瞬时失败仍 merge」用例;test_pr_checks 加 retry 覆盖。 验证:controller 独立重跑 test_pr_checks+wakeup_runner+review_gate+review_gate_e2e+wakeup_plan+controller_actions 309 通过。 * hotfix r12: run_once 不再让 spawn-batch starve drain-only lifecycle — ready PR headless merge,backlog 能 drain 根因(已核实):wakeup_plan 每 tick 把 SPAWN actions(implement intent + design-consensus #495/#496/#490/#491/#418,index 0-5)排在 lifecycle review_gate(#480/#473/#402,index 6-8)之前;run_once 旧逻辑 `if applied_spawns>0 and not is_spawn_action: break` → 只要派了任一 spawn,首个 lifecycle 即 break 整 tick。design-consensus 几乎总有 spawn 活 → review_gate/merge 永远 starve → #473(approve/approve/comment → MERGE_WITH_COMMENTS,MERGEABLE+CI 绿)永不 merge,active 数永不下降。 修法(最小,核心 dispatch loop): - 引入 consumes_spawn_budget = is_spawn_action or _uses_spawn_budget(action);超 budget 时 `continue`(不 break)以便仍能抵达后续 drain-only lifecycle。 - _uses_spawn_budget:dispatch_reviewers=True、review_gate 仅当决策为 FIX(会派 fix worker)=True;否则 review_gate(MERGE/MERGE_WITH_COMMENTS)、close 等 drain-only=False → 不占 spawn budget、floor 填满后仍被评估执行。 - 保留 r6 的 spawn launch-failure break/retry 与 dispatch_design_consensus no-intents skip-and-continue;真值表/head-binding/CI-green/mergeable 安全语义不变。 结果:每 tick 既用 spawn 填满 floor,又评估 merge/close 等 drain-only lifecycle,backlog 能 drain。 验证:controller 独立重跑 test_wakeup_runner+review_gate+review_gate_e2e+wakeup_plan+controller_actions+pr_checks 309 通过;新增 test_wakeup_runner_lifecycle_review_gate_not_starved_after_spawn_batch。 * hotfix r13: 修 WakeupRunner._run_command 把 --repo 注入到 gh 子命令前致全部 gh 调用 malformed — review→merge 根因 根因(实测确认):_run_command 对所有 gh 命令在 full[1:1] 插 --repo(子命令之前)。gh 不接受 --repo 作 pre-subcommand 全局 flag,且 gh api 根本不吃 --repo(repo 在 URL):`gh --repo O/R api repos/O/R/pulls/473` → rc=1 "unknown flag: --repo"。于是 wakeup-runner 的每个 gh 调用都 malformed:CI 读(PrChecksProjection(runner=_run_command) 的 gh api pulls/check-runs)→ ci_unavailable:pull_api_failure;mergeability(gh pr view)→ mergeability_unavailable;live-state 等同理。→ review gate 永远读不到 CI/mergeable → #473(approve/approve/comment=MERGE_WITH_COMMENTS,绿)、#402、#480 永不 headless 落地。r11 的 retry 只是重复同一 malformed 命令。直连 PrChecksProjection()/直连 gh 用的是 plain default runner(无注入)所以正常,掩盖了 bug。 最小修法:_run_command 仅对 `gh pr`/`gh issue` 注入 --repo,且放在子命令(及其 verb)之后的合法位置;`gh api` 完全不动;绝不 pre-subcommand 注入;已存在 --repo 则不重复。 验证:controller 独立重跑 test_wakeup_runner+review_gate+review_gate_e2e+pr_checks+wakeup_plan+controller_actions 312 通过;新增 argv-shape 测试 + e2e(stub subprocess.run 拒绝 malformed `gh --repo ... api`,ready PR 仍 merge)。 * hotfix r14: managed draft PR ready-then-merge — review gate 不再硬挡 pr_draft 根因(r13 修好 gh 调用后浮现):review_gate 的 _review_gate_mergeability_error 把 isDraft=True 当 WAIT_OR_REDISPATCH:pr_draft 硬挡。但本 loop draft-until-consensus:PR 开为 draft 直到 review 共识,merge_pr 在决策 MERGE/MERGE_WITH_COMMENTS 时 ready-then-merge。于是绿 gate 的 managed draft(如 #473 approve/approve/comment)永远卡 pr_draft、永不 headless 落地。 最小修法: - wakeup_runner:删除 mergeability 检查里的 isDraft→pr_draft 硬挡(仍挡 mergeable!=MERGEABLE,即 CONFLICTING/DIRTY)。 - controller_actions.merge_pr:对 live draft PR 先校验 crnd:lifecycle:managed 再 gh pr ready(非 managed draft 不 ready,写 CONTROLLER_ACTION_BLOCKED:target-not-managed 并返回 2);保留既有 ready-then-merge。 - 真值表/head-binding/CI-green/conflicting-blocks 安全语义不变;readying 仅限 managed PR。 验证:controller 独立重跑 test_wakeup_runner+review_gate+review_gate_e2e+controller_actions+wakeup_plan+pr_checks 316 通过;新增 managed-draft merge + 真实 plan→runner→controller ready-then-merge e2e + conflicting/非managed 安全用例。 * #409: 移除 .refactor-loop/host.env runtime fallback,CONSENSUS_RND_HOST_ENV 为唯一 host fact locator(缺失 fail-closed);迁移依赖 legacy fallback 的 test fixture (#473) * hotfix r15 (sshx 共识 B 之一): 统一 gh argv 构造到单一 build_gh_argv helper — 防 r13 类 --repo bug 复发 sshx 一致共识 B 的硬化第1步:把分散重复的 gh --repo 处理收口到 codex_refactor_loop/gh_invoke.py 的 build_gh_argv(slug, argv):gh api 永不加 --repo(repo 在 URL);gh pr/issue 仅在 subcommand 之后、缺失时加 --repo <slug>;绝不 pre-subcommand。wakeup_runner._run_command / ControllerActions.gh / PrChecksProjection 三处 API 调用全部改走该 helper,删除各自的内联 --repo 启发式。行为保持不变(含 r13 修复)。 验证:characterization + source-regression 锁在 test_gh_invoke.py(9 测试);controller 独立重跑 test_gh_invoke+pr_checks+wakeup_runner+review_gate+review_gate_e2e+controller_actions+wakeup_plan 326 通过;pr_checks 直跑 --help 兼容。 注:这是硬化(防复发),不直接提升并发;并发瓶颈在上游 implement→publish 阶段,接下来单独处理。 * hotfix r16 (sshx 共识): 打通 implement→publish 解锁并发瓶颈 — markerless/stale implement 重派 + 安全门控发布 sshx codex-cli triplet 共识(minimal/structural/delete + meta-judge):10 个 design-solving issue 已达成共识但卡在 implement→publish(implement 早跑过却 markerless/未提交/过期 base/没 PR;dispatch_consensus_implementation 被 local_iter_branch 抑制、publish 被 verified_pr_head_unavailable 抑制)→ 无新可派工作 → 并发 ~1。 修法(wakeup_plan/wakeup_runner/controller_actions/git.py): - success-aware 重派:implement 分支/worktree 存在但无 valid clean IMPLEMENT_DONE:ok marker(markerless/failed)或 base 过期 → 重派;fresh_safe_worktree 把 canonical worktree reset/recreate 到当前 origin/$INTEGRATION_BRANCH;仅 genuine in-flight / 已有干净 PR / 待发布 clean marker 才抑制。 - 发布门控(严防误发 stale/wrong-scope):publish_implementation_output 仅在 canonical identity(refactor/iter<issue>-<candidate> + worktree 实际分支匹配)+ fresh integration base(merge-base==origin/integration,过期 base block)+ managed open issue + 无重复 PR + 非空 scoped diff 时,commit→push→open PR→派 reviewers;否则 block。 - wakeup_plan 用 canonical_implementation_identity/single_linked_managed_issue/clean_scoped_diff 替代 verified_pr_head 抑制。 验证:controller 独立重跑 wakeup_plan+wakeup_runner+review_gate+review_gate_e2e+controller_actions+pr_checks+gh_invoke 330 通过。 已知待修(follow-up):worker 把 PR title/body/commit 文案改成英文,违反「GitHub artifact 中文」策略,下一 commit 恢复中文。 * hotfix r17: fresh consensus-implement 重派前清除 terminal 非可发布 implement log — 让卡住的 implement 真正启动 承接 r16:r16 让 markerless/stale implement 重派(reset worktree),但旧的 EXIT=1/markerless implement log 仍占 spawn 的 target_log_absent 前置 → fresh implement 不启动(同一类「按存在抑制」,implement-spawn-log 层)。 修法(controller_actions,success-aware):fresh consensus-implementation dispatch 写 spawn intent 前,仅清除 terminal 非可发布 implement log(EXIT!=0 失败 / EXIT=0 无 IMPLEMENT_DONE:ok marker);保留 genuinely in-flight(无 EXIT)与 clean publish-ready(EXIT=0 + 干净 marker)log 不动。于是卡住的 markerless/failed implement 重派后能真正 launch、跑在 fresh base、产出干净 marker → r16 门控发布。 验证:controller 独立重跑 wakeup_plan+wakeup_runner+review_gate+review_gate_e2e+controller_actions+pr_checks+gh_invoke 333 通过。 设计说明:并发瓶颈用确定性逻辑修对(ready=clean EXIT=0+marker;parallel=scope_paths 不相交),不引入 LLM-in-loop 分发判断(daemon-first;sshx codex 三人组一致 revise:LLM 最多 shadow-mode,不入决策回路)。 * hotfix r18: implement-lifecycle 收敛为单一 success-aware 谓词 + runner 路径自清陈旧 log — headless 自愈,不再需手动清 log 承接 r16/r17(r17 把清 log 放进被抑制的 dispatch 路径,从没执行)。新增 implement_lifecycle.py 单一事实源 classify_implement_attempt → in_flight | publish_ready | redispatch,plan/runner/controller 共用: - runner spawn-apply 路径 _spawn_log_suppresses_retry 仅在 in_flight|publish_ready 时抑制;redispatch(EXIT!=0/markerless/stale-base) 不抑制且 _clear_redispatchable_spawn_log 在 spawn 实际应用处清掉陈旧终态 log → fresh implement 真启动(修 r17 misplacement,免手动清)。 - publish 仅 publish_ready(clean IMPLEMENT_DONE:ok + canonical identity + fresh base + 非空 scoped diff);clean-marker 但 stale-base 改 redispatch 而非死锁(#421 edge)。 - 确定性逻辑(非 LLM-in-loop;daemon-first);merge-gate/#191/#322/#396 安全语义不变。 验证:controller 独立重跑 wakeup_plan+wakeup_runner+review_gate+review_gate_e2e+controller_actions+pr_checks+gh_invoke 339 通过。 * 修复 phase9-router triplet-evidence-invalid 误判致 headless design-consensus wedge solver prompt 注入的 issue source snapshot 含上一轮 design-consensus 的 audit-trail(peer solver log 路径)时,_peer_solver_reference_violation 扫描整个 prompt 误判为 peer-isolation 违规,fail-closed 拒派 meta-judge, 使所有 body 含历史 consensus 记录的 issue 永久 wedge。 修复:peer-isolation 扫描只覆盖 router-controlled 区域,剥离 '## Issue source snapshot' 到 '## Full solver template' 之间的 issue 作者内容;router header / solver template 注入的真实 peer 引用仍拦截。 加两个 behavior test 覆盖 snapshot-排除 与 router-区域-仍拦截。 dogfood headless 实测:reload 后 418/437/474/490/491/493/494/495 全部 恢复 solver→judge→consensus 自驱,#494 已自驱到 implement。 * CLAUDE.md: 加 consensus-rnd:foundational-invariants sentinel block dogfood bootstrap 的 check-project-rules probe 要求 PROJECT_RULES 含此 fixed-point block;缺失时 probe fail-closed 阻断 headless restart。内容 为 probe 生成的 canonical FI-001~007,镜像既有设计哲学,不引入新约束。 * 修复 markerless implement 致 publish 卡死的 headless gap implement worker 干净退出(EXIT=0)但把 IMPLEMENT_DONE marker 只写进 run artifact(runs/implement-issue-<id>.md)而非 log 末尾时(codex stdout marker 落点不可靠),completed_marker_actions 只扫 log marker → markerless → 不生成 publish action → design→implement→PR 链卡在 implement 后。实测 #421:EXIT=0 + artifact 有 IMPLEMENT_DONE:issue-421:ok + 9 文件 staged,却无 PR、label 仍 停在 design-solving。 修复:对 clean-exit 的 implement-issue log,log markerless 时 fallback 读取 run artifact 末尾的 IMPLEMENT_DONE marker,复用 review verdict 已有的 artifact-first 模式。窄作用域(仅 implement-issue + clean-exit),配 2 个 behavior test;全套 wakeup_plan 138 tests green。 * 补全 markerless implement publish:revalidation 也读 run artifact marker 8aeea89 修了 wakeup_plan detection 端,但 wakeup-runner 的 source-marker revalidation(_source_log_has_clean_marker)仍只扫 log,markerless implement publish 仍被 reject(clean_exit_marker_missing)。补全:revalidation 对 clean-exit implement-issue log 在 log markerless 时 fallback 读 runs/implement-issue-<id>.md 的 marker,与 detection 端一致;配 behavior test, 全套 wakeup_runner 76 tests green。 注:dogfood 实测确认 markerless 是系统性病根(还影响 readiness 重派、review verdict 等多处),应走系统性统一(见 #491 日志/observability 与后续 marker-reading 收口);本 commit 只补 implement publish 这条链。 * 日志详细化:wakeup-runner tick 显示全状态计数 + 被掩盖的 blocked/skipped 详情 旧 _wakeup_tick_action 只看 results[0],一个 tick 处理多 action 时 blocked(如 publish 失败)被成功的 spawn 掩盖、完全不可见;graphql-backoff 固定显示误导的 'remaining=unknown'。dogfood 调试时这逼得每次翻 ledger 才知道真实发生了什么。 改:tick log 显示 [applied=N,blocked=M,...] 全状态计数 + 被掩盖的 blocked/skipped 具体 reason+action(graphql-backoff 作整-tick 门控单独报、去掉 unknown);dispatched headline 保留。更新 test 反映可见性提升,全套 wakeup_runner 76 tests green。 * 补全 markerless implement 第三环:readiness 谓词读 run artifact marker classify_implement_attempt(r18 单一 success-aware 谓词)只扫 log 找 IMPLEMENT_DONE:ok,markerless log(marker 落 artifact)→ redispatch:markerless → readiness 不 suppress → 重派覆盖已完成工作(dogfood 实测 #421 重派 4 次、#493 IMPLEMENT_DONE:ok→重派→:partial 工作丢失)。 补全:markerless log 时 fallback 读 runs/implement-<cluster>.md 的 IMPLEMENT_DONE:ok,与 detection(8aeea89)/revalidation(dfacc64)一致。窄作用域 + r17/r18 兼容:只接受 :ok,partial/失败/真 markerless(无 artifact)仍 redispatch recovery — 现有 markerless-redispatch test(wakeup_plan/wakeup_runner/ controller_actions 共 304 tests)全绿,新增 2 behavior test。 至此 implement→PR 的 markerless 三环(detection/revalidation/readiness)打通; review 链 markerless 与系统性统一抽象交 #499 共识。 * #500: design-consensus 编排重设计 — phase9-router 唯一派发 owner,删 wakeup-runner 双重派发 落地 #500 r4 consensus(structural framing,no-new-schema): - phase9-router 成为唯一 design-consensus worker intent owner,新增 META_RESOLVED:re-design → marker.round+1 三路 solver route - 删除 wakeup-runner 的 dispatch_design_consensus(消除双重派发 helper_exit:3) - wakeup-runner 只保留 closed action apply(drop→close、consensus→implement) - dispatch_consensus_implementation readiness 后转 crnd:phase:implementing - 无新增 schema(复用 HARNESS_SPAWN_INTENT) 修复 headless P0:reflector META_RESOLVED 无 consumer + phase9-router/wakeup-runner 双重派发致 0-codex 死锁。14 文件 +207/-282;verification 471 tests 全绿。 共识由 controller 手动驱动 design-consensus r1→r4 达成(daemon 停止期间)。 * #501 fix r1: 补 dispatch_consensus_implementation label-transition failure-branch test tests reviewer reject:新增 label transition(gh issue edit→implementing)只测 success path,缺 gh issue edit 返回 nonzero 时 dispatch stop before worktree/render/intent 的 failure-branch test。本 fix 补该测试。 * 修复 headless 死锁:label 移除集只留 canonical crnd:*,删除历史 alias gh issue/pr edit --remove-label 会因仓库不存在的 label 整条 rc=1 失败。 ISSUE_LABELS_REMOVE/PR_LABELS_REMOVE 含 cleanup_aliases(emoji/legacy 名), 仓库未维护这些历史 label,导致 _move_issue_to_implementing_phase 永久失败, consensus→implement 派发卡死、wakeup_runner 0 codex 自驱死锁。 按 maintainer 指令删除历史 label 兼容(不再管历史标签):移除集只列 canonical crnd:* phase/human/stuck label。新增 source-regression 锁定 两集 canonical-only、无 alias。 * 修复 #500 回归:phase9-router 生产 ctx 丢失 GH_REPO_SLUG 致 design-consensus intake 全死 #500(e733b1a)把 Phase9Router.__init__ 的 ctx 构造从 `LoopContext.load(repo_root=repo_root)` 改成 `LoopContext.load(repo_root=repo_root, env={"REPO_ROOT": str(repo_root)})`。 受限 env 不读 os.environ,使 daemon(经 source host.env 启动)的 ctx gh_repo_slug=None → `_open_design_consensus_issues` 第一行 fail-closed 返回 [] → DesignConsensusIssueIntake 静默永不派 → headless 无法为任何 issue 启动 design-consensus;`_require_open_source_issue` 也因无 slug 失败(marker route 如 #490 redesign 卡在 phase9-source-state-unavailable)。 修复:revert 为 `LoopContext.load(repo_root=repo_root)`,读进程环境解析 host facts。 测试一律用 `Phase9Router(ctx=...)` 显式 ctx,不依赖受限 env;新增回归测试锁定 生产 repo_root 构造路径解析 GH_REPO_SLUG。 * 加 STALE_REVIVAL_HOURS:>阈值未推进的 stuck implement 自动 re-trigger(env 可配,默认 3h) headless 下 partial/failed/markerless 的 implement log 会让已排队的 dispatch-consensus-implementation spawn intent 永久卡在 runner 的 target_log_absent 前置(清 log 的 dispatch_consensus_implementation 又被 pending_implement_intent 抑制)→ stuck implement 不会自愈(如 #421/494/493/474/498 的 10h partial-wedge)。 新增 host-tunable STALE_REVIVAL_HOURS(默认 3,非正/非法回落 3h)。wakeup_plan 投影 implement spawn intent 时,若目标 implement log 是 redispatchable (partial/failed/markerless/stale-base)且 mtime 已超阈值,清掉它 → target_log_absent 通过 → implement 自动重派。安全闸:in-flight(无终止 EXIT)永不清、 publish-ready(:ok+diff)不清、age-gate 防误清刚跑完的。 env 已登记进 SKILL.md host env surface matrix + host.env.example;5 个 behavior test + matrix↔example 对称测试覆盖。 * 扩展 stale-revival 覆盖死 codex:in_flight 无 EXIT 且 >阈值 + 不在存活清单 也 re-trigger 最常见的 headless wedge 是 codex/supervisor 中途死亡(如 daemon 被 kill 截断), log 永远停在 in_flight(无终止 EXIT)→ classify 永判 in_flight → 永不 redispatch。 之前只清 redispatchable(partial/failed/markerless)log,漏了这半边。 现在 _revive_stale_redispatchable_implement_log 在 log mtime 超阈值时,先按 redispatchable 清;否则若 classify 为 in_flight 且 monitor 存活清单里无该 log 的 活进程,则判定为死 worker 清掉。安全性:spawn-codex 的 no-output stall 窗口远小于 默认 3h,故 >阈值仍 in_flight 的 log 必是死 supervisor;再加 monitor 存活校验 双保险,绝不杀活 codex。新增 3 个 behavior test(死 codex revive / fresh 不碰 / 活进程不碰)。 * 加手动 trigger:consensus-rnd-cli revive-implements(立即 re-trigger 卡住的 implement,不等阈值) _revive_stale_redispatchable_implement_log 加 force 参数:跳过 stale_revival_seconds() age gate,但 in_flight log 在 force 下必须经 monitor 存活校验证明无活进程才清(绝不杀 正在跑的 codex)。新增 force_revive_stuck_implements() 扫所有 implement-issue-*.log 强制 revive,和新 CLI 命令 revive-implements(authority delete-log)。auto 路径 force=False 不变。新增 4 个 behavior test。 * 修 env 泄漏:测试套件 import 时隔离 ambient host.env(worktree 里跑 TEST_CMD 不再假失败) daemon spawn 的 implement worker 在 worktree 里跑完整 TEST_CMD 时,继承的相对 CONSENSUS_RND_HOST_ENV=.config/consensus-rnd/host.env 泄漏进 temp-repo LoopContext.load(repo_root=tmp) → 解析成 tmp/.config/... 不存在 → 假 LoopContextError(实测 concurrency_monitor 48 + restart_daemons 23 + … ≈151 errors) → 全套永不绿 → implement 永远 :partial → 进不了 PR。 unittest discover 在 collection 阶段先 import 所有 test_*.py 再跑;新增 test_aaa_host_env_isolation.py(字母序最先)在 import 时 pop 掉 host 注入变量, 全套在任何测试 run 前即隔离。验证:full discover 设 locator 跑 → exit 0 全绿 (此前 同条件 151 errors);targeted before/after 证 48/23/1 errors → OK。 纯测试模块,不碰 production/daemon。 * 修 markerless keystone:solver/judge marker 加 companion-artifact fallback solver/judge codex 有时 EXIT=0 但 SOLVER_DONE/META_JUDGE_DONE marker 只落 run artifact、没在 log 末尾,导致 phase9-router 判 triplet 不完整、永不派 judge, design-consensus 轮卡死(实测 #505 r1 structural 214 次嵌入、0 次行首)。 把已有的 implement artifact-marker fallback 扩到 solver/judge:clean-exit log 末尾无独立 marker 时,从 companion run artifact runs/<log-stem>.md 兜底读。纯 additive(log 有 marker 时行为不变)、prefix-scoped、精确 filename regex、复用 安全的独立 marker 提取(不信嵌入/echo)。不削弱共识(仍要 3 marked solver + judge,只让 marker 来源更稳健)。phase9/router.py + wakeup_plan.py + behavior + source-regression tests;full suite 1367 green。 * 修 publish stale-base 无恢复 + 停 :ok churn:让 implementing 能发出 draft PR implement :ok 但 worktree base 落后 origin/$INTEGRATION_BRANCH 时,publish 原本硬 block(publish_implementation_stale_base)且永不恢复;stale-revival 又把 stale-base 的 :ok implement 当 redispatchable 反复重派同一 stale worktree → 无限 churn 占满 floor、长时间零正式 PR(implement→首个 PR 永远开不出)。 改为:publish 前在 worktree merge origin/$INTEGRATION_BRANCH 恢复 base(冲突则 merge --abort + 明确 reason 交既有 resolver/re-dispatch);clean `:ok` 不再被 stale-revival churn(终态成功走 publish-with-recovery,不重跑);无 open PR 的 :ok 创建 draft PR(per #300 共识前 draft)+ Closes #N。controller 仍拥有 git topology, worker 不 commit/push,不绕 review-gate/merge 真值表。controller_actions.py + wakeup_plan.py + wakeup_runner.py + behavior/source-regression tests;full suite 1374 green。 * 修 markerless implement:EXIT=0+真diff 无干净 marker 时合成 publish 候选,止 stale-revival 空重派死循环 publish build/test 闸做安全网。 * 修 publish 顺序 bug + merge 失败派 codex 兜底 resolver:先 commit worker diff 再 merge fresh base,真冲突不 wedge 改派 resolver,幂等续跑 空判据改 git diff HEAD;顺带修 wakeup_plan stale-suppression 同类 git diff 问题。 * 实现 issue #504 (#519) * 修 headless review-fix prompt 渲染不全:绑定全部 placeholder(PR_NUMBER/标题/轮次/分支/REVIEW_*_PATH 等),解锁 reject PR 的 fix→merge 之前 headless _dispatch_review_fix 只绑 FIX_OUTPUT_PATH,其余 ${} 未解析致 fix codex 读不到 reject 证据。 * 实现 issue #496 (#520) * 修 review-fix codex 派到 main 的 cd bug:改在 PR worktree 跑,worktree 缺失 fail-closed 之前 _dispatch_review_fix cd=repo_root → fix 改 main(污染 daemon checkout)且不落 PR 分支(reject PR 永不 merge)。 * 实现 issue #508 (#523) * 修 wakeup-plan action 排序:review_gate/publish 排到新工作 spawn 前,解 spawn-budget 饿死→reject PR 可被 fix→merge * CLAUDE.md 加宪法工程规则:异常必抛出+记可诊断日志严禁吞掉/静默;测试必断言真实行为禁无意义测试(maintainer 指令) * 实现 issue #503 (#521) * 增加通用工程基本规则,明确面向对象设计要求及实现细则 * 实现 issue #514 (#524) * 完善通用面向对象设计准则,增加核心原则与实现层细则 * 实现 issue #494 (#526) * 实现 issue #517 (#528) * 实现 issue #505 (#510) * 实现 issue #505 * #510 fix r1:补 phase9-router 行为测试覆盖(应对 tests reviewer reject) --------- * 修复 headless FIX_DONE 不提交 fix 输出 gap:wakeup-runner 在 FIX_DONE re-review 前先 commit+push fix worktree headless 下 fix codex 产出 FIX_DONE 但 worker 从不 commit,FIX_DONE 直接路由 dispatch_reviewers, fix 输出永远留在 worktree 未提交,reviewers 永远审旧 head,reject 不收敛,阻断所有需 fix 轮的 PR review→merge。镜像 interactive controller:FIX_DONE 源的 dispatch_reviewers 前,若 fix worktree dirty 则 git add+commit+safe_push,clean 则 no-op。附 2 个 behavior test(dirty 提交/clean 跳过)。 * 实现 issue #491 (#531) * 实现 issue #490 (#529) * 实现 issue #490 * 实现 issue #490 * PR #529 review-fix output * 实现 issue #499 (#512) * 实现 issue #499 * PR #512 review-fix output * 实现 issue #474 (#532) * 实现 issue #474 * 实现 issue #474 * 实现 issue #474 * 实现 issue #474 * PR #532 review-fix output * 实现 issue #476 (#518) * 实现 issue #476 * PR #518 review-fix output * 实现 issue #509 (#527) * 实现 issue #509 * 实现 issue #509 * spawn-claim recycle 改用 artifact-aware terminal marker:companion log 被 24h retention 删除后,已完成任务的 claim 仍可回收(读 runs/ artifact),不再永久阻断重派;running 任务无终止 marker 仍不回收(防 double-spawn) * 实现 issue #421:发行前 clean-room 集成测试制度 (#534) * 实现 issue #421 * rebase #421 onto fresh integration:解决 test_cli_command_router 冲突 + 校验 * 实现 issue #493:测试纪律修宪(behavior-first) (#535) * 实现 issue #493 * rebase #493 onto fresh integration:解决冲突 + 校验 * PR #535 review-fix r1:addressed tests+quality reject(behavior-first test 调整) * 实现 issue #506 (#536) * 实现 issue #506 * 实现 issue #506 * 实现 issue #506 * 实现 issue #506 * PR #536 review-fix output * churn 根治:wakeup-plan 给 consensus-impl spawn-intent 套 open_closing_pr/terminal/in-flight 抑制(对齐 dispatch_consensus_implementation),已有 PR 的 issue 不再被重派 implement * 实现 issue #507 (#525) * 实现 issue #507 * 实现 issue #507 * PR #525 review-fix output * 实现 issue #516 (#530) * 实现 issue #516 * 实现 issue #516 * #530 fix r1:补 ManagedWorkSnapshot fetch-failure stale-cache fallback 行为测试(应对 tests reviewer reject) * PR #530 review-fix output * PR #530 review-fix r2:typed ManagedWorkItem projection(addresses architect 类型边界 reject + tests + contract-tests) * PR #530 review-fix r3:anchor ManagedWorkSnapshot read surface in authorization mirror + cross-artifact source-regression(addresses architect governance reject) * PR #530 review-fix r4:add canonical+legacy managed-label discovery regression test(addresses tests reject) * 修复 worker marker reader 误判相同重复 marker 为冲突 codex 常把终止 marker 回显 2-3 次(含 diff + 前缀行),导致 read_worker_terminal_marker 返回 duplicate_or_conflicting,review 真值表 永不收敛、所有 headless review→merge 卡死。改为:相同重复 marker 折叠为 有效,仅当存在 2+ 个不同 marker 值才判 duplicate_or_conflicting。 覆盖 _last_final_marker / _sentinel_adjacent_marker / _marker_from_companion_artifact,保留 malformed 与 foreign-prefix 检测。 * Reserve implementation PR for issue #537 (#540) ⟦AI:AUTO-LOOP⟧ * 实现 issue #511 (#522) * 实现 issue #511 * PR #522 review-fix output * PR #522 review-fix output * 移除误入 PR 的 .refactor-loop 运行 artifact(architect r8 reject) resolve-pr522-merge.md 是一次性合并解决 summary,属生成物,不应进 durable diff (CLAUDE.md「生成物不当事实源」)。解决说明保留在 commit message / PR body。 --------- * 修复早期 PR reservation 崩溃(#511 回归,阻断所有 implement 派发) _reserve_implementation_pr 用 worker 富正文路径开 reservation PR,但该文件在 reservation 时尚不存在 → FileNotFoundError(未被 except RuntimeError 捕获)→ wakeup-runner tick 崩溃 → 任何 consensus issue 无法 implement → loop P0 wedge。 修复:reservation 前若 body 缺失则写占位正文(## issue #N 实现 + Closes + sentinel, publish 会拒占位逼 worker 产真正文);reservation 幂等(已有 open PR 直接返回; 已有 remote head 则 reset 到 integration + force-with-lease push);捕获 OSError。 * Reserve implementation PR for issue #543 (#544) ⟦AI:AUTO-LOOP⟧ * Reserve implementation PR for issue #541 (#546) ⟦AI:AUTO-LOOP⟧ * revert early-PR reservation(#507):不再开空占位 PR,publish 出真内容才开 PR dispatch_consensus_implementation 不再 reserve/开 PR;publish_implementation_output 恢复 pre-#507 行为——implement 出非空 diff 才 commit+push+open_pr_with_label(用 worker 真 title/body,验证非占位);空 diff 不开 PR、不 merge、不关 issue。删除占位机制 (_reserve_implementation_pr / _placeholder_*),改 wakeup_plan/runner 的 early_pr_missing 投影。 根因:空占位 PR 被 reviewer 在 implement publish 前空合,假性关闭 #537/#541/#543。 全量套件 1496 passed。 * 实现 issue #542:删除 redispatch payload 冗余 head_sha (#547) 移除 review redispatch 的重复 head_sha payload * hotfix: stale consensus-implement intent 指向已删 worktree 不再 suppress fresh re-dispatch consensus_implementation_suppressed_reason 的 pending_implement_intent 分支增加 worktree 存在性 守卫(接入既有 _canonical_consensus_worktree_exists):仅当 stale pending intent 的 canonical worktree 仍存在时才 suppress。revert early-PR reservation(#507)后,#537/#541/#543 的 pending implement intent 指向已删除 worktree,旧逻辑 suppress fresh re-dispatch,而 wakeup-runner 不断把 stale intent spawn 进死 cd 致 os error 2 / EXIT=1 死循环,阻断 consensus→implement 自主链路。 现 worktree 缺失即放行 fresh dispatch 重建 worktree。 补 test_wakeup_plan(worktree 缺失不 suppress / worktree 存在仍 suppress)+ 更新 test_controller_actions 锁旧行为的 subTest(pending case 建 canonical worktree 以保留 reject-before-fresh_safe_worktree 意图)。全套件 1557 passed。 * hotfix: spawn-claim lock 持有者 pid 已死即可回收(自愈,防 cleared-log 永久 HELD) _existing_claim_is_recyclable 增加 pid-liveness 回退:当 lock 记录的持有者 pid 已死(os.kill pid 0 抛 ProcessLookupError)时即可回收,保留既有 terminal-marker 回收与 live-spawn 保护 (pid 存活+无 marker 仍不回收)+ metadata-mismatch fail-closed。根因:implement 失败(EXIT=1) 留 stale lock,dispatch_consensus_implementation 重派时清掉 log → #490 spawn-claim 只在 log 有 EXIT= 时回收 → cleared log 无 marker → 死进程 lock 无法回收 → SPAWN_CLAIM_HELD 永久死锁, 阻断 consensus→implement 重派(#537/#541/#543)。补 7 个 behavior test。全套件 1560 passed。 * hotfix: publish_implementation_output 接受 worker 已 commit 的实现 diff _require_publish_implementation_diff 之前只看 git diff HEAD --quiet(未提交改动), worker 一旦自己 commit(在自己分支上,隔离无害)工作区就 clean → 误判 no_diff → 不开 PR。 现改为:有未提交改动 OR HEAD 相对 integration base 有 committed delta(merge-base..HEAD 非空) 即视为有 diff 可发;_commit_publish_implementation_diff 在工作区已 clean(worker 已 commit)时 跳过提交返回成功,不再误报 publish_commit_failed。修 #541 类 worker-commit→no_diff→无 PR+ daemon 重复 dispatch。补 behavior test。codex 全套件 DISCOVER_STATUS:0 通过。 * 实现 issue #437: .refactor-loop 历史生成物与陈旧 worktree 的有界清理机制 (#548) * #437: 新增 canonical RuntimeRetention owner,log-retention 降为一版 alias;清理覆盖 generated files+pending-events compaction+stale worktree;CLAUDE.md 加 #437 narrow carveout * PR #548 review-fix output * PR #548 review-fix output * PR #548 review-fix output * PR #548 review-fix output * PR #548 review-fix output * hotfix: CONFLICTING managed review PR 的 stale-base 冲突自主 resolve 接线既有但孤儿的 prompts/rebase-resolve.md 进 headless 路径:managed review PR mergeable=CONFLICTING(base 落后)时,controller 在 PR worktree 起 git merge --no-commit --no-ff origin/<integration>——干净则直接 commit+push,有冲突则派 rebase-resolve codex(隔离 worktree 内解+stage,禁 commit/push),收到 REBASE_RESOLVE_DONE 后 controller commit + safe_push 仅推 PR head。结果再过 CI+ review-gate 把关。新增 dispatch_pr_rebase_resolve / commit_push_resolved_pr_rebase (controller_actions)+ wakeup_plan 投影 + wakeup_runner 应用。 安全:只动 refactor/iter<N>-* PR 分支,显式 guard 拒碰 integration/review_base, diff-filter=U 验未解冲突才 commit,任何 abort 路径 git merge --abort 留干净 worktree, 幂等(已含 base / 解析在飞则 NOOP)。修 stale-base churn 致 loop 永久停滞(一个 PR 合了其它全 CONFLICTING 无人解)的根因。codex 全套件 1589 passed。 * hotfix: rebase_resolve_actions 投影前 enrich live mergeability(修生产 gap) 自主-resolve 投影读 item.mergeable 前未 enrich,但生产 GhItem 来自 snapshot mergeable 为空 → 永远 skip → CONFLICTING PR 不投影 dispatch_pr_rebase_resolve → loop 仍停滞。复用同文件 _with_live_mergeability(review_evidence_redispatch_actions 已用同模式)。补 mergeable-为空-需-live-fetch 的回归测试(原测试 mock 了 mergeable 未覆盖此生产路径)。 * hotfix: dispatch_pr_rebase_resolve kind 进 EXECUTABLE_ACTION_KINDS(end-to-end 可执行) _close_projection_action 的 else 分支默认 status_only=True;rebase action 的 kind stale-base-conflicting-pr 不在 EXECUTABLE_ACTION_KINDS → 永远 status_only,runner 不 apply,CONFLICTING PR 永不自主 resolve。加该 kind(+ commit_push completion kind 如需) 进集合;controller_action 已在 RUNNER_NAMED_HELPER_ACTIONS 故随即保持 executable。补 端到端 wakeup-plan pipeline 测试(原测试只测 rebase_resolve_actions 单函数,漏了 closed- action-projection 的 status_only 关卡)。codex 全套件 1593 passed。 * hotfix: rebase-resolve commit/dispatch 投影 gate 在实际 worktree merge 态(止 stale-marker 噪音) commit_push_resolved_pr_rebase 之前只凭持久 REBASE_RESOLVE_DONE marker 投影,worktree 已 commit+push(#549)或 abort(#550/#551)后 marker 仍在 → 每 tick fail-closed 噪音 + 反复 0-codex(zero_streak 触警)+ stale marker 挡 #550/#551 fresh resolve。现 gate:仅当 worktree 真有 merge-in-progress(MERGE_HEAD)且无 unmerged 才投 executable commit_push; 否则不投。并让 worktree clean + 仍 CONFLICTING 的 PR 重新拿 executable dispatch_pr_rebase_resolve (stale DONE marker 不再永久压制)。补端到端测试。codex 全套件通过。 * 实现 issue #502: 删除遗留 label 兼容层:purge emoji/legacy alias 全套(cleanup_aliases / per-spec (#549) * 实现 issue #502: 删除遗留 label 兼容层:purge emoji/legacy alias 全套(cleanup_aliases / per-spec * 修复 PR #549 review r3:#502 label-purge 适配当前 label 代码(contract-tests + architect/tests reject) fix codex round-3 applied-4:对齐 #502 遗留 label 兼容层 purge 与近期新增 label 代码, 修 contract-tests 失败 + architect/tests reject。改 labels.py + SKILL.md + test_wakeup_plan.py。 --------- * 修复 headless review_gate ci_failed 死锁:reject→FIX 移到 ci/mergeability 检查前 _review_gate_decision 之前 ci_error/mergeability 检查在 reject>0→FIX 之前 → CI 红的 PR 即使 reviewer reject 也返回 WAIT_OR_REDISPATCH:ci_failed 干等,而 CI 不修不会绿 → 死锁 (#548/#549 都中,需手动派 fix 破解)。把 reject>0→FIX 移到 ci/mergeability 检查前 (仍在 reviewer-validity/head 检查之后)→ reject 时即使 CI 红也自主派 fix(fix 同解 reject+CI)。 MERGE/MERGE_WITH_COMMENTS 判定完全不变(仍需 ci-green + mergeable + reject=0 + approve>=1), 无误合并风险。补 test_wakeup_runner 端到端测试(reject+ci-red→FIX;reject=0+ci-red 仍 WAIT; happy path MERGE 不变;stale-head+reject 仍 WAIT)。full suite 1600 passed。 * 修正 review_gate 顺序:mergeability 检查移到 reject→FIX 之前(CONFLICTING 不并发 review/fix) 上一修复(a125d19)把 reject→FIX 移到 ci+mergeability 前,破了 ci_failed 死锁但也让 CONFLICTING+reject 的 PR 路由到 FIX → 与独立的 dispatch_pr_rebase_resolve 并发跑同一 worktree(#550 出现 98-file mid-merge + reviewer 并发)。把 mergeability_error 检查移到 reject→FIX 之前:CONFLICTING→WAIT(先 rebase-resolve,不并发 review/fix);MERGEABLE+ CI红+reject→FIX(死锁修复保留);ci_error 仍在 reject→FIX 后(纯 CI 红无 reject 才 WAIT)。 MERGE 判定不变。test_wakeup_runner 90 OK(+conflicting 用例)。 * 实现 issue #498: headless daemon fail-closed 点的 codex 兜底裁决/生成机制(narrow allowlist,非通用 es (#550) * 实现 issue #498 * 实现 issue #498: headless daemon fail-closed 点的 codex 兜底裁决/生成机制(narrow allowlist,非通用 es * PR #550 review-fix output * 新增 patrol-inspector 巡检 issue intake (#551) * 实现 issue #541 * PR #551 review-fix output * PR #551 review-fix output * 修复 PR #551 contract-tests:对齐 patrol 第8 daemon + safe_push/sync_dev 测试 host.env #551 patrol 新增 patrol_inspector_daemon(第8 daemon)→ test_anti_stop_restart 期望 7→8; test_controller_lib_safe_push / test_sync_dev 补 CONSENSUS_RND_HOST_ENV host.env 设置 (代码按 host-config contract 需 host.env locator,rebase-resolve 丢了 base 新测试版本)。 断言未削弱(daemon 数断言强化为8)。full discovery 1634 OK + sshx 13 OK。 * 修复 PR #551 contract-tests(clean-env):e2e fixture 设 META_ESCALATION_STUCK_HOURS 隔离 de-dup 测试 test_batch_and_per_task_lock_do_not_duplicate_spawn 在 clean env(CI)下失败:#506 meta- escalation 因 fixture mock 态被判 stuck 而 fire,产出 repository-stalled RunnerResult 污染 de-dup 断言(expected [] got [RunnerResult])。fixture host.env+env 设 META_ESCALATION_STUCK_ HOURS=999999 禁该测试的 meta-escalation,聚焦 de-dup 行为。断言未削弱。clean discovery 全过。 --------- * 修复 publish-gap:implement readiness 用 git status --porcelain 判 staged diff 原 classify_implement_attempt / wakeup_runner publish 前用 git diff --quiet 只检测 unstaged 改动;worker 正确 git add -A 后 staged diff 被误判 empty_scoped_diff,导致完成的 implement (如 #553 干净 EXIT=0 + 885 行真实 staged diff + 有效 title/body artifacts)永远出不了 PR, wakeup_runner 对 children 反复空转 re-dispatch。改为先 git status --porcelain 判 staged/ unstaged/untracked 任一即 publish-ready,只有真干净才 fallback git diff。publish-time 建 PR 路径不变(不重蹈 #507 early-PR 空 commit/placeholder 死锁)。 * 修复 patrol_inspector daemon 启动崩溃:DaemonHeartbeatLease 用构造函数非 from_env #551 patrol.py daemon 分支调 DaemonHeartbeatLease.from_env()(不存在的方法)→ AttributeError 启动即崩,daemon 从未成功跑起来。改为 DaemonHeartbeatLease( "patrol_inspector_daemon", ctx.repo_root),与 closed_label_reconciler/wakeup_runner 一致,心跳文件名匹配 restart 助手期待的 patrol_inspector_daemon.ts。 * 修复 publish-gap 残留层:duplicate-marker log 读 companion artifact + 取代 superseded spawn intent 层2 残留:implement worker 把 IMPLEMENT_DONE:issue-N:ok 在 log 里 echo 多次→ worker_markers 返回 duplicate_or_conflicting_log_marker fail-closed→classifier 当 markerless 且不查 companion artifact→无 completed-marker action→无 publish→stale harness-spawn-intent:dispatch-consensus-implementation:N 残留致 pending_implement_intent。 修:(1) classify_implement_attempt / completed_marker_actions 遇 duplicate marker 时 narrow 读 companion .refactor-loop/runs/implement-*.md(仅 implement log,仅末 30 行恰好 1 个 IMPLEMENT_DONE:ok 才接受);(2) suppress_publish_superseded_implementation_spawn_intents: 仅当某 issue 已有 executable publish_implementation_output 才把对应 dispatch-consensus- implementation spawn intent 抑制为 status_only(implementation_ready_to_publish)。 不重蹈 #507 死锁:只在 publish 已 ready 后抑制 spawn(不漏派)、publish 仍全验证(不提前/ 重复)、wakeup-runner/publish 授权口径不变。live 验证 #553 现投影 executable publish。 * 实现 issue #555 (#557) * 修复 publish-gap 第3层:wakeup_runner clean_exit revalidation 对 duplicate-marker log 复用 artifact-fallback pubgap2 修了 plan 侧 duplicate-marker artifact-fallback,但 wakeup_runner 的 _source_log_has_clean_marker(clean_exit_source_marker 预条件 revalidation)仍用严格 reader,对 #553 duplicate IMPLEMENT_DONE echo 返回 clean_exit_marker_missing→阻 publish。 改为严格 reader 优先,仅当 duplicate_or_conflicting_log_marker + is_implement_log + _implement_run_artifact_done_marker 精确匹配 projected marker 才 fallback。复用 plan 侧 同一 helper,不弱化安全门(reviewer/release/rebase/非 implement/其它 fail reason 保持严格)。 * 实现 issue #553 * PR #561 review-fix output * PR #561 remote-ci-fix output * PR #561 review-fix output * 收窄 restart daemon 权威到 owner-local 命令面 (#558) * #471 hotfix: wakeup_plan completed-marker 投影按 open-managed 集过滤,closed/merged target 不投影(止血 graphql:消除 wakeup_runner 对已终结 target 的逐条重校验) * #410: SKILL/prompt 注释改引 durable contract anchor,不引用一次性 .refactor-loop/runs/*;新增 test_generated_artifacts_not_authority 窄 source-regression (#472) * #471 hotfix2: wakeup-plan 同一 target 只投影最新有效 marker,旧轮次不再投影 dispatchable action(止 graphql backoff 最后一刀) * skill: 强化 no-gap 规则 — 0 codex + active work 无观察模式豁免,必须当 turn 立即介入派 codex(+source-regression) * #470: direct-post prompt 渲染时 fixed-token 内联 _github-post-rules,host worktree cwd 可达(避免裸相对路径) (#479) * #478 hotfix: daemon spawn 改 launch-and-forget 独立 supervisor(start_new_session 不 wait),daemon reload 不丢 in-flight worker;daemon 每 tick 清晰状态行 * #471: wakeup-plan latest-open-fresh 投影 — completed-marker open-target/latest + release-rollup 仅 latest-per-sha 且 ahead>0 本地 ref 验证(止 stale 投影/graphql) (#482) * #481: consensus->implement readiness-dedup gate(止 daemon 重派 closed/has-PR/in-flight) (#486) * #481: consensus->implement readiness-dedup gate, closed/closing-PR/remote-branch/in-flight target 不投影 dispatchable, 止重复/race * #481 fix r1: dedup gate 复用 concurrency monitor owner surface 测量 in-flight,不重实现 daemon 算法(addr architect) * #481 fix r2: 补 controller helper guard behavior test(addr tests) * #485: consensus->implement 按 scope_paths 冲突分组串行(同组一个 executable,其余 status_only),复用 batching-heuristics,防并行冲突 PR (#489) * #475: wakeup-runner WakeupApplyBudget — spawn-worker action 按 hard_gate.dispatch_required 批量到 floor deficit(lifecycle action 仍 1/tick),修 1/tick 线性恢复 (#492) * hotfix(#475 ext): batch budget 纳入 dispatch_design_consensus —— solver triplet 一 tick 派齐(非 lifecycle,worker 派发),修 design-consensus 仍 1/tick 低并发 * hotfix: headless spawn-intent launch — skipped duplicate 不再 break 整批 spawn,stale applied ledger(log 缺失)可重试,helper_exit:3 加来源诊断事件;修 248 intent 堆积/0 并发 * hotfix r2: blocked lifecycle action 不再 dead-stop 整 tick — 跳过/抑制 stale blocked(close-drop target OPEN / publish 无 verified head)继续 launch 后续 spawn-batch,使 headless 并发拉到 floor * hotfix r3: 根治 headless 0 并发 — detached spawn-codex launch 显式传 env_for_subprocess(修 #478 decouple 丢 env 致 EXIT=127);失败 log(非0 EXIT)可重试 launch,EXIT=0/未完成仍抑制重复;tick 状态汇总后续 launch 不被首个 blocked 掩盖 * hotfix r4: run_once 通用 blocked-not-dead-stop — 任何 blocked/skipped non-spawn action 不再 dead-stop 整 tick,继续 launch 后续 spawn-batch;wakeup-plan 抑制 precondition 注定失败的 stale action;根治 headless 并发=0 * hotfix r5: wakeup-plan 投影侧 suppress stale close_managed_drop(target 实际 OPEN 的 drop-close 注定失败)为 status_only,不再占 tick 挡住后续 design-consensus spawn launch * hotfix r6: wakeup-runner run_once 不再把 no-intents 的 dispatch_design_consensus(helper_exit:3)误判为 codex launch failure dead-stop 整 tick 根因:dispatch_design_consensus 是 spawn-batch action;当 solver triplet 不完整(如 #496 minimal/structural EXIT=0 但未 emit SOLVER_DONE marker)时 helper 返回 exit 3(NO_INTENTS),_spawn_launch_failure 命中 "helper_exit:" 前缀判 True → run_once break,整 tick dead-stop,后续 reviewers/其他 design-consensus/implement 全部不派 → headless 并发=0。 修法:run_once 中 blocked 的 spawn-batch action 若 controller_action != spawn_codex_harness_background(即 dispatch_design_consensus),按 routing no-op skip-and-continue,继续 launch 后续 spawn-batch;仅真正 spawn_codex_harness_background launch failure 才走既有 retry/break。延续 r4 blocked-not-dead-stop 不变量到 design-consensus spawn-batch action。 behavior test: test_wakeup_runner_design_consensus_no_intents_does_not_dead_stop_later_spawn_batch(无修复时 later spawn 不 launch 而 FAIL)。 * hotfix r7: review head_sha binding — 打通 headless review→merge 自驱 根因:reviewer artifact frontmatter 不带 head_sha,_review_evidence_from_artifact 取不到所审 head SHA → 所有 reviewing PR(#480/#473/#402)恒判 WAIT_OR_REDISPATCH:invalid_reviewer_evidence:missing_reviewed_head_sha,且 wakeup-plan 不自动重派 reviewer → review→merge headless 永久卡死(挡住发版)。 修法(codex hotfix worker 实现,controller 验证后提交): - controller_actions 派 reviewer 时取 headRefOid,缺则 fail-closed,注入权威 HEAD_SHA 进 rendered prompt。 - reviewer-{architect,tests,quality}.md frontmatter 写 head_sha: ${HEAD_SHA}。 - wakeup_runner._review_head_sha_for:artifact 缺 head_sha 时从 controller-rendered prompt/log 回收(不依赖 worker 自报,避免 markerless 覆辙);live-head 陈旧判定与 merge 真值表语义不变。 - wakeup_plan 为 missing/stale reviewer head 的 OPEN reviewing PR 投射可执行 dispatch_reviewers 自愈动作。 验证:controller 独立重跑 test_wakeup_runner+review_gate+wakeup_plan+controller_actions 293 通过、marker/prompt 合同 30 通过;review-gate 安全语义(stale head 仍不 merge)由 13 项 review-gate 测试锁住。 * hotfix r8: 让 review-evidence-redispatch 自愈动作可执行 — 打通 headless review→merge 闭环 承接 r7:r7 让 reviewer 证据绑定 head_sha,但 wakeup_plan 投射的 review-evidence-redispatch 自愈动作被 closed-action-projection finalizer 强制 status_only(其 kind 不在 EXECUTABLE_ACTION_KINDS),runner 永不应用 → #480/#473/#402 缺 head 的 review 证据无法自动重派 → review_gate 恒 WAIT_OR_REDISPATCH → 并发耗干到 0。 修法(codex hotfix worker 实现,controller 验证后提交): - wakeup_plan EXECUTABLE_ACTION_KINDS 加 review-evidence-redispatch,finalizer 保留 runner authority 不再强制 status_only。 - controller_actions.dispatch_reviewers 读 stale_review_roles 只重派陈旧角色,且 _pending_review_spawn_exists 跳过已有在飞 dispatch-reviewers:<pr>:<role>:r1 intent(幂等不双派);仍走 r7 的 HEAD_SHA 注入,使重派 reviewer 的新证据 head-bound。 - merge-gate 真值表不变,仅让既有自愈动作可执行 + 定向到陈旧角色。 验证:controller 独立重跑 test_wakeup_plan+wakeup_runner+review_gate+controller_actions 295 通过。 * hotfix r9: reviewer 重派 bump 到下一轮 + 绝对 cd + latest-evidence-per-role — 真正打通 headless review→merge 根因(同一类:按"产物存在"而非"成功+区分维度"抑制):reviewer 重派硬编码回 r1,撞上旧 head 早先成功(EXIT=0)的 r1 log → _harness_spawn_intent_log_suppresses_retry 判"做过了"抑制 → 当前 head 该重跑的 review 永不跑 → review_gate 恒 WAIT_OR_REDISPATCH → 并发 0。且 intent cd 是相对 "." → headless 启动层不投射。 最小修法(按 maintainer directive:文件名即唯一 id,不加 wrapper --id,留在现有 r<R> 命名约定内不改公开命名): - controller_actions.dispatch_reviewers:_next_review_round 取该 PR/role 现有最大轮 +1,渲染 r<N+1> 的 prompt/log/output/intent;pending-spawn 幂等 guard 按真实轮号;_append_harness_spawn_intent 的 cd 改 str(cd.resolve()) 绝对路径,使 headless 投射+启动成立。 - wakeup_plan.latest_reviewer_heads / wakeup_runner._latest_review_evidence_by_role:改为"每 role 取各自最新轮证据"(而非全局最新单轮),使只重派陈旧 role 时不丢其它 role 已 head-bound 的有效证据;merge 仍要求每 role 证据绑定 live head,安全语义不变。 验证:controller 独立重跑 test_wakeup_plan+wakeup_runner+review_gate+controller_actions 299 通过。 * hotfix r10: review_gate action 带上 reviewed head_sha + e2e 锁死 headless review→decision 全路 根因(review path head_sha 串接的第 5 处):wakeup_plan 投影 REVIEW_DONE 的 review_gate action 时只读 log 的 head(log 无 head)→ action.head_sha 空 → wakeup_runner._review_gate 卡 WAIT_OR_REDISPATCH:missing_action_reviewed_head_sha,证据虽已 head-bound 但 gate 连比都没法比。 修法(最小、按文件名即 id 思路): - wakeup_plan.completed_marker_actions:REVIEW_DONE action 的 head_sha 改由 _review_done_action_head_sha 从权威证据面解析(latest_reviewer_heads 含 r7 prompt 注入的 head;或全 role head-bound 时取 live PR head;否则回落 log)。只从真实来源填充,不绕过 gate 的 head 比对,merge 安全语义不变。 - 新增 test_review_gate_e2e.py:从真实 wakeup_plan 投影 → WakeupRunner apply,断言 FIX(有 reject)与 MERGE(全 approve+CI 绿)两条具体决策落地——端到端锁死整条 review→decision,杜绝再冒隐藏层。 - test_wakeup_plan.py:加 prompt-bound reviewed head 的 planner 回归。 验证:controller 独立重跑 test_wakeup_plan+wakeup_runner+review_gate+controller_actions+review_gate_e2e 302 通过。 * hotfix r11: PrChecksProjection 对瞬时 gh-api 失败加 bounded retry — ready PR headless 走到 review_gate 决策 根因:review_gate 的 CI 读 PrChecksProjection.check_pr 对 gh api pulls/<n> 与 commits/<sha>/check-runs 的单次非零返回立即 fail-closed(ci_unavailable:pull_api_failure),无重试;rate limit 健康,实为瞬时 blip → 让 #473/#402(MERGEABLE+CI 绿)每 tick 被瞬时失败挡住、never reach MERGE/FIX。 修法(最小,只动 PrChecksProjection;不碰 #322 ReleaseRequiredChecksProjection): - _run_api_read:对两处 api read 最多 3 次确定性重试(无 sleep),成功即停,持续失败仍 fail-closed(安全)。happy path 无行为变化。 - starvation 结论(worker 核实):review_gate 本就被 apply,blocked ci_unavailable 行可重评估(非 terminal duplicate-suppressed),无需改 run_once。 - e2e:test_review_gate_e2e 加「首次 pulls 读瞬时失败仍 merge」用例;test_pr_checks 加 retry 覆盖。 验证:controller 独立重跑 test_pr_checks+wakeup_runner+review_gate+review_gate_e2e+wakeup_plan+co… Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
摘要
解决设计 issue #471(r2 consensus:hybrid)。完整版 wakeup-plan latest-open-fresh 投影(hotfix1+2 的共识化收口)。
release_rollup_actions()回放陈旧 pendingrelease-rollup-needed事件(全 JSON/tail 扫描),旧 integration SHA / ahead=0 事件持续进入可执行投影;completed-marker 全历史投影。范围
wakeup_plan.py + test_wakeup_plan.py + SKILL.md 投影 anchor + source-regression。基于 hotfix1+2。
Closes #471
🤖 Auto-loop / codex-refactor-loop
⟦AI:AUTO-LOOP⟧