Repository navigation
Commit 806f327
test(plugin-form): object-form
Part of #11550
Clause-②: no
Executes item 1 of triage ruling `5969880008` on the code side: the `{
name }` entry in `object-form` `fields` (and the
`object-master-detail-form` hand-off) is retired from the authoring
faces this PR owns. Item 2, the section "shape 3" inline runtime entry,
is not touched. The governed half, the page-builder guide, is a separate
draft PR from branch `claude/issue-11550-guide-fields-names-only`. The
two land independently, in either order: neither reads the other's
files, and the guide example passes every door with or without this PR.
Session: `https://claude.ai/code/session_01FjqrwXPfSMkSfkKYDSRkN2`
(os-dev, `mode:subagent` of the PM seat; identity = this branch).
## What changes
| File | Before | After |
|---|---|---|
| `fieldSecurityPayload.test.tsx` | `FIELDS` = seven `{ name, label }`
entries | seven field names. Every dropped `label` equalled the object
field's own, and the form never read it |
| `systemManagedPayload.test.tsx` | three `{ name, label }` entries |
three names |
| `drawerFirstLoadWindow-10190.test.tsx` | the "flat fields" shape was
two `{ name }` entries | `['title', 'note']`. The shape exists to drive
the flat (no `sections`) path, not the entry |
| `objectFormFieldsMembers-8071.test.tsx`, row 6 | "tolerates the `{
name }` spelling — recorded as drift, not a second contract" | turned
around: the `ObjectFormSchema` zod mirror refuses the entry, with
exactly one issue (`invalid_type` at `fields.0`); a bare name is the
accepted control; and a STORED entry still draws. The docblock paragraph
that recorded the tolerance now records the retirement |
| `topLevelFieldsWarnCoverage-8847.test.tsx` | "`{ name }` is tolerated
as the same member as the bare name" | relabelled: the master-detail
hand-off keeps the STORED read; not an authoring shape. Same assertion |
| `.changeset/11550-object-form-fields-names-only.md` | none | empty
frontmatter: test-only, no package released |
`drawerFirstLoadWindow-10190` is a fixture the claim's list did not
name. It was found by re-grepping current `main`, and it is in the
claimed class (a fixture that authors `{ name }` field entries).
## The read stays, as stored-value tolerance
`SimpleObjectForm`'s field loop in `ObjectForm.tsx` (the `(fieldName as
any).name` arm) and `buildFlatFields` in `flatFields.ts` still draw a `{
name }` entry. The ruling allows it ("A stored `{ name }` entry may stay
readable, as objectui#11533 kept stored rules readable"), and
measurement shows no stricter door this repo could own:
| Door, measured on `c476be0` (throwaway probe, deleted, never
committed) | `fields: [{ name: ... }]` | `fields: ['...']` |
|---|---|---|
| `ObjectFormSchema` zod mirror (declared `string[]`) | refused,
`invalid_type` at `fields.0` | accepted |
| authored node via `safeValidateSchema` (the guide's example as written
before PR B) | accepted | accepted |
| authored node via `StrictAnyComponentSchema` | accepted | accepted |
The authored node's `properties` bag is `@objectstack/spec`'s
`ComponentPropsMap['object-form']` row by reference (objectui#11276),
and that row types `fields` members as unknown today. objectui does not
narrow a spec row. Triage notes that objectstack-ai/objectstack#21464
types the member as names once its `.objectui-sha` covers this landing.
So the authoring door that would refuse the entry is upstream's; this
side stops teaching it.
## The ruling's three pins
- **A string `fields` entry draws as before.** Rows 1 to 3 of
`objectFormFieldsMembers-8071` and the master-detail member rows are
unchanged and green. The respelled fixtures exercise the string path on
the default, modal and drawer arms.
- **The guide's `os:check` example parses with names only.** That is PR
B; `pnpm check:skill-examples` is green there.
- **The section shape-3 pins stay green.**
`submitTargetRefusal.test.tsx` and `sectionFields.test.ts` are untouched
and green.
## Ablation (one-shot, from the committed state, restored)
Both legs ran through `ablation-replace.mjs` (anchor must hit once,
landing proven by count and blob hash) inside a script with an
EXIT/INT/TERM restore trap. The tests import `../ObjectForm` and
`@object-ui/types/zod`, which the root vitest config aliases to source,
so neither leg needed a rebuild.
- **Leg A, the read.** In `ObjectForm.tsx`, `(fieldName as any).name`
was replaced by `undefined`: anchor 1 to 0, blob `2ae1112530f5` to
`5e6d5e79185d`. `objectFormFieldsMembers-8071` +
`topLevelFieldsWarnCoverage-8847` gave `Tests 2 failed | 13 passed
(15)`, exactly the two stored-read rows. Restored: blob equals HEAD,
`git diff HEAD` empty.
- **Leg B, the declared side.** In the mirror, `fields:
z.array(z.string())` was widened to `z.array(z.unknown())`: anchor 1 to
0, blob `360b2e65b15e` to `7aeed09ef049`. The same two files gave `Tests
1 failed | 14 passed (15)`, row 6 only (`expected [] to deeply equal [ {
code: 'invalid_type', … } ]`). Restored the same way.
## Verification (at `12d4fb1`)
- `pnpm --workspace-concurrency=2 --filter '@object-ui/plugin-form^...'
build`: exit 0.
- `pnpm --filter @object-ui/plugin-form type-check` (`tsc --noEmit &&
tsc -p tsconfig.test.json`): exit 0. `--listFilesOnly` on the test
config lists all five edited test files, among 162 test files.
- `pnpm exec vitest run packages/plugin-form/`: `Test Files 162 passed
(162)`, `Tests 1859 passed | 1 skipped (1860)`.
- The five edited files plus the two shape-3 pins: 104 of 104 passed
before the edit (BASE `c476be0`) and after it.
- Gates, each exit 0: `check:control-bytes`, `check:new-line-citations`
(0 new), `check-changeset-presence` (one empty-frontmatter changeset),
`check:changeset-claims`, `check-changeset-no-major`,
`check-changeset-fixed`, `check:pending-changeset-literals`,
`check:test-path-roots`, `check:vi-mock-specifiers`,
`check-vi-mock-override-shape`. `check-governed-queue-guard.mjs --test`
on all six paths: NOT GOVERNED.
- ESLint, narrowed to the five edited files: 0 errors (25
`no-explicit-any` warnings, none added). Population: all five are inside
eslint's own config (`--print-config` resolves each), and `--format
json` reports 5 files. Invariance: `eslint.config.js` enables no
type-aware linting and no rule under `eslint-rules/` reads the
filesystem, so this diff cannot move a verdict on an untouched file. The
full `pnpm lint` is CI's.
## Acceptance notes
- **Authoring faces outside this claim, not edited, reported to the
seat.** The published registration descriptions in
`packages/plugin-form/src/index.tsx` still say "`{ name }` is tolerated"
for the `fields` input of `object-form`, `view:form` and
`embeddable-form`, and "(`{ name }` tolerated)" for
`object-master-detail-form`. The console warning text in
`warnUnresolvedTopLevelField` (`sectionFields.ts`) says "(`{ name }` is
tolerated)". These still teach the entry. `index.tsx` is held by
objectui#11536 in flight, so it is not edited here. The respelling is to
drop each parenthetical, with a changeset, since `src/` text ships.
- `FlatFieldsContext.fields` in `flatFields.ts` documents the `{ name }`
read. It is not exported from the package entry, and it describes the
read that stays, so it is left as it is.
- objectui#11536 (`index.tsx`, the console parity test) and
objectui#11512 (`MasterDetailForm.i18nLabels.test.tsx`) touch none of
these files.
---
_Generated by [Claude
Code](https://claude.ai/code/session_01FjqrwXPfSMkSfkKYDSRkN2)_
Co-authored-by: Claude <noreply@anthropic.com>fields fixtures name fields as strings; the { name } row pins a stored read the declared member refuses (objectui#11550) (#11560)1 parent b34cc14 commit 806f327
6 files changed
Lines changed: 35 additions & 24 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
73 | 73 | | |
74 | 74 | | |
75 | 75 | | |
76 | | - | |
| 76 | + | |
77 | 77 | | |
78 | 78 | | |
79 | 79 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
49 | 49 | | |
50 | 50 | | |
51 | 51 | | |
52 | | - | |
53 | | - | |
54 | | - | |
55 | | - | |
56 | | - | |
57 | | - | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
58 | 61 | | |
59 | 62 | | |
60 | 63 | | |
61 | 64 | | |
62 | 65 | | |
63 | 66 | | |
| 67 | + | |
64 | 68 | | |
65 | 69 | | |
66 | 70 | | |
67 | 71 | | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
68 | 76 | | |
69 | 77 | | |
70 | 78 | | |
| |||
162 | 170 | | |
163 | 171 | | |
164 | 172 | | |
165 | | - | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
166 | 182 | | |
167 | 183 | | |
168 | 184 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
50 | 50 | | |
51 | 51 | | |
52 | 52 | | |
53 | | - | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
54 | 57 | | |
55 | 58 | | |
56 | 59 | | |
| |||
251 | 254 | | |
252 | 255 | | |
253 | 256 | | |
254 | | - | |
| 257 | + | |
255 | 258 | | |
256 | 259 | | |
257 | 260 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
127 | 127 | | |
128 | 128 | | |
129 | 129 | | |
130 | | - | |
131 | | - | |
132 | | - | |
133 | | - | |
134 | | - | |
135 | | - | |
136 | | - | |
137 | | - | |
138 | | - | |
| 130 | + | |
139 | 131 | | |
140 | 132 | | |
141 | 133 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
214 | 214 | | |
215 | 215 | | |
216 | 216 | | |
217 | | - | |
218 | | - | |
219 | | - | |
220 | | - | |
221 | | - | |
| 217 | + | |
222 | 218 | | |
223 | 219 | | |
224 | 220 | | |
| |||
0 commit comments