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: trueplus 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§
Structs§
- RowReport
- Verify
Args - Parsed
verifysubcommand arguments. - Verify
Outcome - 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-outputreceipt is requested, the receipt is signed.
Functions§
- run
- run_
from_ argv - Entry point dispatched from
mainwhen 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=valueper line, fixed order, trailing newline. The consumer re-derives this from the receipt fields, recomputesHMAC-SHA256(key, preimage), and compares tosignature. Documented indocs/src/verify.md.