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,433 @@
1
+ """v45 SCHED — per-phase git worktree lifecycle (IF-0-SCHED-1 support).
2
+
3
+ Concurrent cross-phase dispatch is only safe when each phase's child executor
4
+ runs in its *own* git worktree: the children run ``git add``/``commit``/``status``
5
+ and would otherwise race on ``index.lock``/HEAD in a shared tree even when their
6
+ owned files are disjoint. ``validate_concurrent_phase_ownership`` guarantees the
7
+ file-disjointness; this module provides the isolation that makes concurrent git
8
+ operations safe and the merge-back conflict-free.
9
+
10
+ Lifecycle per phase in a ready wave:
11
+
12
+ 1. ``create_phase_worktree`` — ``git worktree add -b <temp-branch> <path> <base>``.
13
+ Each phase gets its OWN temporary branch off the pipeline-branch tip, because
14
+ git refuses to check out one branch in two worktrees simultaneously.
15
+ 2. The caller launches the child with ``repo=<worktree_path>`` so the executor's
16
+ ``wrapped_cwd`` points the child into the isolated tree.
17
+ 3. ``integrate_phase_worktree`` — fast-forward/merge the phase's temp branch back
18
+ onto the pipeline branch in the *main* worktree. Because waved siblings own
19
+ disjoint files (enforced upstream), sequential merges never conflict.
20
+ 4. ``teardown_phase_worktree`` — remove the worktree and delete the temp branch.
21
+
22
+ Only repo-tracked content crosses the worktree boundary via the temp branch.
23
+ Runner-owned ledger/state (``events.jsonl``/``state.json`` under ``.phase-loop``)
24
+ is written by the parent against the main repo and is not committed, so it never
25
+ participates in merge-back.
26
+ """
27
+ from __future__ import annotations
28
+
29
+ import subprocess
30
+ from dataclasses import dataclass, field
31
+ from pathlib import Path
32
+
33
+ from .runtime_paths import lane_worktree_path
34
+
35
+
36
+ @dataclass(frozen=True)
37
+ class PhaseWorktreeHandle:
38
+ """Identifies one phase's isolated worktree and its temporary branch."""
39
+
40
+ phase: str
41
+ worktree_path: Path
42
+ temp_branch: str
43
+ target_branch: str
44
+ base_sha: str
45
+
46
+
47
+ @dataclass(frozen=True)
48
+ class WorktreeIntegrationResult:
49
+ """Outcome of merging a phase's temp branch back onto the pipeline branch."""
50
+
51
+ phase: str
52
+ temp_branch: str
53
+ integrated: bool
54
+ conflict: bool = False
55
+ merged_sha: str | None = None
56
+ had_commits: bool = True
57
+ reason: str | None = None
58
+ conflicted_paths: tuple[str, ...] = field(default_factory=tuple)
59
+
60
+ def to_json(self) -> dict[str, object]:
61
+ return {
62
+ "phase": self.phase,
63
+ "temp_branch": self.temp_branch,
64
+ "integrated": self.integrated,
65
+ "conflict": self.conflict,
66
+ "merged_sha": self.merged_sha,
67
+ "had_commits": self.had_commits,
68
+ "reason": self.reason,
69
+ "conflicted_paths": list(self.conflicted_paths),
70
+ }
71
+
72
+
73
+ @dataclass(frozen=True)
74
+ class WorktreeTransferResult:
75
+ """Outcome of transporting a phase child's worktree changes onto main.
76
+
77
+ ``had_changes`` is True when the child produced any delta since base (dirty
78
+ and/or committed). ``applied`` is True when main's working tree now carries
79
+ that delta (or there was nothing to transfer). A failed apply leaves
80
+ ``applied=False`` with ``conflict=True``; ``git apply`` is atomic, so main is
81
+ left untouched and the work is preserved on ``temp_branch`` for diagnosis.
82
+ """
83
+
84
+ phase: str
85
+ temp_branch: str
86
+ had_changes: bool
87
+ applied: bool
88
+ conflict: bool = False
89
+ reason: str | None = None
90
+
91
+ def to_json(self) -> dict[str, object]:
92
+ return {
93
+ "phase": self.phase,
94
+ "temp_branch": self.temp_branch,
95
+ "had_changes": self.had_changes,
96
+ "applied": self.applied,
97
+ "conflict": self.conflict,
98
+ "reason": self.reason,
99
+ }
100
+
101
+
102
+ class PhaseWorktreeError(RuntimeError):
103
+ """Raised when a worktree lifecycle git operation fails unexpectedly."""
104
+
105
+
106
+ def _git(
107
+ repo: Path,
108
+ *args: str,
109
+ check: bool = True,
110
+ ) -> subprocess.CompletedProcess[str]:
111
+ return subprocess.run(
112
+ ["git", "-C", str(repo), *args],
113
+ check=check,
114
+ capture_output=True,
115
+ text=True,
116
+ )
117
+
118
+
119
+ def _git_bytes(
120
+ repo: Path,
121
+ *args: str,
122
+ input_bytes: bytes | None = None,
123
+ ) -> subprocess.CompletedProcess[bytes]:
124
+ """Run git capturing stdout/stderr as raw BYTES (never text-decoded).
125
+
126
+ A git patch is a byte stream that must survive verbatim: routing it through
127
+ ``text=True`` strips ``\\r`` (corrupting CRLF files into spurious apply
128
+ conflicts or silent LF rewrites) and raises ``UnicodeDecodeError`` on any
129
+ non-UTF-8 "text" blob git inlines raw (high bytes without a NUL, so git does
130
+ not base85-encode it). The diff capture and ``git apply`` stdin in
131
+ :func:`transfer_phase_worktree_dirty` therefore use bytes I/O.
132
+ """
133
+
134
+ return subprocess.run(
135
+ ["git", "-C", str(repo), *args],
136
+ check=False,
137
+ capture_output=True,
138
+ input=input_bytes,
139
+ )
140
+
141
+
142
+ def resolve_base_sha(repo: Path, ref: str = "HEAD") -> str:
143
+ """Resolve ``ref`` (default the current tip) to a concrete commit SHA."""
144
+
145
+ result = _git(repo, "rev-parse", ref)
146
+ return result.stdout.strip()
147
+
148
+
149
+ def current_branch(repo: Path) -> str:
150
+ """Name of the branch currently checked out in ``repo``'s main worktree.
151
+
152
+ This is the pipeline branch concurrent phases branch from and integrate back
153
+ onto. Detached HEAD returns ``"HEAD"``.
154
+ """
155
+
156
+ return _git(repo, "rev-parse", "--abbrev-ref", "HEAD").stdout.strip()
157
+
158
+
159
+ def phase_temp_branch(target_branch: str, phase: str) -> str:
160
+ """Deterministic temp-branch name for a phase's isolated worktree.
161
+
162
+ Slashes in the pipeline branch are preserved (git refs allow them); the
163
+ ``phase-loop/sched/`` prefix namespaces these throwaway branches so cleanup
164
+ sweeps can recognize them.
165
+ """
166
+
167
+ return f"phase-loop/sched/{target_branch}/{phase.upper()}"
168
+
169
+
170
+ def _branch_exists(repo: Path, branch: str) -> bool:
171
+ return _git(repo, "rev-parse", "--verify", "--quiet", f"refs/heads/{branch}", check=False).returncode == 0
172
+
173
+
174
+ def _remove_worktree(repo: Path, path: Path) -> None:
175
+ _git(repo, "worktree", "remove", "--force", str(path), check=False)
176
+
177
+
178
+ def create_phase_worktree(
179
+ repo: Path,
180
+ *,
181
+ phase: str,
182
+ target_branch: str,
183
+ base_sha: str,
184
+ workspace_mount: Path | None = None,
185
+ ) -> PhaseWorktreeHandle:
186
+ """Create an isolated worktree for ``phase`` on its own temp branch.
187
+
188
+ Idempotent: a stale worktree at the computed path or a stale temp branch
189
+ (from a crashed prior run) is pruned/deleted before recreation. The new
190
+ worktree is checked out at ``base_sha`` so every concurrent sibling starts
191
+ from the same pipeline-branch tip.
192
+ """
193
+
194
+ phase = phase.upper()
195
+ worktree_path = lane_worktree_path(
196
+ repo,
197
+ branch=target_branch,
198
+ lane_id=phase,
199
+ workspace_mount=workspace_mount,
200
+ )
201
+ temp_branch = phase_temp_branch(target_branch, phase)
202
+
203
+ # Clear stale state from an interrupted prior run before recreating.
204
+ if worktree_path.exists():
205
+ _remove_worktree(repo, worktree_path)
206
+ _git(repo, "worktree", "prune", check=False)
207
+ if _branch_exists(repo, temp_branch):
208
+ _git(repo, "branch", "-D", temp_branch, check=False)
209
+
210
+ worktree_path.parent.mkdir(parents=True, exist_ok=True)
211
+ created = _git(
212
+ repo,
213
+ "worktree",
214
+ "add",
215
+ "-b",
216
+ temp_branch,
217
+ str(worktree_path),
218
+ base_sha,
219
+ check=False,
220
+ )
221
+ if created.returncode != 0:
222
+ raise PhaseWorktreeError(
223
+ f"failed to create worktree for phase {phase} at {worktree_path}: "
224
+ f"{created.stderr.strip() or created.stdout.strip()}"
225
+ )
226
+ return PhaseWorktreeHandle(
227
+ phase=phase,
228
+ worktree_path=worktree_path,
229
+ temp_branch=temp_branch,
230
+ target_branch=target_branch,
231
+ base_sha=base_sha,
232
+ )
233
+
234
+
235
+ def integrate_phase_worktree(
236
+ repo: Path,
237
+ handle: PhaseWorktreeHandle,
238
+ *,
239
+ message: str | None = None,
240
+ ) -> WorktreeIntegrationResult:
241
+ """Merge a phase's temp branch back onto the pipeline branch.
242
+
243
+ Precondition: the main worktree (``repo``) is checked out on
244
+ ``handle.target_branch`` with a clean index for the merged files (the caller
245
+ integrates sequentially after all children finish). Disjoint owned files make
246
+ the merge conflict-free by construction; a conflict is surfaced (and aborted)
247
+ rather than resolved silently, because it signals the ownership gate was
248
+ bypassed.
249
+ """
250
+
251
+ commits = _git(repo, "rev-list", f"{handle.base_sha}..{handle.temp_branch}", check=False)
252
+ if commits.returncode != 0:
253
+ return WorktreeIntegrationResult(
254
+ phase=handle.phase,
255
+ temp_branch=handle.temp_branch,
256
+ integrated=False,
257
+ had_commits=False,
258
+ reason=f"could not inspect commits: {commits.stderr.strip()}",
259
+ )
260
+ if not commits.stdout.strip():
261
+ # Child produced no commits (e.g. plan-only, blocked, or dry run).
262
+ return WorktreeIntegrationResult(
263
+ phase=handle.phase,
264
+ temp_branch=handle.temp_branch,
265
+ integrated=True,
266
+ had_commits=False,
267
+ merged_sha=resolve_base_sha(repo),
268
+ reason="no commits to integrate",
269
+ )
270
+
271
+ merge_message = message or f"phase-loop sched: integrate {handle.phase}"
272
+ merged = _git(
273
+ repo,
274
+ "merge",
275
+ "--no-ff",
276
+ "-m",
277
+ merge_message,
278
+ handle.temp_branch,
279
+ check=False,
280
+ )
281
+ if merged.returncode != 0:
282
+ conflicted = _git(repo, "diff", "--name-only", "--diff-filter=U", check=False)
283
+ conflicted_paths = tuple(
284
+ line.strip() for line in conflicted.stdout.splitlines() if line.strip()
285
+ )
286
+ _git(repo, "merge", "--abort", check=False)
287
+ return WorktreeIntegrationResult(
288
+ phase=handle.phase,
289
+ temp_branch=handle.temp_branch,
290
+ integrated=False,
291
+ conflict=True,
292
+ conflicted_paths=conflicted_paths,
293
+ reason=(
294
+ "merge conflict integrating phase worktree — the concurrent "
295
+ "ownership-disjointness gate should have prevented this"
296
+ ),
297
+ )
298
+ return WorktreeIntegrationResult(
299
+ phase=handle.phase,
300
+ temp_branch=handle.temp_branch,
301
+ integrated=True,
302
+ merged_sha=resolve_base_sha(repo),
303
+ )
304
+
305
+
306
+ def transfer_phase_worktree_dirty(
307
+ repo: Path,
308
+ handle: PhaseWorktreeHandle,
309
+ *,
310
+ commit_message: str | None = None,
311
+ ) -> WorktreeTransferResult:
312
+ """Transport a phase child's worktree work onto main as UNSTAGED changes.
313
+
314
+ Unlike :func:`integrate_phase_worktree` (which merges only *committed* work),
315
+ a real phase executor leaves its verified work DIRTY in the worktree and
316
+ emits ``awaiting_phase_closeout`` — the parent runner's closeout is what
317
+ stages+commits the dirty phase-owned files. So the committed-only merge is a
318
+ no-op against a real child and the work is lost. This brings the child's full
319
+ delta (uncommitted + any self-commits) onto the *main* working tree without
320
+ committing it, so the parent's existing closeout — whose selective
321
+ ``git add -- <owned>`` is what enforces the ownership gate — commits it on the
322
+ pipeline branch exactly as in serial mode.
323
+
324
+ The work is first committed onto ``temp_branch`` (preserving it on a ref), then
325
+ transported via ``git diff base..temp | git apply`` rather than a
326
+ cherry-pick: cherry-pick would pre-stage every changed path into main's index
327
+ and defeat the closeout's selective, ownership-gated staging. ``git apply`` is
328
+ atomic, so a failed apply (which the disjointness gate should make impossible)
329
+ leaves main untouched and the work recoverable on ``temp_branch``.
330
+ """
331
+
332
+ worktree = handle.worktree_path
333
+ # Stage everything dirty (captures untracked new files too) and commit it onto
334
+ # the temp branch so the work survives on a ref even if the apply to main fails.
335
+ _git(worktree, "add", "-A", check=False)
336
+ has_staged = _git(worktree, "diff", "--cached", "--quiet", check=False).returncode != 0
337
+ if has_staged:
338
+ message = commit_message or f"phase-loop sched transport: {handle.phase}"
339
+ committed = _git(worktree, "commit", "-q", "-m", message, check=False)
340
+ if committed.returncode != 0:
341
+ return WorktreeTransferResult(
342
+ phase=handle.phase,
343
+ temp_branch=handle.temp_branch,
344
+ had_changes=True,
345
+ applied=False,
346
+ reason=(
347
+ "failed to commit worktree changes for transport: "
348
+ f"{committed.stderr.strip() or committed.stdout.strip()}"
349
+ ),
350
+ )
351
+
352
+ revs = _git(worktree, "rev-list", f"{handle.base_sha}..{handle.temp_branch}", check=False)
353
+ if revs.returncode != 0:
354
+ # The transport commit above already succeeded (when there was dirt), so
355
+ # the work is on temp_branch — mark had_changes=True so the caller PRESERVES
356
+ # the branch (its preserve guard keys on had_changes) instead of deleting it.
357
+ return WorktreeTransferResult(
358
+ phase=handle.phase,
359
+ temp_branch=handle.temp_branch,
360
+ had_changes=has_staged,
361
+ applied=False,
362
+ conflict=has_staged,
363
+ reason=f"could not inspect commits: {revs.stderr.strip()}",
364
+ )
365
+ if not revs.stdout.strip():
366
+ # Child produced no work (blocked, plan-only, dry run, or a clean
367
+ # self-reported terminal). Nothing to transport; main is untouched.
368
+ return WorktreeTransferResult(
369
+ phase=handle.phase,
370
+ temp_branch=handle.temp_branch,
371
+ had_changes=False,
372
+ applied=True,
373
+ reason="no changes to transfer",
374
+ )
375
+
376
+ # Bytes I/O: the patch must survive verbatim (CRLF, binary, non-UTF-8 blobs).
377
+ diff = _git_bytes(worktree, "diff", "--binary", handle.base_sha, handle.temp_branch)
378
+ if diff.returncode != 0:
379
+ return WorktreeTransferResult(
380
+ phase=handle.phase,
381
+ temp_branch=handle.temp_branch,
382
+ had_changes=True,
383
+ applied=False,
384
+ conflict=True,
385
+ reason=f"could not compute transfer diff: {diff.stderr.decode('utf-8', 'replace').strip()}",
386
+ )
387
+ if not diff.stdout.strip():
388
+ return WorktreeTransferResult(
389
+ phase=handle.phase,
390
+ temp_branch=handle.temp_branch,
391
+ had_changes=False,
392
+ applied=True,
393
+ reason="empty net diff",
394
+ )
395
+
396
+ applied = _git_bytes(repo, "apply", "--whitespace=nowarn", "-", input_bytes=diff.stdout)
397
+ if applied.returncode != 0:
398
+ return WorktreeTransferResult(
399
+ phase=handle.phase,
400
+ temp_branch=handle.temp_branch,
401
+ had_changes=True,
402
+ applied=False,
403
+ conflict=True,
404
+ reason=(
405
+ "git apply failed transporting worktree changes onto main — the "
406
+ "concurrent ownership-disjointness gate should have prevented this: "
407
+ f"{applied.stderr.decode('utf-8', 'replace').strip() or applied.stdout.decode('utf-8', 'replace').strip()}"
408
+ ),
409
+ )
410
+ return WorktreeTransferResult(
411
+ phase=handle.phase,
412
+ temp_branch=handle.temp_branch,
413
+ had_changes=True,
414
+ applied=True,
415
+ )
416
+
417
+
418
+ def teardown_phase_worktree(
419
+ repo: Path,
420
+ handle: PhaseWorktreeHandle,
421
+ *,
422
+ delete_branch: bool = True,
423
+ ) -> None:
424
+ """Remove the phase's worktree and (by default) delete its temp branch.
425
+
426
+ Best-effort: missing worktree/branch is not an error so this is safe to call
427
+ in a ``finally`` even if creation partially failed.
428
+ """
429
+
430
+ _remove_worktree(repo, handle.worktree_path)
431
+ _git(repo, "worktree", "prune", check=False)
432
+ if delete_branch and _branch_exists(repo, handle.temp_branch):
433
+ _git(repo, "branch", "-D", handle.temp_branch, check=False)
@@ -0,0 +1,12 @@
1
+ from __future__ import annotations
2
+
3
+ """Pipeline adapter helpers.
4
+
5
+ The hard-coded v32 governed-pipeline ratification trigger contract is
6
+ `.pipeline/ratification-trigger.json`.
7
+ """
8
+
9
+ from .flag import branchgov_enabled
10
+ from .markers import detect_pipeline_mode
11
+
12
+ __all__ = ("branchgov_enabled", "detect_pipeline_mode")