{"criteria_id":"settlement-evidence/v1","criteria_revision":"1.0.0","family":"settlement-evidence","op":"analyse","ops_not_offered":[],"corpus":{"id":"lifecycle-analytics-corpus/v1","sha256":"4e9468a3c11ab5ac2bd2c0635f76666654b9fc24492a83479e7a917a0276e763"},"corpus_pin_definition":"The corpus pin is the SHA-256 of the corpus's canonical serialization (the corpus object excluding its sha256 field), computed and verifiable by the published harness (harness.mjs). Expected outputs inside corpus cases are derived from the criteria text by an independent implementation in gen-corpus.mjs (never the engine's code path), and each case labels its provenance (constructed from on-disk fleet records vs synthetic).","price":{"usdc_units_per_call":20000,"label":"$0.02","basis":"per log"},"free_tier":{"per_day":100,"min_interval_ms":5000,"on_exhaustion":"402"},"input_contract":{"body":"One JSON request body: { log, as_of?, caller? (free pre-check only) }. log is an array of log lines under the published log-shape contract; as_of is an optional ISO-8601 evaluation instant.","caps":{"body_bytes":262144},"over_cap":"A request body over 262,144 bytes is a free pre-gate refusal naming the cap.","validation":"The log is validated FREE, before any payment: shape, per-line validity under the published malformed rule, and the empty / no-valid-lines refusals. A malformed submission fails free and never consumes a payment. The analysis itself is computed only after payment verification (or a verified-marker resume)."},"log_contract":"Log-shape contract: the log is a JSON array; each line is one issued challenge, a JSON object. Required fields: challenge_id (non-empty string; used only to detect duplicate lines, never printed or stored), issued_at (ISO-8601 timestamp string), expires_at (ISO-8601 timestamp string, strictly after issued_at). Optional fields: used_at (a timestamp string or null; what 'used' requires in the log is a used_at instant at or after issued_at and at or before expires_at — no other field is read as usage evidence; a status or state field, if present, is ignored), rail (a non-empty string when present — the seller's own rail label). Timestamp basis: ISO-8601; offsets are accepted and normalised to the UTC instant; all comparisons are on instants. Any other field on a line is ignored — in particular buyer-identity fields (any field naming a buyer, payer, wallet, customer, or contact) are never read, never stored, and never emitted: this op reports counts only.","malformed_rule":"Malformed lines: a line is malformed when it is not a JSON object; challenge_id is missing, not a string, or empty; issued_at or expires_at is missing, not a string, or not a parseable timestamp; expires_at is not strictly after issued_at; used_at is present and is neither null nor a parseable timestamp string, or its instant lies outside [issued_at, expires_at]; rail is present and is not a non-empty string; or its challenge_id duplicates the challenge_id of an earlier valid line (first valid occurrence wins; an id carried only by malformed lines reserves nothing). Malformed lines are excluded from every lifecycle count and counted once in the malformed_lines factor. A submission with zero lines refuses free (log_empty); a submission whose lines are all malformed refuses free (no_valid_lines).","classification_rule":"Classification at the evaluation instant T (the request's as_of when supplied, else the server's time at the call, printed in the report): over valid lines only, each line is exactly one of USED (the line carries a used_at instant), EXPIRED-UNUSED (no used_at instant and expires_at at or before T), or PENDING (no used_at instant and expires_at after T). issued is the number of valid lines, and when usage is computable, used + expired-unused + pending = issued exactly.","computability_rule":"Computability: the log records usage when at least one valid line carries the used_at field (present, even if null). When no valid line carries the field, the log cannot distinguish a used challenge from an unused one: used, expired_unused, and pending are each reported as NOT-COMPUTABLE; issued and the expiry-window distribution remain computable. The log records rail when at least one valid line carries the rail field; when none does, the per-rail split is reported as NOT-COMPUTABLE. When rail is recorded, the split covers the valid lines that carry a rail value, grouped by that value under the same computability rule, and valid lines without a rail value are counted in rail_absent_lines and appear in no group. No count is ever estimated, interpolated, or carried over from another log.","distribution_rule":"Expiry-window distribution: for each valid line the expiry window is expires_at minus issued_at in seconds, counted in five buckets — le_60 (window at most 60), 61_300 (over 60, at most 300), 301_900 (over 300, at most 900), 901_3600 (over 900, at most 3600), gt_3600 (over 3600). Bucket edges are exact: a window of exactly 60 seconds is in le_60, exactly 300 in 61_300, exactly 900 in 301_900, exactly 3600 in 901_3600. The factors print the minimum, maximum, and mean window in seconds (mean rounded to 3 decimals).","window_buckets":["le_60","61_300","301_900","901_3600","gt_3600"],"not_computable_token":"NOT-COMPUTABLE","verdict_grammar":{"line":"CHALLENGE LIFECYCLE — issued: <n> · used: <x> · expired-unused: <y> · pending: <z> — <evaluation UTC>","vocabulary":"The line carries the headline census; a count the log cannot support prints as NOT-COMPUTABLE. There is no composite score, grade, or band anywhere in this op."},"free_precheck":"The free pre-check (POST /precheck) validates the submitted log under the published contract and returns assessability ONLY: the common signed fields, whether the log is assessable (or the free refusal naming the failure), the line-shape facts (lines submitted, valid lines, malformed lines), and the disclosure/honesty/retention lines. It returns no lifecycle count, no distribution, and no per-rail split. Free allowance: 100 per day per caller wallet, minimum interval 5,000 ms, 402 on exhaustion.","custody":{"construction":"In-memory processing within a single request lifetime; the submitted log persists nowhere, on any path including errors. No hash of a submitted log appears anywhere.","ledger_closed_fields":["payer wallet","timestamp/day","price (USDC units) with the CAD fair-market-value block (rate, rate date, basis, cad_pending, refund)","payment tx id + Solana fee (lamports)","criteria version","verdict line","issued count","used count (number or NOT-COMPUTABLE)","expired-unused count (number or NOT-COMPUTABLE)","house flag"],"ledger_note":"The ledger list above is closed: adding a field is a criteria/handling version change. The ledger NEVER carries any log line, fragment, challenge id, rail label, or buyer-identity value.","errors":"Error handling is closed-form: static strings plus numeric facts only (lengths against caps, line counts, rule ids). No error path interpolates any part of a submitted log."},"forbidden":"Forbidden in every surface of this op (report, pre-check, errors, ledger, metrics): any composite score or grade; any buyer-identity value, challenge id, or log fragment; any estimated count (a count the log cannot support is NOT-COMPUTABLE); any inferred drop-off reason, cause, or intent; any fetched or chain-read data (this op fetches nothing and reads no chain).","boundary_statement":"Boundary vs B1 Settlement Verification (/toll/settlement, settlement-evidence/v1, op verify): B1 reads the chain per payment — one signature, the fields as found — while B5 never reads the chain and never sees a payment: it counts a seller-submitted issuance log, and a used count here is the seller's own log assertion, not a chain-verified settlement. Boundary vs the fleet's own D-02 door counts (the Query Observatory's challenged-but-never-settled series): those are first-party counts at our own door; B5 is the seller-side twin any seller can run over its own log, and the two never mix data. Boundary vs B6 Ledger-Line Completeness Check (same family): B6 censuses the fields of a payments-ledger sample; B5 counts the lifecycle of a challenge-issuance log — different artefact, different counts.","reasons_line":"Why any challenge went unused is unknowable from the issuance log: the log records that challenges were issued, used, or left to expire, and nothing about what any buyer intended, attempted, or met at payment time. No reason, cause, or intent is inferred anywhere in this report.","disclosure_sentence":"Submitting a challenge-issuance log to any third party, this service included, discloses that log to it; the log is processed in memory only and never stored, but the analysis does not undo the disclosure.","honesty_line":"The analysis counts the log exactly as submitted; it states what the seller's own log records and nothing about any challenge the seller issued outside this log, and a used count is the log's assertion, not a chain-verified settlement.","retention":"Submitted logs are processed in memory only and are never stored — not in KV, not in logs, not in the payments ledger, not in metrics, and not in error records. No line, fragment, challenge id, rail label, buyer-identity value, or hash of a log is recorded anywhere. The paid report carries counts, the distribution, the per-rail split, and the factors because that report is the delivery the buyer paid for. The payments ledger records only the closed field list published in the criteria. Because nothing is kept, a paid retry re-submits the log.","payment_includes":"$0.02 per challenge-issuance log. The payment includes: one lifecycle analysis of the challenge-issuance log you submit — the issued / used / expired-unused / pending counts, the expiry-window distribution, and the per-rail split where the log carries a rail field — computed mechanically under the published rules of settlement-evidence/v1 from the log exactly as submitted, returned as one signed report with all factors printed and an evaluation timestamp. Counts only: no buyer identity appears anywhere in the report. A count the submitted log cannot support is reported as NOT-COMPUTABLE, never estimated. A free pre-check validates the log's shape before any payment and returns no counts. The submitted log is processed in memory only and is never stored; the payments ledger records only the payer, the time, the price, the headline counts, and the verdict line.","kill_line":"Kill line (M-23 / B5, under the operator's 2026-11-03 build-bank-hold doctrine): build, bank, and hold; judged at the fleet's periodic reviews. There is NO demand kill line for this item. Day-0 = first outside paid settle (accounting only; house proofs never count). Tripwires, all stop-and-review: (1) refunds >5% in any 30-day window; (2) free use >10x paid use; (3) a wrong count from undisclosed stale or partial data (the error enters the corpus first as a regression case, corrected rules publish as a new criteria version, the corpus re-passes at 100% before serving resumes; issued reports are never amended); (4) confidentiality/custody: any surface emitting a buyer-identity value or a challenge id.","never":"This op never fetches any URL; never reads the chain; never stores a submitted log; never computes a composite score; never estimates a count; never emits a buyer-identity value or a challenge id; never infers why a challenge went unused.","service":"lifecycle-analytics","version":"1.0.0","endpoints":{"criteria":"GET /criteria (free)","precheck":"POST /precheck (free, log validation + assessability only: no counts, no distribution, no split)","analyse":"POST /analyse (paid, $0.02 per log: signed lifecycle analysis)","metrics":"GET /metrics","not_offered":"Any other POST path answers NOT COVERED — this worker serves op analyse only."}}