From 5c9b75dcd8ee934a4f7271a96fc3d7720d601380 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 13 Aug 2026 21:31:46 +0000 Subject: [PATCH 1/4] feat(spec): declare the viewItems channel for non-container view artifacts in assembled manifests (#5320) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Option B of the 2026-08-12 fork ruling on #5320: runtime-assembled manifests (package export, environment artifacts) get a DECLARED home for the view artifacts the authored stack vocabulary refuses — expanded viewKind items, tenant-authored standalone ViewItems, flattened overlays. - AssembledViewArtifactSchema: the non-container branches of the view metadata vocabulary, built from VIEW_METADATA_MEMBERS minus container (no drift). - partitionAssembledViewArtifacts: producer-side re-aggregation (A's mechanical half) — containers travel in views:, exactly-derivable expanded items fold away, everything else travels in viewItems:. - ObjectStackDefinition.viewItems: declared always-refusing (machine-assembled only) so a hand-authored viewItems fails tsc and parse with the prescription instead of being silently stripped. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_012MNV7ZSCjNfA38eDCjsXQL --- .changeset/assembled-views-vocabulary.md | 30 +++ packages/spec/api-surface/ui.json | 5 + packages/spec/export-origins/ui.json | 5 + packages/spec/src/stack.zod.ts | 36 +++ packages/spec/src/ui/assembled-views.test.ts | 189 ++++++++++++++++ packages/spec/src/ui/assembled-views.zod.ts | 224 +++++++++++++++++++ packages/spec/src/ui/index.ts | 3 + 7 files changed, 492 insertions(+) create mode 100644 .changeset/assembled-views-vocabulary.md create mode 100644 packages/spec/src/ui/assembled-views.test.ts create mode 100644 packages/spec/src/ui/assembled-views.zod.ts diff --git a/.changeset/assembled-views-vocabulary.md b/.changeset/assembled-views-vocabulary.md new file mode 100644 index 0000000000..8c682612ed --- /dev/null +++ b/.changeset/assembled-views-vocabulary.md @@ -0,0 +1,30 @@ +--- +"@objectstack/spec": minor +--- + +feat(spec): declare the `viewItems:` channel — a portable home for non-container view artifacts in runtime-assembled manifests (#5320, #8070) + +Runtime-assembled manifests (`GET /packages/:id/export`, environment artifact +bundles) carry view artifacts the authored stack vocabulary refuses: expanded +`viewKind` items (the ADR-0017 dual-read keeps them registered beside their +container), tenant-authored standalone ViewItems, and flattened overlays. +Measured on #5320, 2 of 3 exported entries in the minimal single-container case +were stack-schema-refused yet metadata-door-legal — the export→import round trip +worked only through the runtime registration loop's undeclared wider acceptance. + +Per the 2026-08-12 fork ruling (option B plus A's mechanical half), the bridge +is now declared instead of silent: + +- **`AssembledViewArtifactSchema`** (`ui/assembled-views.zod.ts`) — one entry of + an assembled manifest's `viewItems:` collection: the non-container branches of + the `view` metadata vocabulary, built from `VIEW_METADATA_MEMBERS` minus + `container` so the two doors cannot drift. Strictly schema'd; no passthrough. +- **`partitionAssembledViewArtifacts`** — the producer-side re-aggregation + shared by every manifest assembler: containers travel in `views:`; expanded + items a travelling container re-derives exactly are folded away (reported in + `folded`); everything else — standalone items, overlays, items whose stored + body diverged from their container — travels in `viewItems:`. +- **`ObjectStackDefinition.viewItems`** is declared as an always-refusing key: + hand-authoring it in `defineStack` source fails `tsc` (input type `never`) and + parse, with the prescription (author containers in `views:`; author standalone + views through the metadata door). The channel is machine-assembled by design. diff --git a/packages/spec/api-surface/ui.json b/packages/spec/api-surface/ui.json index 50d002b23e..7e343df25c 100644 --- a/packages/spec/api-surface/ui.json +++ b/packages/spec/api-surface/ui.json @@ -5,6 +5,7 @@ "ACTION_LOCATIONS (const)", "ACTION_PARAM_BUILTIN_KEYS (const)", "AIChatWindowProps (const)", + "ASSEMBLED_VIEW_ITEMS_KEY (const)", "Action (type)", "ActionAi (type)", "ActionAiParsed (type)", @@ -42,6 +43,9 @@ "AppearanceConfigSchema (const)", "AriaProps (type)", "AriaPropsSchema (const)", + "AssembledViewArtifact (type)", + "AssembledViewArtifactSchema (const)", + "AssembledViewPartition (interface)", "BorderRadius (type)", "BorderRadiusSchema (const)", "BreakpointColumnMap (type)", @@ -412,6 +416,7 @@ "normalizeFilterOperator (function)", "normalizeInlineAction (function)", "pageForm (const)", + "partitionAssembledViewArtifacts (function)", "reactBlockTagFor (function)", "reportForm (const)", "reportSelectionOrder (function)", diff --git a/packages/spec/export-origins/ui.json b/packages/spec/export-origins/ui.json index cbb13402d7..0de4cbd73a 100644 --- a/packages/spec/export-origins/ui.json +++ b/packages/spec/export-origins/ui.json @@ -5,6 +5,7 @@ "ACTION_LOCATIONS": "src/ui/action.zod.ts#ACTION_LOCATIONS (const)", "ACTION_PARAM_BUILTIN_KEYS": "src/ui/action-params.zod.ts#ACTION_PARAM_BUILTIN_KEYS (const)", "AIChatWindowProps": "src/ui/component.zod.ts#AIChatWindowProps (const)", + "ASSEMBLED_VIEW_ITEMS_KEY": "src/ui/assembled-views.zod.ts#ASSEMBLED_VIEW_ITEMS_KEY (const)", "Action": "src/ui/action.zod.ts#Action (type)", "ActionAi": "src/ui/action.zod.ts#ActionAi (type)", "ActionAiParsed": "src/ui/action.zod.ts#ActionAiParsed (type)", @@ -42,6 +43,9 @@ "AppearanceConfigSchema": "src/ui/view.zod.ts#AppearanceConfigSchema (const)", "AriaProps": "src/ui/i18n.zod.ts#AriaProps (type)", "AriaPropsSchema": "src/ui/i18n.zod.ts#AriaPropsSchema (const)", + "AssembledViewArtifact": "src/ui/assembled-views.zod.ts#AssembledViewArtifact (type)", + "AssembledViewArtifactSchema": "src/ui/assembled-views.zod.ts#AssembledViewArtifactSchema (const)", + "AssembledViewPartition": "src/ui/assembled-views.zod.ts#AssembledViewPartition (interface)", "BorderRadius": "src/ui/theme.zod.ts#BorderRadius (type)", "BorderRadiusSchema": "src/ui/theme.zod.ts#BorderRadiusSchema (const)", "BreakpointColumnMap": "src/ui/responsive.zod.ts#BreakpointColumnMap (type)", @@ -412,6 +416,7 @@ "normalizeFilterOperator": "src/ui/view.zod.ts#normalizeFilterOperator (function)", "normalizeInlineAction": "src/ui/action.zod.ts#normalizeInlineAction (function)", "pageForm": "src/ui/page.form.ts#pageForm (const)", + "partitionAssembledViewArtifacts": "src/ui/assembled-views.zod.ts#partitionAssembledViewArtifacts (function)", "reactBlockTagFor": "src/ui/react-blocks.ts#reactBlockTagFor (function)", "reportForm": "src/ui/report.form.ts#reportForm (const)", "reportSelectionOrder": "src/ui/report.zod.ts#reportSelectionOrder (function)", diff --git a/packages/spec/src/stack.zod.ts b/packages/spec/src/stack.zod.ts index 090dd89acc..edec6820f0 100644 --- a/packages/spec/src/stack.zod.ts +++ b/packages/spec/src/stack.zod.ts @@ -249,6 +249,37 @@ export const ObjectStackDefinitionSchema = lazySchema(() => z.object({ // LayoutDispatcher, NavigationBuilder or ThemeProvider ever consumed it). // Author external-user UI with apps/views + positions & permission sets. views: z.array(ViewSchema).optional().describe('List Views'), + /** + * [#5320] MACHINE-ASSEMBLED ONLY — not an authoring surface. + * + * Runtime-assembled manifests (`GET /packages/:id/export`, environment + * artifact bundles) carry their non-container view artifacts — tenant- + * authored standalone ViewItems, flattened overlays, expanded items a + * travelling container cannot re-derive — under this key, judged by + * `AssembledViewArtifactSchema` (`ui/assembled-views.zod.ts`). Authored + * stack sources never write it: views are authored as `defineView` + * containers in `views:`, and a standalone view is authored through the + * metadata door (Studio / `PUT /api/v1/meta/view`), not in stack source. + * + * Declared here as an always-refusing key — the `retiredKey()` mechanism, + * applied to a key that is machine-only rather than removed — for the same + * reason the tombstones exist (#3855): this schema is not `.strict()`, so an + * UNDECLARED `viewItems:` would be silently stripped and the author would + * learn nothing. Declared-refusing, the mistake fails `tsc` (input type + * `never`) and the parse refusal carries the prescription itself. + */ + viewItems: z.never({ + error: () => + '`viewItems` is the machine-assembled channel for non-container view artifacts in ' + + 'runtime-assembled manifests (package export, environment artifacts) — it is not an ' + + 'authoring surface. Author views as `defineView` containers in `views:`; author a ' + + 'standalone view through the metadata door (Studio / `PUT /api/v1/meta/view`) instead ' + + 'of stack source.', + }).optional().describe( + '[MACHINE-ASSEMBLED] Non-container view artifacts of a runtime-assembled manifest ' + + '(standalone ViewItems, flattened overlays) — written by package export and artifact ' + + 'factories, refused in authored stack sources (#5320).', + ), pages: z.array(PageSchema).optional().describe('Custom Pages'), dashboards: z.array(DashboardSchema).optional().describe('Dashboards'), reports: z.array(ReportSchema).optional().describe('Analytics Reports'), @@ -1674,6 +1705,11 @@ const COMPOSE_KEY_DISPOSITIONS: Record { + it('accepts an expanded viewKind item (what the ADR-0017 dual-read exports)', () => { + const [expanded] = expandViewContainer('account', CONTAINER); + expect(expanded.viewKind).toBe('list'); + const r = AssembledViewArtifactSchema.safeParse(expanded); + expect(r.success, JSON.stringify((r as { error?: unknown }).error)).toBe(true); + }); + + it('accepts a tenant-authored standalone ViewItem (vocabulary branch 1)', () => { + const r = AssembledViewArtifactSchema.safeParse(STANDALONE_ITEM); + expect(r.success, JSON.stringify((r as { error?: unknown }).error)).toBe(true); + }); + + it('accepts a flattened list overlay (vocabulary branch 3)', () => { + const r = AssembledViewArtifactSchema.safeParse({ + name: 'account.default', + object: 'account', + viewKind: 'list', + type: 'grid', + columns: ['name'], + isPinned: true, + }); + expect(r.success, JSON.stringify((r as { error?: unknown }).error)).toBe(true); + }); + + it('accepts a flattened form overlay (vocabulary branch 4)', () => { + const r = AssembledViewArtifactSchema.safeParse({ + name: 'account.form', + object: 'account', + viewKind: 'form', + type: 'simple', + sections: [{ label: 'Details', fields: [{ field: 'name' }] }], + }); + expect(r.success, JSON.stringify((r as { error?: unknown }).error)).toBe(true); + }); + + it('refuses a container — containers travel in `views:`, not `viewItems:`', () => { + expect(AssembledViewArtifactSchema.safeParse(CONTAINER).success).toBe(false); + }); + + it('refuses a bag that speaks no view vocabulary', () => { + expect(AssembledViewArtifactSchema.safeParse({ nope: 1 }).success).toBe(false); + }); +}); + +describe('partitionAssembledViewArtifacts — re-aggregation where a container exists', () => { + it('folds the minimal single-container export set to the container alone', () => { + // What the registry holds after registering CONTAINER: the container under + // the bare object key AND its expanded items (dual-read) — the exact 3-entry + // set the fork's probe read back from `getMetaItems('view', pkg)`. + const expanded = expandViewContainer('account', CONTAINER); + expect(expanded.map((v) => v.name).sort()).toEqual(['account.default', 'account.form']); + + const { views, viewItems, folded } = partitionAssembledViewArtifacts([ + CONTAINER, + ...(expanded as unknown as Record[]), + ]); + expect(views).toEqual([CONTAINER]); + expect(viewItems).toEqual([]); + expect(folded.sort()).toEqual(['account.default', 'account.form']); + }); + + it('keeps a standalone ViewItem — no container to re-aggregate from', () => { + const { views, viewItems, folded } = partitionAssembledViewArtifacts([ + CONTAINER, + STANDALONE_ITEM as unknown as Record, + ]); + expect(views).toEqual([CONTAINER]); + expect(viewItems).toEqual([STANDALONE_ITEM]); + expect(folded).toEqual([]); + }); + + it('keeps an expanded item whose stored body DIVERGED from its container', () => { + // A tenant edited the expanded item after registration: folding it away + // would silently revert the edit on the next import. It must travel. + const [expandedList] = expandViewContainer('account', CONTAINER); + const edited = { + ...(expandedList as unknown as Record), + config: { type: 'grid', columns: ['name', 'industry'], data: DATA }, + }; + const { viewItems, folded } = partitionAssembledViewArtifacts([CONTAINER, edited]); + expect(viewItems).toEqual([edited]); + expect(folded).toEqual([]); + }); + + it('keeps a personalised expanded item (round-trip keys are payload, not noise)', () => { + const [expandedList] = expandViewContainer('account', CONTAINER); + const pinned = { ...(expandedList as unknown as Record), isPinned: true }; + const { viewItems } = partitionAssembledViewArtifacts([CONTAINER, pinned]); + expect(viewItems).toEqual([pinned]); + }); + + it('keeps a flattened overlay', () => { + const overlay = { + name: 'account.default', + object: 'account', + viewKind: 'list', + type: 'grid', + columns: ['name'], + isPinned: true, + }; + const { viewItems } = partitionAssembledViewArtifacts([overlay]); + expect(viewItems).toEqual([overlay]); + }); + + it('classes an EMPTY container as a container, not a viewItem', () => { + // Schema-legal ({} with identity only), registers nothing on expansion — + // but it is container-shaped and must not be smuggled into `viewItems:`, + // where the strict artifact union would refuse it. + const empty = { name: 'account', object: 'account' }; + const { views, viewItems } = partitionAssembledViewArtifacts([empty]); + expect(views).toEqual([empty]); + expect(viewItems).toEqual([]); + }); +}); + +describe('authored `viewItems:` is refused loudly (machine-assembled only)', () => { + it('names the channel and the prescription in the refusal', () => { + const r = ObjectStackDefinitionSchema.safeParse({ + manifest: { id: 'com.test.app', name: 'test', version: '1.0.0', type: 'app' }, + [ASSEMBLED_VIEW_ITEMS_KEY]: [STANDALONE_ITEM], + }); + expect(r.success).toBe(false); + const issue = (r as { error: { issues: Array<{ path: unknown[]; message: string }> } }).error + .issues.find((i) => i.path[0] === ASSEMBLED_VIEW_ITEMS_KEY); + expect(issue, 'refusal must be located at the `viewItems` key').toBeTruthy(); + expect(issue!.message).toContain('machine-assembled'); + expect(issue!.message).toContain('defineView'); + expect(issue!.message).toContain('metadata door'); + }); + + it('does not disturb a well-formed authored stack (containers in `views:`)', () => { + const r = ObjectStackDefinitionSchema.safeParse({ + manifest: { id: 'com.test.app', name: 'test', version: '1.0.0', type: 'app' }, + views: [CONTAINER], + }); + expect(r.success, JSON.stringify((r as { error?: unknown }).error)).toBe(true); + }); +}); diff --git a/packages/spec/src/ui/assembled-views.zod.ts b/packages/spec/src/ui/assembled-views.zod.ts new file mode 100644 index 0000000000..a70a4691a0 --- /dev/null +++ b/packages/spec/src/ui/assembled-views.zod.ts @@ -0,0 +1,224 @@ +// Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. + +/** + * [#5320/#8070] The declared, portable home for NON-container view artifacts in + * runtime-ASSEMBLED manifests — the `viewItems:` channel. + * + * ## The gap this closes (measured on #5320, ruled 2026-08-12) + * + * Two view vocabularies are declared: the stack manifest's `views:` collection + * accepts CONTAINERS only (`stack.zod.ts`, `z.array(ViewSchema)`), while the + * `view` METADATA door accepts four branches ({@link ViewMetadataSchema} — + * standalone ViewItem records, containers, and the two flattened overlays). + * Manifests the platform assembles at runtime FROM metadata-door artifacts — + * `GET /packages/:id/export` and the cloud env-artifact boot bundle — therefore + * carry entries the stack vocabulary refuses: expanded `viewKind` items (the + * ADR-0017 dual-read keeps them registered beside their container), tenant- + * authored standalone ViewItems, and flattened overlays. Measured by execution, + * 2 of 3 exported entries in the minimal single-container case are refused by + * the stack schema; the round trip worked only through the registration loop's + * UNDECLARED wider acceptance — exactly the runtime-wider hole #5320 records. + * + * The 2026-08-12 fork ruling (option B plus A's mechanical half) closes it by + * DECLARING the bridge instead of keeping it silent: + * + * 1. **This module (B):** an assembled manifest carries its non-container view + * artifacts under the {@link ASSEMBLED_VIEW_ITEMS_KEY} collection, each + * entry judged by {@link AssembledViewArtifactSchema} — strictly schema'd, + * no passthrough bags. + * 2. **Producers (A's mechanical half):** export/artifact factories fold + * expanded items back into their containers where a container exists + * ({@link partitionAssembledViewArtifacts}); only items no container can + * re-derive travel in `viewItems:`. + * 3. **The runtime loop then tightens** `views:` to the declared container-only + * contract, refusing loudly with the wrap-it prescription. + * + * ## `viewItems:` is MACHINE-ASSEMBLED, not a second authoring spelling + * + * The decision is refuse-loudly, documented here and enforced in + * `stack.zod.ts`: an author writing `viewItems:` in `defineStack` source gets a + * named rejection with the prescription (author containers in `views:`; + * standalone views are authored through the metadata door), and `z.input` types + * the key `never` so `tsc` refuses first. Rationale, on the three ruling axes: + * no measured authoring pull exists for pre-expanded items in stack source + * (every in-tree stack authors containers); a hand-written expansion would be a + * SECOND spelling of the container it duplicates, drifting from it silently — + * the exact class of AI-authoring mistake strict schemas exist to prevent; and + * the 2026-08-12 11:15Z ruling forbids widening the authored stack surface. + * + * ## Why the producer helper lives in `packages/spec` + * + * Same precedent as {@link expandViewContainer} (this directory): logic that + * two independent codebases must agree on byte-for-byte belongs beside the + * schema it serves, so the producers cannot drift. The partition is the exact + * inverse of the expansion the registration loop performs — deciding "is this + * item re-derivable from its container?" requires running THE expansion, not a + * re-implementation of it. + */ + +import { z } from 'zod'; +import { lazySchema } from '../shared/lazy-schema'; +import { + VIEW_METADATA_BRANCHES, + VIEW_METADATA_MEMBERS, + expandViewContainer, + isAggregatedViewContainer, +} from './view.zod'; + +/** + * The manifest key runtime-assembled manifests carry non-container view + * artifacts under. Declared as a constant so producers (package export, the + * artifact factories) and the consumer (the ObjectQL registration loop) name + * one key instead of four string literals. + */ +export const ASSEMBLED_VIEW_ITEMS_KEY = 'viewItems' as const; + +/** + * One entry of an assembled manifest's `viewItems:` collection — the + * NON-container branches of the `view` metadata vocabulary, and nothing else. + * + * Built by mapping {@link VIEW_METADATA_BRANCHES} minus `container` over + * {@link VIEW_METADATA_MEMBERS}, so this union cannot drift from the metadata + * door's own members: an artifact legal at the metadata door (standalone + * ViewItem, flattened list/form overlay) is legal here BY CONSTRUCTION, and a + * container is not — containers travel in `views:`, where the stack vocabulary + * has always put them. The members are the WIRE variants (`.strip()`), so + * Studio round-trip keys survive and undeclared bags do not. + */ +export const AssembledViewArtifactSchema = lazySchema(() => { + const members = VIEW_METADATA_BRANCHES + .filter((branch) => branch !== 'container') + .map((branch) => VIEW_METADATA_MEMBERS[branch]); + return z.union(members as unknown as readonly [z.ZodTypeAny, z.ZodTypeAny, ...z.ZodTypeAny[]]) + .describe( + 'A non-container view artifact travelling in a runtime-assembled manifest\'s `viewItems:` ' + + 'collection: a ViewItem record (`viewKind` + `config`), or a flattened list/form overlay. ' + + 'Machine-assembled (package export, environment artifacts) — authored stack sources carry ' + + 'containers in `views:` instead.', + ); +}); + +/** One assembled `viewItems:` entry (input shape). */ +export type AssembledViewArtifact = z.input; +/** Post-parse shape of {@link AssembledViewArtifact} — defaults applied, transforms run (ADR-0122). */ +export type AssembledViewArtifactParsed = z.infer; + +/** Result of {@link partitionAssembledViewArtifacts}. */ +export interface AssembledViewPartition { + /** Container documents — the assembled manifest's `views:` collection. */ + views: Record[]; + /** Non-container artifacts no exported container re-derives — `viewItems:`. */ + viewItems: Record[]; + /** + * Names of expanded items DROPPED because an exported container re-derives + * them byte-for-byte (the re-aggregation): the import side's expansion of + * that container reproduces each, so carrying them too would register every + * view twice and fork the container's authority over its own views. + */ + folded: string[]; +} + +/** Keys the expansion/registration machinery stamps that carry no authored + * content — excluded from the derivability comparison on both sides. */ +const MECHANICAL_KEYS = new Set(['order', 'scope', '_diagnostics']); + +/** Deep structural equality; object keys unordered, arrays ordered. */ +function deepEqual(a: unknown, b: unknown): boolean { + if (a === b) return true; + if (Array.isArray(a) || Array.isArray(b)) { + if (!Array.isArray(a) || !Array.isArray(b) || a.length !== b.length) return false; + return a.every((v, i) => deepEqual(v, b[i])); + } + if (a && b && typeof a === 'object' && typeof b === 'object') { + const ka = Object.keys(a as object); + const kb = Object.keys(b as object); + if (ka.length !== kb.length) return false; + return ka.every((k) => + Object.prototype.hasOwnProperty.call(b, k) + && deepEqual((a as Record)[k], (b as Record)[k]), + ); + } + return false; +} + +/** The comparable projection of an item: mechanical keys dropped, `isDefault` + * normalised (absent ≡ `false` — the expansion stamps it only on winners). */ +function comparable(item: Record): Record { + const out: Record = {}; + for (const [k, v] of Object.entries(item)) { + if (MECHANICAL_KEYS.has(k) || v === undefined) continue; + out[k] = v; + } + if (!out.isDefault) delete out.isDefault; + return out; +} + +/** + * True for a view artifact of CONTAINER shape — including the empty container + * (`{ name }`, schema-legal, registers nothing). {@link isAggregatedViewContainer} + * answers "does this container carry views to expand?", which is false for an + * empty container; classification for travel needs the shape question instead: + * anything that is not a ViewItem record (`viewKind`/`config`) and carries no + * inline view-config fingerprint is a container document. + */ +function isContainerShaped(item: Record): boolean { + if (isAggregatedViewContainer(item)) return true; + if (item.viewKind != null || item.config != null) return false; + // Flattened overlays put single-view config keys at the top level. + return !['type', 'columns', 'sections', 'data', 'filter', 'sort'].some((k) => k in item); +} + +/** + * Partition one package's view artifacts for manifest assembly — A's + * mechanical half of the #5320 fork ruling, shared by every producer. + * + * Containers go to `views:`. Every other artifact is judged individually + * against the containers travelling WITH it: an expanded item that the import + * side's own expansion of its container will reproduce EXACTLY (same name, + * same authored payload — mechanical `order`/`scope`/`_diagnostics` excluded, + * personalisation keys like `isPinned` included, so a personalised or edited + * item is never folded away) is dropped as derivable and reported in `folded`; + * everything else — tenant-authored standalone ViewItems, flattened overlays, + * expanded items whose stored body has since diverged from their container — + * travels in `viewItems:`. + * + * Pure over its input: items are not mutated, and the caller owns any + * provenance stripping (`_`-prefixed keys) before partitioning. + */ +export function partitionAssembledViewArtifacts( + items: readonly Record[], +): AssembledViewPartition { + const views: Record[] = []; + const rest: Record[] = []; + for (const item of items) { + if (item && typeof item === 'object' && isContainerShaped(item)) views.push(item); + else rest.push(item); + } + + // Expand each travelling container ONCE, exactly as the registration loop + // will on import (same helper, same base name), and index by expanded name. + const derivable = new Map>(); + for (const container of views) { + const base = typeof container.name === 'string' && container.name + ? container.name + : typeof container.object === 'string' ? container.object : undefined; + if (!base) continue; + for (const expanded of expandViewContainer(base, container)) { + derivable.set(expanded.name, comparable(expanded as unknown as Record)); + } + } + + const viewItems: Record[] = []; + const folded: string[] = []; + for (const item of rest) { + const name = item && typeof item === 'object' && typeof item.name === 'string' ? item.name : undefined; + const twin = name ? derivable.get(name) : undefined; + if (twin && deepEqual(comparable(item), twin)) { + folded.push(name as string); + continue; + } + viewItems.push(item); + } + + return { views, viewItems, folded }; +} diff --git a/packages/spec/src/ui/index.ts b/packages/spec/src/ui/index.ts index 633e84b375..51bc61bf76 100644 --- a/packages/spec/src/ui/index.ts +++ b/packages/spec/src/ui/index.ts @@ -21,6 +21,9 @@ export * from './responsive.zod'; export * from './app.zod'; export * from './bulk-action.zod'; export * from './view.zod'; +// [#5320] The assembled-manifest channel for non-container view artifacts — +// the `viewItems:` vocabulary and its producer-side partition helper. +export * from './assembled-views.zod'; export * from './dashboard.zod'; export * from './report.zod'; export * from './dataset.zod'; From 20f39baf883bce722b23bb7828bf0003fd6df5c0 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 13 Aug 2026 21:38:30 +0000 Subject: [PATCH 2/4] feat(spec): export the shared container classifier, ADR-0122 Parsed alias, root re-exports, INVALID_METADATA provenance row (#5320) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - isViewContainerShaped: ONE classifier for producers (partition) and the consumer (the registration loop's views: tighten) — two classifiers would let an assembler emit an entry the importer refuses. - AssembledViewArtifactParsed (ADR-0122 alias convention). - Root index re-exports the assembled-views vocabulary (the engine imports from the package root). - ERROR_CODE_LEDGER: INVALID_METADATA provenance row under @objectstack/objectql (third emitter — the views: tighten and the viewItems: channel refuse 422). Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_012MNV7ZSCjNfA38eDCjsXQL --- packages/spec/api-surface/root.json | 7 +++++++ packages/spec/api-surface/ui.json | 2 ++ packages/spec/export-origins/root.json | 7 +++++++ packages/spec/export-origins/ui.json | 2 ++ .../spec/src/api/error-code-ledger.zod.ts | 6 ++++++ packages/spec/src/index.ts | 10 ++++++++++ packages/spec/src/ui/assembled-views.zod.ts | 19 ++++++++++++++----- 7 files changed, 48 insertions(+), 5 deletions(-) diff --git a/packages/spec/api-surface/root.json b/packages/spec/api-surface/root.json index 5b1d1cdba1..a32100f87b 100644 --- a/packages/spec/api-surface/root.json +++ b/packages/spec/api-surface/root.json @@ -4,9 +4,14 @@ "exports": [ "ADMIN_FULL_ACCESS (const)", "ALL_CONVERSIONS (const)", + "ASSEMBLED_VIEW_ITEMS_KEY (const)", "AUDIENCE_ANCHOR_POSITIONS (const)", "Agent (type)", "ApplyConversionsOptions (interface)", + "AssembledViewArtifact (type)", + "AssembledViewArtifactParsed (type)", + "AssembledViewArtifactSchema (const)", + "AssembledViewPartition (interface)", "AuthoringKeySurface (type)", "BUILTIN_IDENTITY_METADATA (const)", "BUILTIN_IDENTITY_NAMES (const)", @@ -166,6 +171,7 @@ "formatZodIssue (function)", "isAggregatedViewContainer (function)", "isKnownPlatformCapability (function)", + "isViewContainerShaped (function)", "lintUnknownAuthoringKeys (function)", "lintUnknownKeysAgainstSchema (function)", "lintUnknownStackKeys (function)", @@ -175,6 +181,7 @@ "normalizePluginMetadata (function)", "normalizeStackInput (function)", "objectStackErrorMap (const)", + "partitionAssembledViewArtifacts (function)", "safeParsePretty (function)", "suggestFieldType (function)", "tmpl (function)" diff --git a/packages/spec/api-surface/ui.json b/packages/spec/api-surface/ui.json index 7e343df25c..622af79287 100644 --- a/packages/spec/api-surface/ui.json +++ b/packages/spec/api-surface/ui.json @@ -44,6 +44,7 @@ "AriaProps (type)", "AriaPropsSchema (const)", "AssembledViewArtifact (type)", + "AssembledViewArtifactParsed (type)", "AssembledViewArtifactSchema (const)", "AssembledViewPartition (interface)", "BorderRadius (type)", @@ -413,6 +414,7 @@ "isActionParamValuePresent (function)", "isAggregatedViewContainer (function)", "isRecordContextBlockType (function)", + "isViewContainerShaped (function)", "normalizeFilterOperator (function)", "normalizeInlineAction (function)", "pageForm (const)", diff --git a/packages/spec/export-origins/root.json b/packages/spec/export-origins/root.json index f19f74d0ae..f256024404 100644 --- a/packages/spec/export-origins/root.json +++ b/packages/spec/export-origins/root.json @@ -4,9 +4,14 @@ "exports": { "ADMIN_FULL_ACCESS": "src/identity/eval-user.zod.ts#ADMIN_FULL_ACCESS (const)", "ALL_CONVERSIONS": "src/conversions/registry.ts#ALL_CONVERSIONS (const)", + "ASSEMBLED_VIEW_ITEMS_KEY": "src/ui/assembled-views.zod.ts#ASSEMBLED_VIEW_ITEMS_KEY (const)", "AUDIENCE_ANCHOR_POSITIONS": "src/identity/position.zod.ts#AUDIENCE_ANCHOR_POSITIONS (const)", "Agent": "src/ai/agent.zod.ts#Agent (type)", "ApplyConversionsOptions": "src/conversions/apply.ts#ApplyConversionsOptions (interface)", + "AssembledViewArtifact": "src/ui/assembled-views.zod.ts#AssembledViewArtifact (type)", + "AssembledViewArtifactParsed": "src/ui/assembled-views.zod.ts#AssembledViewArtifactParsed (type)", + "AssembledViewArtifactSchema": "src/ui/assembled-views.zod.ts#AssembledViewArtifactSchema (const)", + "AssembledViewPartition": "src/ui/assembled-views.zod.ts#AssembledViewPartition (interface)", "AuthoringKeySurface": "src/data/authoring-key-lint.ts#AuthoringKeySurface (type)", "BUILTIN_IDENTITY_METADATA": "src/identity/eval-user.zod.ts#BUILTIN_IDENTITY_METADATA (const)", "BUILTIN_IDENTITY_NAMES": "src/identity/eval-user.zod.ts#BUILTIN_IDENTITY_NAMES (const)", @@ -166,6 +171,7 @@ "formatZodIssue": "src/shared/error-map.zod.ts#formatZodIssue (function)", "isAggregatedViewContainer": "src/ui/view.zod.ts#isAggregatedViewContainer (function)", "isKnownPlatformCapability": "src/kernel/platform-capabilities.ts#isKnownPlatformCapability (function)", + "isViewContainerShaped": "src/ui/assembled-views.zod.ts#isViewContainerShaped (function)", "lintUnknownAuthoringKeys": "src/kernel/metadata-authoring-lint.ts#lintUnknownAuthoringKeys (function)", "lintUnknownKeysAgainstSchema": "src/kernel/metadata-authoring-lint.ts#lintUnknownKeysAgainstSchema (function)", "lintUnknownStackKeys": "src/kernel/metadata-authoring-lint.ts#lintUnknownStackKeys (function)", @@ -175,6 +181,7 @@ "normalizePluginMetadata": "src/shared/metadata-collection.zod.ts#normalizePluginMetadata (function)", "normalizeStackInput": "src/shared/metadata-collection.zod.ts#normalizeStackInput (function)", "objectStackErrorMap": "src/shared/error-map.zod.ts#objectStackErrorMap (const)", + "partitionAssembledViewArtifacts": "src/ui/assembled-views.zod.ts#partitionAssembledViewArtifacts (function)", "safeParsePretty": "src/shared/error-map.zod.ts#safeParsePretty (function)", "suggestFieldType": "src/shared/suggestions.zod.ts#suggestFieldType (function)", "tmpl": "src/shared/expression.zod.ts#tmpl (function)" diff --git a/packages/spec/export-origins/ui.json b/packages/spec/export-origins/ui.json index 0de4cbd73a..7caa4ae5d0 100644 --- a/packages/spec/export-origins/ui.json +++ b/packages/spec/export-origins/ui.json @@ -44,6 +44,7 @@ "AriaProps": "src/ui/i18n.zod.ts#AriaProps (type)", "AriaPropsSchema": "src/ui/i18n.zod.ts#AriaPropsSchema (const)", "AssembledViewArtifact": "src/ui/assembled-views.zod.ts#AssembledViewArtifact (type)", + "AssembledViewArtifactParsed": "src/ui/assembled-views.zod.ts#AssembledViewArtifactParsed (type)", "AssembledViewArtifactSchema": "src/ui/assembled-views.zod.ts#AssembledViewArtifactSchema (const)", "AssembledViewPartition": "src/ui/assembled-views.zod.ts#AssembledViewPartition (interface)", "BorderRadius": "src/ui/theme.zod.ts#BorderRadius (type)", @@ -413,6 +414,7 @@ "isActionParamValuePresent": "src/ui/action-params.zod.ts#isActionParamValuePresent (function)", "isAggregatedViewContainer": "src/ui/view.zod.ts#isAggregatedViewContainer (function)", "isRecordContextBlockType": "src/ui/react-blocks.ts#isRecordContextBlockType (function)", + "isViewContainerShaped": "src/ui/assembled-views.zod.ts#isViewContainerShaped (function)", "normalizeFilterOperator": "src/ui/view.zod.ts#normalizeFilterOperator (function)", "normalizeInlineAction": "src/ui/action.zod.ts#normalizeInlineAction (function)", "pageForm": "src/ui/page.form.ts#pageForm (const)", diff --git a/packages/spec/src/api/error-code-ledger.zod.ts b/packages/spec/src/api/error-code-ledger.zod.ts index c91aa1baea..99b0cf1962 100644 --- a/packages/spec/src/api/error-code-ledger.zod.ts +++ b/packages/spec/src/api/error-code-ledger.zod.ts @@ -344,6 +344,12 @@ export const ERROR_CODE_LEDGER = { 'ERR_BULK_RESULT_MISMATCH', 'ERR_DATASOURCE_UNAVAILABLE', 'ERR_DRIVER_CONNECT', + // [#5320] Third EMITTER of the code (metadata-protocol and plugin-security + // already register it) — the registration loop's `views:` tighten refuses a + // non-container entry, and the `viewItems:` channel refuses an entry the + // assembled vocabulary rejects, both 422/INVALID_METADATA. Provenance, not + // identity, per this file's header. + 'INVALID_METADATA', 'ERR_READONLY_FIELD_REJECTED', // strictReadonlyWrites: the write would strip caller-supplied fields, so it was refused (#5126; since #6437 that covers the primary_key strip too — one code, `drops` carries the per-reason breakdown) 'ERR_SUMMARY_RECOMPUTE', 'VALIDATION_FAILED', diff --git a/packages/spec/src/index.ts b/packages/spec/src/index.ts index b9cf1a5901..2329a483e6 100644 --- a/packages/spec/src/index.ts +++ b/packages/spec/src/index.ts @@ -68,6 +68,16 @@ export * from './stack.zod'; // DX Helper Functions (re-exported for convenience) export { defineView, defineForm, defineViewItem, isAggregatedViewContainer, expandViewContainer, expandViewContainerWithDiagnostics } from './ui/view.zod'; +// [#5320] The assembled-manifest view channel: the `viewItems:` vocabulary, its +// producer-side partition, and the shared container classifier the registration +// loop's `views:` tighten judges by. +export { + ASSEMBLED_VIEW_ITEMS_KEY, + AssembledViewArtifactSchema, + isViewContainerShaped, + partitionAssembledViewArtifacts, +} from './ui/assembled-views.zod'; +export type { AssembledViewArtifact, AssembledViewArtifactParsed, AssembledViewPartition } from './ui/assembled-views.zod'; export type { ExpandedViewItem, ViewKeyCollision, ExpandViewResult } from './ui/view.zod'; export { defineApp } from './ui/app.zod'; export { defineFlow } from './automation/flow.zod'; diff --git a/packages/spec/src/ui/assembled-views.zod.ts b/packages/spec/src/ui/assembled-views.zod.ts index a70a4691a0..1f79dbd99e 100644 --- a/packages/spec/src/ui/assembled-views.zod.ts +++ b/packages/spec/src/ui/assembled-views.zod.ts @@ -160,12 +160,21 @@ function comparable(item: Record): Record { * empty container; classification for travel needs the shape question instead: * anything that is not a ViewItem record (`viewKind`/`config`) and carries no * inline view-config fingerprint is a container document. + * + * EXPORTED because the producers and the consumer must run ONE classifier: the + * partition below routes by it on assembly, and the ObjectQL registration + * loop's `views:` tighten (#5320 step 3) refuses by it on ingestion. Two + * classifiers would let an assembler emit an entry the importer refuses — + * re-opening, one level down, the exact producer/consumer disagreement this + * module exists to close. */ -function isContainerShaped(item: Record): boolean { - if (isAggregatedViewContainer(item)) return true; - if (item.viewKind != null || item.config != null) return false; +export function isViewContainerShaped(item: unknown): boolean { + if (!item || typeof item !== 'object' || Array.isArray(item)) return false; + const rec = item as Record; + if (isAggregatedViewContainer(rec)) return true; + if (rec.viewKind != null || rec.config != null) return false; // Flattened overlays put single-view config keys at the top level. - return !['type', 'columns', 'sections', 'data', 'filter', 'sort'].some((k) => k in item); + return !['type', 'columns', 'sections', 'data', 'filter', 'sort'].some((k) => k in rec); } /** @@ -191,7 +200,7 @@ export function partitionAssembledViewArtifacts( const views: Record[] = []; const rest: Record[] = []; for (const item of items) { - if (item && typeof item === 'object' && isContainerShaped(item)) views.push(item); + if (isViewContainerShaped(item)) views.push(item); else rest.push(item); } From bd6dd7653680c0466f49ec6d52e9a8b2160fbebc Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 13 Aug 2026 21:38:32 +0000 Subject: [PATCH 3/4] merge origin/main (os-regen artifacts taken from main; regeneration follows) --- packages/spec/api-surface/root.json | 7 ------- packages/spec/api-surface/ui.json | 7 ------- packages/spec/export-origins/root.json | 7 ------- packages/spec/export-origins/ui.json | 7 ------- 4 files changed, 28 deletions(-) diff --git a/packages/spec/api-surface/root.json b/packages/spec/api-surface/root.json index a32100f87b..5b1d1cdba1 100644 --- a/packages/spec/api-surface/root.json +++ b/packages/spec/api-surface/root.json @@ -4,14 +4,9 @@ "exports": [ "ADMIN_FULL_ACCESS (const)", "ALL_CONVERSIONS (const)", - "ASSEMBLED_VIEW_ITEMS_KEY (const)", "AUDIENCE_ANCHOR_POSITIONS (const)", "Agent (type)", "ApplyConversionsOptions (interface)", - "AssembledViewArtifact (type)", - "AssembledViewArtifactParsed (type)", - "AssembledViewArtifactSchema (const)", - "AssembledViewPartition (interface)", "AuthoringKeySurface (type)", "BUILTIN_IDENTITY_METADATA (const)", "BUILTIN_IDENTITY_NAMES (const)", @@ -171,7 +166,6 @@ "formatZodIssue (function)", "isAggregatedViewContainer (function)", "isKnownPlatformCapability (function)", - "isViewContainerShaped (function)", "lintUnknownAuthoringKeys (function)", "lintUnknownKeysAgainstSchema (function)", "lintUnknownStackKeys (function)", @@ -181,7 +175,6 @@ "normalizePluginMetadata (function)", "normalizeStackInput (function)", "objectStackErrorMap (const)", - "partitionAssembledViewArtifacts (function)", "safeParsePretty (function)", "suggestFieldType (function)", "tmpl (function)" diff --git a/packages/spec/api-surface/ui.json b/packages/spec/api-surface/ui.json index 622af79287..50d002b23e 100644 --- a/packages/spec/api-surface/ui.json +++ b/packages/spec/api-surface/ui.json @@ -5,7 +5,6 @@ "ACTION_LOCATIONS (const)", "ACTION_PARAM_BUILTIN_KEYS (const)", "AIChatWindowProps (const)", - "ASSEMBLED_VIEW_ITEMS_KEY (const)", "Action (type)", "ActionAi (type)", "ActionAiParsed (type)", @@ -43,10 +42,6 @@ "AppearanceConfigSchema (const)", "AriaProps (type)", "AriaPropsSchema (const)", - "AssembledViewArtifact (type)", - "AssembledViewArtifactParsed (type)", - "AssembledViewArtifactSchema (const)", - "AssembledViewPartition (interface)", "BorderRadius (type)", "BorderRadiusSchema (const)", "BreakpointColumnMap (type)", @@ -414,11 +409,9 @@ "isActionParamValuePresent (function)", "isAggregatedViewContainer (function)", "isRecordContextBlockType (function)", - "isViewContainerShaped (function)", "normalizeFilterOperator (function)", "normalizeInlineAction (function)", "pageForm (const)", - "partitionAssembledViewArtifacts (function)", "reactBlockTagFor (function)", "reportForm (const)", "reportSelectionOrder (function)", diff --git a/packages/spec/export-origins/root.json b/packages/spec/export-origins/root.json index f256024404..f19f74d0ae 100644 --- a/packages/spec/export-origins/root.json +++ b/packages/spec/export-origins/root.json @@ -4,14 +4,9 @@ "exports": { "ADMIN_FULL_ACCESS": "src/identity/eval-user.zod.ts#ADMIN_FULL_ACCESS (const)", "ALL_CONVERSIONS": "src/conversions/registry.ts#ALL_CONVERSIONS (const)", - "ASSEMBLED_VIEW_ITEMS_KEY": "src/ui/assembled-views.zod.ts#ASSEMBLED_VIEW_ITEMS_KEY (const)", "AUDIENCE_ANCHOR_POSITIONS": "src/identity/position.zod.ts#AUDIENCE_ANCHOR_POSITIONS (const)", "Agent": "src/ai/agent.zod.ts#Agent (type)", "ApplyConversionsOptions": "src/conversions/apply.ts#ApplyConversionsOptions (interface)", - "AssembledViewArtifact": "src/ui/assembled-views.zod.ts#AssembledViewArtifact (type)", - "AssembledViewArtifactParsed": "src/ui/assembled-views.zod.ts#AssembledViewArtifactParsed (type)", - "AssembledViewArtifactSchema": "src/ui/assembled-views.zod.ts#AssembledViewArtifactSchema (const)", - "AssembledViewPartition": "src/ui/assembled-views.zod.ts#AssembledViewPartition (interface)", "AuthoringKeySurface": "src/data/authoring-key-lint.ts#AuthoringKeySurface (type)", "BUILTIN_IDENTITY_METADATA": "src/identity/eval-user.zod.ts#BUILTIN_IDENTITY_METADATA (const)", "BUILTIN_IDENTITY_NAMES": "src/identity/eval-user.zod.ts#BUILTIN_IDENTITY_NAMES (const)", @@ -171,7 +166,6 @@ "formatZodIssue": "src/shared/error-map.zod.ts#formatZodIssue (function)", "isAggregatedViewContainer": "src/ui/view.zod.ts#isAggregatedViewContainer (function)", "isKnownPlatformCapability": "src/kernel/platform-capabilities.ts#isKnownPlatformCapability (function)", - "isViewContainerShaped": "src/ui/assembled-views.zod.ts#isViewContainerShaped (function)", "lintUnknownAuthoringKeys": "src/kernel/metadata-authoring-lint.ts#lintUnknownAuthoringKeys (function)", "lintUnknownKeysAgainstSchema": "src/kernel/metadata-authoring-lint.ts#lintUnknownKeysAgainstSchema (function)", "lintUnknownStackKeys": "src/kernel/metadata-authoring-lint.ts#lintUnknownStackKeys (function)", @@ -181,7 +175,6 @@ "normalizePluginMetadata": "src/shared/metadata-collection.zod.ts#normalizePluginMetadata (function)", "normalizeStackInput": "src/shared/metadata-collection.zod.ts#normalizeStackInput (function)", "objectStackErrorMap": "src/shared/error-map.zod.ts#objectStackErrorMap (const)", - "partitionAssembledViewArtifacts": "src/ui/assembled-views.zod.ts#partitionAssembledViewArtifacts (function)", "safeParsePretty": "src/shared/error-map.zod.ts#safeParsePretty (function)", "suggestFieldType": "src/shared/suggestions.zod.ts#suggestFieldType (function)", "tmpl": "src/shared/expression.zod.ts#tmpl (function)" diff --git a/packages/spec/export-origins/ui.json b/packages/spec/export-origins/ui.json index 7caa4ae5d0..cbb13402d7 100644 --- a/packages/spec/export-origins/ui.json +++ b/packages/spec/export-origins/ui.json @@ -5,7 +5,6 @@ "ACTION_LOCATIONS": "src/ui/action.zod.ts#ACTION_LOCATIONS (const)", "ACTION_PARAM_BUILTIN_KEYS": "src/ui/action-params.zod.ts#ACTION_PARAM_BUILTIN_KEYS (const)", "AIChatWindowProps": "src/ui/component.zod.ts#AIChatWindowProps (const)", - "ASSEMBLED_VIEW_ITEMS_KEY": "src/ui/assembled-views.zod.ts#ASSEMBLED_VIEW_ITEMS_KEY (const)", "Action": "src/ui/action.zod.ts#Action (type)", "ActionAi": "src/ui/action.zod.ts#ActionAi (type)", "ActionAiParsed": "src/ui/action.zod.ts#ActionAiParsed (type)", @@ -43,10 +42,6 @@ "AppearanceConfigSchema": "src/ui/view.zod.ts#AppearanceConfigSchema (const)", "AriaProps": "src/ui/i18n.zod.ts#AriaProps (type)", "AriaPropsSchema": "src/ui/i18n.zod.ts#AriaPropsSchema (const)", - "AssembledViewArtifact": "src/ui/assembled-views.zod.ts#AssembledViewArtifact (type)", - "AssembledViewArtifactParsed": "src/ui/assembled-views.zod.ts#AssembledViewArtifactParsed (type)", - "AssembledViewArtifactSchema": "src/ui/assembled-views.zod.ts#AssembledViewArtifactSchema (const)", - "AssembledViewPartition": "src/ui/assembled-views.zod.ts#AssembledViewPartition (interface)", "BorderRadius": "src/ui/theme.zod.ts#BorderRadius (type)", "BorderRadiusSchema": "src/ui/theme.zod.ts#BorderRadiusSchema (const)", "BreakpointColumnMap": "src/ui/responsive.zod.ts#BreakpointColumnMap (type)", @@ -414,11 +409,9 @@ "isActionParamValuePresent": "src/ui/action-params.zod.ts#isActionParamValuePresent (function)", "isAggregatedViewContainer": "src/ui/view.zod.ts#isAggregatedViewContainer (function)", "isRecordContextBlockType": "src/ui/react-blocks.ts#isRecordContextBlockType (function)", - "isViewContainerShaped": "src/ui/assembled-views.zod.ts#isViewContainerShaped (function)", "normalizeFilterOperator": "src/ui/view.zod.ts#normalizeFilterOperator (function)", "normalizeInlineAction": "src/ui/action.zod.ts#normalizeInlineAction (function)", "pageForm": "src/ui/page.form.ts#pageForm (const)", - "partitionAssembledViewArtifacts": "src/ui/assembled-views.zod.ts#partitionAssembledViewArtifacts (function)", "reactBlockTagFor": "src/ui/react-blocks.ts#reactBlockTagFor (function)", "reportForm": "src/ui/report.form.ts#reportForm (const)", "reportSelectionOrder": "src/ui/report.zod.ts#reportSelectionOrder (function)", From 81f5fbf1747cd13375d450623e8414174140314f Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 13 Aug 2026 21:42:00 +0000 Subject: [PATCH 4/4] chore(spec): regenerate api-surface/export-origins after merging origin/main (#5320) Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_012MNV7ZSCjNfA38eDCjsXQL --- packages/spec/api-surface/root.json | 7 +++++++ packages/spec/api-surface/ui.json | 7 +++++++ packages/spec/export-origins/root.json | 7 +++++++ packages/spec/export-origins/ui.json | 7 +++++++ 4 files changed, 28 insertions(+) diff --git a/packages/spec/api-surface/root.json b/packages/spec/api-surface/root.json index 5b1d1cdba1..a32100f87b 100644 --- a/packages/spec/api-surface/root.json +++ b/packages/spec/api-surface/root.json @@ -4,9 +4,14 @@ "exports": [ "ADMIN_FULL_ACCESS (const)", "ALL_CONVERSIONS (const)", + "ASSEMBLED_VIEW_ITEMS_KEY (const)", "AUDIENCE_ANCHOR_POSITIONS (const)", "Agent (type)", "ApplyConversionsOptions (interface)", + "AssembledViewArtifact (type)", + "AssembledViewArtifactParsed (type)", + "AssembledViewArtifactSchema (const)", + "AssembledViewPartition (interface)", "AuthoringKeySurface (type)", "BUILTIN_IDENTITY_METADATA (const)", "BUILTIN_IDENTITY_NAMES (const)", @@ -166,6 +171,7 @@ "formatZodIssue (function)", "isAggregatedViewContainer (function)", "isKnownPlatformCapability (function)", + "isViewContainerShaped (function)", "lintUnknownAuthoringKeys (function)", "lintUnknownKeysAgainstSchema (function)", "lintUnknownStackKeys (function)", @@ -175,6 +181,7 @@ "normalizePluginMetadata (function)", "normalizeStackInput (function)", "objectStackErrorMap (const)", + "partitionAssembledViewArtifacts (function)", "safeParsePretty (function)", "suggestFieldType (function)", "tmpl (function)" diff --git a/packages/spec/api-surface/ui.json b/packages/spec/api-surface/ui.json index 50d002b23e..622af79287 100644 --- a/packages/spec/api-surface/ui.json +++ b/packages/spec/api-surface/ui.json @@ -5,6 +5,7 @@ "ACTION_LOCATIONS (const)", "ACTION_PARAM_BUILTIN_KEYS (const)", "AIChatWindowProps (const)", + "ASSEMBLED_VIEW_ITEMS_KEY (const)", "Action (type)", "ActionAi (type)", "ActionAiParsed (type)", @@ -42,6 +43,10 @@ "AppearanceConfigSchema (const)", "AriaProps (type)", "AriaPropsSchema (const)", + "AssembledViewArtifact (type)", + "AssembledViewArtifactParsed (type)", + "AssembledViewArtifactSchema (const)", + "AssembledViewPartition (interface)", "BorderRadius (type)", "BorderRadiusSchema (const)", "BreakpointColumnMap (type)", @@ -409,9 +414,11 @@ "isActionParamValuePresent (function)", "isAggregatedViewContainer (function)", "isRecordContextBlockType (function)", + "isViewContainerShaped (function)", "normalizeFilterOperator (function)", "normalizeInlineAction (function)", "pageForm (const)", + "partitionAssembledViewArtifacts (function)", "reactBlockTagFor (function)", "reportForm (const)", "reportSelectionOrder (function)", diff --git a/packages/spec/export-origins/root.json b/packages/spec/export-origins/root.json index f19f74d0ae..f256024404 100644 --- a/packages/spec/export-origins/root.json +++ b/packages/spec/export-origins/root.json @@ -4,9 +4,14 @@ "exports": { "ADMIN_FULL_ACCESS": "src/identity/eval-user.zod.ts#ADMIN_FULL_ACCESS (const)", "ALL_CONVERSIONS": "src/conversions/registry.ts#ALL_CONVERSIONS (const)", + "ASSEMBLED_VIEW_ITEMS_KEY": "src/ui/assembled-views.zod.ts#ASSEMBLED_VIEW_ITEMS_KEY (const)", "AUDIENCE_ANCHOR_POSITIONS": "src/identity/position.zod.ts#AUDIENCE_ANCHOR_POSITIONS (const)", "Agent": "src/ai/agent.zod.ts#Agent (type)", "ApplyConversionsOptions": "src/conversions/apply.ts#ApplyConversionsOptions (interface)", + "AssembledViewArtifact": "src/ui/assembled-views.zod.ts#AssembledViewArtifact (type)", + "AssembledViewArtifactParsed": "src/ui/assembled-views.zod.ts#AssembledViewArtifactParsed (type)", + "AssembledViewArtifactSchema": "src/ui/assembled-views.zod.ts#AssembledViewArtifactSchema (const)", + "AssembledViewPartition": "src/ui/assembled-views.zod.ts#AssembledViewPartition (interface)", "AuthoringKeySurface": "src/data/authoring-key-lint.ts#AuthoringKeySurface (type)", "BUILTIN_IDENTITY_METADATA": "src/identity/eval-user.zod.ts#BUILTIN_IDENTITY_METADATA (const)", "BUILTIN_IDENTITY_NAMES": "src/identity/eval-user.zod.ts#BUILTIN_IDENTITY_NAMES (const)", @@ -166,6 +171,7 @@ "formatZodIssue": "src/shared/error-map.zod.ts#formatZodIssue (function)", "isAggregatedViewContainer": "src/ui/view.zod.ts#isAggregatedViewContainer (function)", "isKnownPlatformCapability": "src/kernel/platform-capabilities.ts#isKnownPlatformCapability (function)", + "isViewContainerShaped": "src/ui/assembled-views.zod.ts#isViewContainerShaped (function)", "lintUnknownAuthoringKeys": "src/kernel/metadata-authoring-lint.ts#lintUnknownAuthoringKeys (function)", "lintUnknownKeysAgainstSchema": "src/kernel/metadata-authoring-lint.ts#lintUnknownKeysAgainstSchema (function)", "lintUnknownStackKeys": "src/kernel/metadata-authoring-lint.ts#lintUnknownStackKeys (function)", @@ -175,6 +181,7 @@ "normalizePluginMetadata": "src/shared/metadata-collection.zod.ts#normalizePluginMetadata (function)", "normalizeStackInput": "src/shared/metadata-collection.zod.ts#normalizeStackInput (function)", "objectStackErrorMap": "src/shared/error-map.zod.ts#objectStackErrorMap (const)", + "partitionAssembledViewArtifacts": "src/ui/assembled-views.zod.ts#partitionAssembledViewArtifacts (function)", "safeParsePretty": "src/shared/error-map.zod.ts#safeParsePretty (function)", "suggestFieldType": "src/shared/suggestions.zod.ts#suggestFieldType (function)", "tmpl": "src/shared/expression.zod.ts#tmpl (function)" diff --git a/packages/spec/export-origins/ui.json b/packages/spec/export-origins/ui.json index cbb13402d7..7caa4ae5d0 100644 --- a/packages/spec/export-origins/ui.json +++ b/packages/spec/export-origins/ui.json @@ -5,6 +5,7 @@ "ACTION_LOCATIONS": "src/ui/action.zod.ts#ACTION_LOCATIONS (const)", "ACTION_PARAM_BUILTIN_KEYS": "src/ui/action-params.zod.ts#ACTION_PARAM_BUILTIN_KEYS (const)", "AIChatWindowProps": "src/ui/component.zod.ts#AIChatWindowProps (const)", + "ASSEMBLED_VIEW_ITEMS_KEY": "src/ui/assembled-views.zod.ts#ASSEMBLED_VIEW_ITEMS_KEY (const)", "Action": "src/ui/action.zod.ts#Action (type)", "ActionAi": "src/ui/action.zod.ts#ActionAi (type)", "ActionAiParsed": "src/ui/action.zod.ts#ActionAiParsed (type)", @@ -42,6 +43,10 @@ "AppearanceConfigSchema": "src/ui/view.zod.ts#AppearanceConfigSchema (const)", "AriaProps": "src/ui/i18n.zod.ts#AriaProps (type)", "AriaPropsSchema": "src/ui/i18n.zod.ts#AriaPropsSchema (const)", + "AssembledViewArtifact": "src/ui/assembled-views.zod.ts#AssembledViewArtifact (type)", + "AssembledViewArtifactParsed": "src/ui/assembled-views.zod.ts#AssembledViewArtifactParsed (type)", + "AssembledViewArtifactSchema": "src/ui/assembled-views.zod.ts#AssembledViewArtifactSchema (const)", + "AssembledViewPartition": "src/ui/assembled-views.zod.ts#AssembledViewPartition (interface)", "BorderRadius": "src/ui/theme.zod.ts#BorderRadius (type)", "BorderRadiusSchema": "src/ui/theme.zod.ts#BorderRadiusSchema (const)", "BreakpointColumnMap": "src/ui/responsive.zod.ts#BreakpointColumnMap (type)", @@ -409,9 +414,11 @@ "isActionParamValuePresent": "src/ui/action-params.zod.ts#isActionParamValuePresent (function)", "isAggregatedViewContainer": "src/ui/view.zod.ts#isAggregatedViewContainer (function)", "isRecordContextBlockType": "src/ui/react-blocks.ts#isRecordContextBlockType (function)", + "isViewContainerShaped": "src/ui/assembled-views.zod.ts#isViewContainerShaped (function)", "normalizeFilterOperator": "src/ui/view.zod.ts#normalizeFilterOperator (function)", "normalizeInlineAction": "src/ui/action.zod.ts#normalizeInlineAction (function)", "pageForm": "src/ui/page.form.ts#pageForm (const)", + "partitionAssembledViewArtifacts": "src/ui/assembled-views.zod.ts#partitionAssembledViewArtifacts (function)", "reactBlockTagFor": "src/ui/react-blocks.ts#reactBlockTagFor (function)", "reportForm": "src/ui/report.form.ts#reportForm (const)", "reportSelectionOrder": "src/ui/report.zod.ts#reportSelectionOrder (function)",