Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions .github/workflows/lint.yml
Original file line numberDiff line numberDiff line change
Expand Up@@ -4258,6 +4258,28 @@ jobs:
OS_EXPECT_ROOT_NAMEABILITY: '1'
run: pnpm --filter @objectstack/spec exec vitest run scripts/root-entry-type-nameability.pin.test.ts

# [#11986] The same invariant, generalized from ONE entry to all 17 — the
# C half of the 2026-08-25 ruling on #11709 (A′ was the two re-exports,
# this is the gate that stops a fourth round of per-name repair). The pin
# above keeps its own charter: it reproduces the REAL configs' program
# shape verbatim, fixture file included. This one compiles a probe per
# public entry over every callable export, so no entry sits unmeasured.
#
# ⛔ Never batch the entries into one program to save time. A program file
# importing a subpath entry makes that entry's names nameable PROGRAM-WIDE
# (#11350's control; the gate's --self-test measures it in both
# directions), so a single batched program reports zero leaks no matter how
# many exist — full cost, no measurement. Measured here: 47s for all 17
# entries, 422 probes.
#
# Sits with its family — `check:api-surface` / `check:exported-any` /
# `check:dual-source-exports` — because it reads the built dist a
# consumer's import actually resolves to, so it needs the build steps
# above and refuses (never skips) on a stale or unbuilt tree. Adds no
# required context: a step in an existing lane (#9325).
- name: Check public-entry type nameability (built dist, declaration emit)
run: pnpm --filter @objectstack/spec run check:entry-nameability

# Same surface, the other axis: api-surface/ records that an export
# EXISTS, never what it resolves to — so four exported types sat at `any`
# across a whole major with every gate green (#4171). #4115 tells consumers
Expand Down
47 changes: 47 additions & 0 deletions packages/spec/entry-nameability.baseline.json
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
{
"$comment": [
"Shrink-only ledger for `check:entry-nameability` (#11986). Each entry records a",
"(public entry, type name) pair that the entry-nameability invariant already",
"violates on `main` — a type structurally mentioned in the declaration emitted for",
"a consumer that CALLS one of that entry's exported functions, which cannot be",
"named through the package's `exports` map.",
"",
"HAND-EDITED, NEVER GENERATED, and deliberately so — the same reason",
"`dual-source-exports.baseline.json` is: a `gen:` that rewrote this file would let a",
"new leak be admitted by running a command instead of by a decision, which is the",
"whack-a-mole #11986 exists to end.",
"",
"SHRINK-ONLY IN BOTH DIRECTIONS. A name that appears and is not recorded here fails",
"the gate. A name recorded here that no longer leaks ALSO fails the gate, with an",
"instruction to delete the line: a ledger that keeps entries after they are repaired",
"stops describing the tree and starts covering for it.",
"",
"THE SHRINK PATH IS ONE LINE PER ROW. Each of these is repaired exactly the way",
"#11350 and #11709 were: re-export the named type, on the leaking entry, from the",
"module that declares it. They are NOT repaired here because doing so edits four",
"entry barrels and regenerates `api-surface/` — a different file surface and a",
"different gate family from this card's, and two of those barrels were claimed by",
"other in-flight work when this landed. They are filed for triage instead; see the",
"PR body for the measurement and the issue link.",
"",
"MEASURED ON: cdbd9204b65ae4ebec63f90f61669fb498efaa55 (2026-08-26)."
],
"entries": {
"@objectstack/spec": {
"leaks": ["Book", "FormField", "NavigationItem"],
"why": "Root-entry factories whose return type expands to mention a `/system`, `/ui` type the root entry does not re-export. Same class and same repair as #11350's three names and #11709's two — A′ closed the `defineStack` instance only. Repair: re-export each from its declaring module in `src/index.ts`."
},
"@objectstack/spec/kernel": {
"leaks": ["UnknownAuthoringKeyFinding"],
"why": "A `/kernel` export's call result mentions a finding type declared in an internal module and not re-exported from the `/kernel` entry. Repair: re-export it from `src/kernel/index.ts`."
},
"@objectstack/spec/ai": {
"leaks": ["FilterCondition", "StateNodeConfig"],
"why": "`/ai` factory return types expand to mention a `/data` filter type and an `/automation` state-machine type; both are public on their own subpaths but not nameable from `/ai`. Repair: re-export both from `src/ai/index.ts`."
},
"@objectstack/spec/ui": {
"leaks": ["FilterCondition"],
"why": "`/ui` factory return types expand to mention `/data`'s `FilterCondition`, which `/ui` does not re-export. Repair: re-export it from `src/ui/index.ts`."
}
}
}
1 change: 1 addition & 0 deletions packages/spec/package.json
Original file line numberDiff line numberDiff line change
Expand Up@@ -266,6 +266,7 @@
"check:export-origins": "tsx scripts/build-export-origins.ts --self-test && tsx scripts/build-export-origins.ts --check",
"check:exported-any": "tsx scripts/check-exported-any.ts --self-test && tsx scripts/check-exported-any.ts",
"check:dual-source-exports": "tsx scripts/check-dual-source-exports.ts --self-test && tsx scripts/check-dual-source-exports.ts",
"check:entry-nameability": "tsx scripts/check-entry-nameability.ts",
"check:browser-reachable-entries": "tsx scripts/check-browser-reachable-entries.ts --self-test && tsx scripts/check-browser-reachable-entries.ts",
"check:objectui-pin-citations": "tsx scripts/check-objectui-pin-citations.ts --self-test && tsx scripts/check-objectui-pin-citations.ts",
"check:llms-txt": "tsx scripts/check-llms-txt.ts --self-test && tsx scripts/check-llms-txt.ts",
Expand Down
Loading
Loading