phase-loop-runtime 0.2.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (370) hide show
  1. phase_loop_runtime/__init__.py +20 -0
  2. phase_loop_runtime/_contract_docs/phase-loop/extraction-readiness.md +90 -0
  3. phase_loop_runtime/_contract_docs/phase-loop/granular-execution-policy.md +137 -0
  4. phase_loop_runtime/_contract_docs/phase-loop/harness-capability-matrix.md +510 -0
  5. phase_loop_runtime/_contract_docs/phase-loop/harness-skill-matrix.md +125 -0
  6. phase_loop_runtime/_contract_docs/phase-loop/harness-substrate-manifest.md +232 -0
  7. phase_loop_runtime/_contract_docs/phase-loop/pi-loop-control.md +247 -0
  8. phase_loop_runtime/_contract_docs/phase-loop/protocol.md +2759 -0
  9. phase_loop_runtime/_contract_docs/phase-loop/runtime-boundary.md +289 -0
  10. phase_loop_runtime/_contract_docs/phase-loop/spec-discovery-roots.md +47 -0
  11. phase_loop_runtime/_contract_docs/phase-loop/substrate-soak-governed-pipeline.md +42 -0
  12. phase_loop_runtime/_contract_docs/phase-loop/substrate-soak-portal-projection.md +34 -0
  13. phase_loop_runtime/_contract_docs/phase-loop/substrate-soak-regenesis.md +29 -0
  14. phase_loop_runtime/_contract_docs/phase-loop/substrate-soak-report.md +32 -0
  15. phase_loop_runtime/_contract_docs/runtime/verification-evidence-contract.md +52 -0
  16. phase_loop_runtime/_test_fixtures/evidence-audit-calibration/borderline/borderline-mixed-signals/commands.txt +2 -0
  17. phase_loop_runtime/_test_fixtures/evidence-audit-calibration/borderline/borderline-mixed-signals/manifest.json +16 -0
  18. phase_loop_runtime/_test_fixtures/evidence-audit-calibration/borderline/borderline-mixed-signals/mixed.json +5 -0
  19. phase_loop_runtime/_test_fixtures/evidence-audit-calibration/borderline/borderline-provider-timeout/manifest.json +16 -0
  20. phase_loop_runtime/_test_fixtures/evidence-audit-calibration/borderline/borderline-provider-timeout/timeout-note.txt +2 -0
  21. phase_loop_runtime/_test_fixtures/evidence-audit-calibration/borderline/borderline-redacted-summary/manifest.json +16 -0
  22. phase_loop_runtime/_test_fixtures/evidence-audit-calibration/borderline/borderline-redacted-summary/redacted-summary.json +6 -0
  23. phase_loop_runtime/_test_fixtures/evidence-audit-calibration/borderline/borderline-small-sample/manifest.json +16 -0
  24. phase_loop_runtime/_test_fixtures/evidence-audit-calibration/borderline/borderline-small-sample/sample.json +7 -0
  25. phase_loop_runtime/_test_fixtures/evidence-audit-calibration/borderline/borderline-threshold-edge/edge.txt +2 -0
  26. phase_loop_runtime/_test_fixtures/evidence-audit-calibration/borderline/borderline-threshold-edge/manifest.json +16 -0
  27. phase_loop_runtime/_test_fixtures/evidence-audit-calibration/known-fake/fake-duplicate-png/manifest.json +16 -0
  28. phase_loop_runtime/_test_fixtures/evidence-audit-calibration/known-fake/fake-duplicate-png/shot-a.txt +1 -0
  29. phase_loop_runtime/_test_fixtures/evidence-audit-calibration/known-fake/fake-duplicate-png/shot-b.txt +1 -0
  30. phase_loop_runtime/_test_fixtures/evidence-audit-calibration/known-fake/fake-duplicate-png/shot-c.txt +1 -0
  31. phase_loop_runtime/_test_fixtures/evidence-audit-calibration/known-fake/fake-missing-references/claimed-results.json +5 -0
  32. phase_loop_runtime/_test_fixtures/evidence-audit-calibration/known-fake/fake-missing-references/manifest.json +16 -0
  33. phase_loop_runtime/_test_fixtures/evidence-audit-calibration/known-fake/fake-subtle-low-variance/manifest.json +16 -0
  34. phase_loop_runtime/_test_fixtures/evidence-audit-calibration/known-fake/fake-subtle-low-variance/metrics.json +9 -0
  35. phase_loop_runtime/_test_fixtures/evidence-audit-calibration/known-fake/fake-templated-prose/findings.md +10 -0
  36. phase_loop_runtime/_test_fixtures/evidence-audit-calibration/known-fake/fake-templated-prose/manifest.json +16 -0
  37. phase_loop_runtime/_test_fixtures/evidence-audit-calibration/known-fake/fake-uniform-scores/manifest.json +16 -0
  38. phase_loop_runtime/_test_fixtures/evidence-audit-calibration/known-fake/fake-uniform-scores/scores.json +4 -0
  39. phase_loop_runtime/_test_fixtures/evidence-audit-calibration/known-fake/fake-uniform-scores/summary.txt +1 -0
  40. phase_loop_runtime/_test_fixtures/evidence-audit-calibration/known-real/real-adoption-bundle/bundle-check.json +8 -0
  41. phase_loop_runtime/_test_fixtures/evidence-audit-calibration/known-real/real-adoption-bundle/manifest.json +16 -0
  42. phase_loop_runtime/_test_fixtures/evidence-audit-calibration/known-real/real-adoption-bundle/operator-note.txt +2 -0
  43. phase_loop_runtime/_test_fixtures/evidence-audit-calibration/known-real/real-handoff-ledger/events-sample.jsonl +3 -0
  44. phase_loop_runtime/_test_fixtures/evidence-audit-calibration/known-real/real-handoff-ledger/manifest.json +16 -0
  45. phase_loop_runtime/_test_fixtures/evidence-audit-calibration/known-real/real-handoff-ledger/receipt.txt +1 -0
  46. phase_loop_runtime/_test_fixtures/evidence-audit-calibration/known-real/real-runner-diff/evidence.json +13 -0
  47. phase_loop_runtime/_test_fixtures/evidence-audit-calibration/known-real/real-runner-diff/manifest.json +16 -0
  48. phase_loop_runtime/_test_fixtures/evidence-audit-calibration/known-real/real-runner-diff/summary.txt +2 -0
  49. phase_loop_runtime/_test_fixtures/evidence-audit-calibration/known-real/real-test-matrix/manifest.json +16 -0
  50. phase_loop_runtime/_test_fixtures/evidence-audit-calibration/known-real/real-test-matrix/matrix.json +9 -0
  51. phase_loop_runtime/_test_fixtures/evidence-audit-calibration/known-real/real-test-matrix/notes.md +4 -0
  52. phase_loop_runtime/_test_fixtures/evidence-audit-calibration/known-real/real-ui-screenshot-standin/console-summary.txt +2 -0
  53. phase_loop_runtime/_test_fixtures/evidence-audit-calibration/known-real/real-ui-screenshot-standin/manifest.json +16 -0
  54. phase_loop_runtime/_test_fixtures/evidence-audit-calibration/known-real/real-ui-screenshot-standin/screenshot-standin.ppm +5 -0
  55. phase_loop_runtime/adoption_bundle.py +273 -0
  56. phase_loop_runtime/advisor_board/CONTRACTS.md +257 -0
  57. phase_loop_runtime/advisor_board/__init__.py +288 -0
  58. phase_loop_runtime/advisor_board/backing.py +137 -0
  59. phase_loop_runtime/advisor_board/backing_omnigent.py +498 -0
  60. phase_loop_runtime/advisor_board/config.py +225 -0
  61. phase_loop_runtime/advisor_board/events.py +115 -0
  62. phase_loop_runtime/advisor_board/fixtures/advisor-boards.example.toml +59 -0
  63. phase_loop_runtime/advisor_board/fixtures.py +91 -0
  64. phase_loop_runtime/advisor_board/harness_mapping.py +125 -0
  65. phase_loop_runtime/advisor_board/matrix.py +146 -0
  66. phase_loop_runtime/advisor_board/observability.py +481 -0
  67. phase_loop_runtime/advisor_board/presets.py +188 -0
  68. phase_loop_runtime/advisor_board/registries.py +309 -0
  69. phase_loop_runtime/advisor_board/resolver.py +253 -0
  70. phase_loop_runtime/advisor_board/schema.py +269 -0
  71. phase_loop_runtime/advisor_board/standin.py +166 -0
  72. phase_loop_runtime/advisor_board/validation.py +159 -0
  73. phase_loop_runtime/agent_runtime_provider.py +676 -0
  74. phase_loop_runtime/baml_modular.py +656 -0
  75. phase_loop_runtime/baml_src/dotfiles_adoption_manifest.baml +37 -0
  76. phase_loop_runtime/baml_src/dotfiles_c4_document.baml +14 -0
  77. phase_loop_runtime/baml_src/dotfiles_plan_manifest.baml +50 -0
  78. phase_loop_runtime/baml_src/dotfiles_runtime_projection.baml +16 -0
  79. phase_loop_runtime/baml_src/dotfiles_task_catalog.baml +20 -0
  80. phase_loop_runtime/baml_src/emit_phase_closeout.baml +86 -0
  81. phase_loop_runtime/baml_src/evaluate_suspected_fake_evidence.baml +36 -0
  82. phase_loop_runtime/baml_src/verification_evidence.baml +40 -0
  83. phase_loop_runtime/broker.py +181 -0
  84. phase_loop_runtime/build_bundle.py +294 -0
  85. phase_loop_runtime/capability_registry.py +835 -0
  86. phase_loop_runtime/classifier.py +87 -0
  87. phase_loop_runtime/claude_agent_view.py +625 -0
  88. phase_loop_runtime/claude_channel_sidecar.py +1086 -0
  89. phase_loop_runtime/cli.py +2599 -0
  90. phase_loop_runtime/closeout.py +865 -0
  91. phase_loop_runtime/closeout_classifier.py +120 -0
  92. phase_loop_runtime/closeout_evidence_audit.py +112 -0
  93. phase_loop_runtime/closeout_validation.py +144 -0
  94. phase_loop_runtime/closeout_validators.py +203 -0
  95. phase_loop_runtime/consiliency_gates.py +374 -0
  96. phase_loop_runtime/consiliency_ingest.py +399 -0
  97. phase_loop_runtime/consiliency_layout.py +176 -0
  98. phase_loop_runtime/consiliency_scaffold.py +305 -0
  99. phase_loop_runtime/cross_repo_channel.py +331 -0
  100. phase_loop_runtime/discovery.py +2368 -0
  101. phase_loop_runtime/dispatch_lock.py +167 -0
  102. phase_loop_runtime/doc_delta_validator.py +98 -0
  103. phase_loop_runtime/docs_audit.py +285 -0
  104. phase_loop_runtime/docs_freshness.py +468 -0
  105. phase_loop_runtime/docs_surfaces.py +150 -0
  106. phase_loop_runtime/dotfiles_profile_plugin.py +96 -0
  107. phase_loop_runtime/events.py +154 -0
  108. phase_loop_runtime/events_migration.py +96 -0
  109. phase_loop_runtime/evidence_audit.py +1082 -0
  110. phase_loop_runtime/evidence_audit_config.py +172 -0
  111. phase_loop_runtime/fleet_map.py +426 -0
  112. phase_loop_runtime/fleet_metrics.py +298 -0
  113. phase_loop_runtime/fleet_metrics_export.py +196 -0
  114. phase_loop_runtime/git_discipline.py +479 -0
  115. phase_loop_runtime/git_ops.py +122 -0
  116. phase_loop_runtime/git_topology.py +252 -0
  117. phase_loop_runtime/governed_bundle.py +137 -0
  118. phase_loop_runtime/governed_premerge.py +219 -0
  119. phase_loop_runtime/governed_review.py +264 -0
  120. phase_loop_runtime/handoff.py +932 -0
  121. phase_loop_runtime/handoff_path.py +14 -0
  122. phase_loop_runtime/injection.py +740 -0
  123. phase_loop_runtime/install_status.py +88 -0
  124. phase_loop_runtime/lane_scheduler.py +317 -0
  125. phase_loop_runtime/launcher.py +2760 -0
  126. phase_loop_runtime/lease_store.py +553 -0
  127. phase_loop_runtime/maintenance.py +401 -0
  128. phase_loop_runtime/migrate_handoffs.py +201 -0
  129. phase_loop_runtime/models.py +2144 -0
  130. phase_loop_runtime/observability.py +1290 -0
  131. phase_loop_runtime/panel_invoker.py +1638 -0
  132. phase_loop_runtime/phase_loop_drift_audit.py +388 -0
  133. phase_loop_runtime/phase_worktree_executor.py +433 -0
  134. phase_loop_runtime/pipeline_adapter/__init__.py +12 -0
  135. phase_loop_runtime/pipeline_adapter/branch_ops.py +274 -0
  136. phase_loop_runtime/pipeline_adapter/flag.py +55 -0
  137. phase_loop_runtime/pipeline_adapter/markers.py +13 -0
  138. phase_loop_runtime/pipeline_adapter/merge_policy.py +72 -0
  139. phase_loop_runtime/pipeline_adapter/ratification.py +100 -0
  140. phase_loop_runtime/pipeline_adapter/sibling_matcher.py +123 -0
  141. phase_loop_runtime/plan_ir.py +523 -0
  142. phase_loop_runtime/plan_manifest.py +415 -0
  143. phase_loop_runtime/planner_validation.py +176 -0
  144. phase_loop_runtime/profiles.py +462 -0
  145. phase_loop_runtime/prompts.py +365 -0
  146. phase_loop_runtime/provenance.py +165 -0
  147. phase_loop_runtime/publishing.py +339 -0
  148. phase_loop_runtime/py.typed +1 -0
  149. phase_loop_runtime/reconcile.py +1550 -0
  150. phase_loop_runtime/redaction.py +184 -0
  151. phase_loop_runtime/reflection_sync.py +293 -0
  152. phase_loop_runtime/release_guard.py +186 -0
  153. phase_loop_runtime/render.py +432 -0
  154. phase_loop_runtime/repo_validation.py +427 -0
  155. phase_loop_runtime/review_summary.py +150 -0
  156. phase_loop_runtime/roadmap_lint.py +425 -0
  157. phase_loop_runtime/route_log.py +59 -0
  158. phase_loop_runtime/route_policy/__init__.py +11 -0
  159. phase_loop_runtime/route_policy/fixtures/route_selection.golden.json +263 -0
  160. phase_loop_runtime/runner.py +8400 -0
  161. phase_loop_runtime/runtime_paths.py +225 -0
  162. phase_loop_runtime/runtime_projection.py +113 -0
  163. phase_loop_runtime/runtime_resources.py +36 -0
  164. phase_loop_runtime/schema_export.py +292 -0
  165. phase_loop_runtime/schemas/phase_loop_closeout.schema.json +366 -0
  166. phase_loop_runtime/skill_install.py +176 -0
  167. phase_loop_runtime/skill_inventory.py +662 -0
  168. phase_loop_runtime/skill_paths.py +42 -0
  169. phase_loop_runtime/skill_sources_plugin.py +37 -0
  170. phase_loop_runtime/skills_bundle/claude-advisor-board/README.md +1 -0
  171. phase_loop_runtime/skills_bundle/claude-advisor-board/SKILL.md +38 -0
  172. phase_loop_runtime/skills_bundle/claude-advisor-panel/README.md +1 -0
  173. phase_loop_runtime/skills_bundle/claude-advisor-panel/SKILL.md +38 -0
  174. phase_loop_runtime/skills_bundle/claude-execute-detailed/README.md +1 -0
  175. phase_loop_runtime/skills_bundle/claude-execute-detailed/SKILL.md +152 -0
  176. phase_loop_runtime/skills_bundle/claude-execute-phase/README.md +1 -0
  177. phase_loop_runtime/skills_bundle/claude-execute-phase/SKILL.md +745 -0
  178. phase_loop_runtime/skills_bundle/claude-execute-phase/scripts/allocate_worktree_name.sh +33 -0
  179. phase_loop_runtime/skills_bundle/claude-execute-phase/scripts/audit_lane_file_touches.py +197 -0
  180. phase_loop_runtime/skills_bundle/claude-execute-phase/scripts/cleanup_lane_worktrees.sh +103 -0
  181. phase_loop_runtime/skills_bundle/claude-execute-phase/scripts/parent_tree_leakage_check.sh +125 -0
  182. phase_loop_runtime/skills_bundle/claude-execute-phase/scripts/post_merge_import_smoke.sh +62 -0
  183. phase_loop_runtime/skills_bundle/claude-execute-phase/scripts/pre_merge_destructiveness_check.sh +127 -0
  184. phase_loop_runtime/skills_bundle/claude-execute-phase/scripts/resolve_branch_from_sha.sh +51 -0
  185. phase_loop_runtime/skills_bundle/claude-execute-phase/scripts/state.py +274 -0
  186. phase_loop_runtime/skills_bundle/claude-execute-phase/scripts/sweep_stale_worktrees.sh +62 -0
  187. phase_loop_runtime/skills_bundle/claude-execute-phase/scripts/team_teardown.sh +32 -0
  188. phase_loop_runtime/skills_bundle/claude-execute-phase/scripts/validate_plan_doc.py +642 -0
  189. phase_loop_runtime/skills_bundle/claude-execute-phase/scripts/verify_harness.sh +96 -0
  190. phase_loop_runtime/skills_bundle/claude-phase-loop/README.md +1 -0
  191. phase_loop_runtime/skills_bundle/claude-phase-loop/SKILL.md +115 -0
  192. phase_loop_runtime/skills_bundle/claude-phase-roadmap-builder/README.md +1 -0
  193. phase_loop_runtime/skills_bundle/claude-phase-roadmap-builder/SKILL.md +439 -0
  194. phase_loop_runtime/skills_bundle/claude-phase-roadmap-builder/assets/review_prompt.md +19 -0
  195. phase_loop_runtime/skills_bundle/claude-phase-roadmap-builder/references/parallelization-heuristics.md +111 -0
  196. phase_loop_runtime/skills_bundle/claude-phase-roadmap-builder/references/roadmap-template.md +193 -0
  197. phase_loop_runtime/skills_bundle/claude-phase-roadmap-builder/scripts/validate_roadmap.py +32 -0
  198. phase_loop_runtime/skills_bundle/claude-plan-detailed/README.md +1 -0
  199. phase_loop_runtime/skills_bundle/claude-plan-detailed/SKILL.md +334 -0
  200. phase_loop_runtime/skills_bundle/claude-plan-detailed/assets/review_prompt.md +25 -0
  201. phase_loop_runtime/skills_bundle/claude-plan-phase/README.md +1 -0
  202. phase_loop_runtime/skills_bundle/claude-plan-phase/SKILL.md +776 -0
  203. phase_loop_runtime/skills_bundle/claude-plan-phase/assets/review_prompt.md +17 -0
  204. phase_loop_runtime/skills_bundle/claude-plan-phase/scripts/validate_plan_doc.py +1092 -0
  205. phase_loop_runtime/skills_bundle/claude-run-train/README.md +1 -0
  206. phase_loop_runtime/skills_bundle/claude-run-train/SKILL.md +75 -0
  207. phase_loop_runtime/skills_bundle/claude-skill-editor/README.md +1 -0
  208. phase_loop_runtime/skills_bundle/claude-skill-editor/SKILL.md +243 -0
  209. phase_loop_runtime/skills_bundle/claude-skill-editor/assets/editor_prompt.md +72 -0
  210. phase_loop_runtime/skills_bundle/claude-skill-improvement-planner/README.md +1 -0
  211. phase_loop_runtime/skills_bundle/claude-skill-improvement-planner/SKILL.md +249 -0
  212. phase_loop_runtime/skills_bundle/claude-skill-improvement-planner/assets/aggregator_prompt.md +79 -0
  213. phase_loop_runtime/skills_bundle/claude-task-contextualizer/README.md +1 -0
  214. phase_loop_runtime/skills_bundle/claude-task-contextualizer/SKILL.md +74 -0
  215. phase_loop_runtime/skills_bundle/claude-task-contextualizer/references/task-templates.md +103 -0
  216. phase_loop_runtime/skills_bundle/codex-advisor-board/README.md +1 -0
  217. phase_loop_runtime/skills_bundle/codex-advisor-board/SKILL.md +38 -0
  218. phase_loop_runtime/skills_bundle/codex-advisor-panel/README.md +1 -0
  219. phase_loop_runtime/skills_bundle/codex-advisor-panel/SKILL.md +38 -0
  220. phase_loop_runtime/skills_bundle/codex-execute-detailed/README.md +1 -0
  221. phase_loop_runtime/skills_bundle/codex-execute-detailed/SKILL.md +154 -0
  222. phase_loop_runtime/skills_bundle/codex-execute-phase/README.md +1 -0
  223. phase_loop_runtime/skills_bundle/codex-execute-phase/SKILL.md +231 -0
  224. phase_loop_runtime/skills_bundle/codex-execute-phase/scripts/allocate_worktree_name.sh +33 -0
  225. phase_loop_runtime/skills_bundle/codex-execute-phase/scripts/audit_lane_file_touches.py +197 -0
  226. phase_loop_runtime/skills_bundle/codex-execute-phase/scripts/cleanup_lane_worktrees.sh +103 -0
  227. phase_loop_runtime/skills_bundle/codex-execute-phase/scripts/parent_tree_leakage_check.sh +125 -0
  228. phase_loop_runtime/skills_bundle/codex-execute-phase/scripts/post_merge_import_smoke.sh +62 -0
  229. phase_loop_runtime/skills_bundle/codex-execute-phase/scripts/pre_merge_destructiveness_check.sh +127 -0
  230. phase_loop_runtime/skills_bundle/codex-execute-phase/scripts/resolve_branch_from_sha.sh +51 -0
  231. phase_loop_runtime/skills_bundle/codex-execute-phase/scripts/state.py +274 -0
  232. phase_loop_runtime/skills_bundle/codex-execute-phase/scripts/sweep_stale_worktrees.sh +62 -0
  233. phase_loop_runtime/skills_bundle/codex-execute-phase/scripts/team_teardown.sh +32 -0
  234. phase_loop_runtime/skills_bundle/codex-execute-phase/scripts/validate_plan_doc.py +642 -0
  235. phase_loop_runtime/skills_bundle/codex-execute-phase/scripts/verify_harness.sh +96 -0
  236. phase_loop_runtime/skills_bundle/codex-phase-loop/README.md +1 -0
  237. phase_loop_runtime/skills_bundle/codex-phase-loop/SKILL.md +248 -0
  238. phase_loop_runtime/skills_bundle/codex-phase-roadmap-builder/README.md +1 -0
  239. phase_loop_runtime/skills_bundle/codex-phase-roadmap-builder/SKILL.md +150 -0
  240. phase_loop_runtime/skills_bundle/codex-phase-roadmap-builder/assets/review_prompt.md +19 -0
  241. phase_loop_runtime/skills_bundle/codex-phase-roadmap-builder/references/parallelization-heuristics.md +111 -0
  242. phase_loop_runtime/skills_bundle/codex-phase-roadmap-builder/references/roadmap-template.md +193 -0
  243. phase_loop_runtime/skills_bundle/codex-phase-roadmap-builder/scripts/validate_roadmap.py +32 -0
  244. phase_loop_runtime/skills_bundle/codex-plan-detailed/README.md +1 -0
  245. phase_loop_runtime/skills_bundle/codex-plan-detailed/SKILL.md +119 -0
  246. phase_loop_runtime/skills_bundle/codex-plan-detailed/assets/review_prompt.md +25 -0
  247. phase_loop_runtime/skills_bundle/codex-plan-phase/README.md +1 -0
  248. phase_loop_runtime/skills_bundle/codex-plan-phase/SKILL.md +307 -0
  249. phase_loop_runtime/skills_bundle/codex-plan-phase/assets/review_prompt.md +17 -0
  250. phase_loop_runtime/skills_bundle/codex-plan-phase/scripts/validate_plan_doc.py +1092 -0
  251. phase_loop_runtime/skills_bundle/codex-run-train/README.md +1 -0
  252. phase_loop_runtime/skills_bundle/codex-run-train/SKILL.md +75 -0
  253. phase_loop_runtime/skills_bundle/codex-skill-editor/README.md +1 -0
  254. phase_loop_runtime/skills_bundle/codex-skill-editor/SKILL.md +94 -0
  255. phase_loop_runtime/skills_bundle/codex-skill-editor/assets/editor_prompt.md +72 -0
  256. phase_loop_runtime/skills_bundle/codex-skill-improvement-planner/README.md +1 -0
  257. phase_loop_runtime/skills_bundle/codex-skill-improvement-planner/SKILL.md +114 -0
  258. phase_loop_runtime/skills_bundle/codex-skill-improvement-planner/assets/aggregator_prompt.md +79 -0
  259. phase_loop_runtime/skills_bundle/codex-task-contextualizer/README.md +1 -0
  260. phase_loop_runtime/skills_bundle/codex-task-contextualizer/SKILL.md +102 -0
  261. phase_loop_runtime/skills_bundle/codex-task-contextualizer/references/task-templates.md +103 -0
  262. phase_loop_runtime/skills_bundle/gemini-advisor-board/README.md +1 -0
  263. phase_loop_runtime/skills_bundle/gemini-advisor-board/SKILL.md +38 -0
  264. phase_loop_runtime/skills_bundle/gemini-advisor-panel/README.md +1 -0
  265. phase_loop_runtime/skills_bundle/gemini-advisor-panel/SKILL.md +38 -0
  266. phase_loop_runtime/skills_bundle/gemini-execute-detailed/README.md +1 -0
  267. phase_loop_runtime/skills_bundle/gemini-execute-detailed/SKILL.md +144 -0
  268. phase_loop_runtime/skills_bundle/gemini-execute-phase/README.md +1 -0
  269. phase_loop_runtime/skills_bundle/gemini-execute-phase/SKILL.md +198 -0
  270. phase_loop_runtime/skills_bundle/gemini-execute-phase/scripts/allocate_worktree_name.sh +33 -0
  271. phase_loop_runtime/skills_bundle/gemini-execute-phase/scripts/audit_lane_file_touches.py +197 -0
  272. phase_loop_runtime/skills_bundle/gemini-execute-phase/scripts/cleanup_lane_worktrees.sh +103 -0
  273. phase_loop_runtime/skills_bundle/gemini-execute-phase/scripts/parent_tree_leakage_check.sh +125 -0
  274. phase_loop_runtime/skills_bundle/gemini-execute-phase/scripts/post_merge_import_smoke.sh +62 -0
  275. phase_loop_runtime/skills_bundle/gemini-execute-phase/scripts/pre_merge_destructiveness_check.sh +127 -0
  276. phase_loop_runtime/skills_bundle/gemini-execute-phase/scripts/resolve_branch_from_sha.sh +51 -0
  277. phase_loop_runtime/skills_bundle/gemini-execute-phase/scripts/state.py +274 -0
  278. phase_loop_runtime/skills_bundle/gemini-execute-phase/scripts/sweep_stale_worktrees.sh +62 -0
  279. phase_loop_runtime/skills_bundle/gemini-execute-phase/scripts/team_teardown.sh +32 -0
  280. phase_loop_runtime/skills_bundle/gemini-execute-phase/scripts/validate_plan_doc.py +642 -0
  281. phase_loop_runtime/skills_bundle/gemini-execute-phase/scripts/verify_harness.sh +96 -0
  282. phase_loop_runtime/skills_bundle/gemini-phase-loop/README.md +1 -0
  283. phase_loop_runtime/skills_bundle/gemini-phase-loop/SKILL.md +111 -0
  284. phase_loop_runtime/skills_bundle/gemini-phase-roadmap-builder/README.md +1 -0
  285. phase_loop_runtime/skills_bundle/gemini-phase-roadmap-builder/SKILL.md +147 -0
  286. phase_loop_runtime/skills_bundle/gemini-phase-roadmap-builder/assets/review_prompt.md +19 -0
  287. phase_loop_runtime/skills_bundle/gemini-phase-roadmap-builder/references/parallelization-heuristics.md +111 -0
  288. phase_loop_runtime/skills_bundle/gemini-phase-roadmap-builder/references/roadmap-template.md +193 -0
  289. phase_loop_runtime/skills_bundle/gemini-phase-roadmap-builder/scripts/validate_roadmap.py +32 -0
  290. phase_loop_runtime/skills_bundle/gemini-plan-detailed/README.md +1 -0
  291. phase_loop_runtime/skills_bundle/gemini-plan-detailed/SKILL.md +119 -0
  292. phase_loop_runtime/skills_bundle/gemini-plan-detailed/assets/review_prompt.md +25 -0
  293. phase_loop_runtime/skills_bundle/gemini-plan-phase/README.md +1 -0
  294. phase_loop_runtime/skills_bundle/gemini-plan-phase/SKILL.md +217 -0
  295. phase_loop_runtime/skills_bundle/gemini-plan-phase/assets/review_prompt.md +17 -0
  296. phase_loop_runtime/skills_bundle/gemini-plan-phase/scripts/validate_plan_doc.py +1092 -0
  297. phase_loop_runtime/skills_bundle/gemini-run-train/README.md +1 -0
  298. phase_loop_runtime/skills_bundle/gemini-run-train/SKILL.md +75 -0
  299. phase_loop_runtime/skills_bundle/gemini-skill-editor/README.md +1 -0
  300. phase_loop_runtime/skills_bundle/gemini-skill-editor/SKILL.md +87 -0
  301. phase_loop_runtime/skills_bundle/gemini-skill-editor/assets/editor_prompt.md +72 -0
  302. phase_loop_runtime/skills_bundle/gemini-skill-improvement-planner/README.md +1 -0
  303. phase_loop_runtime/skills_bundle/gemini-skill-improvement-planner/SKILL.md +109 -0
  304. phase_loop_runtime/skills_bundle/gemini-skill-improvement-planner/assets/aggregator_prompt.md +79 -0
  305. phase_loop_runtime/skills_bundle/gemini-task-contextualizer/README.md +1 -0
  306. phase_loop_runtime/skills_bundle/gemini-task-contextualizer/SKILL.md +98 -0
  307. phase_loop_runtime/skills_bundle/gemini-task-contextualizer/references/task-templates.md +103 -0
  308. phase_loop_runtime/skills_bundle/opencode-advisor-board/README.md +1 -0
  309. phase_loop_runtime/skills_bundle/opencode-advisor-board/SKILL.md +38 -0
  310. phase_loop_runtime/skills_bundle/opencode-advisor-panel/README.md +1 -0
  311. phase_loop_runtime/skills_bundle/opencode-advisor-panel/SKILL.md +38 -0
  312. phase_loop_runtime/skills_bundle/opencode-execute-detailed/README.md +1 -0
  313. phase_loop_runtime/skills_bundle/opencode-execute-detailed/SKILL.md +144 -0
  314. phase_loop_runtime/skills_bundle/opencode-execute-phase/README.md +1 -0
  315. phase_loop_runtime/skills_bundle/opencode-execute-phase/SKILL.md +196 -0
  316. phase_loop_runtime/skills_bundle/opencode-execute-phase/scripts/allocate_worktree_name.sh +33 -0
  317. phase_loop_runtime/skills_bundle/opencode-execute-phase/scripts/audit_lane_file_touches.py +197 -0
  318. phase_loop_runtime/skills_bundle/opencode-execute-phase/scripts/cleanup_lane_worktrees.sh +103 -0
  319. phase_loop_runtime/skills_bundle/opencode-execute-phase/scripts/parent_tree_leakage_check.sh +125 -0
  320. phase_loop_runtime/skills_bundle/opencode-execute-phase/scripts/post_merge_import_smoke.sh +62 -0
  321. phase_loop_runtime/skills_bundle/opencode-execute-phase/scripts/pre_merge_destructiveness_check.sh +127 -0
  322. phase_loop_runtime/skills_bundle/opencode-execute-phase/scripts/resolve_branch_from_sha.sh +51 -0
  323. phase_loop_runtime/skills_bundle/opencode-execute-phase/scripts/state.py +274 -0
  324. phase_loop_runtime/skills_bundle/opencode-execute-phase/scripts/sweep_stale_worktrees.sh +62 -0
  325. phase_loop_runtime/skills_bundle/opencode-execute-phase/scripts/team_teardown.sh +32 -0
  326. phase_loop_runtime/skills_bundle/opencode-execute-phase/scripts/validate_plan_doc.py +642 -0
  327. phase_loop_runtime/skills_bundle/opencode-execute-phase/scripts/verify_harness.sh +96 -0
  328. phase_loop_runtime/skills_bundle/opencode-phase-loop/README.md +1 -0
  329. phase_loop_runtime/skills_bundle/opencode-phase-loop/SKILL.md +113 -0
  330. phase_loop_runtime/skills_bundle/opencode-phase-roadmap-builder/README.md +1 -0
  331. phase_loop_runtime/skills_bundle/opencode-phase-roadmap-builder/SKILL.md +147 -0
  332. phase_loop_runtime/skills_bundle/opencode-phase-roadmap-builder/assets/review_prompt.md +19 -0
  333. phase_loop_runtime/skills_bundle/opencode-phase-roadmap-builder/references/parallelization-heuristics.md +111 -0
  334. phase_loop_runtime/skills_bundle/opencode-phase-roadmap-builder/references/roadmap-template.md +193 -0
  335. phase_loop_runtime/skills_bundle/opencode-phase-roadmap-builder/scripts/validate_roadmap.py +32 -0
  336. phase_loop_runtime/skills_bundle/opencode-plan-detailed/README.md +1 -0
  337. phase_loop_runtime/skills_bundle/opencode-plan-detailed/SKILL.md +119 -0
  338. phase_loop_runtime/skills_bundle/opencode-plan-detailed/assets/review_prompt.md +25 -0
  339. phase_loop_runtime/skills_bundle/opencode-plan-phase/README.md +1 -0
  340. phase_loop_runtime/skills_bundle/opencode-plan-phase/SKILL.md +211 -0
  341. phase_loop_runtime/skills_bundle/opencode-plan-phase/assets/review_prompt.md +17 -0
  342. phase_loop_runtime/skills_bundle/opencode-plan-phase/scripts/validate_plan_doc.py +1092 -0
  343. phase_loop_runtime/skills_bundle/opencode-run-train/README.md +1 -0
  344. phase_loop_runtime/skills_bundle/opencode-run-train/SKILL.md +75 -0
  345. phase_loop_runtime/skills_bundle/opencode-skill-editor/README.md +1 -0
  346. phase_loop_runtime/skills_bundle/opencode-skill-editor/SKILL.md +87 -0
  347. phase_loop_runtime/skills_bundle/opencode-skill-editor/assets/editor_prompt.md +72 -0
  348. phase_loop_runtime/skills_bundle/opencode-skill-improvement-planner/README.md +1 -0
  349. phase_loop_runtime/skills_bundle/opencode-skill-improvement-planner/SKILL.md +109 -0
  350. phase_loop_runtime/skills_bundle/opencode-skill-improvement-planner/assets/aggregator_prompt.md +79 -0
  351. phase_loop_runtime/skills_bundle/opencode-task-contextualizer/README.md +1 -0
  352. phase_loop_runtime/skills_bundle/opencode-task-contextualizer/SKILL.md +98 -0
  353. phase_loop_runtime/skills_bundle/opencode-task-contextualizer/references/task-templates.md +103 -0
  354. phase_loop_runtime/state.py +156 -0
  355. phase_loop_runtime/state_degradation.py +136 -0
  356. phase_loop_runtime/state_ops.py +676 -0
  357. phase_loop_runtime/train_ledger.py +215 -0
  358. phase_loop_runtime/train_roadmap.py +339 -0
  359. phase_loop_runtime/train_runner.py +1197 -0
  360. phase_loop_runtime/verification_evidence.py +650 -0
  361. phase_loop_runtime/verification_evidence_validator.py +75 -0
  362. phase_loop_runtime/visual_evidence_validator.py +36 -0
  363. phase_loop_runtime/worker_pool.py +123 -0
  364. phase_loop_runtime/worktree_index.py +270 -0
  365. phase_loop_runtime-0.2.0.data/data/share/phase-loop-runtime/protocol/protocol.md +2475 -0
  366. phase_loop_runtime-0.2.0.dist-info/METADATA +106 -0
  367. phase_loop_runtime-0.2.0.dist-info/RECORD +370 -0
  368. phase_loop_runtime-0.2.0.dist-info/WHEEL +5 -0
  369. phase_loop_runtime-0.2.0.dist-info/entry_points.txt +9 -0
  370. phase_loop_runtime-0.2.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,231 @@
