Files
cleveragents-core/docs/reference/decision_correction.md
T
freemo a0ac30d5de
CI / lint (pull_request) Successful in 21s
CI / typecheck (pull_request) Successful in 52s
CI / security (pull_request) Successful in 55s
CI / quality (pull_request) Successful in 39s
CI / build (pull_request) Successful in 29s
CI / helm (pull_request) Successful in 23s
CI / unit_tests (pull_request) Failing after 6m49s
CI / docker (pull_request) Has been skipped
CI / e2e_tests (pull_request) Successful in 17m22s
CI / integration_tests (pull_request) Failing after 23m1s
CI / coverage (pull_request) Successful in 11m3s
CI / status-check (pull_request) Failing after 1s
CI / benchmark-publish (pull_request) Has been skipped
CI / benchmark-regression (pull_request) Successful in 56m57s
docs: update and extend documentation for v3.8.0 changes
- docs/reference/plan_cli.md: add note about legacy/v3 plan workflow
  mixing being disallowed (introduced in v3.8.0, issue #1577)
- docs/reference/uko_runtime.md: document v3.8.0 provenance tracking
  (sourceResource, validFrom, isCurrent on typed triples) and revision
  chain for temporal queries across indexing runs (issue #891)
- docs/reference/decision_correction.md: add CorrectionAttemptRecord
  section documenting the correction_attempts table, state lifecycle,
  repository API, and usage examples (issue #920)
- docs/modules/uko-provenance.md: new module guide for UKO provenance
  tracking covering purpose, how provenance is attached, revision chain
  mechanics, query patterns, persistence format, BDD coverage, and gotchas
2026-04-05 20:05:48 +00:00

6.6 KiB
Raw Blame History

Decision Correction Reference

Overview

The correction subsystem allows operators to modify a plan's decision tree after execution by either reverting a subtree of decisions or appending new decisions as a child plan.

Correction Modes

Revert

Invalidates the targeted decision and every descendant reachable via BFS traversal. Associated artifacts are archived and affected child plans are rolled back.

          ┌─── D1 (target) ◄── revert starts here
          │       │
          │    ┌──┴──┐
          │    D2    D3          ← all invalidated
          │          │
          │          D4          ← also invalidated

Append

Preserves the original decision and spawns a new child plan rooted at the target node. The child plan carries the operator's guidance and produces additional decisions without disturbing the existing tree.

          D1 (target)
           │
        ┌──┴──────────┐
        D2 (original)  CP-new   ← child plan appended

Impact Analysis — BFS Algorithm

Impact analysis uses breadth-first search over the decision tree's adjacency list (parent → children mapping):

from collections import deque

def compute_affected_subtree(target_id, tree):
    affected = []
    queue = deque([target_id])
    while queue:
        node = queue.popleft()
        affected.append(node)
        queue.extend(tree.get(node, []))
    return affected

Risk Classification

Affected Count Risk Level
≤ 3 low
4 10 medium
> 10 high

Dry-Run Output

A dry-run report contains:

  • impact — Full CorrectionImpact with affected decisions, files, child plans, estimated cost, and risk level.
  • decisions_to_invalidate — Decision IDs that would be marked invalid (revert mode only).
  • child_plans_to_rollback — Child plans that would be rolled back.
  • estimated_recompute_time_seconds — Wall-clock estimate.
  • warnings — Human-readable cautions (e.g. high risk).

Status Lifecycle

PENDING → ANALYZING → EXECUTING → APPLIED
                                 → FAILED
         PENDING → CANCELLED
         ANALYZING → CANCELLED

Service API

Method Description
request_correction() Create a new correction request
analyze_impact() BFS impact analysis on the decision tree
generate_dry_run_report() Full report without side effects
execute_revert() Invalidate subtree + archive artifacts
execute_append() Spawn child plan preserving original decision
execute_correction() Dispatch to revert or append based on mode
get_correction() Retrieve a correction by ID
list_corrections() List corrections (optional plan_id filter)
list_attempts() List execution attempts for a correction
cancel_correction() Cancel a pending/analyzing correction

Correction Attempts (v3.8.0+)

Each execution of a correction is tracked as a CorrectionAttemptRecord. Multiple attempts may exist for a single correction (e.g. if a first attempt fails and the operator retries).

CorrectionAttemptRecord

Module: cleveragents.domain.models.core.correction_attempt

Field Type Description
id str ULID of this attempt
correction_id str Parent correction ULID
plan_id str Plan this correction targets
original_decision_id str Decision being corrected
new_decision_id str | None Replacement decision (set on success)
mode CorrectionMode revert or append
state CorrectionAttemptState Current state (see lifecycle below)
guidance str Operator guidance text (110,000 chars)
created_at datetime UTC creation timestamp
completed_at datetime | None UTC completion timestamp (terminal states only)
archived_artifacts_path str | None Path to archived artifacts (revert mode)

CorrectionAttemptState Lifecycle

pending → executing → complete
                    → failed

Valid transitions:

From To Notes
pending executing Attempt begins execution
executing complete Correction applied successfully
executing failed Correction failed; completed_at auto-set

Terminal states (complete, failed) cannot transition further. Self-transitions are rejected.

CorrectionAttemptRepository

Module: cleveragents.infrastructure.repositories.correction_attempt

Method Description
create(record) Persist a new attempt; raises DatabaseError on FK violation
get(attempt_id) Retrieve by ULID; raises ResourceNotFoundError if absent
list_by_plan(plan_id) List all attempts for a plan (ordered by created_at)
update_state(attempt_id, new_state, *, new_decision_id, completed_at, archived_artifacts_path) Transition state; auto-sets completed_at for terminal states
delete(attempt_id) Hard-delete an attempt record

Usage Example

from cleveragents.domain.models.core.correction_attempt import (
    CorrectionAttemptRecord,
    CorrectionAttemptState,
)
from cleveragents.domain.models.core.correction import CorrectionMode

attempt = CorrectionAttemptRecord(
    id="01HXYZ...",
    correction_id="01HABC...",
    plan_id="01HDEF...",
    original_decision_id="01HGHI...",
    mode=CorrectionMode.REVERT,
    state=CorrectionAttemptState.PENDING,
    guidance="Revert the database migration decision and retry with a safer approach.",
)

# Transition to executing
repo.update_state(attempt.id, CorrectionAttemptState.EXECUTING)

# Complete the attempt
repo.update_state(
    attempt.id,
    CorrectionAttemptState.COMPLETE,
    new_decision_id="01HJKL...",
    archived_artifacts_path="/var/cleveragents/archives/01HXYZ",
)

Database Schema

The correction_attempts table uses RESTRICT foreign keys for both original_decision_id and new_decision_id, preserving the correction audit trail when decisions are cleaned up. The ORM-level cascade="all, delete-orphan" on LifecyclePlanModel ensures that deleting a plan cascades to its correction attempts.