Skip to content

System

A control layer between agent intent and consequential execution

Caretaker separates the decision to act from the authority to execute. Policy determines whether an action is consequential; a named person authorizes the exact proposed change; the decision is signed and recorded; execution is compared with the approved artifact.

Five stages: gate, approve, attest, execute, reconcile. Non-consequential actions bypass approval and proceed to constrained, recorded execution. Audit and provenance run beneath every stage.

The kernel is connector-agnostic. Everything below describes how it is implemented for the current connector, which operates on repositories hosted on GitHub.

Stages

What each stage specifies, and what is built today.

Gate

Design objective
Decide, before execution, whether a proposed action is consequential — without routing every operation to a human.
Current implementation
Each project carries its own path rules. A proposed change is classified by blast radius as infrastructure, functional, or data, using file-path and diff heuristics against those rules, with a model classification as a second opinion; on disagreement the stricter class wins. A separate, stronger tier refuses outright: a change touching a denied path is checked immediately after diagnosis produces its file list, before any commit, test run, or pull request.
Verification
Exercised live against a real repository: a genuine one-character bug in a denied auth module produced a correct diagnosis, which the denial check refused before any branch existed. Confirmed through the provider's API that no branch or pull request was ever created.
Present limitation
The denial model is a small set of path rules per project, not a rule language. Blast-radius-size and dependency-version-bump rules are deliberately deferred. Denial policies are drafted at onboarding and require human review, but two projects onboarded before that gate existed still carry empty denial policies and need a human to fill them in.

Approve

Design objective
Bind authorization to one exact proposed change, granted by a named person, usable once.
Current implementation
A consequential change routes to the project's owner with a link carrying a 32-byte nonce. Validation and consumption are a single atomic statement, with expiry in the same predicate. Read-only preview and consumption are separate call paths, so a mail client prefetching the link cannot burn a valid approval.
Verification
A 25-way concurrent stampede against one token yields exactly one winner. Mutation-checked: restoring the previous two-statement form fails three tests.
Present limitation
The approver identity is a string the caller supplies, not an identity cryptographically bound to a person. There is no SSO or OIDC binding, and the role model distinguishes only membership from non-membership.

Attest

Design objective
Record the proposal, policy decision, approval, and execution as a chain that cannot be edited without breaking a signature.
Current implementation
DSSE envelopes wrapping in-toto Statements, signed with Ed25519. Four keypairs, one per role. Verification checks signatures, role separation, the hash chain, and cross-references between proposal, policy, approval, and execution. Denied proposals get their own signed chain, terminating at the denial.
Verification
Re-run fresh on every read of an incident's ledger rather than cached, so a tampered row shows as broken the moment anyone looks. A live deny-path run produced a two-event chain that independently re-verified.
Present limitation
Tamper-evident, not independently verifiable: the rows and the trust map live in the same database, so the chain being wholesale replaced by a key holder is outside what verification can detect. No transparency-log anchoring or timestamping.

Execute

Design objective
Apply only the approved artifact, and never treat an interface gesture as authorization.
Current implementation
Approval merges the pull request using the project's own stored credential. Approval signing happens before the merge and blocks it on failure. Execution signing happens after the merge and records a signing failure as its own audit event, because the merge has already happened and cannot fail closed.
Verification
Authorization paths are covered by tests that assert security properties rather than behaviour — every organization-scoped read carries its scoping predicate, and approval and escalation reject each link of the project–incident–fix chain with no side effect: no merge, no status change, no decision row, no ledger entry.
Present limitation
There is no automated production deployment step. Merge is where the current connector's authority ends; deploying the merged change is a separate, manual process outside this loop.

Reconcile

Design objective
Compare what executed against what was approved, using evidence the executing system did not produce.
Current implementation
The proposed change is content-addressed over the changed files' blob SHAs at commit time. At merge time the diff is recomputed from the provider's live pull-request files API and compared. A mismatch hard-blocks the merge and is recorded as an escalation.
Verification
Verified against a real pull request — after the first run failed on the honest path and exposed a defect in our own hashing.
Present limitation
Scoped to one boundary. It cannot observe changes applied through any other route, and it cannot detect an execution that never had a proposal.

Cross-cutting substrates

Audit and provenance are not stages.

Audit

The signed attestation chain covers the proposal-to-execution loop and is append-only and hash-linked. Broader incident history — detection, diagnosis, tests, decisions, outcomes — is reconstructed relationally from incident, fix, and decision records rather than from a single global event log. Both are real; they are not the same thing, and we describe them separately.

Provenance

Every distinct piece of context a diagnosis received is recorded with a SHA-256 hash, in two trust classes. Quarantined inputs record both the raw untrusted input and the canonical extraction, so the extraction step itself is checkable. Direct inputs record a hash so a stored manifest can later be compared against live content to detect substitution after the fact.

Threat assumptions

What the model assumes, stated as assumptions.

Threat model assumptions
We assumeWe do not assume
An attacker can get arbitrary text printed during a CI run.That the attacker can modify tracked source, the intent document, or incident metadata.
The agent can write to the branch it proposed.That the agent controls the hosting provider's API responses.
A model may alter its work product rather than refuse or escalate.That the model is adversarial toward the operator in general.
Anyone who can set environment variables on the deployment can reach any secret it holds.That key custody is enforced by anything stronger than configuration today.

Current connector

Repositories hosted on GitHub.

A project is registered by supplying a repository URL and a credential. The system clones the repository once to verify access, reads its README, manifest, and tracked file list, and drafts an intent document together with sensitive, infrastructure, and denied path rules. Nothing is watched until a human reviews and confirms that draft.

Watching runs in one of two modes: polling a health endpoint, or polling the repository’s CI run status and turning a newly completed failed run into an incident. On an incident, the agent clones with per-project credentials, detects the project’s own package manager and test scripts rather than assuming a toolchain, reproduces the failure, diagnoses it, writes a fix on its own branch, and opens a pull request. Fix pull requests must add a test.

Implemented
The connector authenticates with a classic personal access token carrying full repository scope. We state this exactly rather than describing it as “minimal permissions”, because it is not minimal. Narrowing it is real work we have not done: fine-grained tokens require selecting contents, pull request, actions, and metadata permissions individually per repository.
Open question
Connector-specific enforcement is the open half of this. A connector that can only observe and propose is a weaker instrument than one whose target system can itself refuse an unattested change, and which enforcement primitives a given platform exposes varies enormously.

Verification record

What has actually been run.

Live verification runs
DateWhat was runResult
16 July 2026Planted prompt injection inside a real CI log, processed through the real pipelineReader extracted only genuine technical facts; the diagnosis made no reference to the injected instructions.
16 July 2026Diff recomputation against a real pull requestFailed on the honest path, exposing a blob-SHA abbreviation defect; matched exactly after the fix.
17 July 2026Key-separation test, bypassing the code-level role guardDecrypting the approver key with the agent secret fails authenticated decryption; the correct key still succeeds.
27 July 2026Denied-path incident against the live database and a real repositoryIncident reached blocked status with a deny decision, no fix rows, a two-event attestation chain, and no branch or pull request on the target.
5 August 2026Concurrent approval-token stampedeExactly one winner across 25 concurrent consumers; mutation-checked against the previous form.
Open question
The allow path has not been proven end to end in production. A denial terminates the flow after two events, so what has been demonstrated is signing, hashing, and chain-linking — not the harder guarantee that an execution whose applied diff differs from the approved one is rejected in a live run. That demonstration is the next one, and it has not been run.