Phase 0: Capability edge representation #47

Merged
erikinkinen merged 4 commits from 0-capability-edge-representation into main 2026-02-17 05:23:29 +01:00
Owner

Closes #5


Summary

This PR introduces capabilities as first-class graph edges with stable identity. Capabilities are now represented explicitly as CapabilityEdge structures containing an edge identity (EdgeId), a source subject (SubjectId), a target object (ObjectId), and a set of rights (Rights). The implementation provides complete lifecycle management through EdgeStore, which handles creation, storage, deletion, and lookup of capability edges.

This establishes the foundational representation for the capability-based access control model in AES, making authority relationships explicit, queryable, and independently identifiable entities in the system.


Scope

Included

  • CapabilityEdge struct definition with id, from, to, rights fields
  • Debug label support in debug builds for improved debugging experience
  • EdgeStore class for managing the edge collection
  • Edge lifecycle operations: create(), add(), remove()
  • Lookup primitives: get(), exists(), find_from(), find_to(), find_between()
  • Comprehensive test coverage (558 lines of tests across two test suites)
  • Comparison operators for CapabilityEdge

Explicitly excluded

  • Edge traversal algorithms or path-finding logic
  • Capability invocation semantics
  • Attenuation or delegation operations
  • Integration with SubjectStore or ObjectStore validation
  • Persistence or serialization of edges

Design intent

The design establishes capabilities as independent, identifiable entities rather than implicit relationships. This supports several key architectural goals:

  1. Stable identity: Each capability edge has its own EdgeId, enabling precise reference, audit trails, and revocation without ambiguity
  2. Explicit structure: The from/to/rights triple makes authority relationships queryable and introspectable
  3. Separation of concerns: EdgeStore manages edges independently from subjects and objects, maintaining clean boundaries
  4. Query flexibility: Multiple lookup methods (find_from, find_to, find_between) support different access patterns without privileging any particular use case

The store maintains basic invariants (no duplicate IDs, no invalid IDs), but deliberately defers validation of SubjectId/ObjectId existence to higher layers, keeping the edge store focused and composable.

Debug labels are conditionally compiled to provide human-readable context during development without impacting production performance or memory footprint.


Phase discipline

This belongs to Phase 0 and establishes the core graph edge representation.

Design choices aligned with phase discipline:

  • No dynamic behavior or invocation logic (reserved for future phases)
  • No cross-store validation or referential integrity checks (deferred)
  • Rights field is present but edge store does not interpret or enforce rights (enforcement is a higher-layer concern)

The CapabilityEdge structure is intentionally minimal, with room for future extension (e.g., capability metadata, creation timestamps, or lineage tracking) without breaking existing code.


Verification

  • Tests pass (capability_edge_tests, edge_store_tests)
  • Model is internally consistent (edges have stable IDs, store maintains uniqueness)
  • No regressions in existing functionality
  • Error handling validates edge IDs and prevents duplicates
  • Lookup operations correctly filter by subject/object
  • Debug labels compile conditionally and work as expected

Notes

  • Reviewers should focus on the separation of edge identity from subject/object identity, ensuring no implicit coupling that would constrain future phases
  • The find_* methods return const CapabilityEdge* to maintain store ownership while enabling efficient querying
  • Edge IDs are generated via the existing Ids generator, maintaining consistency with subject/object ID allocation
  • Future work will integrate edge store with subject/object stores for validation and add higher-level operations like capability delegation
