{
  "_meta": {
    "jira": "SAIL-173",
    "generated": "2026-09-07T00:00:00.000Z",
    "date": "2026-09-06",
    "question": "If we bolt a Claude rescue step onto the production pipeline (ask Claude to draw stripes our model misses), does the sailor's final scan end up more accurate, and by how much?",
    "inputs": {
      "tasks": "/Volumes/MacMiniExtra/Projects/boats/server/inference/runs/ai-recovery-2026-09-06/tasks.json",
      "rulescoredSummary": "/Volumes/MacMiniExtra/Projects/boats/server/inference/runs/ai-recovery-rulescored-2026-09-06/summary.json",
      "rulescoredPerPhoto": "/Volumes/MacMiniExtra/Projects/boats/server/inference/runs/ai-recovery-rulescored-2026-09-06/per-photo.json",
      "ablationScoreboard": "/Volumes/MacMiniExtra/Projects/boats/server/inference/gate0-ablation-scoreboard.json",
      "holdoutIds": "/Volumes/MacMiniExtra/Projects/boats/server/inference/test-holdout-ids-canonical.json"
    },
    "method": "Arithmetic composition of two already-computed artifacts: tasks.json's nLinesShown (model-found stripes per photo, from the recovery test's own overlay) and targets.length (model-missed stripes per photo) give the model-alone funnel; ai_recovery_rulescore.mjs's RULE-FILTERED Claude numbers (production isGeometryViolation + checkStripeCrossing already applied) give the rescue-recovered count over the identical miss set. No new scoring pass was run.",
    "photoSet": "The ~88-photo AI-recovery test set: photos WITH A MISSING STRIPE by the recovery run's own design (arm A = 38 labeled photos, of which 36 had a correct line synthetically REMOVED to simulate a miss and 2 are real model misses; arm B = 50 Cape31 config-drops, i.e. real production misses). Most 'missed' stripes in arm A are simulated, not organic model failures — say so plainly, do not imply the model failed on all 88 organically. This is NOT a random sample of the 332-photo holdout — it is the hard subset by construction. One of the 88 (\"B frame_180441.jpg\") has no Claude response on disk and is excluded from every ratio below so the model-found and Claude-recovered counts share an identical 87-photo denominator.",
    "excludedPhoto": {
      "key": "B frame_180441.jpg",
      "reason": "no Claude response file in claude-out/",
      "targets": 1,
      "nLinesShown": 2
    },
    "capFraction": 0.03,
    "recoveryDefinition": "A missed stripe is 'recovered' if Claude's proposed line has human-to-line mean chamfer distance <= 3% of the image diagonal, AFTER dropping any proposal that violates production rules (isGeometryViolation) or crosses an already-kept higher-confidence proposal (checkStripeCrossing).",
    "frozenHoldoutNote": "server/inference/test-holdout-ids-canonical.json (332 photos, frozen 2026-08-25) never trains. The whole-holdout figure below is a PROJECTION built from the ablation scoreboard's mean recall, not a re-measurement of Claude rescue against all 332 photos."
  },
  "funnel_hardPhotos": {
    "denominatorLabel": "total real stripes across the 87 hard photos (model already missed >=1 stripe on each)",
    "photos": 87,
    "totalRealStripes": 284,
    "step1_modelFoundAlone": {
      "count": 193,
      "recall": 0.6795774647887324,
      "recallPct": "68.0%"
    },
    "step2_modelMissed": {
      "count": 91,
      "missRate": 0.3204225352112676,
      "missRatePct": "32.0%"
    },
    "step3_claudeRecoveredOfMisses": {
      "count": 71,
      "ofMissed": 91,
      "recoveryRateOfMisses": 0.7802197802197802,
      "recoveryRateOfMissesPct": "78.0%",
      "ruleFiltered": true,
      "rawRecoveredForComparison": 73,
      "note": "RAW (no rule filter) would have been 73/91 — rules cost 2 recoveries here (dropped as geometry violations) vs RAW."
    },
    "step4_combined": {
      "count": 264,
      "recall": 0.9295774647887324,
      "recallPct": "93.0%",
      "stillMissedAfterRescue": 20
    },
    "recallLift": {
      "absolute": 0.25,
      "absolutePercentagePoints": "25.0",
      "relative": 0.3678756476683938,
      "relativePct": "36.8%"
    },
    "precisionCost": {
      "claudeFalseAddsTotal": 21,
      "claudeFalseAddsPerPhoto": 0.2413793103448276,
      "note": "Every rescue call also risks drawing a junk line (a proposal matching no missed target) even after rule-filtering. These are extra lines a sailor could see if the rescue step fires with no additional gate."
    },
    "byArm": {
      "A": {
        "found": 95,
        "missed": 41,
        "photos": 38
      },
      "B": {
        "found": 98,
        "missed": 50,
        "photos": 49
      }
    }
  },
  "funnel_whole332_projection": {
    "denominatorLabel": "PROJECTION only — mean per-photo recall across the full 332-photo frozen holdout, not a stripe-count total (the ablation scoreboard stores mean recall, not raw stripe counts)",
    "isProjection": true,
    "nHoldout": 332,
    "modelAloneMeanRecall_rulesStage": 0.9575301204819278,
    "modelAloneMeanRecall_rulesStagePct": "95.8%",
    "impliedMeanMissRate": 0.04246987951807224,
    "claudeMissRecoveryFractionAppliedUniformly": 0.7802197802197802,
    "claudeMissRecoveryFractionPct": "78.0%",
    "projectedCombinedMeanRecall": 0.9906659605454786,
    "projectedCombinedMeanRecallPct": "99.1%",
    "projectedRecallLift": 0.03313584006355086,
    "projectedRecallLiftPercentagePoints": "3.3",
    "caveat": "This assumes the 88-photo rescue sample's miss-recovery behavior generalizes uniformly to every miss in the 332-photo holdout, and that the ablation scoreboard's 'rules' stage recall is the right model-alone baseline to compose with. It is presented as a bounding estimate, not a measured result. The vast majority of the 332 holdout photos already have recall 1.0 (no miss) and are completely untouched by a rescue step — the lift is real but small in whole-holdout terms because misses are a minority of stripes overall. RECALL ONLY: this projection does not estimate precision at scale. Junk/photo (0.24) was measured only on the 87 hard photos; a production rescue step would also fire on the ~244 no-miss holdout photos, where every proposed line is junk by definition. That false-add rate at scale is unmeasured here."
  },
  "verdict": {
    "onHardPhotos": "Yes — on the 87 photos with a missing stripe (mostly simulated misses + real Cape31 config-drops, per the recovery run's own design), Claude rescue lifts recall from 68.0% to 93.0% (+25.0 percentage points), recovering 71 of 91 missed stripes, at a cost of 0.24 junk lines per photo.",
    "onWholeHoldout": "Projected (recall only) — whole-332-holdout mean recall would move from 95.8% to an estimated 99.1% (+3.3 percentage points), because misses are a minority of all stripes; this is a projection, not a direct measurement, and it does not estimate the junk a rescue step would add on the ~244 no-miss photos."
  }
}