From c386d3af4d3c5c7fc7b67c653bede215439d40e1 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 24 Oct 2026 12:04:08 +0000 Subject: [PATCH 1/5] chore: bump objectstack to e649c2d91e27 chore: version packages (#25606) objectstack@e649c2d91e270e3da26820bcfe54a28445305a75 Moves the pin to the objectstack 18.1.0 release commit (objectui#13440). Claude-Session: https://claude.ai/code/session_01CErMSwkRLW7c7jk23MHfVP Co-authored-by: Claude --- .objectstack-pin/client/package.json | 30 +++++++++++------------ .objectstack-pin/core/package.json | 8 +++--- .objectstack-pin/formula/package.json | 4 +-- .objectstack-pin/lint/package.json | 8 +++--- .objectstack-pin/sdui-parser/package.json | 2 +- .objectstack-pin/spec/package.json | 2 +- .objectstack-pin/types/package.json | 4 +-- .objectstack-sha | 2 +- 8 files changed, 30 insertions(+), 30 deletions(-) diff --git a/.objectstack-pin/client/package.json b/.objectstack-pin/client/package.json index 907a1d12e3..ea23cc5e51 100644 --- a/.objectstack-pin/client/package.json +++ b/.objectstack-pin/client/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/client", - "version": "18.0.0", + "version": "18.1.0", "license": "Apache-2.0", "description": "Official Client SDK for ObjectStack Protocol", "main": "dist/index.js", @@ -13,23 +13,23 @@ } }, "dependencies": { - "@objectstack/core": "18.0.0", - "@objectstack/spec": "18.0.0" + "@objectstack/core": "18.1.0", + "@objectstack/spec": "18.1.0" }, "devDependencies": { "@hono/node-server": "^2.1.1", - "@objectstack/driver-sqlite-wasm": "18.0.0", - "@objectstack/hono": "18.0.0", - "@objectstack/metadata-core": "18.0.0", - "@objectstack/metadata-protocol": "18.0.0", - "@objectstack/objectql": "18.0.0", - "@objectstack/platform-objects": "18.0.0", - "@objectstack/plugin-auth": "18.0.0", - "@objectstack/plugin-hono-server": "18.0.0", - "@objectstack/rest": "18.0.0", - "@objectstack/runtime": "18.0.0", - "@objectstack/service-analytics": "18.0.0", - "@objectstack/service-automation": "18.0.0", + "@objectstack/driver-sqlite-wasm": "18.1.0", + "@objectstack/hono": "18.1.0", + "@objectstack/metadata-core": "18.1.0", + "@objectstack/metadata-protocol": "18.1.0", + "@objectstack/objectql": "18.1.0", + "@objectstack/platform-objects": "18.1.0", + "@objectstack/plugin-auth": "18.1.0", + "@objectstack/plugin-hono-server": "18.1.0", + "@objectstack/rest": "18.1.0", + "@objectstack/runtime": "18.1.0", + "@objectstack/service-analytics": "18.1.0", + "@objectstack/service-automation": "18.1.0", "tsx": "^4.23.15", "typescript": "^6.0.3", "vitest": "^4.1.11" diff --git a/.objectstack-pin/core/package.json b/.objectstack-pin/core/package.json index 16f1f68b36..40d33a91e5 100644 --- a/.objectstack-pin/core/package.json +++ b/.objectstack-pin/core/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/core", - "version": "18.0.0", + "version": "18.1.0", "license": "Apache-2.0", "description": "Microkernel Core for ObjectStack", "type": "module", @@ -19,7 +19,7 @@ } }, "devDependencies": { - "@objectstack/metadata-core": "18.0.0", + "@objectstack/metadata-core": "18.1.0", "@objectstack/refd-timer-testkit": "0.1.0", "@types/node": "^26.6.3", "esbuild": "^0.28.2", @@ -27,8 +27,8 @@ "vitest": "^4.1.11" }, "dependencies": { - "@objectstack/spec": "18.0.0", - "@objectstack/types": "18.0.0", + "@objectstack/spec": "18.1.0", + "@objectstack/types": "18.1.0", "zod": "^4.6.5" }, "keywords": [ diff --git a/.objectstack-pin/formula/package.json b/.objectstack-pin/formula/package.json index 5cdf868cf2..4e6d937e89 100644 --- a/.objectstack-pin/formula/package.json +++ b/.objectstack-pin/formula/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/formula", - "version": "18.0.0", + "version": "18.1.0", "license": "Apache-2.0", "description": "ObjectStack canonical expression engine — CEL (cel-js) + ObjectStack stdlib + dialect registry", "main": "dist/index.js", @@ -14,7 +14,7 @@ }, "dependencies": { "@marcbachmann/cel-js": "^8.0.0", - "@objectstack/spec": "18.0.0" + "@objectstack/spec": "18.1.0" }, "devDependencies": { "@types/node": "^26.6.3", diff --git a/.objectstack-pin/lint/package.json b/.objectstack-pin/lint/package.json index 8817e51fcc..618731e343 100644 --- a/.objectstack-pin/lint/package.json +++ b/.objectstack-pin/lint/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/lint", - "version": "18.0.0", + "version": "18.1.0", "license": "Apache-2.0", "description": "Static, build-time validation for an ObjectStack metadata graph — dashboard widget bindings, CEL/predicate expressions, and more. Pure (stack) => Issue[] functions shared by the CLI's `os validate` and any other consumer (e.g. AI authoring). Depends on @objectstack/spec; never on a runtime.", "type": "module", @@ -39,9 +39,9 @@ } }, "dependencies": { - "@objectstack/formula": "18.0.0", - "@objectstack/sdui-parser": "18.0.0", - "@objectstack/spec": "18.0.0", + "@objectstack/formula": "18.1.0", + "@objectstack/sdui-parser": "18.1.0", + "@objectstack/spec": "18.1.0", "ajv": "^8.20.0", "ajv-formats": "^3.0.1", "sucrase": "^3.35.1", diff --git a/.objectstack-pin/sdui-parser/package.json b/.objectstack-pin/sdui-parser/package.json index 8478df2cb8..f869e0f2c3 100644 --- a/.objectstack-pin/sdui-parser/package.json +++ b/.objectstack-pin/sdui-parser/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/sdui-parser", - "version": "18.0.0", + "version": "18.1.0", "license": "Apache-2.0", "description": "ObjectStack constrained JSX-source → SDUI SchemaNode tree compiler (parse, never execute). Isomorphic, zero React. ADR-0080.", "main": "dist/index.js", diff --git a/.objectstack-pin/spec/package.json b/.objectstack-pin/spec/package.json index 4022d03c77..ba0c88a668 100644 --- a/.objectstack-pin/spec/package.json +++ b/.objectstack-pin/spec/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/spec", - "version": "18.0.0", + "version": "18.1.0", "description": "ObjectStack Protocol & Specification - TypeScript Interfaces, JSON Schemas, and Convention Configurations", "license": "Apache-2.0", "main": "dist/index.js", diff --git a/.objectstack-pin/types/package.json b/.objectstack-pin/types/package.json index 213249a055..52e7bd5417 100644 --- a/.objectstack-pin/types/package.json +++ b/.objectstack-pin/types/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/types", - "version": "18.0.0", + "version": "18.1.0", "license": "Apache-2.0", "description": "Shared interfaces describing the ObjectStack Runtime environment", "main": "dist/index.js", @@ -18,7 +18,7 @@ } }, "dependencies": { - "@objectstack/spec": "18.0.0" + "@objectstack/spec": "18.1.0" }, "devDependencies": { "typescript": "^6.0.3", diff --git a/.objectstack-sha b/.objectstack-sha index d13b4eef21..406c7555ce 100644 --- a/.objectstack-sha +++ b/.objectstack-sha @@ -1 +1 @@ -915e9404992234a7cd0d2dd4701dfbadbe9cb2c7 +e649c2d91e270e3da26820bcfe54a28445305a75 From 36a198078fd7244e9091098166a8f2d6f89e4b41 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 24 Oct 2026 12:08:27 +0000 Subject: [PATCH 2/5] refactor(auth): take ORG_ROLE_EXTERNAL from @objectstack/spec now the pin carries it (objectui#13440) The pin now names objectstack 18.1.0, whose spec exports MEMBERSHIP_ROLE_EXTERNAL and lists `external` in BUILTIN_MEMBERSHIP_ROLES. This is the swap the org-roles tripwire prescribed: - org-roles.ts re-exports MEMBERSHIP_ROLE_EXTERNAL as ORG_ROLE_EXTERNAL (same name, same value 'external') instead of spelling the literal, and ORG_ROLE_LABELS is typed Record again. - The tripwire test is deleted, with its now unused spec namespace import. - InviteMemberDialog.roleCap and org-i18n-holdouts-4474 expect external in the invite dialog's role list, as objectui#13427 announced for a spec that lists the role. Claude-Session: https://claude.ai/code/session_01CErMSwkRLW7c7jk23MHfVP Co-authored-by: Claude --- .../InviteMemberDialog.roleCap.test.tsx | 8 ++-- .../__tests__/org-i18n-holdouts-4474.test.tsx | 4 +- packages/auth/src/__tests__/org-roles.test.ts | 14 ------- packages/auth/src/org-roles.ts | 41 ++++++++----------- 4 files changed, 22 insertions(+), 45 deletions(-) diff --git a/packages/app-shell/src/console/organizations/__tests__/InviteMemberDialog.roleCap.test.tsx b/packages/app-shell/src/console/organizations/__tests__/InviteMemberDialog.roleCap.test.tsx index c3219fdb69..a5bb074b57 100644 --- a/packages/app-shell/src/console/organizations/__tests__/InviteMemberDialog.roleCap.test.tsx +++ b/packages/app-shell/src/console/organizations/__tests__/InviteMemberDialog.roleCap.test.tsx @@ -102,7 +102,7 @@ beforeEach(() => { describe('InviteMemberDialog — role cap (framework#3697)', () => { it('an owner is offered every role, delegated_admin included', async () => { await renderAs('owner'); - expect(offered()).toEqual(['owner', 'admin', 'delegated_admin', 'member']); + expect(offered()).toEqual(['owner', 'admin', 'delegated_admin', 'member', 'external']); }); it('an admin may provision a delegate but may not invite an owner', async () => { @@ -112,18 +112,18 @@ describe('InviteMemberDialog — role cap (framework#3697)', () => { expect(roles).not.toContain('owner'); }); - it('a DELEGATE is offered member only — the escalation chain has no UI entry', async () => { + it('a DELEGATE is offered member and external only — the escalation chain has no UI entry', async () => { // Picking "Admin" here would 403 on the server's role cap; the console must // not propose it. This is the whole reason the select stopped being a // hardcoded three-item list. await renderAs('delegated_admin'); - expect(offered()).toEqual(['member']); + expect(offered()).toEqual(['member', 'external']); expect(screen.queryByTestId('invite-role-admin')).not.toBeInTheDocument(); }); it('an unloaded membership still allows the ordinary member invite', async () => { await renderAs(null); - expect(offered()).toEqual(['member']); + expect(offered()).toEqual(['member', 'external']); }); it('the narrowed default still submits a plain, unchanged invitation', async () => { diff --git a/packages/app-shell/src/console/organizations/__tests__/org-i18n-holdouts-4474.test.tsx b/packages/app-shell/src/console/organizations/__tests__/org-i18n-holdouts-4474.test.tsx index fafc7d18e7..96dcd6a508 100644 --- a/packages/app-shell/src/console/organizations/__tests__/org-i18n-holdouts-4474.test.tsx +++ b/packages/app-shell/src/console/organizations/__tests__/org-i18n-holdouts-4474.test.tsx @@ -254,7 +254,7 @@ describe('#4474 family 1 — role names come from ONE map and resolve in zh', () .filter((o) => o.getAttribute('value')) .map((o) => o.textContent); // Pre-fix this array was ['Owner', 'Admin', 'Delegated Admin', 'Member']. - expect(labels).toEqual(['所有者', '管理员', '受托管理员', '成员']); + expect(labels).toEqual(['所有者', '管理员', '受托管理员', '成员', '外部成员']); }); it('zh: the members page role badges render Chinese — site 2', async () => { @@ -301,7 +301,7 @@ describe('#4474 family 1 — role names come from ONE map and resolve in zh', () const labels = Array.from(screen.getByTestId('select').querySelectorAll('option')) .filter((o) => o.getAttribute('value')) .map((o) => o.textContent); - expect(labels).toEqual(['Owner', 'Admin', 'Delegated Admin', 'Member']); + expect(labels).toEqual(['Owner', 'Admin', 'Delegated Admin', 'Member', 'External']); }); it('an external member\'s badge reads 外部成员 in zh and External in en (objectui#13427)', async () => { diff --git a/packages/auth/src/__tests__/org-roles.test.ts b/packages/auth/src/__tests__/org-roles.test.ts index fd1cb31a32..edf23aa702 100644 --- a/packages/auth/src/__tests__/org-roles.test.ts +++ b/packages/auth/src/__tests__/org-roles.test.ts @@ -20,7 +20,6 @@ */ import { describe, it, expect } from 'vitest'; -import * as spec from '@objectstack/spec'; import { INVITATION_ROLE_ANY_ISSUER, INVITATION_ROLE_GRANTORS } from '@objectstack/spec/identity'; import { ORG_ROLES, @@ -72,19 +71,6 @@ describe('vocabulary', () => { defaultValue: 'External', }); }); - - it('spells external itself only while the pin predates objectstack#25515', () => { - // [tripwire] `org-roles.ts` spells the role because `.objectstack-sha` - // names a spec without it. The pin move that brings #25515 turns this red, - // which is the reminder to swap the literal for the spec's constant. - expect( - (spec as Record).MEMBERSHIP_ROLE_EXTERNAL, - 'the pin now carries objectstack#25515: in org-roles.ts import MEMBERSHIP_ROLE_EXTERNAL as ' + - 'ORG_ROLE_EXTERNAL instead of the literal and drop `| typeof ORG_ROLE_EXTERNAL` from ' + - 'ORG_ROLE_LABELS; then add external to the role lists InviteMemberDialog.roleCap.test.tsx ' + - 'and org-i18n-holdouts-4474.test.tsx expect, and delete this test', - ).toBeUndefined(); - }); }); describe('orgRoleGrade', () => { diff --git a/packages/auth/src/org-roles.ts b/packages/auth/src/org-roles.ts index 3a13a007f2..2df8433b57 100644 --- a/packages/auth/src/org-roles.ts +++ b/packages/auth/src/org-roles.ts @@ -47,6 +47,7 @@ import { MEMBERSHIP_ROLE_ADMIN as ORG_ROLE_ADMIN, MEMBERSHIP_ROLE_DELEGATED_ADMIN as ORG_ROLE_DELEGATED_ADMIN, MEMBERSHIP_ROLE_MEMBER as ORG_ROLE_MEMBER, + MEMBERSHIP_ROLE_EXTERNAL as ORG_ROLE_EXTERNAL, type BuiltinMembershipRole, } from '@objectstack/spec'; @@ -56,27 +57,20 @@ import { // admin, and carries no authority of its own — what a delegate may actually // *place* comes from a separately-granted `adminScope`, surfaced to this // console by `describeDelegableScope()`. -export { ORG_ROLE_OWNER, ORG_ROLE_ADMIN, ORG_ROLE_DELEGATED_ADMIN, ORG_ROLE_MEMBER }; - -/** - * The external population's grade (objectstack#25233, ruling of record - * 6355206139, letter B): portal users admitted through the organization - * invite, who reach less than a `member` — no organization endpoint, no member - * directory, data only through explicit grants. It is exclusive (the server - * refuses it beside any other role) and never placed in a business unit. - * - * ⚠️ SPELLED HERE, not imported, for now. `@objectstack/spec` exports it as - * `MEMBERSHIP_ROLE_EXTERNAL` since objectstack#25515, and this console must - * compile against that spec (objectstack builds it at its own `main`). But - * this repo's pin, `.objectstack-sha`, still names a commit from before - * #25515, held there until objectstack#25251's spec PR lands (its two PRs ship - * in one objectstack release). So the console has to compile against both - * vocabularies: the literal here, and `OrgRole | typeof ORG_ROLE_EXTERNAL` - * below, which is `OrgRole` itself once the pin carries #25515. When the pin - * moves past #25515, import the constant like the four above and drop the - * union: `org-roles.test.ts` goes red on that move and says so. - */ -export const ORG_ROLE_EXTERNAL = 'external'; +// +// `ORG_ROLE_EXTERNAL` is the external population's grade (objectstack#25233, +// ruling of record 6355206139, letter B): portal users admitted through the +// organization invite, who reach less than a `member` — no organization +// endpoint, no member directory, data only through explicit grants. It is +// exclusive (the server refuses it beside any other role) and never placed in +// a business unit. +export { + ORG_ROLE_OWNER, + ORG_ROLE_ADMIN, + ORG_ROLE_DELEGATED_ADMIN, + ORG_ROLE_MEMBER, + ORG_ROLE_EXTERNAL, +}; export type OrgRole = BuiltinMembershipRole; @@ -84,10 +78,7 @@ export type OrgRole = BuiltinMembershipRole; export const ORG_ROLES: readonly OrgRole[] = [...BUILTIN_MEMBERSHIP_ROLES]; /** i18n key + English fallback for a role, so every screen labels it identically. */ -export const ORG_ROLE_LABELS: Record< - OrgRole | typeof ORG_ROLE_EXTERNAL, - { key: string; defaultValue: string } -> = { +export const ORG_ROLE_LABELS: Record = { [ORG_ROLE_OWNER]: { key: 'organization.roles.owner', defaultValue: 'Owner' }, [ORG_ROLE_ADMIN]: { key: 'organization.roles.admin', defaultValue: 'Admin' }, [ORG_ROLE_DELEGATED_ADMIN]: { From 5a75ed3b187e5e38c3f4779dec6304e49256c91b Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 24 Oct 2026 12:14:48 +0000 Subject: [PATCH 3/5] chore: restamp the installed-spec claims and the live-e2e backend at 18.1.0 (objectui#13440) The pin's packed manifests now say 18.1.0, so check:installed-pin-claims (blocking through scripts/__tests__/check-installed-spec-pin-claims.test.ts) flagged 34 present-tense "installed 18.0.0" stamps in 24 files, and ci-cd-pipeline-doc.test.ts flagged e2e/live/ci/backend.env. Re-measured before restamping: between 915e9404 and e649c2d91e the spec source moves only automation/flow.zod.ts (the runAs description), data/object.zod.ts (membershipKeys), identity/*, kernel/execution-context, security/explain and rls, stack.zod.ts and one semantic migration entry. No claim's subject is among them (ui/*, data/field, FieldSchema options, flow node config, ComponentPropsMap rows), and packages/lint's validate-expressions.ts and the trigger packages' sources are unchanged. Each stamp moves 18.0.0 -> 18.1.0; a stamp carrying its re-measure list gains objectui#13440. OBJECTSTACK_VERSION moves to 18.1.0, whose @objectstack/cli tag peels to the pin commit e649c2d91e. Claude-Session: https://claude.ai/code/session_01CErMSwkRLW7c7jk23MHfVP Co-authored-by: Claude --- .../src/__tests__/registry-inputs-spec-parity.test.ts | 6 +++--- e2e/live/ci/backend.env | 2 +- packages/app-shell/src/views/metadata-admin/celAuthoring.ts | 2 +- .../inspectors/FlowNodeInspector.declaredDefault.test.tsx | 2 +- .../inspectors/flow-node-config.startGates-12780.test.ts | 2 +- .../inspectors/flowSingleBrace-12329.test.tsx | 2 +- .../previews/flow-canvas-seeds.saveErrors-10948.test.tsx | 2 +- packages/core/src/evaluator/optionRules.ts | 2 +- packages/plugin-calendar/src/ObjectCalendar.tsx | 2 +- .../src/__tests__/calendarUnionReads-8651.test.tsx | 2 +- packages/plugin-designer/src/MetadataFieldsPage.tsx | 2 +- packages/plugin-detail/src/index.tsx | 4 ++-- .../src/__tests__/formSectionGroupReference-7051.test.tsx | 2 +- .../src/__tests__/masterDetailDetailsMembers-8071.test.tsx | 2 +- packages/plugin-gantt/src/readme-navigation-example.test.ts | 2 +- packages/plugin-kanban/src/index.tsx | 2 +- .../src/__tests__/chartconfig-aria-retired-4044.test.ts | 2 +- .../__tests__/dashboard-aria-retired-contract-twins.test.ts | 4 ++-- .../src/__tests__/object-view-unmirrored-keys-7779.test.ts | 2 +- .../src/__tests__/record-details-top-level-9040.test.ts | 2 +- .../src/__tests__/spec-object-refinements-7715.test.ts | 4 ++-- packages/types/src/field-types.ts | 6 +++--- packages/types/src/objectql.ts | 2 +- packages/types/src/record-components.ts | 6 +++--- packages/types/src/zod/objectql.zod.ts | 4 ++-- 25 files changed, 35 insertions(+), 35 deletions(-) diff --git a/apps/console/src/__tests__/registry-inputs-spec-parity.test.ts b/apps/console/src/__tests__/registry-inputs-spec-parity.test.ts index fc5d077a0d..3389542e94 100644 --- a/apps/console/src/__tests__/registry-inputs-spec-parity.test.ts +++ b/apps/console/src/__tests__/registry-inputs-spec-parity.test.ts @@ -3180,11 +3180,11 @@ const MEMBER_PINS: Record = { }, 'object-grid.data': { file: 'packages/plugin-grid/src/__tests__/gridDataInputContract.test.ts', - pins: 'The `object` arm is `ViewDataSchema` discriminated on `provider`: each of the three providers parses and the retired `api` one is refused (spec 18.0.0, objectui#12370, objectui#12971, objectui#13261), none of them is an array, the declaration is one shape across both registered tags so the alias cannot drift, and it is pinned at compile time too (objectui#5090).', + pins: 'The `object` arm is `ViewDataSchema` discriminated on `provider`: each of the three providers parses and the retired `api` one is refused (spec 18.1.0, objectui#12370, objectui#12971, objectui#13261, objectui#13440), none of them is an array, the declaration is one shape across both registered tags so the alias cannot drift, and it is pinned at compile time too (objectui#5090).', }, 'object-grid.conditionalFormatting': { file: 'packages/plugin-grid/src/__tests__/gridRowDecorationMembers-8071.test.tsx', - pins: 'The members read inside ONE formatting rule, asserted on the `style` attribute of the `` the grid paints. THREE alternative predicate members with a PRECEDENCE between them — one rule carrying `condition`, `expression` and the native `field`/`operator`/`value` triple, each naming a DIFFERENT row, is decided by `condition`; drop it and `expression` decides; drop that and the triple does — so a renderer reading any two of them as equivalent is red in a specific direction rather than merely unpinned. FOUR style members, and the sharp one is a RENAME: `backgroundColor` and `borderColor` keep their authored names on the way to the DOM while `textColor` is read as the CSS `color`, so keeping the authored spelling hands React a key it silently drops — same rules, same background, the text colour gone with nothing thrown. `style` is pinned as the BASE the three colour members override rather than replace (a non-colour member of it survives alongside the override). Two rule-list facts complete it: FIRST-MATCH-WINS with no merge (the second matching rule\'s own `textColor` never lands) and a rule carrying NO predicate member is SKIPPED rather than read as always-true, with the rule after it still deciding. ⚠️ Since objectui#11533 the AUTHORED member is ONE dialect, `{ condition, style }`: `expression`, the native triple and the three top-level colour members are refused by name on `ObjectGridSchema` and the list view (`packages/types/src/__tests__/grid-list-view-conditional-formatting-11533.test.ts`), so the rows that write them pin STORED-rule reads, which the resolver keeps as compatibility arms; a last block pins the two facts side by side — the stored native rule refused at authoring and painted at render, with its respelling painting the same row. The registration is an `array` arm; the installed spec row (18.0.0, re-measured by objectui#12030, objectui#12370, objectui#12626, objectui#12873, objectui#12971, objectui#13261) takes the list view\'s own `{ condition, style }` rule and refuses the native members and any other key, so the spec fixes the AUTHORED shape and the read site is the rest of the member contract, the stored-rule compatibility arms included (objectui#8071 slice 12).', + pins: 'The members read inside ONE formatting rule, asserted on the `style` attribute of the `` the grid paints. THREE alternative predicate members with a PRECEDENCE between them — one rule carrying `condition`, `expression` and the native `field`/`operator`/`value` triple, each naming a DIFFERENT row, is decided by `condition`; drop it and `expression` decides; drop that and the triple does — so a renderer reading any two of them as equivalent is red in a specific direction rather than merely unpinned. FOUR style members, and the sharp one is a RENAME: `backgroundColor` and `borderColor` keep their authored names on the way to the DOM while `textColor` is read as the CSS `color`, so keeping the authored spelling hands React a key it silently drops — same rules, same background, the text colour gone with nothing thrown. `style` is pinned as the BASE the three colour members override rather than replace (a non-colour member of it survives alongside the override). Two rule-list facts complete it: FIRST-MATCH-WINS with no merge (the second matching rule\'s own `textColor` never lands) and a rule carrying NO predicate member is SKIPPED rather than read as always-true, with the rule after it still deciding. ⚠️ Since objectui#11533 the AUTHORED member is ONE dialect, `{ condition, style }`: `expression`, the native triple and the three top-level colour members are refused by name on `ObjectGridSchema` and the list view (`packages/types/src/__tests__/grid-list-view-conditional-formatting-11533.test.ts`), so the rows that write them pin STORED-rule reads, which the resolver keeps as compatibility arms; a last block pins the two facts side by side — the stored native rule refused at authoring and painted at render, with its respelling painting the same row. The registration is an `array` arm; the installed spec row (18.1.0, re-measured by objectui#12030, objectui#12370, objectui#12626, objectui#12873, objectui#12971, objectui#13261, objectui#13440) takes the list view\'s own `{ condition, style }` rule and refuses the native members and any other key, so the spec fixes the AUTHORED shape and the read site is the rest of the member contract, the stored-rule compatibility arms included (objectui#8071 slice 12).', }, 'object-grid.operations': { file: 'packages/plugin-grid/src/__tests__/gridOperationsMembers-8071.test.tsx', @@ -3260,7 +3260,7 @@ const MEMBER_PINS: Record = { }, 'object-kanban.conditionalFormatting': { file: 'packages/plugin-kanban/src/__tests__/ObjectKanban.structuredMembersReachTheirSinks-8313.test.tsx', - pins: 'Members are card STYLE RULES in ONE dialect since objectui#11522, the spec list view\'s `{ condition, style }`, and it reaches the sink: a rule colours the matching card and only it, a second rule aimed at the other card does the same, and the whole `style` map arrives, with the sibling card in the same render as the live non-matching control so a green cannot come from two unstyled cards agreeing. The retired native `{ field, operator, value }` and flat-colour dialects are refused by name on the types side (`packages/types/src/__tests__/kanban-conditional-formatting.test.ts`); these rows are their respellings, painting the same cards. ⛔ NOT an identity pin and not a wire pin: `ObjectKanban.tsx` never names this key at all (measured zero, against nine for `cardFields` in the same file) — it rides the `{ ...schema }` spread into `KanbanRenderer`, which forwards it to `KanbanImpl`\'s `getCardStyles`. That makes the pin load-bearing in a way the others are not: an edit replacing that spread with an explicit key list drops the key silently and nothing else in the repo would notice. The installed spec row (18.0.0, re-measured by objectui#12030, objectui#12370, objectui#12626, objectui#12873, objectui#12971, objectui#13261) takes the list view\'s own `{ condition, style }` rule, so the spec fixes the authored shape and the read site is the rest of the member contract (objectui#8313).', + pins: 'Members are card STYLE RULES in ONE dialect since objectui#11522, the spec list view\'s `{ condition, style }`, and it reaches the sink: a rule colours the matching card and only it, a second rule aimed at the other card does the same, and the whole `style` map arrives, with the sibling card in the same render as the live non-matching control so a green cannot come from two unstyled cards agreeing. The retired native `{ field, operator, value }` and flat-colour dialects are refused by name on the types side (`packages/types/src/__tests__/kanban-conditional-formatting.test.ts`); these rows are their respellings, painting the same cards. ⛔ NOT an identity pin and not a wire pin: `ObjectKanban.tsx` never names this key at all (measured zero, against nine for `cardFields` in the same file) — it rides the `{ ...schema }` spread into `KanbanRenderer`, which forwards it to `KanbanImpl`\'s `getCardStyles`. That makes the pin load-bearing in a way the others are not: an edit replacing that spread with an explicit key list drops the key silently and nothing else in the repo would notice. The installed spec row (18.1.0, re-measured by objectui#12030, objectui#12370, objectui#12626, objectui#12873, objectui#12971, objectui#13261, objectui#13440) takes the list view\'s own `{ condition, style }` rule, so the spec fixes the authored shape and the read site is the rest of the member contract (objectui#8313).', }, 'object-kanban.data': { file: 'packages/plugin-kanban/src/__tests__/ObjectKanban.structuredMembersReachTheirSinks-8313.test.tsx', diff --git a/e2e/live/ci/backend.env b/e2e/live/ci/backend.env index ae042c211b..47d078f403 100644 --- a/e2e/live/ci/backend.env +++ b/e2e/live/ci/backend.env @@ -14,7 +14,7 @@ # # This file declares exactly ONE @objectstack pin, and that is the whole # design: the commit is derived from it, see below. -OBJECTSTACK_VERSION=18.0.0 +OBJECTSTACK_VERSION=18.1.0 # There is deliberately no OBJECTSTACK_REF key here. The objectstack-ai/objectstack # commit the showcase app metadata is sparse-checked-out from is DERIVED at diff --git a/packages/app-shell/src/views/metadata-admin/celAuthoring.ts b/packages/app-shell/src/views/metadata-admin/celAuthoring.ts index 597fb368d2..280b71b596 100644 --- a/packages/app-shell/src/views/metadata-admin/celAuthoring.ts +++ b/packages/app-shell/src/views/metadata-admin/celAuthoring.ts @@ -519,7 +519,7 @@ function loadRowCanon(): Promise { * not re-derived — and the engine's own message ships with it. * * ⚠️ The reason is NOT that the engine's message refuses a `record.` - * rewrite. Measured against the installed 18.0.0 (objectui#12030, objectui#12370, objectui#12626, objectui#12873, objectui#12971, objectui#13261), it mostly PRESCRIBES one: the + * rewrite. Measured against the installed 18.1.0 (objectui#12030, objectui#12370, objectui#12626, objectui#12873, objectui#12971, objectui#13261, objectui#13440), it mostly PRESCRIBES one: the * `current_user` text CONTAINS "To gate on record state, rewrite the predicate * against `record`." — one of the three remedies it offers, and NOT where it * ends (measured: `includes` true, `endsWith` false; every covered slot's text diff --git a/packages/app-shell/src/views/metadata-admin/inspectors/FlowNodeInspector.declaredDefault.test.tsx b/packages/app-shell/src/views/metadata-admin/inspectors/FlowNodeInspector.declaredDefault.test.tsx index 7e52b30300..33f0b9f818 100644 --- a/packages/app-shell/src/views/metadata-admin/inspectors/FlowNodeInspector.declaredDefault.test.tsx +++ b/packages/app-shell/src/views/metadata-admin/inspectors/FlowNodeInspector.declaredDefault.test.tsx @@ -381,7 +381,7 @@ describe('boolean: a declared defaultValue seeds the control (objectui#8451, arm // ⇒ `screen.waitForInput` is the offline undeclared boolean that sentence // says does not exist — and it is undeclared CORRECTLY, so ⛔ do not read // this as an objectui#9277-class omission waiting to be declared. Measured - // on the installed `@objectstack/spec` (18.0.0, objectui#12030, objectui#12370, objectui#12626, objectui#12873, objectui#12971, objectui#13261): `waitForInput` is typed + // on the installed `@objectstack/spec` (18.1.0, objectui#12030, objectui#12370, objectui#12626, objectui#12873, objectui#12971, objectui#13261, objectui#13440): `waitForInput` is typed // `z.boolean().optional()` with no `.default(...)`, so an omitted key // materialises nothing and there is no spec answer for a declaration to // mirror. Declaring one here would invent a default the runtime does not diff --git a/packages/app-shell/src/views/metadata-admin/inspectors/flow-node-config.startGates-12780.test.ts b/packages/app-shell/src/views/metadata-admin/inspectors/flow-node-config.startGates-12780.test.ts index fc51982612..4a95662c57 100644 --- a/packages/app-shell/src/views/metadata-admin/inspectors/flow-node-config.startGates-12780.test.ts +++ b/packages/app-shell/src/views/metadata-admin/inspectors/flow-node-config.startGates-12780.test.ts @@ -6,7 +6,7 @@ * * The table below is what `@objectstack/service-automation`'s * `AutomationEngine` and the trigger packages read, at objectstack - * `18.0.0` (the installed `@objectstack/spec` line): + * `18.1.0` (the installed `@objectstack/spec` line): * * - `secret`: the API trigger arms from `config.secret` (`trigger-api`). * - `objectName`: lifted into the `record_change` binding, which the diff --git a/packages/app-shell/src/views/metadata-admin/inspectors/flowSingleBrace-12329.test.tsx b/packages/app-shell/src/views/metadata-admin/inspectors/flowSingleBrace-12329.test.tsx index 49fd886020..6085bd8eef 100644 --- a/packages/app-shell/src/views/metadata-admin/inspectors/flowSingleBrace-12329.test.tsx +++ b/packages/app-shell/src/views/metadata-admin/inspectors/flowSingleBrace-12329.test.tsx @@ -6,7 +6,7 @@ * * objectstack#19939 S7 deleted the engine's single-brace resolver: a value slot * refuses a `{…}` token, a text slot reads `{{ }}` holes, and every other flow - * string is a literal. The installed spec (`18.0.0`) publishes no + * string is a literal. The installed spec (`18.1.0`) publishes no * `xExpression: 'template'` mark. So the picker has two spellings left — the * bare reference and the `{{ }}` hole — and a literal position has no picker. * diff --git a/packages/app-shell/src/views/metadata-admin/previews/flow-canvas-seeds.saveErrors-10948.test.tsx b/packages/app-shell/src/views/metadata-admin/previews/flow-canvas-seeds.saveErrors-10948.test.tsx index 8b8b10d805..fa44786b8d 100644 --- a/packages/app-shell/src/views/metadata-admin/previews/flow-canvas-seeds.saveErrors-10948.test.tsx +++ b/packages/app-shell/src/views/metadata-admin/previews/flow-canvas-seeds.saveErrors-10948.test.tsx @@ -2,7 +2,7 @@ /** * objectui#10948 — what the designer's live `FlowSchema` pass says about a node - * the author has ADDED but not yet configured, on the installed spec (18.0.0). + * the author has ADDED but not yet configured, on the installed spec (18.1.0). * * Spec 17.5.0 carries objectstack#20316 (a node config key its executor * contract requires, left out, and a decision branch with no `label`, are diff --git a/packages/core/src/evaluator/optionRules.ts b/packages/core/src/evaluator/optionRules.ts index 1f0c665a7d..f6b52938a5 100644 --- a/packages/core/src/evaluator/optionRules.ts +++ b/packages/core/src/evaluator/optionRules.ts @@ -118,7 +118,7 @@ export function resolveVisibleOptions( * This is deliberately NOT the lenient renderer fallback AGENTS.md #0.1 * forbids. That rule governs metadata the contract REFUSES ("if the metadata * is off-spec, fix it at the producer"); an empty label is metadata the - * contract ACCEPTS. Measured on the installed `@objectstack/spec` 18.0.0, + * contract ACCEPTS. Measured on the installed `@objectstack/spec` 18.1.0, * `SelectOptionSchema`: * * { value: 'low', label: 'Low' } -> ACCEPT (lit control) diff --git a/packages/plugin-calendar/src/ObjectCalendar.tsx b/packages/plugin-calendar/src/ObjectCalendar.tsx index be235f85ca..8da57f8a60 100644 --- a/packages/plugin-calendar/src/ObjectCalendar.tsx +++ b/packages/plugin-calendar/src/ObjectCalendar.tsx @@ -1428,7 +1428,7 @@ export const ObjectCalendar: React.FC = ({ * * `@objectstack/spec`'s `CalendarConfigSchema` is a `strictObject` whose ONE * required key is `startDateField`; `titleField` is optional. Re-measured on - * the installed 18.0.0 (objectui#12030, objectui#12370, objectui#12626, objectui#12873, objectui#12971, objectui#13261), three legs: `{}` and `{ titleField: 't' }` both fail + * the installed 18.1.0 (objectui#12030, objectui#12370, objectui#12626, objectui#12873, objectui#12971, objectui#13261, objectui#13440), three legs: `{}` and `{ titleField: 't' }` both fail * `invalid_type` at `startDateField`, and `{ startDateField: 'd' }` parses * CLEAN. The spec's own note on that schema names THIS renderer as the * reason — `resolveTitle` above takes an explicit `titleField` when present diff --git a/packages/plugin-calendar/src/__tests__/calendarUnionReads-8651.test.tsx b/packages/plugin-calendar/src/__tests__/calendarUnionReads-8651.test.tsx index 6d3398d2f8..997ef7b8b3 100644 --- a/packages/plugin-calendar/src/__tests__/calendarUnionReads-8651.test.tsx +++ b/packages/plugin-calendar/src/__tests__/calendarUnionReads-8651.test.tsx @@ -179,7 +179,7 @@ const LEDGERED_OTHER_CARD_READS: readonly string[] = []; * `ObjectCalendarSchema` and must stay so. * * ⚠️ The ground is NOT that the spec singles these two out. MEASURED on - * installed `@objectstack/spec` 18.0.0: `ComponentPropsMap['object-calendar']` + * installed `@objectstack/spec` 18.1.0: `ComponentPropsMap['object-calendar']` * is STRICT and declares exactly ten flat members — `calendar` `data` * `defaultView` `filter` `loading` `locale` `navigation` `objectName` `sort` * `staticData` (nine through 17.4.0; 17.5.0 added `navigation`) — diff --git a/packages/plugin-designer/src/MetadataFieldsPage.tsx b/packages/plugin-designer/src/MetadataFieldsPage.tsx index 98172c0ded..a95a247c82 100644 --- a/packages/plugin-designer/src/MetadataFieldsPage.tsx +++ b/packages/plugin-designer/src/MetadataFieldsPage.tsx @@ -184,7 +184,7 @@ function isDesignerAuthorableType(raw: unknown): raw is DesignerFieldType { * ## Why reading the retired spelling is a RENAME here and not a laundering * * `@objectstack/spec` treats the two as one key under two spellings and says - * so in the refusal itself. Measured on the installed 18.0.0 (objectui#12030, objectui#12370, objectui#12626, objectui#12873, objectui#12971, objectui#13261): + * so in the refusal itself. Measured on the installed 18.1.0 (objectui#12030, objectui#12370, objectui#12626, objectui#12873, objectui#12971, objectui#13261, objectui#13440): * * FieldSchema.safeParse({ type: 'lookup', label: 'L', referenceTo: 'account' }) * => success = false diff --git a/packages/plugin-detail/src/index.tsx b/packages/plugin-detail/src/index.tsx index 2e18b3d525..29b3b91949 100644 --- a/packages/plugin-detail/src/index.tsx +++ b/packages/plugin-detail/src/index.tsx @@ -987,7 +987,7 @@ ComponentRegistry.register('alert', RecordAlertRenderer, { // through `pickLocalized`, which is exactly what these descriptions teach. // Declaring the map arm therefore adds no shape the block does not already // honour; it stops the manifest gate warning `type-mismatch` on the - // recommended write. (The row DOES exist as of the installed 18.0.0 — read + // recommended write. (The row DOES exist as of the installed 18.1.0 — read // for `visible` below, objectui#9100 — so the "no entry" reading is stale; // these two arms are unaffected either way.) { name: 'title', type: ['string', 'object'], description: 'Accepts an inline translation map ({ en, "zh-CN", … })' }, @@ -995,7 +995,7 @@ ComponentRegistry.register('alert', RecordAlertRenderer, { // objectui#9100 — the spec accepts three arms here and the renderer now // resolves all three, so a single `'string'` was the declaration-narrower- // than-the-contract family of objectui#4581, one layer up. Measured on the - // INSTALLED `@objectstack/spec` 18.0.0 (`dist/ui/index.d.ts`, the + // INSTALLED `@objectstack/spec` 18.1.0 (`dist/ui/index.d.ts`, the // `ComponentPropsMap['record:alert']` row): `visible` is // `boolean | string | { dialect: 'cel'|'cron'|'template', source?, … }`, // and `renderers/record-alert.tsx` hands whichever arrives to diff --git a/packages/plugin-form/src/__tests__/formSectionGroupReference-7051.test.tsx b/packages/plugin-form/src/__tests__/formSectionGroupReference-7051.test.tsx index e88ad7e2e1..33475abc03 100644 --- a/packages/plugin-form/src/__tests__/formSectionGroupReference-7051.test.tsx +++ b/packages/plugin-form/src/__tests__/formSectionGroupReference-7051.test.tsx @@ -448,7 +448,7 @@ describe('objectui#7051 — resolveSectionGroupReferences', () => { /** * ⭐ The second axis. The card asks that group-owned presentation keys beside * `group`, and `group` on a wizard step, not be SILENTLY accepted. Measured - * against the installed `@objectstack/spec` (18.0.0): both are refused at PARSE + * against the installed `@objectstack/spec` (18.1.0): both are refused at PARSE * — a stronger door than the lint that objectui#8497 concluded owns EXISTENCE * checking, and a different one. So authored metadata carrying either never * reaches this renderer at all; the renderer's own reports above exist for the diff --git a/packages/plugin-form/src/__tests__/masterDetailDetailsMembers-8071.test.tsx b/packages/plugin-form/src/__tests__/masterDetailDetailsMembers-8071.test.tsx index ba69ed2a96..6cc2d8bafb 100644 --- a/packages/plugin-form/src/__tests__/masterDetailDetailsMembers-8071.test.tsx +++ b/packages/plugin-form/src/__tests__/masterDetailDetailsMembers-8071.test.tsx @@ -504,7 +504,7 @@ type SpecDetailEntry = NonNullable[numbe * The config IS the spec's entry minus `sortField`, by reference * (objectui#11396): a member the spec adds, drops or retypes lands on the * config with no hand edit, and a hand-written restatement that drifts is red - * here before it is red anywhere else. The installed 18.0.0 entry carries a + * here before it is red anywhere else. The installed 18.1.0 entry carries a * `retiredKey()` tombstone for `sortField` (objectstack-ai/objectstack#21589); * 17.6.0 declared it as a string, and the subtraction removes the key either * way. ⛔ No row here pins which of the two shapes the spec has; the `Spec Main diff --git a/packages/plugin-gantt/src/readme-navigation-example.test.ts b/packages/plugin-gantt/src/readme-navigation-example.test.ts index 1a0cd10a9e..12856a067c 100644 --- a/packages/plugin-gantt/src/readme-navigation-example.test.ts +++ b/packages/plugin-gantt/src/readme-navigation-example.test.ts @@ -79,7 +79,7 @@ * * WARNING: `declaredMembers()` cannot derive that key's retirement. When this * was written the spec in the lockfile (17.4.0) still DECLARED `view` as a live - * member. The installed `@objectstack/spec` 18.0.0 lands it as a tombstone, + * member. The installed `@objectstack/spec` 18.1.0 lands it as a tombstone, * as 17.5.0 through 17.7.0 did (objectui#11073 measured it, objectui#11438, * objectui#11717 and objectui#12030 again: a `never` * schema, and `{ view: 'detail' }` is diff --git a/packages/plugin-kanban/src/index.tsx b/packages/plugin-kanban/src/index.tsx index ad1079a9f5..c067e73fdd 100644 --- a/packages/plugin-kanban/src/index.tsx +++ b/packages/plugin-kanban/src/index.tsx @@ -554,7 +554,7 @@ export const ObjectKanbanRenderer: React.FC<{ schema: any; [key: string]: any }> * ## Why these keys were added * * `@objectstack/spec`'s `ComponentPropsMap['object-kanban']` carries FIFTEEN - * top-level keys on the installed 18.0.0 pin, fourteen of them live, the + * top-level keys on the installed 18.1.0 pin, fourteen of them live, the * same set as 17.5.0 through 17.7.0: 17.5.0 * added `navigation` and turned `quickAdd` into a tombstone (typed `never`, * refused by name — objectui#8285's ruled retirement, landed). This list diff --git a/packages/types/src/__tests__/chartconfig-aria-retired-4044.test.ts b/packages/types/src/__tests__/chartconfig-aria-retired-4044.test.ts index 15b08179fb..86f054ce3e 100644 --- a/packages/types/src/__tests__/chartconfig-aria-retired-4044.test.ts +++ b/packages/types/src/__tests__/chartconfig-aria-retired-4044.test.ts @@ -30,7 +30,7 @@ * - **TypeScript.** `complex.ts` re-typed `chartConfig` as `any`, so an * authored `aria` compiled. The member now takes `aria` from the spec's own * input type, which is the spec's retired-key type (the branded `[REMOVED]` - * mark at the pinned 18.0.0 and on objectstack `main`, bare `undefined` + * mark at the pinned 18.1.0 and on objectstack `main`, bare `undefined` * through 17.5.0; both * spellings are `retired-key-type.ts`'s), so an authored value is a compile * error. diff --git a/packages/types/src/__tests__/dashboard-aria-retired-contract-twins.test.ts b/packages/types/src/__tests__/dashboard-aria-retired-contract-twins.test.ts index 0ae5f495e0..4681311086 100644 --- a/packages/types/src/__tests__/dashboard-aria-retired-contract-twins.test.ts +++ b/packages/types/src/__tests__/dashboard-aria-retired-contract-twins.test.ts @@ -29,7 +29,7 @@ * objectui#9736 closed that half. The interface now extends the spec's own * `Dashboard` input type (`Omit< Dashboard, … >` over the exclusion list its * mirror reads), so it inherits the spec's tombstone as a DECLARED member typed - * as the spec's retired key (the branded `[REMOVED]` mark at the pinned 18.0.0 + * as the spec's retired key (the branded `[REMOVED]` mark at the pinned 18.1.0 * and on objectstack `main`, bare `undefined` through 17.5.0) — `aria` is back in the declared key * set, but only as a refusal, * and an authored value is a compile error: the same verdict the Zod twin gives @@ -52,7 +52,7 @@ describe('the TS interface declares `aria` only as the spec tombstone (objectui# it('`aria` is declared, typed as the spec\'s retired key; the neighbours it stood beside still are', () => { // Type-level pins, erased at runtime. `aria` is a DECLARED key again — the // spec projection carries the tombstone — and its type admits no value: - // the branded `[REMOVED]` mark at the pinned 18.0.0 and on objectstack + // the branded `[REMOVED]` mark at the pinned 18.1.0 and on objectstack // `main`, bare `undefined` through 17.5.0 (both spellings are // `retired-key-type.ts`'s, objectui#11330). const ariaDeclared: 'aria' extends Declared ? true : false = true; diff --git a/packages/types/src/__tests__/object-view-unmirrored-keys-7779.test.ts b/packages/types/src/__tests__/object-view-unmirrored-keys-7779.test.ts index 3891effd1a..4edea928ed 100644 --- a/packages/types/src/__tests__/object-view-unmirrored-keys-7779.test.ts +++ b/packages/types/src/__tests__/object-view-unmirrored-keys-7779.test.ts @@ -376,7 +376,7 @@ const NAMED_VIEW_ABSENT_CONTROL = 'stickyHeader'; /** * The protocol's own member set for a named list view — `ObjectListViewSchema`'s - * shape, off `@objectstack/spec` as installed (18.0.0). ⛔ Not a copy of the + * shape, off `@objectstack/spec` as installed (18.1.0). ⛔ Not a copy of the * objectui face and ⛔ not a hand list: it is read off the schema object, so a * spec bump that moves a key moves this. */ diff --git a/packages/types/src/__tests__/record-details-top-level-9040.test.ts b/packages/types/src/__tests__/record-details-top-level-9040.test.ts index 13fe764d93..8c1de6ab00 100644 --- a/packages/types/src/__tests__/record-details-top-level-9040.test.ts +++ b/packages/types/src/__tests__/record-details-top-level-9040.test.ts @@ -174,7 +174,7 @@ type _KeyofStillResolvesOnThisInterface = Expect< /** * The contract's face, untouched by this removal: the tombstone accepts nothing. * Its type is the spec's retired-key type — the branded `[REMOVED]` mark at the - * pinned 18.0.0 and on objectstack `main`, + * pinned 18.1.0 and on objectstack `main`, * bare `undefined` through 17.5.0 — and the helper accepts * exactly those two spellings (objectui#11330). */ diff --git a/packages/types/src/__tests__/spec-object-refinements-7715.test.ts b/packages/types/src/__tests__/spec-object-refinements-7715.test.ts index 0856f64dcb..7f6927c880 100644 --- a/packages/types/src/__tests__/spec-object-refinements-7715.test.ts +++ b/packages/types/src/__tests__/spec-object-refinements-7715.test.ts @@ -345,7 +345,7 @@ const SITES = [ // objectui#12370's view-data check left this list with objectui#12666: objectstack#23784 // removed it from the spec, and 18.0.0-next.3 is the first release without it (objectstack // `a35f7a6`). The census below accounts for it by what it judges, not by name - // (`specChecksRemovedOnMain`), which on the installed 18.0.0 finds nothing. + // (`specChecksRemovedOnMain`), which on the installed 18.1.0 finds nothing. // `checkPageRegionPlacement` joined at 18.0.0-next.2 and was attached by objectui#12626: it // reads `kind` and `template` (by reference) and each region's `name`, which objectui's own // region carries with the meaning `page.tsx` places it by; measured in its describe block above. @@ -450,7 +450,7 @@ const PAGE_SITE = 'SpecPageFields → PageNodeSchema (layout.zod.ts)'; * against its own spec tree, so no file here may name that export. Through * 18.0.0-next.2 the spec exported it and attached it to `PageSchema`, where * the census would miscount by one; 18.0.0-next.3 dropped it (objectstack - * `a35f7a6`), and on the installed 18.0.0 this answers empty. This reads every + * `a35f7a6`), and on the installed 18.1.0 this answers empty. This reads every * exported check no site names and keeps the ones that refuse a slotted * `object-grid` naming `api` at its `properties.data.provider`: on next.2 that * is exactly the removed judge, and on a spec without it the list is empty, so diff --git a/packages/types/src/field-types.ts b/packages/types/src/field-types.ts index 931d7de333..4a74b0dd06 100644 --- a/packages/types/src/field-types.ts +++ b/packages/types/src/field-types.ts @@ -25,7 +25,7 @@ import type { Field as SpecField } from '@objectstack/spec/data'; * sibling field names, or `{ field, param }` entries mapping a sibling onto the * remote query parameter a dependent lookup filters by. * - * Measured on the installed `@objectstack/spec` (18.0.0), `FieldSchema` declares + * Measured on the installed `@objectstack/spec` (18.1.0), `FieldSchema` declares * `dependsOn` as an OPTIONAL ARRAY of `string | { field, param? }` — never a * bare string. That is deliberately narrower than `DependsOnInput` (`form.ts`), * the shape the widget prop `FieldWidgetComponentProps.dependsOn` and @@ -343,7 +343,7 @@ export interface MarkdownFieldMetadata extends BaseFieldMetadata { * annotated literal rejected. Follows the `TextareaFieldMetadata` precedent. * * A DECLARED spec key as of `@objectstack/spec` 17.3.0, which implements that - * same ruling. Measured on the installed `@objectstack/spec` 18.0.0: + * same ruling. Measured on the installed `@objectstack/spec` 18.1.0: * `FieldSchema` ACCEPTS `rows` on all four of textarea/markdown/html/ * richtext, as an integer of at least 1 — a non-integer answers * `invalid_type` and 0 answers `too_small`, so "declared" does not mean "any @@ -692,7 +692,7 @@ export interface SelectOptionMetadata extends SelectOptionBase { * * A DECLARED `SelectOptionSchema` key as of `@objectstack/spec` 17.3.0, * which implements the objectui#6153 half of that ruling. Measured on the - * installed `@objectstack/spec` 18.0.0: an option carrying `description` + * installed `@objectstack/spec` 18.1.0: an option carrying `description` * is ACCEPTED, as a string (a non-string answers `invalid_type`; the empty * string is valid), and a field whose `options` carry it parses whole. ⇒ it * may now be written into authored object metadata, which is the point of diff --git a/packages/types/src/objectql.ts b/packages/types/src/objectql.ts index 6579acdf6d..71e936789f 100644 --- a/packages/types/src/objectql.ts +++ b/packages/types/src/objectql.ts @@ -4285,7 +4285,7 @@ export interface ObjectCalendarSchema extends BaseSchema { * (the spec's own `ObjectCalendarPropsSchema`) declares * `z.array(z.unknown()).optional()`, described *"Pre-fetched records — skips * the internal fetch"*. - * MEASURED on the installed artifact at `@objectstack/spec` 18.0.0 — the + * MEASURED on the installed artifact at `@objectstack/spec` 18.1.0 — the * version this repository's `pnpm-lock.yaml` resolves — through the published * `@objectstack/spec/ui` entry point: the provider block returns * `success=false` with `expected: 'array'` at `path: ['data']`, the array diff --git a/packages/types/src/record-components.ts b/packages/types/src/record-components.ts index a0dcdb2680..e845cdd817 100644 --- a/packages/types/src/record-components.ts +++ b/packages/types/src/record-components.ts @@ -107,7 +107,7 @@ export interface RecordDetailsComponentProps { * It was `number` here until objectui#8604, which is the wrong PRIMITIVE * TYPE, not merely a wider range: `{ columns: 2 }` compiled locally and the * contract refused it at publish with `invalid_value` at `columns` (measured - * on the installed pin, 18.0.0, against a control — `columns: '2'` — that + * on the installed pin, 18.1.0, against a control — `columns: '2'` — that * parses green on the same instrument). Contract-first (Commandment #0.1): * the code moves to the contract's spelling, and today's `columns: 2` * authors are the defect surfacing rather than collateral damage. @@ -367,7 +367,7 @@ export interface RecordHighlightsComponentProps { * `RecordHighlightsProps.fields[]`'s object arm declares exactly * `name`/`label`/`type`/`readonly` and carries a `never` catchall, i.e. it is * `$strict`: an unlisted key is REFUSED, not stripped, and the refusal takes - * the WHOLE document with it. Measured on the installed pin, 18.0.0, + * the WHOLE document with it. Measured on the installed pin, 18.1.0, * `RecordHighlightsProps.safeParse({ fields: [{ name: 'x', icon: 'star' }] })` * is RED with `invalid_union` at `fields.0`. So `{ name: 'amount', icon: * 'dollar-sign' }` type-checked here and was refused at the door — a green @@ -399,7 +399,7 @@ export interface RecordHighlightsComponentProps { * `z.enum(['horizontal','vertical'])` behind a `.default('horizontal')`). * * It offered a third value, `grid`, until objectui#9187, and the contract - * never accepted it: measured on the installed pin, 18.0.0, + * never accepted it: measured on the installed pin, 18.1.0, * `RecordHighlightsProps.safeParse({ fields: ['name'], layout: 'grid' })` is * RED with `invalid_value` at `layout`. So `{ layout: 'grid' }` type-checked * here and was refused at the door — a green local build and a rejection at diff --git a/packages/types/src/zod/objectql.zod.ts b/packages/types/src/zod/objectql.zod.ts index dc592d1193..d7850c29ae 100644 --- a/packages/types/src/zod/objectql.zod.ts +++ b/packages/types/src/zod/objectql.zod.ts @@ -1783,7 +1783,7 @@ const KanbanConfig = stripImportedDefaults(SpecListViewSchema).shape.kanban.unwr * `@objectstack/spec` 17.4.0 (the version in the lockfile then) rather than * reading it — RE-RUN on 17.5.0 (objectui#11073), whose answer moved, as the * last bullet says, RE-RUN on 17.6.0 (objectui#11438), on 17.7.0 (objectui#11717), - * and again on the installed 18.0.0 (objectui#12030, objectui#12370, objectui#12626, objectui#12873, objectui#12971, objectui#13261), each of which answers + * and again on the installed 18.1.0 (objectui#12030, objectui#12370, objectui#12626, objectui#12873, objectui#12971, objectui#13261, objectui#13440), each of which answers * every bullet below as 17.5.0 did: * * - `CalendarConfigSchema`'s `strictObject` options carry `surface` and @@ -1808,7 +1808,7 @@ const KanbanConfig = stripImportedDefaults(SpecListViewSchema).shape.kanban.unwr * prescribes neither. `endField` still draws no hint, and a one-char typo * still resolves by distance (`titleFeld` → `titleField`) — all three * measured on 17.5.0, again on 17.6.0 (objectui#11438), on 17.7.0 - * (objectui#11717), and again on the installed 18.0.0 (objectui#12030, objectui#12370, objectui#12626, objectui#12873, objectui#12971, objectui#13261). + * (objectui#11717), and again on the installed 18.1.0 (objectui#12030, objectui#12370, objectui#12626, objectui#12873, objectui#12971, objectui#13261, objectui#13440). * * ⇒ through 17.4.0 a generic typo-distance suggester picked the wrong sibling. * It was not a declaration, it contradicted no declaration, and ⛔ no upstream From b26cfb18f782461807d9762a2bef77cf1ef9a02e Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 24 Oct 2026 12:14:55 +0000 Subject: [PATCH 4/5] chore(changeset): declare the 18.1.0 pin move and the ORG_ROLE_EXTERNAL re-export (objectui#13440) Claude-Session: https://claude.ai/code/session_01CErMSwkRLW7c7jk23MHfVP Co-authored-by: Claude --- .changeset/13440-objectstack-pin-e649c2d.md | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 .changeset/13440-objectstack-pin-e649c2d.md diff --git a/.changeset/13440-objectstack-pin-e649c2d.md b/.changeset/13440-objectstack-pin-e649c2d.md new file mode 100644 index 0000000000..c839d79ca7 --- /dev/null +++ b/.changeset/13440-objectstack-pin-e649c2d.md @@ -0,0 +1,7 @@ +--- +'@object-ui/auth': patch +--- + +The `@objectstack/*` pin moves from `915e940499` to objectstack `e649c2d91e`, the 18.1.0 release commit (objectstack#25606), past objectstack#25483 and objectstack#25564, which ship together in that release (objectui#13440). + +`@object-ui/auth` now takes `ORG_ROLE_EXTERNAL` from `@objectstack/spec`'s `MEMBERSHIP_ROLE_EXTERNAL` instead of spelling the literal. The exported name and its value (`'external'`) are unchanged, and `ORG_ROLE_LABELS` is typed by `OrgRole` alone again. The published module now imports that constant, so it needs an `@objectstack/spec` that exports it (18.1.0 or later); the publish step floors the `@objectstack/*` ranges at the release that contains the pin. With that spec the invite dialog lists `external` among the roles it offers, as objectui#13427 described for a spec that lists the role. From aad44f7158076ad4ba67204dc853642d0f37d8dc Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 24 Oct 2026 12:25:38 +0000 Subject: [PATCH 5/5] test(app-shell): re-point the ObjectSchema key-count guards to 47 for membershipKeys (objectui#13440) @objectstack/spec 18.1.0 adopts ObjectSchema.membershipKeys (objectstack#25513). Measured against the 915e9404 pin: the spec's authorable-surface/data.json gains exactly data/Object:membershipKeys, none lost. Both files carry the count as a corpus guard for their own membership claims, which stay unchanged, so it is re-pointed 46 -> 47 with its history sentence, as the four earlier adoptions were. Claude-Session: https://claude.ai/code/session_01CErMSwkRLW7c7jk23MHfVP Co-authored-by: Claude --- .../services/MetadataService.retiredObjectEnabled.test.ts | 6 +++++- .../services/MetadataService.specKeyObjectPayload.test.ts | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/packages/app-shell/src/services/MetadataService.retiredObjectEnabled.test.ts b/packages/app-shell/src/services/MetadataService.retiredObjectEnabled.test.ts index 3ba79cb0ad..99e40b910f 100644 --- a/packages/app-shell/src/services/MetadataService.retiredObjectEnabled.test.ts +++ b/packages/app-shell/src/services/MetadataService.retiredObjectEnabled.test.ts @@ -153,8 +153,12 @@ describe('objectui#6238 · the schema oracle — both tombstone keys are refused // `defaultRowScope` (objectstack#24398; measured against the next.3 pin: the // one top-level key `ObjectSchema` gains between the two commits, none lost; // objectui#12971). Re-pointed the same way. + // 47 at `@objectstack/spec` 18.1.0, which adopted `membershipKeys` + // (objectstack#25513; measured against the 915e9404 pin: the spec's own + // `authorable-surface/data.json` gains exactly `data/Object:membershipKeys` + // between the two commits, none lost; objectui#13440). Re-pointed the same way. const accept = new Set(Object.keys(ObjectSchema.shape as Record)); - expect(accept.size).toBe(46); + expect(accept.size).toBe(47); expect(accept.has('enable')).toBe(true); expect(accept.has('enabled')).toBe(false); expect(accept.has('_deleted')).toBe(false); diff --git a/packages/app-shell/src/services/MetadataService.specKeyObjectPayload.test.ts b/packages/app-shell/src/services/MetadataService.specKeyObjectPayload.test.ts index 98a8175e34..e4058be148 100644 --- a/packages/app-shell/src/services/MetadataService.specKeyObjectPayload.test.ts +++ b/packages/app-shell/src/services/MetadataService.specKeyObjectPayload.test.ts @@ -167,8 +167,12 @@ describe('the instrument', () => { // `defaultRowScope` (objectstack#24398; measured against the next.3 pin: the // one top-level key `ObjectSchema` gains between the two commits, none lost; // objectui#12971). Re-pointed the same way. + // 47 at `@objectstack/spec` 18.1.0, which adopted `membershipKeys` + // (objectstack#25513; measured against the 915e9404 pin: the spec's own + // `authorable-surface/data.json` gains exactly `data/Object:membershipKeys` + // between the two commits, none lost; objectui#13440). Re-pointed the same way. const accept = new Set(Object.keys(ObjectSchema.shape as Record)); - expect(accept.size).toBe(46); + expect(accept.size).toBe(47); // `fieldGroups` is the only grouping key on the object, and it groups the // FIELDS INSIDE one object — it is not a category for objects themselves, // so `group` has no mapping target here.