feat: Semantic DAG v0.6.0 — append-only causal graph with signing and sync#76
Merged
ApiliumDevTeam merged 8 commits intodevfrom Mar 13, 2026
Merged
feat: Semantic DAG v0.6.0 — append-only causal graph with signing and sync#76ApiliumDevTeam merged 8 commits intodevfrom
ApiliumDevTeam merged 8 commits intodevfrom
Conversation
…ith indexes Core Semantic DAG types: DagAction, DagActionHash (BLAKE3), DagPayload (7 variants), DagTipSet, DagStore with pluggable backends. - Content-addressable hashing: blake3(parents || author || seq || ts || payload) - DagBackend trait with MemoryDagBackend and SledDagBackend implementations - Author index, affected-triple index, tip persistence - Schema versioning with forward-compat rejection - Rebuild indexes from backend on restart - Pruning with 4 retention policies (KeepAll/KeepSince/KeepLast/KeepDepth) - Topological sort via Kahn's algorithm - Feature gates: dag, dag-sign, sled-backend
…nc protocol - Time-travel: replay DagPayload onto ephemeral GraphDB to reconstruct state at any point in DAG history; DagDiff for ancestry comparison - Export: DagGraph portable structure with DOT (Graphviz), Mermaid, and JSON renderers with color-coded node types - Signing: Ed25519 via ed25519-dalek; sign/verify action hashes; DagSigningKey/DagVerifyingKey with hex serialization (dag-sign feature) - Sync: pull-based protocol — SyncRequest/SyncResponse with compute_missing and ingest (no tip mutation)
GraphDB gains optional DagStore field (feature-gated). Existing insert() and delete() are unchanged — full backward compatibility. New constructors: memory_with_dag(), sled_with_dag() New methods: enable_dag(), enable_dag_persistent(), insert_via_dag(), delete_via_dag(), dag_tips(), dag_action(), dag_history(), dag_chain(), dag_prune(), dag_at(), dag_at_timestamp(), dag_sign(), dag_verify(), dag_export(), dag_ingest(), dag_compute_missing(), dag_diff()
…AG tips
- WalEntryKind::DagAction { action_bytes } — serialized bytes to avoid
circular deps with aingle_graph
- State machine apply_dag_action(): deserialize → DagStore.put() →
apply payload to materialized view (exhaustive match on all variants)
- ClusterSnapshot gains dag_tips with #[serde(default)] for backward compat
- Snapshot builder reads DAG tips; restore rebuilds tip set
- create_triple and delete_triple construct DagActions when dag feature is enabled: determine tips → build action → serialize to WAL → Raft - AppState gains dag_author (NodeId) and dag_seq_counter (AtomicU64) - Startup: enable persistent DAG (Sled) or fallback to in-memory; create genesis action if DAG is empty; set author from cluster node ID - Feature gates: dag = ["cluster", "aingle_graph/dag", "aingle_raft/dag"]
12 new endpoints under /api/v1/dag/: GET tips, action/:hash, history, chain, stats, at/:hash, diff, export POST prune, sync, sync/pull GET verify/:hash (dag-sign feature) Includes DOT/Mermaid/JSON export with content-type negotiation, pull-based cross-node sync, and time-travel state reconstruction.
Every DagAction is now signed with the node's Ed25519 key before Raft submission. The state machine rejects unsigned actions (Genesis exempt). - Merge dag-sign into dag feature (signing always enabled with DAG) - AppState gains dag_signing_key (Arc<DagSigningKey>) loaded from node.key - Signing key initialized from existing P2P identity seed or generated - create_triple/delete_triple sign actions before Raft write - State machine rejects unsigned non-Genesis actions with clear error - Verify endpoint available at GET /api/v1/dag/verify/:hash - Transparent to all exposed APIs — no request/response changes
Update version fields and internal dependency references across all 13 product crates to align with the v0.6.0 release.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Full implementation of the Semantic DAG (Directed Acyclic Graph) for AIngle, adding an append-only causal graph on top of the existing triple store — enabling full traceability, time-travel queries, and cross-node synchronization.
Phases included
Data model & persistent storage —
DagAction,DagActionHash(BLAKE3),DagPayload(7 variants),DagTipSet,DagStorewith pluggable backends (memory + Sled). Author and affected-triple indexes, schema versioning, index rebuild on restart. Pruning with 4 retention policies (KeepAll / KeepSince / KeepLast / KeepDepth).Time-travel, export & sync protocol — State reconstruction at any point in the DAG via replay onto an ephemeral
GraphDB.DagDifffor ancestry comparison. Portable export (DagGraph) with DOT (Graphviz), Mermaid, and JSON renderers. Pull-based sync protocol (SyncRequest/SyncResponse) withcompute_missingandingest.GraphDB integration — 18 new public methods on
GraphDB(feature-gated). Constructors:memory_with_dag(),sled_with_dag(). Methods:insert_via_dag(),delete_via_dag(),dag_tips(),dag_action(),dag_history(),dag_chain(),dag_prune(),dag_at(),dag_at_timestamp(),dag_sign(),dag_verify(),dag_export(),dag_ingest(),dag_compute_missing(),dag_diff(), etc. Full backward compatibility with existinginsert()/delete().WAL + Raft state machine —
WalEntryKind::DagActionvariant for serialization without circular dependencies. State machine applies actions toDagStoreand materialized view. Snapshot includesdag_tipswith backward compat (#[serde(default)]).Write path through Raft —
create_tripleanddelete_tripleconstructDagActionswhen thedagfeature is enabled: determine tips → build action → serialize to WAL → Raft.AppStategainsdag_authoranddag_seq_counter. Startup creates a Genesis action if the DAG is empty.REST endpoints — 12 new endpoints under
/api/v1/dag/:GETtips, action/:hash, history, chain, stats, at/:hash, diff, exportPOSTprune, sync, sync/pullGETverify/:hashMandatory Ed25519 signing — Every
DagActionis signed with the node's Ed25519 key before Raft submission. The state machine rejects unsigned actions (Genesis exempt). Key derived from the existing P2P identity seed. Verification endpoint atGET /api/v1/dag/verify/:hash. Transparent to all exposed APIs.Key changes
aingle_graph::dag::*(action, backend, export, signing, store, sync, timetravel, tips, pruning)dag,dag-sign,sled-backendblake3,ed25519-dalek,rand_core,petgraph(dag feature only)Test plan
cargo build --features dagcargo test --features dagdagfeature is unaffected