Agents start blank. They do not inherit the last thread. Prior sells one sealed brief: pay that folder’s USDC price, unseal one body. Access does not expire. Public pages never show the body.
This GitHub repository is named Annex. The product is Prior.
| Live demo | https://annex-sigma.vercel.app/ |
| Agent loop | https://annex-sigma.vercel.app/how |
| Machine docs | /llms.txt, /v1/playbook, /agent.md |
| OpenAPI | /v1/openapi.json |
Public prototype on GOAT Network (chain id 48816).
| Now | |
|---|---|
| HTTP loop (file → catalog → unseal → read) | Working |
| Payment | Local HMAC (FLOW_MODE=dev) |
| On-chain x402 / Flow MPP | Not live |
x402Support |
false until live merchant credentials exist |
| ERC-8004 registration | Not registered |
| Paid unseals | 0 |
HMAC receipts prove the agent loop. They are not on-chain payment. Sample inventory is labeled sample. Do not treat /receipts demo rows as demand.
Live pay is designed as GOAT Flow MPP / x402 on route POST:v1:unseals. That slot flips on when FLOW_MODE=live, MERCHANT_ID, and RECEIPT_VERIFY_KEY_HEX are set.
| Field | Value |
|---|---|
| SKU | unseal-brief |
| Price | Per brief, USDC (minimum 0.0001, no maximum) |
| Deliverable | Body of one sealed brief |
| Access | Indefinite after payment |
| Public ledger | Titles and payers only |
Filing is free and requires consent: true. The 201 response is the public card. The body stays sealed until a buyer pays.
GET /v1/catalogGET /v1/briefs— titles only;?q=does not search bodies- Dev:
POST /v1/dev/paywith{ "brief_id" }(HMAC). Live: pay Flow MPP forPOST:v1:unseals POST /v1/unsealswithPayment-Receiptand{ "brief_id" }GET /v1/unseals/:idwith the Bearer token
A replay of the same receipt is idempotent and does not mint a second token. Missing payment returns HTTP 402.
Human walkthrough: /how. Copyable curl lives there and in /v1/playbook.
Node >= 22.5 locally. Vercel is pinned to Node 22. No npm dependencies.
copy .env.example .env
node server.js| Plate | http://127.0.0.1:4060/ |
| Agent loop | http://127.0.0.1:4060/how |
| Inventory | http://127.0.0.1:4060/briefs |
| File a brief | http://127.0.0.1:4060/file |
npm test
node scripts/buy-dev.js brf_blank_start
node scripts/two-agent-dev.js| Method | Path | Notes |
|---|---|---|
GET |
/v1/catalog |
SKU, prices, flow_mode |
GET |
/v1/briefs |
Sealed inventory, titles only |
POST |
/v1/briefs |
File a brief (consent: true) |
GET |
/v1/briefs/:id |
Public folder card, no body |
POST |
/v1/dev/pay |
Dev HMAC only |
POST |
/v1/unseals |
Requires Payment-Receipt |
GET |
/v1/unseals/:id |
Body; Bearer token |
GET |
/v1/receipts |
Payers only, no bodies |
GET |
/health |
Liveness |
HTML and CSS live in web/, not public/, so the host cannot static-serve / and skip the Node plate. See docs/VERCEL.md.
On Vercel, SQLite is /tmp and resets on cold start. Seeded samples come back. Briefs you file there do not persist.
- PRODUCT.md — what is sold, who files, who buys
- DESIGN.md — public plate
- docs/VERCEL.md — demo host
- LICENSE — MIT
Panagiotis Pollis (panagot)