# Loom reward settlement

## Status

The run verifier is operational behind `LOOM_VERIFIER_ENABLED=true`: it issues wallet-bound one-use leases, requires one unpredictable checkpoint per server-observed minute, consumes leases with optimistic concurrency control, and calculates nominal rewards from verified duration and the pass tier fixed at issuance. Browser-reported performance cannot increase the reward. This is continuous-participation verification, not cryptographic hardware attestation.

On-chain settlement remains staged and disabled. The current local claim-program source is restricted to NVDAx. The binary previously deployed at `5ouEtFN4VeR9jZB1MQNrAoAkPq2172fhqnAwLJ9ALALp` predates the NVDAx-only policy, is pre-audit and uninitialized, and must not be activated as the production settlement program. No claim is payable until the NVDAx-only source is rebuilt, deployed, configured, funded, reviewed, and tested end to end. Every eligible verifier-accepted GPU vendor maps to one reward asset:

```text
All accepted vendors -> NVDAx -> Xsc9qvGR1efVDFGLrVsmkzv3qi45LTBjeUKSPmx9qEh

NVDAx uses 8 decimals and Token-2022.
```

No signing key, treasury authority, or RPC credential belongs in this repository. The backend accepts `LOOM_KEY` (or `loom_key`) only from the server environment and derives its public key at runtime. That public key is used as both the pre-launch treasury authority and epoch signer. The secret is never returned by an API.

## Settlement boundary

Only runs accepted by the verifier can create a nominal reward liability. Browser-local units, free trials, stopped sessions, failed sessions, missed checkpoints, replayed leases, and unsigned submissions are never settlement inputs. A nominal liability is not a claim: claimable status requires a fully covered vault and a finalized on-chain epoch root.

The coordinator assigns each verified run to one six-hour epoch and records:

- Wallet and one-use lease identifier.
- Verified VCU and policy version.
- Mining-pass tier active when the lease was issued.
- USD-denominated nominal liability.
- Verifier-accepted vendor, fixed NVDAx payout mint, price observation, and raw integer token units.
- Verification and run digests.

## Epoch close

1. Freeze the epoch input set.
2. Reject duplicate leases and runs without accepted proof.
3. Apply the policy and treasury governor.
4. Map every eligible run to NVDAx regardless of its reported GPU vendor.
5. Convert covered rewards into raw units using a recorded Jupiter Price API v3 observation for that mint. Persist its USD price, Solana block ID, source timestamp, and observation timestamp.
6. Aggregate one NVDAx leaf per wallet.
7. Sort leaves deterministically and build the Merkle root.
8. Confirm the NVDAx vault holds at least the full raw-unit liability.
9. Persist the immutable manifest and digest.
10. Submit the root, NVDAx raw-unit total, and manifest digest to the Solana claim program.
11. Mark vouchers claimable only after the root transaction is finalized.

The old deployed program ID is `5ouEtFN4VeR9jZB1MQNrAoAkPq2172fhqnAwLJ9ALALp`; it no longer matches the current NVDAx-only source policy and must not be configured for production settlement. The replacement program must remain disabled until its config is initialized, authority is secured, NVDAx vault is funded, and the binary is independently reviewed. Runtime readiness verifies finalized `getAccountInfo` state and requires the configured address to be executable; an environment string by itself is not accepted.

## Claim

The wallet submits its epoch, NVDAx mint, raw-unit amount, and Merkle proof. The program verifies the proof, checks the epoch state, transfers from the NVDAx vault, and creates a claim receipt in one transaction. A second claim for the same wallet, mint, and epoch must fail.

The current local program source supports only the fixed NVDAx Token-2022 mint, starts paused, reserves every epoch's complete NVDAx liability before activation, and permits claims only after the run window closes. It has no treasury withdrawal instruction in v0.1. See `claim-program/README.md`, `claim-program/SECURITY.md`, and the generated `claim-program/idl/loom_claims.json` after rebuilding.

## Job funding

The buyer flow accepts inference and render jobs only after the server verifies a finalized Solana payment. Verification checks that the connected buyer signed the transaction, the configured treasury authority received at least the required lamports, and the signature has not funded another job. A paid job becomes queued work, not an automatic completion. Compatible miners still need signed leases, output verification, and delivery storage.

Paid job intake must remain disabled until fulfillment capacity is operational. The minimum payment is 0.01 SOL for inference or render; it is a policy value rather than a promise of service.

The private record follows `data/job-schema.json`. It retains the buyer wallet, finalized signature, paid lamports, private workload input, and assignment state. The public API strips the wallet, signature, and input. A dispatcher may move a job from `queued` to `leased` only by binding it to an unused production run lease; output moves through `running` and `verifying` before it can become `complete`.

## Required production configuration

```text
LOOM_KEY
LOOM_CLAIM_PROGRAM_ID
JUPITER_API_KEY (recommended for production)
SOLANA_RPC_URL or HELIUS_RPC_URL
LOOM_JOB_INTAKE_ENABLED=true
LOOM_DISPATCHER_ENABLED=true
LOOM_VERIFIER_ENABLED=true
LOOM_SETTLEMENT_ENABLED=true
```

The NVDAx payout mint is fixed in application code and is not overridden by environment variables. A standard Solana RPC can prove token balances and transactions but cannot supply USD prices. The server therefore resolves the mint with Jupiter Price API v3. The unauthenticated lite endpoint is suitable for preview; production settlement should use `JUPITER_API_KEY`, persist every observation, and halt an epoch if the response is stale or unavailable.

The derived wallet public key is the treasury authority, not a token vault itself. The NVDAx vault is the authority's Token-2022 token account for the fixed mint. The Treasury API reads that owner/mint balance at finalized commitment through the configured Solana RPC and values it with the matching Jupiter observation. The launch switch must remain false until the required token account is funded and the replacement claim program is audited.

Job intake has separate switches for intake, dispatch, and verification. All three must be enabled before the buyer API accepts SOL. This prevents a payment from entering a queue that has no production worker or verification capacity.

## Stonk launch role

$LOOM is intended to launch through Stonk. The Stonk token page is a discovery and trading route; it does not make a runner claim payable. The disclosed protocol treasury allocation is approximately 10% of $LOOM supply and is intended to support covered runner rewards, network incentives, and protocol continuity while buyer-funded compute demand develops. Every NVDAx reward still requires verifier acceptance and sufficient inventory in the NVDAx vault.

## Signing policy

- Keep `LOOM_KEY` only in encrypted server environment storage, never in Vercel source, browser code, logs, or API responses.
- Use a multisig as program upgrade and treasury authority.
- The pre-launch build permits one key for treasury authority and epoch signing as requested. Split those roles before meaningful treasury value is deposited.
- Require an emergency pause and signer rotation procedure.
- Treat webhook and RPC results as observations; verify settlement transactions against finalized Solana state.

## Public artifacts

Every closed epoch publishes the manifest matching `data/settlement-schema.json`, its digest, Merkle root, policy version, vault coverage, and Solana signature. This allows an independent implementation to reproduce the committed root.
