Skip to content

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

Closed

Description

@objectstack-fleet

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).
  • Runtime side: packages/plugins/plugin-security/src/field-masker.ts.
  • 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

Activity

  1. objectstack-fleet commented on Oct 27, 2026

    @objectstack-fleet
    ContributorAuthor

    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.


    Generated by Claude Code

  2. objectstack-fleet commented on Oct 28, 2026

    @objectstack-fleet
    ContributorAuthor

    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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

area:accessPermissions that actually hold — RLS/FLS, sharing model, write-path guardsbugSomething isn't workingdomain:uipriority:p1High: required for production / M2security

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions