Skip to content

refactor(plugin-security): make sys_permission_set data record a pure projection (retire the two-store split-brain) #2875

Description

@os-zhuang

Context

sys_permission_set currently has two stores:

  1. Authoritative metadata — the layered metadata overlay (sys_metadata), written by Studio env-scope edits (saveMetaItem / client.layered).
  2. Queryable data record — snake_case JSON-string columns that Setup reads for lists and user assignment.

These were only synced at boot and on publish. Env-scope metadata edits did not project onto the data record, so Setup showed stale facets — the ADR-0056 display-freshness gap (#2857).

What's already done

framework #2867 (closing #2857) added an onMetadataMutation subscriber that projects env-authored permission-set edits onto the data record.

This is a sync band-aid. It re-couples two independent sources of truth after the fact.

The remaining problem

Two authoritative stores can still drift. Any write path that bypasses the subscriber — a bulk import, a future API, a migration, a background job — desyncs metadata from the data record, and the two disagree with no single winner. The projection is eventually-consistent glue, not a cure for having two truths.

Proposed work

Make the data record a pure read-model:

  • The metadata overlay is the only authoritative store.
  • The data record is projected from it (read-only) and never independently authoritative — reads that need SQL/query go through the projection; writes always target metadata.
  • Alternatively, evaluate collapsing to a single store if the query needs can be served from metadata directly.

This needs an ADR (follow-up to ADR-0056) to choose the direction and define the migration/backfill path.

Acceptance criteria

  • One authoritative store; the other is derived and documented as read-only.
  • No write path can desync the two — enforced structurally, not by a subscriber a new path might forget to trigger.
  • Setup reflects Studio edits with no projection race.

References

Follow-up raised after landing the #2867 projection fix — this issue is the durable root-cause fix.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions