{"criteria_id":"tool-argument/v1","version":"1.0.0","corpus":{"id":"argument-check-corpus/v1","sha256":"572e80b4b849ed769f888404f51aad50548db89b7dc7fbc55da69806a636eeef"},"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).","price":{"usdc_units_per_call":20000,"label":"$0.02","basis":"per check"},"free_tier":{"per_day":100,"min_interval_ms":5000,"on_exhaustion":"402"},"ops":{"check":"POST /check — { arguments: <object>, schema: <JSON Schema> } or { arguments_text: <raw JSON text>, schema: <JSON Schema> }; exactly one arguments form per check"},"verdicts":["VALID — the blob conforms as submitted; the answer states that no repair was needed","REPAIRED — whitelist repairs brought the blob into conformance; the delivery carries the repaired blob and the exact diff","UNREPAIRABLE — every blocking defect is named by path and code; no repaired blob is returned"],"whitelist":[{"id":"R1","name":"close-truncated-json","applies":"arguments_text only","rule":"When the text ends at a token boundary with unclosed { / [ delimiters, append exactly the closing delimiters the open stack requires, in reverse order — nothing else.","cannot_invent":"The appended characters are forced by the delimiters the caller already opened; no token, key, or value is added. Text ending inside a string or mid-token is not repaired (its missing content is the caller's)."},{"id":"R2","name":"drop-trailing-comma","applies":"arguments_text only","rule":"Remove a comma that immediately precedes a closing delimiter or the end of the text.","cannot_invent":"A trailing comma carries no value; removing it deletes punctuation only. Every other comma is structural and untouched."},{"id":"R3","name":"string-to-number","applies":"any node whose schema type is number or integer","rule":"A string matching the JSON number grammar exactly is replaced by that number. For type integer the number must be integral.","cannot_invent":"The digits are the caller's own, character for character; only the JSON type tag changes. A non-numeric string matches nothing and stays a defect."},{"id":"R4","name":"string-to-boolean","applies":"any node whose schema type is boolean","rule":"The string \"true\" becomes true; the string \"false\" becomes false. No other string is repaired.","cannot_invent":"Only the two canonical spellings map, each to the one boolean it names. \"yes\", \"1\", \"True\" would be guesses about intent and are defects."},{"id":"R5","name":"string-json-unwrap","applies":"any node whose schema type is object or array","rule":"A string that itself parses as JSON of exactly the schema's type is replaced by the parsed value, which is then checked recursively.","cannot_invent":"The content was fully supplied by the caller, encoded as text; unwrapping adds nothing and drops nothing. A string that does not parse, or parses to the wrong type, is not repaired."},{"id":"R6","name":"scalar-to-string","applies":"any node whose schema type is string","rule":"A number or boolean is replaced by its exact JSON spelling (7 -> \"7\", true -> \"true\").","cannot_invent":"The replacement is the canonical textual form of the very value submitted — a re-expression, not a new value. Objects and arrays are never stringified (their textual form would be a representation choice, i.e. a guess)."},{"id":"R7","name":"wrap-single-in-array","applies":"any node whose schema type is array","rule":"A non-array value is wrapped as the single element [value]; the element is then checked against items.","cannot_invent":"Wrapping rearranges the caller's value without altering it. If the element then fails items, the node is a defect — the wrap never launders a bad value into a pass."},{"id":"R8","name":"drop-null-optional-property","applies":"object properties only","rule":"A declared property present with value null, NOT in required, whose subschema does not admit null, is removed.","cannot_invent":"Null on an optional field is the absence marker, not a value; removing it supplies nothing and loses no caller value. A required property, or one whose schema admits null, is untouched. No other key is ever removed."},{"id":"R9","name":"enum-case-match","applies":"any node with an all-string enum","rule":"A string value that fails enum but equals exactly ONE enum entry case-insensitively is replaced by that entry.","cannot_invent":"The target value comes from the caller's own schema and the match is unique — there is no choice to make. Zero or multiple case-insensitive matches are defects, never a pick."}],"whitelist_discipline":"The whitelist is CLOSED: a repair not listed here is never improvised. A repair is attempted only where the value currently fails the schema at that node; repairs apply recursively wherever the schema guides (properties, items, R5-unwrapped values); application order is deterministic (text repairs R1/R2 first, then a node's own repair before its children, object children in submitted key order). Repairs are computed tentatively: if any blocking defect remains, the verdict is UNREPAIRABLE and no repaired blob is returned.","never_a_repair":["a missing required field — even when the schema publishes a default (a default is the tool's dispatch-time fallback, never filled here)","deleting a caller-supplied value to force conformance (an undeclared property under additionalProperties:false is the defect additional_property)","guessing a mistyped value (\"abc\" for a number, \"yes\" for a boolean, \"4.5\" for an integer)","trimming, case-folding outside R9, reformatting, or rounding any value","completing truncated content (arguments text ending inside a string or mid-token is invalid_json_text)"],"diff_format":"One entry per repair, in application order: { path, rule, op, before, after }. path: $ is the arguments root, .key descends into an object, [i] into an array, $arguments_text is the raw text form. op: replace (R3-R7, R9) · remove (R8 — after is null; R2 on the text — before is \",\", after is \"\") · append (R1 — before is null, after is the exact appended string). Nothing changes that is not in the diff; the diff plus the submitted blob reproduces the repaired blob exactly.","defect_codes":["missing_required","type_mismatch","enum_mismatch","const_mismatch","string_too_short","string_too_long","pattern_mismatch","minimum_violation","maximum_violation","exclusive_minimum_violation","exclusive_maximum_violation","array_too_short","array_too_long","items_not_unique","too_few_properties","too_many_properties","additional_property","invalid_json_text"],"defect_order":"missing_required first (in required order), then per-node defects in traversal order. A single check names ALL blocking defects found, never just the first.","schema_subset":{"enforced":["type","enum","const","required","properties","additionalProperties","items","minLength","maxLength","pattern","minimum","maximum","exclusiveMinimum","exclusiveMaximum","minItems","maxItems","uniqueItems","minProperties","maxProperties"],"not_checked":"format is NOT checked in phase 1; annotation keywords (title, description, default, examples) are enforced as nothing and default is never applied.","not_covered":["$ref","$defs","definitions","allOf","anyOf","oneOf","not","if","then","else","dependentRequired","dependentSchemas","contains","propertyNames","patternProperties","prefixItems","unevaluatedProperties","unevaluatedItems","contentEncoding","contentMediaType","schema-valued additionalProperties","array-form items","boolean schemas","boolean-form exclusiveMinimum/exclusiveMaximum"]},"free_refusals":["invalid_request_body","schema_missing","schema_invalid","schema_not_covered","arguments_missing","arguments_ambiguous","arguments_not_object","arguments_text_invalid","arguments_too_deep","CAP-EXCEEDED:body_bytes (413)"],"malformed":"A submission that cannot be assessed at all (malformed or not-covered schema, arguments not an object) is a named FREE refusal, before any payment, at the pre-check and at the paid op alike — distinct from an UNREPAIRABLE verdict on a well-formed submission.","honesty_boundary":"A verdict grades the submitted blob against the submitted schema under tool-argument/v1 — nothing else. The service does not know whether the schema is the tool's real schema, does not dispatch the call, and does not judge whether a conforming call is a good idea. A REPAIRED verdict means the listed mechanical repairs brought the blob into conformance with the submitted schema; every repair is shown in the diff, and any change not in the diff did not happen.","boundary":"Boundary: this service validates and mechanically repairs one submitted arguments blob against one caller-supplied schema, pre-dispatch. It does not execute or dispatch the tool call, does not supply argument values, does not fill schema defaults, and never deletes a caller-supplied value to force conformance.","custody":{"ledger_closed_fields":["payer wallet","timestamp","day","price (USDC units) with the CAD fair-market-value block (rate, rate date, basis, cad_pending, refund — null unless refunded)","payment tx id","Solana fee (lamports)","criteria version","op","verdict line","per-check status summary (verdict + counts + defect codes only — never argument values, keys, or fragments)","house flag"],"retention":"Submitted blobs and schemas are processed in memory only, never stored — not in KV, not in logs, not in the payments ledger, not in metrics. The payments ledger records only the closed field list published in the criteria (verdict, counts, and defect codes — never argument values, keys, or fragments). Because nothing is kept, a paid retry re-sends the blob and schema."},"payment_includes":"$0.02 per check. The payment includes: one pre-dispatch check of the one arguments blob and the one tool JSON Schema you submit — a verdict of VALID, REPAIRED, or UNREPAIRABLE; when REPAIRED, the repaired arguments blob and the exact diff (path, before, after, and the whitelist rule applied for every change); when UNREPAIRABLE, every blocking defect named by path and reason. Repairs are mechanical only, from the published whitelist in the criteria: the service never invents an argument value — a missing required field, or a value only a guess could fix, is UNREPAIRABLE. Factors printed; no composite score. Nothing submitted is stored beyond the payments ledger's closed field list.","kill_line":"Kill line (M-41, under the operator's 2026-11-03 zero-demand doctrine): build, bank, and hold; judged at the fleet's periodic reviews. Tripwires, all stop-and-review: refunds >5% of paid calls in any 30-day window; free use >10x paid use; a repair found to have invented a value, or a verdict issued from undisclosed partial schema coverage = stop-serving.","service":"argument-check","endpoints":{"criteria":"GET /criteria (free)","precheck":"POST /precheck (free, validation + assessability only; no verdict, no factors)","check":"POST /check (paid, $0.02 per check: signed argument-check report)","metrics":"GET /metrics"}}