Files
storage/docs/architecture/decisions/035-actors-become-acl-nodes.md
glm-5.1 6b5f32bad4 Add ACL graph architecture spec with principal-agent framework
- New acl.md: AclGraph Module definition (PrincipalNode, ResourceNode,
  DelegatesEdge, ScopesEdge, MemberEdge), principal-agent hierarchy
  with no-escalation invariant, setup-time vs runtime separation,
  multi-parent aggregation rules, cycle detection, scope semantics
- ADR-034: ACL as metagraph (not domain-specific tables)
- ADR-035: Actors become PrincipalNode entries, standalone table removed
- ADR-036: Principal-agent as DelegatesEdge with scope narrowing
- ADR-037: Setup-time definitions seed graph types, runtime instances
  are separate graphs
- Resolve OQ-03 (actors table design) — actors become ACL nodes
- Add OQ-20 through OQ-25 (delegation expiration, evaluator location,
  graph instance lifecycle, BelongsToEdge derivation, identityId
  references, scope string semantics)
- Update README.md and overview.md to reflect new doc and ADRs
- Note: multi-tenancy / graph scoping problem (no ownerId/scopeId on
  graphs table, no identity tables at this level) still needs
  resolution — identity and org tables will likely need to be added
  at this level for referential integrity
2026-05-31 07:11:59 +00:00

2.5 KiB

ADR-035: Actors Become ACL Nodes, Standalone Table Removed

Status

Accepted

Context

The actors table in src/sqlite/tables/actors.ts is a standalone identity table with columns id, metadata, createdAt, updatedAt, name, type (enum: human/llm/agent). It has no foreign key relationships to or from any metagraph table. OQ-03 explicitly deferred the decision on whether actors should be a node type or standalone table until ACL design.

The hub already has authoritative identity tables (accounts, organizations, organization_members, api_keys) that store authentication and membership data. Duplicating those columns in storage would create sync burden and potential inconsistency.

Decision

The actors standalone table is removed. Identity entities (accounts, orgs, services, roles) are represented as PrincipalNode entries in ACL graph instances, with identityId as a logical reference to the hub's authoritative identity tables.

The ACTOR_TYPE enum is replaced by the IdentityType enum in the AclGraph Module (account, service, org, role). The mapping from the old ACTOR_TYPE:

  • HumanidentityType: "account"
  • LlmidentityType: "account" (LLMs are accounts per ADR-012 in the hub)
  • AgentidentityType: "role" (agents fill roles)

Consequences

Positive:

  • Eliminates the disconnected actors table that had no relations (resolves OQ-03)
  • Identity data has a single source of truth: the hub's accounts and organizations tables for auth/membership, the ACL graph for authorization
  • No sync burden between actors table and hub identity tables
  • Principal-agent delegation is naturally expressed as graph edges, not self-joins on an actors table

Negative:

  • Fast "find all actors of type X" queries require JSON path extraction on node attributes ($.identityType) rather than a simple WHERE type = 'X' column query. This is consistent with ADR-033 (JSON path for v1) and can be optimized with computed columns or indexes later.
  • The identityId → hub entity reference is a logical reference, not a FK. Orphaned or dangling references are possible if a hub entity is deleted without updating the ACL graph. Mitigation: the hub's cascade logic should also clean up ACL graph instances.

References

  • acl.md — ACL graph architecture specification
  • OQ-03: Should actors be a node type or a standalone table? (resolved by this ADR)
  • ADR-002: Metagraph over domain-specific tables
  • ADR-012 (hub): Agent vs Role vs Account terminology