test(plugin-form): object-form fields fixtures name fields as strings; the { name } row pins a stored read the declared member refuses (objectui#11550) - #11560
Merged
objectstack-fleet[bot] merged 1 commit intoOct 3, 2026
Conversation
…gs; the `{ name }` row pins a stored read the declared member refuses (objectui#11550)
Executes item 1 of triage ruling 5969880008 on the plugin-form side. The
fixtures that authored `{ name, label }` entries in `object-form` `fields`
(fieldSecurityPayload, systemManagedPayload, the flat drawer shape in
drawerFirstLoadWindow-10190) now name the fields as strings; the dropped
`label`s equalled the object fields' own. The `{ name }` row in
objectFormFieldsMembers-8071 is turned around: it pins that the
`ObjectFormSchema` mirror refuses the entry at `fields.0`, and that a STORED
entry still draws. The master-detail hand-off row is relabelled as the same
stored read. The renderer is unchanged. Section shape 3 is not touched.
Claude-Session: https://claude.ai/code/session_01FjqrwXPfSMkSfkKYDSRkN2
Co-authored-by: Claude <noreply@anthropic.com>
Contributor
✅ Console Performance Budget
The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it. 📦 Bundle Size Report
Size Limits
|
This was referenced Oct 3, 2026
objectstack-fleet
Bot
deleted the
claude/issue-11550-form-fields-names-only
branch
October 3, 2026 15:44
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Part of #11550
Clause-②: no
Executes item 1 of triage ruling
5969880008on the code side: the{ name }entry inobject-formfields(and theobject-master-detail-formhand-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 branchclaude/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:subagentof the PM seat; identity = this branch).What changes
fieldSecurityPayload.test.tsxFIELDS= seven{ name, label }entrieslabelequalled the object field's own, and the form never read itsystemManagedPayload.test.tsx{ name, label }entriesdrawerFirstLoadWindow-10190.test.tsx{ name }entries['title', 'note']. The shape exists to drive the flat (nosections) path, not the entryobjectFormFieldsMembers-8071.test.tsx, row 6{ name }spelling — recorded as drift, not a second contract"ObjectFormSchemazod mirror refuses the entry, with exactly one issue (invalid_typeatfields.0); a bare name is the accepted control; and a STORED entry still draws. The docblock paragraph that recorded the tolerance now records the retirementtopLevelFieldsWarnCoverage-8847.test.tsx{ name }is tolerated as the same member as the bare name".changeset/11550-object-form-fields-names-only.mddrawerFirstLoadWindow-10190is a fixture the claim's list did not name. It was found by re-grepping currentmain, 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 inObjectForm.tsx(the(fieldName as any).namearm) andbuildFlatFieldsinflatFields.tsstill 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:c476be0(throwaway probe, deleted, never committed)fields: [{ name: ... }]fields: ['...']ObjectFormSchemazod mirror (declaredstring[])invalid_typeatfields.0safeValidateSchema(the guide's example as written before PR B)StrictAnyComponentSchemaThe authored node's
propertiesbag is@objectstack/spec'sComponentPropsMap['object-form']row by reference (objectui#11276), and that row typesfieldsmembers 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-shacovers this landing. So the authoring door that would refuse the entry is upstream's; this side stops teaching it.The ruling's three pins
fieldsentry draws as before. Rows 1 to 3 ofobjectFormFieldsMembers-8071and the master-detail member rows are unchanged and green. The respelled fixtures exercise the string path on the default, modal and drawer arms.os:checkexample parses with names only. That is PR B;pnpm check:skill-examplesis green there.submitTargetRefusal.test.tsxandsectionFields.test.tsare 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../ObjectFormand@object-ui/types/zod, which the root vitest config aliases to source, so neither leg needed a rebuild.ObjectForm.tsx,(fieldName as any).namewas replaced byundefined: anchor 1 to 0, blob2ae1112530f5to5e6d5e79185d.objectFormFieldsMembers-8071+topLevelFieldsWarnCoverage-8847gaveTests 2 failed | 13 passed (15), exactly the two stored-read rows. Restored: blob equals HEAD,git diff HEADempty.fields: z.array(z.string())was widened toz.array(z.unknown()): anchor 1 to 0, blob360b2e65b15eto7aeed09ef049. The same two files gaveTests 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.--listFilesOnlyon 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).c476be0) and after it.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 --teston all six paths: NOT GOVERNED.no-explicit-anywarnings, none added). Population: all five are inside eslint's own config (--print-configresolves each), and--format jsonreports 5 files. Invariance:eslint.config.jsenables no type-aware linting and no rule undereslint-rules/reads the filesystem, so this diff cannot move a verdict on an untouched file. The fullpnpm lintis CI's.Acceptance notes
packages/plugin-form/src/index.tsxstill say "{ name }is tolerated" for thefieldsinput ofobject-form,view:formandembeddable-form, and "({ name }tolerated)" forobject-master-detail-form. The console warning text inwarnUnresolvedTopLevelField(sectionFields.ts) says "({ name }is tolerated)". These still teach the entry.index.tsxis held by objectui#11536 in flight, so it is not edited here. The respelling is to drop each parenthetical, with a changeset, sincesrc/text ships.FlatFieldsContext.fieldsinflatFields.tsdocuments 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.index.tsx, the console parity test) and objectui#11512 (MasterDetailForm.i18nLabels.test.tsx) touch none of these files.Generated by Claude Code