phase-loop-runtime 0.7.3__tar.gz → 0.7.4__tar.gz
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-0.7.3 → phase_loop_runtime-0.7.4}/PKG-INFO +1 -1
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/pyproject.toml +1 -1
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/__init__.py +1 -1
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/panel_invoker.py +129 -13
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/train_roadmap.py +54 -8
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime.egg-info/PKG-INFO +1 -1
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime.egg-info/SOURCES.txt +1 -0
- phase_loop_runtime-0.7.4/tests/test_panel_tui_liveness_188.py +191 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_train_invariants.py +46 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_train_roadmap.py +79 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/MANIFEST.in +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/README.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/protocol/protocol.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/setup.cfg +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/_contract_docs/phase-loop/extraction-readiness.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/_contract_docs/phase-loop/granular-execution-policy.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/_contract_docs/phase-loop/harness-capability-matrix.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/_contract_docs/phase-loop/harness-skill-matrix.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/_contract_docs/phase-loop/harness-substrate-manifest.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/_contract_docs/phase-loop/pi-loop-control.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/_contract_docs/phase-loop/protocol.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/_contract_docs/phase-loop/runtime-boundary.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/_contract_docs/phase-loop/spec-discovery-roots.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/_contract_docs/phase-loop/substrate-soak-governed-pipeline.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/_contract_docs/phase-loop/substrate-soak-portal-projection.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/_contract_docs/phase-loop/substrate-soak-regenesis.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/_contract_docs/phase-loop/substrate-soak-report.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/_contract_docs/runtime/verification-evidence-contract.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/_proc_cpu.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/_test_fixtures/evidence-audit-calibration/borderline/borderline-mixed-signals/commands.txt +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/_test_fixtures/evidence-audit-calibration/borderline/borderline-mixed-signals/manifest.json +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/_test_fixtures/evidence-audit-calibration/borderline/borderline-mixed-signals/mixed.json +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/_test_fixtures/evidence-audit-calibration/borderline/borderline-provider-timeout/manifest.json +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/_test_fixtures/evidence-audit-calibration/borderline/borderline-provider-timeout/timeout-note.txt +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/_test_fixtures/evidence-audit-calibration/borderline/borderline-redacted-summary/manifest.json +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/_test_fixtures/evidence-audit-calibration/borderline/borderline-redacted-summary/redacted-summary.json +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/_test_fixtures/evidence-audit-calibration/borderline/borderline-small-sample/manifest.json +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/_test_fixtures/evidence-audit-calibration/borderline/borderline-small-sample/sample.json +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/_test_fixtures/evidence-audit-calibration/borderline/borderline-threshold-edge/edge.txt +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/_test_fixtures/evidence-audit-calibration/borderline/borderline-threshold-edge/manifest.json +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/_test_fixtures/evidence-audit-calibration/known-fake/fake-duplicate-png/manifest.json +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/_test_fixtures/evidence-audit-calibration/known-fake/fake-duplicate-png/shot-a.txt +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/_test_fixtures/evidence-audit-calibration/known-fake/fake-duplicate-png/shot-b.txt +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/_test_fixtures/evidence-audit-calibration/known-fake/fake-duplicate-png/shot-c.txt +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/_test_fixtures/evidence-audit-calibration/known-fake/fake-missing-references/claimed-results.json +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/_test_fixtures/evidence-audit-calibration/known-fake/fake-missing-references/manifest.json +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/_test_fixtures/evidence-audit-calibration/known-fake/fake-subtle-low-variance/manifest.json +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/_test_fixtures/evidence-audit-calibration/known-fake/fake-subtle-low-variance/metrics.json +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/_test_fixtures/evidence-audit-calibration/known-fake/fake-templated-prose/findings.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/_test_fixtures/evidence-audit-calibration/known-fake/fake-templated-prose/manifest.json +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/_test_fixtures/evidence-audit-calibration/known-fake/fake-uniform-scores/manifest.json +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/_test_fixtures/evidence-audit-calibration/known-fake/fake-uniform-scores/scores.json +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/_test_fixtures/evidence-audit-calibration/known-fake/fake-uniform-scores/summary.txt +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/_test_fixtures/evidence-audit-calibration/known-real/real-adoption-bundle/bundle-check.json +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/_test_fixtures/evidence-audit-calibration/known-real/real-adoption-bundle/manifest.json +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/_test_fixtures/evidence-audit-calibration/known-real/real-adoption-bundle/operator-note.txt +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/_test_fixtures/evidence-audit-calibration/known-real/real-handoff-ledger/events-sample.jsonl +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/_test_fixtures/evidence-audit-calibration/known-real/real-handoff-ledger/manifest.json +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/_test_fixtures/evidence-audit-calibration/known-real/real-handoff-ledger/receipt.txt +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/_test_fixtures/evidence-audit-calibration/known-real/real-runner-diff/evidence.json +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/_test_fixtures/evidence-audit-calibration/known-real/real-runner-diff/manifest.json +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/_test_fixtures/evidence-audit-calibration/known-real/real-runner-diff/summary.txt +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/_test_fixtures/evidence-audit-calibration/known-real/real-test-matrix/manifest.json +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/_test_fixtures/evidence-audit-calibration/known-real/real-test-matrix/matrix.json +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/_test_fixtures/evidence-audit-calibration/known-real/real-test-matrix/notes.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/_test_fixtures/evidence-audit-calibration/known-real/real-ui-screenshot-standin/console-summary.txt +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/_test_fixtures/evidence-audit-calibration/known-real/real-ui-screenshot-standin/manifest.json +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/_test_fixtures/evidence-audit-calibration/known-real/real-ui-screenshot-standin/screenshot-standin.ppm +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/adoption_bundle.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/advisor_board/CONTRACTS.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/advisor_board/__init__.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/advisor_board/backing.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/advisor_board/backing_omnigent.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/advisor_board/composition.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/advisor_board/config.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/advisor_board/events.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/advisor_board/fixtures/advisor-boards.example.toml +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/advisor_board/fixtures.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/advisor_board/harness_mapping.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/advisor_board/matrix.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/advisor_board/observability.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/advisor_board/presets.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/advisor_board/registries.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/advisor_board/resolver.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/advisor_board/schema.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/advisor_board/standin.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/advisor_board/validation.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/agent_runtime_provider.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/baml_modular.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/baml_src/dotfiles_adoption_manifest.baml +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/baml_src/dotfiles_c4_document.baml +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/baml_src/dotfiles_plan_manifest.baml +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/baml_src/dotfiles_runtime_projection.baml +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/baml_src/dotfiles_task_catalog.baml +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/baml_src/emit_phase_closeout.baml +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/baml_src/evaluate_suspected_fake_evidence.baml +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/baml_src/verification_evidence.baml +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/broker.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/build_bundle.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/capability_registry.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/classifier.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/claude_agent_view.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/claude_channel_sidecar.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/cli.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/closeout.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/closeout_classifier.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/closeout_evidence_audit.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/closeout_validation.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/closeout_validators.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/conformance/__init__.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/conformance/certificate_tier.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/conformance/git_grounded_projection.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/conformance/outside_agent_advisory.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/conformance/outside_agent_core.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/conformance/outside_agent_imports.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/conformance/outside_agent_pin.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/conformance/outside_agent_provenance.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/conformance/outside_agent_real.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/conformance/outside_agent_real_output.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/conformance/outside_agent_redaction.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/conformance/outside_agent_schema.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/conformance/outside_agent_vectors.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/consiliency_gates.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/consiliency_ingest.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/consiliency_layout.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/consiliency_scaffold.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/cross_repo_channel.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/default_executor_resolver.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/deploy/phase-loop-task-message-broker.service +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/discovery.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/dispatch_lock.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/doc_delta_validator.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/docs_audit.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/docs_freshness.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/docs_surfaces.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/doctor.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/dotfiles_profile_plugin.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/events.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/events_migration.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/evidence_audit.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/evidence_audit_config.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/executor_availability.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/fleet_map.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/fleet_metrics.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/fleet_metrics_export.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/gate_posture.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/git_discipline.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/git_ops.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/git_topology.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/governed_bundle.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/governed_premerge.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/governed_review.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/handoff.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/handoff_path.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/harness_env_signatures.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/injection.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/install_status.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/lane_scheduler.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/launcher.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/lease_store.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/maintenance.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/migrate_handoffs.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/models.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/observability.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/phase_loop_drift_audit.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/phase_worktree_executor.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/pipeline_adapter/__init__.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/pipeline_adapter/branch_ops.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/pipeline_adapter/flag.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/pipeline_adapter/markers.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/pipeline_adapter/merge_policy.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/pipeline_adapter/ratification.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/pipeline_adapter/sibling_matcher.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/plan_ir.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/plan_manifest.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/planner_validation.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/profiles.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/prompts.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/provenance.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/publishing.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/py.typed +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/ratification_policy.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/reconcile.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/redaction.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/reflection_sync.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/release_guard.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/render.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/repo_validation.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/review_summary.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/roadmap_authority.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/roadmap_lint.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/route_log.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/route_policy/__init__.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/route_policy/fixtures/route_selection.golden.json +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/runner.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/runtime_paths.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/runtime_projection.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/runtime_resources.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/schema_export.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/schemas/phase-loop-doctor.v1.golden.json +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/schemas/phase-loop-doctor.v1.schema.json +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/schemas/phase_loop_closeout.schema.json +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skill_install.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skill_inventory.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skill_paths.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skill_sources_plugin.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/claude-advisor-board/README.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/claude-advisor-board/SKILL.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/claude-advisor-panel/README.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/claude-advisor-panel/SKILL.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/claude-execute-detailed/README.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/claude-execute-detailed/SKILL.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/claude-execute-phase/README.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/claude-execute-phase/SKILL.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/claude-execute-phase/scripts/allocate_worktree_name.sh +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/claude-execute-phase/scripts/audit_lane_file_touches.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/claude-execute-phase/scripts/cleanup_lane_worktrees.sh +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/claude-execute-phase/scripts/parent_tree_leakage_check.sh +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/claude-execute-phase/scripts/post_merge_import_smoke.sh +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/claude-execute-phase/scripts/pre_merge_destructiveness_check.sh +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/claude-execute-phase/scripts/prune_merged_worktrees.sh +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/claude-execute-phase/scripts/resolve_branch_from_sha.sh +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/claude-execute-phase/scripts/state.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/claude-execute-phase/scripts/sweep_stale_worktrees.sh +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/claude-execute-phase/scripts/team_teardown.sh +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/claude-execute-phase/scripts/validate_plan_doc.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/claude-execute-phase/scripts/verify_harness.sh +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/claude-phase-loop/README.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/claude-phase-loop/SKILL.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/claude-phase-roadmap-builder/README.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/claude-phase-roadmap-builder/SKILL.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/claude-phase-roadmap-builder/assets/review_prompt.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/claude-phase-roadmap-builder/references/parallelization-heuristics.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/claude-phase-roadmap-builder/references/roadmap-template.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/claude-phase-roadmap-builder/scripts/validate_roadmap.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/claude-plan-detailed/README.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/claude-plan-detailed/SKILL.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/claude-plan-detailed/assets/review_prompt.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/claude-plan-phase/README.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/claude-plan-phase/SKILL.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/claude-plan-phase/assets/review_prompt.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/claude-plan-phase/scripts/validate_plan_doc.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/claude-run-train/README.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/claude-run-train/SKILL.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/claude-skill-editor/README.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/claude-skill-editor/SKILL.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/claude-skill-editor/assets/editor_prompt.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/claude-skill-improvement-planner/README.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/claude-skill-improvement-planner/SKILL.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/claude-skill-improvement-planner/assets/aggregator_prompt.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/claude-task-contextualizer/README.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/claude-task-contextualizer/SKILL.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/claude-task-contextualizer/references/task-templates.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/codex-advisor-board/README.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/codex-advisor-board/SKILL.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/codex-advisor-panel/README.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/codex-advisor-panel/SKILL.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/codex-execute-detailed/README.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/codex-execute-detailed/SKILL.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/codex-execute-phase/README.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/codex-execute-phase/SKILL.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/codex-execute-phase/scripts/allocate_worktree_name.sh +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/codex-execute-phase/scripts/audit_lane_file_touches.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/codex-execute-phase/scripts/cleanup_lane_worktrees.sh +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/codex-execute-phase/scripts/parent_tree_leakage_check.sh +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/codex-execute-phase/scripts/post_merge_import_smoke.sh +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/codex-execute-phase/scripts/pre_merge_destructiveness_check.sh +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/codex-execute-phase/scripts/prune_merged_worktrees.sh +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/codex-execute-phase/scripts/resolve_branch_from_sha.sh +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/codex-execute-phase/scripts/state.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/codex-execute-phase/scripts/sweep_stale_worktrees.sh +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/codex-execute-phase/scripts/team_teardown.sh +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/codex-execute-phase/scripts/validate_plan_doc.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/codex-execute-phase/scripts/verify_harness.sh +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/codex-phase-loop/README.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/codex-phase-loop/SKILL.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/codex-phase-roadmap-builder/README.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/codex-phase-roadmap-builder/SKILL.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/codex-phase-roadmap-builder/assets/review_prompt.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/codex-phase-roadmap-builder/references/parallelization-heuristics.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/codex-phase-roadmap-builder/references/roadmap-template.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/codex-phase-roadmap-builder/scripts/validate_roadmap.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/codex-plan-detailed/README.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/codex-plan-detailed/SKILL.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/codex-plan-detailed/assets/review_prompt.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/codex-plan-phase/README.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/codex-plan-phase/SKILL.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/codex-plan-phase/assets/review_prompt.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/codex-plan-phase/scripts/validate_plan_doc.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/codex-run-train/README.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/codex-run-train/SKILL.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/codex-skill-editor/README.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/codex-skill-editor/SKILL.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/codex-skill-editor/assets/editor_prompt.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/codex-skill-improvement-planner/README.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/codex-skill-improvement-planner/SKILL.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/codex-skill-improvement-planner/assets/aggregator_prompt.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/codex-task-contextualizer/README.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/codex-task-contextualizer/SKILL.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/codex-task-contextualizer/references/task-templates.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/gemini-advisor-board/README.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/gemini-advisor-board/SKILL.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/gemini-advisor-panel/README.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/gemini-advisor-panel/SKILL.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/gemini-execute-detailed/README.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/gemini-execute-detailed/SKILL.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/gemini-execute-phase/README.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/gemini-execute-phase/SKILL.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/gemini-execute-phase/scripts/allocate_worktree_name.sh +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/gemini-execute-phase/scripts/audit_lane_file_touches.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/gemini-execute-phase/scripts/cleanup_lane_worktrees.sh +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/gemini-execute-phase/scripts/parent_tree_leakage_check.sh +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/gemini-execute-phase/scripts/post_merge_import_smoke.sh +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/gemini-execute-phase/scripts/pre_merge_destructiveness_check.sh +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/gemini-execute-phase/scripts/prune_merged_worktrees.sh +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/gemini-execute-phase/scripts/resolve_branch_from_sha.sh +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/gemini-execute-phase/scripts/state.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/gemini-execute-phase/scripts/sweep_stale_worktrees.sh +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/gemini-execute-phase/scripts/team_teardown.sh +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/gemini-execute-phase/scripts/validate_plan_doc.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/gemini-execute-phase/scripts/verify_harness.sh +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/gemini-phase-loop/README.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/gemini-phase-loop/SKILL.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/gemini-phase-roadmap-builder/README.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/gemini-phase-roadmap-builder/SKILL.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/gemini-phase-roadmap-builder/assets/review_prompt.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/gemini-phase-roadmap-builder/references/parallelization-heuristics.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/gemini-phase-roadmap-builder/references/roadmap-template.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/gemini-phase-roadmap-builder/scripts/validate_roadmap.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/gemini-plan-detailed/README.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/gemini-plan-detailed/SKILL.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/gemini-plan-detailed/assets/review_prompt.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/gemini-plan-phase/README.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/gemini-plan-phase/SKILL.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/gemini-plan-phase/assets/review_prompt.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/gemini-plan-phase/scripts/validate_plan_doc.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/gemini-run-train/README.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/gemini-run-train/SKILL.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/gemini-skill-editor/README.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/gemini-skill-editor/SKILL.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/gemini-skill-editor/assets/editor_prompt.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/gemini-skill-improvement-planner/README.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/gemini-skill-improvement-planner/SKILL.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/gemini-skill-improvement-planner/assets/aggregator_prompt.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/gemini-task-contextualizer/README.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/gemini-task-contextualizer/SKILL.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/gemini-task-contextualizer/references/task-templates.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/opencode-advisor-board/README.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/opencode-advisor-board/SKILL.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/opencode-advisor-panel/README.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/opencode-advisor-panel/SKILL.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/opencode-execute-detailed/README.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/opencode-execute-detailed/SKILL.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/opencode-execute-phase/README.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/opencode-execute-phase/SKILL.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/opencode-execute-phase/scripts/allocate_worktree_name.sh +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/opencode-execute-phase/scripts/audit_lane_file_touches.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/opencode-execute-phase/scripts/cleanup_lane_worktrees.sh +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/opencode-execute-phase/scripts/parent_tree_leakage_check.sh +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/opencode-execute-phase/scripts/post_merge_import_smoke.sh +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/opencode-execute-phase/scripts/pre_merge_destructiveness_check.sh +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/opencode-execute-phase/scripts/prune_merged_worktrees.sh +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/opencode-execute-phase/scripts/resolve_branch_from_sha.sh +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/opencode-execute-phase/scripts/state.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/opencode-execute-phase/scripts/sweep_stale_worktrees.sh +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/opencode-execute-phase/scripts/team_teardown.sh +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/opencode-execute-phase/scripts/validate_plan_doc.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/opencode-execute-phase/scripts/verify_harness.sh +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/opencode-phase-loop/README.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/opencode-phase-loop/SKILL.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/opencode-phase-roadmap-builder/README.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/opencode-phase-roadmap-builder/SKILL.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/opencode-phase-roadmap-builder/assets/review_prompt.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/opencode-phase-roadmap-builder/references/parallelization-heuristics.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/opencode-phase-roadmap-builder/references/roadmap-template.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/opencode-phase-roadmap-builder/scripts/validate_roadmap.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/opencode-plan-detailed/README.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/opencode-plan-detailed/SKILL.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/opencode-plan-detailed/assets/review_prompt.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/opencode-plan-phase/README.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/opencode-plan-phase/SKILL.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/opencode-plan-phase/assets/review_prompt.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/opencode-plan-phase/scripts/validate_plan_doc.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/opencode-run-train/README.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/opencode-run-train/SKILL.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/opencode-skill-editor/README.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/opencode-skill-editor/SKILL.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/opencode-skill-editor/assets/editor_prompt.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/opencode-skill-improvement-planner/README.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/opencode-skill-improvement-planner/SKILL.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/opencode-skill-improvement-planner/assets/aggregator_prompt.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/opencode-task-contextualizer/README.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/opencode-task-contextualizer/SKILL.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/skills_bundle/opencode-task-contextualizer/references/task-templates.md +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/state.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/state_degradation.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/state_ops.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/task_message_broker.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/task_message_broker_client.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/task_message_resolver.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/train_ledger.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/train_runner.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/verification_evidence.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/verification_evidence_validator.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/visual_evidence_validator.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/worker_pool.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/worktree_index.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime.egg-info/dependency_links.txt +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime.egg-info/entry_points.txt +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime.egg-info/requires.txt +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime.egg-info/top_level.txt +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_advisor_board_advisory_mode.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_advisor_board_alias_install.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_advisor_board_backcompat.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_advisor_board_backing_homebrew.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_advisor_board_backing_omnigent.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_advisor_board_cli_legacy.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_advisor_board_composition.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_advisor_board_concurrency.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_advisor_board_config.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_advisor_board_golden.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_advisor_board_ingestion.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_advisor_board_integration.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_advisor_board_matrix.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_advisor_board_observability.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_advisor_board_presets.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_advisor_board_registries.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_advisor_board_resolver.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_advisor_board_schema.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_advisor_twin_alias_legacy.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_agent_runtime_provider_cs08.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_autosel.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_branchgov_preflight.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_certificate_tier.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_cli_train_status_45.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_closeout_break_glass_cli.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_closeout_classifier.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_closeout_convergence_fixes.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_closeout_exception_vocab.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_closeout_validator_hook.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_closeout_verification_gate.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_codex_effort_max_clamp_49.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_conformance_golden.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_consiliency_dual_layout.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_consiliency_gates.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_consiliency_ingest.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_consiliency_scaffold.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_coordinator_wave_loop.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_discovery_hygiene_legacy.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_dispatch_lock_cross_roadmap.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_dispatch_lock_helper.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_dispatch_lock_reentrancy.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_dispatch_lock_same_roadmap.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_doc_delta_validator.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_docs_audit.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_docs_freshness.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_doctor_bom.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_dotfiles_tree.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_execgov.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_execreg_launch_registry.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_execute_phase_handoff_mode.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_execution_policy_tiering.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_executor_availability.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_export_schema.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_fleet_map.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_fleet_metrics.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_fleet_metrics_export.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_gate_a_wheel_isolation.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_gate_posture.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_git_discipline.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_git_grounded_projection.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_governed_disjointness_model_first.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_governed_e2e.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_governed_gate_crfixes.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_governed_planning_gate.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_governed_premerge.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_governed_premerge_live.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_governed_review.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_grokexec.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_hotfix_lane.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_injection_skill_failloud.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_lane_ir_override.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_launcher_liveness.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_launchspec_golden.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_lease_store.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_lease_store_conformance.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_ledger_serialization.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_leg_liveness_monitor.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_manifest_per_entry_164.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_model_class_policy.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_model_id_source_guard.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_observability_alerting.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_outside_agent_advisory.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_outside_agent_advisory_cli.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_outside_agent_advisory_fixtures.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_outside_agent_authority_boundary.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_outside_agent_contract_drift.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_outside_agent_contract_imports.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_outside_agent_contract_pin.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_outside_agent_core_api.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_outside_agent_provenance.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_outside_agent_real_ci.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_outside_agent_real_cli.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_outside_agent_real_output.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_outside_agent_real_runtime.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_outside_agent_redaction.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_outside_agent_release_surface.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_outside_agent_schema_validation.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_outside_agent_vectors.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_panel_advisory_mode_63.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_panel_context_refs_114.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_panel_invoker.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_panel_invoker_spawn.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_panel_invoker_timeout_argv.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_panel_leg_auth_preflight_64.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_panel_native_fill_183.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_panel_per_leg_model_66.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_panel_streaming_verdicts.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_panel_tui_eof_48.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_panel_verdict_summary.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_parallel_dispatch_backcompat.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_parallel_dispatch_cli.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_adoption_bundle.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_adoption_bundle_cli.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_baml_dependency.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_baml_end_to_end.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_baml_injection.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_baml_modular.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_baml_prompt_taxonomy.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_baml_runner_closeout.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_baml_schema_export.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_baml_schema_source.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_branch_divergence_event.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_break_glass_rerun.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_build_bundle.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_classifier.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_claude_agent_view_adapter.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_claude_agent_view_lifecycle.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_claude_channel_hooks.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_claude_channel_mcp.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_claude_channel_security.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_claude_channel_session_launch.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_claude_channel_sidecar.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_claude_channel_smoke_suite.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_claude_route_selection.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_cli.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_cli_plugin_load.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_closeout_control_only.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_closeout_event.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_closeout_evidence_audit.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_closeout_hardening.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_closeout_owned_dirty_fallback.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_closeout_schema.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_closeout_validation.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_collaborator_citation.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_collaborator_docs.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_collaborator_rollback.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_concurrent_phase_dispatch.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_def4_writer_namespacing.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_dirty_path_classify_phase_owned_tests.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_dirty_path_classify_previous_phase_owned.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_discovery.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_docs.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_dotfiles_schemas.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_dotfiles_sources.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_downstream_governed_pipeline.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_downstream_instruction_scope_readme.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_downstream_portal.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_downstream_regenesis.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_drift_audit.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_dry_run_closeout_guard.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_dry_run_then_run.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_events_migration.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_evidence_audit.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_evidence_audit_runner.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_evidence_audit_tier2.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_evidence_audit_tier3.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_evidence_audit_tuning.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_execution_policy.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_executor_degradation.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_full_phase_mode.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_handoff.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_handoff_migration.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_init.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_injection.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_install_status.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_issue_84_explicit_phase.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_lane_harnesses.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_lane_ir.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_lane_ir_fixtures.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_lane_scheduler.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_launcher.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_ledger_debug.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_ledger_dedup.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_live_adapters.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_maintenance.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_metrics.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_migration_regressions.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_mixedrun_dispatch.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_mixedrun_matrix.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_mixedrun_observability.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_models.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_native_flags.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_parallel_plan_safe.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_pi_executor.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_pipeline_boundaries.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_pipeline_bridge.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_pipeline_bundle.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_pipeline_closeout.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_pipeline_freshness.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_pipeline_mode.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_plan_doc_skip.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_plan_manifest.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_planner_redispatch_when_plan_current.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_planner_validation.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_policy.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_protocol_contract.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_provenance.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_reconcile.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_reconcile_blocker_self_clear.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_reconcile_recovery_mode.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_reconcile_to_status_planned_recovery.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_reducers.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_repair_precondition_planned_closeout.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_repair_skipped_when_blocker_cleared.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_roadmap_amendments.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_roadmap_validate.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_rotation.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_runner.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_runner_closeout_validation.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_runtime_boundary.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_runtime_decouple.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_runtime_package_data.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_runtime_projection.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_schema_flow.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_skill_baml_closeout.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_skill_bridge_contract.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_skill_contract.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_skill_execute_contract.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_skill_install.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_skill_planner_contract.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_smoke_blockers.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_smoke_exhaustion.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_smoke_reentry.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_spurious_completion_rejection.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_start_gate_phase_status.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_start_gate_refuses_cross_phase_dirty.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_state.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_status_transition_events_emitted.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_substrate_soak_docs.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_substrate_soak_governed.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_substrate_soak_portal.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_terminal_summary_mirrors_baml_closeout.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_v22_e2e.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_v22_principles.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_v45_found_contracts.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_v45_reconcile.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_v45_sched.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_v45_schedharden.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_wave_runner.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_work_unit_observability.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_work_unit_runner.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_work_unit_state.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_loop_worktrees.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_owned_dirty_relaxation.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_phase_worktree_executor.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_pipeline_adapter_branch_ops_create.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_pipeline_adapter_branch_ops_rebase_conflict.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_pipeline_adapter_branch_ops_refuse_default.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_pipeline_adapter_flag.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_pipeline_adapter_markers.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_pipeline_adapter_merge_policy_parse.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_pipeline_adapter_ratification_event_payload.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_pipeline_adapter_ratification_runner.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_pipeline_adapter_ratification_skipped_standalone.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_pipeline_adapter_standalone_regression.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_pkg_layout_freeze.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_plan_ir_iter_waves.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_preflight_verification.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_proc_cpu.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_prune_merged_worktrees_script.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_publishing.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_pushflow.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_ratification_policy.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_reconcile_manifest_dedup_46.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_reconcile_verification_log.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_reflection_sync.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_release_dispatch_operator_approval_145.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_release_pin_autotrack.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_repo_validation.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_review_leg_sandbox.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_review_summary.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_roadmap_authority.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_route_log.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_route_policy_conformance.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_routing_invariants.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_runtime_state_mirror_agreement.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_sibling_matcher_patterns.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_skill_bundle_pinned.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_skill_install_body_expansion.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_skill_plan_manifest_write.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_skill_sources_seam.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_skills_bundle_drift.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_skills_canon_parity.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_skills_src_claude_literal_lint.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_spec_conformance_gate.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_status_read_only_62.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_sweep_fleet_worktrees_script.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_sync_skills_apply_failloud.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_task_message_broker.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_task_message_broker_cli.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_task_message_resolver.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_train_e2e.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_train_merge.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_train_order_only_deps_47.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_train_runner.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_unattended_release.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_v34_parallel_dispatch_soak.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_validate_plan_doc_docs_lane.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_verification_evidence.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_verification_evidence_validator.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_visual_evidence_validator.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_workerpool_failure_isolation.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_workerpool_parallel.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_workerpool_worktree_alloc.py +0 -0
- {phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/tests/test_worktree_index.py +0 -0
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "phase-loop-runtime" # PyPI dist name; NOT "agent-harness" (an unrelated third-party PyPI project)
|
|
7
|
-
version = "0.7.
|
|
7
|
+
version = "0.7.4"
|
|
8
8
|
description = "Harness-neutral phase-loop orchestration runtime and CLI"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.10"
|
{phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/panel_invoker.py
RENAMED
|
@@ -1235,6 +1235,91 @@ def _run_leg_with_liveness(
|
|
|
1235
1235
|
pass
|
|
1236
1236
|
|
|
1237
1237
|
|
|
1238
|
+
# #188 — de-animation of the Claude TUI's cosmetic status line. While the model
|
|
1239
|
+
# call is in flight the TUI repaints an animated "✻ Herding… (Ns · esc to
|
|
1240
|
+
# interrupt)" line ~1x/sec (rotating whimsical verb + a per-second elapsed
|
|
1241
|
+
# counter). Those repaints are PTY output but NOT reviewer progress: a leg wedged
|
|
1242
|
+
# in ``ep_poll`` waiting on a stream that never completes keeps animating that
|
|
1243
|
+
# line forever. Treating any PTY byte as a heartbeat (the pre-#188 behavior) let
|
|
1244
|
+
# a wedged Fable leg hang ~17 min with ~2s CPU and no output. So for the TUI path
|
|
1245
|
+
# the kill clock is reset ONLY by GENUINE reviewer progress — output-file growth,
|
|
1246
|
+
# transcript growth, or SUBSTANTIVE novel de-animated terminal text — never by raw
|
|
1247
|
+
# PTY churn and never by incidental CPU (a Node CLI trickles libuv/GC CPU while
|
|
1248
|
+
# blocked, which would defeat a CPU heartbeat here just as the animation defeats a
|
|
1249
|
+
# byte heartbeat). This is exactly #188's "separate process-alive from
|
|
1250
|
+
# reviewer-heartbeat freshness"; the codex/grok/gemini ``_run_leg_with_liveness``
|
|
1251
|
+
# path keeps its stdout/stderr + CPU heartbeat (load-bearing there) untouched.
|
|
1252
|
+
_ANSI_CSI_RE = re.compile(r"\x1b\[[0-9;?]*[ -/]*[@-~]")
|
|
1253
|
+
_ANSI_OSC_RE = re.compile(r"\x1b\][^\x07\x1b]*(?:\x07|\x1b\\)")
|
|
1254
|
+
_TUI_DIGIT_RUN_RE = re.compile(r"\d+")
|
|
1255
|
+
_TUI_NON_TOKEN_RE = re.compile(r"[^0-9a-zA-Z#]+")
|
|
1256
|
+
# A normalized visible line must be at least this long to count as substantive
|
|
1257
|
+
# novelty — filters out short glyph/one-word blips while any real review sentence
|
|
1258
|
+
# (or streamed token run) clears it easily.
|
|
1259
|
+
_TUI_PROGRESS_MIN_CHARS = 8
|
|
1260
|
+
|
|
1261
|
+
|
|
1262
|
+
def _normalize_tui_line(line: str) -> str:
|
|
1263
|
+
"""Collapse a rendered terminal line to a spinner/timer-invariant token string.
|
|
1264
|
+
|
|
1265
|
+
Digit runs → ``#`` (kills the per-second elapsed counter) and every non-alnum
|
|
1266
|
+
glyph/punctuation is dropped (kills the rotating spinner glyph + box drawing),
|
|
1267
|
+
so the animated status line maps to a FINITE set of normalized strings while
|
|
1268
|
+
genuinely-streamed review text keeps introducing novel ones.
|
|
1269
|
+
"""
|
|
1270
|
+
line = _TUI_DIGIT_RUN_RE.sub("#", line)
|
|
1271
|
+
line = _TUI_NON_TOKEN_RE.sub(" ", line)
|
|
1272
|
+
return " ".join(line.split()).strip().lower()
|
|
1273
|
+
|
|
1274
|
+
|
|
1275
|
+
def _tui_chunk_has_novel_content(chunk: bytes, seen: set[str]) -> bool:
|
|
1276
|
+
"""True iff a PTY chunk carries SUBSTANTIVE new (non-cosmetic) terminal text.
|
|
1277
|
+
|
|
1278
|
+
Strips ANSI escapes, splits on newline AND carriage-return (spinner overwrite),
|
|
1279
|
+
normalizes each visible line, and reports whether any sufficiently-long line
|
|
1280
|
+
has not been seen before. ``seen`` accumulates for the session (bounded by real
|
|
1281
|
+
novelty — a wedge's animation vocabulary is finite, so it saturates and stops
|
|
1282
|
+
resetting the kill clock).
|
|
1283
|
+
"""
|
|
1284
|
+
text = chunk.decode("utf-8", errors="replace")
|
|
1285
|
+
text = _ANSI_OSC_RE.sub("", text)
|
|
1286
|
+
text = _ANSI_CSI_RE.sub("", text)
|
|
1287
|
+
novel = False
|
|
1288
|
+
for raw in re.split(r"[\r\n]+", text):
|
|
1289
|
+
norm = _normalize_tui_line(raw)
|
|
1290
|
+
if len(norm) >= _TUI_PROGRESS_MIN_CHARS and norm not in seen:
|
|
1291
|
+
seen.add(norm)
|
|
1292
|
+
novel = True
|
|
1293
|
+
return novel
|
|
1294
|
+
|
|
1295
|
+
|
|
1296
|
+
# A single ``os.read(8192)`` can split a novel review line across two chunks; each
|
|
1297
|
+
# fragment normalizes differently (or collides with a seen/too-short form), so the
|
|
1298
|
+
# whole-line progress signal is lost. Carry the trailing PARTIAL line (bytes after
|
|
1299
|
+
# the last newline/CR) forward and prepend it to the next chunk, so novelty is only
|
|
1300
|
+
# ever evaluated on COMPLETE lines. Bounded so an unterminated over-long run (a rare
|
|
1301
|
+
# no-newline stream) is flushed rather than growing the buffer without limit.
|
|
1302
|
+
_TUI_CARRY_MAX_BYTES = 1 << 16 # 64 KiB
|
|
1303
|
+
|
|
1304
|
+
|
|
1305
|
+
def _tui_take_complete_lines(carry: bytearray, chunk: bytes) -> bytes:
|
|
1306
|
+
"""Append ``chunk`` to ``carry`` and return the bytes up to the last line
|
|
1307
|
+
terminator (complete lines, safe to scan for novelty), retaining the trailing
|
|
1308
|
+
partial line in ``carry`` for the next read. Carried at the RAW byte level so a
|
|
1309
|
+
straddling ANSI escape (never containing \\n/\\r) also reassembles intact."""
|
|
1310
|
+
carry.extend(chunk)
|
|
1311
|
+
last = max(carry.rfind(b"\n"), carry.rfind(b"\r"))
|
|
1312
|
+
if last < 0:
|
|
1313
|
+
if len(carry) >= _TUI_CARRY_MAX_BYTES:
|
|
1314
|
+
complete = bytes(carry)
|
|
1315
|
+
carry.clear()
|
|
1316
|
+
return complete
|
|
1317
|
+
return b""
|
|
1318
|
+
complete = bytes(carry[: last + 1])
|
|
1319
|
+
del carry[: last + 1]
|
|
1320
|
+
return complete
|
|
1321
|
+
|
|
1322
|
+
|
|
1238
1323
|
def _run_claude_tui_session(
|
|
1239
1324
|
*,
|
|
1240
1325
|
command: Sequence[str],
|
|
@@ -1266,8 +1351,14 @@ def _run_claude_tui_session(
|
|
|
1266
1351
|
next_transcript_check = start_monotonic + _CLAUDE_TUI_TRANSCRIPT_INTERVAL_S
|
|
1267
1352
|
transcript_salvage = ""
|
|
1268
1353
|
last_heartbeat = start_monotonic
|
|
1269
|
-
|
|
1270
|
-
|
|
1354
|
+
# #188: GENUINE-progress heartbeat state. The kill clock (``last_heartbeat``)
|
|
1355
|
+
# is reset ONLY by reviewer progress — never by cosmetic PTY animation or
|
|
1356
|
+
# incidental CPU. ``seen_tui_lines`` accumulates de-animated visible lines so a
|
|
1357
|
+
# wedged TUI's finite animation vocabulary saturates and stops resetting it.
|
|
1358
|
+
seen_tui_lines: set[str] = set()
|
|
1359
|
+
tui_carry = bytearray() # #188 CR: trailing partial line held across os.read boundaries
|
|
1360
|
+
last_review_len = 0
|
|
1361
|
+
last_transcript_len = 0
|
|
1271
1362
|
try:
|
|
1272
1363
|
master_fd, slave_fd = pty.openpty()
|
|
1273
1364
|
try:
|
|
@@ -1293,7 +1384,6 @@ def _run_claude_tui_session(
|
|
|
1293
1384
|
os.close(master_fd)
|
|
1294
1385
|
return 1, "", f"claude_tui_launch_error:{type(exc).__name__}"
|
|
1295
1386
|
|
|
1296
|
-
last_ticks = group_cpu_ticks(proc.pid)
|
|
1297
1387
|
try:
|
|
1298
1388
|
while time.monotonic() < deadline:
|
|
1299
1389
|
if master_fd is not None:
|
|
@@ -1305,7 +1395,17 @@ def _run_claude_tui_session(
|
|
|
1305
1395
|
chunk = b""
|
|
1306
1396
|
if chunk:
|
|
1307
1397
|
terminal_bytes.extend(chunk)
|
|
1308
|
-
|
|
1398
|
+
# #188: a raw PTY chunk is a heartbeat ONLY if it carries
|
|
1399
|
+
# SUBSTANTIVE novel text. The TUI's animated "thinking"
|
|
1400
|
+
# status line (rotating verb + per-second timer) repaints
|
|
1401
|
+
# forever while wedged in ep_poll; de-animation maps it to
|
|
1402
|
+
# already-seen lines so it never resets the kill clock.
|
|
1403
|
+
# #188 CR: carry the trailing partial line across read
|
|
1404
|
+
# boundaries so a novel line split by ``os.read`` is scanned
|
|
1405
|
+
# WHOLE (only complete lines are evaluated).
|
|
1406
|
+
complete = _tui_take_complete_lines(tui_carry, chunk)
|
|
1407
|
+
if complete and _tui_chunk_has_novel_content(complete, seen_tui_lines):
|
|
1408
|
+
last_heartbeat = time.monotonic()
|
|
1309
1409
|
else:
|
|
1310
1410
|
# #48: PTY EOF — the child CLI and ALL its descendants closed
|
|
1311
1411
|
# the slave side, so no further output can arrive. Without this
|
|
@@ -1341,11 +1441,20 @@ def _run_claude_tui_session(
|
|
|
1341
1441
|
except OSError:
|
|
1342
1442
|
return 1, "", "claude_tui_submit_failed"
|
|
1343
1443
|
review_text = _read_review_output(output_file)
|
|
1444
|
+
# #188: canonical review OUTPUT growing is unambiguous reviewer progress.
|
|
1445
|
+
if len(review_text) > last_review_len:
|
|
1446
|
+
last_review_len = len(review_text)
|
|
1447
|
+
last_heartbeat = now
|
|
1344
1448
|
if _completion_ok(review_text, mode):
|
|
1345
1449
|
return 0, review_text, "claude_tui_file_output"
|
|
1346
1450
|
if now >= next_transcript_check:
|
|
1347
1451
|
next_transcript_check = now + _CLAUDE_TUI_TRANSCRIPT_INTERVAL_S
|
|
1348
1452
|
transcript_text = _latest_claude_transcript_text(str(cwd), since=start_wall)
|
|
1453
|
+
# #188: the session transcript growing (tool calls, streamed
|
|
1454
|
+
# messages) is genuine progress even before a file verdict lands.
|
|
1455
|
+
if len(transcript_text) > last_transcript_len:
|
|
1456
|
+
last_transcript_len = len(transcript_text)
|
|
1457
|
+
last_heartbeat = now
|
|
1349
1458
|
if _completion_ok(transcript_text, mode):
|
|
1350
1459
|
transcript_salvage = transcript_text
|
|
1351
1460
|
if proc.poll() is not None:
|
|
@@ -1355,14 +1464,13 @@ def _run_claude_tui_session(
|
|
|
1355
1464
|
return 0, review_text, "claude_tui_file_output"
|
|
1356
1465
|
detail = "claude_tui_missing_canonical_output"
|
|
1357
1466
|
return proc.returncode or 1, review_text or transcript_text, detail
|
|
1358
|
-
#
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
# stall: PTY silent AND CPU-flat past the threshold while still running. The
|
|
1467
|
+
# #188: NO CPU heartbeat on the TUI path. Unlike the print-mode legs, a
|
|
1468
|
+
# Node CLI blocked in ep_poll still trickles libuv/GC CPU, so a CPU-advance
|
|
1469
|
+
# reset would keep a genuinely-wedged TUI alive forever (the ~2s-CPU/17-min
|
|
1470
|
+
# hang). Liveness here is reviewer progress ONLY (novel PTY text / output /
|
|
1471
|
+
# transcript growth above) — "process-alive" is deliberately NOT "leg-alive".
|
|
1472
|
+
#
|
|
1473
|
+
# stall: no GENUINE progress for the threshold while still running. The
|
|
1366
1474
|
# canonical verdict is the review FILE (checked above); nothing to nudge for a
|
|
1367
1475
|
# wedged TUI, so fail closed (rc forced non-zero, like the #48/deadline paths).
|
|
1368
1476
|
if now - last_heartbeat >= _LEG_STALL_THRESHOLD_S:
|
|
@@ -1729,7 +1837,15 @@ def _exec_claude_tui_leg(
|
|
|
1729
1837
|
mode=mode,
|
|
1730
1838
|
backstop_s=backstop_s,
|
|
1731
1839
|
)
|
|
1732
|
-
|
|
1840
|
+
# #188: a heartbeat-reclaimed (genuinely wedged) TUI leg is a TYPED stalled leg,
|
|
1841
|
+
# not a bare ERROR — surface it as DEGRADED so the panel summary names the
|
|
1842
|
+
# liveness reclaim ("process alive but no reviewer heartbeat") while the three
|
|
1843
|
+
# completed seats are preserved. A leg that produced a conforming verdict before
|
|
1844
|
+
# the reclaim still classifies OK (unchanged).
|
|
1845
|
+
status = _classify_leg(rc, review_text, log_text, mode)
|
|
1846
|
+
if log_text == "claude_tui_stalled" and status != "OK":
|
|
1847
|
+
return "DEGRADED", review_text or "claude_tui_stalled: no reviewer heartbeat (liveness reclaim)"
|
|
1848
|
+
return status, review_text or log_text
|
|
1733
1849
|
|
|
1734
1850
|
|
|
1735
1851
|
def _exec_claude_agent_view_attempt(
|
{phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime/train_roadmap.py
RENAMED
|
@@ -128,14 +128,25 @@ _NONE_VALUES = frozenset({"(none)", "none", ""})
|
|
|
128
128
|
|
|
129
129
|
def _parse_node_id(raw: str) -> TrainNode:
|
|
130
130
|
"""Parse ``<repo> / <roadmap>`` or ``<repo>/<roadmap>`` into a TrainNode."""
|
|
131
|
-
|
|
132
|
-
if " / " in
|
|
133
|
-
repo, roadmap =
|
|
134
|
-
elif "/" in
|
|
135
|
-
repo, roadmap =
|
|
131
|
+
original = raw.strip()
|
|
132
|
+
if " / " in original:
|
|
133
|
+
repo, roadmap = original.split(" / ", 1)
|
|
134
|
+
elif "/" in original:
|
|
135
|
+
repo, roadmap = original.split("/", 1)
|
|
136
136
|
else:
|
|
137
|
-
raise ValueError(f"invalid node identifier (expected '<repo> / <
|
|
138
|
-
|
|
137
|
+
raise ValueError(f"invalid node identifier (expected '<repo> / <plan-path>'): {original!r}")
|
|
138
|
+
repo, roadmap = repo.strip(), roadmap.strip()
|
|
139
|
+
# Both components are load-bearing: `repo` selects the workspace and
|
|
140
|
+
# `roadmap` is joined onto it as the plan path. An empty half parses into a
|
|
141
|
+
# degenerate node that only fails later at child-launch (workspace / '' =
|
|
142
|
+
# the workspace dir itself). Reject it at parse time, naming the heading.
|
|
143
|
+
if not repo or not roadmap:
|
|
144
|
+
raise ValueError(
|
|
145
|
+
f"invalid node heading '### Node: {original}': both a repo and a "
|
|
146
|
+
f"plan-path are required in '<repo> / <plan-path>' form "
|
|
147
|
+
f"(got repo={repo!r}, plan-path={roadmap!r})"
|
|
148
|
+
)
|
|
149
|
+
return TrainNode(repo=repo, roadmap=roadmap)
|
|
139
150
|
|
|
140
151
|
|
|
141
152
|
def _extract_node_bodies(text: str) -> List[Tuple[str, str]]:
|
|
@@ -206,7 +217,18 @@ def parse_train_roadmap(text: str) -> TrainRoadmap:
|
|
|
206
217
|
raise ValueError(
|
|
207
218
|
f"node '{downstream.node_id}' depends on unknown node '{dep_id}'"
|
|
208
219
|
)
|
|
209
|
-
channel
|
|
220
|
+
# Name the offending node when the channel descriptor is malformed.
|
|
221
|
+
# parse_channel_line raises a bare "pin channel requires a 'file' param"
|
|
222
|
+
# style error; without this wrapper a train author with N nodes cannot
|
|
223
|
+
# tell WHICH node's **Channel:** line is broken (the opaque
|
|
224
|
+
# roadmap-format-handling symptom of agent-harness#60).
|
|
225
|
+
try:
|
|
226
|
+
channel = parse_channel_line(channel_raw)
|
|
227
|
+
except ValueError as exc:
|
|
228
|
+
raise ValueError(
|
|
229
|
+
f"node '{downstream.node_id}' has a malformed **Channel:** "
|
|
230
|
+
f"descriptor ({channel_raw!r}): {exc}"
|
|
231
|
+
) from exc
|
|
210
232
|
edges.append(TrainEdge(upstream=upstream, downstream=downstream, channel=channel))
|
|
211
233
|
|
|
212
234
|
return TrainRoadmap(title=title, nodes=nodes, edges=edges)
|
|
@@ -233,6 +255,9 @@ def validate_train(roadmap: TrainRoadmap) -> List[str]:
|
|
|
233
255
|
implemented for real consumption and are rejected here so that a
|
|
234
256
|
train with a workspace edge fails the preflight gate — opening zero
|
|
235
257
|
PRs — rather than running until injection fails mid-train.
|
|
258
|
+
(T-F) Node identifiers are unique within the train. A duplicated
|
|
259
|
+
``### Node:`` block would otherwise collapse in the topo-sort
|
|
260
|
+
indegree map and mis-surface as a spurious (T-D) cycle.
|
|
236
261
|
"""
|
|
237
262
|
errors: List[str] = []
|
|
238
263
|
|
|
@@ -287,6 +312,27 @@ def validate_train(roadmap: TrainRoadmap) -> List[str]:
|
|
|
287
312
|
f"'workspace' channels are rejected at preflight to prevent hollow injection."
|
|
288
313
|
)
|
|
289
314
|
|
|
315
|
+
# (T-F) Node identifiers must be unique within the train (authoring guide:
|
|
316
|
+
# "Node identifiers must be unique within the train"). A duplicated
|
|
317
|
+
# `### Node:` block otherwise collapses in the topo-sort indegree map and
|
|
318
|
+
# surfaces as a misleading "(T-D) cycle detected ... unresolved nodes: "
|
|
319
|
+
# with an EMPTY node list. Report it as its own coded, node-named error;
|
|
320
|
+
# the `if not errors` guard on the T-D block below then suppresses the
|
|
321
|
+
# spurious cycle. A duplicate is also a dispatch/ledger-integrity hazard:
|
|
322
|
+
# two nodes with the same id collide on the coordinator ledger key.
|
|
323
|
+
seen_ids: set = set()
|
|
324
|
+
reported_dups: set = set()
|
|
325
|
+
for node in roadmap.nodes:
|
|
326
|
+
nid = node.node_id
|
|
327
|
+
if nid in seen_ids and nid not in reported_dups:
|
|
328
|
+
errors.append(
|
|
329
|
+
f"(T-F) node id '{nid}' is declared more than once; each "
|
|
330
|
+
f"'### Node: <repo> / <plan-path>' block must be unique within "
|
|
331
|
+
f"the train (authoring guide: node identifiers must be unique)"
|
|
332
|
+
)
|
|
333
|
+
reported_dups.add(nid)
|
|
334
|
+
seen_ids.add(nid)
|
|
335
|
+
|
|
290
336
|
# (T-D) Acyclic + serially orderable
|
|
291
337
|
if not errors:
|
|
292
338
|
try:
|
{phase_loop_runtime-0.7.3 → phase_loop_runtime-0.7.4}/src/phase_loop_runtime.egg-info/SOURCES.txt
RENAMED
|
@@ -512,6 +512,7 @@ tests/test_panel_native_fill_183.py
|
|
|
512
512
|
tests/test_panel_per_leg_model_66.py
|
|
513
513
|
tests/test_panel_streaming_verdicts.py
|
|
514
514
|
tests/test_panel_tui_eof_48.py
|
|
515
|
+
tests/test_panel_tui_liveness_188.py
|
|
515
516
|
tests/test_panel_verdict_summary.py
|
|
516
517
|
tests/test_parallel_dispatch_backcompat.py
|
|
517
518
|
tests/test_parallel_dispatch_cli.py
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
"""#188 — the Claude TUI (PTY) advisor leg must be reclaimed on reviewer-heartbeat
|
|
2
|
+
extinction, NOT hang on cosmetic animation and NOT rely on a fixed short timeout.
|
|
3
|
+
|
|
4
|
+
Regression: after ViperJuice/agent-harness#185 the Fable panel leg runs headless
|
|
5
|
+
through a self-allocated PTY (``_run_claude_tui_session`` → ``pty.openpty``). The
|
|
6
|
+
pre-#188 monitor reset its stall clock on ANY PTY byte and on ANY CPU advance. But
|
|
7
|
+
the Claude TUI repaints an animated "✻ Herding… (Ns · esc to interrupt)" status
|
|
8
|
+
line ~1x/sec while blocked in ``ep_poll``, and a Node CLI trickles libuv/GC CPU
|
|
9
|
+
while blocked — so a genuinely-wedged leg (no output, ~2s CPU) hung ~17 min and no
|
|
10
|
+
timeout fired. #188 makes liveness reviewer-progress-based: cosmetic repaints and
|
|
11
|
+
incidental CPU no longer count; genuine novel output / file / transcript growth do.
|
|
12
|
+
|
|
13
|
+
These are real-subprocess PTY tests (like ``test_panel_tui_eof_48``): no mocking of
|
|
14
|
+
the read loop, only a monkeypatched-short stall window so the wedge is caught in
|
|
15
|
+
seconds instead of the production 180s.
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
from __future__ import annotations
|
|
19
|
+
|
|
20
|
+
import shutil
|
|
21
|
+
import time
|
|
22
|
+
|
|
23
|
+
import pytest
|
|
24
|
+
|
|
25
|
+
import phase_loop_runtime.panel_invoker as pi
|
|
26
|
+
from phase_loop_runtime.panel_invoker import _classify_leg, _run_claude_tui_session
|
|
27
|
+
|
|
28
|
+
pytestmark = pytest.mark.skipif(shutil.which("sh") is None, reason="needs POSIX sh")
|
|
29
|
+
|
|
30
|
+
# A hermetic empty transcript: tmp cwds have no ~/.claude project, but pin it so the
|
|
31
|
+
# transcript-growth heartbeat can never spuriously reset the clock in these tests.
|
|
32
|
+
_NO_TRANSCRIPT = lambda *a, **k: "" # noqa: E731
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
# A wedged TUI: repaints the SAME animated status line each ~0.1s (only the elapsed
|
|
36
|
+
# digit changes → de-animates to a single seen line), burns a CPU trickle each
|
|
37
|
+
# iteration, never writes the review file, never exits. This is the "~2s CPU / no
|
|
38
|
+
# output / animating forever" signature of the #188 repro.
|
|
39
|
+
_WEDGE_SCRIPT = (
|
|
40
|
+
"i=0; while :; do "
|
|
41
|
+
" i=$((i+1)); "
|
|
42
|
+
" s=0; while [ $s -lt 3000 ]; do s=$((s+1)); done; " # CPU trickle
|
|
43
|
+
r' printf "\r\033[2K* Herding... (%ss . esc to interrupt)" "$i"; '
|
|
44
|
+
" sleep 0.1; "
|
|
45
|
+
"done"
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
# A slow-but-progressing TUI: emits a NOVEL de-animated line each ~0.6s (distinct
|
|
49
|
+
# words, not just a changing digit) with NO file output, then exits. Each novel line
|
|
50
|
+
# is a genuine reviewer heartbeat; the leg must survive many stall windows.
|
|
51
|
+
_PROGRESS_SCRIPT = (
|
|
52
|
+
"for w in alpha bravo charlie delta echo foxtrot golf hotel india juliet; do "
|
|
53
|
+
r' printf "reviewing the %s section of the staged bundle now\n" "$w"; '
|
|
54
|
+
" sleep 0.6; "
|
|
55
|
+
"done"
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def test_wedged_pty_leg_is_reclaimed_on_heartbeat_extinction(tmp_path, monkeypatch):
|
|
60
|
+
"""(a) A silent-hung PTY leg that keeps ANIMATING (cosmetic repaints) and trickles
|
|
61
|
+
CPU is detected and terminated within the stall window — NOT at the wall-clock
|
|
62
|
+
backstop, NOT never. The generous backstop (120s) proves the kill is heartbeat
|
|
63
|
+
reclaim, not a fixed timeout."""
|
|
64
|
+
monkeypatch.setattr(pi, "_LEG_STALL_THRESHOLD_S", 3)
|
|
65
|
+
monkeypatch.setattr(pi, "_CLAUDE_TUI_SUBMIT_DELAY_S", 999) # never submit; irrelevant here
|
|
66
|
+
monkeypatch.setattr(pi, "_latest_claude_transcript_text", _NO_TRANSCRIPT)
|
|
67
|
+
output_file = tmp_path / "panel-claude.txt" # never written
|
|
68
|
+
|
|
69
|
+
start = time.monotonic()
|
|
70
|
+
rc, text, status = _run_claude_tui_session(
|
|
71
|
+
command=["sh", "-c", _WEDGE_SCRIPT],
|
|
72
|
+
cwd=tmp_path,
|
|
73
|
+
prompt="review this",
|
|
74
|
+
output_file=output_file,
|
|
75
|
+
timeout_s=120,
|
|
76
|
+
env={"PATH": "/usr/bin:/bin"},
|
|
77
|
+
backstop_s=120, # generous: a fixed-timeout kill would need this to be short
|
|
78
|
+
)
|
|
79
|
+
elapsed = time.monotonic() - start
|
|
80
|
+
|
|
81
|
+
assert status == "claude_tui_stalled", (
|
|
82
|
+
f"wedged animating TUI must be reclaimed as stalled; got {status!r} "
|
|
83
|
+
f"(pre-#188: cosmetic repaints reset the heartbeat forever)"
|
|
84
|
+
)
|
|
85
|
+
assert 3 <= elapsed < 30, (
|
|
86
|
+
f"reclaim took {elapsed:.1f}s — must be ~stall_threshold (3s), not the 120s "
|
|
87
|
+
f"backstop (would prove a fixed timeout) and not never"
|
|
88
|
+
)
|
|
89
|
+
assert rc != 0, f"a reclaimed wedge must be fail-closed non-zero; got rc={rc}"
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def test_wedged_stall_marker_classifies_degraded(tmp_path, monkeypatch):
|
|
93
|
+
"""(a cont.) The reclaimed stall is surfaced as a TYPED leg. ``_exec_claude_tui_leg``
|
|
94
|
+
maps the ``claude_tui_stalled`` marker to DEGRADED (never a silent OK / bare ERROR),
|
|
95
|
+
so the panel summary names the reclaim while the completed seats are preserved. This
|
|
96
|
+
exercises the REAL wiring (not a re-implementation of the mapping)."""
|
|
97
|
+
review_dir = tmp_path / "review"
|
|
98
|
+
out_dir = tmp_path / "out"
|
|
99
|
+
review_dir.mkdir()
|
|
100
|
+
out_dir.mkdir()
|
|
101
|
+
# Run the leg RIGHT HERE (headless self-PTY path): not under Claude Code, CLI supported.
|
|
102
|
+
monkeypatch.setattr(pi, "_under_claude_code", lambda env=None: False)
|
|
103
|
+
monkeypatch.setattr(pi, "_claude_code_support_status", lambda: (True, ""))
|
|
104
|
+
monkeypatch.setattr(pi, "_subscription_env", lambda: {"PATH": "/usr/bin:/bin"})
|
|
105
|
+
# The session reclaims a genuinely-wedged leg: non-zero rc, no verdict, stall marker.
|
|
106
|
+
monkeypatch.setattr(pi, "_run_claude_tui_session", lambda **kwargs: (1, "", "claude_tui_stalled"))
|
|
107
|
+
|
|
108
|
+
status, _text = pi._exec_claude_tui_leg(review_dir, out_dir, 120, "bundle")
|
|
109
|
+
|
|
110
|
+
assert status == "DEGRADED", (
|
|
111
|
+
f"a heartbeat-reclaimed wedge must be surfaced as DEGRADED (typed stalled leg), "
|
|
112
|
+
f"not a bare ERROR/silent OK; got {status!r}"
|
|
113
|
+
)
|
|
114
|
+
assert status in pi.LEG_STATUSES
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
def test_slow_but_progressing_pty_leg_is_not_killed(tmp_path, monkeypatch):
|
|
118
|
+
"""(b) A leg that emits NOVEL de-animated terminal text every interval (genuine
|
|
119
|
+
reviewer heartbeat) survives many stall windows and is NOT false-killed — even with
|
|
120
|
+
no file output yet and the same short stall threshold that reclaims the wedge."""
|
|
121
|
+
monkeypatch.setattr(pi, "_LEG_STALL_THRESHOLD_S", 2)
|
|
122
|
+
monkeypatch.setattr(pi, "_CLAUDE_TUI_SUBMIT_DELAY_S", 999) # isolate the PTY-progress signal
|
|
123
|
+
monkeypatch.setattr(pi, "_latest_claude_transcript_text", _NO_TRANSCRIPT)
|
|
124
|
+
output_file = tmp_path / "panel-claude.txt" # intentionally never written by the script
|
|
125
|
+
|
|
126
|
+
start = time.monotonic()
|
|
127
|
+
rc, text, status = _run_claude_tui_session(
|
|
128
|
+
command=["sh", "-c", _PROGRESS_SCRIPT],
|
|
129
|
+
cwd=tmp_path,
|
|
130
|
+
prompt="review this",
|
|
131
|
+
output_file=output_file,
|
|
132
|
+
timeout_s=120,
|
|
133
|
+
env={"PATH": "/usr/bin:/bin"},
|
|
134
|
+
backstop_s=120,
|
|
135
|
+
)
|
|
136
|
+
elapsed = time.monotonic() - start
|
|
137
|
+
|
|
138
|
+
assert status != "claude_tui_stalled", (
|
|
139
|
+
f"a leg emitting novel output every 0.6s must NOT be reclaimed as stalled "
|
|
140
|
+
f"(stall window was 2s); got {status!r} after {elapsed:.1f}s"
|
|
141
|
+
)
|
|
142
|
+
# 10 novel lines × 0.6s ≈ 6s, far past 2× the 2s stall window — proof it lived on
|
|
143
|
+
# its reviewer heartbeat, then exited on its own (no canonical file → typed miss).
|
|
144
|
+
assert elapsed > 4, f"leg exited/was reclaimed too early ({elapsed:.1f}s) — progress heartbeat failed"
|
|
145
|
+
# It lived on its reviewer heartbeat and then ended on ITS OWN terms (the script
|
|
146
|
+
# exits and closes the PTY → structured EOF / missing-canonical result), never a
|
|
147
|
+
# liveness reclaim. The exact terminal detail depends on exit-vs-poll ordering.
|
|
148
|
+
assert status in {"claude_tui_pty_eof_no_output", "claude_tui_missing_canonical_output"}, status
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
def test_novel_line_split_across_read_boundaries_is_detected_whole():
|
|
152
|
+
"""(b cont., #188 CR) A novel review line delivered in TWO halves across two
|
|
153
|
+
``os.read`` boundaries must register as ONE progress event once the line completes
|
|
154
|
+
— the carry-buffer holds the trailing partial line so novelty is evaluated on the
|
|
155
|
+
WHOLE line, not on fragments (which could each collide with a seen/too-short form
|
|
156
|
+
and silently drop the heartbeat)."""
|
|
157
|
+
seen: set[str] = set()
|
|
158
|
+
carry = bytearray()
|
|
159
|
+
|
|
160
|
+
# First read delivers the line WITHOUT a terminator: no complete line yet, so
|
|
161
|
+
# nothing is evaluated and no fragment pollutes `seen`.
|
|
162
|
+
complete1 = pi._tui_take_complete_lines(carry, b"reviewing the acceptance crit")
|
|
163
|
+
assert complete1 == b"", "an unterminated partial line must not be emitted"
|
|
164
|
+
assert not pi._tui_chunk_has_novel_content(complete1, seen)
|
|
165
|
+
assert seen == set(), "no fragment should be recorded before the line completes"
|
|
166
|
+
|
|
167
|
+
# Second read completes the line (adds the tail + newline): now the WHOLE line is
|
|
168
|
+
# evaluated and counts as novel progress.
|
|
169
|
+
complete2 = pi._tui_take_complete_lines(carry, b"eria section now\n")
|
|
170
|
+
assert pi._tui_chunk_has_novel_content(complete2, seen), (
|
|
171
|
+
"the reassembled whole line must be detected as novel progress"
|
|
172
|
+
)
|
|
173
|
+
# The recorded token is the whole normalized line, not either half.
|
|
174
|
+
assert "reviewing the acceptance criteria section now" in seen
|
|
175
|
+
assert carry == bytearray(), "no residue after a terminated line"
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
def test_no_fixed_short_timeout_is_injected_when_caller_did_not_request_one(tmp_path):
|
|
179
|
+
"""(c) With no caller-supplied per-leg timeout, the runtime does NOT inject a fixed
|
|
180
|
+
model timeout: the hard deadline is raised to the _MAX backstop and the real kill is
|
|
181
|
+
heartbeat reclaim (tested above). An explicit override is still honored as-is."""
|
|
182
|
+
(tmp_path / "review-bundle.md").write_text("small bundle", encoding="utf-8")
|
|
183
|
+
|
|
184
|
+
ref_default, deadline_default = pi._leg_deadline_from(None, tmp_path)
|
|
185
|
+
# No fixed short timeout: the backstop is the generous _MAX (>= 1800s), not the base.
|
|
186
|
+
assert deadline_default >= pi._MAX_LEG_TIMEOUT_S
|
|
187
|
+
assert deadline_default > pi._LEG_TIMEOUT_BASE_S
|
|
188
|
+
|
|
189
|
+
# An EXPLICIT caller override is honored verbatim (still bounded — the contract path).
|
|
190
|
+
ref_explicit, deadline_explicit = pi._leg_deadline_from(300, tmp_path)
|
|
191
|
+
assert (ref_explicit, deadline_explicit) == (300, 300)
|
|
@@ -1296,3 +1296,49 @@ class TestInvariant7RunLoopFailureContract:
|
|
|
1296
1296
|
"_pipeline_branch_blocker_from_error each contribute one). "
|
|
1297
1297
|
"A removed default would let a failure path silently emit None."
|
|
1298
1298
|
)
|
|
1299
|
+
|
|
1300
|
+
|
|
1301
|
+
# ---------------------------------------------------------------------------
|
|
1302
|
+
# agent-harness#60 (roadmap-format-handling half): a format defect that survives
|
|
1303
|
+
# parse (a duplicated node block) must be caught by run_train's Step-0 schema
|
|
1304
|
+
# gate as preflight_failed with ZERO publish calls and an actionable, node-named
|
|
1305
|
+
# diagnostic — binding the format fix to INV-3's zero-PR contract.
|
|
1306
|
+
|
|
1307
|
+
TRAIN_DUP_NODE_MD = TRAIN_2NODE_MD + (
|
|
1308
|
+
"\n### Node: repo-a / specs/plan-a.md\n\n"
|
|
1309
|
+
"**Depends on:** (none)\n**Channel:** (none)\n"
|
|
1310
|
+
)
|
|
1311
|
+
|
|
1312
|
+
|
|
1313
|
+
class TestIssue60FormatDefectZeroPRs:
|
|
1314
|
+
def test_duplicate_node_train_preflight_failed_zero_publish(self, tmp_path: Path):
|
|
1315
|
+
roadmap = parse_train_roadmap(TRAIN_DUP_NODE_MD) # parse tolerates dup
|
|
1316
|
+
ws_map = {n.node_id: tmp_path / n.repo for n in roadmap.nodes}
|
|
1317
|
+
ledger = tmp_path / "ledger" / "train.ledger.jsonl"
|
|
1318
|
+
publish_log: List[str] = []
|
|
1319
|
+
|
|
1320
|
+
def _publish_spy(workspace: Path, owned_paths, *, draft: bool, **kw):
|
|
1321
|
+
publish_log.append(workspace.name)
|
|
1322
|
+
return {"status": "published", "branch": "b", "head_sha": "s", "pr_url": "u"}
|
|
1323
|
+
|
|
1324
|
+
result = run_train(
|
|
1325
|
+
roadmap,
|
|
1326
|
+
ledger,
|
|
1327
|
+
run_mode="governed",
|
|
1328
|
+
resolve_workspace=lambda n: ws_map[n.node_id],
|
|
1329
|
+
_run_loop=lambda *a, **kw: (None, []),
|
|
1330
|
+
_publish=_publish_spy,
|
|
1331
|
+
_set_upstream_ref_fn=lambda *a, **kw: [],
|
|
1332
|
+
_preflight_fn=_preflight_pass, # repo-preflight would pass; schema gate must fire first
|
|
1333
|
+
_pr_is_open=_pr_is_open_false,
|
|
1334
|
+
_live_pr_head_sha_fn=lambda ws, br: None,
|
|
1335
|
+
_merge_phase_enabled=True,
|
|
1336
|
+
)
|
|
1337
|
+
|
|
1338
|
+
assert result["status"] == "preflight_failed", result
|
|
1339
|
+
assert publish_log == [], f"format defect must open zero PRs; got {publish_log!r}"
|
|
1340
|
+
joined = " ".join(result["errors"])
|
|
1341
|
+
assert "(T-F)" in joined and "repo-a/specs/plan-a.md" in joined, (
|
|
1342
|
+
f"diagnostic must be coded and name the duplicated node; got: {result['errors']}"
|
|
1343
|
+
)
|
|
1344
|
+
assert not ledger.exists() or read_ledger(ledger) == {}, "no ledger records on schema failure"
|
|
@@ -811,3 +811,82 @@ class TestUnsupportedChannelKindInTrain:
|
|
|
811
811
|
errors = validate_train(r)
|
|
812
812
|
t_e_errors = [e for e in errors if "(T-E)" in e]
|
|
813
813
|
assert not t_e_errors, f"Expected no T-E errors for supported channels; got: {t_e_errors}"
|
|
814
|
+
|
|
815
|
+
|
|
816
|
+
# ---------------------------------------------------------------------------
|
|
817
|
+
# agent-harness#60 — roadmap-format-handling half: opaque parse/validate
|
|
818
|
+
# failures on authoring-guide-shaped input must become actionable diagnostics
|
|
819
|
+
# that name the offending node (and, for duplicates, avoid a false T-D cycle).
|
|
820
|
+
|
|
821
|
+
|
|
822
|
+
class TestIssue60FormatHandling:
|
|
823
|
+
"""Regression tests for the roadmap-format-handling half of #60.
|
|
824
|
+
|
|
825
|
+
Each previously either (a) raised a ValueError that did NOT name which node
|
|
826
|
+
was malformed, (b) was silently accepted, or (c) mis-surfaced as a spurious
|
|
827
|
+
(T-D) cycle with an empty unresolved-node list.
|
|
828
|
+
"""
|
|
829
|
+
|
|
830
|
+
_GOOD = VALID_TRAIN_3NODE_MD
|
|
831
|
+
|
|
832
|
+
# --- Gap A: malformed **Channel:** descriptor must name the node ---------
|
|
833
|
+
|
|
834
|
+
def test_pin_missing_file_names_node(self) -> None:
|
|
835
|
+
bad = self._GOOD.replace(
|
|
836
|
+
"pin file=manifest.json key=deps.alpha-lib", "pin key=deps.alpha-lib"
|
|
837
|
+
)
|
|
838
|
+
with pytest.raises(ValueError) as exc:
|
|
839
|
+
parse_train_roadmap(bad)
|
|
840
|
+
msg = str(exc.value)
|
|
841
|
+
assert "beta/specs/beta.md" in msg, f"error must name the node; got: {msg}"
|
|
842
|
+
assert "Channel" in msg and "pin" in msg
|
|
843
|
+
|
|
844
|
+
def test_unknown_channel_kind_names_node(self) -> None:
|
|
845
|
+
bad = self._GOOD.replace("submodule path=vendor/beta", "submdoule path=vendor/beta")
|
|
846
|
+
with pytest.raises(ValueError) as exc:
|
|
847
|
+
parse_train_roadmap(bad)
|
|
848
|
+
msg = str(exc.value)
|
|
849
|
+
assert "gamma/specs/gamma.md" in msg, f"error must name the node; got: {msg}"
|
|
850
|
+
assert "submdoule" in msg
|
|
851
|
+
|
|
852
|
+
def test_submodule_missing_path_names_node(self) -> None:
|
|
853
|
+
bad = self._GOOD.replace("submodule path=vendor/beta", "submodule")
|
|
854
|
+
with pytest.raises(ValueError) as exc:
|
|
855
|
+
parse_train_roadmap(bad)
|
|
856
|
+
assert "gamma/specs/gamma.md" in str(exc.value)
|
|
857
|
+
|
|
858
|
+
# --- Gap B: duplicate node id → coded (T-F), NOT a spurious cycle --------
|
|
859
|
+
|
|
860
|
+
def test_duplicate_node_id_reports_t_f_not_cycle(self) -> None:
|
|
861
|
+
dup = self._GOOD + (
|
|
862
|
+
"\n### Node: alpha / specs/alpha.md\n\n"
|
|
863
|
+
"**Depends on:** (none)\n**Channel:** (none)\n"
|
|
864
|
+
)
|
|
865
|
+
r = parse_train_roadmap(dup) # parse tolerates; validate is the gate
|
|
866
|
+
errors = validate_train(r)
|
|
867
|
+
t_f = [e for e in errors if "(T-F)" in e]
|
|
868
|
+
assert t_f, f"expected a (T-F) duplicate-node error; got: {errors}"
|
|
869
|
+
assert "alpha/specs/alpha.md" in t_f[0]
|
|
870
|
+
# The old buggy behavior mis-reported this as a (T-D) cycle with an
|
|
871
|
+
# empty unresolved-node list — assert that no longer happens.
|
|
872
|
+
assert not [e for e in errors if "(T-D)" in e], (
|
|
873
|
+
f"duplicate must NOT surface as a (T-D) cycle; got: {errors}"
|
|
874
|
+
)
|
|
875
|
+
|
|
876
|
+
def test_genuine_cycle_still_reports_t_d(self) -> None:
|
|
877
|
+
"""Guard: the T-F check must not mask a real cycle of distinct nodes."""
|
|
878
|
+
r = parse_train_roadmap(CYCLIC_TRAIN_MD)
|
|
879
|
+
errors = validate_train(r)
|
|
880
|
+
assert [e for e in errors if "(T-D)" in e], f"got: {errors}"
|
|
881
|
+
|
|
882
|
+
# --- Gap C: empty repo / plan-path component rejected at parse -----------
|
|
883
|
+
|
|
884
|
+
def test_empty_plan_path_rejected(self) -> None:
|
|
885
|
+
bad = "# Release Train: t\n\n## Nodes\n\n### Node: spec /\n\n**Depends on:** (none)\n**Channel:** (none)\n"
|
|
886
|
+
with pytest.raises(ValueError, match="plan-path"):
|
|
887
|
+
parse_train_roadmap(bad)
|
|
888
|
+
|
|
889
|
+
def test_empty_repo_rejected(self) -> None:
|
|
890
|
+
bad = "# Release Train: t\n\n## Nodes\n\n### Node: / specs/x.md\n\n**Depends on:** (none)\n**Channel:** (none)\n"
|
|
891
|
+
with pytest.raises(ValueError, match="repo"):
|
|
892
|
+
parse_train_roadmap(bad)
|
|
File without changes
|
|
File without changes
|