Files
cleveragents-core/features/autonomy_guardrail_atomic_load.feature
HAL9000 ef532c5302 fix(autonomy-guardrail): make load_from_metadata atomic
Refactor load_from_metadata() to validate both AutonomyGuardrails and
GuardrailAuditTrail models before writing either to state. This ensures
atomicity: if any validation fails, no state is modified.

Previously, guardrails were written before audit trail validation,
leaving the system in an inconsistent state if the second validation
failed.

Changes:
- Validate both models in Phase 1 before any writes
- Write both models atomically in Phase 2 only after validation succeeds
- Add comprehensive BDD tests for atomic load behavior
- Update pyproject.toml to ignore import sorting in features/steps

ISSUES CLOSED: #7504
2026-04-23 09:08:11 +00:00

109 lines
5.3 KiB
Gherkin

Feature: Atomic load_from_metadata for guardrails and audit trails
As a plan executor
I want guardrail state to be loaded atomically from metadata
So that guardrails and audit trails remain consistent even if validation fails
# ---- Atomic loading: both succeed or both fail ----
Scenario: Load valid guardrails and audit trail together
Given I have metadata with valid guardrails and audit trail
When I load the metadata for plan "plan-1"
Then the guardrails should be loaded for plan "plan-1"
And the audit trail should be loaded for plan "plan-1"
And both guardrails and audit trail should be in sync
Scenario: Load only guardrails when audit trail is absent
Given I have metadata with valid guardrails but no audit trail
When I load the metadata for plan "plan-2"
Then the guardrails should be loaded for plan "plan-2"
And the audit trail should be empty for plan "plan-2"
Scenario: Load only audit trail when guardrails are absent
Given I have metadata with valid audit trail but no guardrails
When I load the metadata for plan "plan-3"
Then the guardrails should be absent for plan "plan-3"
And the audit trail should be loaded for plan "plan-3"
Scenario: Load empty metadata
Given I have empty metadata
When I load the metadata for plan "plan-4"
Then the guardrails should be absent for plan "plan-4"
And the audit trail should be empty for plan "plan-4"
# ---- Atomicity: validation failure leaves state unchanged ----
Scenario: Invalid guardrails validation fails atomically
Given I have metadata with invalid guardrails and valid audit trail
When I try to load the metadata for plan "plan-5"
Then a validation error should be raised for metadata load
And the guardrails should remain absent for plan "plan-5"
And the audit trail should remain absent for plan "plan-5"
Scenario: Invalid audit trail validation fails atomically
Given I have metadata with valid guardrails and invalid audit trail
When I try to load the metadata for plan "plan-6"
Then a validation error should be raised for metadata load
And the guardrails should remain absent for plan "plan-6"
And the audit trail should remain absent for plan "plan-6"
Scenario: Both invalid validations fail atomically
Given I have metadata with invalid guardrails and invalid audit trail
When I try to load the metadata for plan "plan-7"
Then a validation error should be raised for metadata load
And the guardrails should remain absent for plan "plan-7"
And the audit trail should remain absent for plan "plan-7"
# ---- Atomicity: partial state is not left behind ----
Scenario: Guardrails not written if audit trail validation fails
Given I have metadata with valid guardrails and invalid audit trail
And plan "plan-8" has no prior state
When I try to load the metadata for plan "plan-8"
Then a validation error should be raised for metadata load
And the guardrails should remain absent for plan "plan-8"
And the audit trail should remain absent for plan "plan-8"
Scenario: Audit trail not written if guardrails validation fails
Given I have metadata with invalid guardrails and valid audit trail
And plan "plan-9" has no prior state
When I try to load the metadata for plan "plan-9"
Then a validation error should be raised for metadata load
And the guardrails should remain absent for plan "plan-9"
And the audit trail should remain absent for plan "plan-9"
# ---- Size guards still apply ----
Scenario: Oversized confirmations list is rejected atomically
Given I have metadata with guardrails containing oversized confirmations
And valid audit trail
When I try to load the metadata for plan "plan-10"
Then a ValueError should be raised for metadata mentioning "required_confirmations"
And the guardrails should remain absent for plan "plan-10"
And the audit trail should remain absent for plan "plan-10"
Scenario: Oversized audit trail entries is rejected atomically
Given I have metadata with valid guardrails
And audit trail containing oversized entries
When I try to load the metadata for plan "plan-11"
Then a ValueError should be raised for metadata mentioning "Audit trail exceeds"
And the guardrails should remain absent for plan "plan-11"
And the audit trail should remain absent for plan "plan-11"
# ---- Overwriting existing state atomically ----
Scenario: Overwrite existing guardrails and audit trail atomically
Given plan "plan-12" has existing guardrails and audit trail
And I have metadata with different valid guardrails and audit trail
When I load the metadata for plan "plan-12"
Then the guardrails should be updated to new values for plan "plan-12"
And the audit trail should be updated to new values for plan "plan-12"
And both should be in sync
Scenario: Failed validation does not overwrite existing state
Given plan "plan-13" has existing guardrails and audit trail
And I have metadata with invalid guardrails and valid audit trail
When I try to load the metadata for plan "plan-13"
Then a validation error should be raised
And the guardrails should retain original values for plan "plan-13"
And the audit trail should retain original values for plan "plan-13"