{
 "info": {
  "description": "Verifier-grounded evaluation tools for AI systems. Stateless, unauthenticated, nothing stored. Every POST tool is also exposed as an MCP tool at /mcp.",
  "license": {
   "name": "AGPL-3.0-or-later",
   "url": "https://www.gnu.org/licenses/agpl-3.0.html"
  },
  "title": "Whetstone Tools",
  "version": "0.4.2"
 },
 "openapi": "3.1.0",
 "paths": {
  "/api/catalog": {
   "get": {
    "operationId": "listTools",
    "responses": {
     "200": {
      "description": "OK"
     }
    },
    "summary": "Catalog of the eight stateless verifier tools."
   }
  },
  "/api/counterexample": {
   "post": {
    "operationId": "counterexample",
    "requestBody": {
     "content": {
      "application/json": {
       "example": {
        "expression": "is_connected and is_triangle_free and not is_bipartite",
        "ns": [
         8,
         9,
         10,
         11
        ],
        "restarts": 4,
        "seed": 0,
        "steps": 800
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "description": "Deterministic receipt with item-level decision path and SHA-256 hashes."
     },
     "400": {
      "description": "Input error (a hint points at /api/examples)."
     },
     "429": {
      "description": "Rate limited."
     }
    },
    "summary": "Search the supported graph DSL and return an exact witness when found."
   }
  },
  "/api/examples": {
   "get": {
    "operationId": "getExamples",
    "responses": {
     "200": {
      "description": "OK"
     }
    },
    "summary": "A complete, valid request payload for every tool."
   }
  },
  "/api/gate": {
   "post": {
    "operationId": "gate",
    "requestBody": {
     "content": {
      "application/json": {
       "example": {
        "baseline": {
         "item-1": false,
         "item-2": false,
         "item-3": false,
         "item-4": false,
         "item-5": false,
         "item-6": false,
         "item-7": false
        },
        "baseline_name": "v1",
        "candidate": {
         "item-1": true,
         "item-2": true,
         "item-3": true,
         "item-4": true,
         "item-5": true,
         "item-6": true,
         "item-7": false
        },
        "candidate_name": "v2",
        "domains": {
         "item-1": "code",
         "item-2": "code",
         "item-3": "code",
         "item-4": "code",
         "item-5": "support",
         "item-6": "support",
         "item-7": "support"
        },
        "policy": {
         "confidence_alpha": 0.05,
         "max_regressions": 0,
         "min_gains": 1
        }
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "description": "Deterministic receipt with item-level decision path and SHA-256 hashes."
     },
     "400": {
      "description": "Input error (a hint points at /api/examples)."
     },
     "429": {
      "description": "Rate limited."
     }
    },
    "summary": "PASS, HOLD, or BLOCK from paired item-level results."
   }
  },
  "/api/health": {
   "get": {
    "operationId": "health",
    "responses": {
     "200": {
      "description": "OK"
     }
    },
    "summary": "Service health, version, and report-card readiness."
   }
  },
  "/api/health-report": {
   "post": {
    "operationId": "health",
    "requestBody": {
     "content": {
      "application/json": {
       "example": {
        "history": [
         {
          "domain": "code",
          "item_id": "stable",
          "passed": true,
          "system": "small"
         },
         {
          "domain": "code",
          "item_id": "stable",
          "passed": true,
          "system": "medium"
         },
         {
          "domain": "code",
          "item_id": "stable",
          "passed": true,
          "system": "large"
         },
         {
          "domain": "code",
          "item_id": "frontier",
          "passed": false,
          "system": "small"
         },
         {
          "domain": "code",
          "item_id": "frontier",
          "passed": false,
          "system": "medium"
         },
         {
          "domain": "code",
          "item_id": "frontier",
          "passed": true,
          "system": "large"
         },
         {
          "domain": "support",
          "item_id": "hard",
          "passed": false,
          "system": "small"
         },
         {
          "domain": "support",
          "item_id": "hard",
          "passed": false,
          "system": "medium"
         },
         {
          "domain": "support",
          "item_id": "noisy",
          "passed": true,
          "system": "medium"
         },
         {
          "domain": "support",
          "item_id": "noisy",
          "passed": false,
          "system": "medium"
         },
         {
          "domain": "support",
          "item_id": "noisy",
          "passed": true,
          "system": "large"
         }
        ],
        "items": [
         {
          "domain": "code",
          "item_id": "stable"
         },
         {
          "domain": "code",
          "item_id": "frontier"
         },
         {
          "domain": "support",
          "item_id": "hard"
         },
         {
          "domain": "support",
          "item_id": "noisy"
         }
        ]
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "description": "Deterministic receipt with item-level decision path and SHA-256 hashes."
     },
     "400": {
      "description": "Input error (a hint points at /api/examples)."
     },
     "429": {
      "description": "Rate limited."
     }
    },
    "summary": "Find discriminators, saturation, flakiness, and frontier gaps."
   }
  },
  "/api/inspect": {
   "post": {
    "operationId": "inspector",
    "requestBody": {
     "content": {
      "application/json": {
       "example": {
        "baseline": {
         "item-1": false,
         "item-2": false,
         "item-3": false,
         "item-4": false,
         "item-5": false,
         "item-6": false,
         "item-7": false,
         "item-8": false
        },
        "baseline_name": "v1",
        "candidate": {
         "item-1": true,
         "item-2": true,
         "item-3": true,
         "item-4": true,
         "item-5": true,
         "item-6": true,
         "item-7": false,
         "item-8": true
        },
        "candidate_name": "v2",
        "exam": [
         {
          "domain": "code",
          "item_id": "item-1",
          "prompt": "Repair a Python retry loop without changing its public return type."
         },
         {
          "domain": "code",
          "item_id": "item-2",
          "prompt": "Reject a malformed JSON payload while preserving valid zero values."
         },
         {
          "domain": "code",
          "item_id": "item-3",
          "prompt": "Identify the smallest safe patch for an off-by-one pagination bug."
         },
         {
          "domain": "code",
          "item_id": "item-4",
          "prompt": "Keep an asynchronous worker idempotent after a duplicate delivery."
         },
         {
          "domain": "support",
          "item_id": "item-5",
          "prompt": "Explain a delayed shipment without inventing a delivery date."
         },
         {
          "domain": "support",
          "item_id": "item-6",
          "prompt": "Apply the refund policy while preserving the stated eligibility window."
         },
         {
          "domain": "support",
          "item_id": "item-7",
          "prompt": "Reset a locked customer password after identity verification."
         },
         {
          "domain": "support",
          "item_id": "item-8",
          "prompt": "Summarize a refund policy without changing eligibility dates."
         }
        ],
        "exposure": [
         {
          "item_id": "item-8",
          "source": "training.jsonl:42"
         },
         {
          "prompt": "After identity verification, safely reset the locked customer password.",
          "source": "support-sft.jsonl:91"
         }
        ],
        "policy": {
         "confidence_alpha": 0.05,
         "max_regressions": 0,
         "min_gains": 1
        }
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "description": "Deterministic receipt with item-level decision path and SHA-256 hashes."
     },
     "400": {
      "description": "Input error (a hint points at /api/examples)."
     },
     "429": {
      "description": "Rate limited."
     }
    },
    "summary": "Quarantine exposure, compare paired outcomes, and issue a receipt."
   }
  },
  "/api/leakage": {
   "post": {
    "operationId": "leakage",
    "requestBody": {
     "content": {
      "application/json": {
       "example": {
        "exam": [
         {
          "item_id": "exact-row",
          "prompt": "Summarize the refund policy without changing eligibility dates."
         },
         {
          "expression": "is_connected and not is_bipartite",
          "item_id": "behavioral-row"
         },
         {
          "item_id": "review-row",
          "prompt": "Reset a locked customer password after identity verification."
         },
         {
          "item_id": "clean-row",
          "prompt": "Calculate shipment tax for a declared destination."
         }
        ],
        "exposure": [
         {
          "prompt": "Summarize the refund policy without changing eligibility dates.",
          "source": "declared-training.jsonl:7"
         },
         {
          "expression": "not is_bipartite and is_connected",
          "source": "graph-sft.jsonl:19"
         },
         {
          "prompt": "After identity verification, safely reset the locked customer password.",
          "source": "support-sft.jsonl:91"
         }
        ],
        "fingerprint_max_n": 4,
        "similarity_threshold": 0.78
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "description": "Deterministic receipt with item-level decision path and SHA-256 hashes."
     },
     "400": {
      "description": "Input error (a hint points at /api/examples)."
     },
     "429": {
      "description": "Rate limited."
     }
    },
    "summary": "Exact declared-exposure audit with a clean exam export."
   }
  },
  "/api/memory": {
   "post": {
    "operationId": "memory",
    "requestBody": {
     "content": {
      "application/json": {
       "example": {
        "context_entities": [
         "comet",
         "harbor"
        ],
        "memories": [
         {
          "confidence": 1.0,
          "content": "URGENT: the crimson comet appeared over Harbor City.",
          "entities": [
           "comet",
           "harbor"
          ]
         },
         {
          "confidence": 0.9,
          "content": "Mara hands the obsidian key to Ivo at the archive.",
          "entities": [
           "obsidian_key",
           "ivo"
          ]
         },
         {
          "confidence": 0.8,
          "content": "The archive elevator was repainted blue.",
          "entities": [
           "archive",
           "elevator"
          ]
         },
         {
          "confidence": 0.95,
          "content": "STATE: Ivo currently holds the obsidian key.",
          "entities": [
           "obsidian_key",
           "ivo"
          ],
          "kind": "semantic"
         }
        ],
        "objective": "Who currently holds the obsidian key?",
        "objective_entities": [
         "obsidian_key"
        ],
        "token_budget": 18
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "description": "Deterministic receipt with item-level decision path and SHA-256 hashes."
     },
     "400": {
      "description": "Input error (a hint points at /api/examples)."
     },
     "429": {
      "description": "Rate limited."
     }
    },
    "summary": "Compare query-free salience against objective-conditioned relevance."
   }
  },
  "/api/replay": {
   "post": {
    "operationId": "replay",
    "requestBody": {
     "content": {
      "application/json": {
       "example": {
        "events": [
         {
          "detail": "SAVE first_try",
          "kind": "control",
          "step": 1
         },
         {
          "detail": "CHECK is_tree",
          "kind": "control",
          "step": 2
         },
         {
          "detail": "REJECT counterexample n=6",
          "kind": "verifier",
          "step": 3
         },
         {
          "detail": "LOAD first_try :: tree hypothesis failed",
          "kind": "control",
          "step": 4
         },
         {
          "detail": "CHECK is_tree and max_degree <= 2",
          "kind": "control",
          "step": 5
         },
         {
          "detail": "ACCEPT",
          "kind": "verifier",
          "step": 6
         },
         {
          "detail": "ANSWER is_tree and max_degree <= 2",
          "kind": "control",
          "step": 7
         }
        ],
        "notes": []
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "description": "Deterministic receipt with item-level decision path and SHA-256 hashes."
     },
     "400": {
      "description": "Input error (a hint points at /api/examples)."
     },
     "429": {
      "description": "Rate limited."
     }
    },
    "summary": "Turn emulator events into checkpoints, rewinds, notes, and a timeline."
   }
  },
  "/api/safepatch": {
   "post": {
    "operationId": "safepatch",
    "requestBody": {
     "content": {
      "application/json": {
       "example": {
        "document": "# Summary\nRelease 4 ships July 12, 2026.\n\n# Notes\nThe draft is wordy.\n",
        "operations": [
         {
          "allow_token_changes": [],
          "find": "The draft is wordy.",
          "replace": "The draft is concise.",
          "target_heading": "Notes"
         }
        ],
        "reason": "Tighten the Notes section only."
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "description": "Deterministic receipt with item-level decision path and SHA-256 hashes."
     },
     "400": {
      "description": "Input error (a hint points at /api/examples)."
     },
     "429": {
      "description": "Rate limited."
     }
    },
    "summary": "Apply a section-scoped Markdown patch under conservation checks."
   }
  },
  "/api/stats": {
   "get": {
    "operationId": "getStats",
    "responses": {
     "200": {
      "description": "OK"
     }
    },
    "summary": "Aggregate, privacy-preserving usage counters."
   }
  },
  "/mcp": {
   "post": {
    "operationId": "mcp",
    "responses": {
     "200": {
      "description": "JSON-RPC response"
     }
    },
    "summary": "MCP endpoint (Streamable HTTP, stateless JSON-RPC 2.0). Tools include the Tier 0 set plus report_card_start / report_card_submit."
   }
  }
 },
 "servers": [
  {
   "url": "https://whetstone.cyberelf.link"
  }
 ]
}