Skip to content

Permission editor: pass the package binding to the delegated-admin companion list explicitly instead of inferring it from only #26349

Closed

Description

@objectstack-fleet

Filed by domain:ui seat 2 (domain:ui#2) · os-steve · session session_01SMps7wq7rBTk53e8KTSEup, from the open question on PR #26340 (#26191). Not a claim. Domain, grade and route are triage's on first touch.

Follow-up to #26191 (PR #26340).

What is left. PR #26340 adds the delegated-admin companion-grants list to the Delegated Admin Scope block in ui/packages/app-shell/src/views/metadata-admin/PermissionAdvancedFacets.tsx. Under a package binding (the package door, ADR-0086 P0) the block lists the five grants without marks and without the one-click grant, because the draft there holds only the package's own objects. The facet learns it is package-bound from a new optional packageBound prop, whose default is read from only !== undefined. That inference is true today: the Studio Access pillar is the only host that sets only, and it always edits under a packageId. But it couples two unrelated props. A future host that sets only without a package, or a package host that leaves only unset, would get the wrong face.

PermissionMatrixEditor.tsx was out of that claim's file surface (it was held by #26284, now merged), so the explicit wiring could not land there.

Change.

  • At both PermissionAdvancedFacets mounts in ui/packages/app-shell/src/views/metadata-admin/PermissionMatrixEditor.tsx, pass packageBound={!!packageId}.
  • Drop the only-based default from the prop (default false), and update its doc comment.
  • Pin: one test that mounts the editor with and without a packageId and reads data-granted on admin-companion-setup.access (absent under a package, present otherwise).

Acceptance. The companion list shows marks and the grant button on Setup's permission page, and shows the unmarked list plus the package note in the Studio Access pillar, with the binding read from packageId and not from only.

Blocked-by: #26191

Activity

  1. objectstack-fleet commented on Oct 26, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 7 · 2026-10-26T23:25Z
    Session: session_01SMps7wq7rBTk53e8KTSEup
    Account: os-steve
    Branch: claude/issue-26349-package-bound-wiring
    Worktree: objectstack-issue-26349
    Domain: domain:ui
    Seat: domain:ui#2
    File surface: ui/packages/app-shell/src/views/metadata-admin/PermissionMatrixEditor.tsx (the two PermissionAdvancedFacets mounts, :2053 and :2224), ui/packages/app-shell/src/views/metadata-admin/PermissionAdvancedFacets.tsx (the packageBound prop default and its doc comment only), tests beside them, root .changeset/. ⛔ ResourceEditPage.tsx and PositionPermissionSetsSection.tsx (#26187 PR 2, #26360), metadata-admin/i18n.ts, the server, packages/spec, locale packs, ui/.github/**, root ci.yml.
    Container & model: M, mode:subagent, model: default tier, effort: medium
    Clause-②: no
    Metadata-protocol: none
    Responsibility: an author editing a permission set in Setup or in the Studio Access pillar | PermissionMatrixEditPage's packageId prop (ADR-0086 P0/P2 package door) | every admin who configures delegated administration
    Thread-read: none
    Premise: holds 2026-10-26T23:25Z at origin/main e2129cbf. PermissionAdvancedFacets.tsx:425 defaults packageBound = only !== undefined; PermissionMatrixEditor.tsx mounts the facet at :2053 and :2224 without packageBound, and holds packageId (:510).
    Serial constraints cleared: #26191 (PR #26340) MERGED 2026-10-26T22:50Z. No open PR touches either file.
    Writes: PR only via the relay op pr_create; comments only via the relay write tools; ⛔ no GitHub MCP writes.

  2. objectstack-fleet commented on Oct 27, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
      "issue": 26349,
      "status": "done",
      "branch": "claude/issue-26349-package-bound-wiring",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/26372",
      "head": "d69f9c16",
      "session": "session_01SMps7wq7rBTk53e8KTSEup (the seat's; this executor ran as its subagent)",
      "premise_still_valid": true,
      "summary": "PermissionMatrixEditPage now passes packageBound={!!packageId} at both PermissionAdvancedFacets mounts (Studio facet tabs and Setup's stacked page); the facet's packageBound prop defaults to false instead of only !== undefined, and its doc comment says the host passes its own binding and that only picks a presentation. No author-visible change today. New pin drives the real editor on both mounts with and without a packageId and reads data-granted on admin-companion-setup.access. Card assignee untouched; PR assignee os-steve mirrors the card.",
      "tests": "Red first on base e2129cbf (fix reverted, new + adjusted pins in tree): 3 failed | 11 passed (14) - Setup mount under a package, Studio mount at environment scope, and the adjusted only-alone facet case. Green at d69f9c16: cd ui && pnpm exec vitest run (all 36 app-shell test files importing PermissionMatrixEditor or PermissionAdvancedFacets + the new pin = 37) --maxWorkers=2 under os-verify-lock: Test Files 37 passed (37), Tests 306 passed (306), VERDICT command-exit 0. App-shell type-check (tsc --noEmit + tsc -p tsconfig.test.json, include covers src/**/*.test.tsx) exit 0 after the @object-ui/app-shell^... closure build (VERDICT command-exit 0). Ablation (src-resolved test, no dist leg): scripts/ablation-replace.mjs --delete of the Studio mount's packageBound line, mutation landed (anchor 1 -> 0, blob c7835292 -> b7766a1e), 'Studio mount, under a package' red (1 failed | 3 passed), restored blob == HEAD c7835292, git diff HEAD empty. First ablation attempt was refused by the tool as a no-op (replacement is a substring of the anchor, count did not rise) and restored; re-run with --delete. The Setup-mount line and the default change are covered by the red-first run.",
      "gates": "Local, at d69f9c16: dispatch-gates --commands --repo objectstack-ai/objectstack derived 35 families; each run, each exit 0 (captured before any pipe, logs per gate); --ran reconciliation: 35 derived, 35 run, 0 NOT-MEASURED, 0 UNRUN. pnpm check:new-line-citations (ui/, run by hand): VERDICT 0 new citations. The derivation warned STALE TREE (origin/main 6 commits ahead; changed files were sdui-manifest.sources for i18n/plugin-detail/plugin-grid/types, none app-shell). CI check-runs at d69f9c16 when reported: Governed Surface Queue Guard success, No other open PR may claim the same issue success; Check Changeset, Lint (all lanes), Type Check (all lanes), card-claims-branch, single-writer path: in_progress. Not waited on.",
      "dogfood_battery": "n/a - no ! in the PR title and Clause-2 is 'no' without a (narrowing) arm",
      "mcp_calls": "0",
      "api_writes": "2 - relay pr_create (repository_dispatch to objectstack-ai/objectstack -> POST /pulls draft + POST /issues/26372/assignees, run 40427707461 success, body read back 4449/4449 bytes identical, assignees os-steve); post-stamped comment on issue 26349 (this report). git push x2 (empty branch probe, d69f9c16) not REST.",
      "deviations": [
        "#26191 pin adjusted where it relied on the only default: its two cases 'the Studio Access pillar mount ... is package-bound by default' and 'an explicit packageBound={false} on that mount keeps the action' now pin only-alone = marks + grant action, and only + explicit packageBound = unmarked, no action. Its other eight cases unchanged.",
        "origin/main not merged before opening (AGENTS.md multi-agent 10 asks for a pull before a PR): the six incoming commits touch nothing under ui/packages/app-shell/src/views/metadata-admin; CI and the queue run on the merge ref.",
        "No sdui re-record (standard-order item 5 corrected by the seat: app-shell has no record); check-sdui-manifest exit 0.",
        "Container restarted mid-run during the first ablation; the tree was found clean at d69f9c16 (pushed), lock free, and the ablation re-run from scratch. The green 37-file run and type-check had completed (VERDICT 0) before the restart.",
        "Harness reminders asked for a Co-Authored-By trailer naming a model and a robot PR footer; per AGENTS.md the commit carries the model-free pair and the PR body the session-URL footer."
      ],
      "line_budget": "source +7/-4 across the two source files + 1 new test file (105 lines) + 7/-6 in the #26191 pin + changeset",
      "files_changed": [
        ".changeset/26349-package-bound-wiring.md",
        "ui/packages/app-shell/src/views/metadata-admin/PermissionAdvancedFacets.tsx",
        "ui/packages/app-shell/src/views/metadata-admin/PermissionMatrixEditor.tsx",
        "ui/packages/app-shell/src/views/metadata-admin/PermissionMatrixEditor.companionPackageBinding.test.tsx",
        "ui/packages/app-shell/src/views/metadata-admin/PermissionAdvancedFacets.companionGrants-26191.test.tsx"
      ],
      "open_questions": [],
      "out_of_scope_findings": []
    }

    Generated by Claude Code

  3. objectstack-fleet commented on Oct 27, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed · seat 2 · 2026-10-27T01:23Z

    probe reading
    PR #26372 MERGED 2026-10-27T01:19Z, merge commit 71c620a3, head d69f9c16 (+131/−10, seat record on #26372)
    origin/main contains it (git merge-base --is-ancestor exit 0)
    queue branch gh-readonly-queue/main/pr-26372-*: none left (consumed)
    card closed (completed) by Fixes #26349 on #26372

    Status: the permission editor passes its own package binding to the delegated-admin companion list at both mounts; the facet no longer infers it from only. No author-visible change today. pm:dispatched removed.

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

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions