diff --git a/.changeset/10061-filter-builder-incomplete-range.md b/.changeset/10061-filter-builder-incomplete-range.md index 7f8e4d807b..bdbf9fa38b 100644 --- a/.changeset/10061-filter-builder-incomplete-range.md +++ b/.changeset/10061-filter-builder-incomplete-range.md @@ -5,7 +5,7 @@ fix(components): a half-typed `between` range in the filter builder shows itself as incomplete instead of being dropped with no signal (objectui#10061) -Ruling batch #146 item 5 letter A (objectstack#18012) declares that while one bound of a +Ruling batch #146 item 5 letter A (objectstack `176b03582`) declares that while one bound of a `between` pair is blank the condition is incomplete — **not emitted, and shown as incomplete in the UI**. The first half has been true since objectui#5025: every write path folds the row through the builder's own arity-aware `isFilterValueComplete`, so a diff --git a/.changeset/10062-dataset-filter-between-arm.md b/.changeset/10062-dataset-filter-between-arm.md index fd9aac614c..1f831d4a11 100644 --- a/.changeset/10062-dataset-filter-between-arm.md +++ b/.changeset/10062-dataset-filter-between-arm.md @@ -5,7 +5,7 @@ fix(app-shell): the Studio dataset-filter inspector stores a `between` range as the spec's `$between`, with both bounds required (objectui#10062) -Executes ruling batch #146 item 5 letter A (objectstack#18012): the `between` arm of the +Executes ruling batch #146 item 5 letter A (objectstack `176b03582`): the `between` arm of the dataset-filter bridge maps once a both-bounds completeness rule exists, and one does. Until now a `Between` row in a dataset's or a measure's filter was dropped on every commit — inertly since objectui#9372, but dropped — so a date range could be drawn in the inspector diff --git a/.changeset/10803-dead-citation-sweep-seventh-batch.md b/.changeset/10803-dead-citation-sweep-seventh-batch.md new file mode 100644 index 0000000000..8c4b7b2e10 --- /dev/null +++ b/.changeset/10803-dead-citation-sweep-seventh-batch.md @@ -0,0 +1,23 @@ +--- +--- + +Comment-only in `@object-ui/app-shell`, `@object-ui/components`, `@object-ui/core`, +`@object-ui/data-objectstack`, `@object-ui/i18n`, `@object-ui/permissions`, +`@object-ui/plugin-calendar`, `@object-ui/plugin-designer`, `@object-ui/plugin-detail`, +`@object-ui/plugin-form`, `@object-ui/plugin-grid`, `@object-ui/plugin-kanban`, +`@object-ui/plugin-list`, `@object-ui/plugin-tree`, `@object-ui/providers`, +`@object-ui/react` and `@object-ui/types` (two console warnings in `@object-ui/app-shell` +and `@object-ui/plugin-detail` are runtime text, declared separately below): docblocks and +code comments that cited an `objectstack` issue or pull request which answers 404 now cite +the commit in that repository that landed the change, written as objectstack and a +9-character sha (objectui#10803, the seventh batch). Where the sentence already names that +change's live pull request or commit, or dates the ruling it points at, the dead number is +dropped instead, and one sentence cites this repository's own landing commit, because the +fix it names landed here. Comments that named the apiMethods whitelist card as a bare +number now read `objectstack#3391`, and the two that paired it with a second bare number +read `objectstack#3546` for it: a bare number resolves to this repository, where both +numbers are unrelated cards. None of these comment edits moves a claim or changes a code or +type token. No published behaviour changes through them, so this declares no release. + +The same repair in the pending changesets that carried these citations is prose-only, and +their frontmatter is byte-identical. diff --git a/.changeset/10803-seventh-batch-runtime-strings.md b/.changeset/10803-seventh-batch-runtime-strings.md new file mode 100644 index 0000000000..0911ff1f80 --- /dev/null +++ b/.changeset/10803-seventh-batch-runtime-strings.md @@ -0,0 +1,17 @@ +--- +'@object-ui/app-shell': patch +'@object-ui/plugin-detail': patch +--- + +fix(app-shell, plugin-detail): the unmapped activity type warnings no longer point at an objectstack issue that answers 404 + +`@object-ui/app-shell` warns on the console, once per value, when a `sys_activity` row's +`type` maps to no activity item type, and `@object-ui/plugin-detail`'s `[record:activity]` +block does the same when it maps to no feed item type. Both messages said `sys_activity.type` is +author-extensible with a pointer to an objectstack issue that answers 404 beside the +ruling's date. A reader of a console warning has no repository to resolve a commit +against, so the pointer is dropped rather than replaced: both now read "author-extensible +(ruled 2026-08-24)" (objectui#10803). + +Nothing else in either message moves, and what renders, and when and how often each +warning fires, are unchanged. diff --git a/.changeset/17147-plugin-disclosure-not-enforced.md b/.changeset/17147-plugin-disclosure-not-enforced.md index a1054cdb84..96f531e8ac 100644 --- a/.changeset/17147-plugin-disclosure-not-enforced.md +++ b/.changeset/17147-plugin-disclosure-not-enforced.md @@ -5,8 +5,8 @@ The marketplace consent panel no longer promises confinement the runtime does not provide. -`PluginDisclosure` introduced a code-bearing package's structured permission set with "On install, this package will be granted:". A list of grants on a security panel is read as a confinement promise — the complement assumed denied — and on this platform it is not. The consented set is persisted (`sys_package_installation.granted_permissions`), re-confirmed on a widening upgrade, and registered on the runtime's `PluginPermissionEnforcer` at load; it is queried by nothing, because `SecurePluginContext` has zero production construction sites and the fs/network gates have no caller at all (measured on objectstack `9bd4344e4`; objectstack#17147). +`PluginDisclosure` introduced a code-bearing package's structured permission set with "On install, this package will be granted:". A list of grants on a security panel is read as a confinement promise — the complement assumed denied — and on this platform it is not. The consented set is persisted (`sys_package_installation.granted_permissions`), re-confirmed on a widening upgrade, and registered on the runtime's `PluginPermissionEnforcer` at load; it is queried by nothing, because `SecurePluginContext` has zero production construction sites and the fs/network gates have no caller at all (measured on objectstack `9bd4344e4`; recorded upstream in objectstack `aaacf1d5c`). `marketplace.disclosure.grantsIntro` now states a REQUEST — "This package requests:" — and a new `marketplace.disclosure.notEnforced` line beside the list says the set is recorded at install, re-confirmed if a later version asks for more, and not yet a runtime restriction. Both land in all ten locale packs; the `ja` value stays predicate-final so that pack's halfwidth-colon rule still decides it. -The trust-tier badge is deliberately untouched: it is objectstack#11330's half of the same panel. +The trust-tier badge is deliberately untouched: it is the trust-tier half of the same panel, which objectstack `a9ee98992` settled separately. diff --git a/.changeset/3719-settings-valuedomain-combobox.md b/.changeset/3719-settings-valuedomain-combobox.md index f39d01bbcc..4def914f6e 100644 --- a/.changeset/3719-settings-valuedomain-combobox.md +++ b/.changeset/3719-settings-valuedomain-combobox.md @@ -24,7 +24,7 @@ exists. **Undeclared → the closed dropdown is untouched**, which is half the change rather than a caveat. Those `options` are still exhaustive under objectstack#5131 (the sms/mail provider selects), and `localization.locale` had its domain declaration deliberately **rejected** in -objectstack#6515 because its options *are* the shipped catalogs. Widening those to free +objectstack `2fdb36eb9` because its options *are* the shipped catalogs. Widening those to free input would be a regression wearing this fix's clothes, so the two branches are pinned against each other from the specifier data rather than from a list of key names — a key that gains a domain server-side joins the right side of the pin with no edit here. diff --git a/.changeset/5896-feeditem-single-constructor.md b/.changeset/5896-feeditem-single-constructor.md index 15b65a81b0..2f8c9d16f5 100644 --- a/.changeset/5896-feeditem-single-constructor.md +++ b/.changeset/5896-feeditem-single-constructor.md @@ -12,7 +12,7 @@ table (objectui#5878) and then built the `FeedItem` itself, ending in situations: a type the table maps to `undefined` **on purpose** (`commented` / `mentioned` / `login` / `logout`), and a type the table has never heard of. The second is an **author-extended** value — `sys_activity.type` is -author-extensible (objectstack#11507 direction 4, ruled 2026-08-24), every +author-extensible (objectstack `88b9d749a`, direction 4, ruled 2026-08-24), every column on that table is `readonly` so objectql never validates a write, and ADR-0052 §5b.2 forwards an author's `activityMilestones[].type` into it verbatim. So an activity that happened, was written and is queryable had no row diff --git a/.changeset/5987-permset-clone-to-customize.md b/.changeset/5987-permset-clone-to-customize.md index 74c094e872..99e6c41277 100644 --- a/.changeset/5987-permset-clone-to-customize.md +++ b/.changeset/5987-permset-clone-to-customize.md @@ -8,7 +8,7 @@ The permission matrix already locks a set a code package ships (the artifact tier: `isArtifactBackedLayer`, the client mirror of the server's `isArtifactBacked`), and its guidance offered only the pre-ruling remedies — edit the source artifact and redeploy, a new runtime set, the -`OS_METADATA_WRITABLE` hatch. The ruled path (objectstack#11513, 「同意 第一步 +`OS_METADATA_WRITABLE` hatch. The ruled path (objectstack `e170b0ae5`, 「同意 第一步 (创业阶段,Salesforce 式)」: lock the base, clone to customize) was never on the screen, and the metadata-door refusal a Studio save receives names only the pre-ruling remedies; the data door's refusal is the one that names the Clone diff --git a/.changeset/6654-retire-preview-mode-consumption.md b/.changeset/6654-retire-preview-mode-consumption.md index b6e71dca3b..6afa6f7a01 100644 --- a/.changeset/6654-retire-preview-mode-consumption.md +++ b/.changeset/6654-retire-preview-mode-consumption.md @@ -7,7 +7,7 @@ Retire the discovery-wire preview mode — the console no longer turns authentication off because a server said `mode: 'preview'` (objectui#6654). `@objectstack/spec` retired the `RuntimeMode` value `'preview'` and the whole -`PreviewModeConfig` block (objectstack#11846). This console still read that +`PreviewModeConfig` block (objectstack `0c2334f6c`). This console still read that surface back off the runtime discovery payload, which is a different layer from the retired compile-time type — so the consumption could not simply be assumed dead, and its removal was ruled deliberately (2026-08-29). diff --git a/.changeset/6730-shared-activity-type-bucket.md b/.changeset/6730-shared-activity-type-bucket.md index 4f8227d02d..52feba272f 100644 --- a/.changeset/6730-shared-activity-type-bucket.md +++ b/.changeset/6730-shared-activity-type-bucket.md @@ -21,7 +21,7 @@ a `scheduled` meeting, a `login`, a nightly `system` rollup and an author's its own icon, label and notification toggle. Following `UNMAPPED_ACTIVITY_FEED_TYPE`'s precedent, an unrecognised value renders through it and is named once on `console.warn` rather than being dropped — - `sys_activity.type` is author-extensible (objectstack#11507 direction 4), so + `sys_activity.type` is author-extensible (objectstack `88b9d749a`, direction 4), so an unmapped value is real activity nobody has ruled on, not a mistake. - The built-ins that had no honest presentation among the four existing kinds — `system`, `completed`, `scheduled`, `login`, `logout` — now land in that diff --git a/.changeset/6748-preview-mode-provenance-ratchet.md b/.changeset/6748-preview-mode-provenance-ratchet.md index 00aa51efa2..59a8474832 100644 --- a/.changeset/6748-preview-mode-provenance-ratchet.md +++ b/.changeset/6748-preview-mode-provenance-ratchet.md @@ -5,7 +5,7 @@ Test-only change in `@object-ui/auth`: `auth-spec-parity.test.ts` now watches `PreviewModeConfig`, the `@objectstack/spec/kernel` symbol that `packages/auth/README.md:328` claims the preview-mode prop aligns with. Upstream retired that symbol in source and registered it as `kernel/PreviewModeConfig` in -`RETIRED_DEFS_BY_MAJOR[18]` (objectstack#11846, landed as PR objectstack#12718), so +`RETIRED_DEFS_BY_MAJOR[18]` (landed as PR objectstack#12718), so it leaves the published set at spec major 18 — it is still exported by the 17.2.0 this repo resolves, which is why the assertion ships green. It goes red at the spec-18 bump, the exact moment the README sentence stops being true, which is the signal to correct diff --git a/.changeset/6757-global-search-notifications-renderers.md b/.changeset/6757-global-search-notifications-renderers.md index 49bc2a8ec1..c6c5f55f94 100644 --- a/.changeset/6757-global-search-notifications-renderers.md +++ b/.changeset/6757-global-search-notifications-renderers.md @@ -6,7 +6,7 @@ Renderers for the `global:search` and `global:notifications` page blocks. A page that declared either member drew the literal "Component Placeholder" scaffold: both are first-class `PageComponentType` members that the 2026-08-26 maintainer ruling on objectstack#12183 kept declared once the -readiness read in objectstack#13117 evidenced both data sources shipped, and +readiness read in objectstack `225e7690f` evidenced both data sources shipped, and the renderer was the remaining half. Neither block adds a data layer — each is a new mount point on plumbing that was diff --git a/.changeset/7015-text-expression-content-channel.md b/.changeset/7015-text-expression-content-channel.md index 4048b82e2c..c9b884a76f 100644 --- a/.changeset/7015-text-expression-content-channel.md +++ b/.changeset/7015-text-expression-content-channel.md @@ -5,7 +5,7 @@ Docs only: the expression guides taught `"value": "${...}"` on `type: "text"` nodes, which the renderer reads back but never evaluates, so the reader saw the literal `${...}` on screen. All 29 authored occurrences now spell the carriage `content`, the ruled sole evaluation channel for `text` (objectui#7015, -maintainer ruling 2026-08-31 on objectstack#13670, option 2). +maintainer ruling 2026-08-31, option 2, recorded in objectstack `8c6a7fc0b`). No package source changed, so this ships nothing — `check-changeset-presence` independently reports "no changeset is owed" for this diff. The declaration is diff --git a/.changeset/7979-package-form-dialog-envelope-reader.md b/.changeset/7979-package-form-dialog-envelope-reader.md index 38baecd818..73049a1c20 100644 --- a/.changeset/7979-package-form-dialog-envelope-reader.md +++ b/.changeset/7979-package-form-dialog-envelope-reader.md @@ -8,7 +8,7 @@ The create / edit / view package dialog POSTs and PATCHes `/api/v1/packages` thr own `apiJson`, which held a fourth copy of the ADR-0112 failure-envelope ladder — character for character the one `PackagesPage` had before `36fc74629`. It read the diagnostic `error.message` and stopped, so two things a refusal carries never reached the -author: the producer's marked `error.userMessage` (present since objectstack#9934, emitted +author: the producer's marked `error.userMessage` (present since objectstack `79c46da90`, emitted by both doors that serve these routes) and `error.code`. The read now comes from the one shared rule, `readEnvelopeFailureText` diff --git a/.changeset/8137-record-activity-calibration-repoint.md b/.changeset/8137-record-activity-calibration-repoint.md index 189c7ed4d3..7105d9bc65 100644 --- a/.changeset/8137-record-activity-calibration-repoint.md +++ b/.changeset/8137-record-activity-calibration-repoint.md @@ -4,7 +4,7 @@ Re-point the `record:activity.types` member calibration control in `registry-inputs-spec-parity` from `'Account'` to `''`. `@objectstack/spec` 17.3.0 made that vocabulary open — -`z.array(z.union([FeedItemType, z.string().min(1)]))`, objectstack#11658 -executing the maintainer's 2026-08-24 ruling on objectstack#11507 — so the old +`z.array(z.union([FeedItemType, z.string().min(1)]))`, objectstack `1a6a19c31` +executing the maintainer's 2026-08-24 ruling — so the old probe now accepts, while `''` is still refused for its CONTENT via `.min(1)`. Test only; no package is released by this change. diff --git a/.changeset/console-form-marked-refusal-5210.md b/.changeset/console-form-marked-refusal-5210.md index 3c95052807..a21a3dd496 100644 --- a/.changeset/console-form-marked-refusal-5210.md +++ b/.changeset/console-form-marked-refusal-5210.md @@ -19,7 +19,7 @@ returning 400 instead of 403 for permission failures, degrading the status semantics logs, monitoring and API consumers depend on. The maintainer ruling (2026-08-19) was a producer-side opt-in rather than a -chattier 403 branch, and the platform half shipped as objectstack#9934: a hook +chattier 403 branch, and the platform half shipped as objectstack `79c46da90`: a hook marks its refusal text with `userMessage` at throw time. This is the consumer half. diff --git a/.changeset/designer-publish-package-binding.md b/.changeset/designer-publish-package-binding.md index ed31e4c009..7d85201ed7 100644 --- a/.changeset/designer-publish-package-binding.md +++ b/.changeset/designer-publish-package-binding.md @@ -7,7 +7,7 @@ The metadata designer states its package on the publish step, not only on the sa Studio's designer save→publish loop bound the draft to a software package on the save (`PUT ?mode=draft&package=`) and then sealed it with a publish that named -no package at all. `objectstack#10354` (shipped in `@objectstack/rest` 17.2.0) taught +no package at all. objectstack `9e04c3e35` (shipped in `@objectstack/rest` 17.2.0) taught `POST /meta/:type/:name/publish` to accept `?package=`, so the second call can now state the same binding the first one already states. diff --git a/.changeset/normalise-client-error-user-message-5901.md b/.changeset/normalise-client-error-user-message-5901.md index d6739f5405..9eb999df01 100644 --- a/.changeset/normalise-client-error-user-message-5901.md +++ b/.changeset/normalise-client-error-user-message-5901.md @@ -4,7 +4,7 @@ Preserve the producer's `userMessage` marking when `normaliseClientError` re-wraps a refusal. -`ApiErrorSchema.userMessage` (objectstack#9934) is the opt-in channel an application author +`ApiErrorSchema.userMessage` (objectstack `79c46da90`) is the opt-in channel an application author sets at throw time to say "this text is for the end user", and the contract states it status-agnostic — any refusal status may carry it. Both of the shapes this adapter re-wraps into typed errors dropped the marking: a hook that refused a write with `VALIDATION_FAILED` diff --git a/.changeset/record-activity-open-vocabulary-fallback.md b/.changeset/record-activity-open-vocabulary-fallback.md index f1e300a948..a4626fef35 100644 --- a/.changeset/record-activity-open-vocabulary-fallback.md +++ b/.changeset/record-activity-open-vocabulary-fallback.md @@ -10,7 +10,7 @@ queryable and invisible, with only a console warning to say so. It now renders through a defined fallback presentation (`UNMAPPED_ACTIVITY_FEED_TYPE`, the generic `system` feed type), still announced once per distinct type. -This follows the maintainer ruling of 2026-08-24 on objectstack#11507, +This follows the maintainer ruling of 2026-08-24 (objectstack `88b9d749a`), direction 4: `sys_activity.type` is **author-extensible**. Every field on `sys_activity` is `readonly: true` and objectql's `validateRecord` skips readonly fields on both write branches, and ADR-0052 §5b.2 forwards an author's diff --git a/.changeset/retire-theme-component-schema-5489.md b/.changeset/retire-theme-component-schema-5489.md index d5c60bf302..fcf839d7b6 100644 --- a/.changeset/retire-theme-component-schema-5489.md +++ b/.changeset/retire-theme-component-schema-5489.md @@ -15,8 +15,8 @@ and in neither `PROTOCOL_COMPONENTS` nor `PALETTE_PLACEHOLDER_BLOCKS` (`packages/components/src/renderers/placeholders.tsx`), so it did not even resolve to a placeholder — a page declaring one got the registry's "Unknown component type" panel (OBJUI-001) instead of a theme manager. Declared-but- -unenforced, removed under the maintainer ruling of 2026-08-21 on -objectstack#10485 (option B). +unenforced, removed under the maintainer ruling of 2026-08-21 +(option B, executed upstream by objectstack `35ad101bc`). Removed from the published surface: the `ThemeComponentSchema` type (`@object-ui/types`), the `ThemeComponentSchema` Zod object diff --git a/.changeset/retire-theme-switcher-preview-5647.md b/.changeset/retire-theme-switcher-preview-5647.md index cd24159343..d6c8e805ac 100644 --- a/.changeset/retire-theme-switcher-preview-5647.md +++ b/.changeset/retire-theme-switcher-preview-5647.md @@ -22,7 +22,7 @@ pipeline: `tooltip` → 1), nor in `PROTOCOL_COMPONENTS` / declares either kind (control: `"type": "form"` → 81) — so a page declaring one got the registry's "Unknown component type" panel (OBJUI-001), never a switcher or a preview. Declared-but-unenforced, removed under the 2026-08-21 -maintainer ruling (option B) on objectstack#10485, extended to these siblings +maintainer ruling (option B, executed upstream by objectstack `35ad101bc`), extended to these siblings by inheritance on identical evidence (objectui#5647). Removed from the published surface: the `ThemeSwitcherSchema` / diff --git a/.changeset/spec-refresh-17-2-0-5668.md b/.changeset/spec-refresh-17-2-0-5668.md index 541883958e..b4ad3b27c3 100644 --- a/.changeset/spec-refresh-17-2-0-5668.md +++ b/.changeset/spec-refresh-17-2-0-5668.md @@ -6,4 +6,4 @@ Refreshes the lockfile so every `@objectstack/*` package resolves at `17.2.0` **The docs-site and console builds stop pulling a Postgres connection-string parser toward the browser bundle.** `@objectstack/spec@17.1.0` imported `pg-connection-string` at the top level of `dist/index.mjs` with no `browser` export condition, so `apps/site`'s production build failed with `Module not found: Can't resolve 'fs'` on every route that reaches `@object-ui/components` from a client component — red on `main` since 2026-08-22 (objectui#5668). `17.2.0` ships the objectstack#11072 fix: `.`, `./data`, `./system`, `./kernel` and `./cloud` now carry `browser` conditions pointing at schema-free `dist/browser/**` bundles, and the site build is back to `Tasks: 29 successful, 29 total`. -The refresh is lockfile-only — every manifest already declared `^17.0.0`, which admits `17.2.0`, so no dependency range changed. No shipped source moves: the two in-repo adaptations are a drift-guard test and a CI gate, both forced by `17.2.0` retiring the spec's theme module (objectstack#10485) exactly as the objectui#5716 localization predicted — its `Theme`/`ThemeMode`/`ColorPalette` ALLOW entries in `check:spec-symbols` went stale and were deleted, and the parity test now pins the vacancy (the spec re-publishing a theme name is a loud collision) instead of a spec leg that no longer exists. +The refresh is lockfile-only — every manifest already declared `^17.0.0`, which admits `17.2.0`, so no dependency range changed. No shipped source moves: the two in-repo adaptations are a drift-guard test and a CI gate, both forced by `17.2.0` retiring the spec's theme module (objectstack `35ad101bc`) exactly as the objectui#5716 localization predicted — its `Theme`/`ThemeMode`/`ColorPalette` ALLOW entries in `check:spec-symbols` went stale and were deleted, and the parity test now pins the vacancy (the spec re-publishing a theme name is a loud collision) instead of a spec leg that no longer exists. diff --git a/.changeset/theme-clientvalidation-dead-entry-5715.md b/.changeset/theme-clientvalidation-dead-entry-5715.md index 0f5648934d..d1c9085d34 100644 --- a/.changeset/theme-clientvalidation-dead-entry-5715.md +++ b/.changeset/theme-clientvalidation-dead-entry-5715.md @@ -4,7 +4,7 @@ Removed the dead `theme:` entry from `clientValidation.ts`'s `LOADERS` table, which read `ThemeSchema` off `@objectstack/spec/ui` — a symbol the spec retired upstream -(objectstack#10485 / PR objectstack#10695, which deleted the whole `ui/theme.zod.ts` +(objectstack `35ad101bc`, which deleted the whole `ui/theme.zod.ts` module). `theme` was never a registered metadata type, so metadata-admin never asked for it (objectui#5715). diff --git a/.changeset/theme-types-localized-5716.md b/.changeset/theme-types-localized-5716.md index 85b3fede0e..5085f8f3a4 100644 --- a/.changeset/theme-types-localized-5716.md +++ b/.changeset/theme-types-localized-5716.md @@ -3,7 +3,7 @@ '@object-ui/providers': minor --- -Localize the theme document types: `@object-ui/types` now owns `Theme`, `ThemeMode` and `ColorPalette` (objectui#5716 ruling, 2026-08-23). The spec retired its theme module (objectstack#10485) while ObjectUI retained the theme system, so the types are hand-written from the last-published `@objectstack/spec` 17.1.0 shapes instead of re-exported — a spec dependency refresh past the retirement no longer breaks these packages. +Localize the theme document types: `@object-ui/types` now owns `Theme`, `ThemeMode` and `ColorPalette` (objectui#5716 ruling, 2026-08-23). The spec retired its theme module (objectstack `35ad101bc`) while ObjectUI retained the theme system, so the types are hand-written from the last-published `@objectstack/spec` 17.1.0 shapes instead of re-exported — a spec dependency refresh past the retirement no longer breaks these packages. Published-name REMOVALS from `@object-ui/types` (zero in-repo readers, deleted under the same ruling's rider): diff --git a/.changeset/theme-zod-retired-spec-reexports.md b/.changeset/theme-zod-retired-spec-reexports.md index 68023be60c..dc73eab39c 100644 --- a/.changeset/theme-zod-retired-spec-reexports.md +++ b/.changeset/theme-zod-retired-spec-reexports.md @@ -4,4 +4,4 @@ Remove the six retired `@objectstack/spec/ui` theme-schema re-exports from `@object-ui/types/zod` — `ColorPaletteSchema`, `TypographySchema`, `BorderRadiusSchema`, `ShadowSchema`, `ThemeModeSchema`, `ThemeDefinitionSchema` (the spec's `ThemeSchema`) — plus their `…SchemaType` inference helpers, and the `theme` / `mode` props of `ThemePreviewSchema` (zod and interface) that consumed them. -objectstack#10485 (ADR-0049 enforce-or-remove, PR objectstack#10695) retired the spec's whole `ui/theme.zod.ts` module, and the maintainer's ruling on objectstack#10856 (Options A + C) has objectui remove the dangling imports first so the Console Pin Gate can build objectui against the framework tree; restoring the spec exports (Option B) was explicitly not taken. Breaking in effect for anyone importing those six names from `@object-ui/types/zod`: there is no replacement — the validators retired upstream with no successor. The theme TYPE surface (`Theme`, `ThemeMode`, `ColorPalette`, … re-exported from `@object-ui/types`) and the ThemeEngine/ThemeProvider runtime are unchanged. +objectstack `35ad101bc` (ADR-0049 enforce-or-remove) retired the spec's whole `ui/theme.zod.ts` module, and the maintainer's ruling on objectstack#10856 (Options A + C) has objectui remove the dangling imports first so the Console Pin Gate can build objectui against the framework tree; restoring the spec exports (Option B) was explicitly not taken. Breaking in effect for anyone importing those six names from `@object-ui/types/zod`: there is no replacement — the validators retired upstream with no successor. The theme TYPE surface (`Theme`, `ThemeMode`, `ColorPalette`, … re-exported from `@object-ui/types`) and the ThemeEngine/ThemeProvider runtime are unchanged. diff --git a/.changeset/view-overlay-write-patch-only-5233.md b/.changeset/view-overlay-write-patch-only-5233.md index fec2936669..e8dc700d92 100644 --- a/.changeset/view-overlay-write-patch-only-5233.md +++ b/.changeset/view-overlay-write-patch-only-5233.md @@ -24,7 +24,7 @@ delete the user's view rather than narrow it. This is the write half of the maintainer's 2026-08-12 ruling (objectstack#7494). It was blocked until `columnState` was admitted to the view-metadata surface as -an explicitly runtime-only overlay key (objectstack#9933, released in +an explicitly runtime-only overlay key (objectstack `d5552ca13`, released in `@objectstack/spec` 17.1.0) — before that a `columnState`-only patch was refused `422 INVALID_METADATA`, and the fat copy was the only thing supplying a recognized key. The read half (`narrowPersonalizationOverlay`) shipped earlier diff --git a/packages/app-shell/src/chrome/ConditionalAuthWrapper.tsx b/packages/app-shell/src/chrome/ConditionalAuthWrapper.tsx index 18efa11559..e7f7702c78 100644 --- a/packages/app-shell/src/chrome/ConditionalAuthWrapper.tsx +++ b/packages/app-shell/src/chrome/ConditionalAuthWrapper.tsx @@ -100,7 +100,7 @@ export function ConditionalAuthWrapper({ children, authUrl }: ConditionalAuthWra // This reading is the ONLY thing that decides it. `discovery.mode` used // to be consulted first: `'preview'` turned auth off outright and // simulated an identity out of `discovery.previewMode`. `@objectstack/spec` - // retired that whole wire surface (objectstack#11846), so this consumer + // retired that whole wire surface (objectstack `0c2334f6c`), so this consumer // is retired with it (objectui#6654) — a deployment still emitting it // falls back to this reading, i.e. it requires login. const isAuthEnabled = isServiceUsable(discovery?.services?.auth); diff --git a/packages/app-shell/src/console/marketplace/PluginDisclosure.tsx b/packages/app-shell/src/console/marketplace/PluginDisclosure.tsx index 7e9f9f4f10..d76583eb5f 100644 --- a/packages/app-shell/src/console/marketplace/PluginDisclosure.tsx +++ b/packages/app-shell/src/console/marketplace/PluginDisclosure.tsx @@ -129,7 +129,7 @@ export function PluginDisclosure({ version }: { version?: MarketplacePackageVers items={perms.fs ?? undefined} /> {/* - objectstack#17147 — say what this list DOES, because a permission + objectstack `aaacf1d5c` — say what this list DOES, because a permission panel that only lists grants is read as a confinement promise. Measured on objectstack `9bd4344e4`: the consented set is persisted (`sys_package_installation.granted_permissions`), re-confirmed on a diff --git a/packages/app-shell/src/layout/ActivityFeed.tsx b/packages/app-shell/src/layout/ActivityFeed.tsx index 3de16f8f68..90c2bde194 100644 --- a/packages/app-shell/src/layout/ActivityFeed.tsx +++ b/packages/app-shell/src/layout/ActivityFeed.tsx @@ -67,7 +67,7 @@ const typeConfig: Record< * `Record` and `tsc` forces every member — but * `ActivityFeed` is published API (the package barrel exports it), so a host * can mount it and pass rows whose `type` came from its own data. - * `sys_activity.type` is author-extensible (objectstack#11507, ruled + * `sys_activity.type` is author-extensible (objectstack `88b9d749a`, ruled * 2026-08-24) and is not validated on write, so those kinds are real. Reading * one as "off" made the row stored, queryable and invisible — the * objectui#5840 failure mode reached from the reader side, and the least diff --git a/packages/app-shell/src/layout/activityItemType.ts b/packages/app-shell/src/layout/activityItemType.ts index 3eb9d3dd29..92d4609e7d 100644 --- a/packages/app-shell/src/layout/activityItemType.ts +++ b/packages/app-shell/src/layout/activityItemType.ts @@ -60,7 +60,7 @@ * `update`. That is not a missing decision, it is a WRONG one stated out loud: * a `scheduled` meeting and an author's `contract_countersigned` both rendered * as "somebody updated this record". `sys_activity.type` is author-extensible - * (objectstack#11507 direction 4, ruled 2026-08-24 — the column's fields are + * (objectstack `88b9d749a`, direction 4, ruled 2026-08-24 — the column's fields are * `readonly: true` so objectql never validates them on write, and ADR-0052 * §5b.2 forwards `activityMilestones[].type` into it verbatim), so unrecognised * values are not mistakes to be papered over; they are real activity nobody has @@ -184,7 +184,7 @@ function warnUnmappedActivityType(type: string): void { console.warn( `[app-shell] rendered a sys_activity row with type "${type}" through the generic ` + `"${UNMAPPED_ACTIVITY_ITEM_TYPE}" presentation: no activity item type is mapped ` - + 'for it. `sys_activity.type` is author-extensible (objectstack#11507, ruled ' + + 'for it. `sys_activity.type` is author-extensible (ruled ' + '2026-08-24) and is not validated on write, so a producer can store a value the ' + 'platform never declared — the row is shown rather than dropped, and it no longer ' + 'claims to be an update. Map it in ACTIVITY_TYPE_TO_ACTIVITY_ITEM_TYPE ' diff --git a/packages/app-shell/src/services/MetadataService.ts b/packages/app-shell/src/services/MetadataService.ts index 9907ce0a68..9901f8d950 100644 --- a/packages/app-shell/src/services/MetadataService.ts +++ b/packages/app-shell/src/services/MetadataService.ts @@ -321,7 +321,7 @@ function describeUnusableTarget(reference: unknown): string { * It WAS a declared divergence when written: 17.3.0's objectstack#13632 refinement spelled * its emptiness test as an equality against `''`, so the spec accepted a * whitespace-only target while this writer refused it. objectstack#16920 - * (merged 2026-09-08, closing objectstack#16126) applies that test to the + * (merged 2026-09-08) applies that test to the * TRIMMED value — `packages/spec/src/data/field.zod.ts`, the `FieldSchema` * `superRefine`: * diff --git a/packages/app-shell/src/views/ActionParamDialog.tsx b/packages/app-shell/src/views/ActionParamDialog.tsx index 0bb989bc7a..90f0939055 100644 --- a/packages/app-shell/src/views/ActionParamDialog.tsx +++ b/packages/app-shell/src/views/ActionParamDialog.tsx @@ -244,7 +244,8 @@ function carryOverDisplayText(value: unknown): string | null { /** * A param that declares `carryOver` (`@objectstack/spec`'s `ActionParamSchema`, - * objectstack#11753 ruling, objectui#6246): a collapsed READ-ONLY summary. + * the 2026-08-25 ruling whose spec half is objectstack `0e4e51b0a`, objectui#6246): a + * collapsed READ-ONLY summary. * * ⛔ No field widget is built for it at all — not a disabled one, not a * read-only one. The ruling's point is that the renderer leaves NO editing diff --git a/packages/app-shell/src/views/ObjectDataPage.tsx b/packages/app-shell/src/views/ObjectDataPage.tsx index e71642806a..41edad4f30 100644 --- a/packages/app-shell/src/views/ObjectDataPage.tsx +++ b/packages/app-shell/src/views/ObjectDataPage.tsx @@ -405,7 +405,7 @@ export function ObjectDataPage({ dataSource, objects }: any) { // `better-auth` objects (whose bucket resolves `create: false`) were still // offered a "New" that navigates to `../new`, an object-level // `userActions: { create: false }` opt-out did not close the button, and the - // #3391 effective-API-operation intersection was absent, so the toolbar could + // objectstack#3391 effective-API-operation intersection was absent, so the toolbar could // offer a create the server would 405. // // Resolved exactly as `ObjectView` does: the spec's bucket/`userActions` @@ -439,7 +439,7 @@ export function ObjectDataPage({ dataSource, objects }: any) { * * LAYERING: surfaced only when the object-level verdict already passed. A * predicate may not RE-OPEN what the bucket, the effective API operations - * (#3391) or the principal's grant have closed; it only narrows further. The + * (objectstack#3391) or the principal's grant have closed; it only narrows further. The * pre-existing `can(...)` gate is not removed, it is one conjunct of this. * * ONE RENDER POINT here, unlike `ObjectView`: this page has no phone FAB — @@ -524,7 +524,7 @@ export function ObjectDataPage({ dataSource, objects }: any) { actions={ <> {/* [#5164] `objectCanCreate && createVisible` — the bucket + - object-level `userActions` + #3391 effective-operations + object-level `userActions` + objectstack#3391 effective-operations verdict (all folded into `affordances.create`) AND the principal's grant, then the toolbar-scope `visibleWhen` layer on top of it. Greyed, not gone, is the `disabledWhen` case. */} diff --git a/packages/app-shell/src/views/ObjectView.tsx b/packages/app-shell/src/views/ObjectView.tsx index 8178615fb5..18b59235ac 100644 --- a/packages/app-shell/src/views/ObjectView.tsx +++ b/packages/app-shell/src/views/ObjectView.tsx @@ -1095,7 +1095,7 @@ export function buildPersistedViewBody( * (`isDefault`, `isPinned`, `sortOrder`; the adapter merges them at the row's * top level), the tab's `visibility`, and `columnState`, the runtime-only key * the spec declares on the ViewItem wire face rather than on the list-view - * body (objectstack#9933). A view-config save is a whole-document PUT, so + * body (objectstack `d5552ca13`). A view-config save is a whole-document PUT, so * these are carried forward at the envelope's top level; dropping them would * erase the default flag, the pin and the column widths the row held. */ @@ -1625,7 +1625,7 @@ function ObjectViewInner({ dataSource, objects, onEdit, externalRefreshKey }: an // hide the lot — those flows go through purpose-built actions on the // source record (e.g. "Submit for Approval" on an Opportunity creates // an `sys_approval_request`). Permissions still gate the buttons. - // [#3391] Intersect the bucket affordances with the server's effective API + // [objectstack#3391] Intersect the bucket affordances with the server's effective API // operation set for this object (from /me/permissions apiOperations), so the // toolbar never offers Import/Export/New/Edit/Delete the server would 405. // `undefined` (unrestricted object / old backend) leaves affordances as-is. @@ -1704,7 +1704,7 @@ function ObjectViewInner({ dataSource, objects, onEdit, externalRefreshKey }: an * * LAYERING: surfaced only when the object-level verdict already passed — * the same posture the related-list bridge takes, because a predicate may - * not RE-OPEN what the bucket, the effective API operations (#3391) or the + * not RE-OPEN what the bucket, the effective API operations (objectstack#3391) or the * principal's grant have closed. The identity-import bypass below is a * different affordance entirely (it does not read `affordances.import`) and * is deliberately left outside this layer. diff --git a/packages/app-shell/src/views/RecordDetailView.tsx b/packages/app-shell/src/views/RecordDetailView.tsx index b7fe8594dc..dfef12536b 100644 --- a/packages/app-shell/src/views/RecordDetailView.tsx +++ b/packages/app-shell/src/views/RecordDetailView.tsx @@ -1709,7 +1709,7 @@ export function RecordDetailView({ dataSource, objects, onEdit, objectNameOverri // drifted the same way one level up: this loop dropped a type the table // does not contain SILENTLY, while the block renders it through // `UNMAPPED_ACTIVITY_FEED_TYPE` and warns once. `sys_activity.type` is - // author-extensible (objectstack#11507 direction 4, ruled 2026-08-24) and + // author-extensible (objectstack `88b9d749a`, direction 4, ruled 2026-08-24) and // is never validated on write, so that drop made every author-extended // row stored, queryable and INVISIBLE on the surface where a shipped // producer's rows are most likely to be watched — objectui#5840's failure diff --git a/packages/app-shell/src/views/metadata-admin/PermissionMatrixEditor.tsx b/packages/app-shell/src/views/metadata-admin/PermissionMatrixEditor.tsx index 9d9039cc05..8ca508067f 100644 --- a/packages/app-shell/src/views/metadata-admin/PermissionMatrixEditor.tsx +++ b/packages/app-shell/src/views/metadata-admin/PermissionMatrixEditor.tsx @@ -319,7 +319,7 @@ export function PermissionMatrixEditPage({ type, name, packageId, onDraftSaved, // `protocol.ts`). Gating on `allowOrgOverride` alone therefore locked a // surface the server accepts: `permission` is `allowOrgOverride: false` // (ADR-0005 forbids per-org overlay of a packaged permission set — silent - // privilege drift) but `allowRuntimeCreate: true`, and objectstack#6483 + // privilege drift) but `allowRuntimeCreate: true`, and objectstack `ee58392e1` // kept that second door open on purpose ("Runtime-created sets … ride // `allowRuntimeCreate` (still `true`) and keep working"). // `useMetadata.ts` states the convention on the field itself: "UI diff --git a/packages/app-shell/src/views/metadata-admin/ResourceEditPage.tsx b/packages/app-shell/src/views/metadata-admin/ResourceEditPage.tsx index 0d8b3dbea0..2ea9e12ae3 100644 --- a/packages/app-shell/src/views/metadata-admin/ResourceEditPage.tsx +++ b/packages/app-shell/src/views/metadata-admin/ResourceEditPage.tsx @@ -221,7 +221,7 @@ const CANVAS_OWNED_KEYS: Record = { * ## Why this is a function and not two inline reads * * Both steps of the loop send this value — `doSave` binds the draft row to the - * package (`PUT ?package=`), and since objectstack#10354 `doPublish` states the + * package (`PUT ?package=`), and since objectstack `9e04c3e35`, `doPublish` states the * same package on the promotion (`POST .../publish?package=`) so #9612's * package-closure narrowing at the runtime publish gate is reachable from an * HTTP-driven promotion at all. One value, one spelling, both steps — which @@ -1680,7 +1680,7 @@ function MetadataResourceEditPageImpl({ // Absent (not empty) when the designer holds no binding: the framework // branches on the KEY BEING PRESENT downstream, where a present-but-null // package pins the draft lookup to unbound rows and a packaged draft - // stops being found (`no_draft`) — see objectstack#10354's own warning. + // stops being found (`no_draft`) — see objectstack `9e04c3e35`'s own warning. const activePackage = readActivePackageBinding(); await client.publish(type, name, { ...(activePackage ? { packageId: activePackage } : {}), diff --git a/packages/app-shell/src/views/metadata-admin/SchemaForm.tsx b/packages/app-shell/src/views/metadata-admin/SchemaForm.tsx index 0eb5270382..92756ffabf 100644 --- a/packages/app-shell/src/views/metadata-admin/SchemaForm.tsx +++ b/packages/app-shell/src/views/metadata-admin/SchemaForm.tsx @@ -901,7 +901,7 @@ function resolveFieldWidget({ * spec's normaliser REWRITES the alias instead of keeping both: a parsed * `FormView` carries `visibleWhen` and no `visibleOn` at all * (`@objectstack/spec` `shared/visibility.ts`). Reading only `visibleOn` — what - * this admin engine did until objectstack#6331 — therefore found `undefined` on + * this admin engine did until `7a197e7c5` — therefore found `undefined` on * every spec-served form and short-circuited each predicate to "always * visible", so conditional fields/sections rendered unconditionally. * diff --git a/packages/app-shell/src/views/metadata-admin/clientValidation.ts b/packages/app-shell/src/views/metadata-admin/clientValidation.ts index 21c65c03aa..68fa2b9afe 100644 --- a/packages/app-shell/src/views/metadata-admin/clientValidation.ts +++ b/packages/app-shell/src/views/metadata-admin/clientValidation.ts @@ -668,7 +668,7 @@ const LOADERS: Record = { action: async () => (await import('@objectstack/spec/ui')).ActionSchema as unknown as ZodLikeSchema, // `theme` is intentionally absent. It was never a registered metadata type, // so metadata-admin never asks for it — and the spec retired the whole - // `ui/theme.zod.ts` module (objectstack#10485 / PR objectstack#10695), so the + // `ui/theme.zod.ts` module (objectstack `35ad101bc`), so the // `ThemeSchema` the old entry read off this subpath is gone upstream. Nothing // here ever went red because objectui's own `@objectstack/spec` pin (17.1.0) // still publishes that symbol: the entry type-checked and resolved, and would diff --git a/packages/app-shell/src/views/metadata-admin/form-spec.ts b/packages/app-shell/src/views/metadata-admin/form-spec.ts index b72c00a9c1..e163f8b90d 100644 --- a/packages/app-shell/src/views/metadata-admin/form-spec.ts +++ b/packages/app-shell/src/views/metadata-admin/form-spec.ts @@ -135,7 +135,7 @@ export interface FormFieldSpec { * renderer does not honour — the very shape the `visibleWhen` half of * this comment exists to close. * - * ⚠️ RULED 2026-08-28 (objectui#6263 / objectstack#12868, executed + * ⚠️ RULED 2026-08-28 (objectui#6263, executed * upstream by objectstack `c459da6bc`), so this is no longer an open * question this file is holding open: the FORM-VIEW option vocabulary * does not accept a per-option `default`, and the drop above is now the diff --git a/packages/app-shell/src/views/metadata-admin/i18n.ts b/packages/app-shell/src/views/metadata-admin/i18n.ts index 32e2657309..b7b43bdcf6 100644 --- a/packages/app-shell/src/views/metadata-admin/i18n.ts +++ b/packages/app-shell/src/views/metadata-admin/i18n.ts @@ -2274,8 +2274,8 @@ const ENGINE_STRINGS_EN: Record = { // because a code package ships it and overwriting a packaged item is an // overlay — which `permission` has not opted into. 'perm.readOnly.artifact': 'Read-only (this set is provided by a code package)', - // objectui#5987 — the ruled path comes FIRST (maintainer ruling on - // objectstack#11513: lock the base, clone to customize). The remedies that + // objectui#5987 — the ruled path comes FIRST (maintainer ruling of + // 2026-08-24, objectstack `e170b0ae5`: lock the base, clone to customize). The remedies that // used to lead ("edit the source artifact and redeploy", a new runtime set, // the operator hatch) stay, as the secondary routes they are. 'perm.readOnly.artifact.hint': diff --git a/packages/app-shell/src/views/metadata-admin/permission-set-clone-dispatch.ts b/packages/app-shell/src/views/metadata-admin/permission-set-clone-dispatch.ts index 79d19b2217..d9c6055d9d 100644 --- a/packages/app-shell/src/views/metadata-admin/permission-set-clone-dispatch.ts +++ b/packages/app-shell/src/views/metadata-admin/permission-set-clone-dispatch.ts @@ -5,7 +5,7 @@ * `clone_permission_set` record action and shaping its dispatch. * * The permission matrix locks a set a code package ships (the artifact tier). - * The maintainer's ruling on objectstack#11513 — lock the base, clone to + * The maintainer's 2026-08-24 ruling (objectstack `e170b0ae5`) — lock the base, clone to * customize — makes cloning the sanctioned edit path, and the server's own * `403 not_overridable` refusal names the `clone_permission_set` action as the * remedy. The editor therefore runs THAT action, resolved by name off the @@ -13,7 +13,7 @@ * hand-rolls a copy out of create/update calls: the action's `params` list IS * the payload (which facets a clone carries is decided where the action is * declared), and a second spelling of it here would be the silent-grant-loss - * shape objectstack#11703 closed. + * shape objectstack `5cb62d88b` closed. * * ## Why this lives beside the editor rather than in it * diff --git a/packages/components/src/custom/filter-builder.tsx b/packages/components/src/custom/filter-builder.tsx index 8a85db8da9..50d3cb3c92 100644 --- a/packages/components/src/custom/filter-builder.tsx +++ b/packages/components/src/custom/filter-builder.tsx @@ -1634,7 +1634,7 @@ function FilterBuilder({ /** * WHICH bound is missing on a half-filled pair — `0`, `1`, or `null` when * the row is not half-filled at all (objectui#10061, executing ruling - * batch #146 item 5 letter A on objectstack#18012). + * batch #146 item 5 letter A, which objectstack `176b03582` executed upstream). * * The ruling's two halves are 「not emitted」 and 「shown as incomplete」. * The first has been true since objectui#5025: every write path asks diff --git a/packages/components/src/renderers/form/form.tsx b/packages/components/src/renderers/form/form.tsx index 268af5d2fd..805d147387 100644 --- a/packages/components/src/renderers/form/form.tsx +++ b/packages/components/src/renderers/form/form.tsx @@ -2451,7 +2451,7 @@ ComponentRegistry.register('form', // pi-TgoJ4_DM55Fqz" (objectstack#3821). A permission denial is a // condition the UI already knows how to name, so say it in the user's // language and keep the server text for the console. - // …unless the AUTHOR opted in. `userMessage` (objectstack#9934) is the + // …unless the AUTHOR opted in. `userMessage` (objectstack `79c46da90`) is the // producer-side marking: a hook sets it at throw time to // say "this text is for the end user". It is a separate field from // `message`, so nothing unmarked can reach here — the substitution above diff --git a/packages/components/src/renderers/layout/containers.tsx b/packages/components/src/renderers/layout/containers.tsx index 1289e3ab1b..6b277bb712 100644 --- a/packages/components/src/renderers/layout/containers.tsx +++ b/packages/components/src/renderers/layout/containers.tsx @@ -63,7 +63,7 @@ import { MoreHorizontal, RefreshCw } from 'lucide-react'; * `page:footer`, `page:sidebar` (objectui#4027). * * `@objectstack/spec` declares all three through one shared `PageContainerProps` - * whose single key is `children` (objectstack#5775, PR objectstack#6281, merged + * whose single key is `children` (objectstack#5775, objectstack `85ec26d28`, merged * 2026-08-07). They had been declared `EmptyProps` upstream — "this component * takes zero props" — while their renderers have always rendered a child list; * this side carried the mirror-image gap, registering all three with no `inputs` diff --git a/packages/core/src/actions/ActionRunner.ts b/packages/core/src/actions/ActionRunner.ts index e418b95063..5708840ea5 100644 --- a/packages/core/src/actions/ActionRunner.ts +++ b/packages/core/src/actions/ActionRunner.ts @@ -177,8 +177,8 @@ export interface ActionDef { * field, because the 2026-08-06 maintainer ruling on objectstack#4075 gave * both keys ONE shape: `boolean | string(CEL) | { dialect, source }` — * "boolean = 条件的退化形字面量,string = CEL 简写,信封 = 完整形". The - * envelope arm arrived in `@objectstack/spec` 17.0.0-rc.6 (objectstack#5970, - * PR objectstack#6450); until then this was a hand-written `string | boolean` + * envelope arm arrived in `@objectstack/spec` 17.0.0-rc.6 (objectstack + * `97e7e3caa`); until then this was a hand-written `string | boolean` * that could not describe the envelope, which is why `DeclaredActionsBar` * read it through an `(action as any).disabled` cast. Derived, not restated, * so the two keys cannot drift apart again. @@ -386,7 +386,7 @@ export interface ActionDef { * spec 采纳 —— `visible` / `disabled` 两键在 spec 侧统一收敛为 * `boolean | string(CEL) | {dialect, source}`(boolean = 条件的退化形字面量, * string = CEL 简写,信封 = 完整形)". `@objectstack/spec` 17.0.0-rc.6 carries - * it (objectstack#5970, PR objectstack#6450), so the local `| boolean` is no + * it (objectstack `97e7e3caa`), so the local `| boolean` is no * longer a tolerance to declare — it is part of the derived type, and adding * it back would restate a spec arm rather than widen anything. */ @@ -690,7 +690,8 @@ export interface ActionParamDef { visible?: string; /** * Carry-over declaration — `@objectstack/spec`'s `ActionParamSchema.carryOver` - * (objectstack#11753 ruling, objectui#6246), passed through unchanged by + * (the 2026-08-25 ruling whose spec half is objectstack `0e4e51b0a`, + * objectui#6246), passed through unchanged by * `resolveActionParams()`. The param's value is carried through the dialog * rather than collected from the user: seeded from the row (the spec refuses * the key without `defaultFromRow: true`), rendered by `ActionParamDialog` as diff --git a/packages/core/src/utils/filter-tokens.ts b/packages/core/src/utils/filter-tokens.ts index baca3333ab..ac7bdac708 100644 --- a/packages/core/src/utils/filter-tokens.ts +++ b/packages/core/src/utils/filter-tokens.ts @@ -115,7 +115,7 @@ const WHOLE_TOKEN_RE = /^\$?\{([a-zA-Z0-9_]+)\}$/; * than special-casing the two spellings measured today: this object has no * prototype at all, so *no* key — known or future — can resolve through it. * `@objectstack/spec`'s own map is left untouched (out of scope here; the - * identical shape in its `classifyFilterToken` is objectstack#17762). + * identical shape in its `classifyFilterToken` is the one objectstack `4342c9923` closed). */ const NEAR_MISS_SUGGESTIONS: Readonly> = Object.assign( Object.create(null), diff --git a/packages/core/src/utils/managedBy.ts b/packages/core/src/utils/managedBy.ts index a0d7d16c09..cd47869f85 100644 --- a/packages/core/src/utils/managedBy.ts +++ b/packages/core/src/utils/managedBy.ts @@ -19,7 +19,7 @@ * * What is genuinely objectui's and keeps a local name: * {@link resolveEffectiveCrudAffordances} — the spec's object-level matrix - * INTERSECTED with the server-resolved effective API operation set (#3391), so + * INTERSECTED with the server-resolved effective API operation set (objectstack#3391), so * the UI never offers a button the server would 405. The spec's function has * no such notion; naming ours after it was the misdescription this burn-down * removes. @@ -142,7 +142,7 @@ export function userActionPredicates( /** * The affordance-bit → server API-operation mapping used to intersect the - * UI-intent affordances with the server's effective API operation set (#3391). + * UI-intent affordances with the server's effective API operation set (objectstack#3391). * This is the objectui end of the framework's `API_METHOD_DERIVATION` contract: * the button predicate is `affordance(op) ∧ effective.api(op)`. */ @@ -167,7 +167,7 @@ const AFFORDANCE_TO_API_OPERATION = { * * @param obj The object schema (managedBy bucket + userActions overrides). * @param effectiveApiOperations OPTIONAL server-resolved effective API operation - * set for this object (from `/me/permissions` `apiOperations`, #3391). When + * set for this object (from `/me/permissions` `apiOperations`, objectstack#3391). When * provided, each affordance bit is ANDed with the corresponding API operation * (create/import→create/import, edit→update, delete→delete, exportCsv→export), * so the UI never shows a button the server would 405. Passing `undefined` @@ -188,7 +188,7 @@ export function resolveEffectiveCrudAffordances( typeof resolveSpecCrudAffordances >[0]['userActions'], }); - // [#3391] Intersect with the server's effective API operations when present. + // [objectstack#3391] Intersect with the server's effective API operations when present. // The frontend consumes the effective set the server hands down; it never // reads the raw `apiMethods` nor re-derives. if (Array.isArray(effectiveApiOperations)) { @@ -238,7 +238,7 @@ export function isSystemWritable(obj: SchemaLike | null | undefined): boolean { * object-level editability, so only the resolved boolean matters here.) * * @param effectiveApiOperations OPTIONAL server-resolved effective API operation - * set for this object (`/me/permissions` `apiOperations`, #3391/#3546). When + * set for this object (`/me/permissions` `apiOperations`, objectstack#3391/objectstack#3546). When * provided, inline-edit is additionally ANDed with the server allowing * `update`, so a record page never offers double-click/pencil editing the * server would 405. `undefined` (old backend / unrestricted) leaves the diff --git a/packages/data-objectstack/src/index.ts b/packages/data-objectstack/src/index.ts index a3295660f8..17c52bc94b 100644 --- a/packages/data-objectstack/src/index.ts +++ b/packages/data-objectstack/src/index.ts @@ -1629,7 +1629,7 @@ export class ConcurrentUpdateError extends Error { readonly currentRecord: unknown; /** * The refusal text the PRODUCER marked as addressed to the end user - * (`ApiErrorSchema.userMessage`, objectstack#9934), or `null` when the + * (`ApiErrorSchema.userMessage`, objectstack `79c46da90`), or `null` when the * refusal carried no marking. * * Declared on the class because this error has no `details` bag: the shared @@ -1695,7 +1695,7 @@ type MarkedRefusal = Pick; /** * Lift the producer's user-facing marking off a client error. * - * `userMessage` (`ApiErrorSchema.userMessage`, objectstack#9934) is the opt-in + * `userMessage` (`ApiErrorSchema.userMessage`, objectstack `79c46da90`) is the opt-in * channel an application author sets at throw time to say "this text is for * the end user". The contract states it **status-agnostic** — not a 403 * special case, any refusal status may carry it — so this read is @@ -2850,7 +2850,7 @@ function isPersonalizationOverlayRow(item: any, spec: any): boolean { * (objectui#10210, ruling B — see {@link isPersonalizationOverlayRow}). * - **write** (objectui#5233, `buildPersistedViewBody` in app-shell's * `ObjectView`, unblocked by `columnState`'s admission to the view-metadata - * surface as a runtime-only overlay key — objectstack#9933, released in + * surface as a runtime-only overlay key — objectstack `d5552ca13`, released in * `@objectstack/spec` 17.1.0): a *system view's* overlay is now written as * the patch alone, so no new row freezes anything, and because the write is * a whole-document PUT the next toggle also strips an old fat row. A *saved diff --git a/packages/data-objectstack/src/metadata-client.ts b/packages/data-objectstack/src/metadata-client.ts index f643b95900..76b67ad9cc 100644 --- a/packages/data-objectstack/src/metadata-client.ts +++ b/packages/data-objectstack/src/metadata-client.ts @@ -1484,7 +1484,7 @@ export class MetadataClient { name: string, options: { message?: string; packageId?: string } = {}, ): Promise { - // objectstack#10354 (`@objectstack/rest` 17.2.0) — this door accepts + // objectstack `9e04c3e35` (`@objectstack/rest` 17.2.0) — this door accepts // `?package=` and forwards it as the promotion's package binding, so // #9612's package-closure narrowing at the runtime publish gate is // reachable from an HTTP-driven promotion at all. Deliberately the SAME diff --git a/packages/i18n/src/useObjectLabel.ts b/packages/i18n/src/useObjectLabel.ts index cb79c3a774..e243de63d4 100644 --- a/packages/i18n/src/useObjectLabel.ts +++ b/packages/i18n/src/useObjectLabel.ts @@ -268,8 +268,8 @@ export function useObjectLabel() { * name under `_views` — the runtime view identity's own name, stripped of the * object prefix. That single spelling is canonical per the objectstack#5164 * ruling A (2026-08-06): the i18n extractor asks the view composer for the key - * (objectstack#6124) and `packages/lint` enforces exactly that spelling - * (objectstack#6038), so this resolver accepts exactly what those produce. + * (objectstack `b3c1f3cd5`) and `packages/lint` enforces exactly that spelling + * (objectstack `7618ee814`), so this resolver accepts exactly what those produce. * * Deliberately NOT a second candidate: the prefixed full name * (`_views..`). Accepting it made this client more diff --git a/packages/permissions/src/MePermissionsProvider.tsx b/packages/permissions/src/MePermissionsProvider.tsx index 80fc4e6db0..b81c5e742b 100644 --- a/packages/permissions/src/MePermissionsProvider.tsx +++ b/packages/permissions/src/MePermissionsProvider.tsx @@ -43,7 +43,7 @@ export interface MePermissionsResponse { viewAllRecords?: boolean; modifyAllRecords?: boolean; /** - * [#3391] Server-resolved effective API operation set for this object + * [objectstack#3391] Server-resolved effective API operation set for this object * (enum-ordered). Present only when the object tightens exposure via * `apiMethods`; absent = unrestricted (client default-allow). The frontend * consumes THIS, never a raw `apiMethods` whitelist. @@ -343,7 +343,7 @@ export function MePermissionsProvider({ update: 'allowEdit', edit: 'allowEdit', delete: 'allowDelete', - // [#3391] import derives from create∨update, export from list(read) — + // [objectstack#3391] import derives from create∨update, export from list(read) — // gate them on the base write/read permission bit (the per-object // effective API operation set adds the finer apiMethods layer on top, // consumed via getObjectApiOperations + resolveCrudAffordances). diff --git a/packages/permissions/src/PermissionContext.ts b/packages/permissions/src/PermissionContext.ts index a37ca12288..d83bb91240 100644 --- a/packages/permissions/src/PermissionContext.ts +++ b/packages/permissions/src/PermissionContext.ts @@ -19,7 +19,7 @@ export interface PermissionContextValue { /** Get row filter for an object */ getRowFilter: (object: string) => string | undefined; /** - * [#3391] Server-resolved effective API operation set for an object (from + * [objectstack#3391] Server-resolved effective API operation set for an object (from * `/me/permissions` `apiOperations`), or `undefined` when the object carries * no effective set (unrestricted object / old backend / no provider). The UI * intersects this with its CRUD affordances (`resolveCrudAffordances`), never diff --git a/packages/permissions/src/PermissionProvider.tsx b/packages/permissions/src/PermissionProvider.tsx index 899df91fea..e05855d2c2 100644 --- a/packages/permissions/src/PermissionProvider.tsx +++ b/packages/permissions/src/PermissionProvider.tsx @@ -55,7 +55,7 @@ const VALUE = createDiscardProofCache(); const NO_USER: object = { user: 'absent' }; /** - * [#3391] Role-based provider does not model the server's effective API + * [objectstack#3391] Role-based provider does not model the server's effective API * operation set — return undefined so consumers keep current behavior. * * [objectui#6813] Module-level rather than a literal rebuilt inside the value diff --git a/packages/plugin-calendar/src/ObjectCalendar.tsx b/packages/plugin-calendar/src/ObjectCalendar.tsx index b92e047baa..a383dec3d4 100644 --- a/packages/plugin-calendar/src/ObjectCalendar.tsx +++ b/packages/plugin-calendar/src/ObjectCalendar.tsx @@ -1004,8 +1004,8 @@ export const ObjectCalendar: React.FC = ({ // with visual-regression evidence across all four surfaces in one stroke. // ⛔ The ONE cast objectui#8651 left standing, deliberately. `navigation` is // objectui#8652's key: the maintainer ruled B there — declare it on the - // platform element schemas first, then mirror — and that card is `pm:blocked` - // on objectstack#17987. Its declaredness verdict at this read site is + // platform element schemas first, then mirror — and that card waits on + // objectstack `e233db9db`. Its declaredness verdict at this read site is // UNCHANGED by this card: through the retired union it was undeclared too, // and it is undeclared on `ObjectCalendarSchema`. The rule that makes that // come out right is NOT "declared on every arm". In the checker reading @@ -1086,7 +1086,7 @@ export const ObjectCalendar: React.FC = ({ // Surface the failure — never silently snap the event back. A row-level // security denial (403) is the common case: the user lacks permission to // reschedule this record. (cloud#864) - // …unless the AUTHOR opted in. `userMessage` (objectstack#9934) is the + // …unless the AUTHOR opted in. `userMessage` (objectstack `79c46da90`) is the // producer-side marking: a field set at throw time to say "this text is // for the end user". It is a SEPARATE field from `message`, so nothing // unmarked can reach here — the substitution below still governs every diff --git a/packages/plugin-designer/src/MetadataFieldsPage.tsx b/packages/plugin-designer/src/MetadataFieldsPage.tsx index 7e776b5181..72d54cb9e5 100644 --- a/packages/plugin-designer/src/MetadataFieldsPage.tsx +++ b/packages/plugin-designer/src/MetadataFieldsPage.tsx @@ -615,7 +615,7 @@ function describeUnusableTarget(reference: unknown): string { * It WAS a declared divergence when written: 17.3.0's objectstack#13632 refinement spelled * its emptiness test as an equality against `''`, so the spec accepted a * whitespace-only target while this page refused it. objectstack#16920 (merged - * 2026-09-08, closing objectstack#16126) applies that test to the TRIMMED value + * 2026-09-08) applies that test to the TRIMMED value * — `packages/spec/src/data/field.zod.ts`, the `FieldSchema` `superRefine`: * * if ( diff --git a/packages/plugin-detail/src/index.tsx b/packages/plugin-detail/src/index.tsx index bd23f817f8..d03a928814 100644 --- a/packages/plugin-detail/src/index.tsx +++ b/packages/plugin-detail/src/index.tsx @@ -75,7 +75,7 @@ export { * loop, and the two constructions had already drifted three ways — the console * copy dropped an unmapped type SILENTLY where {@link activityRowToFeedItem} * renders it through {@link UNMAPPED_ACTIVITY_FEED_TYPE} and says so once - * (objectstack#11507 direction 4, ruled 2026-08-24), and its timestamp + * (objectstack `88b9d749a`, direction 4, ruled 2026-08-24), and its timestamp * fallback could leave `createdAt` `undefined` where the helper yields `''`. * * So the exported surface is the whole reading — table, fallback, and the diff --git a/packages/plugin-detail/src/renderers/recordActivityFeed.ts b/packages/plugin-detail/src/renderers/recordActivityFeed.ts index b94c65acee..3997af308e 100644 --- a/packages/plugin-detail/src/renderers/recordActivityFeed.ts +++ b/packages/plugin-detail/src/renderers/recordActivityFeed.ts @@ -94,7 +94,7 @@ export const DEFAULT_ACTIVITY_LIMIT = 20; * * ## The vocabulary is OPEN — ruled. Do NOT restore set-equality. * - * Maintainer ruling of 2026-08-24 on objectstack#11507, **direction 4**: + * Maintainer ruling of 2026-08-24 (objectstack `88b9d749a`), **direction 4**: * `sys_activity.type` is AUTHOR-EXTENSIBLE. The declared select options are the * platform's BUILT-IN set, not the column's domain, and the two facts above are * why — readonly fields are never validated on write, and ADR-0052 §5b.2 @@ -141,7 +141,7 @@ export const ACTIVITY_TYPE_TO_FEED_TYPE: Readonly `[record:activity] rendered a sys_activity row with type "${type}" through the ` + `generic "${UNMAPPED_ACTIVITY_FEED_TYPE}" presentation: no feed item type is ` - + 'mapped for it. `sys_activity.type` is author-extensible (objectstack#11507, ' + + 'mapped for it. `sys_activity.type` is author-extensible (' + 'ruled 2026-08-24) and is not validated on write, so a producer can store a ' + 'value the platform never declared — the row is shown rather than dropped. ' + 'Map it in ACTIVITY_TYPE_TO_FEED_TYPE (@object-ui/plugin-detail) to give it ' @@ -742,7 +742,7 @@ export function resetUnknownActivityTypeWarnings(): void { * record activity (see {@link ACTIVITY_TYPE_TO_FEED_TYPE}). * * Three outcomes, and the difference between the last two is the whole of the - * objectstack#11507 direction-4 ruling (2026-08-24): + * direction-4 ruling (2026-08-24, objectstack `88b9d749a`): * * - a type mapped to a feed type renders with THAT presentation; * - a type the table maps to `undefined` is a DELIBERATE exclusion — `null`, diff --git a/packages/plugin-form/src/fieldWriteGate.ts b/packages/plugin-form/src/fieldWriteGate.ts index 50b199b5a0..ad8bb94458 100644 --- a/packages/plugin-form/src/fieldWriteGate.ts +++ b/packages/plugin-form/src/fieldWriteGate.ts @@ -162,7 +162,7 @@ export function applyFieldPermissions>( /** * The principal surface {@link gateFormFields} reads: the field-level resolver * plus the server's effective API operation set for an object (`/me/permissions` - * `apiOperations`, #3391). `undefined` from it means "no effective set", which + * `apiOperations`, objectstack#3391). `undefined` from it means "no effective set", which * leaves the object's own affordance standing. */ export interface FormFieldPrincipal extends FieldWritePrincipal { diff --git a/packages/plugin-form/src/occSave.tsx b/packages/plugin-form/src/occSave.tsx index f0d66a0234..fc90d61f0f 100644 --- a/packages/plugin-form/src/occSave.tsx +++ b/packages/plugin-form/src/occSave.tsx @@ -153,7 +153,7 @@ interface ConflictState { currentVersion?: string; /** * The refusal text the PRODUCER marked as addressed to the end user - * (`userMessage`, objectstack#9934), or `undefined` when the 409 carried no + * (`userMessage`, objectstack `79c46da90`), or `undefined` when the 409 carried no * marking. Read through `declaredUserMessage`, never duck-typed here: the * marking lands in two different places depending on which error the adapter * built (a typed member on `ConcurrentUpdateError`, the details bag on diff --git a/packages/plugin-grid/src/ImportWizard.tsx b/packages/plugin-grid/src/ImportWizard.tsx index e1f7859db3..6618e8ed21 100644 --- a/packages/plugin-grid/src/ImportWizard.tsx +++ b/packages/plugin-grid/src/ImportWizard.tsx @@ -192,7 +192,7 @@ export const IMPORT_DEFAULT_TRANSLATIONS: Record = { // fallback (server `/import` route unavailable) — no server-side coercion. 'grid.import.legacyFallbackNotice': 'Imported via a compatibility fallback: this connection doesn’t support the server import route, so values were saved as text without server-side type coercion. Upgrade the backend/client for full import support (type coercion and relation lookups).', // Shown when the server refuses import with 405 because the object does not - // expose the import operation (#3391) — distinct from "route not found". + // expose the import operation (objectstack#3391) — distinct from "route not found". 'grid.import.notAllowed': 'This object is not open for import.', 'grid.import.requiredMark': '*', }; @@ -640,7 +640,7 @@ function isUnsupportedImportJob(err: unknown): boolean { } /** True when the SERVER refused the import because the object does not expose - * the import operation (405 / `OBJECT_API_METHOD_NOT_ALLOWED`, #3391). + * the import operation (405 / `OBJECT_API_METHOD_NOT_ALLOWED`, objectstack#3391). * * The opposite of {@link isUnsupportedImportJob} (404 = the async-job ROUTE is * absent → fall back to sync) and {@link isUnsupportedImport} (adapter can't @@ -1937,7 +1937,7 @@ export const ImportWizard: React.FC = ({ try { created = await ds.createImportJob(objectName, request); } catch (err) { - // [#3391] A 405 (object not open for import) must NOT fall back to the + // [objectstack#3391] A 405 (object not open for import) must NOT fall back to the // sync route (which 405s too) — rethrow so handleImport surfaces the // dedicated message. Checked BEFORE the 404-based unsupported fallback. if (isImportNotAllowed(err)) throw err; @@ -2029,7 +2029,7 @@ export const ImportWizard: React.FC = ({ const handled = await runAsyncImport(request); if (handled) return; } catch (err) { - // [#3391] Object not open for import (405) → stop with the dedicated + // [objectstack#3391] Object not open for import (405) → stop with the dedicated // message; never fall back to the sync route (it 405s too). if (isImportNotAllowed(err)) { const importResult: ImportResult = { @@ -2077,7 +2077,7 @@ export const ImportWizard: React.FC = ({ setResult(importResult); setImporting(false); onComplete?.(importResult); return; } catch (err) { - // [#3391] Object not open for import (405) → stop with the dedicated + // [objectstack#3391] Object not open for import (405) → stop with the dedicated // message; never fall back to the legacy per-row loop (it 405s too). if (isImportNotAllowed(err)) { const importResult: ImportResult = { @@ -2121,7 +2121,7 @@ export const ImportWizard: React.FC = ({ const res = await serverImport.call(dataSource, objectName, buildImportRequest(true)); setDryRunResult(res); } catch (err) { - // [#3391] Object not open for import (405) → surface the dedicated + // [objectstack#3391] Object not open for import (405) → surface the dedicated // message in the dry-run summary; checked before the /import unsupported // fall-back (which would silently hide the refusal). if (isImportNotAllowed(err)) { diff --git a/packages/plugin-grid/src/ObjectGrid.tsx b/packages/plugin-grid/src/ObjectGrid.tsx index 520a199693..b51be6017f 100644 --- a/packages/plugin-grid/src/ObjectGrid.tsx +++ b/packages/plugin-grid/src/ObjectGrid.tsx @@ -1666,7 +1666,7 @@ export const ObjectGrid: React.FC = ({ */ const objectTypesPending = !!objectName && typeof dataSource?.getObjectSchema === 'function' && !objectFields; - // [#3391] Server-resolved effective API operation set for this object + // [objectstack#3391] Server-resolved effective API operation set for this object // (/me/permissions `apiOperations`). The Export button and handler AND their // gate with this — a missing set (unrestricted object / old backend / no // provider) keeps the current behavior. The frontend consumes the effective @@ -1713,7 +1713,7 @@ export const ObjectGrid: React.FC = ({ // door into the same state that never passes through ListView. Spelling the // gate identically here is what keeps the two from drifting: the object's // resolved affordance — ADR-0103 bucket ∧ `userActions.edit` ∧ the server's - // effective API operations (#3391/#3546), which is what `isObjectInlineEditable` + // effective API operations (objectstack#3391/objectstack#3546), which is what `isObjectInlineEditable` // names — AND the current principal's own grant (#4096). // // Fail-open, like every sibling gate in this file. `can()` answers `true` @@ -3905,7 +3905,7 @@ export const ObjectGrid: React.FC = ({ const handleExport = useCallback((format: ListViewExportFormat) => { // Object-level export permission gate. Default-allow: an explicit // `operations.export === false` blocks it, and — when the server hands down - // an effective API operation set for this object (#3391) — so does its + // an effective API operation set for this object (objectstack#3391) — so does its // exclusion of `export`. Missing effective set keeps current behavior. if (schema.operations?.export === false) return; if (effectiveApiOps && !effectiveApiOps.includes('export')) return; @@ -5905,7 +5905,7 @@ export const ObjectGrid: React.FC = ({ // `__tests__/gridNonAuthorKeys.test.tsx`. const showRowHeightToggle = schema.rowHeight !== undefined && !(schema as any).hideRowHeightToggle; // Export is offered only when configured AND not blocked by object-level perms - // — including the server's effective API operation set (#3391): when present + // — including the server's effective API operation set (objectstack#3391): when present // and it excludes `export`, the button is hidden. Missing set → unchanged. const exportEnabled = !!schema.exportOptions && diff --git a/packages/plugin-kanban/src/ObjectKanban.tsx b/packages/plugin-kanban/src/ObjectKanban.tsx index 2fb0c8a0bd..af7639f655 100644 --- a/packages/plugin-kanban/src/ObjectKanban.tsx +++ b/packages/plugin-kanban/src/ObjectKanban.tsx @@ -1364,7 +1364,7 @@ export const ObjectKanban: React.FC = ({ // Surface the failure — never silently snap the card back. A row-level // security denial (403) is the common case: the user lacks permission // to change this record's status. (cloud#864) - // …unless the AUTHOR opted in. `userMessage` (objectstack#9934) is the + // …unless the AUTHOR opted in. `userMessage` (objectstack `79c46da90`) is the // producer-side marking: a field set at throw time to say "this text is // for the end user". It is a SEPARATE field from `message`, so nothing // unmarked can reach here — the substitution below still governs every diff --git a/packages/plugin-list/src/ListView.tsx b/packages/plugin-list/src/ListView.tsx index b401c18e24..7681e474a9 100644 --- a/packages/plugin-list/src/ListView.tsx +++ b/packages/plugin-list/src/ListView.tsx @@ -1626,7 +1626,7 @@ export const ListView = React.forwardRef(({ // Object-level export permission gate. Default-allow: export stays enabled // unless `allowExport === false` or `operations.export === false`, AND — when // the server hands down an effective API operation set for this object - // (/me/permissions `apiOperations`, #3391) — unless it excludes `export`. + // (/me/permissions `apiOperations`, objectstack#3391) — unless it excludes `export`. // Missing effective set (unrestricted object / old backend / no provider) // keeps the current behavior. The frontend consumes the effective set the // server resolved; it never reads the raw `apiMethods`. @@ -1643,7 +1643,7 @@ export const ListView = React.forwardRef(({ // entry is a WIRING declaration, not a permission grant, so the built-in // `delete` is dropped unless the object's resolved delete affordance allows // it: the ADR-0103 bucket lock ∧ `userActions.delete` ∧ the server's - // effective API operation set (#3391). Custom action ids pass through + // effective API operation set (objectstack#3391). Custom action ids pass through // untouched — they route through the action runner with their own gates. // [#4096] ∧ the CURRENT PRINCIPAL's `allowDelete` — the three layers above // all describe the OBJECT, so without this the most destructive entry on a @@ -1733,7 +1733,7 @@ export const ListView = React.forwardRef(({ * * The gate is `permittedBulkActions`' verbatim, with the operation moved from * `delete` to `update`: the object's resolved affordance — ADR-0103 bucket ∧ - * `userActions.edit` ∧ the server's effective API operations (#3391) — AND + * `userActions.edit` ∧ the server's effective API operations (objectstack#3391) — AND * the CURRENT PRINCIPAL's grant (#4096). The first half is spelled * `isObjectInlineEditable`, which IS * `resolveEffectiveCrudAffordances(...).edit` under the name that says what diff --git a/packages/plugin-tree/src/ObjectTree.tsx b/packages/plugin-tree/src/ObjectTree.tsx index efc3263e4f..20120656e4 100644 --- a/packages/plugin-tree/src/ObjectTree.tsx +++ b/packages/plugin-tree/src/ObjectTree.tsx @@ -1051,7 +1051,7 @@ export const ObjectTree: React.FC = ({ // // ⛔ And this card does NOT rule it. `navigation` is objectui#8652's // family: maintainer-ruled option B — declare on the PLATFORM element - // schemas first, then mirror — blocked on objectstack#17987, whose unlock + // schemas first, then mirror — blocked on objectstack `e233db9db`, whose unlock // criterion is a released `@objectstack/spec` carrying the declaration // being installable here. Measured on the installed spec: `navigation` is // declared on exactly one `ComponentPropsMap` entry, `object-grid`, and diff --git a/packages/providers/src/types.ts b/packages/providers/src/types.ts index 2ca2bad186..f2998f2952 100644 --- a/packages/providers/src/types.ts +++ b/packages/providers/src/types.ts @@ -29,7 +29,7 @@ export interface MetadataProviderProps { * * Derivation history (objectui#5716): this union was born reading the spec's * `ThemeModeSchema` through its `_zod` input carrier. The spec then retired - * its whole theme module (objectstack#10485), objectui assumed ownership of + * its whole theme module (objectstack `35ad101bc`), objectui assumed ownership of * the theme document types, and the mode vocabulary's owner is now * `@object-ui/types` (`ThemeMode`, with the `THEME_MODES` runtime witness) — * so the derivation reads from there. A mode the owner adds still arrives diff --git a/packages/react/src/utils/error-message.ts b/packages/react/src/utils/error-message.ts index 83546b56af..1d199cad26 100644 --- a/packages/react/src/utils/error-message.ts +++ b/packages/react/src/utils/error-message.ts @@ -93,7 +93,7 @@ export function extractWriteErrorMessage(err: unknown): string | null { * The refusal text the PRODUCER explicitly marked as addressed to the end user, * or `null` when the refusal carries no marking. * - * `userMessage` is the opt-in channel added by objectstack#9934 (maintainer + * `userMessage` is the opt-in channel added by objectstack `79c46da90` (maintainer * ruling 2026-08-19 on objectui#5210), declared on `ApiErrorSchema` / * `EnhancedApiErrorSchema` in the pinned `@objectstack/spec`. * Three properties of the contract decide this reader's whole shape: diff --git a/packages/types/src/index.ts b/packages/types/src/index.ts index 524ce3bf71..4bfd99ecfd 100644 --- a/packages/types/src/index.ts +++ b/packages/types/src/index.ts @@ -802,7 +802,7 @@ import type { AppComponentSchema } from './app.js'; export type { // Theme System — the document vocabulary is owned HERE since objectui#5716 // (maintainer ruling 2026-08-23, option A — localize): the spec retired its - // theme module (objectstack#10485) while objectui RETAINED the theme system, + // theme module (objectstack `35ad101bc`) while objectui RETAINED the theme system, // so the types moved into `./theme` with the last-published 17.1.0 shapes as // the blueprint. `Typography` / `BorderRadius` / `Shadow` / // `ThemeDefinition` were DELETED under the same ruling's zero-reader rider diff --git a/packages/types/src/objectql.ts b/packages/types/src/objectql.ts index 4e20532e67..fe860f56e3 100644 --- a/packages/types/src/objectql.ts +++ b/packages/types/src/objectql.ts @@ -69,7 +69,7 @@ export type { ObjectCalendarBlockConfig } from './zod/objectql.zod.js'; * types depending on the entry point — the 7-value enum on `./shared` / `./api` * (which adds `HEAD` / `OPTIONS`) and the 5-value UI subset on `./ui`. 17.0.0 * split them as `HttpMethodType` (objectstack#4691); 17.0.0-rc.5 renamed that - * again to `HttpMethodSubset` (objectstack#5832, PR objectstack#5976), because + * again to `HttpMethodSubset` (objectstack#5832, objectstack `795b6e1aa`), because * `schemaNameFromExportKey` strips the `Schema` suffix and both enums published * as `shared/HttpMethod` — the later write won, so the emitted JSON Schema and * reference page described only the 5-value one. diff --git a/packages/types/src/spec-ui-namespace.ts b/packages/types/src/spec-ui-namespace.ts index 986b3cdc72..a41e085b85 100644 --- a/packages/types/src/spec-ui-namespace.ts +++ b/packages/types/src/spec-ui-namespace.ts @@ -13,7 +13,7 @@ * Existence note (objectui#5716). `index.ts` used to point that namespace * export straight at `@objectstack/spec/ui`, so the namespace tracked * whatever the installed pin publishes — and on the dependency refresh past - * the spec's theme retirement (objectstack#10485), the `UI.Theme`-family + * the spec's theme retirement (objectstack `35ad101bc`), the `UI.Theme`-family * members would have vanished with no error anywhere in this repo. The * objectui#5716 ruling says that silent narrowing must stop for the theme * family. This shim is the mechanism: an explicit re-export beats a star diff --git a/packages/types/src/theme.ts b/packages/types/src/theme.ts index 748abb7a42..007f6d5b2e 100644 --- a/packages/types/src/theme.ts +++ b/packages/types/src/theme.ts @@ -22,7 +22,7 @@ // Theme Document Vocabulary (formerly `@objectstack/spec/ui`) // ============================================================================ // `@objectstack/spec` retired its whole theme module: `ui/theme.zod.ts` went -// in objectstack#10485 (PR objectstack#10695), and the objectstack#10856 +// in objectstack `35ad101bc`, and the objectstack#10856 // ruling had objectui drop the dangling VALUE re-exports (objectui#5710). // This block is the TYPE half. The maintainer ruling on objectui#5716 // (2026-08-23, option A — localize) makes objectui the owner of the theme @@ -206,8 +206,8 @@ export interface Theme { // ============================================================================ // `ThemeComponentSchema` (`type: 'theme'`) RETIRED in `78cbdb530`, under the -// maintainer ruling of 2026-08-21 on objectstack#10485 (option B, quoted -// verbatim and untranslated): +// maintainer ruling of 2026-08-21 (option B, executed upstream by objectstack +// `35ad101bc`; quoted verbatim and untranslated): // // 「B:退役授权面 —— 收掉 `themes` 载体键与 schema,`app.branding` 留作唯一颜色面; // objectui 引擎代码与单测保留」 diff --git a/packages/types/src/zod/base.zod.ts b/packages/types/src/zod/base.zod.ts index 407fa98702..fe6c4371c2 100644 --- a/packages/types/src/zod/base.zod.ts +++ b/packages/types/src/zod/base.zod.ts @@ -801,7 +801,7 @@ export const HTMLAttributesSchema = z.record(z.string(), z.any()).describe('HTML * exempts index signatures by design ("no keys to compare"). This note, not a * gate, is what records the absence. * - * Precedent of the same shape: objectstack#12009 / objectstack `89448a52b`. + * Precedent of the same shape: objectstack `89448a52b`. */ /** diff --git a/packages/types/src/zod/index.zod.ts b/packages/types/src/zod/index.zod.ts index bdd57555a9..f4c224d606 100644 --- a/packages/types/src/zod/index.zod.ts +++ b/packages/types/src/zod/index.zod.ts @@ -351,8 +351,8 @@ export { // tombstone for the retired theme component-kind surface: // - `ColorPaletteSchema` / `TypographySchema` / `BorderRadiusSchema` / // `ShadowSchema` / `ThemeModeSchema` / `ThemeDefinitionSchema` RETIRED with -// the spec's whole `ui/theme.zod.ts` module (objectstack#10485, PR -// objectstack#10695; removal ruled on objectstack#10856, executed as +// the spec's whole `ui/theme.zod.ts` module (objectstack `35ad101bc`; +// removal ruled on objectstack#10856, executed as // objectui#5710). // - `ThemeComponentSchema` RETIRED in `78cbdb530`. // - `ThemeSwitcherSchema` / `ThemePreviewSchema` / `ThemeUnionSchema` RETIRED diff --git a/packages/types/src/zod/theme.zod.ts b/packages/types/src/zod/theme.zod.ts index 2fc25ec04b..bfe2999788 100644 --- a/packages/types/src/zod/theme.zod.ts +++ b/packages/types/src/zod/theme.zod.ts @@ -18,8 +18,8 @@ * - The six `@objectstack/spec/ui` theme-schema re-exports * (`ColorPaletteSchema`, `TypographySchema`, `BorderRadiusSchema`, * `ShadowSchema`, `ThemeModeSchema`, `ThemeDefinitionSchema` — the spec's - * `ThemeSchema`): objectstack#10485 (ADR-0049 enforce-or-remove, PR - * objectstack#10695) deleted the spec's whole `ui/theme.zod.ts` module — + * `ThemeSchema`): objectstack `35ad101bc` (ADR-0049 enforce-or-remove) + * deleted the spec's whole `ui/theme.zod.ts` module — * values AND types, `AnimationSchema`/`ZIndexSchema` having gone earlier in * 17.0.0-rc.3 (objectstack#5021) — and the maintainer's ruling on * objectstack#10856 (2026-08-22, Options A + C) had objectui REMOVE these @@ -27,8 +27,8 @@ * (Option B) was explicitly not taken. * * - The theme COMPONENT kinds: `ThemeComponentSchema` (`type: 'theme'`) - * RETIRED in `78cbdb530` under the 2026-08-21 maintainer ruling on - * objectstack#10485 (option B); then `ThemeSwitcherSchema` + * RETIRED in `78cbdb530` under the 2026-08-21 maintainer ruling + * (option B, executed upstream by objectstack `35ad101bc`); then `ThemeSwitcherSchema` * (`type: 'theme-switcher'`), `ThemePreviewSchema` (`type: 'theme-preview'`) * and `ThemeUnionSchema` — which after `78cbdb530` held only those two * members — RETIRED in objectui#5647, by inheritance of the same ruling on