Skip to content

The route-ledger conformance guards' host-app-reach limb scans RAW source, so a prose mention of getRawApp reads as a second reacher #12398

Description

@os-warren

Filed unassigned from #12140's implementation round — an observation, not a claim on anyone's
time, and deliberately not fixed there (that card hardens a dev door and changed no guard).

What was measured

packages/metadata/src/metadata-route-ledger.conformance.test.ts has a limb that asserts an
IDENTITY — "plugin.ts is the only file that reaches for the host app":

constHOST_APP_REACH=/getRawApp|['"`]http-server['"`]|['"`]http\.server['"`]/;constreadSource=(file: string): string=>readFileSync(join(SRC_DIR,file),'utf8');constreaching=packageSourceFiles().filter((f)=>HOST_APP_REACH.test(readSource(f)));expect(reaching,'…').toEqual([HOST_APP_REACH_FILE]);

readSource is the RAW file. Every other limb in that same file runs its input through
stripComments() first, and the file's own header says why:

Strip comments before scanning. Prose cannot mount a route, and this package's headers
quote the wire paths they serve — a raw-text scan would report a documented path as an
unledgered mount.

That ruling is correct and this limb does not apply it. The consequence: a comment in any
non-excluded, non-test source file of the package that quotes getRawApp, 'http-server' or
'http.server' fails the identity assertion, naming a file that reaches for nothing.

Not hypothetical — it fired on #12140's first draft. A docblock added to
packages/metadata/src/routes/hmr-routes.ts explaining why the mount sits outside the auth
seam ("the mount takes the framework-native handle through IHttpServer.getRawApp()") was
enough:

- Expected - 0
+ Received + 1
[
"plugin.ts",
+ "routes/hmr-routes.ts",
]

#12140 worked around it by not repeating the spelling in that module's prose (with a comment
saying why), which is a documentation tax on the module that most needs to explain the seam.

Why it is worth a card rather than a shrug

The failure invites the WRONG repair. The message reads "files reaching for the host HTTP
app … ledger its routes and add its module to MOUNT_SOURCES before adding it here", so the
obvious response to a prose-only hit is to add the file to the expected identity list — which
permanently widens an assertion whose whole value is that it is an identity. A guard that is
green because someone widened its expectation is worse than no guard.

Scope: this is a family, not one file

The same raw-text limb is replicated across at least three packages, each with its own copy of
the regex:

  • packages/metadata/src/metadata-route-ledger.conformance.test.ts (readSource, no strip)
  • packages/cloud-connection/src/cloud-connection-route-ledger.conformance.test.ts (same
    HOST_APP_REACH spelling, readSource, no strip)
  • packages/triggers/trigger-api/src/trigger-api-route-ledger.conformance.test.ts (same limb,
    reads the file inline with readFileSync, no strip)

packages/cli/src/utils/console-route-ledger.conformance.test.ts is in the same family and
should be checked with them.

What a fix would have to keep

Not simply "strip comments everywhere". Two properties are load-bearing and pull in opposite
directions, which is why this wants a considered fix rather than a one-line edit:

  1. Comments must not count — prose cannot reach for anything. This is the fix.
  2. String literals must still count — the limb detects ctx.getService('http.server'),
    so the sibling maskStrings() helper (used by other limbs) must NOT be applied here or
    the limb detects nothing and passes vacuously. Stripping comments is safe; masking strings
    would be a silent disarm.

A fix should also confirm the limb still FAILS on a real second reacher after the change —
the anti-vacuity measurement these guards already carry for their other limbs.

Refs: #12140 (where it was measured) · #11882 (the metadata ledger these limbs guard)

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions