Skip to content

Make the ladder's non-vacuity control assert something, and emit its maps - #143

Merged
patchstackdave merged 1 commit into
mainfrom
feature/map-ladder-emitter
Aug 19, 2026
Merged

Make the ladder's non-vacuity control assert something, and emit its maps#143
patchstackdave merged 1 commit into
mainfrom
feature/map-ladder-emitter

Conversation

@patchstackdave

Copy link
Copy Markdown
Contributor

Stacked on #142 — based on that branch so the diff here is only its own two files. Retarget to main
after #142 squash-merges.

Both defects were found reviewing the consumer side that grades these maps.

The control asserted nothing

expect(declared(mapFor(c)).length + (mapFor(c).apiInvocations ?? []).length).toBeGreaterThanOrEqual(0);

A sum of two lengths is always >= 0. It passes for an empty inventory, an empty invocation list, or
both — the exact state it exists to rule out. The suite is layered so that an app landing on its rung
because nothing was analysed cannot pass for the wrong reason, and this was one of the two controls
holding that up.

It now asserts the analysis attributed something for this app: every ladder app imports express — that is
why it is in all five — so an inventory without it means the scan came back empty and every assertion in
the file is vacuous. Verified by flipping the expected package name: five failures, not zero.

The maps had no generator

A consumer checks these five documents in and asserts what each grades to. They are generated artifacts,
and the harness kept nothing: build in a temp directory, assert, delete. So the consumer's copies were
produced by a manual pass and could only be reproduced by hand.

That matters in one direction specifically. A broken fixture is caught by the consumer's own controls
(schema version, required blocks). A stale one is not: it still parses and still grades, it just
answers for an app this extractor now reads differently. Nothing anywhere detects that.

PS_LADDER_EMIT_DIR=<dir> npx vitest run tests/map/ladder-emit

Skipped without the variable, so a normal run writes nothing and needs no directory. It emits the
consumer's exact on-disk form — same volatile-field stripping, same two-space indent, same trailing
newline — and I confirmed the output is byte-identical to the copies already checked in, because a
regeneration that diffs on noise stops being run. It also writes a manifest pairing each rung with its
advisory and package, so a consumer can key its expectations off the fixture instead of restating them.

It is a spec rather than a script in scripts/ for a mechanical reason: src/map/* imports with ESM
.js specifiers pointing at .ts sources, so plain node cannot load it and a script would have to run
against a build. Living beside the app definitions is also the point — that is the drift this prevents.

Three assertions run in a normal suite without writing anything: the volatile fields are really gone, both
evidence blocks survive (a map missing one grades lower rather than failing, so a silently truncating
emitter would produce fixtures that pass as conservative verdicts), and the serialization is exact.

Verification

Full suite 1103 passed, 1 skipped (the emitter). Typecheck clean.

@coderbuds

coderbuds Bot commented Aug 18, 2026

Copy link
Copy Markdown

Well-structured emitter tests, but ladder.test misuses the async mapFor function.

🎯 Quality: 83% Excellent · 📦 Size: Medium

📈 This month: Your 80th PR — above team average · Averaging Good

See how your team is trending →

@patchstackdave

Copy link
Copy Markdown
Contributor Author

/review

Base automatically changed from feature/map-invocation-naming to main August 19, 2026 07:06
…maps

Two defects, shipped together because the second is what keeps the first honest across repos.

**The control asserted nothing.** `expect(imports.length + invocations.length).toBeGreaterThanOrEqual(0)`
is true of the empty map it existed to exclude. The suite is layered precisely so an app landing on its
rung *because nothing was analysed* cannot pass for the wrong reason, and this was one of the two
controls holding that up. It now asserts the analysis attributed something: every ladder app imports
express — that is why it is in all five — so an inventory without it means the scan came back empty and
every assertion in the file is vacuous. Verified by flipping the expected package: five failures, not
zero.

**The maps had no generator.** A consumer checks these five documents in and grades them, and until now
the harness built each app in a temp directory, asserted, and deleted it — so those copies could only be
reproduced by hand, and nothing detected them going stale. A stale fixture is the quiet case: it still
parses and still grades, it just answers for an app this extractor now reads differently.

The emitter lives beside the app definitions, which is the drift it exists to prevent, and runs only
when handed an output directory:

    PS_LADDER_EMIT_DIR=<dir> npx vitest run tests/map/ladder-emit

It strips the per-machine measurements and writes the consumer's exact on-disk form, byte for byte —
confirmed against the checked-in copies — because a regeneration that diffs on noise stops being run. It
also writes a manifest pairing each rung with its advisory and package, so a consumer can key
expectations off the fixture rather than restating them.

Three assertions run in a normal suite without writing anything: the volatile fields are gone, both
evidence blocks survive (a map missing one grades LOWER rather than failing, so a silently truncating
emitter would produce fixtures that pass as conservative verdicts), and the serialization is exact.
@patchstackdave
patchstackdave force-pushed the feature/map-ladder-emitter branch from 392bed7 to 81aa51f Compare August 19, 2026 07:06
@patchstackdave
patchstackdave merged commit 8bb4a65 into main Aug 19, 2026
6 checks passed
@patchstackdave
patchstackdave deleted the feature/map-ladder-emitter branch August 19, 2026 07:09
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