1
+ ---
2
+ name: codex-execute-phase
3
+ description: "Harness-optimized executor for a `<harness>-plan-phase` lane plan. Use when the user wants Harness to implement a planned phase. Executes lanes with clean git preflight, owned-file boundaries, verification, and optional explicit worker-subagent fanout for disjoint lanes."
4
+ ---
5
+
6
+ # Harness Execute Phase
7
+
8
+ Executes a phase plan produced by `<harness>-plan-phase`. The default executor is the main Harness thread. Worker subagents are optional and only used when the user explicitly asks for subagents, delegation, or parallel execution. Write-capable parallel execution also requires machine-verified disjoint lanes and scheduler-owned worktree assignments; prose lane labels are not sufficient.
9
+
10
+ ## Core Rules
11
+
12
+ Use `phase_loop_runtime.skill_paths` resolver helpers for harness skill roots, handoff roots, helper roots, and reflection roots.
13
+
14
+ - Read the full phase plan before editing.
15
+ - Preserve user work. Never revert changes you did not make.
16
+ - Use `apply_patch` for manual edits.
17
+ - When implementation depends on current external documentation, use PMCP first. Context7 is the preferred path for library docs; Bright Data or other search/scrape tools may be used only when `gateway_catalog_search` shows they are available.
18
+ - Before asking the user for credentials, account setup, infrastructure state, admin action, or another access blocker, inspect repo-local docs/config and safe read-only or metadata-only state from available CLIs: `op`, `gh`, `vercel`/`npx vercel`, `supabase`/`npx supabase`, `gcloud`, `wrangler`, `cloudflared`, and `gam`. Never record secret values.
19
+ - Keep lane ownership boundaries. If implementation requires touching another lane's files, stop and revise the plan or ask the user.
20
+ - Treat ignored, private, raw-data, credential, and evidence-source files as read-protected unless the phase plan or source bundle explicitly allowlists the exact path or glob for read access. Do not infer permission from nearby owned output paths, old memory, or prior phases.
21
+ - Before final closeout, compare `git status --short` dirty paths against the active plan's owned files and control artifacts. If any generated path is unowned, ignored without explicit allowlist/staging policy, or derived from unauthorized raw/private inputs, stop with `dirty_worktree_conflict` instead of calling the phase complete.
22
+ - For Pipeline-aware plans, recompute `source_bundle_sha256` from source bundle bytes before implementation or child work; treat `freshness.source_bundle_hash` as Pipeline-owned metadata unless it is a sha256 digest. For pipeline_required execution, validate protected-source hashes and stop before child launch on missing, stale, malformed, or mismatched source bundles.
23
+ - Refuse protected Pipeline writes, including `.pipeline/**`, `pipeline.definition.json`, governed-pipeline specs, Portal contracts, Greenfield authority files, private evidence, raw data, raw evidence, credentials, provider-supplied payloads, or legacy `.codex/phase-loop/` state unless the source-bundle write policy and phase-plan owned files both explicitly authorize the output path. The active plan and source bundle explicitly own the exact path or glob before these inputs or outputs may be read or written.
24
+ - Preserve standalone execution behavior for local phase plans without Pipeline metadata; governed-pipeline, Portal, Greenfield, `.pipeline/**`, and source bundles are not mandatory for manual dotfiles use.
25
+ - Use `## Execution Policy` only for model, effort, work-unit defaults, lane-specific policy, fallback, policy source, or override reason. `Dispatch Hints` remain executor fallback metadata. Supported selectors are `work-unit defaults`, `roadmap`, `plan`, `execute`, `repair`, `review`, `maintain-skills`, and lane selectors such as `SL-2`; reducer and verification work use lane selectors with `work-unit=phase_reducer` or `work-unit=phase_verify`. Policy precedence is CLI/operator override, phase-plan policy, roadmap policy, `Dispatch Hints`, then registry defaults; policy precedence must not allow silent downgrade without explicit fallback or default inheritance.
26
+ - Do not run destructive git commands such as `git reset --hard` or `git checkout -- <path>` unless the user explicitly requested that operation.
27
+ - Do not commit, push, or merge unless the user asked for those git actions.
28
+ - Claude Code CLI exception wording means local Claude Code CLI execution through the phase-loop launcher, not Anthropic API-key execution or PI provider fallback. Harness and Gemini fallback wording must stay CLI-based and reason-coded.
29
+
30
+ ## Runner-Owned Lane Work Units
31
+
32
+ Injected HARNESSLANE runs may include a `HarnessLaneAssignment` from
33
+ `shared/phase-loop/protocol.md`. Treat that assignment as the work-unit
34
+ contract: execute only the selected `lane_id`, write only the listed
35
+ `owned_files`, treat `consumed_interfaces` as read-only, and emit one shared
36
+ `automation:` closeout for that work unit. Installed-skill drift is
37
+ warning-only when the repo-injected context is present.
38
+
39
+ Review, reducer, verify, and closeout prompts are distinct from implementation
40
+ prompts. If the selected policy is unsupported by the active harness, stop with
41
+ a typed non-human blocker instead of silently downgrading. Do not spawn peer
42
+ harnesses directly; cross-harness execute, repair, or review work must be
43
+ externalized as a typed `DelegationRequest`.
44
+
45
+ ## Inputs
46
+
47
+ - Plan path: default latest `plans/phase-plan-*.md`.
48
+ - `--dry-run`: parse and print the lane schedule without editing.
49
+ - `--parallel`: allowed only when the user explicitly requests parallel worker execution.
50
+
51
+ If no plan path is explicit, first check the current repo and branch handoff from `<harness>-plan-phase` using `<harness>-config/shared/runtime-state.md`: read the repo-local handoff resolver target `.dev-skills/handoffs/<harness>-plan-phase/latest.md`, validate `from`, `repo`, `repo_root`, `branch`, `branch_slug`, `commit`, and `artifact`, then use the artifact only if it exists under the current repo root. Ignore missing or mismatched handoffs unless the user explicitly asks to reuse cross-branch state.
52
+
53
+ ## Preflight
54
+
55
+ 1. Resolve repo root and plan path.
56
+ 2. Run `git status --short`.
57
+ 3. Run `git status --short -- <plan_path>` and classify the plan as tracked, modified, or untracked. If untracked, warn before editing or executing: `This execution input is untracked and can be deleted by git clean -fd.`
58
+ 4. If the tree has unrelated dirty files, leave them alone and scope edits around them.
59
+ 5. Parse:
60
+ - interface gates;
61
+ - lane DAG;
62
+ - owned files;
63
+ - any explicit read allowlists for ignored, private, raw-data, credential, or evidence-source paths;
64
+ - task lists;
65
+ - verification commands.
66
+ - optional dispatch hints from the roadmap or plan `## Dispatch Hints` section, using only:
67
+ `preferred executors`, `allowed executors`, `fallback executors`, `disabled executors`, and `required capabilities`
68
+ with optional action selectors `roadmap`, `plan`, `execute`, `repair`, `review`, and `maintain-skills`.
69
+ Treat lane `**Owned files**` entries as the execution ownership contract:
70
+ repo-relative literals and globs inside backticks are owned paths, `none`
71
+ owns nothing, and the active roadmap plus active plan artifact are always
72
+ control paths. Treat `Interfaces consumed` as read-only contract inputs
73
+ unless the same path is also listed under `Owned files`. If a test or docs
74
+ update pressures execution to rewrite a consumed upstream artifact, first
75
+ adjust the current phase's owned tests/docs to consume the existing
76
+ contract; if that is impossible, stop and route back to `<harness>-plan-phase`
77
+ for an ownership or downstream-roadmap amendment.
78
+ Owned files authorize writes, not unrestricted reads of ignored/private/raw
79
+ inputs. Read ignored data, private evidence, raw corpora, local-only
80
+ exports, credentials, or user data only when the plan/source bundle names
81
+ the path or glob as an allowed read input; otherwise use metadata-only
82
+ fixtures, committed docs, or stop with a non-human plan/contract blocker.
83
+ 6. Validate producer dependencies:
84
+ - any lane that consumes another lane's findings, interfaces, or artifacts must list that producer lane in `Depends on`;
85
+ - any lane that writes a synthesized artifact must be downstream of every producer lane it summarizes;
86
+ - if dependencies are missing, stop and require a plan correction before execution.
87
+ 7. For Pipeline-aware plans, run `pipeline_execution_plan_diagnostic`: parse `phase-source-bundle.v1`, recompute `source_bundle_sha256` from source bundle bytes, re-check protected sources, and compare `freshness.source_bundle_hash` only when it is sha256-shaped. Stale source bundles, changed protected sources, missing Pipeline phase artifacts, and unknown Pipeline phase ids are repairable non-human blockers routed to planning or repair with `human_required=false` and `blocker_class=contract_bug`.
88
+ 8. For `--dry-run`, report the topological lane order and stop.
89
+
90
+ ## Execution Workflow
91
+
92
+ 1. Execute lanes in topological order.
93
+ 2. For each lane:
94
+ - resolve executor policy in this order: CLI/operator override, then phase-plan hints, then roadmap hints, then registry defaults;
95
+ - reject disabled or capability-mismatched preferred executors with a typed non-human blocker instead of silently falling through;
96
+ - read the owned files and related tests;
97
+ - write or update tests first when practical;
98
+ - implement only lane-scoped changes;
99
+ - for Pipeline-aware lanes, keep writes inside both the phase-plan owned files and source-bundle-authorized Pipeline outputs;
100
+ - do not edit consumed-interface artifacts unless they are also owned by
101
+ the active lane;
102
+ - run lane verification (normalize any phase-plan pytest `-k` selector whose prose terms contain spaces — e.g. `remote connect` becomes `'remote and connect'` — or quote it; a bare spaced `-k` term is an executor-side normalization, not a plan blocker);
103
+ - run any phase-level checks that cover touched files.
104
+ 3. After each lane:
105
+ - inspect `git diff -- <owned files>`;
106
+ - confirm no peer-owned files were modified;
107
+ - run `git status --short` and confirm every new or modified path is either lane-owned or a planning/control artifact;
108
+ - for any phase-owned generated path under an ignored parent, confirm the plan/source bundle explicitly allows it to be preserved or force-staged;
109
+ - run `pipeline_write_boundary_diagnostic` when the plan has Pipeline metadata, and fail closed on unauthorized `.pipeline/**`, protected Pipeline, `pipeline.definition.json`, or portal contract writes;
110
+ - record completed gates.
111
+ 4. After all lanes:
112
+ - run the full phase verification commands;
113
+ - if execution discoveries change downstream work, amend the phase roadmap at the nearest downstream phase in the amended roadmap that is not already executing;
114
+ - treat any older downstream phase plan or handoff as stale after a roadmap amendment and route the next step back through `<harness>-plan-phase` for the newly selected downstream phase;
115
+ - summarize changed files, tests run, and any residual risks.
116
+
117
+ ## Optional Worker Fanout
118
+
119
+ Use worker subagents only when the user explicitly authorizes parallel agent work and the DAG-ready lanes are disjoint.
120
+
121
+ For every worker brief:
122
+
123
+ - State that they are not alone in the codebase.
124
+ - Assign exact owned files or globs.
125
+ - List files they may read but not edit.
126
+ - Tell them not to revert unrelated changes.
127
+ - Require a final response with changed paths, tests run, failures, and blockers.
128
+ - Do not give two workers overlapping write ownership.
129
+
130
+ The main thread remains responsible for integrating results, reviewing diffs, running final verification, and resolving conflicts.
131
+
132
+ ## Failure Policy
133
+
134
+ - Test failure in a lane: diagnose once, fix within the lane if the cause is local, otherwise stop and report.
135
+ - Ownership violation: stop and revise the plan before continuing.
136
+ - Missing dependency, malformed lane dependency, or unclear interface: stop and route back to `<harness>-plan-phase` with `human_required=false` unless a true product or human decision is missing.
137
+ - Verification command unavailable: report the missing tool and run the closest available static check only if it is meaningful.
138
+ - True human-required blockers must use the frozen blocker taxonomy from `<harness>-config/shared/runtime-state.md`: `missing_secret`, `account_or_billing_setup`, `admin_approval`, `destructive_operation`, `ambiguous_roadmap_selection`, `product_decision_missing`, `dirty_worktree_conflict`, `branch_sync_conflict`, `stalled_child_observation`, `repeated_verification_failure`, or `unretryable_external_outage`.
139
+ - If the same verification remains failing after one local diagnosis and repair attempt, set `blocker_class=repeated_verification_failure`. If unrelated user work overlaps required lane files, set `blocker_class=dirty_worktree_conflict`.
140
+ - If a release plan with `phase_loop_mutation: release_dispatch` discovers that release-affecting files must be edited before dispatch, do not call the external release command. Stop with `automation.status=blocked`, `human_required=true`, `blocker_class=dirty_worktree_conflict`, and a summary telling the operator to complete/commit the prepare work first.
141
+ - If a phase is ready to report `complete`, verify that `git status --short` is clean for the target repo. If the repo is dirty only because of phase-owned output and required verification passed, do not report it as a human blocker; report `blocked`, `human_required=false`, `blocker_class=dirty_worktree_conflict`, and state that a loop repair turn can commit, isolate, or convert the state to a true human blocker. Use `human_required=true` only when pre-existing unrelated dirty paths overlap the required work, the repo is on the wrong branch/ref, or a true human/product/access decision is needed.
142
+
143
+
144
+ ## Runner Verification Evidence
145
+
146
+ Before reporting a successful closeout, require the runner-owned verification artifact. The closeout must name `verification_artifact_path`, quote the artifact summary line, and must not report `verification_status=passed` unless that artifact exists and supports the executed work. Treat dependency-manifest install refresh and the full suite before closeout as runner-enforced expectations, not optional narrative checks. A blocked gate may be re-verdicted only by rerunning the originally specified runner check; proxy evidence requires a roadmap or plan amendment before the verdict changes. A prior run's terminal-summary is authoritative for reconcile-or-skip only when that closeout was accepted; a rejected or blocked prior closeout — regardless of any self-reported `complete`/`passed` — must not be reconciled against. On a re-run, re-do and re-verify the phase work from scratch rather than skipping on a stale summary.
147
+
148
+
149
+ ## Spec Delta Closeout
150
+
151
+ When reporting `verification_status=passed` for a generic phase, attach the runner verification artifact (the closeout's `artifact_paths.verification`, or a top-level `verification_artifact_path`). If the phase legitimately has no executable verification (docs-only, config-only), record a `verification_evidence_opt_out` reason instead — one of `no_executable_verification`, `verification_deferred_to_later_phase`, or `operator_attested_manual`. This is the input the autonomy-first verification-evidence review gate checks (warn by default); recording the artifact or a typed opt-out keeps the closeout clean with no human.
152
+
153
+ Before final closeout, when the diff touches a user-visible public surface (CLI flags, exported symbols, config/openapi schema, contract docs, `README.md`, or `CHANGELOG.md`), record a `doc_delta_decision`: `docs_updated` (you updated the matching doc surface in this phase), `docs_follow_up_filed` (tracked for a later phase), or `no_doc_delta` (the change needs no doc update — state why). This is the input the autonomy-first doc-delta review gate checks; the gate defaults to `PHASE_LOOP_REVIEW=warn` (records the finding and the loop continues), so recording the decision keeps the closeout clean and is satisfiable by the agent with no human. Prefer updating the doc surface within the phase's docs lane over deferring.
154
+
155
+ Before final closeout, when the diff changes a UI/visual surface (`*.tsx`, `*.jsx`, `*.vue`, `*.svelte`, `*.css`/`*.scss`, or `components/**`), capture a screenshot of the rendered result (claude-in-chrome or Playwright-via-PMCP) and record its path as `visual_evidence_path` (with a brief `visual_evidence_observed` note). This is the input the autonomy-first visual-evidence review gate checks; it defaults to warn (recorded, non-blocking) and is satisfiable by the agent capturing the screenshot — no human eyeball needed to pass. The screenshot is the artifact a human spot-checks after a bounded run.
156
+
157
+ Before final closeout, choose exactly one `spec_delta_closeout.v1` decision: `no_spec_delta`, `roadmap_amendment`, `canonical_spec_update`, `governed_pipeline_refresh`, `mirror_cutover_required`, `dotfiles_skill_source_update`, or `human_source_judgment_required`. Cite metadata-only evidence paths such as the active plan, lane closeouts, targeted pytest output, and `git diff --check` output. Preserve the phase plan's target surfaces and `redaction_posture=metadata_only`; do not include raw specification bodies, raw patch bodies, credentials, provider-supplied payloads, local environment values, or evidence-source contents. Missing or malformed spec-closeout evidence is a repairable automation blocker with `blocker_class=contract_bug` unless the decision is `human_source_judgment_required`.
158
+
159
+ ## Closeout
160
+
161
+ ### Manifest lifecycle
162
+
163
+ After plan validation and before lane execution, perform a best-effort `plan-manifest append` lifecycle update through `phase_loop_runtime.plan_manifest.update_lifecycle` to mark the matching `type=phase` entry `executing` with run metadata. During closeout, update the same entry to `completed` or `failed` with verification metadata, reflection metadata, produced-gate metadata, `if_gates_produced`, and dirty-worktree summary fields as available. `if_gates_produced` must list only the IF gates the active phase produces per its own plan; never carry a prior phase's gate forward into this phase's closeout. Manifest lifecycle failures are non-fatal during the dual-mode window: emit a ledger warning, mention the warning in the mandatory reflection, and preserve the existing phase closeout JSON, verification, and dirty-worktree behavior.
164
+
165
+ Before final closeout, run `git status --short -- <plan_path> <roadmap_path>` for every consumed or updated planning artifact. If any planning artifact is untracked or modified and the user did not explicitly forbid staging, run `git add <path>` for each artifact. Rerun status and report `Artifact state: staged|tracked|modified|unstaged|blocked` for each artifact. Do not commit unless requested. Repo-local handoff files are operational state: do not `git add` an ignored handoff alongside the plan artifact unless the plan's owned-files/allowlist explicitly includes the handoff directory; leave ignored handoffs ignored and exclude them from artifact-state reporting.
166
+
167
+ Also run a whole-tree `git status --short` closeout audit. Classify every dirty path as phase-owned, planning/control, pre-existing unrelated, or unowned. For ignored phase-owned outputs that must be preserved, verify an explicit plan/source-bundle allowlist or staging policy before using `git add -f`; otherwise report a repairable `dirty_worktree_conflict`. Precedence for a verified phase: when required verification passed and the ONLY uncommitted paths are phase-owned outputs this run was not authorized to commit, report `terminal_status=awaiting_phase_closeout` and let the runner's graduated closeout gate commit them — do NOT report `dirty_worktree_conflict`; reserve that conflict for unowned, unauthorized-ignored, or overlapping-unrelated dirty paths. Never report `complete` while unowned generated files, unauthorized ignored outputs, or outputs derived from unauthorized raw/private reads remain in the worktree.
168
+
169
+ Determine the next step before final response and handoff:
170
+
171
+ - If the current phase is incomplete or verification failed, report `Next phase: <current alias> - blocked: <blocker>` and `Next command: none - <blocker>`.
172
+ - If another generated phase plan is ready, report `Next phase: <next alias> - execution ready` and `Next command: <harness>-execute-phase <next_plan_path>`.
173
+ - If the roadmap has an unplanned ready phase, report `Next phase: <next alias> - planning ready` and `Next command: <harness>-plan-phase <roadmap_path> <next_alias>`.
174
+ - If the roadmap needs extension, report `Next phase: none - roadmap extension needed` and `Next command: <harness>-phase-roadmap-builder <roadmap_path>`.
175
+ - If all phases are complete, report `Next phase: none - roadmap complete` and `Next command: none - roadmap complete`.
176
+
177
+ Add a machine-readable automation handoff that agrees with the human-readable next step fields. Closeout payload shape is defined by `EmitPhaseCloseout` in `phase_loop_runtime/baml_src/emit_phase_closeout.baml` (if that path is absent in the checkout, use the operator/prompt-supplied field contract or the installed `phase_loop_runtime` package — the missing vendored BAML source is not a blocker); keep skill text focused on value selection and handoff routing, not duplicated field ceremony.
178
+
179
+ Before final response, write a reflection for every non-trivial run. Write it to `resolve_skill_bundle_root("codex")/<harness>-execute-phase/reflections/<repo_hash>/<branch_slug>/<run_id>.md`. The reflection must include `## Run context` with skill name, ISO timestamp, repo, branch, commit, and artifact path if any, followed by `## What worked`, `## What didn't`, and `## Improvements to SKILL.md`. skip only when no artifact was produced AND no decision was made AND the run was pure inspection.
180
+
181
+ Set `automation.status=complete`, `verification_status=passed`, and `human_required=false` only when acceptance criteria and required verification are satisfied. Set `automation.status=executed` when implementation ran but acceptance reduction, artifact tracking, or a required verification remains unresolved. Use the consumed phase plan as the handoff `artifact`; the autonomous phase loop trusts phase status handoffs only when that plan's phase-loop frontmatter still matches the selected roadmap. For repairable plan gaps such as malformed dependencies or missing lane interfaces, set `automation.status=blocked`, `next_skill=<harness>-plan-phase`, `next_command=<harness>-plan-phase <roadmap_path> <current_alias>`, `next_model_hint=plan`, `next_effort_hint=high`, and `human_required=false`. For true human blockers, set `human_required=true`, a frozen `blocker_class`, a redacted `blocker_summary`, non-secret `required_human_inputs`, and redacted `access_attempts` when access was involved. Never include secret values.
182
+
183
+ Manual TUI runs remain valid without the outer phase loop. When `.phase-loop/` exists, treat it as the authoritative runner state; legacy `.codex/phase-loop/` files are compatibility artifacts only and must not block or supersede canonical `.phase-loop/` state. When canonical `.phase-loop/state.json` or `tui-handoff.md` lags behind the newer `.phase-loop/events.jsonl` plus live git topology, reconcile current phase state from the ledger and `git status --short`/HEAD and cite that reconciliation; stale handoff text is not blocking. Only append a legacy `manual` source event to `.codex/phase-loop/events.jsonl` for standalone manual compatibility when no canonical `.phase-loop/` runtime exists, using the same `automation.status`, `next_skill`, `next_command`, `next_model_hint`, `next_effort_hint`, `human_required`, `blocker_class`, `blocker_summary`, `required_human_inputs`, `verification_status`, `artifact`, and `artifact_state` values. This manual event import must preserve the same machine-readable closeout contract. If execution amended the roadmap downstream, compute `roadmap_sha256` and `phase_sha256` from the amended roadmap for the completed current phase before appending the event; do not reuse stale plan frontmatter, next-phase hashes, or pre-amendment roadmap hashes.
184
+
185
+ Report:
186
+
187
+ - lanes completed;
188
+ - files changed;
189
+ - planning artifact tracking state;
190
+ - next phase and next command;
191
+ - verification commands and results;
192
+ - commands not run and why;
193
+ - follow-up risks or manual checks.
194
+
195
+ Resolve closeout writes through `shared/phase-loop/handoff_path.py` and the repo-local handoff resolver; legacy harness handoff roots are read only for migration. Follow `<harness>-config/shared/runtime-state.md` and use Harness paths only:
196
+
197
+ - Reflection: `resolve_skill_bundle_root("codex")/<harness>-execute-phase/reflections/<repo_hash>/<branch_slug>/<run_id>.md`
198
+ - Handoff: `<repo>/.dev-skills/handoffs/<harness>-execute-phase/<run_id>.md`
199
+ - Latest handoff pointer: `<repo>/.dev-skills/handoffs/<harness>-execute-phase/latest.md`
200
+
201
+ Handoff frontmatter must include `from: <harness>-execute-phase`, `timestamp:`, `repo:`, `repo_root:`, `branch:`, `branch_slug:`, `commit:`, `run_id:`, `artifact:`, `artifact_state:`, `next_skill:`, `next_command:`, and `next_phase:`. Put open follow-up items in the body, and update `latest.md` with the same handoff content.
202
+
203
+ If execution is blocked by credentials, account setup, infrastructure state, admin action, or other access prerequisites, write a handoff with `human_required=true` and redacted `access_attempts` entries before asking the user to act. Each `access_attempts` entry must include `source`, `probe`, `result`, `details`, and `timestamp`, and `details` may report only metadata such as command availability, account or project identity, vault/item/field names, environment variable names, presence, and validation status.
204
+
205
+
206
+ ## Publication mode
207
+
208
+ After verified phase work, select exactly one of three modes. **Default to (a) unless a
209
+ clear interactive signal is present** — a run missing BOTH the adapter prompt prefix AND
210
+ `PHASE_LOOP_RUN_MODE` is AMBIGUOUS and MUST be treated as (a) (fail safe toward the runner).
211
+
212
+ - (a) Runner-managed closeout (incl. governed mode), OR ambiguous mode. If this is the
213
+ phase-loop adapter (the prompt begins with `<harness>-execute-phase <plan>` from a
214
+ pipeline run dir), or `PHASE_LOOP_RUN_MODE` is set (autonomous/governed), OR neither
215
+ interactive signal is clearly present, the RUNNER owns closeout and commit. Do NOT
216
+ independently publish — defer entirely to runner closeout (`awaiting_phase_closeout` /
217
+ runner commit). Publishing here would bypass the governed pre-merge review panel.
218
+ - (b) Interactive orchestrator on a clean, non-protected feature branch (a clear
219
+ interactive signal, and the merge target passed the merge-target safety gate). After the
220
+ Step-9 clean-tree state, push the merge-target branch and open a PR (`gh pr create`,
221
+ `--draft` if dependencies remain or verification was partial/skipped, else ready) instead
222
+ of leaving the lane merge only local.
223
+ - (c) Merge target is `main` or a protected branch. Already STOPPED at the merge-target
224
+ safety gate before any lane merge — never merge lanes onto `main`/protected. Re-target a
225
+ feature branch or take explicit instruction.
226
+
227
+ This applies only to interactive (non-runner) completion; it never overrides
228
+ `awaiting_phase_closeout`, the runner's deliberate non-complete terminal. Allowed runner
229
+ hygiene (forced lane-worktree removal, `branch -D`, `sweep_stale_worktrees.sh`) is
230
+ unchanged — the destructive-op ban targets publication branches/worktrees holding
231
+ unmerged work.
@@ -0,0 +1,33 @@
1
+ #!/usr/bin/env bash
2
+ # allocate_worktree_name.sh — emit a collision-impossible worktree name
3
+ # for a swim-lane teammate.
4
+ #
5
+ # Usage:
6
+ # allocate_worktree_name.sh <sl-id>
7
+ #
8
+ # <sl-id> Lane identifier, e.g. "sl-1" or "sl-2b".
9
+ #
10
+ # Emits exactly one line to stdout:
11
+ # lane-<sl-id>-<UTC-YYYYMMDDHHMMSS>-<4char-random>
12
+ #
13
+ # Rationale: the default `lane-<sl-id>` naming is not unique across rapid
14
+ # consecutive dispatch of in-process teammates — two teammates spawned in
15
+ # the same message can race on the same EnterWorktree slot. The 4-char
16
+ # random suffix + UTC timestamp eliminates the race by construction.
17
+
18
+ set -euo pipefail
19
+
20
+ if [[ $# -ne 1 ]]; then
21
+ echo "usage: allocate_worktree_name.sh <sl-id>" >&2
22
+ exit 2
23
+ fi
24
+
25
+ sl_id="$1"
26
+ ts="$(date -u +%Y%m%dT%H%M%S)"
27
+ rand="$(tr -dc 'a-z0-9' </dev/urandom | head -c 4 || true)"
28
+ if [[ -z "$rand" ]]; then
29
+ # Extremely unlikely; fall back to $RANDOM-derived 4 chars.
30
+ rand="$(printf "%04x" "$((RANDOM & 0xFFFF))")"
31
+ fi
32
+
33
+ echo "lane-${sl_id}-${ts}-${rand}"
@@ -0,0 +1,197 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ audit_lane_file_touches.py — audit a lane's commit against the plan's
4
+ disjoint-owned-files contract.
5
+
6
+ Usage:
7
+ audit_lane_file_touches.py <lane-sha> <plan-doc-path> <this-lane-id>
8
+
9
+ Emits EXACTLY one token on stdout, exit 0 always (verdict is on stdout
10
+ for the orchestrator to act on):
11
+
12
+ CLEAN
13
+ - Every file touched by <lane-sha> (vs its first-parent ancestor)
14
+ falls within <this-lane-id>'s `Owned files` globs from the plan
15
+ doc.
16
+
17
+ PEER_INTRUSION
18
+ - One or more files touched match some OTHER lane's `Owned files`
19
+ globs. The lane wandered into a peer's territory. Orchestrator
20
+ surfaces to user for merge/no-merge decision — defensive cross-
21
+ lane test-mock edits happen and are usually benign, but should be
22
+ reviewed rather than surfacing as a later merge conflict.
23
+
24
+ ORPHAN_FILES
25
+ - One or more files touched fall OUTSIDE every lane's globs. The
26
+ teammate worked outside any declared lane scope — probable bug.
27
+
28
+ Any combination of intrusion + orphan is reported with intrusion winning.
29
+ Details (which peer, which files) are written to stderr.
30
+ """
31
+
32
+ from __future__ import annotations
33
+
34
+ import re
35
+ import subprocess
36
+ import sys
37
+ from pathlib import Path
38
+ from typing import Dict, List, Optional, Set
39
+
40
+
41
+ _SL_SECTION_RE = re.compile(r"^###\s+(SL-\d+)\b.*$", re.MULTILINE)
42
+ _OWNED_BULLET_RE = re.compile(
43
+ r"^\s*-\s*\*\*Owned files\*\*\s*:\s*(.*?)\s*$",
44
+ re.IGNORECASE,
45
+ )
46
+ _CODE_TOKEN_RE = re.compile(r"`([^`]+)`")
47
+
48
+
49
+ def _fail(msg: str) -> None:
50
+ print(f"audit_lane_file_touches: {msg}", file=sys.stderr)
51
+
52
+
53
+ def _read(path: Path) -> str:
54
+ try:
55
+ return path.read_text(encoding="utf-8")
56
+ except Exception as exc:
57
+ _fail(f"cannot read {path}: {exc}")
58
+ sys.exit(2)
59
+
60
+
61
+ def _extract_lanes_body(src: str) -> str:
62
+ """Return the body between '## Lanes' and the next '## '."""
63
+ lines = src.splitlines()
64
+ out: List[str] = []
65
+ in_section = False
66
+ for line in lines:
67
+ if line.startswith("## ") and line.strip() == "## Lanes":
68
+ in_section = True
69
+ continue
70
+ if in_section and line.startswith("## "):
71
+ break
72
+ if in_section:
73
+ out.append(line)
74
+ return "\n".join(out)
75
+
76
+
77
+ def _parse_owned_globs(lanes_body: str) -> Dict[str, List[str]]:
78
+ """Map SL-N -> list of owned globs as declared in the plan."""
79
+ matches = list(_SL_SECTION_RE.finditer(lanes_body))
80
+ result: Dict[str, List[str]] = {}
81
+ for idx, m in enumerate(matches):
82
+ sl_id = m.group(1)
83
+ start = m.end()
84
+ end = matches[idx + 1].start() if idx + 1 < len(matches) else len(lanes_body)
85
+ body = lanes_body[start:end]
86
+ globs: List[str] = []
87
+ for line in body.splitlines():
88
+ mb = _OWNED_BULLET_RE.match(line)
89
+ if not mb:
90
+ continue
91
+ raw = mb.group(1)
92
+ tokens = _CODE_TOKEN_RE.findall(raw)
93
+ globs.extend(t.strip() for t in tokens if t.strip())
94
+ # Drop annotation-only items like "(NEW)" / "(DELETE)".
95
+ globs = [
96
+ g.split()[0].strip() for g in globs
97
+ if g and not g.startswith("(")
98
+ ]
99
+ result[sl_id] = globs
100
+ return result
101
+
102
+
103
+ def _glob_to_regex(pattern: str) -> re.Pattern:
104
+ """Minimal glob → regex. ** → any depth; * → any non-/; ? → one non-/."""
105
+ s = pattern.strip("`").strip()
106
+ esc = re.escape(s)
107
+ esc = esc.replace(r"\*\*", ".*").replace(r"\*", "[^/]*").replace(r"\?", "[^/]")
108
+ return re.compile("^" + esc + "$")
109
+
110
+
111
+ def _touched_files(sha: str) -> List[str]:
112
+ """Files changed by <sha> relative to its first parent."""
113
+ try:
114
+ r = subprocess.run(
115
+ ["git", "diff", "--name-only", f"{sha}^..{sha}"],
116
+ capture_output=True, text=True, check=True,
117
+ )
118
+ except subprocess.CalledProcessError:
119
+ # Commit has no parent (e.g., root) — fall back to diff against empty tree.
120
+ r = subprocess.run(
121
+ ["git", "show", "--name-only", "--pretty=", sha],
122
+ capture_output=True, text=True, check=True,
123
+ )
124
+ return [line for line in r.stdout.splitlines() if line.strip()]
125
+
126
+
127
+ def main(argv: List[str]) -> int:
128
+ if len(argv) != 4:
129
+ _fail("usage: audit_lane_file_touches.py <lane-sha> <plan-doc-path> <this-lane-id>")
130
+ return 2
131
+
132
+ lane_sha = argv[1]
133
+ plan_path = Path(argv[2])
134
+ this_lane = argv[3]
135
+
136
+ if not plan_path.exists():
137
+ _fail(f"plan doc not found: {plan_path}")
138
+ return 2
139
+
140
+ src = _read(plan_path)
141
+ lanes_body = _extract_lanes_body(src)
142
+ owned_map = _parse_owned_globs(lanes_body)
143
+
144
+ if this_lane not in owned_map:
145
+ _fail(f"lane {this_lane} not found in plan doc's `## Lanes` section")
146
+ return 2
147
+
148
+ # Compile regexes per lane.
149
+ compiled: Dict[str, List[re.Pattern]] = {
150
+ sl: [_glob_to_regex(g) for g in globs]
151
+ for sl, globs in owned_map.items()
152
+ }
153
+
154
+ touched = _touched_files(lane_sha)
155
+
156
+ def match_any(path: str, pats: List[re.Pattern]) -> bool:
157
+ return any(p.match(path) for p in pats)
158
+
159
+ intrusions: Dict[str, List[str]] = {}
160
+ orphans: List[str] = []
161
+ clean: List[str] = []
162
+ for path in touched:
163
+ if match_any(path, compiled[this_lane]):
164
+ clean.append(path)
165
+ continue
166
+ peer_hit: Optional[str] = None
167
+ for sl, pats in compiled.items():
168
+ if sl == this_lane:
169
+ continue
170
+ if match_any(path, pats):
171
+ peer_hit = sl
172
+ break
173
+ if peer_hit is not None:
174
+ intrusions.setdefault(peer_hit, []).append(path)
175
+ else:
176
+ orphans.append(path)
177
+
178
+ # Emit verdict. Intrusion takes precedence over orphan (intrusion is more actionable).
179
+ if intrusions:
180
+ for peer, paths in sorted(intrusions.items()):
181
+ _fail(f"{this_lane} touched files owned by {peer}: {paths}")
182
+ if orphans:
183
+ _fail(f"{this_lane} also touched orphan files (no lane owns): {orphans}")
184
+ print("PEER_INTRUSION")
185
+ return 0
186
+
187
+ if orphans:
188
+ _fail(f"{this_lane} touched files outside any lane's Owned files: {orphans}")
189
+ print("ORPHAN_FILES")
190
+ return 0
191
+
192
+ print("CLEAN")
193
+ return 0
194
+
195
+
196
+ if __name__ == "__main__":
197
+ sys.exit(main(sys.argv))
@@ -0,0 +1,103 @@
1
+ #!/usr/bin/env bash
2
+ # cleanup_lane_worktrees.sh — remove lane worktrees and their auto-named
3
+ # branches after a phase merges.
4
+ #
5
+ # Usage:
6
+ # cleanup_lane_worktrees.sh <branch-pattern>
7
+ #
8
+ # <branch-pattern> Glob applied to each worktree's branch name (the
9
+ # short name, not refs/heads/…). Defaults to
10
+ # 'worktree-*' so the common case works with no arg.
11
+ #
12
+ # Behavior:
13
+ # - Enumerates every worktree via `git worktree list --porcelain`.
14
+ # - Skips the orchestrator's own worktree (identified by matching the
15
+ # `git rev-parse --show-toplevel` of the current cwd).
16
+ # - For each remaining worktree whose branch matches <branch-pattern>:
17
+ # * `git worktree remove --force <path>`
18
+ # * If the branch also matches 'worktree-*' or 'phase/*/sl-*',
19
+ # `git branch -D <branch>` (salvage footgun: -D, not -d).
20
+ # - Never blocks the phase: exit 0 even on individual cleanup failures;
21
+ # each failure is logged to stderr.
22
+ #
23
+ # Rationale: Step 7 post-merge cleanup. Keeps human-named branches intact
24
+ # (skills/*, feature/*, fix/*) even when accidentally matched by glob.
25
+
26
+ set -uo pipefail
27
+
28
+ pattern="${1:-worktree-*}"
29
+
30
+ # Resolve orchestrator's anchored worktree so we don't try to delete it.
31
+ orch_root=""
32
+ if orch_root="$(git rev-parse --show-toplevel 2>/dev/null)"; then
33
+ :
34
+ fi
35
+
36
+ removed=0
37
+ skipped=0
38
+
39
+ # Parse `git worktree list --porcelain`. Each record is separated by a blank line:
40
+ # worktree <path>
41
+ # HEAD <sha>
42
+ # branch refs/heads/<name>
43
+ while IFS= read -r block; do
44
+ # `git worktree list --porcelain` actually yields one line per key; we
45
+ # collapse them back into records here.
46
+ [[ -z "$block" ]] && continue
47
+ key="${block%% *}"
48
+ value="${block#* }"
49
+ case "$key" in
50
+ worktree)
51
+ wt_path="$value"
52
+ wt_branch=""
53
+ ;;
54
+ branch)
55
+ # value looks like 'refs/heads/worktree-sl-1'
56
+ wt_branch="${value#refs/heads/}"
57
+ ;;
58
+ HEAD) ;; # ignore
59
+ detached) wt_branch="" ;;
60
+ esac
61
+ # When we hit a new `worktree` line, the previous record is complete —
62
+ # but the block-mode loop above feeds us line-by-line. We process each
63
+ # line and finalize when we hit a record boundary below.
64
+ done < <(git worktree list --porcelain)
65
+
66
+ # Process each worktree block (re-read cleanly; the above was an artifact).
67
+ while IFS= read -r path; do
68
+ [[ -z "$path" ]] && continue
69
+ # Skip orchestrator's anchor.
70
+ if [[ "$path" == "$orch_root" ]]; then
71
+ skipped=$((skipped + 1))
72
+ continue
73
+ fi
74
+ # Resolve this worktree's branch.
75
+ branch="$(git -C "$path" rev-parse --abbrev-ref HEAD 2>/dev/null || echo '')"
76
+ if [[ -z "$branch" || "$branch" == "HEAD" ]]; then
77
+ # Detached HEAD worktree — skip.
78
+ skipped=$((skipped + 1))
79
+ continue
80
+ fi
81
+ # Apply the branch pattern.
82
+ # shellcheck disable=SC2053
83
+ if [[ "$branch" != $pattern ]]; then
84
+ skipped=$((skipped + 1))
85
+ continue
86
+ fi
87
+ # Remove the worktree.
88
+ if git worktree remove --force "$path" 2>/dev/null; then
89
+ removed=$((removed + 1))
90
+ else
91
+ echo "cleanup_lane_worktrees: failed to remove worktree $path (branch=$branch)" >&2
92
+ continue
93
+ fi
94
+ # Delete the branch only if it's an auto-named pattern.
95
+ if [[ "$branch" == worktree-* || "$branch" == phase/*/sl-* ]]; then
96
+ if ! git branch -D "$branch" 2>/dev/null; then
97
+ echo "cleanup_lane_worktrees: failed to delete branch $branch" >&2
98
+ fi
99
+ fi
100
+ done < <(git worktree list --porcelain | awk '$1 == "worktree" { print $2 }')
101
+
102
+ echo "cleanup_lane_worktrees: removed $removed, skipped $skipped"
103
+ exit 0