Files
cleveragents-core/robot/influence_dag_traversal.robot
freemo 8e6642e8c9 feat(decision): implement influence DAG traversal in correction affected subtree computation
Extended _compute_affected_subtree() to BFS over both the structural tree
(parent-child plan relationships) and decision_dependencies edges (influence
DAG). The algorithm performs a single O(V+E) BFS pass that unions neighbors
from both edge sources, using a visited set for cycle detection to guard
against data corruption.

Decision creation now supports dependency_decision_ids parameter in
record_decision() which populates the in-memory influence DAG store.
get_influence_edges() returns the adjacency list format consumed by
CorrectionService.

All public CorrectionService methods (analyze_impact, execute_revert,
execute_correction, generate_dry_run_report) accept an optional
influence_edges parameter while remaining backward-compatible (defaults
to None, preserving structural-only traversal when not provided).

Key design decisions:
- Single BFS pass over union of structural + influence edges rather than
  separate traversals, ensuring O(V+E) complexity and consistent visit order
- Cycle detection via visited set with warning log (not an error) since
  cycles indicate data corruption, not a programming error
- Influence edge logging: traversal emits count of influence edges processed
  for observability
- Backward-compatible API: existing callers that only pass decision_tree
  continue to work identically

ISSUES CLOSED: #542
2026-03-04 15:36:34 +00:00

54 lines
2.6 KiB
Plaintext

*** Settings ***
Documentation End-to-end correction with influence DAG traversal.
... Verifies that corrections cascade through both structural
... tree edges and influence DAG (decision_dependencies) edges.
Resource ${CURDIR}/common.resource
Suite Setup Setup Test Environment
Suite Teardown Cleanup Test Environment
*** Variables ***
${HELPER} robot/helper_influence_dag_traversal.py
*** Test Cases ***
Structural Only Revert
[Documentation] Revert with only structural children
[Tags] phase2 correction influence_dag
${result}= Run Process ${PYTHON} ${HELPER} structural-only cwd=${WORKSPACE}
Should Be Equal As Integers ${result.rc} 0
Should Contain ${result.stdout} structural-only-ok
Influence Only Revert
[Documentation] Revert with only influence DAG edges
[Tags] phase2 correction influence_dag
${result}= Run Process ${PYTHON} ${HELPER} influence-only cwd=${WORKSPACE}
Should Be Equal As Integers ${result.rc} 0
Should Contain ${result.stdout} influence-only-ok
Combined Structural And Influence Revert
[Documentation] Revert traverses union of structural + influence edges
[Tags] phase2 correction influence_dag
${result}= Run Process ${PYTHON} ${HELPER} combined-revert cwd=${WORKSPACE}
Should Be Equal As Integers ${result.rc} 0
Should Contain ${result.stdout} combined-revert-ok
Cycle Detection In Influence DAG
[Documentation] Corrupt cycle in influence DAG handled gracefully
[Tags] phase2 correction influence_dag
${result}= Run Process ${PYTHON} ${HELPER} cycle-detection cwd=${WORKSPACE}
Should Be Equal As Integers ${result.rc} 0
Should Contain ${result.stdout} cycle-detection-ok
Decision Creation Records Dependencies
[Documentation] record_decision with dependency_decision_ids populates DAG
[Tags] phase2 correction influence_dag
${result}= Run Process ${PYTHON} ${HELPER} record-deps cwd=${WORKSPACE}
Should Be Equal As Integers ${result.rc} 0
Should Contain ${result.stdout} record-deps-ok
End To End Correction With Influence Cascade
[Documentation] Full flow: record decisions with deps, then revert cascades
[Tags] phase2 correction influence_dag
${result}= Run Process ${PYTHON} ${HELPER} e2e-cascade cwd=${WORKSPACE}
Should Be Equal As Integers ${result.rc} 0
Should Contain ${result.stdout} e2e-cascade-ok