Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .changeset/10117-page-header-title-lookup-fallback.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
'@object-ui/components': patch
---

fix(components): `page:header` resolves a lookup title candidate instead of handing its expanded object to JSX (objectui#10117)
fix(components): `page:header` resolves a lookup title candidate instead of handing its expanded object to JSX

A record whose declared name field was empty took the whole `page:header` block
down with "Objects are not valid as a React child" (React #31), leaving the red
Expand Down
2 changes: 1 addition & 1 deletion .changeset/10120-form-omits-fls-denied-fields.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
'@object-ui/fields': patch
---

A form no longer submits — nor offers — a field the CALLER may read but not edit (objectui#10120).
A form no longer submits — nor offers — a field the CALLER may read but not edit.

**Clause-②: no** — no exported symbol is added, removed, renamed or retyped, no key on a published payload moves, and no accept set is relaxed. `sanitizeFormData` gains an optional third argument and `fieldWriteGate` / `applyFieldPermissions` are new, but `@object-ui/plugin-form` publishes `.` only, from `index.tsx`, which re-exports neither module — measured on the built `dist/index.d.ts`, where neither name appears. `LookupField`'s props are unchanged. What moves is what the client PUTS on the wire and which controls it draws.

Expand Down
3 changes: 1 addition & 2 deletions .changeset/10129-action-param-field-backed-picker.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@
---

A field-backed action param reaches its record picker, and a param whose backing
field cannot be read is refused instead of rendered as an empty text box
(objectui#10129).
field cannot be read is refused instead of rendered as an empty text box.

An action declaring a `params` entry backed by a `lookup` field rendered as a bare
text input: no options, no typeahead, and no request for the referenced object on
Expand Down
2 changes: 1 addition & 1 deletion .changeset/10132-dashboard-i18n-declared-not-resolved.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
'@object-ui/plugin-dashboard': patch
---

fix(dashboard,charts): two dashboard surfaces the spec types as translatable now resolve (objectui#10132)
fix(dashboard,charts): two dashboard surfaces the spec types as translatable now resolve

`@objectstack/spec` declares both of these translatable and the Console resolved neither, so
an author could set a key the contract documents and nothing happened. They turned out to be
Expand Down
2 changes: 1 addition & 1 deletion .changeset/10163-line-items-field-write-gate.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

A `record:line_items` grid no longer offers a cell the CALLER may read but not edit (objectui#10163).

**What it was.** objectui#10120 taught the record-form containers to render a field the caller's permission set marks `editable: false` as disabled, through one shared render pass. The line-items panel stayed outside that pass: it read `readonly` and nothing else, so on the same page the same column rendered as a live, editable cell — inviting an edit the server refuses.
**What it was.** `80c54122e` taught the record-form containers to render a field the caller's permission set marks `editable: false` as disabled, through one shared render pass. The line-items panel stayed outside that pass: it read `readonly` and nothing else, so on the same page the same column rendered as a live, editable cell — inviting an edit the server refuses.

**What changed, in observable terms.**

Expand Down
2 changes: 1 addition & 1 deletion .changeset/10563-form-arms-write-payload.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ The `tabbed`, `wizard` and `split` form layouts now write what the simple form w

**Clause-②: no.** No exported symbol, type or prop changes. The shared sequence lives in an internal module that `index.tsx` does not re-export. The change is in what the client sends, and ⚠️ in what a host `submitHandler` receives from these layouts (see below).

**Before.** The simple form, `ModalForm` and `DrawerForm` strip a save before sending it, and on an edit they send only the fields that differ from the record they read (objectui#10108, objectui#10120, objectui#10156). `TabbedForm`, `SplitForm` and `WizardForm` did neither. An edit sent every value the form held: `id`, `owner_id`, `created_by`, `updated_at`, formula columns, and fields the caller's field-level security refuses. The server answered with a `403` or an unknown-field refusal. A create seeded with a whole record, such as a copy of an existing one, posted those columns too. A simple form whose mobile `stepper` option shows it one step at a time renders through `WizardForm`, so it had the same defect.
**Before.** The simple form, `ModalForm` and `DrawerForm` strip a save before sending it, and on an edit they send only the fields that differ from the record they read (objectui#10108, `80c54122e`, objectui#10156). `TabbedForm`, `SplitForm` and `WizardForm` did neither. An edit sent every value the form held: `id`, `owner_id`, `created_by`, `updated_at`, formula columns, and fields the caller's field-level security refuses. The server answered with a `403` or an unknown-field refusal. A create seeded with a whole record, such as a copy of an existing one, posted those columns too. A simple form whose mobile `stepper` option shows it one step at a time renders through `WizardForm`, so it had the same defect.

**What changed, in observable terms.**

Expand Down
4 changes: 2 additions & 2 deletions .changeset/10746-joined-report-clears-binding.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ to `joined`, and in the same render hid its dataset / values / rows / columns /
controls, while the spec's own `reportForm` hid the whole "Dataset binding" section
(`order` included) through `visibleWhen: "data.type != 'joined'"`. A report that was
bound first and switched second kept every one of those keys invisibly. `ReportSchema`'s
joined arm refuses a container `dataset` / `rows` / `columns` / `values` (objectstack PR
#20160: "a `joined` report selects per block — move `KEY` onto `blocks[]`, or delete it")
joined arm refuses a container `dataset` / `rows` / `columns` / `values` (PR
objectstack#20160: "a `joined` report selects per block — move `KEY` onto `blocks[]`, or delete it")
and has always refused a container `order`, so the save was refused at a path no control
on the Properties tab could reach; only the JSON source tab could delete the key.

Expand Down
24 changes: 24 additions & 0 deletions .changeset/10803-dead-citation-sweep-sixth-batch.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
---
---

Comment-only in `@object-ui/app-shell`, `@object-ui/components`, `@object-ui/core`,
`@object-ui/data-objectstack`, `@object-ui/fields`, `@object-ui/layout`,
`@object-ui/plugin-dashboard`, `@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-view` and `@object-ui/types` (whose runtime
text is declared separately below): docblocks and code comments that cited objectui issues
which answer 404 now cite the commit that landed each change, as a 9-character sha, and
where nothing answers they name the card by role (objectui#10803, the sixth batch). Bare
numbers that were sister-repo cards or pull requests are now written `objectstack#N`, and
where the sister-repo pull request itself answers 404 the sentence cites its commit in
that repository instead. Two `@object-ui/plugin-grid` sites beside `objectstack#3720` that
named the apiMethods whitelist card bare now read `objectstack#3391`, the card they meant.
Some of these docblocks reach the
emitted `.d.ts` and `.js`; none of them moves a claim, and none of these comment edits
changes a code or type token. No published behaviour changes through them, so this
declares no release. The one runtime string the sweep touches, a zod `.describe()` string
in `@object-ui/types`, is declared on its own as a patch in
`10803-sixth-batch-runtime-strings.md`.

The same repair in the pending changesets that carried these citations is prose-only, and
their frontmatter is byte-identical.
14 changes: 14 additions & 0 deletions .changeset/10803-sixth-batch-runtime-strings.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
'@object-ui/types': patch
---

fix(types): `InputSchema.wrapperClass`'s description no longer points at an objectui issue that answers 404

The zod `.describe()` text of `InputSchema.wrapperClass` ended with a pointer to an
objectui issue that answers 404. A reader of a zod `description` has no repository to
resolve a commit against, so the pointer is dropped rather than replaced: the description
now reads "Classes on the wrapper div around the input and its label" (objectui#10803).

Nothing else in the string moves, and no key, path, issue code, accept set, refusal or
severity changes: every document that parsed before parses the same way and is refused at
the same path with the same code.
2 changes: 1 addition & 1 deletion .changeset/14026-list-import-mappings-pin.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@
---

Pin `listImportMappings(objectName)` against the framework's measured
`GET /api/v1/meta/mapping` body (objectui#14026). Test only; no package is
`GET /api/v1/meta/mapping` body (objectstack#14026). Test only; no package is
released by this change.
2 changes: 1 addition & 1 deletion .changeset/6594-headercolor-mirror-enum.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ the contract — the TypeScript declaration and the `@object-ui/types/zod` mirro
objectstack#12126). The six are `muted`, `muted/50`, `accent`, `primary/10`, `secondary/10`
and `destructive/10`: exactly what `@object-ui/plugin-detail`'s `HEADER_COLOR_CLASSES`
resolves (objectui#6178) and exactly what `@objectstack/spec` declares on its strict
`record:details` section schema (objectstack PR #12616).
`record:details` section schema (PR objectstack#12616).

## ⚠️ Accept-set narrowing — these spellings stop validating

Expand Down
2 changes: 1 addition & 1 deletion .changeset/6748-preview-mode-provenance-ratchet.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 objectstack PR #12718), so
`RETIRED_DEFS_BY_MAJOR[18]` (objectstack#11846, 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
Expand Down
4 changes: 2 additions & 2 deletions .changeset/6985-wizard-card-r-alignment.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

Wizard view v1, the objectui half (Card R, objectui#6985) — alignment + pins for the
ruled `type: 'wizard'` tightening (objectstack#13622 D1–D8, maintainer ruling
2026-08-31; spec half objectstack PR #13733).
2026-08-31; spec half PR objectstack#13733).

The renderer was already aligned: `WizardStepConfig` carries no predicate/collapse
keys (objectui#6237's ruled split), the wizard route drops-and-reports an authored
Expand Down Expand Up @@ -42,5 +42,5 @@ exemption since #2959. This card lands the residue:
half records the 17.2.x accept-set it measured. `steps:` is pinned refused on
every spec line.

No teaching material — the #13337/#13086 fence lifts only after both halves land;
No teaching material — the objectstack#13337 / objectstack#13267 fence lifts only after both halves land;
docs changes here are TSDoc/comments only.
2 changes: 1 addition & 1 deletion .changeset/7415-action-type-input-rename.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ actually set it:
last, so `type="api"` replaced the component discriminator and the node stopped resolving
to a component at all. `validate.ts` cannot report that: `type` is in `BASE_PROPS`, so it
is skipped before the declared-input check runs. Two mechanisms, one outcome, no
diagnostic. objectstack PR #14274 landed a refusal on this tier whose prescription
diagnostic. PR objectstack#14274 landed a refusal on this tier whose prescription
("write the tag you meant") is wrong for exactly these two components.
- **react-page tier** — the wrapper stamps `type: tag` last and parks the author's value
under `specType` (objectui#2880), which neither action renderer reads.
Expand Down
2 changes: 1 addition & 1 deletion .changeset/7714-lookup-draft-stays-client-side.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ objectstack#4001 closed.

**The whitespace row follows the contract; it is not a local opinion.** The predicate
is `typeof reference === 'string' && reference.trim() !== ''`. It was a declared
divergence when written — 17.3.0's #13632 refinement spelled its emptiness test as an
divergence when written — 17.3.0's objectstack#13632 refinement spelled its emptiness test as an
equality against `''`, so the spec accepted `reference: ' '` while these writers
refused it. objectstack#16920 applies that test to the TRIMMED value, so the spec now
refuses the identical shape under the same `custom` issue at the same `reference`
Expand Down
2 changes: 1 addition & 1 deletion .changeset/7722-wrapper-class-five-more.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,6 @@ admitted unexamined on all five mirrors, pinned per mirror with a control key
the renderer does not read. `InputSchema.wrapperClass`, declared on the TS face
only, was a recorded row of the parity ledger (`UnmirroredDeclared`) and this
card left it there; the new sweep pin carried it as a self-expiring exemption.
objectui#8072 has since mirrored that key, so the row and the exemption are both
`c974edf14` has since mirrored that key, so the row and the exemption are both
gone — the exemption expired exactly as designed, and the sweep now judges all
nine readers alike.
2 changes: 1 addition & 1 deletion .changeset/7735-zod-mirrors-stop-authoring-defaults.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ was not even self-consistent.
**What changed.** All 41 `.default()` call sites under `packages/types/src/zod/`
are removed — `layout.zod.ts` 22, `crud.zod.ts` 11, `form.zod.ts` 5,
`views.zod.ts` 2, `app.zod.ts` 1. `@object-ui/components` reconciles the third
face objectui#8229 found: `flex`'s registration `defaultProps.align` seeded
face a separate finding found: `flex`'s registration `defaultProps.align` seeded
`'center'`, the value its own renderer never applies, so a designer-made node
laid out differently from a hand-authored one; it now seeds `'start'`.

Expand Down
2 changes: 1 addition & 1 deletion .changeset/7741-list-import-mappings-discriminate.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,6 @@ a channel added ALONGSIDE that contract, not a change to it.
user without devtools open can tell "there are none" from "we could not find out".
Three new `console.importMappings*` keys ship in all ten locale packs.

This applies framework #13906 decision 1 option A — *a thing that could not be READ is
This applies framework objectstack#13906 decision 1 option A — *a thing that could not be READ is
not a thing that is ABSENT* — at this seam. It is an already-adopted discrimination, not
a new principle.
2 changes: 1 addition & 1 deletion .changeset/8072-input-wrapper-class-mirrored.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
'@object-ui/types': patch
---

Mirror `wrapperClass` on `InputSchema` (objectui#8072 — the last
Mirror `wrapperClass` on `InputSchema` (the last
`schema.wrapperClass` reader whose value the validator admitted unexamined).

`packages/components/src/renderers/form/input.tsx` reads
Expand Down
2 changes: 1 addition & 1 deletion .changeset/8137-record-activity-calibration-repoint.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
---

Re-point the `record:activity.types` member calibration control in
`registry-inputs-spec-parity` from `'Account'` to `''` (objectui#8137).
`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
Expand Down
2 changes: 1 addition & 1 deletion .changeset/8204-refuseskind-invalid-type-decisive.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Test-only change: repair the `registry-inputs-spec-parity` kind classifier so a
whose contract is a `z.union` is judged by what the union actually refused. No published
behaviour changes; nothing outside `apps/console/src/__tests__/` is touched.

objectui#8204. `refusesKind` asked "is EVERY complaint at this node a kind complaint",
`refusesKind` asked "is EVERY complaint at this node a kind complaint",
and Zod keeps running a schema's checks after its type check has failed: for
`z.string().min(1)` the probe `[]` comes back as both `invalid_type` AND `too_small`.
Read by `every`, that pair is a CONTENT refusal — so the array probe that
Expand Down
2 changes: 1 addition & 1 deletion .changeset/8236-collapsible-open-intercept-retire.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ change the block runs on its own published `inputs` (`defaultOpen` / `disabled`

**The order is load-bearing and is not an implementation detail.** The renderer-side
exclusion lands FIRST and the retirement second, because the render path runs no
`safeParse` (objectui#9585 measured it NOT GATED). Retiring the declaration alone would
`safeParse` (a pin in this change measures it NOT GATED). Retiring the declaration alone would
have deleted the author's only warning while leaving the takeover running — strictly
worse than doing nothing. Both halves are in this change; ⛔ neither is safe to remove
alone.
Expand Down
2 changes: 1 addition & 1 deletion .changeset/8291-workspace-admin-reads-the-rung.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ the two scalar legs, where they are the raw membership role and the stored `user

The docblock that argued AGAINST reading `user.isPlatformAdmin` — on the grounds that the server
computed it as `'platform_admin' in positions`, "two spellings for one fact" — is rewritten rather
than left standing. After #15948 the flag derives from the unscoped `admin_full_access` grant and
than left standing. After objectstack#15948 the flag derives from the unscoped `admin_full_access` grant and
the array does not, so they can disagree and the rung is right.

No behaviour changes for a genuine administrator: a platform administrator on a single-tenant
Expand Down
3 changes: 1 addition & 2 deletions .changeset/8307-kanban-lane-count-honesty.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@
'@object-ui/plugin-kanban': patch
---

A Kanban lane header over a windowed fetch now says `77+` instead of `77`
(objectui#8307).
A Kanban lane header over a windowed fetch now says `77+` instead of `77`.

**The defect.** `object-kanban` fetches with a real `$top` (objectui#4025) and then
groups **what came back** into lanes client-side, so `col.cards.length` counts fetched
Expand Down
2 changes: 1 addition & 1 deletion .changeset/8408-public-form-title-description.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
---

Public form `/f/:slug` renders its authored `title` and `description` instead of the
object API name (objectui#8408).
object API name.

The one Console surface an **unauthenticated** visitor sees greeted them with a
database table name. `GET /api/v1/forms/:slug` serves the authored copy intact
Expand Down
2 changes: 1 addition & 1 deletion .changeset/8458-parity-header-pairs-figure.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ so the file never reaches a consumer. Declared as releasing nothing.
- objectui#8458: the WIDER ledger's objectui#7760 movement sentence said "16 pairs",
the one figure in that paragraph no `headerFigures` pin reached. Re-derived as 18
(13 emptied + 5 reduced), defined, and pinned.
- objectui#8248: objectui#8222's exclusion note called the seed decomposition a LIVE
- objectui#8222's exclusion note called the seed decomposition a LIVE
figure, which objectui#8243 made historical. The guidance clause is amended per the
maintainer ruling (decision batch #71); the two measurement-record clauses are
untouched, and the record-vs-guidance rule is now written once in the file header.
2 changes: 1 addition & 1 deletion .changeset/8603-record-details-hide-empty-restored.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,6 @@

**What did NOT change.** The empty ROWS of a section that still has a filled row stay with `DetailSection`'s auto-hide heuristic and the reader's "Show N empty fields" toggle, which no authored value overrides in either polarity (objectui#7129 Q2-C, left standing by the ruling). Inline-edit mode renders an all-empty section either way, so its fields never become unreachable. `record:reference_rail`'s own component-level `hideEmpty` and the `detail.hideEmptyFields` toggle label are different keys and are untouched.

**Why it moved twice.** objectui#7129 (maintainer 2026-09-01) retired the declaration and the read because `@objectstack/spec` REFUSED the key — true at the 17.2.0 pin this repo held. Upstream had already declared it (17.3.0, upstream #11289, maintainer ruling 2026-08-23 direction 1, taken from a measured symptom), so once the pin moved the contract promised an author a behaviour the renderer no longer had, and it parsed green at publish. objectui#8603 (director seat batch #137 item 3, maintainer 2026-09-15) ruled the protocol correct and restored the read; #7129's Q1-A is superseded for this key only.
**Why it moved twice.** objectui#7129 (maintainer 2026-09-01) retired the declaration and the read because `@objectstack/spec` REFUSED the key — true at the 17.2.0 pin this repo held. Upstream had already declared it (17.3.0, upstream objectstack#11289, maintainer ruling 2026-08-23 direction 1, taken from a measured symptom), so once the pin moved the contract promised an author a behaviour the renderer no longer had, and it parsed green at publish. objectui#8603 (director seat batch #137 item 3, maintainer 2026-09-15) ruled the protocol correct and restored the read; #7129's Q1-A is superseded for this key only.

All four parties now agree — the spec declares it, `@object-ui/types` declares it, the `DetailViewSectionSchema` zod mirror carries it, and the renderer reads it — pinned together in `packages/plugin-detail/src/renderers/__tests__/record-details.hideEmptyRetired-7129.test.tsx`.
Loading
Loading