Skip to content

Add the §2 eval gate, on green, and prove it can fail - #8

Merged
MichalAFerber merged 1 commit into
mainfrom
shawn/s2-no-eval
Sep 7, 2026
Merged

MichalAFerber merged 1 commit into
mainfrom
shawn/s2-no-eval

Conversation

@MichalAFerber

Copy link
Copy Markdown
Member

DS §2 says built output MUST be free of runtime code generation, and that scripts/no-eval.sh MUST run in CI against it. This repo shipped neither the script nor the step.

Estate context: 11 Node repos ship a build script and 7 already run this scan. This is the last of the 4 that did not. Tracked in MichalAFerber/tgwab-standards#173.

Measured, not inherited

The two repos already gated under #173 are LAN Astro sites. Nothing about their result carries here — inheriting a scan result across repos is precisely the failure that issue was filed against. Built from origin/main (c7f4561):

step result
npm ci (prepare runs the build) → lint → test all exit 0
dist 1 file — markdownwizard-tools.iife.js, 46,037 bytes
./scripts/no-eval.sh dist eval-free: OK (dist) — exit 0

Proved able to fail

::error::runtime code-generation found in dist (CSP has no 'unsafe-eval')
dist/__ctl__/x.js:1:const f = new Function("a","return a"); eval("1");
exit 1

Removing the planted file returns the run to green. The gate goes on green because nothing eval-shaped reaches the bundle, not because the scan is lenient.

Scope — and this one is specific to a published package

Worth reading before treating a green check here as full coverage:

  • The files list ships both src and dist.
  • The default export is "." : "./src/index.js".

So a consumer writing import … from 'markdownwizard-tools' gets the source; only the ./iife subpath resolves to what this scan covers. no-eval.sh dist does not cover the path most consumers use.

Nothing is hiding there — src/ scans clean today, all 8 files, exit 0. But whether §2's target should widen for a package whose default export is source is a standards question, and this repo should not answer it by quietly editing its own step. Raised in MichalAFerber/tgwab-standards#173. If the ruling is to widen, dist src is a one-word change and is green today.

Placement

No subtlety: prepare is the build, so npm ci produces dist and the scan has the bundle to read from that point on. It sits after test to keep the §15 gates contiguous.

Refs MichalAFerber/tgwab-standards#173

🤖 Generated with Claude Code

https://claude.ai/code/session_016beCydw4C9VrgL9eHzGUG2

DS §2 says built output MUST be free of runtime code generation and that
`scripts/no-eval.sh` MUST run in CI against it. This repo shipped neither the
script nor the step, so the rule had no instrument here.

Estate context: 11 Node repos ship a `build` script and 7 already run this
scan. This is the last of the 4 that did not (tgwab-standards#173).

MEASURED, NOT INHERITED. The two repos already gated under #173 are LAN Astro
sites and nothing about their result carries here — inheriting a scan result
across repos is the failure that issue was filed against. Built from
origin/main (c7f4561) and scanned:

    npm ci (prepare runs the build) -> lint (0) -> test (0)
    dist: 1 file, markdownwizard-tools.iife.js, 46,037 bytes
    ./scripts/no-eval.sh dist       eval-free: OK       exit 0

AND PROVED ABLE TO FAIL. Planting one file in dist:

    ::error::runtime code-generation found in dist (CSP has no 'unsafe-eval')
    dist/__ctl__/x.js:1:const f = new Function("a","return a"); eval("1");
                                                                    exit 1

Removing it returns the run to green. So the gate goes on green because
nothing eval-shaped reaches the bundle, not because the scan is lenient.

SCOPE, STATED SO A GREEN RUN IS NOT READ AS MORE THAN IT IS — and this one is
specific to a published package rather than a site. The `files` list ships
BOTH `src` and `dist`, and the default export is `"." : "./src/index.js"`, so
a consumer writing `import … from 'markdownwizard-tools'` gets the SOURCE.
Only the `./iife` subpath resolves to what this scan covers.

Nothing is hiding there: src/ scans clean today, all 8 files, exit 0. But
whether §2's target should widen for a package whose default export is source
is a STANDARDS question, not one this repo should answer by quietly editing
its own step. Raised in tgwab-standards#173. Widening to `dist src` is a
one-word change and is green today if that is the ruling.

No placement subtlety: `prepare` is the build, so `npm ci` produces dist and
the scan has the bundle to read wherever it sits after that. It is placed
after `test` to keep the §15 gates contiguous.

Refs MichalAFerber/tgwab-standards#173

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016beCydw4C9VrgL9eHzGUG2
@MichalAFerber
MichalAFerber marked this pull request as ready for review September 7, 2026 09:37
@MichalAFerber
MichalAFerber merged commit dc6649d into main Sep 7, 2026
3 checks passed
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