Files
cleveragents-core/docs/adr/ADR-007-decision-tree-and-correction.md
T
CoreRasurae 007af498b8
CI / benchmark-publish (pull_request) Has been skipped
CI / build (pull_request) Successful in 17s
CI / helm (pull_request) Successful in 33s
CI / lint (pull_request) Successful in 3m42s
CI / security (pull_request) Successful in 4m8s
CI / quality (pull_request) Successful in 4m9s
CI / typecheck (pull_request) Successful in 4m20s
CI / integration_tests (pull_request) Successful in 7m2s
CI / unit_tests (pull_request) Successful in 7m55s
CI / docker (pull_request) Successful in 1m19s
CI / coverage (pull_request) Successful in 8m46s
CI / e2e_tests (pull_request) Successful in 16m1s
CI / status-check (pull_request) Successful in 1s
CI / build (push) Successful in 17s
CI / helm (push) Successful in 22s
CI / quality (push) Successful in 31s
CI / lint (push) Successful in 3m28s
CI / typecheck (push) Successful in 3m54s
CI / benchmark-regression (push) Has been skipped
CI / security (push) Successful in 4m5s
CI / integration_tests (push) Successful in 6m13s
CI / unit_tests (push) Successful in 6m28s
CI / docker (push) Successful in 1m34s
CI / coverage (push) Successful in 12m5s
CI / e2e_tests (push) Successful in 18m47s
CI / status-check (push) Successful in 1s
CI / benchmark-publish (push) Successful in 28m0s
CI / benchmark-regression (pull_request) Successful in 59m48s
refactor(autonomy): rename automation profile task flags to spec names
Renamed all 11 task-type confidence threshold fields in AutomationProfile
from phase-transition semantics to spec-defined task-type semantics.
Updated all 8 built-in profiles, CLI formatting, YAML schema, services,
and all Behave/Robot tests referencing the old field names.

Post-review fixes:
- Fixed 24 stale old field names in M6 fixture files
  (automation_profiles.json, autonomy_guardrails.json)
- Added model_validator(mode='before') to detect legacy field names
  and raise actionable ValueError with rename mapping
- Added semantic bridge comments in PlanLifecycleService mapping
  task-type thresholds to phase-transition gates
- Added threshold_field to structured log messages for observability
- Restored categorised CLI automation-profile show output to match
  spec (Phase Transitions / Decision Automation / Self-Repair /
  Execution Controls) instead of flat list
- Added missing access_network field to spec show output examples
  (Rich, Plain, JSON, YAML variants)
- Aligned ADR-017 profile fields table to all 11 fields with
  descriptions matching spec Automatable Tasks table
- Aligned automation_profiles.md threshold descriptions with spec
- Added spec section references in phase_reversion.md, error_recovery.md,
  and plan_execute.md for field naming context
- Extended repository roundtrip test to assert all 11 threshold fields
- Fixed benchmark _make_profile() passing safety fields as top-level
  kwargs instead of via SafetyProfile sub-model (incompatible with
  extra="forbid")
- Aligned CLI JSON/YAML output structure for automation-profile show
  with the specification grouped format (phase_transitions,
  decision_automation, self_repair, execution_controls)
- Moved safety boolean fields into the Execution Controls section
  of Rich output per spec examples
- Reverted auto profile description to "Fully automatic except apply"
  per specification (line 16703, line 28406)
- Improved bridge comments in test steps with semantic context for
  threshold-to-gate mappings

ISSUES CLOSED: #902
2026-03-30 13:18:07 +01:00

11 KiB

