Phase 0: Graph indexing and integrity #48

Merged
erikinkinen merged 4 commits from 0-graph-indexing-and-integrity into main 2026-02-17 05:58:48 +01:00
Owner

Closes #6


Summary

This PR implements graph indexing and structural validation for the authority graph in Phase 0. It introduces adjacency and reverse indexes to enable efficient edge queries by subject and object, implements a formal invariant checker (validate_graph()) that verifies structural consistency, and enforces deterministic iteration order across all graph stores.

These additions complete the foundational infrastructure layer required for Phase 0, providing both runtime verification of graph invariants and query capabilities needed for future revocation semantics.


Scope

Included

  • Adjacency indexes (outgoing edges per subject) in EdgeStore::find_from()
  • Reverse indexes (incoming edges per object) in EdgeStore::find_to()
  • Between-query support (EdgeStore::find_between()) for subject-object pairs
  • validate_graph() function that checks invariants I2, I6, and I7
  • Deterministic iteration order based on numeric ID ordering (invariant I10)
  • Comprehensive test coverage for edge queries and validation logic
  • Internal consistency checks across global edge storage and adjacency indices

Explicitly excluded

  • Revocation semantics or propagation logic (Phase 1)
  • Edge deletion operations (deferred until needed)
  • Performance optimization of index structures
  • Serialization or persistence of graph state

Design intent

The core design principle is structural integrity at the substrate level. The authority graph must be query-able, well-formed, and mechanically verifiable before any semantic behavior is introduced.

Adjacency and reverse indexes are maintained as internal implementation details of EdgeStore. They are automatically updated during edge creation (create() and add()) to ensure consistency without imposing coordination burden on callers. The index structure uses std::map with stable numeric IDs as keys, guaranteeing deterministic iteration order (I10).

The validate_graph() function provides runtime verification of Phase 0 invariants:

  • I2 (Identifier validity): All IDs are non-zero and exist in their respective stores
  • I6 (Referential integrity): No dangling references between edges and nodes
  • I7 (Structural consistency): Adjacency indices match the global edge set exactly

Validation is intentionally separate from normal graph operations. It is designed for testing, debugging, and post-replay verification, not as a runtime precondition. This separation keeps the critical path fast while ensuring that structural violations can be detected mechanically.

Deterministic iteration is enforced by using std::map ordered by numeric ID across all stores. This satisfies invariant I10 and ensures that graph state is reproducible across runs, which is essential for replay validation and future event logging.


Phase discipline

This PR belongs to Phase 0 and completes the foundational graph infrastructure layer.

All changes respect Phase 0 boundaries:

  • No authority semantics or revocation behavior
  • No event logging or replay (though structures are compatible)
  • No performance claims or experimental evaluation

The introduced structures are forward-compatible with later phases:

  • Adjacency indices will support revocation traversal (Phase 1)
  • validate_graph() can be extended with additional invariant checks
  • Index structures can be optimized without changing the API

This PR does not modify existing Phase 0 invariants; it implements enforcement mechanisms for invariants already defined in docs/model.md.


Verification

  • All tests pass (edge_store_tests, graph_validation_tests)
  • Invariant checks cover I2, I6, I7 as documented
  • Deterministic iteration verified across Subject, Object, and Edge stores
  • No regressions in existing functionality
  • Index consistency maintained across all edge operations

Notes

For reviewers: Focus on the consistency guarantees between the global edge set and the adjacency/reverse indices. The index update logic in edge_store.cpp is critical and should be verified against the invariant definitions in docs/model.md.

Known limitations: Currently, edge deletion is not implemented. When added, it must maintain index consistency by removing entries from both adjacency and reverse indices.

Follow-up work: Integration with event logging and replay validation will be addressed separately once the Phase 0 event system is designed.

