code-coordinator 0.5.195__tar.gz → 0.5.196__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.195 → code_coordinator-0.5.196}/.github/workflows/test.yml +33 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/PKG-INFO +1 -1
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/code_coordinator.egg-info/PKG-INFO +1 -1
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/code_coordinator.egg-info/SOURCES.txt +2 -1
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/code_coordinator.egg-info/scm_file_list.json +2 -1
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/code_coordinator.egg-info/scm_version.json +2 -2
- code_coordinator-0.5.196/scripts/check_gh_argv_containment.py +176 -0
- code_coordinator-0.5.196/tests/test_check_gh_argv_containment.py +156 -0
- code_coordinator-0.5.195/tests/test_no_direct_gh_calls.py +0 -112
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/.claude/commands/board.md +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/.claude/commands/complete-session.md +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/.claude/commands/coordinator.md +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/.githooks/_lib.sh +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/.githooks/post-checkout +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/.githooks/post-commit +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/.githooks/post-merge +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/.github/coord-ci-acceptance.yml +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/.github/workflows/auto-release.yml +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/.github/workflows/cargo-test.yml +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/.github/workflows/publish.yml +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/.github/workflows/release-tui.yml +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/.gitignore +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/CLAUDE.md +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/GOAL.md +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/LICENSE +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/MANIFEST.in +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/README.md +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/code_coordinator.egg-info/dependency_links.txt +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/code_coordinator.egg-info/entry_points.txt +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/code_coordinator.egg-info/requires.txt +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/code_coordinator.egg-info/top_level.txt +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/__init__.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/_board_mapping.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/acceptance.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/acceptance_drivers.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/agent.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/agent_app.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/agent_update.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/agents/opencode/.gitignore +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/agents/opencode/agents/work.md +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/agents/opencode/routing.jsonc +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/audit.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/auto_loop.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/block_log.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/board_bool_guard.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/board_service.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/board_wire.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/brain.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/branch_model.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/bug_intake.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/cargo_cache.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/ci_github.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/ci_store.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/claim.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/cli.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/client.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/commands/__init__.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/commands/_common.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/commands/acceptance.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/commands/agent_ops.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/commands/audit.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/commands/chat.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/commands/dispatch.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/commands/dispatch_workers.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/commands/drive.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/commands/drive_queue.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/commands/gate_a.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/commands/gates.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/commands/issues.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/commands/lifecycle.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/commands/merge.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/commands/milestone.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/commands/plan_followup.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/commands/plans.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/commands/portal.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/commands/release.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/commands/repo.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/commands/report.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/commands/review.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/commands/scorecard.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/commands/sessions.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/commands/setup.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/commands/status.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/commands/terminal.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/commands/test_gate.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/commands/tui.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/comments.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/config.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/config_reload.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/confirm_test.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/conflict_fix.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/dao.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/dashboard/__init__.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/dashboard/fixture.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/dashboard/index.html +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/dashboard/server.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/dashboard/terminal.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/db.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/dead_end.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/deploy/README.md +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/deploy/coord-agent.service +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/deploy/coord-db-backup.service +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/deploy/coord-db-backup.sh +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/deploy/coord-db-backup.timer +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/deploy/coord-drive-queue.service +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/deploy/coord-drive-queue.timer +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/deploy/coord-notify.service +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/deploy/coord-notify.timer +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/deploy/coord-release-propagate.service +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/deploy/coord-release-propagate.timer +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/deploy/coord-release-window.service +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/deploy/coord-release-window.timer +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/deploy/coord-serve.service +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/deploy/coord-web-dist-build.service +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/deploy/coord-web-dist-build.timer +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/deploy/coord-web.service +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/deploy_manifest.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/deploy_units.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/deps.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/diagnose.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/dispatch.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/dist_name.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/drive.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/drive_queue.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/drive_state.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/events.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/failure_class.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/filelock.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/fleet_config_health.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/forge_availability.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/freshness.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/gate_a.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/gate_b.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/gate_snapshot.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/gates.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/github_ops.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/goal.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/graph_health.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/health/__init__.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/health/aggregate.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/health/checks/__init__.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/health/checks/agent_install.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/health/checks/cargo_targets.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/health/checks/claude_binary.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/health/checks/coord_web_ci_pin.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/health/checks/deploy_lane_facts.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/health/checks/disk.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/health/checks/fleet_board.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/health/checks/fleet_deploy_lanes.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/health/checks/fleet_phantom.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/health/checks/fleet_unit_drift.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/health/checks/graph.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/health/checks/graphify_cli.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/health/checks/index_lock.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/health/checks/plan_usage.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/health/checks/repo_state.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/health/checks/spawned_coord.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/health/checks/timer_active.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/health/checks/toolchain.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/health/checks/unit_drift.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/health/checks/unit_enablement.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/health/checks/worktrees.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/health/cli.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/health/context.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/health/fleet_snapshot.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/health/models.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/health/pypi.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/health/registry.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/health/render.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/health/units.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/hooks.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/housekeeping.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/interactive.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/issue_store.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/liveness_auditor.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/machine_pause.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/merge_queue.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/milestone_chat.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/milestone_dispatch.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/milestone_gate.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/milestone_order.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/mock_author.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/models.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/network.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/new_issue_chat.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/notifier/__init__.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/notifier/baseline.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/notifier/cli.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/notifier/collect.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/notifier/digest.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/notifier/models.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/notifier/predicate.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/notifier/service.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/notifier/store.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/notifier/transport.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/notify.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/openapi.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/overlap_fence.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/overlap_predict.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/parentage.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/parentage_github.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/pipeline.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/plan_parser.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/plans.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/platform_paths.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/portal_bridge.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/portal_store.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/portal_sync.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/pr_body_lint.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/prereqs.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/progress.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/providers/__init__.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/providers/base.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/providers/claude.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/providers/claude_pty.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/providers/opencode.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/queue_diagnose.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/reconcile.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/reconcile_tick.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/refine_chat.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/release_cordon.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/release_propagate.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/release_verify.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/release_window.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/repo_edit.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/repo_onboard.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/reports.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/revalidate.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/review.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/scorecard.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/self_health.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/serve_app.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/skills/coord-dispatch-verbs/SKILL.md +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/skills/drive-queue-preflight/SKILL.md +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/skills/fleet-restart-safety/SKILL.md +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/skills/merge-stuck-triage/SKILL.md +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/skills/pipeline-limbo-triage/SKILL.md +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/skills/portal-followup/SKILL.md +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/skills/review-verdict-recovery/SKILL.md +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/skills/tui-quadraui-workflow/SKILL.md +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/skills/update-issue/SKILL.md +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/smoke.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/spend_ceiling.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/split_work.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/stage_projection.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/state.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/test_author.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/test_chat.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/test_orchestrator.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/test_report.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/tui_release.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/usage.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/usage_limits.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/usage_rollup.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coord/worker_events.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/coordinator.example.yml +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/deploy/coord-agent.service +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/deploy/coord-db-backup.service +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/deploy/coord-db-backup.sh +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/deploy/coord-db-backup.timer +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/deploy/coord-drive-queue.service +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/deploy/coord-drive-queue.timer +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/deploy/coord-notify.service +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/deploy/coord-notify.timer +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/deploy/coord-release-propagate.service +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/deploy/coord-release-propagate.timer +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/deploy/coord-release-window.service +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/deploy/coord-release-window.timer +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/deploy/coord-serve.service +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/deploy/coord-web-dist-build.service +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/deploy/coord-web-dist-build.sh +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/deploy/coord-web-dist-build.timer +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/deploy/coord-web-rollback.sh +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/deploy/coord-web.service +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/deploy/node-shim.sh +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/docs/ADR_COORD_WEB_ACCEPTANCE_SUITE.md +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/docs/ADR_COORD_WEB_CI.md +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/docs/ADR_COORD_WEB_DIST.md +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/docs/AGENT_OPERATIONS.md +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/docs/ARCHITECTURE.md +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/docs/ARCH_SECURITY_GATES.md +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/docs/COCKPIT.md +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/docs/CONTROL_CENTER.md +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/docs/COST_DISCIPLINE.md +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/docs/CROSS_PLATFORM.md +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/docs/CUSTOMER_PORTAL.md +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/docs/DRIVE_QUEUE.md +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/docs/EPHEMERAL_WORKERS.md +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/docs/FORGE_MIGRATION.md +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/docs/GRAPHIFY_SETUP.md +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/docs/ISSUE_GUIDANCE.md +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/docs/MAC_MINI.md +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/docs/MERGE_AUTO_DRAIN_TRUST_BAR.md +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/docs/NOTIFIER.md +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/docs/OPENCODE_VERIFICATION.md +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/docs/OPERATING_GOTCHAS.md +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/docs/ORACLE_LOOP.md +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/docs/PHONE_WEBAPP.md +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/docs/PIPELINE_V2.md +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/docs/PLATFORM_EVOLUTION.md +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/docs/SECOND_BACKEND.md +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/docs/STORE_SERVICE.md +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/docs/TEST_FIRST_BUG_LANE.md +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/docs/WEB_CONTROL_CENTER.md +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/docs/WSL_WINDOWS_WORKER.md +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/docs/mocks/web/README.md +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/docs/mocks/web/_tokens.css +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/docs/mocks/web/issue-detail.html +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/docs/mocks/web/pipeline-narrow.html +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/docs/mocks/web/pipeline-wide.html +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/graphify-out/.gitignore +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/install-agent.sh +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/pyproject.toml +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/scripts/audit_review_verdict_overrides.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/scripts/azure-workers/bootstrap-shared.sh +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/scripts/azure-workers/build-worker-image.sh +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/scripts/azure-workers/coordinator-machine.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/scripts/azure-workers/epic-down.sh +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/scripts/azure-workers/epic-up.sh +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/scripts/azure-workers/preflight.sh +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/scripts/azure-workers/provision-worker.sh +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/scripts/azure-workers/scrub-and-generalize.sh +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/scripts/azure-workers/tailnet-acl.hujson +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/scripts/azure-workers/verify-github-token.sh +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/scripts/codegen.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/scripts/coord-test-runner.sh +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/scripts/drive-batch.sh +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/scripts/gen_board_fixture.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/scripts/next_release_tag.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/scripts/run_tests_in_populated_home.sh +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/scripts/run_tests_without_gh.sh +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/scripts/smoke_437_interactive.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/scripts/verify_878_review_capture.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/scripts/verify_release_published.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/scripts/verify_release_wheel.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/setup.cfg +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/SMOKE_SET.md +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/__init__.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/acceptance/ms-33/audit_1039.rs +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/acceptance/ms-33/contract.md +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/acceptance/ms-33/manifest.yml +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/acceptance/ms-33/mocks/audit-panel-detail.screen +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/acceptance/ms-33/mocks/audit-panel-empty.screen +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/acceptance/ms-33/mocks/audit-panel-filters.screen +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/acceptance/ms-33/mocks/audit-panel-populated.screen +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/acceptance/ms-37/conftest.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/acceptance/ms-37/contract.md +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/acceptance/ms-37/manifest.yml +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/acceptance/ms-37/test_usage_cli_1115.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/acceptance/ms-37/test_usage_core_1118.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/acceptance/ms-38/contract.md +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/acceptance/ms-38/manifest.yml +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/acceptance/ms-38/mocks/plans-base.screen +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/acceptance/ms-38/mocks/plans-detail-pane.screen +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/acceptance/ms-38/mocks/plans-help-overlay.screen +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/acceptance/ms-38/mocks/plans-palette.screen +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/acceptance/ms-38/mocks/plans-rightclick-epic.screen +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/acceptance/ms-38/mocks/plans-rightclick-header.screen +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/acceptance/ms-38/mocks/plans-rightclick-stub.screen +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/acceptance/ms-38/plans_detail_1122.rs +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/acceptance/ms-38/plans_help_1124.rs +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/acceptance/ms-38/plans_rightclick_1123.rs +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/acceptance/ms-51/contract.md +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/acceptance/ms-51/home-active-extended.spec.ts +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/acceptance/ms-51/home-active.spec.ts +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/acceptance/ms-51/manifest.yml +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/acceptance/ms-51/mocks/home-active.html +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/acceptance/ms-51/tsconfig.json +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/acceptance/ms-65/board_split_2288.rs +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/acceptance/ms-65/board_tabs_2282.rs +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/acceptance/ms-65/board_tabs_close_2283.rs +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/acceptance/ms-65/contract.md +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/acceptance/ms-65/detail_substate_2285.rs +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/acceptance/ms-65/manifest.yml +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/acceptance/ms-65/mocks/board-baseline-no-tabs.screen +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/acceptance/ms-65/mocks/board-pinned-3-tabs.screen +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/acceptance/ms-65/mocks/board-preview-tab.screen +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/acceptance/ms-65/mocks/board-split-side-by-side.screen +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/acceptance/ms-65/mocks/board-tab-context-menu.screen +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/acceptance/ms-65/mocks/board-tabs-help-overlay.screen +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/acceptance/ms-65/mocks/board-tabs-overflow.screen +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/acceptance/ms-65/mocks/pipeline-tabs-independent.screen +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/acceptance/ms-65/pipeline_tabs_2284.rs +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/acceptance/ms-65/tabs_discoverability_2287.rs +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/acceptance/ms-65/tabs_persistence_2286.rs +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/acceptance/ms-example/mocks/home-active.html +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/conftest.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/fixtures/board-pipeline-basic.json +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/fixtures/board-pipeline-terminal-gates.json +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/fixtures/opencode_run_failure_sample.jsonl +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/fixtures/opencode_run_length_sample.jsonl +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/fixtures/opencode_run_sample.jsonl +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/fixtures/playwright/all_pass.json +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/fixtures/playwright/global_setup_crash.json +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/fixtures/playwright/mixed_fail.json +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/fixtures/playwright/retry_then_pass.json +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/fixtures/playwright/retry_then_pass.junit.xml +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/fixtures/playwright/skip.json +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/fixtures/playwright/truncated.json +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/fixtures/test_report/cargo_compile_error.txt +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/fixtures/test_report/cargo_multi_target_failures.txt +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/fixtures/test_report/cargo_no_parseable_failures.txt +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/fixtures/test_report/pytest_collection_error.txt +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/fixtures/test_report/pytest_error_string_in_body.txt +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/fixtures/test_report/pytest_internal_error.txt +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/fixtures/test_report/pytest_mixed_failures.txt +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/fixtures/test_report/pytest_no_parseable_failures.txt +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_acceptance.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_acceptance_drivers.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_agent.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_agent_api_error.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_agent_app.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_agent_branch_base.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_agent_branch_capture.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_agent_config_free_1712.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_agent_deploy_units_endpoint.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_agent_dirty_worktree.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_agent_drive_queue_reconcile_2373.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_agent_graph_self_heal.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_agent_health_h3.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_agent_idle_restart.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_agent_push_failure.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_agent_reap.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_agent_repos_and_pull.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_agent_restart_services_endpoint.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_agent_skills_self_heal.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_agent_startup_diagnostics.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_agent_update.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_agent_update_bluegreen.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_agent_usage_limit.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_agent_zero_commit.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_ambient_home_isolation.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_approve_reject_plan.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_approve_usage_gate.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_assignment_already_recorded_daemon.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_audit_log.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_audit_outcome.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_audit_query.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_auto_loop.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_auto_release_publish_2035.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_base_checkout_restore.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_block_log.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_board_cap_762.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_board_fixture.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_board_read_path.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_board_service.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_board_state.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_board_wire.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_brain.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_branch_model.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_bug_intake.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_build_worker_image_env_update.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_cargo_cache.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_ci_acceptance_gate_1950.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_ci_parity_2091.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_ci_store.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_claim.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_cli_acceptance.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_cli_assign.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_cli_assign_interactive_oracle_gate.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_cli_assign_interactive_remote.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_cli_assign_provider.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_cli_assign_repo_drift_2219.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_cli_audit.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_cli_chat_continue.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_cli_decide.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_cli_diagnose_config_provenance.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_cli_diagnose_forge_availability.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_cli_diagnose_graph.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_cli_diagnose_self.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_cli_doctor.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_cli_doctor_config_free_1801.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_cli_doctor_config_mismatch_1712.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_cli_drive.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_cli_drive_queue.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_cli_escalate.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_cli_fix_headless_review.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_cli_gate_a.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_cli_install_drift.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_cli_install_skills.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_cli_issue_create_label.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_cli_issue_reopen.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_cli_merge.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_cli_milestone_assign.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_cli_milestone_capture.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_cli_milestone_chat_add_child.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_cli_milestone_dispatch.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_cli_milestone_gate_b.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_cli_milestone_gate_c.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_cli_milestone_order.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_cli_milestone_remove_and_issue_close.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_cli_milestone_ship.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_cli_network.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_cli_new_issue_chat.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_cli_plans.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_cli_portal.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_cli_pull_artifact.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_cli_queue.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_cli_reattach_sessions.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_cli_refine_board.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_cli_release_preflight.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_cli_release_propagate.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_cli_release_window.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_cli_repo_2220.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_cli_scorecard.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_cli_set_review_findings.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_cli_status_advisory_terminal.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_cli_status_merge_queue.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_cli_status_provider.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_cli_status_review_finalizing.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_cli_status_test_failed_tag.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_cli_status_usage_limit.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_cli_sync_comments_873.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_cli_test_plan.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_cli_track.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_cli_tui_update.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_cli_wait.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_client_base_install.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_comments.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_completion_summary.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_config.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_config_acceptance.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_config_audit.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_config_pricing.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_config_snapshot_noncanonical_2208.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_config_usage_gate.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_confirm_test.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_conflict_fix.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_conflict_fix_semantic.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_coord_test.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_coord_test_runner_baseline.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_coord_test_runner_populated_home.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_coord_test_runner_routing.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_coord_test_runner_toolchain.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_coord_web_sse_restart_live.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_coordinator_machine.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_cross_platform_imports.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_dashboard.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_dashboard_fixture.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_dashboard_terminal.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_dashboard_terminal_live.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_db.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_dead_end.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_deploy_coord_db_backup.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_deploy_coord_web_dist.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_deploy_coord_web_rollback.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_deploy_drive_queue_unit.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_deploy_manifest.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_deploy_units_lane.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_deploy_web_unit.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_deps.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_diagnose.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_dispatch.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_dispatch_target_validation.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_dist_name.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_done_housekeeping.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_drive.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_drive_queue.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_drive_state.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_drive_tmux.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_epic_up_capability_detection.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_epic_up_down_symlinked_config_1887.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_epic_up_image_provenance.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_errors.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_events.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_failure_class.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_filelock.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_finalize_interactive_exit_test_verdict.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_fix_of_force_override.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_fleet_config_health.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_fleet_health_probes.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_fleet_health_snapshot.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_forge_availability.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_freshness.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_gate_a.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_gate_b.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_gate_snapshot_staleness.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_gates.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_gather_fleet_tmux_sessions.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_generated_types_fixture.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_github_ops.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_goal.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_graph_health.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_graph_selfheal_absent_2237.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_handoff.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_health_checks.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_health_cli.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_health_cli_graph.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_health_config.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_health_context.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_health_coord_web_ci_pin.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_health_deploy_lane_facts.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_health_incident_regression.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_health_pypi.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_health_registry.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_health_timer_active.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_health_toolchain.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_health_unit_drift.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_health_unit_enablement.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_hooks.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_human_attended_437.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_init.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_integration.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_interactive_briefing_echo.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_interactive_prefill_state.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_interactive_session_relaunch.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_interactive_test_verdict_backstop.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_interactive_token_attribution.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_interactive_worktree.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_issue_store_seam.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_liveness_auditor.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_liveness_notify.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_machine_pause.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_merge_queue.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_merge_verify.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_milestone_chat.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_milestone_dispatch.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_milestone_gate.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_milestone_order.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_milestone_seam.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_mock_author.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_model_tiering.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_models.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_models_config_labels.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_needs_attention.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_network.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_new_issue_chat.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_next_release_tag.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_node_shim.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_notifier_baseline.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_notifier_cli.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_notifier_collect.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_notifier_config.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_notifier_drive_seam.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_notifier_isolation.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_notifier_predicate.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_notifier_quiet_hours.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_notifier_service.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_notify.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_notify_drain.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_openapi.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_operational_defaults.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_overlap_fence.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_overlap_predict.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_packaged_deploy_units.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_parentage.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_paste_landed.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_pipeline.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_plan_followup_approve_plan_command.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_plan_followup_pr_command.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_plan_followup_review_command.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_plan_only.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_plan_parser.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_platform_paths.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_portal_bridge.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_portal_config.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_portal_sync.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_pr_body_lint.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_prereqs.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_production_db_guard.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_progress.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_provider_seam.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_providers.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_providers_config_labels.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_providers_pty.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_quiet_hours.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_quiet_hours_store_2146.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_reap_merged_sessions.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_reap_stale_interactive_tick.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_reconcile.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_reconcile_branch.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_reconcile_completions.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_reconcile_merges.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_reconcile_no_agent_record.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_reconcile_tick.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_reconcile_usage_limit_done.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_refine_chat.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_release_cordon_2101.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_release_cordon_daemon_leads_2176.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_release_cordon_deadlock_2240.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_release_propagate.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_release_unified_1242.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_release_verify.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_release_window.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_remote_auto_prune.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_remote_interactive_reaper.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_repo_edit_2220.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_repo_graph_fleet_2237.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_repo_onboard_2220.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_report_result_push.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_reports.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_retry.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_retry_advisory_1606.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_retry_type_1636.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_revalidate.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_review.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_review_end_review_without_verdict.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_review_parse_failure_diagnostic.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_review_reaffirm.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_review_state.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_review_verdict_backstop.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_review_verdict_override_audit.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_review_verdict_relay.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_review_zero_commits.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_scoped_review_wiring.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_scorecard.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_self_health.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_serve.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_serve_app_board_trim.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_session.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_slice_issue_attribution.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_smoke.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_smoke_live_checkout_restore.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_smoke_workflow.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_spend_ceiling.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_spend_ceiling_coordinator.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_split.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_split_work.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_stage_projection.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_stalled_pipeline.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_state.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_state_review_findings_daemon.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_status_fleet_footer.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_stop_1567.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_stuck.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_terminal_command.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_test_author.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_test_chat.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_test_orchestrator.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_test_report.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_test_verdict_parsing.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_test_verdict_transcript_floor.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_thin_client_board_audit.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_thin_client_config_load_1080.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_thin_client_daemon_routing_906.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_tmux_host.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_tmux_session.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_transcript_floor.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_usage.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_usage_limits.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_usage_rollup.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_venv_live_install_2121.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_version_single_source.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_watch.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_windows_job_is_a_real_gate_2000.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_worker_events.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_worker_image_pin_sync.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_worker_safety.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_worker_test_scoping.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_worktree.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tests/test_worktree_rmtree_chokepoint.py +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tui/Cargo.lock +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tui/Cargo.toml +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tui/cargo-config-local-quadraui.toml.example +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tui/src/app/audit.rs +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tui/src/app/chat.rs +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tui/src/app/data.rs +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tui/src/app/dialogs.rs +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tui/src/app/doc_tabs.rs +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tui/src/app/drive.rs +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tui/src/app/drive_queue.rs +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tui/src/app/escalation.rs +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tui/src/app/events.rs +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tui/src/app/fixtures.rs +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tui/src/app/fleet_health.rs +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tui/src/app/fleet_sessions.rs +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tui/src/app/fleet_terminals.rs +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tui/src/app/format.rs +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tui/src/app/milestone_dag.rs +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tui/src/app/mod.rs +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tui/src/app/msv.rs +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tui/src/app/pipeline.rs +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tui/src/app/plans.rs +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tui/src/app/render.rs +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tui/src/app/reports.rs +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tui/src/app/sessions.rs +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tui/src/app/settings_ui.rs +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tui/src/app/sidebar.rs +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tui/src/app/terminal.rs +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tui/src/app/tests.rs +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tui/src/app/types.rs +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tui/src/app/workspace.rs +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tui/src/bin/gtk.rs +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tui/src/commands.rs +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tui/src/lib.rs +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tui/src/main.rs +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tui/src/settings.rs +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tui/tests/acceptance.rs +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tui/tests/cli.rs +0 -0
- {code_coordinator-0.5.195 → code_coordinator-0.5.196}/tui/tests/fixtures/board_sample.json +0 -0
|
@@ -153,6 +153,39 @@ jobs:
|
|
|
153
153
|
# gated separately through the #2164 CI wrapper.
|
|
154
154
|
- run: scripts/run_tests_without_gh.sh python -m pytest tests/ -q --ignore=tests/acceptance
|
|
155
155
|
|
|
156
|
+
# #2135 (child of epic #1902): "every `gh` argv construction lives inside
|
|
157
|
+
# coord/github_ops.py" is the load-bearing assumption under the #1902
|
|
158
|
+
# forge-portability cost estimate — it's the fact that makes the eventual
|
|
159
|
+
# port a refactor instead of a rewrite. #1483 already guarded direct
|
|
160
|
+
# call-argument leaks with an AST scan (formerly
|
|
161
|
+
# tests/test_no_direct_gh_calls.py), but that walk missed the
|
|
162
|
+
# variable-indirection shape (`cmd = ["gh", ...]; subprocess.run(cmd)`).
|
|
163
|
+
# This job's dedicated regex scan catches that gap too, so
|
|
164
|
+
# test_no_direct_gh_calls.py was retired in its favor rather than kept
|
|
165
|
+
# running alongside it as a second, disagreeing implementation of the
|
|
166
|
+
# same invariant (#2135 review) — see scripts/check_gh_argv_containment.py's
|
|
167
|
+
# module docstring for the full reconciliation.
|
|
168
|
+
#
|
|
169
|
+
# scripts/check_gh_argv_containment.py scans coord/**/*.py for a bare
|
|
170
|
+
# `"gh"`/`'gh'` token outside coord/github_ops.py, with one explicit,
|
|
171
|
+
# commented allowlist entry for coord/prereqs.py's binary-version probe
|
|
172
|
+
# (it checks `gh` is installed; it doesn't drive the forge). See that
|
|
173
|
+
# script's module docstring for the full rationale and
|
|
174
|
+
# tests/test_check_gh_argv_containment.py for the negative-test proof
|
|
175
|
+
# that the guard can actually fail.
|
|
176
|
+
#
|
|
177
|
+
# Stdlib-only (re/pathlib/dataclasses), so no `pip install` needed here —
|
|
178
|
+
# this is meant to be as cheap as `no-gh-on-path` above, a grep-shaped
|
|
179
|
+
# check, not a build step.
|
|
180
|
+
gh-argv-containment:
|
|
181
|
+
runs-on: ubuntu-latest
|
|
182
|
+
steps:
|
|
183
|
+
- uses: actions/checkout@v4
|
|
184
|
+
- uses: actions/setup-python@v5
|
|
185
|
+
with:
|
|
186
|
+
python-version: "3.12"
|
|
187
|
+
- run: python scripts/check_gh_argv_containment.py .
|
|
188
|
+
|
|
156
189
|
# #2170: run the full suite in the environment of a REAL FLEET MACHINE — a
|
|
157
190
|
# populated `~/.coord/` (thin-client shaped), no `sqlite3` on PATH, and a
|
|
158
191
|
# `$TMPDIR` under an ancestor pytest config.
|
|
@@ -309,6 +309,7 @@ docs/mocks/web/pipeline-narrow.html
|
|
|
309
309
|
docs/mocks/web/pipeline-wide.html
|
|
310
310
|
graphify-out/.gitignore
|
|
311
311
|
scripts/audit_review_verdict_overrides.py
|
|
312
|
+
scripts/check_gh_argv_containment.py
|
|
312
313
|
scripts/codegen.py
|
|
313
314
|
scripts/coord-test-runner.sh
|
|
314
315
|
scripts/drive-batch.sh
|
|
@@ -379,6 +380,7 @@ tests/test_branch_model.py
|
|
|
379
380
|
tests/test_bug_intake.py
|
|
380
381
|
tests/test_build_worker_image_env_update.py
|
|
381
382
|
tests/test_cargo_cache.py
|
|
383
|
+
tests/test_check_gh_argv_containment.py
|
|
382
384
|
tests/test_ci_acceptance_gate_1950.py
|
|
383
385
|
tests/test_ci_parity_2091.py
|
|
384
386
|
tests/test_ci_store.py
|
|
@@ -554,7 +556,6 @@ tests/test_needs_attention.py
|
|
|
554
556
|
tests/test_network.py
|
|
555
557
|
tests/test_new_issue_chat.py
|
|
556
558
|
tests/test_next_release_tag.py
|
|
557
|
-
tests/test_no_direct_gh_calls.py
|
|
558
559
|
tests/test_node_shim.py
|
|
559
560
|
tests/test_notifier_baseline.py
|
|
560
561
|
tests/test_notifier_cli.py
|
{code_coordinator-0.5.195 → code_coordinator-0.5.196}/code_coordinator.egg-info/scm_file_list.json
RENAMED
|
@@ -313,6 +313,7 @@
|
|
|
313
313
|
"scripts/azure-workers/scrub-and-generalize.sh",
|
|
314
314
|
"scripts/azure-workers/tailnet-acl.hujson",
|
|
315
315
|
"scripts/azure-workers/verify-github-token.sh",
|
|
316
|
+
"scripts/check_gh_argv_containment.py",
|
|
316
317
|
"scripts/codegen.py",
|
|
317
318
|
"scripts/coord-test-runner.sh",
|
|
318
319
|
"scripts/drive-batch.sh",
|
|
@@ -441,6 +442,7 @@
|
|
|
441
442
|
"tests/test_bug_intake.py",
|
|
442
443
|
"tests/test_build_worker_image_env_update.py",
|
|
443
444
|
"tests/test_cargo_cache.py",
|
|
445
|
+
"tests/test_check_gh_argv_containment.py",
|
|
444
446
|
"tests/test_ci_acceptance_gate_1950.py",
|
|
445
447
|
"tests/test_ci_parity_2091.py",
|
|
446
448
|
"tests/test_ci_store.py",
|
|
@@ -616,7 +618,6 @@
|
|
|
616
618
|
"tests/test_network.py",
|
|
617
619
|
"tests/test_new_issue_chat.py",
|
|
618
620
|
"tests/test_next_release_tag.py",
|
|
619
|
-
"tests/test_no_direct_gh_calls.py",
|
|
620
621
|
"tests/test_node_shim.py",
|
|
621
622
|
"tests/test_notifier_baseline.py",
|
|
622
623
|
"tests/test_notifier_cli.py",
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""check_gh_argv_containment.py -- CI guard for #2135 (child of epic #1902).
|
|
3
|
+
|
|
4
|
+
The epic's headline finding (#1902) is that **every `["gh", ...]` argv
|
|
5
|
+
construction in this repo already lives inside `coord/github_ops.py`** --
|
|
6
|
+
that single fact is what makes the eventual forge-portability port a
|
|
7
|
+
*refactor* instead of a rewrite, and it is the load-bearing assumption
|
|
8
|
+
under the whole #1902 cost estimate. Until this script, that invariant was
|
|
9
|
+
protected by nothing but convention: whoever last thought to grep for it.
|
|
10
|
+
|
|
11
|
+
Same spirit as `scripts/run_tests_without_gh.sh` (#1484, the `no-gh-on-path`
|
|
12
|
+
CI job) -- that script proved `gh` calls are *mockable* by making the
|
|
13
|
+
binary unresolvable and watching the suite still pass; this script proves
|
|
14
|
+
they are *contained* by refusing any `gh` argv construction that lives
|
|
15
|
+
outside the one file that owns them. Deliberately kept a plain regex scan,
|
|
16
|
+
not an AST walk -- cheap enough to run on every PR, and the invariant it
|
|
17
|
+
guards ("does this file spell the literal string `gh` as its own quoted
|
|
18
|
+
token") does not need a parser to detect.
|
|
19
|
+
|
|
20
|
+
Supersedes `tests/test_no_direct_gh_calls.py` (#1483's original AST-based
|
|
21
|
+
guard for this same invariant, added when only `github_ops.py`'s
|
|
22
|
+
call-site shape needed catching). #2135 review flagged that the two
|
|
23
|
+
guards were an undocumented split-brain: the AST walk only fires when a
|
|
24
|
+
`["gh", ...]` literal is a *direct call argument*
|
|
25
|
+
(`subprocess.run(["gh", ...])`), so it silently missed the
|
|
26
|
+
variable-indirection shape (`cmd = ["gh", ...]; subprocess.run(cmd)`) that
|
|
27
|
+
this regex scan does catch, since it matches the token wherever it sits on
|
|
28
|
+
the line. Rather than keep two independently-maintained implementations of
|
|
29
|
+
one invariant with two different blind spots, `test_no_direct_gh_calls.py`
|
|
30
|
+
was deleted and this script is now the single implementation, exercised
|
|
31
|
+
both by the dedicated `gh-argv-containment` CI job (`.github/workflows/
|
|
32
|
+
test.yml`) and by the ordinary `pytest tests/` run, via
|
|
33
|
+
`tests/test_check_gh_argv_containment.py::test_real_tree_is_clean` and
|
|
34
|
+
friends -- one scan, reachable both ways, per the repo's "one question,
|
|
35
|
+
one answer" rule (epic #2096). The trade-off this leaves: being a plain
|
|
36
|
+
token scan rather than an AST walk, it can false-positive on a `"gh"`
|
|
37
|
+
token that isn't argv (e.g. inside a docstring or an unrelated string
|
|
38
|
+
literal) -- accepted deliberately, since a false positive costs an
|
|
39
|
+
allowlist entry or a reword, while a false negative (the AST gap above)
|
|
40
|
+
costs a silent regression of the epic's #1902 load-bearing assumption.
|
|
41
|
+
|
|
42
|
+
Usage:
|
|
43
|
+
python scripts/check_gh_argv_containment.py [repo-root]
|
|
44
|
+
|
|
45
|
+
Exit codes: 0 if the tree is clean, 1 if a `gh` argv construction is found
|
|
46
|
+
in coord/**/*.py outside coord/github_ops.py.
|
|
47
|
+
"""
|
|
48
|
+
|
|
49
|
+
from __future__ import annotations
|
|
50
|
+
|
|
51
|
+
import re
|
|
52
|
+
import sys
|
|
53
|
+
from dataclasses import dataclass
|
|
54
|
+
from pathlib import Path
|
|
55
|
+
|
|
56
|
+
SEAM = "coord/github_ops.py"
|
|
57
|
+
|
|
58
|
+
# Matches a bare `"gh"` or `'gh'` token -- the exact spelling every gh argv
|
|
59
|
+
# construction in this repo starts with, whether written `["gh", ...]`,
|
|
60
|
+
# `("gh", ...)`, or (as in github_ops.py's PR-checks call, where the list is
|
|
61
|
+
# opened on the previous line) as a bare leading element `"gh", "pr", ...,`.
|
|
62
|
+
# The closing quote must land immediately after the 'h', so this does not
|
|
63
|
+
# match longer identifiers that merely contain "gh", like "github" or
|
|
64
|
+
# "ghost".
|
|
65
|
+
_GH_TOKEN_RE = re.compile(r"""(["'])gh\1""")
|
|
66
|
+
|
|
67
|
+
# Explicit allowlist: (file, substring-of-the-matched-line) pairs for
|
|
68
|
+
# known-legitimate `gh` mentions outside the seam. Keyed on line CONTENT,
|
|
69
|
+
# not a line number -- numbers drift as a file changes (this very entry's
|
|
70
|
+
# line moved from prereqs.py:288, where #2135 was filed, to prereqs.py:290
|
|
71
|
+
# by the time this script was written), and a number-keyed allowlist would
|
|
72
|
+
# either miss a real leak that later lands on that number, or stop
|
|
73
|
+
# exempting the intended line the moment it shifts.
|
|
74
|
+
#
|
|
75
|
+
# Add an entry here ONLY with a comment explaining why the mention is not
|
|
76
|
+
# an argv construction -- a loose pattern (e.g. "any line in prereqs.py")
|
|
77
|
+
# would let a real leak through under cover of the exemption, which is
|
|
78
|
+
# exactly the failure mode this script exists to prevent.
|
|
79
|
+
_ALLOWLIST: tuple[tuple[str, str], ...] = (
|
|
80
|
+
(
|
|
81
|
+
"coord/prereqs.py",
|
|
82
|
+
'tool="gh", binary="gh"',
|
|
83
|
+
),
|
|
84
|
+
# ^ Prereq(tool="gh", binary="gh", version_args=("--version",), ...)
|
|
85
|
+
# probes for the `gh` BINARY's presence/version via shutil.which +
|
|
86
|
+
# `gh --version` -- it does not drive the forge, so it correctly lives
|
|
87
|
+
# outside the seam (#2135).
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
@dataclass(frozen=True)
|
|
92
|
+
class Violation:
|
|
93
|
+
path: str
|
|
94
|
+
lineno: int
|
|
95
|
+
line: str
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def _is_allowlisted(rel_path: str, line: str) -> bool:
|
|
99
|
+
return any(
|
|
100
|
+
rel_path == allow_path and allow_substr in line
|
|
101
|
+
for allow_path, allow_substr in _ALLOWLIST
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def find_violations(repo_root: Path) -> list[Violation]:
|
|
106
|
+
"""Scan coord/**/*.py for `gh` argv construction outside the seam.
|
|
107
|
+
|
|
108
|
+
Pure function of the filesystem under ``repo_root`` -- no subprocess,
|
|
109
|
+
no network -- so it is cheap to point at a synthetic fixture tree in
|
|
110
|
+
tests, not just the real repo.
|
|
111
|
+
"""
|
|
112
|
+
violations: list[Violation] = []
|
|
113
|
+
coord_dir = repo_root / "coord"
|
|
114
|
+
if not coord_dir.is_dir():
|
|
115
|
+
return violations
|
|
116
|
+
for path in sorted(coord_dir.rglob("*.py")):
|
|
117
|
+
rel = path.relative_to(repo_root).as_posix()
|
|
118
|
+
if rel == SEAM:
|
|
119
|
+
continue
|
|
120
|
+
try:
|
|
121
|
+
text = path.read_text(encoding="utf-8")
|
|
122
|
+
except (UnicodeDecodeError, OSError) as exc:
|
|
123
|
+
# Every file under coord/ is expected to be UTF-8 Python
|
|
124
|
+
# source, so this should never actually fire -- but if it
|
|
125
|
+
# ever does, skipping silently would mean a real `gh` leak in
|
|
126
|
+
# that file goes undetected with no trace. Surface it on
|
|
127
|
+
# stderr rather than swallow it (#2135 review).
|
|
128
|
+
print(
|
|
129
|
+
f"check_gh_argv_containment: skipping {rel} "
|
|
130
|
+
f"(unreadable: {exc}) -- unable to scan for `gh` argv "
|
|
131
|
+
f"construction in this file",
|
|
132
|
+
file=sys.stderr,
|
|
133
|
+
)
|
|
134
|
+
continue
|
|
135
|
+
for lineno, line in enumerate(text.splitlines(), start=1):
|
|
136
|
+
if _GH_TOKEN_RE.search(line) and not _is_allowlisted(rel, line):
|
|
137
|
+
violations.append(Violation(rel, lineno, line.strip()))
|
|
138
|
+
return violations
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
def format_report(violations: list[Violation]) -> str:
|
|
142
|
+
lines = [
|
|
143
|
+
f"check_gh_argv_containment: found `gh` argv construction outside "
|
|
144
|
+
f"{SEAM}:",
|
|
145
|
+
"",
|
|
146
|
+
]
|
|
147
|
+
for v in violations:
|
|
148
|
+
lines.append(f" {v.path}:{v.lineno}: {v.line}")
|
|
149
|
+
lines += [
|
|
150
|
+
"",
|
|
151
|
+
"Every `gh` invocation must go through coord/github_ops.py -- that "
|
|
152
|
+
"chokepoint is the load-bearing assumption behind the #1902 "
|
|
153
|
+
"forge-portability epic (it's what makes the eventual port a "
|
|
154
|
+
"refactor instead of a rewrite), and it's what makes `gh` mockable "
|
|
155
|
+
"for tests (the no-gh-on-path CI job, #1484, depends on it too).",
|
|
156
|
+
"",
|
|
157
|
+
'Fix: move this call into coord/github_ops.py. If it is a genuine '
|
|
158
|
+
'non-forge use of the literal string "gh" (like the binary-version '
|
|
159
|
+
"probe in coord/prereqs.py), add it to the ALLOWLIST in "
|
|
160
|
+
"scripts/check_gh_argv_containment.py with a comment explaining "
|
|
161
|
+
"why -- see #2135.",
|
|
162
|
+
]
|
|
163
|
+
return "\n".join(lines)
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
def main(argv: list[str]) -> int:
|
|
167
|
+
repo_root = Path(argv[1]) if len(argv) > 1 else Path(".")
|
|
168
|
+
violations = find_violations(repo_root.resolve())
|
|
169
|
+
if not violations:
|
|
170
|
+
return 0
|
|
171
|
+
print(format_report(violations), file=sys.stderr)
|
|
172
|
+
return 1
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
if __name__ == "__main__":
|
|
176
|
+
sys.exit(main(sys.argv))
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
"""#2135 (child of epic #1902): CI guard for the gh-argv containment
|
|
2
|
+
invariant -- "every `gh` argv construction lives inside
|
|
3
|
+
coord/github_ops.py".
|
|
4
|
+
|
|
5
|
+
This is build tooling with no user-visible behavior, so it's exempt from
|
|
6
|
+
the black-box acceptance bar (CLAUDE.md's "Testing" section) -- but per
|
|
7
|
+
that same section's note on this issue, a guard that cannot fail is worse
|
|
8
|
+
than no guard, so this file's job is proving the negative case: a
|
|
9
|
+
deliberately-introduced `gh` argv construction outside the seam actually
|
|
10
|
+
trips scripts/check_gh_argv_containment.py.
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
from __future__ import annotations
|
|
14
|
+
|
|
15
|
+
from pathlib import Path
|
|
16
|
+
|
|
17
|
+
from scripts.check_gh_argv_containment import find_violations, format_report
|
|
18
|
+
|
|
19
|
+
REPO_ROOT = Path(__file__).resolve().parent.parent
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def test_real_tree_is_clean() -> None:
|
|
23
|
+
"""The acceptance bar from #2135: the current tree passes today, with
|
|
24
|
+
coord/prereqs.py exempted by explicit allowlist rather than by
|
|
25
|
+
accident (i.e. its exemption is on record, not just an absence of
|
|
26
|
+
other violations)."""
|
|
27
|
+
violations = find_violations(REPO_ROOT)
|
|
28
|
+
assert violations == [], format_report(violations)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def test_prereqs_binary_probe_is_allowlisted_not_absent() -> None:
|
|
32
|
+
"""Guard against the allowlist silently becoming dead code: prove
|
|
33
|
+
coord/prereqs.py actually contains a `gh` token that the scan visits
|
|
34
|
+
and exempts, not that the scanner simply never looks at that file."""
|
|
35
|
+
prereqs = REPO_ROOT / "coord" / "prereqs.py"
|
|
36
|
+
text = prereqs.read_text(encoding="utf-8")
|
|
37
|
+
assert 'tool="gh", binary="gh"' in text, (
|
|
38
|
+
"coord/prereqs.py's Prereq(tool=\"gh\", binary=\"gh\", ...) moved or "
|
|
39
|
+
"was rewritten -- update the ALLOWLIST entry (and this test) to "
|
|
40
|
+
"match its new shape, per #2135."
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def test_deliberate_leak_outside_the_seam_is_caught(tmp_path: Path) -> None:
|
|
45
|
+
"""The acceptance criterion from #2135: a deliberately-added
|
|
46
|
+
`subprocess.run(["gh", "pr", "view", "1"])` in any coord/*.py other
|
|
47
|
+
than github_ops.py fails the check."""
|
|
48
|
+
coord_dir = tmp_path / "coord"
|
|
49
|
+
coord_dir.mkdir()
|
|
50
|
+
(coord_dir / "github_ops.py").write_text(
|
|
51
|
+
'import subprocess\n'
|
|
52
|
+
'subprocess.run(["gh", "pr", "view", "1"])\n',
|
|
53
|
+
encoding="utf-8",
|
|
54
|
+
)
|
|
55
|
+
leaky = coord_dir / "review.py"
|
|
56
|
+
leaky.write_text(
|
|
57
|
+
'import subprocess\n'
|
|
58
|
+
'\n'
|
|
59
|
+
'def peek(number):\n'
|
|
60
|
+
' subprocess.run(["gh", "pr", "view", str(number)])\n',
|
|
61
|
+
encoding="utf-8",
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
violations = find_violations(tmp_path)
|
|
65
|
+
|
|
66
|
+
assert len(violations) == 1
|
|
67
|
+
v = violations[0]
|
|
68
|
+
assert v.path == "coord/review.py"
|
|
69
|
+
assert v.lineno == 4
|
|
70
|
+
assert '"gh"' in v.line
|
|
71
|
+
|
|
72
|
+
report = format_report(violations)
|
|
73
|
+
assert "coord/review.py:4" in report
|
|
74
|
+
assert "coord/github_ops.py" in report
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def test_single_and_double_quote_forms_are_both_caught(tmp_path: Path) -> None:
|
|
78
|
+
"""Requirement from #2135: detect both quote styles."""
|
|
79
|
+
coord_dir = tmp_path / "coord"
|
|
80
|
+
coord_dir.mkdir()
|
|
81
|
+
(coord_dir / "github_ops.py").write_text("# the seam\n", encoding="utf-8")
|
|
82
|
+
(coord_dir / "leaky_double.py").write_text(
|
|
83
|
+
'CMD = ["gh", "pr", "list"]\n', encoding="utf-8"
|
|
84
|
+
)
|
|
85
|
+
(coord_dir / "leaky_single.py").write_text(
|
|
86
|
+
"CMD = ('gh', 'pr', 'list')\n", encoding="utf-8"
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
violations = find_violations(tmp_path)
|
|
90
|
+
|
|
91
|
+
flagged = {v.path for v in violations}
|
|
92
|
+
assert flagged == {"coord/leaky_double.py", "coord/leaky_single.py"}
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
def test_explicit_allowlist_entry_is_exempted(tmp_path: Path) -> None:
|
|
96
|
+
"""The allowlist is content-keyed, not a blanket per-file exemption:
|
|
97
|
+
the exact allowlisted line is spared, but the file is otherwise still
|
|
98
|
+
scanned."""
|
|
99
|
+
coord_dir = tmp_path / "coord"
|
|
100
|
+
coord_dir.mkdir()
|
|
101
|
+
(coord_dir / "github_ops.py").write_text("# the seam\n", encoding="utf-8")
|
|
102
|
+
(coord_dir / "prereqs.py").write_text(
|
|
103
|
+
'Prereq(\n'
|
|
104
|
+
' tool="gh", binary="gh", version_args=("--version",),\n'
|
|
105
|
+
')\n',
|
|
106
|
+
encoding="utf-8",
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
violations = find_violations(tmp_path)
|
|
110
|
+
|
|
111
|
+
assert violations == []
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
def test_allowlist_does_not_blanket_exempt_other_gh_leaks_in_same_file(
|
|
115
|
+
tmp_path: Path,
|
|
116
|
+
) -> None:
|
|
117
|
+
"""A loose allowlist ("any line in prereqs.py") would let a real leak
|
|
118
|
+
through under cover of the exemption -- exactly the failure mode
|
|
119
|
+
#2135 calls out. This pins the allowlist to line CONTENT, so an
|
|
120
|
+
unrelated `gh` argv construction added to the same file is still
|
|
121
|
+
caught."""
|
|
122
|
+
coord_dir = tmp_path / "coord"
|
|
123
|
+
coord_dir.mkdir()
|
|
124
|
+
(coord_dir / "github_ops.py").write_text("# the seam\n", encoding="utf-8")
|
|
125
|
+
(coord_dir / "prereqs.py").write_text(
|
|
126
|
+
'Prereq(\n'
|
|
127
|
+
' tool="gh", binary="gh", version_args=("--version",),\n'
|
|
128
|
+
')\n'
|
|
129
|
+
'\n'
|
|
130
|
+
'import subprocess\n'
|
|
131
|
+
'subprocess.run(["gh", "pr", "view", "1"])\n',
|
|
132
|
+
encoding="utf-8",
|
|
133
|
+
)
|
|
134
|
+
|
|
135
|
+
violations = find_violations(tmp_path)
|
|
136
|
+
|
|
137
|
+
assert len(violations) == 1
|
|
138
|
+
assert violations[0].path == "coord/prereqs.py"
|
|
139
|
+
assert violations[0].lineno == 6
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
def test_does_not_flag_words_that_merely_contain_gh(tmp_path: Path) -> None:
|
|
143
|
+
"""`"github"`, `"ghost"`, etc. must not false-positive -- the closing
|
|
144
|
+
quote has to land immediately after the 'h'."""
|
|
145
|
+
coord_dir = tmp_path / "coord"
|
|
146
|
+
coord_dir.mkdir()
|
|
147
|
+
(coord_dir / "github_ops.py").write_text("# the seam\n", encoding="utf-8")
|
|
148
|
+
(coord_dir / "fine.py").write_text(
|
|
149
|
+
'HOST = "github.com"\n'
|
|
150
|
+
'NAME = "ghost"\n',
|
|
151
|
+
encoding="utf-8",
|
|
152
|
+
)
|
|
153
|
+
|
|
154
|
+
violations = find_violations(tmp_path)
|
|
155
|
+
|
|
156
|
+
assert violations == []
|
|
@@ -1,112 +0,0 @@
|
|
|
1
|
-
"""Regression guard for #1483: `gh` must be invoked from exactly one place.
|
|
2
|
-
|
|
3
|
-
``coord/github_ops.py`` is the legitimate GitHub adapter -- "the single sink
|
|
4
|
-
that a GitLab backend would sit beside" (#1483). Several other modules used
|
|
5
|
-
to shell out to `gh` directly (``coord/review.py``, ``coord/drive.py``,
|
|
6
|
-
``coord/ci_github.py``, ``coord/test_orchestrator.py``,
|
|
7
|
-
``coord/commands/test_gate.py``), which:
|
|
8
|
-
|
|
9
|
-
- makes worker/daemon hosts implicitly depend on `gh` being on PATH for code
|
|
10
|
-
paths that have nothing to do with choosing a forge backend (the elitebook
|
|
11
|
-
incident: a worker silently lost GitHub access because `gh` lived at a
|
|
12
|
-
linuxbrew path outside the systemd unit's PATH -- 98 failures burned
|
|
13
|
-
diagnosing "environment", not the code);
|
|
14
|
-
- in ``coord/drive.py``, made behaviour silently depend on whether a `gh`
|
|
15
|
-
binary happened to be on PATH (``shutil.which("gh")``), with no log line
|
|
16
|
-
and no verdict;
|
|
17
|
-
- blocks a future GitLab / bare-DB backend from swapping in cleanly, since
|
|
18
|
-
each leak is one more place that would need to learn about the new
|
|
19
|
-
backend.
|
|
20
|
-
|
|
21
|
-
This test statically scans every non-adapter module under ``coord/`` for a
|
|
22
|
-
literal ``"gh"``/``'gh'`` used as a subprocess argv[0], or
|
|
23
|
-
``shutil.which("gh")``, and fails if either turns up outside
|
|
24
|
-
``coord/github_ops.py``. New `gh` call sites belong in ``github_ops.py``;
|
|
25
|
-
everything else should call through that seam.
|
|
26
|
-
"""
|
|
27
|
-
|
|
28
|
-
from __future__ import annotations
|
|
29
|
-
|
|
30
|
-
import ast
|
|
31
|
-
from pathlib import Path
|
|
32
|
-
|
|
33
|
-
REPO_ROOT = Path(__file__).resolve().parent.parent
|
|
34
|
-
COORD_DIR = REPO_ROOT / "coord"
|
|
35
|
-
|
|
36
|
-
# The one legitimate `gh` sink -- new gh functionality belongs here, not
|
|
37
|
-
# scattered across the codebase.
|
|
38
|
-
ALLOWED_FILES = {COORD_DIR / "github_ops.py"}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
def _iter_coord_py_files() -> list[Path]:
|
|
42
|
-
return [
|
|
43
|
-
path
|
|
44
|
-
for path in sorted(COORD_DIR.rglob("*.py"))
|
|
45
|
-
if path not in ALLOWED_FILES and "__pycache__" not in path.parts
|
|
46
|
-
]
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
def _is_gh_argv0(node: ast.AST) -> bool:
|
|
50
|
-
"""True if *node* is a list/tuple literal whose first element is the
|
|
51
|
-
string literal ``"gh"`` -- the shape of ``subprocess.run(["gh", ...])`` /
|
|
52
|
-
``subprocess.Popen(["gh", ...])`` (under any import alias)."""
|
|
53
|
-
if not isinstance(node, (ast.List, ast.Tuple)) or not node.elts:
|
|
54
|
-
return False
|
|
55
|
-
first = node.elts[0]
|
|
56
|
-
return isinstance(first, ast.Constant) and first.value == "gh"
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
def _is_shutil_which_gh(node: ast.Call) -> bool:
|
|
60
|
-
"""True for ``shutil.which("gh")`` / ``which("gh")`` -- the silent,
|
|
61
|
-
host-dependent-behaviour shape #1483 called out explicitly in
|
|
62
|
-
``coord/drive.py``."""
|
|
63
|
-
func = node.func
|
|
64
|
-
name = func.attr if isinstance(func, ast.Attribute) else (
|
|
65
|
-
func.id if isinstance(func, ast.Name) else None
|
|
66
|
-
)
|
|
67
|
-
if name != "which":
|
|
68
|
-
return False
|
|
69
|
-
return any(
|
|
70
|
-
isinstance(arg, ast.Constant) and arg.value == "gh" for arg in node.args
|
|
71
|
-
)
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
def _find_violations(path: Path) -> list[str]:
|
|
75
|
-
tree = ast.parse(path.read_text(), filename=str(path))
|
|
76
|
-
violations = []
|
|
77
|
-
for node in ast.walk(tree):
|
|
78
|
-
if not isinstance(node, ast.Call):
|
|
79
|
-
continue
|
|
80
|
-
if _is_shutil_which_gh(node):
|
|
81
|
-
violations.append(f'{path}:{node.lineno}: shutil.which("gh")')
|
|
82
|
-
continue
|
|
83
|
-
for arg in node.args:
|
|
84
|
-
if _is_gh_argv0(arg):
|
|
85
|
-
violations.append(f'{path}:{node.lineno}: subprocess argv0 "gh" literal')
|
|
86
|
-
break
|
|
87
|
-
return violations
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
def test_no_direct_gh_invocations_outside_github_ops() -> None:
|
|
91
|
-
all_violations: list[str] = []
|
|
92
|
-
for path in _iter_coord_py_files():
|
|
93
|
-
all_violations.extend(_find_violations(path))
|
|
94
|
-
assert not all_violations, (
|
|
95
|
-
"Direct `gh` invocation(s) found outside coord/github_ops.py -- "
|
|
96
|
-
"route through the github_ops seam instead (#1483):\n" + "\n".join(all_violations)
|
|
97
|
-
)
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
def test_guard_actually_detects_a_leak(tmp_path) -> None:
|
|
101
|
-
"""Prove the AST scan isn't a no-op -- planting a leak must trip it."""
|
|
102
|
-
leak = tmp_path / "leaky.py"
|
|
103
|
-
leak.write_text(
|
|
104
|
-
"import subprocess\n"
|
|
105
|
-
"def f():\n"
|
|
106
|
-
" subprocess.run(['gh', 'pr', 'view', '1'])\n"
|
|
107
|
-
)
|
|
108
|
-
assert _find_violations(leak)
|
|
109
|
-
|
|
110
|
-
which_leak = tmp_path / "leaky_which.py"
|
|
111
|
-
which_leak.write_text("import shutil\nshutil.which('gh')\n")
|
|
112
|
-
assert _find_violations(which_leak)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{code_coordinator-0.5.195 → code_coordinator-0.5.196}/code_coordinator.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
{code_coordinator-0.5.195 → code_coordinator-0.5.196}/code_coordinator.egg-info/entry_points.txt
RENAMED
|
File without changes
|
{code_coordinator-0.5.195 → code_coordinator-0.5.196}/code_coordinator.egg-info/requires.txt
RENAMED
|
File without changes
|
{code_coordinator-0.5.195 → code_coordinator-0.5.196}/code_coordinator.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|