Skip to content

fix(diagnose): surface orphaned Goal state - #4912

Merged
huangruiteng merged 7 commits into
loopx-project:mainfrom
Duang777:codex/diagnose-orphaned-goal-state
Sep 23, 2026
Merged

huangruiteng merged 7 commits into
loopx-project:mainfrom
Duang777:codex/diagnose-orphaned-goal-state

Conversation

@Duang777

@Duang777 Duang777 commented Sep 22, 2026 •

Copy link
Copy Markdown
Contributor

Goal And Delivered Outcome

Scope And Continuation

Validation

  • Tested revision: a595fe5fb96aa0b4a46df224ff4a31db0928b1e3
  • Run state: finished
  • Input classes: synthetic
Check kind Result Public-safe evidence / limitation
regression_parity passed New real CLI test failed on the unchanged implementation because diagnose exited 0; it passes on this head with a blocking orphan signal and no quota or --execute command.
unit passed 121 tests passed on the exact head across the new diagnose regression and the semantic vocabulary and frozen incident-retrodiction checks.
real_entrypoint passed Synthetic loopx diagnose --goal-id reset-goal returned ok=false, preserved status_ok=true, reported the relative surviving-state route, and exposed only status plus backup preview. Default Markdown renders the same gate.
integration passed agent-diagnose-packet-smoke.py, bootstrap-command-pack-smoke.py, and status-neutral-run-window-smoke.py passed.
static passed Ruff, Python compilation, git diff --check, the 14-test maintainability ratchet, and the public-boundary scan passed. The exact-head semantic vocabulary and frozen incident-retrodiction checks pass after keeping the diagnostic action out of the typed quota-action field. A standalone mypy run reports the same 10 pre-existing loopx/diagnose.py errors on base and head.
  • Coverage and gaps: the shared orphan detector already covers .loopx, .codex, .claude, and .local Goal-state roots. This change tests the public JSON and Markdown diagnose surfaces plus a no-state negative twin. diagnose without an explicit Goal id does not scan arbitrary orphan directories; [Bug]: Guard orphaned Goal state before guided bootstrap or host activation #4801 is scoped to the requested id. Invalid registry JSON remains a distinct fail-closed collection error rather than being reclassified here.

See validation disclosure guidance.

Frontend / Visual Evidence

  • UI impact: none
  • Before: N/A
  • After: N/A
  • States and viewports shown: N/A
  • Source data: synthetic
  • Attention review: no frontend or first-screen surface changes.

Type of Change

  • Bug fix
  • New feature
  • Breaking change
  • Refactoring (no functional changes)
  • Documentation update
  • Test update

LoopX Area

  • Control plane (goals, todos, quota, scheduler, registry, runtime)
  • Benchmark boundary (adapters, runners, verifiers, scoring, evidence)
  • Capability or extension (providers, adapters, skills)
  • Public docs or presentation surface (README, protocols, dashboard)
  • Build, packaging, installer, or CI
  • Host or runtime integration

Technical Direction

Shared-authority RFC fixture impact

  • Production-scale fixture schema: N/A; no persisted schema changes.
  • Semantic dimensions changed, or reviewed no-impact rationale: N/A; this is a read-only diagnosis projection over the existing orphan fact.
  • Provider conformance arms run: none; no AuthorityStore or provider behavior changed.
  • Read-only legacy/file/PostgreSQL three-arm rehearsal: not applicable; no runtime routing or persistence behavior changed.

Boundary Checklist

  • Neither the diff nor this PR body/comments/attachments disclose private state, credentials, raw traces or verifier output, internal links, or local machine paths.
  • I did not duplicate maintainer-owned benchmark work unless a maintainer split out a public issue for it.
  • I kept the change scoped to the linked issue/task.
  • I completed the visual evidence section for UI changes, or marked UI impact none.
  • Every commit includes a DCO Signed-off-by trailer (git commit -s).

Signed-off-by: duanjialing.777 <duanjialing.777@bytedance.com>
Signed-off-by: duanjialing.777 <duanjialing.777@bytedance.com>
@Duang777

Duang777 commented Sep 22, 2026 •

Copy link
Copy Markdown
Contributor Author

Exact-head CI triage for a595fe5fb96aa0b4a46df224ff4a31db0928b1e3:

  • test-shard (1) now passes, confirming the unregistered effective_action and frozen retrodiction failures are fixed.
  • test-shard (4), Windows, Dashboard, DCO, dependency review, release build, and all Stage 2C lanes pass.
  • test-shard (2) and (3) fail only in the two stale canonical-read test doubles already fixed on approved ci: restore TypeScript qualification reliability #4906.
  • node-minimum-compatibility fails in the archive cases already fixed on ci: restore TypeScript qualification reliability #4906.
  • kernel-static-checks reaches the old 30-minute cap that ci: restore TypeScript qualification reliability #4906 raises to 60 minutes. The non-blocking Node forward probe reaches its existing 20-minute cap.
  • The aggregate checks, pytest, and merge-gate failures reflect those dependent jobs; no additional failure appeared.

