Repository navigation
TEST-001A2 — Reject sensitive emitted test artifacts and require the scrubber gate #177
Description
Outcome
Add a dependency-free, read-only, fail-closed validator for emitted test artifacts, make it a named hosted CI gate, and require that exact gate in both protected-release job checks.
This child completes only TEST-001A2. It does not expand the runtime/provider safety boundary delivered by #175.
Why this is needed
Tests can pass while a report, log, snapshot, or coverage file contains a credential, capability URL, or personal data. Current CI uploads no test artifacts, but later TEST-001B–E work may add reports. We need a narrow validator before any report becomes acceptable for upload or release evidence.
This is separate from the existing generic source secret scan. It scans only explicit emitted-test-output roots.
Dependencies
- TEST-001A1 — Add the fail-closed synthetic provider test harness #175 / TEST-001A1 merged as
e6d8929698b95ddcda78b00108cc7665bf9f5e01. - CI-001B2 — Make releases protected, backend-first, and fail-closed #135 protected-release source validation is merged.
- No provider, production-data, legal, or owner-console decision is required.
Safety invariants
- The scanner is read-only and uses Node built-ins only.
- Callers must name one or more narrow artifact roots. Missing, source-root, repository-root, parent, or otherwise broad roots fail closed.
- Traversal is deterministic and bounded by file count, byte size, and directory depth.
- Symlinks, path escapes, unreadable entries, binary files, archives, and unsupported types fail closed.
- Only regular UTF-8 text, JSON, JSONL, XML, TAP, and LCOV-style output is accepted.
- Failures use fixed rule IDs and exit codes. They never echo matched bytes, hostile values, or secret-bearing filenames.
- Reject recognizable credentials/capabilities and non-reserved personal data, including bearer/cookie/auth material, JWT/private-key shapes, Stripe/cloud/provider keys, sensitive query/fragment URLs, known production Firebase/project authority, non-reserved email/phone values, and sensitive identity fields.
- Allow reserved
.testidentities, RFC example data, demo-only project IDs, loopback endpoints, explicit redaction markers, counts, digests, and correlation IDs. - The CI job must be named exactly
Test artifact scrubber, must be unskippable, and must not usecontinue-on-error. - Both protected-release required-job loops must require the exact successful scrubber job.
- Later report-producing issues must invoke this validator before upload. This issue uploads nothing and does not claim existing reports were sanitized.
- No source file, website build, runtime log, provider response, or production data is scanned by this child.
Exact owned paths
- New:
.github/scripts/scan-test-artifacts.mjs - New:
tests/test-artifact-safety.test.js .github/workflows/ci.yml— add one exact named Node 20 job and the minimum static-workflow validation..github/workflows/deploy.yml— add only the exact job name to both existing required-job loops.- Minimum status/evidence hunks in:
SECURITY.mdGITHUB_ISSUES.mdGITHUB_ISSUE_SLICES.mdOPERATIONS_RUNBOOK.md
- Officer checklist wording only:
OFFICER_START_HERE.mddocs/officers/PUBLISH_AND_CHECK.md
Everything else is immutable. In particular: no package/lockfile, application runtime, Functions runtime, Firestore Rules, Firebase config, public asset, production provider, branch-protection, upload-artifact, or deployment-target change.
Required tests
The test suite must create bounded temporary artifact roots and prove:
- Safe nested synthetic reports pass.
- A source canary outside the explicit root is ignored.
- Each forbidden category is assembled dynamically in temporary output and fails.
- Errors do not contain the canary value or secret-bearing filename.
- JSON-escaped, mixed-case, and URL-encoded variants fail.
- Missing/broad roots, symlinks, path escapes, binary/archive/unsupported files, unreadable input, oversize input, excessive depth, and excess-file input fail.
- Traversal order and repeat runs are deterministic.
- Workflow mutations fail when the scrubber job is missing, renamed, skipped, allowed to fail, swallowed, runs the wrong test, exposes secret-bearing job input, or is absent from either protected-release loop.
- Static workflow validation proves current CI has no unscanned test-artifact upload path.
Verification
Run with Node 20:
- Focused scanner and workflow-mutation tests.
- Existing protected-release workflow tests.
- Frontend Jest and SPA callback suites.
- Functions lint/unit suite.
- Auth/Firestore and commerce-journal emulator suites where relevant.
- Firestore Rules suite.
- Diagnostic frontend build.
- Diff, changed-path, relative-link, and sensitive-literal checks.
Obtain two independent exact-snapshot reviews before merge.
Officer continuity
Officer impact: Release approvers will see one additional required green check named Test artifact scrubber. Member and website behavior do not change.
Officer documentation: Update OFFICER_START_HERE.md and docs/officers/PUBLISH_AND_CHECK.md in the same PR. Use plain language: the check proves the deliberate synthetic test-output scan ran; it does not prove production publication, Firebase deployment, provider configuration, or that an artifact was uploaded.
Approver: A repository maintainer may approve the source merge after exact hosted checks and independent review. A production release remains a separate approval.
Undo: Revert the exact merge only after confirming no later workflow/report producer depends on the job name. Never bypass the check to make a release pass.
Escalation: Stop and open a security incident if any real credential, member data, or private capability appears in output. Do not copy it into an issue, screenshot, email, or AI tool.
Deployment truth required at closure
Record separately:
- source changed
- local tests passed
- code merged
- hosted CI gate passed
- protected-release validation passed
- website publication state
runmprc.comverification state- Firebase deployment state
- provider configuration/contact state
- production behavior verification state
A green scrubber gate alone proves none of the last five states.
Definition of done
Implementation, deliberate positive/negative tests, workflow mutation protection, existing-suite compatibility, two independent reviews, officer checklists, exact hosted evidence, merge/closure evidence, and explicit release of every claimed path are complete.
Activity
daliu commentedon Jul 13, 2026
CLAIMED — 2026-07-13T19:54:17Z
/rootcodex/issue-177-test-artifact-scrubber/Users/daveliu/Code/Run-MPRC.test-001a2e6d8929698b95ddcda78b00108cc7665bf9f5e01Do not edit these exact files/hunks until a timestamped release is posted here.
daliu commentedon Jul 13, 2026
EXTRACTION FINISHED — 2026-07-13T20:53:45Z
/rootcodex/issue-177-test-artifact-scrubber88b45e0c71d08ff628223358e5d9d0392969f4e36017493f3366790eefba5d00baf3df7211dfc380(DATA-001C1 — Pause optional My Account phone collection during privacy review #178 preserved; no owned-path overlap)This is source/test extraction evidence only. No website publication,
runmprc.comcheck, Firebase deployment, provider configuration, artifact upload, or production behavior is claimed. The claim remains active through PR merge/closure.daliu commentedon Jul 13, 2026
COMPLETE / CLAIM RELEASED — 2026-07-13T20:59:02Z
88b45e0c71d08ff628223358e5d9d0392969f4e3main:97ec6eeccc99e27d00ca271a0c874cbba9f36420Test artifact scrubberpassed in 13 seconds.6017493f3366790eefba5d00baf3df7211dfc380before PR publication.Deployment truth: source changed, tests passed, code merged, and the named hosted gate passed. No website publication or
runmprc.comverification was needed or performed. No Firebase deployment, provider configuration/contact, test-artifact upload, or production behavior test occurred.The timestamped claim on all ten #177 paths is released. Later report-producing work may depend on the exact
Test artifact scrubberjob name and must scan its explicit output before upload.