Files
stack/docs/plans/2026-08-10-ci-queue-purpose-implementation.md
T
veronica 12d5258e20 docs(W4): apply fred's six contract decisions from PR #1350 comment 23693
A - docs/README.md:149-190 rewritten. It prescribed a competing front-matter schema
    (title/type/audience/status/source_of_truth) adopted by 4 of 128 live documents. Two
    documented conventions in one repo is the defect this pass removes, so the README now
    documents the contract and the 4 files convert in the same commit: `type` dropped
    (kind replaces it), `title`/`audience`/`source_of_truth` kept.
B - source-of-truth leaves the kind enum, which is now 6 values, and returns as an orthogonal
    boolean. kind was carrying two independent facts. docs/requirements/native-kanban-sot.md
    is stamped `kind: spec` + `source_of_truth: true`, which is what it always was.
C - status gains `completed`. Applied to the two executed plans, on artifact evidence rather
    than on their own say-so: --purpose push|merge ships in ci-queue-wait.sh, and every section
    the README plan specifies exists in docs/README.md today.
D - kind follows content, never filename. docs/native-kanban-sot/TASKS.md is `kind: spec`
    because its body says "a build plan, not a task tracker". The name stays wrong; that is a
    rename and it is out of scope here.
E - the contract covers .md only, written into the README as a decision with vision's
    YAML.parse measurement as the reason, so the omission does not read as an oversight.
F - channel-protocol.md guide -> spec. Applied, with a correction the reviewer should see: the
    ruling cites "7 normative MUSTs" and there are ZERO uppercase RFC2119 terms in that file.
    Control: the identical grep returns 25 lines in docs/requirements/native-kanban-sot.md. The
    citation half of the finding does hold and is larger than stated. Consequence recorded in
    the worklist: the file's own banner now contradicts its header.

