Files
cleveragents-core/docs/reference/decision_service.md
T

5.4 KiB
Raw Blame History

Decision Service Reference

Overview

DecisionService provides the application-layer interface for recording decisions during plan execution, retrieving decision histories, and managing context snapshots. It lives in src/cleveragents/application/services/decision_service.py.

Dual-Mode Persistence

Mode UnitOfWork Storage
In-memory None Internal dicts (_decisions, _plan_decisions)
Persisted provided DB via DecisionRepository + in-memory cache

When a UnitOfWork is wired, mutations are written to the database first, then the in-memory cache is updated (write-through).

Constructor

DecisionService(
    settings: Settings | None = None,
    unit_of_work: UnitOfWork | None = None,
)
  • settings Application settings (optional for in-memory mode).
  • unit_of_work When provided, decisions are persisted via DecisionRepository.

Recording

record_decision()

svc.record_decision(
    plan_id="01HV...",
    decision_type=DecisionType.STRATEGY_CHOICE,   # or a string
    question="Which approach?",
    chosen_option="Build a REST API",
    parent_decision_id=None,            # optional
    alternatives_considered=None,       # list[str]
    confidence_score=None,              # 0.0-1.0
    rationale="",                       # human-readable
    actor_reasoning=None,               # raw LLM trace
    context_snapshot=None,              # auto-captured if omitted
    artifacts_produced=None,            # list[ArtifactRef]
    is_correction=False,
    corrects_decision_id=None,
    correction_reason=None,
)
  • Auto-assigns a monotonically increasing sequence number per plan.
  • Auto-generates a ULID for decision_id.
  • Auto-captures a context snapshot (SHA-256 hash) when no explicit snapshot is provided.
  • Stores the snapshot in the built-in SnapshotStore.

Raises:

  • ValidationError required fields missing or empty.
  • DuplicateDecisionError decision ID already exists.

Retrieval

Method Description
get_decision(decision_id) Single decision by ULID
list_decisions(plan_id) All decisions for a plan, ordered by seq
list_by_type(plan_id, decision_type) Filtered by type, ordered by seq

All raise DecisionNotFoundError when the target decision does not exist (where applicable).

Tree Operations

Method Description
get_tree(plan_id) BFS from root(s), level by level
get_path_to_root(decision_id) Walk from a decision up to the root

Superseded Decisions

Method Description
mark_superseded(decision_id, new_decision_id) Mark a decision as superseded
get_superseded(plan_id) List all superseded decisions

Delete

svc.delete_decision(decision_id)  # -> True

Removes from both persistence and the snapshot store. Raises DecisionNotFoundError if not found.

Snapshot Store

SnapshotStore manages ContextSnapshot objects keyed by decision ID with hash-based deduplication.

Method Description
get_snapshot(decision_id) Retrieve snapshot for a decision
get_snapshots_for_plan(plan_id) All snapshots for a plan's decisions
snapshots.get_by_hash(hash) Decision IDs sharing the same context hash
snapshots.store(id, snap) Store a snapshot (internal)
snapshots.remove(id) Remove a snapshot

Statistics

Method Description
count_decisions(plan_id) Number of decisions for a plan
get_next_sequence(plan_id) Next available sequence number

Custom Exceptions

Exception Base Description
DuplicateDecisionError BusinessRuleViolation Decision ID already exists
DecisionNotFoundError ResourceNotFoundError Decision not found
SequenceConflictError BusinessRuleViolation Sequence number already used

Running Tests

# Behave BDD tests
nox -s unit_tests -- features/decision_recording.feature

# Robot Framework integration smoke tests
nox -s integration_tests

# ASV benchmarks
nox -s benchmark
  • Domain model: src/cleveragents/domain/models/core/decision.py
  • Persistence: src/cleveragents/infrastructure/database/repositories.py (DecisionRepository)
  • Database schema: docs/reference/database_schema.md
  • ADR: docs/adr/ADR-033-decision-recording-protocol.md