-
-
Raised live: the receipt returns before anyone decides, and it’s the first signed event in the chain.
-
Tier 1 is declared but unprovisioned, so it reports a broken promise rather than retrying into silence. Tier 2 is Amazon SES.
-
Released by the answer. Six signed events, released true, and the receipt claims only what the code actually checked.
-
Architecture: the agent gets a receipt immediately, Step Functions holds the action, and only a classified direction reaches Release.
-
All ten acceptance criteria, forty assertions, one command. Runs offline with no AWS credentials.
The problem
An agent facing a decision it shouldn't make alone usually has two options, and both are bad. It halts into a queue nobody watches, or it proceeds and writes a log entry. The second is more dangerous, because a record of what an agent decided is not evidence that anyone authorized it.
That gap is where governance theater lives: the approval nobody reads, the audit trail that documents an action instead of proving consent to it, the timeout that quietly counts as a yes.
What it does
When an agent reaches the edge of its own authority it stops. Reachee reaches a person through a contact policy that person declared in advance, and only that person's answer releases the held action.
The held action releases on one path only, from an explicit direction by someone who answered. A timeout, a denial, and an unclassified reply all end the escalation without releasing anything. Acceptance by a provider, receipt by a person, and classification of their answer are three separate signed receipts and are never collapsed into one.
Before any provider is touched, the escalation passes attention gates: coalescing, an attention budget, and quiet hours. Human attention is the scarce resource here, not compute, and reaching someone twice for one event costs their trust.
How I built it
Amazon SES v2 carries the reach. A Step Functions Standard execution holds the action on a task token while a person decides. Four Go Lambdas on arm64, a DynamoDB single table, Secrets Manager for the signing key, an API Gateway HTTP API, and the demo page on CloudFront behind OAC. All of it is Terraform.
Every step writes an Ed25519-signed, hash-chained receipt. The chain holds content hashes and never message bodies, so verifying that a person was reached and decided discloses nothing about what was said.
The verifier is the part I'd point at. verify/verify_chain.py uses only the
Python standard library, shares no code with the service, and implements the
canonical byte format and Ed25519 from scratch. It checks signatures against a
key published on the site rather than the one carried in the file, because a
bundle checked against its own key proves only that it's internally
consistent.
Total AWS usage for the whole build came to $0.034 before credits.
Challenges
Three worth naming.
Getting a Go encoder, a Python verifier, and an in-browser serializer to agree byte for byte. All three are pinned to one golden file rather than to each other, which caught real divergences in escape handling.
Proving the test harness isn't decoration. make criteria asserts all ten
acceptance criteria in one command, offline, with no AWS credentials. I
validated it by breaking the product sixteen ways and confirming each break
turned the right criterion red. Fifteen were caught. The one that wasn't is
now pinned by a test.
Finding my own overclaims. A receipt recorded confidence: "button and note
agree" when the code only checked a note against a keyword list. It couldn't
know the two agreed. The receipt now says what was actually checked. A
quiet-hours time zone that failed to load silently fell back to UTC, which
would have paged a clinician at 2am in the exact system built to prevent that.
It's now a refusal.
What I learned
That the discipline has to point inward or it means nothing. A verifier that accepts everything proves nothing, and neither does a criterion that passes because the bar was lowered to meet it. Every time I held the project to its own standard, it found something.
What's next
The gaps are listed in the README rather than left for a reader to find. The one I'd close first: a deferred escalation currently isn't re-queued when the quiet-hours window closes.
Built With
- amazon-api-gateway
- amazon-cloudfront
- amazon-dynamodb
- amazon-ses
- amazon-web-services
- aws-lambda
- aws-secrets-manager
- aws-step-functions
- ed25519
- go
- javascript
- python
- terraform
Log in or sign up for Devpost to join the conversation.