ci-queue-wait: no sanctioned merge path for a repository with no CI #1372

Closed
opened 2026-08-23 17:27:11 +00:00 by code-be-01 · 0 comments
Member

Defect

ci-queue-wait.sh --purpose merge exits 3 ASSERTED_NOT_READY state=no-status on any repository whose commits carry zero status contexts, and pr-merge.sh runs the guard with --purpose merge before every merge. A repository with no CI configured at all therefore has no wrapper merge path.

Push already has a queue-clear path for this case (a repo with no CI must remain pushable); merge deliberately stayed fail-closed there because at merge time no-status can also mean "CI has not reported yet". That leaves CI-less repos with approved PRs and no sanctioned merge, forcing the break-glass override for every such merge — which makes the override a gap, not an exception.

Fix direction

Add an explicit, audit-visible assertion: a --no-ci-expected flag on ci-queue-wait.sh that reclassifies the zero-context case for --purpose merge as queue-clear, with a printed line distinguishable from every other outcome (purpose, branch, asserting identity, reason). Without the flag, behavior is unchanged (merge on no-status still exits 3).

The assertion requires elevated identity: honored only when the acting token holds admin permission on the target repository. A non-admin caller gets a distinct refusal (own error text, exit code that is not 3) so the audit trail separates "asserted by a non-admin" from "CI late". pr-merge.sh gains a pass-through flag that forwards it to the guard call.

Acceptance criteria

  1. merge + no-status + flag + admin token -> exit 0 with the assertion audit line; a JSONL audit record is written.
  2. merge + no-status without the flag -> exit 3, existing error text unchanged.
  3. merge + no-status + flag + non-admin token -> distinct refusal, exit code not 3.
  4. flag + --require-status -> usage error.
  5. flag has no effect when any status context exists (pending still holds, failure still fails).
  6. push + no-status behavior unchanged.
  7. pr-merge.sh --no-ci-expected forwards the flag to the guard; absence does not.
  8. All existing test-ci-queue-wait-* and test-pr-merge-* suites still pass.
## Defect `ci-queue-wait.sh --purpose merge` exits 3 `ASSERTED_NOT_READY state=no-status` on any repository whose commits carry zero status contexts, and `pr-merge.sh` runs the guard with `--purpose merge` before every merge. A repository with no CI configured at all therefore has no wrapper merge path. Push already has a queue-clear path for this case (a repo with no CI must remain pushable); merge deliberately stayed fail-closed there because at merge time `no-status` can also mean "CI has not reported yet". That leaves CI-less repos with approved PRs and no sanctioned merge, forcing the break-glass override for every such merge — which makes the override a gap, not an exception. ## Fix direction Add an explicit, audit-visible assertion: a `--no-ci-expected` flag on `ci-queue-wait.sh` that reclassifies the zero-context case for `--purpose merge` as queue-clear, with a printed line distinguishable from every other outcome (purpose, branch, asserting identity, reason). Without the flag, behavior is unchanged (merge on no-status still exits 3). The assertion requires elevated identity: honored only when the acting token holds admin permission on the target repository. A non-admin caller gets a distinct refusal (own error text, exit code that is not 3) so the audit trail separates "asserted by a non-admin" from "CI late". `pr-merge.sh` gains a pass-through flag that forwards it to the guard call. ## Acceptance criteria 1. merge + no-status + flag + admin token -> exit 0 with the assertion audit line; a JSONL audit record is written. 2. merge + no-status without the flag -> exit 3, existing error text unchanged. 3. merge + no-status + flag + non-admin token -> distinct refusal, exit code not 3. 4. flag + `--require-status` -> usage error. 5. flag has no effect when any status context exists (pending still holds, failure still fails). 6. push + no-status behavior unchanged. 7. `pr-merge.sh --no-ci-expected` forwards the flag to the guard; absence does not. 8. All existing `test-ci-queue-wait-*` and `test-pr-merge-*` suites still pass.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: mosaicstack/stack#1372