{
 "tool": "eclipse-ledger-mcp",
 "version": "0.1.0",
 "bench_date": "2026-10-25",
 "bench_version": "0.1.0",
 "environment": "local",
 "qualifier": "local",
 "verdict": "CERTIFIED(local)",
 "checks": [
  {
   "id": "H1",
   "name": "limit asymmetry: decrease instant; every increase route (early confirm, lapse-then-confirm, re-request) never effective early; stricter state delay governs",
   "verdict": "pass",
   "evidence": "wager/daily 100 set instantly, cut to 50 in the same call; raise to 200 returns PENDING_INCREASE (72h) with the effective amount still 50; limit_confirm at +1h is refused LIMIT_INCREASE_PENDING and the active limit is still 50; stake_cap raise left unconfirmed past its confirm_by is refused LIMIT_INCREASE_LAPSED with the cap still 25; confirm at +73h (inside the window) is the only route that made 200 effective; an MA profile's deposit raise waits 2160h (the state's 90d fixture beats the 72h suite floor \u2014 the maximum governs)"
  },
  {
   "id": "H2",
   "name": "credential-shaped input refused by name at any depth on EVERY tool; values never stored",
   "verdict": "pass",
   "evidence": "all 22 tools refuse a credential-shaped probe (top-level session_token + nested api_key) with CREDENTIALS_NOT_ACCEPTED; a password nested three levels deep is refused identically on spot-checked tools; neither probe value appears anywhere in the persisted state file"
  },
  {
   "id": "H3",
   "name": "exclusion record boundary probes (pending vs settled vs exclusion-era)",
   "verdict": "pass",
   "evidence": "exclusion started mid-session (state-program, 365d); during it: a bet PLACED pre-exclusion but still UNSETTLED is refused EXCLUDED (with help resources in the refusal), a bet placed pre-exclusion and SETTLED is recorded as history (the only record written), and a bet placed DURING the exclusion is refused even though settled; exactly 2 record_add_denied receipts and 1 stored record"
  },
  {
   "id": "A1",
   "name": "ADJUDICATION: settled-backfill boundary vs spec 3.3 intent",
   "verdict": "pass",
   "evidence": "ADJUDICATION \u2014 the boundary as built MATCHES spec 3.3's intent. 3.3 denies 'every function that could lead to a wager' and preserves 'historical records (read-only)' plus 'reality snapshots of past activity'. Bench evidence: (i) a SETTLED bet placed before the exclusion records during it \u2014 a closed outcome is pure history, and P&L truth (the mirror 3.3 explicitly preserves) is corrupted if final outcomes cannot be entered; its settlement may have occurred during the exclusion without any act by the user \u2014 time passing is not wagering, and the record shape carries no settled_ts, so 'settled before' and 'settled during' are rightly the same case: placement before + finality at recording is the line the code can see, and it is the right line. (ii) an UNSETTLED pre-exclusion bet is denied \u2014 a pending record is an open wagering position, not yet history; entering it sustains engagement with live action, so the denial errs in the protective direction 3.3 demands, and the refusal text states the rule accurately ('already settled may still be backfilled as history'). (iii) a bet placed DURING the exclusion is denied even settled \u2014 the wager itself postdates the exclusion. No leak found: nothing recordable during exclusion can create, price, or advance a wager."
  },
  {
   "id": "H4",
   "name": "exclusion absoluteness on every surface + end refused before expiry + reactivation gates",
   "verdict": "pass",
   "evidence": "with the exclusion active: odds_compare, arb_observe and slip_prepare all deny EXCLUDED (odds refusal carries the help line); records_list, reality_snapshot (excluded=true, resources attached) and pnl_summary still answer; limits remain manageable (weekly wager limit set instantly); exclusion_end at day 20 is refused EXCLUSION_IRREVOCABLE_UNTIL_EXPIRY and the refusal is receipted; past legal expiry, ending without the reactivation attestations is refused REACTIVATION_INCOMPLETE, and with both it expires cleanly; a bench timeout on separate state denies odds with TIMEOUT_ACTIVE"
  },
  {
   "id": "H5",
   "name": "jurisdiction: variant classes differ, tribal-only denies, stale matrix degrades to UNKNOWN=deny",
   "verdict": "pass",
   "evidence": "same state, same pick'em family, different legal objects: NY pickem-ath (against-the-house) verdict NOT_LEGAL while NY pickem-p2p verdict ALLOWED; FL sportsbook row LEGAL_TRIBAL_ONLY maps to NOT_LEGAL for a consumer sportsbook surface; TX sportsbook NOT_LEGAL; every verdict receipted (receipt_seq on the ALLOWED NJ verdict); at +31d the matrix (TTL 30d) is stale: verdict UNKNOWN with stale_matrix=true and odds_compare is refused JURISDICTION_UNKNOWN, while records remain readable"
  },
  {
   "id": "H6",
   "name": "odds: price-only ordering (incl. bench-shuffled books), promos stripped, stale prices labeled",
   "verdict": "pass",
   "evidence": "every outcome's rows are ordered by implied probability ascending (best price first), with each row's implied probability matching an independent recomputation from its American price; a second call is byte-identical; in a bench-shuffled copy of the product (bookmaker order randomized, seed 20261025) the ordering and the best-price book per outcome still follow price alone; the fixture's operator promotion is stripped (promotions_stripped >= 1, promo text absent); at +1h every row is labeled stale with stale_age_seconds >= 900; arb_observe carries execution_support=null and the mandatory books-limit-winners honesty"
  },
  {
   "id": "H7",
   "name": "resource block: summaries, denials, pattern-flag trigger all carry it",
   "verdict": "pass",
   "evidence": "deposit-velocity pattern flag fires from bench deposits (100 in 7d vs 40 in the prior 7d) and the snapshot carrying it attaches the resource block; pnl_summary always carries the block (a 1-800 entry plus the reverify_due marker \u2014 build-verified help-line data per spec 1.4/3.5); resources_get answers directly; exclusion denials carrying the block are proven in H3/H4"
  },
  {
   "id": "H8",
   "name": "P&L truth recomputed independently from raw records (bonus stake never cash; unsettled bonus = 0)",
   "verdict": "pass",
   "evidence": "headline cash_net_position 85 is reproduced exactly by an independent recomputation over records_list raw_records (settled cash staked 150, payouts 235); the settled bonus bet contributes its 45 of winnings and ZERO stake (cash_stake 0, stake_returned=false); the unsettled bonus bet is worth 0 in the headline (unsettled_bonus_value 0.0, per-record cash_net 0, payout null) with the stake-not-returned note attached"
  },
  {
   "id": "H9",
   "name": "claims refusal is total (no pick leaks); slip is unsubmittable data",
   "verdict": "pass",
   "evidence": "a request naming a lock and a guaranteed system gets CLAIMS_REFUSAL and nothing resembling a pick (no fixture team name appears in the refusal); slip_prepare returns a record whose status is 'prepared' and whose own note states no tool in this suite can submit it (spec 13.7 + slip-as-data)"
  },
  {
   "id": "H10",
   "name": "receipt chain valid; tamper detected",
   "verdict": "pass",
   "evidence": "receipt_list reports chain_valid=true over 40 receipts and the module verifier agrees; flipping one character class in the first receipt's detail on a bench copy makes verification fail (tamper detected)"
  },
  {
   "id": "H11",
   "name": "no banned-claim or dark-pattern phrase on any bench output",
   "verdict": "pass",
   "evidence": "none of the 15 banned claim phrases (risk-free / guaranteed / lock class / you're due class) and no operator promotion text appears in any of the 89 bench outputs collected this run"
  },
  {
   "id": "H12",
   "name": "no-placement surface by enumeration; forbidden verbs refused -32602; denylist in source",
   "verdict": "pass",
   "evidence": "tools/list returns exactly the 22 B0 tools; all 25 forbidden verbs probed directly (placement, account connection, instant limit raise, early exclusion end, timeout end, arb/stake calculators, pick generators, proxy betting) are refused -32602; the capability denylist is enumerated in server.py (spec 13.2/13.6)"
  },
  {
   "id": "H13",
   "name": "policy floor tamper (delay + confirm window) exits 2 at load with TIER_FLOOR_VIOLATION",
   "verdict": "pass",
   "evidence": "two bench tamperings of a copied policy.json \u2014 the daily increase delay lowered 72h -> 71h (below the suite floor) and the confirm window raised past its bound \u2014 each make the copied server exit 2 at load with TIER_FLOOR_VIOLATION on stderr; the floor cannot be quietly edited down (spec 3.2/7)"
  },
  {
   "id": "U1",
   "name": "auth enforced",
   "verdict": "na",
   "evidence": "no credential layer exists in B0 to test: the suite accepts no credentials by construction \u2014 that surface is probed directly in H2 (CREDENTIALS_NOT_ACCEPTED on every tool); operator auth is process ownership on local stdio, the standing note"
  },
  {
   "id": "U2",
   "name": "schema valid",
   "verdict": "pass",
   "evidence": "tools/list returns exactly the 22 B0 tools, each with inputSchema type object + properties + required"
  },
  {
   "id": "U3",
   "name": "no network surface (source-level)",
   "verdict": "pass",
   "evidence": "server.py contains no network call sites \u2014 the fixtures-only B0 claim is structural; no feed or operator can be contacted by this build"
  },
  {
   "id": "U4",
   "name": "no secret leak",
   "verdict": "pass",
   "evidence": "no secret patterns in 114 tool outputs"
  },
  {
   "id": "U5",
   "name": "sane errors",
   "verdict": "pass",
   "evidence": "unknown product_class, zero-stake record and unknown limit kind -> named errors; malformed line survived (receipt_list answers); unknown method -> -32601"
  },
  {
   "id": "U6",
   "name": "process health",
   "verdict": "pass",
   "evidence": "initialize answered in 58 ms; ping ok"
  },
  {
   "id": "U7",
   "name": "audit completeness",
   "verdict": "pass",
   "evidence": "ledger covers the run: 40 receipts, seq strictly increasing, chain valid; ALLOWs and DENYs are both receipted (limit lifecycle, exclusion lifecycle incl. its refused end, record denials, jurisdiction verdicts, slip prep, claims refusal all present)"
  },
  {
   "id": "U8",
   "name": "bench isolation",
   "verdict": "pass",
   "evidence": "workspace product state byte-identical before/after bench"
  }
 ],
 "notes": [
  "Local scope: B0 runs entirely on product fixtures (odds shaped like The Odds API v4, jurisdiction matrix fixture as of 2026-10-25 with a 30-day TTL) and bench-owned synthetic records; no live feed, operator account, or user exists in this bench.",
  "Live-user launch is behind the spec's counsel gate (D4) and a licensed-feed signup (owner step); both are in the manifest not_tested list and were not exercised.",
  "A1 is an adjudication, not a probe: it rules on the builder's boundary call in t_bet_record_add (settled pre-exclusion bets recordable during exclusion; unsettled or exclusion-era bets denied) against spec 3.3's intent.",
  "Run 1 (eclipse-ledger-mcp-2026-10-25.json, FAILED, retained append-only) failed on a defect in THIS bench suite, not the product: H1's lapse probe presented a clock past the wager pending's confirm-by before the happy-path confirm, so the product correctly lapsed that increase (and U7 consequently saw no limit_increase_confirmed receipt). Probe order fixed; run 2 is the standing card."
 ],
 "history": "append-only; prior runs retained in results/"
}