Work / 01
MetricTrust Control Plane
An analytics agent wants to roll an experiment from 20% to 50%. Is that specific action backed by evidence that is current, tested and approved right now?
An execution control layer that sits between an analytics agent and the systems it wants to change. It does not ask whether the agent may call a tool. It asks whether this action is justified by the current dbt results, the metric's approval status and the agent's authority, and only then issues a signed, single-use permit.
Aug 2026 · Working, tested, live demo
- Agent proposesagent, action, resource, parameters
- Evidence brokerparses real dbt manifest and run results, hashes the bundle
- Policy engineYAML rules, forbid first, fail closed: DENY, REQUIRE_APPROVAL or PERMIT
- Approvaldurable state machine; evidence re-verified after a human says yes
- Signed permitRS256 token, short TTL, single use
- Protected executorthe only component with write access; guardrail breach triggers rollback
- An evidence broker that reads the manifest and run results dbt actually produces, queries the fact table directly and hashes the exact rows a decision rests on.
- A deterministic policy engine in YAML. Forbid rules are checked first, and anything the engine cannot decide is denied.
- A database-backed approval workflow (PENDING, APPROVED, DENIED, EXPIRED) that survives restarts, and re-checks the evidence hash after a human approves and before the permit is issued.
- Signed permits that bind the action, the parameters hash, the evidence bundle hash, the metric definition hash and the dataset snapshot. The executor accepts nothing from the agent directly.
- 21 pytest tests covering policy branches, permit tampering, expiry and audience checks, and a full HTTP walkthrough: propose, approve, execute, replay rejected, audit reconstructed.
The rule shape (principal, action, resource, context, forbid and permit) is a straight port, so swapping in Cedar later is a policy-file change, not a rewrite. It also removed a toolchain I did not need for a solo build.
I kept the cryptography that matters, real signing and single-use nonces, without standing up an identity server for a one-person project.
Same contract, same restart behaviour, one fewer service to operate.
Both were preview-stage. The README says so and points to the roadmap instead of simulating something it does not do.
A single number hides which part of the evidence moved. The permit needs to say what it was bound to.
The approval check that failed on every approval
The evidence hash originally included source freshness in minutes, which changes with wall-clock time. So the hash changed between an agent proposing an action and a human approving it a few seconds later, and the stale-approval check I had built tripped on every approval, not only on genuinely stale ones. The fix was separating what identifies evidence (the dbt run, the dataset snapshot, the test results) from what gates it live (freshness against a policy threshold, checked fresh every time and never hashed). I had not thought about that distinction clearly until a failing test forced it.
A one-second permit that lived five hours
Permit expiry was computed from a naive datetime's .timestamp(), which assumes local time. On a host five hours behind UTC, a permit with a one-second lifetime did not expire for five hours. A test called test_expired_permit_is_rejected caught it. Inspection did not.
- Replace the YAML engine with Cedar behind the same policy files.
- Move agent identity from static keys to workload identity.
- Add hardware attestation once the tooling is out of preview.