Skip to content

TEST-001A2 — Reject sensitive emitted test artifacts and require the scrubber gate #177

Closed

Description

@daliu

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

Safety invariants

  1. The scanner is read-only and uses Node built-ins only.
  2. Callers must name one or more narrow artifact roots. Missing, source-root, repository-root, parent, or otherwise broad roots fail closed.
  3. Traversal is deterministic and bounded by file count, byte size, and directory depth.
  4. Symlinks, path escapes, unreadable entries, binary files, archives, and unsupported types fail closed.
  5. Only regular UTF-8 text, JSON, JSONL, XML, TAP, and LCOV-style output is accepted.
  6. Failures use fixed rule IDs and exit codes. They never echo matched bytes, hostile values, or secret-bearing filenames.
  7. 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.
  8. Allow reserved .test identities, RFC example data, demo-only project IDs, loopback endpoints, explicit redaction markers, counts, digests, and correlation IDs.
  9. The CI job must be named exactly Test artifact scrubber, must be unskippable, and must not use continue-on-error.
  10. Both protected-release required-job loops must require the exact successful scrubber job.
  11. Later report-producing issues must invoke this validator before upload. This issue uploads nothing and does not claim existing reports were sanitized.
  12. 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.md
    • GITHUB_ISSUES.md
    • GITHUB_ISSUE_SLICES.md
    • OPERATIONS_RUNBOOK.md
  • Officer checklist wording only:
    • OFFICER_START_HERE.md
    • docs/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.com verification 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

  1. self-assigned this
    on Jul 13, 2026
  2. added
    priority:P0Launch blocker or urgent security risk
    type:securitySecurity or privacy boundary
    area:ciContinuous integration and deployment
    size:MMedium multi-file issue
    status:readyDependencies complete and ready to claim
    type:testingTest infrastructure and quality gates
    status:in-progressClaimed and actively being implemented
    and removed
    status:readyDependencies complete and ready to claim
    on Jul 13, 2026
  3. daliu commented on Jul 13, 2026

    @daliu
    ContributorAuthor

    CLAIMED — 2026-07-13T19:54:17Z

    • Owner: /root
    • Branch: codex/issue-177-test-artifact-scrubber
    • Isolated worktree: /Users/daveliu/Code/Run-MPRC.test-001a2
    • Exact base: e6d8929698b95ddcda78b00108cc7665bf9f5e01
    • Dependency proof: TEST-001A1 — Add the fail-closed synthetic provider test harness #175 is closed/merged; its eight-path claim is released. CI-001B2 — Make releases protected, backend-first, and fail-closed #135 is merged.
    • Claimed paths: the exact ten paths listed in this issue. No package/lockfile, runtime, Rules, Firebase, public asset, provider, branch-setting, or deployment-target path.
    • Invariant: read-only explicit artifact roots; bounded deterministic scanning; fixed redacted failures; one exact unskippable CI job required by both protected-release loops.
    • Delivery order: demonstrate failures, implement the minimum scanner/workflow gate, run focused/full checks, obtain two independent exact-snapshot reviews, then publish one PR.

    Do not edit these exact files/hunks until a timestamped release is posted here.

  4. daliu commented on Jul 13, 2026

    @daliu
    ContributorAuthor

    EXTRACTION FINISHED — 2026-07-13T20:53:45Z

    • Owner: /root
    • Branch: codex/issue-177-test-artifact-scrubber
    • Exact source commit: 88b45e0c71d08ff628223358e5d9d0392969f4e3
    • Exact base: 6017493f3366790eefba5d00baf3df7211dfc380 (DATA-001C1 — Pause optional My Account phone collection during privacy review #178 preserved; no owned-path overlap)
    • Changed paths: exactly the ten paths claimed in this issue.
    • Focused/combined Node 20 proof: 22/22 focused groups and 38/38 combined workflow groups.
    • Full compatibility proof: frontend 134/134; SPA 10/10; Functions 931/931 unit and 932/932 emulator; Rules 311/311; commerce journal 25/25; Functions lint and diagnostic build passed.
    • Independent reviews: exact frozen snapshot approved twice; the security matrix passed 61/61.
    • Link/scope proof: 16/16 relative links resolved; diff checks clean; no private Google Doc URL or complete live-credential/private-key fixture literal.

    This is source/test extraction evidence only. No website publication, runmprc.com check, Firebase deployment, provider configuration, artifact upload, or production behavior is claimed. The claim remains active through PR merge/closure.

  5. daliu commented on Jul 13, 2026

    @daliu
    ContributorAuthor

    COMPLETE / CLAIM RELEASED — 2026-07-13T20:59:02Z

    Deployment truth: source changed, tests passed, code merged, and the named hosted gate passed. No website publication or runmprc.com verification 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 scrubber job name and must scan its explicit output before upload.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

area:ciContinuous integration and deploymentpriority:P0Launch blocker or urgent security risksize:MMedium multi-file issuetype:securitySecurity or privacy boundarytype:testingTest infrastructure and quality gates

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions