SaneCheck

Last 15 runs. 7 silent failures caught, 1 routed to review.

Needs review (1)

#time (UTC)sourcestatusfailed checkspayload
162026-09-09T05:18:35Ztender-scraperfailvolume_drop: Only 0 item(s) this run; typical is 42 (median of the last 3 runs).
show raw JSON
{
  "items": [],
  "page": 1
}
142026-09-09T05:16:58Ztender-scraperpass—
show raw JSON
{
  "items": [
    {
      "id": 0,
      "title": "tender 0"
    },
    {
      "id": 1,
      "title": "tender 1"
    },
    {
      "id": 2,
      "title": "tender 2"
    },
    {
      "id": 3,
      "title": "tender 3"
    },
    {
      "id": 4,
      "title": "tender 4"
    },
    {
      "id": 5,
      "title": "tender 5"
    },
    {
      "id": 6,
      "title": "tender 6"
    },
    {
      "id": 7,
      "title": "tender 7"
    },
    {
      "id": 8,
      "title": "tender 8"
    },
    {
      "id": 9,
      "title": "tender 9"
    },
    {
      "id": 10,
      "title": "tender 10"
    },
    {
      "id": 11,
      "title": "tender 11"
    },
    {
      "id": 12,
      "title": "tender 12"
    },
    {
      "id": 13,
      "title": "tender 13"
    },
    {
      "id": 14,
      "title": "tender 14"
    },
    {
      "id": 15,
      "title": "tender 15"
    },
    {
      "id": 16,
      "title": "tender 16"
    },
    {
      "id": 17,
      "title": "tender 17"
    },
    {
      "id": 18,
      "title": "tender 18"
    },
    {
      "id": 19,
      "title": "tender 19"
    },
    {
      "id": 20,
      "title": "tender 20"
    },
    {
      "id": 21,
      "title": "tender 21"
    },
    {
      "id": 22,
      "title": "tender 22"
    },
    {
      "id": 23,
      "title": "tender 23"
    },
    {
      "id": 24,
      "title": "tender 24"
    },
    {
      "id": 25,
      "title": "tender 25"
    },
    {
      "id": 26,
      "title": "tender 26"
    },
    {
      "id": 27,
      "title": "tender 27"
    },
    {
      "id": 28,
      "title": "tender 28"
    },
    {
      "id": 29,
      "title": "tender 29"
    },
    {
      "id": 30,
      "title": "tender 30"
    },
    {
      "id": 31,
      "title": "tender 31"
    },
    {
      "id": 32,
      "title": "tender 32"
    },
    {
      "id": 33,
      "title": "tender 33"
    },
    {
      "id": 34,
      "title": "tender 34"
    },
    {
      "id": 35,
      "title": "tender 35"
    },
    {
      "id": 36,
      "title": "tender 36"
    },
    {
      "id": 37,
      "title": "tender 37"
    },
    {
      "id": 38,
      "title": "tender 38"
    },
    {
      "id": 39,
      "title": "tender 39"
    },
    {
      "id": 40,
      "title": "tender 40"
    },
    {
      "id": 41,
      "title": "tender 41"
    },
    {
      "id": 42,
      "title": "tender 42"
    },
    {
      "id": 43,
      "title": "tender 43"
    }
  ],
  "page": 1
}
132026-09-09T05:16:58Ztender-scraperpass—
show raw JSON
{
  "items": [
    {
      "id": 0,
      "title": "tender 0"
    },
    {
      "id": 1,
      "title": "tender 1"
    },
    {
      "id": 2,
      "title": "tender 2"
    },
    {
      "id": 3,
      "title": "tender 3"
    },
    {
      "id": 4,
      "title": "tender 4"
    },
    {
      "id": 5,
      "title": "tender 5"
    },
    {
      "id": 6,
      "title": "tender 6"
    },
    {
      "id": 7,
      "title": "tender 7"
    },
    {
      "id": 8,
      "title": "tender 8"
    },
    {
      "id": 9,
      "title": "tender 9"
    },
    {
      "id": 10,
      "title": "tender 10"
    },
    {
      "id": 11,
      "title": "tender 11"
    },
    {
      "id": 12,
      "title": "tender 12"
    },
    {
      "id": 13,
      "title": "tender 13"
    },
    {
      "id": 14,
      "title": "tender 14"
    },
    {
      "id": 15,
      "title": "tender 15"
    },
    {
      "id": 16,
      "title": "tender 16"
    },
    {
      "id": 17,
      "title": "tender 17"
    },
    {
      "id": 18,
      "title": "tender 18"
    },
    {
      "id": 19,
      "title": "tender 19"
    },
    {
      "id": 20,
      "title": "tender 20"
    },
    {
      "id": 21,
      "title": "tender 21"
    },
    {
      "id": 22,
      "title": "tender 22"
    },
    {
      "id": 23,
      "title": "tender 23"
    },
    {
      "id": 24,
      "title": "tender 24"
    },
    {
      "id": 25,
      "title": "tender 25"
    },
    {
      "id": 26,
      "title": "tender 26"
    },
    {
      "id": 27,
      "title": "tender 27"
    },
    {
      "id": 28,
      "title": "tender 28"
    },
    {
      "id": 29,
      "title": "tender 29"
    },
    {
      "id": 30,
      "title": "tender 30"
    },
    {
      "id": 31,
      "title": "tender 31"
    },
    {
      "id": 32,
      "title": "tender 32"
    },
    {
      "id": 33,
      "title": "tender 33"
    },
    {
      "id": 34,
      "title": "tender 34"
    },
    {
      "id": 35,
      "title": "tender 35"
    },
    {
      "id": 36,
      "title": "tender 36"
    },
    {
      "id": 37,
      "title": "tender 37"
    },
    {
      "id": 38,
      "title": "tender 38"
    }
  ],
  "page": 1
}
122026-09-09T05:16:58Ztender-scraperpass—
show raw JSON
{
  "items": [
    {
      "id": 0,
      "title": "tender 0"
    },
    {
      "id": 1,
      "title": "tender 1"
    },
    {
      "id": 2,
      "title": "tender 2"
    },
    {
      "id": 3,
      "title": "tender 3"
    },
    {
      "id": 4,
      "title": "tender 4"
    },
    {
      "id": 5,
      "title": "tender 5"
    },
    {
      "id": 6,
      "title": "tender 6"
    },
    {
      "id": 7,
      "title": "tender 7"
    },
    {
      "id": 8,
      "title": "tender 8"
    },
    {
      "id": 9,
      "title": "tender 9"
    },
    {
      "id": 10,
      "title": "tender 10"
    },
    {
      "id": 11,
      "title": "tender 11"
    },
    {
      "id": 12,
      "title": "tender 12"
    },
    {
      "id": 13,
      "title": "tender 13"
    },
    {
      "id": 14,
      "title": "tender 14"
    },
    {
      "id": 15,
      "title": "tender 15"
    },
    {
      "id": 16,
      "title": "tender 16"
    },
    {
      "id": 17,
      "title": "tender 17"
    },
    {
      "id": 18,
      "title": "tender 18"
    },
    {
      "id": 19,
      "title": "tender 19"
    },
    {
      "id": 20,
      "title": "tender 20"
    },
    {
      "id": 21,
      "title": "tender 21"
    },
    {
      "id": 22,
      "title": "tender 22"
    },
    {
      "id": 23,
      "title": "tender 23"
    },
    {
      "id": 24,
      "title": "tender 24"
    },
    {
      "id": 25,
      "title": "tender 25"
    },
    {
      "id": 26,
      "title": "tender 26"
    },
    {
      "id": 27,
      "title": "tender 27"
    },
    {
      "id": 28,
      "title": "tender 28"
    },
    {
      "id": 29,
      "title": "tender 29"
    },
    {
      "id": 30,
      "title": "tender 30"
    },
    {
      "id": 31,
      "title": "tender 31"
    },
    {
      "id": 32,
      "title": "tender 32"
    },
    {
      "id": 33,
      "title": "tender 33"
    },
    {
      "id": 34,
      "title": "tender 34"
    },
    {
      "id": 35,
      "title": "tender 35"
    },
    {
      "id": 36,
      "title": "tender 36"
    },
    {
      "id": 37,
      "title": "tender 37"
    },
    {
      "id": 38,
      "title": "tender 38"
    },
    {
      "id": 39,
      "title": "tender 39"
    },
    {
      "id": 40,
      "title": "tender 40"
    },
    {
      "id": 41,
      "title": "tender 41"
    }
  ],
  "page": 1
}
112026-09-07T20:06:51Zstrict-demofailempty_output: Output is empty / whitespace only.
show raw JSON
""
102026-09-07T20:06:51Zresearch-agentpass—
show raw JSON
"Acme Corp Q3 2026 filing found: revenue up 12% year over year, two sources attached."
92026-09-07T20:06:51Zresearch-agentfailpossible_loop: Semantic thrash: web_search called 3x with near-identical arguments after an empty result (similarity 1.00 >= 0.85) (possible loop).
show raw JSON
"Could not find the Acme Corp Q3 2026 filing yet, retrying with a different phrasing."
82026-09-07T20:06:51Zresearch-agentfailpossible_loop: Tool call repeated 4x with identical arguments: web_search({"q": "Acme Corp Q3 2026 filing"}) (possible loop).
show raw JSON
"Searching for Acme Corp Q3 2026 filings. Searching for Acme Corp Q3 2026 filings. Searching for Acme Corp Q3 2026 filings. Searching for Acme Corp Q3 2026 filings."
72026-09-07T20:06:51Zapi-normalizerfailschema_drift: Output shape changed vs. baseline: type changed: tags (string -> array)
show raw JSON
{
  "title": "Widget",
  "tags": [
    "blue",
    "small"
  ],
  "meta": {
    "id": 41
  }
}
62026-09-07T20:06:51Zapi-normalizerpass—
show raw JSON
{
  "title": "Widget",
  "tags": "blue,small",
  "meta": {
    "id": 41
  }
}
52026-09-07T20:06:51Zweekly-researchreview—
show raw JSON
{
  "summary": "Acme Corp Q3 2026: preliminary figures suggest revenue up about 10%.",
  "sources": [
    {
      "url": "https://example.com/acme-prelim"
    }
  ],
  "confidence": "medium"
}
42026-09-07T20:06:51Zweekly-researchfailcontract_violation: output does not mention required input: 'Acme Corp'; output does not mention required input: 'Q3 2026'
show raw JSON
{
  "summary": "Global SaaS market grew 9% last quarter according to analysts.",
  "sources": [
    {
      "url": "https://example.com/saas-market"
    },
    {
      "url": "https://example.com/x"
    }
  ],
  "confidence": "medium"
}
32026-09-07T20:06:51Zweekly-researchpass—
show raw JSON
{
  "summary": "Acme Corp Q3 2026: revenue up 12% year over year, driven by enterprise renewals.",
  "sources": [
    {
      "url": "https://example.com/acme-q3"
    },
    {
      "url": "https://example.com/acme-ir"
    }
  ],
  "confidence": "high"
}
22026-09-07T20:06:51Zdemofailschema_drift: Output shape changed vs. baseline: type changed: age (number -> string)
show raw JSON
{
  "name": "Ada",
  "email": "ada@example.com",
  "age": "2026-09-05"
}
12026-09-07T20:06:51Zdemopass—
show raw JSON
{
  "name": "Ada",
  "email": "ada@example.com",
  "age": 36
}

Schema drift: the first run per source sets the baseline shape (keys + types). To re-learn after an intentional change: POST /schema/reset?source=NAME with your X-API-Key. Per-run detail: GET /run/{id}. Review: a passing run can be routed to a human via contract.review (if_missing / if_contains / sample_rate) or payload review:true; reject with add_rule to harden the contract. Dead-letter: the response is synchronous, branch on status; or send strict:true (env SANECHECK_STRICT=1) and a failed run answers HTTP 422 so your node's error output fires. Loops: meta.tool_calls repeated with identical arguments, near-identical arguments (canonicalized + Jaccard >= 0.85 vs the last 3 calls), or the same line repeating in the output, flag possible_loop. Contracts (job drift): send a 'contract' object with required fields / must_contain, or store one via POST /contract?source=NAME.

SaneCheck v0.8.0