Verified: 128 live .md under docs/ (127 baseline + this PR's worklist), 107 stamped, 0 invalid
kinds, 17 operator-held + 3 supersede-stamp deferrals + 1 generated = 21 unstamped. 107+21=128.
Control: the verifier reports valid=False when a kind is corrupted to `nonsense`, so the
0-invalid result is a real result. prettier --check clean across docs/.
2026-08-20 19:58:17 -05:00

6.8 KiB

kind, status
kind status
spec completed

CI Queue Guard Purpose Semantics Implementation Plan

For Claude: REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.

Goal: Make the pre-push CI queue guard pass when no pipeline is queued or running while preserving fail-closed merge readiness.

Architecture: Keep provider lookup and tri-state classification unchanged. Make only the final state dispatch purpose-sensitive: push treats valid non-pending states as queue-clear, while merge continues to require terminal success. Preserve --require-status, malformed-payload rejection, unknown-state rejection, and audited provider-unavailable behavior.

Tech Stack: Bash, process-level shell regression harnesses, Gitea/GitHub status APIs.


Task 1: Freeze Purpose-Specific State Semantics

Files:

  • Modify: packages/mosaic/framework/tools/git/test-ci-queue-wait-tristate.sh
  • Test: packages/mosaic/framework/tools/git/test-ci-queue-wait-tristate.sh

Step 1: Add failing push assertions

Change push expectations so terminal-failure and no-status require exit 0 plus an explicit queue-clear diagnostic. Add a --require-status assertion that keeps push/no-status non-zero.

Step 2: Add failing merge assertions

Invoke the same harness with MOSAIC_TEST_PURPOSE=merge and assert terminal failure and no status remain non-zero while terminal success remains zero.

Step 3: Add unknown-state coverage

Add a stub payload with a syntactically valid but unsupported status value and assert both purposes reject it.

Step 4: Run the focused test and verify RED

Run:

bash packages/mosaic/framework/tools/git/test-ci-queue-wait-tristate.sh

Expected: failures showing push terminal-failure and no-status returned exit 3 instead of exit 0 or lacked queue-clear diagnostics.

Step 5: Commit the failing tests

git add packages/mosaic/framework/tools/git/test-ci-queue-wait-tristate.sh
git commit -m "test(ci): define purpose-aware queue readiness"

Task 2: Implement Purpose-Sensitive Final-State Dispatch

Files:

  • Modify: packages/mosaic/framework/tools/git/ci-queue-wait.sh:458-481
  • Test: packages/mosaic/framework/tools/git/test-ci-queue-wait-tristate.sh
  • Test: packages/mosaic/framework/tools/git/test-ci-queue-wait-github-checks.sh

Step 1: Implement push queue-clear behavior

For no-status, retain the existing --require-status failure. Otherwise, return success for push with an explicit diagnostic such as:

[ci-queue-wait] queue-clear state=no-status purpose=push branch=<branch>; no queued or running CI.

For terminal-failure, return success only for push with the same queue-clear wording. Merge must continue returning asserted non-readiness.

Step 2: Preserve malformed and unknown rejection

Keep malformed, unknown, and unrecognized states non-zero for both purposes.

Step 3: Run focused tests and verify GREEN

Run:

bash packages/mosaic/framework/tools/git/test-ci-queue-wait-tristate.sh
bash packages/mosaic/framework/tools/git/test-ci-queue-wait-github-checks.sh

Expected: both scripts exit 0 and report their regression suites passed.

Step 4: Commit implementation

git add packages/mosaic/framework/tools/git/ci-queue-wait.sh
git commit -m "fix(ci): separate push queue clearance from merge readiness"

Task 3: Verify, Review, and Document Evidence

Files:

  • Modify: docs/scratchpads/1146-ci-queue-purpose.md

Step 1: Run shell syntax and focused regressions

bash -n packages/mosaic/framework/tools/git/ci-queue-wait.sh
bash -n packages/mosaic/framework/tools/git/test-ci-queue-wait-tristate.sh
bash packages/mosaic/framework/tools/git/test-ci-queue-wait-tristate.sh
bash packages/mosaic/framework/tools/git/test-ci-queue-wait-github-checks.sh

Step 2: Run repository quality gates

pnpm preflight
pnpm typecheck
pnpm lint
pnpm test
pnpm format:check

Expected: every command exits 0.

Step 3: Obtain independent review

Request review of the exact branch head. Remediate all blocking findings and rerun focused and baseline gates.

Step 4: Record evidence and commit

Update the scratchpad with test output, review result, and residual risk, then commit it:

git add docs/scratchpads/1146-ci-queue-purpose.md
git commit -m "docs(ci): record queue guard verification"

Task 4: Keep the Merge Wrapper Aligned with the next Lane

Files:

  • Modify: packages/mosaic/framework/tools/git/pr-merge.sh:97-101
  • Test: packages/mosaic/framework/tools/git/test-pr-merge-head-pin.sh

Step 1: Write the failing regression

Run the exact-head merge regression with its Gitea fixture targeting next and confirm the current wrapper rejects it because it only permits main.

Step 2: Allow only documented integration targets

Permit main and next; reject every other target. Do not alter exact-head pinning, queue-guard invocation, provider selection, or merge method enforcement.

Step 3: Run focused merge regressions

bash packages/mosaic/framework/tools/git/test-pr-merge-head-pin.sh
bash packages/mosaic/framework/tools/git/test-pr-merge-queue-branch.sh
bash packages/mosaic/framework/tools/git/test-pr-merge-gitea-empty-uid.sh

Expected: all pass, including a Gitea merge fixture targeting next.

Step 4: Commit

git add packages/mosaic/framework/tools/git/pr-merge.sh packages/mosaic/framework/tools/git/test-pr-merge-head-pin.sh
git commit -m "fix(ci): allow reviewed merges into next"

Task 5: Activate and Deliver Through next

Files:

  • Installed output: ~/.config/mosaic/tools/git/ci-queue-wait.sh

Step 1: Activate through the canonical installer

From the reviewed worktree, run the framework installer in sync-only keep mode so operator files remain protected:

MOSAIC_SYNC_ONLY=1 MOSAIC_INSTALL_MODE=keep MOSAIC_SKIP_SKILLS_SYNC=1 \
  bash packages/mosaic/framework/install.sh

Step 2: Verify installed/source parity

cmp -s \
  packages/mosaic/framework/tools/git/ci-queue-wait.sh \
  ~/.config/mosaic/tools/git/ci-queue-wait.sh

Expected: exit 0.

Step 3: Run mandatory pre-push queue guard

~/.config/mosaic/tools/git/ci-queue-wait.sh --purpose push -B fix/1146-ci-queue-purpose

Expected: branch-absent or queue-clear success.

Step 4: Push and open a PR against next

git push -u origin fix/1146-ci-queue-purpose
~/.config/mosaic/tools/git/pr-create.sh \
  -t "fix(ci): make queue guard purpose-sensitive" \
  -b "Closes #1146" \
  -B next \
  -H fix/1146-ci-queue-purpose \
  -i 1146

Step 5: Complete reviewed integration

Wait for exact-head terminal-green CI, obtain the required review, merge via the Mosaic wrapper, verify merged CI, and close #1146. Do not bypass any gate.