Skip to content

Releases: amabito/veronica-core

v3.10.0 -- Self-Healing Containment Layer

Choose a tag to compare

@amabito amabito released this 02 Apr 12:59

[3.10.0] -- 2026-04-02 -- Self-Healing Containment Layer

Breaking changes: none

Added

  • recovery subpackage -- self-healing containment layer for post-compromise recovery
  • IntegrityMonitor -- runtime PolicyBundle content_hash re-verification (sampled, timing-safe)
  • CheckpointManager -- HMAC-SHA256 signed containment state snapshots with ring buffer
  • HeartbeatProtocol + SentinelMonitor -- mutual watchdog with signed heartbeats, nonce replay prevention
  • RecoveryOrchestrator -- coordinates all recovery subsystems, fail-closed on any exception
  • 72 tests for recovery module (99% coverage)

Fixed

  • Nonce-burn DoS in heartbeat protocol (signature verification before nonce registration)
  • Infinite RESTORED loop (QUARANTINED verdict goes directly to QUARANTINE_ALL)
  • Fail-open on content_hash() exception (now fail-closed)
  • Fail-open on hmac.compare_digest type error (extended try/except scope)
  • NaN/Inf values in checkpoint capture (coerced to 0.0 via math.isfinite)

Stats

6776 tests, 99% recovery coverage, zero required dependencies.

v3.9.0 -- Codebase Hardening + Full Simplify

Choose a tag to compare

@amabito amabito released this 20 Mar 13:11

Summary

  • 9 commits since v3.8.1
  • 95 new tests (6602 -> 6697)
  • Full 159-file codebase simplify
  • audit + review

Security fixes

  • uv subcommand index bug: option-value position was returned instead of actual subcommand position
  • --python, --python-version, -p added to _UV_OPTS_WITH_VALUE
  • uv pip --quiet install bypass: flags before sub-subcommand were not skipped

Highlights

  • require_strict_int() + check_path_within_root() shared utilities
  • PolicyLoader(policy_root=...) and ShieldConfig.from_yaml(config_root=...) path traversal prevention
  • ComplianceExporter O(1) dedup attach with max_attached cap
  • RetryContainer.record_failure() threshold aligned with execute() semantics
  • Hot-path optimizations: pre-bound masking closures, frozenset caching, deque eviction
  • MemoryGovernor public API for diagnostics decoupling

Breaking changes

None.

v3.8.1 -- Fail-Closed Security Hardening

Choose a tag to compare

@amabito amabito released this 18 Mar 07:20

Fixed

  • integration.py: if state_data: -> if state_data is not None: -- empty dict from backend was silently treated as missing state.
  • A2A server: unrecognised governance hook verdict now returns DENY instead of falling through to ALLOW.
  • DefaultCardVerifier: no longer grants card_verified=True without cryptographic verification.
  • MemoryBoundaryConfig: default changed from allow-all to deny-all (fail-closed).
  • OpenAIAgentsConfig: max_retries renamed to max_retries_total; max_steps default aligned to 25.

Breaking

  • MemoryBoundaryConfig.default_allow now defaults to False. Pass default_allow=True explicitly to restore previous behaviour.
  • DefaultCardVerifier.verify() always returns card_verified=False.

6602 tests passing.

v3.8.0 -- Policy Consolidation + Authority + Side-Effects

Choose a tag to compare

@amabito amabito released this 17 Mar 01:19

Added

  • Authority-aware execution policy -- AuthoritySource enum, AuthorityClaim, trust ceiling enforcement
  • Runtime side-effect classification -- SideEffectClass, SideEffectProfile, classify_action (fail-closed)
  • Tool description pinning -- ToolPinRegistry with SHA-256, PinVerification structured result
  • 5 built-in policy packs -- ReadOnlyAssistant, NoNetwork, NoShell, ApproveSideEffects, UntrustedToolMode
  • Shared policy utilities -- _extract_command_stem, command sets, authority helpers

Fixed

  • default.yaml 4 duplicate shell keys merged
  • NoNetworkPolicy URL allowlist case-insensitive
  • ToolPinRegistry double json.dumps
  • classify_action unknown -> IRREVERSIBLE (fail-closed)

Stats

6602 tests, ruff clean.

v3.7.8 -- Full Codebase Review Hardening

Choose a tag to compare

@amabito amabito released this 16 Mar 07:57

Security

  • detect_security_level: warn on DEV fallback from missing env markers
  • parse_version rollback guard: fail-closed on malformed min_engine_version

Fixed

  • ShieldPipeline hook wiring: all 5 protocol types now wired (was PreDispatchHook only)
  • Two-phase budget reservation drift: actual-estimate delta committed to backend
  • HALT vs error node classification in _handle_fn_error
  • Memory governance decision threading: real verdict passed to after-hooks (per-node)
  • CircuitBreakerCapability cleanup() for stale breaker pruning
  • A2A rate limiter stale key eviction on access
  • MemoryGovernor notify_after on normal success path

Deferred to v3.8.0

  • _mg_decision cleanup on all early-return paths (requires _wrap refactoring)

Full Changelog: v3.7.7...v3.7.8

v3.7.7 -- AG2 Adapter Fixes

Choose a tag to compare

@amabito amabito released this 16 Mar 05:15

