From f59cf5609e070fb4aece931d597bcac4362dae07 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 18 Aug 2026 20:25:09 +0000 Subject: [PATCH] feat(spec): declare organizationId on the meta-read request schemas (#9726) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The metadata-protocol implementation accepts and honours organizationId on getMetaItems / getMetaItem / getMetaItemCached — it selects the org partition in the ADR-0005 overlay read order — but none of the three request schemas declared it. Declare the member (optional string, matching the enforced shape), plus GetMetaItemLayeredRequestSchema mirroring the layered verb's inline parameter type next to its already-declared response schema. The MetadataProtocol interface member for getMetaItemLayered is deliberately NOT added: tsc proves the implementation's inline lockSource annotation carries an 'overlay' arm its producer (resolveLockState) can never emit, so declaring the member today would either widen the wire enum untruthfully or break the implementing class. Filed separately. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_016D9wdJR14KKCxz1WgdAzcw --- .../meta-read-organization-id-declared.md | 5 ++ content/docs/references/api/protocol.mdx | 21 +++++- content/docs/references/index.mdx | 10 +-- ...07-unknown-key-strictness-ledger.counts.md | 2 +- packages/spec/api-surface/api.json | 2 + packages/spec/authorable-surface/api.json | 7 ++ packages/spec/export-origins/api.json | 2 + packages/spec/json-schema.manifest/api.json | 1 + packages/spec/src/api/protocol.test.ts | 64 +++++++++++++++++++ packages/spec/src/api/protocol.zod.ts | 57 +++++++++++++++++ .../src/type-alias-convention.pin.test.ts | 13 +++- 11 files changed, 173 insertions(+), 11 deletions(-) create mode 100644 .changeset/meta-read-organization-id-declared.md diff --git a/.changeset/meta-read-organization-id-declared.md b/.changeset/meta-read-organization-id-declared.md new file mode 100644 index 0000000000..54681b918c --- /dev/null +++ b/.changeset/meta-read-organization-id-declared.md @@ -0,0 +1,5 @@ +--- +"@objectstack/spec": minor +--- + +Declare `organizationId` on the metadata read request schemas — `GetMetaItemsRequestSchema`, `GetMetaItemRequestSchema` and `GetMetaItemCachedRequestSchema` — matching the member the protocol implementation has accepted and honoured all along (it selects the org partition in the ADR-0005 overlay read order, deciding which tenant's customization rows are served; on the cached read it also enters the ETag). Also declares `GetMetaItemLayeredRequestSchema` (+ `GetMetaItemLayeredRequest`), the request shape of `GET /api/v1/meta/:type/:name/layers`, mirroring the implementation's parameter type member for member alongside the already-declared layered response schema. Accept-set widening catch-up only: no runtime behaviour changes, and requests without `organizationId` remain valid environment-wide reads. diff --git a/content/docs/references/api/protocol.mdx b/content/docs/references/api/protocol.mdx index 22860de089..f18ed94d5f 100644 --- a/content/docs/references/api/protocol.mdx +++ b/content/docs/references/api/protocol.mdx @@ -12,8 +12,8 @@ description: Protocol protocol schemas ## TypeScript Usage ```typescript -import { AiAgentCapabilitiesSchema, AiAgentChatRequestSchema, AiAgentSummarySchema, AiAgentsResponseSchema, AiChatRequestSchema, AiChatResponseSchema, AiCompleteRequestSchema, AiConversationSchema, AiMessageSchema, AiModelsResponseSchema, AiPendingActionSchema, AiPendingActionStatusSchema, AiStreamChunkSchema, ApproveAiPendingActionResponseSchema, AutomationActionsResponseSchema, AutomationTriggerRequestSchema, AutomationTriggerResponseSchema, BatchDataRequestSchema, BatchDataResponseSchema, CheckPermissionRequestSchema, CheckPermissionResponseSchema, CreateAiConversationRequestSchema, CreateDataRequestSchema, CreateDataResponseSchema, CreateManyDataRequestSchema, CreateManyDataResponseSchema, DeleteDataRequestSchema, DeleteDataResponseSchema, DeleteManyDataRequestSchema, DeleteManyDataResponseSchema, DeleteMetaItemRequestSchema, DeleteMetaItemResponseSchema, DisablePackageRequestSchema, DisablePackageResponseSchema, EnablePackageRequestSchema, EnablePackageResponseSchema, FindDataRequestSchema, FindDataResponseSchema, GetDataRequestSchema, GetDataResponseSchema, GetDiscoveryRequestSchema, GetDiscoveryResponseSchema, GetEffectivePermissionsRequestSchema, GetEffectivePermissionsResponseSchema, GetFieldLabelsRequestSchema, GetFieldLabelsResponseSchema, GetLocalesRequestSchema, GetLocalesResponseSchema, GetMetaItemCachedRequestSchema, GetMetaItemCachedResponseSchema, GetMetaItemLayeredResponseSchema, GetMetaItemRequestSchema, GetMetaItemResponseSchema, GetMetaItemsRequestSchema, GetMetaItemsResponseSchema, GetMetaTypesRequestSchema, GetMetaTypesResponseSchema, GetNotificationPreferencesRequestSchema, GetNotificationPreferencesResponseSchema, GetObjectPermissionsRequestSchema, GetObjectPermissionsResponseSchema, GetPackageRequestSchema, GetPackageResponseSchema, GetPresenceRequestSchema, GetPresenceResponseSchema, GetTranslationsRequestSchema, GetTranslationsResponseSchema, GetUiViewRequestSchema, GetUiViewResponseSchema, HttpFindQueryParamsSchema, InstallPackageRequestSchema, InstallPackageResponseSchema, ListAiConversationsRequestSchema, ListAiConversationsResponseSchema, ListAiPendingActionsRequestSchema, ListAiPendingActionsResponseSchema, ListNotificationsRequestSchema, ListNotificationsResponseSchema, ListPackagesRequestSchema, ListPackagesResponseSchema, MarkAllNotificationsReadRequestSchema, MarkAllNotificationsReadResponseSchema, MarkNotificationsReadRequestSchema, MarkNotificationsReadResponseSchema, NotificationSchema, NotificationPreferencesSchema, PublishMetaItemResponseSchema, PublishPackageDraftsResponseSchema, RealtimeConnectRequestSchema, RealtimeConnectResponseSchema, RealtimeDisconnectRequestSchema, RealtimeDisconnectResponseSchema, RealtimeSubscribeRequestSchema, RealtimeSubscribeResponseSchema, RealtimeUnsubscribeRequestSchema, RealtimeUnsubscribeResponseSchema, RegisterDeviceRequestSchema, RegisterDeviceResponseSchema, RejectAiPendingActionResponseSchema, RuntimeAuthoringIssueSchema, SaveMetaItemRequestSchema, SaveMetaItemResponseSchema, SetPresenceRequestSchema, SetPresenceResponseSchema, UninstallPackageRequestSchema, UninstallPackageResponseSchema, UnregisterDeviceRequestSchema, UnregisterDeviceResponseSchema, UpdateAiConversationRequestSchema, UpdateDataRequestSchema, UpdateDataResponseSchema, UpdateManyDataRequestSchema, UpdateManyDataResponseSchema, UpdateNotificationPreferencesRequestSchema, UpdateNotificationPreferencesResponseSchema, ValidateDataIssueSchema, ValidateDataRequestSchema, ValidateDataResponseSchema } from '@objectstack/spec/api'; -import type { AiAgentCapabilities, AiAgentChatRequest, AiAgentSummary, AiAgentsResponse, AiChatRequest, AiChatResponse, AiCompleteRequest, AiConversation, AiMessage, AiModelsResponse, AiPendingAction, AiPendingActionStatus, AiStreamChunk, ApproveAiPendingActionResponse, AutomationActionsResponse, AutomationTriggerRequest, AutomationTriggerResponse, BatchDataRequest, BatchDataResponse, CheckPermissionRequest, CheckPermissionResponse, CreateAiConversationRequest, CreateDataRequest, CreateDataResponse, CreateManyDataRequest, CreateManyDataResponse, DeleteDataRequest, DeleteDataResponse, DeleteManyDataRequest, DeleteManyDataResponse, DeleteMetaItemRequest, DeleteMetaItemResponse, DisablePackageRequest, DisablePackageResponse, EnablePackageRequest, EnablePackageResponse, FindDataRequest, FindDataResponse, GetDataRequest, GetDataResponse, GetDiscoveryRequest, GetDiscoveryResponse, GetEffectivePermissionsRequest, GetEffectivePermissionsResponse, GetFieldLabelsRequest, GetFieldLabelsResponse, GetLocalesRequest, GetLocalesResponse, GetMetaItemCachedRequest, GetMetaItemCachedResponse, GetMetaItemLayeredResponse, GetMetaItemRequest, GetMetaItemResponse, GetMetaItemsRequest, GetMetaItemsResponse, GetMetaTypesRequest, GetMetaTypesResponse, GetNotificationPreferencesRequest, GetNotificationPreferencesResponse, GetObjectPermissionsRequest, GetObjectPermissionsResponse, GetPackageRequest, GetPackageResponse, GetPresenceRequest, GetPresenceResponse, GetTranslationsRequest, GetTranslationsResponse, GetUiViewRequest, GetUiViewResponse, InstallPackageRequest, InstallPackageResponse, ListAiConversationsRequest, ListAiConversationsResponse, ListAiPendingActionsRequest, ListAiPendingActionsResponse, ListNotificationsRequest, ListNotificationsResponse, ListPackagesRequest, ListPackagesResponse, MarkAllNotificationsReadRequest, MarkAllNotificationsReadResponse, MarkNotificationsReadRequest, MarkNotificationsReadResponse, Notification, NotificationPreferences, PublishMetaItemResponse, PublishPackageDraftsResponse, RealtimeConnectRequest, RealtimeConnectResponse, RealtimeDisconnectRequest, RealtimeDisconnectResponse, RealtimeSubscribeRequest, RealtimeSubscribeResponse, RealtimeUnsubscribeRequest, RealtimeUnsubscribeResponse, RegisterDeviceRequest, RegisterDeviceResponse, RejectAiPendingActionResponse, RuntimeAuthoringIssue, SaveMetaItemRequest, SaveMetaItemResponse, SetPresenceRequest, SetPresenceResponse, UninstallPackageRequest, UninstallPackageResponse, UnregisterDeviceRequest, UnregisterDeviceResponse, UpdateAiConversationRequest, UpdateDataRequest, UpdateDataResponse, UpdateManyDataRequest, UpdateManyDataResponse, UpdateNotificationPreferencesRequest, UpdateNotificationPreferencesResponse, ValidateDataIssue, ValidateDataRequest, ValidateDataResponse } from '@objectstack/spec/api'; +import { AiAgentCapabilitiesSchema, AiAgentChatRequestSchema, AiAgentSummarySchema, AiAgentsResponseSchema, AiChatRequestSchema, AiChatResponseSchema, AiCompleteRequestSchema, AiConversationSchema, AiMessageSchema, AiModelsResponseSchema, AiPendingActionSchema, AiPendingActionStatusSchema, AiStreamChunkSchema, ApproveAiPendingActionResponseSchema, AutomationActionsResponseSchema, AutomationTriggerRequestSchema, AutomationTriggerResponseSchema, BatchDataRequestSchema, BatchDataResponseSchema, CheckPermissionRequestSchema, CheckPermissionResponseSchema, CreateAiConversationRequestSchema, CreateDataRequestSchema, CreateDataResponseSchema, CreateManyDataRequestSchema, CreateManyDataResponseSchema, DeleteDataRequestSchema, DeleteDataResponseSchema, DeleteManyDataRequestSchema, DeleteManyDataResponseSchema, DeleteMetaItemRequestSchema, DeleteMetaItemResponseSchema, DisablePackageRequestSchema, DisablePackageResponseSchema, EnablePackageRequestSchema, EnablePackageResponseSchema, FindDataRequestSchema, FindDataResponseSchema, GetDataRequestSchema, GetDataResponseSchema, GetDiscoveryRequestSchema, GetDiscoveryResponseSchema, GetEffectivePermissionsRequestSchema, GetEffectivePermissionsResponseSchema, GetFieldLabelsRequestSchema, GetFieldLabelsResponseSchema, GetLocalesRequestSchema, GetLocalesResponseSchema, GetMetaItemCachedRequestSchema, GetMetaItemCachedResponseSchema, GetMetaItemLayeredRequestSchema, GetMetaItemLayeredResponseSchema, GetMetaItemRequestSchema, GetMetaItemResponseSchema, GetMetaItemsRequestSchema, GetMetaItemsResponseSchema, GetMetaTypesRequestSchema, GetMetaTypesResponseSchema, GetNotificationPreferencesRequestSchema, GetNotificationPreferencesResponseSchema, GetObjectPermissionsRequestSchema, GetObjectPermissionsResponseSchema, GetPackageRequestSchema, GetPackageResponseSchema, GetPresenceRequestSchema, GetPresenceResponseSchema, GetTranslationsRequestSchema, GetTranslationsResponseSchema, GetUiViewRequestSchema, GetUiViewResponseSchema, HttpFindQueryParamsSchema, InstallPackageRequestSchema, InstallPackageResponseSchema, ListAiConversationsRequestSchema, ListAiConversationsResponseSchema, ListAiPendingActionsRequestSchema, ListAiPendingActionsResponseSchema, ListNotificationsRequestSchema, ListNotificationsResponseSchema, ListPackagesRequestSchema, ListPackagesResponseSchema, MarkAllNotificationsReadRequestSchema, MarkAllNotificationsReadResponseSchema, MarkNotificationsReadRequestSchema, MarkNotificationsReadResponseSchema, NotificationSchema, NotificationPreferencesSchema, PublishMetaItemResponseSchema, PublishPackageDraftsResponseSchema, RealtimeConnectRequestSchema, RealtimeConnectResponseSchema, RealtimeDisconnectRequestSchema, RealtimeDisconnectResponseSchema, RealtimeSubscribeRequestSchema, RealtimeSubscribeResponseSchema, RealtimeUnsubscribeRequestSchema, RealtimeUnsubscribeResponseSchema, RegisterDeviceRequestSchema, RegisterDeviceResponseSchema, RejectAiPendingActionResponseSchema, RuntimeAuthoringIssueSchema, SaveMetaItemRequestSchema, SaveMetaItemResponseSchema, SetPresenceRequestSchema, SetPresenceResponseSchema, UninstallPackageRequestSchema, UninstallPackageResponseSchema, UnregisterDeviceRequestSchema, UnregisterDeviceResponseSchema, UpdateAiConversationRequestSchema, UpdateDataRequestSchema, UpdateDataResponseSchema, UpdateManyDataRequestSchema, UpdateManyDataResponseSchema, UpdateNotificationPreferencesRequestSchema, UpdateNotificationPreferencesResponseSchema, ValidateDataIssueSchema, ValidateDataRequestSchema, ValidateDataResponseSchema } from '@objectstack/spec/api'; +import type { AiAgentCapabilities, AiAgentChatRequest, AiAgentSummary, AiAgentsResponse, AiChatRequest, AiChatResponse, AiCompleteRequest, AiConversation, AiMessage, AiModelsResponse, AiPendingAction, AiPendingActionStatus, AiStreamChunk, ApproveAiPendingActionResponse, AutomationActionsResponse, AutomationTriggerRequest, AutomationTriggerResponse, BatchDataRequest, BatchDataResponse, CheckPermissionRequest, CheckPermissionResponse, CreateAiConversationRequest, CreateDataRequest, CreateDataResponse, CreateManyDataRequest, CreateManyDataResponse, DeleteDataRequest, DeleteDataResponse, DeleteManyDataRequest, DeleteManyDataResponse, DeleteMetaItemRequest, DeleteMetaItemResponse, DisablePackageRequest, DisablePackageResponse, EnablePackageRequest, EnablePackageResponse, FindDataRequest, FindDataResponse, GetDataRequest, GetDataResponse, GetDiscoveryRequest, GetDiscoveryResponse, GetEffectivePermissionsRequest, GetEffectivePermissionsResponse, GetFieldLabelsRequest, GetFieldLabelsResponse, GetLocalesRequest, GetLocalesResponse, GetMetaItemCachedRequest, GetMetaItemCachedResponse, GetMetaItemLayeredRequest, GetMetaItemLayeredResponse, GetMetaItemRequest, GetMetaItemResponse, GetMetaItemsRequest, GetMetaItemsResponse, GetMetaTypesRequest, GetMetaTypesResponse, GetNotificationPreferencesRequest, GetNotificationPreferencesResponse, GetObjectPermissionsRequest, GetObjectPermissionsResponse, GetPackageRequest, GetPackageResponse, GetPresenceRequest, GetPresenceResponse, GetTranslationsRequest, GetTranslationsResponse, GetUiViewRequest, GetUiViewResponse, InstallPackageRequest, InstallPackageResponse, ListAiConversationsRequest, ListAiConversationsResponse, ListAiPendingActionsRequest, ListAiPendingActionsResponse, ListNotificationsRequest, ListNotificationsResponse, ListPackagesRequest, ListPackagesResponse, MarkAllNotificationsReadRequest, MarkAllNotificationsReadResponse, MarkNotificationsReadRequest, MarkNotificationsReadResponse, Notification, NotificationPreferences, PublishMetaItemResponse, PublishPackageDraftsResponse, RealtimeConnectRequest, RealtimeConnectResponse, RealtimeDisconnectRequest, RealtimeDisconnectResponse, RealtimeSubscribeRequest, RealtimeSubscribeResponse, RealtimeUnsubscribeRequest, RealtimeUnsubscribeResponse, RegisterDeviceRequest, RegisterDeviceResponse, RejectAiPendingActionResponse, RuntimeAuthoringIssue, SaveMetaItemRequest, SaveMetaItemResponse, SetPresenceRequest, SetPresenceResponse, UninstallPackageRequest, UninstallPackageResponse, UnregisterDeviceRequest, UnregisterDeviceResponse, UpdateAiConversationRequest, UpdateDataRequest, UpdateDataResponse, UpdateManyDataRequest, UpdateManyDataResponse, UpdateNotificationPreferencesRequest, UpdateNotificationPreferencesResponse, ValidateDataIssue, ValidateDataRequest, ValidateDataResponse } from '@objectstack/spec/api'; // Validate data const result = AiAgentCapabilitiesSchema.parse(data); @@ -681,6 +681,7 @@ Enable package response | **name** | `string` | ✅ | Item name | | **cacheRequest** | `{ ifNoneMatch?: string; ifModifiedSince?: string; cacheControl?: object }` | optional | Cache validation parameters | | **locale** | `string` | optional | Resolved response locale. Folded into the ETag so a language switch never returns a stale-locale 304 — metadata is translated *after* the cache validator check (issue #1319). | +| **organizationId** | `string` | optional | Organization (tenant) scope for the read. Selects the org partition in the ADR-0005 overlay read order — org overlay wins over env-wide overlay wins over packaged artifact — exactly as on the uncached read (#9454). Also folded into the ETag, so a scope switch never returns a stale 304 from another scope's cached representation. Absent = environment-wide read. | --- @@ -699,6 +700,20 @@ Enable package response | **version** | `string` | optional | Metadata version identifier | +--- + +## GetMetaItemLayeredRequest + +### Properties + +| Property | Type | Required | Description | +| :--- | :--- | :--- | :--- | +| **type** | `string` | ✅ | Metadata type name | +| **name** | `string` | ✅ | Item name | +| **packageId** | `string` | optional | Optional package ID — scopes the `code` layer so a same-name collision resolves to the requested package's artifact (ADR-0048). | +| **organizationId** | `string` | optional | Organization (tenant) scope for the read. Selects the org partition in the ADR-0005 overlay read order, so it decides which tenant's customization row is reported as the `overlay` layer (and merged into `effective`). Absent = environment-wide read: `overlay` reports the env-level row only. | + + --- ## GetMetaItemLayeredResponse @@ -737,6 +752,7 @@ Enable package response | **type** | `string` | ✅ | Metadata type name | | **name** | `string` | ✅ | Item name (snake_case identifier) | | **packageId** | `string` | optional | Optional package ID to filter items by | +| **organizationId** | `string` | optional | Organization (tenant) scope for the read. Selects the org partition in the ADR-0005 overlay read order — org overlay wins over env-wide overlay wins over packaged artifact — so it decides which tenant's customization row is served as the item. Absent = environment-wide read: only env-level overlays apply and no org partition is consulted. | --- @@ -772,6 +788,7 @@ Enable package response | :--- | :--- | :--- | :--- | | **type** | `string` | ✅ | Metadata type name (e.g., "object", "plugin") | | **packageId** | `string` | optional | Optional package ID to filter items by | +| **organizationId** | `string` | optional | Organization (tenant) scope for the read. Selects the org partition in the ADR-0005 overlay read order — org overlay wins over env-wide overlay wins over packaged artifact — so it decides which tenant's customization rows are merged into the list. Absent = environment-wide read: only env-level overlays apply and no org partition is consulted. | --- diff --git a/content/docs/references/index.mdx b/content/docs/references/index.mdx index 13f0a57890..3dc3f1d836 100644 --- a/content/docs/references/index.mdx +++ b/content/docs/references/index.mdx @@ -1,6 +1,6 @@ --- title: Protocol Reference -description: Every schema published by @objectstack/spec — 1588 schemas across 14 protocol modules +description: Every schema published by @objectstack/spec — 1589 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/. */} @@ -20,7 +20,7 @@ counts are sums of the rows they head. Regenerate with | Module | Pages | Schemas | Description | | :--- | ---: | ---: | :--- | | [AI Protocol](/docs/references/ai) | 11 | 66 | Agents, tools, skills, RAG and knowledge sources, model registry, conversations. | -| [API Protocol](/docs/references/api) | 28 | 414 | REST/GraphQL contracts, endpoints, routing, realtime, batch, discovery. | +| [API Protocol](/docs/references/api) | 28 | 415 | REST/GraphQL contracts, endpoints, routing, realtime, batch, discovery. | | [Automation Protocol](/docs/references/automation) | 13 | 68 | Flows and their nodes, approvals, ETL pipelines, webhooks, state machines, execution records. | | [Cloud Protocol](/docs/references/cloud) | 11 | 94 | Environments, packages and versions, marketplace, developer portal, tenancy. | | [Data Protocol](/docs/references/data) | 29 | 166 | Objects, fields, queries, filters, datasources and drivers — the ObjectQL layer. | @@ -33,7 +33,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) | 36 | 287 | The runtime environment — logging, jobs, cache, metrics, notifications, i18n and compliance. | | [UI Protocol](/docs/references/ui) | 17 | 162 | Apps, pages, views, dashboards, reports, actions and themes — the ObjectUI layer. | -| **Total** | **199** | **1588** | 14 protocol modules | +| **Total** | **199** | **1589** | 14 protocol modules | --- @@ -61,7 +61,7 @@ Agents, tools, skills, RAG and knowledge sources, model registry, conversations. ## API Protocol -**Source:** `packages/spec/src/api/` · **Import:** `@objectstack/spec/api` · **28 pages, 414 schemas** +**Source:** `packages/spec/src/api/` · **Import:** `@objectstack/spec/api` · **28 pages, 415 schemas** REST/GraphQL contracts, endpoints, routing, realtime, batch, discovery. @@ -86,7 +86,7 @@ REST/GraphQL 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`, `GetInstalledPackageResponse`, `ListInstalledPackagesRequest`, `ListInstalledPackagesResponse`, `PackageApiErrorCode`, `PackageInstallRequest`, `PackageInstallResponse`, `PackagePathParams`, `PackageRollbackRequest`, `PackageRollbackResponse`, `PackageUpgradeRequest`, `PackageUpgradeResponse`, `ResolveDependenciesRequest`, `ResolveDependenciesResponse`, `UninstallPackageApiRequest`, `UninstallPackageApiResponse`, `UploadArtifactRequest`, `UploadArtifactResponse` | | [`plugin-rest-api.zod.ts`](/docs/references/api/plugin-rest-api) | `ErrorHandlingConfig`, `HandlerStatus`, `OpenApiGenerationConfig`, `RequestValidationConfig`, `ResponseEnvelopeConfig`, `RestApiEndpoint`, `RestApiPluginConfig`, `RestApiRouteCategory`, `RestApiRouteRegistration`, `RouteCoverageEntry`, `RouteCoverageReport`, `ValidationMode` | -| [`protocol.zod.ts`](/docs/references/api/protocol) | `AiAgentCapabilities`, `AiAgentChatRequest`, `AiAgentSummary`, `AiAgentsResponse`, `AiChatRequest`, `AiChatResponse`, `AiCompleteRequest`, `AiConversation`, `AiMessage`, `AiModelsResponse`, `AiPendingAction`, `AiPendingActionStatus`, `AiStreamChunk`, `ApproveAiPendingActionResponse`, `AutomationActionsResponse`, `AutomationTriggerRequest`, `AutomationTriggerResponse`, `BatchDataRequest`, `BatchDataResponse`, `CheckPermissionRequest`, `CheckPermissionResponse`, `CreateAiConversationRequest`, `CreateDataRequest`, `CreateDataResponse`, `CreateManyDataRequest`, `CreateManyDataResponse`, `DeleteDataRequest`, `DeleteDataResponse`, `DeleteManyDataRequest`, `DeleteManyDataResponse`, `DeleteMetaItemRequest`, `DeleteMetaItemResponse`, `DisablePackageRequest`, `DisablePackageResponse`, `EnablePackageRequest`, `EnablePackageResponse`, `FindDataRequest`, `FindDataResponse`, `GetDataRequest`, `GetDataResponse`, `GetDiscoveryRequest`, `GetDiscoveryResponse`, `GetEffectivePermissionsRequest`, `GetEffectivePermissionsResponse`, `GetFieldLabelsRequest`, `GetFieldLabelsResponse`, `GetLocalesRequest`, `GetLocalesResponse`, `GetMetaItemCachedRequest`, `GetMetaItemCachedResponse`, `GetMetaItemLayeredResponse`, `GetMetaItemRequest`, `GetMetaItemResponse`, `GetMetaItemsRequest`, `GetMetaItemsResponse`, `GetMetaTypesRequest`, `GetMetaTypesResponse`, `GetNotificationPreferencesRequest`, `GetNotificationPreferencesResponse`, `GetObjectPermissionsRequest`, `GetObjectPermissionsResponse`, `GetPackageRequest`, `GetPackageResponse`, `GetPresenceRequest`, `GetPresenceResponse`, `GetTranslationsRequest`, `GetTranslationsResponse`, `GetUiViewRequest`, `GetUiViewResponse`, `HttpFindQueryParams`, `InstallPackageRequest`, `InstallPackageResponse`, `ListAiConversationsRequest`, `ListAiConversationsResponse`, `ListAiPendingActionsRequest`, `ListAiPendingActionsResponse`, `ListNotificationsRequest`, `ListNotificationsResponse`, `ListPackagesRequest`, `ListPackagesResponse`, `MarkAllNotificationsReadRequest`, `MarkAllNotificationsReadResponse`, `MarkNotificationsReadRequest`, `MarkNotificationsReadResponse`, `Notification`, `NotificationPreferences`, `PublishMetaItemResponse`, `PublishPackageDraftsResponse`, `RealtimeConnectRequest`, `RealtimeConnectResponse`, `RealtimeDisconnectRequest`, `RealtimeDisconnectResponse`, `RealtimeSubscribeRequest`, `RealtimeSubscribeResponse`, `RealtimeUnsubscribeRequest`, `RealtimeUnsubscribeResponse`, `RegisterDeviceRequest`, `RegisterDeviceResponse`, `RejectAiPendingActionResponse`, `RuntimeAuthoringIssue`, `SaveMetaItemRequest`, `SaveMetaItemResponse`, `SetPresenceRequest`, `SetPresenceResponse`, `UninstallPackageRequest`, `UninstallPackageResponse`, `UnregisterDeviceRequest`, `UnregisterDeviceResponse`, `UpdateAiConversationRequest`, `UpdateDataRequest`, `UpdateDataResponse`, `UpdateManyDataRequest`, `UpdateManyDataResponse`, `UpdateNotificationPreferencesRequest`, `UpdateNotificationPreferencesResponse`, `ValidateDataIssue`, `ValidateDataRequest`, `ValidateDataResponse` | +| [`protocol.zod.ts`](/docs/references/api/protocol) | `AiAgentCapabilities`, `AiAgentChatRequest`, `AiAgentSummary`, `AiAgentsResponse`, `AiChatRequest`, `AiChatResponse`, `AiCompleteRequest`, `AiConversation`, `AiMessage`, `AiModelsResponse`, `AiPendingAction`, `AiPendingActionStatus`, `AiStreamChunk`, `ApproveAiPendingActionResponse`, `AutomationActionsResponse`, `AutomationTriggerRequest`, `AutomationTriggerResponse`, `BatchDataRequest`, `BatchDataResponse`, `CheckPermissionRequest`, `CheckPermissionResponse`, `CreateAiConversationRequest`, `CreateDataRequest`, `CreateDataResponse`, `CreateManyDataRequest`, `CreateManyDataResponse`, `DeleteDataRequest`, `DeleteDataResponse`, `DeleteManyDataRequest`, `DeleteManyDataResponse`, `DeleteMetaItemRequest`, `DeleteMetaItemResponse`, `DisablePackageRequest`, `DisablePackageResponse`, `EnablePackageRequest`, `EnablePackageResponse`, `FindDataRequest`, `FindDataResponse`, `GetDataRequest`, `GetDataResponse`, `GetDiscoveryRequest`, `GetDiscoveryResponse`, `GetEffectivePermissionsRequest`, `GetEffectivePermissionsResponse`, `GetFieldLabelsRequest`, `GetFieldLabelsResponse`, `GetLocalesRequest`, `GetLocalesResponse`, `GetMetaItemCachedRequest`, `GetMetaItemCachedResponse`, `GetMetaItemLayeredRequest`, `GetMetaItemLayeredResponse`, `GetMetaItemRequest`, `GetMetaItemResponse`, `GetMetaItemsRequest`, `GetMetaItemsResponse`, `GetMetaTypesRequest`, `GetMetaTypesResponse`, `GetNotificationPreferencesRequest`, `GetNotificationPreferencesResponse`, `GetObjectPermissionsRequest`, `GetObjectPermissionsResponse`, `GetPackageRequest`, `GetPackageResponse`, `GetPresenceRequest`, `GetPresenceResponse`, `GetTranslationsRequest`, `GetTranslationsResponse`, `GetUiViewRequest`, `GetUiViewResponse`, `HttpFindQueryParams`, `InstallPackageRequest`, `InstallPackageResponse`, `ListAiConversationsRequest`, `ListAiConversationsResponse`, `ListAiPendingActionsRequest`, `ListAiPendingActionsResponse`, `ListNotificationsRequest`, `ListNotificationsResponse`, `ListPackagesRequest`, `ListPackagesResponse`, `MarkAllNotificationsReadRequest`, `MarkAllNotificationsReadResponse`, `MarkNotificationsReadRequest`, `MarkNotificationsReadResponse`, `Notification`, `NotificationPreferences`, `PublishMetaItemResponse`, `PublishPackageDraftsResponse`, `RealtimeConnectRequest`, `RealtimeConnectResponse`, `RealtimeDisconnectRequest`, `RealtimeDisconnectResponse`, `RealtimeSubscribeRequest`, `RealtimeSubscribeResponse`, `RealtimeUnsubscribeRequest`, `RealtimeUnsubscribeResponse`, `RegisterDeviceRequest`, `RegisterDeviceResponse`, `RejectAiPendingActionResponse`, `RuntimeAuthoringIssue`, `SaveMetaItemRequest`, `SaveMetaItemResponse`, `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` | | [`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` | diff --git a/docs/audits/2026-07-unknown-key-strictness-ledger.counts.md b/docs/audits/2026-07-unknown-key-strictness-ledger.counts.md index 2f0ba98f8b..22cc1cd2dc 100644 --- a/docs/audits/2026-07-unknown-key-strictness-ledger.counts.md +++ b/docs/audits/2026-07-unknown-key-strictness-ledger.counts.md @@ -258,7 +258,7 @@ directory rather than per file. | Dir | Sites | |---|---| | `ai/` | 77 | -| `api/` | 405 | +| `api/` | 406 | | `cloud/` | 83 | | `identity/` | 32 | | `integration/` | 10 | diff --git a/packages/spec/api-surface/api.json b/packages/spec/api-surface/api.json index 5f7c960288..af93d4b8f3 100644 --- a/packages/spec/api-surface/api.json +++ b/packages/spec/api-surface/api.json @@ -414,6 +414,8 @@ "GetMetaItemCachedResponse (type)", "GetMetaItemCachedResponseParsed (type)", "GetMetaItemCachedResponseSchema (const)", + "GetMetaItemLayeredRequest (type)", + "GetMetaItemLayeredRequestSchema (const)", "GetMetaItemLayeredResponse (type)", "GetMetaItemLayeredResponseSchema (const)", "GetMetaItemRequest (type)", diff --git a/packages/spec/authorable-surface/api.json b/packages/spec/authorable-surface/api.json index 27908ccbbb..a3217c9514 100644 --- a/packages/spec/authorable-surface/api.json +++ b/packages/spec/authorable-surface/api.json @@ -707,6 +707,7 @@ "api/GetMetaItemCachedRequest:cacheRequest", "api/GetMetaItemCachedRequest:locale", "api/GetMetaItemCachedRequest:name", + "api/GetMetaItemCachedRequest:organizationId", "api/GetMetaItemCachedRequest:type", "api/GetMetaItemCachedResponse:cacheControl", "api/GetMetaItemCachedResponse:data", @@ -714,6 +715,10 @@ "api/GetMetaItemCachedResponse:lastModified", "api/GetMetaItemCachedResponse:notModified", "api/GetMetaItemCachedResponse:version", + "api/GetMetaItemLayeredRequest:name", + "api/GetMetaItemLayeredRequest:organizationId", + "api/GetMetaItemLayeredRequest:packageId", + "api/GetMetaItemLayeredRequest:type", "api/GetMetaItemLayeredResponse:_diagnostics", "api/GetMetaItemLayeredResponse:code", "api/GetMetaItemLayeredResponse:deletable", @@ -732,6 +737,7 @@ "api/GetMetaItemLayeredResponse:resettable", "api/GetMetaItemLayeredResponse:type", "api/GetMetaItemRequest:name", + "api/GetMetaItemRequest:organizationId", "api/GetMetaItemRequest:packageId", "api/GetMetaItemRequest:type", "api/GetMetaItemResponse:deletable", @@ -747,6 +753,7 @@ "api/GetMetaItemResponse:provenance", "api/GetMetaItemResponse:resettable", "api/GetMetaItemResponse:type", + "api/GetMetaItemsRequest:organizationId", "api/GetMetaItemsRequest:packageId", "api/GetMetaItemsRequest:type", "api/GetMetaItemsResponse:items", diff --git a/packages/spec/export-origins/api.json b/packages/spec/export-origins/api.json index 55955a7f7e..ac851d53c6 100644 --- a/packages/spec/export-origins/api.json +++ b/packages/spec/export-origins/api.json @@ -414,6 +414,8 @@ "GetMetaItemCachedResponse": "src/api/protocol.zod.ts#GetMetaItemCachedResponse (type)", "GetMetaItemCachedResponseParsed": "src/api/protocol.zod.ts#GetMetaItemCachedResponseParsed (type)", "GetMetaItemCachedResponseSchema": "src/api/protocol.zod.ts#GetMetaItemCachedResponseSchema (const)", + "GetMetaItemLayeredRequest": "src/api/protocol.zod.ts#GetMetaItemLayeredRequest (type)", + "GetMetaItemLayeredRequestSchema": "src/api/protocol.zod.ts#GetMetaItemLayeredRequestSchema (const)", "GetMetaItemLayeredResponse": "src/api/protocol.zod.ts#GetMetaItemLayeredResponse (type)", "GetMetaItemLayeredResponseSchema": "src/api/protocol.zod.ts#GetMetaItemLayeredResponseSchema (const)", "GetMetaItemRequest": "src/api/protocol.zod.ts#GetMetaItemRequest (type)", diff --git a/packages/spec/json-schema.manifest/api.json b/packages/spec/json-schema.manifest/api.json index f8bafc440d..d2d8bbef4f 100644 --- a/packages/spec/json-schema.manifest/api.json +++ b/packages/spec/json-schema.manifest/api.json @@ -174,6 +174,7 @@ "api/GetLocalesResponse", "api/GetMetaItemCachedRequest", "api/GetMetaItemCachedResponse", + "api/GetMetaItemLayeredRequest", "api/GetMetaItemLayeredResponse", "api/GetMetaItemRequest", "api/GetMetaItemResponse", diff --git a/packages/spec/src/api/protocol.test.ts b/packages/spec/src/api/protocol.test.ts index d9d7e8982e..0bb6034ff6 100644 --- a/packages/spec/src/api/protocol.test.ts +++ b/packages/spec/src/api/protocol.test.ts @@ -1286,3 +1286,67 @@ describe('PublishPackageDraftsResponseSchema published[].advisories (#9343 — # ).toBe(false); }); }); + +// Deliberately its own import line, matching the file's later blocks: this +// group pins one change (#9726) and reads as one unit. +import { + GetMetaItemsRequestSchema, + GetMetaItemRequestSchema, + GetMetaItemCachedRequestSchema, + GetMetaItemLayeredRequestSchema, +} from './protocol.zod'; + +describe('meta-read request schemas declare organizationId (#9726 — declared = enforced)', () => { + // The implementation (`@objectstack/metadata-protocol`) accepts and HONOURS + // `organizationId` on all four read verbs: it selects the org partition in + // the ADR-0005 overlay read order, i.e. it decides which tenant's row is + // served. These pins hold the DECLARED surface to that enforced shape. + // + // Why the accept-pin asserts the parsed VALUE, not just `success`: these are + // non-strict objects, so before #9726 a request carrying `organizationId` + // still parsed green — the member was silently STRIPPED. Presence in the + // parse OUTPUT is the observable that actually changed. + const cases = [ + ['GetMetaItemsRequestSchema', GetMetaItemsRequestSchema, { type: 'object' }], + ['GetMetaItemRequestSchema', GetMetaItemRequestSchema, { type: 'view', name: 'account_list' }], + ['GetMetaItemCachedRequestSchema', GetMetaItemCachedRequestSchema, { type: 'view', name: 'account_list' }], + ['GetMetaItemLayeredRequestSchema', GetMetaItemLayeredRequestSchema, { type: 'view', name: 'account_list' }], + ] as const; + + it.each(cases)('%s accepts organizationId and PRESERVES it through parse', (_n, schema, base) => { + const result = schema.safeParse({ ...base, organizationId: 'org_alpha' }); + expect(result.success).toBe(true); + if (result.success) { + expect((result.data as { organizationId?: string }).organizationId).toBe('org_alpha'); + } + }); + + it.each(cases)('%s keeps organizationId OPTIONAL — an env-wide (org-less) read stays valid', (_n, schema, base) => { + const result = schema.safeParse(base); + expect(result.success).toBe(true); + if (result.success) { + expect('organizationId' in (result.data as object)).toBe(false); + } + }); + + it.each(cases)('%s rejects a non-string organizationId — the scope key is a value, not a bag', (_n, schema, base) => { + expect(schema.safeParse({ ...base, organizationId: 42 }).success).toBe(false); + expect(schema.safeParse({ ...base, organizationId: { id: 'org_alpha' } }).success).toBe(false); + }); + + it('GetMetaItemLayeredRequestSchema mirrors the implementation inline type member for member', () => { + // `{ type, name, packageId?, organizationId? }` — the exact parameter type + // of `getMetaItemLayered` in metadata-protocol. packageId scopes the code + // layer (ADR-0048); nothing else is declared because nothing else is + // enforced. + const full = GetMetaItemLayeredRequestSchema.safeParse({ + type: 'view', + name: 'account_list', + packageId: 'pkg_crm', + organizationId: 'org_alpha', + }); + expect(full.success).toBe(true); + expect(GetMetaItemLayeredRequestSchema.safeParse({ type: 'view' }).success).toBe(false); + expect(GetMetaItemLayeredRequestSchema.safeParse({ name: 'account_list' }).success).toBe(false); + }); +}); diff --git a/packages/spec/src/api/protocol.zod.ts b/packages/spec/src/api/protocol.zod.ts index 5a3150dac5..039a5644ce 100644 --- a/packages/spec/src/api/protocol.zod.ts +++ b/packages/spec/src/api/protocol.zod.ts @@ -217,6 +217,13 @@ export const GetMetaTypesResponseSchema = lazySchema(() => z.object({ export const GetMetaItemsRequestSchema = lazySchema(() => z.object({ type: z.string().describe('Metadata type name (e.g., "object", "plugin")'), packageId: z.string().optional().describe('Optional package ID to filter items by'), + organizationId: z.string().optional().describe( + 'Organization (tenant) scope for the read. Selects the org partition in the ' + + 'ADR-0005 overlay read order — org overlay wins over env-wide overlay wins ' + + 'over packaged artifact — so it decides which tenant\'s customization rows ' + + 'are merged into the list. Absent = environment-wide read: only env-level ' + + 'overlays apply and no org partition is consulted.', + ), })); /** @@ -235,6 +242,13 @@ export const GetMetaItemRequestSchema = lazySchema(() => z.object({ type: z.string().describe('Metadata type name'), name: z.string().describe('Item name (snake_case identifier)'), packageId: z.string().optional().describe('Optional package ID to filter items by'), + organizationId: z.string().optional().describe( + 'Organization (tenant) scope for the read. Selects the org partition in the ' + + 'ADR-0005 overlay read order — org overlay wins over env-wide overlay wins ' + + 'over packaged artifact — so it decides which tenant\'s customization row ' + + 'is served as the item. Absent = environment-wide read: only env-level ' + + 'overlays apply and no org partition is consulted.', + ), })); /** @@ -349,6 +363,30 @@ export const GetMetaItemResponseSchema = lazySchema(() => z.object({ ...MetadataProtectionEnvelopeFields, })); +/** + * Get Metadata Item — LAYERED Request + * + * Request shape for `GET /api/v1/meta/:type/:name/layers` (the + * `getMetaItemLayered` protocol method). Mirrors the implementation's + * parameter type in `@objectstack/metadata-protocol` member for member — a + * declared-surface catch-up, not a new capability: the verb and every member + * here already ship and are enforced. + */ +export const GetMetaItemLayeredRequestSchema = lazySchema(() => z.object({ + type: z.string().describe('Metadata type name'), + name: z.string().describe('Item name'), + packageId: z.string().optional().describe( + 'Optional package ID — scopes the `code` layer so a same-name collision ' + + 'resolves to the requested package\'s artifact (ADR-0048).', + ), + organizationId: z.string().optional().describe( + 'Organization (tenant) scope for the read. Selects the org partition in the ' + + 'ADR-0005 overlay read order, so it decides which tenant\'s customization ' + + 'row is reported as the `overlay` layer (and merged into `effective`). ' + + 'Absent = environment-wide read: `overlay` reports the env-level row only.', + ), +})); + /** * Get Metadata Item — LAYERED Response * @@ -921,6 +959,13 @@ export const GetMetaItemCachedRequestSchema = lazySchema(() => z.object({ + 'never returns a stale-locale 304 — metadata is translated *after* the ' + 'cache validator check (issue #1319).', ), + organizationId: z.string().optional().describe( + 'Organization (tenant) scope for the read. Selects the org partition in the ' + + 'ADR-0005 overlay read order — org overlay wins over env-wide overlay wins ' + + 'over packaged artifact — exactly as on the uncached read (#9454). Also ' + + 'folded into the ETag, so a scope switch never returns a stale 304 from ' + + 'another scope\'s cached representation. Absent = environment-wide read.', + ), })); /** @@ -2035,6 +2080,7 @@ export type GetMetaItemsRequest = z.input; export type GetMetaItemsResponse = z.input; export type GetMetaItemRequest = z.input; export type GetMetaItemResponse = z.input; +export type GetMetaItemLayeredRequest = z.input; export type GetMetaItemLayeredResponse = z.input; /** * One #4463 runtime authoring-gate finding. The SINGLE declaration of the shape; @@ -2291,6 +2337,17 @@ export interface MetadataProtocol { */ deleteMetaItem?(request: DeleteMetaItemRequest): Promise; getMetaItemCached?(request: GetMetaItemCachedRequest): Promise; + // `getMetaItemLayered` is deliberately NOT declared here yet, although both + // its request and response schemas are (see them above). Declaring the + // member makes tsc check `metadata-protocol`'s implementation against + // `GetMetaItemLayeredResponse`, and that check currently fails on one + // member: the implementation's inline return type annotates `lockSource` + // with an `'overlay'` arm that its only producer (`resolveLockState`, whose + // return is typed `MetadataLockSource | undefined`) can never emit — an + // over-wide annotation, not enforced behaviour. Until that annotation is + // corrected at the implementation, adding the member here would either lie + // about the wire enum or hard-break the implementing class. Tracked as its + // own card (filed from #9726). getUiView?(request: GetUiViewRequest): Promise; } diff --git a/packages/spec/src/type-alias-convention.pin.test.ts b/packages/spec/src/type-alias-convention.pin.test.ts index 4a05640cbe..51d37c9dc4 100644 --- a/packages/spec/src/type-alias-convention.pin.test.ts +++ b/packages/spec/src/type-alias-convention.pin.test.ts @@ -264,7 +264,7 @@ import type * as M167 from './ui/view.zod.js'; import type * as M170 from './ui/component.zod.js'; // --------------------------------------------------------------------------- -// 839 isomorphic aliases: `z.input` === `z.infer`, so no `XParsed` is declared. +// 840 isomorphic aliases: `z.input` === `z.infer`, so no `XParsed` is declared. // // That number is machine-checked, not hand-kept. The runtime companion at the // bottom of this file recomputes the pin count from the source and asserts that @@ -469,6 +469,7 @@ export type Iso131 = Assert, export type Iso132 = Assert, z.infer< typeof M28.GetMetaItemsResponseSchema > >>; export type Iso133 = Assert, z.infer< typeof M28.GetMetaItemRequestSchema > >>; export type Iso134 = Assert, z.infer< typeof M28.GetMetaItemResponseSchema > >>; +export type Iso853 = Assert, z.infer< typeof M28.GetMetaItemLayeredRequestSchema > >>; export type Iso833 = Assert, z.infer< typeof M28.GetMetaItemLayeredResponseSchema > >>; export type Iso135 = Assert, z.infer< typeof M28.SaveMetaItemRequestSchema > >>; export type Iso136 = Assert, z.infer< typeof M28.SaveMetaItemResponseSchema > >>; @@ -1656,7 +1657,7 @@ describe('ADR-0122 type-alias convention', () => { // this title and the section header above the pin list — are now asserted // against the recomputed count below, so neither can go stale without a red // test naming it. - it('still declares all 839 isomorphic pins', () => { + it('still declares all 840 isomorphic pins', () => { // The truth of each pin is proved by tsc, not here — an `Assert>` // that stops holding is a compile error with the alias named. What tsc // cannot notice is a pin that was DELETED: removing the assertion removes @@ -1906,9 +1907,15 @@ describe('ADR-0122 type-alias convention', () => { // byte-stability promise (an advisory-free publish response unchanged by // the declaration) relies on parse fabricating nothing. Pinned as // `Iso852`, the next free id. + // + // 839 -> 840 is #9726 — `GetMetaItemLayeredRequestSchema`, the declared- + // surface catch-up for the layered read verb: four plain string members + // (two optional), no `.default()`, `.transform()`, `.catch()` or `.pipe()`, + // mirroring metadata-protocol's inline parameter type member for member. + // Pinned as `Iso853`, the next free id. const self = readFileSync(fileURLToPath(import.meta.url), 'utf8'); const pins = self.match(/^export type Iso\d+ = Assert