Closes #6 --- ## Summary This PR implements **graph indexing and structural validation** for the authority graph in Phase 0. It introduces adjacency and reverse indexes to enable efficient edge queries by subject and object, implements a formal invariant checker (`validate_graph()`) that verifies structural consistency, and enforces deterministic iteration order across all graph stores. These additions complete the foundational infrastructure layer required for Phase 0, providing both runtime verification of graph invariants and query capabilities needed for future revocation semantics. --- ## Scope ### **Included** - Adjacency indexes (outgoing edges per subject) in `EdgeStore::find_from()` - Reverse indexes (incoming edges per object) in `EdgeStore::find_to()` - Between-query support (`EdgeStore::find_between()`) for subject-object pairs - `validate_graph()` function that checks invariants I2, I6, and I7 - Deterministic iteration order based on numeric ID ordering (invariant I10) - Comprehensive test coverage for edge queries and validation logic - Internal consistency checks across global edge storage and adjacency indices ### **Explicitly excluded** - Revocation semantics or propagation logic (Phase 1) - Edge deletion operations (deferred until needed) - Performance optimization of index structures - Serialization or persistence of graph state --- ## Design intent The core design principle is **structural integrity at the substrate level**. The authority graph must be query-able, well-formed, and mechanically verifiable before any semantic behavior is introduced. **Adjacency and reverse indexes** are maintained as internal implementation details of `EdgeStore`. They are automatically updated during edge creation (`create()` and `add()`) to ensure consistency without imposing coordination burden on callers. The index structure uses `std::map` with stable numeric IDs as keys, guaranteeing deterministic iteration order (I10). **The `validate_graph()` function** provides runtime verification of Phase 0 invariants: - **I2 (Identifier validity)**: All IDs are non-zero and exist in their respective stores - **I6 (Referential integrity)**: No dangling references between edges and nodes - **I7 (Structural consistency)**: Adjacency indices match the global edge set exactly Validation is intentionally separate from normal graph operations. It is designed for testing, debugging, and post-replay verification, not as a runtime precondition. This separation keeps the critical path fast while ensuring that structural violations can be detected mechanically. **Deterministic iteration** is enforced by using `std::map` ordered by numeric ID across all stores. This satisfies invariant I10 and ensures that graph state is reproducible across runs, which is essential for replay validation and future event logging. --- ## Phase discipline This PR belongs to **Phase 0** and completes the foundational graph infrastructure layer. All changes respect Phase 0 boundaries: - No authority semantics or revocation behavior - No event logging or replay (though structures are compatible) - No performance claims or experimental evaluation The introduced structures are **forward-compatible** with later phases: - Adjacency indices will support revocation traversal (Phase 1) - `validate_graph()` can be extended with additional invariant checks - Index structures can be optimized without changing the API This PR does not modify existing Phase 0 invariants; it implements enforcement mechanisms for invariants already defined in `docs/model.md`. --- ## Verification - [x] All tests pass (edge_store_tests, graph_validation_tests) - [x] Invariant checks cover I2, I6, I7 as documented - [x] Deterministic iteration verified across Subject, Object, and Edge stores - [x] No regressions in existing functionality - [x] Index consistency maintained across all edge operations --- ## Notes **For reviewers**: Focus on the consistency guarantees between the global edge set and the adjacency/reverse indices. The index update logic in `edge_store.cpp` is critical and should be verified against the invariant definitions in `docs/model.md`. **Known limitations**: Currently, edge deletion is not implemented. When added, it must maintain index consistency by removing entries from both adjacency and reverse indices. **Follow-up work**: Integration with event logging and replay validation will be addressed separately once the Phase 0 event system is designed.
erikinkinen added this to the Phase 0 milestone 2026-02-17 05:58:10 +01:00
Add adjacency indexes (outgoing per subject) (#6)
All checks were successful
ci / smoke (push) Successful in 8s
clang-format / check-format (push) Successful in 8s
markdownlint / markdown-lint (push) Successful in 11s
69a6aa305c
Add reverse indexes (incoming per object) (#6)
All checks were successful
ci / smoke (push) Successful in 8s
clang-format / check-format (push) Successful in 7s
markdownlint / markdown-lint (push) Successful in 9s
f54ad5cb5e
Implement validate_graph() invariant checker (#6)
All checks were successful
ci / smoke (push) Successful in 8s
clang-format / check-format (push) Successful in 7s
markdownlint / markdown-lint (push) Successful in 10s
f5cf0567a5
Enforce deterministic iteration order (#6)
All checks were successful
ci / smoke (pull_request) Successful in 8s
clang-format / check-format (pull_request) Successful in 7s
markdownlint / markdown-lint (pull_request) Successful in 11s
ci / smoke (push) Successful in 8s
clang-format / check-format (push) Successful in 7s
markdownlint / markdown-lint (push) Successful in 12s
5126e672d6
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!48
No description provided.