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.
- phase_loop_runtime/__init__.py +20 -0
- phase_loop_runtime/_contract_docs/phase-loop/extraction-readiness.md +90 -0
- phase_loop_runtime/_contract_docs/phase-loop/granular-execution-policy.md +137 -0
- phase_loop_runtime/_contract_docs/phase-loop/harness-capability-matrix.md +510 -0
- phase_loop_runtime/_contract_docs/phase-loop/harness-skill-matrix.md +125 -0
- phase_loop_runtime/_contract_docs/phase-loop/harness-substrate-manifest.md +232 -0
- phase_loop_runtime/_contract_docs/phase-loop/pi-loop-control.md +247 -0
- phase_loop_runtime/_contract_docs/phase-loop/protocol.md +2759 -0
- phase_loop_runtime/_contract_docs/phase-loop/runtime-boundary.md +289 -0
- phase_loop_runtime/_contract_docs/phase-loop/spec-discovery-roots.md +47 -0
- phase_loop_runtime/_contract_docs/phase-loop/substrate-soak-governed-pipeline.md +42 -0
- phase_loop_runtime/_contract_docs/phase-loop/substrate-soak-portal-projection.md +34 -0
- phase_loop_runtime/_contract_docs/phase-loop/substrate-soak-regenesis.md +29 -0
- phase_loop_runtime/_contract_docs/phase-loop/substrate-soak-report.md +32 -0
- phase_loop_runtime/_contract_docs/runtime/verification-evidence-contract.md +52 -0
- phase_loop_runtime/_test_fixtures/evidence-audit-calibration/borderline/borderline-mixed-signals/commands.txt +2 -0
- phase_loop_runtime/_test_fixtures/evidence-audit-calibration/borderline/borderline-mixed-signals/manifest.json +16 -0
- phase_loop_runtime/_test_fixtures/evidence-audit-calibration/borderline/borderline-mixed-signals/mixed.json +5 -0
- phase_loop_runtime/_test_fixtures/evidence-audit-calibration/borderline/borderline-provider-timeout/manifest.json +16 -0
- phase_loop_runtime/_test_fixtures/evidence-audit-calibration/borderline/borderline-provider-timeout/timeout-note.txt +2 -0
- phase_loop_runtime/_test_fixtures/evidence-audit-calibration/borderline/borderline-redacted-summary/manifest.json +16 -0
- phase_loop_runtime/_test_fixtures/evidence-audit-calibration/borderline/borderline-redacted-summary/redacted-summary.json +6 -0
- phase_loop_runtime/_test_fixtures/evidence-audit-calibration/borderline/borderline-small-sample/manifest.json +16 -0
- phase_loop_runtime/_test_fixtures/evidence-audit-calibration/borderline/borderline-small-sample/sample.json +7 -0
- phase_loop_runtime/_test_fixtures/evidence-audit-calibration/borderline/borderline-threshold-edge/edge.txt +2 -0
- phase_loop_runtime/_test_fixtures/evidence-audit-calibration/borderline/borderline-threshold-edge/manifest.json +16 -0
- phase_loop_runtime/_test_fixtures/evidence-audit-calibration/known-fake/fake-duplicate-png/manifest.json +16 -0
- phase_loop_runtime/_test_fixtures/evidence-audit-calibration/known-fake/fake-duplicate-png/shot-a.txt +1 -0
- phase_loop_runtime/_test_fixtures/evidence-audit-calibration/known-fake/fake-duplicate-png/shot-b.txt +1 -0
- phase_loop_runtime/_test_fixtures/evidence-audit-calibration/known-fake/fake-duplicate-png/shot-c.txt +1 -0
- phase_loop_runtime/_test_fixtures/evidence-audit-calibration/known-fake/fake-missing-references/claimed-results.json +5 -0
- phase_loop_runtime/_test_fixtures/evidence-audit-calibration/known-fake/fake-missing-references/manifest.json +16 -0
- phase_loop_runtime/_test_fixtures/evidence-audit-calibration/known-fake/fake-subtle-low-variance/manifest.json +16 -0
- phase_loop_runtime/_test_fixtures/evidence-audit-calibration/known-fake/fake-subtle-low-variance/metrics.json +9 -0
- phase_loop_runtime/_test_fixtures/evidence-audit-calibration/known-fake/fake-templated-prose/findings.md +10 -0
- phase_loop_runtime/_test_fixtures/evidence-audit-calibration/known-fake/fake-templated-prose/manifest.json +16 -0
- phase_loop_runtime/_test_fixtures/evidence-audit-calibration/known-fake/fake-uniform-scores/manifest.json +16 -0
- phase_loop_runtime/_test_fixtures/evidence-audit-calibration/known-fake/fake-uniform-scores/scores.json +4 -0
- phase_loop_runtime/_test_fixtures/evidence-audit-calibration/known-fake/fake-uniform-scores/summary.txt +1 -0
- phase_loop_runtime/_test_fixtures/evidence-audit-calibration/known-real/real-adoption-bundle/bundle-check.json +8 -0
- phase_loop_runtime/_test_fixtures/evidence-audit-calibration/known-real/real-adoption-bundle/manifest.json +16 -0
- phase_loop_runtime/_test_fixtures/evidence-audit-calibration/known-real/real-adoption-bundle/operator-note.txt +2 -0
- phase_loop_runtime/_test_fixtures/evidence-audit-calibration/known-real/real-handoff-ledger/events-sample.jsonl +3 -0
- phase_loop_runtime/_test_fixtures/evidence-audit-calibration/known-real/real-handoff-ledger/manifest.json +16 -0
- phase_loop_runtime/_test_fixtures/evidence-audit-calibration/known-real/real-handoff-ledger/receipt.txt +1 -0
- phase_loop_runtime/_test_fixtures/evidence-audit-calibration/known-real/real-runner-diff/evidence.json +13 -0
- phase_loop_runtime/_test_fixtures/evidence-audit-calibration/known-real/real-runner-diff/manifest.json +16 -0
- phase_loop_runtime/_test_fixtures/evidence-audit-calibration/known-real/real-runner-diff/summary.txt +2 -0
- phase_loop_runtime/_test_fixtures/evidence-audit-calibration/known-real/real-test-matrix/manifest.json +16 -0
- phase_loop_runtime/_test_fixtures/evidence-audit-calibration/known-real/real-test-matrix/matrix.json +9 -0
- phase_loop_runtime/_test_fixtures/evidence-audit-calibration/known-real/real-test-matrix/notes.md +4 -0
- phase_loop_runtime/_test_fixtures/evidence-audit-calibration/known-real/real-ui-screenshot-standin/console-summary.txt +2 -0
- phase_loop_runtime/_test_fixtures/evidence-audit-calibration/known-real/real-ui-screenshot-standin/manifest.json +16 -0
- phase_loop_runtime/_test_fixtures/evidence-audit-calibration/known-real/real-ui-screenshot-standin/screenshot-standin.ppm +5 -0
- phase_loop_runtime/adoption_bundle.py +273 -0
- phase_loop_runtime/advisor_board/CONTRACTS.md +257 -0
- phase_loop_runtime/advisor_board/__init__.py +288 -0
- phase_loop_runtime/advisor_board/backing.py +137 -0
- phase_loop_runtime/advisor_board/backing_omnigent.py +498 -0
- phase_loop_runtime/advisor_board/config.py +225 -0
- phase_loop_runtime/advisor_board/events.py +115 -0
- phase_loop_runtime/advisor_board/fixtures/advisor-boards.example.toml +59 -0
- phase_loop_runtime/advisor_board/fixtures.py +91 -0
- phase_loop_runtime/advisor_board/harness_mapping.py +125 -0
- phase_loop_runtime/advisor_board/matrix.py +146 -0
- phase_loop_runtime/advisor_board/observability.py +481 -0
- phase_loop_runtime/advisor_board/presets.py +188 -0
- phase_loop_runtime/advisor_board/registries.py +309 -0
- phase_loop_runtime/advisor_board/resolver.py +253 -0
- phase_loop_runtime/advisor_board/schema.py +269 -0
- phase_loop_runtime/advisor_board/standin.py +166 -0
- phase_loop_runtime/advisor_board/validation.py +159 -0
- phase_loop_runtime/agent_runtime_provider.py +676 -0
- phase_loop_runtime/baml_modular.py +656 -0
- phase_loop_runtime/baml_src/dotfiles_adoption_manifest.baml +37 -0
- phase_loop_runtime/baml_src/dotfiles_c4_document.baml +14 -0
- phase_loop_runtime/baml_src/dotfiles_plan_manifest.baml +50 -0
- phase_loop_runtime/baml_src/dotfiles_runtime_projection.baml +16 -0
- phase_loop_runtime/baml_src/dotfiles_task_catalog.baml +20 -0
- phase_loop_runtime/baml_src/emit_phase_closeout.baml +86 -0
- phase_loop_runtime/baml_src/evaluate_suspected_fake_evidence.baml +36 -0
- phase_loop_runtime/baml_src/verification_evidence.baml +40 -0
- phase_loop_runtime/broker.py +181 -0
- phase_loop_runtime/build_bundle.py +294 -0
- phase_loop_runtime/capability_registry.py +835 -0
- phase_loop_runtime/classifier.py +87 -0
- phase_loop_runtime/claude_agent_view.py +625 -0
- phase_loop_runtime/claude_channel_sidecar.py +1086 -0
- phase_loop_runtime/cli.py +2599 -0
- phase_loop_runtime/closeout.py +865 -0
- phase_loop_runtime/closeout_classifier.py +120 -0
- phase_loop_runtime/closeout_evidence_audit.py +112 -0
- phase_loop_runtime/closeout_validation.py +144 -0
- phase_loop_runtime/closeout_validators.py +203 -0
- phase_loop_runtime/consiliency_gates.py +374 -0
- phase_loop_runtime/consiliency_ingest.py +399 -0
- phase_loop_runtime/consiliency_layout.py +176 -0
- phase_loop_runtime/consiliency_scaffold.py +305 -0
- phase_loop_runtime/cross_repo_channel.py +331 -0
- phase_loop_runtime/discovery.py +2368 -0
- phase_loop_runtime/dispatch_lock.py +167 -0
- phase_loop_runtime/doc_delta_validator.py +98 -0
- phase_loop_runtime/docs_audit.py +285 -0
- phase_loop_runtime/docs_freshness.py +468 -0
- phase_loop_runtime/docs_surfaces.py +150 -0
- phase_loop_runtime/dotfiles_profile_plugin.py +96 -0
- phase_loop_runtime/events.py +154 -0
- phase_loop_runtime/events_migration.py +96 -0
- phase_loop_runtime/evidence_audit.py +1082 -0
- phase_loop_runtime/evidence_audit_config.py +172 -0
- phase_loop_runtime/fleet_map.py +426 -0
- phase_loop_runtime/fleet_metrics.py +298 -0
- phase_loop_runtime/fleet_metrics_export.py +196 -0
- phase_loop_runtime/git_discipline.py +479 -0
- phase_loop_runtime/git_ops.py +122 -0
- phase_loop_runtime/git_topology.py +252 -0
- phase_loop_runtime/governed_bundle.py +137 -0
- phase_loop_runtime/governed_premerge.py +219 -0
- phase_loop_runtime/governed_review.py +264 -0
- phase_loop_runtime/handoff.py +932 -0
- phase_loop_runtime/handoff_path.py +14 -0
- phase_loop_runtime/injection.py +740 -0
- phase_loop_runtime/install_status.py +88 -0
- phase_loop_runtime/lane_scheduler.py +317 -0
- phase_loop_runtime/launcher.py +2760 -0
- phase_loop_runtime/lease_store.py +553 -0
- phase_loop_runtime/maintenance.py +401 -0
- phase_loop_runtime/migrate_handoffs.py +201 -0
- phase_loop_runtime/models.py +2144 -0
- phase_loop_runtime/observability.py +1290 -0
- phase_loop_runtime/panel_invoker.py +1638 -0
- phase_loop_runtime/phase_loop_drift_audit.py +388 -0
- phase_loop_runtime/phase_worktree_executor.py +433 -0
- phase_loop_runtime/pipeline_adapter/__init__.py +12 -0
- phase_loop_runtime/pipeline_adapter/branch_ops.py +274 -0
- phase_loop_runtime/pipeline_adapter/flag.py +55 -0
- phase_loop_runtime/pipeline_adapter/markers.py +13 -0
- phase_loop_runtime/pipeline_adapter/merge_policy.py +72 -0
- phase_loop_runtime/pipeline_adapter/ratification.py +100 -0
- phase_loop_runtime/pipeline_adapter/sibling_matcher.py +123 -0
- phase_loop_runtime/plan_ir.py +523 -0
- phase_loop_runtime/plan_manifest.py +415 -0
- phase_loop_runtime/planner_validation.py +176 -0
- phase_loop_runtime/profiles.py +462 -0
- phase_loop_runtime/prompts.py +365 -0
- phase_loop_runtime/provenance.py +165 -0
- phase_loop_runtime/publishing.py +339 -0
- phase_loop_runtime/py.typed +1 -0
- phase_loop_runtime/reconcile.py +1550 -0
- phase_loop_runtime/redaction.py +184 -0
- phase_loop_runtime/reflection_sync.py +293 -0
- phase_loop_runtime/release_guard.py +186 -0
- phase_loop_runtime/render.py +432 -0
- phase_loop_runtime/repo_validation.py +427 -0
- phase_loop_runtime/review_summary.py +150 -0
- phase_loop_runtime/roadmap_lint.py +425 -0
- phase_loop_runtime/route_log.py +59 -0
- phase_loop_runtime/route_policy/__init__.py +11 -0
- phase_loop_runtime/route_policy/fixtures/route_selection.golden.json +263 -0
- phase_loop_runtime/runner.py +8400 -0
- phase_loop_runtime/runtime_paths.py +225 -0
- phase_loop_runtime/runtime_projection.py +113 -0
- phase_loop_runtime/runtime_resources.py +36 -0
- phase_loop_runtime/schema_export.py +292 -0
- phase_loop_runtime/schemas/phase_loop_closeout.schema.json +366 -0
- phase_loop_runtime/skill_install.py +176 -0
- phase_loop_runtime/skill_inventory.py +662 -0
- phase_loop_runtime/skill_paths.py +42 -0
- phase_loop_runtime/skill_sources_plugin.py +37 -0
- phase_loop_runtime/skills_bundle/claude-advisor-board/README.md +1 -0
- phase_loop_runtime/skills_bundle/claude-advisor-board/SKILL.md +38 -0
- phase_loop_runtime/skills_bundle/claude-advisor-panel/README.md +1 -0
- phase_loop_runtime/skills_bundle/claude-advisor-panel/SKILL.md +38 -0
- phase_loop_runtime/skills_bundle/claude-execute-detailed/README.md +1 -0
- phase_loop_runtime/skills_bundle/claude-execute-detailed/SKILL.md +152 -0
- phase_loop_runtime/skills_bundle/claude-execute-phase/README.md +1 -0
- phase_loop_runtime/skills_bundle/claude-execute-phase/SKILL.md +745 -0
- phase_loop_runtime/skills_bundle/claude-execute-phase/scripts/allocate_worktree_name.sh +33 -0
- phase_loop_runtime/skills_bundle/claude-execute-phase/scripts/audit_lane_file_touches.py +197 -0
- phase_loop_runtime/skills_bundle/claude-execute-phase/scripts/cleanup_lane_worktrees.sh +103 -0
- phase_loop_runtime/skills_bundle/claude-execute-phase/scripts/parent_tree_leakage_check.sh +125 -0
- phase_loop_runtime/skills_bundle/claude-execute-phase/scripts/post_merge_import_smoke.sh +62 -0
- phase_loop_runtime/skills_bundle/claude-execute-phase/scripts/pre_merge_destructiveness_check.sh +127 -0
- phase_loop_runtime/skills_bundle/claude-execute-phase/scripts/resolve_branch_from_sha.sh +51 -0
- phase_loop_runtime/skills_bundle/claude-execute-phase/scripts/state.py +274 -0
- phase_loop_runtime/skills_bundle/claude-execute-phase/scripts/sweep_stale_worktrees.sh +62 -0
- phase_loop_runtime/skills_bundle/claude-execute-phase/scripts/team_teardown.sh +32 -0
- phase_loop_runtime/skills_bundle/claude-execute-phase/scripts/validate_plan_doc.py +642 -0
- phase_loop_runtime/skills_bundle/claude-execute-phase/scripts/verify_harness.sh +96 -0
- phase_loop_runtime/skills_bundle/claude-phase-loop/README.md +1 -0
- phase_loop_runtime/skills_bundle/claude-phase-loop/SKILL.md +115 -0
- phase_loop_runtime/skills_bundle/claude-phase-roadmap-builder/README.md +1 -0
- phase_loop_runtime/skills_bundle/claude-phase-roadmap-builder/SKILL.md +439 -0
- phase_loop_runtime/skills_bundle/claude-phase-roadmap-builder/assets/review_prompt.md +19 -0
- phase_loop_runtime/skills_bundle/claude-phase-roadmap-builder/references/parallelization-heuristics.md +111 -0
- phase_loop_runtime/skills_bundle/claude-phase-roadmap-builder/references/roadmap-template.md +193 -0
- phase_loop_runtime/skills_bundle/claude-phase-roadmap-builder/scripts/validate_roadmap.py +32 -0
- phase_loop_runtime/skills_bundle/claude-plan-detailed/README.md +1 -0
- phase_loop_runtime/skills_bundle/claude-plan-detailed/SKILL.md +334 -0
- phase_loop_runtime/skills_bundle/claude-plan-detailed/assets/review_prompt.md +25 -0
- phase_loop_runtime/skills_bundle/claude-plan-phase/README.md +1 -0
- phase_loop_runtime/skills_bundle/claude-plan-phase/SKILL.md +776 -0
- phase_loop_runtime/skills_bundle/claude-plan-phase/assets/review_prompt.md +17 -0
- phase_loop_runtime/skills_bundle/claude-plan-phase/scripts/validate_plan_doc.py +1092 -0
- phase_loop_runtime/skills_bundle/claude-run-train/README.md +1 -0
- phase_loop_runtime/skills_bundle/claude-run-train/SKILL.md +75 -0
- phase_loop_runtime/skills_bundle/claude-skill-editor/README.md +1 -0
- phase_loop_runtime/skills_bundle/claude-skill-editor/SKILL.md +243 -0
- phase_loop_runtime/skills_bundle/claude-skill-editor/assets/editor_prompt.md +72 -0
- phase_loop_runtime/skills_bundle/claude-skill-improvement-planner/README.md +1 -0
- phase_loop_runtime/skills_bundle/claude-skill-improvement-planner/SKILL.md +249 -0
- phase_loop_runtime/skills_bundle/claude-skill-improvement-planner/assets/aggregator_prompt.md +79 -0
- phase_loop_runtime/skills_bundle/claude-task-contextualizer/README.md +1 -0
- phase_loop_runtime/skills_bundle/claude-task-contextualizer/SKILL.md +74 -0
- phase_loop_runtime/skills_bundle/claude-task-contextualizer/references/task-templates.md +103 -0
- phase_loop_runtime/skills_bundle/codex-advisor-board/README.md +1 -0
- phase_loop_runtime/skills_bundle/codex-advisor-board/SKILL.md +38 -0
- phase_loop_runtime/skills_bundle/codex-advisor-panel/README.md +1 -0
- phase_loop_runtime/skills_bundle/codex-advisor-panel/SKILL.md +38 -0
- phase_loop_runtime/skills_bundle/codex-execute-detailed/README.md +1 -0
- phase_loop_runtime/skills_bundle/codex-execute-detailed/SKILL.md +154 -0
- phase_loop_runtime/skills_bundle/codex-execute-phase/README.md +1 -0
- phase_loop_runtime/skills_bundle/codex-execute-phase/SKILL.md +231 -0
- phase_loop_runtime/skills_bundle/codex-execute-phase/scripts/allocate_worktree_name.sh +33 -0
- phase_loop_runtime/skills_bundle/codex-execute-phase/scripts/audit_lane_file_touches.py +197 -0
- phase_loop_runtime/skills_bundle/codex-execute-phase/scripts/cleanup_lane_worktrees.sh +103 -0
- phase_loop_runtime/skills_bundle/codex-execute-phase/scripts/parent_tree_leakage_check.sh +125 -0
- phase_loop_runtime/skills_bundle/codex-execute-phase/scripts/post_merge_import_smoke.sh +62 -0
- phase_loop_runtime/skills_bundle/codex-execute-phase/scripts/pre_merge_destructiveness_check.sh +127 -0
- phase_loop_runtime/skills_bundle/codex-execute-phase/scripts/resolve_branch_from_sha.sh +51 -0
- phase_loop_runtime/skills_bundle/codex-execute-phase/scripts/state.py +274 -0
- phase_loop_runtime/skills_bundle/codex-execute-phase/scripts/sweep_stale_worktrees.sh +62 -0
- phase_loop_runtime/skills_bundle/codex-execute-phase/scripts/team_teardown.sh +32 -0
- phase_loop_runtime/skills_bundle/codex-execute-phase/scripts/validate_plan_doc.py +642 -0
- phase_loop_runtime/skills_bundle/codex-execute-phase/scripts/verify_harness.sh +96 -0
- phase_loop_runtime/skills_bundle/codex-phase-loop/README.md +1 -0
- phase_loop_runtime/skills_bundle/codex-phase-loop/SKILL.md +248 -0
- phase_loop_runtime/skills_bundle/codex-phase-roadmap-builder/README.md +1 -0
- phase_loop_runtime/skills_bundle/codex-phase-roadmap-builder/SKILL.md +150 -0
- phase_loop_runtime/skills_bundle/codex-phase-roadmap-builder/assets/review_prompt.md +19 -0
- phase_loop_runtime/skills_bundle/codex-phase-roadmap-builder/references/parallelization-heuristics.md +111 -0
- phase_loop_runtime/skills_bundle/codex-phase-roadmap-builder/references/roadmap-template.md +193 -0
- phase_loop_runtime/skills_bundle/codex-phase-roadmap-builder/scripts/validate_roadmap.py +32 -0
- phase_loop_runtime/skills_bundle/codex-plan-detailed/README.md +1 -0
- phase_loop_runtime/skills_bundle/codex-plan-detailed/SKILL.md +119 -0
- phase_loop_runtime/skills_bundle/codex-plan-detailed/assets/review_prompt.md +25 -0
- phase_loop_runtime/skills_bundle/codex-plan-phase/README.md +1 -0
- phase_loop_runtime/skills_bundle/codex-plan-phase/SKILL.md +307 -0
- phase_loop_runtime/skills_bundle/codex-plan-phase/assets/review_prompt.md +17 -0
- phase_loop_runtime/skills_bundle/codex-plan-phase/scripts/validate_plan_doc.py +1092 -0
- phase_loop_runtime/skills_bundle/codex-run-train/README.md +1 -0
- phase_loop_runtime/skills_bundle/codex-run-train/SKILL.md +75 -0
- phase_loop_runtime/skills_bundle/codex-skill-editor/README.md +1 -0
- phase_loop_runtime/skills_bundle/codex-skill-editor/SKILL.md +94 -0
- phase_loop_runtime/skills_bundle/codex-skill-editor/assets/editor_prompt.md +72 -0
- phase_loop_runtime/skills_bundle/codex-skill-improvement-planner/README.md +1 -0
- phase_loop_runtime/skills_bundle/codex-skill-improvement-planner/SKILL.md +114 -0
- phase_loop_runtime/skills_bundle/codex-skill-improvement-planner/assets/aggregator_prompt.md +79 -0
- phase_loop_runtime/skills_bundle/codex-task-contextualizer/README.md +1 -0
- phase_loop_runtime/skills_bundle/codex-task-contextualizer/SKILL.md +102 -0
- phase_loop_runtime/skills_bundle/codex-task-contextualizer/references/task-templates.md +103 -0
- phase_loop_runtime/skills_bundle/gemini-advisor-board/README.md +1 -0
- phase_loop_runtime/skills_bundle/gemini-advisor-board/SKILL.md +38 -0
- phase_loop_runtime/skills_bundle/gemini-advisor-panel/README.md +1 -0
- phase_loop_runtime/skills_bundle/gemini-advisor-panel/SKILL.md +38 -0
- phase_loop_runtime/skills_bundle/gemini-execute-detailed/README.md +1 -0
- phase_loop_runtime/skills_bundle/gemini-execute-detailed/SKILL.md +144 -0
- phase_loop_runtime/skills_bundle/gemini-execute-phase/README.md +1 -0
- phase_loop_runtime/skills_bundle/gemini-execute-phase/SKILL.md +198 -0
- phase_loop_runtime/skills_bundle/gemini-execute-phase/scripts/allocate_worktree_name.sh +33 -0
- phase_loop_runtime/skills_bundle/gemini-execute-phase/scripts/audit_lane_file_touches.py +197 -0
- phase_loop_runtime/skills_bundle/gemini-execute-phase/scripts/cleanup_lane_worktrees.sh +103 -0
- phase_loop_runtime/skills_bundle/gemini-execute-phase/scripts/parent_tree_leakage_check.sh +125 -0
- phase_loop_runtime/skills_bundle/gemini-execute-phase/scripts/post_merge_import_smoke.sh +62 -0
- phase_loop_runtime/skills_bundle/gemini-execute-phase/scripts/pre_merge_destructiveness_check.sh +127 -0
- phase_loop_runtime/skills_bundle/gemini-execute-phase/scripts/resolve_branch_from_sha.sh +51 -0
- phase_loop_runtime/skills_bundle/gemini-execute-phase/scripts/state.py +274 -0
- phase_loop_runtime/skills_bundle/gemini-execute-phase/scripts/sweep_stale_worktrees.sh +62 -0
- phase_loop_runtime/skills_bundle/gemini-execute-phase/scripts/team_teardown.sh +32 -0
- phase_loop_runtime/skills_bundle/gemini-execute-phase/scripts/validate_plan_doc.py +642 -0
- phase_loop_runtime/skills_bundle/gemini-execute-phase/scripts/verify_harness.sh +96 -0
- phase_loop_runtime/skills_bundle/gemini-phase-loop/README.md +1 -0
- phase_loop_runtime/skills_bundle/gemini-phase-loop/SKILL.md +111 -0
- phase_loop_runtime/skills_bundle/gemini-phase-roadmap-builder/README.md +1 -0
- phase_loop_runtime/skills_bundle/gemini-phase-roadmap-builder/SKILL.md +147 -0
- phase_loop_runtime/skills_bundle/gemini-phase-roadmap-builder/assets/review_prompt.md +19 -0
- phase_loop_runtime/skills_bundle/gemini-phase-roadmap-builder/references/parallelization-heuristics.md +111 -0
- phase_loop_runtime/skills_bundle/gemini-phase-roadmap-builder/references/roadmap-template.md +193 -0
- phase_loop_runtime/skills_bundle/gemini-phase-roadmap-builder/scripts/validate_roadmap.py +32 -0
- phase_loop_runtime/skills_bundle/gemini-plan-detailed/README.md +1 -0
- phase_loop_runtime/skills_bundle/gemini-plan-detailed/SKILL.md +119 -0
- phase_loop_runtime/skills_bundle/gemini-plan-detailed/assets/review_prompt.md +25 -0
- phase_loop_runtime/skills_bundle/gemini-plan-phase/README.md +1 -0
- phase_loop_runtime/skills_bundle/gemini-plan-phase/SKILL.md +217 -0
- phase_loop_runtime/skills_bundle/gemini-plan-phase/assets/review_prompt.md +17 -0
- phase_loop_runtime/skills_bundle/gemini-plan-phase/scripts/validate_plan_doc.py +1092 -0
- phase_loop_runtime/skills_bundle/gemini-run-train/README.md +1 -0
- phase_loop_runtime/skills_bundle/gemini-run-train/SKILL.md +75 -0
- phase_loop_runtime/skills_bundle/gemini-skill-editor/README.md +1 -0
- phase_loop_runtime/skills_bundle/gemini-skill-editor/SKILL.md +87 -0
- phase_loop_runtime/skills_bundle/gemini-skill-editor/assets/editor_prompt.md +72 -0
- phase_loop_runtime/skills_bundle/gemini-skill-improvement-planner/README.md +1 -0
- phase_loop_runtime/skills_bundle/gemini-skill-improvement-planner/SKILL.md +109 -0
- phase_loop_runtime/skills_bundle/gemini-skill-improvement-planner/assets/aggregator_prompt.md +79 -0
- phase_loop_runtime/skills_bundle/gemini-task-contextualizer/README.md +1 -0
- phase_loop_runtime/skills_bundle/gemini-task-contextualizer/SKILL.md +98 -0
- phase_loop_runtime/skills_bundle/gemini-task-contextualizer/references/task-templates.md +103 -0
- phase_loop_runtime/skills_bundle/opencode-advisor-board/README.md +1 -0
- phase_loop_runtime/skills_bundle/opencode-advisor-board/SKILL.md +38 -0
- phase_loop_runtime/skills_bundle/opencode-advisor-panel/README.md +1 -0
- phase_loop_runtime/skills_bundle/opencode-advisor-panel/SKILL.md +38 -0
- phase_loop_runtime/skills_bundle/opencode-execute-detailed/README.md +1 -0
- phase_loop_runtime/skills_bundle/opencode-execute-detailed/SKILL.md +144 -0
- phase_loop_runtime/skills_bundle/opencode-execute-phase/README.md +1 -0
- phase_loop_runtime/skills_bundle/opencode-execute-phase/SKILL.md +196 -0
- phase_loop_runtime/skills_bundle/opencode-execute-phase/scripts/allocate_worktree_name.sh +33 -0
- phase_loop_runtime/skills_bundle/opencode-execute-phase/scripts/audit_lane_file_touches.py +197 -0
- phase_loop_runtime/skills_bundle/opencode-execute-phase/scripts/cleanup_lane_worktrees.sh +103 -0
- phase_loop_runtime/skills_bundle/opencode-execute-phase/scripts/parent_tree_leakage_check.sh +125 -0
- phase_loop_runtime/skills_bundle/opencode-execute-phase/scripts/post_merge_import_smoke.sh +62 -0
- phase_loop_runtime/skills_bundle/opencode-execute-phase/scripts/pre_merge_destructiveness_check.sh +127 -0
- phase_loop_runtime/skills_bundle/opencode-execute-phase/scripts/resolve_branch_from_sha.sh +51 -0
- phase_loop_runtime/skills_bundle/opencode-execute-phase/scripts/state.py +274 -0
- phase_loop_runtime/skills_bundle/opencode-execute-phase/scripts/sweep_stale_worktrees.sh +62 -0
- phase_loop_runtime/skills_bundle/opencode-execute-phase/scripts/team_teardown.sh +32 -0
- phase_loop_runtime/skills_bundle/opencode-execute-phase/scripts/validate_plan_doc.py +642 -0
- phase_loop_runtime/skills_bundle/opencode-execute-phase/scripts/verify_harness.sh +96 -0
- phase_loop_runtime/skills_bundle/opencode-phase-loop/README.md +1 -0
- phase_loop_runtime/skills_bundle/opencode-phase-loop/SKILL.md +113 -0
- phase_loop_runtime/skills_bundle/opencode-phase-roadmap-builder/README.md +1 -0
- phase_loop_runtime/skills_bundle/opencode-phase-roadmap-builder/SKILL.md +147 -0
- phase_loop_runtime/skills_bundle/opencode-phase-roadmap-builder/assets/review_prompt.md +19 -0
- phase_loop_runtime/skills_bundle/opencode-phase-roadmap-builder/references/parallelization-heuristics.md +111 -0
- phase_loop_runtime/skills_bundle/opencode-phase-roadmap-builder/references/roadmap-template.md +193 -0
- phase_loop_runtime/skills_bundle/opencode-phase-roadmap-builder/scripts/validate_roadmap.py +32 -0
- phase_loop_runtime/skills_bundle/opencode-plan-detailed/README.md +1 -0
- phase_loop_runtime/skills_bundle/opencode-plan-detailed/SKILL.md +119 -0
- phase_loop_runtime/skills_bundle/opencode-plan-detailed/assets/review_prompt.md +25 -0
- phase_loop_runtime/skills_bundle/opencode-plan-phase/README.md +1 -0
- phase_loop_runtime/skills_bundle/opencode-plan-phase/SKILL.md +211 -0
- phase_loop_runtime/skills_bundle/opencode-plan-phase/assets/review_prompt.md +17 -0
- phase_loop_runtime/skills_bundle/opencode-plan-phase/scripts/validate_plan_doc.py +1092 -0
- phase_loop_runtime/skills_bundle/opencode-run-train/README.md +1 -0
- phase_loop_runtime/skills_bundle/opencode-run-train/SKILL.md +75 -0
- phase_loop_runtime/skills_bundle/opencode-skill-editor/README.md +1 -0
- phase_loop_runtime/skills_bundle/opencode-skill-editor/SKILL.md +87 -0
- phase_loop_runtime/skills_bundle/opencode-skill-editor/assets/editor_prompt.md +72 -0
- phase_loop_runtime/skills_bundle/opencode-skill-improvement-planner/README.md +1 -0
- phase_loop_runtime/skills_bundle/opencode-skill-improvement-planner/SKILL.md +109 -0
- phase_loop_runtime/skills_bundle/opencode-skill-improvement-planner/assets/aggregator_prompt.md +79 -0
- phase_loop_runtime/skills_bundle/opencode-task-contextualizer/README.md +1 -0
- phase_loop_runtime/skills_bundle/opencode-task-contextualizer/SKILL.md +98 -0
- phase_loop_runtime/skills_bundle/opencode-task-contextualizer/references/task-templates.md +103 -0
- phase_loop_runtime/state.py +156 -0
- phase_loop_runtime/state_degradation.py +136 -0
- phase_loop_runtime/state_ops.py +676 -0
- phase_loop_runtime/train_ledger.py +215 -0
- phase_loop_runtime/train_roadmap.py +339 -0
- phase_loop_runtime/train_runner.py +1197 -0
- phase_loop_runtime/verification_evidence.py +650 -0
- phase_loop_runtime/verification_evidence_validator.py +75 -0
- phase_loop_runtime/visual_evidence_validator.py +36 -0
- phase_loop_runtime/worker_pool.py +123 -0
- phase_loop_runtime/worktree_index.py +270 -0
- phase_loop_runtime-0.2.0.data/data/share/phase-loop-runtime/protocol/protocol.md +2475 -0
- phase_loop_runtime-0.2.0.dist-info/METADATA +106 -0
- phase_loop_runtime-0.2.0.dist-info/RECORD +370 -0
- phase_loop_runtime-0.2.0.dist-info/WHEEL +5 -0
- phase_loop_runtime-0.2.0.dist-info/entry_points.txt +9 -0
- phase_loop_runtime-0.2.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,745 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: claude-execute-phase
|
|
3
|
+
description: "Harness Code executor for a <harness>-plan-phase lane plan. Uses TeamCreate, worktree-isolated teammates, lane DAG ordering, verification gates, and retry-once failure handling."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# <harness>-execute-phase
|
|
7
|
+
|
|
8
|
+
## Runtime State
|
|
9
|
+
|
|
10
|
+
For reflections, handoffs, and latest handoff pointers, follow `<harness>-config/shared/runtime-state.md`. This repo/branch/run-isolated contract supersedes any older flat closeout examples retained for historical context in this skill.
|
|
11
|
+
|
|
12
|
+
`shared/phase-loop/protocol.md` is the canonical shared contract for the
|
|
13
|
+
`automation:` object, `verification_status`, frozen blocker taxonomy,
|
|
14
|
+
manual event import, and downstream roadmap-amendment handling.
|
|
15
|
+
|
|
16
|
+
When launched by the live phase-loop adapter, this skill runs through
|
|
17
|
+
non-interactive `<harness> -p`; its final reply must still emit the shared
|
|
18
|
+
`automation:` closeout or the parent runner will reduce the turn to
|
|
19
|
+
`repeated_verification_failure` rather than silent success. The repo-injected
|
|
20
|
+
workflow bundle remains authoritative whether the adapter delivers it inline or
|
|
21
|
+
through the run-local context-file fallback.
|
|
22
|
+
That repo-owned bundle includes the full Harness workflow pack
|
|
23
|
+
(`<harness>-phase-roadmap-builder`, `<harness>-plan-phase`,
|
|
24
|
+
`<harness>-execute-phase`, and `<harness>-phase-loop`) and does not depend on
|
|
25
|
+
installed bridge skills under `resolve_skill_bundle_root("claude")/`.
|
|
26
|
+
|
|
27
|
+
Harness closeout and blocker reporting must use the shared literals directly,
|
|
28
|
+
including `dirty_worktree_conflict`, and must treat older downstream plans as
|
|
29
|
+
stale after a roadmap amendment.
|
|
30
|
+
|
|
31
|
+
## Runner-Owned Lane Work Units
|
|
32
|
+
|
|
33
|
+
Injected HARNESSLANE runs may include a `HarnessLaneAssignment` from
|
|
34
|
+
`shared/phase-loop/protocol.md`. Treat that assignment as the work-unit
|
|
35
|
+
contract: execute only the selected `lane_id`, write only the listed
|
|
36
|
+
`owned_files`, treat `consumed_interfaces` as read-only, and emit one shared
|
|
37
|
+
`automation:` closeout for that work unit. Installed-skill drift is
|
|
38
|
+
warning-only when the repo-injected context is present.
|
|
39
|
+
|
|
40
|
+
Native Harness subagent and `agent_team` activity stays internal unless it emits
|
|
41
|
+
a typed `DelegationRequest` and the runner approves it. Review, reducer,
|
|
42
|
+
verify, and closeout prompts are distinct from implementation prompts. If the
|
|
43
|
+
selected policy is unsupported by the active harness, stop with a typed
|
|
44
|
+
non-human blocker instead of silently downgrading.
|
|
45
|
+
|
|
46
|
+
## Phase-Loop Adapter Mode
|
|
47
|
+
|
|
48
|
+
When the prompt or run-local context file starts with a concrete
|
|
49
|
+
`<harness>-execute-phase <plan>` command from `.codex/phase-loop/runs/`, this
|
|
50
|
+
adapter mode overrides the orchestrator-only interactive workflow below.
|
|
51
|
+
|
|
52
|
+
- Do not read installed handoffs under `resolve_skill_bundle_root("claude")/**`; the run-local
|
|
53
|
+
context and the plan artifact are the only predecessor context.
|
|
54
|
+
- Do not call `ToolSearch`, `TaskCreate`, `TaskUpdate`, `TaskList`,
|
|
55
|
+
`TeamCreate`, `TeamDelete`, `Agent`, `SendMessage`, `EnterWorktree`,
|
|
56
|
+
`ExitWorktree`, or `AskUserQuestion`.
|
|
57
|
+
- Do not create `.claude/worktrees/` or lane branches. Execute the plan
|
|
58
|
+
directly in the provided workspace, respecting the plan's owned-file
|
|
59
|
+
boundaries and running the narrowest applicable verification commands.
|
|
60
|
+
- Treat ignored, private, raw-data, credential, and evidence-source files as
|
|
61
|
+
read-protected unless the run-local context, phase plan, or source bundle
|
|
62
|
+
explicitly allowlists the exact path or glob for read access. Do not infer
|
|
63
|
+
permission from nearby owned output paths, old memory, or prior phases.
|
|
64
|
+
- Do not read or write `~/.claude/**` reflection or handoff files, and do not
|
|
65
|
+
edit `.codex/phase-loop/` runner artifacts. Adapter-mode closeout happens
|
|
66
|
+
only through stdout plus repo-local artifacts.
|
|
67
|
+
- If a missing script or unavailable helper is nonessential, replace it with a
|
|
68
|
+
direct repo-local check and record the substitution in the closeout. If the
|
|
69
|
+
missing input is essential, stop with a shared blocked `automation:`
|
|
70
|
+
closeout.
|
|
71
|
+
- If ambiguity, access, dirty-state, or merge safety handling would normally
|
|
72
|
+
ask a user, stop and emit a shared `automation:` closeout with
|
|
73
|
+
`status: blocked`, `human_required` set accurately, the frozen
|
|
74
|
+
`blocker_class`, concrete `blocker_summary`, and `verification_status:
|
|
75
|
+
blocked`.
|
|
76
|
+
- End stdout with one shared `automation:` closeout. Do not wait for
|
|
77
|
+
interactive approval after verification is complete.
|
|
78
|
+
- Do not emit a `/clear` recommendation or any human-only context-reset
|
|
79
|
+
instruction. Continuity to the next phase is the run-local handoff plus the
|
|
80
|
+
runner re-invoking the next phase in a fresh executor process — that fresh
|
|
81
|
+
process is the context reset. There is no human in this loop to reset it.
|
|
82
|
+
- Before that closeout, run `git status --short` and classify dirty paths
|
|
83
|
+
against the active plan's owned files and control artifacts. If a generated
|
|
84
|
+
path is unowned, ignored without explicit allowlist/staging policy, or
|
|
85
|
+
derived from unauthorized raw/private inputs, stop with
|
|
86
|
+
`dirty_worktree_conflict` instead of reporting completion. But when required
|
|
87
|
+
verification passed and the ONLY uncommitted paths are phase-owned outputs this
|
|
88
|
+
run was not authorized to commit, report `awaiting_phase_closeout` and let the
|
|
89
|
+
runner's graduated closeout gate commit them — reserve `dirty_worktree_conflict`
|
|
90
|
+
for unowned, unauthorized-ignored, or overlapping-unrelated paths.
|
|
91
|
+
|
|
92
|
+
Follow-on executor for `/<harness>-plan-phase`. Consumes the plan doc + TaskCreate'd lane tasks and drives them to completion: root lanes first, parallel lanes in parallel, auto-merge on green, retry-once on failure, halt-all on second failure.
|
|
93
|
+
|
|
94
|
+
## When to use
|
|
95
|
+
|
|
96
|
+
- `/<harness>-plan-phase` has produced `plans/phase-plan-<VERSION>-<PHASE_ALIAS>.md` and a `TaskCreate`'d task per lane.
|
|
97
|
+
- You want the phase executed **full-auto** end-to-end, with lanes merging to the current branch as their gates go green.
|
|
98
|
+
- The working tree is clean and you're on the branch lanes should merge into.
|
|
99
|
+
|
|
100
|
+
## When NOT to use
|
|
101
|
+
|
|
102
|
+
- Plan doc has never been produced → run `/<harness>-plan-phase` first.
|
|
103
|
+
- You want human checkpoints between lanes → execute lanes manually (`Agent(isolation: "worktree", name: "<SL-ID>")` with the lane's section pasted in).
|
|
104
|
+
- The plan doc's DAG has cycles or a lane's owned files overlap another lane's → fix the plan first.
|
|
105
|
+
|
|
106
|
+
## Model tiers (edit on Anthropic releases)
|
|
107
|
+
|
|
108
|
+
Model IDs appear only in this table. All model-routing logic in the workflow references the tier name.
|
|
109
|
+
|
|
110
|
+
| Tier | Model | Use for |
|
|
111
|
+
|-----------|--------------------|---------------------------------------------------------------|
|
|
112
|
+
| frontier | claude-opus-4-8 | retry escalation ceiling, highest-stakes lanes |
|
|
113
|
+
| strong | claude-sonnet-5 | contract-authoring (IF-freeze), schema/migration, algorithmic |
|
|
114
|
+
| fast | claude-haiku-4-5 | mechanical wiring, small components against frozen types |
|
|
115
|
+
|
|
116
|
+
These map to the runtime `model_class` axis: planner = frontier, implementer =
|
|
117
|
+
strong, worker = fast. The shipped `model_policy` dispatches **implementation at
|
|
118
|
+
the implementer class**; on repeated failure the escalation ladder steps the
|
|
119
|
+
class up (implementer → planner) before, in **governed** `run_mode` only,
|
|
120
|
+
invoking the advisor panel. The default `run_mode` is `autonomous` — no panel,
|
|
121
|
+
no `human_required`; every governed escalation terminal is a non-human
|
|
122
|
+
`review_gate_block` surfaced in the run-end summary, never a synchronous human
|
|
123
|
+
wait.
|
|
124
|
+
|
|
125
|
+
Governed mode is **live on the serial path** (`--governed` / `PHASE_LOOP_RUN_MODE=governed`,
|
|
126
|
+
model-routing-v2): a pre-merge panel gate (codex + gemini) reviews the
|
|
127
|
+
implementation diff *before* the closeout commit and runs a bounded
|
|
128
|
+
review→fix→re-review loop; a `block` finding holds the merge until fixed or the
|
|
129
|
+
bounded loop terminates non-human. Autonomous runs spawn no panel. Concurrent-wave
|
|
130
|
+
dispatch is not governed yet.
|
|
131
|
+
|
|
132
|
+
## Inputs
|
|
133
|
+
|
|
134
|
+
| Arg | Required | Meaning |
|
|
135
|
+
|---|---|---|
|
|
136
|
+
| `<plan-path>` | no | Path to plan doc. Default: auto-detected via env vars + filename convention. |
|
|
137
|
+
| `--dry-run` | no | Parse + validate, print the dispatch schedule with per-lane model assignments, do not spawn teammates. |
|
|
138
|
+
| `--resume` | no | Continue a partially executed plan: skip lanes already merged (their merge commit is on the target branch and their produced gates are closed). |
|
|
139
|
+
|
|
140
|
+
## Environment variables
|
|
141
|
+
|
|
142
|
+
Plan-location variables are inherited from `<harness>-plan-phase` so the two skills resolve the same defaults:
|
|
143
|
+
|
|
144
|
+
| Variable | Default | Meaning |
|
|
145
|
+
|---|---|---|
|
|
146
|
+
| `PLAN_SPEC` | Auto-detected highest `specs/phase-plans-v*.md` | Path to spec file (used only for version extraction here). |
|
|
147
|
+
| `PLAN_VERSION` | Extracted `v\d+` from spec filename | Version token embedded in plan-doc filename. |
|
|
148
|
+
| `PLAN_PHASE_ALIASES` | Built-in alias table | Path to alias-map JSON. |
|
|
149
|
+
| `PLAN_DOC` | `plans/phase-plan-<VERSION>-<PHASE_ALIAS>.md` | Override the resolved plan-doc path directly. |
|
|
150
|
+
| `EXECUTE_MERGE_TARGET` | Current branch at invocation | Branch lanes merge into. |
|
|
151
|
+
| `EXECUTE_WORKTREE_ROOT` | `.worktrees/` (inside repo; auto-gitignored) | Root dir for per-lane worktrees. |
|
|
152
|
+
| `EXECUTE_MAX_PARALLEL_LANES` | `4` | Max concurrent lane dispatches per wave; parallelism-maximizing default. Lower to `2` when stale-base churn becomes problematic on phases with many interdependent lanes. |
|
|
153
|
+
|
|
154
|
+
## Expected helpers
|
|
155
|
+
|
|
156
|
+
Helpers under `resolve_skill_bundle_root("claude")/_shared/` may be absent on some hosts. Each helper degrades as listed:
|
|
157
|
+
|
|
158
|
+
- `_shared/next_reflection_path.py` — legacy helper only; current closeout writes reflections to `resolve_skill_bundle_root("codex")/<harness>-execute-phase/reflections/<repo_hash>/<branch_slug>/<run_id>.md`.
|
|
159
|
+
- `_shared/review_with_cli.py` — used only with `--review-external`; no fallback (required for that flag).
|
|
160
|
+
|
|
161
|
+
## Deferred tool preloading
|
|
162
|
+
|
|
163
|
+
Several tools this skill uses are deferred and must be registered via `ToolSearch` before first call. Load them in a single query at the top of Step 1 so mid-workflow calls (especially `TaskUpdate` on every dispatch and `AskUserQuestion` on preflight failures) don't pay a round-trip:
|
|
164
|
+
|
|
165
|
+
```
|
|
166
|
+
ToolSearch(query: "select:TaskCreate,TaskUpdate,TaskList,TeamCreate,AskUserQuestion")
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
## Workflow (orchestrator-only main thread)
|
|
170
|
+
|
|
171
|
+
The main thread reads exactly two things: the plan doc and the TaskList. It does not Grep/Read repo source — lane teammates own their files. If the main thread is reaching for Grep or Read on source files, the teammate brief was incomplete; re-brief via `SendMessage`.
|
|
172
|
+
|
|
173
|
+
### Step 0 — Read predecessor handoff (if present)
|
|
174
|
+
|
|
175
|
+
Handoffs are keyed on the current repo so each workspace has its own slot. Resolve the predecessor path first:
|
|
176
|
+
|
|
177
|
+
```bash
|
|
178
|
+
REPO_ROOT=$(git rev-parse --show-toplevel 2>/dev/null)
|
|
179
|
+
if [ -z "$REPO_ROOT" ]; then
|
|
180
|
+
REPO_KEY="_no-git-$(pwd | sha1sum | cut -c1-12)"
|
|
181
|
+
else
|
|
182
|
+
REPO_KEY="$(basename "$REPO_ROOT")-$(printf '%s' "$REPO_ROOT" | sha1sum | cut -c1-12)"
|
|
183
|
+
fi
|
|
184
|
+
PREDECESSOR_HANDOFF="$(python3 - <<'PYH'
|
|
185
|
+
from importlib import util
|
|
186
|
+
from pathlib import Path
|
|
187
|
+
repo = Path.cwd().resolve()
|
|
188
|
+
spec = util.spec_from_file_location("handoff_path", repo / "shared" / "phase-loop" / "handoff_path.py")
|
|
189
|
+
mod = util.module_from_spec(spec)
|
|
190
|
+
spec.loader.exec_module(mod)
|
|
191
|
+
print(mod.resolve_handoff_path(repo, "<harness>-plan-phase"))
|
|
192
|
+
PYH
|
|
193
|
+
)"
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
If `$PREDECESSOR_HANDOFF` exists, `Read` it in full — `<harness>-plan-phase` just produced the lane plan and may have flagged gotchas the dispatch loop needs to know about.
|
|
197
|
+
|
|
198
|
+
Defense-in-depth checks (the repo-key scheme prevents the common cross-project case, but these still catch symlink-shared workspaces, manual file copies, and stale handoffs):
|
|
199
|
+
|
|
200
|
+
- `from:` must be `<harness>-plan-phase`.
|
|
201
|
+
- Timestamp must be <7 days.
|
|
202
|
+
- Every `artifact:` path must resolve under `$(git rev-parse --show-toplevel)`.
|
|
203
|
+
|
|
204
|
+
On any failure, flag via `AskUserQuestion` with `[use anyway, ignore, abort]`.
|
|
205
|
+
|
|
206
|
+
Fold the handoff's "Open items" and "Repo-specific gotchas" into each lane teammate's brief (Step 5's Teammate brief contents) so they carry the same context without the user having to reinject it.
|
|
207
|
+
|
|
208
|
+
If absent, proceed standalone — the plan doc is authoritative either way.
|
|
209
|
+
|
|
210
|
+
### Step 1 — Resolve + parse plan doc
|
|
211
|
+
|
|
212
|
+
Resolve in order: `$PLAN_DOC` → `<plan-path>` arg → default path built from `$PLAN_VERSION` + phase alias argument.
|
|
213
|
+
|
|
214
|
+
`Read` the plan doc. Parse these sections (headings are stable IDs from `<harness>-plan-phase`):
|
|
215
|
+
|
|
216
|
+
- `## Interface Freeze Gates` — list of `IF-0-<PHASE>-<N>` items with descriptions.
|
|
217
|
+
- `## Cross-Repo Gates` (optional) — `IF-XR-<N>`.
|
|
218
|
+
- `## Lane Index & Dependencies` — machine-readable DAG block (`SL-N`, `Depends on:`, `Blocks:`, `Parallel-safe:`).
|
|
219
|
+
- `## Lanes` — per-lane: `Scope`, `Owned files`, `Interfaces provided`, `Interfaces consumed`, task table.
|
|
220
|
+
- `## Verification` — final end-to-end commands.
|
|
221
|
+
|
|
222
|
+
Build the lane graph. Topologically sort it; reject on cycle with a clear error.
|
|
223
|
+
|
|
224
|
+
### Step 2 — Preflight
|
|
225
|
+
|
|
226
|
+
- **Run `scripts/verify_harness.sh <merge-target>`.** Enforces the hard gates: git + git-worktree available, inside a work tree, merge-target branch exists locally, working tree clean (allowlist: `.claude/worktrees/`, `.claude/<harness>-execute-phase-state.json`), `.gitignore` covers worktree paths. **Non-zero exit blocks dispatch.** On dirty-tree failure, invoke `AskUserQuestion` with `[commit the changes as a chore, stash for the duration of the phase, abort /<harness>-execute-phase]` and take the user's answer. No override.
|
|
227
|
+
- Record merge target = current branch (or `$EXECUTE_MERGE_TARGET`).
|
|
228
|
+
- **Merge-target safety gate (before any lane dispatch or merge).** If the resolved merge
|
|
229
|
+
target is `main` or a protected branch, STOP — do not dispatch lanes or run any
|
|
230
|
+
`git merge` onto it. Interactive: check out / create a dedicated feature branch first and
|
|
231
|
+
re-resolve the merge target; runner/adapter: the runner resolves a runner-managed branch.
|
|
232
|
+
This gate precedes Step 7's auto-merge, which would otherwise mutate `main` directly.
|
|
233
|
+
- Sanity check: every symbol appearing in any lane's `Interfaces consumed` must either be produced by an upstream lane's `Interfaces provided` OR be pre-existing (skip unknown symbols with a warning, don't hard-fail).
|
|
234
|
+
- Producer-dependency check: if a lane consumes another lane's findings, interfaces, or artifacts, that producer lane must appear in `Depends on`. If a lane writes a synthesized artifact, it must be downstream of every producer lane it summarizes. Missing dependencies block execution until the plan is corrected.
|
|
235
|
+
- If `--dry-run`: print the topological schedule with per-lane model/thinking assignments (see Step 3) and stop here.
|
|
236
|
+
|
|
237
|
+
### Step 2.5 — Baseline-capture
|
|
238
|
+
|
|
239
|
+
Run the plan's full regression command once at phase start against the pre-phase tip. Cache the failing-test list to `.claude/<harness>-execute-phase-state.json#baseline_fails`. Step 9 diffs against this cached list rather than reconstructing it.
|
|
240
|
+
|
|
241
|
+
Before hypothesizing test pollution on a post-merge failure, run the failing test in isolation (fresh process) to distinguish a direct regression from fixture pollution.
|
|
242
|
+
|
|
243
|
+
### Step 2a — Worktree hygiene preflight
|
|
244
|
+
|
|
245
|
+
Prune stale worktrees in `.claude/worktrees/` at phase start. Skip on `--resume`.
|
|
246
|
+
|
|
247
|
+
```bash
|
|
248
|
+
bash "$(git rev-parse --show-toplevel)/.claude/skills/<harness>-execute-phase/scripts/sweep_stale_worktrees.sh"
|
|
249
|
+
# Pass --dry-run to preview decisions without removing anything.
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
For each worktree marked `PRUNE`:
|
|
253
|
+
|
|
254
|
+
1. `git worktree unlock <path>` (succeeds silently if unlocked).
|
|
255
|
+
2. `git worktree remove -f -f <path>` — double-force bypasses both the lock and the unmerged-changes check (safe since the ancestor check already confirmed incorporation).
|
|
256
|
+
3. `git branch -D <branch>` **only** if the branch name matches an auto-named pattern (`worktree-*`, `phase/*/sl-*`). Leave human-named branches (`skills/*`, `feature/*`, `fix/*`) intact even when their work is on the merge target — the user may still want the reference.
|
|
257
|
+
|
|
258
|
+
Worktrees marked `KEEP` are left alone; log a one-line warning per worktree.
|
|
259
|
+
|
|
260
|
+
### Step 3 — Assign model + thinking per lane
|
|
261
|
+
|
|
262
|
+
Each lane gets a model and thinking level matched to its complexity. The assignment is encoded on the `Agent` call via `model:` and communicated as guidance in the brief.
|
|
263
|
+
|
|
264
|
+
Apply in order, first match wins:
|
|
265
|
+
|
|
266
|
+
1. Lane has `Execution hint: <tier>/<thinking>` inside its `### SL-N` section → use it verbatim.
|
|
267
|
+
2. Lane publishes any `IF-0-*` gate (contract-authoring) → `strong` / high. Downstream lanes depend on the symbols being correct.
|
|
268
|
+
3. Lane scope mentions migrations, schema, or SQL → `strong` / high. Bad migrations are expensive to unwind.
|
|
269
|
+
4. Lane scope mentions algorithmic/computed logic AND has tests as first task → `strong` / medium.
|
|
270
|
+
5. Lane owns >10 files AND publishes no interfaces (wiring / mechanical refactor) → `fast` / low.
|
|
271
|
+
6. Lane implements small components against already-frozen types → `fast` / low.
|
|
272
|
+
7. Default fallback → `strong` / medium.
|
|
273
|
+
|
|
274
|
+
Resolve tier → model from the Model tiers table at the top of this skill and pass the concrete model ID to `Agent(model: …)`.
|
|
275
|
+
|
|
276
|
+
**Retry escalation** (after a lane's first failure):
|
|
277
|
+
|
|
278
|
+
- `fast` → `strong`
|
|
279
|
+
- `strong` → `frontier`
|
|
280
|
+
- `frontier` → stay at `frontier`
|
|
281
|
+
- Thinking level bumps up one tier (`low → medium → high`).
|
|
282
|
+
|
|
283
|
+
`Agent` does not expose a direct thinking-level parameter — convey it in the brief's framing (e.g., "Think carefully before editing shared type definitions" vs "These are mechanical edits; move quickly").
|
|
284
|
+
|
|
285
|
+
### Step 4 — TeamCreate
|
|
286
|
+
|
|
287
|
+
**Preflight (before any `Agent` or `TeamCreate` call).** Flush inherited team context from a predecessor skill run via `TeamList` (or a defensive `TeamDelete`). On the error signature `"already leading team X"`, `TeamDelete` the stale team and retry with a repo-scoped suffix — e.g., the short hash of `$(git rev-parse --show-toplevel)` — to prevent cross-project team-name collisions. Same-aliased phases from different repos collide on the global team namespace without a suffix. Error signature `"Team X does not exist"` on `TeamDelete` is a no-op; proceed.
|
|
288
|
+
|
|
289
|
+
Create one team for the phase:
|
|
290
|
+
|
|
291
|
+
- **Team name**: `phase-<PHASE_ALIAS>` (e.g., `phase-p1`), with repo-scoped suffix appended when collision is detected.
|
|
292
|
+
- **Teammates**: one per lane, `subagent_type: "general-purpose"`. Teammate names use the allocator — see Step 5.
|
|
293
|
+
|
|
294
|
+
TeamCreate registration enables `SendMessage` retry rounds without fresh Agent spawns.
|
|
295
|
+
|
|
296
|
+
### Step 5 — Dispatch loop
|
|
297
|
+
|
|
298
|
+
State per lane: `pending | running | verify-ok | merged | failed`. State per gate: `open | closed`.
|
|
299
|
+
|
|
300
|
+
Repeat until all lanes are `merged` or halt is triggered:
|
|
301
|
+
|
|
302
|
+
1. **Find ready lanes** — `pending` lanes whose upstream lanes are all `merged` AND all consumed `IF-0-*` gates are `closed`. Synthesized artifact writer lanes are ready only after every producer lane named in `Interfaces consumed` is merged. Cap the dispatch batch at `EXECUTE_MAX_PARALLEL_LANES` (default 4). Slice the eligible set to the first N (lower SL-ID first) and queue the rest.
|
|
303
|
+
|
|
304
|
+
2. **Allocate worktree names**. For each ready lane, run `scripts/allocate_worktree_name.sh <sl-id>`. Substitute the emitted name (e.g., `lane-sl-1-20260418T144536-nxz5`) into both `Agent(name=…)` and the briefed `EnterWorktree(name=…)`. Bare `lane-<sl-id>` names collide under rapid dispatch.
|
|
305
|
+
|
|
306
|
+
3. **Dispatch in parallel** — single message with one `Agent(team_name: "phase-<alias>", name: "<allocated-name>", subagent_type: "general-purpose", model: "<assigned>")` call per ready lane. Sequential dispatch within a wave is a bug. Do NOT pass `isolation: "worktree"` when `team_name` is set — the harness drops `isolation` in that combination. Use `team_name` for coordination + teammate-called `EnterWorktree` for filesystem isolation.
|
|
307
|
+
|
|
308
|
+
4. **Teammate brief** contains:
|
|
309
|
+
- **Worktree isolation (mandatory, first tool call)**: Load `EnterWorktree` via `ToolSearch(query="select:EnterWorktree,ExitWorktree")` if not already in the tool registry. Call `ExitWorktree(action="keep")` FIRST (no-op if no session active; clears any stale session-state flag inherited from a prior teammate). Then call `EnterWorktree(name: "<allocated-name>")` as the very next tool call, BEFORE any file operation. Every subsequent edit/commit goes into that worktree. At the end, call `ExitWorktree(action: "keep")` so the worktree and branch remain available for the orchestrator to merge.
|
|
310
|
+
- The full `### SL-N` section copied verbatim from the plan doc.
|
|
311
|
+
- **Architecture context** (1–2 sentences): how this lane fits the phase; how this phase fits the roadmap.
|
|
312
|
+
- **Related files** the lane reads but does not own: type defs, test fixtures, shared config. Distinct from `Owned files`.
|
|
313
|
+
- Concrete upstream artifact paths (populated from now-merged upstream lanes) for every entry in `Interfaces consumed`.
|
|
314
|
+
- The merge target branch and the orchestrator's current tip SHA, injected as `<TIP_SHA>` (used by the stale-base check below).
|
|
315
|
+
- The lane's test → impl → verify task list. The lane's verify command must include regression files listed in the plan's `## Verification` section that reference this lane's owned files, not only the lane's new tests. Each lane must enumerate tests that mock or stub any existing public function the lane's scope adds a call to, and include those tests in verify.
|
|
316
|
+
- Thinking-level guidance matching the lane's profile.
|
|
317
|
+
- **Stale-base discipline**: AFTER `EnterWorktree` returns and BEFORE any code change, run `git rebase main` (or `git merge main --no-ff -m "merge: incorporate prior-lane foundation"`). Verify with `git merge-base --is-ancestor <TIP_SHA> HEAD && echo OK || echo STALE`. Repeat the rebase immediately before your final commit. On conflicts, STOP and report — do not resolve silently. Never `git reset --hard` or `git checkout HEAD~N -- …` in a stale worktree; this destroys peer-lane work on `--no-ff` merge.
|
|
318
|
+
- **Staging discipline**: Forbid `git add -A` and `git add .`. Stage with explicit pathspecs drawn from the lane's `Owned files`.
|
|
319
|
+
- **No self-merge**: DO NOT run `git merge` or `git push` against the merge-target branch yourself; the orchestrator owns merges.
|
|
320
|
+
- **Structured-reply instruction**: "When done, reply with JSON `{lane, verify_exit_code, failed_tasks, pre_existing_failures, tsc_error_delta, notes, commit_sha, branch, worktree_path}`. `failed_tasks` lists failures attributable to this lane; `pre_existing_failures` lists failures reproducible on the base SHA (capture the base-SHA reproduction command as evidence). When the lane's verify chain runs whole-repo type-checking, populate `tsc_error_delta` (errors-after minus errors-before); accept `tsc_error_delta <= 0` as a pass even if raw exit code is non-zero. `branch` and `worktree_path` come from `EnterWorktree`'s return value."
|
|
321
|
+
|
|
322
|
+
Apply the `/<harness>-task-contextualizer` checklist to every brief.
|
|
323
|
+
|
|
324
|
+
5. **Await completions**. For each:
|
|
325
|
+
- `verify_exit_code == 0` → run gate verification (Step 6). On green → auto-merge (Step 7). Mark lane `merged`, flip produced gates to `closed`, update the lane's `TaskCreate`'d task to `completed`.
|
|
326
|
+
- Non-zero or gate failure → retry-once (Step 8).
|
|
327
|
+
- **Idle without JSON reply** → handle per the decision table below. After one `SendMessage` retry with no response in a reasonable interval, escalate directly to SHA-discovery rather than continuing to ping.
|
|
328
|
+
|
|
329
|
+
| Case | Condition | Action |
|
|
330
|
+
|---|---|---|
|
|
331
|
+
| (a) | Idle + no commits | `SendMessage` one nudge requesting commit + envelope. |
|
|
332
|
+
| (b) | Idle + commit on identifiable lane branch | Treat the commit as the result; run Step 6.5 / Step 7 audits; proceed on `CLEAN`. |
|
|
333
|
+
| (c) | Idle + multiple candidate commits | One more `SendMessage`; if no response, halt for user. |
|
|
334
|
+
| (d) | Idle + commits landed on merge-target directly | Route to `PARENT_ON_MERGE_TARGET` verdict (Step 6.5). |
|
|
335
|
+
|
|
336
|
+
6. Persist lane + gate state to `.claude/<harness>-execute-phase-state.json` after every transition (enables `--resume`).
|
|
337
|
+
|
|
338
|
+
### Step 6 — Gate verification
|
|
339
|
+
|
|
340
|
+
For each gate the lane provides:
|
|
341
|
+
|
|
342
|
+
1. If the plan doc's `## Verification` section has a command that names this gate's artifact (e.g., `psql` for schema gates, `grep` for symbol gates), run it against the lane's worktree.
|
|
343
|
+
2. Else fall back:
|
|
344
|
+
- Files listed under `Owned files` exist.
|
|
345
|
+
- Symbols listed under `Interfaces provided` are grep-visible at expected paths.
|
|
346
|
+
- Lane's own verify command exited 0.
|
|
347
|
+
|
|
348
|
+
Any failure here counts as a lane failure and triggers retry-once.
|
|
349
|
+
|
|
350
|
+
### Step 6.5 — Parent-tree leakage check
|
|
351
|
+
|
|
352
|
+
Detects two isolation failure modes before merge: (a) teammate writes landing in the parent checkout, (b) `EnterWorktree` falling back to in-place branch creation on the parent.
|
|
353
|
+
|
|
354
|
+
Run:
|
|
355
|
+
```bash
|
|
356
|
+
bash scripts/parent_tree_leakage_check.sh <lane-id> <owned-globs-file> <merge-target>
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
Verdicts (emitted on stdout; details on stderr):
|
|
360
|
+
|
|
361
|
+
- **`CLEAN`** — proceed to Step 7.
|
|
362
|
+
- **`LEAKAGE_DETECTED`** (dirty files overlap the lane's owned globs):
|
|
363
|
+
1. Verify byte-equality: for each leaked path, `git diff <lane-sha> -- <path>` must be zero lines (confirms the leak is a redundant copy of committed lane work). If non-zero, treat as independent uncommitted work and STOP.
|
|
364
|
+
2. Clean the parent: `git checkout -- <modified>` for tracked changes; `rm <untracked>` for new files. Do NOT `git stash`.
|
|
365
|
+
3. Record in `.claude/<harness>-execute-phase-state.json` under the lane's `notes`.
|
|
366
|
+
4. Proceed to Step 7.
|
|
367
|
+
- **`UNRELATED_DIRTY_TREE`** (dirty files outside the lane's globs) → STOP. Ask via `AskUserQuestion` whether to stash, commit, or abort.
|
|
368
|
+
- **`PARENT_ON_WRONG_BRANCH`** (tree clean but parent on a non-merge-target branch — `EnterWorktree` fell back to in-place branch creation):
|
|
369
|
+
1. Merge by SHA per Step 7.
|
|
370
|
+
2. Run `git checkout <merge-target>` in the parent BEFORE Step 7's worktree cleanup — otherwise `git worktree remove` refuses.
|
|
371
|
+
3. Record parent-fallback note in state.
|
|
372
|
+
- **`PARENT_ON_MERGE_TARGET`** (alias `LANE_BYPASSED_ISOLATION`) — resolve the reply envelope's `commit_sha`; if `git merge-base --is-ancestor <sha> <merge-target>` is already true before any merge step, the commit landed directly on the target via an `EnterWorktree` fallback:
|
|
373
|
+
1. Skip the merge (already merged).
|
|
374
|
+
2. Clean up the worktree and branch per Step 7's post-merge cleanup.
|
|
375
|
+
3. Record the fallback in `.claude/<harness>-execute-phase-state.json` and note it in the close-out.
|
|
376
|
+
|
|
377
|
+
### Step 7 — Auto-merge
|
|
378
|
+
|
|
379
|
+
**Branch discovery.** Resolve the lane's branch/worktree from the reply envelope's `commit_sha` via `git log --oneline -1 <commit_sha>` + `git worktree list`. Never trust the briefed branch name.
|
|
380
|
+
|
|
381
|
+
**Cross-lane file-touch audit.** Before the destructiveness check, run:
|
|
382
|
+
|
|
383
|
+
```bash
|
|
384
|
+
python scripts/audit_lane_file_touches.py <lane-sha> <plan-doc-path> <this-lane-id>
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
**Parser contract.** After matching the `**Owned files**:` heading, the parser walks subsequent deeper-indented bullets until the next sibling bullet or blank line and accumulates backticked tokens. Both inline form (`- **Owned files**: \`path/one\`, \`path/two\``) and nested-bullet form (heading followed by ` - \`path/one\``) are supported. A unit test covering both formats ships alongside the script.
|
|
388
|
+
|
|
389
|
+
Verdicts:
|
|
390
|
+
|
|
391
|
+
- **`CLEAN`** → every touched file is within this lane's `Owned files` globs. Proceed.
|
|
392
|
+
- **`PEER_INTRUSION`** → the lane touched files owned by another lane. Stderr lists peer + files. Pause on `AskUserQuestion`: merge anyway, bounce the lane, or ask the teammate to revert the peer edits.
|
|
393
|
+
- **`ORPHAN_FILES`** → the lane touched files outside every lane's globs. Surface to user — likely plan or impl bug.
|
|
394
|
+
|
|
395
|
+
**Pre-merge destructiveness check** — lanes that committed against a stale base can wipe peer-lane work on `--no-ff` merge. Use the three-outcome script:
|
|
396
|
+
|
|
397
|
+
```bash
|
|
398
|
+
bash scripts/pre_merge_destructiveness_check.sh <lane-sha> <merge-target> <whitelist-path>
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
Where `<whitelist-path>` is a file (one path per line) of deletions the lane legitimately performs per its plan section; `/dev/null` if the lane is purely additive.
|
|
402
|
+
|
|
403
|
+
The script (or a sibling) also runs an ADDITION-side check mirroring the deletion check: flag commits that ADD more than N files (default ~50) or more than M lines outside the lane's owned globs. Out-of-scope adds surface as a verdict alongside deletions to catch lanes that wandered.
|
|
404
|
+
|
|
405
|
+
Verdicts:
|
|
406
|
+
|
|
407
|
+
- **`SAFE`** — deletion list empty or all whitelisted. Merge with `git merge --no-ff <lane-sha>`.
|
|
408
|
+
- **`STALE_BASE_DETECTED`** — lane branched from a pre-peer-merge main but did not actively delete. Preview, then finalize with the 3-way merge:
|
|
409
|
+
```bash
|
|
410
|
+
git merge --no-ff --no-commit <lane-sha>
|
|
411
|
+
ls <peer-lane-owned-paths> # must exist
|
|
412
|
+
git commit --no-edit
|
|
413
|
+
```
|
|
414
|
+
Do NOT salvage — salvage loses commit lineage.
|
|
415
|
+
- **`CONFLICT`** — lane actively removed files. DO NOT `--no-ff` merge. Salvage:
|
|
416
|
+
```bash
|
|
417
|
+
git checkout <lane-sha> -- <lane's owned paths from the plan doc>
|
|
418
|
+
git commit -m "feat(<phase>,<sl-id>): <subject>
|
|
419
|
+
|
|
420
|
+
Salvage of <SL-ID> lane work: lane commit was based on stale main and
|
|
421
|
+
would have deleted <peer lanes' files>. Cherry-picked in-scope additions only."
|
|
422
|
+
```
|
|
423
|
+
Count this as a successful completion — no retry.
|
|
424
|
+
|
|
425
|
+
**Merge conflict** (non-destructive case) → treat as lane failure: `git merge --abort`, surface the conflict to the teammate via `SendMessage` asking it to rebase inside its worktree, then retry the merge.
|
|
426
|
+
|
|
427
|
+
**Post-merge import smoke** — run immediately after `git merge --no-ff` and before dispatching the next wave:
|
|
428
|
+
|
|
429
|
+
```bash
|
|
430
|
+
packages="$(git diff --name-only HEAD~..HEAD \
|
|
431
|
+
| grep '__init__\.py$' \
|
|
432
|
+
| sed 's|/__init__\.py$||; s|/|.|g' \
|
|
433
|
+
| sort -u)"
|
|
434
|
+
if [[ -n "$packages" ]]; then
|
|
435
|
+
bash scripts/post_merge_import_smoke.sh $packages
|
|
436
|
+
fi
|
|
437
|
+
```
|
|
438
|
+
|
|
439
|
+
On non-zero exit, the merge broke package load. Unwind with `git reset --hard HEAD~`, then retry per Step 8. Second failure halts the phase.
|
|
440
|
+
|
|
441
|
+
**Post-merge cleanup.** First, `cd "$(git rev-parse --show-toplevel)"` so subsequent Bash calls survive. Then `git worktree remove --force` any worktrees the lane used. `git branch -D` (not `-d`) every lane branch — salvaged work leaves branches unreachable from the merge target. If Step 6.5 returned `PARENT_ON_WRONG_BRANCH`, `git checkout <merge-target>` in the parent BEFORE removing worktrees.
|
|
442
|
+
|
|
443
|
+
### Step 8 — Retry-once, then halt
|
|
444
|
+
|
|
445
|
+
On first failure for a lane, decide between SendMessage-resume and kill-and-respawn based on whether the lane committed anything:
|
|
446
|
+
|
|
447
|
+
- **`commit_sha` empty AND `verify_exit_code != 0`** (teammate STOPped during preflight, no work done): kill via `TaskStop` and re-`Agent`-spawn fresh. Never resume a STOPped teammate with no commits — the worktree may be reaped and the resumed instance writes into the parent.
|
|
448
|
+
- **`commit_sha` populated AND verify failed** (teammate did work but it broke): re-address the same named teammate via `SendMessage` to preserve branch-state context.
|
|
449
|
+
|
|
450
|
+
In either case, the brief includes: the failure log, the escalated model+thinking hint, and the instruction to fix the failing task and re-run verify.
|
|
451
|
+
|
|
452
|
+
On second failure:
|
|
453
|
+
|
|
454
|
+
- Cancel all still-running lane Agents via their task IDs.
|
|
455
|
+
- Emit a diagnostic report naming the failing lane, the failing task, the last ~30 log lines, and which lanes were merged vs pending.
|
|
456
|
+
- Persist state to `.claude/<harness>-execute-phase-state.json` and exit cleanly. User can fix and re-run with `--resume`.
|
|
457
|
+
|
|
458
|
+
### Step 9 — Final verification, cleanup, and summary
|
|
459
|
+
|
|
460
|
+
After all lanes merged:
|
|
461
|
+
|
|
462
|
+
1. Run every command under the plan doc's `## Verification` section against the merged tree.
|
|
463
|
+
2. Run every assertion under `## Acceptance Criteria` that can be mechanically checked.
|
|
464
|
+
3. **Team teardown**. Try `TeamDelete` first. If it blocks (in-process teammates ignore `shutdown_request`), fall back to filesystem cleanup: `bash scripts/team_teardown.sh phase-<alias>` (rm on `the Harness home directory/teams/<team>/` + `the Harness home directory/tasks/<team>/`).
|
|
465
|
+
4. **Kill leftover background processes**. Run `ps aux | grep -E "next dev|node.*dev"` and `kill` any stragglers spawned by lane teammates.
|
|
466
|
+
5. **Clean-tree verification**. Run `git status`. After successful completion the tree must be clean (lane merges are the only changes, and they're committed). Allowlist: `.claude/worktrees/`, `.claude/<harness>-execute-phase-state.json`. Anything else → stop and surface.
|
|
467
|
+
6. Emit final summary:
|
|
468
|
+
- Lanes merged (with merge-commit SHAs)
|
|
469
|
+
- Gates closed
|
|
470
|
+
- Final verification pass/fail
|
|
471
|
+
- Total wall-clock duration
|
|
472
|
+
- Per-lane breakdown: model used, duration, token spend, retry count
|
|
473
|
+
7. Mark the phase's parent TaskCreate (if one exists) as completed.
|
|
474
|
+
|
|
475
|
+
**Halt exception**: on Step 8 second-failure halt, `.claude/<harness>-execute-phase-state.json` persists for `--resume`. This is the documented dirty-tree exception; no commit required.
|
|
476
|
+
|
|
477
|
+
### Step 9.5 — Close-out: Reflection + Handoff
|
|
478
|
+
|
|
479
|
+
Before close-out, run `git status --short -- <plan_path> <roadmap_path>` for every consumed or updated planning artifact. If any planning artifact is untracked or modified and the user did not explicitly forbid staging, run `git add <path>` for each artifact. Rerun status and report `Artifact state: staged|tracked|modified|unstaged|blocked` for each artifact. Do not commit unless the user explicitly asked for a commit. Repo-local handoff files are operational state: do not `git add` an ignored handoff alongside the plan artifact unless the plan's owned-files/allowlist explicitly includes the handoff directory; leave ignored handoffs ignored and exclude them from artifact-state reporting.
|
|
480
|
+
|
|
481
|
+
Determine the next step before final response and handoff:
|
|
482
|
+
|
|
483
|
+
- If the current phase is incomplete or verification failed, set `Next phase: <current alias> - blocked: <blocker>` and `Next command: none - <blocker>`.
|
|
484
|
+
- If another generated phase plan is ready, set `Next phase: <next alias> - execution ready` and `Next command: /<harness>-execute-phase <next-alias>`.
|
|
485
|
+
- If the roadmap has an unplanned ready phase, set `Next phase: <next alias> - planning ready` and `Next command: /<harness>-plan-phase <next-alias>`.
|
|
486
|
+
- If the roadmap needs extension, set `Next phase: none - roadmap extension needed` and `Next command: /<harness>-phase-roadmap-builder`.
|
|
487
|
+
- If all phases are complete, set `Next phase: none - roadmap complete` and `Next command: none - roadmap complete`.
|
|
488
|
+
|
|
489
|
+
Resolve paths, with an inline fallback for the reflection helper:
|
|
490
|
+
|
|
491
|
+
```bash
|
|
492
|
+
REFLECTION_PATH=resolve_skill_bundle_root("codex")/<harness>-execute-phase/reflections/<repo_hash>/<branch_slug>/<run_id>.md
|
|
493
|
+
REPO_ROOT=$(git rev-parse --show-toplevel 2>/dev/null || pwd)
|
|
494
|
+
REPO_LOCAL_HANDOFF=$(python3 - <<'PYH'
|
|
495
|
+
from importlib import util
|
|
496
|
+
from pathlib import Path
|
|
497
|
+
repo = Path.cwd().resolve()
|
|
498
|
+
spec = util.spec_from_file_location("handoff_path", repo / "shared" / "phase-loop" / "handoff_path.py")
|
|
499
|
+
mod = util.module_from_spec(spec)
|
|
500
|
+
spec.loader.exec_module(mod)
|
|
501
|
+
print(mod.resolve_handoff_path(repo, "<harness>-execute-phase"))
|
|
502
|
+
PYH
|
|
503
|
+
)
|
|
504
|
+
mkdir -p "$(dirname "$REPO_LOCAL_HANDOFF")"
|
|
505
|
+
SKILL_MD=resolve_skill_bundle_root("codex")/<harness>-execute-phase/SKILL.md
|
|
506
|
+
```
|
|
507
|
+
|
|
508
|
+
**Primary path — orchestrator writes inline.** The orchestrator writes BOTH files directly via the Write tool using the schemas below. This is the default.
|
|
509
|
+
|
|
510
|
+
**Optional alternative.** The orchestrator MAY instead spawn a frontier-tier agent for fresh-context independent review. Use this only when independent review is desired.
|
|
511
|
+
|
|
512
|
+
FILE 1 — REPO-AGNOSTIC reflection → write to `<REFLECTION_PATH>`
|
|
513
|
+
|
|
514
|
+
```
|
|
515
|
+
# <harness>-execute-phase reflection — <ISO timestamp>
|
|
516
|
+
|
|
517
|
+
## Run context
|
|
518
|
+
- Skill: <harness>-execute-phase
|
|
519
|
+
- Timestamp: <ISO timestamp>
|
|
520
|
+
- Repo: <repo>
|
|
521
|
+
- Branch: <branch>
|
|
522
|
+
- Commit: <commit>
|
|
523
|
+
- Artifact: <artifact path if any, or none>
|
|
524
|
+
|
|
525
|
+
## What worked
|
|
526
|
+
- <bullet, about the SKILL's instructions>
|
|
527
|
+
|
|
528
|
+
## What didn't
|
|
529
|
+
- <bullet, about friction or gaps in the SKILL's instructions>
|
|
530
|
+
|
|
531
|
+
## Improvements to SKILL.md
|
|
532
|
+
- <specific, actionable change to the instructions>
|
|
533
|
+
```
|
|
534
|
+
|
|
535
|
+
Do NOT reference this project, codebase, filenames, or domain.
|
|
536
|
+
|
|
537
|
+
FILE 2 — REPO-SPECIFIC handoff → write to `<REPO_LOCAL_HANDOFF>` (per-repo slot; overwrites any prior handoff from this skill in the same repo)
|
|
538
|
+
|
|
539
|
+
```
|
|
540
|
+
<!--
|
|
541
|
+
Consumer validation — before acting on this handoff:
|
|
542
|
+
1. Verify `from:` matches the expected predecessor skill.
|
|
543
|
+
2. Verify `timestamp:` is within the last 7 days.
|
|
544
|
+
3. Verify every `artifact:` path resolves under your current
|
|
545
|
+
`$(git rev-parse --show-toplevel)`. If any path points to a
|
|
546
|
+
different repo, stop and surface it to the user — the handoff
|
|
547
|
+
was written against a different workspace.
|
|
548
|
+
-->
|
|
549
|
+
---
|
|
550
|
+
from: <harness>-execute-phase
|
|
551
|
+
timestamp: <ISO>
|
|
552
|
+
artifact: <phase alias that was executed, merge-commit SHAs>
|
|
553
|
+
artifact_state: <staged|tracked|modified|unstaged|blocked>
|
|
554
|
+
next_skill: <<harness>-execute-phase|<harness>-plan-phase|<harness>-phase-roadmap-builder|none>
|
|
555
|
+
next_command: </<harness>-execute-phase next-alias|/<harness>-plan-phase next-alias|/<harness>-phase-roadmap-builder|none - reason>
|
|
556
|
+
next_phase: <next alias - status|none - reason>
|
|
557
|
+
---
|
|
558
|
+
|
|
559
|
+
# Handoff for the next skill
|
|
560
|
+
|
|
561
|
+
The next skill in the chain is usually `/<harness>-plan-phase` for the
|
|
562
|
+
subsequent phase, or `/<harness>-phase-roadmap-builder` if the user is
|
|
563
|
+
appending new phases to the roadmap.
|
|
564
|
+
|
|
565
|
+
## Summary
|
|
566
|
+
<2-3 sentences: which phase completed, how many lanes merged,
|
|
567
|
+
final verification state.>
|
|
568
|
+
|
|
569
|
+
## Key decisions made this run
|
|
570
|
+
- <numbered, one line each — salvaged commits, retry outcomes,
|
|
571
|
+
which lanes needed escalated models>
|
|
572
|
+
|
|
573
|
+
## Open items for the next skill
|
|
574
|
+
- <concrete — e.g., "Phase P2A is next; its Interfaces consumed
|
|
575
|
+
list references IF-0-P1-1 which was frozen with signature X">
|
|
576
|
+
|
|
577
|
+
## Repo-specific gotchas surfaced
|
|
578
|
+
- <surprises this run: slow tests, flaky browser checks,
|
|
579
|
+
unexpected module coupling, quirks worth knowing>
|
|
580
|
+
|
|
581
|
+
## Files committed this run
|
|
582
|
+
- <merge-commit SHAs, with lane ID and brief description>
|
|
583
|
+
|
|
584
|
+
## Planning artifacts staged this run
|
|
585
|
+
- <path> @ <artifact_state>
|
|
586
|
+
|
|
587
|
+
## Next skill's likely scope
|
|
588
|
+
- <forecast of what <harness>-plan-phase / <harness>-phase-roadmap-builder will touch next>
|
|
589
|
+
```
|
|
590
|
+
|
|
591
|
+
After both files are written, **in the interactive TUI path only** (a human is
|
|
592
|
+
driving), print to the user:
|
|
593
|
+
|
|
594
|
+
> Phase `<alias>` complete. `<N>` lanes merged; final verification `<pass|fail>`.
|
|
595
|
+
> Reflection saved to `<REFLECTION_PATH>`.
|
|
596
|
+
> Handoff written to `<REPO_LOCAL_HANDOFF>`.
|
|
597
|
+
> Artifact state: `<staged|tracked|modified|unstaged|blocked>`.
|
|
598
|
+
>
|
|
599
|
+
> Next phase: `<next alias - status|none - reason>`.
|
|
600
|
+
> Next command: `<exact command or none - reason>`.
|
|
601
|
+
> Recommended next step (interactive only): either run `/clear` to reset your
|
|
602
|
+
> context window and then invoke the next command above, **or** dispatch a fresh
|
|
603
|
+
> subagent (Task/Agent) to carry the next phase in clean context when this loop
|
|
604
|
+
> is skill/tool-driven. The next skill reads the handoff automatically.
|
|
605
|
+
|
|
606
|
+
`/clear` is a human-operated reset and applies only to the interactive TUI path
|
|
607
|
+
above. **Do not emit it in Phase-Loop Adapter (autonomous) mode** — an
|
|
608
|
+
autonomous loop has no human to run it and cannot clear its own context.
|
|
609
|
+
In autonomous runs, continuity is the written handoff and the runner re-invokes
|
|
610
|
+
the next phase in a fresh executor process; that fresh process *is* the context
|
|
611
|
+
reset. See "Phase-Loop Adapter Mode" above.
|
|
612
|
+
|
|
613
|
+
## Lane state machine
|
|
614
|
+
|
|
615
|
+
```
|
|
616
|
+
pending ──► running ──► verify-ok ──► merged
|
|
617
|
+
│ ▲
|
|
618
|
+
└─fail─► failed ─retry─►─┘ (once)
|
|
619
|
+
│
|
|
620
|
+
└─fail2─► HALT
|
|
621
|
+
```
|
|
622
|
+
|
|
623
|
+
## Parallelism contract
|
|
624
|
+
|
|
625
|
+
- All lanes whose dependencies are satisfied at the same time MUST be dispatched in the same message (parallel `Agent` tool calls), up to `EXECUTE_MAX_PARALLEL_LANES`.
|
|
626
|
+
- Lanes must not share files. The plan's lane-validation checklist guarantees disjoint ownership; <harness>-execute-phase trusts the plan and does not re-verify file-glob intersections.
|
|
627
|
+
- Shared generated files (e.g., barrel index files, generated types) are called out in the plan's `## Execution Notes`; only the lane that lists them under `Owned files` may modify them.
|
|
628
|
+
|
|
629
|
+
## Model selection quick-reference
|
|
630
|
+
|
|
631
|
+
| Symptom in the plan doc | Assigned tier | Thinking |
|
|
632
|
+
|---|---|---|
|
|
633
|
+
| `Scope` mentions schema / migration / SQL | `strong` | high |
|
|
634
|
+
| `Interfaces provided` includes any `IF-0-*` gate | `strong` | high |
|
|
635
|
+
| `Scope` mentions algorithm / compute / worker logic | `strong` | medium |
|
|
636
|
+
| `Owned files` glob expands to >10 files, no interfaces provided | `fast` | low |
|
|
637
|
+
| `Scope` is "small components against frozen types" | `fast` | low |
|
|
638
|
+
| `Execution hint:` line is present in lane section | Use it verbatim | Use it verbatim |
|
|
639
|
+
| Retry | One tier up | One tier up |
|
|
640
|
+
|
|
641
|
+
Resolve tier names to model IDs via the Model tiers table at the top of this skill.
|
|
642
|
+
|
|
643
|
+
## Output contract
|
|
644
|
+
|
|
645
|
+
On successful completion:
|
|
646
|
+
|
|
647
|
+
1. Every lane's branch merged into the target branch with a `--no-ff` commit, in topological order.
|
|
648
|
+
2. All lane worktrees removed; lane branches deleted.
|
|
649
|
+
3. All `TaskCreate`'d lane tasks marked `completed`.
|
|
650
|
+
4. `.claude/<harness>-execute-phase-state.json` deleted (or the `status` field set to `complete`).
|
|
651
|
+
5. Team torn down via `TeamDelete` or `team_teardown.sh`.
|
|
652
|
+
6. Final summary message to the user.
|
|
653
|
+
|
|
654
|
+
On halt:
|
|
655
|
+
|
|
656
|
+
1. Lanes that completed remain merged; their state is preserved.
|
|
657
|
+
2. `.claude/<harness>-execute-phase-state.json` contains the failing lane's name, task, log tail, and which gates/lanes were green vs open.
|
|
658
|
+
3. User can `/<harness>-execute-phase --resume` after fixing the blocker.
|
|
659
|
+
|
|
660
|
+
## Worktree layout
|
|
661
|
+
|
|
662
|
+
```
|
|
663
|
+
<repo>/
|
|
664
|
+
├── .claude/
|
|
665
|
+
│ ├── worktrees/
|
|
666
|
+
│ │ ├── lane-sl-1-<timestamp>-<random>/
|
|
667
|
+
│ │ └── …
|
|
668
|
+
│ └── <harness>-execute-phase-state.json
|
|
669
|
+
```
|
|
670
|
+
|
|
671
|
+
Both paths are auto-added to `.gitignore` in Step 2.
|
|
672
|
+
|
|
673
|
+
## Teamwork posture (hard rules)
|
|
674
|
+
|
|
675
|
+
- **Main thread = dispatcher.** Read plan doc + TaskList + git state. Do not Grep/Read source code during execution, except for the Step 7 destructiveness check and file-touch audit.
|
|
676
|
+
- **Parallel-by-default.** Ready lanes dispatch in a single message, every round.
|
|
677
|
+
- **Name every teammate via the allocator.** Bare `lane-<sl-id>` names collide in rapid dispatch.
|
|
678
|
+
- **TaskCreate tasks are the source of truth for lane status.** Update them as lanes transition.
|
|
679
|
+
- **No speculative refactoring.** Lane teammates must stay within their `Owned files` globs; reject their work at gate verification if they wandered. Use the file-touch audit to catch this pre-merge.
|
|
680
|
+
- **Never trust a branch name.** Resolve work by `commit_sha` from the reply envelope.
|
|
681
|
+
- **Never `--no-ff` merge without the destructiveness check.**
|
|
682
|
+
- **Never resume a STOPped teammate with no commits.** Kill + respawn.
|
|
683
|
+
- **Never override the dirty-tree preflight.** `verify_harness.sh` is the gate. Only paths forward: (a) commit as `chore:`, (b) `git stash push -u` and restore post-phase, (c) abort.
|
|
684
|
+
- **Never rely on implicit shell CWD.** Every orchestrator git/script invocation MUST either wrap as `bash -c 'cd "$(git rev-parse --show-toplevel)" && <cmd>'` or pass `git -C <repo-root>`. `git worktree remove` on the shell's current CWD bricks subsequent Bash calls.
|
|
685
|
+
|
|
686
|
+
## Browser verification capabilities
|
|
687
|
+
|
|
688
|
+
When a plan's `## Verification` section includes Playwright/e2e commands or lane tasks ask for browser smoke-testing, run them:
|
|
689
|
+
|
|
690
|
+
- **Playwright via PMCP** — `pmcp_invoke(tool_id="playwright::browser_navigate", ...)` and related `playwright::*` tools. Default.
|
|
691
|
+
- **Chrome DevTools Protocol (CDP)** — low-level debugging (performance traces, CPU profiling).
|
|
692
|
+
- **`claude-in-chrome`** — extension-context automation only.
|
|
693
|
+
|
|
694
|
+
The PMCP Playwright server provisions on demand. If the repo lacks a Playwright config, add one in the lane rather than deferring the test.
|
|
695
|
+
|
|
696
|
+
|
|
697
|
+
Use `phase_loop_runtime.skill_paths` resolver helpers for harness skill roots, handoff roots, helper roots, and reflection roots.
|
|
698
|
+
|
|
699
|
+
|
|
700
|
+
## Runner Verification Evidence
|
|
701
|
+
|
|
702
|
+
Before reporting a successful closeout, require the runner-owned verification artifact. The closeout must name `verification_artifact_path`, quote the artifact summary line, and must not report `verification_status=passed` unless that artifact exists and supports the executed work. Treat dependency-manifest install refresh and the full suite before closeout as runner-enforced expectations, not optional narrative checks. A blocked gate may be re-verdicted only by rerunning the originally specified runner check; proxy evidence requires a roadmap or plan amendment before the verdict changes. A prior run's terminal-summary is authoritative for reconcile-or-skip only when that closeout was accepted; a rejected or blocked prior closeout — regardless of any self-reported `complete`/`passed` — must not be reconciled against. On a re-run, re-do and re-verify the phase work from scratch rather than skipping on a stale summary.
|
|
703
|
+
|
|
704
|
+
|
|
705
|
+
## Spec Delta Closeout
|
|
706
|
+
|
|
707
|
+
Before final closeout, choose exactly one `spec_delta_closeout.v1` decision: `no_spec_delta`, `roadmap_amendment`, `canonical_spec_update`, `governed_pipeline_refresh`, `mirror_cutover_required`, `dotfiles_skill_source_update`, or `human_source_judgment_required`. Cite metadata-only evidence paths such as the active plan, lane closeouts, targeted pytest output, and `git diff --check` output. Preserve the phase plan's target surfaces and `redaction_posture=metadata_only`; do not include raw specification bodies, raw patch bodies, credentials, provider-supplied payloads, local environment values, or evidence-source contents. Missing or malformed spec-closeout evidence is a repairable automation blocker with `blocker_class=contract_bug` unless the decision is `human_source_judgment_required`.
|
|
708
|
+
|
|
709
|
+
## Closeout
|
|
710
|
+
|
|
711
|
+
### Manifest lifecycle
|
|
712
|
+
|
|
713
|
+
After plan validation and before lane execution, perform a best-effort `plan-manifest append` lifecycle update through `phase_loop_runtime.plan_manifest.update_lifecycle` to mark the matching `type=phase` entry `executing` with run metadata. During closeout, update the same entry to `completed` or `failed` with verification metadata, reflection metadata, produced-gate metadata, `if_gates_produced`, and dirty-worktree summary fields as available. `if_gates_produced` must list only the IF gates the active phase produces per its own plan; never carry a prior phase's gate forward into this phase's closeout. Manifest lifecycle failures are non-fatal during the dual-mode window: emit a ledger warning, mention the warning in the mandatory reflection, and preserve the existing phase closeout JSON, verification, and dirty-worktree behavior.
|
|
714
|
+
|
|
715
|
+
Closeout payload shape is defined by `EmitPhaseCloseout` in `phase_loop_runtime/baml_src/emit_phase_closeout.baml` (if that path is absent in the checkout, use the operator/prompt-supplied field contract or the installed `phase_loop_runtime` package — the missing vendored BAML source is not a blocker); keep skill text focused on value selection and handoff routing, not duplicated field ceremony.
|
|
716
|
+
|
|
717
|
+
Before final response, write a reflection for every non-trivial run. Write it to `resolve_skill_bundle_root("codex")/<harness>-execute-phase/reflections/<repo_hash>/<branch_slug>/<run_id>.md`. The reflection must include `## Run context` with skill name, ISO timestamp, repo, branch, commit, and artifact path if any, followed by `## What worked`, `## What didn't`, and `## Improvements to SKILL.md`. skip only when no artifact was produced AND no decision was made AND the run was pure inspection.
|
|
718
|
+
|
|
719
|
+
|
|
720
|
+
## Publication mode
|
|
721
|
+
|
|
722
|
+
After verified phase work, select exactly one of three modes. **Default to (a) unless a
|
|
723
|
+
clear interactive signal is present** — a run missing BOTH the adapter prompt prefix AND
|
|
724
|
+
`PHASE_LOOP_RUN_MODE` is AMBIGUOUS and MUST be treated as (a) (fail safe toward the runner).
|
|
725
|
+
|
|
726
|
+
- (a) Runner-managed closeout (incl. governed mode), OR ambiguous mode. If this is the
|
|
727
|
+
phase-loop adapter (the prompt begins with `<harness>-execute-phase <plan>` from a
|
|
728
|
+
pipeline run dir), or `PHASE_LOOP_RUN_MODE` is set (autonomous/governed), OR neither
|
|
729
|
+
interactive signal is clearly present, the RUNNER owns closeout and commit. Do NOT
|
|
730
|
+
independently publish — defer entirely to runner closeout (`awaiting_phase_closeout` /
|
|
731
|
+
runner commit). Publishing here would bypass the governed pre-merge review panel.
|
|
732
|
+
- (b) Interactive orchestrator on a clean, non-protected feature branch (a clear
|
|
733
|
+
interactive signal, and the merge target passed the merge-target safety gate). After the
|
|
734
|
+
Step-9 clean-tree state, push the merge-target branch and open a PR (`gh pr create`,
|
|
735
|
+
`--draft` if dependencies remain or verification was partial/skipped, else ready) instead
|
|
736
|
+
of leaving the lane merge only local.
|
|
737
|
+
- (c) Merge target is `main` or a protected branch. Already STOPPED at the merge-target
|
|
738
|
+
safety gate before any lane merge — never merge lanes onto `main`/protected. Re-target a
|
|
739
|
+
feature branch or take explicit instruction.
|
|
740
|
+
|
|
741
|
+
This applies only to interactive (non-runner) completion; it never overrides
|
|
742
|
+
`awaiting_phase_closeout`, the runner's deliberate non-complete terminal. Allowed runner
|
|
743
|
+
hygiene (forced lane-worktree removal, `branch -D`, `sweep_stale_worktrees.sh`) is
|
|
744
|
+
unchanged — the destructive-op ban targets publication branches/worktrees holding
|
|
745
|
+
unmerged work.
|