Skip to content
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
This repository was archived by the owner on Nov 4, 2026. It is now read-only.

Studio Access pillar: package-level OWD overview — audit & batch-edit sharingModel across all objects in a package #2505

Closed

Description

@os-zhuang

Problem

For a package author, the record-sharing baseline (OWD, sharingModel / externalSharingModel) of the package's objects can only be inspected and edited one object at a time, via the Data pillar → object → Settings tab (ObjectSettingsPanel.tsx). The permission matrix (PermissionMatrixEditor.tsx) shows a read-only OWD badge per object row, but offers no way to change it and no package-wide view.

Consequences:

  • A package with 20 objects requires opening 20 settings pages to audit its baseline posture. In practice this means nobody audits it: in the com.example.showcase dogfood app, most objects sit at public_read_write while a few are private, and this imbalance is invisible from any single screen.
  • ADR-0090 D1 made explicit OWD mandatory precisely because the silent-widening failure class (objectui#2348) is invisible object-by-object. A per-object-only editing surface leaves the review side of that decision unsupported: there is no screen on which "which of my objects are org-wide writable?" can be answered at a glance.
  • The externalSharingModel ≤ sharingModel constraint (ADR-0090 D11) is validated per object at authoring/lint time, but an author can't survey the external dimension across the package before publish.

Proposal

Add a package-scoped "Record Sharing Baseline (OWD)" panel to the Studio Access pillar, as a sibling surface next to the permission-set rail (not inside the permission matrix):

  • A table of object × sharingModel × externalSharingModel covering every object owned by the current package (published ∪ pending drafts, same merge the pillars already do).
  • Inline select per cell using the canonical four values (private | public_read | public_read_write | controlled_by_parent), reusing the option labels/help copy from ObjectSettingsPanel and the badge/i18n helpers from views/metadata-admin (owdLabel, views/metadata-admin/i18n.ts).
  • controlled_by_parent rows display the master link (read-only) instead of an external dial, mirroring the per-object settings behavior.
  • Row-level validation external ≤ internal (the OWD_WIDTH comparison already implemented in ObjectSettingsPanel.tsx) surfaced inline before save.
  • Save = per-object metadata drafts under the package scope — exactly what the per-object Settings tab writes today, just N objects in one action. Publish then flows through the existing security-domain gate unchanged (ADR-0090 D7 lint + human gate; the D6 semantic diff is naturally per-row: "showcase_contact widens private → public_read").
  • Deep-linkable via the existing ?surface= plumbing (useSurfaceDeepLink), so the read-only OWD badge in the permission matrix can link here.

Why this does not blur the ADR-0090 concept boundaries

Merging OWD into the permission-set matrix was considered and rejected (ADR-0090; permission sets are additive per-principal unions, OWD is a per-object scalar baseline with a different owner). This proposal is not that: every row in this table has the same owner — the package author ("OWD: object author · sharing: environment", docs/design/permission-model.md). It is an aggregation of N editing entry points within one ownership boundary, not a merge of two concepts. It has no principal dimension and binds to nobody.

Non-goals

  • No package-level default OWD with inheritance. The table batch-edits N explicit per-object values. A package default that objects inherit would reintroduce the ambient "unset" state ADR-0090 D1 abolished.
  • Not merging OWD editing into the permission-set matrix. The matrix keeps its read-only badge (now linkable).
  • enable.* capability switches are out of scope. The same ownership argument supports a package-level "object × capability switch" overview, but those are behavior config, not authorization — if pursued, it belongs in the Data pillar as a follow-up issue.
  • No changes to enforcement, lint rules, or the publish pipeline — this is purely an authoring-surface addition.

Implementation notes

  • Entry point: StudioDesignSurface.tsx → AccessPillar (rail pattern, ?surface= deep-link, publishNonce re-read after publish are all established there).
  • Reuse: OWD select options + external-dial + OWD_WIDTH validation from views/studio-design/ObjectSettingsPanel.tsx (likely extract a shared control); OWD label/i18n from views/metadata-admin/i18n.ts.
  • Data: client.list('object', { packageId }) ∪ client.listDrafts({ packageId, type: 'object' }); per-object draft save on batch apply; OCC / destructive-change dialog conventions per the existing editors.
  • Read-only mode must follow the pillar's readOnly courtesy gate (package read-only ⇒ table renders badges only).

Acceptance criteria

  • Access pillar shows an OWD overview listing all objects of the current package (published ∪ drafts) with internal + external sharing model per row.
  • Author can change multiple objects' OWD and save once; each change lands as that object's package-scoped draft; publish goes through the unchanged security-domain gate.
  • external > internal is blocked inline per row; controlled_by_parent rows show the master and no external dial.
  • The OWD badge in PermissionMatrixEditor deep-links to this panel.
  • Read-only packages render the table non-editable.
  • ADR-0054 testability proofs for the new surface (list render, edit→draft, validation block, deep-link).

References

  • framework ADR-0090 (Permission Model v2 — D1 mandatory explicit OWD, D4 canonical enum, D11 external dial, D6 explain / D7 security-domain gate) and companion docs/design/permission-model.md
  • objectui ADR-0056 (permission editing belongs in Studio — "one validated authoring path per concern")
  • objectui#2348 (OWD control in Studio + dogfood incident), objectui#2403 (structured permission editors)

Origin: Studio dogfooding of com.example.showcase — auditing the package's record baseline currently requires visiting every object's settings page individually.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions