{
 "tool": "eclipse-orbit-mcp",
 "version": "0.1.0",
 "bench_date": "2026-10-25",
 "bench_version": "0.1.0",
 "environment": "simulator",
 "qualifier": "simulator",
 "verdict": "CERTIFIED(simulator)",
 "checks": [
  {
   "id": "O1",
   "name": "unclassified tool refusal identical to nonexistent (no oracle)",
   "verdict": "pass",
   "evidence": "crm_export_all is present in the vendor inventory but withheld as UNCLASSIFIED, and calling it fails with a refusal identical (modulo the echoed tool name) to calling a tool that does not exist at all \u2014 the proxy is not an oracle for the vendor's unclassified surface"
  },
  {
   "id": "O2",
   "name": "classified-but-never-surfaced tools (delete/bulk) unreachable via any proxy path",
   "verdict": "pass",
   "evidence": "crm_delete_contact and crm_bulk_update are classified (T3) but withheld as CLASSIFIED_NOT_SURFACED_V1; vendor_call refuses both with the same non-oracle refusal, and a direct MCP call to the vendor tool name is refused at the proxy surface (-32602 unknown or C0-forbidden) \u2014 no proxy path reaches them"
  },
  {
   "id": "O3",
   "name": "OBJECT_GAP declared on every inventory view",
   "verdict": "pass",
   "evidence": "both inventory views (vendor_tools and vendor_refresh) declare object_gaps_declared containing hubspot_custom_objects \u2014 the gap is stated on every surface that lists the wrap's reach, never silently omitted"
  },
  {
   "id": "O4",
   "name": "egress masking owner-vs-analytic; receipts content-free",
   "verdict": "pass",
   "evidence": "egress masking is proven against the stub's PII: analytic surface returns email domain-only (***@acme.example) while owner returns the full email; phone is partial (last 2) on BOTH surfaces; and a scan of every receipt (state + receipt_list) finds no full email, phone, or ticket subject \u2014 receipts carry hashes only"
  },
  {
   "id": "O5",
   "name": "drift tier-rise halts with EXACTLY ONE notice receipt",
   "verdict": "pass",
   "evidence": "raising the vendor tier hint for deal_stage_move (T2 classified -> T3 hint) halts the tool on refresh; after two further refreshes and an inventory read there is still EXACTLY ONE vendor_tier_rise_halt notice receipt (classified_tier 2, vendor_hint_tier 3)"
  },
  {
   "id": "O6",
   "name": "valid approval token cannot move a halted tool",
   "verdict": "pass",
   "evidence": "while halted, even the correctly computed approval token for the exact arguments cannot move deal_stage_move: the call is refused TOOL_HALTED_TIER_RISE and the denial is receipted with that reason"
  },
  {
   "id": "O7",
   "name": "owner clear-halt resumes, flagged acknowledged",
   "verdict": "pass",
   "evidence": "a wrong clear token fails and the tool stays halted; the owner token clear-halt-deal_stage_move resumes it, the inventory now surfaces it flagged tier_rise_acknowledged=3, calls succeed again with the T2 token, and a further refresh mints no second notice for the acknowledged rise"
  },
  {
   "id": "O8",
   "name": "drift-ADDED tool withheld uncallable",
   "verdict": "pass",
   "evidence": "a vendor tool added mid-flight (crm_bench_new_tool) is withheld as UNCLASSIFIED on the next refresh, never surfaces, and calling it fails with the same non-oracle refusal as a nonexistent tool \u2014 new vendor surface is invisible until the proxy classifies it"
  },
  {
   "id": "O9",
   "name": "receipt chain valid; tamper detected",
   "verdict": "pass",
   "evidence": "receipt_list reports chain_valid over 13 receipts (proxied calls, denials, halt notice, halt clear, refreshes); the product verifier confirms it, and a deep copy with one altered receipt detail verifies false"
  },
  {
   "id": "U1",
   "name": "auth enforced",
   "verdict": "na",
   "evidence": "no live vendor credential exists in C0 to test (the vendor is a local stub; real OAuth 2.1 + PKCE is C1); process ownership is the boundary"
  },
  {
   "id": "U2",
   "name": "schema valid",
   "verdict": "pass",
   "evidence": "tools/list returns exactly the 5 proxy tools, each with inputSchema type object + properties + required"
  },
  {
   "id": "U3",
   "name": "no network surface (local stub vendor link)",
   "verdict": "pass",
   "evidence": "server.py contains no network call sites \u2014 the vendor link is a local stdio subprocess (the shipped stub in C0); no HubSpot endpoint can be reached by this build"
  },
  {
   "id": "U4",
   "name": "no secret leak",
   "verdict": "pass",
   "evidence": "no secret patterns in 28 tool outputs"
  },
  {
   "id": "U5",
   "name": "sane errors",
   "verdict": "pass",
   "evidence": "vendor_call without a tool and halt_clear on a non-halted tool -> named errors; malformed line survived (receipt_list answers); unknown method -> -32601"
  },
  {
   "id": "U6",
   "name": "process health",
   "verdict": "pass",
   "evidence": "initialize answered in 48 ms; ping ok"
  },
  {
   "id": "U7",
   "name": "audit completeness",
   "verdict": "pass",
   "evidence": "ledger covers the run in order (['vendor_call_proxied', 'vendor_tier_rise_halt', 'vendor_call_denied', 'vendor_halt_cleared', 'vendor_inventory_refreshed'] present as a subsequence); 13 receipts, seq strictly increasing, chain valid \u2014 proxied calls, the halt, its denials, and the owner clear are all receipted"
  },
  {
   "id": "U8",
   "name": "bench isolation",
   "verdict": "pass",
   "evidence": "workspace product state byte-identical before/after bench"
  }
 ],
 "notes": [
  "Simulator scope: the vendor is a local stub shaped like HubSpot's MCP tool surface; the real HubSpot server is C1 (owner account) and is in the manifest not_tested list. The drift rules are proven against the stub's drift fixtures (tier rise, added tool).",
  "Approval tokens are computed bench-side from the spec 6.3 shape (approve-call-<tool>-<args hash12>) rather than imported from the product, so the gate is checked against an independent construction."
 ],
 "history": "append-only; prior runs retained in results/"
}