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 Access pillar: the field-permission editor shows a different edit right for a field with no explicit rule than the runtime enforces, and its bulk controls change edit rights silently (detail withheld pending maintainer) #26597
Filing gate: ① product defect, reproduced and confirmed in code, landing site named (maintainer direct dispatch, authorizing words quoted in the audit comment).
Symptom (customer-visible)
In Studio › Access › a permission set › an object's field sub-table, the readable/editable state shown for a field that has no explicit field rule disagrees with what the server enforces for that same field. An admin who trusts the screen gets the opposite of what they see.
The bulk/clear controls in that sub-table look like no-ops on screen, but they write explicit field rules that change who can edit.
This is an authorization-display defect, so the step-by-step reproduction and the exact direction of the mismatch are withheld from this card, per the maintainer's instruction. They go to the implementer privately.
Measured
Repo 3fcafcd3, 2026-10-27, by the Studio QA Access card. The member's write was refused or accepted against what the editor displayed.
The coordinator confirmed the mismatch by reading the editor's render default against the server's field-masking rule for unruled fields.
Landing site (suspected — the implementer verifies)
Editor side: ui/packages/app-shell/src/views/metadata-admin/PermissionMatrixEditor.tsx (field sub-table render default and the field-permission seed on update).
Which side is wrong is decided by the spec's declared meaning of an absent field rule (packages/spec/src/security/permission.zod.ts). Per the protocol-first rule, code aligns to the spec; changing the spec is a separate card.
Acceptance
For every combination of object grant × field rule (absent / readable-only / editable), the editor shows exactly what the runtime enforces.
No bulk or clear control writes an edit right the admin did not see change on screen.
A pin covers the absent-rule case on both sides (editor render and runtime enforcement), so they cannot drift again.
Filing facts
Business reason: admins decide who may change sensitive fields from this screen. A display that disagrees with enforcement either leaves a field editable that the admin believes is locked, or locks one they meant to keep open, with no signal either way.
Reader who acts: an os-dev implementer, dispatched directly by this PM session on the maintainer's instruction (domain:ui).
Claim: PM loop round 1 (maintainer direct dispatch)
Session: session_01J8VVAkZns5rNnK2rtszzbQ
Account: huangyiirene
Branch: claude/issue-26597-field-perm-editor-display
Worktree: objectstack-issue-26597
Domain: domain:ui
Seat: domain:ui#1 (direct-dispatch session, not a lane seat)
File surface: ui/packages/app-shell/src/views/metadata-admin/** (field-permission editor) and, only if the spec's meaning of an absent field rule says the runtime is the wrong side, packages/plugins/plugin-security/src/field-masker.ts (stop on breach; explain in the report)
Container & model: M, mode:subagent, model: TIER_DEFAULT (dispatch-gates --tier: no path-derived mandate), effort: xhigh (security, p1)
Clause-②: no
Metadata-protocol: none
Responsibility: Studio's field-permission editor renders and seeds an unruled field differently from runtime enforcement | none | every admin who sets field permissions in Studio Access; the screen misstates edit rights
Thread-read: none
Premise: holds (measured 2026-10-27 at 3fcafcd by the Access QA card; coordinator code-confirmed; no change on origin/main 898703f to either file)
Serial constraints cleared: open draft PR #26593 (studio i18n namespace, moves perm.* strings) may touch the same editor — rebase over it if it lands first; no other in-flight claim on this surface
Direct-dispatch authority — maintainer, this session, 2026-10-27, verbatim: 「3 个 AUTH 类问题(复现细节都不公开);你可以直接派发处理」
Reproduction steps stay off GitHub per that instruction; they go to the implementer in the private dispatch prompt.
{
"issue": 26597,
"status": "done",
"branch": "claude/issue-26597-field-perm-editor-display",
"pr": "https://github.com/objectstack-ai/objectstack/pull/27006",
"session": "session_01J8VVAkZns5rNnK2rtszzbQ (subagent: the parent session id)",
"premise_still_valid": true,
"summary": "The field-permission editor now shows and writes exactly what the runtime enforces for a field with no explicit rule. One pure source (fieldRuleCell / fieldRuleSeed / applyFieldBulk in permission-slice.ts) draws each field row and drives every click and shortcut; a row without a rule draws the object grant through the spec fold objectPermissionGrants, marked inherited; shortcuts write only rows whose boxes change; the preview lists every declared field rule. Runtime and spec unchanged; a runtime pin was added. Mechanism readings and reproduction detail go to the coordinator only (maintainer disclosure rule).",
"tests": "At a723bac9: ui vitest over the permission editor, slice, preview and studio-namespace files: Test Files 42 passed (42), Tests 318 passed (318), exit 0. plugin-security src/field-rule-object-grant.test.ts: 7 passed, exit 0. app-shell type-check, i18n type-check, plugin-security typecheck: exit 0 each. Ablation at ab5961d4 through scripts/ablation-replace.mjs: 12 of 24 editor-side cases red, restored to the HEAD blob. One-time HTTP measurement through bootStack agreed with both pins in all six cells.",
"gates": "dispatch-gates --commands (no paths) derived 96 families; all 96 run locally at a723bac9, every one exit 0 (ui scripts vitest: 178 files passed, 2 skipped); --ran: 96 derived, 96 run, 0 NOT-MEASURED, 0 UNRUN. ui/package.json i18n and citation gates: exit 0 each. CI on PR head a723bac9 at report time: in_progress (Lint, Type Check, Check Changeset, Governed Surface Queue Guard and the rest); filter-skipped: 18.x upgrade harness, packed-tarball smoke.",
"dogfood_battery": "n/a, no ! in the PR title and Clause-2 has no (narrowing) arm",
"mcp_calls": "0",
"api_writes": "2 relay strokes: pr_create (POST /repos/objectstack-ai/objectstack/dispatches; executor: create pull 27006 + assignee POST) and this os-dev-report comment (post-stamped).",
"open_questions": [],
"out_of_scope_findings": [
"One finding in the same display family was measured with a failing probe; its class, reach and evidence are held for the coordinator (security detail, maintainer disclosure rule)."
],
"deviations": [
"Gate derivation ran without paths as the role file requires; the dispatch named paths.",
"This GitHub copy of the report redacts the private readings the dispatch reserves for the coordinator; the final report message carries them.",
"origin/main merged twice (the second resolved a conflict in app-shell metadata-admin i18n.ts by taking main and adding the preview row to the studio namespace)."
],
"files_changed": 15
}
Activity
objectstack-fleet commentedon Oct 27, 2026
Claim: PM loop round 1 (maintainer direct dispatch)
Session:
session_01J8VVAkZns5rNnK2rtszzbQAccount:
huangyiireneBranch:
claude/issue-26597-field-perm-editor-displayWorktree:
objectstack-issue-26597Domain:
domain:uiSeat:
domain:ui#1(direct-dispatch session, not a lane seat)File surface:
ui/packages/app-shell/src/views/metadata-admin/**(field-permission editor) and, only if the spec's meaning of an absent field rule says the runtime is the wrong side,packages/plugins/plugin-security/src/field-masker.ts(stop on breach; explain in the report)Container & model:
M,mode:subagent,model: TIER_DEFAULT (dispatch-gates --tier: no path-derived mandate),effort: xhigh(security, p1)Clause-②: no
Metadata-protocol: none
Responsibility:
Studio's field-permission editor renders and seeds an unruled field differently from runtime enforcement|none|every admin who sets field permissions in Studio Access; the screen misstates edit rightsThread-read: none
Premise: holds (measured 2026-10-27 at 3fcafcd by the Access QA card; coordinator code-confirmed; no change on origin/main 898703f to either file)
Serial constraints cleared: open draft PR #26593 (studio i18n namespace, moves perm.* strings) may touch the same editor — rebase over it if it lands first; no other in-flight claim on this surface
Direct-dispatch authority — maintainer, this session, 2026-10-27, verbatim: 「3 个 AUTH 类问题(复现细节都不公开);你可以直接派发处理」
Reproduction steps stay off GitHub per that instruction; they go to the implementer in the private dispatch prompt.
Generated by Claude Code
objectstack-fleet commentedon Oct 28, 2026
os-dev-report
{ "issue": 26597, "status": "done", "branch": "claude/issue-26597-field-perm-editor-display", "pr": "https://github.com/objectstack-ai/objectstack/pull/27006", "session": "session_01J8VVAkZns5rNnK2rtszzbQ (subagent: the parent session id)", "premise_still_valid": true, "summary": "The field-permission editor now shows and writes exactly what the runtime enforces for a field with no explicit rule. One pure source (fieldRuleCell / fieldRuleSeed / applyFieldBulk in permission-slice.ts) draws each field row and drives every click and shortcut; a row without a rule draws the object grant through the spec fold objectPermissionGrants, marked inherited; shortcuts write only rows whose boxes change; the preview lists every declared field rule. Runtime and spec unchanged; a runtime pin was added. Mechanism readings and reproduction detail go to the coordinator only (maintainer disclosure rule).", "tests": "At a723bac9: ui vitest over the permission editor, slice, preview and studio-namespace files: Test Files 42 passed (42), Tests 318 passed (318), exit 0. plugin-security src/field-rule-object-grant.test.ts: 7 passed, exit 0. app-shell type-check, i18n type-check, plugin-security typecheck: exit 0 each. Ablation at ab5961d4 through scripts/ablation-replace.mjs: 12 of 24 editor-side cases red, restored to the HEAD blob. One-time HTTP measurement through bootStack agreed with both pins in all six cells.", "gates": "dispatch-gates --commands (no paths) derived 96 families; all 96 run locally at a723bac9, every one exit 0 (ui scripts vitest: 178 files passed, 2 skipped); --ran: 96 derived, 96 run, 0 NOT-MEASURED, 0 UNRUN. ui/package.json i18n and citation gates: exit 0 each. CI on PR head a723bac9 at report time: in_progress (Lint, Type Check, Check Changeset, Governed Surface Queue Guard and the rest); filter-skipped: 18.x upgrade harness, packed-tarball smoke.", "dogfood_battery": "n/a, no ! in the PR title and Clause-2 has no (narrowing) arm", "mcp_calls": "0", "api_writes": "2 relay strokes: pr_create (POST /repos/objectstack-ai/objectstack/dispatches; executor: create pull 27006 + assignee POST) and this os-dev-report comment (post-stamped).", "open_questions": [], "out_of_scope_findings": [ "One finding in the same display family was measured with a failing probe; its class, reach and evidence are held for the coordinator (security detail, maintainer disclosure rule)." ], "deviations": [ "Gate derivation ran without paths as the role file requires; the dispatch named paths.", "This GitHub copy of the report redacts the private readings the dispatch reserves for the coordinator; the final report message carries them.", "origin/main merged twice (the second resolved a conflict in app-shell metadata-admin i18n.ts by taking main and adding the preview row to the studio namespace)." ], "files_changed": 15 }Generated by Claude Code