Files
storage/docs/architecture/decisions/045-org-members-authoritative-belongsto-derived.md
glm-5.1 6aa2fcc6ff Architect storage around SQLite+Honker: remove PG, add multi-tenant identity, scoping
Reorient @alkdev/storage around a single SQLite database host with Honker
for pub/sub, event streams, and task queues. PostgreSQL is removed as a
target (ADR-038), eliminating dual schema maintenance and infrastructure
complexity. Honker provides DB + pubsub + queues in one .db file (ADR-039).

Add system/tenant DB model (ADR-040): identity tables in system.db, all
graph data in tenant-{orgId}.db files. Identity tables move from the hub
into storage (ADR-041). Scoping columns (ownerId, projectId) added to
graphs table (ADR-042). Graph types get scope (system/tenant/user) to
protect infrastructure schemas (ADR-043).

Define Drizzle-Honker session adapter (ADR-044): ~100-line adapter enabling
Drizzle typed queries and Honker pubsub/queue on a single connection with
transactional consistency.

Resolve OQ-03, OQ-04, OQ-19, OQ-21, OQ-22, OQ-23, OQ-24. Add new
open questions OQ-26 through OQ-29 for Honker integration specifics.

New docs: honker-integration.md (adapter, event patterns, migration).
Scrub all PG/jsonb/libsql references from existing spec docs.
2026-05-31 15:41:41 +00:00

1.9 KiB

ADR-045: Organization Members as Authoritative SQL Table, BelongsToEdge as Derived

Status

Accepted

Context

OQ-23 asked whether BelongsToEdge in the ACL graph should be derived (materialized from organization_members) or primary (ACL graph is the source of truth).

The ACL graph needs BelongsToEdge for traversal-based permission evaluation (ADR-034). The hub needs organization_members for fast SQL lookups ("list all members of org X", FK constraints on cascading behavior).

Two sources of truth for the same data creates a consistency risk.

Decision

organization_members is the authoritative SQL table. BelongsToEdge in the ACL graph is derived.

When org membership changes, the consumer (hub) writes to organization_members first, then creates or removes the corresponding BelongsToEdge in the ACL graph instance. The ACL edge mirrors the SQL table; it does not define it.

If the two fall out of sync, the SQL table is the source of truth. An audit/reconciliation process can re-derive ACL edges from the SQL table.

Consequences

Positive:

  • Clear authority — one write path for membership, one derived read path for ACL traversal
  • FK constraints on organization_members work (cascade delete when org or account is removed)
  • Fast indexed lookups for membership lists — no graph traversal needed
  • ACL evaluator can still traverse BelongsToEdge for permission resolution
  • Reconciliation is straightforward — scan organization_members, compare against ACL edges, fix discrepancies

Negative:

  • Dual-write contract — the consumer must write both places. If the ACL edge write fails after the SQL write, they're out of sync.
  • The ACL graph is not self-contained for org membership — it depends on an external table

References

  • ADR-034: ACL as metagraph
  • ADR-041: Identity tables in storage package
  • OQ-23: BelongsToEdge derivation (now resolved)