Skip to content

Commit e23eccb

Browse files
feat(spec,metadata-protocol)!: rename the type registry's allowOrgOverride to allowEnvironmentOverlay, on the registry and on GET /meta/types (#22874)
Part of #22340 Clause-②: yes (narrowing) ADR-0131 C5's spec half (stage S2): the metadata type registry's `allowOrgOverride` is renamed to `allowEnvironmentOverlay`, on `DEFAULT_METADATA_TYPE_REGISTRY` and on the `GET /meta/types` wire field, under ruling C on #22007 (`6028809298`), ruling `6073921182` (Q1 A, Q2 A) and the pre-build contract review `6109457426`, which fixed the name. #22340 stays open for S3, the governed text. **The console pin moves with the rename, in this PR.** `.objectui-sha` is objectui `e5311165a8d6`, the merge of objectstack-ai/objectui#12168, which carries objectstack-ai/objectui#12141: from that commit on, objectui's metadata admin reads the wire field under its new name only, with no dual read. The two halves land together. Any other pin bump past `e5311165a8` before this PR lands would show the five overlay-enabled types read-only in Studio. The landing record is the contract review on this post-pin head. ## What changes - **The key.** `MetadataTypeRegistryEntry.allowEnvironmentOverlay` (default `false`) with the contract review's describe and TSDoc. `allowOrgOverride` is a `retiredKey()` tombstone on `MetadataTypeRegistryEntryBaseSchema` whose prescription names the new key: the old key fails `tsc` and fails the parse (`invalid_type` at `allowOrgOverride`). The prescription reads "was renamed to `allowEnvironmentOverlay` (ADR-0131 D6)" and names no version: the changeset ships this as `major` on the `18.0.0-next` line, and the TSDoc's "in 18" names the protocol major. All 28 built-in rows spell the new key; every value is unchanged (the true set is `view`, `dashboard`, `report`, `translation`, `email_template`). - **The ledger (ADR-0087).** Retired-keys entry `18.kernel__MetadataTypeRegistryEntry__allowOrgOverride`; D3 semantic entry `metadata-type-registry-allow-org-override-renamed`, covering the registry key AND the wire field; its `STEP18_RATIONALE` fragment (order 94). No D2 conversion, as ruled: no manifest, stack or stored row can carry a registry entry. No `registry.ts`, `spec-changes.json` or upgrade guide is committed (git-ignored, generated). - **The wire, one spelling.** `getMetaTypes` writes the `OS_METADATA_WRITABLE` elevation onto `allowEnvironmentOverlay` on BOTH arms: the registry arm (the `...base` spread already carries the new key, and the elevated value overwrites it) and the synthesised arm of a runtime type with no registry row. No entry carries `allowOrgOverride`. The field's describe says the elevation opens only items no managed package ships; `overrideSource` keeps `registry` / `env` and its describe names the new field. - **The read-side trap, hand-renamed.** A truthiness reader of the old key compiles against the tombstone and reads `undefined`, which closes all five types. The readers moved by hand: `protocol.ts` `getMetaTypes` (both arms) and `OVERLAY_ALLOWED_TYPES`, and `sys-metadata-repository.ts`'s `OVERLAY_ALLOWED_TYPES`. Every test reader moved with them. - **`supportsOverlay` keeps its name and both keys stay** (contract review item 2: ADR-0049 retires neither). Its TSDoc and its three describes (registry, `GetMetaTypesResponse`, `MetadataTypeInfoResponse`) and the stale read claims in `protocol.ts` and `sys-metadata-repository.ts` now say what it gates: the delete carve-out, no save and no read. **Wording used: PR #22833's**, which landed (`8c105e3d67`) before this branch merged `main`: the removal "removes no managed definition, and changes what is served for `permission` alone". - **Prose that tied the flag to organization scope** is rewritten, not mechanically renamed: the key's TSDoc and describe, `email-template.zod.ts`, `kernel/index.ts`, the `customizationPolicies` prescription (and its pin), the unreleased D3 `metadata-customization-protocol-retired` and its fragment, and the comments in `protocol.ts`, `rest-server.ts`, runtime `packages.ts` / `mcp.ts` and `sys-flow-credential.object.ts`. A comment that records history keeps the name of its time: `sys-metadata-repository.ts` still says commit `ee58392e1` rolled `allowOrgOverride` back. - **The refusal sentences** that named the flag name the new key; codes and statuses are unchanged. - **Tests.** The 74 files that named the key move to the new key. The 20 files that pin the RETIRED per-organization path label their specimens as the five overlay-enabled types (the set those doors once scoped to an organization), so no label reads as "org-overridable = `allowEnvironmentOverlay`"; their `ORG_OVERRIDABLE` identifiers are now `PRE_D6_ORG_SCOPED`. The two plugin-security doubles throw the sentence the producer emits today. - **Docs and tooling.** `metadata-lifecycle.mdx`'s whitelist table header moves with `check-overlay-whitelist-table.mjs`'s `COL_FLAG` and its self-test fixtures, in one change; 10 more `content/docs` pages; 8 platform-checklist files, both `metadata-plugin.zod.ts#allowOrgOverride` anchors re-pointed to `#allowEnvironmentOverlay` (revision-history `change` entries keep the old name); 3 liveness notes; 2 ADR anchors; the regenerated references. - **The changeset** (`major` on the v18 pre-mode line, the `22572` precedent): BREAKING, the FROM / TO table for registry entries and `/meta/types` entries, `Clause-②: yes (narrowing)` and the ADR-0087 `registered` marker. ## The console pin (round 2) **The hop.** objectui `4997995022f8..e5311165a8d6` (`.objectui-sha` was `4997995022f8` on `main` at the merge): 24 commits, all non-merge squashes, over 287 paths (214 modified, 69 added, 4 deleted, none renamed), +13412 / −2428. objectui `4baa8a67c4` (objectui#12170: `slotsForType` stops reading the retired `flow-template` ledger role) is INSIDE it, two commits below the new tip: `git merge-base --is-ancestor 4baa8a67c4 e5311165a8` exits 0, and `--is-ancestor 4baa8a67c4 4997995022f8` exits 1, read in a full (non-shallow) clone whose control leg (`d32869883b`, 50 commits below the old pin) answers 0. Its changeset is release-nothing, so the console changeset counts it among the 2 release-nothing changesets rather than listing it. **The Console Pin Gate's steps, run locally on this head:** `turbo run build --filter=@objectstack/client...` exit 0; `scripts/build-console.sh` exit 0 at `e5311165a8d6` (objectui cloned from the pin into `.cache/`, 8872 modules; bundle canary `import/jobs` present; one zod version literal; "Console bundle carries THIS tree's @objectstack/spec, and only it"); the dist and its `.objectui-sha` stamp in place; `pnpm check:console-sha` exit 0 (objectui@e5311165a8d6); `pnpm check:console-injection --require-stamp` exit 0. The injection's stale detector is the published spec's describe of the retired key, "Allow per-org overlay writes via runtime metadata API", and it is absent from the bundle. **Against this PR's wire.** The built bundle's app code reads `allowEnvironmentOverlay` 15 times (`metadata-admin`, `packagedActions` and the shell; for example the read-only verdict is `!u.allowEnvironmentOverlay && !u.allowRuntimeCreate`). `allowOrgOverride` occurs only inside this tree's spec, in the tombstone and its prescription text (4 occurrences, all in the `vendor-objectstack` chunk); no app code reads it. Then the two together, on a booted backend: `pnpm dev -- --fresh -p 38977` on this head (showcase, the console dist above, `check:console-sha` green at boot). The live `GET /api/v1/meta/types` answered 34 entries: all 34 carry `allowEnvironmentOverlay`, none carries `allowOrgOverride`, and `true` is exactly `view`, `dashboard`, `report`, `translation` and `email_template`, each with `overrideSource: registry`. In a headless Chromium signed in as the seeded admin, the console's Setup metadata pages read that wire: a packaged `view` (`showcase_task.in_progress`) and a packaged `dashboard` (`showcase_chart_gallery`) open with the `writable` badge and an editable designer, while a packaged `flow` (`showcase_task_completed`) and a packaged `object` (`showcase_account`) open `create-only` and "locked". No page names `allowOrgOverride`. The server was stopped afterwards. In process, the `getMetaTypes` pin (`protocol-meta-types-rich.test.ts`) and S1's five-type file on both topologies are green on this head. **The artefacts that travel with the pin**, in the shape PR #22794 used: - `.changeset/console-e5311165a8d6.md`, derived by `scripts/bump-objectui.sh` from the changesets objectui declared over the range (21 releasing, 4 breaking by their authors' annotation, no declared `major`). Its ADR-0087 disposition is `not-required (no-migration-prescription)`, and it answers each declared-breaking objectui change: objectui#12141 is this PR's own rename, whose prescription and `registered` disposition live in `22340-registry-allow-environment-overlay.md`; the three objectui#12130 changes move objectui's own form-field face, no ObjectStack key. - `sdui.manifest.json` and `scripts/sdui-manifest.record.json`, regenerated from the built tree at the pin: 107 components; one input description changed (the record activity feed's `showCompleted`, objectui#12106), and no component, input, type or required flag moved. - `packages/sdui-parser/objectui-lockstep.json`, re-recorded at the pin: the 214-line grammar region, the 25 diagnostic codes and the containment predicate are unchanged. - `.changeset/objectui-pin-citations-e5311165a8d6.md` (`@objectstack/spec` patch, `Clause-②: no`) and the re-measured citations. All 55 asserting citations (49 hand-written, 6 in the generated migrations registry) were mapped through the hop. Five cited files changed (`ObjectGrid.tsx`, `data-table.tsx`, `form.tsx`, `record-related-list.tsx`, `data-objectstack/src/index.ts`) and every cited line in them moved or held byte-identical; each record gains a hop sentence, and the anchors that moved are re-pointed where the records cite them at this pin. The six migration entries' corpus counts were re-taken with `git grep -o -F` (8506 tracked files; 124 zero tokens still zero; `Span` 517 to 519, both new hits `colSpan`). `check:objectui-pin-citations --verify-anchors` against objectui at the pin: 55 asserting citations match, 13 anchor content assertions verified. ## New pins - `kernel/metadata-type-registry-allow-org-override-retirement.test.ts`: the parse refuses the old key with the rename (code, path, prescription text; `false` refused like `true`); the new key parses and defaults to `false` with no old key grown back; every built-in row states the new key, none the old, and the true set is exactly the five; the retired-keys registration. - `kernel/metadata-type-registry-allow-org-override-absence.test.ts` (`repo` project, radius already declared for `@objectstack/spec#test:repo`): a tree-scoped, AST-read absence of any CODE reference to `allowOrgOverride` in `packages/**/*.ts` and `examples/*/src/**/*.ts`. Comments and strings are history and are not judged; the tombstone declaration is exempt by shape. The sibling refusal pin is counted apart and REQUIRED to be found, so the walk carries a live positive control. - `objectql/protocol-meta-types-rich.test.ts`: both writer arms carry `allowEnvironmentOverlay`, the hatch elevation lands on it on both arms, and `not.toHaveProperty('allowOrgOverride')` on every entry. - S1's `environment-overlay-five-types.test.ts` under the new name on both topologies, plus the wire absence; the identity pins (`org-scoped-write-refused`, `adr0005-org-override-rollback`, `overlay-precedence`) read the new key. ## Ablation (round 1; committed fix first; restored blob-equal) Dropped the hand rename of `OVERLAY_ALLOWED_TYPES`'s reader (`if (!entry.allowEnvironmentOverlay) continue;` back to the old key) through `scripts/ablation-replace.mjs`: anchor 1 → 0, mutant 0 → 1 on disk; `@objectstack/metadata-protocol` rebuilt; `ablation-dist-preflight` found the marker in `dist/index.js` and `dist/index.cjs`. S1's five-type file: **20 failed / 6 passed of 26** (the 6 are the wire and identity cases, which do not read that set). Restored: blob `eff1a12c83e2` equals HEAD, `git diff HEAD` empty; rebuilt; preflight `--absent` clean over 24 built files; the same file **26 / 26 passed**. ## Readings (head `49ef13a518`) - **Residual `allowOrgOverride` in non-test source:** the tombstone, its prescription and TSDoc, the registry's naming note, the retired-keys and D3 entries, the rationale fragment, two shipped protocol-17 D3 entries, `18.metadata-write-organization-scope-refused` (history), the generated `authorable-surface/kernel.json` `[RETIRED]` row and the untouched `authorable-surface.base.json`, four history comments (`protocol.ts` retired exemption, a quoted docs sentence and the commit `ee58392e1` record in `sys-metadata-repository.ts`, `rest-server.ts`), two ADR-anchor history notes, and the checker's header note. No code reference (the absence pin). - **Surfaces (spec-property-retirement).** Apply: schema, retired-keys + D3 + fragment, generated baselines (`authorable-surface/kernel.json`, `authorable-defaults/kernel.json`, four reference pages), pin tests (radius declared), examples (one comment), docs, changeset, the `check:generated` source audits and the dogfood radius. Do not apply: orphan value schema (boolean), D2 conversion (ruled out), liveness ledger row (none exists for the registry entry; the three prose notes follow the name), forms and i18n (no `*.form.ts` input), CLI advisory lint (ledger-driven, no row), published skills (S3). `api-surface`, `json-schema.manifest` and `export-origins` do not move (no export renamed); `authorable-surface.base.json` is written only by `gen:authorable-surface-base` and is untouched. `acceptRetiredDefaultResidue` is not needed: no built artifact or stored row carries a registry entry. - **Size.** 162 files, +1509 / −649 = 2158 changed lines, generated included, under the 3,000 line. The pin round's own files: 21, +350 / −79. ## Not in this PR - The governed text (S3): `AGENTS.md` Prime Directive 7, `skills/objectstack-ai/SKILL.md`, ADR-0005 (and the dated ADR records). - cloud's two test helpers (`service-ai-studio` `write-door.ts` and `metadata-tools.test.ts`): recorded on the card (`6109343061` item 5) for a seat that reaches cloud. - CHANGELOGs and every other pending changeset. ## Acceptance notes - `check:platform-checklist` is red on this head on 8 findings in files this PR does not touch, each byte-identical to `main`: the 7 recorded in round 1 (`areas/access-security.json`, `areas/attachments-storage.json`) and one more, `areas/search.json` citing `protocol.ts#countable`, a symbol main's PR #22857 (`55382dc02a`) removed. `countable` reads 0 in `protocol.ts` on `origin/main` and on this head. Not this diff. - The ADR-0087 marker names only the D3 id: the gate resolves ids from the semantic and conversion registries and refused the retired-keys string as an id. The retired-keys entry is named in the changeset body. - `pnpm --filter @objectstack/spec check:migration-registry` does not exist (the registry is git-ignored and generated); `gen:migration-registry` ran green on this head (424 semantic, 259 retired-key, 222 retired-def). - This branch merged `main` at `018b077fbf` (round 2, through `os-regen-merge.sh`; two hand-written conflicts, `email-template.zod.ts` and `liveness/README.md`, resolved by stacking both intents). `main` has moved 9 commits since; `git merge-tree --write-tree HEAD origin/main` is clean, and none of those commits adds a line naming either key or an asserting pin citation. ## Verification (head `49ef13a518`) - `@objectstack/spec`: `typecheck` exit 0; `test` (local) 649 files / 19398 tests passed (1 todo); `repo` project: the absence pin, `retired-key-migrate-sentence` and `step18-rationale-merge`, 3 files / 26 tests passed. - `@objectstack/metadata-protocol`: `test` 226 files passed, 3 skipped (28171 tests passed, 19 skipped); `typecheck` exit 0. - `@objectstack/objectql`: S1's `environment-overlay-five-types.test.ts` and the wire pin `protocol-meta-types-rich.test.ts`, 2 files / 33 tests passed. - Built first: `turbo run build --filter=@objectstack/example-showcase...` (61 tasks, exit 0); later, eight packages outside that closure, by name, for two gates' prerequisites and the boot (`client-react`, the five packages `check:published-readme-exports` reads, `studio`, `service-cluster-redis`). No `pnpm build`. `check:generated` exit 0 (all 14 artifacts up to date against that dist); `check:api-surface` "unchanged"; `check:authorable-surface` exit 0 (`authorable-surface.base.json` trails `018b077fbf88`, an information line); `check:future-spec-major` exit 0 (no citation names a major above 17, with the version word gone from the prescription). - The Console Pin Gate's steps: see the pin section; every step exit 0. - `node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack` (no paths) at this head printed 155 commands; every one run except two, and `--ran` reconciles: 155 derived, 153 run, 2 NOT-MEASURED (claimed), 0 UNRUN. Exit codes: 152 × 0 and `check:platform-checklist` × 1 (above). `check:skill-examples` first refused with exit 3 (`@objectstack/client-react` unbuilt), then exit 0 after that package was built. NOT MEASURED: `check:dual-build-cjs-loads` (no whole-workspace build this round) and `check:type-check-debt` (the derived command is the `--re-measure` this round does not run). - Artifact rosters (41), with `PR_NUMBER=22874`, `PR_HEAD_REF`, `PR_BODY` and `GITHUB_REPOSITORY` wired for `closing-target-claim`, `partof-closing-keyword` and `single-claim-paths`: 41 × exit 0. Two needed a rerun: `check:published-readme-exports` refused with exit 3 until five packages outside the showcase closure were built, and `check:select-shard-packages`'s self-test compared output that the proxy variable the PR-context guards need had polluted with a warning; rerun without it, exit 0. - `check:pm-dispatch-gates` (fast tier): 1828 cases pass, exit 0. `check-adr-0087-registration --base origin/main` exit 0: two declared-breaking changesets, `22340-registry-allow-environment-overlay.md` (`registered metadata-type-registry-allow-org-override-renamed`) and `console-e5311165a8d6.md` (`not-required (no-migration-prescription)`). Round 2 (the pin round) was written by session `session_01KNKBCRDJCu5tGy3TEbvtrF` under claim `6109485204`, on the seat's order `6117020961`. --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent 21914c3 commit e23eccb

162 files changed

Lines changed: 1509 additions & 649 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
---
2+
'@objectstack/spec': major
3+
'@objectstack/metadata-protocol': major
4+
---
5+
6+
feat(spec,metadata-protocol)!: the metadata type registry's `allowOrgOverride` is renamed to `allowEnvironmentOverlay`, on the registry and on `GET /meta/types`
7+
8+
Clause-②: yes (narrowing)
9+
10+
<!-- adr-0087: registered metadata-type-registry-allow-org-override-renamed -->
11+
12+
**BREAKING**: a renamed authorable key and a renamed response field, shipped as `major` on the v18 line (`.changeset/pre.json` is open on `main` in `next` pre mode, so the release is `18.0.0-next.*`).
13+
14+
**Why.** ADR-0131 D6 retired the per-organization overlay axis: every metadata write and read is environment-wide. The registry flag kept the name that said "per-org" while it decided one environment-scope question at every door — whether an environment may overlay an item of the type that a managed package ships: the metadata protocol's save door, the managed-content seal on write and on the served read, the repository's put gate, and Studio's write gate through `GET /meta/types`. It is renamed to say that. One key, not two, and not the old name with a new meaning; no window in which both spellings are accepted or served.
15+
16+
## FROM → TO
17+
18+
| where | you wrote / read | write / read instead |
19+
|:--|:--|:--|
20+
| a `DEFAULT_METADATA_TYPE_REGISTRY` entry (`MetadataTypeRegistryEntry`, `@objectstack/spec/kernel`) | `allowOrgOverride: true` | `allowEnvironmentOverlay: true` |
21+
| a reader of a registry entry | `entry.allowOrgOverride` | `entry.allowEnvironmentOverlay` |
22+
| each `entries[]` item of `GET /api/v1/meta/types` (`GetMetaTypesResponse`) | `allowOrgOverride` | `allowEnvironmentOverlay` |
23+
24+
**The one-line fix: rename the key, and every read of it; the value is unchanged.**
25+
26+
Every value is unchanged: `true` on `view`, `dashboard`, `report`, `translation` and `email_template`, `false` on every other built-in type. On the wire the value is still the registry's grant OR the `OS_METADATA_WRITABLE` hatch naming the type (`overrideSource: 'env'`), and the hatch still opens only items no managed package ships, never a managed one. `overrideSource` keeps its `registry` / `env` values; its describe now names the new field.
27+
28+
⚠️ **Read the old key nowhere.** Writing `allowOrgOverride` fails to compile (its input type is `never`) and fails to parse with the rename prescription (issue code `invalid_type` at path `allowOrgOverride`). A READER does not fail: `if (!entry.allowOrgOverride)`, a filter on it or a partial-match assertion still compiles against the tombstone and reads `undefined`, which treats every type as closed to environment overlays. A client that declares its own type for the `/meta/types` response, instead of importing `GetMetaTypesResponse`, sees no compile error at all and reads every type as locked. Search for the old name, do not wait for `tsc`.
29+
30+
**`supportsOverlay` keeps its name; its describes now say what it gates.** It decides one thing: a stored overlay row of an item a managed package ships may be removed through the ordinary delete door without the type's environment-overlay permission: the removal removes no managed definition, and changes what is served for `permission` alone. It opens no save and it decides no read. The registry's describe, the `GET /meta/types` describe and `MetadataTypeInfoResponse`'s describe used to promise that "the loader can merge overlays", in the retired per-organization wording.
31+
32+
**Who is affected, measured.** No manifest, stack, plugin configuration or stored row can carry a registry entry (`contributes.kinds` is closed, `config.additionalTypes` is a tombstone, the registry is a TypeScript literal), so no authored metadata changes. The readers are code: every reader in this repository moved in this change, and a reader of the `/meta/types` field outside it moves with it — the Studio console reads the field and moves in its own repository's paired change, which the console pin carries.
33+
34+
### The kit
35+
36+
- **The tombstone.** `MetadataTypeRegistryEntry.allowOrgOverride` is a `retiredKey()` naming `allowEnvironmentOverlay` (`kernel/metadata-plugin.zod.ts`); the 28 built-in rows spell the new key.
37+
- **The ledger.** The retired-keys entry `kernel/MetadataTypeRegistryEntry:allowOrgOverride` and the D3 semantic entry `metadata-type-registry-allow-org-override-renamed` (protocol 18), which records the registry key and the wire field together. No D2 conversion: there is no authored or stored source a conversion could rewrite.
38+
- **The wire.** `getMetaTypes` writes the hatch elevation onto `allowEnvironmentOverlay` on both of its arms — a registry type and a runtime-registered type with no registry row — and no entry carries `allowOrgOverride`.
39+
- **The refusal sentences** that named the flag name the new key: `… takes no environment overlay (allowEnvironmentOverlay=false) …`, `… has neither allowEnvironmentOverlay nor allowRuntimeCreate …`, `… allowRuntimeCreate=false and allowEnvironmentOverlay=false …`. Codes and statuses are unchanged.

‎.changeset/console-e5311165a8d6.md‎

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
---
2+
"@objectstack/console": minor
3+
---
4+
5+
Console (objectui) refreshed to `e5311165a8d6`. Frontend changes in this range:
6+
7+
Derived from the changesets objectui declared over the range — 21 releasing of 23 changesets added across 24 non-merge commits; omitted: 2 release-nothing changesets, 1 commit carrying no changeset (they ship no package code).
8+
9+
- **minor** — **BREAKING** — Studio and the metadata admin read a metadata type's overlay flag under its new name, `allowEnvironmentOverlay`, and the read-only banners name `OS_METADATA_WRITABLE` (objectui#12… (objectui `e5311165a`)
10+
- **minor** — The marketplace package page's **Update** button opens an update dialog, and a package README's raw HTML is no longer printed as text (objectui#12146). (objectui `82bb1d584`)
11+
- **minor** — **BREAKING** — A form field declares `step` and `className` on both faces, so the strict authoring face stops telling authors to remove two keys that work. A built-in form branch now joins an en… (objectui `d2500d8be`)
12+
- **minor** — "Clone to customize" on a packaged permission set calls the server's clone door (objectui#7611, objectstack ADR-0126 §7.1). (objectui `6d5879fe9`)
13+
- **minor** — **A dashboard or a list view the server refuses you, opened by its URL, now says it was refused** (objectui#12112, the console half of objectstack#22611's ruling A). (objectui `43e150518`)
14+
- **minor** — Setup's "Assigned users" on a permission set writes a new grant by the set's name alone (objectui#7611, after objectstack#22863, ADR-0131 stage 6b-2-pre). (objectui `faf4ce952`)
15+
- **minor** — **BREAKING** — A form field declares `avatarField`, the record field each candidate of the search picker draws its avatar from, on both faces, so the strict authoring face stops telling authors… (objectui `c0c2f792b`)
16+
- **minor** — A `position` decision output lists the position registry and commits position names (objectui#7611, objectstack ADR-0131 D3/D4). (objectui `8cc7158b4`)
17+
- **minor** — The capability select lists the capability registry, and the permission-set editor's provenance badge reads the layered envelope (objectui#7611, objectstack ADR-0131 D3/D7). (objectui `53ee2f854`)
18+
- **minor** — **BREAKING** — A form field declares the rest of the field metadata its widget reads off the `fields[]` entry, on both faces, so the strict authoring face stops telling authors to remove keys th… (objectui `0665c3be7`)
19+
- **minor** — Screen readers hear the names of more controls in the viewer's language (objectui#12145). (objectui `e723f58ee`)
20+
- **minor** — The suggested-bindings panel shows each suggestion's real state and can revoke an acceptance (objectui#7611, after objectstack#22854). (objectui `f962cdc09`)
21+
- **minor** — The record feed and a related list's Add existing and fallback remove read the affordance-to-grant map, so a caller without the grant is no longer offered a write the server then… (objectui `158c75d90`)
22+
- **minor** — A paged table's first, previous, next and last page buttons have accessible names (objectui#12124). (objectui `dc6d28e86`)
23+
- **patch** — The Studio app's root now opens the app's first navigation entry, like every other app's root, and `StudioHomePage`, Studio's old metadata overview, is retired (objectui#12113). (objectui `ed12d48ec`)
24+
- **patch** — A form field's own `defaultValue` is no longer drawn in its control, so the form never shows a value it does not save (objectui#12155). (objectui `f3d540814`)
25+
- **patch** — A grouped grid's own first, previous, next and last page buttons have accessible names (objectui#12143). (objectui `2381c07f3`)
26+
- **patch** — Console rendering fixes from the HotCRM browser pass (objectui#12110): (objectui `5330038f4`)
27+
- **patch** — The record page's discussion shows stored replies under their comment, and every comment offers the reply input where the caller may post one (objectui#12144). (objectui `a7d492011`)
28+
- **patch** — A record activity feed shows an object's `activityMilestones` rows of type `completed`, such as "Case resolved", instead of hiding them as completed tasks (objectui#12106). (objectui `1d1cfe0c1`)
29+
- **patch** — A record-source refusal (`RECORD_SOURCE_REQUIRED`, raised by every arm that requires a record source) now reports the same path every time (objectui#5250). (objectui `9b7550999`)
30+
31+
⚠️ 4 of these carry a breaking change: 4 by the author's own breaking annotation in the changeset body — objectui declares no `major` inside a launch window (`scripts/check-changeset-no-major.mjs`). Each is marked **BREAKING** in the list above — read them before compiling the release record.
32+
33+
**In this console build, declared nowhere** — objectui merged 1 commit in this range with no `.changeset/*.md`. The code is inside the pin above and ships here, but nothing upstream declared it, so it appears in no objectui CHANGELOG and in no entry above. Listed by subject rather than counted, because a count cannot tell a dependency bump from a form-behaviour change (objectstack#6174); the upstream gate that would prevent this is objectui#3387.
34+
35+
- _(no changeset)_ feat(scripts): the JSON-fence gate reads the published READMEs (objectui#12131, phase 2) (#12139) (objectui `ce9811c96`)
36+
37+
<!-- adr-0087: not-required (no-migration-prescription)
38+
This console changeset moves `.objectui-sha` and the artefacts that travel with it: the
39+
re-recorded `scripts/sdui-manifest.record.json` and the regenerated `sdui.manifest.json`
40+
(107 components; one input description changed, the record activity feed's
41+
`showCompleted` (objectui#12106), and no component, input, type or required flag moved),
42+
the re-recorded `packages/sdui-parser/objectui-lockstep.json` (its grammar region,
43+
diagnostic codes and containment predicate are unchanged across the range) and the
44+
re-measured pin citations in `packages/spec/src`, which carry their own
45+
`@objectstack/spec` patch changeset. It adds, removes or renames no ObjectStack-authorable
46+
key of its own. The one ObjectStack rename this pin follows,
47+
`MetadataTypeRegistryEntry.allowOrgOverride` to `allowEnvironmentOverlay` and the
48+
`GET /meta/types` field with it, is this same diff's: its FROM/TO prescription and its
49+
`registered metadata-type-registry-allow-org-override-renamed` disposition live in
50+
`.changeset/22340-registry-allow-environment-overlay.md`, so this body carries no FROM/TO
51+
prescription of its own.
52+
The range carries four declared-breaking objectui changes, each by its author's breaking
53+
annotation and none by a declared `major`. Each is answered here:
54+
(1) objectui#12141 (`e5311165a`): `@object-ui/app-shell`'s `RichMetadataTypeEntry` and
55+
`resolveResourceConfig` read `allowEnvironmentOverlay` in place of `allowOrgOverride`,
56+
with no dual read. It is the console half of this diff's own rename and reads the one
57+
name this diff's `GET /meta/types` writes, on both of its arms; it is why this pin and
58+
that rename land together.
59+
(2) objectui#12130 (`d2500d8be`): objectui's form-field type declares `step` as the
60+
spec's number and `className` as a string, so its tolerant face refuses `step: 'any'`.
61+
objectui's own authoring face; `@objectstack/spec` declares and moves nothing here.
62+
(3) objectui#12130 (`c0c2f792b`): objectui's form-field type declares `avatarField`, and
63+
its tolerant face refuses a non-string value. objectui's own face; no ObjectStack key.
64+
(4) objectui#12130 (`0665c3be7`): objectui's form-field type declares the field-metadata
65+
keys its widgets read off a `fields[]` entry, by reference to `@objectstack/spec`'s
66+
`FieldSchema` members, with value checks on its tolerant face. objectui's own face; the
67+
spec members it references do not move.
68+
No commit subject in the range carries `!`. Scope of the claim, stated rather than
69+
implied: it is a claim about THIS diff, not a per-entry re-measurement of the upstream
70+
declared-breaking entries. -->
71+
72+
objectui range: `4997995022f8...e5311165a8d6`
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
---
2+
'@objectstack/spec': patch
3+
---
4+
5+
The spec's objectui citations, and the shipped description text that names the `.objectui-sha` pin (the `FormField.span` describe and six migration-entry descriptions), are re-measured against the new console pin, objectui `e5311165a8d6`.
6+
7+
Clause-②: no
8+
9+
Every anchor was mapped through the objectui diff `4997995022f8..e5311165a8d6`: 287 paths over 24 commits, four deleted (`StudioHomePage.tsx`, its two tests and `permission-set-clone-dispatch.ts`, none of which a record cites) and none renamed. Five files a record cites changed on the hop, plus the `en` / `zh` / `de` packs (whose `calendar.configRequired` strings did not change): `ObjectGrid.tsx` (objectui#12110 and objectui#12143), `data-table.tsx` (objectui#12124 and objectui#12145), `form.tsx` (objectui#12110, objectui#12130 and objectui#12155), `record-related-list.tsx` (objectui#12082) and `data-objectstack/src/index.ts` (objectui#12112). Every cited line in them moved or held with its text byte-identical, and each record that cites one is re-pointed with a hop sentence that says by how much. The records that cite only byte-identical files gain a hop sentence that says so.
10+
11+
Two readings sit beside a cited read, and each hop sentence says what it found:
12+
13+
- `record-related-list.tsx`: the list's fallback remove now reads the affordance-to-grant map's `relatedRowDelete` row (objectui#12082). The hunks sit above and below the `requiredPermissions` gate; the gate and the related object's read gate are byte-identical, 17 lines down.
14+
- `form.tsx`: the built-in branches now settle the widget a field hint renders and the props they hand their control (objectui#12110, objectui#12155, objectui#12130). `spanLadderFor` and its one call site are byte-identical, so the `span` describe's reading holds.
15+
16+
The six migration entries' corpus counts were re-taken with `git grep -o -F`, the method that reproduces every `4997995022f8` number. The corpus is now 8506 tracked files. Every token an entry counts as zero still reads zero: 124 candidate tokens (every export of the four spec files the entries name, and every key they name) read zero at both pins. `Span` reads 519 against 517, both new hits `colSpan`, and `SpanSchema` reads 57 at both pins, as the tracing entry records. The controls moved with the corpus, for example `objectstack` from 18271 to 18355 and `timeout` from 1704 to 1706.
17+
18+
No key, default, enum member or export moves.

‎.objectui-sha‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
4997995022f8e65946f6362b7434685539cc72b7
1+
e5311165a8d6aa77b5cb7d9fd05da8451a2c21aa

‎content/docs/ai/agents.mdx‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ assistant to *write* your metadata and never run. Same word, two layers.
117117
</Callout>
118118

119119
`*.agent.ts` is **closed to third parties** — the `agent` metadata type is
120-
`allowRuntimeCreate:false, allowOrgOverride:false`, reserved for the two platform
120+
`allowRuntimeCreate:false, allowEnvironmentOverlay:false`, reserved for the two platform
121121
agents and platform-owned subagents (ADR-0063 §2). To give the `ask` agent a new
122122
capability you author an agent **skill** (`*.skill.ts`). Every skill declares
123123
`surface: 'ask' | 'build' | 'both'`, and an agent's tool set is the **union of its
@@ -240,7 +240,7 @@ LLM-callable.
240240
The agent definitions below illustrate agent **anatomy** — how an `AgentSchema`
241241
record is shaped (that schema and the `defineAgent` factory are part of the open
242242
`@objectstack/spec/ai` package). Note that the `agent` metadata type is
243-
`allowRuntimeCreate:false` / `allowOrgOverride:false` (ADR-0063 §2): the **cloud /
243+
`allowRuntimeCreate:false` / `allowEnvironmentOverlay:false` (ADR-0063 §2): the **cloud /
244244
Enterprise** in-product runtime honors only the two platform agents `ask` and
245245
`build`, so you do not ship a custom agent *to that runtime* — you extend it by
246246
authoring a **skill** (open metadata) that attaches to `ask`. In the open edition,

‎content/docs/api/declarative-endpoints.mdx‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,7 @@ PUT /api/v1/meta/api/acme_lead_feed → 403 {"code":"NOT_CREATABLE"}
280280
```
281281

282282
The `api` metadata type is registered with `allowRuntimeCreate: false` and
283-
`allowOrgOverride: false`, and that refusal runs **before any body validation** — so a
283+
`allowEnvironmentOverlay: false`, and that refusal runs **before any body validation** — so a
284284
perfectly valid endpoint body gets the same `403`, in `?mode=draft` as well as direct
285285
writes. There is no per-organization overlay of an endpoint either.
286286

‎content/docs/api/metadata-api.mdx‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ Create or update a metadata item.
5959

6060
Creates are gated per type: `MetadataTypeRegistryEntry.allowRuntimeCreate` decides
6161
whether a **brand-new** name may be minted under that type at all, separately from
62-
whether an item that already exists may be overlaid (`allowOrgOverride`). A type that
62+
whether an item that already exists may be overlaid (`allowEnvironmentOverlay`). A type that
6363
declines the create half still accepts updates to names that already exist, and its
6464
refusal — `403 NOT_CREATABLE` — names the route that does work. The flags are
6565
documented on

‎content/docs/automation/jobs.mdx‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ writes carry*:
4242
| | `job` | `schedule`-type flow |
4343
|:---|:---|:---|
4444
| What runs | a sandboxed `body`, a mapping `pull`, or (deprecated) one TypeScript function from `defineStack({ functions })` | a node graph — record operations, `notify`, `http`, approvals, subflows |
45-
| Changeable after deploy | **No.** `job` is `allowRuntimeCreate: false` and `allowOrgOverride: false` — there is no "create job" in Studio and no per-tenant fork | Yes — a new flow can be authored through Studio / `PUT /meta` (`allowRuntimeCreate: true`) |
45+
| Changeable after deploy | **No.** `job` is `allowRuntimeCreate: false` and `allowEnvironmentOverlay: false` — there is no "create job" in Studio and no per-tenant fork | Yes — a new flow can be authored through Studio / `PUT /meta` (`allowRuntimeCreate: true`) |
4646
| Identity of its data writes | system, in the job's declared [`organization`](#the-organization-a-job-runs-as) | declared by [`runAs`](/docs/automation/flows) — and a `user` run that resolves no trigger user has its data operations **refused**, so a scheduled flow normally declares `runAs: 'system'` |
4747
| Retry / time limit | `retryPolicy` + `timeoutMs` on the job, honoured by the job adapter | the flow's own error handling |
4848
| Run history | `sys_job` + `sys_job_run` | `sys_automation_run` |

0 commit comments

Comments
 (0)