adr_number, title, status_history, tier, authors, superseded_by, related_adrs, acceptance
adr_number title status_history tier authors superseded_by related_adrs acceptance
7 Decision Tree and Correction
2026-02-16
Proposed
Jeffrey Phillips Freeman
2026-02-16
Accepted
Jeffrey Phillips Freeman
2
Jeffrey Phillips Freeman
null
number title relationship
6 Plan Lifecycle Decision trees are built during lifecycle phases and drive phase transitions
number title relationship
16 Invariant System Enforced invariants are recorded as decision nodes in the tree
number title relationship
17 Automation Profiles Confidence thresholds determine which decisions require human intervention
number title relationship
33 Decision Recording Protocol Details the tool-based mechanism by which decisions are recorded in the tree
number title relationship
34 Decision Tree Versioning and History Defines the dual structure (structural tree + influence DAG) and versioning model for the decision tree
number title relationship
35 Decision Tree Rollback and Replay Specifies the rollback and replay mechanics for corrections within the decision tree
votes_for votes_against abstentions
voter comment
Jeffrey Phillips Freeman <Jeffrey.Freeman@CleverThis.com> Persistent decision graphs enable targeted correction without re-running entire plans

Context

When an AI system generates a plan and executes it, individual decisions along the way may prove incorrect — a strategy choice may be suboptimal, a resource selection may be wrong, or the original prompt may be too vague. Without a persistent record of what decisions were made, why, and how they relate to each other, correction requires re-running the entire plan from scratch. For large, hierarchically decomposed plans, this is prohibitively expensive.

The system needs a structured decision graph that captures every choice point, its rationale, its context, and its downstream dependencies — enabling targeted correction that only invalidates and re-runs the affected subtree.

Decision Drivers

  • Individual decisions in a plan may prove incorrect, but re-running the entire plan from scratch is prohibitively expensive for large hierarchically decomposed plans
  • Must capture every choice point with its rationale, context, and downstream dependencies to enable targeted correction
  • Corrections (including prompt corrections) should use a single unified mechanism operating on decision nodes
  • The dependency graph between decisions must be explicit so invalidation cascades affect only the relevant subtree
  • Context snapshots must be preserved per-decision to enable replay and debugging in isolation
  • Confidence-based autonomy requires structured decision records with scores to determine when human intervention is needed

Decision

Every plan maintains a persistent decision tree where each node is a typed decision record. The tree captures the prompt, invariant enforcement, strategy choices, resource selections, child plan blueprints, tool invocations, error recoveries, validation responses, and user interventions. All corrections — including prompt corrections — use a unified agents plan correct command that operates on decision nodes by ID.

Design

Decision Types

The system defines eleven decision types:

Type Description Phase
prompt_definition The prompt/description for this plan (root decision) Strategize
invariant_enforced An invariant applicable to this plan, added as a constraint Strategize
strategy_choice High-level approach decision Strategize
implementation_choice How to implement a specific task Execute
resource_selection Which resources to read/modify Strategize or Execute
subplan_spawn Decision to create a child plan Strategize
subplan_parallel_spawn Decision to spawn a group of child plans concurrently Strategize
tool_invocation Which tool to use Execute
error_recovery How to handle a failure Execute
validation_response Response to a validation failure Execute
user_intervention User-provided guidance or correction Any

The Prompt as Root Decision

The prompt passed to the strategy actor is the root prompt_definition decision node. This is significant because:

  • Parent plans create child plan prompts as prompt_definition decisions in their own tree, which become root decisions of child plan trees.
  • Invariants are recorded as invariant_enforced decisions, making them explicit tree nodes that constrain downstream decisions.
  • Correcting the prompt uses the same mechanism as correcting any other decision.

Decision Record Structure

Each decision record contains:

Identity: decision_id (ULID), plan_id, parent_decision_id (for tree structure), sequence_number.

Classification: decision_type (one of the eleven types above).

The decision itself: question (what was being answered), chosen_option, alternatives_considered, confidence_score (0.0-1.0, optional).

Context snapshot: hot_context_hash, hot_context_ref, relevant_resources (list of resource references), actor_state_ref (LangGraph checkpoint).

Rationale: rationale (why this option was chosen), actor_reasoning (raw LLM reasoning, optional).

Downstream impact (populated during Execute): downstream_decision_ids, downstream_plan_ids, artifacts_produced.

Correction metadata: is_correction, corrects_decision_id, correction_reason, superseded_by.

Decision Timing

