SmartMemory
Examples

Decisions Lifecycle

This walkthrough drives a Decision through its lifecycle with the local Python API:

  1. Create a decision with evidence, rejected alternatives, constraints, and rationale
  2. Reinforce it as new evidence arrives
  3. Contradict it when counter-evidence appears
  4. Supersede it when reality changes
  5. Search and retrieve the current decision
  6. Inspect provenance and causal chains
  7. Retract it when it is no longer valid

Decisions are first-class memory items in SmartMemory. See concepts/decision-memory for the model. This guide focuses on the runnable local API surface.

Source: smart-memory-core/smartmemory/smart_memory.py, smart-memory-core/smartmemory/decisions/manager.py.

End-to-end lifecycle

from smartmemory.models.decision import Decision
from smartmemory.models.memory_item import MemoryItem
from smartmemory.pipeline.config import PipelineConfig
from smartmemory.tools.factory import lite_context

lite = dict(pipeline_profile=PipelineConfig.lite(llm_enabled=False))

with lite_context(**lite) as memory:
    evidence_id = memory.add(
        MemoryItem(
            content="Latency p95 measured at 850ms after switching to pgbouncer.",
            memory_type="observation",
        )
    )

    decision = memory.add_decision(
        "Use pgbouncer transaction pooling for the billing service.",
        decision_type="choice",
        confidence=0.85,
        evidence_ids=[evidence_id],
        domain="billing",
        tags=["infra", "pooling"],
        rationale="Reduces connection churn and brings p95 under 200ms.",
        rejected_alternatives=["session pooling", "client-side pooling"],
        constraints=["max_client_conns <= 200"],
    )

    support_id = memory.add(
        MemoryItem(
            content="After 2 weeks in prod: p95 is about 140ms.",
            memory_type="observation",
        )
    )
    reinforced = memory.reinforce_decision(decision.decision_id, support_id)

    contradiction_id = memory.add(
        MemoryItem(
            content="Spike day: transaction pooling broke prepared statements.",
            memory_type="observation",
        )
    )
    contradicted = memory.contradict_decision(
        decision.decision_id,
        contradiction_id,
    )

    replacement = Decision(
        content="Use pgbouncer session pooling with a prepared-statement workaround.",
        decision_type="choice",
        confidence=0.8,
    )
    replacement = memory.supersede_decision(
        decision.decision_id,
        replacement,
        reason="Transaction pooling broke ORM prepared statements.",
    )

    hits = memory.search("billing pooling decision", expertise=True)
    retrieved = memory.get_decision(replacement.decision_id)
    provenance = memory.get_decision_provenance(replacement.decision_id)
    causal = memory.get_decision_causal_chain(
        replacement.decision_id,
        direction="both",
        max_depth=3,
    )

    memory.retract_decision(
        replacement.decision_id,
        reason="Pooling no longer needed after load dropped.",
    )
    retracted = memory.get_decision(replacement.decision_id)

    print(decision.decision_id)
    print(reinforced.reinforcement_count, contradicted.contradiction_count)
    print(memory.get_decision(decision.decision_id).status, retrieved.status)
    print([d.content for d in hits["decision"]])
    print(sorted(provenance.keys()), sorted(causal.keys()))
    print(retracted.status)

add_decision(...) returns a Decision object with .decision_id, .rejected_alternatives, .rationale, .constraints, .confidence, and .status. reinforce_decision(...), contradict_decision(...), supersede_decision(...), and retract_decision(...) are real lifecycle methods on SmartMemory.

search(expertise=True) returns a dictionary keyed by expertise type, not a flat list. Read decisions from hits["decision"].

Service and client notes

The authenticated service exposes the same lifecycle under /memory/decisions/*, and smartmemory-client exposes helpers such as create_decision(...), reinforce_decision(...), supersede_decision(...), retract_decision(...), get_decision(...), list_decisions(...), get_provenance_chain(...), and get_causal_chain(...).

For local examples and tests, prefer the core API above. It runs without a service, token, or workspace UUID.

On this page