Files
cleveragents-core/docs/reference/decision_correction.md
T
HAL9000 18d00c04c4
CI / lint (pull_request) Failing after 1m15s
CI / quality (pull_request) Successful in 1m21s
CI / typecheck (pull_request) Successful in 1m34s
CI / security (pull_request) Successful in 1m37s
CI / coverage (pull_request) Has been skipped
CI / unit_tests (pull_request) Failing after 1m37s
CI / docker (pull_request) Has been skipped
CI / build (pull_request) Successful in 33s
CI / helm (pull_request) Successful in 26s
CI / push-validation (pull_request) Successful in 19s
CI / e2e_tests (pull_request) Successful in 3m20s
CI / integration_tests (pull_request) Successful in 4m32s
CI / status-check (pull_request) Failing after 3s
fix(skills): implement multi-scope agent skill discovery for global, project, and local tiers
Implements AgentSkillDiscovery class to support discovering Agent Skills from
multiple configured directories across three scopes (global, project, local).
Handles name collisions with precedence: local > project > global.

Adds comprehensive BDD test coverage for multi-scope discovery scenarios including:
- Global-only, project-only, and local-only discovery
- Combined discovery from all scopes
- Name collision resolution with proper precedence
- Non-existent and empty scope directory handling
- Multiple skills in same scope discovery

ISSUES CLOSED: #9369
2026-05-06 19:55:22 +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.