From 15160c452a6cd4b551cf91a957e48d06285b8d78 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 2 Nov 2026 05:28:56 +0000 Subject: [PATCH 1/8] feat(spec): declare the whole-deployment package export bundle (`GET /packages/export`) `PackageExportBundleSchema` in `@objectstack/spec/api`: `{ packages }`, every installed package but the platform's own (manifest scope `system`), each as `GET /packages/:id/export` answers it, dependencies first (ADR-0141 D5). The entries ARE `PackageExportManifestSchema`, so the per-package export stays the one producer and the bundle composes it. Strict at the top level. Spec slice only: the route, the CLI command and the round-trip tests are the server slice. Claude-Session: https://claude.ai/code/session_01ADHkmScwpkMFTAD5HHubn1 Co-authored-by: Claude --- .../spec/src/api/package-lifecycle.test.ts | 96 +++++++++++++++++++ .../spec/src/api/package-lifecycle.zod.ts | 71 ++++++++++++++ 2 files changed, 167 insertions(+) diff --git a/packages/spec/src/api/package-lifecycle.test.ts b/packages/spec/src/api/package-lifecycle.test.ts index c0f4845849a..8a992d38ba8 100644 --- a/packages/spec/src/api/package-lifecycle.test.ts +++ b/packages/spec/src/api/package-lifecycle.test.ts @@ -16,6 +16,7 @@ import { RevertPackageCommitResponseSchema, RollbackToPackageCommitResponseSchema, PackageExportManifestSchema, + PackageExportBundleSchema, ReassignOrphanedMetadataResponseSchema, DuplicatePackageResponseSchema, PackagePublishResultSchema, @@ -221,6 +222,101 @@ describe('PackageExportManifestSchema declares the four fixed keys and stays ope }); }); +describe('PackageExportBundleSchema declares the whole-deployment export as composed per-package exports (#28914)', () => { + /** + * The bundle the card's done criteria name: a base, its `.custom` pair and a + * third package that extends the base, dependencies first. Each entry is + * shaped as `GET /packages/:id/export` answers it — the pair carries its + * overriding item with the `overrides` block (ADR-0146 D8 item 3), and the + * connector keeps its `credentialRef` as the reference it is. + */ + const bundle = { + packages: [ + { + id: 'com.example.crm', + name: 'example-crm', + version: '2.1.0', + label: 'Example CRM', + objects: [{ name: 'crm_customer', label: 'Customer', fields: { name: { type: 'text' } } }], + views: [{ name: 'crm_customer_list', object: 'crm_customer', type: 'grid' }], + connectors: [{ + name: 'crm_vendor', + label: 'Vendor', + type: 'api', + provider: 'openapi', + providerConfig: { spec: 'https://vendor.example.com/openapi.json' }, + auth: { + type: 'oauth2', + grant: 'client_credentials', + tokenUrl: 'https://vendor.example.com/oauth/token', + clientId: 'client-123', + credentialRef: 'VENDOR_CLIENT_SECRET', + }, + }], + }, + { + id: 'com.example.crm.custom', + name: 'com.example.crm.custom', + version: '1.0.0', + views: [{ + name: 'crm_customer_list', + object: 'crm_customer', + type: 'grid', + overrides: { package: 'com.example.crm', basedOn: '2.1.0' }, + }], + }, + { + id: 'com.example.revenue', + name: 'example-revenue', + version: '1.0.0', + objectExtensions: [{ extend: 'crm_customer', fields: { revenue_tier: { type: 'text' } } }], + }, + ], + }; + + it('parses the bundle and PRESERVES every entry, in the order listed', () => { + const result = PackageExportBundleSchema.safeParse(bundle); + expect(result.success).toBe(true); + if (!result.success) return; + expect(result.data).toEqual(bundle); + expect(result.data.packages.map((entry) => entry.id)).toEqual([ + 'com.example.crm', + 'com.example.crm.custom', + 'com.example.revenue', + ]); + }); + + it('judges each entry by THE per-package export schema — composed, never a second copy', () => { + expect(PackageExportBundleSchema.shape.packages.element).toBe(PackageExportManifestSchema); + const nameless = { packages: [bundle.packages[0], { objects: [] }] }; + const result = PackageExportBundleSchema.safeParse(nameless); + expect(result.success).toBe(false); + if (result.success) return; + expect(result.error.issues.map((issue) => issue.path.join('.'))).toEqual( + expect.arrayContaining(['packages.1.id', 'packages.1.name', 'packages.1.version']), + ); + }); + + it('parses an empty bundle — a deployment that holds only platform packages', () => { + expect(PackageExportBundleSchema.safeParse({ packages: [] }).success).toBe(true); + }); + + it('requires `packages` — an answer with no list is not a bundle', () => { + const result = PackageExportBundleSchema.safeParse({}); + expect(result.success).toBe(false); + if (result.success) return; + expect(result.error.issues[0]?.path).toEqual(['packages']); + }); + + it('is strict at the top level — a member the door starts serving is a change here first', () => { + const result = PackageExportBundleSchema.safeParse({ ...bundle, cycles: [] }); + expect(result.success).toBe(false); + if (result.success) return; + expect(result.error.issues[0]?.code).toBe('unrecognized_keys'); + expect((result.error.issues[0] as { keys?: string[] }).keys).toEqual(['cycles']); + }); +}); + describe('ReassignOrphanedMetadataResponseSchema declares the adopt-orphans body', () => { /** A verbatim-shaped capture of a real `reassignOrphanedMetadata` return. */ const realResponse = { diff --git a/packages/spec/src/api/package-lifecycle.zod.ts b/packages/spec/src/api/package-lifecycle.zod.ts index bae0d604e0f..ad533652c00 100644 --- a/packages/spec/src/api/package-lifecycle.zod.ts +++ b/packages/spec/src/api/package-lifecycle.zod.ts @@ -191,6 +191,74 @@ export const PackageExportManifestSchema = lazySchema(() => z.object({ + 'is registry-derived at runtime and deliberately NOT enumerated here.', ))); +/** + * `GET /packages/export` — the deployment's whole ontology as installable + * packages, in one read (#28914): the exit right that + * {@link PackageExportManifestSchema}'s route grants one package at a time. + * + * Unlike its lifecycle siblings this is not a transcription: the route is new, + * and this declaration is its contract (Clause-②, widening). Served by the + * runtime dispatcher and enveloped like them (`{ success, data }`); this + * schema declares the `data`. + * + * ## One producer + * + * Each entry is exactly what `GET /packages/:id/export` answers for that + * package. The bundle composes the per-package export and never assembles, + * cleans or redacts an item a second way, so the two reads cannot disagree + * about a package. Two consequences are this record's on purpose: + * + * - **A `.custom` pair is its own entry**, carrying its overriding items with + * their `overrides` blocks (ADR-0146 D8 item 3), and its base's entry carries + * the base unchanged. Environment-scope customizations are where the + * per-package export already places them: under the package that owns them. + * - **No credential value leaves.** The per-package export withholds credential + * positions as every served metadata read does, and the bundle adds no rule + * of its own: a `credentialRef` stays the reference it is. + * + * ## Which packages, in which order + * + * Every package the deployment holds, enabled or not, each once, except the + * platform's own: a package whose manifest `scope` is `system` is shipped by + * every runtime for itself, so an install of the bundle never re-installs it. + * A pair of such a base is still exported. A metadata item bound to no package + * is in no entry; ADR-0146 D11's migration binds it to one first. + * + * The order is ADR-0141 D5's, the order a boot hydrates installed packages in: + * dependencies first. An entry comes after every entry its package's + * `manifest.dependencies` names, so a pair comes after its base, and installing + * the entries in the order listed is the whole consumption rule: a consumer + * never re-sorts. Members of a dependency cycle keep the read's listing order + * among themselves, as a boot hydrates them. + * + * ## The door + * + * The read gate is the per-package export's: `studio.access` or `setup.access`, + * or a system context, asked before anything is read. The query set is CLOSED + * and empty: a query parameter is refused `400 VALIDATION_ERROR` naming it. No + * request schema is declared, because the door reads no path id, no body and + * no parameter. `export` can never be a package id (one has at least two + * dot-separated segments, `MANIFEST_ID_PATTERN`), so the path never shadows + * `GET /packages/:id`. + * + * The answer is whole or absent: a package whose export cannot be assembled + * fails the read, naming that package. ⛔ Never a bundle that silently lacks a + * package. Strict at the top level: a member the door starts serving is a + * change to this declaration first. Each entry stays open, as ruled for + * {@link PackageExportManifestSchema}. + */ +export const PackageExportBundleSchema = lazySchema(() => z.object({ + packages: z.array(PackageExportManifestSchema).describe( + 'Every package of the deployment but the platform\'s own (manifest `scope` `system`), each once and each as ' + + '`GET /packages/:id/export` answers it, dependencies first: an entry comes after every entry its package\'s ' + + '`manifest.dependencies` names, so a `.custom` pair comes after its base. Install the entries in this order; ' + + 'never re-sort them. Empty when the deployment holds only platform packages.', + ), +}).strict().describe( + 'Whole-deployment export: every installed package but the platform\'s own, as installable packages in ' + + 'dependency order. Carries no credential value.', +)); + /** * `POST /packages/:id/adopt-orphans` — bulk-rebind package-less (orphaned) * metadata into this base (ADR-0070 D5); the client method is @@ -508,6 +576,9 @@ export type RollbackToPackageCommitResponseParsed = z.infer; /** Post-parse shape of {@link PackageExportManifest} — defaults applied, transforms run (ADR-0122). */ export type PackageExportManifestParsed = z.infer; +export type PackageExportBundle = z.input; +/** Post-parse shape of {@link PackageExportBundle} — defaults applied, transforms run (ADR-0122). */ +export type PackageExportBundleParsed = z.infer; export type ReassignOrphanedMetadataResponse = z.input; /** Post-parse shape of {@link ReassignOrphanedMetadataResponse} — defaults applied, transforms run (ADR-0122). */ export type ReassignOrphanedMetadataResponseParsed = z.infer; From 020adeb08339a2d4c8be7f8aef980d5f6c6711a0 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 2 Nov 2026 05:36:35 +0000 Subject: [PATCH 2/8] chore(spec): regenerate artifacts and add the changeset for the export bundle Regenerated by `check:generated --fix` (5 stale: api-surface, export-origins, declaration-map, references docs, strictness-ledger counts). Claude-Session: https://claude.ai/code/session_01ADHkmScwpkMFTAD5HHubn1 Co-authored-by: Claude --- .changeset/28914-package-export-bundle.md | 14 ++++++++++ .../docs/references/api/package-lifecycle.mdx | 26 +++++++++++++++++-- content/docs/references/index.mdx | 10 +++---- .../api.md | 2 +- packages/spec/api-surface/api.json | 3 +++ packages/spec/authorable-surface/api.json | 1 + packages/spec/declaration-map/api.json | 2 ++ packages/spec/export-origins/api.json | 3 +++ packages/spec/json-schema.manifest/api.json | 1 + 9 files changed, 54 insertions(+), 8 deletions(-) create mode 100644 .changeset/28914-package-export-bundle.md diff --git a/.changeset/28914-package-export-bundle.md b/.changeset/28914-package-export-bundle.md new file mode 100644 index 00000000000..00d82cd5e8e --- /dev/null +++ b/.changeset/28914-package-export-bundle.md @@ -0,0 +1,14 @@ +--- +'@objectstack/spec': minor +--- + +feat(spec): `PackageExportBundleSchema` declares the whole-deployment export, every installed package as installable packages in one read + +Clause-②: yes (widening) +Metadata-protocol: added + +A tenant on ObjectOS Cloud or Enterprise can take its ontology to the Apache-2.0 runtime only one package at a time today (`GET /packages/:id/export`). This declares the contract of the read that answers all of it at once, `GET /packages/export`. The route and the `os package export` command that calls it follow in `@objectstack/runtime` and `@objectstack/cli`; no runtime serves it yet. + +- **`@objectstack/spec`**: `PackageExportBundleSchema` (with `PackageExportBundle` and `PackageExportBundleParsed`) in `@objectstack/spec/api`. The answer is `{ packages }`: every package the deployment holds except the platform's own (manifest `scope: 'system'`, which every runtime ships for itself), each exactly as `GET /packages/:id/export` answers it. The entries are `PackageExportManifestSchema` itself, so the per-package export stays the one producer. A base's `.custom` pair is its own entry with its override declarations, and environment customizations stay under the package that owns them. The bundle carries no credential value: the per-package export withholds credential positions, and a `credentialRef` stays a reference. +- **Order**: dependencies first, the order a boot hydrates installed packages in (ADR-0141 D5). An entry comes after every entry its package's `manifest.dependencies` names, so a pair comes after its base. Install the entries in the order listed; a consumer never re-sorts them. +- The answer is strict at the top level; each entry stays open, as the per-package export is. diff --git a/content/docs/references/api/package-lifecycle.mdx b/content/docs/references/api/package-lifecycle.mdx index 34ff077ecc0..bc2a8aec3e8 100644 --- a/content/docs/references/api/package-lifecycle.mdx +++ b/content/docs/references/api/package-lifecycle.mdx @@ -50,8 +50,8 @@ authored after that retirement per the ruling's sequencing (3A). ## TypeScript Usage ```typescript -import { DiscardPackageDraftsResponseSchema, DuplicatePackageResponseSchema, EnsureCustomizationPackageRequestSchema, EnsureCustomizationPackageResponseSchema, GetPackageCustomizationsRequestSchema, GetPackageCustomizationsResponseSchema, ImportUnmanagedPackageRequestSchema, ImportUnmanagedPackageResponseSchema, ListPackageCommitsResponseSchema, PackageExportManifestSchema, PackagePublishResultSchema, ReassignOrphanedMetadataResponseSchema, RevertPackageCommitResponseSchema, RollbackToPackageCommitResponseSchema } from '@objectstack/spec/api'; -import type { DiscardPackageDraftsResponse, DuplicatePackageResponse, EnsureCustomizationPackageRequest, EnsureCustomizationPackageResponse, GetPackageCustomizationsRequest, GetPackageCustomizationsResponse, ImportUnmanagedPackageRequest, ImportUnmanagedPackageResponse, ListPackageCommitsResponse, PackageExportManifest, PackagePublishResult, ReassignOrphanedMetadataResponse, RevertPackageCommitResponse, RollbackToPackageCommitResponse } from '@objectstack/spec/api'; +import { DiscardPackageDraftsResponseSchema, DuplicatePackageResponseSchema, EnsureCustomizationPackageRequestSchema, EnsureCustomizationPackageResponseSchema, GetPackageCustomizationsRequestSchema, GetPackageCustomizationsResponseSchema, ImportUnmanagedPackageRequestSchema, ImportUnmanagedPackageResponseSchema, ListPackageCommitsResponseSchema, PackageExportBundleSchema, PackageExportManifestSchema, PackagePublishResultSchema, ReassignOrphanedMetadataResponseSchema, RevertPackageCommitResponseSchema, RollbackToPackageCommitResponseSchema } from '@objectstack/spec/api'; +import type { DiscardPackageDraftsResponse, DuplicatePackageResponse, EnsureCustomizationPackageRequest, EnsureCustomizationPackageResponse, GetPackageCustomizationsRequest, GetPackageCustomizationsResponse, ImportUnmanagedPackageRequest, ImportUnmanagedPackageResponse, ListPackageCommitsResponse, PackageExportBundle, PackageExportManifest, PackagePublishResult, ReassignOrphanedMetadataResponse, RevertPackageCommitResponse, RollbackToPackageCommitResponse } from '@objectstack/spec/api'; // Validate data const result = DiscardPackageDraftsResponseSchema.parse(data); @@ -292,6 +292,28 @@ Per-package customization read: overrides, extensions and switched-off items of | **createdAt** | `string` | optional | When the commit was made (ISO-8601 string), when recorded. | +--- + +## PackageExportBundle + +Whole-deployment export: every installed package but the platform's own, as installable packages in dependency order. Carries no credential value. + +### Properties + +| Property | Type | Required | Description | +| :--- | :--- | :--- | :--- | +| **packages** | `({ id: string; name: string; version: string; label?: string } & Record)[]` | ✅ | Every package of the deployment but the platform's own (manifest `scope` `system`), each once and each as `GET /packages/:id/export` answers it, dependencies first: an entry comes after every entry its package's `manifest.dependencies` names, so a `.custom` pair comes after its base. Install the entries in this order; never re-sort them. Empty when the deployment holds only platform packages. | + +### Nested Shape: `PackageExportBundle.packages[number]` + +| Property | Type | Required | Description | +| :--- | :--- | :--- | :--- | +| **id** | `string` | ✅ | The exported package's id. | +| **name** | `string` | ✅ | The exported package's machine name. | +| **version** | `string` | ✅ | The exported package's version. | +| **label** | `string` | optional | Display label, when the package declares one. | + + --- ## PackageExportManifest diff --git a/content/docs/references/index.mdx b/content/docs/references/index.mdx index 74dc8adcecf..cd8ae0647b8 100644 --- a/content/docs/references/index.mdx +++ b/content/docs/references/index.mdx @@ -1,7 +1,7 @@ --- title: Protocol reference — every schema by module navTitle: Protocol Reference -description: Every schema published by @objectstack/spec — 1594 schemas across 14 protocol modules +description: Every schema published by @objectstack/spec — 1595 schemas across 14 protocol modules --- {/* ⚠️ AUTO-GENERATED — DO NOT EDIT. Run build-docs.ts to regenerate. Hand-written docs live in the module folders under content/docs/. */} @@ -21,7 +21,7 @@ counts are sums of the rows they head. Regenerate with | Module | Pages | Schemas | Description | | :--- | ---: | ---: | :--- | | [AI Protocol](/docs/references/ai) | 12 | 68 | Agents, tools, skills, RAG and knowledge sources, model registry, conversations. | -| [API Protocol](/docs/references/api) | 34 | 469 | REST contracts, endpoints, routing, realtime, batch, discovery. | +| [API Protocol](/docs/references/api) | 34 | 470 | REST contracts, endpoints, routing, realtime, batch, discovery. | | [Automation Protocol](/docs/references/automation) | 15 | 78 | Flows and their nodes, approvals, ETL pipelines, webhooks, state machines, execution records. | | [Data Protocol](/docs/references/data) | 31 | 174 | Objects, fields, queries, filters, datasources and drivers — the ObjectQL layer. | | [Identity Protocol](/docs/references/identity) | 5 | 27 | Users and accounts, organizations, positions, SCIM provisioning. | @@ -34,7 +34,7 @@ counts are sums of the rows they head. Regenerate with | [Studio Protocol](/docs/references/studio) | 3 | 35 | Studio designer metadata — the authoring surfaces for the protocols above. | | [System Protocol](/docs/references/system) | 37 | 287 | The runtime environment — logging, jobs, cache, metrics, notifications, i18n and compliance. | | [UI Protocol](/docs/references/ui) | 16 | 175 | Apps, pages, views, dashboards, reports, actions and themes — the ObjectUI layer. | -| **Total** | **205** | **1594** | 14 protocol modules | +| **Total** | **205** | **1595** | 14 protocol modules | --- @@ -63,7 +63,7 @@ Agents, tools, skills, RAG and knowledge sources, model registry, conversations. ## API Protocol -**Source:** `packages/spec/src/api/` · **Import:** `@objectstack/spec/api` · **34 pages, 469 schemas** +**Source:** `packages/spec/src/api/` · **Import:** `@objectstack/spec/api` · **34 pages, 470 schemas** REST contracts, endpoints, routing, realtime, batch, discovery. @@ -90,7 +90,7 @@ REST contracts, endpoints, routing, realtime, batch, discovery. | [`odata.zod.ts`](/docs/references/api/odata) | `ODataConfig`, `ODataError`, `ODataFilterFunction`, `ODataMetadata`, `ODataQuery`, `ODataResponse` | | [`package-api.zod.ts`](/docs/references/api/package-api) | `GetInstalledPackageRequest`, `ListInstalledPackagesRequest`, `PackageApiErrorCode`, `PackageInstallBody`, `PackageInstallManifest`, `PackageInstallRequest`, `PackageInstallResponse`, `PackagePathParams`, `PackageRollbackRequest`, `PackageUpgradeRequest`, `PackageUpgradeResponse`, `ResolveDependenciesRequest`, `ResolveDependenciesResponse`, `UninstallPackageApiRequest`, `UninstallPackageApiResponse`, `UploadArtifactRequest`, `UploadArtifactResponse` | | [`package-api-assembled.zod.ts`](/docs/references/api/package-api-assembled) | `AssembledInstalledPackage`, `GetInstalledPackageResponse`, `InstalledPackageAtEitherStage`, `ListInstalledPackagesResponse` | -| [`package-lifecycle.zod.ts`](/docs/references/api/package-lifecycle) | `DiscardPackageDraftsResponse`, `DuplicatePackageResponse`, `EnsureCustomizationPackageRequest`, `EnsureCustomizationPackageResponse`, `GetPackageCustomizationsRequest`, `GetPackageCustomizationsResponse`, `ImportUnmanagedPackageRequest`, `ImportUnmanagedPackageResponse`, `ListPackageCommitsResponse`, `PackageExportManifest`, `PackagePublishResult`, `ReassignOrphanedMetadataResponse`, `RevertPackageCommitResponse`, `RollbackToPackageCommitResponse` | +| [`package-lifecycle.zod.ts`](/docs/references/api/package-lifecycle) | `DiscardPackageDraftsResponse`, `DuplicatePackageResponse`, `EnsureCustomizationPackageRequest`, `EnsureCustomizationPackageResponse`, `GetPackageCustomizationsRequest`, `GetPackageCustomizationsResponse`, `ImportUnmanagedPackageRequest`, `ImportUnmanagedPackageResponse`, `ListPackageCommitsResponse`, `PackageExportBundle`, `PackageExportManifest`, `PackagePublishResult`, `ReassignOrphanedMetadataResponse`, `RevertPackageCommitResponse`, `RollbackToPackageCommitResponse` | | [`plugin-rest-api.zod.ts`](/docs/references/api/plugin-rest-api) | `ErrorHandlingConfig`, `OpenApiGenerationConfig`, `RequestValidationConfig`, `ResponseEnvelopeConfig`, `RestApiEndpoint`, `RestApiPluginConfig`, `RestApiRouteCategory`, `RestApiRouteRegistration`, `ValidationMode` | | [`protocol.zod.ts`](/docs/references/api/protocol) | `AiAgentCapabilities`, `AiAgentChatRequest`, `AiAgentSummary`, `AiAgentsResponse`, `AiChatRequest`, `AiChatResponse`, `AiCompleteRequest`, `AiConversation`, `AiMessage`, `AiModelsResponse`, `AiPendingAction`, `AiPendingActionStatus`, `AiStreamChunk`, `ApproveAiPendingActionResponse`, `AuditMetaItemRequest`, `AuditMetaItemResponse`, `AutomationActionsResponse`, `AutomationTriggerRequest`, `AutomationTriggerResponse`, `BatchDataRequest`, `BatchDataResponse`, `CheckPermissionRequest`, `CheckPermissionResponse`, `CloneDataResponse`, `CreateAiConversationRequest`, `CreateDataRequest`, `CreateDataResponse`, `CreateManyDataRequest`, `CreateManyDataResponse`, `DeleteDataRequest`, `DeleteDataResponse`, `DeleteManyDataRequest`, `DeleteManyDataResponse`, `DeleteMetaItemRequest`, `DeleteMetaItemResponse`, `DiffMetaItemResponse`, `DisablePackageRequest`, `DisablePackageResponse`, `EnablePackageRequest`, `EnablePackageResponse`, `FindDataRequest`, `FindDataResponse`, `FindReferencesToMetaResponse`, `FlowRegistration`, `FlowRegistrationRefusal`, `GetDataRequest`, `GetDataResponse`, `GetDiscoveryRequest`, `GetDiscoveryResponse`, `GetEffectivePermissionsRequest`, `GetEffectivePermissionsResponse`, `GetFieldLabelsRequest`, `GetFieldLabelsResponse`, `GetLocalesRequest`, `GetLocalesResponse`, `GetMetaDiagnosticsResponse`, `GetMetaItemCachedRequest`, `GetMetaItemCachedResponse`, `GetMetaItemLayeredRequest`, `GetMetaItemLayeredResponse`, `GetMetaItemRequest`, `GetMetaItemResponse`, `GetMetaItemsRequest`, `GetMetaItemsResponse`, `GetMetaTypesRequest`, `GetMetaTypesResponse`, `GetNotificationPreferencesRequest`, `GetNotificationPreferencesResponse`, `GetObjectPermissionsRequest`, `GetObjectPermissionsResponse`, `GetPackageRequest`, `GetPackageResponse`, `GetPresenceRequest`, `GetPresenceResponse`, `GetPublishedMetaItemResponse`, `GetRecordFieldAccessResponse`, `GetTranslationsRequest`, `GetTranslationsResponse`, `GetUiViewRequest`, `GetUiViewResponse`, `HistoryMetaItemRequest`, `HistoryMetaItemResponse`, `HttpFindQueryParams`, `InstallPackageRequest`, `InstallPackageResponse`, `ListAiConversationsRequest`, `ListAiConversationsResponse`, `ListAiPendingActionsRequest`, `ListAiPendingActionsResponse`, `ListDraftsResponse`, `ListNotificationsRequest`, `ListNotificationsResponse`, `ListPackagesRequest`, `ListPackagesResponse`, `MarkAllNotificationsReadRequest`, `MarkAllNotificationsReadResponse`, `MarkNotificationsReadRequest`, `MarkNotificationsReadResponse`, `MetadataAuthoringClient`, `MetadataAuthoringSurface`, `MetadataConflictError`, `Notification`, `NotificationPreferences`, `PublicFormSubmitResponse`, `PublishMetaItemRequest`, `PublishMetaItemResponse`, `PublishPackageDraftsRequest`, `PublishPackageDraftsResponse`, `RealtimeConnectRequest`, `RealtimeConnectResponse`, `RealtimeDisconnectRequest`, `RealtimeDisconnectResponse`, `RealtimeSubscribeRequest`, `RealtimeSubscribeResponse`, `RealtimeUnsubscribeRequest`, `RealtimeUnsubscribeResponse`, `RegisterDeviceRequest`, `RegisterDeviceResponse`, `RejectAiPendingActionResponse`, `RollbackMetaItemResponse`, `RuntimeAuthoringIssue`, `SaveMetaItemRequest`, `SaveMetaItemResponse`, `SearchAllHit`, `SearchAllPageHit`, `SearchAllResponse`, `SetPresenceRequest`, `SetPresenceResponse`, `UninstallPackageRequest`, `UninstallPackageResponse`, `UnregisterDeviceRequest`, `UnregisterDeviceResponse`, `UpdateAiConversationRequest`, `UpdateDataRequest`, `UpdateDataResponse`, `UpdateManyDataRequest`, `UpdateManyDataResponse`, `UpdateNotificationPreferencesRequest`, `UpdateNotificationPreferencesResponse`, `ValidateDataIssue`, `ValidateDataRequest`, `ValidateDataResponse` | | [`query-adapter.zod.ts`](/docs/references/api/query-adapter) | `ODataQueryAdapter`, `OperatorMapping`, `QueryAdapterConfig`, `QueryAdapterTarget`, `RestQueryAdapter` | diff --git a/docs/audits/2026-07-unknown-key-strictness-ledger.counts/api.md b/docs/audits/2026-07-unknown-key-strictness-ledger.counts/api.md index 2c0c689bc41..26026f6c8a3 100644 --- a/docs/audits/2026-07-unknown-key-strictness-ledger.counts/api.md +++ b/docs/audits/2026-07-unknown-key-strictness-ledger.counts/api.md @@ -19,4 +19,4 @@ hand-patch a number here** — fix the code or the verdict and regenerate. | Dir | Sites | |---|---| -| `api/` | 484 | +| `api/` | 485 | diff --git a/packages/spec/api-surface/api.json b/packages/spec/api-surface/api.json index 45fb85e1e06..ad96dc175cc 100644 --- a/packages/spec/api-surface/api.json +++ b/packages/spec/api-surface/api.json @@ -778,6 +778,9 @@ "PROVENANCE_WAIVERS (const)", "PackageApiErrorCode (const)", "PackageApiErrorCode (type)", + "PackageExportBundle (type)", + "PackageExportBundleParsed (type)", + "PackageExportBundleSchema (const)", "PackageExportManifest (type)", "PackageExportManifestParsed (type)", "PackageExportManifestSchema (const)", diff --git a/packages/spec/authorable-surface/api.json b/packages/spec/authorable-surface/api.json index 5281170fcd3..e6ea61bbc56 100644 --- a/packages/spec/authorable-surface/api.json +++ b/packages/spec/authorable-surface/api.json @@ -1300,6 +1300,7 @@ "api/OperatorMapping:odata", "api/OperatorMapping:operator", "api/OperatorMapping:rest", + "api/PackageExportBundle:packages", "api/PackageExportManifest:id", "api/PackageExportManifest:label", "api/PackageExportManifest:name", diff --git a/packages/spec/declaration-map/api.json b/packages/spec/declaration-map/api.json index 7dc7834fd01..3a692ea9d0b 100644 --- a/packages/spec/declaration-map/api.json +++ b/packages/spec/declaration-map/api.json @@ -570,6 +570,8 @@ "OperatorMapping": "api/OperatorMapping", "OperatorMappingSchema": "api/OperatorMapping", "PackageApiErrorCode": "api/PackageApiErrorCode", + "PackageExportBundle": "api/PackageExportBundle", + "PackageExportBundleSchema": "api/PackageExportBundle", "PackageExportManifest": "api/PackageExportManifest", "PackageExportManifestSchema": "api/PackageExportManifest", "PackageInstallBody": "api/PackageInstallBody", diff --git a/packages/spec/export-origins/api.json b/packages/spec/export-origins/api.json index 1644454b500..337aeff56b5 100644 --- a/packages/spec/export-origins/api.json +++ b/packages/spec/export-origins/api.json @@ -750,6 +750,9 @@ "OperatorMappingSchema": "src/api/query-adapter.zod.ts#OperatorMappingSchema (const)", "PROVENANCE_WAIVERS": "src/api/error-code-ledger.zod.ts#PROVENANCE_WAIVERS (const)", "PackageApiErrorCode": "src/api/package-api.zod.ts#PackageApiErrorCode (type)", + "PackageExportBundle": "src/api/package-lifecycle.zod.ts#PackageExportBundle (type)", + "PackageExportBundleParsed": "src/api/package-lifecycle.zod.ts#PackageExportBundleParsed (type)", + "PackageExportBundleSchema": "src/api/package-lifecycle.zod.ts#PackageExportBundleSchema (const)", "PackageExportManifest": "src/api/package-lifecycle.zod.ts#PackageExportManifest (type)", "PackageExportManifestParsed": "src/api/package-lifecycle.zod.ts#PackageExportManifestParsed (type)", "PackageExportManifestSchema": "src/api/package-lifecycle.zod.ts#PackageExportManifestSchema (const)", diff --git a/packages/spec/json-schema.manifest/api.json b/packages/spec/json-schema.manifest/api.json index 8eb2355c6f9..94c44656168 100644 --- a/packages/spec/json-schema.manifest/api.json +++ b/packages/spec/json-schema.manifest/api.json @@ -311,6 +311,7 @@ "api/OpenApiSpec", "api/OperatorMapping", "api/PackageApiErrorCode", + "api/PackageExportBundle", "api/PackageExportManifest", "api/PackageInstallBody", "api/PackageInstallManifest", From 2882de4aa79316ae63fd7ceec6ac279fca5f40c7 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 2 Nov 2026 07:23:19 +0000 Subject: [PATCH 3/8] chore(spec): regenerate the merged artifacts from the merged tree `origin/main` 12aad143 moved the same api generated artifacts; the merge took main's side and `check:generated --fix` regenerated them, so each holds main's entries plus this branch's PackageExportBundle rows (+1 over main's counts). Claude-Session: https://claude.ai/code/session_01ADHkmScwpkMFTAD5HHubn1 Co-authored-by: Claude --- content/docs/references/index.mdx | 10 +++++----- .../api.md | 2 +- packages/spec/api-surface/api.json | 8 ++++++++ packages/spec/authorable-surface/api.json | 6 ++++++ packages/spec/declaration-map/api.json | 4 ++++ packages/spec/export-origins/api.json | 8 ++++++++ packages/spec/json-schema.manifest/api.json | 2 ++ 7 files changed, 34 insertions(+), 6 deletions(-) diff --git a/content/docs/references/index.mdx b/content/docs/references/index.mdx index cd8ae0647b8..f27ebf7efa3 100644 --- a/content/docs/references/index.mdx +++ b/content/docs/references/index.mdx @@ -1,7 +1,7 @@ --- title: Protocol reference — every schema by module navTitle: Protocol Reference -description: Every schema published by @objectstack/spec — 1595 schemas across 14 protocol modules +description: Every schema published by @objectstack/spec — 1597 schemas across 14 protocol modules --- {/* ⚠️ AUTO-GENERATED — DO NOT EDIT. Run build-docs.ts to regenerate. Hand-written docs live in the module folders under content/docs/. */} @@ -21,7 +21,7 @@ counts are sums of the rows they head. Regenerate with | Module | Pages | Schemas | Description | | :--- | ---: | ---: | :--- | | [AI Protocol](/docs/references/ai) | 12 | 68 | Agents, tools, skills, RAG and knowledge sources, model registry, conversations. | -| [API Protocol](/docs/references/api) | 34 | 470 | REST contracts, endpoints, routing, realtime, batch, discovery. | +| [API Protocol](/docs/references/api) | 34 | 472 | REST contracts, endpoints, routing, realtime, batch, discovery. | | [Automation Protocol](/docs/references/automation) | 15 | 78 | Flows and their nodes, approvals, ETL pipelines, webhooks, state machines, execution records. | | [Data Protocol](/docs/references/data) | 31 | 174 | Objects, fields, queries, filters, datasources and drivers — the ObjectQL layer. | | [Identity Protocol](/docs/references/identity) | 5 | 27 | Users and accounts, organizations, positions, SCIM provisioning. | @@ -34,7 +34,7 @@ counts are sums of the rows they head. Regenerate with | [Studio Protocol](/docs/references/studio) | 3 | 35 | Studio designer metadata — the authoring surfaces for the protocols above. | | [System Protocol](/docs/references/system) | 37 | 287 | The runtime environment — logging, jobs, cache, metrics, notifications, i18n and compliance. | | [UI Protocol](/docs/references/ui) | 16 | 175 | Apps, pages, views, dashboards, reports, actions and themes — the ObjectUI layer. | -| **Total** | **205** | **1595** | 14 protocol modules | +| **Total** | **205** | **1597** | 14 protocol modules | --- @@ -63,7 +63,7 @@ Agents, tools, skills, RAG and knowledge sources, model registry, conversations. ## API Protocol -**Source:** `packages/spec/src/api/` · **Import:** `@objectstack/spec/api` · **34 pages, 470 schemas** +**Source:** `packages/spec/src/api/` · **Import:** `@objectstack/spec/api` · **34 pages, 472 schemas** REST contracts, endpoints, routing, realtime, batch, discovery. @@ -96,7 +96,7 @@ REST contracts, endpoints, routing, realtime, batch, discovery. | [`query-adapter.zod.ts`](/docs/references/api/query-adapter) | `ODataQueryAdapter`, `OperatorMapping`, `QueryAdapterConfig`, `QueryAdapterTarget`, `RestQueryAdapter` | | [`realtime.zod.ts`](/docs/references/api/realtime) | `RealtimeConfig`, `RealtimeEvent`, `RealtimeEventType`, `RealtimePresence`, `Subscription`, `SubscriptionEvent`, `TransportProtocol` | | [`realtime-shared.zod.ts`](/docs/references/api/realtime-shared) | `BasePresence`, `PresenceStatus`, `RealtimeRecordAction` | -| [`record-page.zod.ts`](/docs/references/api/record-page) | `RecordPageActivityRequest`, `RecordPageApprovals`, `RecordPageAttachmentsRequest`, `RecordPageDiscussion`, `RecordPageDiscussionReactions`, `RecordPageExplainAnswer`, `RecordPageExplainOperation`, `RecordPagePartError`, `RecordPagePartRefusal`, `RecordPageRelatedAnswer`, `RecordPageRelatedRefusal`, `RecordPageRelatedRequest`, `RecordPageRelatedRows`, `RecordPageRequest`, `RecordPageResponse`, `RecordPageStreamRefusal`, `RecordPageStreamRows` | +| [`record-page.zod.ts`](/docs/references/api/record-page) | `RecordPageActivityRequest`, `RecordPageApprovals`, `RecordPageAttachmentsRequest`, `RecordPageDiscussion`, `RecordPageDiscussionReactions`, `RecordPageExplainAnswer`, `RecordPageExplainOperation`, `RecordPagePartError`, `RecordPagePartRefusal`, `RecordPageRelatedAnswer`, `RecordPageRelatedRefusal`, `RecordPageRelatedRequest`, `RecordPageRelatedRows`, `RecordPageRequest`, `RecordPageResponse`, `RecordPageStreamRefusal`, `RecordPageStreamRows`, `RecordPageTimelineCount`, `RecordPageTimelineRequest` | | [`rest-server.zod.ts`](/docs/references/api/rest-server) | `BatchEndpointsConfig`, `CrudEndpointsConfig`, `CrudOperation`, `EndpointRegistry`, `GeneratedEndpoint`, `MetadataEndpointsConfig`, `RestApiConfig`, `RestServerConfig`, `RouteGenerationConfig` | | [`router.zod.ts`](/docs/references/api/router) | `ConflictResolutionStrategy`, `HttpMethod`, `RouteCategory`, `RouteDefinition`, `RouterConfig` | | [`sortability.zod.ts`](/docs/references/api/sortability) | `FieldSortability`, `ObjectSortability` | diff --git a/docs/audits/2026-07-unknown-key-strictness-ledger.counts/api.md b/docs/audits/2026-07-unknown-key-strictness-ledger.counts/api.md index 26026f6c8a3..fb80356f948 100644 --- a/docs/audits/2026-07-unknown-key-strictness-ledger.counts/api.md +++ b/docs/audits/2026-07-unknown-key-strictness-ledger.counts/api.md @@ -19,4 +19,4 @@ hand-patch a number here** — fix the code or the verdict and regenerate. | Dir | Sites | |---|---| -| `api/` | 485 | +| `api/` | 487 | diff --git a/packages/spec/api-surface/api.json b/packages/spec/api-surface/api.json index ad96dc175cc..98bbe0964fd 100644 --- a/packages/spec/api-surface/api.json +++ b/packages/spec/api-surface/api.json @@ -852,6 +852,8 @@ "RECORD_PAGE_MAX_RELATED (const)", "RECORD_PAGE_MAX_RELATED_ROWS (const)", "RECORD_PAGE_MAX_RELATED_SORT (const)", + "RECORD_TIMELINE_UNDRAWN_ACTIVITY_TYPES (const)", + "RECORD_TIMELINE_UPDATE_ACTIVITY_TYPE (const)", "REGISTERED_ERROR_CODES (const)", "RawUploadResponse (type)", "RawUploadResponseParsed (type)", @@ -940,6 +942,12 @@ "RecordPageStreamRows (type)", "RecordPageStreamRowsParsed (type)", "RecordPageStreamRowsSchema (const)", + "RecordPageTimelineCount (type)", + "RecordPageTimelineCountParsed (type)", + "RecordPageTimelineCountSchema (const)", + "RecordPageTimelineRequest (type)", + "RecordPageTimelineRequestParsed (type)", + "RecordPageTimelineRequestSchema (const)", "RefreshTokenRequest (type)", "RefreshTokenRequestSchema (const)", "RegisterDeviceRequest (type)", diff --git a/packages/spec/authorable-surface/api.json b/packages/spec/authorable-surface/api.json index e6ea61bbc56..837ab95c135 100644 --- a/packages/spec/authorable-surface/api.json +++ b/packages/spec/authorable-surface/api.json @@ -1502,6 +1502,7 @@ "api/RecordPageRequest:explain", "api/RecordPageRequest:fieldAccess", "api/RecordPageRequest:related", + "api/RecordPageRequest:timeline", "api/RecordPageResponse:activity", "api/RecordPageResponse:approvals", "api/RecordPageResponse:attachments", @@ -1512,9 +1513,14 @@ "api/RecordPageResponse:object", "api/RecordPageResponse:record", "api/RecordPageResponse:related", + "api/RecordPageResponse:timeline", "api/RecordPageStreamRefusal:error", "api/RecordPageStreamRows:records", "api/RecordPageStreamRows:total", + "api/RecordPageTimelineCount:total", + "api/RecordPageTimelineRequest:activity", + "api/RecordPageTimelineRequest:discussion", + "api/RecordPageTimelineRequest:fieldChanges", "api/RefreshTokenRequest:refreshToken", "api/RegisterDeviceRequest:deviceId", "api/RegisterDeviceRequest:name", diff --git a/packages/spec/declaration-map/api.json b/packages/spec/declaration-map/api.json index 3a692ea9d0b..fbc39c06ae3 100644 --- a/packages/spec/declaration-map/api.json +++ b/packages/spec/declaration-map/api.json @@ -685,6 +685,10 @@ "RecordPageStreamRefusalSchema": "api/RecordPageStreamRefusal", "RecordPageStreamRows": "api/RecordPageStreamRows", "RecordPageStreamRowsSchema": "api/RecordPageStreamRows", + "RecordPageTimelineCount": "api/RecordPageTimelineCount", + "RecordPageTimelineCountSchema": "api/RecordPageTimelineCount", + "RecordPageTimelineRequest": "api/RecordPageTimelineRequest", + "RecordPageTimelineRequestSchema": "api/RecordPageTimelineRequest", "RefreshTokenRequest": "api/RefreshTokenRequest", "RefreshTokenRequestSchema": "api/RefreshTokenRequest", "RegisterDeviceRequest": "api/RegisterDeviceRequest", diff --git a/packages/spec/export-origins/api.json b/packages/spec/export-origins/api.json index 337aeff56b5..1b9791a7814 100644 --- a/packages/spec/export-origins/api.json +++ b/packages/spec/export-origins/api.json @@ -823,6 +823,8 @@ "RECORD_PAGE_MAX_RELATED": "src/api/record-page.zod.ts#RECORD_PAGE_MAX_RELATED (const)", "RECORD_PAGE_MAX_RELATED_ROWS": "src/api/record-page.zod.ts#RECORD_PAGE_MAX_RELATED_ROWS (const)", "RECORD_PAGE_MAX_RELATED_SORT": "src/api/record-page.zod.ts#RECORD_PAGE_MAX_RELATED_SORT (const)", + "RECORD_TIMELINE_UNDRAWN_ACTIVITY_TYPES": "src/api/record-page.zod.ts#RECORD_TIMELINE_UNDRAWN_ACTIVITY_TYPES (const)", + "RECORD_TIMELINE_UPDATE_ACTIVITY_TYPE": "src/api/record-page.zod.ts#RECORD_TIMELINE_UPDATE_ACTIVITY_TYPE (const)", "REGISTERED_ERROR_CODES": "src/api/error-code-ledger.zod.ts#REGISTERED_ERROR_CODES (const)", "RawUploadResponse": "src/api/storage.zod.ts#RawUploadResponse (type)", "RawUploadResponseParsed": "src/api/storage.zod.ts#RawUploadResponseParsed (type)", @@ -909,6 +911,12 @@ "RecordPageStreamRows": "src/api/record-page.zod.ts#RecordPageStreamRows (type)", "RecordPageStreamRowsParsed": "src/api/record-page.zod.ts#RecordPageStreamRowsParsed (type)", "RecordPageStreamRowsSchema": "src/api/record-page.zod.ts#RecordPageStreamRowsSchema (const)", + "RecordPageTimelineCount": "src/api/record-page.zod.ts#RecordPageTimelineCount (type)", + "RecordPageTimelineCountParsed": "src/api/record-page.zod.ts#RecordPageTimelineCountParsed (type)", + "RecordPageTimelineCountSchema": "src/api/record-page.zod.ts#RecordPageTimelineCountSchema (const)", + "RecordPageTimelineRequest": "src/api/record-page.zod.ts#RecordPageTimelineRequest (type)", + "RecordPageTimelineRequestParsed": "src/api/record-page.zod.ts#RecordPageTimelineRequestParsed (type)", + "RecordPageTimelineRequestSchema": "src/api/record-page.zod.ts#RecordPageTimelineRequestSchema (const)", "RefreshTokenRequest": "src/api/auth.zod.ts#RefreshTokenRequest (type)", "RefreshTokenRequestSchema": "src/api/auth.zod.ts#RefreshTokenRequestSchema (const)", "RegisterDeviceRequest": "src/api/protocol.zod.ts#RegisterDeviceRequest (type)", diff --git a/packages/spec/json-schema.manifest/api.json b/packages/spec/json-schema.manifest/api.json index 94c44656168..f21644eaa6b 100644 --- a/packages/spec/json-schema.manifest/api.json +++ b/packages/spec/json-schema.manifest/api.json @@ -371,6 +371,8 @@ "api/RecordPageResponse", "api/RecordPageStreamRefusal", "api/RecordPageStreamRows", + "api/RecordPageTimelineCount", + "api/RecordPageTimelineRequest", "api/RefreshTokenRequest", "api/RegisterDeviceRequest", "api/RegisterDeviceResponse", From cf37246eeb72def8400733fa552b513d49a3bc4c Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 2 Nov 2026 08:12:30 +0000 Subject: [PATCH 4/8] fix(spec): the whole-deployment export reads as declared ahead of its producer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit No runtime mounts `GET /packages/export` yet, so the docblock no longer states the route, its read gate, its closed query set or its whole-or-absent failure as served facts. It states them as the contract the server slice must meet (ADR-0049), and the schema's describe opens with `[PLANNED — not yet served]` until a runtime mounts the route. A test pins the marker and that the describe names no tracker id; the server slice drops the marker with its route-ledger row and flips the test. Claude-Session: https://claude.ai/code/session_01ADHkmScwpkMFTAD5HHubn1 Co-authored-by: Claude --- .changeset/28914-package-export-bundle.md | 2 +- .../docs/references/api/package-lifecycle.mdx | 2 +- .../spec/src/api/package-lifecycle.test.ts | 13 +++ .../spec/src/api/package-lifecycle.zod.ts | 84 +++++++++++-------- 4 files changed, 66 insertions(+), 35 deletions(-) diff --git a/.changeset/28914-package-export-bundle.md b/.changeset/28914-package-export-bundle.md index 00d82cd5e8e..a91e4d57af0 100644 --- a/.changeset/28914-package-export-bundle.md +++ b/.changeset/28914-package-export-bundle.md @@ -7,7 +7,7 @@ feat(spec): `PackageExportBundleSchema` declares the whole-deployment export, ev Clause-②: yes (widening) Metadata-protocol: added -A tenant on ObjectOS Cloud or Enterprise can take its ontology to the Apache-2.0 runtime only one package at a time today (`GET /packages/:id/export`). This declares the contract of the read that answers all of it at once, `GET /packages/export`. The route and the `os package export` command that calls it follow in `@objectstack/runtime` and `@objectstack/cli`; no runtime serves it yet. +A tenant on ObjectOS Cloud or Enterprise can take its ontology to the Apache-2.0 runtime only one package at a time today (`GET /packages/:id/export`). This declares the contract of the read that answers all of it at once, `GET /packages/export`. The route and the `os package export` command that calls it follow in `@objectstack/runtime` and `@objectstack/cli`; no runtime serves it yet. Until a runtime mounts the route, the schema's description opens with `[PLANNED — not yet served]` (ADR-0049): the shape is the contract that door must answer, not a read a client can make today. - **`@objectstack/spec`**: `PackageExportBundleSchema` (with `PackageExportBundle` and `PackageExportBundleParsed`) in `@objectstack/spec/api`. The answer is `{ packages }`: every package the deployment holds except the platform's own (manifest `scope: 'system'`, which every runtime ships for itself), each exactly as `GET /packages/:id/export` answers it. The entries are `PackageExportManifestSchema` itself, so the per-package export stays the one producer. A base's `.custom` pair is its own entry with its override declarations, and environment customizations stay under the package that owns them. The bundle carries no credential value: the per-package export withholds credential positions, and a `credentialRef` stays a reference. - **Order**: dependencies first, the order a boot hydrates installed packages in (ADR-0141 D5). An entry comes after every entry its package's `manifest.dependencies` names, so a pair comes after its base. Install the entries in the order listed; a consumer never re-sorts them. diff --git a/content/docs/references/api/package-lifecycle.mdx b/content/docs/references/api/package-lifecycle.mdx index bc2a8aec3e8..07464c2248a 100644 --- a/content/docs/references/api/package-lifecycle.mdx +++ b/content/docs/references/api/package-lifecycle.mdx @@ -296,7 +296,7 @@ Per-package customization read: overrides, extensions and switched-off items of ## PackageExportBundle -Whole-deployment export: every installed package but the platform's own, as installable packages in dependency order. Carries no credential value. +[PLANNED — not yet served] Whole-deployment export: every installed package but the platform's own, as installable packages in dependency order. Carries no credential value. Declared ahead of its producer (ADR-0049): no runtime serves `GET /packages/export` yet. The server half of the whole-deployment package export mounts it and the `os package export` command that calls it; until then this is the contract that door must answer, not a read a client can make. ### Properties diff --git a/packages/spec/src/api/package-lifecycle.test.ts b/packages/spec/src/api/package-lifecycle.test.ts index 8a992d38ba8..2e7919afbb6 100644 --- a/packages/spec/src/api/package-lifecycle.test.ts +++ b/packages/spec/src/api/package-lifecycle.test.ts @@ -315,6 +315,19 @@ describe('PackageExportBundleSchema declares the whole-deployment export as comp expect(result.error.issues[0]?.code).toBe('unrecognized_keys'); expect((result.error.issues[0] as { keys?: string[] }).keys).toEqual(['cycles']); }); + + // Declared before it is served (ADR-0049): no runtime mounts + // `GET /packages/export` until the server slice of #28914 lands. That + // change drops the marker, adds the route-ledger row and the + // `PackageApiContracts` entry, and flips this test. + it('is PLANNED until a runtime serves the route: the describe says so, naming no tracker id', () => { + const description = PackageExportBundleSchema.description ?? ''; + expect(description).toMatch(/^\[PLANNED — not yet served\] /); + expect(description).toContain('ADR-0049'); + expect(description).toContain('no runtime serves `GET /packages/export` yet'); + // Customer-facing prose carries no tracker id (check:doc-authoring); the slice is named in the comments. + expect(description).not.toMatch(/#\d{3,}/); + }); }); describe('ReassignOrphanedMetadataResponseSchema declares the adopt-orphans body', () => { diff --git a/packages/spec/src/api/package-lifecycle.zod.ts b/packages/spec/src/api/package-lifecycle.zod.ts index ad533652c00..ecb7144aad8 100644 --- a/packages/spec/src/api/package-lifecycle.zod.ts +++ b/packages/spec/src/api/package-lifecycle.zod.ts @@ -196,25 +196,36 @@ export const PackageExportManifestSchema = lazySchema(() => z.object({ * packages, in one read (#28914): the exit right that * {@link PackageExportManifestSchema}'s route grants one package at a time. * - * Unlike its lifecycle siblings this is not a transcription: the route is new, - * and this declaration is its contract (Clause-②, widening). Served by the - * runtime dispatcher and enveloped like them (`{ success, data }`); this - * schema declares the `data`. + * ⚠️ DECLARED AHEAD OF ITS PRODUCER (ADR-0049). No runtime serves + * `GET /packages/export` yet: no handler mounts it, so a call today is not + * answered with this shape. This declaration is the contract the server slice + * of #28914 must meet (Clause-②, widening): it mounts the route on the runtime + * dispatcher, enveloped like its lifecycle siblings (`{ success, data }`), and + * answers this schema as the `data`. Until it does, the describe carries + * `[PLANNED — not yet served]`. The house has no other planned channel for an + * API response: the liveness ledgers are per metadata type, the runtime route + * ledger records only what the dispatcher serves, and `PackageApiContracts` + * binds a route only in the change that mounts it. So the server slice drops + * the marker in the same change that mounts the route, adds its route-ledger + * row and its `PackageApiContracts` entry, and flips the test that pins the + * marker. + * + * Everything below is what that door MUST do. None of it is served today. * * ## One producer * - * Each entry is exactly what `GET /packages/:id/export` answers for that - * package. The bundle composes the per-package export and never assembles, - * cleans or redacts an item a second way, so the two reads cannot disagree - * about a package. Two consequences are this record's on purpose: + * Each entry must be exactly what `GET /packages/:id/export` (served today) + * answers for that package. The bundle composes the per-package export and + * must never assemble, clean or redact an item a second way, so the two reads + * cannot disagree about a package. Two consequences follow on purpose: * * - **A `.custom` pair is its own entry**, carrying its overriding items with * their `overrides` blocks (ADR-0146 D8 item 3), and its base's entry carries - * the base unchanged. Environment-scope customizations are where the + * the base unchanged. Environment-scope customizations stay where the * per-package export already places them: under the package that owns them. - * - **No credential value leaves.** The per-package export withholds credential - * positions as every served metadata read does, and the bundle adds no rule - * of its own: a `credentialRef` stays the reference it is. + * - **No credential value leaves.** The per-package export already withholds + * credential positions, as every served metadata read does. The bundle must + * add no rule of its own: a `credentialRef` stays the reference it is. * * ## Which packages, in which order * @@ -224,28 +235,28 @@ export const PackageExportManifestSchema = lazySchema(() => z.object({ * A pair of such a base is still exported. A metadata item bound to no package * is in no entry; ADR-0146 D11's migration binds it to one first. * - * The order is ADR-0141 D5's, the order a boot hydrates installed packages in: - * dependencies first. An entry comes after every entry its package's - * `manifest.dependencies` names, so a pair comes after its base, and installing - * the entries in the order listed is the whole consumption rule: a consumer - * never re-sorts. Members of a dependency cycle keep the read's listing order - * among themselves, as a boot hydrates them. + * The order must be ADR-0141 D5's, the order a boot hydrates installed + * packages in: dependencies first. An entry comes after every entry its + * package's `manifest.dependencies` names, so a pair comes after its base. + * Installing the entries in the order listed is the whole consumption rule: a + * consumer never re-sorts. Members of a dependency cycle keep the read's + * listing order among themselves, as a boot hydrates them. * * ## The door * - * The read gate is the per-package export's: `studio.access` or `setup.access`, - * or a system context, asked before anything is read. The query set is CLOSED - * and empty: a query parameter is refused `400 VALIDATION_ERROR` naming it. No - * request schema is declared, because the door reads no path id, no body and - * no parameter. `export` can never be a package id (one has at least two - * dot-separated segments, `MANIFEST_ID_PATTERN`), so the path never shadows - * `GET /packages/:id`. - * - * The answer is whole or absent: a package whose export cannot be assembled - * fails the read, naming that package. ⛔ Never a bundle that silently lacks a - * package. Strict at the top level: a member the door starts serving is a - * change to this declaration first. Each entry stays open, as ruled for - * {@link PackageExportManifestSchema}. + * The read gate must be the per-package export's: `studio.access` or + * `setup.access`, or a system context, asked before anything is read. The + * query set must be CLOSED and empty: the door refuses a query parameter + * `400 VALIDATION_ERROR`, naming it. No request schema is declared, because + * the door reads no path id, no body and no parameter. `export` can never be a + * package id (one has at least two dot-separated segments, + * `MANIFEST_ID_PATTERN`), so the path never shadows `GET /packages/:id`. + * + * The answer must be whole or absent: a package whose export cannot be + * assembled fails the read, naming that package. ⛔ Never a bundle that + * silently lacks a package. Strict at the top level: a member the door starts + * serving is a change to this declaration first. Each entry stays open, as + * ruled for {@link PackageExportManifestSchema}. */ export const PackageExportBundleSchema = lazySchema(() => z.object({ packages: z.array(PackageExportManifestSchema).describe( @@ -254,9 +265,16 @@ export const PackageExportBundleSchema = lazySchema(() => z.object({ + '`manifest.dependencies` names, so a `.custom` pair comes after its base. Install the entries in this order; ' + 'never re-sort them. Empty when the deployment holds only platform packages.', ), + // Declared before it is served (ADR-0049): the marker comes off when the + // server slice of #28914 mounts `GET /packages/export` in + // packages/runtime/src/domains/packages.ts, in the same change as its + // route-ledger row and its `PackageApiContracts` entry. }).strict().describe( - 'Whole-deployment export: every installed package but the platform\'s own, as installable packages in ' - + 'dependency order. Carries no credential value.', + '[PLANNED — not yet served] Whole-deployment export: every installed package but the platform\'s own, as ' + + 'installable packages in dependency order. Carries no credential value. Declared ahead of its producer ' + + '(ADR-0049): no runtime serves `GET /packages/export` yet. The server half of the whole-deployment package ' + + 'export mounts it and the `os package export` command that calls it; until then this is the contract that ' + + 'door must answer, not a read a client can make.', )); /** From a373ba5338bee5e443a061ebd1b053cedead96bd Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 2 Nov 2026 09:00:49 +0000 Subject: [PATCH 5/8] fix(spec): the export bundle's describe names no CLI command that does not exist yet MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit check:cli-command-ids resolves every quoted `os …` phrase outside packages/cli to a command under packages/cli/src/commands/, and the whole-deployment export command lands only with the server slice. The describe and the changeset now say "a CLI command that calls it" instead. Claude-Session: https://claude.ai/code/session_01ADHkmScwpkMFTAD5HHubn1 Co-authored-by: Claude --- .changeset/28914-package-export-bundle.md | 2 +- content/docs/references/api/package-lifecycle.mdx | 2 +- packages/spec/src/api/package-lifecycle.zod.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.changeset/28914-package-export-bundle.md b/.changeset/28914-package-export-bundle.md index a91e4d57af0..0dc27647060 100644 --- a/.changeset/28914-package-export-bundle.md +++ b/.changeset/28914-package-export-bundle.md @@ -7,7 +7,7 @@ feat(spec): `PackageExportBundleSchema` declares the whole-deployment export, ev Clause-②: yes (widening) Metadata-protocol: added -A tenant on ObjectOS Cloud or Enterprise can take its ontology to the Apache-2.0 runtime only one package at a time today (`GET /packages/:id/export`). This declares the contract of the read that answers all of it at once, `GET /packages/export`. The route and the `os package export` command that calls it follow in `@objectstack/runtime` and `@objectstack/cli`; no runtime serves it yet. Until a runtime mounts the route, the schema's description opens with `[PLANNED — not yet served]` (ADR-0049): the shape is the contract that door must answer, not a read a client can make today. +A tenant on ObjectOS Cloud or Enterprise can take its ontology to the Apache-2.0 runtime only one package at a time today (`GET /packages/:id/export`). This declares the contract of the read that answers all of it at once, `GET /packages/export`. The route, and a CLI command that calls it, follow in `@objectstack/runtime` and `@objectstack/cli`; no runtime serves it yet. Until a runtime mounts the route, the schema's description opens with `[PLANNED — not yet served]` (ADR-0049): the shape is the contract that door must answer, not a read a client can make today. - **`@objectstack/spec`**: `PackageExportBundleSchema` (with `PackageExportBundle` and `PackageExportBundleParsed`) in `@objectstack/spec/api`. The answer is `{ packages }`: every package the deployment holds except the platform's own (manifest `scope: 'system'`, which every runtime ships for itself), each exactly as `GET /packages/:id/export` answers it. The entries are `PackageExportManifestSchema` itself, so the per-package export stays the one producer. A base's `.custom` pair is its own entry with its override declarations, and environment customizations stay under the package that owns them. The bundle carries no credential value: the per-package export withholds credential positions, and a `credentialRef` stays a reference. - **Order**: dependencies first, the order a boot hydrates installed packages in (ADR-0141 D5). An entry comes after every entry its package's `manifest.dependencies` names, so a pair comes after its base. Install the entries in the order listed; a consumer never re-sorts them. diff --git a/content/docs/references/api/package-lifecycle.mdx b/content/docs/references/api/package-lifecycle.mdx index 07464c2248a..cc1f473c123 100644 --- a/content/docs/references/api/package-lifecycle.mdx +++ b/content/docs/references/api/package-lifecycle.mdx @@ -296,7 +296,7 @@ Per-package customization read: overrides, extensions and switched-off items of ## PackageExportBundle -[PLANNED — not yet served] Whole-deployment export: every installed package but the platform's own, as installable packages in dependency order. Carries no credential value. Declared ahead of its producer (ADR-0049): no runtime serves `GET /packages/export` yet. The server half of the whole-deployment package export mounts it and the `os package export` command that calls it; until then this is the contract that door must answer, not a read a client can make. +[PLANNED — not yet served] Whole-deployment export: every installed package but the platform's own, as installable packages in dependency order. Carries no credential value. Declared ahead of its producer (ADR-0049): no runtime serves `GET /packages/export` yet. The server half of the whole-deployment package export mounts it, together with a future CLI command that calls it; until then this is the contract that door must answer, not a read a client can make. ### Properties diff --git a/packages/spec/src/api/package-lifecycle.zod.ts b/packages/spec/src/api/package-lifecycle.zod.ts index ecb7144aad8..0839603f8b2 100644 --- a/packages/spec/src/api/package-lifecycle.zod.ts +++ b/packages/spec/src/api/package-lifecycle.zod.ts @@ -273,7 +273,7 @@ export const PackageExportBundleSchema = lazySchema(() => z.object({ '[PLANNED — not yet served] Whole-deployment export: every installed package but the platform\'s own, as ' + 'installable packages in dependency order. Carries no credential value. Declared ahead of its producer ' + '(ADR-0049): no runtime serves `GET /packages/export` yet. The server half of the whole-deployment package ' - + 'export mounts it and the `os package export` command that calls it; until then this is the contract that ' + + 'export mounts it, together with a future CLI command that calls it; until then this is the contract that ' + 'door must answer, not a read a client can make.', )); From 1ce77b0aaac41e3eb9e0f6187a18b35a1d8cdbcc Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 2 Nov 2026 11:05:08 +0000 Subject: [PATCH 6/8] fix(spec): the export bundle selects by the registry row's source, and says it carries no enabled state The bundle left out "the platform's own" by `manifest.scope: 'system'`. The registry forbids deriving a package's origin from `manifest.scope` (`InstalledPackageSourceSchema`), and the runtime already corrected the same derivation once. The rule now reads the registry row's `source`: every package whose `source` is not `code` (marketplace and authored packages, a `.custom` pair among them). A `code` package travels with the code that registers it, not with the bundle. Both describes now say the bundle carries no enabled state, so every entry installs enabled. The docblock no longer orders the server slice to add a `PackageApiContracts` entry (that table binds only the list, get, install and uninstall doors) or names its file; the marker comes off with the route's ledger row. A new test pins the selection by `source`, the absence of `scope` and the enabled-state sentence in both describes. Claude-Session: https://claude.ai/code/session_01ADHkmScwpkMFTAD5HHubn1 Co-authored-by: Claude --- .changeset/28914-package-export-bundle.md | 2 +- .../docs/references/api/package-lifecycle.mdx | 4 +- .../spec/src/api/package-lifecycle.test.ts | 20 ++++++- .../spec/src/api/package-lifecycle.zod.ts | 52 ++++++++++++------- 4 files changed, 53 insertions(+), 25 deletions(-) diff --git a/.changeset/28914-package-export-bundle.md b/.changeset/28914-package-export-bundle.md index 0dc27647060..bb2c4a23f25 100644 --- a/.changeset/28914-package-export-bundle.md +++ b/.changeset/28914-package-export-bundle.md @@ -9,6 +9,6 @@ Metadata-protocol: added A tenant on ObjectOS Cloud or Enterprise can take its ontology to the Apache-2.0 runtime only one package at a time today (`GET /packages/:id/export`). This declares the contract of the read that answers all of it at once, `GET /packages/export`. The route, and a CLI command that calls it, follow in `@objectstack/runtime` and `@objectstack/cli`; no runtime serves it yet. Until a runtime mounts the route, the schema's description opens with `[PLANNED — not yet served]` (ADR-0049): the shape is the contract that door must answer, not a read a client can make today. -- **`@objectstack/spec`**: `PackageExportBundleSchema` (with `PackageExportBundle` and `PackageExportBundleParsed`) in `@objectstack/spec/api`. The answer is `{ packages }`: every package the deployment holds except the platform's own (manifest `scope: 'system'`, which every runtime ships for itself), each exactly as `GET /packages/:id/export` answers it. The entries are `PackageExportManifestSchema` itself, so the per-package export stays the one producer. A base's `.custom` pair is its own entry with its override declarations, and environment customizations stay under the package that owns them. The bundle carries no credential value: the per-package export withholds credential positions, and a `credentialRef` stays a reference. +- **`@objectstack/spec`**: `PackageExportBundleSchema` (with `PackageExportBundle` and `PackageExportBundleParsed`) in `@objectstack/spec/api`. The answer is `{ packages }`: every package whose registry row's `source` is not `code` (the marketplace and authored packages, a `.custom` pair among them; a `code` package is registered by the deployment's own code and travels with that code, not with the bundle), enabled or not, each exactly as `GET /packages/:id/export` answers it. The bundle carries no enabled state, so every entry installs enabled. The entries are `PackageExportManifestSchema` itself, so the per-package export stays the one producer. A base's `.custom` pair is its own entry with its override declarations, and environment customizations stay under the package that owns them. The bundle carries no credential value: the per-package export withholds credential positions, and a `credentialRef` stays a reference. - **Order**: dependencies first, the order a boot hydrates installed packages in (ADR-0141 D5). An entry comes after every entry its package's `manifest.dependencies` names, so a pair comes after its base. Install the entries in the order listed; a consumer never re-sorts them. - The answer is strict at the top level; each entry stays open, as the per-package export is. diff --git a/content/docs/references/api/package-lifecycle.mdx b/content/docs/references/api/package-lifecycle.mdx index cc1f473c123..50b15720eae 100644 --- a/content/docs/references/api/package-lifecycle.mdx +++ b/content/docs/references/api/package-lifecycle.mdx @@ -296,13 +296,13 @@ Per-package customization read: overrides, extensions and switched-off items of ## PackageExportBundle -[PLANNED — not yet served] Whole-deployment export: every installed package but the platform's own, as installable packages in dependency order. Carries no credential value. Declared ahead of its producer (ADR-0049): no runtime serves `GET /packages/export` yet. The server half of the whole-deployment package export mounts it, together with a future CLI command that calls it; until then this is the contract that door must answer, not a read a client can make. +[PLANNED — not yet served] Whole-deployment export: every installed package the deployment's own code does not register (registry `source` other than `code`), as installable packages in dependency order. Carries no credential value and no enabled state. Declared ahead of its producer (ADR-0049): no runtime serves `GET /packages/export` yet. The server half of the whole-deployment package export mounts it, together with a future CLI command that calls it; until then this is the contract that door must answer, not a read a client can make. ### Properties | Property | Type | Required | Description | | :--- | :--- | :--- | :--- | -| **packages** | `({ id: string; name: string; version: string; label?: string } & Record)[]` | ✅ | Every package of the deployment but the platform's own (manifest `scope` `system`), each once and each as `GET /packages/:id/export` answers it, dependencies first: an entry comes after every entry its package's `manifest.dependencies` names, so a `.custom` pair comes after its base. Install the entries in this order; never re-sort them. Empty when the deployment holds only platform packages. | +| **packages** | `({ id: string; name: string; version: string; label?: string } & Record)[]` | ✅ | Every package whose registry row's `source` is not `code` (the marketplace and authored packages, a `.custom` pair among them), enabled or not, each once and each as `GET /packages/:id/export` answers it, dependencies first: an entry comes after every entry its package's `manifest.dependencies` names, so a `.custom` pair comes after its base. Install the entries in this order; never re-sort them. No entry carries an enabled state, so every entry installs enabled. Empty when every package of the deployment is registered by its own code. | ### Nested Shape: `PackageExportBundle.packages[number]` diff --git a/packages/spec/src/api/package-lifecycle.test.ts b/packages/spec/src/api/package-lifecycle.test.ts index 2e7919afbb6..b9369a3a23b 100644 --- a/packages/spec/src/api/package-lifecycle.test.ts +++ b/packages/spec/src/api/package-lifecycle.test.ts @@ -24,6 +24,7 @@ import { EnsureCustomizationPackageResponseSchema, } from './package-lifecycle.zod'; import { PackagePublishResultSchema as SystemPackagePublishResultSchema } from '../system/metadata-persistence.zod'; +import { InstalledPackageSourceSchema } from '../kernel/package-registry.zod'; describe('the ruled re-export of PackagePublishResultSchema into the `/api` namespace', () => { it('is the SAME declaration as the `/system` original — a re-export, never a second copy', () => { @@ -318,8 +319,7 @@ describe('PackageExportBundleSchema declares the whole-deployment export as comp // Declared before it is served (ADR-0049): no runtime mounts // `GET /packages/export` until the server slice of #28914 lands. That - // change drops the marker, adds the route-ledger row and the - // `PackageApiContracts` entry, and flips this test. + // change drops the marker, adds the route's ledger row and flips this test. it('is PLANNED until a runtime serves the route: the describe says so, naming no tracker id', () => { const description = PackageExportBundleSchema.description ?? ''; expect(description).toMatch(/^\[PLANNED — not yet served\] /); @@ -328,6 +328,22 @@ describe('PackageExportBundleSchema declares the whole-deployment export as comp // Customer-facing prose carries no tracker id (check:doc-authoring); the slice is named in the comments. expect(description).not.toMatch(/#\d{3,}/); }); + + // Which packages the door selects is read off the registry row's `source` + // (InstalledPackageSourceSchema), never derived from `manifest.scope`: the + // registry's own rule, and the runtime's #14375 correction of the same + // derivation. Both describes state the selection and the missing enabled state. + it('selects by the registry row\'s `source`, never by `manifest.scope`, and says it carries no enabled state', () => { + const packagesDescription = PackageExportBundleSchema.shape.packages.description ?? ''; + const description = PackageExportBundleSchema.description ?? ''; + for (const text of [packagesDescription, description]) { + expect(text).toContain('`source`'); + expect(text).toContain('`code`'); + expect(text).not.toMatch(/scope/); + expect(text).toContain('enabled'); + } + expect(InstalledPackageSourceSchema.options).toContain('code'); + }); }); describe('ReassignOrphanedMetadataResponseSchema declares the adopt-orphans body', () => { diff --git a/packages/spec/src/api/package-lifecycle.zod.ts b/packages/spec/src/api/package-lifecycle.zod.ts index 0839603f8b2..e2ed998f193 100644 --- a/packages/spec/src/api/package-lifecycle.zod.ts +++ b/packages/spec/src/api/package-lifecycle.zod.ts @@ -203,12 +203,10 @@ export const PackageExportManifestSchema = lazySchema(() => z.object({ * dispatcher, enveloped like its lifecycle siblings (`{ success, data }`), and * answers this schema as the `data`. Until it does, the describe carries * `[PLANNED — not yet served]`. The house has no other planned channel for an - * API response: the liveness ledgers are per metadata type, the runtime route - * ledger records only what the dispatcher serves, and `PackageApiContracts` - * binds a route only in the change that mounts it. So the server slice drops - * the marker in the same change that mounts the route, adds its route-ledger - * row and its `PackageApiContracts` entry, and flips the test that pins the - * marker. + * API response: the liveness ledgers are per metadata type, and the runtime + * route ledger records only what the dispatcher serves. So the change that + * mounts the route drops the marker, adds the route's ledger row and flips the + * test that pins the marker. * * Everything below is what that door MUST do. None of it is served today. * @@ -229,11 +227,23 @@ export const PackageExportManifestSchema = lazySchema(() => z.object({ * * ## Which packages, in which order * - * Every package the deployment holds, enabled or not, each once, except the - * platform's own: a package whose manifest `scope` is `system` is shipped by - * every runtime for itself, so an install of the bundle never re-installs it. - * A pair of such a base is still exported. A metadata item bound to no package - * is in no entry; ADR-0146 D11's migration binds it to one first. + * Every package whose registry row's `source` (`InstalledPackageSourceSchema`, + * kernel/package-registry.zod.ts) is not `code`, each once: the marketplace + * and authored packages, a `.custom` pair among them. A `code` package is + * registered by the running deployment's own code (a `defineStack()` host's + * packages, a plugin's bundled manifest, a platform package), so it travels + * with that code and not with the bundle: an install of the bundle never + * re-installs it. The row's `source` is the one key that says so: the + * registry's own ⛔ forbids deriving it from `manifest.scope` or `writable`, + * and the per-package export already reads the row that carries it. A pair of + * a `code` base is still exported. A metadata item bound to no package is in + * no entry; ADR-0146 D11's migration binds it to one first. + * + * Enabled or not, every such package is exported, and the bundle carries no + * enabled state: the per-package export has no `enabled` or `status` key, so an + * install of the bundle installs every entry enabled. A package the tenant + * switched off comes back on, and the consumer disables it again if it wants it + * off. * * The order must be ADR-0141 D5's, the order a boot hydrates installed * packages in: dependencies first. An entry comes after every entry its @@ -260,18 +270,20 @@ export const PackageExportManifestSchema = lazySchema(() => z.object({ */ export const PackageExportBundleSchema = lazySchema(() => z.object({ packages: z.array(PackageExportManifestSchema).describe( - 'Every package of the deployment but the platform\'s own (manifest `scope` `system`), each once and each as ' - + '`GET /packages/:id/export` answers it, dependencies first: an entry comes after every entry its package\'s ' - + '`manifest.dependencies` names, so a `.custom` pair comes after its base. Install the entries in this order; ' - + 'never re-sort them. Empty when the deployment holds only platform packages.', + 'Every package whose registry row\'s `source` is not `code` (the marketplace and authored packages, a `.custom` ' + + 'pair among them), enabled or not, each once and each as `GET /packages/:id/export` answers it, dependencies ' + + 'first: an entry comes after every entry its package\'s `manifest.dependencies` names, so a `.custom` pair ' + + 'comes after its base. Install the entries in this order; never re-sort them. No entry carries an enabled ' + + 'state, so every entry installs enabled. Empty when every package of the deployment is registered by its ' + + 'own code.', ), // Declared before it is served (ADR-0049): the marker comes off when the - // server slice of #28914 mounts `GET /packages/export` in - // packages/runtime/src/domains/packages.ts, in the same change as its - // route-ledger row and its `PackageApiContracts` entry. + // server slice of #28914 mounts `GET /packages/export`, in the same change + // as the route's ledger row. }).strict().describe( - '[PLANNED — not yet served] Whole-deployment export: every installed package but the platform\'s own, as ' - + 'installable packages in dependency order. Carries no credential value. Declared ahead of its producer ' + '[PLANNED — not yet served] Whole-deployment export: every installed package the deployment\'s own code does ' + + 'not register (registry `source` other than `code`), as installable packages in dependency order. Carries no ' + + 'credential value and no enabled state. Declared ahead of its producer ' + '(ADR-0049): no runtime serves `GET /packages/export` yet. The server half of the whole-deployment package ' + 'export mounts it, together with a future CLI command that calls it; until then this is the contract that ' + 'door must answer, not a read a client can make.', From 1e673873a5ee904add4be3a27a81a3654d4d71fe Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 2 Nov 2026 17:38:09 +0000 Subject: [PATCH 7/8] chore(spec): regenerate the merged artifacts from the merged tree `origin/main` 399df5bb moved the same generated artifacts; the merge took main's side and `check:generated --fix` regenerated the two it named stale (the package-lifecycle reference page and the strictness-ledger `api` shard), so each holds main's entries plus this branch's PackageExportBundle rows. Claude-Session: https://claude.ai/code/session_01ADHkmScwpkMFTAD5HHubn1 Co-authored-by: Claude --- .../docs/references/api/package-lifecycle.mdx | 20 ++++++++++++++++--- .../api.md | 2 +- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/content/docs/references/api/package-lifecycle.mdx b/content/docs/references/api/package-lifecycle.mdx index 50b15720eae..2b163f98475 100644 --- a/content/docs/references/api/package-lifecycle.mdx +++ b/content/docs/references/api/package-lifecycle.mdx @@ -163,7 +163,7 @@ Per-package customization read request: the base package id, no query parameters ## GetPackageCustomizationsResponse -Per-package customization read: overrides, extensions and switched-off items of one installed base, and the fields and flows other packages contribute to it. +Per-package customization read: overrides, extensions and switched-off items of one installed base, and the fields, flows and (not yet served) navigation items other packages contribute to it. ### Properties @@ -173,7 +173,7 @@ Per-package customization read: overrides, extensions and switched-off items of | **overrides** | `{ type: string; name: string; member?: string; basedOn?: string; … }[]` | ✅ | Every ACTIVE item of the base's paired `.custom` package that declares `overrides.package` = the base and that the effective read serves over the base's item of the same name: the rows the served-override predicate admits (a declaration from any other package, and an undeclared pair item, are not listed), minus the stored rows every read declines (a shipped flow name). Ordered by type, name and member. | | **extensions** | `{ object: string; kind: Enum<'field' \| 'validation' \| 'index'>; name?: string; fields?: string[] }[]` | ✅ | Every field, validation rule and index the paired `.custom` package declares in an object extension (`objectExtensions`) of an object the base owns, one entry per member, as the extension declares it. Ordered by object, kind and name. | | **switchedOff** | `{ type: string; name: string }[]` | ✅ | Every activation-ledger row (`sys_metadata_activation`) that records the base as its package and `active: false`: the base's items this deployment switched off. Ordered by type and name. | -| **contributions** | `{ kind: Enum<'field' \| 'flow'>; object: string; name: string; packageId: string }[]` | ✅ | Every field and flow another installed package contributes to the base's objects, one entry per item and contributing package: the fields of every object extension of an object the base owns, from any package but the base and its pair, and every flow registered under such a package whose trigger object the base owns (a flow of a disabled package is not served, so not listed). Ordered by object, kind, name and package. | +| **contributions** | `({ kind: Enum<'field' \| 'flow'>; object: string; name: string; packageId: string } \| { kind: 'nav'; app: string; group?: string; name: string; … })[]` | ✅ | Every field, flow and navigation item another installed package contributes to the base, one entry per item and contributing package: the fields of every object extension of an object the base owns, from any package but the base and its pair; every flow registered under such a package whose trigger object the base owns (a flow of a disabled package is not served, so not listed); and, declared ahead of its producer and not yet served, every navigation item such a package contributes to an app the base owns. The entry shape is per `kind`: `object` for `field` and `flow`, `app` and an optional `group` for `nav`. Ordered: the `field` and `flow` entries first, by object, kind, name and package; then the `nav` entries, by app, group (an entry with no group first), name and package. | | **counts** | `{ overrides: integer; extensions: integer; switchedOff: integer; contributions: integer }` | ✅ | Each list's length, derived from the lists in this same answer. | ### Nested Shape: `GetPackageCustomizationsResponse.overrides[number]` @@ -202,7 +202,9 @@ Per-package customization read: overrides, extensions and switched-off items of | **type** | `string` | ✅ | The ledger row's metadata type (`flow`, `action`, `position`, …). | | **name** | `string` | ✅ | The switched-off item's name. | -### Nested Shape: `GetPackageCustomizationsResponse.contributions[number]` +### Nested Shape: `GetPackageCustomizationsResponse.contributions[number][option 1]` + +A field or flow another package contributes to one of the base's objects. | Property | Type | Required | Description | | :--- | :--- | :--- | :--- | @@ -211,6 +213,18 @@ Per-package customization read: overrides, extensions and switched-off items of | **name** | `string` | ✅ | The item's name: the field name as the extension declares it, or the flow's name. | | **packageId** | `string` | ✅ | The package that contributes the item: the extension's package, or the package the flow is registered under. Never the base and never its `.custom` pair. | +### Nested Shape: `GetPackageCustomizationsResponse.contributions[number][option 2]` + +[PLANNED — not yet served] Declared ahead of its producer (ADR-0049): the read lists no `nav` entry yet. A navigation item another installed package contributes to an app the base owns, one entry per item of the contribution's `items` (a contributed group's children ride inside it and are not entries of their own), read from the same contribution registry the served app's navigation fold reads (ADR-0029 D7). An item that declares no `id` (a separator may omit it) has no `name` to give and is not an entry. A disabled package's contributions are not listed, as the fold drops them. + +| Property | Type | Required | Description | +| :--- | :--- | :--- | :--- | +| **kind** | `'nav'` | ✅ | What is contributed: `nav`, a navigation item another package's `navigationContributions` entry adds to the navigation of an app the base owns. | +| **app** | `string` | ✅ | The base-owned app the item is contributed to: the contribution's `app`. | +| **group** | `string` | optional | The group nav item the contribution targets: its `group`, as the contribution declares it. Absent when the contribution targets the app's top level. A group the app does not declare is still named here, though the served navigation appends those items at the app's top level. | +| **name** | `string` | ✅ | The nav item's id, as the contribution's `items` declare it. | +| **packageId** | `string` | ✅ | The package that contributes the item: the package whose `navigationContributions` declares it. Never the base and never its `.custom` pair. | + ### Nested Shape: `GetPackageCustomizationsResponse.counts` | Property | Type | Required | Description | diff --git a/docs/audits/2026-07-unknown-key-strictness-ledger.counts/api.md b/docs/audits/2026-07-unknown-key-strictness-ledger.counts/api.md index fb80356f948..2124b03f462 100644 --- a/docs/audits/2026-07-unknown-key-strictness-ledger.counts/api.md +++ b/docs/audits/2026-07-unknown-key-strictness-ledger.counts/api.md @@ -19,4 +19,4 @@ hand-patch a number here** — fix the code or the verdict and regenerate. | Dir | Sites | |---|---| -| `api/` | 487 | +| `api/` | 488 | From 007f80b9dd596ee0978d1ad312128a8f648e34e2 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 2 Nov 2026 19:27:17 +0000 Subject: [PATCH 8/8] chore(spec): regenerate the merged artifacts from the merged tree origin/main moved the api shard and the authorable surface again; the merge took main's side of the generated files, and check:generated --fix rewrote them from the merged source with this branch's rows. Co-authored-by: Claude Claude-Session: https://claude.ai/code/session_01ADHkmScwpkMFTAD5HHubn1 --- content/docs/references/index.mdx | 15 +++++++++------ .../api.md | 2 +- packages/spec/api-surface/api.json | 4 ++++ packages/spec/authorable-surface/api.json | 6 ++++++ packages/spec/declaration-map/api.json | 4 ++++ packages/spec/export-origins/api.json | 4 ++++ packages/spec/json-schema.manifest/api.json | 2 ++ 7 files changed, 30 insertions(+), 7 deletions(-) diff --git a/content/docs/references/index.mdx b/content/docs/references/index.mdx index f27ebf7efa3..f2196d8f9e6 100644 --- a/content/docs/references/index.mdx +++ b/content/docs/references/index.mdx @@ -1,7 +1,7 @@ --- title: Protocol reference — every schema by module navTitle: Protocol Reference -description: Every schema published by @objectstack/spec — 1597 schemas across 14 protocol modules +description: Every schema published by @objectstack/spec — 1604 schemas across 14 protocol modules --- {/* ⚠️ AUTO-GENERATED — DO NOT EDIT. Run build-docs.ts to regenerate. Hand-written docs live in the module folders under content/docs/. */} @@ -21,7 +21,7 @@ counts are sums of the rows they head. Regenerate with | Module | Pages | Schemas | Description | | :--- | ---: | ---: | :--- | | [AI Protocol](/docs/references/ai) | 12 | 68 | Agents, tools, skills, RAG and knowledge sources, model registry, conversations. | -| [API Protocol](/docs/references/api) | 34 | 472 | REST contracts, endpoints, routing, realtime, batch, discovery. | +| [API Protocol](/docs/references/api) | 35 | 474 | REST contracts, endpoints, routing, realtime, batch, discovery. | | [Automation Protocol](/docs/references/automation) | 15 | 78 | Flows and their nodes, approvals, ETL pipelines, webhooks, state machines, execution records. | | [Data Protocol](/docs/references/data) | 31 | 174 | Objects, fields, queries, filters, datasources and drivers — the ObjectQL layer. | | [Identity Protocol](/docs/references/identity) | 5 | 27 | Users and accounts, organizations, positions, SCIM provisioning. | @@ -32,9 +32,9 @@ counts are sums of the rows they head. Regenerate with | [Security Protocol](/docs/references/security) | 6 | 37 | Permission sets, row-level security, sharing rules, tenancy posture. | | [Shared Protocol](/docs/references/shared) | 10 | 31 | Primitives used across every protocol — identifiers, HTTP, expressions, error maps, enums. | | [Studio Protocol](/docs/references/studio) | 3 | 35 | Studio designer metadata — the authoring surfaces for the protocols above. | -| [System Protocol](/docs/references/system) | 37 | 287 | The runtime environment — logging, jobs, cache, metrics, notifications, i18n and compliance. | +| [System Protocol](/docs/references/system) | 39 | 292 | The runtime environment — logging, jobs, cache, metrics, notifications, i18n and compliance. | | [UI Protocol](/docs/references/ui) | 16 | 175 | Apps, pages, views, dashboards, reports, actions and themes — the ObjectUI layer. | -| **Total** | **205** | **1597** | 14 protocol modules | +| **Total** | **208** | **1604** | 14 protocol modules | --- @@ -63,7 +63,7 @@ Agents, tools, skills, RAG and knowledge sources, model registry, conversations. ## API Protocol -**Source:** `packages/spec/src/api/` · **Import:** `@objectstack/spec/api` · **34 pages, 472 schemas** +**Source:** `packages/spec/src/api/` · **Import:** `@objectstack/spec/api` · **35 pages, 474 schemas** REST contracts, endpoints, routing, realtime, batch, discovery. @@ -93,6 +93,7 @@ REST contracts, endpoints, routing, realtime, batch, discovery. | [`package-lifecycle.zod.ts`](/docs/references/api/package-lifecycle) | `DiscardPackageDraftsResponse`, `DuplicatePackageResponse`, `EnsureCustomizationPackageRequest`, `EnsureCustomizationPackageResponse`, `GetPackageCustomizationsRequest`, `GetPackageCustomizationsResponse`, `ImportUnmanagedPackageRequest`, `ImportUnmanagedPackageResponse`, `ListPackageCommitsResponse`, `PackageExportBundle`, `PackageExportManifest`, `PackagePublishResult`, `ReassignOrphanedMetadataResponse`, `RevertPackageCommitResponse`, `RollbackToPackageCommitResponse` | | [`plugin-rest-api.zod.ts`](/docs/references/api/plugin-rest-api) | `ErrorHandlingConfig`, `OpenApiGenerationConfig`, `RequestValidationConfig`, `ResponseEnvelopeConfig`, `RestApiEndpoint`, `RestApiPluginConfig`, `RestApiRouteCategory`, `RestApiRouteRegistration`, `ValidationMode` | | [`protocol.zod.ts`](/docs/references/api/protocol) | `AiAgentCapabilities`, `AiAgentChatRequest`, `AiAgentSummary`, `AiAgentsResponse`, `AiChatRequest`, `AiChatResponse`, `AiCompleteRequest`, `AiConversation`, `AiMessage`, `AiModelsResponse`, `AiPendingAction`, `AiPendingActionStatus`, `AiStreamChunk`, `ApproveAiPendingActionResponse`, `AuditMetaItemRequest`, `AuditMetaItemResponse`, `AutomationActionsResponse`, `AutomationTriggerRequest`, `AutomationTriggerResponse`, `BatchDataRequest`, `BatchDataResponse`, `CheckPermissionRequest`, `CheckPermissionResponse`, `CloneDataResponse`, `CreateAiConversationRequest`, `CreateDataRequest`, `CreateDataResponse`, `CreateManyDataRequest`, `CreateManyDataResponse`, `DeleteDataRequest`, `DeleteDataResponse`, `DeleteManyDataRequest`, `DeleteManyDataResponse`, `DeleteMetaItemRequest`, `DeleteMetaItemResponse`, `DiffMetaItemResponse`, `DisablePackageRequest`, `DisablePackageResponse`, `EnablePackageRequest`, `EnablePackageResponse`, `FindDataRequest`, `FindDataResponse`, `FindReferencesToMetaResponse`, `FlowRegistration`, `FlowRegistrationRefusal`, `GetDataRequest`, `GetDataResponse`, `GetDiscoveryRequest`, `GetDiscoveryResponse`, `GetEffectivePermissionsRequest`, `GetEffectivePermissionsResponse`, `GetFieldLabelsRequest`, `GetFieldLabelsResponse`, `GetLocalesRequest`, `GetLocalesResponse`, `GetMetaDiagnosticsResponse`, `GetMetaItemCachedRequest`, `GetMetaItemCachedResponse`, `GetMetaItemLayeredRequest`, `GetMetaItemLayeredResponse`, `GetMetaItemRequest`, `GetMetaItemResponse`, `GetMetaItemsRequest`, `GetMetaItemsResponse`, `GetMetaTypesRequest`, `GetMetaTypesResponse`, `GetNotificationPreferencesRequest`, `GetNotificationPreferencesResponse`, `GetObjectPermissionsRequest`, `GetObjectPermissionsResponse`, `GetPackageRequest`, `GetPackageResponse`, `GetPresenceRequest`, `GetPresenceResponse`, `GetPublishedMetaItemResponse`, `GetRecordFieldAccessResponse`, `GetTranslationsRequest`, `GetTranslationsResponse`, `GetUiViewRequest`, `GetUiViewResponse`, `HistoryMetaItemRequest`, `HistoryMetaItemResponse`, `HttpFindQueryParams`, `InstallPackageRequest`, `InstallPackageResponse`, `ListAiConversationsRequest`, `ListAiConversationsResponse`, `ListAiPendingActionsRequest`, `ListAiPendingActionsResponse`, `ListDraftsResponse`, `ListNotificationsRequest`, `ListNotificationsResponse`, `ListPackagesRequest`, `ListPackagesResponse`, `MarkAllNotificationsReadRequest`, `MarkAllNotificationsReadResponse`, `MarkNotificationsReadRequest`, `MarkNotificationsReadResponse`, `MetadataAuthoringClient`, `MetadataAuthoringSurface`, `MetadataConflictError`, `Notification`, `NotificationPreferences`, `PublicFormSubmitResponse`, `PublishMetaItemRequest`, `PublishMetaItemResponse`, `PublishPackageDraftsRequest`, `PublishPackageDraftsResponse`, `RealtimeConnectRequest`, `RealtimeConnectResponse`, `RealtimeDisconnectRequest`, `RealtimeDisconnectResponse`, `RealtimeSubscribeRequest`, `RealtimeSubscribeResponse`, `RealtimeUnsubscribeRequest`, `RealtimeUnsubscribeResponse`, `RegisterDeviceRequest`, `RegisterDeviceResponse`, `RejectAiPendingActionResponse`, `RollbackMetaItemResponse`, `RuntimeAuthoringIssue`, `SaveMetaItemRequest`, `SaveMetaItemResponse`, `SearchAllHit`, `SearchAllPageHit`, `SearchAllResponse`, `SetPresenceRequest`, `SetPresenceResponse`, `UninstallPackageRequest`, `UninstallPackageResponse`, `UnregisterDeviceRequest`, `UnregisterDeviceResponse`, `UpdateAiConversationRequest`, `UpdateDataRequest`, `UpdateDataResponse`, `UpdateManyDataRequest`, `UpdateManyDataResponse`, `UpdateNotificationPreferencesRequest`, `UpdateNotificationPreferencesResponse`, `ValidateDataIssue`, `ValidateDataRequest`, `ValidateDataResponse` | +| [`push-delivery.zod.ts`](/docs/references/api/push-delivery) | `PushDeliveryData`, `PushRoute` | | [`query-adapter.zod.ts`](/docs/references/api/query-adapter) | `ODataQueryAdapter`, `OperatorMapping`, `QueryAdapterConfig`, `QueryAdapterTarget`, `RestQueryAdapter` | | [`realtime.zod.ts`](/docs/references/api/realtime) | `RealtimeConfig`, `RealtimeEvent`, `RealtimeEventType`, `RealtimePresence`, `Subscription`, `SubscriptionEvent`, `TransportProtocol` | | [`realtime-shared.zod.ts`](/docs/references/api/realtime-shared) | `BasePresence`, `PresenceStatus`, `RealtimeRecordAction` | @@ -324,7 +325,7 @@ Studio designer metadata — the authoring surfaces for the protocols above. ## System Protocol -**Source:** `packages/spec/src/system/` · **Import:** `@objectstack/spec/system` · **37 pages, 287 schemas** +**Source:** `packages/spec/src/system/` · **Import:** `@objectstack/spec/system` · **39 pages, 292 schemas** The runtime environment — logging, jobs, cache, metrics, notifications, i18n and compliance. @@ -355,6 +356,8 @@ The runtime environment — logging, jobs, cache, metrics, notifications, i18n a | [`migration.zod.ts`](/docs/references/system/migration) | `AddFieldOperation`, `ChangeSet`, `CreateObjectOperation`, `DataMigrationFlag`, `DeleteObjectOperation`, `ExecuteSqlOperation`, `MigrationDependency`, `MigrationJournalEvent`, `MigrationOperation`, `ModifyFieldOperation`, `OrganizationOwnershipBirthMarker`, `RemoveFieldOperation`, `RenameObjectOperation` | | [`notification.zod.ts`](/docs/references/system/notification) | `NotificationChannel` | | [`object-storage.zod.ts`](/docs/references/system/object-storage) | `AccessControlConfig`, `BucketConfig`, `FileMetadata`, `LifecycleAction`, `LifecyclePolicyConfig`, `LifecyclePolicyRule`, `MultipartUploadConfig`, `ObjectMetadata`, `ObjectStorageConfig`, `PresignedUrlConfig`, `StorageAcl`, `StorageClass`, `StorageConnection`, `StorageProvider`, `StorageScope` | +| [`push-config.zod.ts`](/docs/references/system/push-config) | `ApnsTransportConfig`, `FcmTransportConfig`, `PushServiceConfig`, `PushVendor` | +| [`push-device.zod.ts`](/docs/references/system/push-device) | `UserDevice` | | [`registry-config.zod.ts`](/docs/references/system/registry-config) | `RegistryConfig`, `RegistrySyncPolicy`, `RegistryUpstream` | | [`search-engine.zod.ts`](/docs/references/system/search-engine) | `AnalyzerConfig`, `FacetConfig`, `SearchConfig`, `SearchIndexConfig`, `SearchProvider` | | [`security-context.zod.ts`](/docs/references/system/security-context) | `ComplianceAuditRequirement`, `ComplianceEncryptionRequirement`, `ComplianceFramework`, `DataClassification`, `DataClassificationPolicy`, `MaskingVisibilityRule`, `SecurityContextConfig`, `SecurityEventCorrelation` | diff --git a/docs/audits/2026-07-unknown-key-strictness-ledger.counts/api.md b/docs/audits/2026-07-unknown-key-strictness-ledger.counts/api.md index 2124b03f462..77495e7d445 100644 --- a/docs/audits/2026-07-unknown-key-strictness-ledger.counts/api.md +++ b/docs/audits/2026-07-unknown-key-strictness-ledger.counts/api.md @@ -19,4 +19,4 @@ hand-patch a number here** — fix the code or the verdict and regenerate. | Dir | Sites | |---|---| -| `api/` | 488 | +| `api/` | 489 | diff --git a/packages/spec/api-surface/api.json b/packages/spec/api-surface/api.json index 98bbe0964fd..3ac6b824000 100644 --- a/packages/spec/api-surface/api.json +++ b/packages/spec/api-surface/api.json @@ -839,6 +839,10 @@ "PublishPackageDraftsRequestSchema (const)", "PublishPackageDraftsResponse (type)", "PublishPackageDraftsResponseSchema (const)", + "PushDeliveryData (type)", + "PushDeliveryDataSchema (const)", + "PushRoute (type)", + "PushRouteSchema (const)", "QueryAdapterConfig (type)", "QueryAdapterConfigParsed (type)", "QueryAdapterConfigSchema (const)", diff --git a/packages/spec/authorable-surface/api.json b/packages/spec/authorable-surface/api.json index 837ab95c135..ff3d9739939 100644 --- a/packages/spec/authorable-surface/api.json +++ b/packages/spec/authorable-surface/api.json @@ -215,6 +215,7 @@ "api/AuthFeaturesConfig:passkeys [RETIRED]", "api/AuthFeaturesConfig:phoneNumber", "api/AuthFeaturesConfig:phoneNumberOtp", + "api/AuthFeaturesConfig:sso", "api/AuthFeaturesConfig:ssoEnforced", "api/AuthFeaturesConfig:turnstileSiteKey", "api/AuthFeaturesConfig:twoFactor", @@ -1424,6 +1425,8 @@ "api/PublishPackageDraftsResponse:success", "api/PublishPackageDraftsResponse:unhiddenApps", "api/PublishPackageDraftsResponse:unhideError", + "api/PushDeliveryData:notificationId", + "api/PushDeliveryData:route", "api/QueryAdapterConfig:odata", "api/QueryAdapterConfig:operatorMappings", "api/QueryAdapterConfig:rest", @@ -1522,10 +1525,13 @@ "api/RecordPageTimelineRequest:discussion", "api/RecordPageTimelineRequest:fieldChanges", "api/RefreshTokenRequest:refreshToken", + "api/RegisterDeviceRequest:appId", "api/RegisterDeviceRequest:deviceId", + "api/RegisterDeviceRequest:locale", "api/RegisterDeviceRequest:name", "api/RegisterDeviceRequest:platform", "api/RegisterDeviceRequest:token", + "api/RegisterDeviceRequest:vendor", "api/RegisterDeviceResponse:deviceId", "api/RegisterDeviceResponse:success", "api/RegisterRequest:email", diff --git a/packages/spec/declaration-map/api.json b/packages/spec/declaration-map/api.json index fbc39c06ae3..74683917166 100644 --- a/packages/spec/declaration-map/api.json +++ b/packages/spec/declaration-map/api.json @@ -615,6 +615,10 @@ "PublishPackageDraftsRequestSchema": "api/PublishPackageDraftsRequest", "PublishPackageDraftsResponse": "api/PublishPackageDraftsResponse", "PublishPackageDraftsResponseSchema": "api/PublishPackageDraftsResponse", + "PushDeliveryData": "api/PushDeliveryData", + "PushDeliveryDataSchema": "api/PushDeliveryData", + "PushRoute": "api/PushRoute", + "PushRouteSchema": "api/PushRoute", "QueryAdapterConfig": "api/QueryAdapterConfig", "QueryAdapterConfigSchema": "api/QueryAdapterConfig", "QueryAdapterTarget": "api/QueryAdapterTarget", diff --git a/packages/spec/export-origins/api.json b/packages/spec/export-origins/api.json index 1b9791a7814..fca37e62787 100644 --- a/packages/spec/export-origins/api.json +++ b/packages/spec/export-origins/api.json @@ -810,6 +810,10 @@ "PublishPackageDraftsRequestSchema": "src/api/protocol.zod.ts#PublishPackageDraftsRequestSchema (const)", "PublishPackageDraftsResponse": "src/api/protocol.zod.ts#PublishPackageDraftsResponse (type)", "PublishPackageDraftsResponseSchema": "src/api/protocol.zod.ts#PublishPackageDraftsResponseSchema (const)", + "PushDeliveryData": "src/api/push-delivery.zod.ts#PushDeliveryData (type)", + "PushDeliveryDataSchema": "src/api/push-delivery.zod.ts#PushDeliveryDataSchema (const)", + "PushRoute": "src/api/push-delivery.zod.ts#PushRoute (type)", + "PushRouteSchema": "src/api/push-delivery.zod.ts#PushRouteSchema (const)", "QueryAdapterConfig": "src/api/query-adapter.zod.ts#QueryAdapterConfig (type)", "QueryAdapterConfigParsed": "src/api/query-adapter.zod.ts#QueryAdapterConfigParsed (type)", "QueryAdapterConfigSchema": "src/api/query-adapter.zod.ts#QueryAdapterConfigSchema (const)", diff --git a/packages/spec/json-schema.manifest/api.json b/packages/spec/json-schema.manifest/api.json index f21644eaa6b..9d1ebd2e95f 100644 --- a/packages/spec/json-schema.manifest/api.json +++ b/packages/spec/json-schema.manifest/api.json @@ -335,6 +335,8 @@ "api/PublishMetaItemResponse", "api/PublishPackageDraftsRequest", "api/PublishPackageDraftsResponse", + "api/PushDeliveryData", + "api/PushRoute", "api/QueryAdapterConfig", "api/QueryAdapterTarget", "api/QueryOptimizationConfig",