Skip to content

fix(ci): make fixture-detection checks hermetic (unblock v0.8.10 npm publish) - #187

Merged
Rome-1 merged 1 commit into
mainfrom
fix/release-integrity-fixture-detection
Jun 28, 2026
Merged

fix(ci): make fixture-detection checks hermetic (unblock v0.8.10 npm publish)#187
Rome-1 merged 1 commit into
mainfrom
fix/release-integrity-fixture-detection

Conversation

@Rome-1

@Rome-1 Rome-1 commented Jun 28, 2026

Copy link
Copy Markdown
Collaborator

Problem

The v0.8.10 publish failed (run 28332931747). publish-python succeeded (PyPI → 0.8.10) but test-node failed at github-action.test.ts "CLI detects secrets in fixture file" (exit 0, expected 1), which gated publish-node. Result: npm is stuck at 0.8.9 while PyPI shipped 0.8.10 — dual-implementation version parity is broken on the registries.

Root cause

PR #184 added a repo-root .rafter.yml that declassifies **/fixtures/** and .github/fixtures/** as triaged false positives for the dogfooding security gate. Six checks scan .github/fixtures expecting detection, but policy discovery walks cwd → git root, finds .rafter.yml, and suppresses the finding → exit 0:

  1. node/tests/github-action.test.ts"CLI detects secrets in fixture file" (the confirmed failure)
  2. publish.yamlsmoke-test-node detection step (would fail; was skipped)
  3. publish.yamlsmoke-test-python detection step (would fail; was skipped)
    4–6. test-action.ymldetect-secrets / pip-install / published-v1 jobs (dormant — the path filter didn't fire on security: remediate Rafter scan (deps + FP triage + tarball hardening) [sable-qsig] #184's root-file change)

Fix

Keep .rafter.yml exactly as the #184 (backend-verified) security review set it. Instead make the detection checks hermetic — they verify the detection engine, which must be decoupled from the repo's own self-scan policy:

  • Unit + smoke tests: copy the fixture to a mktemp -d dir outside the repo and scan there (no .rafter.yml above it).
  • Action jobs: stage the fixture at a neutral /tmp path the policy globs don't match.

The fixture's bytes are copied verbatim, so the engine scans identical content; only the repo's self-scan policy is excluded. github-action.test.ts:556 still guards the in-repo fixture content via fs. Verified locally: isolation restores exit 1 for node file/dir scans + the python file scan; github-action.test.ts 81/81.

Release impact

Version stays 0.8.10: twine upload --skip-existing no-ops the existing PyPI upload, npm publish ships 0.8.10 fresh, and create-release cuts the v0.8.10 tag. After this lands on main, a main → prod merge re-triggers publish.yaml to bring npm to parity.

Review

  • rafter-code-review walkthrough (CWE-78/CWE-22 on the added CI bash): clean — variables quoted, mktemp paths, no Actions-expression injection; tests still genuinely assert detection (not vacuous). Remote rafter run not executable here (no RAFTER_API_KEY); diff is CI/test-only with no product-code surface.

Bead: sable-nfjq

🤖 Generated with Claude Code

….yml can't suppress them

The v0.8.10 publish (run 28332931747) failed at github-action.test.ts
"CLI detects secrets in fixture file" (exit 0, expected 1), which gated
publish-node — leaving npm at 0.8.9 while PyPI shipped 0.8.10, breaking
dual-implementation version parity on the registries.

Root cause: PR #184 added a repo-root .rafter.yml that declassifies
**/fixtures/** and .github/fixtures/** as triaged false positives for the
dogfooding security gate. Six checks scan .github/fixtures expecting
detection, but policy discovery walks cwd -> git root, finds .rafter.yml,
and suppresses the finding:
  - node/tests/github-action.test.ts "CLI detects secrets in fixture file"
  - publish.yaml smoke-test-node / smoke-test-python detection steps
  - test-action.yml detect-secrets / pip-install / published-v1 jobs
    (dormant — the path filter didn't fire on #184's root-file change)

Fix: keep .rafter.yml exactly as the #184 backend-verified security review
set it. Instead, make the detection checks hermetic — copy the fixture to a
temp dir outside the repo (smoke/unit tests) or a neutral /tmp path the
policy globs don't match (action jobs) so no .rafter.yml is discovered.
These checks verify the detection ENGINE and must be decoupled from the
repo's own self-scan policy. Verified locally: isolation restores exit 1 for
node file/dir scans and the python file scan; github-action.test.ts 81/81.

Version stays 0.8.10: twine --skip-existing no-ops the existing PyPI upload,
npm publishes 0.8.10 fresh, and create-release cuts the v0.8.10 tag.

Bead: sable-nfjq

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@Rome-1
Rome-1 merged commit 3e4f2cb into main Jun 28, 2026
8 checks passed
@Rome-1
Rome-1 deleted the fix/release-integrity-fixture-detection branch June 28, 2026 19:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant