From c292a64004ab1fdbc6f2bd89cfa4340c8cda863b Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 28 Sep 2026 10:21:36 +0000 Subject: [PATCH] docs(citations): re-point the dead objectstack#N citations and the bare apiMethods-card number (objectui#10803, batch 7) The 30 objectstack issue and pull-request numbers that answer 404 in the card's two classes (pending changeset prose and non-test packages/*/src) now cite the objectstack commit that landed each change, or drop the dead number where the sentence already names the live pull request or commit, or dates the ruling it points at. One sentence cites this repository's own landing commit. The 28 comment lines that wrote the apiMethods whitelist card as a bare number now read objectstack#3391 (and objectstack#3546 on the two lines that pair it). Two console warnings in @object-ui/app-shell and @object-ui/plugin-detail lose the dead pointer and nothing else (patch changeset); every other edit is comment or changeset prose, and every edited changeset keeps its frontmatter byte-identical. Co-Authored-By: Claude Claude-Session: https://claude.ai/code/session_01DuWo5bdP9SdVebamn99GGk --- .../10061-filter-builder-incomplete-range.md | 2 +- .../10062-dataset-filter-between-arm.md | 2 +- ...10803-dead-citation-sweep-seventh-batch.md | 23 +++++++++++++++++++ .../10803-seventh-batch-runtime-strings.md | 17 ++++++++++++++ .../17147-plugin-disclosure-not-enforced.md | 4 ++-- .../3719-settings-valuedomain-combobox.md | 2 +- .../5896-feeditem-single-constructor.md | 2 +- .changeset/5987-permset-clone-to-customize.md | 2 +- .../6654-retire-preview-mode-consumption.md | 2 +- .../6730-shared-activity-type-bucket.md | 2 +- .../6748-preview-mode-provenance-ratchet.md | 2 +- ...7-global-search-notifications-renderers.md | 2 +- .../7015-text-expression-content-channel.md | 2 +- ...979-package-form-dialog-envelope-reader.md | 2 +- ...137-record-activity-calibration-repoint.md | 4 ++-- .../console-form-marked-refusal-5210.md | 2 +- .../designer-publish-package-binding.md | 2 +- ...ormalise-client-error-user-message-5901.md | 2 +- ...ecord-activity-open-vocabulary-fallback.md | 2 +- .../retire-theme-component-schema-5489.md | 4 ++-- .../retire-theme-switcher-preview-5647.md | 2 +- .changeset/spec-refresh-17-2-0-5668.md | 2 +- .../theme-clientvalidation-dead-entry-5715.md | 2 +- .changeset/theme-types-localized-5716.md | 2 +- .../theme-zod-retired-spec-reexports.md | 2 +- .../view-overlay-write-patch-only-5233.md | 2 +- .../src/chrome/ConditionalAuthWrapper.tsx | 2 +- .../console/marketplace/PluginDisclosure.tsx | 2 +- .../app-shell/src/layout/ActivityFeed.tsx | 2 +- .../app-shell/src/layout/activityItemType.ts | 4 ++-- .../app-shell/src/services/MetadataService.ts | 2 +- .../app-shell/src/views/ActionParamDialog.tsx | 3 ++- .../app-shell/src/views/ObjectDataPage.tsx | 6 ++--- packages/app-shell/src/views/ObjectView.tsx | 6 ++--- .../app-shell/src/views/RecordDetailView.tsx | 2 +- .../metadata-admin/PermissionMatrixEditor.tsx | 2 +- .../views/metadata-admin/ResourceEditPage.tsx | 4 ++-- .../src/views/metadata-admin/SchemaForm.tsx | 2 +- .../views/metadata-admin/clientValidation.ts | 2 +- .../src/views/metadata-admin/form-spec.ts | 2 +- .../src/views/metadata-admin/i18n.ts | 4 ++-- .../permission-set-clone-dispatch.ts | 4 ++-- .../components/src/custom/filter-builder.tsx | 2 +- .../components/src/renderers/form/form.tsx | 2 +- .../src/renderers/layout/containers.tsx | 2 +- packages/core/src/actions/ActionRunner.ts | 9 ++++---- packages/core/src/utils/filter-tokens.ts | 2 +- packages/core/src/utils/managedBy.ts | 10 ++++---- packages/data-objectstack/src/index.ts | 6 ++--- .../data-objectstack/src/metadata-client.ts | 2 +- packages/i18n/src/useObjectLabel.ts | 4 ++-- .../permissions/src/MePermissionsProvider.tsx | 4 ++-- packages/permissions/src/PermissionContext.ts | 2 +- .../permissions/src/PermissionProvider.tsx | 2 +- .../plugin-calendar/src/ObjectCalendar.tsx | 6 ++--- .../src/MetadataFieldsPage.tsx | 2 +- packages/plugin-detail/src/index.tsx | 2 +- .../src/renderers/recordActivityFeed.ts | 8 +++---- packages/plugin-form/src/fieldWriteGate.ts | 2 +- packages/plugin-form/src/occSave.tsx | 2 +- packages/plugin-grid/src/ImportWizard.tsx | 12 +++++----- packages/plugin-grid/src/ObjectGrid.tsx | 8 +++---- packages/plugin-kanban/src/ObjectKanban.tsx | 2 +- packages/plugin-list/src/ListView.tsx | 6 ++--- packages/plugin-tree/src/ObjectTree.tsx | 2 +- packages/providers/src/types.ts | 2 +- packages/react/src/utils/error-message.ts | 2 +- packages/types/src/index.ts | 2 +- packages/types/src/objectql.ts | 2 +- packages/types/src/spec-ui-namespace.ts | 2 +- packages/types/src/theme.ts | 6 ++--- packages/types/src/zod/base.zod.ts | 2 +- packages/types/src/zod/index.zod.ts | 4 ++-- packages/types/src/zod/theme.zod.ts | 8 +++---- 74 files changed, 157 insertions(+), 115 deletions(-) create mode 100644 .changeset/10803-dead-citation-sweep-seventh-batch.md create mode 100644 .changeset/10803-seventh-batch-runtime-strings.md 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