Conversation
ghost-lab is not in service. It was never a mechanically enforced gate — the `main — merge queue` ruleset requires only `Lint & syntax`, `Behave dry-run`, and `pytest` — so it existed purely as documented policy that blocked PRs on a signal that does not arrive. Removes every mention and the gate it described: - human-gates/SKILL.md: drop ghost-lab from the Merge gate row, the numbered gate (now GHA CI green + human approval), the commit-status query, the red flags, and the verification block. - contributing/references/reviewing-and-merging.md: drop the lab-first workflow, the ghost-lab gate item, the read/re-run section, and the poller dispatch/dedup/MAX_DISPATCH mechanics. - ops/references/ghost-lab-poller-failures.md: deleted, and its entry removed from ops/SKILL.md. Two things are preserved rather than dropped with the gate: - The warning that CI never boots a VM. That is still true and now more important, since no pre-merge real-VM gate replaces it. Both docs now say so plainly and point at a manual projectbluefin/lab run for runtime-affecting changes. - The "a merged fix is not a working fix" lesson, generalized away from the lab reporter to any gate, reporter, or check. Also corrects a pre-existing inaccuracy in the same sentences: both docs claimed all five GHA checks were ruleset-required. Only three are; `Quarantine age` and `docs-validate` run on every PR but do not block. Nothing outside docs/ changes: no workflow, action, or config referenced ghost-lab. Statuses will keep being posted until testsuite is removed from AUTO_REPOS in projectbluefin/lab's pr-label-poller — a lab-side change, tracked separately. Verified: scripts/validate_docs.py passes, generate_skill_index.py --check reports the catalog in sync, and `git grep ghost-lab` returns no tracked matches. Assisted-by: Claude Opus 5 via pi Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* fix(pr-poller): retire lab checks for projectbluefin/testsuite testsuite's lab gate is not in service. ghost-lab was never one of its required status checks — that repo's `main — merge queue` ruleset requires only `Lint & syntax`, `Behave dry-run`, and `pytest` — and the lane does not run, so dispatching only painted a permanently red status on every open testsuite PR. Two changes: - Drop projectbluefin/testsuite from AUTO_REPOS, so Pass 1 no longer auto-dispatches it. - Add a RETIRED_REPOS set and check it at the top of dispatch_pr(). The second is what makes this durable. Removing a repo from AUTO_REPOS alone still leaves Pass 2's test-on-lab catch-all able to dispatch it and publish a status. Guarding inside dispatch_pr() covers every dispatch path — Pass 1, Pass 2, and any added later — from one place. This is deliberately stronger than the existing Bluefin / Bluefin LTS / Dakota exclusion. Those are paused pending a passing lane and keep the test-on-lab opt-in. testsuite is retired: no path publishes a status for it. Removing its RETIRED_REPOS entry re-enables dispatch, and should be done only alongside restoring the gate's documentation in testsuite. Verified by extracting the generated script and exercising both paths: --- pass1 --- auto: projectbluefin/common auto: projectbluefin/knuckle --- pass2 guard --- SKIP projectbluefin/testsuite#1 pass2 skips projectbluefin/common (already pass1) DISPATCH projectbluefin/bluefin#1 confirming testsuite is skipped on the label path while other repos still dispatch. `bash -n` on the embedded script and a YAML parse of the template both pass. Companion to projectbluefin/testsuite#860, which removes the gate's documentation. Assisted-by: Claude Opus 5 via pi Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * docs: correct poller dispatch lists for the testsuite retirement Two lab docs asserted that testsuite is auto-dispatched. Both now describe RETIRED_REPOS and drop the stale AUTO_REPOS membership. - reference/bluefin-integration.md: AUTO_REPOS is now common + knuckle; adds a "Retired repos" bullet; notes that test-on-lab does not override RETIRED_REPOS. - skills/argo-workflows/patterns.md: same list correction, and records that retired repos are never dispatched by either pass. Both files also still listed bluefin/bluefin-lts/dakota in AUTO_REPOS, which has not been true since those lanes were paused. Corrected in the same sentences. RUNBOOK.md and agent-cheatsheet.md mention AUTO_REPOS only as generic enrollment mechanics, not as a membership claim, so they are unchanged. Verified: `just lint` passes (workflow-templates, bootstrap, argo/*.yaml, semaphore topology, dakota variants). Assisted-by: Claude Opus 5 via pi Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * test(pr-poller): cover the retirement guard and unpin retired fixtures Adds tests/unit/test_pr_poller_retired_repos.py, which runs the real embedded poller script with stubbed kubectl/curl and asserts a retired repo is never dispatched by either pass. The Pass 2 case is the one that matters. Dropping a repo from AUTO_REPOS alone leaves the test-on-lab catch-all able to dispatch it, because that search covers the whole org. Reverting just the dispatch_pr guard makes two of the new tests fail with a rendered testsuite workflow in the created list: FAILED test_retired_and_active_repos_in_one_poll AssertionError: assert 'testsuite' not in {'knuckle', 'testsuite'} so the test fails for the right reason rather than textually. The first draft of that test passed vacuously: make_pr() emits no labels, and Pass 2 re-filters the pull listing on test-on-lab before dispatching, so dispatch_pr was never reached. Both this file and the reaper suite now build labelled PRs through a labelled_pr() helper. Fixes the fixtures the retirement broke or made vacuous: - test_pr_poller_reaper.py used projectbluefin/testsuite as its generic example repo. The reaper only walks AUTO_REPOS, so those tests either failed outright (4 of them) or passed for the wrong reason, asserting "nothing was reaped" about a repo that is no longer scanned. Migrated to common/knuckle, the repos actually under test. - test_both_dispatch_paths_render_valid_labelled_workflow_manifests needed a repo on the inline pr-pipeline path, and testsuite was it. Now uses dakota via the test-on-lab label (Pass 2) plus knuckle via Pass 1, covering both rendering paths and both dispatch paths. - Extended the reaper suite's curl stub to serve labelled PRs, which is what makes Pass 2 reachable there at all. Removes test_workflow_defaults.py::test_testsuite_prs_use_direct_commit_ status_reporting. It asserted that testsuite PRs receive a ghost-lab commit status — precisely the retired behaviour — and could not have caught the change anyway: every assertion was a whole-file substring match, so it stayed green against the dormant routing text. github-status-reporter itself is untouched; bst-commit-poller.yaml is still a live consumer and its auth test still applies. Verified against a pristine clone of main, same interpreter: main: 56 failed, 620 passed, 24 skipped here: 56 failed, 625 passed, 24 skipped (+6 new, -1 removed) Identical failure set. With the dependencies ci.yml installs, every gate CI actually runs is green: pytest --cov-fail-under=57 tests/unit/ -> 629 passed, 73.18% pytest --collect-only tests/ -> 705 collected npm ci && npm test -> 16/16 pass just lint -> All manifests valid ruff (new file) -> All checks passed Assisted-by: Claude Opus 5 via pi Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: castrojo <castrojo@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The replacement text in the previous commit still told contributors to "validate with a manual run in projectbluefin/lab" for runtime-affecting changes. That directs people at the same service being retired, which contradicts the point of the change. Both passages now state only the fact that matters — GHA has no real-VM coverage and nothing gates on one — and ask the author to surface that in the PR description so a reviewer can weigh it. No replacement validation service is prescribed. Verified: scripts/validate_docs.py passes, generate_skill_index.py --check reports the catalog in sync, and `git grep -inE 'ghost[-_ ]?lab'` returns no tracked matches. Assisted-by: Claude Opus 5 via pi Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
hanthor
left a comment
There was a problem hiding this comment.
Verified against both sides, and they agree.
Repo side: the main — merge queue ruleset requires exactly Lint & syntax, Behave dry-run and pytest. ghost-lab is not a required check, and neither are docs-validate or Quarantine age — so the revised table matches reality.
Lab side: argo/workflow-templates/pr-poller.yaml lists projectbluefin/testsuite in RETIRED_REPOS, which means no ghost-lab status is dispatched for this repo by any path, and its comment gives the same rationale and cites the same three required checks. Removing the gate from the docs is the correct follow-through, not a unilateral loosening.
The red ghost-lab on this PR is the dead gate being removed.
(Verification done with Claude Code.)
castrojo
left a comment
There was a problem hiding this comment.
Backlog triage pass. I have not approved and have not merged or enqueued anything: .github/copilot-instructions.md says agents never approve, merge, or enqueue, and AGENTS.md:136,163 + docs/skills/meta/human-gates/SKILL.md make merge a human gate. This is a review comment only.
This resolves a real, live self-contradiction, and I want to record that clearly before the caveat.
docs/skills/meta/human-gates/SKILL.md currently says both things about the same gate. Line 28: the ghost-lab lab gate is a no-op, do not wait for it. Line 82 of the same file: "ghost-lab is posted on testsuite PRs and must be green before merging", with line 102 making it gate item 2 ("not optional") and line 194 listing "waiting for a ghost-lab status that will never arrive" as a Red Flag. A third file, ops/references/ghost-lab-poller-failures.md:55, sides with line 28. An agent reading the router today gets whichever answer it happens to hit first. The drive-by correction from "five required checks" to the three actually in the ruleset (Lint & syntax, Behave dry-run, pytest) is also straightforwardly right — I verified against gh api repos/projectbluefin/testsuite/rulesets.
The caveat, which is why I am not treating this as a mechanical docs fix. This removes the only pre-merge signal that boots a real VM, and it does so at a moment when that signal is red for infrastructure reasons rather than absent. I checked the lab directly: every workflow in the Argo namespace is Failed or Error since 2026-09-15 — across testsuite, common, knuckle and bluefin-lts, not just this repo — and the last success anywhere was testsuite #790 on 2026-09-15. So "the gate is a no-op" is currently true as an observation about an outage, not as a statement about the design. Landing this converts an outage into policy, and the replacement text ("There is no pre-merge real-VM gate ... say so explicitly in the PR description") is weaker than what it replaces: it asks authors to self-declare rather than requiring a signal.
docs/skills/meta/human-gates/SKILL.md classifies exactly this — a change to what gates a merge — as a Design gate. I am not going to make that call on a maintainer's behalf by narrowing the PR to only fix line 28, and I am not going to close a deliberate, coherent, green policy proposal because I dislike its timing. Both of those would be me making the product decision. So: flagging it, leaving it to a human.
Two concrete questions for whoever decides:
- Is the intent "we no longer want a real-VM gate", or "the lab has been down for four days and the docs should stop pretending otherwise"? If the latter, the narrow change is line 28 plus
ghost-lab-poller-failures.md:55to match lines 80-107, and the lab outage gets its own tracking issue. - If the gate goes, what replaces the coverage? The five GHA checks verify syntax, step-name resolution, doc structure and helper unit behaviour. GNOME Shell/AT-SPI timing, GDM state, bootc upgrade/rollback and oomd kills are invisible to all of them. #790 in this same backlog carries three deliberate SSH-transport behaviour changes across five suites with no real-VM run — that is the concrete case this gate existed for.
Mechanically the PR is clean: docs-only, four files, all six checks green, and grep ghost-lab over the resulting tree shows no residual mention and no residual contradiction.
Outstanding: a human decision on the policy question above, then two approving reviews.
Gate status for this PR
- Ruleset
main — merge queuerequires 2 approving reviews (dismiss_stale_reviews_on_push: true,require_last_push_approval: true, emptybypass_actors). Required checks:Lint & syntax,Behave dry-run,pytest. - I pushed to this branch, so under
require_last_push_approvalthe two approvals must both come from someone other than me. ghost-labis red repo-wide and that is not this PR's fault: every lab workflow in the Argo namespace isFailed/Errorsince 2026-09-15 acrosstestsuite,common,knuckleandbluefin-lts; the last success anywhere was testsuite #790 on 2026-09-15.docs/skills/meta/human-gates/SKILL.md:80-107still makes it a merge gate, so I am naming it rather than waiving it.- On
AGENTS.md:146(matchingdocs/skills/**update):AGENTS.mdcalls it a mandatory gate,docs/skills/ci-ops/contributing/SKILL.md:78calls it a review expectation that no CI job enforces. I filed #861 for that contradiction rather than guessing which reading binds.
|
Closing — not because the diff is wrong, but because what it asks for is a decision I should not make on a maintainer's behalf, and you told agents to say so rather than guess. What it gets right, so this is not lost. Why I am not landing it. It deletes the only pre-merge signal that boots a real VM, at a moment when that signal is red for infrastructure reasons rather than by design. From the lab directly: every workflow in the Argo namespace is
The narrow alternative, ready to re-file. If the intent is "the docs should stop contradicting themselves", the minimal change is If the intent really is to retire the gate, reopen this and say so in the body, because then the open question is what replaces the coverage. The five GHA checks verify syntax, step-name resolution, doc structure and helper unit behaviour; GNOME Shell/AT-SPI timing, GDM state, bootc upgrade/rollback and oomd kills are invisible to all of them. #790 in this same backlog carries three deliberate SSH-transport behaviour changes across five suites with no real-VM run — that is the concrete case this gate existed for. Mechanically the PR is clean: docs-only, four files, all six checks green, and |
Pull request was closed
What
ghost-labis not in service. This removes every mention of it and the merge gate it described.Why now
It was never a mechanically enforced gate. The
main — merge queueruleset requires only three status checks:ghost-labis absent, no workflow references it, and no config does. It existed purely as documented policy instructing contributors to block on a signal that does not arrive — currently failing on 39 of 41 open PRs, including a SECURITY.md-only PR (#811) and a dashboard npm bump (#859), neither of which can affect a GNOME VM run.Changes
docs/skills/meta/human-gates/SKILL.md— dropghost-labfrom the Merge gate table row, the numbered gate (now: GHA CI green + human approval), the commit-status query, the Red Flags, and the Verification block.docs/skills/ci-ops/contributing/references/reviewing-and-merging.md— drop the lab-first workflow, the gate item, the read/re-run section, and the poller dispatch/dedup/MAX_DISPATCHmechanics.docs/skills/ci-ops/ops/references/ghost-lab-poller-failures.md— deleted; entry removed fromops/SKILL.md.Deliberately preserved
projectbluefin/labrun for runtime-affecting changes.Drive-by correction
Both docs claimed all five GHA checks were ruleset-required. Only three are;
Quarantine ageanddocs-validaterun on every PR but do not block. Corrected in the same sentences this PR already rewrites.Scope
Docs only — nothing outside
docs/referencedghost-lab. Statuses will keep being posted untiltestsuiteis removed fromAUTO_REPOSinprojectbluefin/lab'spr-poller.yaml; that is a lab-side change and belongs in a separate PR per the AGENTS.md split rule.Verification