Skip to content

Emit the canary map, and assert what the chain depends on - #185

Merged
patchstackdave merged 1 commit into
mainfrom
feat/canary-map-emitter
Aug 27, 2026
Merged

patchstackdave merged 1 commit into
mainfrom
feat/canary-map-emitter

Conversation

@patchstackdave

Copy link
Copy Markdown
Contributor

Produces the map artifact the platform vendors for the cross-repo canary — one vertical slice through the product claim for CVE-2017-5941 (node-serialize's unserialize executes an embedded function expression, so a request body reaching it is remote code execution).

Public CVE, so the app, the rule and the request controls can all live in the open; the review rationale and detector recipe stay private in hub.

Why this belongs here

The platform commits the map and grades it into a verdict and a rule, which makes the map an artifact of this package. The ladder maps established the pattern and its one weakness, in their own README:

It does not stop these fixtures drifting from the extractor; nothing here can, because no job in this repository runs the extractor.

So this adds the two things that help:

  • An emitter, run like the ladder one:
    PS_CANARY_EMIT_DIR=/path/to/back/tests/Fixtures/Canary npx vitest run tests/map/canary-emit
    
  • A provenance file naming the commit that produced the artifact. The ladder maps carry that as a hand-maintained README line, which is only as fresh as whoever last remembered.

The platform's integration job then regenerates from this emitter and compares bytes, which turns that documented gap into an actual check.

The assertions do not skip

They run on every suite run, not only when emitting. A change to the app or the extractor that would invalidate a vendored copy fails here, with a message about the map — rather than three repositories away, as a rule that quietly stopped being generated.

Pinned: the endpoint, the coordinate (post.state), the sink (eval/node-serialize/unserialize), and the flow's tier, role, family and generatability. Plus that recognizedSinkKinds is non-empty — an empty list means "no model of this API", and the recipe's gate is dataflow, so an empty list would silently turn the whole canary into a needs-review case.

The app is minimal on purpose

A wrapper, a validation step or a rename would move the flow off exact-local — the one auto-promotable tier — and the canary would then be proving that a review-grade flow generates a rule. That is a different and weaker claim than the one it advertises.

canary-case.ts holds the app as data because two things consume it and must not drift: these assertions and the emitter, generated from one definition.

Full suite: 1665 passed, 7 skipped.

🤖 Generated with Claude Code

The cross-repo canary is one vertical slice through the whole product claim — a reviewed recipe in hub, a
verdict and generated rule in the platform, and this engine blocking the exploit — proved as a chain
rather than as three sets of green unit tests. CVE-2017-5941 is the slice: `node-serialize`'s
`unserialize` executes an embedded function expression, so a request body reaching it is remote code
execution, and it is public, so the app, the rule and the requests can all live in the open while the
review rationale and detector recipe stay private in hub.

The platform vendors the map, which makes the map an artifact of this package. The ladder fixtures
established the pattern and its one weakness: nothing downstream can detect a fixture going stale,
because no job over there runs this extractor. So this adds the two things that help.

An emitter, run the same way as the ladder one:

  PS_CANARY_EMIT_DIR=/path/to/back/tests/Fixtures/Canary npx vitest run tests/map/canary-emit

and a provenance file naming the commit that produced the artifact — the ladder maps carry that as a
hand-maintained line in a README, which is only as fresh as whoever last remembered.

The assertions do NOT skip when the emit directory is absent. They run on every suite run, so a change to
the app or the extractor that would invalidate a vendored copy fails HERE, with a message about the map,
rather than three repositories away as a rule that quietly stopped being generated. They pin the endpoint,
the coordinate, the sink, and the flow's tier, role, family and generatability — plus that
`recognizedSinkKinds` is non-empty, since an empty list means "no model of this API" and the recipe's gate
is `dataflow`, which would make the whole canary a needs-review case.

The app is the simplest one that carries the vulnerability, and that is load-bearing rather than lazy: a
wrapper, a validation step or a rename would move the flow off `exact-local`, and the canary would then be
proving that a review-grade flow generates a rule — a different and weaker claim.

`canary-case.ts` holds the app as data because two things consume it and must not drift: the assertions
here and the emitter, generated from one definition.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@coderbuds

coderbuds Bot commented Aug 27, 2026

Copy link
Copy Markdown

Well-structured, thorough canary tests with detailed documentation and clear assertions.

🎯 Quality: 100% Elite · 📦 Size: Medium

📈 This month: Your 144th PR — above team average · Averaging Excellent

See how your team is trending →

@patchstackdave

Copy link
Copy Markdown
Contributor Author

/review

@patchstackdave
patchstackdave merged commit ed99ca5 into main Aug 27, 2026
6 checks passed
@patchstackdave
patchstackdave deleted the feat/canary-map-emitter branch August 27, 2026 08:35
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.

2 participants