code-coordinator 0.5.218__tar.gz → 0.5.220__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.
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/PKG-INFO +1 -1
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/code_coordinator.egg-info/PKG-INFO +1 -1
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/code_coordinator.egg-info/scm_version.json +2 -2
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/commands/lifecycle.py +18 -2
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/commands/merge.py +66 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/comments.py +59 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/config.py +27 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220/coord}/deploy/coord-notify.service +9 -3
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/diagnose.py +157 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/notify.py +136 -10
- {code_coordinator-0.5.218/coord → code_coordinator-0.5.220}/deploy/coord-notify.service +9 -3
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/docs/AGENT_OPERATIONS.md +22 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_auto_loop.py +41 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_cli_merge.py +96 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_comments.py +42 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_diagnose.py +137 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_drive.py +18 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_notify.py +95 -15
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_stalled_pipeline.py +1 -1
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_stuck.py +4 -4
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/.claude/commands/board.md +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/.claude/commands/complete-session.md +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/.claude/commands/coordinator.md +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/.githooks/_lib.sh +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/.githooks/post-checkout +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/.githooks/post-commit +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/.githooks/post-merge +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/.github/coord-ci-acceptance.yml +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/.github/workflows/auto-release.yml +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/.github/workflows/cargo-test.yml +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/.github/workflows/publish.yml +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/.github/workflows/release-tui.yml +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/.github/workflows/test.yml +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/.gitignore +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/CLAUDE.md +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/GOAL.md +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/LICENSE +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/MANIFEST.in +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/README.md +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/code_coordinator.egg-info/SOURCES.txt +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/code_coordinator.egg-info/dependency_links.txt +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/code_coordinator.egg-info/entry_points.txt +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/code_coordinator.egg-info/requires.txt +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/code_coordinator.egg-info/scm_file_list.json +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/code_coordinator.egg-info/top_level.txt +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/__init__.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/_board_mapping.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/acceptance.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/acceptance_drivers.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/agent.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/agent_app.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/agent_update.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/agents/opencode/.gitignore +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/agents/opencode/agents/work.md +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/agents/opencode/routing.jsonc +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/approved_work.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/audit.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/auto_loop.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/block_log.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/board_bool_guard.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/board_service.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/board_wire.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/brain.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/branch_model.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/bug_intake.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/cargo_cache.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/ci_fix.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/ci_github.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/ci_gitlab.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/ci_store.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/claim.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/cli.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/client.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/commands/__init__.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/commands/_common.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/commands/acceptance.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/commands/agent_ops.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/commands/audit.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/commands/chat.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/commands/dispatch.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/commands/dispatch_workers.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/commands/drive.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/commands/drive_queue.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/commands/gate_a.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/commands/gates.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/commands/issues.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/commands/milestone.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/commands/plan_followup.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/commands/plans.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/commands/portal.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/commands/release.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/commands/repo.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/commands/report.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/commands/review.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/commands/scorecard.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/commands/sessions.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/commands/setup.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/commands/status.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/commands/terminal.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/commands/test_gate.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/commands/tui.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/config_reload.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/confirm_test.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/conflict_fix.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/dao.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/dashboard/__init__.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/dashboard/fixture.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/dashboard/index.html +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/dashboard/server.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/dashboard/terminal.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/db.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/dead_end.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/deploy/README.md +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/deploy/coord-agent.service +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/deploy/coord-db-backup.service +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/deploy/coord-db-backup.sh +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/deploy/coord-db-backup.timer +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/deploy/coord-drive-queue.service +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/deploy/coord-drive-queue.timer +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/deploy/coord-notify.timer +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/deploy/coord-release-propagate.service +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/deploy/coord-release-propagate.timer +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/deploy/coord-release-window.service +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/deploy/coord-release-window.timer +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/deploy/coord-serve.service +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/deploy/coord-web-dist-build.service +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/deploy/coord-web-dist-build.timer +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/deploy/coord-web.service +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/deploy_manifest.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/deploy_units.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/deps.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/dispatch.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/dist_name.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/drive.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/drive_queue.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/drive_state.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/events.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/failure_class.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/filelock.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/fleet_config_health.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/forge_availability.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/freshness.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/gate_a.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/gate_b.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/gate_snapshot.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/gates.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/github_ops.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/goal.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/graph_health.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/health/__init__.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/health/aggregate.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/health/checks/__init__.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/health/checks/agent_install.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/health/checks/cargo_targets.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/health/checks/claude_binary.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/health/checks/coord_web_ci_pin.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/health/checks/deploy_lane_facts.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/health/checks/disk.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/health/checks/fleet_board.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/health/checks/fleet_deploy_lanes.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/health/checks/fleet_phantom.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/health/checks/fleet_unit_drift.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/health/checks/graph.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/health/checks/graphify_cli.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/health/checks/index_lock.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/health/checks/plan_usage.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/health/checks/repo_state.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/health/checks/spawned_coord.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/health/checks/timer_active.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/health/checks/toolchain.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/health/checks/unit_drift.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/health/checks/unit_enablement.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/health/checks/worktrees.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/health/cli.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/health/context.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/health/fleet_snapshot.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/health/models.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/health/pypi.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/health/registry.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/health/render.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/health/units.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/hooks.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/housekeeping.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/interactive.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/issue_store.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/liveness_auditor.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/machine_pause.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/merge_queue.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/milestone_chat.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/milestone_dispatch.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/milestone_gate.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/milestone_order.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/mock_author.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/models.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/network.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/new_issue_chat.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/notifier/__init__.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/notifier/baseline.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/notifier/cli.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/notifier/collect.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/notifier/digest.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/notifier/models.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/notifier/predicate.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/notifier/service.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/notifier/store.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/notifier/transport.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/openapi.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/overlap_fence.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/overlap_predict.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/parentage.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/parentage_github.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/pipeline.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/plan_parser.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/plans.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/platform_paths.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/portal_bridge.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/portal_store.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/portal_sync.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/pr_body_lint.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/prereqs.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/progress.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/providers/__init__.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/providers/base.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/providers/claude.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/providers/claude_pty.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/providers/opencode.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/queue_diagnose.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/reconcile.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/reconcile_tick.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/refine_chat.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/release_cordon.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/release_propagate.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/release_verify.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/release_window.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/repo_edit.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/repo_onboard.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/reports.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/revalidate.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/review.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/scorecard.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/self_health.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/serve_app.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/skills/coord-dispatch-verbs/SKILL.md +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/skills/drive-queue-preflight/SKILL.md +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/skills/fleet-restart-safety/SKILL.md +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/skills/merge-stuck-triage/SKILL.md +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/skills/pipeline-limbo-triage/SKILL.md +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/skills/portal-followup/SKILL.md +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/skills/review-verdict-recovery/SKILL.md +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/skills/tui-quadraui-workflow/SKILL.md +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/skills/update-issue/SKILL.md +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/smoke.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/spend_ceiling.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/split_work.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/stage_projection.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/state.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/test_author.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/test_chat.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/test_orchestrator.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/test_report.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/tui_release.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/usage.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/usage_limits.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/usage_rollup.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coord/worker_events.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/coordinator.example.yml +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/deploy/coord-agent.service +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/deploy/coord-db-backup.service +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/deploy/coord-db-backup.sh +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/deploy/coord-db-backup.timer +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/deploy/coord-drive-queue.service +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/deploy/coord-drive-queue.timer +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/deploy/coord-notify.timer +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/deploy/coord-release-propagate.service +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/deploy/coord-release-propagate.timer +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/deploy/coord-release-window.service +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/deploy/coord-release-window.timer +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/deploy/coord-serve.service +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/deploy/coord-web-dist-build.service +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/deploy/coord-web-dist-build.sh +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/deploy/coord-web-dist-build.timer +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/deploy/coord-web-rollback.sh +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/deploy/coord-web.service +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/deploy/node-shim.sh +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/docs/ADR_COORD_WEB_ACCEPTANCE_SUITE.md +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/docs/ADR_COORD_WEB_CI.md +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/docs/ADR_COORD_WEB_DIST.md +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/docs/ARCHITECTURE.md +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/docs/ARCH_SECURITY_GATES.md +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/docs/COCKPIT.md +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/docs/CONTROL_CENTER.md +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/docs/COST_DISCIPLINE.md +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/docs/CROSS_PLATFORM.md +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/docs/CUSTOMER_PORTAL.md +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/docs/DRIVE_QUEUE.md +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/docs/EPHEMERAL_WORKERS.md +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/docs/FORGE_MIGRATION.md +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/docs/GRAPHIFY_SETUP.md +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/docs/ISSUE_GUIDANCE.md +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/docs/MAC_MINI.md +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/docs/MERGE_AUTO_DRAIN_TRUST_BAR.md +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/docs/NOTIFIER.md +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/docs/OPENCODE_VERIFICATION.md +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/docs/OPERATING_GOTCHAS.md +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/docs/ORACLE_LOOP.md +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/docs/PHONE_WEBAPP.md +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/docs/PIPELINE_V2.md +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/docs/PLATFORM_EVOLUTION.md +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/docs/SECOND_BACKEND.md +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/docs/STORE_SERVICE.md +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/docs/TEST_FIRST_BUG_LANE.md +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/docs/WEB_CONTROL_CENTER.md +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/docs/WSL_WINDOWS_WORKER.md +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/docs/mocks/web/README.md +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/docs/mocks/web/_tokens.css +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/docs/mocks/web/issue-detail.html +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/docs/mocks/web/pipeline-narrow.html +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/docs/mocks/web/pipeline-wide.html +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/graphify-out/.gitignore +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/install-agent.sh +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/pyproject.toml +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/scripts/audit_review_verdict_overrides.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/scripts/azure-workers/bootstrap-shared.sh +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/scripts/azure-workers/build-worker-image.sh +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/scripts/azure-workers/coordinator-machine.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/scripts/azure-workers/epic-down.sh +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/scripts/azure-workers/epic-up.sh +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/scripts/azure-workers/preflight.sh +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/scripts/azure-workers/provision-worker.sh +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/scripts/azure-workers/scrub-and-generalize.sh +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/scripts/azure-workers/tailnet-acl.hujson +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/scripts/azure-workers/verify-github-token.sh +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/scripts/check_gh_argv_containment.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/scripts/codegen.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/scripts/coord-test-runner.sh +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/scripts/drive-batch.sh +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/scripts/gen_board_fixture.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/scripts/gen_mock_index.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/scripts/next_release_tag.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/scripts/run_tests_in_populated_home.sh +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/scripts/run_tests_without_gh.sh +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/scripts/smoke_437_interactive.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/scripts/verify_878_review_capture.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/scripts/verify_release_published.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/scripts/verify_release_wheel.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/setup.cfg +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/SMOKE_SET.md +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/__init__.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/acceptance/ms-33/audit_1039.rs +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/acceptance/ms-33/contract.md +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/acceptance/ms-33/manifest.yml +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/acceptance/ms-33/mocks/audit-panel-detail.screen +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/acceptance/ms-33/mocks/audit-panel-empty.screen +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/acceptance/ms-33/mocks/audit-panel-filters.screen +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/acceptance/ms-33/mocks/audit-panel-populated.screen +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/acceptance/ms-37/conftest.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/acceptance/ms-37/contract.md +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/acceptance/ms-37/manifest.yml +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/acceptance/ms-37/test_usage_cli_1115.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/acceptance/ms-37/test_usage_core_1118.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/acceptance/ms-38/contract.md +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/acceptance/ms-38/manifest.yml +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/acceptance/ms-38/mocks/plans-base.screen +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/acceptance/ms-38/mocks/plans-detail-pane.screen +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/acceptance/ms-38/mocks/plans-help-overlay.screen +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/acceptance/ms-38/mocks/plans-palette.screen +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/acceptance/ms-38/mocks/plans-rightclick-epic.screen +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/acceptance/ms-38/mocks/plans-rightclick-header.screen +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/acceptance/ms-38/mocks/plans-rightclick-stub.screen +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/acceptance/ms-38/plans_detail_1122.rs +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/acceptance/ms-38/plans_help_1124.rs +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/acceptance/ms-38/plans_rightclick_1123.rs +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/acceptance/ms-51/contract.md +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/acceptance/ms-51/home-active-extended.spec.ts +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/acceptance/ms-51/home-active.spec.ts +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/acceptance/ms-51/manifest.yml +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/acceptance/ms-51/mocks/home-active.html +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/acceptance/ms-51/tsconfig.json +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/acceptance/ms-65/board_split_2288.rs +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/acceptance/ms-65/board_tabs_2282.rs +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/acceptance/ms-65/board_tabs_close_2283.rs +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/acceptance/ms-65/contract.md +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/acceptance/ms-65/detail_substate_2285.rs +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/acceptance/ms-65/manifest.yml +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/acceptance/ms-65/mocks/board-baseline-no-tabs.screen +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/acceptance/ms-65/mocks/board-pinned-3-tabs.screen +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/acceptance/ms-65/mocks/board-preview-tab.screen +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/acceptance/ms-65/mocks/board-split-side-by-side.screen +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/acceptance/ms-65/mocks/board-tab-context-menu.screen +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/acceptance/ms-65/mocks/board-tabs-help-overlay.screen +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/acceptance/ms-65/mocks/board-tabs-overflow.screen +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/acceptance/ms-65/mocks/pipeline-tabs-independent.screen +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/acceptance/ms-65/pipeline_tabs_2284.rs +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/acceptance/ms-65/tabs_discoverability_2287.rs +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/acceptance/ms-65/tabs_persistence_2286.rs +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/acceptance/ms-67/approved_items_2532.rs +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/acceptance/ms-67/contract.md +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/acceptance/ms-67/manifest.yml +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/acceptance/ms-67/mocks/approved-items-chat-opened.screen +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/acceptance/ms-67/mocks/approved-items-context-menu.screen +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/acceptance/ms-67/mocks/approved-items-detail.screen +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/acceptance/ms-67/mocks/approved-items-empty.screen +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/acceptance/ms-67/mocks/approved-items-populated.screen +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/acceptance/ms-example/mocks/home-active.html +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/conftest.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/fixtures/board-pipeline-basic.json +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/fixtures/board-pipeline-terminal-gates.json +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/fixtures/opencode_run_failure_sample.jsonl +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/fixtures/opencode_run_length_sample.jsonl +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/fixtures/opencode_run_sample.jsonl +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/fixtures/playwright/all_pass.json +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/fixtures/playwright/global_setup_crash.json +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/fixtures/playwright/mixed_fail.json +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/fixtures/playwright/retry_then_pass.json +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/fixtures/playwright/retry_then_pass.junit.xml +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/fixtures/playwright/skip.json +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/fixtures/playwright/truncated.json +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/fixtures/test_report/cargo_compile_error.txt +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/fixtures/test_report/cargo_multi_target_failures.txt +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/fixtures/test_report/cargo_no_parseable_failures.txt +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/fixtures/test_report/pytest_collection_error.txt +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/fixtures/test_report/pytest_error_string_in_body.txt +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/fixtures/test_report/pytest_internal_error.txt +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/fixtures/test_report/pytest_mixed_failures.txt +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/fixtures/test_report/pytest_no_parseable_failures.txt +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_acceptance.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_acceptance_drivers.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_agent.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_agent_api_error.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_agent_app.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_agent_branch_base.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_agent_branch_capture.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_agent_config_free_1712.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_agent_deploy_units_endpoint.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_agent_dirty_worktree.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_agent_drive_queue_reconcile_2373.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_agent_graph_self_heal.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_agent_health_h3.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_agent_idle_restart.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_agent_push_failure.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_agent_reap.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_agent_repos_and_pull.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_agent_restart_services_endpoint.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_agent_skills_self_heal.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_agent_startup_diagnostics.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_agent_update.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_agent_update_bluegreen.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_agent_usage_limit.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_agent_zero_commit.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_ambient_home_isolation.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_approve_reject_plan.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_approve_usage_gate.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_approved_work_2532.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_assignment_already_recorded_daemon.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_audit_log.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_audit_outcome.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_audit_query.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_auto_release_publish_2035.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_base_checkout_restore.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_block_log.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_board_cap_762.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_board_fixture.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_board_read_path.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_board_service.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_board_state.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_board_wire.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_brain.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_branch_model.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_bug_intake.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_build_worker_image_env_update.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_cargo_cache.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_check_gh_argv_containment.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_ci_acceptance_gate_1950.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_ci_fix.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_ci_gitlab.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_ci_parity_2091.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_ci_store.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_claim.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_cli_acceptance.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_cli_assign.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_cli_assign_interactive_oracle_gate.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_cli_assign_interactive_remote.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_cli_assign_provider.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_cli_assign_repo_drift_2219.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_cli_audit.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_cli_chat_continue.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_cli_decide.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_cli_diagnose_config_provenance.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_cli_diagnose_forge_availability.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_cli_diagnose_graph.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_cli_diagnose_self.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_cli_doctor.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_cli_doctor_config_free_1801.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_cli_doctor_config_mismatch_1712.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_cli_drive.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_cli_drive_queue.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_cli_escalate.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_cli_fix_headless_review.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_cli_gate_a.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_cli_install_drift.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_cli_install_skills.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_cli_issue_create_label.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_cli_issue_reopen.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_cli_milestone_assign.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_cli_milestone_capture.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_cli_milestone_chat_add_child.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_cli_milestone_dispatch.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_cli_milestone_gate_b.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_cli_milestone_gate_c.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_cli_milestone_order.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_cli_milestone_remove_and_issue_close.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_cli_milestone_ship.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_cli_network.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_cli_new_issue_chat.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_cli_plans.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_cli_portal.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_cli_pull_artifact.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_cli_queue.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_cli_reattach_sessions.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_cli_refine_board.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_cli_release_preflight.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_cli_release_propagate.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_cli_release_window.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_cli_repo_2220.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_cli_scorecard.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_cli_set_review_findings.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_cli_status_advisory_terminal.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_cli_status_merge_queue.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_cli_status_provider.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_cli_status_review_finalizing.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_cli_status_test_failed_tag.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_cli_status_usage_limit.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_cli_sync_comments_873.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_cli_test_plan.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_cli_track.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_cli_tui_update.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_cli_wait.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_client_base_install.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_completion_summary.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_config.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_config_acceptance.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_config_audit.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_config_pricing.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_config_snapshot_noncanonical_2208.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_config_usage_gate.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_confirm_test.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_conflict_fix.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_conflict_fix_semantic.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_coord_test.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_coord_test_runner_baseline.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_coord_test_runner_populated_home.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_coord_test_runner_routing.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_coord_test_runner_toolchain.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_coord_web_sse_restart_live.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_coordinator_machine.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_cross_platform_imports.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_dashboard.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_dashboard_fixture.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_dashboard_terminal.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_dashboard_terminal_live.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_db.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_dead_end.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_deploy_coord_db_backup.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_deploy_coord_web_dist.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_deploy_coord_web_rollback.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_deploy_drive_queue_unit.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_deploy_manifest.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_deploy_units_lane.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_deploy_web_unit.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_deps.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_dispatch.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_dispatch_target_validation.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_dist_name.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_done_housekeeping.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_drive_queue.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_drive_state.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_drive_tmux.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_epic_up_capability_detection.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_epic_up_down_symlinked_config_1887.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_epic_up_image_provenance.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_errors.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_events.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_failure_class.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_filelock.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_finalize_interactive_exit_test_verdict.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_fix_of_force_override.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_fleet_config_health.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_fleet_health_probes.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_fleet_health_snapshot.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_forge_availability.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_freshness.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_gate_a.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_gate_b.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_gate_snapshot_staleness.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_gates.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_gather_fleet_tmux_sessions.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_gen_mock_index.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_generated_types_fixture.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_github_ops.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_goal.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_graph_health.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_graph_selfheal_absent_2237.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_handoff.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_health_checks.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_health_cli.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_health_cli_graph.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_health_config.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_health_context.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_health_coord_web_ci_pin.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_health_deploy_lane_facts.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_health_incident_regression.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_health_pypi.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_health_registry.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_health_timer_active.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_health_toolchain.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_health_unit_drift.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_health_unit_enablement.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_hooks.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_human_attended_437.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_init.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_integration.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_interactive_briefing_echo.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_interactive_prefill_state.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_interactive_session_relaunch.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_interactive_test_verdict_backstop.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_interactive_token_attribution.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_interactive_worktree.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_issue_store_seam.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_liveness_auditor.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_liveness_notify.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_machine_pause.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_merge_queue.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_merge_verify.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_milestone_chat.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_milestone_dispatch.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_milestone_gate.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_milestone_order.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_milestone_seam.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_mock_author.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_model_tiering.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_models.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_models_config_labels.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_needs_attention.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_network.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_new_issue_chat.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_next_release_tag.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_node_shim.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_notifier_baseline.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_notifier_cli.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_notifier_collect.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_notifier_config.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_notifier_drive_seam.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_notifier_isolation.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_notifier_predicate.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_notifier_quiet_hours.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_notifier_service.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_notify_drain.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_openapi.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_operational_defaults.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_overlap_fence.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_overlap_predict.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_packaged_deploy_units.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_parentage.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_paste_landed.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_pipeline.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_plan_followup_approve_plan_command.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_plan_followup_pr_command.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_plan_followup_review_command.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_plan_only.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_plan_parser.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_platform_paths.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_portal_bridge.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_portal_config.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_portal_store.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_portal_sync.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_pr_body_lint.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_prereqs.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_production_db_guard.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_progress.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_provider_seam.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_providers.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_providers_config_labels.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_providers_pty.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_quiet_hours.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_quiet_hours_store_2146.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_reap_merged_sessions.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_reap_stale_interactive_tick.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_reconcile.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_reconcile_branch.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_reconcile_completions.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_reconcile_merges.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_reconcile_no_agent_record.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_reconcile_tick.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_reconcile_usage_limit_done.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_refine_chat.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_release_cordon_2101.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_release_cordon_daemon_leads_2176.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_release_cordon_deadlock_2240.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_release_cordon_stuck_2490.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_release_propagate.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_release_unified_1242.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_release_verify.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_release_window.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_remote_auto_prune.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_remote_interactive_reaper.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_repo_edit_2220.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_repo_graph_fleet_2237.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_repo_onboard_2220.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_report_result_push.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_reports.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_retry.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_retry_advisory_1606.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_retry_type_1636.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_revalidate.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_review.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_review_end_review_without_verdict.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_review_parse_failure_diagnostic.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_review_reaffirm.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_review_state.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_review_verdict_backstop.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_review_verdict_override_audit.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_review_verdict_relay.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_review_zero_commits.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_scoped_review_wiring.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_scorecard.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_self_health.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_serve.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_serve_app_board_trim.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_session.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_slice_issue_attribution.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_smoke.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_smoke_live_checkout_restore.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_smoke_workflow.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_spend_ceiling.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_spend_ceiling_coordinator.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_split.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_split_work.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_stage_projection.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_state.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_state_review_findings_daemon.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_status_fleet_footer.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_stop_1567.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_terminal_command.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_test_author.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_test_chat.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_test_orchestrator.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_test_report.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_test_verdict_parsing.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_test_verdict_transcript_floor.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_thin_client_board_audit.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_thin_client_config_load_1080.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_thin_client_daemon_routing_906.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_tmux_host.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_tmux_session.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_transcript_floor.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_usage.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_usage_limits.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_usage_rollup.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_venv_live_install_2121.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_version_single_source.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_watch.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_windows_job_is_a_real_gate_2000.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_worker_events.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_worker_image_pin_sync.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_worker_safety.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_worker_test_scoping.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_worktree.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tests/test_worktree_rmtree_chokepoint.py +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tui/Cargo.lock +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tui/Cargo.toml +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tui/cargo-config-local-quadraui.toml.example +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tui/src/app/approved.rs +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tui/src/app/audit.rs +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tui/src/app/chat.rs +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tui/src/app/data.rs +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tui/src/app/dialogs.rs +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tui/src/app/doc_tabs.rs +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tui/src/app/drive.rs +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tui/src/app/drive_queue.rs +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tui/src/app/escalation.rs +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tui/src/app/events.rs +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tui/src/app/fixtures.rs +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tui/src/app/fleet_health.rs +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tui/src/app/fleet_sessions.rs +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tui/src/app/fleet_terminals.rs +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tui/src/app/format.rs +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tui/src/app/milestone_dag.rs +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tui/src/app/mod.rs +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tui/src/app/msv.rs +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tui/src/app/pipeline.rs +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tui/src/app/plans.rs +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tui/src/app/render.rs +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tui/src/app/reports.rs +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tui/src/app/sessions.rs +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tui/src/app/settings_ui.rs +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tui/src/app/sidebar.rs +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tui/src/app/terminal.rs +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tui/src/app/tests.rs +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tui/src/app/types.rs +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tui/src/app/workspace.rs +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tui/src/bin/gtk.rs +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tui/src/commands.rs +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tui/src/lib.rs +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tui/src/main.rs +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tui/src/settings.rs +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tui/tests/acceptance.rs +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tui/tests/cli.rs +0 -0
- {code_coordinator-0.5.218 → code_coordinator-0.5.220}/tui/tests/fixtures/board_sample.json +0 -0
|
@@ -130,8 +130,15 @@ def notify(config_path: Path) -> None:
|
|
|
130
130
|
from coord.notify import run as run_notify
|
|
131
131
|
|
|
132
132
|
cfg = _load_config(config_path)
|
|
133
|
-
posted, stuck, needs_attention, stalled, liveness = run_notify(cfg)
|
|
134
|
-
if
|
|
133
|
+
posted, stuck, needs_attention, stalled, liveness, phantom_healed = run_notify(cfg)
|
|
134
|
+
if (
|
|
135
|
+
not posted
|
|
136
|
+
and not stuck
|
|
137
|
+
and not needs_attention
|
|
138
|
+
and not stalled
|
|
139
|
+
and not liveness
|
|
140
|
+
and not phantom_healed
|
|
141
|
+
):
|
|
135
142
|
click.echo("No new transitions to notify.")
|
|
136
143
|
return
|
|
137
144
|
if posted:
|
|
@@ -173,6 +180,15 @@ def notify(config_path: Path) -> None:
|
|
|
173
180
|
f"#{lv.issue_number} (assignment {lv.assignment_id}, "
|
|
174
181
|
f"{lv.consecutive_blocked} consecutive blocked verdicts)"
|
|
175
182
|
)
|
|
183
|
+
if phantom_healed:
|
|
184
|
+
click.echo(f"Auto-healed {len(phantom_healed)} phantom row(s) (#2536):")
|
|
185
|
+
for h in phantom_healed:
|
|
186
|
+
click.echo(
|
|
187
|
+
f" [phantom-healed:{h.stage}] {h.machine_name} → {h.repo_name} "
|
|
188
|
+
f"#{h.issue_number} (assignment {h.assignment_id})"
|
|
189
|
+
)
|
|
190
|
+
click.echo(f" {h.detail}")
|
|
191
|
+
click.echo(f" → {h.action}")
|
|
176
192
|
board = read_board()
|
|
177
193
|
|
|
178
194
|
if is_round_complete(board) and cfg.hooks.on_round_complete:
|
|
@@ -1933,6 +1933,35 @@ def merge(
|
|
|
1933
1933
|
"— nothing to do"
|
|
1934
1934
|
)
|
|
1935
1935
|
sys.exit(0)
|
|
1936
|
+
# #2558: a CONFLICT entry used to dead-end right here — the generic
|
|
1937
|
+
# "not PENDING) — cannot merge" refusal below applies equally to
|
|
1938
|
+
# HUMAN_REQUIRED/DROPPED, but CONFLICT is different from those: it is
|
|
1939
|
+
# the state #241's conflict-fix exists to clear, and nothing else
|
|
1940
|
+
# ever gives it a second look (`merge_queue.process()` only acts on
|
|
1941
|
+
# PENDING; the reconcile pass above only unparks an entry GitHub
|
|
1942
|
+
# already reports mergeable again). Give it the SAME
|
|
1943
|
+
# classify-and-dispatch chance the whole-queue path gets for a fresh
|
|
1944
|
+
# conflict, then still fall through to the generic refusal below —
|
|
1945
|
+
# dispatching a fix does not put the branch on the target branch
|
|
1946
|
+
# THIS pass, so the postcondition genuinely isn't met yet.
|
|
1947
|
+
if only_entry.state == CONFLICT:
|
|
1948
|
+
_verb = "(dry run) would retry" if dry_run else "retrying"
|
|
1949
|
+
click.echo(
|
|
1950
|
+
f" {only_entry.repo_name} #{only_entry.issue_number} "
|
|
1951
|
+
f"({only_entry.branch}): still CONFLICT — {_verb} #241 "
|
|
1952
|
+
"conflict-fix dispatch instead of refusing outright (#2558)"
|
|
1953
|
+
)
|
|
1954
|
+
_dispatch_conflict_fixes(
|
|
1955
|
+
[mq.MergeEvent(only_entry, "conflict", only_entry.error)],
|
|
1956
|
+
cfg_only, dry_run=dry_run,
|
|
1957
|
+
)
|
|
1958
|
+
if not dry_run:
|
|
1959
|
+
all_items_only = mq.load_queue()
|
|
1960
|
+
by_id_only = {only_entry.assignment_id: only_entry}
|
|
1961
|
+
merged_only = [
|
|
1962
|
+
by_id_only.get(x.assignment_id, x) for x in all_items_only
|
|
1963
|
+
]
|
|
1964
|
+
mq.save_queue(merged_only)
|
|
1936
1965
|
if only_entry.state != PENDING:
|
|
1937
1966
|
click.echo(
|
|
1938
1967
|
f"merge-queue: entry {only_assignment!r} is in state "
|
|
@@ -2292,7 +2321,44 @@ def merge(
|
|
|
2292
2321
|
presorted = True
|
|
2293
2322
|
|
|
2294
2323
|
pending = [x for x in items if x.state == PENDING]
|
|
2324
|
+
|
|
2325
|
+
# #2558: a CONFLICT row is a dead end everywhere else in this command.
|
|
2326
|
+
# #241's conflict-fix is normally dispatched off a FRESH transition into
|
|
2327
|
+
# CONFLICT — process() below, the sibling sweep, --revalidate — because
|
|
2328
|
+
# all three build their dispatch event from the transition itself. An
|
|
2329
|
+
# entry that transitioned on some EARLIER tick and is still sitting
|
|
2330
|
+
# there (no machine was free at the time, the fix is still running, or
|
|
2331
|
+
# dispatch was simply declined) never reappears in a fresh `events`
|
|
2332
|
+
# list, so nothing ever asks again — see the #2558 issue's coord-portal
|
|
2333
|
+
# #131 repro, wedged this way with zero conflict-fix assignments ever
|
|
2334
|
+
# dispatched. Give every standing CONFLICT row a fresh chance on EVERY
|
|
2335
|
+
# invocation, before the terminal-state early-return below — a queue
|
|
2336
|
+
# that is 100% terminal (#131's exact shape) is exactly the case that
|
|
2337
|
+
# return skips.
|
|
2338
|
+
standing_conflicts = [x for x in items if x.state == CONFLICT]
|
|
2339
|
+
if standing_conflicts:
|
|
2340
|
+
_verb = "(dry run) would retry" if dry_run else "retrying"
|
|
2341
|
+
for x in standing_conflicts:
|
|
2342
|
+
click.echo(
|
|
2343
|
+
f" {x.repo_name} #{x.issue_number} ({x.branch}): still "
|
|
2344
|
+
f"CONFLICT — {_verb} #241 conflict-fix dispatch (#2558)"
|
|
2345
|
+
)
|
|
2346
|
+
_dispatch_conflict_fixes(
|
|
2347
|
+
[mq.MergeEvent(x, "conflict", x.error) for x in standing_conflicts],
|
|
2348
|
+
cfg, dry_run=dry_run,
|
|
2349
|
+
)
|
|
2350
|
+
|
|
2295
2351
|
if not pending:
|
|
2352
|
+
if not dry_run and standing_conflicts:
|
|
2353
|
+
# process() never runs this pass (nothing is PENDING), so its
|
|
2354
|
+
# own save-queue step below is unreached — persist whatever the
|
|
2355
|
+
# redispatch above mutated (e.g. a retry-cap escalation to
|
|
2356
|
+
# HUMAN_REQUIRED) before returning, same convention as the
|
|
2357
|
+
# --only path above.
|
|
2358
|
+
all_items = mq.load_queue()
|
|
2359
|
+
by_id = {x.assignment_id: x for x in items}
|
|
2360
|
+
merged = [by_id.get(x.assignment_id, x) for x in all_items]
|
|
2361
|
+
mq.save_queue(merged)
|
|
2296
2362
|
# Still surface terminal states so the user knows what happened.
|
|
2297
2363
|
for x in items:
|
|
2298
2364
|
click.echo(f" [{x.state}] {x.repo_name} #{x.issue_number} ({x.branch})")
|
|
@@ -53,6 +53,16 @@ EVENT_STALLED = "stalled_pipeline"
|
|
|
53
53
|
# surfacing only, exactly like EVENT_NEEDS_ATTENTION/EVENT_STALLED: never
|
|
54
54
|
# gates status/review_state/test_state.
|
|
55
55
|
EVENT_LIVENESS_STALL = "liveness_stall"
|
|
56
|
+
# #2536: a `running` row the fleet-wide sweep
|
|
57
|
+
# (`coord.diagnose.sweep_dead_running_rows`) confirmed dead via its own
|
|
58
|
+
# recorded machine's live status, found aged well past its own
|
|
59
|
+
# EVENT_NEEDS_ATTENTION wall-clock threshold, and auto-healed with the same
|
|
60
|
+
# non-destructive recovery `coord diagnose --reset` runs by hand — branch
|
|
61
|
+
# and commits preserved, stage re-dispatchable, and (as a side effect of the
|
|
62
|
+
# row leaving `running`) its repo's drive-queue concurrency slot freed.
|
|
63
|
+
# Unlike every other EVENT_* above, this one narrates an action ALREADY
|
|
64
|
+
# TAKEN, not only a finding.
|
|
65
|
+
EVENT_PHANTOM_HEALED = "phantom_row_healed"
|
|
56
66
|
|
|
57
67
|
|
|
58
68
|
@dataclass
|
|
@@ -479,6 +489,55 @@ def format_liveness_stall(
|
|
|
479
489
|
return "\n".join(lines)
|
|
480
490
|
|
|
481
491
|
|
|
492
|
+
def format_phantom_row_healed(
|
|
493
|
+
*,
|
|
494
|
+
assignment_id: str,
|
|
495
|
+
machine_name: str,
|
|
496
|
+
repo_name: str,
|
|
497
|
+
issue_number: int,
|
|
498
|
+
stage: str,
|
|
499
|
+
detail: str,
|
|
500
|
+
action: str,
|
|
501
|
+
) -> str:
|
|
502
|
+
"""Format a "phantom row auto-healed" comment (#2536).
|
|
503
|
+
|
|
504
|
+
Mirrors :func:`format_needs_attention`'s shape (same headings, same
|
|
505
|
+
"detection ... human should look" register), with one deliberate
|
|
506
|
+
difference: this one is posted AFTER the automatic, non-destructive
|
|
507
|
+
``coord diagnose --reset``-equivalent recovery already ran, not before
|
|
508
|
+
it — *detail* explains what was confirmed (dead session, aged past
|
|
509
|
+
threshold), *action* what was actually done.
|
|
510
|
+
"""
|
|
511
|
+
marker = _marker(
|
|
512
|
+
EVENT_PHANTOM_HEALED,
|
|
513
|
+
assignment=assignment_id,
|
|
514
|
+
machine=machine_name,
|
|
515
|
+
repo=repo_name,
|
|
516
|
+
stage=stage,
|
|
517
|
+
)
|
|
518
|
+
lines = [
|
|
519
|
+
marker,
|
|
520
|
+
"## 🩹 Phantom row auto-healed",
|
|
521
|
+
f"**Machine:** {machine_name}",
|
|
522
|
+
f"**Assignment:** {assignment_id}",
|
|
523
|
+
f"**Issue:** #{issue_number}",
|
|
524
|
+
f"**Stage:** {stage}",
|
|
525
|
+
"",
|
|
526
|
+
detail.strip(),
|
|
527
|
+
"",
|
|
528
|
+
f"**Action taken:** {action.strip()}",
|
|
529
|
+
"",
|
|
530
|
+
"This session's own recorded machine reported nothing active for "
|
|
531
|
+
"it, and the row had already sat well past its own needs-attention "
|
|
532
|
+
"threshold — the same phantom-row recovery `coord diagnose "
|
|
533
|
+
"--reset` performs by hand ran automatically. The branch and any "
|
|
534
|
+
"commits are preserved, the stage is re-dispatchable, and this "
|
|
535
|
+
"repo's drive-queue slot is freed. If this looks wrong, `coord log "
|
|
536
|
+
"<id>` / `coord diagnose <repo> <issue>` can confirm what happened.",
|
|
537
|
+
]
|
|
538
|
+
return "\n".join(lines)
|
|
539
|
+
|
|
540
|
+
|
|
482
541
|
_STALLED_REASON_LABELS = {
|
|
483
542
|
"review_request_changes_no_fix": "Review requested changes, no fix dispatched",
|
|
484
543
|
"review_done_no_verdict": "Review finished with no verdict ever captured (#812)",
|
|
@@ -989,6 +989,25 @@ class PipelineConfig:
|
|
|
989
989
|
stands. Costs one real suite run per Test-stage completion where it
|
|
990
990
|
*can* apply; set ``false`` (or ``COORD_CONFIRM_TEST_VERDICT=0``) to opt
|
|
991
991
|
back out.
|
|
992
|
+
|
|
993
|
+
``auto_heal_phantom_rows`` (#2536) controls whether
|
|
994
|
+
``coord.notify._sweep_phantom_rows`` gets to act, on
|
|
995
|
+
``coord-notify.timer``'s existing cadence, on a ``running`` board row
|
|
996
|
+
its own recorded machine confirms is dead (see
|
|
997
|
+
``coord.diagnose.sweep_dead_running_rows``). **Defaults to ``True``**,
|
|
998
|
+
the same posture as ``confirm_test_verdict`` and for the same reason:
|
|
999
|
+
this closes a real bug (a phantom row silently holding its repo's
|
|
1000
|
+
entire drive-queue concurrency slot indefinitely — #2536) rather than
|
|
1001
|
+
adding a new capability, and every action it takes is gated behind a
|
|
1002
|
+
CONFIRMED-dead liveness read (never an ambiguous "unknown" one — #1870)
|
|
1003
|
+
plus a wall-clock buffer past the row's own ``needs_attention``
|
|
1004
|
+
threshold, so it never races a session that is merely idle between
|
|
1005
|
+
turns. Unlike ``auto_dispatch_stalled``/``escalate_semantic_conflicts``,
|
|
1006
|
+
it never dispatches new work and never touches a branch — the recovery
|
|
1007
|
+
is the same non-destructive one ``coord diagnose --reset`` already
|
|
1008
|
+
performs by hand (branch/commits preserved, stage re-dispatchable). Set
|
|
1009
|
+
``false`` to require a human to run ``coord diagnose --reset``
|
|
1010
|
+
themselves, as before #2536.
|
|
992
1011
|
"""
|
|
993
1012
|
|
|
994
1013
|
default_gates: list[str] = field(default_factory=lambda: ["test", "review", "merge"])
|
|
@@ -1009,6 +1028,8 @@ class PipelineConfig:
|
|
|
1009
1028
|
liveness_auditor: LivenessAuditorConfig = field(default_factory=LivenessAuditorConfig)
|
|
1010
1029
|
# #2464 — DEFAULT ON. See the class docstring.
|
|
1011
1030
|
confirm_test_verdict: bool = True
|
|
1031
|
+
# #2536 — DEFAULT ON. See the class docstring.
|
|
1032
|
+
auto_heal_phantom_rows: bool = True
|
|
1012
1033
|
|
|
1013
1034
|
def attention_threshold_for(
|
|
1014
1035
|
self,
|
|
@@ -2763,6 +2784,12 @@ def _parse_pipeline(raw: Any) -> PipelineConfig:
|
|
|
2763
2784
|
raise ConfigError("pipeline.confirm_test_verdict must be a boolean")
|
|
2764
2785
|
cfg.confirm_test_verdict = value
|
|
2765
2786
|
|
|
2787
|
+
if "auto_heal_phantom_rows" in raw:
|
|
2788
|
+
value = raw["auto_heal_phantom_rows"]
|
|
2789
|
+
if not isinstance(value, bool):
|
|
2790
|
+
raise ConfigError("pipeline.auto_heal_phantom_rows must be a boolean")
|
|
2791
|
+
cfg.auto_heal_phantom_rows = value
|
|
2792
|
+
|
|
2766
2793
|
if "max_review_iterations" in raw:
|
|
2767
2794
|
value = raw["max_review_iterations"]
|
|
2768
2795
|
if not isinstance(value, int) or value < 1:
|
|
@@ -2,9 +2,15 @@
|
|
|
2
2
|
#
|
|
3
3
|
# A systemd *user* unit (mirrors coord-agent/coord-serve/coord-web), paired
|
|
4
4
|
# with coord-notify.timer. Runs `coord notify` on a schedule: polls each
|
|
5
|
-
# agent for completion, posts the GH completion/failure comments,
|
|
6
|
-
#
|
|
7
|
-
# re-review-on-fix-completion)
|
|
5
|
+
# agent for completion, posts the GH completion/failure comments, triggers
|
|
6
|
+
# the auto-loop (review-on-completion, fix-on-request-changes,
|
|
7
|
+
# re-review-on-fix-completion), and — #2536 — auto-heals any `running` board
|
|
8
|
+
# row whose recorded machine confirms is dead and aged well past its own
|
|
9
|
+
# needs-attention threshold (the same non-destructive recovery `coord
|
|
10
|
+
# diagnose --reset` performs by hand; see
|
|
11
|
+
# docs/AGENT_OPERATIONS.md → "Periodic coord notify" for the guardrails, and
|
|
12
|
+
# `pipeline.auto_heal_phantom_rows` in coordinator.yml to opt out). Install
|
|
13
|
+
# ONLY on the box that owns
|
|
8
14
|
# ~/.coord/coord.db (dellserver in production — the same host that runs
|
|
9
15
|
# coord-serve/coord-web) — it must NOT run on a thin-client machine, since
|
|
10
16
|
# `coord notify` there would just re-route itself back over HTTP to the
|
|
@@ -1454,6 +1454,163 @@ def _is_stale(assignment: "Assignment", *, max_age_hours: float = 12.0) -> bool:
|
|
|
1454
1454
|
return (time.time() - assignment.dispatched_at) > max_age_hours * 3600.0
|
|
1455
1455
|
|
|
1456
1456
|
|
|
1457
|
+
# ── #2536: fleet-wide phantom-row self-heal sweep ───────────────────────────
|
|
1458
|
+
#
|
|
1459
|
+
# `_cleanup_issue` above already recovers phantom `running` rows — but only
|
|
1460
|
+
# ONE issue at a time, and only when a human happens to run `coord diagnose
|
|
1461
|
+
# <repo> <issue> --reset`. Nothing runs that recovery on its own, so a
|
|
1462
|
+
# phantom row can sit indefinitely holding its repo's entire drive-queue
|
|
1463
|
+
# concurrency slot (`coord/drive_queue.py`'s own capacity comment: "a drive
|
|
1464
|
+
# whose observer died still holds its repo's slot until something reconciles
|
|
1465
|
+
# it"). :func:`sweep_dead_running_rows` is that "something" — a fleet-wide,
|
|
1466
|
+
# board-scanning counterpart callable periodically (see
|
|
1467
|
+
# `coord.notify._sweep_phantom_rows`, which piggybacks it on
|
|
1468
|
+
# `coord-notify.timer`'s existing 5-minute cadence) rather than only on
|
|
1469
|
+
# operator demand.
|
|
1470
|
+
|
|
1471
|
+
# How far past a row's own needs-attention wall-clock threshold it must sit
|
|
1472
|
+
# before this sweep will treat a CONFIRMED-dead session as safe to
|
|
1473
|
+
# auto-heal. Two full `coord-notify.timer` cycles (5min cadence) of margin:
|
|
1474
|
+
# large enough that `coord.notify.detect_needs_attention` has already had a
|
|
1475
|
+
# full extra tick to flag (and a human a full extra tick to notice) the same
|
|
1476
|
+
# row via the existing `needs_attention` comment before this sweep ever
|
|
1477
|
+
# touches it, small enough that a genuinely dead row doesn't sit much longer
|
|
1478
|
+
# than it already would have. Never a substitute for the liveness check
|
|
1479
|
+
# below — a row can be arbitrarily old and still left alone if its session
|
|
1480
|
+
# reads "live" or "unknown".
|
|
1481
|
+
PHANTOM_HEAL_BUFFER_SECONDS = 600.0
|
|
1482
|
+
|
|
1483
|
+
|
|
1484
|
+
@dataclass
|
|
1485
|
+
class PhantomRowHeal:
|
|
1486
|
+
"""One board row this sweep confirmed dead, aged out past its own
|
|
1487
|
+
needs-attention threshold, and healed automatically (or, in a dry run,
|
|
1488
|
+
WOULD heal) — see :func:`sweep_dead_running_rows`."""
|
|
1489
|
+
|
|
1490
|
+
assignment_id: str
|
|
1491
|
+
machine_name: str
|
|
1492
|
+
repo_name: str
|
|
1493
|
+
issue_number: int
|
|
1494
|
+
stage: str
|
|
1495
|
+
detail: str
|
|
1496
|
+
action: str = ""
|
|
1497
|
+
|
|
1498
|
+
|
|
1499
|
+
def sweep_dead_running_rows(
|
|
1500
|
+
board: "Board",
|
|
1501
|
+
config: "Config",
|
|
1502
|
+
*,
|
|
1503
|
+
now: float | None = None,
|
|
1504
|
+
dry_run: bool = False,
|
|
1505
|
+
) -> list[PhantomRowHeal]:
|
|
1506
|
+
"""The automatic counterpart to a human running ``coord diagnose <repo>
|
|
1507
|
+
<issue> --reset`` on a phantom ``running`` row (#2536).
|
|
1508
|
+
|
|
1509
|
+
Scans every ``running``/``pending`` row on *board* (fleet-wide, not
|
|
1510
|
+
scoped to one issue — unlike :func:`_cleanup_issue`) and, for each,
|
|
1511
|
+
applies the same two guards a careful human would before touching a
|
|
1512
|
+
row that merely *looks* wedged:
|
|
1513
|
+
|
|
1514
|
+
1. **Confirmed dead, never ambiguous** — liveness is read via
|
|
1515
|
+
:func:`_session_state` (tmux first, local or remote, falling back to
|
|
1516
|
+
the assignment's own recorded machine's ``/status``), and only a
|
|
1517
|
+
``"dead"`` verdict is actionable. ``"unknown"`` (an unresolvable or
|
|
1518
|
+
unconfigured machine, an unreachable agent, a probe error) is always
|
|
1519
|
+
left alone, exactly like ``"live"`` — the same #1870 caution
|
|
1520
|
+
``coord/drive_queue.py`` documents ("liveness cannot be verified from
|
|
1521
|
+
here, so this is UNKNOWN, not dead") applies here too: only the
|
|
1522
|
+
assignment's own recorded machine can make this call.
|
|
1523
|
+
2. **Aged out, not merely between turns** — the row must be running
|
|
1524
|
+
longer than its own ``config.pipeline.attention_threshold_for(...)``
|
|
1525
|
+
(the same wall-clock threshold
|
|
1526
|
+
:func:`coord.notify.detect_needs_attention` uses) PLUS
|
|
1527
|
+
:data:`PHANTOM_HEAL_BUFFER_SECONDS` of margin, so a session that is
|
|
1528
|
+
merely idle between turns or briefly disconnected is never raced.
|
|
1529
|
+
|
|
1530
|
+
Recovery, once both guards pass, is byte-for-byte
|
|
1531
|
+
:func:`_finalize_dead` — the exact non-destructive action ``coord
|
|
1532
|
+
diagnose --reset`` runs for a phantom row: branch and commits are always
|
|
1533
|
+
preserved, and the stage becomes re-dispatchable. Writes go through the
|
|
1534
|
+
same seam (``issue_store``, not ``save_board``) :func:`_cleanup_issue`
|
|
1535
|
+
already uses, so this function never mutates *board* and the caller
|
|
1536
|
+
does not need to persist it. Freeing the row's repo's drive-queue slot
|
|
1537
|
+
is then a side effect of the write, not something this function or its
|
|
1538
|
+
caller has to do explicitly — the next board read simply no longer
|
|
1539
|
+
counts the row as ``running``.
|
|
1540
|
+
|
|
1541
|
+
Returns one :class:`PhantomRowHeal` per row healed (or, when *dry_run*,
|
|
1542
|
+
per row that WOULD be healed), so the caller can post a GitHub comment
|
|
1543
|
+
recording it — mirroring the existing ``needs_attention`` comment's
|
|
1544
|
+
posture, but reporting an action already taken rather than only a
|
|
1545
|
+
finding.
|
|
1546
|
+
"""
|
|
1547
|
+
if now is None:
|
|
1548
|
+
now = time.time()
|
|
1549
|
+
|
|
1550
|
+
healed: list[PhantomRowHeal] = []
|
|
1551
|
+
seen_ids: set[str] = set()
|
|
1552
|
+
for a in (board.active + board.completed):
|
|
1553
|
+
if a.status not in ("running", "pending"):
|
|
1554
|
+
continue
|
|
1555
|
+
if not a.assignment_id or a.assignment_id in seen_ids:
|
|
1556
|
+
continue
|
|
1557
|
+
seen_ids.add(a.assignment_id)
|
|
1558
|
+
if not a.dispatched_at:
|
|
1559
|
+
continue # nothing to compute an age from — never guess
|
|
1560
|
+
|
|
1561
|
+
threshold = config.pipeline.attention_threshold_for(
|
|
1562
|
+
a.type or "work",
|
|
1563
|
+
provider_name=a.provider_name,
|
|
1564
|
+
review_of_assignment_id=a.review_of_assignment_id,
|
|
1565
|
+
)
|
|
1566
|
+
if threshold == float("inf"):
|
|
1567
|
+
continue # interactive session type — no wall-clock concept
|
|
1568
|
+
running_for = now - a.dispatched_at
|
|
1569
|
+
if running_for <= threshold + PHANTOM_HEAL_BUFFER_SECONDS:
|
|
1570
|
+
continue # not aged out yet — don't race a session between turns
|
|
1571
|
+
|
|
1572
|
+
if _session_state(a, config) != "dead":
|
|
1573
|
+
# "unknown" or "live" — only ever act on a CONFIRMED-dead read,
|
|
1574
|
+
# never an ambiguous one (#1870/#2536).
|
|
1575
|
+
continue
|
|
1576
|
+
|
|
1577
|
+
detail = (
|
|
1578
|
+
f"{a.type or 'work'} row running {running_for / 60.0:.0f}m "
|
|
1579
|
+
f"(past its {threshold / 60.0:.0f}m needs-attention threshold + "
|
|
1580
|
+
f"{PHANTOM_HEAL_BUFFER_SECONDS / 60.0:.0f}m buffer) — session "
|
|
1581
|
+
f"confirmed dead on machine {a.machine_name!r}"
|
|
1582
|
+
)
|
|
1583
|
+
if dry_run:
|
|
1584
|
+
healed.append(PhantomRowHeal(
|
|
1585
|
+
assignment_id=a.assignment_id,
|
|
1586
|
+
machine_name=a.machine_name or "unknown",
|
|
1587
|
+
repo_name=a.repo_name,
|
|
1588
|
+
issue_number=a.issue_number,
|
|
1589
|
+
stage=a.type or "work",
|
|
1590
|
+
detail=detail,
|
|
1591
|
+
action="(dry-run) would finalize the phantom session",
|
|
1592
|
+
))
|
|
1593
|
+
continue
|
|
1594
|
+
|
|
1595
|
+
try:
|
|
1596
|
+
action = f"finalized phantom session ({_finalize_dead(a, config)})"
|
|
1597
|
+
except Exception as exc: # noqa: BLE001 — fall back to a direct terminal mark
|
|
1598
|
+
_mark_terminal(a, config)
|
|
1599
|
+
action = f"finalize failed ({exc}); marked row terminal directly"
|
|
1600
|
+
|
|
1601
|
+
healed.append(PhantomRowHeal(
|
|
1602
|
+
assignment_id=a.assignment_id,
|
|
1603
|
+
machine_name=a.machine_name or "unknown",
|
|
1604
|
+
repo_name=a.repo_name,
|
|
1605
|
+
issue_number=a.issue_number,
|
|
1606
|
+
stage=a.type or "work",
|
|
1607
|
+
detail=detail,
|
|
1608
|
+
action=action,
|
|
1609
|
+
))
|
|
1610
|
+
|
|
1611
|
+
return healed
|
|
1612
|
+
|
|
1613
|
+
|
|
1457
1614
|
# ── #618: orphaned worktree detection + pruning ──────────────────────────────
|
|
1458
1615
|
|
|
1459
1616
|
|
|
@@ -11,6 +11,7 @@ from typing import TYPE_CHECKING
|
|
|
11
11
|
import httpx
|
|
12
12
|
|
|
13
13
|
if TYPE_CHECKING:
|
|
14
|
+
from coord.diagnose import PhantomRowHeal
|
|
14
15
|
from coord.merge_queue import QueuedMerge
|
|
15
16
|
from coord.models import Assignment, Board
|
|
16
17
|
from coord.progress import SmokeVerdict
|
|
@@ -3544,6 +3545,106 @@ def _sweep_stalled_pipeline(
|
|
|
3544
3545
|
return posted
|
|
3545
3546
|
|
|
3546
3547
|
|
|
3548
|
+
# ── #2536: fleet-wide phantom-row self-heal sweep ───────────────────────────
|
|
3549
|
+
#
|
|
3550
|
+
# See `coord.diagnose.sweep_dead_running_rows`'s docstring for the full
|
|
3551
|
+
# rationale. This is the thin `coord notify` glue around it: read the board,
|
|
3552
|
+
# run the sweep (which does the actual recovery write per row), post one
|
|
3553
|
+
# comment per row it healed, and audit-log it. No board write-back is needed
|
|
3554
|
+
# here — the sweep writes through `issue_store` directly (the same seam
|
|
3555
|
+
# `_cleanup_issue` uses), never mutating the in-memory `board` object.
|
|
3556
|
+
|
|
3557
|
+
|
|
3558
|
+
def post_phantom_row_healed(heal: "PhantomRowHeal", config: Config) -> None:
|
|
3559
|
+
"""Post the #2536 auto-heal comment for one board row
|
|
3560
|
+
:func:`_sweep_phantom_rows` just recovered."""
|
|
3561
|
+
from coord.comments import ( # noqa: PLC0415
|
|
3562
|
+
format_phantom_row_healed,
|
|
3563
|
+
)
|
|
3564
|
+
|
|
3565
|
+
repo = config.repo(heal.repo_name)
|
|
3566
|
+
repo_github = repo.github if repo is not None else None
|
|
3567
|
+
if not repo_github:
|
|
3568
|
+
return
|
|
3569
|
+
body = format_phantom_row_healed(
|
|
3570
|
+
assignment_id=heal.assignment_id,
|
|
3571
|
+
machine_name=heal.machine_name,
|
|
3572
|
+
repo_name=heal.repo_name,
|
|
3573
|
+
issue_number=heal.issue_number,
|
|
3574
|
+
stage=heal.stage,
|
|
3575
|
+
detail=heal.detail,
|
|
3576
|
+
action=heal.action,
|
|
3577
|
+
)
|
|
3578
|
+
github_ops.post_issue_comment(repo_github, heal.issue_number, body)
|
|
3579
|
+
|
|
3580
|
+
|
|
3581
|
+
def _sweep_phantom_rows(config: Config) -> list["PhantomRowHeal"]:
|
|
3582
|
+
"""Scan the board for ``running``/``pending`` rows whose session is
|
|
3583
|
+
CONFIRMED dead and aged well past their own needs-attention threshold,
|
|
3584
|
+
auto-heal them with the same non-destructive recovery ``coord diagnose
|
|
3585
|
+
--reset`` performs by hand, and post one comment per row recovered
|
|
3586
|
+
(#2536).
|
|
3587
|
+
|
|
3588
|
+
Gated by ``config.pipeline.auto_heal_phantom_rows`` (**default
|
|
3589
|
+
``True``** — see that field's docstring for why this ships lit unlike
|
|
3590
|
+
``auto_dispatch_stalled``/``escalate_semantic_conflicts``: every action
|
|
3591
|
+
here is gated behind a confirmed-dead liveness read plus an aged-out
|
|
3592
|
+
wall-clock buffer, and the recovery itself never dispatches work or
|
|
3593
|
+
touches a branch).
|
|
3594
|
+
|
|
3595
|
+
Best-effort per row, mirroring :func:`_sweep_stalled_pipeline`'s
|
|
3596
|
+
contract: a comment-posting failure for one row must not stop the sweep
|
|
3597
|
+
from reaching the rest, and does not block the row's own recovery
|
|
3598
|
+
(already durably written by the time this posts) — it just means the
|
|
3599
|
+
GitHub comment is missing, which a future manual `coord diagnose` can
|
|
3600
|
+
still explain.
|
|
3601
|
+
"""
|
|
3602
|
+
if not config.pipeline.auto_heal_phantom_rows:
|
|
3603
|
+
return []
|
|
3604
|
+
|
|
3605
|
+
from coord.board_service import read_board # noqa: PLC0415
|
|
3606
|
+
from coord.diagnose import sweep_dead_running_rows # noqa: PLC0415
|
|
3607
|
+
|
|
3608
|
+
board = read_board()
|
|
3609
|
+
healed = sweep_dead_running_rows(board, config)
|
|
3610
|
+
|
|
3611
|
+
posted: list["PhantomRowHeal"] = []
|
|
3612
|
+
for heal in healed:
|
|
3613
|
+
try:
|
|
3614
|
+
post_phantom_row_healed(heal, config)
|
|
3615
|
+
except Exception: # noqa: BLE001
|
|
3616
|
+
log.exception(
|
|
3617
|
+
"post_phantom_row_healed failed for %s", heal.assignment_id,
|
|
3618
|
+
)
|
|
3619
|
+
continue
|
|
3620
|
+
posted.append(heal)
|
|
3621
|
+
|
|
3622
|
+
try:
|
|
3623
|
+
from coord.audit import record_audit # noqa: PLC0415
|
|
3624
|
+
|
|
3625
|
+
record_audit(
|
|
3626
|
+
tier="business",
|
|
3627
|
+
category="pipeline",
|
|
3628
|
+
event_type="phantom_row_auto_healed",
|
|
3629
|
+
actor="coordinator",
|
|
3630
|
+
summary=(
|
|
3631
|
+
f"phantom-row sweep healed {heal.stage} row "
|
|
3632
|
+
f"{heal.assignment_id} for {heal.repo_name}#{heal.issue_number}"
|
|
3633
|
+
),
|
|
3634
|
+
repo=heal.repo_name,
|
|
3635
|
+
issue=heal.issue_number,
|
|
3636
|
+
assignment_id=heal.assignment_id,
|
|
3637
|
+
machine=heal.machine_name,
|
|
3638
|
+
details={"detail": heal.detail, "action": heal.action},
|
|
3639
|
+
)
|
|
3640
|
+
except Exception: # noqa: BLE001
|
|
3641
|
+
log.exception(
|
|
3642
|
+
"record_audit failed for phantom-row heal %s", heal.assignment_id,
|
|
3643
|
+
)
|
|
3644
|
+
|
|
3645
|
+
return posted
|
|
3646
|
+
|
|
3647
|
+
|
|
3547
3648
|
@dataclass(frozen=True)
|
|
3548
3649
|
class DrainResult:
|
|
3549
3650
|
"""What one :func:`run_drain` pass actually did.
|
|
@@ -3828,23 +3929,27 @@ def run(
|
|
|
3828
3929
|
list[NeedsAttentionDetection],
|
|
3829
3930
|
list[StalledDetection],
|
|
3830
3931
|
list[LivenessStallDetection],
|
|
3932
|
+
list["PhantomRowHeal"],
|
|
3831
3933
|
]:
|
|
3832
3934
|
"""Detect and post all pending transitions, stuck signals, #846
|
|
3833
|
-
needs-attention detections, #1441 stalled-pipeline detections,
|
|
3834
|
-
|
|
3935
|
+
needs-attention detections, #1441 stalled-pipeline detections, #2048
|
|
3936
|
+
liveness-auditor stalls, and #2536 phantom-row auto-heals.
|
|
3835
3937
|
|
|
3836
3938
|
Also dispatches any pending reviews found on the saved board so that
|
|
3837
3939
|
``coord notify`` acts as a reliable review-dispatch trigger in addition
|
|
3838
3940
|
to ``coord status --reconcile``.
|
|
3839
3941
|
|
|
3840
3942
|
Returns (posted_transitions, posted_stuck, posted_needs_attention,
|
|
3841
|
-
posted_stalled, posted_liveness).
|
|
3842
|
-
appended rather than inserted,
|
|
3843
|
-
|
|
3844
|
-
is a good thing (it
|
|
3845
|
-
wired up, not silently
|
|
3846
|
-
|
|
3847
|
-
|
|
3943
|
+
posted_stalled, posted_liveness, posted_phantom_healed). Each of the
|
|
3944
|
+
liveness and phantom-healed entries was appended rather than inserted,
|
|
3945
|
+
following #1441's own precedent: any existing caller unpacking a
|
|
3946
|
+
shorter tuple positionally breaks loudly, which is a good thing (it
|
|
3947
|
+
means the CLI/board/TUI surfacing was actually wired up, not silently
|
|
3948
|
+
skipped). ``posted_liveness`` is always ``[]`` when
|
|
3949
|
+
``config.pipeline.liveness_auditor.enabled`` is ``False`` (the
|
|
3950
|
+
default); ``posted_phantom_healed`` is always ``[]`` when
|
|
3951
|
+
``config.pipeline.auto_heal_phantom_rows`` is ``False`` (not the
|
|
3952
|
+
default — see that field's docstring).
|
|
3848
3953
|
"""
|
|
3849
3954
|
# Refresh the agent-host cache so _try_parse_and_post_review (and any
|
|
3850
3955
|
# other helper using _agent_host) can resolve hostnames without
|
|
@@ -3929,6 +4034,20 @@ def run(
|
|
|
3929
4034
|
except Exception: # noqa: BLE001
|
|
3930
4035
|
log.exception("detect_needs_attention: unexpected error")
|
|
3931
4036
|
|
|
4037
|
+
# #2536: fleet-wide phantom-row self-heal — a `running` row whose
|
|
4038
|
+
# session its own recorded machine confirms is dead, aged well past its
|
|
4039
|
+
# own needs-attention threshold, gets the same non-destructive recovery
|
|
4040
|
+
# `coord diagnose --reset` performs by hand, automatically. Runs right
|
|
4041
|
+
# after the needs-attention scan above (same "long-running row" concern,
|
|
4042
|
+
# acted on rather than only narrated) and before the dispatch steps
|
|
4043
|
+
# below, so a slot this sweep frees is visible to them in the same pass.
|
|
4044
|
+
# Best-effort, non-fatal — mirrors every other sweep in this function.
|
|
4045
|
+
phantom_healed_posted: list["PhantomRowHeal"] = []
|
|
4046
|
+
try:
|
|
4047
|
+
phantom_healed_posted = _sweep_phantom_rows(config)
|
|
4048
|
+
except Exception: # noqa: BLE001
|
|
4049
|
+
log.exception("_sweep_phantom_rows: unexpected error")
|
|
4050
|
+
|
|
3932
4051
|
# Dispatch pending Test-stage smoke from the saved board (#1426;
|
|
3933
4052
|
# best-effort, non-fatal). Runs BEFORE review dispatch to mirror the
|
|
3934
4053
|
# pipeline's Work -> Test -> Review order, though ordering isn't load-
|
|
@@ -4036,4 +4155,11 @@ def run(
|
|
|
4036
4155
|
except Exception: # noqa: BLE001
|
|
4037
4156
|
log.exception("detect_liveness_stall: unexpected error")
|
|
4038
4157
|
|
|
4039
|
-
return
|
|
4158
|
+
return (
|
|
4159
|
+
posted,
|
|
4160
|
+
stuck_posted,
|
|
4161
|
+
needs_attention_posted,
|
|
4162
|
+
stalled_posted,
|
|
4163
|
+
liveness_posted,
|
|
4164
|
+
phantom_healed_posted,
|
|
4165
|
+
)
|
|
@@ -2,9 +2,15 @@
|
|
|
2
2
|
#
|
|
3
3
|
# A systemd *user* unit (mirrors coord-agent/coord-serve/coord-web), paired
|
|
4
4
|
# with coord-notify.timer. Runs `coord notify` on a schedule: polls each
|
|
5
|
-
# agent for completion, posts the GH completion/failure comments,
|
|
6
|
-
#
|
|
7
|
-
# re-review-on-fix-completion)
|
|
5
|
+
# agent for completion, posts the GH completion/failure comments, triggers
|
|
6
|
+
# the auto-loop (review-on-completion, fix-on-request-changes,
|
|
7
|
+
# re-review-on-fix-completion), and — #2536 — auto-heals any `running` board
|
|
8
|
+
# row whose recorded machine confirms is dead and aged well past its own
|
|
9
|
+
# needs-attention threshold (the same non-destructive recovery `coord
|
|
10
|
+
# diagnose --reset` performs by hand; see
|
|
11
|
+
# docs/AGENT_OPERATIONS.md → "Periodic coord notify" for the guardrails, and
|
|
12
|
+
# `pipeline.auto_heal_phantom_rows` in coordinator.yml to opt out). Install
|
|
13
|
+
# ONLY on the box that owns
|
|
8
14
|
# ~/.coord/coord.db (dellserver in production — the same host that runs
|
|
9
15
|
# coord-serve/coord-web) — it must NOT run on a thin-client machine, since
|
|
10
16
|
# `coord notify` there would just re-route itself back over HTTP to the
|