# Independent Node paid-flow evidence

18 September 2026. The working draft-3 source now includes a second implementation of the ordinary fixed-quote paid flow. [paid-client.mjs](../verification/paid-client.mjs) is a phased native Node client; [paid-verifier.mjs](../verification/paid-verifier.mjs) implements its paid semantics. Neither imports Python, invokes Python validators or treats a successful schema check as semantic verification. Its Python harness supplies real HTTPS servers and independently provisioned test identities.

This closes the independent **paid-flow** portion of M5. The [native asset graph client](INDEPENDENT-ASSET-CLIENT.md) is now separately evidenced. The M6 consolidated review edition and complete current-source validation are now prepared; integrated review and release operations remain. This is not external certification or a public release change.

## What is independently checked

| Boundary | Node behavior |
| --- | --- |
| Origin and service | Fetches exact policy/authority over certificate-verified HTTPS; selects the configured service/tenant/delegation and cumulative retrieval duties; retains revision, issuer, key identity and terminal-state history across processes |
| Quote | Checks the exact offered digest, offer/origin/service/payer/verifier binding, validity, approved currency/scale/payees/items and a positive exact sum using `BigInt`; resource and provider fees stay separate |
| Assent and receipt | Signs only exact agent assent; verifies the origin-appointed ES256 receipt, closed paid shape, pending state and exact accepted windows; receipt is neither a payer mandate nor a bearer |
| Payer | Uses a different credential and pinned signing key; signs the exact one-quote mandate; agent credentials/signatures are rejected by the Python payer endpoint |
| Payment verifier | Resolves its separate origin appointment before sending a scoped read-only credential and again after receiving the reply; verifies the provider's original JWS and every accepted transaction field |
| Financial history | Replays sequence, event time, exact-check identity, provider reference and allowed transitions; distinguishes fresh assertions from read-only historical retries; expiry/reversal/revocation cannot restore access |
| Service agreement state | Compares the service's state for the same check with the independently verified provider result; verifies signed status and rejects known terminal-state rollback |
| Delivery and reporting | Obtains an opaque token, fetches actual protected bytes, compares their independently configured digest and emits a client-reported retrieval; verifies the collector's exact original intake and retry |

There is no debit, refund or payment initiation API. A signed provider assertion is not proof of bank settlement. A collector signature authenticates the participating client's claim; it does not prove downstream model use.

## Executed evidence

The final [eight Python harness methods](../tests/test_paid_node.py) pass in [the current wire run](../verification/paid-node-wire-tests.txt). They invoke **74 separate Node processes**, each resuming a private journal. Two lifecycle scenarios execute 29 phases each:

- The origin hosts the agreement service directly; only the read-only verifier is delegated to the second HTTPS origin.
- Both the agreement service and read-only verifier are explicitly delegated to the second HTTPS origin.

Both scenarios cover pending and mandate-only denial, failed-to-confirmed recovery, exact retries, actual delivery, signed reporting, reversal, old-bearer denial, historical-check replay without resurrection, status and revocation. The other scenarios reject valid-but-unapproved prices/payees before assent, a correctly signed receipt falsely claiming active access, a wrong provider amount/signer, withdrawal after a provider response, observed origin rollback, altered known compromise history and a compromised key reintroduced under another identifier. The unsupported-duty scenario deliberately performs **no network request**. No outside provider/account is contacted; the payment server is a synthetic signed-status fixture.

The [complete standalone Node run](../verification/paid-node-regressions.txt) passes **140 tests**, comprising the existing 91 and **49 new paid semantic cases**. Those new cases include decimal/sum and fee separation, role separation, exact accepted bindings, current verifier authority, authenticated hostile responses, sequence/transaction conflicts, late financial confirmation without access extension, an original receipt after offer expiry and a stale new response distinguished from an exact historical retry. See [native test source](../verification/test_paid_verifier.mjs).

A preceding [10-method wire regression](../verification/paid-node-wire-regressions.txt) combined the then-six paid scenarios with the existing direct/delegated free and continuing-storage Node exchanges. Those four existing exchanges passed unchanged. The final paid-only run includes the two later scenarios and final client guards. Counts from these overlapping runs must not be added together or presented as a new complete Python suite. The current [compatibility inventory](../verification/paid-node-checks.json) records exact source/evidence hashes.

