From 4a1cc602133bd09823b5cfbaaf20214dc6894aae Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 28 Aug 2026 07:23:51 +0000 Subject: [PATCH 1/2] fix(spec): close entry-nameability on the four remaining leaking entries Repairs the seven (entry, type) pairs #11986's generalized gate found still leaking the entry-nameability invariant (maintainer ruling recorded on #11350) after #11350/#11709 repaired only the defineStack/root instance: Book, FormField, NavigationItem on the root @objectstack/spec entry; UnknownAuthoringKeyFinding on /kernel; FilterCondition and StateNodeConfig on /ai; FilterCondition on /ui. One re-export line per name, on the leaking entry, from the module that already declares the type as public on its own subpath -- the same shape #11350 and #11709 used. entry-nameability.baseline.json's `entries` is now {} (all seven rows deleted per the ledger's shrink-only rule). api-surface/ regenerated for the four touched entries. Card relationship is stated once, in the PR body, not here. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01LpRNHxWZgSUgVnFT9mQQo4 --- .../entry-nameability-generalized-closure.md | 5 +++ packages/spec/api-surface/ai.json | 2 ++ packages/spec/api-surface/kernel.json | 1 + packages/spec/api-surface/root.json | 3 ++ packages/spec/api-surface/ui.json | 1 + packages/spec/entry-nameability.baseline.json | 33 ++++--------------- packages/spec/src/ai/index.ts | 8 +++++ packages/spec/src/index.ts | 10 ++++++ packages/spec/src/kernel/index.ts | 7 ++++ packages/spec/src/ui/index.ts | 6 ++++ 10 files changed, 49 insertions(+), 27 deletions(-) create mode 100644 .changeset/entry-nameability-generalized-closure.md diff --git a/.changeset/entry-nameability-generalized-closure.md b/.changeset/entry-nameability-generalized-closure.md new file mode 100644 index 0000000000..12b67f253f --- /dev/null +++ b/.changeset/entry-nameability-generalized-closure.md @@ -0,0 +1,5 @@ +--- +"@objectstack/spec": minor +--- + +Close the entry-nameability invariant on the four remaining public entries that leaked it (#12414). Generalizing #11350/#11709's `defineStack`-only probe to every public entry found the class was never fully closed: seven (entry, type) pairs across four entries still had a `define*` factory's return type expand to mention a type the entry itself did not re-export — `Book`, `FormField`, `NavigationItem` from the root `@objectstack/spec` entry, `UnknownAuthoringKeyFinding` from `@objectstack/spec/kernel`, `FilterCondition` and `StateNodeConfig` from `@objectstack/spec/ai`, and `FilterCondition` from `@objectstack/spec/ui`. Each is repaired the same way as the prior two rounds: one re-export line on the leaking entry, from the module that already declares the type as public on its own subpath. A consumer writing an un-annotated `export const x = defineBook(...)` (or the `/ui`, `/ai`, `/kernel` equivalent) previously hit TS2883 naming an unaddressable hash-named internal dist chunk and could not build; all seven now declaration-emit cleanly with no annotation required. No runtime change. `packages/spec/entry-nameability.baseline.json`, the shrink-only ledger `check:entry-nameability` (#11986) reads, is now empty — the class it was tracking is closed. diff --git a/packages/spec/api-surface/ai.json b/packages/spec/api-surface/ai.json index 80b47f6e6e..6a8122026f 100644 --- a/packages/spec/api-surface/ai.json +++ b/packages/spec/api-surface/ai.json @@ -51,6 +51,7 @@ "FileContentSchema (const)", "FileKnowledgeSource (type)", "FileKnowledgeSourceSchema (const)", + "FilterCondition (type)", "FunctionCall (type)", "FunctionCallSchema (const)", "HttpKnowledgeSource (type)", @@ -138,6 +139,7 @@ "SolutionBlueprintSchema (const)", "SolutionBlueprintStrict (type)", "SolutionBlueprintStrictSchema (const)", + "StateNodeConfig (type)", "StructuredOutputConfig (type)", "StructuredOutputConfigParsed (type)", "StructuredOutputConfigSchema (const)", diff --git a/packages/spec/api-surface/kernel.json b/packages/spec/api-surface/kernel.json index 8ce5a68ead..31eb715f9b 100644 --- a/packages/spec/api-surface/kernel.json +++ b/packages/spec/api-surface/kernel.json @@ -444,6 +444,7 @@ "UninstallPackageRequestSchema (const)", "UninstallPackageResponse (type)", "UninstallPackageResponseSchema (const)", + "UnknownAuthoringKeyFinding (interface)", "UpgradeImpactLevel (type)", "UpgradeImpactLevelSchema (const)", "UpgradePackageRequest (type)", diff --git a/packages/spec/api-surface/root.json b/packages/spec/api-surface/root.json index acce710909..501ca7cf70 100644 --- a/packages/spec/api-surface/root.json +++ b/packages/spec/api-surface/root.json @@ -23,6 +23,7 @@ "BUILTIN_MEMBERSHIP_ROLES (const)", "BUILTIN_MEMBERSHIP_ROLE_OPTIONS (const)", "BaseValidationRuleShape (interface)", + "Book (type)", "BuiltinIdentityName (type)", "BuiltinMembershipRole (type)", "CONVERSIONS_BY_MAJOR (const)", @@ -61,6 +62,7 @@ "F (const)", "FIELD_KEY_GUIDANCE (const)", "FilterCondition (type)", + "FormField (type)", "FormFieldInput (type)", "GUEST_POSITION (const)", "LintableAuthoringCollection (interface)", @@ -82,6 +84,7 @@ "MigrationHopResult (interface)", "MigrationStep (interface)", "MigrationTodo (interface)", + "NavigationItem (type)", "NavigationItemInput (type)", "NormalizeStackInputOptions (interface)", "OBJECT_KEY_GUIDANCE (const)", diff --git a/packages/spec/api-surface/ui.json b/packages/spec/api-surface/ui.json index 072c606a6b..a81ecdfc09 100644 --- a/packages/spec/api-surface/ui.json +++ b/packages/spec/api-surface/ui.json @@ -148,6 +148,7 @@ "FieldWidgetProps (type)", "FieldWidgetPropsParsed (type)", "FieldWidgetPropsSchema (const)", + "FilterCondition (type)", "FormButtonConfig (type)", "FormButtonConfigSchema (const)", "FormField (type)", diff --git a/packages/spec/entry-nameability.baseline.json b/packages/spec/entry-nameability.baseline.json index 00bde656a0..182c12922b 100644 --- a/packages/spec/entry-nameability.baseline.json +++ b/packages/spec/entry-nameability.baseline.json @@ -16,32 +16,11 @@ "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)." + "#12414 repaired the seven (entry, type) pairs this ledger was carrying — one", + "re-export line per name, on the leaking entry, from the module that declares", + "it — and deleted them here per the shrink-only rule above. `entries` is empty", + "on purpose: the class #11986 measured is closed, and a name that leaks again", + "fails the gate rather than landing pre-accommodated." ], - "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`." - } - } + "entries": {} } diff --git a/packages/spec/src/ai/index.ts b/packages/spec/src/ai/index.ts index c0cbfc3da6..55a878bacd 100644 --- a/packages/spec/src/ai/index.ts +++ b/packages/spec/src/ai/index.ts @@ -35,3 +35,11 @@ export * from './mcp.zod'; export * from './knowledge-source.zod'; export * from './knowledge-document.zod'; export * from './solution-blueprint.zod'; + +// [#12414] entry-nameability: these factories' return types expand to mention +// `/data`'s `FilterCondition` and `/automation`'s `StateNodeConfig` — both +// public on their own subpaths but not nameable from `/ai`. Same invariant +// (maintainer ruling recorded on #11350), same repair: re-export from the +// declaring module. +export type { FilterCondition } from '../data/filter.zod'; +export type { StateNodeConfig } from '../automation/state-machine.zod'; diff --git a/packages/spec/src/index.ts b/packages/spec/src/index.ts index 4acfd285a6..e0e1f9565f 100644 --- a/packages/spec/src/index.ts +++ b/packages/spec/src/index.ts @@ -153,6 +153,16 @@ export type { StateNodeConfig } from './automation/state-machine.zod'; // declaring module (both already public on `/data`). export type { BaseValidationRuleShape } from './data/validation.zod'; export type { FilterCondition } from './data/filter.zod'; +// [#12414] The invariant generalized to every public entry, not just the root: +// probing every `define*` factory across all 17 subpaths found the class was +// never closed by #11350/#11709 — four more entries leak a structurally- +// mentioned type through a factory return value. Same invariant (maintainer +// ruling recorded on #11350), same one-line-per-name repair: re-export from +// the declaring module. All three are already public on their own subpaths +// (`/system`, `/ui`). +export type { Book } from './system/book.zod'; +export type { FormField } from './ui/view.zod'; +export type { NavigationItem } from './ui/app.zod'; // DX factories for the remaining authoring domains (issue #2035) — one type-safe // entry per writable domain, mirroring the 19 factories above. `defineX` is a diff --git a/packages/spec/src/kernel/index.ts b/packages/spec/src/kernel/index.ts index b9d5c1802e..851e248211 100644 --- a/packages/spec/src/kernel/index.ts +++ b/packages/spec/src/kernel/index.ts @@ -38,6 +38,13 @@ export * from './metadata-type-redaction'; // Pre-parse unknown-key walker over EVERY metadata collection (#3786). Lives // here, not in data/, because covering every type means importing every schema. export * from './metadata-authoring-lint'; +// [#12414] entry-nameability: `metadata-authoring-lint` IMPORTS (does not +// re-declare) `UnknownAuthoringKeyFinding` from `../data/authoring-key-lint`, +// so the `export *` above does not carry it — the finding type its lint +// functions return was unnameable from this entry. Same invariant (maintainer +// ruling recorded on #11350), same repair: re-export from the declaring +// module, which is already public on `/data`. +export type { UnknownAuthoringKeyFinding } from '../data/authoring-key-lint'; export * from './package-artifact.zod'; export * from './package-registry.zod'; export * from './package-upgrade.zod'; diff --git a/packages/spec/src/ui/index.ts b/packages/spec/src/ui/index.ts index be6415cf21..6546e4c47a 100644 --- a/packages/spec/src/ui/index.ts +++ b/packages/spec/src/ui/index.ts @@ -92,3 +92,9 @@ export * from './sharing.zod'; // memo may evaluate at a node's top level, plus the per-component carriage // map the objectui memo consumes instead of hard-coding a twin list. export * from './expression-bindable-text-keys.zod'; + +// [#12414] entry-nameability: factory return types expand to mention +// `/data`'s `FilterCondition`, which `/ui` does not re-export. Same invariant +// (maintainer ruling recorded on #11350), same repair: re-export from the +// declaring module. +export type { FilterCondition } from '../data/filter.zod'; From 20a810a903815700955a9c71c6e7875fba723d4e Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 28 Aug 2026 13:06:49 +0000 Subject: [PATCH 2/2] fix(spec): regenerate export-origins/api-surface after the #12718 merge Patch round on #12414/PR #12899: CI flagged check:export-origins STALE on ai.json/kernel.json/root.json/ui.json -- the seven re-exports this branch adds regenerated api-surface but not the sibling export-origins artifact when the branch was first merged with origin/main (the #12949 precedent this diff follows regenerates both). Root cause, precisely: merging origin/main (which had since landed #12718, retiring PreviewModeConfig) picked up main's source changes but the two GENERATED artifacts derived from that merged source were never rebuilt -- kernel.json's api-surface still listed the retired PreviewModeConfig/PreviewModeConfigParsed/PreviewModeConfigSchema, and export-origins hadn't gained entries for this branch's seven new re-exports at all. Fix: pnpm --filter @objectstack/spec build (fresh dist reflecting both this branch's re-exports and #12718's retirement), then gen:export-origins + gen:api-surface. Read the resulting diff per the gate's own #4411 dual-source-trap remedy: each of the seven names' newly-gained export-origins entry was cross-checked against its origin on every sibling entry that already carried it (root vs /system vs /ui, kernel vs /data, /ai and /ui vs /data and /automation) -- all match byte-for-byte, so this is the harmless re-export shape, never dual-source. kernel.json's api-surface diff is exactly the PreviewModeConfig removal #12718 made; nothing from this branch's own repair moved. Verified: check:export-origins, check:dual-source-exports and check:generated (14/14 generated artifacts) all green on the merged + rebuilt tree. Part of #12414 Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01LpRNHxWZgSUgVnFT9mQQo4 --- packages/spec/api-surface/kernel.json | 3 --- packages/spec/export-origins/ai.json | 2 ++ packages/spec/export-origins/kernel.json | 1 + packages/spec/export-origins/root.json | 3 +++ packages/spec/export-origins/ui.json | 1 + 5 files changed, 7 insertions(+), 3 deletions(-) diff --git a/packages/spec/api-surface/kernel.json b/packages/spec/api-surface/kernel.json index 31eb715f9b..ca8f39685b 100644 --- a/packages/spec/api-surface/kernel.json +++ b/packages/spec/api-surface/kernel.json @@ -356,9 +356,6 @@ "PluginVersionMetadata (type)", "PluginVersionMetadataParsed (type)", "PluginVersionMetadataSchema (const)", - "PreviewModeConfig (type)", - "PreviewModeConfigParsed (type)", - "PreviewModeConfigSchema (const)", "ProtocolFeature (type)", "ProtocolFeatureParsed (type)", "ProtocolFeatureSchema (const)", diff --git a/packages/spec/export-origins/ai.json b/packages/spec/export-origins/ai.json index e87553c3e9..13e696d5c3 100644 --- a/packages/spec/export-origins/ai.json +++ b/packages/spec/export-origins/ai.json @@ -51,6 +51,7 @@ "FileContentSchema": "src/ai/conversation.zod.ts#FileContentSchema (const)", "FileKnowledgeSource": "src/ai/knowledge-source.zod.ts#FileKnowledgeSource (type)", "FileKnowledgeSourceSchema": "src/ai/knowledge-source.zod.ts#FileKnowledgeSourceSchema (const)", + "FilterCondition": "src/data/filter.zod.ts#FilterCondition (type)", "FunctionCall": "src/ai/conversation.zod.ts#FunctionCall (type)", "FunctionCallSchema": "src/ai/conversation.zod.ts#FunctionCallSchema (const)", "HttpKnowledgeSource": "src/ai/knowledge-source.zod.ts#HttpKnowledgeSource (type)", @@ -138,6 +139,7 @@ "SolutionBlueprintSchema": "src/ai/solution-blueprint.zod.ts#SolutionBlueprintSchema (const)", "SolutionBlueprintStrict": "src/ai/solution-blueprint.zod.ts#SolutionBlueprintStrict (type)", "SolutionBlueprintStrictSchema": "src/ai/solution-blueprint.zod.ts#SolutionBlueprintStrictSchema (const)", + "StateNodeConfig": "src/automation/state-machine.zod.ts#StateNodeConfig (type)", "StructuredOutputConfig": "src/ai/agent.zod.ts#StructuredOutputConfig (type)", "StructuredOutputConfigParsed": "src/ai/agent.zod.ts#StructuredOutputConfigParsed (type)", "StructuredOutputConfigSchema": "src/ai/agent.zod.ts#StructuredOutputConfigSchema (const)", diff --git a/packages/spec/export-origins/kernel.json b/packages/spec/export-origins/kernel.json index 6347ed682a..4d5fb99470 100644 --- a/packages/spec/export-origins/kernel.json +++ b/packages/spec/export-origins/kernel.json @@ -441,6 +441,7 @@ "UninstallPackageRequestSchema": "src/kernel/package-registry.zod.ts#UninstallPackageRequestSchema (const)", "UninstallPackageResponse": "src/kernel/package-registry.zod.ts#UninstallPackageResponse (type)", "UninstallPackageResponseSchema": "src/kernel/package-registry.zod.ts#UninstallPackageResponseSchema (const)", + "UnknownAuthoringKeyFinding": "src/data/authoring-key-lint.ts#UnknownAuthoringKeyFinding (interface)", "UpgradeImpactLevel": "src/kernel/package-upgrade.zod.ts#UpgradeImpactLevel (type)", "UpgradeImpactLevelSchema": "src/kernel/package-upgrade.zod.ts#UpgradeImpactLevelSchema (const)", "UpgradePackageRequest": "src/kernel/package-upgrade.zod.ts#UpgradePackageRequest (type)", diff --git a/packages/spec/export-origins/root.json b/packages/spec/export-origins/root.json index 5a8916ac1d..a4f7c068aa 100644 --- a/packages/spec/export-origins/root.json +++ b/packages/spec/export-origins/root.json @@ -23,6 +23,7 @@ "BUILTIN_MEMBERSHIP_ROLES": "src/identity/membership-role.ts#BUILTIN_MEMBERSHIP_ROLES (const)", "BUILTIN_MEMBERSHIP_ROLE_OPTIONS": "src/identity/membership-role.ts#BUILTIN_MEMBERSHIP_ROLE_OPTIONS (const)", "BaseValidationRuleShape": "src/data/validation.zod.ts#BaseValidationRuleShape (interface)", + "Book": "src/system/book.zod.ts#Book (type)", "BuiltinIdentityName": "src/identity/eval-user.zod.ts#BuiltinIdentityName (type)", "BuiltinMembershipRole": "src/identity/membership-role.ts#BuiltinMembershipRole (type)", "CONVERSIONS_BY_MAJOR": "src/conversions/registry.ts#CONVERSIONS_BY_MAJOR (const)", @@ -61,6 +62,7 @@ "F": "src/shared/expression.zod.ts#F (const)", "FIELD_KEY_GUIDANCE": "src/data/authoring-key-lint.ts#FIELD_KEY_GUIDANCE (const)", "FilterCondition": "src/data/filter.zod.ts#FilterCondition (type)", + "FormField": "src/ui/view.zod.ts#FormField (type)", "FormFieldInput": "src/ui/view.zod.ts#FormFieldInput (type)", "GUEST_POSITION": "src/identity/position.zod.ts#GUEST_POSITION (const)", "LintableAuthoringCollection": "src/kernel/metadata-authoring-lint.ts#LintableAuthoringCollection (interface)", @@ -82,6 +84,7 @@ "MigrationHopResult": "src/migrations/types.ts#MigrationHopResult (interface)", "MigrationStep": "src/migrations/types.ts#MigrationStep (interface)", "MigrationTodo": "src/migrations/types.ts#MigrationTodo (interface)", + "NavigationItem": "src/ui/app.zod.ts#NavigationItem (type)", "NavigationItemInput": "src/ui/app.zod.ts#NavigationItemInput (type)", "NormalizeStackInputOptions": "src/shared/metadata-collection.zod.ts#NormalizeStackInputOptions (interface)", "OBJECT_KEY_GUIDANCE": "src/data/authoring-key-lint.ts#OBJECT_KEY_GUIDANCE (const)", diff --git a/packages/spec/export-origins/ui.json b/packages/spec/export-origins/ui.json index c57a6f5d81..30fd33aa29 100644 --- a/packages/spec/export-origins/ui.json +++ b/packages/spec/export-origins/ui.json @@ -148,6 +148,7 @@ "FieldWidgetProps": "src/ui/widget.zod.ts#FieldWidgetProps (type)", "FieldWidgetPropsParsed": "src/ui/widget.zod.ts#FieldWidgetPropsParsed (type)", "FieldWidgetPropsSchema": "src/ui/widget.zod.ts#FieldWidgetPropsSchema (const)", + "FilterCondition": "src/data/filter.zod.ts#FilterCondition (type)", "FormButtonConfig": "src/ui/view.zod.ts#FormButtonConfig (type)", "FormButtonConfigSchema": "src/ui/view.zod.ts#FormButtonConfigSchema (const)", "FormField": "src/ui/view.zod.ts#FormField (type)",