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,188 @@
|
|
|
1
|
+
"""Named board presets (ABDREG, Phase 2 — lane 4).
|
|
2
|
+
|
|
3
|
+
Nine built-in presets, each a named, purpose-tagged, open-ended seat list:
|
|
4
|
+
|
|
5
|
+
* ``default`` — IS ``fixtures.DEFAULT_BOARD`` (imported, not re-declared), so
|
|
6
|
+
the back-compat keystone holds by construction: the default
|
|
7
|
+
board reconstructs today's exact three seats (the claude seat
|
|
8
|
+
on Fable, ``claude-fable-5``).
|
|
9
|
+
* ``code-review`` — three frontier vendors, each adversarial: codex ``gpt-5.5``,
|
|
10
|
+
``Gemini 3.1 Pro``, and ``claude-fable-5``.
|
|
11
|
+
* ``brainstorm`` — multi-vendor divergent thinking, lens-differentiated.
|
|
12
|
+
* ``doc-edit`` — a lighter documentation-editing board.
|
|
13
|
+
* ``legal-review`` / ``legal-strategy-review`` / ``legal-brainstorm`` — the legal
|
|
14
|
+
boards (see below).
|
|
15
|
+
|
|
16
|
+
**Review-class boards run on frontier models, never the implementer.** Pre-merge
|
|
17
|
+
and legal review are mid-tier decisions where being wrong is expensive, so the
|
|
18
|
+
review-class boards (``default``, ``code-review``, ``legal-review``,
|
|
19
|
+
``legal-strategy-review``) seat Fable (``claude-fable-5``) on the claude lane, not
|
|
20
|
+
the implementer ``claude-sonnet-5``. The divergent-thinking boards (``brainstorm``,
|
|
21
|
+
``doc-edit``, ``legal-brainstorm``) deliberately KEEP Sonnet — a diverse voice / a
|
|
22
|
+
low-stakes copyedit / an aggressive-but-cheap ideation seat — where it is the right
|
|
23
|
+
tool.
|
|
24
|
+
|
|
25
|
+
Every preset seat uses only REGISTERED, VALID ``(model, harness)`` pairs on the
|
|
26
|
+
built-3 + ``opencode`` lanes (no ``pi`` / ``cursor`` / unregistered-model seats),
|
|
27
|
+
so the presets pass their OWN config-time validation — ``config.load_boards()``
|
|
28
|
+
self-validates every preset (``tests/test_advisor_board_config.py``). Adding a
|
|
29
|
+
preset seat on an unregistered model or an incompatible lane would turn the suite
|
|
30
|
+
red, which is the intended guardrail. ``lens`` and ``purpose`` are free-form
|
|
31
|
+
strings (``schema.py``): the legal lenses/purposes below need no enum extension.
|
|
32
|
+
"""
|
|
33
|
+
from __future__ import annotations
|
|
34
|
+
|
|
35
|
+
from .fixtures import DEFAULT_BOARD
|
|
36
|
+
from .schema import Board, Seat
|
|
37
|
+
|
|
38
|
+
# code-review: review-class = three frontier vendors, always. Each seat carries the
|
|
39
|
+
# adversarial lens (find-the-bug framing); the claude seat is Fable, not the
|
|
40
|
+
# implementer. This supersedes the old two-seat (codex + sonnet) composition.
|
|
41
|
+
CODE_REVIEW_BOARD: Board = Board(
|
|
42
|
+
name="code-review",
|
|
43
|
+
purpose="code-review",
|
|
44
|
+
seats=(
|
|
45
|
+
Seat(model="gpt-5.5", effort="max", harness="codex", lens="adversarial"),
|
|
46
|
+
Seat(model="Gemini 3.1 Pro", effort="high", harness="gemini", lens="adversarial"),
|
|
47
|
+
Seat(model="claude-fable-5", effort="max", harness="claude", lens="adversarial"),
|
|
48
|
+
),
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
# brainstorm: divergent, multi-vendor, each seat a different thinking lens.
|
|
52
|
+
BRAINSTORM_BOARD: Board = Board(
|
|
53
|
+
name="brainstorm",
|
|
54
|
+
purpose="brainstorm",
|
|
55
|
+
seats=(
|
|
56
|
+
Seat(model="claude-sonnet-5", effort="high", harness="claude", lens="adversarial"),
|
|
57
|
+
Seat(model="gpt-5.5", effort="high", harness="codex", lens="supportive"),
|
|
58
|
+
Seat(model="Gemini 3.1 Pro", effort="high", harness="gemini", lens="lateral"),
|
|
59
|
+
),
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
# doc-edit: a lighter documentation-editing board (structure + copyedit).
|
|
63
|
+
DOC_EDIT_BOARD: Board = Board(
|
|
64
|
+
name="doc-edit",
|
|
65
|
+
purpose="doc-edit",
|
|
66
|
+
seats=(
|
|
67
|
+
Seat(model="claude-sonnet-5", effort="medium", harness="claude", lens="copyedit"),
|
|
68
|
+
Seat(model="gpt-5.5", effort="medium", harness="codex", lens="structure"),
|
|
69
|
+
),
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
# --- legal boards ----------------------------------------------------------
|
|
73
|
+
#
|
|
74
|
+
# Each seat below encodes the PRIMARY review lens per vendor. The richer treatment
|
|
75
|
+
# — four lenses per seat, an apex-Opus seat, a verify-round, and retrieval-grounded
|
|
76
|
+
# citation-verification — is a documented deep-seat FOLLOW-ON (see CONTRACTS.md),
|
|
77
|
+
# intentionally NOT built here. Review-class legal boards seat Fable on claude;
|
|
78
|
+
# legal-brainstorm keeps Sonnet as a cheap aggressive ideation voice.
|
|
79
|
+
|
|
80
|
+
# legal-review: document/contract review. Opposing-counsel adversary, risk/liability
|
|
81
|
+
# scan, and authority (citation/precedent) verification.
|
|
82
|
+
LEGAL_REVIEW_BOARD: Board = Board(
|
|
83
|
+
name="legal-review",
|
|
84
|
+
purpose="legal-review",
|
|
85
|
+
seats=(
|
|
86
|
+
Seat(model="gpt-5.5", effort="max", harness="codex", lens="opposing-counsel"),
|
|
87
|
+
Seat(model="Gemini 3.1 Pro", effort="high", harness="gemini", lens="risk-liability"),
|
|
88
|
+
Seat(model="claude-fable-5", effort="max", harness="claude", lens="authority-verification"),
|
|
89
|
+
),
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
# legal-strategy-review: red-team a legal strategy — attack it, surface alternatives,
|
|
93
|
+
# and stress the downside / ethical exposure.
|
|
94
|
+
LEGAL_STRATEGY_REVIEW_BOARD: Board = Board(
|
|
95
|
+
name="legal-strategy-review",
|
|
96
|
+
purpose="legal-strategy-review",
|
|
97
|
+
seats=(
|
|
98
|
+
Seat(model="gpt-5.5", effort="max", harness="codex", lens="red-team"),
|
|
99
|
+
Seat(model="Gemini 3.1 Pro", effort="high", harness="gemini", lens="alternatives"),
|
|
100
|
+
Seat(model="claude-fable-5", effort="max", harness="claude", lens="downside-ethics"),
|
|
101
|
+
),
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
# legal-brainstorm: divergent legal ideation. KEEPS Sonnet (aggressive, cheap voice)
|
|
105
|
+
# alongside a conservative and a creative seat.
|
|
106
|
+
LEGAL_BRAINSTORM_BOARD: Board = Board(
|
|
107
|
+
name="legal-brainstorm",
|
|
108
|
+
purpose="legal-brainstorm",
|
|
109
|
+
seats=(
|
|
110
|
+
Seat(model="claude-sonnet-5", effort="high", harness="claude", lens="aggressive"),
|
|
111
|
+
Seat(model="gpt-5.5", effort="high", harness="codex", lens="conservative"),
|
|
112
|
+
Seat(model="Gemini 3.1 Pro", effort="high", harness="gemini", lens="creative"),
|
|
113
|
+
),
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
# --- general-purpose catch-alls -------------------------------------------
|
|
117
|
+
#
|
|
118
|
+
# For use cases we have NOT pre-modeled, so the board library is open-ended rather
|
|
119
|
+
# than limited to the named domains. Both default to TOP-END models: an unanticipated
|
|
120
|
+
# task cannot be assumed low-stakes, so the safe default is frontier — dial down
|
|
121
|
+
# explicitly (a cheaper board or max_concurrency aside) when a task is known-cheap.
|
|
122
|
+
|
|
123
|
+
# general: the domain-agnostic top-tier PANEL. Three frontier vendors with generic
|
|
124
|
+
# critical lenses (adversarial / alternative-angle / completeness) — hand it any
|
|
125
|
+
# task + brief and it convenes a cross-vendor frontier review.
|
|
126
|
+
GENERAL_BOARD: Board = Board(
|
|
127
|
+
name="general",
|
|
128
|
+
purpose="general",
|
|
129
|
+
seats=(
|
|
130
|
+
Seat(model="gpt-5.5", effort="max", harness="codex", lens="adversarial"),
|
|
131
|
+
Seat(model="Gemini 3.1 Pro", effort="high", harness="gemini", lens="alternative"),
|
|
132
|
+
Seat(model="claude-fable-5", effort="max", harness="claude", lens="completeness"),
|
|
133
|
+
),
|
|
134
|
+
)
|
|
135
|
+
|
|
136
|
+
# solo: the general-purpose single MEMBER — one quick top-end opinion when a full
|
|
137
|
+
# panel is overkill. A one-seat board resolves + validates like any other.
|
|
138
|
+
SOLO_BOARD: Board = Board(
|
|
139
|
+
name="solo",
|
|
140
|
+
purpose="general",
|
|
141
|
+
seats=(
|
|
142
|
+
Seat(model="claude-fable-5", effort="max", harness="claude", lens="completeness"),
|
|
143
|
+
),
|
|
144
|
+
)
|
|
145
|
+
|
|
146
|
+
# The built-in presets, keyed by name. ``default`` IS the shared fixture board.
|
|
147
|
+
PRESETS: dict[str, Board] = {
|
|
148
|
+
DEFAULT_BOARD.name: DEFAULT_BOARD,
|
|
149
|
+
CODE_REVIEW_BOARD.name: CODE_REVIEW_BOARD,
|
|
150
|
+
BRAINSTORM_BOARD.name: BRAINSTORM_BOARD,
|
|
151
|
+
DOC_EDIT_BOARD.name: DOC_EDIT_BOARD,
|
|
152
|
+
LEGAL_REVIEW_BOARD.name: LEGAL_REVIEW_BOARD,
|
|
153
|
+
LEGAL_STRATEGY_REVIEW_BOARD.name: LEGAL_STRATEGY_REVIEW_BOARD,
|
|
154
|
+
LEGAL_BRAINSTORM_BOARD.name: LEGAL_BRAINSTORM_BOARD,
|
|
155
|
+
GENERAL_BOARD.name: GENERAL_BOARD,
|
|
156
|
+
SOLO_BOARD.name: SOLO_BOARD,
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
PRESET_NAMES: tuple[str, ...] = tuple(PRESETS)
|
|
160
|
+
|
|
161
|
+
# The board a bare ``advisor-board`` invocation resolves to absent a user override.
|
|
162
|
+
DEFAULT_BOARD_NAME: str = DEFAULT_BOARD.name
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
def get_preset(name: str) -> Board:
|
|
166
|
+
"""Return a built-in preset by name, or raise ``KeyError`` naming the known
|
|
167
|
+
presets."""
|
|
168
|
+
try:
|
|
169
|
+
return PRESETS[name]
|
|
170
|
+
except KeyError as exc:
|
|
171
|
+
known = ", ".join(PRESET_NAMES)
|
|
172
|
+
raise KeyError(f"unknown board preset {name!r}; known presets: {known}") from exc
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
__all__ = [
|
|
176
|
+
"PRESETS",
|
|
177
|
+
"PRESET_NAMES",
|
|
178
|
+
"DEFAULT_BOARD_NAME",
|
|
179
|
+
"CODE_REVIEW_BOARD",
|
|
180
|
+
"BRAINSTORM_BOARD",
|
|
181
|
+
"DOC_EDIT_BOARD",
|
|
182
|
+
"LEGAL_REVIEW_BOARD",
|
|
183
|
+
"LEGAL_STRATEGY_REVIEW_BOARD",
|
|
184
|
+
"LEGAL_BRAINSTORM_BOARD",
|
|
185
|
+
"GENERAL_BOARD",
|
|
186
|
+
"SOLO_BOARD",
|
|
187
|
+
"get_preset",
|
|
188
|
+
]
|
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
"""Registry interfaces + (model x harness) matrix API — INTERFACES ONLY
|
|
2
|
+
(IF-0-ABDFREEZE-2).
|
|
3
|
+
|
|
4
|
+
This freezes the *return types* and the *method surface* that ABDREG populates
|
|
5
|
+
and that ABDRESOLVE / ABDHOME import. It ships importable Protocols, the frozen
|
|
6
|
+
record + result types, and ``NotImplemented``-raising stubs — **no six-harness
|
|
7
|
+
data** (that is ABDREG). Keeping the return types concrete here (rather than bare
|
|
8
|
+
tuples) is what lets ABDREG's matrix and ABDRESOLVE's validation compile against
|
|
9
|
+
the same shapes without divergence.
|
|
10
|
+
"""
|
|
11
|
+
from __future__ import annotations
|
|
12
|
+
|
|
13
|
+
from dataclasses import dataclass
|
|
14
|
+
from typing import Protocol, runtime_checkable
|
|
15
|
+
|
|
16
|
+
from .schema import AUTH_SUBSCRIPTION, BACKING_HOMEBREW
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
# --- frozen record + result types (imported by ABDREG and ABDRESOLVE) -------
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
@dataclass(frozen=True)
|
|
23
|
+
class HarnessSpec:
|
|
24
|
+
"""A registered harness (execution lane). Populated by ABDREG.
|
|
25
|
+
|
|
26
|
+
``cli`` is the availability-probe binary (e.g. ``codex`` / ``agy`` / ``claude``
|
|
27
|
+
/ ``cursor-agent``); ``auth_lanes`` the credential lanes it supports; ``backing``
|
|
28
|
+
its default provider transport. ``available`` is a *probe result*, not frozen
|
|
29
|
+
data — the stub registry leaves it ``None`` (unknown)."""
|
|
30
|
+
|
|
31
|
+
name: str
|
|
32
|
+
cli: str
|
|
33
|
+
auth_lanes: tuple[str, ...] = (AUTH_SUBSCRIPTION,)
|
|
34
|
+
backing: str = BACKING_HOMEBREW
|
|
35
|
+
available: bool | None = None
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
@dataclass(frozen=True)
|
|
39
|
+
class ModelSpec:
|
|
40
|
+
"""A registered model. Populated by ABDREG.
|
|
41
|
+
|
|
42
|
+
``default_lane`` the harness a bare seat resolves to; ``runnable_by`` the
|
|
43
|
+
harness lanes that can run it; ``effort_ceiling`` the max canonical effort the
|
|
44
|
+
model honors (a seat above it is clamped/rejected at validation)."""
|
|
45
|
+
|
|
46
|
+
model: str
|
|
47
|
+
vendor_family: str
|
|
48
|
+
default_lane: str
|
|
49
|
+
runnable_by: tuple[str, ...] = ()
|
|
50
|
+
effort_ceiling: str = "max"
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
@dataclass(frozen=True)
|
|
54
|
+
class AuthAvailability:
|
|
55
|
+
"""Which credential lanes are usable for a ``(model, harness)`` pair.
|
|
56
|
+
|
|
57
|
+
Returned as the second element of ``CompatibilityMatrix.is_valid``. Concrete
|
|
58
|
+
(not a bare bool) so no-silent-key is *testable* for a seat: a seat may be a
|
|
59
|
+
valid pairing yet have neither lane available (skip-with-warning), or only the
|
|
60
|
+
subscription lane (the default), or the api-key lane behind an explicit
|
|
61
|
+
board opt-in."""
|
|
62
|
+
|
|
63
|
+
subscription: bool = False
|
|
64
|
+
api_key: bool = False
|
|
65
|
+
detail: str = ""
|
|
66
|
+
|
|
67
|
+
@property
|
|
68
|
+
def any_available(self) -> bool:
|
|
69
|
+
return self.subscription or self.api_key
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
# ``is_valid`` return alias — frozen so both the matrix impl and validation import it.
|
|
73
|
+
MatrixVerdict = tuple[bool, AuthAvailability]
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
# --- interfaces (Protocols) -------------------------------------------------
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
@runtime_checkable
|
|
80
|
+
class HarnessRegistry(Protocol):
|
|
81
|
+
"""The six-harness registry (claude, codex, gemini, opencode, pi, cursor)."""
|
|
82
|
+
|
|
83
|
+
def list_harnesses(self) -> tuple[HarnessSpec, ...]: ...
|
|
84
|
+
|
|
85
|
+
def get(self, name: str) -> HarnessSpec: ...
|
|
86
|
+
|
|
87
|
+
def is_available(self, name: str) -> bool: ...
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
@runtime_checkable
|
|
91
|
+
class ModelRegistry(Protocol):
|
|
92
|
+
"""Model -> default lane / runnable_by / effort ceiling."""
|
|
93
|
+
|
|
94
|
+
def list_models(self) -> tuple[ModelSpec, ...]: ...
|
|
95
|
+
|
|
96
|
+
def get(self, model: str) -> ModelSpec: ...
|
|
97
|
+
|
|
98
|
+
def default_lane(self, model: str) -> str: ...
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
@runtime_checkable
|
|
102
|
+
class CompatibilityMatrix(Protocol):
|
|
103
|
+
"""The ``(model x harness)`` compatibility + per-lane auth-availability API.
|
|
104
|
+
|
|
105
|
+
``is_valid(model, harness)`` -> ``(ok, AuthAvailability)``: ``ok`` is whether
|
|
106
|
+
the pairing is *expressible at all* (an invalid pairing such as
|
|
107
|
+
``claude:gpt-5.5`` is rejected at config time with a clear message); the
|
|
108
|
+
``AuthAvailability`` reports which lanes are actually usable so a valid-but-
|
|
109
|
+
unauthed seat degrades rather than blocks. ``default_lane`` is the harness a
|
|
110
|
+
bare ``model`` seat resolves onto.
|
|
111
|
+
"""
|
|
112
|
+
|
|
113
|
+
def is_valid(self, model: str, harness: str) -> MatrixVerdict: ...
|
|
114
|
+
|
|
115
|
+
def default_lane(self, model: str) -> str: ...
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
# --- stubs (ABDREG replaces these with populated data) ----------------------
|
|
119
|
+
|
|
120
|
+
_STUB_MSG = "advisor-board registry is populated in ABDREG (Phase 2); this is the frozen stub"
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
@dataclass
|
|
124
|
+
class StubHarnessRegistry:
|
|
125
|
+
"""Importable placeholder satisfying ``HarnessRegistry``. Every accessor raises
|
|
126
|
+
so a phase that accidentally depends on real data before ABDREG fails loudly."""
|
|
127
|
+
|
|
128
|
+
def list_harnesses(self) -> tuple[HarnessSpec, ...]:
|
|
129
|
+
raise NotImplementedError(_STUB_MSG)
|
|
130
|
+
|
|
131
|
+
def get(self, name: str) -> HarnessSpec:
|
|
132
|
+
raise NotImplementedError(_STUB_MSG)
|
|
133
|
+
|
|
134
|
+
def is_available(self, name: str) -> bool:
|
|
135
|
+
raise NotImplementedError(_STUB_MSG)
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
@dataclass
|
|
139
|
+
class StubModelRegistry:
|
|
140
|
+
def list_models(self) -> tuple[ModelSpec, ...]:
|
|
141
|
+
raise NotImplementedError(_STUB_MSG)
|
|
142
|
+
|
|
143
|
+
def get(self, model: str) -> ModelSpec:
|
|
144
|
+
raise NotImplementedError(_STUB_MSG)
|
|
145
|
+
|
|
146
|
+
def default_lane(self, model: str) -> str:
|
|
147
|
+
raise NotImplementedError(_STUB_MSG)
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
@dataclass
|
|
151
|
+
class StubCompatibilityMatrix:
|
|
152
|
+
def is_valid(self, model: str, harness: str) -> MatrixVerdict:
|
|
153
|
+
raise NotImplementedError(_STUB_MSG)
|
|
154
|
+
|
|
155
|
+
def default_lane(self, model: str) -> str:
|
|
156
|
+
raise NotImplementedError(_STUB_MSG)
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
# ===========================================================================
|
|
160
|
+
# ABDREG (Phase 2) — populated registries.
|
|
161
|
+
#
|
|
162
|
+
# Everything above is the ABDFREEZE interface freeze and is byte-frozen (the
|
|
163
|
+
# stubs still raise; ``tests/test_advisor_board_registries.py`` asserts it).
|
|
164
|
+
# Below is the real six-harness / model data ABDREG owns. It is additive: no
|
|
165
|
+
# frozen type, protocol, or stub changes. The compatibility + auth matrix that
|
|
166
|
+
# consumes these lives in ``matrix.py``; the presets + config loader in
|
|
167
|
+
# ``presets.py`` / ``config.py``.
|
|
168
|
+
# ===========================================================================
|
|
169
|
+
|
|
170
|
+
import shutil
|
|
171
|
+
from collections.abc import Callable
|
|
172
|
+
|
|
173
|
+
from .schema import AUTH_API_KEY, BACKING_OMNIGENT, vendor_family, vendor_of_harness
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
class UnknownModelError(KeyError):
|
|
177
|
+
"""A seat references a model the registry does not know. Raised with the
|
|
178
|
+
known-model list so a config-time rejection is actionable."""
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
class UnknownHarnessError(KeyError):
|
|
182
|
+
"""A seat references a harness the registry does not know."""
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
# --- harness registry data --------------------------------------------------
|
|
186
|
+
|
|
187
|
+
# The six harnesses. claude / codex / gemini are the built-3 (homebrew, native +
|
|
188
|
+
# TUI legs, ABDHOME); opencode / pi / cursor are breadth — registered here
|
|
189
|
+
# regardless, but their default transport is ``omnigent`` (routed via
|
|
190
|
+
# omniagent-plus -> Omnigent per ABDOMNI; NOT hand-written homebrew adapters).
|
|
191
|
+
# ``cli`` is the availability-probe binary: codex -> ``codex``, gemini -> ``agy``
|
|
192
|
+
# (panel_invoker._LEG_CLI), cursor -> ``cursor-agent`` (so cursor is gated on the
|
|
193
|
+
# cursor-agent binary being present). All six support both credential lanes; the
|
|
194
|
+
# subscription lane is the default and the api-key lane is reachable only behind a
|
|
195
|
+
# board opt-in (never-silent-key).
|
|
196
|
+
_BOTH_LANES: tuple[str, ...] = (AUTH_SUBSCRIPTION, AUTH_API_KEY)
|
|
197
|
+
|
|
198
|
+
_HARNESS_SPECS: tuple[HarnessSpec, ...] = (
|
|
199
|
+
HarnessSpec(name="claude", cli="claude", auth_lanes=_BOTH_LANES, backing=BACKING_HOMEBREW),
|
|
200
|
+
HarnessSpec(name="codex", cli="codex", auth_lanes=_BOTH_LANES, backing=BACKING_HOMEBREW),
|
|
201
|
+
HarnessSpec(name="gemini", cli="agy", auth_lanes=_BOTH_LANES, backing=BACKING_HOMEBREW),
|
|
202
|
+
HarnessSpec(name="opencode", cli="opencode", auth_lanes=_BOTH_LANES, backing=BACKING_OMNIGENT),
|
|
203
|
+
HarnessSpec(name="pi", cli="pi", auth_lanes=_BOTH_LANES, backing=BACKING_OMNIGENT),
|
|
204
|
+
HarnessSpec(name="cursor", cli="cursor-agent", auth_lanes=_BOTH_LANES, backing=BACKING_OMNIGENT),
|
|
205
|
+
)
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
@dataclass
|
|
209
|
+
class DefaultHarnessRegistry:
|
|
210
|
+
"""Populated ``HarnessRegistry`` over the six harnesses.
|
|
211
|
+
|
|
212
|
+
``is_available`` is a PATH probe only (``shutil.which``) — metadata-only, it
|
|
213
|
+
never authenticates or spends tokens, mirroring
|
|
214
|
+
``panel_invoker.available_panel_legs``. The probe is injectable so tests are
|
|
215
|
+
deterministic (cursor's gate is just ``which("cursor-agent")``).
|
|
216
|
+
"""
|
|
217
|
+
|
|
218
|
+
probe: Callable[[str], bool] | None = None
|
|
219
|
+
|
|
220
|
+
def _probe(self) -> Callable[[str], bool]:
|
|
221
|
+
return self.probe if self.probe is not None else (lambda cli: shutil.which(cli) is not None)
|
|
222
|
+
|
|
223
|
+
def list_harnesses(self) -> tuple[HarnessSpec, ...]:
|
|
224
|
+
return _HARNESS_SPECS
|
|
225
|
+
|
|
226
|
+
def get(self, name: str) -> HarnessSpec:
|
|
227
|
+
key = (name or "").lower()
|
|
228
|
+
for spec in _HARNESS_SPECS:
|
|
229
|
+
if spec.name == key:
|
|
230
|
+
return spec
|
|
231
|
+
known = ", ".join(s.name for s in _HARNESS_SPECS)
|
|
232
|
+
raise UnknownHarnessError(f"unknown harness {name!r}; known harnesses: {known}")
|
|
233
|
+
|
|
234
|
+
def is_available(self, name: str) -> bool:
|
|
235
|
+
spec = self.get(name)
|
|
236
|
+
return self._probe()(spec.cli)
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
# --- model registry data ----------------------------------------------------
|
|
240
|
+
|
|
241
|
+
# (model, default_lane, effort_ceiling). ``vendor_family`` is derived from the
|
|
242
|
+
# FROZEN ``schema.vendor_family`` projection (not retyped, so it can never drift
|
|
243
|
+
# from the governed-gate mapping). ``runnable_by`` is derived from that family
|
|
244
|
+
# across the six harnesses (a harness runs a model iff its lane vendor-family
|
|
245
|
+
# matches). ``default_lane`` is PINNED to a built-3 leg so a bare seat resolves
|
|
246
|
+
# onto the native lane — e.g. ``gpt-5.5`` is runnable by both ``codex`` and
|
|
247
|
+
# ``opencode`` but a bare ``gpt-5.5`` seat MUST resolve to ``codex`` or the
|
|
248
|
+
# default board's back-compat breaks. ``effort_ceiling`` defaults to the ladder
|
|
249
|
+
# max; lower it only where there is concrete evidence a model caps out below max
|
|
250
|
+
# (none of the built-3 do — codex's ``xhigh`` IS canonical ``max``).
|
|
251
|
+
_MODEL_DEFS: tuple[tuple[str, str, str], ...] = (
|
|
252
|
+
("gpt-5.5", "codex", "max"),
|
|
253
|
+
("claude-sonnet-5", "claude", "max"),
|
|
254
|
+
("claude-opus-4-8", "claude", "max"),
|
|
255
|
+
("claude-haiku-4-5", "claude", "max"),
|
|
256
|
+
("claude-fable-5", "claude", "max"),
|
|
257
|
+
("Gemini 3.1 Pro", "gemini", "max"),
|
|
258
|
+
)
|
|
259
|
+
|
|
260
|
+
|
|
261
|
+
def _runnable_by(model_vendor: str) -> tuple[str, ...]:
|
|
262
|
+
"""Harness lanes that can run a model of ``model_vendor``: those whose lane
|
|
263
|
+
vendor-family matches. Derived from the six registered harnesses so a new
|
|
264
|
+
harness automatically joins its family's runnable set."""
|
|
265
|
+
return tuple(s.name for s in _HARNESS_SPECS if vendor_of_harness(s.name) == model_vendor)
|
|
266
|
+
|
|
267
|
+
|
|
268
|
+
def _build_model_specs() -> tuple[ModelSpec, ...]:
|
|
269
|
+
specs: list[ModelSpec] = []
|
|
270
|
+
for model, default_lane, ceiling in _MODEL_DEFS:
|
|
271
|
+
family = vendor_family(model, default_lane)
|
|
272
|
+
specs.append(
|
|
273
|
+
ModelSpec(
|
|
274
|
+
model=model,
|
|
275
|
+
vendor_family=family,
|
|
276
|
+
default_lane=default_lane,
|
|
277
|
+
runnable_by=_runnable_by(family),
|
|
278
|
+
effort_ceiling=ceiling,
|
|
279
|
+
)
|
|
280
|
+
)
|
|
281
|
+
return tuple(specs)
|
|
282
|
+
|
|
283
|
+
|
|
284
|
+
_MODEL_SPECS: tuple[ModelSpec, ...] = _build_model_specs()
|
|
285
|
+
|
|
286
|
+
|
|
287
|
+
@dataclass
|
|
288
|
+
class DefaultModelRegistry:
|
|
289
|
+
"""Populated ``ModelRegistry``. ``get`` / ``default_lane`` raise
|
|
290
|
+
``UnknownModelError`` (with the known-model list) for an unregistered model —
|
|
291
|
+
this IS the unknown-model config-time rejection."""
|
|
292
|
+
|
|
293
|
+
def list_models(self) -> tuple[ModelSpec, ...]:
|
|
294
|
+
return _MODEL_SPECS
|
|
295
|
+
|
|
296
|
+
def get(self, model: str) -> ModelSpec:
|
|
297
|
+
for spec in _MODEL_SPECS:
|
|
298
|
+
if spec.model == model:
|
|
299
|
+
return spec
|
|
300
|
+
known = ", ".join(s.model for s in _MODEL_SPECS)
|
|
301
|
+
raise UnknownModelError(f"unknown model {model!r}; known models: {known}")
|
|
302
|
+
|
|
303
|
+
def default_lane(self, model: str) -> str:
|
|
304
|
+
return self.get(model).default_lane
|
|
305
|
+
|
|
306
|
+
|
|
307
|
+
# Module-level singletons the matrix / config loader default to.
|
|
308
|
+
DEFAULT_HARNESS_REGISTRY = DefaultHarnessRegistry()
|
|
309
|
+
DEFAULT_MODEL_REGISTRY = DefaultModelRegistry()
|