code-coordinator 0.5.219__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.219 → code_coordinator-0.5.220}/PKG-INFO +1 -1
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/code_coordinator.egg-info/PKG-INFO +1 -1
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/code_coordinator.egg-info/scm_version.json +2 -2
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/commands/lifecycle.py +18 -2
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/comments.py +59 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/config.py +27 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220/coord}/deploy/coord-notify.service +9 -3
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/diagnose.py +157 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/notify.py +136 -10
- {code_coordinator-0.5.219/coord → code_coordinator-0.5.220}/deploy/coord-notify.service +9 -3
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/docs/AGENT_OPERATIONS.md +22 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_auto_loop.py +41 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_comments.py +42 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_diagnose.py +137 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_drive.py +18 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_notify.py +95 -15
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_stalled_pipeline.py +1 -1
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_stuck.py +4 -4
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/.claude/commands/board.md +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/.claude/commands/complete-session.md +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/.claude/commands/coordinator.md +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/.githooks/_lib.sh +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/.githooks/post-checkout +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/.githooks/post-commit +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/.githooks/post-merge +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/.github/coord-ci-acceptance.yml +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/.github/workflows/auto-release.yml +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/.github/workflows/cargo-test.yml +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/.github/workflows/publish.yml +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/.github/workflows/release-tui.yml +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/.github/workflows/test.yml +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/.gitignore +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/CLAUDE.md +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/GOAL.md +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/LICENSE +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/MANIFEST.in +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/README.md +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/code_coordinator.egg-info/SOURCES.txt +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/code_coordinator.egg-info/dependency_links.txt +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/code_coordinator.egg-info/entry_points.txt +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/code_coordinator.egg-info/requires.txt +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/code_coordinator.egg-info/scm_file_list.json +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/code_coordinator.egg-info/top_level.txt +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/__init__.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/_board_mapping.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/acceptance.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/acceptance_drivers.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/agent.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/agent_app.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/agent_update.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/agents/opencode/.gitignore +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/agents/opencode/agents/work.md +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/agents/opencode/routing.jsonc +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/approved_work.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/audit.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/auto_loop.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/block_log.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/board_bool_guard.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/board_service.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/board_wire.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/brain.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/branch_model.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/bug_intake.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/cargo_cache.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/ci_fix.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/ci_github.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/ci_gitlab.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/ci_store.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/claim.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/cli.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/client.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/commands/__init__.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/commands/_common.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/commands/acceptance.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/commands/agent_ops.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/commands/audit.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/commands/chat.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/commands/dispatch.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/commands/dispatch_workers.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/commands/drive.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/commands/drive_queue.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/commands/gate_a.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/commands/gates.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/commands/issues.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/commands/merge.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/commands/milestone.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/commands/plan_followup.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/commands/plans.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/commands/portal.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/commands/release.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/commands/repo.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/commands/report.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/commands/review.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/commands/scorecard.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/commands/sessions.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/commands/setup.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/commands/status.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/commands/terminal.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/commands/test_gate.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/commands/tui.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/config_reload.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/confirm_test.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/conflict_fix.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/dao.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/dashboard/__init__.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/dashboard/fixture.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/dashboard/index.html +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/dashboard/server.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/dashboard/terminal.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/db.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/dead_end.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/deploy/README.md +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/deploy/coord-agent.service +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/deploy/coord-db-backup.service +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/deploy/coord-db-backup.sh +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/deploy/coord-db-backup.timer +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/deploy/coord-drive-queue.service +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/deploy/coord-drive-queue.timer +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/deploy/coord-notify.timer +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/deploy/coord-release-propagate.service +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/deploy/coord-release-propagate.timer +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/deploy/coord-release-window.service +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/deploy/coord-release-window.timer +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/deploy/coord-serve.service +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/deploy/coord-web-dist-build.service +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/deploy/coord-web-dist-build.timer +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/deploy/coord-web.service +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/deploy_manifest.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/deploy_units.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/deps.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/dispatch.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/dist_name.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/drive.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/drive_queue.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/drive_state.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/events.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/failure_class.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/filelock.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/fleet_config_health.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/forge_availability.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/freshness.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/gate_a.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/gate_b.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/gate_snapshot.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/gates.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/github_ops.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/goal.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/graph_health.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/health/__init__.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/health/aggregate.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/health/checks/__init__.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/health/checks/agent_install.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/health/checks/cargo_targets.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/health/checks/claude_binary.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/health/checks/coord_web_ci_pin.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/health/checks/deploy_lane_facts.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/health/checks/disk.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/health/checks/fleet_board.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/health/checks/fleet_deploy_lanes.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/health/checks/fleet_phantom.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/health/checks/fleet_unit_drift.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/health/checks/graph.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/health/checks/graphify_cli.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/health/checks/index_lock.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/health/checks/plan_usage.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/health/checks/repo_state.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/health/checks/spawned_coord.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/health/checks/timer_active.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/health/checks/toolchain.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/health/checks/unit_drift.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/health/checks/unit_enablement.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/health/checks/worktrees.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/health/cli.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/health/context.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/health/fleet_snapshot.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/health/models.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/health/pypi.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/health/registry.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/health/render.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/health/units.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/hooks.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/housekeeping.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/interactive.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/issue_store.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/liveness_auditor.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/machine_pause.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/merge_queue.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/milestone_chat.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/milestone_dispatch.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/milestone_gate.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/milestone_order.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/mock_author.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/models.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/network.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/new_issue_chat.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/notifier/__init__.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/notifier/baseline.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/notifier/cli.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/notifier/collect.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/notifier/digest.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/notifier/models.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/notifier/predicate.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/notifier/service.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/notifier/store.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/notifier/transport.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/openapi.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/overlap_fence.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/overlap_predict.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/parentage.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/parentage_github.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/pipeline.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/plan_parser.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/plans.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/platform_paths.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/portal_bridge.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/portal_store.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/portal_sync.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/pr_body_lint.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/prereqs.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/progress.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/providers/__init__.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/providers/base.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/providers/claude.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/providers/claude_pty.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/providers/opencode.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/queue_diagnose.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/reconcile.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/reconcile_tick.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/refine_chat.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/release_cordon.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/release_propagate.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/release_verify.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/release_window.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/repo_edit.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/repo_onboard.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/reports.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/revalidate.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/review.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/scorecard.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/self_health.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/serve_app.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/skills/coord-dispatch-verbs/SKILL.md +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/skills/drive-queue-preflight/SKILL.md +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/skills/fleet-restart-safety/SKILL.md +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/skills/merge-stuck-triage/SKILL.md +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/skills/pipeline-limbo-triage/SKILL.md +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/skills/portal-followup/SKILL.md +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/skills/review-verdict-recovery/SKILL.md +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/skills/tui-quadraui-workflow/SKILL.md +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/skills/update-issue/SKILL.md +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/smoke.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/spend_ceiling.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/split_work.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/stage_projection.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/state.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/test_author.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/test_chat.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/test_orchestrator.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/test_report.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/tui_release.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/usage.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/usage_limits.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/usage_rollup.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coord/worker_events.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/coordinator.example.yml +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/deploy/coord-agent.service +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/deploy/coord-db-backup.service +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/deploy/coord-db-backup.sh +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/deploy/coord-db-backup.timer +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/deploy/coord-drive-queue.service +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/deploy/coord-drive-queue.timer +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/deploy/coord-notify.timer +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/deploy/coord-release-propagate.service +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/deploy/coord-release-propagate.timer +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/deploy/coord-release-window.service +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/deploy/coord-release-window.timer +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/deploy/coord-serve.service +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/deploy/coord-web-dist-build.service +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/deploy/coord-web-dist-build.sh +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/deploy/coord-web-dist-build.timer +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/deploy/coord-web-rollback.sh +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/deploy/coord-web.service +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/deploy/node-shim.sh +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/docs/ADR_COORD_WEB_ACCEPTANCE_SUITE.md +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/docs/ADR_COORD_WEB_CI.md +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/docs/ADR_COORD_WEB_DIST.md +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/docs/ARCHITECTURE.md +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/docs/ARCH_SECURITY_GATES.md +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/docs/COCKPIT.md +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/docs/CONTROL_CENTER.md +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/docs/COST_DISCIPLINE.md +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/docs/CROSS_PLATFORM.md +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/docs/CUSTOMER_PORTAL.md +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/docs/DRIVE_QUEUE.md +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/docs/EPHEMERAL_WORKERS.md +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/docs/FORGE_MIGRATION.md +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/docs/GRAPHIFY_SETUP.md +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/docs/ISSUE_GUIDANCE.md +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/docs/MAC_MINI.md +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/docs/MERGE_AUTO_DRAIN_TRUST_BAR.md +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/docs/NOTIFIER.md +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/docs/OPENCODE_VERIFICATION.md +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/docs/OPERATING_GOTCHAS.md +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/docs/ORACLE_LOOP.md +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/docs/PHONE_WEBAPP.md +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/docs/PIPELINE_V2.md +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/docs/PLATFORM_EVOLUTION.md +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/docs/SECOND_BACKEND.md +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/docs/STORE_SERVICE.md +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/docs/TEST_FIRST_BUG_LANE.md +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/docs/WEB_CONTROL_CENTER.md +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/docs/WSL_WINDOWS_WORKER.md +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/docs/mocks/web/README.md +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/docs/mocks/web/_tokens.css +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/docs/mocks/web/issue-detail.html +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/docs/mocks/web/pipeline-narrow.html +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/docs/mocks/web/pipeline-wide.html +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/graphify-out/.gitignore +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/install-agent.sh +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/pyproject.toml +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/scripts/audit_review_verdict_overrides.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/scripts/azure-workers/bootstrap-shared.sh +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/scripts/azure-workers/build-worker-image.sh +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/scripts/azure-workers/coordinator-machine.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/scripts/azure-workers/epic-down.sh +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/scripts/azure-workers/epic-up.sh +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/scripts/azure-workers/preflight.sh +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/scripts/azure-workers/provision-worker.sh +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/scripts/azure-workers/scrub-and-generalize.sh +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/scripts/azure-workers/tailnet-acl.hujson +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/scripts/azure-workers/verify-github-token.sh +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/scripts/check_gh_argv_containment.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/scripts/codegen.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/scripts/coord-test-runner.sh +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/scripts/drive-batch.sh +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/scripts/gen_board_fixture.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/scripts/gen_mock_index.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/scripts/next_release_tag.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/scripts/run_tests_in_populated_home.sh +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/scripts/run_tests_without_gh.sh +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/scripts/smoke_437_interactive.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/scripts/verify_878_review_capture.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/scripts/verify_release_published.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/scripts/verify_release_wheel.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/setup.cfg +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/SMOKE_SET.md +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/__init__.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/acceptance/ms-33/audit_1039.rs +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/acceptance/ms-33/contract.md +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/acceptance/ms-33/manifest.yml +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/acceptance/ms-33/mocks/audit-panel-detail.screen +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/acceptance/ms-33/mocks/audit-panel-empty.screen +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/acceptance/ms-33/mocks/audit-panel-filters.screen +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/acceptance/ms-33/mocks/audit-panel-populated.screen +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/acceptance/ms-37/conftest.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/acceptance/ms-37/contract.md +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/acceptance/ms-37/manifest.yml +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/acceptance/ms-37/test_usage_cli_1115.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/acceptance/ms-37/test_usage_core_1118.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/acceptance/ms-38/contract.md +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/acceptance/ms-38/manifest.yml +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/acceptance/ms-38/mocks/plans-base.screen +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/acceptance/ms-38/mocks/plans-detail-pane.screen +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/acceptance/ms-38/mocks/plans-help-overlay.screen +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/acceptance/ms-38/mocks/plans-palette.screen +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/acceptance/ms-38/mocks/plans-rightclick-epic.screen +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/acceptance/ms-38/mocks/plans-rightclick-header.screen +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/acceptance/ms-38/mocks/plans-rightclick-stub.screen +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/acceptance/ms-38/plans_detail_1122.rs +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/acceptance/ms-38/plans_help_1124.rs +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/acceptance/ms-38/plans_rightclick_1123.rs +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/acceptance/ms-51/contract.md +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/acceptance/ms-51/home-active-extended.spec.ts +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/acceptance/ms-51/home-active.spec.ts +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/acceptance/ms-51/manifest.yml +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/acceptance/ms-51/mocks/home-active.html +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/acceptance/ms-51/tsconfig.json +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/acceptance/ms-65/board_split_2288.rs +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/acceptance/ms-65/board_tabs_2282.rs +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/acceptance/ms-65/board_tabs_close_2283.rs +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/acceptance/ms-65/contract.md +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/acceptance/ms-65/detail_substate_2285.rs +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/acceptance/ms-65/manifest.yml +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/acceptance/ms-65/mocks/board-baseline-no-tabs.screen +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/acceptance/ms-65/mocks/board-pinned-3-tabs.screen +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/acceptance/ms-65/mocks/board-preview-tab.screen +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/acceptance/ms-65/mocks/board-split-side-by-side.screen +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/acceptance/ms-65/mocks/board-tab-context-menu.screen +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/acceptance/ms-65/mocks/board-tabs-help-overlay.screen +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/acceptance/ms-65/mocks/board-tabs-overflow.screen +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/acceptance/ms-65/mocks/pipeline-tabs-independent.screen +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/acceptance/ms-65/pipeline_tabs_2284.rs +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/acceptance/ms-65/tabs_discoverability_2287.rs +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/acceptance/ms-65/tabs_persistence_2286.rs +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/acceptance/ms-67/approved_items_2532.rs +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/acceptance/ms-67/contract.md +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/acceptance/ms-67/manifest.yml +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/acceptance/ms-67/mocks/approved-items-chat-opened.screen +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/acceptance/ms-67/mocks/approved-items-context-menu.screen +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/acceptance/ms-67/mocks/approved-items-detail.screen +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/acceptance/ms-67/mocks/approved-items-empty.screen +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/acceptance/ms-67/mocks/approved-items-populated.screen +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/acceptance/ms-example/mocks/home-active.html +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/conftest.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/fixtures/board-pipeline-basic.json +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/fixtures/board-pipeline-terminal-gates.json +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/fixtures/opencode_run_failure_sample.jsonl +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/fixtures/opencode_run_length_sample.jsonl +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/fixtures/opencode_run_sample.jsonl +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/fixtures/playwright/all_pass.json +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/fixtures/playwright/global_setup_crash.json +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/fixtures/playwright/mixed_fail.json +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/fixtures/playwright/retry_then_pass.json +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/fixtures/playwright/retry_then_pass.junit.xml +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/fixtures/playwright/skip.json +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/fixtures/playwright/truncated.json +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/fixtures/test_report/cargo_compile_error.txt +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/fixtures/test_report/cargo_multi_target_failures.txt +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/fixtures/test_report/cargo_no_parseable_failures.txt +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/fixtures/test_report/pytest_collection_error.txt +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/fixtures/test_report/pytest_error_string_in_body.txt +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/fixtures/test_report/pytest_internal_error.txt +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/fixtures/test_report/pytest_mixed_failures.txt +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/fixtures/test_report/pytest_no_parseable_failures.txt +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_acceptance.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_acceptance_drivers.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_agent.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_agent_api_error.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_agent_app.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_agent_branch_base.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_agent_branch_capture.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_agent_config_free_1712.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_agent_deploy_units_endpoint.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_agent_dirty_worktree.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_agent_drive_queue_reconcile_2373.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_agent_graph_self_heal.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_agent_health_h3.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_agent_idle_restart.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_agent_push_failure.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_agent_reap.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_agent_repos_and_pull.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_agent_restart_services_endpoint.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_agent_skills_self_heal.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_agent_startup_diagnostics.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_agent_update.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_agent_update_bluegreen.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_agent_usage_limit.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_agent_zero_commit.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_ambient_home_isolation.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_approve_reject_plan.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_approve_usage_gate.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_approved_work_2532.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_assignment_already_recorded_daemon.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_audit_log.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_audit_outcome.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_audit_query.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_auto_release_publish_2035.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_base_checkout_restore.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_block_log.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_board_cap_762.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_board_fixture.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_board_read_path.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_board_service.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_board_state.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_board_wire.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_brain.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_branch_model.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_bug_intake.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_build_worker_image_env_update.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_cargo_cache.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_check_gh_argv_containment.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_ci_acceptance_gate_1950.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_ci_fix.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_ci_gitlab.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_ci_parity_2091.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_ci_store.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_claim.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_cli_acceptance.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_cli_assign.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_cli_assign_interactive_oracle_gate.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_cli_assign_interactive_remote.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_cli_assign_provider.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_cli_assign_repo_drift_2219.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_cli_audit.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_cli_chat_continue.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_cli_decide.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_cli_diagnose_config_provenance.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_cli_diagnose_forge_availability.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_cli_diagnose_graph.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_cli_diagnose_self.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_cli_doctor.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_cli_doctor_config_free_1801.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_cli_doctor_config_mismatch_1712.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_cli_drive.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_cli_drive_queue.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_cli_escalate.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_cli_fix_headless_review.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_cli_gate_a.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_cli_install_drift.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_cli_install_skills.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_cli_issue_create_label.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_cli_issue_reopen.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_cli_merge.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_cli_milestone_assign.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_cli_milestone_capture.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_cli_milestone_chat_add_child.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_cli_milestone_dispatch.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_cli_milestone_gate_b.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_cli_milestone_gate_c.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_cli_milestone_order.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_cli_milestone_remove_and_issue_close.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_cli_milestone_ship.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_cli_network.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_cli_new_issue_chat.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_cli_plans.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_cli_portal.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_cli_pull_artifact.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_cli_queue.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_cli_reattach_sessions.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_cli_refine_board.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_cli_release_preflight.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_cli_release_propagate.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_cli_release_window.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_cli_repo_2220.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_cli_scorecard.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_cli_set_review_findings.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_cli_status_advisory_terminal.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_cli_status_merge_queue.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_cli_status_provider.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_cli_status_review_finalizing.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_cli_status_test_failed_tag.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_cli_status_usage_limit.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_cli_sync_comments_873.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_cli_test_plan.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_cli_track.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_cli_tui_update.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_cli_wait.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_client_base_install.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_completion_summary.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_config.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_config_acceptance.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_config_audit.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_config_pricing.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_config_snapshot_noncanonical_2208.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_config_usage_gate.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_confirm_test.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_conflict_fix.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_conflict_fix_semantic.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_coord_test.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_coord_test_runner_baseline.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_coord_test_runner_populated_home.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_coord_test_runner_routing.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_coord_test_runner_toolchain.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_coord_web_sse_restart_live.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_coordinator_machine.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_cross_platform_imports.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_dashboard.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_dashboard_fixture.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_dashboard_terminal.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_dashboard_terminal_live.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_db.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_dead_end.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_deploy_coord_db_backup.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_deploy_coord_web_dist.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_deploy_coord_web_rollback.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_deploy_drive_queue_unit.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_deploy_manifest.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_deploy_units_lane.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_deploy_web_unit.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_deps.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_dispatch.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_dispatch_target_validation.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_dist_name.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_done_housekeeping.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_drive_queue.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_drive_state.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_drive_tmux.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_epic_up_capability_detection.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_epic_up_down_symlinked_config_1887.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_epic_up_image_provenance.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_errors.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_events.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_failure_class.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_filelock.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_finalize_interactive_exit_test_verdict.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_fix_of_force_override.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_fleet_config_health.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_fleet_health_probes.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_fleet_health_snapshot.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_forge_availability.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_freshness.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_gate_a.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_gate_b.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_gate_snapshot_staleness.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_gates.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_gather_fleet_tmux_sessions.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_gen_mock_index.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_generated_types_fixture.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_github_ops.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_goal.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_graph_health.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_graph_selfheal_absent_2237.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_handoff.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_health_checks.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_health_cli.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_health_cli_graph.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_health_config.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_health_context.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_health_coord_web_ci_pin.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_health_deploy_lane_facts.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_health_incident_regression.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_health_pypi.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_health_registry.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_health_timer_active.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_health_toolchain.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_health_unit_drift.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_health_unit_enablement.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_hooks.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_human_attended_437.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_init.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_integration.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_interactive_briefing_echo.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_interactive_prefill_state.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_interactive_session_relaunch.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_interactive_test_verdict_backstop.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_interactive_token_attribution.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_interactive_worktree.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_issue_store_seam.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_liveness_auditor.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_liveness_notify.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_machine_pause.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_merge_queue.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_merge_verify.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_milestone_chat.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_milestone_dispatch.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_milestone_gate.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_milestone_order.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_milestone_seam.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_mock_author.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_model_tiering.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_models.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_models_config_labels.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_needs_attention.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_network.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_new_issue_chat.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_next_release_tag.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_node_shim.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_notifier_baseline.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_notifier_cli.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_notifier_collect.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_notifier_config.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_notifier_drive_seam.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_notifier_isolation.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_notifier_predicate.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_notifier_quiet_hours.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_notifier_service.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_notify_drain.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_openapi.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_operational_defaults.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_overlap_fence.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_overlap_predict.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_packaged_deploy_units.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_parentage.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_paste_landed.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_pipeline.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_plan_followup_approve_plan_command.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_plan_followup_pr_command.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_plan_followup_review_command.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_plan_only.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_plan_parser.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_platform_paths.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_portal_bridge.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_portal_config.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_portal_store.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_portal_sync.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_pr_body_lint.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_prereqs.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_production_db_guard.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_progress.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_provider_seam.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_providers.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_providers_config_labels.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_providers_pty.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_quiet_hours.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_quiet_hours_store_2146.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_reap_merged_sessions.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_reap_stale_interactive_tick.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_reconcile.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_reconcile_branch.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_reconcile_completions.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_reconcile_merges.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_reconcile_no_agent_record.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_reconcile_tick.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_reconcile_usage_limit_done.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_refine_chat.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_release_cordon_2101.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_release_cordon_daemon_leads_2176.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_release_cordon_deadlock_2240.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_release_cordon_stuck_2490.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_release_propagate.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_release_unified_1242.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_release_verify.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_release_window.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_remote_auto_prune.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_remote_interactive_reaper.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_repo_edit_2220.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_repo_graph_fleet_2237.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_repo_onboard_2220.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_report_result_push.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_reports.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_retry.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_retry_advisory_1606.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_retry_type_1636.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_revalidate.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_review.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_review_end_review_without_verdict.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_review_parse_failure_diagnostic.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_review_reaffirm.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_review_state.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_review_verdict_backstop.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_review_verdict_override_audit.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_review_verdict_relay.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_review_zero_commits.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_scoped_review_wiring.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_scorecard.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_self_health.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_serve.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_serve_app_board_trim.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_session.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_slice_issue_attribution.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_smoke.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_smoke_live_checkout_restore.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_smoke_workflow.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_spend_ceiling.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_spend_ceiling_coordinator.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_split.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_split_work.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_stage_projection.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_state.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_state_review_findings_daemon.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_status_fleet_footer.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_stop_1567.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_terminal_command.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_test_author.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_test_chat.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_test_orchestrator.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_test_report.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_test_verdict_parsing.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_test_verdict_transcript_floor.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_thin_client_board_audit.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_thin_client_config_load_1080.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_thin_client_daemon_routing_906.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_tmux_host.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_tmux_session.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_transcript_floor.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_usage.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_usage_limits.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_usage_rollup.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_venv_live_install_2121.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_version_single_source.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_watch.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_windows_job_is_a_real_gate_2000.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_worker_events.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_worker_image_pin_sync.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_worker_safety.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_worker_test_scoping.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_worktree.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tests/test_worktree_rmtree_chokepoint.py +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tui/Cargo.lock +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tui/Cargo.toml +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tui/cargo-config-local-quadraui.toml.example +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tui/src/app/approved.rs +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tui/src/app/audit.rs +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tui/src/app/chat.rs +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tui/src/app/data.rs +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tui/src/app/dialogs.rs +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tui/src/app/doc_tabs.rs +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tui/src/app/drive.rs +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tui/src/app/drive_queue.rs +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tui/src/app/escalation.rs +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tui/src/app/events.rs +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tui/src/app/fixtures.rs +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tui/src/app/fleet_health.rs +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tui/src/app/fleet_sessions.rs +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tui/src/app/fleet_terminals.rs +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tui/src/app/format.rs +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tui/src/app/milestone_dag.rs +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tui/src/app/mod.rs +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tui/src/app/msv.rs +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tui/src/app/pipeline.rs +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tui/src/app/plans.rs +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tui/src/app/render.rs +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tui/src/app/reports.rs +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tui/src/app/sessions.rs +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tui/src/app/settings_ui.rs +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tui/src/app/sidebar.rs +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tui/src/app/terminal.rs +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tui/src/app/tests.rs +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tui/src/app/types.rs +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tui/src/app/workspace.rs +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tui/src/bin/gtk.rs +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tui/src/commands.rs +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tui/src/lib.rs +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tui/src/main.rs +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tui/src/settings.rs +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tui/tests/acceptance.rs +0 -0
- {code_coordinator-0.5.219 → code_coordinator-0.5.220}/tui/tests/cli.rs +0 -0
- {code_coordinator-0.5.219 → 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:
|
|
@@ -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
|
|
@@ -827,6 +827,28 @@ auto-loop dispatch path. Low risk today (flat headless-only dispatch has no
|
|
|
827
827
|
than blocking this timer — flag it if it ever bites (a fix worker firing while
|
|
828
828
|
someone is mid-`--fix-of` on the same issue).
|
|
829
829
|
|
|
830
|
+
**Phantom-row self-heal rides the same timer (#2536).** Every `coord notify`
|
|
831
|
+
pass this timer fires also sweeps the board for a `status='running'` row
|
|
832
|
+
whose recorded machine's own `/status` shows nothing active for it — a
|
|
833
|
+
session that finished or died without the board ever finding out. Left
|
|
834
|
+
alone, that phantom row sits forever (nothing else notices) and — per
|
|
835
|
+
`coord/drive_queue.py`'s own capacity comment — holds its repo's *entire*
|
|
836
|
+
drive-queue concurrency slot, blocking every other queued issue in that
|
|
837
|
+
repo. The sweep only ever acts on a **confirmed**-dead session (never an
|
|
838
|
+
"unknown" read — an unresolvable machine, an unreachable agent, a probe
|
|
839
|
+
error all count as "leave it alone", same as "live"), and only once the row
|
|
840
|
+
is aged well past its own `needs_attention` wall-clock threshold plus a
|
|
841
|
+
buffer, so it can never race a session that's merely idle between turns.
|
|
842
|
+
When both hold, it runs the exact same non-destructive recovery a human
|
|
843
|
+
would via `coord diagnose <repo> <issue> --reset` — branch and commits are
|
|
844
|
+
always preserved, the stage becomes re-dispatchable — and posts a GitHub
|
|
845
|
+
comment recording that it happened (`coord.diagnose.sweep_dead_running_rows`,
|
|
846
|
+
`coord.notify._sweep_phantom_rows`). Governed by
|
|
847
|
+
`pipeline.auto_heal_phantom_rows` in `coordinator.yml` (**default `true`**,
|
|
848
|
+
unlike most other auto-dispatch flags in this file — see
|
|
849
|
+
`PipelineConfig`'s docstring in `coord/config.py` for why); set it `false`
|
|
850
|
+
to go back to requiring a human to run `--reset` by hand.
|
|
851
|
+
|
|
830
852
|
## Periodic `coord drive-queue tick` (`coord-drive-queue` timer, #1756)
|
|
831
853
|
|
|
832
854
|
Same shape as the `coord-notify` timer above — a `Type=oneshot` unit fired on
|
|
@@ -1272,6 +1272,47 @@ class TestPipelineConfigParsing:
|
|
|
1272
1272
|
):
|
|
1273
1273
|
load(p)
|
|
1274
1274
|
|
|
1275
|
+
def test_auto_heal_phantom_rows_defaults_to_true(self, tmp_path) -> None:
|
|
1276
|
+
"""#2536: unlike auto_dispatch_stalled, the phantom-row self-heal
|
|
1277
|
+
sweep ships lit — every action it takes is gated behind a
|
|
1278
|
+
confirmed-dead liveness read plus an aged-out wall-clock buffer, and
|
|
1279
|
+
it never dispatches work or touches a branch."""
|
|
1280
|
+
from coord.config import load
|
|
1281
|
+
|
|
1282
|
+
p = tmp_path / "coordinator.yml"
|
|
1283
|
+
p.write_text(
|
|
1284
|
+
"repos:\n - name: api\n github: acme/api\n"
|
|
1285
|
+
"machines:\n - name: laptop\n host: laptop.tail\n repos: [api]\n"
|
|
1286
|
+
)
|
|
1287
|
+
cfg = load(p)
|
|
1288
|
+
assert cfg.pipeline.auto_heal_phantom_rows is True
|
|
1289
|
+
|
|
1290
|
+
def test_can_disable_auto_heal_phantom_rows(self, tmp_path) -> None:
|
|
1291
|
+
from coord.config import load
|
|
1292
|
+
|
|
1293
|
+
p = tmp_path / "coordinator.yml"
|
|
1294
|
+
p.write_text(
|
|
1295
|
+
"repos:\n - name: api\n github: acme/api\n"
|
|
1296
|
+
"machines:\n - name: laptop\n host: laptop.tail\n repos: [api]\n"
|
|
1297
|
+
"pipeline:\n auto_heal_phantom_rows: false\n"
|
|
1298
|
+
)
|
|
1299
|
+
cfg = load(p)
|
|
1300
|
+
assert cfg.pipeline.auto_heal_phantom_rows is False
|
|
1301
|
+
|
|
1302
|
+
def test_invalid_auto_heal_phantom_rows_raises(self, tmp_path) -> None:
|
|
1303
|
+
from coord.config import ConfigError, load
|
|
1304
|
+
|
|
1305
|
+
p = tmp_path / "coordinator.yml"
|
|
1306
|
+
p.write_text(
|
|
1307
|
+
"repos:\n - name: api\n github: acme/api\n"
|
|
1308
|
+
"machines:\n - name: laptop\n host: laptop.tail\n repos: [api]\n"
|
|
1309
|
+
"pipeline:\n auto_heal_phantom_rows: maybe\n"
|
|
1310
|
+
)
|
|
1311
|
+
with pytest.raises(
|
|
1312
|
+
ConfigError, match="pipeline.auto_heal_phantom_rows must be a boolean"
|
|
1313
|
+
):
|
|
1314
|
+
load(p)
|
|
1315
|
+
|
|
1275
1316
|
|
|
1276
1317
|
# ── Unit tests: Assignment.review_iteration persistence ─────────────────────
|
|
1277
1318
|
|