Closes #5 --- ## Summary This PR introduces **capabilities as first-class graph edges with stable identity**. Capabilities are now represented explicitly as `CapabilityEdge` structures containing an edge identity (`EdgeId`), a source subject (`SubjectId`), a target object (`ObjectId`), and a set of rights (`Rights`). The implementation provides complete lifecycle management through `EdgeStore`, which handles creation, storage, deletion, and lookup of capability edges. This establishes the foundational representation for the capability-based access control model in AES, making authority relationships explicit, queryable, and independently identifiable entities in the system. --- ## Scope ### **Included** - `CapabilityEdge` struct definition with `id`, `from`, `to`, `rights` fields - Debug label support in debug builds for improved debugging experience - `EdgeStore` class for managing the edge collection - Edge lifecycle operations: `create()`, `add()`, `remove()` - Lookup primitives: `get()`, `exists()`, `find_from()`, `find_to()`, `find_between()` - Comprehensive test coverage (558 lines of tests across two test suites) - Comparison operators for `CapabilityEdge` ### **Explicitly excluded** - Edge traversal algorithms or path-finding logic - Capability invocation semantics - Attenuation or delegation operations - Integration with `SubjectStore` or `ObjectStore` validation - Persistence or serialization of edges --- ## Design intent The design establishes capabilities as **independent, identifiable entities** rather than implicit relationships. This supports several key architectural goals: 1. **Stable identity**: Each capability edge has its own `EdgeId`, enabling precise reference, audit trails, and revocation without ambiguity 2. **Explicit structure**: The `from`/`to`/`rights` triple makes authority relationships queryable and introspectable 3. **Separation of concerns**: `EdgeStore` manages edges independently from subjects and objects, maintaining clean boundaries 4. **Query flexibility**: Multiple lookup methods (`find_from`, `find_to`, `find_between`) support different access patterns without privileging any particular use case The store maintains basic invariants (no duplicate IDs, no invalid IDs), but deliberately defers validation of `SubjectId`/`ObjectId` existence to higher layers, keeping the edge store focused and composable. Debug labels are conditionally compiled to provide human-readable context during development without impacting production performance or memory footprint. --- ## Phase discipline This belongs to **Phase 0** and establishes the core graph edge representation. Design choices aligned with phase discipline: - No dynamic behavior or invocation logic (reserved for future phases) - No cross-store validation or referential integrity checks (deferred) - Rights field is present but edge store does not interpret or enforce rights (enforcement is a higher-layer concern) The `CapabilityEdge` structure is intentionally minimal, with room for future extension (e.g., capability metadata, creation timestamps, or lineage tracking) without breaking existing code. --- ## Verification - [x] Tests pass (capability_edge_tests, edge_store_tests) - [x] Model is internally consistent (edges have stable IDs, store maintains uniqueness) - [x] No regressions in existing functionality - [x] Error handling validates edge IDs and prevents duplicates - [x] Lookup operations correctly filter by subject/object - [x] Debug labels compile conditionally and work as expected --- ## Notes - Reviewers should focus on the **separation of edge identity from subject/object identity**, ensuring no implicit coupling that would constrain future phases - The `find_*` methods return `const CapabilityEdge*` to maintain store ownership while enabling efficient querying - Edge IDs are generated via the existing `Ids` generator, maintaining consistency with subject/object ID allocation - Future work will integrate edge store with subject/object stores for validation and add higher-level operations like capability delegation
erikinkinen added this to the Phase 0 milestone 2026-02-17 05:22:50 +01:00
Define CapabilityEdge { from, to, rights } (#5)
All checks were successful
ci / smoke (push) Successful in 9s
clang-format / check-format (push) Successful in 8s
markdownlint / markdown-lint (push) Successful in 10s
b38d4ff770
Implement edge storage (#5)
All checks were successful
ci / smoke (push) Successful in 8s
clang-format / check-format (push) Successful in 7s
markdownlint / markdown-lint (push) Successful in 11s
7dfa8ecfed
Implement add/remove edge API (#5)
All checks were successful
ci / smoke (push) Successful in 8s
clang-format / check-format (push) Successful in 7s
markdownlint / markdown-lint (push) Successful in 11s
a7e1db3d11
Add lookup helpers (#5)
All checks were successful
ci / smoke (push) Successful in 8s
clang-format / check-format (push) Successful in 7s
markdownlint / markdown-lint (push) Successful in 12s
ci / smoke (pull_request) Successful in 8s
clang-format / check-format (pull_request) Successful in 7s
markdownlint / markdown-lint (pull_request) Successful in 11s
79c0a084f0
Sign in to join this conversation.
No reviewers
No milestone
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
erikinkinen/AES!47
No description provided.