Phase Activity
Strategize Initial decisions are created: prompt_definition, invariant_enforced, strategy_choice, subplan_spawn, subplan_parallel_spawn. downstream_plan_ids is empty.
Execute Child plans are spawned and downstream_plan_ids is populated. Additional decisions may be created (implementation_choice, resource_selection, tool_invocation, error_recovery), constrained by Strategize-phase decisions.
Apply No new decisions. History may be flagged for cleanup after successful apply.

Decision Making and Autonomy

Who makes decisions depends on the automation profile:

  • edit_code = 1.0 (always manual): User is prompted for each decision during Strategize.
  • edit_code = 0.0 (always automatic): Strategy actor decides autonomously, records reasoning.
  • Intermediate thresholds: Auto-decide only when the confidence score meets or exceeds the threshold; otherwise prompt the user.

The same pattern applies to execute_command for Execute-phase decisions.

Unified Correction Mechanism

All corrections use:

agents plan correct <decision_id> --mode=<mode> --guidance "<text>"

Parameters: decision_id (ULID), --mode (revert — rollback and re-run, or append — add fix at end), --guidance (free-form corrected decision text).

Correcting a decision automatically invalidates all downstream decisions in the affected subtree (including child plans). The system knows the dependency graph and can re-run only the invalidated portion.

Correction Scenarios

Situation Approach
Original request was too vague Correct the prompt_definition decision
Strategy actor made a bad specific choice Correct that specific strategy_choice decision
Parent gave child a bad prompt Correct the child's prompt_definition
An invariant should not apply Correct (remove) the invariant_enforced decision
A missing constraint should be added Add a new invariant_enforced decision
Sequential children should be parallel Correct decisions to use subplan_parallel_spawn

Storage Schema

Decisions are stored in a decisions table with columns for all record fields, plus decision_dependencies (parent-child edges) and correction_attempts (correction history with attempt number, mode, guidance, and outcomes).

Constraints

  • Every decision must have a decision_type from the eleven defined types. No untyped decisions.
  • The prompt_definition decision is always the root of a plan's decision tree. Every plan has exactly one.
  • Decisions created during Execute must be constrained by Strategize-phase decisions. Violation of this rule triggers phase reversion, not silent override.
  • Correction of a decision must invalidate all downstream decisions in the subtree. Partial invalidation is not permitted.
  • The context_snapshot must be sufficient to replay the decision in isolation (hash of hot context, pointer to full snapshot, actor state checkpoint).

Consequences

Positive

  • Targeted correction avoids re-executing entire plans. Only the invalidated subtree is re-run.
  • The persistent decision graph enables full auditability — every choice can be traced to its context and rationale.
  • Treating the prompt as a decision node unifies the correction mechanism — no special case for prompt changes.
  • The context snapshot enables debugging and replay of any individual decision.

Negative

  • Storing context snapshots and full decision records for every choice consumes significant storage, especially for large plans with many tool invocations.
  • The dependency graph tracking adds complexity to the plan execution engine.
  • Correction with downstream invalidation requires careful coordination when child plans are running concurrently.

Risks

  • Context snapshot storage could grow unbounded without retention policies.
  • Correction cascades in deep hierarchies could invalidate large portions of completed work.
  • The confidence score threshold mechanism depends on LLM-provided confidence values, which may not be well-calibrated.

Alternatives Considered

Flat decision log (append-only, no tree structure) — Simpler to implement but does not support targeted correction. Correcting a single decision would require identifying all dependent decisions manually, which is error-prone and infeasible for large plans.

No persistent decision tracking (re-run from scratch on correction) — Adequate for small plans but prohibitively expensive for hierarchically decomposed plans where only a small subtree needs correction.

Compliance

  • Decision type coverage tests: Unit tests verify that all eleven decision types can be created, stored, retrieved, and corrected.
  • Correction cascade tests: Tests verify that correcting a decision invalidates exactly the right downstream subtree — no more, no less.
  • Context snapshot integrity: Tests verify that replaying a decision from its context snapshot produces consistent results.
  • BDD scenarios: Behave features exercise correction workflows including prompt correction, strategy revision, and cross-hierarchy correction.
  • Storage retention tests: Tests verify that decision history cleanup respects retention policies.