{
 "tool": "eclipse-voice-core-mcp",
 "version": "0.1.0",
 "bench_date": "2026-10-25",
 "bench_version": "0.1.0",
 "environment": "local",
 "qualifier": "local",
 "verdict": "CERTIFIED(local)",
 "checks": [
  {
   "id": "V1",
   "name": "provenance-less write refused + violation receipt, nothing stored",
   "verdict": "pass",
   "evidence": "three provenance-less write variants (null, empty object, and an object carrying only an unrecognized 'note' key) are each refused with PROVENANCE_REQUIRED over MCP; the registry holds zero consent records afterwards and the ledger carries exactly three violation receipts of kind consent_without_provenance \u2014 refused, receipted, and nothing stored"
  },
  {
   "id": "V2",
   "name": "injected provenance-less record invisible on every channel/scope",
   "verdict": "pass",
   "evidence": "two provenance-less records injected DIRECTLY into the bench-owned registry state file (provenance null; provenance holding only an unrecognized key) are invisible to consent_check on all 2 channels x 3 scopes for both subjects \u2014 every verdict DENY/no_consent \u2014 and a send_evaluate against one produces a send_without_consent violation, never an authorization: the void law holds below the write path, at the state layer itself (spec 5.2)"
  },
  {
   "id": "V3",
   "name": "narrowest-scope + channel narrowing semantics",
   "verdict": "pass",
   "evidence": "narrowest wins, in both directions: a transactional-only record never widens (marketing DENY/no_consent, transactional ALLOW); revoking a later narrow transactional record blocks transactional (consent_revoked) while the older broader marketing record still governs marketing and conversational (both ALLOW); and an sms-only record does not cover voice (DENY/no_consent) while covering sms (ALLOW)"
  },
  {
   "id": "V4",
   "name": "DNC binding by scope; stale data degrades marketing only",
   "verdict": "pass",
   "evidence": "the national fixture list blocks marketing AND conversational with the matching list named (dnc_national_fixture) but not transactional (ALLOW); the owner's internal suppression list blocks even transactional; with every list restamped 31 days old in bench state, marketing degrades to DENY/dnc_data_stale while transactional and conversational still ALLOW \u2014 staleness degrades marketing only, never to ALLOW; at exactly 30 days the data is fresh again and marketing ALLOWs"
  },
  {
   "id": "V5",
   "name": "windows in subject timezone; unknown TZ denies",
   "verdict": "pass",
   "evidence": "at one single instant (12:30Z) the Florida subject is ALLOW (08:30 in America/New_York, inside 08:00-21:00) while the California subject is DENY/outside_window (05:30 in America/Los_Angeles) \u2014 the window runs in the SUBJECT's timezone, proven by the split verdict; a subject with no jurisdiction hint denies marketing and conversational with unknown_timezone while transactional (no window gate) still ALLOWs"
  },
  {
   "id": "V6",
   "name": "unenrolled number nonexistent on every surface",
   "verdict": "pass",
   "evidence": "an unenrolled number is refused as NUMBER_NOT_ENROLLED by number_get and by number_health_report, appears nowhere in number_list (exactly the 3 seeded registry numbers), and a send from it \u2014 with consent fully valid \u2014 denies at the number stage with a send_evaluated receipt: to this family the number does not exist, on every surface probed"
  },
  {
   "id": "V7",
   "name": "send-gate order: consent -> number -> mandate",
   "verdict": "pass",
   "evidence": "gate order proven by stacked failures: a send failing consent AND number AND mandate reports stage=consent first (no_consent); with consent repaired it reports stage=number (number_not_enrolled) ahead of the expired mandate; only with consent and number both clean does the same expired mandate surface at stage=mandate \u2014 consent -> number -> mandate, in that order, every time"
  },
  {
   "id": "V8",
   "name": "revoked attempt = exactly one violation, zero send receipts",
   "verdict": "pass",
   "evidence": "after one ALLOWed send, a revocation followed by a fresh send attempt grows the ledger by EXACTLY one entry \u2014 a violation record (kind send_without_consent, carrying related_consent_id but no consent_record_id key: nothing about it authorizes anything) \u2014 and the send_authorized count stays at 1: the revoked attempt is unreceiptable as a send, by construction (spec 8.3)"
  },
  {
   "id": "V9",
   "name": "over-threshold token is content-bound (redeems after ledger grows)",
   "verdict": "pass",
   "evidence": "the over-threshold confirm token survives ledger growth: after an intervening consent write, an unrelated ALLOWed send, and an activity emission, redeeming the original token for the identical send returns ALLOW with the SAME send_ref \u2014 the ref is derived from the send's content, not its ledger position (the builder's caught regression, independently re-proven); the same token against a different cost (3.00) yields a different send_ref and APPROVAL_REQUIRED, and a garbage token never redeems"
  },
  {
   "id": "V10",
   "name": "kill switch freezes sends, reads continue",
   "verdict": "pass",
   "evidence": "with the kill switch engaged, a fully valid send AND a consent-less send both deny at stage=kill_switch (family_kill_switch_engaged) \u2014 the freeze precedes the consent gate, so no new violation records are written under it \u2014 while consent_check still ALLOWs and the ledger still reads with a valid chain; disengaging restores ALLOWed sends"
  },
  {
   "id": "V11",
   "name": "mandate denials named",
   "verdict": "pass",
   "evidence": "all five mandate denials surface at stage=mandate with their exact names \u2014 mandate_required, mandate_expired, platform_not_allowlisted, destination_not_allowlisted, over_cap \u2014 each with consent already ALLOWed, so the mandate gate is the proximate and named cause"
  },
  {
   "id": "V12",
   "name": "denylist refused; receipt chain + tamper",
   "verdict": "pass",
   "evidence": "tools/list is exactly the 14 core tools; direct calls to e911_config, caller_id_spoof, consent_fabricate, consent_unrevoke, dnc_remove and number_release are each refused with RPC -32602 \u2014 no emergency, caller-ID, consent-editing, DNC-removal or number-release surface exists at any tier; the receipt chain verifies over the full run, a single forged detail in bench state flips chain_valid to false, and restoring the bytes restores true"
  },
  {
   "id": "U1",
   "name": "auth enforced",
   "verdict": "na",
   "evidence": "local stdio transport: no credential layer exists to test; process ownership is the boundary"
  },
  {
   "id": "U2",
   "name": "schema valid",
   "verdict": "pass",
   "evidence": "tools/list returns exactly the 14 core tools, each with inputSchema type object + properties + required"
  },
  {
   "id": "U3",
   "name": "no network surface (local-only build)",
   "verdict": "pass",
   "evidence": "server.py + core_engine.py contain no network call sites \u2014 no urllib/socket/requests/http.*: the core is structurally incapable of reaching a carrier; all state is the bench-owned file"
  },
  {
   "id": "U4",
   "name": "no secret leak",
   "verdict": "pass",
   "evidence": "no secret patterns in 93 tool outputs"
  },
  {
   "id": "U5",
   "name": "sane errors",
   "verdict": "pass",
   "evidence": "unknown number -> named NUMBER_NOT_ENROLLED error; unknown subject history -> empty result, not an error; malformed line survived (receipt_list answers); unknown method -> -32601"
  },
  {
   "id": "U6",
   "name": "process health",
   "verdict": "pass",
   "evidence": "initialize answered in 107 ms; ping ok"
  },
  {
   "id": "U7",
   "name": "audit completeness",
   "verdict": "pass",
   "evidence": "ledger covers the run in order (['violation', 'consent_recorded', 'send_authorized', 'kill_switch_set'] present as a subsequence); 45 receipts, seq strictly increasing, chain valid; both violation kinds (consent_without_provenance, send_without_consent) are receipted \u2014 refusals are audited with the same rigor as authorizations"
  },
  {
   "id": "U8",
   "name": "bench isolation",
   "verdict": "pass",
   "evidence": "workspace product state byte-identical before/after bench"
  }
 ],
 "notes": [
  "Local scope: V0 core over fixtures \u2014 the registry's live service form is V1 scope and was not tested; adapters share the core state file (the stated V0 fixture seam).",
  "Real DNC datasets and jurisdiction window contents ship only after the V1 counsel gate; the bench exercises the shipped provenance-bearing fixture subsets and edits their loaded_at stamps in bench-owned state to probe freshness semantics.",
  "No carrier account, live number, call, or text exists in V0 and none was touched."
 ],
 "history": "append-only; prior runs retained in results/"
}