- 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
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:
Human→identityType: "account"Llm→identityType: "account"(LLMs are accounts per ADR-012 in the hub)Agent→identityType: "role"(agents fill roles)
Consequences
Positive:
- Eliminates the disconnected
actorstable that had no relations (resolves OQ-03) - Identity data has a single source of truth: the hub's
accountsandorganizationstables for auth/membership, the ACL graph for authorization - No sync burden between
actorstable 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 simpleWHERE 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