fix(ci): make queue guard purpose-sensitive (#1148)
ci/woodpecker/push/publish Pipeline failed
ci/woodpecker/push/publish Pipeline failed
This commit was merged in pull request #1148.
This commit is contained in:
@@ -0,0 +1,33 @@
|
||||
# CI Queue Guard Purpose Semantics
|
||||
|
||||
- **Issue:** #1146
|
||||
- **Target branch:** `next`
|
||||
|
||||
## Problem
|
||||
|
||||
`ci-queue-wait.sh` treats any result other than terminal success as asserted non-readiness. That is correct for merge readiness, but incorrect for the pre-push queue guard: a terminal failure or an empty status set means no pipeline is queued or running, so the queue is clear.
|
||||
|
||||
## Design
|
||||
|
||||
Make final-state handling purpose-sensitive while preserving the existing provider and payload safeguards:
|
||||
|
||||
- `--purpose push`
|
||||
- wait while state is `pending`;
|
||||
- return success for `terminal-success`, `terminal-failure`, and `no-status`;
|
||||
- continue rejecting `malformed`, `unknown`, and unrecognized states.
|
||||
- `--purpose merge`
|
||||
- return success only for `terminal-success`;
|
||||
- continue rejecting `terminal-failure`, `no-status`, malformed, unknown, and unrecognized states.
|
||||
- `--require-status` remains authoritative: `no-status` fails for either purpose when it is supplied.
|
||||
|
||||
Diagnostics will explicitly distinguish a queue-clear push result from successful CI so callers cannot mistake an old failure for a green pipeline.
|
||||
|
||||
## Testing
|
||||
|
||||
Extend the process-level tri-state regression harness with separate push and merge assertions:
|
||||
|
||||
1. Push passes for terminal success, terminal failure, and no status.
|
||||
2. Push still fails for pending, malformed, and unknown states.
|
||||
3. `--require-status` makes push/no-status fail.
|
||||
4. Merge behavior remains fail-closed except for terminal success.
|
||||
5. Existing provider-unavailable audit behavior remains unchanged.
|
||||
@@ -0,0 +1,208 @@
|
||||
# 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=<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: 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
|
||||
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**
|
||||
|
||||
```bash
|
||||
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:
|
||||
|
||||
```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.
|
||||
Reference in New Issue
Block a user