This branch intentionally does not duplicate #4906. I will merge current main into this branch after #4906 lands, rerun exact-head CI, and then request review.

Signed-off-by: duanjialing.777 <duanjialing.777@bytedance.com>
Signed-off-by: duanjialing.777 <duanjialing.777@bytedance.com>
…ed-goal-state

Signed-off-by: duanjialing.777 <duanjialing.777@bytedance.com>
…ed-goal-state

Signed-off-by: duanjialing.777 <duanjialing.777@bytedance.com>
…ed-goal-state

Signed-off-by: duanjialing.777 <duanjialing.777@bytedance.com>

@huangruiteng huangruiteng left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

评审 exact head:68ae3cef27eb422e09937c88cf3b60d4fa9543d8。结论:APPROVE(仅覆盖本 PR 的只读诊断切片,不代表 #4801 的恢复/身份问题已完成)。

动机

#4801 要求在 Goal 注册项消失但项目内状态尚存时,diagnose 不能报告普通“未连接”。我用同一合成输入在合并基线和此 head 的真实 CLI 重放:基线退出 0、ok=true、仍给 quota should-run;此 head 退出 1,明确给 orphaned_goal_state,只留下只读检查与备份预览。这个切片完成了 #4801 的 diagnose 可见性要求;项目本地 archive/adopt 和 Goal lifetime identity 仍属于后续里程碑。

改动思路

入口仍是 diagnose --goal-id。代码先从 status 快照确认该 id 的 registry_member=false,再复用 #4808 已交付的四根目录孤儿状态探测与 resolution gate;项目 registry 仍是注册权威,状态文件只提供冲突事实。诊断包改为 blocked,不创建状态也不提供 bootstrap、quota 或 --execute 续行。无孤儿文件时保留原普通未连接路径;这比另写一套扫描/恢复机制更合适。

具体改动

  • loopx/diagnose.py 增加冲突探测、将既有 gate 映射到 JSON packet,并在 Markdown 展示原因、相对状态路径和禁止操作;顶层 ok/退出码与所选 Goal 的阻断状态一致。
  • 新增 tests/control_plane/test_diagnose_orphaned_goal_state.py,覆盖真实 CLI 的孤儿 JSON、无状态对照和 Markdown 安全命令。没有持久化 schema、前端或 Lark 改动。

关键代码讲解

  • _orphaned_goal_state_for_diagnosis(line 125):仅在 status 明确给 registry_member=false 时调用既有投影,避免将已注册 Goal 误判为孤儿。
  • _apply_orphaned_goal_state_diagnosis(line 494):复用安全 gate 并替换不适用的 quota/agent 命令;此处只构造诊断证据,不授予恢复权限。
  • collect_diagnosis(line 539)与 render_diagnosis_markdown(line 652):将该状态传播到机器可读退出结果和人工可读视图。

对主干的风险

最强反例是遗漏 .loopx、.codex、.claude、.local 中任一状态根,或把普通未连接误阻断。我用真实 CLI 对四根目录逐一验证:均退出 1、should_run=false、只有两条非执行命令;无状态对照仍退出 0。基线同输入复现旧误判。focused pytest 3/3、agent-diagnose 与 bootstrap smokes、Ruff、diff check 均通过。风险 canary 首次因隔离 worktree 缺 Node parser 依赖而失败;执行 npm ci --ignore-scripts 后原命令重跑 2/2 通过、无 warning。按 Goal wait_for_ci=false 未查询远端 CI。

语义与 CI 对齐

此 PR 复用现有 orphaned_goal_state 语义而非新增并行分类;diagnose 的机器阻断不等于已经实现 archive/adopt 或 Goal instance fence。后者必须继续按 #4914 RFC 和 #4801 验证。这里无阻断性发现。

我的整体评价

2 文件改动把已有安全事实接入独立诊断入口,范围与风险相称,未引入第二个权威或破坏正常缺席分支;相关小型未来改进已体现在复用现有 gate,而不宜在此 PR 扩为恢复事务。批准此 exact head。合并权限、远端检查和 #4801 剩余验收仍是独立门禁。

English verdict: APPROVE - At 68ae3cef27eb422e09937c88cf3b60d4fa9543d8, real CLI baseline/head and four-root negative checks confirm the read-only orphan diagnosis; focused tests and risk canary pass. Recovery and lifetime fencing remain separate work.

@huangruiteng
huangruiteng merged commit a41fa6e into loopx-project:main Sep 23, 2026
24 of 25 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants