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,835 @@
1
+ from __future__ import annotations
2
+
3
+ from pathlib import Path
4
+
5
+ from .models import (
6
+ ClaudeTeamPolicy,
7
+ DispatchDecision,
8
+ DispatchHints,
9
+ ExecutorCapabilityRecord,
10
+ NORMALIZED_EFFORT_LEVELS,
11
+ PRODUCT_LOOP_ACTIONS,
12
+ ProviderPolicyCapability,
13
+ UNSUPPORTED_POLICY_BEHAVIORS,
14
+ WORK_UNIT_KINDS,
15
+ )
16
+ from .state_degradation import active_degraded_executors
17
+
18
+
19
+ DEFAULT_EXECUTOR = "codex"
20
+ DEFAULT_LANE_EXECUTOR = "pi"
21
+ CLAUDE_HEAVY_MODEL = "claude-opus-4-8"
22
+ _CLAUDE_BASE_ALLOWED_TOOLS = ("Bash", "Read", "Edit", "MultiEdit", "Write", "Glob", "Grep", "LS")
23
+ _CLAUDE_COLLABORATION_TOOLS = (
24
+ "Agent",
25
+ "TaskCreate",
26
+ "TaskUpdate",
27
+ "TaskList",
28
+ "TeamCreate",
29
+ "TeamDelete",
30
+ "SendMessage",
31
+ "EnterWorktree",
32
+ "ExitWorktree",
33
+ "ToolSearch",
34
+ )
35
+ _CLAUDE_BASE_DISALLOWED_TOOLS = (
36
+ "Agent",
37
+ "TaskCreate",
38
+ "TaskUpdate",
39
+ "TaskList",
40
+ "TeamCreate",
41
+ "TeamDelete",
42
+ "SendMessage",
43
+ "EnterWorktree",
44
+ "ExitWorktree",
45
+ "AskUserQuestion",
46
+ "ExitPlanMode",
47
+ "ToolSearch",
48
+ "advisor",
49
+ )
50
+ _CLAUDE_SUBAGENT_ALLOWED_TOOLS = _CLAUDE_BASE_ALLOWED_TOOLS + (
51
+ "Agent",
52
+ "TaskCreate",
53
+ "TaskUpdate",
54
+ "TaskList",
55
+ "SendMessage",
56
+ "ToolSearch",
57
+ )
58
+ _CLAUDE_TEAM_ALLOWED_TOOLS = _CLAUDE_BASE_ALLOWED_TOOLS + _CLAUDE_COLLABORATION_TOOLS
59
+ _CLAUDE_TEAM_DISALLOWED_TOOLS = (
60
+ "AskUserQuestion",
61
+ "ExitPlanMode",
62
+ "advisor",
63
+ )
64
+
65
+ _ACTION_DEFAULT_PROFILES = {
66
+ "roadmap": "roadmap",
67
+ "plan": "plan",
68
+ "execute": "execute",
69
+ "repair": "repair",
70
+ "review": "review",
71
+ "maintain-skills": "skill-maintenance",
72
+ }
73
+
74
+ DEFAULT_CAPABILITY_REGISTRY = {
75
+ "codex": ExecutorCapabilityRecord(
76
+ executor="codex",
77
+ supported_actions=PRODUCT_LOOP_ACTIONS,
78
+ capabilities=(
79
+ "live_launch",
80
+ "dry_run",
81
+ "skill_bundle_injection",
82
+ "subagents",
83
+ "explicit_approval_controls",
84
+ "structured_output",
85
+ ),
86
+ strengths=("repo-native execution", "stable automation contract", "shared phase-loop ownership"),
87
+ limits=("requires local Codex subscription auth",),
88
+ injection_mode="prompt_only",
89
+ permission_posture="explicit",
90
+ subagent_posture="native",
91
+ live_available=True,
92
+ dry_run_available=True,
93
+ live_proof_gate="none",
94
+ promotion_status="live",
95
+ promotion_requirements=("shared launch contract", "shared terminal summary contract"),
96
+ auth_preflight_mode="metadata_only",
97
+ auth_preflight_probes=("codex --version", "codex --help", "codex login status"),
98
+ timeout_posture="runner_managed",
99
+ output_capture_format="json_stream",
100
+ default_model_profiles=dict(_ACTION_DEFAULT_PROFILES),
101
+ ),
102
+ "claude": ExecutorCapabilityRecord(
103
+ executor="claude",
104
+ supported_actions=("roadmap", "plan", "execute", "repair", "review"),
105
+ capabilities=(
106
+ "live_launch",
107
+ "dry_run",
108
+ "skill_bundle_injection",
109
+ "inline_instructions",
110
+ "context_file_instructions",
111
+ "subagents",
112
+ "explicit_approval_controls",
113
+ "structured_output",
114
+ ),
115
+ strengths=("native prompt injection", "documented effort controls", "authenticated local CLI"),
116
+ limits=(
117
+ "requires local Claude subscription auth",
118
+ "current autonomous live proof is blocked on non-interactive closeout parity",
119
+ ),
120
+ injection_mode="inline",
121
+ permission_posture="explicit",
122
+ subagent_posture="native",
123
+ live_available=True,
124
+ dry_run_available=True,
125
+ live_proof_gate="disposable_proof_required",
126
+ promotion_status="proof_gated",
127
+ promotion_requirements=(
128
+ "fake harness parity regression proof",
129
+ "disposable live roadmap proof",
130
+ "launch.json",
131
+ "terminal-summary.json",
132
+ ),
133
+ auth_preflight_mode="metadata_only",
134
+ auth_preflight_probes=("claude --version", "claude --help", "claude auth status"),
135
+ timeout_posture="runner_managed",
136
+ output_capture_format="terminal_summary",
137
+ known_failure_cases=(
138
+ "non_interactive_timeout",
139
+ "empty_or_unusable_output_capture",
140
+ "missing_automation_block",
141
+ "missing_terminal_summary",
142
+ "stale_handoff_after_repair",
143
+ ),
144
+ default_model_profiles={action: _ACTION_DEFAULT_PROFILES[action] for action in ("roadmap", "plan", "execute", "repair", "review")},
145
+ default_claude_execution_mode="solo",
146
+ claude_execution_policies=(
147
+ ClaudeTeamPolicy(
148
+ execution_mode="solo",
149
+ maturity_label="proof_blocked",
150
+ live_proof_gate="disposable_proof_required",
151
+ promotion_status="proof_gated",
152
+ launch_default=True,
153
+ default_model=CLAUDE_HEAVY_MODEL,
154
+ default_effort="high",
155
+ budget_guidance={"mode": "metadata_only", "notes": "Native solo launch keeps team fanout at zero."},
156
+ allowed_actions=("roadmap", "plan", "execute", "repair", "review"),
157
+ allowed_tools=_CLAUDE_BASE_ALLOWED_TOOLS,
158
+ disallowed_tools=_CLAUDE_BASE_DISALLOWED_TOOLS,
159
+ task_lifecycle_supported=False,
160
+ ),
161
+ ClaudeTeamPolicy(
162
+ execution_mode="subagent",
163
+ maturity_label="experimental",
164
+ live_proof_gate="disposable_proof_required",
165
+ promotion_status="proof_gated",
166
+ max_native_tasks=2,
167
+ max_delegation_depth=1,
168
+ max_fanout=2,
169
+ default_model=CLAUDE_HEAVY_MODEL,
170
+ default_effort="high",
171
+ budget_guidance={"mode": "metadata_only", "max_cost_usd": 3.0, "notes": "Bounded native subagent fanout only."},
172
+ allowed_actions=("execute", "repair", "review"),
173
+ disallowed_actions=("roadmap", "plan", "maintain-skills"),
174
+ allowed_tools=_CLAUDE_SUBAGENT_ALLOWED_TOOLS,
175
+ disallowed_tools=_CLAUDE_TEAM_DISALLOWED_TOOLS + ("TeamCreate", "TeamDelete", "EnterWorktree", "ExitWorktree"),
176
+ requires_disjoint_owned_files=True,
177
+ task_lifecycle_supported=True,
178
+ ),
179
+ ClaudeTeamPolicy(
180
+ execution_mode="agent_team",
181
+ maturity_label="experimental",
182
+ live_proof_gate="disposable_proof_required",
183
+ promotion_status="proof_gated",
184
+ max_teammates=3,
185
+ max_native_tasks=4,
186
+ max_delegation_depth=1,
187
+ max_fanout=2,
188
+ default_model=CLAUDE_HEAVY_MODEL,
189
+ default_effort="high",
190
+ budget_guidance={"mode": "metadata_only", "max_cost_usd": 5.0, "notes": "Task-list or teammate activity stays gated behind TEAMGOV and TASKLEDGER evidence."},
191
+ allowed_actions=("execute", "repair", "review"),
192
+ disallowed_actions=("roadmap", "plan", "maintain-skills"),
193
+ allowed_tools=_CLAUDE_TEAM_ALLOWED_TOOLS,
194
+ disallowed_tools=_CLAUDE_TEAM_DISALLOWED_TOOLS,
195
+ requires_disjoint_owned_files=True,
196
+ direct_teammate_messaging_allowed=True,
197
+ task_lifecycle_supported=True,
198
+ ),
199
+ ),
200
+ ),
201
+ "gemini": ExecutorCapabilityRecord(
202
+ executor="gemini",
203
+ supported_actions=("roadmap", "plan", "execute", "repair", "review"),
204
+ # v46 EXEC: agy (the gemini executor's CLI) has NO --output-format (the
205
+ # closeout is prompt-injected + text-parsed) and NO granular approval mode, so
206
+ # `structured_output` and `explicit_approval_controls` are dropped here.
207
+ capabilities=(
208
+ "live_launch",
209
+ "dry_run",
210
+ "skill_bundle_injection",
211
+ "inline_instructions",
212
+ "context_file_instructions",
213
+ ),
214
+ strengths=("native skill ecosystem", "context-file friendly", "authenticated local CLI"),
215
+ # v46 EXEC: the gemini executor now drives the Antigravity CLI (`agy`); the
216
+ # standalone gemini CLI was sunset. agy auth is a subscription OAuth token.
217
+ # NOTE: write actions auto-approve via --dangerously-skip-permissions
218
+ # (permissive-in-effect); `review` stays read-only. Flipping permission_posture
219
+ # to `permissive` (forcing explicit opt-in) is a follow-up product decision.
220
+ limits=(
221
+ "requires local Antigravity (agy) subscription auth",
222
+ "agy has no granular approval mode: write actions auto-approve, review is read-only",
223
+ "agy emits no structured JSON; closeout is prompt-injected and text-parsed",
224
+ ),
225
+ injection_mode="context_file",
226
+ permission_posture="explicit",
227
+ subagent_posture="limited",
228
+ live_available=True,
229
+ dry_run_available=True,
230
+ live_proof_gate="disposable_proof_recorded",
231
+ promotion_status="live",
232
+ promotion_requirements=(
233
+ "fake harness parity regression proof",
234
+ "disposable live roadmap proof",
235
+ "launch.json",
236
+ "terminal-summary.json",
237
+ ),
238
+ auth_preflight_mode="metadata_only",
239
+ auth_preflight_probes=("agy --version", "agy --help"),
240
+ timeout_posture="runner_managed",
241
+ output_capture_format="terminal_summary",
242
+ default_model_profiles={action: _ACTION_DEFAULT_PROFILES[action] for action in ("roadmap", "plan", "execute", "repair", "review")},
243
+ ),
244
+ "opencode": ExecutorCapabilityRecord(
245
+ executor="opencode",
246
+ supported_actions=("roadmap", "plan", "execute", "repair", "review"),
247
+ capabilities=(
248
+ "live_launch",
249
+ "dry_run",
250
+ "skill_bundle_injection",
251
+ "inline_instructions",
252
+ "context_file_instructions",
253
+ "explicit_approval_controls",
254
+ "structured_output",
255
+ ),
256
+ strengths=("agent-oriented CLI", "context-file delivery"),
257
+ limits=("requires local OpenCode subscription auth", "live launch requires explicit opt-in when the selected agent posture is permissive"),
258
+ injection_mode="context_file",
259
+ permission_posture="explicit",
260
+ subagent_posture="limited",
261
+ live_available=True,
262
+ dry_run_available=True,
263
+ live_proof_gate="disposable_proof_recorded",
264
+ promotion_status="live",
265
+ promotion_requirements=(
266
+ "fake harness parity regression proof",
267
+ "disposable live roadmap proof",
268
+ "launch.json",
269
+ "terminal-summary.json",
270
+ ),
271
+ auth_preflight_mode="metadata_only",
272
+ auth_preflight_probes=("opencode --version", "opencode run --help", "opencode agent list"),
273
+ timeout_posture="runner_managed",
274
+ output_capture_format="terminal_summary",
275
+ default_model_profiles={action: _ACTION_DEFAULT_PROFILES[action] for action in ("roadmap", "plan", "execute", "repair", "review")},
276
+ ),
277
+ "pi": ExecutorCapabilityRecord(
278
+ executor="pi",
279
+ supported_actions=("roadmap", "plan", "execute", "repair", "review"),
280
+ capabilities=(
281
+ "live_launch",
282
+ "dry_run",
283
+ "skill_bundle_injection",
284
+ "context_file_instructions",
285
+ "explicit_approval_controls",
286
+ "structured_output",
287
+ ),
288
+ strengths=(
289
+ "repo-local phase-loop-pi package",
290
+ "bounded simple-lane child runner",
291
+ "shared automation closeout contract",
292
+ ),
293
+ limits=(
294
+ "requires local Pi Agent CLI and provider auth outside phase-loop",
295
+ "not a global scheduler, runtime ledger owner, worktree allocator, or merge reducer",
296
+ ),
297
+ injection_mode="context_file",
298
+ permission_posture="explicit",
299
+ subagent_posture="none",
300
+ live_available=True,
301
+ dry_run_available=True,
302
+ live_proof_gate="disposable_proof_recorded",
303
+ promotion_status="live",
304
+ promotion_requirements=(
305
+ "fake harness parity regression proof",
306
+ "fake Pi adapter matrix",
307
+ "launch.json",
308
+ "terminal-summary.json",
309
+ ),
310
+ auth_preflight_mode="metadata_only",
311
+ auth_preflight_probes=("pi --version", "pi --help"),
312
+ timeout_posture="runner_managed",
313
+ output_capture_format="terminal_summary",
314
+ default_model_profiles={action: _ACTION_DEFAULT_PROFILES[action] for action in ("roadmap", "plan", "execute", "repair", "review")},
315
+ ),
316
+ "command": ExecutorCapabilityRecord(
317
+ executor="command",
318
+ supported_actions=("roadmap", "plan", "execute", "repair", "review"),
319
+ capabilities=("live_launch", "dry_run", "context_file_instructions", "structured_output"),
320
+ strengths=("explicit command wrapper", "runner-owned launch artifacts"),
321
+ limits=("requires explicit adapter template", "non-default executor", "unsupported command shapes fail closed"),
322
+ injection_mode="context_file",
323
+ permission_posture="manual",
324
+ subagent_posture="none",
325
+ live_available=True,
326
+ dry_run_available=True,
327
+ live_proof_gate="none",
328
+ promotion_status="manual_only",
329
+ promotion_requirements=(
330
+ "fake harness parity regression proof",
331
+ "typed adapter contract",
332
+ "explicit operator selection",
333
+ "launch.json",
334
+ "terminal-summary.json",
335
+ ),
336
+ timeout_posture="runner_managed",
337
+ output_capture_format="terminal_summary",
338
+ default_model_profiles={
339
+ "roadmap": _ACTION_DEFAULT_PROFILES["roadmap"],
340
+ "plan": _ACTION_DEFAULT_PROFILES["plan"],
341
+ "execute": _ACTION_DEFAULT_PROFILES["execute"],
342
+ "repair": _ACTION_DEFAULT_PROFILES["repair"],
343
+ "review": _ACTION_DEFAULT_PROFILES["review"],
344
+ },
345
+ ),
346
+ "manual": ExecutorCapabilityRecord(
347
+ executor="manual",
348
+ supported_actions=("repair", "review"),
349
+ capabilities=("dry_run", "manual_handoff"),
350
+ strengths=("operator handoff"),
351
+ limits=("metadata-only until manual import completes",),
352
+ injection_mode="manual",
353
+ permission_posture="manual",
354
+ subagent_posture="none",
355
+ live_available=False,
356
+ dry_run_available=True,
357
+ promotion_status="manual_only",
358
+ promotion_requirements=("manual import", "shared automation handoff"),
359
+ timeout_posture="unknown",
360
+ default_model_profiles={"repair": "repair", "review": "review"},
361
+ ),
362
+ }
363
+
364
+ DEFAULT_EXECUTOR_POLICY = {
365
+ "roadmap": "codex",
366
+ "plan": "codex",
367
+ "execute": "codex",
368
+ "repair": "codex",
369
+ "review": "codex",
370
+ "maintain-skills": "codex",
371
+ }
372
+
373
+ _ALL_WORK_UNITS = WORK_UNIT_KINDS
374
+ _ALL_EFFORTS = NORMALIZED_EFFORT_LEVELS
375
+ _FAIL_CLOSED = UNSUPPORTED_POLICY_BEHAVIORS[0]
376
+
377
+ DEFAULT_PROVIDER_POLICY_CAPABILITIES = {
378
+ "codex": ProviderPolicyCapability(
379
+ provider="openai",
380
+ executor="codex",
381
+ supported_work_units=_ALL_WORK_UNITS,
382
+ supported_efforts=_ALL_EFFORTS,
383
+ unsupported_policy_behavior=_FAIL_CLOSED,
384
+ default_effort="medium",
385
+ effort_map={effort: effort for effort in _ALL_EFFORTS},
386
+ notes=("Codex/OpenAI accepts normalized reasoning effort metadata directly.",),
387
+ ),
388
+ "claude": ProviderPolicyCapability(
389
+ provider="claude-code",
390
+ executor="claude",
391
+ supported_work_units=_ALL_WORK_UNITS,
392
+ supported_efforts=("low", "medium", "high", "max"),
393
+ unsupported_policy_behavior=_FAIL_CLOSED,
394
+ default_effort="high",
395
+ effort_map={
396
+ "minimal": "low",
397
+ "low": "low",
398
+ "medium": "medium",
399
+ "high": "high",
400
+ "xhigh": "max",
401
+ "max": "max",
402
+ },
403
+ notes=("Claude Code has documented effort controls but no separate xhigh literal.",),
404
+ ),
405
+ "gemini": ProviderPolicyCapability(
406
+ provider="gemini-cli",
407
+ executor="gemini",
408
+ supported_work_units=_ALL_WORK_UNITS,
409
+ supported_efforts=("medium", "high"),
410
+ unsupported_policy_behavior=_FAIL_CLOSED,
411
+ default_effort="medium",
412
+ effort_map={
413
+ "minimal": "medium",
414
+ "low": "medium",
415
+ "medium": "medium",
416
+ "high": "high",
417
+ "xhigh": "high",
418
+ "max": "high",
419
+ },
420
+ model_aliases={
421
+ "roadmap_build": "phase-loop-plan-high",
422
+ "phase_plan": "phase-loop-plan-high",
423
+ "lane_execute": "phase-loop-execute-medium",
424
+ "lane_review": "phase-loop-review-high",
425
+ "phase_reducer": "phase-loop-review-high",
426
+ "phase_verify": "phase-loop-review-high",
427
+ "repair": "phase-loop-execute-medium",
428
+ "closeout": "phase-loop-review-high",
429
+ },
430
+ requires_run_local_user_scope=True,
431
+ notes=(
432
+ "Gemini CLI fallback stays CLI-based and reason-coded; API-key execution requires an explicit command adapter.",
433
+ "Gemini CLI defaults use built-in routing aliases (`pro` for planning/review and `auto` for execution/repair) to preserve CLI fallback behavior.",
434
+ "Model-routing-v3 uses explicit `Gemini 3.5 Flash (High)` for implementer/worker model_class routing, but Gemini remains capped at high effort and is not max-effort planner-of-record eligible.",
435
+ "Run-local user-scope modelConfigs.customAliases remain available only for explicit phase-loop thinking-level proof runs.",
436
+ "thinkingConfig.thinkingLevel is carried by custom aliases and is not exposed as a CLI flag.",
437
+ ),
438
+ ),
439
+ "gemini-api": ProviderPolicyCapability(
440
+ provider="gemini-api-openai-compatible",
441
+ executor="command",
442
+ supported_work_units=_ALL_WORK_UNITS,
443
+ supported_efforts=("medium", "high"),
444
+ unsupported_policy_behavior=_FAIL_CLOSED,
445
+ default_effort="medium",
446
+ effort_map={
447
+ "minimal": "medium",
448
+ "low": "medium",
449
+ "medium": "medium",
450
+ "high": "high",
451
+ "xhigh": "high",
452
+ "max": "high",
453
+ },
454
+ notes=("Gemini API/OpenAI-compatible policy is command-adapter metadata only in v8.",),
455
+ ),
456
+ "opencode": ProviderPolicyCapability(
457
+ provider="opencode",
458
+ executor="opencode",
459
+ supported_work_units=_ALL_WORK_UNITS,
460
+ supported_efforts=_ALL_EFFORTS,
461
+ unsupported_policy_behavior=_FAIL_CLOSED,
462
+ default_effort="medium",
463
+ effort_map={effort: effort for effort in _ALL_EFFORTS},
464
+ notes=("OpenCode policy is normalized for future adapter selection without changing dispatch.",),
465
+ ),
466
+ "pi": ProviderPolicyCapability(
467
+ provider="pi-agent",
468
+ executor="pi",
469
+ supported_work_units=_ALL_WORK_UNITS,
470
+ supported_efforts=("low", "medium", "high"),
471
+ unsupported_policy_behavior=_FAIL_CLOSED,
472
+ default_effort="medium",
473
+ effort_map={
474
+ "minimal": "low",
475
+ "low": "low",
476
+ "medium": "medium",
477
+ "high": "high",
478
+ "xhigh": "high",
479
+ "max": "high",
480
+ },
481
+ notes=(
482
+ "Pi Agent is the default executor for simple bounded scheduler-assigned lane execution.",
483
+ "Pi Agent runner path is repo-local and bounded to one scheduler-assigned lane.",
484
+ "Claude/Anthropic model work defaults to Claude Code CLI unless policy explicitly selects a Pi-wrapped Claude route with an override reason.",
485
+ "Unsupported effort or tool-policy requests fail closed unless the phase policy explicitly falls back.",
486
+ ),
487
+ ),
488
+ "command": ProviderPolicyCapability(
489
+ provider="generic-command-adapter",
490
+ executor="command",
491
+ supported_work_units=_ALL_WORK_UNITS,
492
+ supported_efforts=_ALL_EFFORTS,
493
+ unsupported_policy_behavior=_FAIL_CLOSED,
494
+ default_effort="medium",
495
+ effort_map={effort: effort for effort in _ALL_EFFORTS},
496
+ notes=("Generic command adapters must fail closed when unsupported policy cannot be mapped.",),
497
+ ),
498
+ "manual": ProviderPolicyCapability(
499
+ provider="manual-handoff",
500
+ executor="manual",
501
+ supported_work_units=_ALL_WORK_UNITS,
502
+ supported_efforts=_ALL_EFFORTS,
503
+ unsupported_policy_behavior=_FAIL_CLOSED,
504
+ default_effort="medium",
505
+ effort_map={effort: effort for effort in _ALL_EFFORTS},
506
+ notes=("Manual handoff is non-default and must be selected explicitly.",),
507
+ ),
508
+ }
509
+
510
+
511
+ def capability_registry() -> dict[str, ExecutorCapabilityRecord]:
512
+ return DEFAULT_CAPABILITY_REGISTRY
513
+
514
+
515
+ def provider_policy_capabilities() -> dict[str, ProviderPolicyCapability]:
516
+ return DEFAULT_PROVIDER_POLICY_CAPABILITIES
517
+
518
+
519
+ def claude_support_slice_posture() -> dict[str, dict[str, object]]:
520
+ record = DEFAULT_CAPABILITY_REGISTRY["claude"]
521
+ policy_by_mode = {
522
+ policy.execution_mode: policy for policy in record.claude_execution_policies
523
+ }
524
+ solo = policy_by_mode["solo"]
525
+ subagent = policy_by_mode["subagent"]
526
+ agent_team = policy_by_mode["agent_team"]
527
+ return {
528
+ "claude_solo": {
529
+ "execution_mode": "solo",
530
+ "maturity_label": solo.maturity_label,
531
+ "live_proof_gate": solo.live_proof_gate,
532
+ "promotion_status": solo.promotion_status,
533
+ "launch_default": solo.launch_default,
534
+ "requires_disjoint_owned_files": solo.requires_disjoint_owned_files,
535
+ "allows_read_only_lanes": solo.allows_read_only_lanes,
536
+ "max_delegation_depth": 0,
537
+ "max_fanout": 0,
538
+ "budget_guidance": solo.budget_guidance,
539
+ },
540
+ "claude_delegated_worker": {
541
+ "execution_mode": "delegated_worker",
542
+ "maturity_label": "proof_blocked",
543
+ "live_proof_gate": record.live_proof_gate,
544
+ "promotion_status": record.promotion_status,
545
+ "launch_default": False,
546
+ "requires_disjoint_owned_files": True,
547
+ "allows_read_only_lanes": True,
548
+ "max_delegation_depth": 1,
549
+ "max_fanout": 1,
550
+ "budget_guidance": {
551
+ "mode": "metadata_only",
552
+ "notes": "Runner-brokered Claude child work stays bounded by typed delegation budget metadata.",
553
+ },
554
+ },
555
+ "claude_subagent": {
556
+ "execution_mode": "subagent",
557
+ "maturity_label": subagent.maturity_label,
558
+ "live_proof_gate": subagent.live_proof_gate,
559
+ "promotion_status": subagent.promotion_status,
560
+ "launch_default": subagent.launch_default,
561
+ "requires_disjoint_owned_files": subagent.requires_disjoint_owned_files,
562
+ "allows_read_only_lanes": subagent.allows_read_only_lanes,
563
+ "max_delegation_depth": subagent.max_delegation_depth,
564
+ "max_fanout": subagent.max_fanout,
565
+ "budget_guidance": subagent.budget_guidance,
566
+ },
567
+ "claude_agent_team": {
568
+ "execution_mode": "agent_team",
569
+ "maturity_label": agent_team.maturity_label,
570
+ "live_proof_gate": agent_team.live_proof_gate,
571
+ "promotion_status": agent_team.promotion_status,
572
+ "launch_default": agent_team.launch_default,
573
+ "requires_disjoint_owned_files": agent_team.requires_disjoint_owned_files,
574
+ "allows_read_only_lanes": agent_team.allows_read_only_lanes,
575
+ "max_delegation_depth": agent_team.max_delegation_depth,
576
+ "max_fanout": agent_team.max_fanout,
577
+ "budget_guidance": agent_team.budget_guidance,
578
+ },
579
+ }
580
+
581
+
582
+ def claude_team_capability_posture() -> dict[str, dict[str, object]]:
583
+ slice_posture = claude_support_slice_posture()
584
+ return {
585
+ "solo": slice_posture["claude_solo"],
586
+ "subagent": slice_posture["claude_subagent"],
587
+ "agent_team": slice_posture["claude_agent_team"],
588
+ }
589
+
590
+
591
+ def default_executor_for_action(action: str) -> str:
592
+ if action == "maintain-skills":
593
+ return "codex"
594
+ return DEFAULT_EXECUTOR_POLICY.get(action, DEFAULT_EXECUTOR)
595
+
596
+
597
+ def default_executor_for_work_unit(work_unit_kind: str, *, scheduler_assigned: bool = False) -> str:
598
+ if scheduler_assigned and work_unit_kind == "lane_execute":
599
+ return DEFAULT_LANE_EXECUTOR
600
+ return default_executor_for_action("execute" if work_unit_kind == "lane_execute" else "review")
601
+
602
+
603
+ def merge_dispatch_hints(
604
+ *,
605
+ action: str,
606
+ operator: DispatchHints | None = None,
607
+ plan: DispatchHints | None = None,
608
+ roadmap: DispatchHints | None = None,
609
+ ) -> DispatchHints:
610
+ preferred = _first_nonempty(operator, plan, roadmap, field="preferred_executors")
611
+ allowed = _first_nonempty(operator, plan, roadmap, field="allowed_executors")
612
+ fallback = _first_nonempty(operator, plan, roadmap, field="fallback_executors")
613
+ disabled = _union(operator, plan, roadmap, field="disabled_executors")
614
+ required = _union(operator, plan, roadmap, field="required_capabilities")
615
+ source = _source_name(operator, plan, roadmap, preferred, allowed, fallback)
616
+ return DispatchHints(
617
+ preferred_executors=preferred,
618
+ allowed_executors=allowed,
619
+ fallback_executors=fallback,
620
+ disabled_executors=disabled,
621
+ required_capabilities=required,
622
+ source=source,
623
+ action=action,
624
+ )
625
+
626
+
627
+ def resolve_dispatch_decision(
628
+ *,
629
+ action: str,
630
+ dry_run: bool,
631
+ repo: Path | None = None,
632
+ registry: dict[str, ExecutorCapabilityRecord] | None = None,
633
+ operator: DispatchHints | None = None,
634
+ plan: DispatchHints | None = None,
635
+ roadmap: DispatchHints | None = None,
636
+ ) -> DispatchDecision:
637
+ registry = registry or capability_registry()
638
+ if action == "maintain-skills":
639
+ return DispatchDecision(
640
+ action=action,
641
+ selected_executor="codex",
642
+ source="maintain-skills-fixed",
643
+ considered_executors=("codex",),
644
+ selected_via="fixed_action_policy",
645
+ )
646
+
647
+ merged = merge_dispatch_hints(action=action, operator=operator, plan=plan, roadmap=roadmap)
648
+ allowed = merged.allowed_executors or tuple(
649
+ executor for executor, record in registry.items() if action in record.supported_actions
650
+ )
651
+ preferred = merged.preferred_executors or (default_executor_for_action(action),)
652
+ fallback = tuple(executor for executor in merged.fallback_executors if executor not in preferred)
653
+ candidate_order = _dedupe((*preferred, *fallback, *allowed, default_executor_for_action(action)))
654
+ considered: list[str] = []
655
+ degraded = active_degraded_executors(repo) if repo is not None and not dry_run else set()
656
+ degraded_viable: list[str] = []
657
+
658
+ for executor in candidate_order:
659
+ considered.append(executor)
660
+ if executor in merged.disabled_executors:
661
+ if executor in preferred:
662
+ return _blocked_decision(
663
+ action,
664
+ merged,
665
+ tuple(considered),
666
+ "disabled_executor",
667
+ f"Dispatch policy rejected `{executor}` for `{action}` because it is disabled by hints.",
668
+ )
669
+ continue
670
+ if executor not in allowed:
671
+ if executor in preferred:
672
+ return _blocked_decision(
673
+ action,
674
+ merged,
675
+ tuple(considered),
676
+ "executor_not_allowed",
677
+ f"Dispatch policy rejected `{executor}` for `{action}` because it is outside the allowed executor set.",
678
+ )
679
+ continue
680
+ record = registry.get(executor)
681
+ if record is None or action not in record.supported_actions:
682
+ if executor in preferred:
683
+ return _blocked_decision(
684
+ action,
685
+ merged,
686
+ tuple(considered),
687
+ "unsupported_action",
688
+ f"Dispatch policy rejected `{executor}` for `{action}` because the registry does not support that action.",
689
+ )
690
+ continue
691
+ missing = tuple(capability for capability in merged.required_capabilities if capability not in record.capabilities)
692
+ if missing:
693
+ if executor in preferred:
694
+ return _blocked_decision(
695
+ action,
696
+ merged,
697
+ tuple(considered),
698
+ "missing_required_capabilities",
699
+ f"Dispatch policy rejected `{executor}` for `{action}` because it lacks required capabilities: {', '.join(missing)}.",
700
+ )
701
+ continue
702
+ if dry_run:
703
+ if not record.dry_run_available:
704
+ continue
705
+ elif not record.live_available:
706
+ if executor in preferred and not fallback:
707
+ return _blocked_decision(
708
+ action,
709
+ merged,
710
+ tuple(considered),
711
+ "live_launch_unavailable",
712
+ f"Dispatch policy selected `{executor}` for `{action}`, but that executor is currently dry-run-only.",
713
+ )
714
+ if executor in preferred and fallback:
715
+ continue
716
+ continue
717
+ if executor in degraded:
718
+ degraded_viable.append(executor)
719
+ continue
720
+ return DispatchDecision(
721
+ action=action,
722
+ selected_executor=executor,
723
+ source=merged.source,
724
+ preferred_executors=preferred,
725
+ allowed_executors=allowed,
726
+ fallback_executors=fallback,
727
+ disabled_executors=merged.disabled_executors,
728
+ required_capabilities=merged.required_capabilities,
729
+ considered_executors=tuple(considered),
730
+ fallback_applied=executor not in preferred,
731
+ selected_via="fallback" if executor not in preferred else "preferred",
732
+ )
733
+
734
+ if degraded_viable:
735
+ return _blocked_decision(
736
+ action,
737
+ merged,
738
+ tuple(considered or candidate_order),
739
+ "all_candidates_session_degraded",
740
+ f"Dispatch policy could not resolve a live executor for `{action}` because all otherwise viable candidates are session-degraded.",
741
+ )
742
+
743
+ return _blocked_decision(
744
+ action,
745
+ merged,
746
+ tuple(considered or candidate_order),
747
+ "no_allowed_executor",
748
+ f"Dispatch policy could not resolve an executor for `{action}` with the current hints and registry.",
749
+ )
750
+
751
+
752
+ def describe_dispatch_decision(decision: DispatchDecision) -> str:
753
+ if decision.blocked:
754
+ return decision.blocked_summary or "dispatch blocked"
755
+ parts = [f"selected `{decision.selected_executor}` via {decision.source}"]
756
+ if decision.fallback_applied:
757
+ parts.append("fallback applied")
758
+ if decision.required_capabilities:
759
+ parts.append(f"required capabilities: {', '.join(decision.required_capabilities)}")
760
+ return "; ".join(parts)
761
+
762
+
763
+ def default_model_profile_for_executor(action: str, executor: str) -> str:
764
+ record = capability_registry()[executor]
765
+ return record.default_model_profiles.get(action, _ACTION_DEFAULT_PROFILES[action])
766
+
767
+
768
+ def _first_nonempty(*hints: DispatchHints | None, field: str) -> tuple[str, ...]:
769
+ for hint in hints:
770
+ if hint is None:
771
+ continue
772
+ values = getattr(hint, field)
773
+ if values:
774
+ return tuple(values)
775
+ return ()
776
+
777
+
778
+ def _union(*hints: DispatchHints | None, field: str) -> tuple[str, ...]:
779
+ values: list[str] = []
780
+ for hint in reversed(hints):
781
+ if hint is None:
782
+ continue
783
+ values.extend(getattr(hint, field))
784
+ return _dedupe(values)
785
+
786
+
787
+ def _dedupe(values: tuple[str, ...] | list[str] | tuple[str, ...]) -> tuple[str, ...]:
788
+ seen: list[str] = []
789
+ for value in values:
790
+ if value not in seen:
791
+ seen.append(value)
792
+ return tuple(seen)
793
+
794
+
795
+ def _source_name(
796
+ operator: DispatchHints | None,
797
+ plan: DispatchHints | None,
798
+ roadmap: DispatchHints | None,
799
+ preferred: tuple[str, ...],
800
+ allowed: tuple[str, ...],
801
+ fallback: tuple[str, ...],
802
+ ) -> str:
803
+ for source_name, hint in (("operator", operator), ("plan", plan), ("roadmap", roadmap)):
804
+ if hint is None:
805
+ continue
806
+ if preferred and hint.preferred_executors == preferred:
807
+ return source_name
808
+ if allowed and hint.allowed_executors == allowed:
809
+ return source_name
810
+ if fallback and hint.fallback_executors == fallback:
811
+ return source_name
812
+ return "registry_default"
813
+
814
+
815
+ def _blocked_decision(
816
+ action: str,
817
+ merged: DispatchHints,
818
+ considered: tuple[str, ...],
819
+ blocked_reason: str,
820
+ blocked_summary: str,
821
+ ) -> DispatchDecision:
822
+ return DispatchDecision(
823
+ action=action,
824
+ selected_executor=None,
825
+ source=merged.source,
826
+ preferred_executors=merged.preferred_executors or (default_executor_for_action(action),),
827
+ allowed_executors=merged.allowed_executors,
828
+ fallback_executors=merged.fallback_executors,
829
+ disabled_executors=merged.disabled_executors,
830
+ required_capabilities=merged.required_capabilities,
831
+ considered_executors=considered,
832
+ blocked_reason=blocked_reason,
833
+ blocked_summary=blocked_summary,
834
+ selected_via=None,
835
+ )