Capability manifest
1. What Submind is
Submind is a forecasting + claim-verification engine. Given a question or claim it decomposes the problem, gathers and weighs independent evidence, and emits a calibrated probability with a tamper-evident receipt. Every verdict gets a verdict_id = sha256(RFC-8785-canonicalized payload) and a public audit-trail page at /p/<slug>. The receipt is the product: an agent can recompute the hash locally to confirm the verdict it was handed has not been altered. Submind refuses (returns no number) rather than guess when evidence is too thin — refusals are first-class and enumerated below.
2. API endpoint
POST https://submind.us/api/predict. None required to read or to mint. Optional Authorization: Bearer <api_key> or X-API-Key raises the rate-limit tier. Send Accept: text/event-stream for SSE stage events; default is a single JSON response.
{
"request_bodies": {
"forecast": {
"question": "string (3-1000 chars, required)",
"force": "boolean (optional — bypass dedup)"
},
"verify": {
"claim": "string (3-1000 chars, required)",
"pipeline_mode": "string (optional — 'live' opts into the LLM cascade)"
}
},
"response_top_level": [
"id",
"question",
"probability",
"confidence_lower",
"confidence_upper",
"domain",
"sub_claims",
"metadata",
"convergence",
"verdict_id",
"refusal_reason",
"created_at"
],
"rate_limits": {
"anonymous": {
"burst": "10 req / 60s per IP",
"quota": "5 / hour, 20 / day"
},
"api_key_free": {
"burst": "30 req / 60s",
"quota": "30 / hour, 200 / day"
},
"api_key_pro": {
"burst": "100 req / 60s",
"quota": "30 / hour, 200 / day (shared authed quota — a pro key raises the burst ceiling only, not the hour/day cap)"
},
"headers": [
"X-RateLimit-Limit",
"X-RateLimit-Remaining",
"X-RateLimit-Reset",
"Retry-After (on 429)"
],
"on_limit": "HTTP 429 { error, code: \"RATE_LIMITED\" | \"QUOTA_EXCEEDED\", retryAfter }"
}
}curl -X POST https://submind.us/api/predict \
-H "Content-Type: application/json" \
-d '{"question":"Will OpenAI release GPT-5 before 2027-01-01?"}'3. MCP tool — mint_claim
Mint a receipt from an agent via the stdio MCP server. The npm package submind-mcp-server exposes verify-only tools; use the stdio server to mint.
{
"stdio_server": {
"install": "claude mcp add submind 'node /absolute/path/to/mcp_server/index.js'",
"protocol": "JSON-RPC 2.0 over stdio (MCP 2024-11-05)",
"tools": [
"verify_receipt",
"mint_claim",
"list_receipts",
"get_stats",
"list_agents"
],
"mint_claim_input": {
"claim": "string (3-1000, required)",
"agent_id": "string (optional)",
"agent_metadata": "object (optional — model/session provenance)"
},
"mint_claim_returns": [
"verdict_id",
"receipt_url",
"receipt_hash",
"pipeline_mode",
"agent_id",
"server_response_summary"
]
},
"npm_package": {
"name": "submind-mcp-server",
"status": "not yet published to npm — publish pending (registry 404 today)",
"install": "Publish pending; until it lands on npm, use the stdio server above.",
"tools": [
"verify_claim",
"verify_receipt"
],
"stub_tools": [
"contest_verdict (R4 — returns not_yet_implemented)"
],
"note": "Does NOT expose mint_claim — use the stdio server to mint."
}
}4. Refusal taxonomy
When evidence is too thin or the question is out of scope, Submind sets refusal_reason rather than guess. 11 are 0.5 stubs (empty sub_claims); low_corroboration is the lone quality flag where a real probability still ships.
| refusal_reason | stub? | meaning | agent action |
|---|---|---|---|
| insufficient_evidence | yes (0.5) | Evidence search returned no effective sources. No number rather than a dressed-up coin flip. | Treat as "unknown". Re-ask later or supply sources; never read the ~0.5 as a forecast. |
| synthesize_failed | yes (0.5) | The synthesis step threw; refuses rather than ship a fabricated verdict (evidence may have been plentiful). | Transient/internal. Retry the mint. |
| judge_admitted_low_signal | yes (0.5) | The engine's own judge flagged the retrieved evidence as unrelated/insufficient. | Treat as "unknown". Reasoning + sources are still shown for inspection. |
| quantitative_no_threshold_anchor | yes (0.5) | Asks for a number, not yes/no (or binarized to a vacuous threshold). Submind emits binary forecasts. | Rephrase as a thresholded binary, e.g. "Will it open above $100M?". |
| cascade_exhausted_at_synth | yes (0.5) | All LLM providers were rate-limited/unavailable at synthesis. Persisted so a poll recovers a row, not a 404. | Transient. Retry in ~60s (provider limits reset). |
| decompose_cascade_exhausted | yes (0.5) | Providers exhausted at the DECOMPOSE stage; declined rather than fabricate a placeholder decomposition. | Transient. Retry in ~60s. |
| deadline_passed | yes (0.5) | The event deadline is already in the past — nothing left to forecast. | Resolve against the actual outcome instead of forecasting. |
| fabricated_entity | yes (0.5) | A question entity could not be verified to exist (no matching Wikipedia entry). | If the entity is real but obscure, rephrase with its full/common name. |
| non_binary_question | yes (0.5) | Asks for a name/title/value, not a yes/no — a percentage would be meaningless. | Rephrase as a yes/no question. |
| compound_question | yes (0.5) | Bundles several independent yes/no claims; their conjoint probability is not one number. | Ask each part as its own question. |
| duplicate_of_pending | yes (0.5) | A near-identical open prediction (same subject/deadline/threshold) already exists; see response_payload.duplicate_of_id. | Follow the original for the live verdict instead of re-minting. |
| low_corroboration | no | NOT a stub: a real probability shipped, but cross-source entity-pair corroboration was weak. | Use the probability, but weight it as weakly corroborated. |
5. Receipt format spec
{
"verdict_id": "sha256:<64-hex> = \"sha256:\" + SHA-256(RFC-8785-canonicalize(receipt.payload))",
"canonicalization": "RFC 8785 JSON Canonicalization Scheme (npm canonicalize), UTF-8",
"hashed_payload_keys": [
"formula_version",
"code_version",
"flags",
"inputs",
"outputs",
"adversarial_forum",
"novel_sources",
"novel_source_review_flag"
],
"receipt_url": "https://submind.us/p/<slug> (slug = encodeURIComponent(question) with spaces as \"+\")",
"permalink": "https://submind.us/receipt/<verdict_id> (308-redirects to the canonical /p/<slug>)",
"short_permalink": "https://submind.us/r/<verdict_id> (308-redirects to the canonical /p/<slug>, same destination as /receipt/<verdict_id>)",
"verify_locally": "Recompute sha256(canonicalize(receipt.payload)) and compare to verdict_id. Sibling fields are excluded from the hash by design."
}| sibling field (NOT hashed) | what it carries |
|---|---|
| plain_summary | Read-time narrative prose. |
| narrative_meta | Narrative synthesis provenance (source, provider, tokens). |
| counter_pass | Adversarial cross-model counter-investigation outcome. |
| evidence_filtering_meta | Per-provider relevance-floor telemetry. |
| refusal_prior_correction | Bayesian refusal-prior adjustment metadata. |
| refusal_methodology | How a refusal was reached (render-only). |
Sibling fields live on response_payload and are excluded from the hash — changing them never changes the verdict_id. Hashed keys: formula_version, code_version, flags, inputs, outputs, adversarial_forum, novel_sources, novel_source_review_flag.
6. Example queries
[
{
"question": "Will OpenAI release GPT-5 publicly before 2027-01-01?",
"expect": "probability in [0,1], sub_claims[] with evidence_for/against, verdict_id, /p/<slug>"
},
{
"question": "Will the US Federal Reserve cut rates at its next meeting?",
"expect": "probability + confidence_lower/upper + convergence"
},
{
"question": "Will SpaceX launch Starship to orbit before 2026-12-31?",
"expect": "probability; or refusal_reason if evidence is too thin"
}
]7. Capability declaration
{
"name": "submind",
"description": "Forecasting + claim-verification engine with tamper-evident receipts.",
"endpoint": "https://submind.us/api/predict",
"methods": [
"POST",
"GET",
"PUT"
],
"auth": "optional-api-key",
"request": {
"question": "string?",
"claim": "string?",
"force": "boolean?",
"pipeline_mode": "string?"
},
"response": [
"id",
"question",
"probability",
"confidence_lower",
"confidence_upper",
"domain",
"sub_claims",
"metadata",
"convergence",
"verdict_id",
"refusal_reason",
"created_at"
],
"refusal_reasons": [
"insufficient_evidence",
"synthesize_failed",
"judge_admitted_low_signal",
"quantitative_no_threshold_anchor",
"cascade_exhausted_at_synth",
"decompose_cascade_exhausted",
"deadline_passed",
"fabricated_entity",
"non_binary_question",
"compound_question",
"duplicate_of_pending",
"low_corroboration"
],
"receipt": {
"verdict_id": "sha256:<hex>",
"url": "/p/<slug>",
"permalink": "/receipt/<verdict_id>",
"short_permalink": "/r/<verdict_id>"
},
"hashed_payload_keys": [
"formula_version",
"code_version",
"flags",
"inputs",
"outputs",
"adversarial_forum",
"novel_sources",
"novel_source_review_flag"
],
"sibling_fields": [
"plain_summary",
"narrative_meta",
"counter_pass",
"evidence_filtering_meta",
"refusal_prior_correction",
"refusal_methodology"
],
"mcp": {
"tool": "mint_claim",
"transport": "stdio",
"install": "claude mcp add submind 'node /absolute/path/to/mcp_server/index.js'"
}
}