F045: Decision Graph Storage Layer
Status: P1 Implemented Priority: High Research basis: Context Graphs (Masood 2026), Graph-Constrained Reasoning (ICML 2025), MemoBrain (Qian et al. 2026), KnowFlow (Neural Networks 2026), Dual Memory Knowledge Graphs (ScienceDirect 2026)
Problem
Section titled “Problem”CSTP stores decisions as independent documents with flat related_to links discovered via semantic similarity. This misses structural relationships that only a graph can express:
- No traversal: Can’t follow chains of decisions to find root causes or downstream impacts
- No centrality: Can’t determine which decisions are structurally important (many dependents) vs peripheral
- No contradiction detection: Conflicting active decisions aren’t surfaced unless semantically similar
- No constrained reasoning: Agents can make decisions that violate the existing dependency structure
- Compaction is time-based, not salience-based: Old but structurally critical decisions get summarized equally
CSTP is already 80% of a decision knowledge graph - it has nodes (decisions), edges (related_to), attributes (confidence, outcome, bridge-definitions), and semantic search. Adding a proper graph layer unlocks the remaining 20%.
Solution
Section titled “Solution”Add a graph storage layer alongside ChromaDB that represents decisions as nodes and their relationships as typed, directed edges. Queries can use graph traversal, semantic search, or both.
Architecture
Section titled “Architecture”┌─────────────────────────────────────┐│ CSTP API Layer │├──────────────┬──────────────────────┤│ ChromaDB │ Graph Store ││ (vectors) │ (structure) ││ │ ││ Semantic │ Traversal ││ similarity │ Centrality ││ Bridge │ Path finding ││ search │ Contradiction ││ │ detection │└──────────────┴──────────────────────┘ │ │ └───── Dual Retrieval ────────┘ (F024 upgrade)Graph Model
Section titled “Graph Model”Nodes: Each decision becomes a graph node with properties:
class DecisionNode: id: str # Decision ID category: str stakes: str confidence: float outcome: str | None date: str tags: list[str] pattern: str | None # Abstract pattern (F027) structure_desc: str | None # Bridge structure (F024) function_desc: str | None # Bridge function (F024) salience: float # Computed: graph centrality scoreEdges: Typed, directed relationships between decisions:
class DecisionEdge: source_id: str target_id: str edge_type: EdgeType # See below weight: float # Strength of relationship created_at: datetime created_by: str # Agent or auto-detected context: str | NoneEdge Types:
| Type | Direction | Meaning |
|---|---|---|
depends_on |
A → B | A required B to exist first |
supersedes |
A → B | A replaces B (B is obsolete) |
contradicts |
A ↔ B | A and B conflict (bidirectional) |
refines |
A → B | A narrows or improves on B |
relates_to |
A ↔ B | Topically connected (existing, auto-populated) |
caused_by |
A → B | A was a consequence of B’s outcome |
blocks |
A → B | B cannot proceed until A resolves |
Storage Backend
Section titled “Storage Backend”Phase 1: NetworkX (in-process)
- Zero infrastructure - pure Python, in-memory graph
- Persist as JSONL alongside ChromaDB
- Sufficient for hundreds to low thousands of decisions
- Built-in centrality algorithms (PageRank, betweenness)
Phase 2: Neo4j (optional, at scale)
- For deployments with 10K+ decisions or multi-agent federation
- Cypher queries for complex traversal
- Native graph visualization
- Docker-composable with existing CSTP stack
# Graph CRUDcstp.linkDecisions - Create typed edge between decisionscstp.unlinkDecisions - Remove edgecstp.getGraph - Get subgraph (node + N hops, optional edge type filter)
# Graph Queriescstp.findPath - Shortest path between two decisionscstp.getAncestors - All decisions this one depends oncstp.getDescendants - All decisions that depend on this onecstp.findContradictions - Active decisions with contradiction edgescstp.getBlockedChain - Decisions blocked by unresolved dependencies
# Saliencecstp.computeSalience - Recalculate centrality scores for all nodescstp.getHighSalience - Top N structurally important decisionsDual Retrieval (upgrades F024 Bridge Search)
Section titled “Dual Retrieval (upgrades F024 Bridge Search)”Current F024 bridge search uses two semantic paths (structure vs function). Graph layer adds a third:
- Semantic (vector): “What decisions are about similar topics?” (ChromaDB)
- Structural (graph): “What decisions are connected to this one?” (Graph traversal)
- Hybrid: Combine both - semantically similar AND structurally connected = highest relevance
def dual_query(query: str, decision_id: str | None = None, hops: int = 2): # Semantic results from ChromaDB semantic = chromadb.query(query, top_k=10)
# Graph results if we have a starting node if decision_id: graph_neighbors = graph.get_subgraph(decision_id, hops=hops) # Boost decisions that appear in BOTH result sets return merge_and_rank(semantic, graph_neighbors)
return semanticSalience-Based Compaction (upgrades F041)
Section titled “Salience-Based Compaction (upgrades F041)”Instead of time-based decay, use graph centrality to determine compaction priority:
| Salience | Compaction | Reason |
|---|---|---|
| High (top 20%) | Never compact | Many dependents, structurally critical |
| Medium | Summary after 30 days | Some connections, moderate importance |
| Low (leaf nodes, reviewed) | Digest after 14 days | Peripheral, outcome captured |
| Superseded | Fold into successor immediately | Obsolete by definition |
Graph-Aware Guardrails (upgrades F030)
Section titled “Graph-Aware Guardrails (upgrades F030)”New guardrail type: graph-constraint
# Block decisions that contradict active high-salience decisions{ "name": "no-contradict-high-salience", "type": "graph-constraint", "rule": "New decision must not contradict any active decision with salience > 0.7", "action": "block", "message": "This contradicts {conflicting_decision}. Supersede it first."}Auto-Edge Detection
Section titled “Auto-Edge Detection”When recording a new decision, automatically detect potential edges:
- Run semantic query for similar decisions
- Compare patterns and tags for potential
refinesorcontradicts - Check if any active decisions in the same category have opposing outcomes → suggest
contradicts - If decision references another decision’s outcome → suggest
caused_by
Phases
Section titled “Phases”P1: Foundation (NetworkX + basic edges)
Section titled “P1: Foundation (NetworkX + basic edges)”- NetworkX graph initialized from existing
related_todata linkDecisionsandgetGraphAPI endpoints- JSONL persistence alongside ChromaDB
- Edge types:
relates_to,supersedes,depends_on
P2: Salience + Dual Retrieval
Section titled “P2: Salience + Dual Retrieval”- PageRank-based salience scoring
computeSalience,getHighSalienceendpoints- Dual retrieval: semantic + graph merged results
- Salience field added to query response
P3: Graph-Aware Guardrails
Section titled “P3: Graph-Aware Guardrails”contradictsandblocksedge typesfindContradictions,getBlockedChainendpoints- Graph-constraint guardrail type
- Auto-edge detection on
recordDecision
P4: Advanced Queries + Visualization
Section titled “P4: Advanced Queries + Visualization”- Path finding, ancestor/descendant traversal
- Graph export for dashboard visualization (D3.js/Cypher)
- Integration with F044 (Work Discovery) - graph-informed ready queue
- Optional Neo4j backend for scale
Integration Points
Section titled “Integration Points”- F002 (Query): Dual retrieval merges semantic + graph results
- F024 (Bridge Definitions): Graph adds structural retrieval path
- F027 (Decision Quality): Edge count and diversity as quality signals
- F030 (Circuit Breakers): Graph-constraint guardrails
- F040 (Task Graph): Tasks as a subgraph connected to decision nodes
- F041 (Compaction): Salience-based instead of time-based decay
- F042 (Dependencies): F045 subsumes F042 - this IS the dependency graph
- F043 (Distributed Merge): Graph edges included in merge protocol
- F044 (Work Discovery): Contradictions, blocked chains, low-salience clusters in ready queue
Research References
Section titled “Research References”- Context Graphs (Masood, 2026) - Governed queryable memory layer connecting entities, decisions, evidence. Explanation packets: answer + evidence paths + provenance.
- Graph-Constrained Reasoning (Luo et al., ICML 2025) - Constrains LLM reasoning to valid knowledge graph paths. KG-Trie structure.
- MemoBrain (Qian et al., 2026) - Dependency-aware memory over reasoning steps. Prunes invalid steps, folds sub-trajectories, preserves reasoning backbone.
- KnowFlow (Neural Networks, 2026) - Knowledge-streamlined agent design. Structured knowledge pipeline consulted before acting.
- Dual Memory Knowledge Graph (ScienceDirect, 2026) - Integrates semantic memory (meaning) with observability memory (what happened). Reduces hallucination.
Note on F042
Section titled “Note on F042”F045 subsumes F042 (Decision Dependency Graph). F042 described typed links between decisions; F045 provides the full storage layer, algorithms, and integration. F042 should be marked as “merged into F045” in the index.