openapi: 3.2.0 info: title: invinoveritas Inference API description: The **verification layer for autonomous agents** — a neutral verdict before an irreversible action (`/review`), a signed proof after (`/prove`), and a public, on-chain-verifiable track record (`/ledger`) you can audit without trusting us. contact: name: invinoveritas url: https://api.babyblueviper.com/ email: contact@agents.babyblueviper.com license: name: Apache 2.0 url: https://www.apache.org/licenses/LICENSE-2.0.html version: 1.13.0 x-guidance: 'invinoveritas — the VERIFICATION LAYER for autonomous agents: a neutral verdict before an irreversible action, a signed proof after, and a public, on-chain-verifiable track record of those verdicts you can audit without trusting us — the oversight + judgment the agent can''t self-issue. Pay-per-call services settled in USDC via x402 on Base (also Lightning/L402 or a funded Bearer balance). Paid resources carry x-payment-info and answer an unauthenticated probe with a 402 challenge; send the JSON body in the operation schema, then retry with the X-PAYMENT header. Good entry points: POST /review (capital-scale-aware verdict before an agent ships an irreversible action), POST /prove (signed, independently-verifiable attestation of a prior execution), GET /ledger (the public signed verdict track record). Routes marked security:[] are free or Bearer/identity-gated and are not x402 resources.' tags: - name: Inference description: Reasoning and decision endpoints paths: /reason: post: tags: - Inference summary: Reason operationId: reason_reason_post requestBody: content: application/json: schema: anyOf: - $ref: '#/components/schemas/ReasoningRequest' - type: 'null' title: Data responses: '200': description: Successful Response content: application/json: schema: {} '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' '402': description: Payment Required — pay in USDC via x402 (or Lightning/L402) and retry with the X-PAYMENT header. x-payment-info: price: mode: fixed currency: USD amount: '0.105652' protocols: - x402: {} /decision: post: tags: - Inference summary: Decision operationId: decision_decision_post requestBody: content: application/json: schema: anyOf: - $ref: '#/components/schemas/DecisionRequest' - type: 'null' title: Data responses: '200': description: Successful Response content: application/json: schema: {} '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' '402': description: Payment Required — pay in USDC via x402 (or Lightning/L402) and retry with the X-PAYMENT header. x-payment-info: price: mode: fixed currency: USD amount: '0.190173' protocols: - x402: {} /review: post: tags: - Inference summary: Review operationId: review_review_post requestBody: content: application/json: schema: anyOf: - $ref: '#/components/schemas/ReviewRequest' - type: 'null' title: Data responses: '200': description: Successful Response content: application/json: schema: {} '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' '402': description: Payment Required — pay in USDC via x402 (or Lightning/L402) and retry with the X-PAYMENT header. x-payment-info: price: mode: fixed currency: USD amount: '0.211303' protocols: - x402: {} /review/known-bad: get: tags: - Inference summary: Review Known Bad Registry description: 'Public, free, no-auth read of the deterministic known-bad-address registry (services/ known_bad_registry.py, 2026-08-01) that /review''s known_bad_registry gate checks against. Exists so the "byte-reproducible without trusting the LLM" claim on a registry-hit reject is checkable by anyone, not just assertable — pull this, pull the artifact you''re verifying, confirm a match yourself. Self-building: grows automatically whenever a real /review call rejects an onchain_action/sanctions_screening artifact containing a new address.' operationId: review_known_bad_registry_review_known_bad_get responses: '200': description: Successful Response content: application/json: schema: {} security: [] /review/external: post: tags: - Inference summary: Review External operationId: review_external_review_external_post requestBody: content: application/json: schema: $ref: '#/components/schemas/ReviewRequest' required: true responses: '200': description: Successful Response content: application/json: schema: {} '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' '402': description: Payment Required — pay in USDC via x402 (or Lightning/L402) and retry with the X-PAYMENT header. x-payment-info: price: mode: fixed currency: USD amount: '0.950865' protocols: - x402: {} /agent-economy-brief: post: tags: - Inference summary: Agent Economy Brief description: Latest ecosystem research brief — observational only. Paid Bearer or L402. operationId: agent_economy_brief_agent_economy_brief_post responses: '200': description: Successful Response content: application/json: schema: {} '402': description: Payment Required — pay in USDC via x402 (or Lightning/L402) and retry with the X-PAYMENT header. x-payment-info: price: mode: fixed currency: USD amount: '0.068267' protocols: - x402: {} /audit/agent-readiness: post: tags: - Inference summary: Audit Agent Readiness description: Agent-readiness / verifiability audit of a target URL. Paid x402 / Bearer / L402 (S199). operationId: audit_agent_readiness_audit_agent_readiness_post responses: '200': description: Successful Response content: application/json: schema: {} '402': description: Payment Required — pay in USDC via x402 (or Lightning/L402) and retry with the X-PAYMENT header. x-payment-info: price: mode: fixed currency: USD amount: '1.162168' protocols: - x402: {} /x402/seller-intel: post: tags: - Inference summary: X402 Seller Intel description: x402 Bazaar seller intelligence — buyer-wallet behavior OR discoverability audit. Paid (S199). operationId: x402_seller_intel_x402_seller_intel_post responses: '200': description: Successful Response content: application/json: schema: {} '402': description: Payment Required — pay in USDC via x402 (or Lightning/L402) and retry with the X-PAYMENT header. x-payment-info: price: mode: fixed currency: USD amount: '0.190173' protocols: - x402: {} components: schemas: ValidationError: properties: loc: items: anyOf: - type: string - type: integer type: array title: Location msg: type: string title: Message type: type: string title: Error Type input: title: Input ctx: type: object title: Context type: object required: - loc - msg - type title: ValidationError HTTPValidationError: properties: detail: items: $ref: '#/components/schemas/ValidationError' type: array title: Detail type: object title: HTTPValidationError DecisionRequest: properties: goal: type: string title: Goal description: The overall goal or objective context: type: string title: Context description: Background context (market conditions, positions, risk tolerance, etc.) default: '' question: type: string title: Question description: The specific decision question style: type: string enum: - short - concise - normal - detailed title: Style description: 'Response style: short, concise, normal, or detailed' default: normal want_confidence: type: boolean title: Want Confidence description: Include confidence score, risk level, and uncertainty factors (recommended for decisions) default: true response_format: anyOf: - additionalProperties: true type: object - type: 'null' title: Response Format description: Optional JSON schema for structured output type: object required: - goal - question title: DecisionRequest ReviewRequest: properties: artifact: type: string maxLength: 20000 minLength: 1 title: Artifact description: 'The thing to review: a code diff, shell command, plan, config change, analysis, etc. Aliases `action` / `proposed_action` / `input` are also accepted.' artifact_type: type: string enum: - code_diff - patch - shell_command - plan - config_change - analysis - agent_output - trade - onchain_action - sanctions_screening - general title: Artifact Type description: 'What kind of artifact this is. Used to tailor review focus. Use ''trade'' for a proposed entry/exit/risk decision — triggers the capital-scale-aware risk-manager review. Use ''onchain_action'' for a proposed on-chain transaction (transfer, swap, approval, bridge, contract call — e.g. a Base MCP action) BEFORE approval — triggers the on-chain risk review (scam/honeypot token, unlimited-allowance drainer, address poisoning, slippage/MEV). Use ''sanctions_screening'' for a compliance/AML screening result (sanctions, KYB, PII checks) BEFORE acting on it — triggers a deterministic check that a categorical verdict (e.g. CLEAN) carries its own scope (which lists, what matched), not just an unscoped claim. IMPORTANT for ''trade'' / ''onchain_action'' / ''sanctions_screening'' (the irreversible-class types): a REJECT verdict can now happen even when the review''s own confidence would otherwise support approve/approve_with_concerns, IF that confidence is below a floor (0.5 by default) — see the response''s reversibility_gate field (triggered/original_verdict/confidence/threshold) for whether this fired on your call. Low-confidence approval on an action you can''t undo is not treated as a safe default; check reversibility_gate before assuming a reject means the content itself was bad.' default: general context: type: string maxLength: 4000 title: Context description: What this is trying to do, why now, what success looks like. Helps the reviewer judge whether the artifact actually achieves it. default: '' concerns: type: string maxLength: 2000 title: Concerns description: Specific things you want checked (e.g., 'is this safe to run on production', 'does this match the intent', 'any edge cases'). default: '' severity_threshold: type: string enum: - blocker - high - medium - all title: Severity Threshold description: Lowest severity to surface in issues list. 'blocker' = only show ship-stopping issues. default: all include_trading_state: type: boolean title: Include Trading State description: 'Sentinel mode: auto-inject a compact summary of current Sovereign Earner / Sentinel state (equity, regime, open position, recent PnL, pause status) into the review context. Use when reviewing a trading-related diff/config/directive — gives the reviewer concrete portfolio state without the caller hand-pasting it. Opt-in.' default: false sign: type: boolean title: Sign description: Return a PORTABLE, SIGNED proof of this verdict (a schnorr-signed Nostr event binding the verdict + a hash of the reviewed artifact + our published pubkey), including a content-addressed decision_ref = sha256(JCS({artifact_hash, artifact_type, policy_version, verdict, source_class})). Attach it to your output so a downstream agent can confirm — WITHOUT trusting you OR us — that invinoveritas issued this verdict for this exact artifact, via POST /verify-proof. The agent-to-agent trust handshake. For artifact_type=trade|onchain_action|sanctions_screening, the proof also carries source_class ('agent_reported' today) and, when applicable, a vantage_limitation field disclosing that the verdict is occurrence evidence, not an absence/completeness claim — check it before treating an irreversible-class verdict as sufficient on its own. default: false seed: type: boolean title: Seed description: INTERNAL patient-zero seeding flag. When set by OUR OWN fleet (honored only for localhost callers), a signed proof is counted as 'proofs_seeded' (our fleet attaching proofs to public output) rather than 'proofs_issued' (external paid demand) — so dogfood never masquerades as demand. Ignored for external callers. default: false state_hash: anyOf: - type: string maxLength: 128 - type: 'null' title: State Hash description: 'Optional SHA-256 hex digest of the caller''s graph/agent state at the moment of the review request (e.g. sha256(json.dumps(state, sort_keys=True))). When provided, the signed proof binds to BOTH the artifact AND the state — so a downstream verifier can confirm the decision was made against the exact state the caller had, not just the action it proposed. This is a COMMITMENT, not an enforced execution-binding check: nothing here automatically re-verifies state_hash at execution time, and the proof''s own signature stays valid even if the caller''s state has since drifted. If your integration needs a fail-closed guarantee that a stale-state proof can''t be consumed, YOU must recompute state_hash immediately before acting and compare it to this field — we don''t sit in your execution path to enforce that for you.' dry_run: type: boolean title: Dry Run description: 'Preview mode: compute and return artifact_hash + decision_ref (the values a real signed proof would bind) WITHOUT actually signing anything — no Nostr event is built, no schnorr signature is produced, nothing is committed. Use this to confirm the hash of your content before requesting a real, permanent proof with sign=true. NOTE: authenticated/paid callers are auto-signed by default (see the `sign` field''s own note) — dry_run=true is the only way to see what WOULD be signed without actually signing it, and takes priority over sign/the auto-sign behavior when true. The response''s `proof_preview` field carries the hashes; there is no `proof` field on a dry_run response.' default: false related_proof_event: anyOf: - additionalProperties: true type: object - type: 'null' title: Related Proof Event description: 'Optional: if the artifact being reviewed here IS another party''s already-signed verdict proof (a verdict-of-verdict re-review), pass that proof''s full signed event — the exact {id, pubkey, created_at, kind, tags, content, sig} block from its own /prove or /review(sign=true) response. We independently re-verify it ourselves (schnorr signature + decision_ref recompute — never your claim about it) before its source_class can affect this call''s own: the outer verdict''s source_class is capped at the inner verdict''s, never upgraded by it (an independent_mediator outer call reviewing an agent_reported inner verdict stays agent_reported). If the inner event fails to verify, this call proceeds at agent_reported regardless of your own registry status (fail-closed) — an unverifiable amplification claim never gets the benefit of the doubt. One hop only: we do not walk the inner verdict''s own related_decision_ref transitively. HONEST SCOPE: we verify the cited event''s own authenticity and source_class — NOT that it is actually, topically what this call''s artifact claims to be re-reviewing. related_decision_ref being present proves the cited proof is authentic and was accounted for, not that it''s genuinely related.' intended_audience: anyOf: - type: string maxLength: 256 - type: 'null' title: Intended Audience description: 'Optional: declare who/what this verdict is intended for (your own DID, endpoint URL, or gateway identifier) — a real context-binding replay-protection gap, not present in earlier policy versions. Bound into decision_ref so it cannot be silently stripped or altered once issued. NOT independently verified (we cannot confirm who will actually present the proof downstream) — a reader compares this against their own identity and treats a mismatch as a signal the proof may be presented outside the context it was declared for, rather than trusting a generally-reusable artifact by default.' intended_verifier: anyOf: - type: string maxLength: 256 - type: 'null' title: Intended Verifier description: 'Optional: a CAIP-10 string naming the specific on-chain verifier/gate this verdict is meant to be checked against, e.g. ''eip155:8453:0x8004A169FB4a3325136EB29fA0ceB6D2e539a432'' (same convention as agent-registration.json''s agentRegistry field). Closes a real gap: the raw signed bytes (NIP-01 event id) bind only to our pubkey + content, nothing to a specific chain/contract — a valid proof is otherwise replayable against any gate willing to accept it. Bound into decision_ref (itself inside the schnorr-signed content), so this IS real crypto-level domain separation, one hop through decision_ref. NOT independently verified (we cannot confirm which gate actually consumes the proof) — a gate compares this against its own chain_id/address and treats a mismatch as a replay-outside-intended-verifier signal.' request_capture_ref: anyOf: - type: string maxLength: 256 - type: 'null' title: Request Capture Ref description: 'Optional: a requester-controlled commitment (a hash/id you generated and can independently prove existed at request-time, e.g. published on your own log or committed on-chain) that this specific artifact_hash was submitted for review. This is the ''captured-admission'' primitive co-designed with trustless-ai/recompute-kit (captured-admission-v0): since the reviewer (us) and the only party who could suppress a verdict are the same party here, self-anchoring by US proves nothing — but a requester-anchored capture receipt means a verdict that never gets published against a receipt someone else already committed to having submitted becomes a provable gap, not something we could silently suppress without it being independently checkable. Echoed back verbatim in the response''s admission_receipt block. NOT independently verified by us (we don''t check where you anchored it) — closes the gap only for requesters who opt in, same honest-scope caveat as every other optional declaration field on this endpoint.' operation_id: anyOf: - type: string maxLength: 128 - type: 'null' title: Operation Id description: Optional idempotency key (any stable string you generate, e.g. a UUID) for Bearer-auth calls only. If a prior call with the SAME operation_id AND the same artifact from your API key already completed successfully within the last 24h, that exact original response is returned again — no new sats are deducted and no new verdict is computed. Use this so a dropped connection can be safely retried without double-billing or getting a second (possibly different) verdict for the same submission. Reusing an operation_id with a DIFFERENT artifact is refused with HTTP 409, not silently served — same semantics as a Stripe idempotency-key body mismatch — so generate a fresh operation_id per logical submission, not per artifact. If your artifact is JSON, it's canonicalized before comparison (sorted keys, whole-number floats normalized) so a retry through a different serializer of the SAME logical payload won't false-positive as a conflict; a genuine 409 names which top-level field(s) actually diverged. Has no effect on L402/x402 calls (those rails already single-use their own payment_hash) or on dry_run. confidentiality_tier: type: string enum: - hash_only - partial_disclosure - full_disclosure title: Confidentiality Tier description: 'Which privacy/evidentiary tradeoff this verdict should use, only meaningful with sign=true. ''hash_only'' (default, unchanged from all prior policy versions): the signed proof carries only artifact_hash — the raw artifact content is never disclosed anywhere. Strongest privacy, but the weakest evidentiary tier standalone — a third party with no independent access to your original content can only confirm ''this hash got this verdict,'' not what the hash actually corresponds to, unless you separately reveal the content to check it against. ''partial_disclosure'': pass disclosed_summary (a real, human-readable, redacted-as-needed description you choose to make public) — bound directly into decision_ref so it can''t be swapped after issuance, giving a third party real checkable context without full content exposure. ''full_disclosure'': records your intent to have this specific verdict published to the public /ledger track record (full_disclosure_requested=true in the proof) — the strongest evidentiary tier, independently verifiable with zero cooperation from us or you, but note this only records the request; actual /ledger publication is still a separate, curated step on our side as of this policy version, not yet fully self-serve.' default: hash_only disclosed_summary: anyOf: - type: string maxLength: 2000 - type: 'null' title: Disclosed Summary description: Only used when confidentiality_tier='partial_disclosure'. A real, human-readable description of the reviewed artifact/decision that you're choosing to make public — bound raw (not just hashed) into decision_ref, so a downstream verifier reads real context, not just a hash. Ignored for other confidentiality_tier values. artifact_source: anyOf: - additionalProperties: true type: object - type: 'null' title: Artifact Source description: "Optional: a coordinate naming real content to independently fetch and review, instead of trusting the `artifact` field's caller-supplied bytes. Real gap this closes (named by Dipankar Sarkar, 2026-08-12, trustless-ai working group): a hand-typed artifact and a hand-typed SUMMARY of one are indistinguishable to a reviewer that only ever sees pasted text — a summary has no coordinates that let anyone reproduce it. Two shapes, detected by which keys are present (not a separate discriminator field):\n 1. For artifact_type='code_diff'/'patch': {'repo': 'owner/name', 'base_sha': ..., 'head_sha': ...} — fetches `https://github.com/{repo}/compare/{base_sha}...{head_sha}.diff` ourselves (public repos only, no auth).\n 2. For artifact_type='onchain_action' (or any on-chain state read): {'chain_id': 8453 or 84532, 'block_number': , 'contract_address': '0x...', 'calldata': '0x...', 'block_hash': } — independently re-runs the exact `eth_call` at that pinned block via a public RPC and reviews the returned bytes. Deterministic and STRONGER than a git sha (Dipankar's own follow-up taxonomy, same day): anyone with an archive node re-runs the call pinned to that block and gets the identical bytes, because the execution itself is deterministic too, not just the storage. `block_hash`, if supplied, is cross-checked against the answering RPC's own block hash at that number and the call fails closed (422) on a mismatch — a block NUMBER alone isn't a stable identity until finalization, so this catches a reorg or a different chain view rather than silently reviewing the wrong fork (Dipankar's same-day follow-up, 2026-08-12). The returned artifact also records the resolved block_hash and which RPC endpoint answered, since public RPCs prune state — a re-fetch at this same block can start failing months later purely because it fell outside a node's retention window, which is not evidence the original claim was wrong; the result bytes captured at review time remain the source of truth either way.\n 3. For an on-chain EFFECT rather than a state read: {'chain_id': 8453 or 84532, 'tx_hash': '0x...'} — fetches the transaction receipt and DERIVES block_number, block_hash, contract_address, status and logs from it. Added 2026-08-24 to close a real seam shape 2 does not: shape 2's re-derivation is strong (EIP-1898 requireCanonical on eth_call, non-canonical fails closed, RPC set is ours not caller-nominated) but its COORDINATE is chosen by the party submitting the evidence, so an agent authorized to release escrow A can submit a truthful, canonically-pinned, independently re-derivable read of escrow B and every check passes. Under shape 3 the coordinate fields are OUTPUTS, never inputs; if you also send contract_address, block_number or block_hash they are treated as assertions, checked against the receipt, and a mismatch is a hard 422 rather than something reviewed. Canonicality is confirmed by re-fetching the block by hash and cross-checking its number and the transaction's inclusion in it. A REVERTED transaction (status 0x0) is returned with an explicit `reverted: true` and a note, not rejected — it is a real on-chain fact and often the disputed one. What shape 3 still does NOT establish, stated so it isn't read as more than it is: that this transaction is the one a given authorization or policy decision referred to. That binding belongs to the authorization layer's own preimage.\nIn all cases the `artifact` field, if also sent, is discarded, never merged with the fetched content. artifact_hash and every downstream hash bind to the independently-fetched bytes, not what you sent. FAILS CLOSED: if the fetch fails (private repo, bad sha, unsupported chain_id, RPC error) the call returns an error rather than silently falling back to caller-supplied text — a silent fallback would defeat the property this field exists to provide. The response's `artifact_provenance` field discloses which mode a given verdict actually used ('independently_fetched_github', 'independently_fetched_onchain', 'independently_fetched_onchain_effect', or 'caller_supplied') — informational only as of this policy version, not yet bound into decision_ref (a live, already-adopted signing contract — extending its preimage needs its own careful version bump, tracked separately, not done in this same change). A third tier — witnessed capture, for content that genuinely can't be re-derived later (e.g. a revised/backfilled order-book quote) — already exists as a SEPARATE endpoint, `/witness`, rather than a mode of `/review`: it anchors a third party's exact claim bytes as-is, unjudged, distinct from `/review`'s own independent judgment on a fetched-or-supplied artifact." action_binding: anyOf: - additionalProperties: true type: object - type: 'null' title: Action Binding description: 'Optional: the exact real-world action this verdict authorizes — tool identity, materialized (not templated) arguments, and the id of the agent that will execute it. This is the piece named but explicitly deferred in `artifact_source`''s own docstring above (''that binding belongs to the authorization layer''s own preimage'') — now built. Distinct from `artifact` (free text arguing FOR the action — recomputable via artifact_hash, but only as strong as whatever the caller chose to include) and from `state_hash` (a broader graph/agent-state commitment that is explicitly NOT bound into decision_ref — see its own docstring). Shape: {''tool'': ''place_order'', ''agent_id'': ''your-stable-agent-id'', ''args'': {...materialized parameters...}} — any JSON object under ~8KB is accepted; this shape is a convention, not an enforced schema, and every sub-key is optional (absent ones simply don''t produce their corresponding hash below). v14 (2026-08-31, delphisecurity/xaidr#1, anirudhraokotaru): `tool` and `args` are bound as SEPARATE preimage fields — action_binding_tool_hash = sha256(tool, raw UTF-8) and action_binding_args_hash = sha256(RFC-8785-JCS(args)) — rather than one opaque blob hash (v13''s shape), so a verifier can actually assert ''same tool, different arguments'' as a checkable statement instead of just seeing an opaque diff. `agent_id` is bound DIRECTLY as a plain string (action_binding_agent_id, not hashed — short ids gain nothing from hashing and lose direct readability) — same treatment as `intended_verifier`/`intended_audience` elsewhere on this endpoint. All three are bound into decision_ref (see decision_ref_preimage_fields in the response), so decision_ref commits to the exact action, not just the artifact text or the verdict conclusion — recomputing decision_ref without byte-identical tool/args/agent_id values produces a different hash. HONEST, NAMED LIMIT (not fixed by this field split, a real open question named by anirudhraokotaru): nothing stops a caller from submitting an UNDER-SPECIFIED action_binding (e.g. tool+side but not size) and getting an approval that''s replayable across whatever dimension was omitted — that''s a property of who controls what goes INTO the fingerprint, not how it''s hashed once it''s there. We hash exactly what you send and do not independently verify it matches what actually executes; a caller who wants that guarantee needs an in-process sensor emitting the fingerprint from the real call, not an external judgment layer like this one.' external_evidence: anyOf: - items: additionalProperties: true type: object type: array - type: 'null' title: External Evidence description: 'Optional: third-party evidence this judgment relied on (e.g. a tool-reliability registry''s own PASS/FAIL record) — the composition pattern worked out with arian-gogani/nobulex-registry#1 (2026-09-10): OUR judgment is point-in-time action soundness, a registry''s is historical/empirical tool truthfulness, and the two compose as an input rather than one replacing the other. Each entry: {''source'': str, ''record'': str (the evidence issuer''s OWN exact saved bytes, verbatim — NOT a JSON object we reserialize; UTF-8 text), ''record_sha256'': str (sha256 of `record` computed by the ISSUER over their own stored bytes, so a mismatch here means either you or they transcribed it wrong), ''evidence_type'': str, ''observed_at'': str (ISO 8601), ''validity_until'': str | None (ISO 8601, if the issuer defines a validity window)}. DELIBERATE DESIGN CHOICE, not an oversight: `record` is bound as opaque raw text, never re-parsed and re-emitted as JSON on our side — RFC-8785 JCS canonicalization (used for `action_binding.args` above) exists to let two parties who might each reconstruct the SAME logical object differently agree on one byte sequence; a third-party record has no such ambiguity; it''s already one fixed byte sequence the issuer produced, so re-encoding it would only risk silently diverging from what they actually stored. All entries are hashed together (sha256 over the JCS-canonicalized array) into `external_evidence_hash`, bound into decision_ref — so ''our verdict explicitly accounted for this exact evidence, as of this exact byte sequence'' is independently checkable, not just claimed in prose. We do NOT verify record_sha256 against `record`, authenticate the issuer, freshness, or whether the record is genuine — this field states what evidence the CALLER supplied and commits it into the hash; verifying it is real is the caller''s own responsibility before relying on our verdict, same honest-limit shape as action_binding above.' consistency_explanations: anyOf: - items: type: string type: array - type: 'null' title: Consistency Explanations description: 'Optional: N (>=2) paraphrased-framing responses YOU collected from the agent being reviewed — the same underlying decision explained N different ways (e.g. ask your agent ''why this action'' with differently-worded prompts, pass each answer here). We embed each and compute a cross-context consistency signal (services/consistency_check.py, built on the public SAC3 paraphrase-consistency lineage, arXiv 2311.01740) as an early detector for strategic or unstable reasoning — high pairwise divergence across framings of the SAME decision is a real tell independent of whether any single framing looks fine on its own. Returned in the response''s `consistency_check` field, purely additive: it never touches `verdict`/`confidence`/`reversibility_gate`, and the review runs normally if this is omitted. HONEST SCOPE: this call has no live handle back into your agent — it cannot generate the paraphrases itself, you must collect and pass them; a future callback/tool-use redesign that removes this friction is a separate, larger, not-yet-built product decision. The returned `flag` is explicitly UNCALIBRATED (no labeled data validates the threshold for this specific use case yet) — read it as directional, not a verdict.' type: object required: - artifact title: ReviewRequest ReasoningRequest: properties: question: type: string title: Question description: The question to reason about style: type: string enum: - short - concise - normal - detailed - comprehensive title: Style description: 'Response style: short (1 sentence), concise (2-3 sentences), normal, detailed, or comprehensive' default: normal want_confidence: type: boolean title: Want Confidence description: Whether to include confidence score and uncertainty flags default: false response_format: anyOf: - additionalProperties: true type: object - type: 'null' title: Response Format description: Optional JSON schema for structured output type: object required: - question title: ReasoningRequest