3.1 KiB
3.1 KiB
RI-1-002 — Publish-gate negative controls (SDLC-D-034 second half)
- Task: RI-1-002 (docs/release-integrity workstream, PRD item RI-N1), issue ref #1275
- Branch:
test/ri-050-publish-gate-negative(baseorigin/next@d8e0aec9= PR #1277, RI-1-001) - Budget: worker estimate ~45K tokens; keep scoped to the two test files + scratchpad.
Objective
Checked-in negative-control tests that PROVE the publish gate fails when it must:
- Broken mandatory check blocks every publish step (structural DAG proof from
.woodpecker/publish.yml). - Bypass shapes fail the checker: missing edge, hidden effect (non-
publishname), detached verify, always-pass verify (failure: ignore/successoverride), conditional verify (when). - Exact-commit identity: no HEAD-moving step between verify and publish effects; legitimate re-checkout requires verify to re-run after it.
verify-release.mjscomposition control: a SUBSET stage list fails the composition check.
Plan
- NEW
scripts/publish-gate-structure.test.mjs— self-contained structural checker (assertPublishGateBlocksOnVerify) + positive control on the real pipeline + one negative-control test per bypass shape (S1–S6, documented in file header) + positive control for the legitimate re-checkout shape. - EXTEND
scripts/verify-release.test.mjs— refactor the stage-mirror test body intoassertStagesMirrorCi(stages, ci); add negative control dropping each stage one at a time (subset must throw).
Conventions confirmed
- Root
test:checkout=node --test scripts/*.test.mjs→ new file auto-joinspnpm test. - Test-enumeration guard population is
*test*.shunderpackages/mosaic/framework/tools/only → unaffected. - Root eslint covers only
**/*.{ts,tsx}→ .mjs files need Prettier style only (printWidth 100, singleQuote, semi, trailingComma all). - Do NOT touch docs/TASKS.md, docs/release-integrity/TASKS.md, docs/scratchpads/.
Progress log
- Base verified: publish.yml
verifystep + verify-release.mjs present; HEAD contains origin/next. - Wrote scripts/publish-gate-structure.test.mjs
- Extended scripts/verify-release.test.mjs (mirror fn + subset negative control)
- Gates: node --test scripts (31 tests pass), prettier clean on touched files, pnpm typecheck PASS, pnpm lint PASS, pnpm format:check PASS
- Committed
ff585b88+ pushed, PR #1305 → next (no conflicts). Stopped before merge per task instruction.
Evidence
node --test scripts/verify-release.test.mjs scripts/publish-gate-structure.test.mjs→ 31 tests, 0 fail.- Mutation sanity: temporarily removing the
verifyedge from build-gateway in publish.yml → structure test goes red (verified manually during dev, then reverted). - Gates run from repo root on this worktree; results in Progress log.
Risks / notes
- Effect detection (
isPublishCommand) is deliberately over-broad (any npm/pnpm/yarn command mentioningpublish, any kaniko/docker-push/--destination) — fail-closed: a false positive forces justification, a false negative is the actual hazard. git fetchflagged as HEAD-moving even though fetch alone doesn't move HEAD — fail-closed on the classicfetch && resetpair.