Skip to content

Commit 2dfe070

Browse files
docs(spec): meta-read organizationId describes stop promising a supplied org is always consulted (#16524) (#20177)
Fixes #16524 Clause-②: no ## What this changes Three published `.describe()` strings in `packages/spec/src/api/protocol.zod.ts`, the `organizationId` member of: | schema | was | now | |:--|:--|:--| | `GetMetaItemRequestSchema` | "Selects the org partition in the ADR-0005 overlay read order … Absent = environment-wide read: only env-level overlays apply and no org partition is consulted." | "When an org partition applies, this selects it in the ADR-0005 overlay read order … Supplying a value does not by itself guarantee an org partition is consulted; where none applies, and whenever it is absent, the read is environment-wide and only env-level overlays apply." | | `GetMetaItemLayeredRequestSchema` | "Selects the org partition … Absent = environment-wide read: `overlay` reports the env-level row only." | "When an org partition applies, this selects it … Supplying a value does not by itself guarantee an org partition is consulted; where none applies, and whenever it is absent, the read is environment-wide: `overlay` reports the env-level row only." | | `GetMetaItemCachedRequestSchema` | "Selects the org partition … exactly as on the uncached read. Also folded into the ETag, … Absent = environment-wide read." | "When an org partition applies, this selects it … exactly as on the uncached read. Also folded into the ETag, … Supplying a value does not by itself guarantee an org partition is consulted; where none applies, and whenever it is absent, the read is environment-wide." | Plus the regenerated `content/docs/references/api/protocol.mdx` (three table rows) and an `@objectstack/spec` **patch** changeset. Prose only: no key, export, accept set or runtime behaviour changes. A supplied `organizationId` is still accepted on all three requests, and the runtime still drops it where no org partition applies. ## Rulings carried - Ruling B (comment 5567936958), maintainer, verbatim: 「协议不对不是应该修改协议吗?」. The describes are protocol text, so they are corrected now. The wording qualifies the promise, states the negative, names neither `allowOrgOverride` nor the registry (no registry clause), and adds no key. Its shape matches the sibling `GetMetaItemsRequestSchema.organizationId` row reworded in PR #16523, so the four meta-read rows now read the same way. - Scope ruling (comment 5807019811), maintainer, verbatim: 「16524 改文档,不需要按组织取」. This PR changes published text only: no runtime change, and no refusal of a supplied `organizationId`. - Measured correction (comment 5612706063): on `GetMetaItemCachedRequestSchema` only the opening sentence overstated. The ETag sentence ("Also folded into the ETag, so a scope switch never returns a stale 304 from another scope's cached representation.") is true, is pinned by PR #17292, and is **kept byte-for-byte**. Its source line does not appear in this diff. ## Premise re-verified on today's tree Measured on `84880f9` (BASE); the merge of `369bcbed` touched no file below. - The gate is `organizationIdForMetaRead` (`packages/metadata-core/src/meta-write-org-scope.ts:184`). It returns `undefined` unless `declaresOrgOverride(type)` holds. - `getMetaItem` (`packages/metadata-protocol/src/protocol.ts`) reads `request.organizationId` only through the gate (`:8123`). A gated-away value resolves `findDraft(null)` (`:8161`) and `findOverlay(null)` (`:8227`-`:8228`), which are env-level. - `getMetaItemLayered` gates at `:8633`. `if (orgId)` at `:8728` skips the org overlay read entirely, and only `findOverlay(null)` runs. - `getMetaItemCached` delegates to `getMetaItem` (`:12199`), so the same drop applies. The ETag folds the *supplied* value (`:12294`), so the kept ETag sentence stays true. The runtime still behaves as the ruling describes, so no stop was needed. ## Verification All at head `3388f2920` (branch merged with `origin/main` `369bcbed`), unless noted. Every heavy run went through `scripts/pm/os-verify-lock.sh`, and each result is the `VERDICT command-exit` line. - `pnpm --filter @objectstack/spec build`, then `check:generated`: before `--fix`, exactly 1 of 15 artefacts was stale (`content/docs/references/**`). `--fix` regenerated that one, and the three `organizationId` rows in `protocol.mdx` are the only lines that moved. After the merge: "All 15 generated artifacts are up to date", exit 0. - `pnpm --filter @objectstack/spec test`: 540 files, 15820 passed and 2 todo, exit 0. `src/api/protocol.test.ts` alone: 178 passed. - `pnpm --filter @objectstack/spec typecheck` (tsc, scripts, and the test layer): exit 0. - Compiled `dist` read back: the three new descriptions are present, "allowOrgOverride" and "registry" each count 0 in them, and the ETag sentence occurs verbatim once. - `node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack` derived 101 commands, the same list before and after the merge. `--ran` reconciliation reads "101 derived, 100 run, 1 NOT-MEASURED, 0 UNRUN". All 100 that ran exited 0. - NOT MEASURED: `pnpm check:dual-build-cjs-loads` (exit 3, PREREQUISITE NOT MET). It needs every publishable package built: 33 still had no `dist/` after the closure build below, and CI's `Build Core` runs it. As a declared narrowing, I loaded every `require` entry of `@objectstack/spec`, the only package this diff rebuilds, under CJS: 23 of 23 loaded. The gate's own `--list` names 18 spec entries, all inside those 23. Every other package's dist is unaffected by string edits in `packages/spec/src`. - For five gates the first run refused with PREREQUISITE NOT MET (unbuilt `lint` / `formula` / `client-react` / `objectql`): `check:skill-examples`, `check:doc-formula-expressions`, `check:doc-security-posture`, `check:docs-transcript-drift` and `check:lean-entry-closure`. After a turbo build of that 34-task closure they ran green. `check-plugin-teardown-shape --self-test` first refused on the shallow clone; it went green after a depth-1 fetch of its pinned fixture commit. - `check:dts-closure` and `check:sourcemap-no-sources-content` swept 1 built package, `@objectstack/spec`, which is the one this diff touches. - ESLint (narrowed, a measurement rather than a skip): `eslint --no-inline-config --format json` over the three touched paths returns 3 entries. `protocol.zod.ts` has 0 errors and 0 warnings. The `.md` and `.mdx` answer "no matching configuration", which means they are outside the population defined by `eslint.config.mjs`'s `files` globs. The config enables no type-aware linting (no `parserOptions.project`, zero `projectService`), so this diff cannot move a verdict on any untouched file. The repo-wide `pnpm lint` is left to CI. - No pin test is added. These strings are prose that no consumer parses, and pinning their wording would only freeze the wording. ## Acceptance notes - `packages/spec/src/api/protocol.test.ts:1599`-`1602`, a test comment, still says the implementation "accepts and HONOURS `organizationId` on all four read verbs: it selects the org partition … it decides which tenant's row is served". That is the same overstatement, in an unpublished test comment. It is outside this card's claimed file surface, so I left it. Carrier: none. - Draft PR #19637 also regenerates `content/docs/references/api/protocol.mdx`. Whichever PR lands second regenerates that file; the file is routed to the `os-regen` merge driver. --- _Generated by [Claude Code](https://claude.ai/code/session_01CiCTczDo7tGhafXjf61dUJ)_ --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent 836aad2 commit 2dfe070

3 files changed

Lines changed: 37 additions & 16 deletions

File tree

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
---
2+
'@objectstack/spec': patch
3+
---
4+
5+
docs(spec): the `organizationId` describes on `GetMetaItemRequestSchema`, `GetMetaItemLayeredRequestSchema` and `GetMetaItemCachedRequestSchema` no longer promise that a supplied organization is always consulted (#16524)
6+
7+
Clause-②: no
8+
9+
Each of the three published `describe()`s opened with "Selects the org partition in the ADR-0005 overlay read order" and closed with an absent-only statement ("Absent = environment-wide read …"). Read together, an integrator completes that as *present ⇒ consulted*, and it is not: on `getMetaItem`, `getMetaItemLayered` and `getMetaItemCached` a supplied organization is dropped wherever no org partition applies, and the read resolves environment-wide exactly as if none had been sent.
10+
11+
The corrected text takes the same shape as the sibling `GetMetaItemsRequestSchema.organizationId` describe: the parameter selects the org partition **when an org partition applies**, and supplying a value "does not by itself guarantee an org partition is consulted; where none applies, and whenever it is absent, the read is environment-wide". On `GetMetaItemCachedRequestSchema` the ETag sentence ("Also folded into the ETag, so a scope switch never returns a stale 304 from another scope's cached representation") is true and is kept byte-for-byte.
12+
13+
Prose only. No key is added, removed or renamed, no export moves, no accept set changes and no runtime behaviour changes — a supplied `organizationId` is still accepted on all three requests, and the runtime still drops it where no org partition applies. What ships is the JSON-Schema `description` of the existing `organizationId` key on the three requests and the matching rows in the generated API reference.

‎content/docs/references/api/protocol.mdx‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1216,7 +1216,7 @@ Enable package response
12161216
| **name** | `string` | ✅ | Item name |
12171217
| **cacheRequest** | `{ ifNoneMatch?: string; ifModifiedSince?: string; cacheControl?: object }` | optional | Cache validation parameters |
12181218
| **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). |
1219-
| **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. Also folded into the ETag, so a scope switch never returns a stale 304 from another scope's cached representation. Absent = environment-wide read. |
1219+
| **organizationId** | `string` | optional | Organization (tenant) scope for the read. When an org partition applies, this selects it in the ADR-0005 overlay read order — org overlay wins over env-wide overlay wins over packaged artifact — exactly as on the uncached read. Also folded into the ETag, so a scope switch never returns a stale 304 from another scope's cached representation. Supplying a value does not by itself guarantee an org partition is consulted; where none applies, and whenever it is absent, the read is environment-wide. |
12201220

12211221
### Nested Shape: `GetMetaItemCachedRequest.cacheRequest`
12221222

@@ -1270,7 +1270,7 @@ Enable package response
12701270
| **type** | `string` | ✅ | Metadata type name |
12711271
| **name** | `string` | ✅ | Item name |
12721272
| **packageId** | `string` | optional | Optional package ID — scopes the `code` layer so a same-name collision resolves to the requested package's artifact (ADR-0048). |
1273-
| **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. |
1273+
| **organizationId** | `string` | optional | Organization (tenant) scope for the read. When an org partition applies, this selects it 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`). Supplying a value does not by itself guarantee an org partition is consulted; where none applies, and whenever it is absent, the read is environment-wide: `overlay` reports the env-level row only. |
12741274

12751275

12761276
---
@@ -1319,7 +1319,7 @@ Enable package response
13191319
| **type** | `string` | ✅ | Metadata type name |
13201320
| **name** | `string` | ✅ | Item name (snake_case identifier) |
13211321
| **packageId** | `string` | optional | Optional package ID to filter items by |
1322-
| **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. |
1322+
| **organizationId** | `string` | optional | Organization (tenant) scope for the read. When an org partition applies, this selects it 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. Supplying a value does not by itself guarantee an org partition is consulted; where none applies, and whenever it is absent, the read is environment-wide and only env-level overlays apply. |
13231323
| **state** | `Enum<'active' \| 'draft'>` | optional | Draft-visibility switch — which lifecycle row to read (strict mode): `'draft'` opens the pending draft buffer (Studio's editor read) and fails when no draft exists; absent or `'active'` reads the live published row. Distinct from `previewDrafts`, which FALLS BACK to the active row when no draft exists. Declaration ≠ authorization: this member only selects which stored row is read — ADR-0106 masking is unaffected, and draft access is gated upstream, not by this schema. |
13241324
| **previewDrafts** | `boolean` | optional | Draft-visibility switch (ADR-0033 draft-overlay preview, non-strict): when true and `state` is not `'draft'`, a pending draft row is preferred if one exists, else the read falls back to the active row — the render path degrades to the published value instead of erroring. A served draft is tagged `_draft: true` so UIs can badge it. Declaration ≠ authorization: this member only switches which row is read, and ADR-0106 masking is unaffected — draft preview is admin-gated upstream, not by this schema. |
13251325

‎packages/spec/src/api/protocol.zod.ts‎

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -274,11 +274,13 @@ export const GetMetaItemRequestSchema = lazySchema(() => z.object({
274274
name: z.string().describe('Item name (snake_case identifier)'),
275275
packageId: z.string().optional().describe('Optional package ID to filter items by'),
276276
organizationId: z.string().optional().describe(
277-
'Organization (tenant) scope for the read. Selects the org partition in the '
278-
+ 'ADR-0005 overlay read order — org overlay wins over env-wide overlay wins '
279-
+ 'over packaged artifact — so it decides which tenant\'s customization row '
280-
+ 'is served as the item. Absent = environment-wide read: only env-level '
281-
+ 'overlays apply and no org partition is consulted.',
277+
'Organization (tenant) scope for the read. When an org partition applies, '
278+
+ 'this selects it in the ADR-0005 overlay read order — org overlay wins '
279+
+ 'over env-wide overlay wins over packaged artifact — so it decides which '
280+
+ 'tenant\'s customization row is served as the item. Supplying a value '
281+
+ 'does not by itself guarantee an org partition is consulted; where none '
282+
+ 'applies, and whenever it is absent, the read is environment-wide and '
283+
+ 'only env-level overlays apply.',
282284
),
283285
state: z.enum(['active', 'draft']).optional().describe(
284286
'Draft-visibility switch — which lifecycle row to read (strict mode): '
@@ -444,10 +446,13 @@ export const GetMetaItemLayeredRequestSchema = lazySchema(() => z.object({
444446
+ 'resolves to the requested package\'s artifact (ADR-0048).',
445447
),
446448
organizationId: z.string().optional().describe(
447-
'Organization (tenant) scope for the read. Selects the org partition in the '
448-
+ 'ADR-0005 overlay read order, so it decides which tenant\'s customization '
449-
+ 'row is reported as the `overlay` layer (and merged into `effective`). '
450-
+ 'Absent = environment-wide read: `overlay` reports the env-level row only.',
449+
'Organization (tenant) scope for the read. When an org partition applies, '
450+
+ 'this selects it in the ADR-0005 overlay read order, so it decides which '
451+
+ 'tenant\'s customization row is reported as the `overlay` layer (and '
452+
+ 'merged into `effective`). Supplying a value does not by itself guarantee '
453+
+ 'an org partition is consulted; where none applies, and whenever it is '
454+
+ 'absent, the read is environment-wide: `overlay` reports the env-level '
455+
+ 'row only.',
451456
),
452457
}));
453458

@@ -1818,11 +1823,14 @@ export const GetMetaItemCachedRequestSchema = lazySchema(() => z.object({
18181823
+ 'cache validator check (issue).',
18191824
),
18201825
organizationId: z.string().optional().describe(
1821-
'Organization (tenant) scope for the read. Selects the org partition in the '
1822-
+ 'ADR-0005 overlay read order — org overlay wins over env-wide overlay wins '
1823-
+ 'over packaged artifact — exactly as on the uncached read. Also '
1826+
'Organization (tenant) scope for the read. When an org partition applies, '
1827+
+ 'this selects it in the ADR-0005 overlay read order — org overlay wins '
1828+
+ 'over env-wide overlay wins over packaged artifact — exactly as on the '
1829+
+ 'uncached read. Also '
18241830
+ 'folded into the ETag, so a scope switch never returns a stale 304 from '
1825-
+ 'another scope\'s cached representation. Absent = environment-wide read.',
1831+
+ 'another scope\'s cached representation. Supplying a value does not by '
1832+
+ 'itself guarantee an org partition is consulted; where none applies, and '
1833+
+ 'whenever it is absent, the read is environment-wide.',
18261834
),
18271835
}));
18281836

0 commit comments

Comments
 (0)