Skip to main content

Module verify

Module verify 

Source
Expand description

pounce verify <problem.nl> <claim.sol> — independent solution checker.

§Why this exists

When pounce is a tool an agent calls, the agent should never be the thing you trust for “the solution satisfies the constraints.” Trust belongs to a small, deterministic checker that re-derives the answer from the canonical problem — not from the agent’s narration and not even from the solver’s own exit string. Optimization is the rare setting where this is cheap: a claimed x* is just numbers, and feasibility is one constraint evaluation (g_l ≤ g(x*) ≤ g_u, x_l ≤ x* ≤ x_u), O(nnz) work with no resolve.

pounce verify loads the canonical .nl, reads a claimed .sol, and reports the worst constraint/bound violation (and, when the .sol carries constraint duals, a first-order/KKT stationarity residual). It defends the three agent-workflow failure modes:

  • fabrication (“here’s a solution that looks like pounce ran”) — invented numbers fail the residual check against the real model;
  • ignoring the solver — a downstream consumer gates on the receipt’s verified: true plus the problem hash, not on prose;
  • solving the wrong problem (dropping/relaxing a constraint to dodge infeasibility) — the check runs against the canonical constraints and bounds, so a point that is only feasible for a relaxed model is caught here.

The JSON receipt content-addresses both inputs by SHA-256 so a consumer can confirm which problem was verified. When the POUNCE_VERIFY_KEY environment variable holds a secret the agent does not have, the receipt is additionally signed with HMAC-SHA256 over a float-free preimage (see signing_preimage) — so an agent cannot mint a receipt that a consumer holding the key will accept. The consumer recomputes the HMAC over the same preimage and compares.

Verdict / exit code: 0 when every violation is within tolerance (FEASIBLE); 20 when a violation exceeds tolerance (INFEASIBLE); 2 on a usage or I/O error. Optimality is reported but, by default, does not gate — feasibility is the rigorous, sign-convention-independent guarantee; pass --require-optimal to also gate on the stationarity residual.

Modules§

sha256

Structs§

RowReport
VerifyArgs
Parsed verify subcommand arguments.
VerifyOutcome
The fully-evaluated verification result. Serialized to the JSON receipt and rendered to the console.

Constants§

KEY_ENV
Environment variable holding the HMAC key. When set (non-empty) and a --json-output receipt is requested, the receipt is signed.

Functions§

run
run_from_argv
Entry point dispatched from main when argv[1] == “verify”.
signing_preimage
The exact byte string that gets HMAC-signed. Deliberately float-free — only hex hashes, integer counts, and the verdict — so any language reproduces it byte-for-byte (no float-formatting parity problems between Rust and a Python/JS consumer). One key=value per line, fixed order, trailing newline. The consumer re-derives this from the receipt fields, recomputes HMAC-SHA256(key, preimage), and compares to signature. Documented in docs/src/verify.md.