## Reproduce

Use Node.js 24 and the documented Python environment from this source root:

```sh
node --test verification/test_paid_verifier.mjs
ODEXA_NODE="$(command -v node)" \
  ODEXA_PAID_NODE_REPORT_DIR=verification/local-paid-node-run \
  python -m unittest discover -s tests -p test_paid_node.py -v
```

The harness generates temporary private TLS/credential material, starts two local HTTPS origins and destroys the temporary deployment after the run. Optional saved reports contain scenario results, not private JWKs, passwords, verifier credentials or bearer tokens. The Node client itself uses native crypto, HTTPS and files, plus independently implemented JavaScript primitives already used by the free client. The free helper change only exports those existing primitives; it changes no free wire behavior.

## Phases and private configuration

For an independently provisioned reference deployment, supply a private JSON config and a new journal filename inside an owner-only directory:

```sh
node verification/paid-client.mjs --config /private/path/client.json \
  --state /private/path/paid-state.json --phase agree
```

The trusted config fields are:

| Fields | Source and meaning |
| --- | --- |
| `publisherOrigin`, `serviceId`, `baseUrl`, `delegationId` | Expected origin/service/tenant and explicit selected delegation; null only for a direct service |
| `caFile` | Absolute filename of the explicitly trusted CA bundle for the configured deployment |
| `request`, `accessSeconds`, `useSeconds` | Intended scope and accepted durations; this client supports `retrieve` / `public_retrieval` and attribution only |
| `expectedTermsDigest`, `expectedResourceDigest` | Independently approved terms and test-article digests; never learned solely from the untrusted response being checked |
| `agent` | `clientId`, `principalId`, `password`, `keyId`, `reporterId`, `privateJwk` provisioned for agent assent/reporting |
| `payer` | Different `clientId`, `payerId`, `password`, `keyId`, `privateJwk`, plus independently pinned `publicJwk` for the payer role |
| `verifier` | `serviceId`, `providerId`, exact `endpoint`, `delegationId` and explicitly scoped read-only `authorization` |
| `approvedQuote` | Exact `currency`, `minor_unit_scale`, `total_minor` and `items` approved out of band, before signing a payer mandate |

The verifier credential is supplied only for this independent read-only comparison. It is not implied by an agent's ordinary agreement credential. A real payer should keep its signing/provisioning boundary separate; this same-owner fixture holds both roles solely to demonstrate that the wire service rejects role substitution.

Normal phases are `observe`, `agree`, `acceptance-retry`, `mandate`, `verify`, `service-check`, `retrieve`, `resource`, `report`, `status` and `revoke`. Use `verify --check-id UUID` to create/replay a particular check, then `service-check --check-id UUID` to compare the service's application of that same independently observed check. `resource` deliberately reuses a privately retained bearer so the harness can verify denial after revocation. `mandate-agent-credential` and `mandate-agent-signature` are explicit negative-test phases against your own prepared test service. They are not alternate authorization methods.

Each process acquires an exclusive journal lock and atomically replaces/fsyncs the saved state. The config and journal must be regular, owner-only files on a POSIX host. **The journal can contain a bearer token** alongside exact assent, receipts, mandate, reporting material and historical observations. Never publish it or confuse it with a portable evidence archive. Scenario reports exclude those secrets. A crashed process may leave the lock; establish that its process has stopped before manually recovering that lock. There is no time-based automatic unlock or concurrent-writer merge.

The client uses a fixed independently configured service/payer/verifier identity and a currently supported retrieval policy. It declines other execution duties. It does not perform provider handover, transparently follow policy lineage changes, implement continuing storage or verify paid archives. Use the separately evidenced [storage client](STORAGE-INTEGRATION.md), [handover procedure](PROVIDER-HANDOVER.md), [paid archive verifier](PAID-PORTABILITY.md) and [installed operator path](CURRENT-QUICKSTART.md) for those capabilities. Keeping these capability boundaries explicit avoids presenting a retrieval test client as full Agent Core conformance.
