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
fields: userCell gates by the authored reference of a user field, but objectstack now resolves every user field to sys_user (objectstack#24952) #25937
Filing gate ③ a follow-up owed by landing work, from the contract review of objectstack-ai/objectstack PR #25074 (card #24952). Filed by the objectstack domain:spec seat 3 (session session_01D6F9axfoPzR7t8G1J7Ytzz). ⛔ Not a claim. Grade and routing are this repo's triage's.
FieldSchema refuses a type: 'user' field whose reference names anything but sys_user.
referenceTargetOf resolves every user field to sys_user, including a stored object saved before the refusal that still carries a foreign reference. Such an object keeps loading.
The drift here
At the pinned objectstack SHA cf153eb2e5:
packages/fields/src/__tests__/userCell.readGate-10535.test.tsx:154-164 builds { type: 'user', reference: 'crm_member' } and pins that the cell's person object is the authored reference.
The user cell reads reference directly, so for such a stored body it gates its read by a different object than the one the runtime resolves.
This is not a pin-gate hazard: objectui parses neither FieldSchema nor ObjectSchema and does not call referenceTargetOf.
Candidate shape (for triage)
Have the user cell treat a user field's person object as sys_user (the type's constant), ignoring an authored reference.
Method: objectui issues updated since 2026-10-01 (any state), matched on userCell|readGate-10535|crm_member. The only hit is objectui#13199, closed and on a different subject. New.
Dedupe words: userCell reference crm_member, user field sys_user renderer, readGate-10535.
objectui's .objectstack-sha is 06cab4849a (objectstack 18.0.0's version commit). REST compare 2069b81c2...06cab4849a reads behind_by 165, so the pin does not contain it.
The pin cannot simply move. objectui#13261 (the last pin move) records that "the pin does not move past 06cab4849a until objectui 18.0.0 is published", and at any later objectstack main commit "objectui's publish is refused until objectstack 18.1.0 is on npm".
So this card waits on a pin move that releases gate, and no pin-move card for it exists yet (objectui's last 300 updated issues and PRs, grepped for pin with objectstack: open hits are only objectui#13017, which is unrelated). The executable unlock reading: curl -sS https://api.github.com/repos/objectstack-ai/objectstack/compare/2069b81c266836fd6d7b52fc5e6679c734bdcd3c...$(git show origin/main:.objectstack-sha) in an objectui checkout answers statusahead or identical.
For triage: the legal parking is pm:blocked + Blocked-by: on a pin-move chore card, and that card does not exist yet. This seat leaves the card in pm:queue (filed 2026-10-21T07:16Z).
Pause lifted · domain:ui seat 4 (vacant; written by its signed-off session session_01XWGTsmqrtrt1Zqh1ioWqsT) · 2026-10-25T14:11Z
The os-sales tenure held this card back for the planned objectui → objectstack repo move. The maintainer lifted that pause in this project on 2026-10-25T14:08Z: 「你放回队列就写」. The card already carries pm:queue and is dispatchable under the normal rules. Nothing dispatches it now, because the domain:ui lane is off duty, so a future seat picks it up from the queue.
Transferred 2026-10-26T04:51Z from objectstack-ai/objectui#13305, with its comments and timeline; the old URL redirects here. objectui moved into this repository as the ui/ workspace (epic #25677) and is being archived (#25854). The body is left exactly as filed.
Paths. Read every repository path in the body with a ui/ prefix: packages/fields/src/__tests__/userCell.readGate-10535.test.tsx is now ui/packages/fields/src/__tests__/userCell.readGate-10535.test.tsx.
⛔ Not a claim, ⛔ not a dispatch. First touch after the transfer from objectui. The card had no triage audit comment there or here, which is what the domain:ui seat (#25966) needs before it can pick it.
Claim: PM loop round 1 · 2026-10-26T08:29Z
Session: session_01SMps7wq7rBTk53e8KTSEup
Account: os-steve
Branch: claude/issue-25937-user-cell-sys-user
Worktree: objectstack-issue-25937
Domain: domain:ui
Seat: domain:ui#2
File surface: ui/packages/fields/src/index.tsx (UserCellRenderer and its JSDoc only, the personObject read; NOT the DateTimeCellRenderer region seat 1's #25897 holds), ui/packages/fields/src/widgets/UserField.tsx (the picker's reference fallback, same reader pattern, declared here by the seat), ui/packages/fields/src/__tests__/userCell.readGate-10535.test.tsx (the crm_member case flips), scripts/sdui-manifest.record.json (re-record), root .changeset/25937-user-cell-sys-user.md (stop on breach; explain in the report). ⛔ ui/.github/** and the root .github/workflows/ci.yml are out of bounds (maintainer's word).
Container & model: S, mode:subagent, model: default tier (dispatch-gates --tier --repo objectstack-ai/objectstack: no path-derived mandate), effort: medium
Clause-②: no
Metadata-protocol: none
Responsibility: the user cell's own read of the authored reference (renderer drift after #24952) | the runtime's referenceTargetOf already resolves every user field to sys_user | any reader of a stored object saved before the refusal that still carries a foreign reference
Thread-read: 6410220656
Premise: holds — on origin/main05f7758f05UserCellRenderer reads field.reference || 'sys_user'; the spec refuses a foreign user reference and referenceTargetOf maps user to sys_user (read-only premise check, 2026-10-26T08:25Z)
Serial constraints cleared: ui/packages/fields/src/index.tsx is in #25897's surface (seat 1, DateTimeCellRenderer region only); this card edits the UserCellRenderer region — merge main before opening and before landing. No other open claim on these files.
Writes: PR only via the relay op pr_create; comments/labels only via the relay write tools; ⛔ no GitHub MCP writes.
Mechanism assumption (measure it): the read gate is keyed by object name, so a stored body with a foreign reference now gates by the sys_user policy. That is the runtime's resolution and the card's intent; state it in the PR.
Suggested route: use the type's constant sys_user, not the throwing referenceTargetOf helper in a render path.
{
"issue": 25937,
"status": "done",
"branch": "claude/issue-25937-user-cell-sys-user",
"pr": "https://github.com/objectstack-ai/objectstack/pull/26050",
"session": "session_01SMps7wq7rBTk53e8KTSEup",
"premise_still_valid": true,
"summary": "Measured on origin/main 05f7758f: UserCellRenderer derived personObject from field.reference || 'sys_user' and passed it to withoutDeniedFields; UserField used meta?.reference || 'sys_user'. Both assumptions hold. Both now use the user type's constant 'sys_user', matching the spec contract from #24952 (FieldSchema refuses a foreign user reference, and referenceTargetOf maps user to sys_user). The renderer no longer reads field at all. The JSDoc, the test header and the old test title are rewritten. The crm_member case flips: that field is now gated by the sys_user policy, byte-equal to a plain user field. The retired reference_to case is unchanged and passes. The PR body states mechanism assumption 3: the gate is keyed by object name, so a stored body with a foreign reference now gates by the sys_user policy. scripts/sdui-manifest.record.json was re-recorded; only the registry digest changed, and the manifest is byte-identical. The landing is exactly the five claimed files.",
"tests": "All at head 11a85a02, with origin/main c8cb510a merged in. (1) cd ui && pnpm exec vitest run --maxWorkers=2 packages/fields/ under the lock: Test Files 277 passed | 1 skipped (278), Tests 4290 passed | 7 skipped (4297), VERDICT command-exit 0. (2) pnpm --filter @object-ui/fields type-check (tsc --noEmit && tsc -p tsconfig.test.json): VERDICT command-exit 0. (3) eslint over the 3 edited ui files: 0 errors (152 warnings, all already there). (4) Ablation with the fix committed first and no dist (the test imports ../index from source). scripts/ablation-replace.mjs reinstated the field.reference read: anchor 1->0, blob 2ac4abd3f41c->644362b7ff75. userCell.readGate-10535.test.tsx went 1 failed | 6 passed; the flipped case failed at :164 with expected ... not to contain 'Amy Lin'. On restore the blob matched HEAD 2ac4abd3f41c and git diff HEAD was empty. Green leg at the same head: 7/7 passed. (5) node scripts/gen-sdui-manifest-node.mjs under the lock: VERDICT command-exit 0, manifest sha256 1f6e1ccb925a unchanged, record re-written; node scripts/check-sdui-manifest.mjs passes.",
"gates": "Derived at 11a85a02 with node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack: 46 commands, each run separately, exit codes captured before any pipe, all 46 exit 0. pnpm check:type-check-debt was killed by a 300 s local timeout (124) on its first run; the rerun exited 0 (1 ledger entry re-measured, no surplus). --ran reconciliation: 46 derived, 46 run, 0 NOT-MEASURED, 0 UNRUN (a DERIVED zero, every line carrying an exit code). Outside the derived set: node scripts/check-changeset-fixed.mjs exit 0 (its roster is under .changeset/, which this PR touches). CI on PR #26050: no check-runs had been reported for head 11a85a02 when this was written (in_progress); not waited on.",
"dogfood_battery": "n/a: the PR title has no ! and Clause-② is 'no' with no (narrowing) arm",
"line_budget": "72 changed lines in the code commit (+49/-23, 4 files) plus 1 changed line in the record re-write; under the 3000 human-merge threshold",
"files_changed": [
".changeset/25937-user-cell-sys-user.md",
"scripts/sdui-manifest.record.json",
"ui/packages/fields/src/__tests__/userCell.readGate-10535.test.tsx",
"ui/packages/fields/src/index.tsx",
"ui/packages/fields/src/widgets/UserField.tsx"
],
"deviations": [
"The first commit (d9b0e1e5) was made with git commit --no-verify. At that moment the git hooks were not yet registered for this clone (core.hooksPath unset), because pnpm install was still running, so no hook was actually skipped. Later commits ran the hooks. No commit was rewritten.",
"pnpm install took about 20 minutes and was moved to the background by the harness's 10-minute foreground ceiling. I waited for it in the foreground with tail --pid before running anything that needed it.",
"ui tests run through the ui workspace's vitest: cd ui && pnpm exec vitest run packages/fields/. The literal pnpm --filter @object-ui/fields exec vitest failed with 'vitest not found', because vitest is installed only at ui/node_modules/.bin.",
"The PR was opened before the CI run on PR #26050 started; gates are reported as in_progress."
],
"mcp_calls": "0: no GitHub MCP tools were called",
"api_writes": "2: (1) POST /repos/objectstack-ai/objectstack/dispatches, a fleet-write relay pr_create stroke (run 40305075601, success) that opened draft PR #26050 and added assignee os-steve; (2) this os-dev-report comment, POST /repos/objectstack-ai/objectstack/issues/25937/comments via scripts/pm/post-stamped.mjs. git push is not counted.",
"open_questions": [],
"out_of_scope_findings": [
"carrier: none · noted in the PR's Acceptance notes, not filed · the LookupCellRenderer comment in ui/packages/fields/src/index.tsx (about line 2566) still lists UserField among the readers of reference; it is now stale, and it sits outside the claimed UserCellRenderer region",
"carrier: none · observation only · RecordMetaFooter UserRef (ui/packages/plugin-detail) still builds reference from fieldDef?.reference || 'sys_user'; for a user-typed audit field the cell now ignores it, so nothing visible changes"
]
}
Surface amendment · domain:ui seat 2 · 2026-10-26T10:34Z
Session: session_01SMps7wq7rBTk53e8KTSEup
Seat: domain:ui#2
Branch: claude/issue-25937-user-cell-sys-user
Amends: Claim on this card
File surface (added): ui/packages/plugin-grid/src/relationalMetaKeys.ts. Only the reference entry of RELATIONAL_META_READ_SET changes: user-editor leaves its readers. Reason: CI Test UI (1/16) on PR #26050 (head 11d09014) fails relationalMetaCopySet.derivation.test.ts:327, the "carries no orphan" check. UserField.tsx no longer reads meta.reference, so the table's reader entry is stale. Fixing the entry is what the derivation test requires. No other claim holds this file, and ObjectGrid.tsx is not touched.
Status: the user cell and UserField gate on the authored reference of a user field, and the grid's relational meta keys follow. The fields line drains here. On the plugin-grid line #26217 (#25942 step 2) is next. pm:dispatched removed.
Activity
objectstack-fleet commentedon Oct 22, 2026
Not dispatched this round ·
domain:uiseat 3 ·session_019Bd3muSBdHUFdJiKqnsM2W(os-sales) · 2026-10-22T10:00Z · ⛔ Not a claim, ⛔ not a state change.The card's own ordering line, "Land after the objectstack pin moves past PR #25074", does not hold yet:
2069b81c2(2026-10-22T08:40Z)..objectstack-shais06cab4849a(objectstack 18.0.0's version commit). RESTcompare 2069b81c2...06cab4849areadsbehind_by 165, so the pin does not contain it.06cab4849auntil objectui 18.0.0 is published", and at any later objectstackmaincommit "objectui's publish is refused until objectstack 18.1.0 is on npm".So this card waits on a pin move that releases gate, and no pin-move card for it exists yet (objectui's last 300 updated issues and PRs, grepped for
pinwithobjectstack: open hits are only objectui#13017, which is unrelated). The executable unlock reading:curl -sS https://api.github.com/repos/objectstack-ai/objectstack/compare/2069b81c266836fd6d7b52fc5e6679c734bdcd3c...$(git show origin/main:.objectstack-sha)in an objectui checkout answersstatusaheadoridentical.For triage: the legal parking is
pm:blocked+Blocked-by:on a pin-move chore card, and that card does not exist yet. This seat leaves the card inpm:queue(filed 2026-10-21T07:16Z).objectstack-fleet commentedon Oct 25, 2026
Pause lifted ·
domain:uiseat 4 (vacant; written by its signed-off sessionsession_01XWGTsmqrtrt1Zqh1ioWqsT) · 2026-10-25T14:11ZThe
os-salestenure held this card back for the planned objectui → objectstack repo move. The maintainer lifted that pause in this project on 2026-10-25T14:08Z: 「你放回队列就写」. The card already carriespm:queueand is dispatchable under the normal rules. Nothing dispatches it now, because thedomain:uilane is off duty, so a future seat picks it up from the queue.Generated by Claude Code
objectstack-fleet commentedon Oct 26, 2026
Transferred 2026-10-26T04:51Z from objectstack-ai/objectui#13305, with its comments and timeline; the old URL redirects here. objectui moved into this repository as the
ui/workspace (epic #25677) and is being archived (#25854). The body is left exactly as filed.Paths. Read every repository path in the body with a
ui/prefix:packages/fields/src/__tests__/userCell.readGate-10535.test.tsxis nowui/packages/fields/src/__tests__/userCell.readGate-10535.test.tsx.No stale
pm:dispatchedor assignee to strip.Generated by Claude Code
objectstack-fleet commentedon Oct 26, 2026
Triage: first touch —
bug·priority:p2·domain:ui·area:records·pm:queue· triage seat ·session_01AavokzJ5DndAwitDXvKy4U· 2026-10-26T07:02Z⛔ Not a claim, ⛔ not a dispatch. First touch after the transfer from objectui. The card had no triage audit comment there or here, which is what the
domain:uiseat (#25966) needs before it can pick it.userfields resolve tosys_user). Now thatui/is in this tree, the renderer change can land against the samemain, with no pin wait.Generated by Claude Code
objectstack-fleet commentedon Oct 26, 2026
Claim: PM loop round 1 · 2026-10-26T08:29Z
Session:
session_01SMps7wq7rBTk53e8KTSEupAccount:
os-steveBranch:
claude/issue-25937-user-cell-sys-userWorktree:
objectstack-issue-25937Domain:
domain:uiSeat:
domain:ui#2File surface:
ui/packages/fields/src/index.tsx(UserCellRendererand its JSDoc only, thepersonObjectread; NOT theDateTimeCellRendererregion seat 1's #25897 holds),ui/packages/fields/src/widgets/UserField.tsx(the picker'sreferencefallback, same reader pattern, declared here by the seat),ui/packages/fields/src/__tests__/userCell.readGate-10535.test.tsx(thecrm_membercase flips),scripts/sdui-manifest.record.json(re-record), root.changeset/25937-user-cell-sys-user.md(stop on breach; explain in the report). ⛔ui/.github/**and the root.github/workflows/ci.ymlare out of bounds (maintainer's word).Container & model:
S,mode:subagent,model: default tier (dispatch-gates --tier --repo objectstack-ai/objectstack: no path-derived mandate),effort: mediumClause-②: no
Metadata-protocol: none
Responsibility:
the user cell's own read of the authored reference (renderer drift after #24952) | the runtime's referenceTargetOf already resolves every user field to sys_user | any reader of a stored object saved before the refusal that still carries a foreign referenceThread-read: 6410220656
Premise: holds — on
origin/main05f7758f05UserCellRendererreadsfield.reference || 'sys_user'; the spec refuses a foreignuserreference andreferenceTargetOfmapsusertosys_user(read-only premise check, 2026-10-26T08:25Z)Serial constraints cleared:
ui/packages/fields/src/index.tsxis in #25897's surface (seat 1,DateTimeCellRendererregion only); this card edits theUserCellRendererregion — mergemainbefore opening and before landing. No other open claim on these files.Writes: PR only via the relay op
pr_create; comments/labels only via the relay write tools; ⛔ no GitHub MCP writes.userfield whosereferencenames an object other thansys_user, and resolve everyuserfield tosys_user(the refusal half of #24808) #24952 / PR feat(spec)!: refuse a user field whose reference names an object other than sys_user; every user field resolves to sys_user #25074) is the governing text: auserfield's target is fixed tosys_user.referencenow gates by thesys_userpolicy. That is the runtime's resolution and the card's intent; state it in the PR.sys_user, not the throwingreferenceTargetOfhelper in a render path.objectstack-fleet commentedon Oct 26, 2026
os-dev-report
{ "issue": 25937, "status": "done", "branch": "claude/issue-25937-user-cell-sys-user", "pr": "https://github.com/objectstack-ai/objectstack/pull/26050", "session": "session_01SMps7wq7rBTk53e8KTSEup", "premise_still_valid": true, "summary": "Measured on origin/main 05f7758f: UserCellRenderer derived personObject from field.reference || 'sys_user' and passed it to withoutDeniedFields; UserField used meta?.reference || 'sys_user'. Both assumptions hold. Both now use the user type's constant 'sys_user', matching the spec contract from #24952 (FieldSchema refuses a foreign user reference, and referenceTargetOf maps user to sys_user). The renderer no longer reads field at all. The JSDoc, the test header and the old test title are rewritten. The crm_member case flips: that field is now gated by the sys_user policy, byte-equal to a plain user field. The retired reference_to case is unchanged and passes. The PR body states mechanism assumption 3: the gate is keyed by object name, so a stored body with a foreign reference now gates by the sys_user policy. scripts/sdui-manifest.record.json was re-recorded; only the registry digest changed, and the manifest is byte-identical. The landing is exactly the five claimed files.", "tests": "All at head 11a85a02, with origin/main c8cb510a merged in. (1) cd ui && pnpm exec vitest run --maxWorkers=2 packages/fields/ under the lock: Test Files 277 passed | 1 skipped (278), Tests 4290 passed | 7 skipped (4297), VERDICT command-exit 0. (2) pnpm --filter @object-ui/fields type-check (tsc --noEmit && tsc -p tsconfig.test.json): VERDICT command-exit 0. (3) eslint over the 3 edited ui files: 0 errors (152 warnings, all already there). (4) Ablation with the fix committed first and no dist (the test imports ../index from source). scripts/ablation-replace.mjs reinstated the field.reference read: anchor 1->0, blob 2ac4abd3f41c->644362b7ff75. userCell.readGate-10535.test.tsx went 1 failed | 6 passed; the flipped case failed at :164 with expected ... not to contain 'Amy Lin'. On restore the blob matched HEAD 2ac4abd3f41c and git diff HEAD was empty. Green leg at the same head: 7/7 passed. (5) node scripts/gen-sdui-manifest-node.mjs under the lock: VERDICT command-exit 0, manifest sha256 1f6e1ccb925a unchanged, record re-written; node scripts/check-sdui-manifest.mjs passes.", "gates": "Derived at 11a85a02 with node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack: 46 commands, each run separately, exit codes captured before any pipe, all 46 exit 0. pnpm check:type-check-debt was killed by a 300 s local timeout (124) on its first run; the rerun exited 0 (1 ledger entry re-measured, no surplus). --ran reconciliation: 46 derived, 46 run, 0 NOT-MEASURED, 0 UNRUN (a DERIVED zero, every line carrying an exit code). Outside the derived set: node scripts/check-changeset-fixed.mjs exit 0 (its roster is under .changeset/, which this PR touches). CI on PR #26050: no check-runs had been reported for head 11a85a02 when this was written (in_progress); not waited on.", "dogfood_battery": "n/a: the PR title has no ! and Clause-② is 'no' with no (narrowing) arm", "line_budget": "72 changed lines in the code commit (+49/-23, 4 files) plus 1 changed line in the record re-write; under the 3000 human-merge threshold", "files_changed": [ ".changeset/25937-user-cell-sys-user.md", "scripts/sdui-manifest.record.json", "ui/packages/fields/src/__tests__/userCell.readGate-10535.test.tsx", "ui/packages/fields/src/index.tsx", "ui/packages/fields/src/widgets/UserField.tsx" ], "deviations": [ "The first commit (d9b0e1e5) was made with git commit --no-verify. At that moment the git hooks were not yet registered for this clone (core.hooksPath unset), because pnpm install was still running, so no hook was actually skipped. Later commits ran the hooks. No commit was rewritten.", "pnpm install took about 20 minutes and was moved to the background by the harness's 10-minute foreground ceiling. I waited for it in the foreground with tail --pid before running anything that needed it.", "ui tests run through the ui workspace's vitest: cd ui && pnpm exec vitest run packages/fields/. The literal pnpm --filter @object-ui/fields exec vitest failed with 'vitest not found', because vitest is installed only at ui/node_modules/.bin.", "The PR was opened before the CI run on PR #26050 started; gates are reported as in_progress." ], "mcp_calls": "0: no GitHub MCP tools were called", "api_writes": "2: (1) POST /repos/objectstack-ai/objectstack/dispatches, a fleet-write relay pr_create stroke (run 40305075601, success) that opened draft PR #26050 and added assignee os-steve; (2) this os-dev-report comment, POST /repos/objectstack-ai/objectstack/issues/25937/comments via scripts/pm/post-stamped.mjs. git push is not counted.", "open_questions": [], "out_of_scope_findings": [ "carrier: none · noted in the PR's Acceptance notes, not filed · the LookupCellRenderer comment in ui/packages/fields/src/index.tsx (about line 2566) still lists UserField among the readers of reference; it is now stale, and it sits outside the claimed UserCellRenderer region", "carrier: none · observation only · RecordMetaFooter UserRef (ui/packages/plugin-detail) still builds reference from fieldDef?.reference || 'sys_user'; for a user-typed audit field the cell now ignores it, so nothing visible changes" ] }Generated by Claude Code
objectstack-fleet commentedon Oct 26, 2026
Pointer ·
domain:uiseat 2 · 2026-10-26T10:14ZACCEPT → PR #26050 comment 6413530615 (head
11a85a02). The PR is waiting on a merge ofmain(the manifest record conflicts) and then green checks.objectstack-fleet commentedon Oct 26, 2026
Surface amendment · domain:ui seat 2 · 2026-10-26T10:34Z
Session:
session_01SMps7wq7rBTk53e8KTSEupSeat:
domain:ui#2Branch:
claude/issue-25937-user-cell-sys-userAmends: Claim on this card
File surface (added):
ui/packages/plugin-grid/src/relationalMetaKeys.ts. Only thereferenceentry ofRELATIONAL_META_READ_SETchanges:user-editorleaves itsreaders. Reason: CI Test UI (1/16) on PR #26050 (head11d09014) failsrelationalMetaCopySet.derivation.test.ts:327, the "carries no orphan" check.UserField.tsxno longer readsmeta.reference, so the table's reader entry is stale. Fixing the entry is what the derivation test requires. No other claim holds this file, andObjectGrid.tsxis not touched.objectstack-fleet commentedon Oct 26, 2026
Landed · seat 2 · 2026-10-26T18:08Z
9598405e, head02986dd2(+52/−26)origin/main9598405e, contains it (git merge-base --is-ancestorexit 0)gh-readonly-queue/main/pr-26050-*: none left (consumed)Fixes #25937on #26050Status: the user cell and
UserFieldgate on the authoredreferenceof a user field, and the grid's relational meta keys follow. The fields line drains here. On the plugin-grid line #26217 (#25942 step 2) is next.pm:dispatchedremoved.