fix: preserve redacted artifact integrity - #2341
Merged
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
state-transition-ledgertyped artifact containingstate-lossandauthorization-bypassRoot Causes
wordpress.browser-actionsscreenshot steps wrote PNGs underfiles/browser/, but older browser action results did not expose those paths throughBrowserArtifact.files.screenshots, so final manifest assembly could not include them and strict orphan detection rejected the bundle. Main already contains the production registration fix froma6067fca(fix: manifest all browser screenshots); this PR adds strict end-to-end coverage proving every named screenshot is manifested exactly once.typed-artifacts/index.jsonpassed through text-orientedredactString(). Its assignment heuristic could interpret values such asstate-transition-ledgeras secret assignments and replace the following comma, changing valid JSON like\"name\": \"state-transition-ledger\",into malformed\"name\": \"state-transition-ledger\"[redacted]. Typed payload refs were also hashed before that later capture-time mutation, leaving embedded hashes pointed at pre-redaction bytes.Redaction And Digest Ordering
JSON capture now parses the document, redacts by key/value policy, and serializes valid JSON instead of applying assignment regexes to serialized syntax. Typed JSON bytes are structurally redacted before
materializeStructuredArtifactFiles()computes payload hashes and builds the typed index; capture then hashes the final persisted bytes.Before:
{ "name": "state-transition-ledger"[redacted] "type": "fixture/state-transition-ledger/v1" }After:
{ "name": "state-transition-ledger", "type": "fixture/state-transition-ledger/v1", "payload": { "oracleIds": ["state-loss", "authorization-bypass"], "authorization": "[redacted]", "api_token": "[redacted]" } }Secret Safety
The strict integration fixture includes an authorization value and an OpenAI-shaped token. It asserts both are redacted, the token is absent from payload and index bytes, oracle IDs remain exact, the typed payload SHA-256 equals the index reference, both screenshots occur once in
manifest.json, and strict verification returns no violations.Verification
npm run test:artifact-redaction-integritynpm run test:browser-artifact-sessionnpm run test:redactionnpx tsx tests/structured-artifact-materializer.test.tsnpx tsx scripts/artifact-bundle-verifier-smoke.tsnpx tsx scripts/artifact-redaction-smoke.tsnpx tsx scripts/typed-artifacts-smoke.tsnpx tsx tests/adversarial-campaign.test.ts(11 passed)npx tsx tests/recipe-browser-evidence.test.tsnpm run test:browser-actions-environment(10 passed)npm run test:browser-transport-faults(5 passed)npm run build:releasenpm run smoke -- --group=package(passed; Docker-only MySQL E2E skipped because Docker is unavailable)npm run test:release-package-coveragenpm run test:cli-build-freshness(7 passed)The broader artifact smoke group reaches two unrelated existing failures: patch-path expectation #2064 and executable browser DTO fixture #2340. All artifact smoke commands relevant to this change pass.
Consumer Relation
Studio PR #184 remains a valid consumer mitigation for WP Codebox 0.23.3: it removed explicit named screenshot steps and collected ledgers as parsed declared artifacts while keeping strict verification enabled. This PR fixes the typed JSON redaction/hash ordering underneath that mitigation and locks in the already-landed named screenshot registration so consumers can safely restore the original shape.
Closes #2339