# job.open milestone — current integration

## Before this milestone

The repository contained an ownerless exact-output router, unit/fuzz/invariant tests and nine real-fork tests. The frontend already read balances, used the Quoter, and built Permit2 plus QuoteApproval signatures. Historical evidence recorded 48 contract tests and 23 frontend tests. The checkout supported multiple actions, mixed signing and submission in one action, lacked an explicit state machine, and was hidden behind the launch redirect.

A new live probe exposed a concrete incompatibility: the old validation expected a resource ending in `/submit`; the actual challenge binds `https://api.imd.fun/requests/{id}`. The submit endpoint itself still ends in `/submit`. This was corrected using a captured real response and a regression test. The old schema discarded some quote fields; the current client retains and compares the entire strict quote, including terms, policy and expiry, and verifies the canonical prepared input hash.

## Current architecture

`Checkout.tsx` is an English job-only view. `job-flow.ts` owns the explicit transition graph and manual commands. `imd-client.ts` validates discovery, capabilities, check, quote, unsigned challenge and status. `job-wallet.ts` reads balances and allowance, simulates exact-output purchase, verifies the configured router's code hash and getters, and requests transactions/signatures only from the connected wallet. `payment.ts` and `payment-window.ts` bind the two signatures to the saved challenge and enforce time constraints. The Next.js proxy forwards only allowed IMD requests and blocks signed submission by default. The read-only RPC proxy never broadcasts.

The only checkout action is `job.open`, initially a bounded research-report input. The landing-page read-only educational demo still shows other IMD use cases; it is not a paid-action selector.

```text
idle → checking → quote_created → imd_required → swap_quote_ready
→ awaiting_swap_confirmation → swap_pending → imd_acquired
→ awaiting_payment_signature → payment_submitting → payment_pending
→ job_admitted
```

Failures enter `failed`. Enough existing IMD skips the purchase states. Recovery starts at `checking`, resolves saved transactions and checks the same API order. Preparing/signing never triggers submission. Pending status is checked manually. No timer retries a payment. The UI's one-second timer only updates displayed time.

## Current verified market

Read-only chain verification at Ethereum block **26126161**, hash `0x43b354d499dc12ab1bcca008960a5edd772a5f5d4178aec49b3b48fc6963062f`:

| Item | Value |
| --- | --- |
| currency0 | `0x0000000000000000000000000000000000000000` (native ETH) |
| currency1 / IMD | `0xD34a99Bc0f67aE1bbd63C660e6d0b0dd03E263B7` |
| fee / tickSpacing | `10000` / `60` |
| hook | `0xc6C965Bd164c483e87d0B550671798e9A3602840` |
| PoolManager | `0x000000000004444c5dc75cB358380D2e3dE08A90` |
| pool ID | `0x415829f72e9f54531c26eae76f107618540e898a45d6ae35959e143f5faca704` |

PoolKey hashing, hook getters, market-open state, 18 token decimals and deployed code were checked. Token and hook deployed bytecode matched explorer-verified bytecode. Sources: official IMD and POOL4 documentation, official Uniswap v4 deployment list, Ethereum RPC and explorer code. `milestone-chain.json` records this pinned verification; `chain-refresh.json` records the subsequent current-state refresh. Market liquidity/availability remains owner-dependent and can change.

## Executed verification

- `forge fmt --check`, `forge build`, `forge test -vvv`: passed, **49 tests**, zero failed/skipped. Includes unit tests, 3 fuzz properties at 256 runs and 2 invariants at 128 sequences / 4096 calls.
- Dedicated `forge test --match-contract RouterForkTest -vvv`: **10 passed**, including 256 fork-fuzz runs, at block 26126161. New test obtains `IMD_JOB_AMOUNT` from current capabilities, begins with zero IMD, buys the exact requirement and proves no automatic Permit2 allowance.
- Initial unchanged-contract verification also passed nine fork tests at block 26126159 before implementation.
- `slither . --json ...`: 65 findings, identical detector/severity/description set to the prior reviewed report: 3 High, 22 Medium, 1 Low, 39 Informational. High/Medium dispositions were reviewed against unchanged contract source and refreshed tests. No new unresolved exploitable High/Medium issue was identified internally. This is not an independent audit. Slither reports findings rather than a clean zero-alert pass.
- Production state machine plus wallet adapter and actual unpaid IMD API succeeded against local Anvil: zero initial IMD, API-required exact output acquired, sufficient balance confirmed, ending at `awaiting_payment_signature`. No mocked POOL4/token or private wallet key; only the wallet's selected account was modeled for Anvil impersonation.

