Skip to content

invoked-as.mjs names scripts/check-entry-guard.mjs as its enforcement; that file does not exist, and 27 hand-typed entry guards still carry the spelling it documents as silently inert #6078

Description

@yinlianghui-tw

Filed unassigned by the dev seat implementing #5793 (branch claude/issue-5793-spec-range-floors, session session_019b5UBNMtTzKbVtZZGvFuxe). Out of that card's scope entirely — noticed while adopting isEntrypoint for a new gate. Recording it, not acting on it.

What was measured

scripts/invoked-as.mjs landed recently (#5984, ported from objectstack). Its header states, as the reason the module exists at all:

scripts/check-entry-guard.mjs enforces this: a process.argv[1] in an entry-guard position anywhere in scripts/** that is not this module is a failure. That gate is what stops a TWELFTH spelling, which is the whole reason this file exists rather than a one-time sweep.

Measured on a1c41c516:

  • scripts/check-entry-guard.mjsdoes not exist. The string check-entry-guard appears in exactly one place in the whole repository — that sentence in invoked-as.mjs itself. Nothing in package.json or .github/workflows/ runs such a gate.
  • 27 files under scripts/ still spell their entry guard by hand with process.argv[1] (every .mjs there except invoked-as.mjs that has one). Only two modules import isEntrypoint: scripts/pm/check-half-states.mjs, which arrived in the same PR, and the gate added by Packages whose published d.ts references spec-17.1.0-only symbols still declare "@objectstack/spec": "^17.0.0" — the range admits a spec that lacks the symbols #5793.
  • All 27 use the plain resolve(process.argv[1]) === fileURLToPath(import.meta.url) shape with no realpath leg — which is precisely the spelling invoked-as.mjs's own header documents as the failure that motivated it:

Node resolves symlinks for the module graph but leaves process.argv[1] as the caller typed it. Reach a script through a symlink and the two name different paths, the guard answers false, and the script does NOTHING — with exit 0 and no output.

Examples: check-published-dist-tooling.mjs:400, check-package-self-import.mjs:446, check-action-forward-parity.mjs:1061, check-doc-component-types.mjs:1006, check-doc-links.mjs:970, check-spec-symbol-derivation.mjs:1179, check-i18n-en-drift.mjs:553, check-changeset-fixed.mjs:232, sync-quick-reference-release.mjs:408, extract-mdx-demos.mjs:417.

Why it can bite

The silent direction is the one that matters, and invoked-as.mjs argues it better than this issue can: CI wrappers hold result.status only, so an inert child is a green gate. Several of the 27 are blocking checks — check-published-dist-tooling.mjs guards the publish path, check-doc-component-types.mjs and check-action-forward-parity.mjs gate pull requests.

No current invocation goes through a symlink, so nothing is failing today. What is broken now is the claim: a header states a gate enforces the single-spelling rule, that gate is absent, and the sweep it was supposed to protect never happened either. Both halves of the port landed as documentation. That is the same declared≠enforced shape check-spec-symbol-derivation.mjs's header calls "a planted premise for the next session" — an agent reading invoked-as.mjs reasonably concludes the tree is already converted and enforced, and neither is true.

The call to make

Probably two pieces, and they are separable:

  1. Port or write the missing gate, so a twenty-eighth hand-typed spelling cannot land. Without it, converting the 27 is a one-time sweep that starts rotting the day it merges — the explicit argument the header makes.
  2. Convert the 27 call sites to isEntrypoint(import.meta.url). Mechanical, but it is a lot of blocking gates to touch at once and wants its own review; it may be worth doing after (1), since the gate names its own worklist.

If the enforcement is genuinely not wanted here, the alternative is to correct invoked-as.mjs's header so it stops asserting a gate that does not exist — the claim is what makes this expensive, not the spellings.

Refs: #5984 (the port that introduced the module and its one adopter) · #5793 (the card whose seat found it).


Generated by Claude Code

Metadata

Metadata

Labels

domain:devxobjectui devx stream: fix lands on .github/, scripts/ or release pipeline — devx lane cross-repopm:dispatched

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions