All notable changes to ClampAI are documented in this file.
Format follows Keep a Changelog. Versions follow Semantic Versioning.
ClampAI is in the 0.x phase while the API stabilises.
- Patch releases (
0.y.Z) never break backwards compatibility. You can always upgrade a patch version safely. - Minor releases (
0.Y.0) may include breaking changes. Read the migration notes in the relevant section before upgrading. - 1.0.0 is the API-stability milestone. Once published, the public API
(everything in
clampai/__init__.py) will follow full SemVer guarantees: no breaking changes without a major-version bump.
- PyPI metadata: expanded keywords to multi-word search phrases for better
Elasticsearch ranking (
"llm safety","budget enforcement","agent guardrails","langchain safety","openai guardrails","ai automation", and 35 more). - README: added keyword-rich opening paragraph for Google indexing of the PyPI page.
pyproject.toml: bumped Development Status to5 - Production/Stable, addedTopic :: Securityclassifier,Operating System :: OS Independent.
API-stability milestone. The public API (clampai/__init__.py) is now frozen
under full SemVer: no breaking changes without a major-version bump.
LangGraph adapter (clampai/adapters/langgraph_adapter.py)
SafetyNode— a LangGraph-compatible callable that wraps any node function with ClampAI budget enforcement and invariant checking. Budget and step count persist across calls;reset()restores the initial state.@clampai_node(budget, cost_per_step, invariants)— decorator equivalent ofSafetyNode, preserving__name__and__doc__viafunctools.update_wrapper.budget_guard(budget, cost_per_step)— factory that returns a pass-through LangGraph node enforcing a budget cap. RaisesClampAIBudgetError(HTTP analogue: 429) when exhausted.invariant_guard(invariants)— factory that returns a pass-through LangGraph node checking invariants with no budget charge. RaisesClampAIInvariantErroron blocking-mode violations.- Three typed exception classes:
ClampAISafetyError(base),ClampAIBudgetError,ClampAIInvariantError. - Install:
pip install clampai[langgraph]
FastAPI / Starlette middleware (clampai/adapters/fastapi_middleware.py)
ClampAIMiddleware(app, budget, cost_per_request, invariants, state_fn)— StarletteBaseHTTPMiddlewaresubclass. Every incoming request is evaluated by aSafetyKernelbefore the endpoint handler is called.- Budget exhaustion returns 429 Too Many Requests (JSON). Invariant violation returns 422 Unprocessable Entity (JSON).
state_fnhook lets callers inject extra fields (user ID, tenant, etc.) into the state dict checked by invariants.budget_remainingandrequests_processedproperties for observability.reset()method for re-use across test suites and app restarts.- Install:
pip install clampai[fastapi]
Improved invariant suggestions (clampai/invariants.py)
- All 25 pre-built invariant factories now return actionable, specific
suggestionstrings that tell the agent exactly what to do when violated. Previously some suggestions were generic placeholders. - Fixed a bug in
monotone_increasing_invariantandmonotone_decreasing_invariantwhere the suggestion string captured theinitial_value(always 0.0 / ∞) instead of describing the violated condition.
New optional extras (pyproject.toml)
clampai[langgraph]—langgraph>=0.2clampai[fastapi]—fastapi>=0.100.0,starlette>=0.27.0
Tests (tests/)
tests/test_langgraph_adapter.py— 55 tests across 9 classes coveringSafetyNode,@clampai_node,budget_guard,invariant_guard, and the three exception types.tests/test_fastapi_middleware.py— 50 tests across 8 classes coveringClampAIMiddlewarebudget enforcement, invariant violation, state_fn, error response format, and reset behaviour.
LangChain callback handler (clampai/adapters/langchain_callback.py)
ClampAICallbackHandler(budget, cost_per_action, invariants, state_fn, raise_on_block)— LangChainBaseCallbackHandlersubclass. Enforces ClampAI budget and invariants inon_agent_action()before any tool executes. Requires zero changes to the agent — attach viaconfig={"callbacks": [handler]}.raise_on_block=Falsefor monitoring-only mode.budget_remaining,actions_blocked,tool_calls_made,step_countproperties.reset()for reuse across agent runs.ClampAICallbackError(RuntimeError)— raised (by default) when blocked.- Install:
pip install clampai[langchain]
CrewAI adapter (clampai/adapters/crewai_adapter.py)
ClampAISafeCrewTool(func, name, description, budget, cost, invariants)— callable CrewAI tool wrapper with full ClampAI enforcement.ClampAICrewCallback(budget, cost_per_step, invariants)— step and task callbacks forCrew(step_callback=..., task_callback=...).@safe_crew_tool(budget, cost, name, description, invariants)— decorator.ClampAICrewBudgetError,ClampAICrewInvariantErrorexception types.
AutoGen adapter (clampai/adapters/autogen_adapter.py)
ClampAISafeAutoGenAgent(fn, budget, cost_per_reply, invariants, agent_name)— AutoGen reply function wrapper.check(message, sender, extra_state)as a standalone gate;__call__foragent.register_reply(...).@autogen_reply_fn(budget, cost_per_reply, agent_name, invariants)— decorator.- Returns
(True, result)on success,(False, None)whenfn=None. ClampAIAutoGenBudgetError,ClampAIAutoGenInvariantErrorexception types.
HTTP sidecar server (clampai/server.py)
ClampAIServer(budget, invariants, host, port, min_action_cost)— HTTP server wrapping a sharedSafetyKernel. Zero external dependencies (stdlibHTTPServeronly; FastAPI optional for full ASGI).- Endpoints:
POST /evaluate,POST /execute,POST /reset,GET /status,GET /health. start_background()for non-blocking use;stop()for teardown.- CLI:
python -m clampai.server --budget 1000.0 --port 8765.
reconcile_fn hook in SafetyKernel (clampai/formal.py)
SafetyKernel(budget, invariants, ..., reconcile_fn=None)— new optional parameter. Called post-commit with(model_state, action, trace_entry). If it returns a non-NoneState, that state is used instead of the model state, bridging the spec-reality gap. Failures are silently swallowed.- Applies to both
execute()andevaluate_and_execute_atomic().
OTelTraceExporter (clampai/adapters/metrics.py)
OTelTraceExporter(tracer)— convertsTraceEntryobjects to OpenTelemetry spans.export_entry(entry)for manual export;make_reconcile_fn()returns a closure compatible withSafetyKernel(reconcile_fn=...)for automatic per-commit export.
Examples
examples/06_langgraph_agent.py— four LangGraph integration patterns:@clampai_node,budget_guard,invariant_guard, combined usage.examples/07_fastapi_middleware.py— FastAPI middleware demo with standalone runner (no uvicorn required).
Tests (tests/)
tests/test_langchain_callback.py— 45 tests forClampAICallbackHandler.tests/test_crewai_adapter.py— 53 tests forClampAISafeCrewTool,ClampAICrewCallback, and@safe_crew_tool.tests/test_autogen_adapter.py— 43 tests forClampAISafeAutoGenAgentand@autogen_reply_fn.tests/test_server.py— 44 tests forClampAIServerendpoints using real stdlib HTTP connections.tests/test_reconcile_fn.py— 30 tests forreconcile_fninSafetyKernel.
Total test suite: 1296 tests passing, ruff clean, mypy clean. Chaos fuzzer: 45/45 attacks blocked. Coverage: 91%.
clampai/__init__.py:__version__bumped to"1.0.0".clampai/adapters/__init__.py: exportsSafetyNode,clampai_node,budget_guard,invariant_guard,ClampAISafetyError,ClampAIBudgetError,ClampAIInvariantError,ClampAIMiddleware,ClampAICallbackHandler,ClampAICallbackError,ClampAISafeCrewTool,ClampAICrewCallback,safe_crew_tool,ClampAICrewBudgetError,ClampAICrewInvariantError,ClampAISafeAutoGenAgent,autogen_reply_fn,ClampAIAutoGenBudgetError,ClampAIAutoGenInvariantError,OTelTraceExporter.
README.md: changed three relative file links (MATHEMATICAL_COMPLIANCE.md,VULNERABILITIES.md,BENCHMARKS.md) to absolute GitHub URLs so they resolve correctly on PyPI.CITATION.cff: bumpedversionto0.4.1anddate-releasedto2026-02-28.
AsyncOrchestrator (clampai/orchestrator.py)
- Native-async drop-in replacement for
Orchestrator. The execution loop, LLM call, and kernel commit are all coroutines. UsesAsyncSafetyKernelinternally so competing coroutines yield to the event loop rather than blocking OS threads. - All T1–T8 guarantees are preserved: the
asyncio.LockinAsyncSafetyKernel.execute_atomic()serialises budget charge, step increment, and trace append exactly as thethreading.Lockdoes in the synchronous kernel. - Accepts an optional
kernel=keyword argument, enabling multipleAsyncOrchestratorinstances to share a singleAsyncSafetyKernelfor joint budget enforcement across concurrent agents. - TOCTOU safety: the fast pre-check (
await kernel.evaluate()) is followed by a locked atomic commit (await kernel.execute_atomic()). If the budget changes between the two calls,execute_atomiccatches it and the action is rejected — never silently over-spent. - Exported from
clampaiasAsyncOrchestrator.
AsyncSafetyKernel.record_rejection() (clampai/formal.py)
- Delegation method added to
AsyncSafetyKernel; routes to the wrapped synchronous kernel'srecord_rejection()so the async orchestrator can append rejection trace entries without acquiring the async lock (the operation is read-only with respect to budget and step count).
Test coverage (tests/test_async_orchestrator.py)
- 40 tests covering
AsyncOrchestrator:- All seven
TerminationReasonpaths (GOAL_ACHIEVED, BUDGET_EXHAUSTED, STEP_LIMIT, LLM_STOP, MAX_FAILURES, ERROR, STUCK-adjacent) AsyncSafetyKernel.record_rejectiondelegation- T1 budget guarantee verified at scale
- Blocking vs monitoring invariant enforcement
- Dominant-strategy LLM skip (no adapter call with 1 action)
- LLM exception → fallback selection
- Invalid JSON response → fallback
- Shared-kernel T1 enforcement across two concurrent agents
- Ten concurrent independent runs with
asyncio.gather ExecutionResultshape,to_dict(),summary()- Custom
goal_progress_fn - Proof-path artifact written on async run
- Bayesian priors initialised correctly
- All seven
Test utilities module (clampai/testing.py)
make_state(**vars)— construct aStatefrom keyword arguments; one-liner for test fixtures.make_action(name, cost, *, reversible, tags, **effects)— construct anActionSpecwith each keyword argument becoming anEffect("set", ...); auto-generates a UUID-based action id.SafetyHarness(budget, invariants, *, min_action_cost, emergency_actions)— context-manager test harness wrapping aSafetyKernelwith assertion helpers:.assert_allowed(state, action)— raisesAssertionErrorif action is blocked..assert_blocked(state, action, *, reason_contains)— raises if action is approved; optional substring check on the rejection reason..assert_budget_remaining(expected, tol)— checkskernel.budget.remaining..assert_step_count(expected)— checkskernel.step_count..execute(state, action)— callsevaluate_and_execute_atomic; returns newStateor raisesRuntimeErrorif blocked..reset()— recreates the kernel with original budget and invariants.
- All three exported from
clampai.__init__.
New invariant factory functions (clampai/invariants.py)
string_length_invariant(key, max_length, *, enforcement, suggestion)— blocks iflen(str(state[key]))exceedsmax_length. Absent andNonevalues pass. Non-string values are coerced viastr().pii_guard_invariant(*keys, enforcement, suggestion)— blocks if any of the given state keys contain patterns for SSN (\d{3}-\d{2}-\d{4}), 16-digit credit-card numbers, email addresses, or North American phone numbers. Patterns are compiled once at factory call time. Absent /Nonevalues pass.time_window_rate_invariant(key, max_count, window_seconds, *, enforcement, suggestion)— blocks ifstate[key]contains>= max_countfloat Unix timestamps within the lastwindow_seconds. Usestime.time()for "now" (patchable in tests viaclampai.invariants._time.time). Absent,None, and non-list values pass.json_schema_invariant(key, schema, *, enforcement, suggestion)— blocks ifstate[key]is not adict, or if any field present in bothstate[key]andschemahas the wrong Python type.schemaisDict[str, type]. Missing fields in the dict are not checked (userequired_fields_invariantfor that). Absent andNonevalues pass.- All four exported from
clampai.invariants.__all__andclampai.__init__.
Test coverage — new invariants (tests/test_new_invariants.py)
- 57 tests across 4 classes covering all edge cases: absent keys,
Nonevalues, non-string coercion, enforcement modes, name and suggestion propagation, boundary conditions, and time-window boundary semantics.
Test coverage — orchestrator (tests/test_orchestrator_coverage.py)
- 50 tests across 11 classes covering:
Outcomeproperties (succeeded,state_matches_expected),ProgressMonitor(record, current_progress, progress_rate, estimated_steps_to_goal, is_stuck, to_llm_text),ExecutionResultserialization (to_dict,summary), and sevenOrchestratorintegration scenarios (initial state violation → ERROR, goal satisfied immediately, goal achieved via action, step limit, max consecutive failures, budget exhausted, fallback selection).
Test coverage — reference monitor (tests/test_reference_monitor_coverage.py)
- 40 tests across 8 classes covering:
DataLabellattice algebra (__le__,__ge__,__eq__,__hash__,join),SafeHoverState.to_action(),ControlBarrierFunction.evaluate(),CaptureBasin.evaluate_reachability(),ContractSpecification.is_satisfied_by(),OperadicComposition.compose(), andReferenceMonitorregistration methods.
Test coverage — testing utilities (tests/test_testing_module.py)
- 60 tests across 9 classes covering
make_state,make_action, and allSafetyHarnessassertion methods plus context-manager lifecycle and integration scenarios.
README additions
- LLM Adapters section with a full table of all supported backends including OpenClaw.
- OpenClaw integration code example with prerequisites.
- "Why ClampAI vs. alternatives" comparison table against custom validation, LangChain callbacks, and METR-style eval harnesses.
OpenClaw super-wrapper (clampai/adapters/openclaw_adapter.py)
Based on a full audit of the OpenClaw
CLI (openclaw agent, openclaw gateway, openclaw models, openclaw sessions,
openclaw memory). The adapter now wraps all relevant Gateway capabilities,
not just the agent subcommand.
New classes:
OpenClawGateway(*, executable, timeout)— programmatic interface to the OpenClaw Gateway control plane. Methods:health()→GatewayHealth(liveness probe viaopenclaw gateway health --json);status(*, deep)→dict(detailed Gateway status);call(method, params)(raw JSON-RPC viaopenclaw gateway call);list_models()→ list (available model descriptors viaopenclaw models list --json);list_sessions(*, agent_id, all_agents)→ list (active sessions viaopenclaw sessions --json);search_memory(query, *, agent_id)→ str (semantic memory viaopenclaw memory search);version()→ str (CLI version string). Every method has a*_asynccounterpart running inasyncio.to_thread.GatewayHealth(running, url, latency_ms, raw)— structured health probe result dataclass;running=Falsewhen the Gateway is unreachable (never raises).OpenClawResponse(text, session_id, thinking_level, raw)— structured response dataclass returned bycomplete_rich().openclaw_session(*, prefix, thinking, executable, timeout, **kwargs)— sync context manager that auto-generates a unique--session-id; the Gateway maintains conversation history for all calls within the block.async_openclaw_session(*, prefix, thinking, executable, timeout, **kwargs)— async context manager equivalent.
New keyword-only parameters added to OpenClawAdapter and AsyncOpenClawAdapter
(placed after *; existing callers are unaffected):
session_id=— forwarded as--session-id; enables conversation continuity across multiple calls (the Gateway maintains the full message history).agent_id=— forwarded as--agent; targets a specific configured agent.local=True— adds--local; bypasses the Gateway for offline use.max_retries=1— retries transientRuntimeErrorfailures with exponential back-off (0.5 s, 1 s, 2 s, …);TimeoutErroris never retried.check_gateway=True— probesopenclaw gateway healthat construction time; raisesRuntimeErrorimmediately if the Gateway is not running..with_new_session(prefix, **kwargs)— classmethod factory that generates a unique session ID automatically..session_id/.agent_id— read-only properties..gateway— returns anOpenClawGatewaybound to the same executable..complete_rich(prompt, system_prompt)— returnsOpenClawResponseinstead of a plain string.
New exports from clampai.adapters: OpenClawGateway, GatewayHealth,
OpenClawResponse, openclaw_session, async_openclaw_session.
Test coverage — OpenClaw super-wrapper (tests/test_openclaw_adapter.py)
- 187 tests across 24 test classes covering:
OpenClawResponseandGatewayHealthdataclasses;OpenClawGatewayall seven sync methods and all seven async variants;OpenClawAdapterinit (new params,check_gateway,repr),with_new_session, properties,complete(session/agent/local flags in CLI, system prompt, extra args, ANSI stripping, all error paths), retry logic (exponential back-off, timeout not retried, zero retries),complete_rich,acomplete;AsyncOpenClawAdapterinit (same new params),with_new_session, properties, blocking path (all flags, all error paths, timeout + process kill), streaming path (per-line tokens, ANSI, blank lines, empty/nonzero-exit, timeout), retry (blocking and streaming);openclaw_sessionandasync_openclaw_sessioncontext managers; cross-adapter parity assertions.
Repository hygiene
.gitignore— addedFIRST_30_DAYS.mdandsafety_evaluation/to exclude AI-generated planning and evaluation files from the repository and PyPI sdist.
Chaos fuzzer cleanup (tests/chaos_fuzzer.py)
- Replaced emoji output markers (
🛡,✅,⚠,💥) with plain ASCII equivalents ([OK],ALL ATTACKS BLOCKED,[FAIL],[!!]) for professional terminal output and clean CI logs.
Distributed multi-agent budget (clampai/formal.py)
ProcessSharedBudgetController(budget)— cross-process-safe budget controller usingmultiprocessing.Value(int64 shared memory) andmultiprocessing.Lockfor atomicity. Safe across OS processes spawned with fork, forkserver, or spawn. Preserves T1 (spent_net ≤ B₀) and T4 (monotone gross spend) via the same_BudgetLogicarithmetic asBudgetController. Process-local ledger; for a full cross-process audit log write entries to an external store. Exported fromclampai.__init__.
Native-async safety kernel (clampai/formal.py)
AsyncSafetyKernel(budget, invariants, *, min_action_cost, emergency_actions, metrics)— wrapsSafetyKernelwith a lazily-initialisedasyncio.Lock.evaluate()acquires no lock (read-only).execute_atomic()acquires the asyncio lock — concurrent coroutines yield to the event loop rather than blocking OS threads. All T1–T8 guarantees are preserved. Full proxy surface:budget,invariants,step_count,max_steps,trace,add_precondition(),rollback(),status(). Exported fromclampai.__init__.
Native-async adapters (clampai/adapters/)
AsyncAnthropicAdapter(client, model, default_system_prompt)— native-async Anthropic adapter usinganthropic.AsyncAnthropic. No thread pool.acomplete()dispatches to blocking or streaming path.complete()raisesNotImplementedError(async-only). Exported fromclampai.adapters.AsyncOpenAIAdapter(client, model, default_system_prompt)— native-async OpenAI adapter usingopenai.AsyncOpenAI(orAsyncAzureOpenAI)._acomplete_streaming()usesasync for chunk in streamwithout a thread pool.complete()raisesNotImplementedError(async-only). Exported fromclampai.adapters.
Mock adapter async support (clampai/reasoning.py)
MockLLMAdapter.acomplete()— async variant ofcomplete(). No I/O occurs, so no thread pool is needed. Suitable for use withAsyncSafetyKernelin tests and deterministic simulations.
Test coverage
tests/test_async_and_distributed.py— 71 tests covering all four new classes plusMockLLMAdapter.acomplete(). Includes concurrency test forAsyncSafetyKernel.execute_atomic()(6 coroutines viaasyncio.gather).
-
AsyncSafetyKernel.evaluate()signature simplified: removed unuseddry_runandtimeout_mskwargs (delegatedSafetyKernel.evaluatedoes not accept them). -
AnthropicAdapter.acomplete()docstring updated to recommendAsyncAnthropicAdapterfor production async use. -
OpenAIAdapter.acomplete()docstring note about "planned v0.6 adapter" removed;AsyncOpenAIAdapteris now available. -
All OpenClaw public APIs are now fully keyword-only (0.x breaking change, permitted by the versioning policy above). The following previously accepted positional arguments and no longer do:
OpenClawGateway.__init__:executable,timeoutOpenClawAdapter.__init__:executable,thinking,timeout,default_system_prompt,extra_argsAsyncOpenClawAdapter.__init__: same five paramsopenclaw_session():prefix,thinking,executable,timeoutasync_openclaw_session(): same four params
Migration: add the argument name explicitly.
OpenClawAdapter("openclaw", "medium")→OpenClawAdapter(executable="openclaw", thinking="medium"). All documented usage examples already use keyword form.
Zero-config decorator API (clampai/api.py)
safe(budget, *, cost_per_call, invariants, state_fn, action_name)— one-line@safedecorator that wraps any callable with a dedicatedSafetyKernel. Chargescost_per_callon every invocation; evaluates all invariants on the projected next state (T3 semantics — invariants see the state after effects, not before). Thread-safe viathreading.Lock.SafetyViolation(reason, verdict)— raised when the kernel blocks a call; carries the structuredSafetyVerdictfor programmatic handling._SafeWrapper— runtime object installed bysafe(); exposes.kernel,.audit_log, and.reset()for introspection and test isolation.clampai_safe— backwards-compatibility alias forsafe.- Both
safeandSafetyViolationexported fromclampai.__init__.
MCP adapter (clampai/adapters/mcp_server.py)
SafeMCPServer(name, budget, cost_per_tool, invariants, min_action_cost)— a ClampAI-guarded wrapper aroundFastMCP(from themcppackage, optional extra). All tools registered via@server.tool()share a singleSafetyKernel. Per-toolcost=andinvariants=override the server defaults. Thread-safe for concurrent tool calls.- Install with
pip install clampai[mcp].
Progressive examples (examples/)
01_hello_safety.py— minimal: one kernel, oneevaluate, oneexecute.02_budget_enforcement.py— budget tracking and the@safedecorator.03_invariants.py— custom and factory invariants, blocking vs monitoring.04_orchestrator.py— fullTaskDefinition→Orchestratorpipeline.05_safe_patterns.py— four@safepatterns: basic,state_fn, chained pipeline, and per-testreset().
Packaging and infrastructure
pyproject.toml— replacessetup.pywith PEP 621-compliant packaging. Extras:anthropic,openai,langchain,mcp,prometheus,opentelemetry,dev.clampai/py.typed— PEP 561 marker file for downstream type-checkers..github/workflows/test.yml— CI matrix: Python 3.9, 3.11, 3.13 × ubuntu-latest and macos-latest; 85 % coverage floor (adapter modules excluded from measurement; covered bytest-integrations.yml).ruff checkandmypysteps run before pytest..github/workflows/publish.yml— automated PyPI publishing via OIDC Trusted Publisher; gated on the test workflow passing..github/workflows/test-integrations.yml— nightly integration matrix for[anthropic],[openai],[langchain], and[prometheus]extras.
Adapters package (clampai/adapters/)
AnthropicAdapter— production-ready Anthropic Claude adapter with streaming (stream_tokenscallback) and async (acomplete()) support.OpenAIAdapter— production-ready OpenAI adapter with the same streaming and async interface asAnthropicAdapter.langchain_tool.py—ClampAISafeTool, aBaseToolsubclass that wraps any ClampAI action as a kernel-gated LangChain tool. Every tool call passes throughSafetyKernel.evaluate()before execution.metrics.py—PrometheusMetricsandOTelMetrics, concrete implementations of theMetricsBackendprotocol defined informal.py.PrometheusMetrics: fine-grained latency buckets (0.1 ms – 10 s), lazy registration, label-aware counters/histograms/gauges.OTelMetrics: OpenTelemetry API adapter; lazy instrument creation; never raises (failures silently absorbed so the kernel is never disrupted). Both are exported fromclampai.adapters.
LLMAdapter API hardening
- Keyword-only
*separator added betweensystem_promptandtemperaturein every publiccomplete()/acomplete()signature:clampai.reasoning.LLMAdapter(Protocol)clampai.reasoning.MockLLMAdapterAnthropicAdapter.complete()/acomplete()OpenAIAdapter.complete()/acomplete()This makes all callers passtemperature=,max_tokens=, andstream_tokens=as keywords, preventing silent positional-argument mis-wiring.
acomplete()added toLLMAdapterProtocol (async variant; experimental — wrapscomplete()inasyncio.to_thread()). Native async adapters planned for v0.6.
Documentation
docs/STREAMING.md— design rationale for buffering LLM responses before safety evaluation: T5 atomicity requires a completeActionSpec; the 0.061 ms safety check is unmeasurable against 1 000–5 000 ms LLM latency; thestream_tokenscallback provides UX streaming without compromising the kernel.docs/MULTI_AGENT_RFC.md— RFC for shared-kernel multi-agent patterns: thread-safe budget sharing, per-agent invariant namespacing, and the single-process vs. multi-process distinction.FIRST_30_DAYS.md— 24-item actionable sprint plan for the v0.3.1 launch window: bug fixes, PyPI publication, DX test, email demo, multi-agent example.safety_evaluation/LLM_RED_TEAM_PROTOCOL.md— formal adversarial LLM red-team protocol. Classifies 6 attack vectors with pre-assessed kernel responses; defines a 3-model test (Claude Sonnet 4.6, GPT-4o, open-source baseline); commits to verbatim publication of results; scheduled weeks 8–10 post-launch.MATHEMATICAL_COMPLIANCE.md— added Lean 4 prerequisites assessment: skills gate, dependency map, concrete learning path, and estimated timeline.CONTRIBUTING.md— keyword-only parameter convention fully documented with rationale and examples.SECURITY.md— added slow-predicate DoS note (invariant predicates withmax_eval_mstimeout), response SLAs, CVE criteria, and reporter credit programme.README.md— guarantee map table; async and LangChain integration notes; "Zero-config API:@safe" section; updated installation extras table and progressive-examples table.OWASP_MAPPING.md— maps all ten OWASP LLM Top 10 (2025) risks to the ClampAI theorems that address them.CHANGELOG.md— this file.
Examples
examples/email_safety.py --adversarialflag — runs a scripted adversary that attempts prompt injection, budget exhaustion, and invariant-boundary walking; all three attacks are blocked by the kernel and logged.examples/multi_agent_shared_kernel.py— 8 concurrent agents sharing oneSafetyKernel; demonstrates thread-safety ofBudgetControllerunder concurrent load.
Safety evaluation
safety_evaluation/llm_red_team_informal_2026.md— structured capture template for informal red-team observations from runningemail_safety.py --real-llm; three session slots (baseline, explicit deletion, adversarial) with per-turn transcript tables and post-session assessment questions.
setup.pysimplified to a singlesetup()call; all metadata now lives exclusively inpyproject.toml.setup.pyis retained for legacy editable-install compatibility and will be removed at 1.0.0.pyproject.toml[langchain]extra pinned tolangchain>=0.2.0andlangchain-core>=0.3.0(waslangchain>=0.1.0);pydantic>=2.0added as explicit dependency (LangChain 0.2+ requires Pydantic v2).pyproject.toml[dev]extra gainspytest-asyncio>=0.21for testingacomplete()coroutines.
clampai/active_hjb_barrier.py—Dictused in type annotations but not imported; added tofrom typing import.clampai/formal.py—State.__slots__attributes (_vars,_json,_hash) lacked class-level annotations; mypy could not resolve them. Added_vars: Mapping[str, Any],_json: str,_hash: int. Also added missing-> Nonereturn types on__init__,__setattr__,__delattr__,__post_init__,ExecutionTrace.__init__, andSafetyKernel.add_precondition.clampai/hardening.py— threeimplicit-optionalviolations (working_dir,command_allowlist,ids) changed toOptional[...]. Loop variablepin_chi2pshadowed the method parameterp(renamed topval).VALID_TRANSITIONSannotated asClassVar.clampai/guards.py—Callableused in a return type annotation but not imported (F821 undefined name); added tofrom typing import. Ambiguous variable namesl/rrenamed tolv/rv.clampai/invariants.py— missing default-argument type annotations on inner closures inno_sensitive_substring_invariant; addedfl: List[str].clampai/adapters/mcp_server.py— removed redundant# type: ignore[import]on theFastMCPimport;ignore_missing_imports = truein mypy already handles missing optional stubs.SafeHoverState.to_action()(reference_monitor.py): now constructsActionSpecwith only declared fields; previously passed an unrecognisedmetadatakeyword argument that raisedTypeErrorat runtime.QPProjector.project_cost()(reference_monitor.py):budget_remainingparameter now defaults tofloat('inf')instead of the hardcoded10.0that caused incorrect QP projections when the actual budget exceeded 10 resource units.SafetyKernel.__init__()(formal.py): removed duplicateself.emergency_actionsassignment; the set is now initialised once from theemergency_actionsconstructor parameter.pyproject.tomlbuild backend changed fromsetuptools.backends.legacy:buildtosetuptools.build_meta; thebackendssubpackage is absent from conda-distributed setuptools builds, causingpip installto fail withBackendUnavailable.pyproject.tomlclassifiers: removed"License :: OSI Approved :: MIT License"classifier; it conflicts with thelicense = "MIT"SPDX expression field under PEP 639 (enforced by setuptools ≥ 67).BudgetController(formal.py): all arithmetic now delegates to_BudgetLogicstatic methods (to_millicents,from_millicents,can_afford_i,remaining_i,utilization, newcan_refund_i)._BudgetLogicwas already present but was dead code —BudgetControllerhad duplicate inline arithmetic. The extraction is now complete: a futureAsyncBudgetControllercan wrap_BudgetLogicwithasyncio.Lockwithout duplicating any arithmetic logic.
- Eight proven theorems (T1–T8) enforced by the safety kernel:
- T1 — Budget safety:
spent(t) <= budgetfor all t. - T2 — Bounded termination: halts in at most
floor(budget / min_cost)steps (conditional onmin_cost > 0). - T3 — Invariant preservation: every declared blocking invariant holds on every reachable state.
- T4 — Monotone resource consumption: gross spend is non-decreasing.
- T5 — Atomicity: rejected actions leave state and budget unchanged.
- T6 — Trace integrity: the execution log is append-only and SHA-256
hash-chained; verified by
ExecutionTrace.verify_integrity(). - T7 — Exact rollback:
rollback(execute(s, a)) == sexactly, realised viaInverseAlgebraininverse_algebra.py. - T8 — Emergency escape: the escape action is always executable regardless of budget or invariant state (conditional on correct configuration).
- T1 — Budget safety:
- Layer 0 — Safety Kernel (
formal.py):State,Effect,ActionSpec,Invariant,SafetyKernel,BudgetController,ExecutionTrace. - Layer 1 — Reasoning Engine (
reasoning.py): Bayesian beliefs (Beta posterior), causal graph, multi-dimensional action value computation, Integral Sensitivity Filter for prompt pruning,LLMAdapterinterface,MockLLMAdapterfor zero-dependency testing. - Layer 2 — Orchestrator (
orchestrator.py): main execution loop, LLM-failure fallback to highest-value READY action,ProgressMonitor. - Layer 3 — Hardening (
hardening.py):SubprocessAttestor(binary allowlist, noshell=True),TemporalCausalGraph(readiness probes with exponential backoff),CostAwarePriorFactory,EnvironmentReconciler,MultiDimensionalAttestor. - Reference monitor (
reference_monitor.py): information flow control (IFC), control barrier functions (CBF), QP action repair viaQPProjector. - Operadic composition (
operadic_composition.py): compositional verification —Verified(A) and Verified(B)impliesVerified(A composed B)for compatible interface signatures. - Active HJB barrier (
active_hjb_barrier.py): k-step lookahead to detect multi-step traps before they close. - Gradient tracker (
gradient_tracker.py): finite-difference Jacobian for boundary-proximity scoring. - Jacobian fusion (
jacobian_fusion.py): boundary sensitivity scoring for prompt saliency. - Safe hover (
safe_hover.py): hard enforcement gate / emergency stop. - Saliency engine (
saliency.py): Integral Sensitivity Filter for reducing token usage while preserving safety-relevant state visibility. - Verification log (
verification_log.py): proof record writer. - Full test suite:
test_clampai.py(T1–T8 unit tests),test_monte_carlo.py(1,000-run probabilistic validation),chaos_fuzzer.py(45 adversarial attack scenarios),test_composition.py,test_integration.py,test_soft_gaps_fixed.py,test_boundary_enforcement.py. - Safety evaluation harness: 39 attack vectors across 9 threat categories; 89.7 % recall, zero false positives at sub-millisecond latency.
- PyPI name reservation for
clampai. - Placeholder
README.mdandLICENSE(MIT).