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
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 |
|
2 |
|
null |
|
|
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_definitiondecisions in their own tree, which become root decisions of child plan trees. - Invariants are recorded as
invariant_enforceddecisions, 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_typefrom the eleven defined types. No untyped decisions. - The
prompt_definitiondecision 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_snapshotmust 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.