{"workflow":null,"planning":null,"id":"04415684-bed9-4c18-bed1-fc3746741138","state":"completed","template":"shape:chain","objective":"README accuracy follow-up. 1 The README says 80 tests and 20 conformance checks; the real counts are 94 and 22. Replace hard-coded counts with wording that will not go stale, or correct them. 2 The step-3 402 response row omits input; show the real 402 body fields including input. 3 Extend test/readme.test.ts so it runs the README's conformance commands and the library snippet too, not only the hand-run block. Add a CHANGELOG.md entry listing each item and what changed. Keep the existing experimental label everywhere it already appears.","blockedReason":null,"createdAt":"2026-10-02T23:44:22.223Z","updatedAt":"2026-10-02T23:53:55.778Z","paidBy":"0x50cb1f4eb0d2739803c174b395a04ce4f5f109e6","parentJobId":"8d15e132-1ef6-42b5-aa2d-d0a0d7b4abbd","project":{"id":"fb018b04-0661-41fd-88d5-51bb90863d72","head":"04415684-bed9-4c18-bed1-fc3746741138","running":null,"versions":[{"jobId":"fb018b04-0661-41fd-88d5-51bb90863d72","workflowId":null,"objective":"Build imd-mock: a local mock of the IMD paid-request API so anyone can test integrations without spending IMD. Routes: GET /requests/capabilities, GET /openapi.json (a minimal x-imd-actions), POST /requests/check (canned verdicts, plus a flaky mode that refuses a body once then accepts it), POST /requests/quote, POST /requests/{id}/submit (402 challenge without payment, then verifies the Permit2 and QuoteApproval signatures by recovering the signer and checking every field), GET /requests/{id}, GET /jobs/{id}. Deterministic test keys and fixtures, `npx github:<owner>/<repo>` starts it on a port, and a conformance suite that any client can run against it. Response shapes follow the flow below exactly. Paid-request flow on https://api.imd.fun (server-side only; browser origins get 403). 1) Make a bearer token: 32 random bytes as hex, header Authorization: Bearer <token>. 2) POST /requests/quote {requestKey: new UUID, action, input} returns {order:{id}} (422 invalid_input lists problems). 3) POST /requests/{id}/submit with no body returns 402 with a challenge: accepts[], quote{id, quoteHash, action, payment{asset, amount, payTo}, expiresAt}, resource, resourceUrl, requesterScopeHash. 4) Check accepts[0] against capabilities and the quote. 5) Sign EIP-712 Permit2 PermitWitnessTransferFrom: domain {name \"Permit2\", chainId 1, verifyingContract 0x000000000022D473030F116dDEE9F6B43aC78BA3}; types PermitWitnessTransferFrom(TokenPermissions permitted, address spender, uint256 nonce, uint256 deadline, Witness witness), TokenPermissions(address token, uint256 amount), Witness(address to, uint256 validAfter); spender = x402 exact Permit2 proxy 0x402085c248EeA27D92E8b30b2C58ed07f9E20001; random 256-bit nonce; deadline at most quote.expiresAt minus 5 s; witness {to: payTo, validAfter: 0}. The payment object is {x402Version: 2, resource, accepted: accepts[0], payload: {signature, permit2Authorization: {from, permitted{token, amount}, spender, nonce, deadline, witness{to, validAfter}}}} with numbers as decimal strings and no extra fields (extra fields fail as invalid_payment_shape). 6) Sign EIP-712 QuoteApproval: domain {name \"IdentityMD Paid Action\", version \"1\", chainId 1}; fields resource string (= resourceUrl), requesterScopeHash bytes32 (0x + value), quoteId string, quoteHash bytes32 (0x + value), paymentHash bytes32 (sha256 of the payment object serialised as key-sorted JSON), action string, asset address, amount uint256, payTo address, expiresAt uint256. 7) POST /requests/{id}/submit again with header PAYMENT-SIGNATURE: base64(JSON payment) and body {quoteSignature}: 202 pending or 200 outcome. 8) Poll GET /requests/{id} with the same bearer until the status leaves quoted, payment_pending and admission_pending. Payment is IMD 0xd34a99bc0f67ae1bbd63c660e6d0b0dd03e263b7 on Ethereum mainnet, 0.5 IMD per action (per run for schedules); the wallet needs a one-time IMD approve to Permit2; the server pays gas. Free helpers: POST /requests/check {action, input} (the evaluator's verdict, no payment; it is noisy, so retry up to 3 times), POST /requests/import {url, kind} (public GitHub repo to repoUrl + baseCommit), GET /openapi.json (actions and limits under x-imd-actions), GET /requests/capabilities (price, asset, payTo, quote lifetime, launch chains). Full reference: https://imd.fun/docs#paid Label it everywhere it is presented (README top, CLI --help, site banner) as experimental: \"Experimental, commissioned as a test of the IMD swarm. It may not work as described. Read the code, start with small amounts, no warranty.\"  Label it everywhere it is presented (README top, CLI --help, site banner) as experimental: \"Experimental, commissioned as a test of the IMD swarm. It may not work as described. Read the code, start with small amounts, no warranty.\" Add one line at the end of the README: \"Commissioned through paid IMD swarm requests.\"","baseCommit":"0243d7da4a4337ae8b16bcdf15bb4ead736fd68f","state":"completed","createdAt":"2026-10-02T18:19:23.859Z"},{"jobId":"8d15e132-1ef6-42b5-aa2d-d0a0d7b4abbd","workflowId":null,"objective":"Bring the README in line with the mock as it is now. 1 \"Try it by hand\" uses action echo, which the mock rejects with 422 (must be one of job.open, ...). Use real actions such as job.open. 2 The README documents a check response {verdict, reasons}; the mock (and the live POST https://api.imd.fun/requests/check) return {action, blockers, suggestions, kind, plan, facts, judged}. Document that shape. 3 Remove or update every remaining echo or implement reference (README lines about 40, 42, 79, 129, 130, 140, 142, 194, 206, 234). 4 Add a short \"Known open question\" note: the mock moves an order to payment_pending on an unpaid 402 submit (src/server.ts around line 347); whether the live server does the same is unconfirmed. Do not change server behaviour in this job. Every command in the README must run as written against the mock; add a test that runs the README's commands. Verify against the LIVE API at https://api.imd.fun with read-only GETs (and the free POST /requests/check where it applies), not only against a mock you write yourself; save the live response bodies you relied on under fixtures/live/ or the test folder and build any mock from them. Add a CHANGELOG.md entry (create it if missing) that lists each item below and what changed. Keep the existing experimental label everywhere it already appears (\"Experimental, commissioned as a test of the IMD swarm. It may not work as described. Read the code, start with small amounts, no warranty.\").","baseCommit":"cccc34b0bd17a5cb9c9c2383fae481134075bf03","state":"completed","createdAt":"2026-10-02T21:50:56.723Z"},{"jobId":"04415684-bed9-4c18-bed1-fc3746741138","workflowId":null,"objective":"README accuracy follow-up. 1 The README says 80 tests and 20 conformance checks; the real counts are 94 and 22. Replace hard-coded counts with wording that will not go stale, or correct them. 2 The step-3 402 response row omits input; show the real 402 body fields including input. 3 Extend test/readme.test.ts so it runs the README's conformance commands and the library snippet too, not only the hand-run block. Add a CHANGELOG.md entry listing each item and what changed. Keep the existing experimental label everywhere it already appears.","baseCommit":"4ac45801437755051c8bb9bf15cde813dfd5cfa4","state":"completed","createdAt":"2026-10-02T23:44:22.223Z"}]},"deliver":true,"host":false,"site":null,"launch":{"requested":false,"kind":null,"id":null,"status":null,"chainId":null},"oracleRequestId":null,"delivery":{"repoUrl":"https://github.com/identity-md-launches/launch-608-build-imd-mock-local-mock","pullRequestUrl":"https://github.com/identity-md-launches/launch-608-build-imd-mock-local-mock/pull/3","commit":"7f1e8e7fff637ef5dc6d639fa5d26ec65c058f1b","deliveredAt":"2026-10-02T23:54:01.979Z","media":null},"media":null,"nodes":[{"key":"adversarial_review","role":"review","state":"accepted","attempt":1,"revisions":0,"judgeRevisions":0,"dependsOn":["refine_project"],"allowedPaths":[],"failureReason":null,"dispatchNote":null,"dispatchNoteAt":null,"updatedAt":"2026-10-02T23:53:55.778Z","verdict":null,"seat":{"tokenId":"13","agentId":"51504"},"live":null},{"key":"refine_project","role":"implement","state":"accepted","attempt":1,"revisions":0,"judgeRevisions":0,"dependsOn":[],"allowedPaths":["README.md","CHANGELOG.md","test/**"],"failureReason":null,"dispatchNote":null,"dispatchNoteAt":null,"updatedAt":"2026-10-02T23:47:49.327Z","verdict":{"status":"accepted","profile":"none","evaluation":"structural","rejectionCode":null,"detail":"paths and tree verified; no suite was run for this kind of work","verifierVersion":"0.1.0+b537d296","verifiedTreeHash":"af0f999ef193c3b63f332f667d9bb2fb8adf0c62","at":"2026-10-02T23:47:49.328Z","failedChecks":[]},"seat":{"tokenId":"524","agentId":"51293"},"live":null}],"reviews":[{"status":"sent","chainId":1,"txHash":"0x0a1181cfc9ead7534e32f3adeb1f55592d5bac2b13b04f1c13eb13064beaa2c0","blockNumber":26115036,"sentAt":"2026-10-03T23:15:14.796Z","entries":[{"nodeKey":"adversarial_review","agentId":"51504","value":1,"role":"review:submission"},{"nodeKey":"refine_project","agentId":"51293","value":1,"role":"verification:structural"}]}]}