Skip to main content

OAIP — Observed Action & Intent Protocol

A content-addressed causal graph of what humans, agents, and tools actually did — and on what observed basis you accepted the result.

Git remembers what changed. OAIP remembers the rest: why (intent), by whom, from which workspace state, on what observed evidence, what was validated, and — the part that matters for agents — that a change was accepted, not just that a command exited 0.

intent  →  execution  →  effects  →  claim  →  ACCEPT
"reject   "ran the      "src/auth.py  "auth       a signed Warrant, citing the
 expired   change"       modified,      rejects     provenance as evidence and the
 tokens"                 test added"    expired"    validation as a re-runnable check

The accepted decision is a real, signed, hash-addressed Warrant record — not a line in console.log.

Why not just a trace log / agent-observability tool?

Because those treat an agent's own JSON as fact: it wrote "fixed auth", so the dashboard says auth is fixed. OAIP's cardinal rule (SPEC §4):

execution success ≠ validation success ≠ acceptance. A zero exit code earns execution success only. A claim is acceptable only if a separate validation check passes, and acceptance is a signed Warrant filed under policy.

So the bridge refuses to accept a claim whose check failed — even if the command returned 0. That refusal is the whole product.

Ten seconds

cd your-git-repo
oaip=~/…/oaip/impl/oaip.py
python3 $oaip init         # ledger + a local Warrant store, and a signing key
                           # in a TRUST ROOT *outside* this repo (see below)

# one-shot: intent → run the agent action → validate → accept ONLY if the check passes
python3 $oaip do --intent "make login reject expired tokens" \
        --predicate auth.rejects-expired \
        --check "python3 tests/test_auth.py" \
        --actor you@host \
        -- your-agent-command

python3 $oaip log        # intent → execution → effects → claim → warrant
python3 $oaip verify     # artifacts match their addresses; the store verifies;
                         # every OAIP acceptance was signed by a key bound to the
                         # actor it claims; and the key custody is reported
                         # (see llms.txt for what that does and does not establish)
python3 $oaip trust-root # where the key and keyring live, and what that stops

If the validation check passes, do files a signed Warrant. If the command exits 0 but the check fails, do refuses and files nothing — that refusal is the whole point (SPEC §4). The four verbs (intent / run / claim / accept) are also available separately when you want to inspect each step; examples/auth-demo.sh walks them, including the refusal case.

What it gets right by construction

  • before_state = HEAD lies. The observer snapshots the full workspace (tracked + staged + untracked + env/toolchain fingerprint) into a throwaway git index — content-addressed, no commits added to your history. (SPEC §2.2)
  • Canonical vs projection. The truth is the content-addressed artifacts + the Warrant store. The SQLite ledger is a projection you can delete and rebuild. (SPEC §5)
  • Causality is honest. Attribution carries a confidence in parts-per-million integers (no floats); an honest "probably the agent" beats a deterministic lie. (SPEC §2.6)
  • It reuses, doesn't reinvent. Warrant SPEC §4 canonicalization verbatim; accepted claims are Warrant records; Σ-GLYPH ski@v1 is the forward path for portable checks. OAIP adds exactly one layer: a clean input to the decision layer.
  • The record formats are pinned by vectors, not by the implementation. examples/vectors.json pins how a record serializes and examples/record-vectors.json pins what a record is — positive shapes and, more usefully, the shapes that MUST be refused. Until 2026-07-30 only the first existed, and the reference implementation wrote a different record from SPEC §2 for every type in it while reporting conformance; llms.txt tells that story. (SPEC §10)
  • It says what it is not. SPEC §9 maps every record onto W3C PROV and onto in-toto/SLSA, states where IETF SCITT begins and OAIP stops, and names the two things OAIP actually adds — the acceptance boundary and uncertain attribution. If those two are not what you need, §9 says so and points elsewhere.

Where it fits

Reactions        (budget-bounded; not in v0.1)
Policies         (execution / decision / reaction)
Warrant          signed decisions + causal DAG        ← github.com/s0fractal/warrant
Claims           formalized assertions about states
── OAIP ──────── observed causality: intent/execution/effect/attribution
Σ-GLYPH          deterministic portable checks         ← github.com/s0fractal/sigma-glyph
Git / CAS        content-addressed bytes

The bridge generalizes: graduating decisions

The accept bridge isn't code-specific. The same subject + evidence + reason → signed Warrant move graduates any decision that is attributed and tamper-evident but not yet signed — for instance a decision node in a mind-os / workos thought-graph, whose own README calls per-author cryptographic signatures "the deliberate next tier." This bridge is that tier: it reads the decision's public projection and files a Warrant that ratifies it, citing the source as evidence — without the source taking a hard dependency on Warrant. See examples/graduate-decision.sh. So the four repos compose into one stack: Σ-GLYPH computes checks, OAIP observes doing, mind-os records reasoning, and Warrant is the signed-decision tier both provenance halves graduate into.

Who can forge an acceptance here

The point of the §4 gate is that the party being gated cannot supply its own acceptance. That is a property of where the signing key is, so OAIP keeps the key and the keyring in a trust root outside the observed workspace$XDG_CONFIG_HOME/oaip/roots/<ledger> by default, or wherever --trust-root / $OAIP_TRUST_ROOT says. oaip run hands the observed command a workspace; it no longer hands it the key that signs the verdict on that command's work.

Stated as precisely as it can be (the full matrix is SPEC §8, and it is executed by tests/privilege_separation.py):

  • An agent with write access to the workspace can no longer mint an acceptance: a keyring it writes at .oaip/trust.json is never read, deleting or rewriting .oaip/store.json does not move the answer, and the key is not there to read. It can still make OAIP refuse — it can delete store records — and every such loss is reported non-zero.
  • The same agent running unconfined as the observer's own uid can read the trust root wherever it is. Relocation buys nothing there; that needs a second uid or a separate signing process (SPEC §8.4 profiles C and D — documented, not implemented). Relocation is decisive when the agent's write access is confined to the workspace: a container mount, a CI checkout, a sandboxed tool.
  • Anyone who can write the trust root, or control the environment, can forge freely. Nothing stops them, and SPEC §8.2 says so rather than describing a control that does not exist.
  • The check the claim is judged by still runs against post-agent state. An agent that rewrites its own test passes honestly. That hole is open (SPEC §8.5).

Existing ledgers with an in-workspace key keep working, say so on every accept, and move with one command: oaip trust-root --migrate.

Status

v0.1 DRAFT — see SPEC.md. Reference implementation in impl/oaip.py (stdlib + the Warrant CLI), which as of 2026-07-30 emits the records SPEC §2 declares; ledgers written before that are read under §6.4 legacy mode and marked, never rewritten. The wedge is provable agent-action acceptance for regulated / multi-agent development, not a general dev tool; for a solo human in an IDE, git is enough.

Deliberately not here yet: semantic-entity (tree-sitter) scope, a reaction runtime, federation. Those are refinements above this input layer, added only when a real workflow needs them.

License: MIT (implementation); the spec text is CC-BY-4.0.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

oaip-0.2.0.tar.gz (74.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

oaip-0.2.0-py3-none-any.whl (74.1 kB view details)

Uploaded Python 3

File details

Details for the file oaip-0.2.0.tar.gz.

File metadata

  • Download URL: oaip-0.2.0.tar.gz
  • Upload date:
  • Size: 74.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for oaip-0.2.0.tar.gz
Algorithm Hash digest
SHA256 cee0419f40ce7f0cbd6fe3b0c5263c81a27940c62135344f291c0a46c89a386f
MD5 a535e1c089dccbfccceed7a775803d41
BLAKE2b-256 cec8fa11cec9d0025f952dd001b82443bfca3f1d47d3d59ea3382a232730436d

See more details on using hashes here.

Provenance

The following attestation bundles were made for oaip-0.2.0.tar.gz:

Publisher: publish.yml on s0fractal/oaip

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file oaip-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: oaip-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 74.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for oaip-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 6e909cf493c7c8e6bda670c7f3ade6ffa56c0aa4e17e95dc0ebd77b8c6fc5cd0
MD5 8952a7a0747ff0957665117b93eb93a5
BLAKE2b-256 5a04f7f22c9b75fde7244e3e7de37e3fbb667f95ad0167e4efe852e167d2dbce

See more details on using hashes here.

Provenance

The following attestation bundles were made for oaip-0.2.0-py3-none-any.whl:

Publisher: publish.yml on s0fractal/oaip

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

0.3.0

2 files

0.2.1

2 files

This release

0.2.0 This release

2 files

0.1.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page