Flagship dossier · No. I
Agent safety substrate — leased authority, a global e-stop, a fault bus, provenance-stamped claims
Agents act with ambient, unexpiring authority: filesystem, credentials, network — granted once for the whole session, revoked only by killing the process. Interlock makes authority a loan, not a possession. Zero-dependency Python. v0.1.0, MIT, CI green.
The 2026 agent stack has an authority problem, not a capability problem. A coding agent holds its tools the way a process holds file descriptors — everything it might need, for as long as it runs. When the agent misbehaves, the audit trail is a transcript: what the tool returned, not what was permitted, by whom, under what grant, or whether the grant was even live.
Credentials and capabilities granted once, valid forever. There is no moment where the system re-asks whether this agent should still hold this power.
Killing the process is the only e-stop, and it destroys the evidence along with the execution. A stop that erases the record is not a safety mechanism.
When the agent reports what it did, the report carries no authority record and no expiry date. A claim you cannot audit is a story, not a receipt.
Mobile robots solved this a decade ago. Boston Dynamics' Spot admits intent through a narrow gate of command plus lease plus clock — keepalives, a global e-stop, and a fault taxonomy as structure, not policy. Interlock transfers that architecture to software agents. Authority comes into existence in exactly one place, and it expires.
Authority is born here and nowhere else. ilk.grant(resource, holder, ttl) mints a lease with a holder, a scope, and a clock. No lease, no action — there is no ambient authority to fall back on.
Every action passes the gate. E-stop clear? Lease live and keepalive-fresh? No gating fault on the resource? The permit context raises LeaseExpired, EStopEngaged, or FaultActive otherwise. A reported fault refuses further permits on the affected resource — the agent cannot burn the night hammering a dead endpoint.
Claims carry their provenance. Every claim records its source, the authority it acted under, a review date, and a falsifier — and is auto-appended to the ledger's claims series. The ledger's closing index makes any moment of the run randomly accessible to an auditor.
from interlock import Interlock
ilk = Interlock()
# STAGE 1 — GRANT: authority comes into existence only here, and it expires.
lease = ilk.grant(resource="docs:write", holder="research-agent", ttl=1800)
# STAGE 2 — EXERCISE: every action passes the gate.
with ilk.permit(lease, action="write", target="brief.md"):
... # raises LeaseExpired, EStopEngaged, or FaultActive otherwise
# A fault refuses further permits on the affected resource.
ilk.faults.report(code="TOOL_TIMEOUT", severity="major", resource="web:read")
# STAGE 3 — AUDIT: claims carry provenance, authority, review date, falsifier.
claim = ilk.claim(
text="14 pages fetched; 2 endpoints timed out.",
provenance="tool:web-fetch",
authority=lease.id,
review_after_days=7,
falsifier="re-fetch returns different content",
)
Cross-domain transfers are named, never silent. The intake ledger records every source behind the transfer — what was read deeply, what was skimmed, what is index-only — plus an explicit unverified list: what was not verified is recorded alongside what was. Fluency is not proof, and the ledger is what keeps the transfer honest.