Files
cleveragents-core/robot/invariant_reconciliation_autowire.robot
Luis Mendes a0c7f5188e
CI / lint (pull_request) Successful in 19s
CI / quality (pull_request) Successful in 32s
CI / build (pull_request) Successful in 17s
CI / typecheck (pull_request) Successful in 55s
CI / security (pull_request) Successful in 54s
CI / helm (pull_request) Successful in 47s
CI / unit_tests (pull_request) Successful in 6m37s
CI / docker (pull_request) Successful in 1m19s
CI / coverage (pull_request) Successful in 10m3s
CI / e2e_tests (pull_request) Successful in 16m47s
CI / integration_tests (pull_request) Successful in 22m14s
CI / status-check (pull_request) Successful in 1s
CI / benchmark-publish (pull_request) Has been skipped
CI / benchmark-regression (pull_request) Successful in 56m42s
feat(plan): wire invariant reconciliation actor auto-invocation
Wire the InvariantReconciliationActor into PlanLifecycleService phase
transitions so that invariant reconciliation runs automatically at each
lifecycle boundary. This ensures plan invariants are verified before
processing can proceed.

Changes:
- Add InvariantService as a new optional dependency on PlanLifecycleService
  (injected via the DI container as a Singleton provider)
- Add _run_invariant_reconciliation() method that creates and invokes the
  reconciliation actor, emits INVARIANT_RECONCILED events on success, and
  raises ReconciliationBlockedError (with INVARIANT_VIOLATED event) on
  failure to block the phase transition
- Invoke reconciliation at three phase transition points:
  1. start_strategize() - after preflight guardrails, before PROCESSING
  2. execute_plan() - after estimation/error patterns, before Execute
  3. apply_plan() - after state validation, before Apply transition
- Subscribe to CORRECTION_APPLIED events for post-correction reconciliation
  (best-effort, failures logged but not re-raised)
- Per-plan disable: reconciliation is skipped when plan.invariant_actor is
  None or "__optional__", following the established estimation actor pattern
- Decision recording: the reconciliation actor already records
  invariant_enforced decisions via DecisionService

Tests:
- Behave: 10 scenarios in invariant_reconciliation_autowire.feature
  covering auto-invocation, skip-when-disabled, transition blocking,
  decision recording, and post-correction reconciliation
- Robot: 5 integration tests in invariant_reconciliation_autowire.robot
- All nox sessions pass (lint, typecheck, unit_tests, integration_tests,
  coverage_report at 97%)

ISSUES CLOSED: #829
2026-04-05 05:46:05 +00:00

57 lines
2.7 KiB
Plaintext

*** Settings ***
Documentation Integration tests for Invariant Reconciliation Actor auto-invocation
... Verifies that the reconciliation actor is automatically invoked during
... plan lifecycle phase transitions and blocks transitions on failure.
Resource ${CURDIR}/common.resource
Suite Setup Setup Test Environment
Suite Teardown Cleanup Test Environment
*** Variables ***
${HELPER} ${CURDIR}/helper_invariant_reconciliation_autowire.py
*** Test Cases ***
Reconciliation Auto-Invocation At Strategize Start
[Documentation] Reconciliation runs automatically when start_strategize is called
${result}= Run Process ${PYTHON} ${HELPER} strategize cwd=${WORKSPACE}
Log ${result.stdout}
Log ${result.stderr}
Should Be Equal As Integers ${result.rc} 0
Should Contain ${result.stdout} autowire-strategize-ok
Should Contain ${result.stdout} reconciliation_invoked
Reconciliation Auto-Invocation At Execute Transition
[Documentation] Reconciliation runs automatically at execute_plan transition
${result}= Run Process ${PYTHON} ${HELPER} execute cwd=${WORKSPACE}
Log ${result.stdout}
Log ${result.stderr}
Should Be Equal As Integers ${result.rc} 0
Should Contain ${result.stdout} autowire-execute-ok
Should Contain ${result.stdout} reconciliation_invoked
Reconciliation Auto-Invocation At Apply Transition
[Documentation] Reconciliation runs automatically at apply_plan transition
${result}= Run Process ${PYTHON} ${HELPER} apply cwd=${WORKSPACE}
Log ${result.stdout}
Log ${result.stderr}
Should Be Equal As Integers ${result.rc} 0
Should Contain ${result.stdout} autowire-apply-ok
Should Contain ${result.stdout} reconciliation_invoked
Reconciliation Blocks Transition On Failure
[Documentation] When reconciliation fails, the phase transition is blocked
${result}= Run Process ${PYTHON} ${HELPER} block cwd=${WORKSPACE}
Log ${result.stdout}
Log ${result.stderr}
Should Be Equal As Integers ${result.rc} 0
Should Contain ${result.stdout} autowire-block-ok
Should Contain ${result.stdout} ReconciliationBlockedError
Reconciliation Skipped When Actor Unset
[Documentation] No reconciliation when invariant_actor is None
${result}= Run Process ${PYTHON} ${HELPER} skip cwd=${WORKSPACE}
Log ${result.stdout}
Log ${result.stderr}
Should Be Equal As Integers ${result.rc} 0
Should Contain ${result.stdout} autowire-skip-ok
Should Contain ${result.stdout} reconciliation_skipped