That run observed `500000000000000000` required atomic IMD, an estimate of `2093011346256632` wei and a 1% maximum of `2113941459719199` wei. These are timestamped test results, not constants or current price promises. API status remained `quoted`; signatures requested and real payments were both zero. Evidence: `milestone-client-fork.json`.

## IMD endpoints verified

| Endpoint | Observed result |
| --- | --- |
| GET `/requests/capabilities` | 200; Ethereum IMD payment policy and current job.open amount |
| GET `/openapi.json` | 200; OpenAPI 3.1 and QuoteApproval type/domain matched |
| POST `/requests/check` | 200; explicit report input had no blockers |
| POST `/requests/quote` | 201; saved unpaid job.open quote |
| POST `/requests/{id}/submit` without payment | 402; Permit2 challenge, timeout 300 seconds in the observed response |
| GET `/requests/{id}` | 200; `quoted`, no admission/payment |

Today's OpenAPI omits `/requests/check` from its path map although the current API guide documents it and the actual endpoint succeeds. The client uses the verified guide response shape rather than inventing an OpenAPI entry. Signed submit was deliberately not sent to the live service.

## Security and unresolved acceptance

The router remains unchanged. A swap is atomic but the later API payment is a separate operation. Unsigned/pre-submission failure leaves purchased IMD with the user. A lost response after signed submission is ambiguous: settlement may have occurred, so status must be reconciled and the same authorization reused only with explicit approval.

No mainnet deployment, real wallet signing, real IMD allowance, real x402 settlement or paid job admission occurred. A reviewed verified deployment, operator runtime hash, disposable human-controlled EOA and explicit final payment authorization are still required. The exact paid acceptance sequence is in LIVE_IMD_TEST.md. The milestone demonstrates preparation readiness, not completed mainnet admission.

Session recovery stores bearer credentials and signed bytes in the browser session, never a private key. Same-origin script compromise is a risk; public hosting still requires HTTPS, appropriate headers, controlled scripts and edge rate limiting. Payment signatures are locally checked cryptographically before submission. No token fees, USDC, escrow, smart accounts or mainnet broadcasting were added.

## Files changed

Checkout view and route; `imd-client.ts`, `job-flow.ts`, `job-wallet.ts`, `payment-window.ts`; payment/challenge validation and API transport/proxy; frontend environment example; state, signature and proxy tests; new real-requirement fork test; local full-flow verification script; documentation and recorded evidence. The Solidity router and fixed market configuration were not altered.

## Frontend and browser verification

`npm run test`: 43 tests passed, including end-to-end state progression with local test signatures, safe-mode proxy rejection, exact-byte recovery, stale estimates, changed wallets/balances, invalid stored signatures, cancelled signing, confirmed reverts and quote expiry during a pending swap. `npm run typecheck` and `npm run build` passed. No wallet private key is used by the application or backend; the test-only public unfunded signing key never touches a network.

The built `/checkout` was inspected at 1440 by 1000 and 390 by 844. At mobile size, client and scroll widths were both 375 pixels. Live required IMD loaded, objective and slippage inputs worked, and all value-moving buttons remained disabled in safe mode without a connected wallet. Captured console warnings/errors were empty. Screenshots are milestone-checkout-desktop.png and milestone-checkout-mobile.png. A real browser-wallet connection/signature was not performed.

For repeatable verification, script/TestMainnet.ps1 fetches the current job.open policy, validates chain/token/decimals, supplies IMD_JOB_AMOUNT and runs the required Foundry commands. MAINNET_FORK_BLOCK is optional; leaving it unset uses current state. This helper contains no broadcast or payment operation.
