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,365 @@
1
+ from __future__ import annotations
2
+
3
+ import re
4
+ import subprocess
5
+ from pathlib import Path
6
+
7
+ from .discovery import manifest_plan_artifact, roadmap_fingerprint, roadmap_repo_relative_path
8
+ from .injection import build_lane_prompt_bundle, build_prompt_bundle
9
+ from .models import DelegationRequest, HarnessLaneAssignment, ParentChildRunMetadata, PhaseSourceBundle, PromptBundle
10
+
11
+
12
+ def build_prompt(
13
+ action: str,
14
+ roadmap: Path,
15
+ phase: str | None = None,
16
+ plan: Path | None = None,
17
+ blocker_summary: str | None = None,
18
+ repair_context: dict[str, object] | None = None,
19
+ harness_target: str = "codex",
20
+ injection_mode_override: str | None = None,
21
+ harness_lane_assignment: HarnessLaneAssignment | None = None,
22
+ delegation_request: DelegationRequest | None = None,
23
+ parent_child_metadata: ParentChildRunMetadata | None = None,
24
+ planner_source_bundle_context: PhaseSourceBundle | None = None,
25
+ ) -> PromptBundle:
26
+ repo = _roadmap_repo_root(roadmap)
27
+ if harness_lane_assignment is not None:
28
+ return _with_delegation_guidance(
29
+ build_lane_prompt_bundle(
30
+ repo=repo,
31
+ harness_target=harness_target,
32
+ action=action,
33
+ roadmap=roadmap,
34
+ assignment=harness_lane_assignment,
35
+ plan=plan,
36
+ injection_mode_override=injection_mode_override,
37
+ ),
38
+ delegation_request=delegation_request,
39
+ parent_child_metadata=parent_child_metadata,
40
+ )
41
+ if action == "roadmap":
42
+ return build_prompt_bundle(
43
+ repo=repo,
44
+ harness_target=harness_target,
45
+ action="roadmap",
46
+ roadmap=roadmap,
47
+ injection_mode_override=injection_mode_override,
48
+ )
49
+ if action == "plan":
50
+ body = _plan_execution_body(repo, roadmap, phase)
51
+ if planner_source_bundle_context is not None:
52
+ body = f"{body}\n\n{_planner_source_bundle_section(planner_source_bundle_context)}"
53
+ return build_prompt_bundle(
54
+ repo=repo,
55
+ harness_target=harness_target,
56
+ action="plan",
57
+ roadmap=roadmap,
58
+ phase=phase,
59
+ body=body,
60
+ injection_mode_override=injection_mode_override,
61
+ )
62
+ if action == "execute":
63
+ return _with_delegation_guidance(
64
+ build_prompt_bundle(
65
+ repo=repo,
66
+ harness_target=harness_target,
67
+ action="execute",
68
+ roadmap=roadmap,
69
+ phase=phase,
70
+ plan=plan,
71
+ injection_mode_override=injection_mode_override,
72
+ body=(
73
+ "If this phase discovers steering that changes downstream work, amend the phase roadmap at the nearest downstream phase "
74
+ "that is not already executing. Do not treat an older downstream phase plan as authoritative after a roadmap amendment. "
75
+ "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. "
76
+ "Before closeout, run `git status --short` and classify every dirty path against the active owned-file contract; report a repairable dirty_worktree_conflict instead of completion for unowned generated files, unauthorized ignored outputs, or outputs derived from unauthorized raw/private reads."
77
+ ),
78
+ ),
79
+ delegation_request=delegation_request,
80
+ parent_child_metadata=parent_child_metadata,
81
+ )
82
+ if action == "skill-maintenance":
83
+ return build_prompt_bundle(repo=repo, harness_target="codex", action="maintain-skills", roadmap=roadmap)
84
+ if action == "repair":
85
+ summary = blocker_summary or "non-human phase-loop blocker"
86
+ context = repair_context or {}
87
+ state_path = context.get("state_path", ".phase-loop/state.json")
88
+ events_path = context.get("events_path", ".phase-loop/events.jsonl")
89
+ handoff_path = context.get("handoff_path", ".phase-loop/tui-handoff.md")
90
+ handoff_command = context.get("handoff_command", "phase-loop handoff")
91
+ status_command = context.get("status_command", "phase-loop status --json")
92
+ plan_path = str(plan or context.get("plan_path") or "none")
93
+ terminal_summary = context.get("terminal_summary") or {}
94
+ closeout_summary = context.get("closeout_summary") or {}
95
+ artifact_paths = context.get("artifact_paths") or {}
96
+ dirty_paths = context.get("dirty_paths") or ()
97
+ phase_owned_dirty_paths = context.get("phase_owned_dirty_paths") or ()
98
+ previous_phase_owned_paths = context.get("previous_phase_owned_paths") or ()
99
+ unowned_dirty_paths = context.get("unowned_dirty_paths") or ()
100
+ pre_existing_dirty_paths = context.get("pre_existing_dirty_paths") or ()
101
+ phase_owned_dirty = str(bool(context.get("phase_owned_dirty", False))).lower()
102
+ continuation_guidance = (
103
+ "These paths were recorded as phase-owned output from a previous attempt for this same phase. "
104
+ "Continue or restart the previous execute attempt; do not treat these as unrelated dirty files.\n"
105
+ if previous_phase_owned_paths
106
+ else ""
107
+ )
108
+ return _with_delegation_guidance(
109
+ build_prompt_bundle(
110
+ repo=repo,
111
+ harness_target=harness_target,
112
+ action="repair",
113
+ roadmap=roadmap,
114
+ phase=phase,
115
+ plan=plan,
116
+ injection_mode_override=injection_mode_override,
117
+ body=(
118
+ f"Current blocker: {summary}\n\n"
119
+ "Canonical runner state:\n"
120
+ "- When `.phase-loop/` exists, it is the authoritative phase-loop state.\n"
121
+ "- Legacy `.codex/phase-loop/` files are compatibility artifacts only; do not use them to block or supersede canonical `.phase-loop/` state.\n\n"
122
+ "Repair checklist:\n"
123
+ f"1. Inspect `{state_path}`.\n"
124
+ f"2. Inspect `{events_path}`.\n"
125
+ f"3. Inspect `{handoff_path}` or run `{handoff_command}`.\n"
126
+ f"4. Inspect the active phase plan artifact: `{plan_path}`.\n"
127
+ f"5. Re-check machine state with `{status_command}` before and after any local repair.\n"
128
+ "6. Verify whether every dirty path is phase-owned before changing repo state.\n"
129
+ "7. Apply closeout only when the recorded closeout policy allows it.\n"
130
+ "8. Runner-owned `.phase-loop/` ledger writes are optional and must only be attempted when this launch explicitly allows them. "
131
+ "If adapter constraints make `.phase-loop/` read-only or ignored, do not claim ledger mutation; emit a valid shared automation closeout so the parent runner can reconcile the repair.\n"
132
+ "9. 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.\n"
133
+ "10. Before repair closeout, classify every dirty path against the active owned-file contract; preserve ignored phase-owned outputs only when the plan/source bundle includes an explicit allowlist or staging policy.\n\n"
134
+ f"{continuation_guidance}"
135
+ "Allowed outcomes only:\n"
136
+ "- Make the smallest local repair that clears the blocker and leaves the phase resume-ready.\n"
137
+ "- Refresh stale roadmap or phase-plan artifacts when the repair is purely mechanical.\n"
138
+ "- Preserve or freeze a true human blocker with `human_required=true` and the frozen blocker taxonomy.\n\n"
139
+ "Trusted machine context:\n"
140
+ f"- terminal_status={terminal_summary.get('terminal_status', 'unknown')}\n"
141
+ f"- verification_status={terminal_summary.get('verification_status', 'unknown')}\n"
142
+ f"- next_action={terminal_summary.get('next_action', 'unknown')}\n"
143
+ f"- dirty_paths={', '.join(dirty_paths) if dirty_paths else 'none'}\n"
144
+ f"- phase_owned_dirty={phase_owned_dirty}\n"
145
+ f"- phase_owned_dirty_paths={', '.join(phase_owned_dirty_paths) if phase_owned_dirty_paths else 'none'}\n"
146
+ f"- previous_phase_owned_paths={', '.join(previous_phase_owned_paths) if previous_phase_owned_paths else 'none'}\n"
147
+ f"- unowned_dirty_paths={', '.join(unowned_dirty_paths) if unowned_dirty_paths else 'none'}\n"
148
+ f"- pre_existing_dirty_paths={', '.join(pre_existing_dirty_paths) if pre_existing_dirty_paths else 'none'}\n"
149
+ f"- closeout_mode={closeout_summary.get('closeout_mode', 'none')}\n"
150
+ f"- closeout_action={closeout_summary.get('closeout_action', 'none')}\n"
151
+ f"- closeout_verification={closeout_summary.get('verification_status', 'none')}\n"
152
+ f"- latest_run_log={artifact_paths.get('log', 'none')}\n"
153
+ f"- latest_terminal_summary={artifact_paths.get('terminal', 'none')}\n"
154
+ f"- latest_launch_metadata={artifact_paths.get('metadata', 'none')}\n\n"
155
+ "If release preparation and release dispatch are mixed, amend the roadmap at the nearest downstream phase "
156
+ "that is not already executing so preparation and `phase_loop_mutation: release_dispatch` happen in "
157
+ "separate phases. If the operator TUI is stale, point it back to the handoff file or commands above "
158
+ "instead of inventing a new recovery path."
159
+ ),
160
+ ),
161
+ delegation_request=delegation_request,
162
+ parent_child_metadata=parent_child_metadata,
163
+ )
164
+ return _with_delegation_guidance(
165
+ build_prompt_bundle(
166
+ repo=repo,
167
+ harness_target=harness_target,
168
+ action="review",
169
+ roadmap=roadmap,
170
+ phase=phase,
171
+ plan=plan,
172
+ injection_mode_override=injection_mode_override,
173
+ ),
174
+ delegation_request=delegation_request,
175
+ parent_child_metadata=parent_child_metadata,
176
+ )
177
+
178
+
179
+ def build_skill_maintenance_prompt(options) -> str:
180
+ if not options.apply_skill_edits:
181
+ return f"codex-skill-improvement-planner --min-reflections {options.min_reflections}"
182
+ parts = ["codex-skill-editor", "--improvement-plan", str(options.improvement_plan)]
183
+ for skill in options.allow_skills:
184
+ parts.extend(["--allow-skill", skill])
185
+ return " ".join(parts)
186
+
187
+
188
+ def _plan_execution_body(repo: Path, roadmap: Path, phase: str | None) -> str:
189
+ roadmap_rel = roadmap_repo_relative_path(repo, roadmap)
190
+ plan_rel = _expected_plan_artifact_path(roadmap, phase)
191
+ try:
192
+ roadmap_hash = roadmap_fingerprint(roadmap)
193
+ except OSError:
194
+ roadmap_hash = "<compute-from-roadmap>"
195
+ phase_text = phase or "the selected phase"
196
+ return (
197
+ "This phase-loop planning run is execution mode, not planning-only review mode. "
198
+ f"Write the repo-local phase plan artifact for {phase_text} instead of returning only `<proposed_plan>` unless a real blocker prevents the write. "
199
+ f"Write it exactly to `{plan_rel}`; do not use lowercase or alternate filename variants. "
200
+ f"Use `roadmap: {roadmap_rel}` and `roadmap_sha256: {roadmap_hash}` in the plan frontmatter. "
201
+ "Treat `.phase-loop/` as the authoritative runner state when it exists. Legacy `.codex/phase-loop/` files are compatibility artifacts only; do not use them to block or supersede canonical `.phase-loop/` state. "
202
+ "Use optional `## Execution Policy` only for model, effort, work-unit defaults, lane-specific policy, fallback, policy source, or override reason; `Dispatch Hints` remain the executor-only fallback. "
203
+ "Execution Policy selectors must be `work-unit defaults`, `roadmap`, `plan`, `execute`, `repair`, `review`, `maintain-skills`, or lane selectors such as `SL-2`; do not invent action selectors like `reduce` or `verify`. "
204
+ "Reducer and verification work use lane selectors with `work-unit=phase_reducer` or `work-unit=phase_verify`. "
205
+ "Policy precedence is CLI/operator override, phase-plan policy, roadmap policy, `Dispatch Hints`, then registry defaults, and silent downgrade is forbidden without explicit fallback or default inheritance."
206
+ )
207
+
208
+
209
+ def _planner_source_bundle_section(bundle: PhaseSourceBundle) -> str:
210
+ protected_summary = ", ".join(
211
+ f"{source.path} ({source.category}, sha256={source.sha256 or 'none'})"
212
+ for source in bundle.protected_sources
213
+ )
214
+ source_files = ", ".join(
215
+ f"{item.get('path')} ({item.get('purpose', 'source')}, sha256={item.get('sha256', 'none')})"
216
+ for item in bundle.source_files
217
+ if item.get("path")
218
+ )
219
+ owned_files = bundle.delegated_write_policy.get("owned_files", ())
220
+ read_only_files = bundle.delegated_write_policy.get("read_only_files", ())
221
+ return (
222
+ "## Pipeline planning source bundle\n\n"
223
+ "Prefer the bundled canonical specs, diagrams, current-state artifacts, execution graph inputs, "
224
+ "and protected source manifest over ambient repository guesses.\n\n"
225
+ f"- source_bundle: `{bundle.path}`\n"
226
+ f"- source_bundle_sha256: `{bundle.sha256}`\n"
227
+ f"- pipeline_phase_id: `{bundle.phase_id}`\n"
228
+ f"- pipeline_phase_alias: `{bundle.phase_alias}`\n"
229
+ f"- pipeline_mode: `{bundle.pipeline_mode}`\n"
230
+ f"- roadmap: `{bundle.roadmap_path}` sha256=`{bundle.roadmap_sha256}`\n"
231
+ f"- phase_plan_path: `{bundle.phase_plan_path}`\n"
232
+ f"- artifact_target_root: `{bundle.artifact_target_root or 'none'}`\n"
233
+ f"- protected_sources: {protected_summary or 'none'}\n"
234
+ f"- source_files: {source_files or 'none'}\n"
235
+ f"- delegated_write_policy.owned_files: {_policy_values(owned_files)}\n"
236
+ f"- delegated_write_policy.read_only_files: {_policy_values(read_only_files)}\n\n"
237
+ "When writing the plan frontmatter, include `source_bundle`, `source_bundle_sha256`, "
238
+ "`pipeline_phase_id`, and `pipeline_mode` exactly from this bundle. Preserve the exact artifact path supplied by the bundle "
239
+ "for the phase plan target. The delegated write policy names the only Pipeline-owned write scope; "
240
+ "protected-source entries are read-only unless that policy explicitly owns the exact path or glob. "
241
+ "Do not infer writes to `.pipeline/**`, governed-pipeline specs, Portal contracts, Greenfield authority files, "
242
+ "private evidence, raw data, credentials, provider payloads, or legacy `.codex/phase-loop/` state from ambient repo context. "
243
+ "If any bundle freshness or protected-source entry is stale, block with a repairable non-human blocker instead of writing a partial plan."
244
+ )
245
+
246
+
247
+ def _policy_values(value: object) -> str:
248
+ if isinstance(value, (list, tuple)):
249
+ return ", ".join(str(item) for item in value) or "none"
250
+ return str(value) if value else "none"
251
+
252
+
253
+ def _roadmap_repo_root(roadmap: Path) -> Path:
254
+ resolved = roadmap.expanduser().resolve()
255
+ cwd = resolved.parent if resolved.parent.exists() else Path.cwd()
256
+ try:
257
+ output = subprocess.check_output(
258
+ ["git", "-C", str(cwd), "rev-parse", "--show-toplevel"],
259
+ text=True,
260
+ stderr=subprocess.DEVNULL,
261
+ ).strip()
262
+ if output:
263
+ return Path(output).resolve()
264
+ except Exception:
265
+ pass
266
+ return resolved.parents[1] if len(resolved.parents) > 1 else resolved.parent
267
+
268
+
269
+ def _expected_plan_artifact_path(roadmap: Path, phase: str | None) -> str:
270
+ if phase:
271
+ repo = _roadmap_repo_root(roadmap)
272
+ manifest_plan, conflict = manifest_plan_artifact(repo, phase, roadmap=roadmap)
273
+ if manifest_plan is not None and conflict is None:
274
+ try:
275
+ return manifest_plan.relative_to(repo).as_posix()
276
+ except ValueError:
277
+ pass
278
+ version_match = re.search(r"(v[\w.-]+)", roadmap.stem)
279
+ version = version_match.group(1) if version_match else "v1"
280
+ alias = phase or "selected-phase"
281
+ return f"plans/phase-plan-{version}-{alias}.md"
282
+
283
+
284
+ def _with_delegation_guidance(
285
+ bundle: PromptBundle,
286
+ *,
287
+ delegation_request: DelegationRequest | None,
288
+ parent_child_metadata: ParentChildRunMetadata | None,
289
+ ) -> PromptBundle:
290
+ body_sections = [bundle.body.strip()] if bundle.body.strip() else []
291
+ context_sections = [bundle.context_body.strip()] if bundle.context_body else ([bundle.body.strip()] if bundle.body.strip() else [])
292
+ guidance = _delegation_request_guidance()
293
+ body_sections.append(guidance)
294
+ context_sections.append(guidance)
295
+ if delegation_request is not None:
296
+ delegated_context = _delegation_request_context(delegation_request, parent_child_metadata)
297
+ body_sections.append(delegated_context)
298
+ context_sections.append(delegated_context)
299
+ return PromptBundle(
300
+ workflow_command=bundle.workflow_command,
301
+ body="\n\n".join(section for section in body_sections if section).strip(),
302
+ injection_mode=bundle.injection_mode,
303
+ context_body="\n\n".join(section for section in context_sections if section).strip(),
304
+ expected_skill_pack=bundle.expected_skill_pack,
305
+ product_action=bundle.product_action,
306
+ skill_bundle_id=bundle.skill_bundle_id,
307
+ skill_bundle_sha256=bundle.skill_bundle_sha256,
308
+ fallback_mode=bundle.fallback_mode,
309
+ context_path=bundle.context_path,
310
+ recommended_installed_roots=bundle.recommended_installed_roots,
311
+ installed_skill_roots=bundle.installed_skill_roots,
312
+ installed_skill_warnings=bundle.installed_skill_warnings,
313
+ bridge_skill_inventory=bundle.bridge_skill_inventory,
314
+ )
315
+
316
+
317
+ def _delegation_request_guidance() -> str:
318
+ return (
319
+ "Delegation broker contract:\n"
320
+ "- Do not spawn peer harnesses directly.\n"
321
+ "- Native Claude team tasks stay internal unless they emit a typed runner delegation request.\n"
322
+ "- If review, repair, or execute work should move to another harness, emit a typed delegation request instead.\n"
323
+ "- Required request fields: `request_id`, `product_action`, `target_executor`, `reason`, `owned_files`, `expected_output`, `priority`.\n"
324
+ "- Optional request fields: `review_context`, `repair_context`, metadata-only `budget`.\n"
325
+ "- Approved cross-harness child work is limited to `codex` or `claude` for `execute`, `repair`, and `review`.\n"
326
+ "- Keep owned-file claims narrow and phase-valid. The runner validates active-loop mode, ownership, depth, fanout, budget metadata, and dispatch policy before any child launch."
327
+ )
328
+
329
+
330
+ def _delegation_request_context(
331
+ request: DelegationRequest,
332
+ parent_child_metadata: ParentChildRunMetadata | None,
333
+ ) -> str:
334
+ lines = [
335
+ "Delegated child context:",
336
+ f"- request id: `{request.request_id}`",
337
+ f"- requested action: `{request.product_action}`",
338
+ f"- target executor: `{request.target_executor}`",
339
+ f"- priority: `{request.priority}`",
340
+ f"- reason: {request.reason}",
341
+ f"- owned files: `{', '.join(request.owned_files) if request.owned_files else 'none'}`",
342
+ f"- expected output: {request.expected_output}",
343
+ ]
344
+ if request.review_context:
345
+ lines.append(f"- review context: {request.review_context}")
346
+ if request.repair_context:
347
+ lines.append(f"- repair context: {request.repair_context}")
348
+ if request.budget is not None:
349
+ budget = request.budget.to_json()
350
+ if budget:
351
+ rendered = ", ".join(f"{key}={value}" for key, value in budget.items())
352
+ lines.append(f"- budget: `{rendered}`")
353
+ if parent_child_metadata is not None:
354
+ lines.append(f"- parent phase: `{parent_child_metadata.parent_phase}`")
355
+ if parent_child_metadata.parent_executor:
356
+ lines.append(f"- parent executor: `{parent_child_metadata.parent_executor}`")
357
+ if parent_child_metadata.parent_run_id:
358
+ lines.append(f"- parent run id: `{parent_child_metadata.parent_run_id}`")
359
+ if parent_child_metadata.child_executor:
360
+ lines.append(f"- resolved child executor: `{parent_child_metadata.child_executor}`")
361
+ if parent_child_metadata.child_worktree_root:
362
+ lines.append(f"- child worktree root: `{parent_child_metadata.child_worktree_root}`")
363
+ if parent_child_metadata.child_closeout_result:
364
+ lines.append(f"- child closeout result: {parent_child_metadata.child_closeout_result}")
365
+ return "\n".join(lines)
@@ -0,0 +1,165 @@
1
+ from __future__ import annotations
2
+
3
+ import hashlib
4
+ import re
5
+ from dataclasses import dataclass
6
+ from pathlib import Path
7
+
8
+
9
+ ROADMAP_LEDGER_SCHEMA_VERSION = 2
10
+ # Phase headings accept integer phase numbers (Phase 1, Phase 2, ...) and
11
+ # decimal sub-phase numbers (Phase 2.1, Phase 3.5, ...). Decimal sub-phases
12
+ # are added post-hoc when an executor formalizes a recurring operator-fix
13
+ # pattern (e.g. v24's Phase 2.1 ADOPTBUNDLEREFRESH formalizing the
14
+ # adoption-bundle refresh that ran as operator-fix in v23 and v24).
15
+ # Without the (?:\.\d+)? group, decimal-phase aliases fail phase_sha256
16
+ # lookup → status_provenance_matches returns False → reducer rejects
17
+ # manual_repair/complete events → state stuck in stale state.
18
+ PHASE_HEADING_RE = re.compile(r"^###\s+Phase\s+\d+(?:\.\d+)?\s+.*?\(([A-Z][A-Z0-9._-]*)\)[ \t]*(?:\S[^\n]*)?$", re.MULTILINE)
19
+
20
+
21
+ @dataclass(frozen=True)
22
+ class PhaseProvenance:
23
+ alias: str
24
+ roadmap_sha256: str
25
+ phase_sha256: str
26
+
27
+
28
+ @dataclass(frozen=True)
29
+ class ValidationFinding:
30
+ line_number: int
31
+ raw_text: str
32
+ reason: str
33
+ suggested_fix: str
34
+
35
+
36
+ def roadmap_sha256(roadmap: Path) -> str:
37
+ return hashlib.sha256(roadmap.read_bytes()).hexdigest()
38
+
39
+
40
+ def phase_blocks(roadmap: Path) -> dict[str, str]:
41
+ text = roadmap.read_text()
42
+ matches = list(PHASE_HEADING_RE.finditer(text))
43
+ blocks: dict[str, str] = {}
44
+ for index, match in enumerate(matches):
45
+ alias = match.group(1).strip().upper()
46
+ end = matches[index + 1].start() if index + 1 < len(matches) else len(text)
47
+ blocks[alias] = text[match.start() : end]
48
+ return blocks
49
+
50
+
51
+ def validate_roadmap_phase_headings(roadmap: Path) -> list[ValidationFinding]:
52
+ text = roadmap.read_text()
53
+ findings: list[ValidationFinding] = []
54
+ seen_aliases: dict[str, int] = {}
55
+ alias_re = re.compile(r"\(([^\s()]+)\)[ \t]*(?:\S[^\n]*)?$")
56
+ valid_alias_re = re.compile(r"^[A-Z][A-Z0-9._-]*$")
57
+ fix = (
58
+ "Use `### Phase <number> <dash> Title (ALIAS)` where <dash> is either "
59
+ "ASCII hyphen-minus `-` or em-dash `—` (both accepted) and alias matches "
60
+ "[A-Z][A-Z0-9._-]*. The constraint is the alias-in-parens, not the dash style."
61
+ )
62
+
63
+ for line_number, line in enumerate(text.splitlines(), start=1):
64
+ if not re.match(r"^###\s+Phase\b", line):
65
+ continue
66
+ strict_match = PHASE_HEADING_RE.match(line)
67
+ alias_match = alias_re.search(line)
68
+ alias = alias_match.group(1) if alias_match else None
69
+ normalized_alias = alias.upper() if alias else None
70
+
71
+ if alias is not None and not valid_alias_re.fullmatch(alias):
72
+ findings.append(
73
+ ValidationFinding(
74
+ line_number=line_number,
75
+ raw_text=line,
76
+ reason=f"invalid-alias: alias {alias!r} does not match [A-Z][A-Z0-9._-]*",
77
+ suggested_fix=fix,
78
+ )
79
+ )
80
+ elif strict_match is None:
81
+ findings.append(
82
+ ValidationFinding(
83
+ line_number=line_number,
84
+ raw_text=line,
85
+ reason="loose-match: heading starts with `### Phase` but did not yield a phase_sha256 entry",
86
+ suggested_fix=fix,
87
+ )
88
+ )
89
+
90
+ if normalized_alias and valid_alias_re.fullmatch(normalized_alias):
91
+ first_line = seen_aliases.get(normalized_alias)
92
+ if first_line is None:
93
+ seen_aliases[normalized_alias] = line_number
94
+ else:
95
+ findings.append(
96
+ ValidationFinding(
97
+ line_number=line_number,
98
+ raw_text=line,
99
+ reason=f"duplicate-alias: alias {normalized_alias} first appeared on line {first_line}",
100
+ suggested_fix="Give each roadmap phase a unique alias in the final parenthesized token.",
101
+ )
102
+ )
103
+
104
+ return findings
105
+
106
+
107
+ def phase_sha256(roadmap: Path, phase: str) -> str | None:
108
+ block = phase_blocks(roadmap).get(phase.upper())
109
+ if block is None:
110
+ return None
111
+ return hashlib.sha256(block.encode()).hexdigest()
112
+
113
+
114
+ def phase_provenance_map(roadmap: Path) -> dict[str, str]:
115
+ return {alias: hashlib.sha256(block.encode()).hexdigest() for alias, block in phase_blocks(roadmap).items()}
116
+
117
+
118
+ def event_provenance(roadmap: Path, phase: str) -> dict[str, object]:
119
+ return {
120
+ "schema_version": ROADMAP_LEDGER_SCHEMA_VERSION,
121
+ "roadmap_sha256": roadmap_sha256(roadmap),
122
+ "phase_sha256": phase_sha256(roadmap, phase),
123
+ }
124
+
125
+
126
+ def snapshot_provenance(roadmap: Path) -> dict[str, object]:
127
+ return {
128
+ "schema_version": ROADMAP_LEDGER_SCHEMA_VERSION,
129
+ "roadmap_sha256": roadmap_sha256(roadmap),
130
+ "phase_sha256": phase_provenance_map(roadmap),
131
+ }
132
+
133
+
134
+ def status_provenance_matches(
135
+ status: str,
136
+ entry_roadmap_sha: str | None,
137
+ entry_phase_sha: str | None,
138
+ current_roadmap_sha: str | None,
139
+ current_phase_sha: str | None,
140
+ ) -> bool:
141
+ if not entry_phase_sha or not current_phase_sha:
142
+ return False
143
+ if status in {"complete", "executed", "awaiting_phase_closeout", "blocked", "unknown"}:
144
+ return entry_phase_sha == current_phase_sha
145
+ if status in {"planned", "executing"}:
146
+ return entry_phase_sha == current_phase_sha and entry_roadmap_sha == current_roadmap_sha
147
+ return False
148
+
149
+
150
+ def provenance_mismatch_reason(
151
+ status: str,
152
+ entry_roadmap_sha: str | None,
153
+ entry_phase_sha: str | None,
154
+ current_roadmap_sha: str | None,
155
+ current_phase_sha: str | None,
156
+ ) -> str:
157
+ if not entry_roadmap_sha or not entry_phase_sha:
158
+ return "legacy"
159
+ if not current_phase_sha:
160
+ return "phase_missing"
161
+ if entry_phase_sha != current_phase_sha:
162
+ return "phase_mismatch"
163
+ if status in {"planned", "executing"} and entry_roadmap_sha != current_roadmap_sha:
164
+ return "roadmap_mismatch"
165
+ return "unknown"