diff --git a/docs/plans/2026-08-10-ci-queue-purpose-implementation.md b/docs/plans/2026-08-10-ci-queue-purpose-implementation.md new file mode 100644 index 00000000..894b7b72 --- /dev/null +++ b/docs/plans/2026-08-10-ci-queue-purpose-implementation.md @@ -0,0 +1,176 @@ +# 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 +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** + +```bash +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: + +```text +[ci-queue-wait] queue-clear state=no-status purpose=push 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 +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** + +```bash +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 +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** + +```bash +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: + +```bash +git add docs/scratchpads/1146-ci-queue-purpose.md +git commit -m "docs(ci): record queue guard verification" +``` + +### Task 4: 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: + +```bash +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** + +```bash +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** + +```bash +~/.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`** + +```bash +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.