agenticraft_foundation.verification.invariant_checker¶
Runtime invariant checker — register invariants, check state transitions, track violations.
Runtime invariant checking for distributed systems.
This module provides tools for runtime verification of distributed system invariants, enabling early detection of protocol violations.
Features: - State transition monitoring - Invariant assertion and logging - Violation reporting and debugging - Thread-safe concurrent access via RLock
Thread Safety
All mutable state in InvariantRegistry is protected by RLock, enabling safe concurrent invariant checking across threads.
Version: 0.1.0 Date: 2025-12-20
ViolationSeverity
¶
Bases: str, Enum
Severity levels for invariant violations.
Invariant
dataclass
¶
A runtime invariant to be checked.
| ATTRIBUTE | DESCRIPTION |
|---|---|
name |
Descriptive name
TYPE:
|
condition |
Function that returns True if invariant holds
TYPE:
|
severity |
Severity level if violated
TYPE:
|
message |
Message to log on violation
TYPE:
|
enabled |
Whether invariant checking is enabled
TYPE:
|
check(*args, **kwargs)
¶
Check if invariant holds.
| PARAMETER | DESCRIPTION |
|---|---|
*args
|
Arguments to pass to condition
TYPE:
|
**kwargs
|
Keyword arguments to pass to condition
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
bool
|
True if invariant holds |
Violation
dataclass
¶
Record of an invariant violation.
| ATTRIBUTE | DESCRIPTION |
|---|---|
invariant_name |
Name of violated invariant
TYPE:
|
severity |
Severity of violation
TYPE:
|
message |
Violation message
TYPE:
|
context |
Context at time of violation
TYPE:
|
timestamp |
When violation occurred
TYPE:
|
stack_trace |
Optional stack trace
TYPE:
|
InvariantRegistry
¶
Registry for managing system invariants.
Provides centralized management of invariants with checking and violation tracking.
Thread Safety
All mutable state is protected by RLock, enabling safe concurrent access from multiple threads. RLock is used (vs Lock) to allow re-entrant calls from violation handlers.
__init__(name='default')
¶
Initialize registry.
| PARAMETER | DESCRIPTION |
|---|---|
name
|
Registry name for logging
TYPE:
|
register(name, condition, severity=ViolationSeverity.ERROR, message='')
¶
Register a new invariant.
Thread-safe: Protected by RLock.
| PARAMETER | DESCRIPTION |
|---|---|
name
|
Unique name for invariant
TYPE:
|
condition
|
Function returning True if invariant holds
TYPE:
|
severity
|
Severity level if violated
TYPE:
|
message
|
Message to log on violation
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
Invariant
|
The registered Invariant |
unregister(name)
¶
Unregister an invariant.
Thread-safe: Protected by RLock.
| PARAMETER | DESCRIPTION |
|---|---|
name
|
Invariant name to remove
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
bool
|
True if invariant was removed |
check(name, *args, context=None, **kwargs)
¶
Check a specific invariant.
Thread-safe: Protected by RLock. The invariant condition is evaluated outside the lock to avoid blocking concurrent access during potentially long-running checks.
| PARAMETER | DESCRIPTION |
|---|---|
name
|
Invariant name to check
TYPE:
|
*args
|
Arguments to pass to invariant condition
TYPE:
|
context
|
Additional context for violation reporting
TYPE:
|
**kwargs
|
Keyword arguments to pass to condition
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
bool
|
True if invariant holds |
| RAISES | DESCRIPTION |
|---|---|
KeyError
|
If invariant not found |
check_all(*args, context=None, **kwargs)
¶
Check all registered invariants.
Thread-safe: Iterates over a snapshot of invariant names.
| PARAMETER | DESCRIPTION |
|---|---|
*args
|
Arguments to pass to invariant conditions
TYPE:
|
context
|
Additional context for violation reporting
TYPE:
|
**kwargs
|
Keyword arguments to pass to conditions
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
list[str]
|
List of violated invariant names |
on_violation(handler)
¶
Register a violation handler.
Thread-safe: Protected by RLock.
| PARAMETER | DESCRIPTION |
|---|---|
handler
|
Function to call on violation
TYPE:
|
get_violations(since=None, severity=None)
¶
Get recorded violations.
Thread-safe: Returns a snapshot copy of violations.
| PARAMETER | DESCRIPTION |
|---|---|
since
|
Only violations after this timestamp
TYPE:
|
severity
|
Filter by severity level
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
list[Violation]
|
List of matching violations |
clear_violations()
¶
Clear all recorded violations.
Thread-safe: Protected by RLock.
enable()
¶
Enable invariant checking.
Thread-safe: Protected by RLock.
disable()
¶
Disable invariant checking.
Thread-safe: Protected by RLock.
stats()
¶
Get checking statistics.
Thread-safe: Returns a snapshot of statistics.
| RETURNS | DESCRIPTION |
|---|---|
dict[str, Any]
|
Dictionary with check and violation counts |
StateTransitionMonitor
¶
Monitors state transitions and checks invariants.
Useful for verifying state machine correctness.
Thread Safety
All mutable state is protected by RLock for safe concurrent access.
current_state
property
¶
Get current state.
Thread-safe: Protected by RLock.
__init__(name='state_monitor', valid_transitions=None)
¶
Initialize monitor.
| PARAMETER | DESCRIPTION |
|---|---|
name
|
Monitor name
TYPE:
|
valid_transitions
|
Map of state to valid next states
TYPE:
|
set_valid_transitions(transitions)
¶
Set valid state transitions.
Thread-safe: Protected by RLock.
| PARAMETER | DESCRIPTION |
|---|---|
transitions
|
Map of state to valid next states
TYPE:
|
transition(new_state)
¶
Record a state transition.
Thread-safe: Protected by RLock.
| PARAMETER | DESCRIPTION |
|---|---|
new_state
|
The new state
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
bool
|
True if transition is valid |
get_history()
¶
Get transition history.
Thread-safe: Returns a copy of the history.
| RETURNS | DESCRIPTION |
|---|---|
list[tuple[str, str, float]]
|
List of (from_state, to_state, timestamp) tuples |
get_invalid_transitions()
¶
Get invalid transitions that occurred.
Thread-safe: Returns a copy of invalid transitions.
| RETURNS | DESCRIPTION |
|---|---|
list[tuple[str, str]]
|
List of (from_state, to_state) tuples |
reset()
¶
Reset monitor state.
Thread-safe: Protected by RLock.
register_invariant(name, condition, severity=ViolationSeverity.ERROR, message='', registry=None)
¶
Register an invariant in the default or specified registry.
| PARAMETER | DESCRIPTION |
|---|---|
name
|
Unique name for invariant
TYPE:
|
condition
|
Function returning True if invariant holds
TYPE:
|
severity
|
Severity level if violated
TYPE:
|
message
|
Message to log on violation
TYPE:
|
registry
|
Registry to use (default if None)
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
Invariant
|
The registered Invariant |
check_invariant(name, *args, context=None, registry=None, **kwargs)
¶
Check an invariant in the default or specified registry.
| PARAMETER | DESCRIPTION |
|---|---|
name
|
Invariant name to check
TYPE:
|
*args
|
Arguments to pass to invariant condition
TYPE:
|
context
|
Additional context for violation reporting
TYPE:
|
registry
|
Registry to use (default if None)
TYPE:
|
**kwargs
|
Keyword arguments to pass to condition
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
bool
|
True if invariant holds |
invariant(name, condition=None, severity=ViolationSeverity.ERROR, message='')
¶
Decorator to add invariant checking to a function.
The invariant is checked before and after the function executes.
| PARAMETER | DESCRIPTION |
|---|---|
name
|
Invariant name
TYPE:
|
condition
|
Condition to check (receives function args)
TYPE:
|
severity
|
Severity level if violated
TYPE:
|
message
|
Message to log on violation
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
Callable[[Callable[P, R]], Callable[P, R]]
|
Decorated function |
Example
@invariant( "positive_balance", lambda self: self.balance >= 0, message="Balance cannot be negative" ) def withdraw(self, amount): self.balance -= amount
assert_invariant(condition, message='Assertion failed', severity=ViolationSeverity.ERROR)
¶
Assert an invariant condition.
Thread-safe: Uses thread-safe record_violation method.
| PARAMETER | DESCRIPTION |
|---|---|
condition
|
Condition that should be true
TYPE:
|
message
|
Message if condition is false
TYPE:
|
severity
|
Severity of violation
TYPE:
|
| RAISES | DESCRIPTION |
|---|---|
AssertionError
|
If condition is false and severity is FATAL |