{
 "schema": "cain42.driftguard.evolution.v1",
 "date": "2026-11-02",
 "version_after": "DriftGuard 1.1.0 (suite product, repo /root/products-sjc/driftguard commit 1d77fb0)",
 "blind_set": "scripts/driftguard/blind_2026_11_02.py (18 cases, written before any change)",
 "runs": [
  {
   "run": 1,
   "version": "1.0.0",
   "held": "8/18",
   "note": "the reported blind result"
  },
  {
   "run": 2,
   "version": "1.1.0",
   "held": "18/18",
   "note": "after the fixes; the harness now names each test definition after its tool id (1.1.0 refuses a name/id mismatch, which run 1's harness relied on); the name-mismatch case keeps its own name"
  }
 ],
 "held_on_1_0_0": [
  "unchanged definition matches; key order irrelevant",
  "description rug pull caught with a field diff",
  "invisible character change caught",
  "annotation flip (destructiveHint) caught",
  "unpinned verify 404; no key 401"
 ],
 "findings": [
  {
   "id": "DG-11-02-1",
   "what": "All key holders shared one pin namespace: one customer could read another's pins or replace them (silently approving an attacker's definition)",
   "before": "shared",
   "after": "pins scoped per API key (SHA-256)"
  },
  {
   "id": "DG-11-02-2",
   "what": "The README's tool-shadowing defence did not exist: server_id was stored but ignored, a second server's pin replaced the first, and its definition then verified",
   "before": "replaced; match",
   "after": "pins keyed by (key, server, tool); no server_id: the single pinned server, or 409 when two or more"
  },
  {
   "id": "DG-11-02-3",
   "what": "A definition poisoned from the start (<IMPORTANT> block asking to read ~/.ssh/id_rsa, 'do not tell the user') was pinned silently",
   "before": "pinned",
   "after": "deterministic screen at pin: 409 with findings unless a person acknowledges; keyless POST /v1/screen"
  },
  {
   "id": "DG-11-02-4",
   "what": "A pin whose definition name differs from the tool id was accepted",
   "before": "accepted",
   "after": "422"
  },
  {
   "id": "DG-11-02-5",
   "what": "Re-pinning erased the previous baseline",
   "before": "lost",
   "after": "pin history with previous hash"
  },
  {
   "id": "DG-11-02-6",
   "what": "No size limit on definitions",
   "before": "2 MB accepted",
   "after": "64 KB limit (413)"
  },
  {
   "id": "DG-11-02-7",
   "what": "Diff said only 'inputSchema' changed",
   "before": "inputSchema",
   "after": "inputSchema.properties.bcc"
  },
  {
   "id": "DG-11-02-8",
   "what": "1 vs 1.0 in a schema reported as drift (false alarm)",
   "before": "drift",
   "after": "match"
  }
 ],
 "poisoning_screen_false_alarms": {
  "corpus": "2,812 tool definitions from 400 public MCP servers (registry probe 2026-10-30)",
  "first_version": "559 flagged (19.9%)",
  "after_tuning_on_the_same_corpus": "6 flagged (0.21%)",
  "held_out": "only 6 other real tools exist in the repo: the 4 ordinary ones not flagged, the 2 deliberately poisoned samples flagged",
  "honest_reading": "the 0.21% was tuned on that corpus, so it is not an independent false-alarm rate; an independent measurement is still owed"
 },
 "compatibility": {
  "breaking": [
   "history returns {pins, verifications}",
   "pins are per key and per server"
  ],
  "kept_working": "the public demo pin (made with server_id mail-mcp) still verifies without a server_id: checked on a copy of the live database"
 },
 "tests": {
  "driftguard_repo": "19 -> 23",
  "all_pass": true
 },
 "live": "not yet: the suite host runs a copy in /var/lib/cain-suite/driftguard; updating it is owner-run (bash scripts/sjc_import/deploy_product.sh driftguard)",
 "self_run": "our own runs; no independent test",
 "run1_rows": [
  {
   "name": "unchanged_matches",
   "want": "ok",
   "outcome": "ok",
   "detail": "True",
   "pass": true
  },
  {
   "name": "key_order_irrelevant",
   "want": "ok",
   "outcome": "ok",
   "detail": "ok",
   "pass": true
  },
  {
   "name": "description_rug_pull_caught",
   "want": "refused",
   "outcome": "refused",
   "detail": "['description']",
   "pass": true
  },
  {
   "name": "zero_width_change_caught",
   "want": "refused",
   "outcome": "refused",
   "detail": "zero-width",
   "pass": true
  },
  {
   "name": "annotation_flip_caught",
   "want": "refused",
   "outcome": "refused",
   "detail": "annotations",
   "pass": true
  },
  {
   "name": "diff_names_nested_schema_field",
   "want": "refused",
   "outcome": "accepted",
   "detail": "diff fields ['inputSchema']",
   "pass": false
  },
  {
   "name": "equal_numbers_not_drift",
   "want": "ok",
   "outcome": "broken",
   "detail": "1 vs 1.0 -> match=False",
   "pass": false
  },
  {
   "name": "shadowing_second_server_does_not_replace_first_pin",
   "want": "refused",
   "outcome": "accepted",
   "detail": "server-a's own definition after server-b pinned: match=False",
   "pass": false
  },
  {
   "name": "shadowing_other_server_definition_not_accepted",
   "want": "refused",
   "outcome": "accepted",
   "detail": "server-b's definition verified for server-a: match=True",
   "pass": false
  },
  {
   "name": "poisoned_definition_flagged_at_pin",
   "want": "refused",
   "outcome": "accepted",
   "detail": "pin HTTP 200 keys ['definition_hash', 'pinned_at', 'tool_id', 'updated_at']",
   "pass": false
  },
  {
   "name": "pin_name_mismatch_refused",
   "want": "refused",
   "outcome": "accepted",
   "detail": "pin tool_id send_email_11 with definition name delete_all_files: HTTP 200",
   "pass": false
  },
  {
   "name": "repin_keeps_previous_baseline_in_history",
   "want": "refused",
   "outcome": "accepted",
   "detail": "first pin hash recorded in history: False",
   "pass": false
  },
  {
   "name": "tenants_do_not_share_pins",
   "want": "refused",
   "outcome": "accepted",
   "detail": "tenant B verify of tenant A's pin: HTTP 200 match=True",
   "pass": false
  },
  {
   "name": "tenant_cannot_overwrite_other_tenant_pin",
   "want": "refused",
   "outcome": "accepted",
   "detail": "tenant A's pin after tenant C re-pinned",
   "pass": false
  },
  {
   "name": "oversized_definition_refused",
   "want": "refused",
   "outcome": "accepted",
   "detail": "HTTP 200",
   "pass": false
  },
  {
   "name": "unpinned_verify_404",
   "want": "refused",
   "outcome": "refused",
   "detail": "404",
   "pass": true
  },
  {
   "name": "no_key_refused",
   "want": "refused",
   "outcome": "refused",
   "detail": "401",
   "pass": true
  },
  {
   "name": "legit_repin_after_review_then_matches",
   "want": "ok",
   "outcome": "ok",
   "detail": "ok",
   "pass": true
  }
 ]
}