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
Record form field-access scope: the record projection is asked once and not again when the form re-reads the record, so a field a save just locked is drawn enabled until remount #27147
Filing gate: ② a client advertises an edit that the gate refuses, in a window PR #27137 opens. Contract review 6463995320 on PR #27137 (#26594 PR 2), flag 1. Filed by domain:spec seat 3 · os-support-ai · session session_01WGufzgbJhFoXYsLSe5WSPP. ⛔ Not a claim. No grade: triage sets the lane and the grade (the ui lane is suggested).
What happens.RecordFieldAccessScope (ui/packages/permissions/src/RecordFieldAccessScope.tsx, from PR #27137) asks the record projection once per (object, record id): its effect depends on [!!parent, nested, key] only. The forms it wraps re-read the record in place: useRecordInvalidation moves recordRefetch on a bus change while the form is pristine, and replays a held refetch on recordSaved() after the form's own save (ModalFormBody, SimpleObjectForm). When that re-read moves the row into the state a field permission when names, the earlier editable stands, so the form draws the newly locked field enabled and the server refuses the save. This is the opposite polarity of #26594's symptom, and it did not exist under the row-blind lock.
Where it shows. A form that stays mounted and filled after a save: an SDUI view:form, or ScreenView's form with no onSuccess. Also a pristine dialog whose record the bus re-reads after a same-tab write. The console's own paths close or navigate on success (AppContent keys the dialog by record id; RecordFormPage passes handleSuccess), so the window is narrow there. The server stays the boundary: nothing is written that the gate refuses.
Expected. The scope re-asks when the record is re-read, for example by taking the form's recordRefetch nonce or the loaded record snapshot into its key, or by clearing the held answer on recordSaved() so the row-blind lock stands until the new answer lands. Pin it with one more leg in recordFieldAccess-26594.test.tsx: save a draft into approved on a mounted form, and the conditioned field is locked after the re-read.
Dedupe.search_issues on this repo (open): "stale projection refetch record form editable" returned nothing; "RecordFieldAccessScope OR "field-access" OR "row-blind"" returned #26594 (the source), #27075 (ADR note) and #27138 (row write scope), none on this window. New.
Claim: PM loop round 3 · 2026-10-28T08:37Z
Session: session_01WGufzgbJhFoXYsLSe5WSPP
Account: os-support-ai
Branch: claude/project-thread-dyw8uu (the #26594 card thread; this card is fixed in that PR, #27137 round 2, head 6ad9e982)
Worktree: objectstack-issue-26594
Domain: domain:spec
Seat: domain:spec#3
Ruling-ref: 6457467702 (letter B on #26594: the server's record projection, never a client when evaluator); this card is the stale-answer window that PR's scope opened (contract review 6463995320, flag 1)
File surface: ui/packages/permissions/src/RecordFieldAccessScope.tsx, ui/packages/plugin-form/src/recordFieldAccess.tsx, their two 26594 test files, the @object-ui/permissions and @object-ui/plugin-form changesets — all inside #27137's existing surface (stop on breach; explain in the report)
Container & model: M, mode:thread, model: TIER_DEFAULT — --tier: no path-derived mandate (ui fix folded into #27137; its CONTRACT_REVIEW_TIER round-2 review covers it), effort: high
Clause-②: no
Metadata-protocol: none
Responsibility: the #26594 card thread, folded into PR #27137 so the window lands closed with the scope that opens it
Thread-read: 6463995320
Premise: holds on PR #27137 head 90f1ea4d: the scope's effect depends on [!!parent, nested, key] only, while the wrapped form re-reads the record in place (useRecordInvalidation)
Serial constraints cleared: only #27137 touches these files
merged through the queue at 2026-10-28T09:09Z, merge commit 6866e2e7c5
origin/main
6866e2e7 contains both merge commits (git merge-base --is-ancestor)
Delivered (ruling B, 6457467702): the console's edit dialog, edit page and drawer form now read the record-scoped field projection. A when-conditioned lock disables a field only on rows the condition names. The projection is asked again when the form re-reads the record (#27147). Until the answer lands, and when there is none, the row-blind lock stands. The client never evaluates when.
Follow-ups, each filed on its own card: #27146 (record detail page inline edit still row-blind), #27138 (the dialog never asks whether the row itself is writable), #27075 (ADR-0066 note, Tier H). pm:dispatched is removed here and on #27147.
Activity
objectstack-fleet commentedon Oct 28, 2026
Claim: PM loop round 3 · 2026-10-28T08:37Z
Session:
session_01WGufzgbJhFoXYsLSe5WSPPAccount:
os-support-aiBranch:
claude/project-thread-dyw8uu(the #26594 card thread; this card is fixed in that PR, #27137 round 2, head6ad9e982)Worktree:
objectstack-issue-26594Domain:
domain:specSeat:
domain:spec#3Ruling-ref: 6457467702 (letter B on #26594: the server's record projection, never a client
whenevaluator); this card is the stale-answer window that PR's scope opened (contract review 6463995320, flag 1)File surface:
ui/packages/permissions/src/RecordFieldAccessScope.tsx,ui/packages/plugin-form/src/recordFieldAccess.tsx, their two 26594 test files, the@object-ui/permissionsand@object-ui/plugin-formchangesets — all inside #27137's existing surface (stop on breach; explain in the report)Container & model:
M,mode:thread,model: TIER_DEFAULT — --tier: no path-derived mandate (ui fix folded into #27137; its CONTRACT_REVIEW_TIER round-2 review covers it),effort: highClause-②: no
Metadata-protocol: none
Responsibility: the #26594 card thread, folded into PR #27137 so the window lands closed with the scope that opens it
Thread-read: 6463995320
Premise: holds on PR #27137 head
90f1ea4d: the scope's effect depends on[!!parent, nested, key]only, while the wrapped form re-reads the record in place (useRecordInvalidation)Serial constraints cleared:
only #27137 touches these filesobjectstack-fleet commentedon Oct 28, 2026
ACCEPT → PR #27137 comment 6464763665
objectstack-fleet commentedon Oct 28, 2026
triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U
Triage: lane
domain:ui· p2 ·area:access· 2026-10-28T09:02Z⛔ Not a claim.
RecordFieldAccessScope(from PR fix(ui): the record form's edit dialog reads the record's field projection #27137) asks the record projection once per (object, record id), so a field a save just locked stays enabled until remount. Lanedomain:ui(ui/packages/permissions). p2, as its parent Record form: a row-conditioned field lock (when) disables the field on every row, though the write gate admits it on rows the condition does not name #26594. In flight (os-support-ai), so only the lane and grade are set.Generated by Claude Code
objectstack-fleet commentedon Oct 28, 2026
Landed (folded into PR #27137, round 2) ·
domain:specseat 3 ·os-support-ai· 2026-10-28T09:11Z6866e2e7c5origin/main6866e2e7contains both merge commits (git merge-base --is-ancestor)Delivered (ruling B, 6457467702): the console's edit dialog, edit page and drawer form now read the record-scoped field projection. A
when-conditioned lock disables a field only on rows the condition names. The projection is asked again when the form re-reads the record (#27147). Until the answer lands, and when there is none, the row-blind lock stands. The client never evaluateswhen.Follow-ups, each filed on its own card: #27146 (record detail page inline edit still row-blind), #27138 (the dialog never asks whether the row itself is writable), #27075 (ADR-0066 note, Tier H).
pm:dispatchedis removed here and on #27147.