What did your fleet approve this week that never completed — and why? Approvals across an agent operation — PR merges, money-moving tool calls, payment/checkout completions, disclosure acks, filing submissions — are each recorded as a one-shot state inside their own silo, with no owner-after-approver, no retry budget, and no approved-but-not-completed count, so finished, approved work dies on transient causes in every domain at once. Your producers emit one signed record per approval lifecycle event (type, owner-after-approver, cause from one shared taxonomy, attempt, deadline) through an emit() shim that is identical for every approval type. The census verifies every Ed25519 signature, rejects replays, sequence gaps, undeclared types and cross-producer contamination, and derives a per-approval verdict — COMPLETED / WORKING (cause + attempt) / GIVEN-UP (cause) / EXPIRED — plus the weekly report: approved but not completed, by cause, by approval type, with declared-but-silent types named as coverage gaps, never read as healthy zeroes.
Verdict lookup $0.01/verdict (x402) · Solo $4.99/operator/mo (up to 500 census records, 1 producer integration, weekly give-up report) · Fleet $14.99/operator/mo (up to 5,000 records, 10 producer integrations, per-type cause reports; records beyond 5,000 meter at $0.01 each) · Scale $49.99/operator/mo (up to 10,000 records included, records beyond meter at $0.01 each, unlimited integrations, custom retention) · ONE free weekly census report per operator ever (x402, pay-to 0x7a482F3B58780519880a6A13F983E958f2Ed6A61).
1. POST /register {"operator": "your-name"} → account token (shown once). 2. Generate an Ed25519 keypair per producer; POST /producers {"producer_id", "public_key", "types"} with your Bearer token — the service stores the public key only; a producer_id can never be re-registered with a different key. 3. Emit one signed record per approval lifecycle event (approved / attempt_failed / completed / given_up / expired) via POST /records or the MCP emit_record tool. 4. Read GET /verdict?approval_id= and GET /report/weekly.
Approval ids are unique across the census: the first producer to emit for an approval_id binds that approval to itself and its type, and records from any other producer for the same id are rejected — namespace your approval ids (for example "<producer>:<your-id>").
"""Producer emit() shim — identical for every approval type (49-line shape).
Register once, then emit() per lifecycle event. Your private key never
leaves your process; the census holds your public key only."""
import json, time
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
from cryptography.hazmat.primitives import serialization
def _canon(rec):
body = {k: rec[k] for k in sorted(rec) if k != "sig"}
return json.dumps(body, sort_keys=True, separators=(",", ":")).encode()
class Producer:
def __init__(self, producer_id, private_key_hex):
self.pid = producer_id
self._key = Ed25519PrivateKey.from_private_bytes(bytes.fromhex(private_key_hex))
self._seq = {}
@property
def public_key(self):
return self._key.public_key().public_bytes(
serialization.Encoding.Raw, serialization.PublicFormat.Raw).hex()
def registration(self, types):
return {"producer_id": self.pid, "public_key": self.public_key, "types": types}
def emit(self, approval_id, atype, event, owner, cause=None, attempt=0,
deadline=None, ts=None):
seq = self._seq.get(approval_id, 0) + 1
self._seq[approval_id] = seq
rec = {"v": 1, "producer": self.pid, "approval_id": approval_id,
"type": atype, "event": event, "owner": owner, "cause": cause,
"attempt": attempt, "deadline": deadline,
"ts": ts if ts is not None else time.time(), "seq": seq,
"scheme": "ed25519"}
rec["sig"] = self._key.sign(_canon(rec)).hex()
return rec # POST this object to /records with your account Bearer token
Approval types: merge, payment, disclosure, filing, gated_tool_call. Causes: CI_WAIT_TIMEOUT, FIX_AGENT_CRASH, RUNNER_GONE, FIX_ROUND_CRASH, BRANCH_TIP_UNVERIFIABLE, PROVIDER_TIMEOUT, HUMAN_NO_RESPONSE, DEPENDENCY_GONE, STATE_LOST_ON_RESTART, OTHER (issued honestly, never force-fit).
Documented limits: the shared cause taxonomy covers 95.5% of cross-domain give-ups in the lab's 44 builder-authored fixtures, with an honest 4.5% OTHER residue — live cause distribution may differ and the OTHER share is monitored, not assumed away. Real-silo wiring time per producer type is unmeasured — the emit() shim is identical per type (1 registration + 1 emit() per lifecycle event); locating the lifecycle points inside your own code is your integration work, and time-to-first-record is measured in production. Willingness to pay for the census rung specifically is UNMEASURED — nobody has sold a cross-domain approval census before. Coverage is limited to registered producers: a producer that never registers is outside the census by construction, and a declared-but-silent type is named as a coverage gap, never read as healthy. Q1's scraper undercount (12 of 58 give-ups, 20.7%) was measured on the three synthetic silo shapes in the lab, not against every real silo. This product counts and attributes; it does not complete approvals — completion ownership stays with each domain's own shepherd or gate.
Support: support@textforagents.com · Terms · Privacy · OpenAPI