Fixed

  • Step counter asymmetry (Critical): register_veronica_hook no longer increments step_guard.step() unconditionally
  • supported_versions cross-file inconsistency: shared _AG2_SUPPORTED_VERSIONS constant
  • _originals dict memory leak: weakref.WeakMethod prevents agent GC retention
  • breakers property inconsistency: first-match semantics (same as get_breaker)
  • _emit_ag2_otel_event duplication: deduplicated into _ag2_helpers.py

Full Changelog: v3.7.6...v3.7.7

v3.7.6 -- 3-Agent Parallel Review Hardening

Choose a tag to compare

@amabito amabito released this 14 Mar 14:08

Security

  • os.path.basename cross-platform bypass (Rule 32): _eval_git() replaced with manual split
  • Frozen dataclass metadata mutation: AgentIdentity.metadata, ChainMetadata.tags, ContextSnapshot fields now frozen
  • Log info leakage (Rule 5): str(exc) removed from logger.error/warning

Bug fixes

  • fd leak on os.fdopen failure: fdopen_ok flag pattern prevents both fd leak and double-close
  • BudgetEnforcer zero-budget invariant: is_exceeded=True from construction, reset() preserves
  • DegradeDirective serialization round-trip: list->tuple coercion in post_init
  • DummyClient.call_count race: read inside lock scope

Breaking changes

ContextSnapshot.nodes and ContextSnapshot.events changed from list to tuple.

Stats

6131 tests, 0 failures, ruff clean. 3-agent parallel review-fix loop: 2 consecutive CLEAN.

v3.7.5 -- Adapter Unification + nogil CI

Choose a tag to compare

@amabito amabito released this 13 Mar 16:01

Breaking changes: veronica_core.adapter removed (deprecated since v3.4.0, DeprecationWarning emitted on import). Replace:

from veronica_core.adapter import SecureExecutor       # old
from veronica_core.adapter.exec import SecureExecutor  # old

with:

from veronica_core.adapters.exec import SecureExecutor  # new

Same for AdapterConfig, ApprovalRequiredError, SecurePermissionError.

Changed

  • adapter/ removed: Backward-compat shim deleted. All imports unified to veronica_core.adapters.exec. 9 files updated, 60 lines removed.
  • CI: Python 3.13 + free-threaded: Standard matrix expanded to 3.10-3.13. New test-nogil job runs full suite under Python 3.13t with PYTHON_GIL=0.
  • pyproject.toml: Added Programming Language :: Python :: 3.13 classifier.
  • Lint allowlist: Removed stale adapter/exec.py entry from tools/lint_no_raw_exec.py.

Stats

6125 tests, 94% coverage.

v3.7.4 -- A2A Containment Adapters

Choose a tag to compare

@amabito amabito released this 13 Mar 13:44

[3.7.4] -- 2026-03-13 -- A2A Containment Adapters

Breaking changes: none

Added

  • A2A client adapter (adapters/a2a_client.py): A2AContainmentAdapter with circuit breaker pre-check, budget probe, per-token cost delta, streaming support, stats cap, and BoundA2AAdapter convenience wrapper.
  • A2A server middleware (adapters/a2a_server.py): A2AServerContainmentMiddleware with message size check, per-tenant/per-sender sliding-window rate limiting, Agent Card verification, trust escalation, governance hooks, fail-closed mode.
  • A2A base types (adapters/_a2a_base.py): Frozen dataclasses for config, request, decision, stream event, and message cost with full __post_init__ validation (bool-as-int, NaN/Inf, negative, boundary guards).
  • A2A identity provenance (a2a/provenance.py): A2AIdentityProvenance frozen dataclass with card_verified bool enforcement.
  • Card utilities (a2a/card.py): identity_from_a2a_card with non-dict guard and PRIVILEGED downgrade; verify_card_signature with fail-closed on non-serializable cards.

Fixed

  • Rule 5 info leakage: 12 source files -- replaced type(exc).__name__ / str(exc) in user-facing error strings with fixed messages; diagnostics moved to logger.debug.
  • Rule 30 timezone safety: backends.py and persist.py now use datetime.now(timezone.utc).

Tests

  • 300 A2A-specific tests (base types, server middleware, client adapter, card verification, provenance).
  • Rule 5/30 hardening: updated assertions in 8 test files, added compound state and git variant parametrize tests.
  • F.R.I.D.A.Y. 3-body parallel review-fix loop: R8-R11 (14 fixes), R12+R13 = 2 consecutive CLEAN rounds.

Stats

6123 tests, 94% coverage.

v3.7.3 -- Tri-Memory Mathematical Consistency

Choose a tag to compare

@amabito amabito released this 13 Mar 07:55

Fixed

  • governor: evaluate_message() now preserves degrade_directive on QUARANTINE verdict (mirroring evaluate() fix from v3.7.2)
  • compactness: raw_replay_ratio float conversion now guarded with try/except for corrupted metadata (fail-closed to inf)
  • message_governance: allowed_message_types=frozenset() now correctly denies all types instead of silently allowing all (falsy check fixed to is not None)
  • message_governance: _degrade_at clamped to max(1, ...) to prevent zero-threshold edge case
  • policy/memory_rules: _parse_float now rejects NaN/Inf values with math.isfinite() guard
  • types: MessageContext.content_size_bytes now validates isinstance(int) to prevent NaN bypass
  • types: MemoryOperation.content_size_bytes now validates isinstance(int) for consistency

Tests

  • Updated 8 test assertions to match corrected behavior
  • 5766 tests passing, 94% coverage