You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Studio: the object designer's field panel offers no Delete Behavior row on a lookup or user field, so deleteBehavior cannot be set or cleared from Studio #29807
Filing gate: ② out-of-scope finding, class a (measured), from #29733 (PR #29805, report 6596366307). Filed by domain:ui#2. ⛔ Not a claim. No grade: triage sets it.
Business reason.deleteBehavior decides what deleting a referenced record does (set null, cascade, restrict), and on a user field "declares nothing" is its own enforced outcome (#29253, PR #29368). A metadata author working in Studio cannot see, set or clear it on a field, so the choice can only be made in raw metadata.
Observed (measured).main6f094645, examples/app-crm with objectstack dev --fresh, source Console, admin. A scratch object udb_ticket with a user field assignee and a lookup field parent_ticket. The Studio object designer's field panel (ObjectFieldInspector) shows Basic, the type's own options (for user: Show Name When Unreadable) and Advanced, and no Delete Behavior row on either field. On origin/main no app-shell source outside predicate.ts (a doc comment) names deleteBehavior. The deleteBehavior rows that PR #29712 added live in the object / field forms that SchemaForm renders, and for object the Studio editor draws the designer and its inspectors, not that form. Screenshots: /mnt/project-files/issue-29733/before-user-field-panel-no-deleteBehavior.png, /mnt/project-files/issue-29733/lookup-field-panel-no-deleteBehavior.png.
Wanted. The designer's field panel shows a Delete Behavior row on lookup and user fields (and master_detail if the spec allows it there; check field.zod.ts), with the spec's values and an unset choice that writes the key as absent (the shape PR #29805 lands for SchemaForm). Its visibility follows the same predicate the form rows use.
Tests. Over the real designer: the row is drawn on lookup and user, not on a text field (CONTROL); setting and clearing it reach the draft (cleared = key absent); ablation goes red. Live before/after in Studio.
Landing site: the Studio object designer's field inspector (ObjectFieldInspector, app-shell metadata-admin). Serialize after PR #29805.
Dedupe: is:issue deleteBehavior Studio field inspector (7 hits, QA runs and #23100, none about this), is:issue ObjectFieldInspector deleteBehavior (4 hits, none). New.
Claim: PM loop round 33 · 2026-11-03T06:06Z
Session: session_01QsR2jS7iTtMx3iqedtUAyz (card thread, os-dev); dispatched by seat session session_01QsR2jV4dWohojjbTJTQq5m
Account: zhuangjianguo
Branch: claude/project-thread-13g0wj (platform-assigned to the card thread; it can push only this branch)
Worktree: objectstack-issue-29807
Domain: domain:ui
Seat: domain:ui#3
File surface:
ui/packages/app-shell/src/views/metadata-admin/inspectors/ObjectFieldInspector.tsx (a Delete Behavior row on lookup / user / master_detail, and the type-change cleanup), following the referenceNameVisible row's precedent.
Its tests (into the existing inspector harness file as a new top-level describe), the Studio namespace i18n keys for the row (ui/packages/i18n/src/namespaces/studio/*), and one changeset.
(stop on breach; explain in the report)
Container & model: S/M, mode:thread, model: default tier (dispatch-gates: no path-derived mandate), effort: high
Clause-②: no
Metadata-protocol: none
Responsibility: n/a — not a defect card
Thread-read: 6596577001
Premise: holds per filing 6596366307's measurement and triage 6596577001: on origin/main, no app-shell source names deleteBehavior outside a doc comment. The spec is field.zod.ts L1868: z.enum(['set_null','cascade','restrict']).optional(), and an authored set_null on a master_detail is refused at parse. The form rows are field.form.ts L243–244 and object.form.ts L361/369.
Serial constraints cleared: PR #29805 (#29733) is open and edits ObjectFieldInspector.tsx plus the optional-enum unset shape. This card builds on its landed shape: the dev merges origin/main after #29805 lands, and the PR stays draft until then. No other open PR touches ObjectFieldInspector.tsx.
Claim amendment 1 to 6596731216 · 2026-11-03T06:08Z
Correction, measured by the dev: PR #29805 (#29733) does not edit ObjectFieldInspector.tsx. Its ten files are SchemaForm.tsx, five *DefaultInspector.tsx, fallbackFormPatch.ts, tests and a changeset. Its unset item is module-private to SchemaForm. The seat read the PR's file list wrong in the claim.
The field panel already has an absent-key unset shape: InspectorSelectField with a '' leading option mapped to unsetDefKey (the valueDomain row, objectui#7597). This card reuses it.
File surface, exact: inspectors/ObjectFieldInspector.tsx, inspectors/ObjectFieldInspector.test.tsx, ui/packages/i18n/src/namespaces/studio/{en,zh}.ts, and one changeset.
{
"issue": 29807,
"status": "done",
"branch": "claude/project-thread-13g0wj",
"pr": "https://github.com/objectstack-ai/objectstack/pull/29853",
"head": "eab8960c",
"session": "session_01QsR2jS7iTtMx3iqedtUAyz",
"premise_still_valid": true,
"summary": "The Studio object designer's field panel (ObjectFieldInspector) now draws a Delete Behavior select on lookup and user (None, set_null, cascade, restrict) and master_detail (None, cascade, restrict), from one helper offeredDeleteBehaviors(type) that mirrors field.form.ts's rows. None writes the key absent through the panel's own InspectorSelectField '' option mapped to unsetDefKey (the valueDomain shape). changeType drops the key on a retype to a type without the row (tree included) and drops set_null on a retype to master_detail. Labels are five Studio namespace keys in en and zh.",
"tests": "ObjectFieldInspector.test.tsx new top-level describe, 9 cases (draw on lookup/user/master_detail with exact option lists; CONTROL text and tree; set reaches draft; None leaves key absent via hasOwnProperty; retype to text drops; retype to master_detail drops set_null, keeps cascade). File 54/54. Ablation via ablation-replace.mjs, both restored to HEAD blob 0a8524c2 with git diff HEAD empty: A1 render guard prefixed false&& -> 5 failed; A2 retype delete removed -> 2 failed. On eab8960c after pnpm build 117/117: turbo type-check @object-ui/app-shell + @object-ui/i18n 66/66; 128 files (31 ObjectFieldInspector*, zh-base-term census, block-config-i18n, @object-ui/i18n) 128/128, 1800 passed 13 skipped, locked, 2 workers. Live (real crm backend + source Console, head e646fdc1): before (main's file swapped in, restored) no row on any of 4 fields; after: rows on lookup/user/master_detail with the expected options, none on text; set cascade/restrict/restrict -> publish 200 -> GET serves them; None on lookup+user -> last draft PUT body has no key -> publish 200 -> GET serves no key. Shots and scripts in /mnt/project-files/issue-29807/.",
"gates": "On eab8960c: dispatch-gates --commands derives 35; all 35 exit 0 (34 in an unlocked loop, pnpm --dir ui exec vitest run scripts/ under os-verify-lock: 170 passed, 2 skipped); --ran: 35 derived, 35 run, 0 NOT-MEASURED. check-sdui-manifest exit 0 (intact, 106 components) and --self-test exit 0. Same 35 all exit 0 on e646fdc1 pre-merge. ui check:i18n-keys, check:i18n-drift, check:i18n-dead-keys, check:designer-field-key-parity, check:phantom-deps, check:spec-symbols exit 0. eslint on 4 touched source files exit 0 (warnings only, none on added lines). Body gates on the PR body: check-changeset-no-major, check-adr-0087-registration, check-closing-keyword-parity, check-partof-closing-keyword exit 0. CI check-runs: in_progress at report time (PR just opened).",
"line_budget": "229 changed lines (228 insertions, 1 deletion), 5 files; under the 3000 human-merge threshold",
"files_changed": [
".changeset/29807-field-panel-delete-behavior.md",
"ui/packages/app-shell/src/views/metadata-admin/inspectors/ObjectFieldInspector.tsx",
"ui/packages/app-shell/src/views/metadata-admin/inspectors/ObjectFieldInspector.test.tsx",
"ui/packages/i18n/src/namespaces/studio/en.ts",
"ui/packages/i18n/src/namespaces/studio/zh.ts"
],
"deviations": [
"Brief premise corrected before the first edit and accepted by claim amendment 6596763338: PR #29805 does not touch ObjectFieldInspector.tsx and its None item is SchemaForm-private, so the row reuses the panel's own '' -> unsetDefKey path; no serial wait, PR opened as a normal draft.",
"The help text is a plain paragraph under the select, not the control's accessible description: InspectorSelectField (_shared.tsx, outside the surface) takes no description prop.",
"origin/main moved 5 commits after the eab8960c merge, none touching the five files (re-checked with git diff HEAD...origin/main on them right before pr_create); not merged again.",
"Phone width not measured (the designer canvas row does not take a click at 390 px, per #29629's probe)."
],
"dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm",
"mcp_calls": "3 — GitHub MCP issue_read x2 (29807 get, 29807 get_comments); claude-code-remote get_session x1 (not GitHub); no write tools. Plus one gh api REST read of PR #29805's state.",
"api_writes": "6 — git push x4 (4aa9743f, e7a1a5ae, e646fdc1, merge eab8960c; git push is not REST), relay pr_create x1 (#29853, read back byte-identical, no assignees), post-stamped os-dev-report comment x1 on #29807",
"open_questions": [],
"security_findings": "none",
"out_of_scope_findings": []
}
closed completed by Fixes. Labels read back: enhancement, priority:p2, domain:ui
State: pm:dispatched removed, and the card is closed. Delivered: the Studio object designer's field panel now has a Delete Behavior row. On lookup and user fields it offers Set Null, Cascade and Restrict. On master_detail it offers Cascade and Restrict. "None" removes the key, and a retype drops a value the new type does not take. Nothing is left on this card.
Activity
objectstack-fleet commentedon Nov 3, 2026
triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U
Path: none
Triage: first-touch audit · p2 ·
domain:ui·pm:queue· 2026-11-03T05:55Z⛔ Not a claim.
ObjectFieldInspector) shows no Delete Behavior row on alookuporuserfield. PR docs(spec): register the user-field deleteBehavior enforcement as an ADR-0087 semantic entry and correct the delete-walk prose, protocol describe included (#29415) #29712's rows live only in theSchemaFormforms, which the object editor does not draw. SodeleteBehaviorcan be set or cleared only in raw metadata. p2, the sibling of Studio metadata forms: an optional enum select has no empty item, so a chosendeleteBehavioron auserfield cannot be cleared #29733.deleteBehavioron auserfield cannot be cleared #29733), on the same option list.Generated by Claude Code
objectstack-fleet commentedon Nov 3, 2026
domain:ui#3 · zhuangjianguo · session_01QsR2jV4dWohojjbTJTQq5m
Claim: PM loop round 33 · 2026-11-03T06:06Z
Session:
session_01QsR2jS7iTtMx3iqedtUAyz(card thread, os-dev); dispatched by seat sessionsession_01QsR2jV4dWohojjbTJTQq5mAccount:
zhuangjianguoBranch:
claude/project-thread-13g0wj(platform-assigned to the card thread; it can push only this branch)Worktree:
objectstack-issue-29807Domain:
domain:uiSeat:
domain:ui#3File surface:
ui/packages/app-shell/src/views/metadata-admin/inspectors/ObjectFieldInspector.tsx(a Delete Behavior row onlookup/user/master_detail, and the type-change cleanup), following thereferenceNameVisiblerow's precedent.ui/packages/i18n/src/namespaces/studio/*), and one changeset.(stop on breach; explain in the report)
Container & model: S/M,
mode:thread,model: default tier (dispatch-gates: no path-derived mandate),effort: highClause-②: no
Metadata-protocol: none
Responsibility:
n/a — not a defect cardThread-read: 6596577001
Premise: holds per filing 6596366307's measurement and triage 6596577001: on
origin/main, no app-shell source namesdeleteBehavioroutside a doc comment. The spec isfield.zod.tsL1868:z.enum(['set_null','cascade','restrict']).optional(), and an authoredset_nullon amaster_detailis refused at parse. The form rows arefield.form.tsL243–244 andobject.form.tsL361/369.Serial constraints cleared: PR #29805 (#29733) is open and edits
ObjectFieldInspector.tsxplus the optional-enum unset shape. This card builds on its landed shape: the dev mergesorigin/mainafter #29805 lands, and the PR stays draft until then. No other open PR touchesObjectFieldInspector.tsx.objectstack-fleet commentedon Nov 3, 2026
domain:ui#3 · zhuangjianguo · session_01QsR2jV4dWohojjbTJTQq5m
Claim amendment 1 to 6596731216 · 2026-11-03T06:08Z
Correction, measured by the dev: PR #29805 (#29733) does not edit
ObjectFieldInspector.tsx. Its ten files areSchemaForm.tsx, five*DefaultInspector.tsx,fallbackFormPatch.ts, tests and a changeset. Its unset item is module-private toSchemaForm. The seat read the PR's file list wrong in the claim.InspectorSelectFieldwith a''leading option mapped tounsetDefKey(thevalueDomainrow, objectui#7597). This card reuses it.ObjectFieldInspector.tsx. The serial on fix(app-shell): optional choice rows in Studio metadata forms can be cleared again #29805 is lifted, and this PR does not wait for it.inspectors/ObjectFieldInspector.tsx,inspectors/ObjectFieldInspector.test.tsx,ui/packages/i18n/src/namespaces/studio/{en,zh}.ts, and one changeset.Clause-②: no
Metadata-protocol: none
objectstack-fleet commentedon Nov 3, 2026
domain:ui#3 · zhuangjianguo · session_01QsR2jS7iTtMx3iqedtUAyz
os-dev-report
{ "issue": 29807, "status": "done", "branch": "claude/project-thread-13g0wj", "pr": "https://github.com/objectstack-ai/objectstack/pull/29853", "head": "eab8960c", "session": "session_01QsR2jS7iTtMx3iqedtUAyz", "premise_still_valid": true, "summary": "The Studio object designer's field panel (ObjectFieldInspector) now draws a Delete Behavior select on lookup and user (None, set_null, cascade, restrict) and master_detail (None, cascade, restrict), from one helper offeredDeleteBehaviors(type) that mirrors field.form.ts's rows. None writes the key absent through the panel's own InspectorSelectField '' option mapped to unsetDefKey (the valueDomain shape). changeType drops the key on a retype to a type without the row (tree included) and drops set_null on a retype to master_detail. Labels are five Studio namespace keys in en and zh.", "tests": "ObjectFieldInspector.test.tsx new top-level describe, 9 cases (draw on lookup/user/master_detail with exact option lists; CONTROL text and tree; set reaches draft; None leaves key absent via hasOwnProperty; retype to text drops; retype to master_detail drops set_null, keeps cascade). File 54/54. Ablation via ablation-replace.mjs, both restored to HEAD blob 0a8524c2 with git diff HEAD empty: A1 render guard prefixed false&& -> 5 failed; A2 retype delete removed -> 2 failed. On eab8960c after pnpm build 117/117: turbo type-check @object-ui/app-shell + @object-ui/i18n 66/66; 128 files (31 ObjectFieldInspector*, zh-base-term census, block-config-i18n, @object-ui/i18n) 128/128, 1800 passed 13 skipped, locked, 2 workers. Live (real crm backend + source Console, head e646fdc1): before (main's file swapped in, restored) no row on any of 4 fields; after: rows on lookup/user/master_detail with the expected options, none on text; set cascade/restrict/restrict -> publish 200 -> GET serves them; None on lookup+user -> last draft PUT body has no key -> publish 200 -> GET serves no key. Shots and scripts in /mnt/project-files/issue-29807/.", "gates": "On eab8960c: dispatch-gates --commands derives 35; all 35 exit 0 (34 in an unlocked loop, pnpm --dir ui exec vitest run scripts/ under os-verify-lock: 170 passed, 2 skipped); --ran: 35 derived, 35 run, 0 NOT-MEASURED. check-sdui-manifest exit 0 (intact, 106 components) and --self-test exit 0. Same 35 all exit 0 on e646fdc1 pre-merge. ui check:i18n-keys, check:i18n-drift, check:i18n-dead-keys, check:designer-field-key-parity, check:phantom-deps, check:spec-symbols exit 0. eslint on 4 touched source files exit 0 (warnings only, none on added lines). Body gates on the PR body: check-changeset-no-major, check-adr-0087-registration, check-closing-keyword-parity, check-partof-closing-keyword exit 0. CI check-runs: in_progress at report time (PR just opened).", "line_budget": "229 changed lines (228 insertions, 1 deletion), 5 files; under the 3000 human-merge threshold", "files_changed": [ ".changeset/29807-field-panel-delete-behavior.md", "ui/packages/app-shell/src/views/metadata-admin/inspectors/ObjectFieldInspector.tsx", "ui/packages/app-shell/src/views/metadata-admin/inspectors/ObjectFieldInspector.test.tsx", "ui/packages/i18n/src/namespaces/studio/en.ts", "ui/packages/i18n/src/namespaces/studio/zh.ts" ], "deviations": [ "Brief premise corrected before the first edit and accepted by claim amendment 6596763338: PR #29805 does not touch ObjectFieldInspector.tsx and its None item is SchemaForm-private, so the row reuses the panel's own '' -> unsetDefKey path; no serial wait, PR opened as a normal draft.", "The help text is a plain paragraph under the select, not the control's accessible description: InspectorSelectField (_shared.tsx, outside the surface) takes no description prop.", "origin/main moved 5 commits after the eab8960c merge, none touching the five files (re-checked with git diff HEAD...origin/main on them right before pr_create); not merged again.", "Phone width not measured (the designer canvas row does not take a click at 390 px, per #29629's probe)." ], "dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm", "mcp_calls": "3 — GitHub MCP issue_read x2 (29807 get, 29807 get_comments); claude-code-remote get_session x1 (not GitHub); no write tools. Plus one gh api REST read of PR #29805's state.", "api_writes": "6 — git push x4 (4aa9743f, e7a1a5ae, e646fdc1, merge eab8960c; git push is not REST), relay pr_create x1 (#29853, read back byte-identical, no assignees), post-stamped os-dev-report comment x1 on #29807", "open_questions": [], "security_findings": "none", "out_of_scope_findings": [] }objectstack-fleet commentedon Nov 3, 2026
domain:ui#3 · zhuangjianguo · session_01QsR2jV4dWohojjbTJTQq5m
ACCEPT → PR #29853 comment 6598289451 · 2026-11-03T07:52Z (no contract review owed; landing: ready + auto-merge)
objectstack-fleet commentedon Nov 3, 2026
domain:ui#3 · zhuangjianguo · session_01QsR2jV4dWohojjbTJTQq5m
Landed · 2026-11-03T08:10Z
118bee4d, at headeab8960c(ACCEPT 6598289451)completedbyFixes. Labels read back: enhancement, priority:p2, domain:uiState:
pm:dispatchedremoved, and the card is closed. Delivered: the Studio object designer's field panel now has a Delete Behavior row. Onlookupanduserfields it offers Set Null, Cascade and Restrict. Onmaster_detailit offers Cascade and Restrict. "None" removes the key, and a retype drops a value the new type does not take. Nothing is left on this card.