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,656 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
import hashlib
|
|
5
|
+
import os
|
|
6
|
+
import re
|
|
7
|
+
import site
|
|
8
|
+
import sysconfig
|
|
9
|
+
import types
|
|
10
|
+
from dataclasses import dataclass
|
|
11
|
+
from functools import lru_cache
|
|
12
|
+
from pathlib import Path
|
|
13
|
+
from typing import Any, Literal
|
|
14
|
+
|
|
15
|
+
from pydantic import BaseModel, ConfigDict, Field, ValidationError, field_validator
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class BamlValidationError(ValueError):
|
|
19
|
+
"""Local, redacted BAML validation failure."""
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class PhaseLoopCloseoutV1(BaseModel):
|
|
23
|
+
model_config = ConfigDict(extra="forbid")
|
|
24
|
+
|
|
25
|
+
terminal_status: str
|
|
26
|
+
verification_status: Literal["not_run", "passed", "failed", "blocked"]
|
|
27
|
+
dirty_paths: list[str]
|
|
28
|
+
produced_if_gates: list[str]
|
|
29
|
+
next_action: str | None = None
|
|
30
|
+
blocker_class: str | None = None
|
|
31
|
+
blocker_summary: str | None = None
|
|
32
|
+
human_required: bool | None = None
|
|
33
|
+
required_human_inputs: list[str]
|
|
34
|
+
|
|
35
|
+
@field_validator("terminal_status")
|
|
36
|
+
@classmethod
|
|
37
|
+
def _terminal_status_literal(cls, value: str) -> str:
|
|
38
|
+
PHASE_STATUSES = _enum_literals("terminal_status")
|
|
39
|
+
if value not in PHASE_STATUSES:
|
|
40
|
+
raise ValueError(f"invalid terminal_status: {value}")
|
|
41
|
+
return value
|
|
42
|
+
|
|
43
|
+
@field_validator("blocker_class")
|
|
44
|
+
@classmethod
|
|
45
|
+
def _blocker_class_literal(cls, value: str | None) -> str | None:
|
|
46
|
+
BLOCKER_CLASSES = _enum_literals("blocker_class")
|
|
47
|
+
if value is not None and value not in (*BLOCKER_CLASSES, "none"):
|
|
48
|
+
raise ValueError(f"invalid blocker_class: {value}")
|
|
49
|
+
return value
|
|
50
|
+
|
|
51
|
+
@field_validator("produced_if_gates")
|
|
52
|
+
@classmethod
|
|
53
|
+
def _complete_requires_gates(cls, value: list[str], info) -> list[str]:
|
|
54
|
+
if info.data.get("terminal_status") == "complete" and not value:
|
|
55
|
+
raise ValueError("completed closeout reported zero produced_if_gates")
|
|
56
|
+
return value
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
@dataclass(frozen=True)
|
|
60
|
+
class BamlRequest:
|
|
61
|
+
id: str | None
|
|
62
|
+
url: str
|
|
63
|
+
method: str
|
|
64
|
+
headers: dict[str, str]
|
|
65
|
+
body: dict[str, Any]
|
|
66
|
+
prompt: str
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
@dataclass(frozen=True)
|
|
70
|
+
class ParsedResponse:
|
|
71
|
+
function_name: str
|
|
72
|
+
payload: dict[str, Any]
|
|
73
|
+
value: Any
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def build_baml_request(function_name: str, payload: dict[str, Any] | None = None) -> BamlRequest:
|
|
77
|
+
if function_name == "EmitPhaseCloseout":
|
|
78
|
+
return _build_emit_phase_closeout_request(payload or {})
|
|
79
|
+
|
|
80
|
+
runtime, ctx_manager = _runtime()
|
|
81
|
+
try:
|
|
82
|
+
request = runtime.build_request_sync(
|
|
83
|
+
function_name,
|
|
84
|
+
payload or {},
|
|
85
|
+
ctx_manager.clone_context(),
|
|
86
|
+
None,
|
|
87
|
+
None,
|
|
88
|
+
_filtered_env(),
|
|
89
|
+
False,
|
|
90
|
+
)
|
|
91
|
+
except Exception as exc: # pragma: no cover - exact BAML errors vary by version
|
|
92
|
+
_raise_baml_validation_error(exc)
|
|
93
|
+
except BaseException as exc: # pragma: no cover - depends on PyO3 runtime panics
|
|
94
|
+
if _is_pyo3_panic(exc):
|
|
95
|
+
_raise_baml_validation_error(exc)
|
|
96
|
+
raise
|
|
97
|
+
body = request.body.json()
|
|
98
|
+
return BamlRequest(
|
|
99
|
+
id=getattr(request, "id", None),
|
|
100
|
+
url=str(request.url),
|
|
101
|
+
method=str(request.method),
|
|
102
|
+
headers={str(key): str(value) for key, value in dict(request.headers).items()},
|
|
103
|
+
body=body,
|
|
104
|
+
prompt=_extract_prompt(body),
|
|
105
|
+
)
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def parse_baml_response(function_name: str, raw_text: str) -> ParsedResponse:
|
|
109
|
+
if _is_class_name(function_name):
|
|
110
|
+
schema = export_function_schema(function_name)
|
|
111
|
+
payload = _find_json_payload(str(raw_text or ""))
|
|
112
|
+
_validate_payload_against_schema(payload, schema)
|
|
113
|
+
return ParsedResponse(function_name=function_name, payload=payload, value=payload)
|
|
114
|
+
|
|
115
|
+
runtime, ctx_manager = _runtime()
|
|
116
|
+
enum_module, class_module = _type_modules()
|
|
117
|
+
try:
|
|
118
|
+
value = runtime.parse_llm_response(
|
|
119
|
+
function_name,
|
|
120
|
+
str(raw_text or ""),
|
|
121
|
+
enum_module,
|
|
122
|
+
class_module,
|
|
123
|
+
class_module,
|
|
124
|
+
False,
|
|
125
|
+
ctx_manager.clone_context(),
|
|
126
|
+
None,
|
|
127
|
+
None,
|
|
128
|
+
_filtered_env(),
|
|
129
|
+
)
|
|
130
|
+
if isinstance(value, PhaseLoopCloseoutV1):
|
|
131
|
+
typed = value
|
|
132
|
+
elif hasattr(value, "model_dump"):
|
|
133
|
+
typed = PhaseLoopCloseoutV1.model_validate(value.model_dump())
|
|
134
|
+
elif isinstance(value, dict):
|
|
135
|
+
typed = PhaseLoopCloseoutV1.model_validate(value)
|
|
136
|
+
else:
|
|
137
|
+
typed = PhaseLoopCloseoutV1.model_validate(_find_json_payload(str(raw_text or "")))
|
|
138
|
+
except Exception as exc:
|
|
139
|
+
_raise_baml_validation_error(exc)
|
|
140
|
+
except BaseException as exc: # pragma: no cover - depends on PyO3 runtime panics
|
|
141
|
+
if _is_pyo3_panic(exc):
|
|
142
|
+
_raise_baml_validation_error(exc)
|
|
143
|
+
raise
|
|
144
|
+
return ParsedResponse(function_name=function_name, payload=typed.model_dump(), value=typed)
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
def export_function_schema(function_name: str) -> dict[str, Any]:
|
|
148
|
+
baml_files = _read_baml_files()
|
|
149
|
+
baml_text = "\n".join(baml_files.values())
|
|
150
|
+
return_type = _export_target_type(baml_text, function_name)
|
|
151
|
+
fields = _class_fields(baml_text, return_type)
|
|
152
|
+
enum_literals = _enum_literal_map()
|
|
153
|
+
required = _required_fields(return_type, fields)
|
|
154
|
+
properties = {
|
|
155
|
+
field_name: _schema_for_baml_field(baml_text, field_name, field_type, optional, enum_literals, seen=(return_type,))
|
|
156
|
+
for field_name, field_type, optional in fields
|
|
157
|
+
}
|
|
158
|
+
return {
|
|
159
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
160
|
+
"title": "PhaseLoopNativeCloseout" if return_type == "PhaseLoopCloseoutV1" else return_type,
|
|
161
|
+
"type": "object",
|
|
162
|
+
"additionalProperties": False,
|
|
163
|
+
"required": required,
|
|
164
|
+
"properties": properties,
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
def inject_schema_description(prompt: str, schema: dict[str, Any]) -> str:
|
|
169
|
+
rendered = _render_schema_description(schema)
|
|
170
|
+
body = str(prompt or "").strip()
|
|
171
|
+
return f"{rendered}\n\n{body}" if body else rendered
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
def render_baml_prompt(prompt_template: str, context_constants: dict[str, Any]) -> str:
|
|
175
|
+
def replace(match: re.Match[str]) -> str:
|
|
176
|
+
expression = match.group("expression").strip()
|
|
177
|
+
name_match = re.fullmatch(r"([A-Za-z_][A-Za-z0-9_]*)", expression)
|
|
178
|
+
join_match = re.fullmatch(r"([A-Za-z_][A-Za-z0-9_]*)\s*\|\s*join\((['\"])(.*?)\2\)", expression)
|
|
179
|
+
if join_match:
|
|
180
|
+
name = join_match.group(1)
|
|
181
|
+
if name not in context_constants:
|
|
182
|
+
if _is_taxonomy_constant(name):
|
|
183
|
+
raise BamlValidationError(f"BAML prompt taxonomy constant not found: {name}")
|
|
184
|
+
return match.group(0)
|
|
185
|
+
value = context_constants[name]
|
|
186
|
+
if not isinstance(value, (list, tuple)):
|
|
187
|
+
raise BamlValidationError(f"BAML prompt taxonomy constant is not joinable: {name}")
|
|
188
|
+
return join_match.group(3).join(str(item) for item in value)
|
|
189
|
+
if name_match:
|
|
190
|
+
name = name_match.group(1)
|
|
191
|
+
if name not in context_constants:
|
|
192
|
+
if _is_taxonomy_constant(name):
|
|
193
|
+
raise BamlValidationError(f"BAML prompt taxonomy constant not found: {name}")
|
|
194
|
+
return match.group(0)
|
|
195
|
+
return str(context_constants[name])
|
|
196
|
+
return match.group(0)
|
|
197
|
+
|
|
198
|
+
return re.sub(r"\{\{\s*(?P<expression>.*?)\s*\}\}", replace, str(prompt_template or ""))
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
@lru_cache(maxsize=1)
|
|
202
|
+
def _runtime():
|
|
203
|
+
from baml_py import BamlCtxManager, BamlRuntime
|
|
204
|
+
|
|
205
|
+
files = _read_baml_files()
|
|
206
|
+
runtime = BamlRuntime.from_files("baml_src", files, _filtered_env())
|
|
207
|
+
return runtime, BamlCtxManager(runtime)
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
def _read_baml_files() -> dict[str, str]:
|
|
211
|
+
src_dir = _baml_src_dir()
|
|
212
|
+
context_constants = _baml_prompt_context_constants()
|
|
213
|
+
return {
|
|
214
|
+
path.name: render_baml_prompt(path.read_text(encoding="utf-8"), context_constants)
|
|
215
|
+
for path in sorted(src_dir.glob("*.baml"))
|
|
216
|
+
if path.is_file()
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
def _baml_prompt_context_constants() -> dict[str, tuple[str, ...]]:
|
|
221
|
+
from . import models
|
|
222
|
+
|
|
223
|
+
return {
|
|
224
|
+
"allowed_terminal_statuses": tuple(models.PHASE_STATUSES),
|
|
225
|
+
"allowed_verification_statuses": ("not_run", "passed", "failed", "blocked"),
|
|
226
|
+
"allowed_blocker_classes": (*models.BLOCKER_CLASSES, "none"),
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
|
|
230
|
+
def _is_taxonomy_constant(name: str) -> bool:
|
|
231
|
+
return name in {"allowed_terminal_statuses", "allowed_verification_statuses", "allowed_blocker_classes"}
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
def _baml_src_dir() -> Path:
|
|
235
|
+
# Primary: the packaged baml_src shipped as package-data inside
|
|
236
|
+
# phase_loop_runtime, resolved via importlib.resources so it travels in the
|
|
237
|
+
# wheel regardless of installer (DECOUPLE SL-0/SL-2). The legacy candidates
|
|
238
|
+
# are kept as a fallback for editable/source layouts and the old data-files
|
|
239
|
+
# share/ install, but resolution no longer depends on a repo-relative walk.
|
|
240
|
+
from .runtime_resources import package_root
|
|
241
|
+
|
|
242
|
+
root = package_root()
|
|
243
|
+
if root is not None:
|
|
244
|
+
packaged = root / "baml_src"
|
|
245
|
+
if (packaged / "emit_phase_closeout.baml").is_file():
|
|
246
|
+
return packaged
|
|
247
|
+
candidates = [
|
|
248
|
+
# In-package source/editable layout (the same dir importlib.resources
|
|
249
|
+
# resolves once installed). The old repo-root vendor/.../baml_src candidate
|
|
250
|
+
# was removed in DECOUPLE -- that path no longer exists after the move.
|
|
251
|
+
Path(__file__).resolve().parent / "baml_src",
|
|
252
|
+
Path(sysconfig.get_paths().get("data", "")) / "share" / "phase-loop-runtime" / "baml_src",
|
|
253
|
+
Path(site.USER_BASE) / "share" / "phase-loop-runtime" / "baml_src",
|
|
254
|
+
Path(__file__).resolve().parents[4] / "share" / "phase-loop-runtime" / "baml_src",
|
|
255
|
+
]
|
|
256
|
+
for candidate in candidates:
|
|
257
|
+
if (candidate / "emit_phase_closeout.baml").exists():
|
|
258
|
+
return candidate
|
|
259
|
+
raise BamlValidationError("BAML source file not found: emit_phase_closeout.baml")
|
|
260
|
+
|
|
261
|
+
|
|
262
|
+
def _function_return_type(baml_text: str, function_name: str) -> str:
|
|
263
|
+
match = re.search(rf"\bfunction\s+{re.escape(function_name)}\s*\([^)]*\)\s*->\s*([A-Za-z_][A-Za-z0-9_]*)\s*\{{", baml_text, re.DOTALL)
|
|
264
|
+
if not match:
|
|
265
|
+
raise BamlValidationError(f"BAML function not found: {function_name}")
|
|
266
|
+
return match.group(1)
|
|
267
|
+
|
|
268
|
+
|
|
269
|
+
def _export_target_type(baml_text: str, name: str) -> str:
|
|
270
|
+
try:
|
|
271
|
+
return _function_return_type(baml_text, name)
|
|
272
|
+
except BamlValidationError:
|
|
273
|
+
if _class_exists(baml_text, name):
|
|
274
|
+
return name
|
|
275
|
+
raise
|
|
276
|
+
|
|
277
|
+
|
|
278
|
+
def _is_class_name(name: str) -> bool:
|
|
279
|
+
return _class_exists("\n".join(_read_baml_files().values()), name)
|
|
280
|
+
|
|
281
|
+
|
|
282
|
+
def _class_exists(baml_text: str, class_name: str) -> bool:
|
|
283
|
+
return bool(re.search(rf"\bclass\s+{re.escape(class_name)}\s*\{{", baml_text))
|
|
284
|
+
|
|
285
|
+
|
|
286
|
+
def _class_fields(baml_text: str, class_name: str) -> list[tuple[str, str, bool]]:
|
|
287
|
+
match = re.search(rf"\bclass\s+{re.escape(class_name)}\s*\{{(?P<body>.*?)\n\}}", baml_text, re.DOTALL)
|
|
288
|
+
if not match:
|
|
289
|
+
raise BamlValidationError(f"BAML class not found: {class_name}")
|
|
290
|
+
fields: list[tuple[str, str, bool]] = []
|
|
291
|
+
for raw_line in match.group("body").splitlines():
|
|
292
|
+
line = raw_line.strip()
|
|
293
|
+
if not line or line.startswith("//"):
|
|
294
|
+
continue
|
|
295
|
+
field_match = re.fullmatch(r"([A-Za-z_][A-Za-z0-9_]*)\s+([A-Za-z_][A-Za-z0-9_]*(?:\[\])?)(\?)?", line)
|
|
296
|
+
if not field_match:
|
|
297
|
+
raise BamlValidationError(f"unsupported BAML class field syntax in {class_name}: {line}")
|
|
298
|
+
fields.append((field_match.group(1), field_match.group(2), bool(field_match.group(3))))
|
|
299
|
+
if not fields:
|
|
300
|
+
raise BamlValidationError(f"BAML class has no exportable fields: {class_name}")
|
|
301
|
+
return fields
|
|
302
|
+
|
|
303
|
+
|
|
304
|
+
@lru_cache(maxsize=1)
|
|
305
|
+
def _enum_literal_map() -> dict[str, tuple[str, ...]]:
|
|
306
|
+
baml_text = "\n".join(_read_baml_files().values())
|
|
307
|
+
result: dict[str, list[str]] = {}
|
|
308
|
+
current: str | None = None
|
|
309
|
+
for raw_line in baml_text.splitlines():
|
|
310
|
+
line = raw_line.strip()
|
|
311
|
+
header = re.fullmatch(r"//\s*([A-Za-z_][A-Za-z0-9_]*)\s+enum literals:\s*(.*)", line)
|
|
312
|
+
if header:
|
|
313
|
+
current = header.group(1)
|
|
314
|
+
result[current] = []
|
|
315
|
+
_extend_enum_literals(result[current], header.group(2))
|
|
316
|
+
continue
|
|
317
|
+
if current and line.startswith("//"):
|
|
318
|
+
content = line[2:].strip()
|
|
319
|
+
if " enum literals:" in content:
|
|
320
|
+
current = None
|
|
321
|
+
continue
|
|
322
|
+
_extend_enum_literals(result[current], content)
|
|
323
|
+
continue
|
|
324
|
+
if current and line and not line.startswith("//"):
|
|
325
|
+
current = None
|
|
326
|
+
from . import models
|
|
327
|
+
|
|
328
|
+
result["terminal_status"] = list(models.PHASE_STATUSES)
|
|
329
|
+
result["verification_status"] = ["not_run", "passed", "failed", "blocked"]
|
|
330
|
+
result["blocker_class"] = [*models.BLOCKER_CLASSES, "none"]
|
|
331
|
+
return {key: tuple(values) for key, values in result.items()}
|
|
332
|
+
|
|
333
|
+
|
|
334
|
+
def _extend_enum_literals(values: list[str], text: str) -> None:
|
|
335
|
+
for item in text.split(","):
|
|
336
|
+
literal = item.strip().strip("`.")
|
|
337
|
+
if literal:
|
|
338
|
+
values.append(literal)
|
|
339
|
+
|
|
340
|
+
|
|
341
|
+
def _enum_literals(field_name: str) -> tuple[str, ...]:
|
|
342
|
+
values = _enum_literal_map().get(field_name)
|
|
343
|
+
if not values:
|
|
344
|
+
raise BamlValidationError(f"BAML enum literals not found for field: {field_name}")
|
|
345
|
+
return values
|
|
346
|
+
|
|
347
|
+
|
|
348
|
+
def _schema_for_baml_field(
|
|
349
|
+
baml_text: str,
|
|
350
|
+
field_name: str,
|
|
351
|
+
field_type: str,
|
|
352
|
+
optional: bool,
|
|
353
|
+
enum_literals: dict[str, tuple[str, ...]],
|
|
354
|
+
*,
|
|
355
|
+
seen: tuple[str, ...],
|
|
356
|
+
) -> dict[str, Any]:
|
|
357
|
+
array_item_type = field_type[:-2] if field_type.endswith("[]") else None
|
|
358
|
+
if field_type == "string":
|
|
359
|
+
schema: dict[str, Any] = {"type": ["string", "null"] if optional else "string"}
|
|
360
|
+
elif field_type == "bool":
|
|
361
|
+
schema = {"type": ["boolean", "null"] if optional else "boolean"}
|
|
362
|
+
elif field_type == "float":
|
|
363
|
+
schema = {"type": ["number", "null"] if optional else "number"}
|
|
364
|
+
elif field_type == "int":
|
|
365
|
+
schema = {"type": ["integer", "null"] if optional else "integer"}
|
|
366
|
+
elif array_item_type == "string":
|
|
367
|
+
if optional:
|
|
368
|
+
schema = {"type": ["array", "null"], "items": {"type": "string"}}
|
|
369
|
+
else:
|
|
370
|
+
schema = {"type": "array", "items": {"type": "string"}}
|
|
371
|
+
elif array_item_type and _class_exists(baml_text, array_item_type):
|
|
372
|
+
item_schema = _schema_for_baml_class(baml_text, array_item_type, enum_literals, seen=seen)
|
|
373
|
+
if optional:
|
|
374
|
+
schema = {"type": ["array", "null"], "items": item_schema}
|
|
375
|
+
else:
|
|
376
|
+
schema = {"type": "array", "items": item_schema}
|
|
377
|
+
elif _class_exists(baml_text, field_type):
|
|
378
|
+
object_schema = _schema_for_baml_class(baml_text, field_type, enum_literals, seen=seen)
|
|
379
|
+
if optional:
|
|
380
|
+
schema = {**object_schema, "type": ["object", "null"]}
|
|
381
|
+
else:
|
|
382
|
+
schema = object_schema
|
|
383
|
+
else:
|
|
384
|
+
raise BamlValidationError(f"unsupported BAML field type for schema export: {field_type}")
|
|
385
|
+
if field_name in enum_literals:
|
|
386
|
+
enum_values: list[str | None] = list(enum_literals[field_name])
|
|
387
|
+
if optional:
|
|
388
|
+
enum_values.append(None)
|
|
389
|
+
schema["enum"] = enum_values
|
|
390
|
+
description = _FIELD_DESCRIPTIONS.get(field_name)
|
|
391
|
+
if description:
|
|
392
|
+
schema["description"] = description
|
|
393
|
+
return schema
|
|
394
|
+
|
|
395
|
+
|
|
396
|
+
def _schema_for_baml_class(
|
|
397
|
+
baml_text: str,
|
|
398
|
+
class_name: str,
|
|
399
|
+
enum_literals: dict[str, tuple[str, ...]],
|
|
400
|
+
*,
|
|
401
|
+
seen: tuple[str, ...],
|
|
402
|
+
) -> dict[str, Any]:
|
|
403
|
+
if class_name in seen:
|
|
404
|
+
raise BamlValidationError(f"recursive BAML class export is unsupported: {class_name}")
|
|
405
|
+
fields = _class_fields(baml_text, class_name)
|
|
406
|
+
required = _required_fields(class_name, fields)
|
|
407
|
+
return {
|
|
408
|
+
"type": "object",
|
|
409
|
+
"additionalProperties": False,
|
|
410
|
+
"required": required,
|
|
411
|
+
"properties": {
|
|
412
|
+
field_name: _schema_for_baml_field(
|
|
413
|
+
baml_text,
|
|
414
|
+
field_name,
|
|
415
|
+
field_type,
|
|
416
|
+
optional,
|
|
417
|
+
enum_literals,
|
|
418
|
+
seen=(*seen, class_name),
|
|
419
|
+
)
|
|
420
|
+
for field_name, field_type, optional in fields
|
|
421
|
+
},
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
|
|
425
|
+
def _required_fields(class_name: str, fields: list[tuple[str, str, bool]]) -> list[str]:
|
|
426
|
+
if class_name == "PhaseLoopCloseoutV1":
|
|
427
|
+
return [field_name for field_name, _field_type, _optional in fields]
|
|
428
|
+
return [field_name for field_name, _field_type, optional in fields if not optional]
|
|
429
|
+
|
|
430
|
+
|
|
431
|
+
def _validate_payload_against_schema(payload: Any, schema: dict[str, Any], path: str = "$") -> None:
|
|
432
|
+
allowed_type = schema.get("type")
|
|
433
|
+
if isinstance(allowed_type, list) and payload is None and "null" in allowed_type:
|
|
434
|
+
return
|
|
435
|
+
effective_type = next((item for item in allowed_type if item != "null"), None) if isinstance(allowed_type, list) else allowed_type
|
|
436
|
+
if effective_type == "object":
|
|
437
|
+
if not isinstance(payload, dict):
|
|
438
|
+
raise BamlValidationError(f"{path} must be an object")
|
|
439
|
+
required = set(schema.get("required", ()))
|
|
440
|
+
missing = required.difference(payload)
|
|
441
|
+
extra = set(payload).difference(schema.get("properties", {}))
|
|
442
|
+
if missing:
|
|
443
|
+
raise BamlValidationError(f"{path} missing required fields: {', '.join(sorted(missing))}")
|
|
444
|
+
if schema.get("additionalProperties") is False and extra:
|
|
445
|
+
raise BamlValidationError(f"{path} has unsupported fields: {', '.join(sorted(extra))}")
|
|
446
|
+
for field_name, field_schema in schema.get("properties", {}).items():
|
|
447
|
+
if field_name in payload:
|
|
448
|
+
_validate_payload_against_schema(payload[field_name], field_schema, f"{path}.{field_name}")
|
|
449
|
+
elif effective_type == "array":
|
|
450
|
+
if not isinstance(payload, list):
|
|
451
|
+
raise BamlValidationError(f"{path} must be an array")
|
|
452
|
+
for index, item in enumerate(payload):
|
|
453
|
+
_validate_payload_against_schema(item, schema.get("items", {}), f"{path}[{index}]")
|
|
454
|
+
elif effective_type == "string":
|
|
455
|
+
if not isinstance(payload, str):
|
|
456
|
+
raise BamlValidationError(f"{path} must be a string")
|
|
457
|
+
elif effective_type == "boolean":
|
|
458
|
+
if not isinstance(payload, bool):
|
|
459
|
+
raise BamlValidationError(f"{path} must be a boolean")
|
|
460
|
+
elif effective_type == "number":
|
|
461
|
+
# JSON Schema "number" accepts both int and float (but rejects bool which subclasses int in Python)
|
|
462
|
+
if not isinstance(payload, (int, float)) or isinstance(payload, bool):
|
|
463
|
+
raise BamlValidationError(f"{path} must be a number")
|
|
464
|
+
elif effective_type == "integer":
|
|
465
|
+
if not isinstance(payload, int) or isinstance(payload, bool):
|
|
466
|
+
raise BamlValidationError(f"{path} must be an integer")
|
|
467
|
+
else:
|
|
468
|
+
raise BamlValidationError(f"{path} has unsupported schema type: {allowed_type}")
|
|
469
|
+
if "enum" in schema and payload not in schema["enum"]:
|
|
470
|
+
raise BamlValidationError(f"{path} has unsupported literal")
|
|
471
|
+
|
|
472
|
+
|
|
473
|
+
_FIELD_DESCRIPTIONS = {
|
|
474
|
+
"terminal_status": "Final phase status claimed by the executor closeout.",
|
|
475
|
+
"verification_status": "Verification outcome for the reported phase work.",
|
|
476
|
+
"dirty_paths": "Repo-relative dirty paths left after execution.",
|
|
477
|
+
"produced_if_gates": "Interface-freeze gates actually produced by this closeout.",
|
|
478
|
+
"next_action": "Concise next action for the operator or runner. May be null.",
|
|
479
|
+
"blocker_class": "Frozen blocker class when terminal_status is blocked. Null otherwise.",
|
|
480
|
+
"blocker_summary": "Actionable non-secret blocker summary. Null when not blocked.",
|
|
481
|
+
"human_required": "Whether the blocker requires a human decision. Null when not blocked.",
|
|
482
|
+
"required_human_inputs": "Non-secret human inputs required to unblock execution. Empty when not blocked.",
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
|
|
486
|
+
def _render_schema_description(schema: dict[str, Any]) -> str:
|
|
487
|
+
canonical = json.dumps(schema, sort_keys=True, separators=(",", ":"))
|
|
488
|
+
lines = [
|
|
489
|
+
"Phase-loop closeout JSON schema description:",
|
|
490
|
+
f"schema_sha256: {hashlib.sha256(canonical.encode('utf-8')).hexdigest()}",
|
|
491
|
+
f"type: {schema.get('type')}",
|
|
492
|
+
f"additionalProperties: {json.dumps(schema.get('additionalProperties'))}",
|
|
493
|
+
"required: " + ", ".join(str(field) for field in schema.get("required", ())),
|
|
494
|
+
"properties:",
|
|
495
|
+
]
|
|
496
|
+
for field_name in schema.get("required", ()):
|
|
497
|
+
field_schema = schema.get("properties", {}).get(field_name, {})
|
|
498
|
+
line = f"- {field_name}: type={json.dumps(field_schema.get('type'), sort_keys=True)}"
|
|
499
|
+
if "enum" in field_schema:
|
|
500
|
+
line += "; enum=" + ", ".join("null" if value is None else str(value) for value in field_schema["enum"])
|
|
501
|
+
if field_schema.get("items"):
|
|
502
|
+
line += "; items=" + json.dumps(field_schema["items"], sort_keys=True, separators=(",", ":"))
|
|
503
|
+
lines.append(line)
|
|
504
|
+
return "\n".join(lines)
|
|
505
|
+
|
|
506
|
+
|
|
507
|
+
def _build_emit_phase_closeout_request(payload: dict[str, Any]) -> BamlRequest:
|
|
508
|
+
prompt = _render_emit_phase_closeout_prompt(payload)
|
|
509
|
+
return BamlRequest(
|
|
510
|
+
id=None,
|
|
511
|
+
url="https://example.invalid/v1/chat/completions",
|
|
512
|
+
method="POST",
|
|
513
|
+
headers={"content-type": "application/json"},
|
|
514
|
+
body={
|
|
515
|
+
"model": "phase-loop-closeout",
|
|
516
|
+
"messages": [{"role": "user", "content": prompt}],
|
|
517
|
+
},
|
|
518
|
+
prompt=prompt,
|
|
519
|
+
)
|
|
520
|
+
|
|
521
|
+
|
|
522
|
+
def _render_emit_phase_closeout_prompt(payload: dict[str, Any]) -> str:
|
|
523
|
+
template = _function_prompt_template("EmitPhaseCloseout")
|
|
524
|
+
rendered = _render_baml_list_loop(template, "plan_produces", payload.get("plan_produces") or [])
|
|
525
|
+
rendered = _render_baml_list_loop(rendered, "plan_owned_files", payload.get("plan_owned_files") or [])
|
|
526
|
+
rendered = re.sub(
|
|
527
|
+
r"\{\{\s*closeout_commit_sha\s*\|\s*default\((['\"])none\1\)\s*\}\}",
|
|
528
|
+
str(payload.get("closeout_commit_sha") or "none"),
|
|
529
|
+
rendered,
|
|
530
|
+
)
|
|
531
|
+
rendered = re.sub(r"\{\{\s*ctx\.output_format\s*\}\}", _closeout_output_format(), rendered)
|
|
532
|
+
return render_baml_prompt(
|
|
533
|
+
rendered,
|
|
534
|
+
{
|
|
535
|
+
**_baml_prompt_context_constants(),
|
|
536
|
+
"phase_alias": str(payload.get("phase_alias") or ""),
|
|
537
|
+
},
|
|
538
|
+
).strip()
|
|
539
|
+
|
|
540
|
+
|
|
541
|
+
def _render_baml_list_loop(template: str, list_name: str, items: list[Any]) -> str:
|
|
542
|
+
pattern = re.compile(
|
|
543
|
+
r"\{%\s*for\s+(?P<var>[A-Za-z_][A-Za-z0-9_]*)\s+in\s+"
|
|
544
|
+
+ re.escape(list_name)
|
|
545
|
+
+ r"\s*%\}(?P<body>.*?)\{%\s*endfor\s*%\}",
|
|
546
|
+
re.DOTALL,
|
|
547
|
+
)
|
|
548
|
+
|
|
549
|
+
def replace(match: re.Match[str]) -> str:
|
|
550
|
+
loop_var = match.group("var")
|
|
551
|
+
body = match.group("body")
|
|
552
|
+
rendered_items = []
|
|
553
|
+
for item in items:
|
|
554
|
+
rendered_items.append(
|
|
555
|
+
re.sub(r"\{\{\s*" + re.escape(loop_var) + r"\s*\}\}", str(item), body)
|
|
556
|
+
)
|
|
557
|
+
return "".join(rendered_items)
|
|
558
|
+
|
|
559
|
+
return pattern.sub(replace, template)
|
|
560
|
+
|
|
561
|
+
|
|
562
|
+
def _function_prompt_template(function_name: str) -> str:
|
|
563
|
+
baml_text = (_baml_src_dir() / "emit_phase_closeout.baml").read_text(encoding="utf-8")
|
|
564
|
+
match = re.search(
|
|
565
|
+
rf"\bfunction\s+{re.escape(function_name)}\s*\([^)]*\)\s*->\s*[A-Za-z_][A-Za-z0-9_]*\s*\{{.*?prompt\s+#\"(?P<prompt>.*?)\"#",
|
|
566
|
+
baml_text,
|
|
567
|
+
re.DOTALL,
|
|
568
|
+
)
|
|
569
|
+
if not match:
|
|
570
|
+
raise BamlValidationError(f"BAML prompt not found: {function_name}")
|
|
571
|
+
return match.group("prompt")
|
|
572
|
+
|
|
573
|
+
|
|
574
|
+
def _closeout_output_format() -> str:
|
|
575
|
+
schema = export_function_schema("EmitPhaseCloseout")
|
|
576
|
+
lines = ["Answer in JSON using this schema:"]
|
|
577
|
+
for field_name in schema.get("required", ()):
|
|
578
|
+
field_schema = schema.get("properties", {}).get(field_name, {})
|
|
579
|
+
line = f"- {field_name}: {_schema_type_label(field_schema)}"
|
|
580
|
+
if "enum" in field_schema:
|
|
581
|
+
line += "; enum=" + ", ".join("null" if value is None else str(value) for value in field_schema["enum"])
|
|
582
|
+
lines.append(line)
|
|
583
|
+
lines.append("")
|
|
584
|
+
lines.append(_render_schema_description(schema))
|
|
585
|
+
return "\n".join(lines)
|
|
586
|
+
|
|
587
|
+
|
|
588
|
+
def _schema_type_label(field_schema: dict[str, Any]) -> str:
|
|
589
|
+
field_type = field_schema.get("type")
|
|
590
|
+
if isinstance(field_type, list):
|
|
591
|
+
return " | ".join(str(item) for item in field_type)
|
|
592
|
+
if field_type == "array":
|
|
593
|
+
item_type = field_schema.get("items", {}).get("type", "unknown")
|
|
594
|
+
return f"{item_type}[]"
|
|
595
|
+
if field_type == "integer":
|
|
596
|
+
return "int"
|
|
597
|
+
return str(field_type or "unknown")
|
|
598
|
+
|
|
599
|
+
|
|
600
|
+
@lru_cache(maxsize=1)
|
|
601
|
+
def _type_modules() -> tuple[types.ModuleType, types.ModuleType]:
|
|
602
|
+
enum_module = types.ModuleType("phase_loop_runtime.baml_enums")
|
|
603
|
+
class_module = types.ModuleType("phase_loop_runtime.baml_classes")
|
|
604
|
+
class_module.PhaseLoopCloseoutV1 = PhaseLoopCloseoutV1
|
|
605
|
+
return enum_module, class_module
|
|
606
|
+
|
|
607
|
+
|
|
608
|
+
def _filtered_env() -> dict[str, str]:
|
|
609
|
+
return {key: value for key, value in os.environ.items() if value is not None}
|
|
610
|
+
|
|
611
|
+
|
|
612
|
+
def _extract_prompt(body: dict[str, Any]) -> str:
|
|
613
|
+
parts: list[str] = []
|
|
614
|
+
for message in body.get("messages") or []:
|
|
615
|
+
content = message.get("content") if isinstance(message, dict) else None
|
|
616
|
+
if isinstance(content, list):
|
|
617
|
+
for item in content:
|
|
618
|
+
if isinstance(item, dict) and isinstance(item.get("text"), str):
|
|
619
|
+
parts.append(item["text"])
|
|
620
|
+
elif content is not None:
|
|
621
|
+
parts.append(str(content))
|
|
622
|
+
return "\n\n".join(part for part in parts if part).strip()
|
|
623
|
+
|
|
624
|
+
|
|
625
|
+
def _find_json_payload(text: str) -> dict[str, Any]:
|
|
626
|
+
decoder = json.JSONDecoder()
|
|
627
|
+
for index, char in enumerate(text):
|
|
628
|
+
if char != "{":
|
|
629
|
+
continue
|
|
630
|
+
try:
|
|
631
|
+
data, _end = decoder.raw_decode(text[index:])
|
|
632
|
+
except json.JSONDecodeError:
|
|
633
|
+
continue
|
|
634
|
+
if isinstance(data, dict):
|
|
635
|
+
return data
|
|
636
|
+
raise BamlValidationError("no JSON object found in BAML response")
|
|
637
|
+
|
|
638
|
+
|
|
639
|
+
def _sanitize_error(exc: BaseException) -> str:
|
|
640
|
+
message = str(exc)
|
|
641
|
+
if isinstance(exc, ValidationError):
|
|
642
|
+
message = "; ".join(error.get("msg", "validation error") for error in exc.errors())
|
|
643
|
+
message = re.sub(r"(?i)(api[_-]?key|authorization|token|secret|password)[^\\s,;]*", r"\\1=<redacted>", message)
|
|
644
|
+
message = " ".join(message.split())
|
|
645
|
+
if len(message) > 500:
|
|
646
|
+
message = message[:497] + "..."
|
|
647
|
+
return message or exc.__class__.__name__
|
|
648
|
+
|
|
649
|
+
|
|
650
|
+
def _is_pyo3_panic(exc: BaseException) -> bool:
|
|
651
|
+
cls = exc.__class__
|
|
652
|
+
return cls.__module__ == "pyo3_runtime" and cls.__name__ == "PanicException"
|
|
653
|
+
|
|
654
|
+
|
|
655
|
+
def _raise_baml_validation_error(exc: BaseException) -> None:
|
|
656
|
+
raise BamlValidationError(_sanitize_error(exc)) from exc
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
class DotfilesSourceRoot {
|
|
2
|
+
path_glob string
|
|
3
|
+
classification string
|
|
4
|
+
owner string
|
|
5
|
+
ingestion_policy string
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
class DotfilesSchemaRef {
|
|
9
|
+
class_name string
|
|
10
|
+
source_path string
|
|
11
|
+
digest string
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
class DotfilesC4Ref {
|
|
15
|
+
title string
|
|
16
|
+
source_path string
|
|
17
|
+
anchor string
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
class DotfilesTaskCatalogRef {
|
|
21
|
+
catalog_id string
|
|
22
|
+
source_path string
|
|
23
|
+
audience string
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
class DotfilesAdoptionManifest {
|
|
27
|
+
source_roots DotfilesSourceRoot[]
|
|
28
|
+
schema_refs DotfilesSchemaRef[]
|
|
29
|
+
plan_refs DotfilesPlanRef[]
|
|
30
|
+
c4_document_refs DotfilesC4Ref[]
|
|
31
|
+
task_catalog_refs DotfilesTaskCatalogRef[]
|
|
32
|
+
operating_mode string
|
|
33
|
+
redacted_metadata_ref string
|
|
34
|
+
visibility_contract_ref string
|
|
35
|
+
version string
|
|
36
|
+
generated_at string
|
|
37
|
+
}
|