Deterministic claim-verification correction harness for AI agents, built on Liminate.
Project description
liminate-invariant
Invariant by Liminate. A deterministic claim-verification correction harness for AI agents, built on liminate.run(): it hosts an agent behind a callable, runs a Liminate contract against the agent's output each cycle, reads structured failure details off the result stream, feeds them back to the agent, and re-runs until claims verify, stall, or the ground proves unstable. Per-claim status, partial-pass acceptance, and honest escalation (a stall is not the same as flaky ground, and neither is a plain fail) are the point.
import liminate_invariant as invariant
result = invariant.run(contract_text, agent, probes={"build-output": run_build})
agent is a callable of AgentTask -> AgentResponse: it receives the contract text, the current cycle number, and the failure details from the previous cycle, and returns the claims it produced this round. probes are optional callables that acquire ground truth directly (test output, a build status, a metric) — Invariant re-acquires and re-samples them each cycle to tell a genuinely unstable measurement (flaky) apart from a claim the agent keeps getting wrong (a stall).
run() never writes anything. It proposes a result; the caller decides what to do with it.
Status vocabulary
Each claim resolves to one of:
verified— passed on the first cycle.corrected— failed at least once, then passed after the agent revised its claim.escalated— did not resolve.escalation_reasonis one of:"claim will not converge"— the same failure recurs across consecutive cycles; re-eliciting from the agent isn't fixing it."ground will not stabilize"— the probe-acquired ground itself won't settle into a stable pass or fail.
pending— reserved for a future prediction capability (condition-gated re-check). This build's loop never assigns it.
Quick start with simple()
For a plain string-in/string-out function, skip the structured interface:
import liminate_invariant as invariant
def call_my_agent(prompt: str) -> str:
... # however you talk to your model of choice
agent = invariant.simple(call_my_agent, source="build-status")
result = invariant.run(contract_text, agent)
simple() serializes the contract and failure details into a single prompt string for you. It's the fast on-ramp — the structured AgentTask / AgentResponse interface is the recommended integration, since serializing to a prompt string discards machine-readable failure identity that a real integration can use directly.
Generating governance
Pass narratia= to have repeated failures propose durable inherited when handlers instead of just failing the same way forever:
import liminate_invariant as invariant
narratia = invariant.NarratiaReference(complete=lambda prompt: client(prompt))
result = invariant.run(contract_text, agent, narratia=narratia)
complete is any string-in/string-out completion callable wrapped in a lambda — there's zero LLM SDK dependency inside Invariant itself. Every proposal Narratia returns passes a deterministic gate before it can touch a cycle: it's parsed by the same engine that runs your contract, and checked for contradictions against the contract's obligations. Every rejection is recorded, not silently dropped.
Admitted handlers apply in memory for the rest of the run and come back as InvariantResult.new_handlers — canonical, attributed inherited when ... from narratia text. run() still never writes: committing those handlers to your actual contract is yours to do.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file liminate_invariant-0.1.0.tar.gz.
File metadata
- Download URL: liminate_invariant-0.1.0.tar.gz
- Upload date:
- Size: 31.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c862a621148dac32e70138db25b3eafd11713c58643886c57cba65cc8cb79c53
|
|
| MD5 |
a03a332797b1630816a0dac0d7013044
|
|
| BLAKE2b-256 |
e65d72beb771f18d5475677ec16c5c83be59c6f795b55253ef09766089f490de
|
File details
Details for the file liminate_invariant-0.1.0-py3-none-any.whl.
File metadata
- Download URL: liminate_invariant-0.1.0-py3-none-any.whl
- Upload date:
- Size: 17.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
61a4c512792cec79033678d8dd1c06ba5b1f75db94f3105aceb2d8a95fa54c22
|
|
| MD5 |
8513b1e54589a09b7d55755c9f2b0d3f
|
|
| BLAKE2b-256 |
f5dff734cb2bb05134d163f07b6c01e2210660c82b93bd5593427a6bc786de8e
|