{
 "provenance": {
  "engine_commit": "a65ef230a3b1",
  "uncommitted_changes": false,
  "command": "uv run python -m virtual_build.risk_report --spec specs/tracker_puck.yaml --out examples/build-risk-report"
 },
 "label": "Simulated, uncalibrated, synthetic part",
 "product": "Synthetic coin-cell tracker puck",
 "spec": {
  "file": "specs/tracker_puck.yaml",
  "digest": "800e67cef127"
 },
 "n": 5000,
 "seed": 42,
 "line": {
  "first_pass_yield": 0.963,
  "first_pass_good": 4815,
  "final_yield": 0.9656,
  "good_units": 4828,
  "retries": 13,
  "recovered_by_retry": 13,
  "good_units_per_hour": 462.1621667391606,
  "bottleneck": "S2",
  "makespan_s": 37607.57857492376,
  "transport": {
   "pallets": 24,
   "speed_m_per_min": 12.0
  }
 },
 "stations": [
  {
   "id": "S1",
   "ops": [
    "place_board"
   ],
   "label": "Place board",
   "units_lost": 0,
   "classes": {},
   "retries": 2,
   "utilization": 0.6645781130074933,
   "cycle_mean_s": 3.4972299148243327
  },
  {
   "id": "S2",
   "ops": [
    "drive_screws"
   ],
   "label": "Drive screws",
   "units_lost": 0,
   "classes": {},
   "retries": 2,
   "utilization": 0.9982327136791982,
   "cycle_mean_s": 6.0058003846089125
  },
  {
   "id": "S3",
   "ops": [
    "insert_cell"
   ],
   "label": "Insert cell",
   "units_lost": 1,
   "classes": {
    "cell_not_seated": 1
   },
   "retries": 3,
   "utilization": 0.5986468378000913,
   "cycle_mean_s": 3.0010080452343804
  },
  {
   "id": "S4",
   "ops": [
    "press_cover"
   ],
   "label": "Press cover",
   "units_lost": 151,
   "classes": {
    "no_engage_loose": 70,
    "jam_misalignment": 61,
    "stack_interference": 20
   },
   "retries": 6,
   "utilization": 0.7981855314992644,
   "cycle_mean_s": 4.499441519479498
  },
  {
   "id": "S5",
   "ops": [
    "inspect_gap",
    "power_test"
   ],
   "label": "Inspect gap, power test",
   "units_lost": 20,
   "classes": {
    "gap_uneven": 20
   },
   "retries": 0,
   "utilization": 0.8375360835994509,
   "cycle_mean_s": 4.997562164439268
  }
 ],
 "risks": [
  {
   "rank": 1,
   "id": "R1",
   "station": "S4",
   "class": "no_engage_loose",
   "label": "No-engage / loose",
   "meaning": "A hook misses its window, engages too little, has too much axial play, or the press stops before it snaps.",
   "units_lost": 70,
   "share": 0.014,
   "units_flagged": 70,
   "drivers": [
    {
     "factor": "parts.base.outline.diameter",
     "name": "base diameter",
     "kind": "product",
     "value": "29.80 \u00b10.08 mm",
     "evidence": "SYNTHETIC",
     "flagged_if_nominal": 5,
     "corr": 0.16269652842159665,
     "direction": "larger is safer"
    },
    {
     "factor": "parts.cover.outline.inner_diameter",
     "name": "cover inner diameter",
     "kind": "product",
     "value": "30.10 \u00b10.08 mm",
     "evidence": "SYNTHETIC",
     "flagged_if_nominal": 6,
     "corr": -0.1701000208059823,
     "direction": "smaller is safer"
    },
    {
     "factor": "parts.base.features.hooks.undercut",
     "name": "base hooks undercut",
     "kind": "product",
     "value": "0.45 \u00b10.04 mm",
     "evidence": "SYNTHETIC",
     "flagged_if_nominal": 26,
     "corr": 0.04227248731047145,
     "direction": "spread only"
    }
   ],
   "fix": {
    "change": "parts.base.outline.diameter=+0.08",
    "kind": "design nominal",
    "driver": "base diameter",
    "factor": "parts.base.outline.diameter",
    "evidence": "SYNTHETIC",
    "from": "29.80 \u00b10.08 mm",
    "to": "29.88 \u00b10.08 mm",
    "first_pass_yield": 0.9778,
    "first_pass_good": 4889,
    "final_yield": 0.9804,
    "good_units": 4902,
    "retries": 13,
    "recovered_by_retry": 13,
    "good_units_per_hour": 469.24584535115275,
    "bottleneck": "S2",
    "class_lost": 1,
    "station_lost": 75,
    "station_lost_before": 151,
    "rises": [
     {
      "station": "S4",
      "class": "hook_overstrain",
      "label": "Hook overstrain (crack risk)",
      "units": 2
     },
     {
      "station": "S5",
      "class": "gap_uneven",
      "label": "Gap uneven",
      "units": 2
     }
    ],
    "gain_units": 74,
    "ties": [
     {
      "change": "parts.cover.outline.inner_diameter=-0.08",
      "driver": "cover inner diameter",
      "factor": "parts.cover.outline.inner_diameter",
      "from": "30.10 \u00b10.08 mm",
      "to": "30.02 \u00b10.08 mm",
      "class_lost": 1
     }
    ]
   },
   "candidates": [
    {
     "change": "parts.base.outline.diameter=+0.04",
     "kind": "design nominal",
     "driver": "base diameter",
     "factor": "parts.base.outline.diameter",
     "evidence": "SYNTHETIC",
     "from": "29.80 \u00b10.08 mm",
     "to": "29.84 \u00b10.08 mm",
     "first_pass_yield": 0.976,
     "first_pass_good": 4880,
     "final_yield": 0.9786,
     "good_units": 4893,
     "retries": 13,
     "recovered_by_retry": 13,
     "good_units_per_hour": 468.38431687131583,
     "bottleneck": "S2",
     "class_lost": 3,
     "station_lost": 84,
     "station_lost_before": 151,
     "rises": [
      {
       "station": "S4",
       "class": "hook_overstrain",
       "label": "Hook overstrain (crack risk)",
       "units": 1
      },
      {
       "station": "S5",
       "class": "gap_uneven",
       "label": "Gap uneven",
       "units": 2
      }
     ]
    },
    {
     "change": "parts.base.outline.diameter=+0.08",
     "kind": "design nominal",
     "driver": "base diameter",
     "factor": "parts.base.outline.diameter",
     "evidence": "SYNTHETIC",
     "from": "29.80 \u00b10.08 mm",
     "to": "29.88 \u00b10.08 mm",
     "first_pass_yield": 0.9778,
     "first_pass_good": 4889,
     "final_yield": 0.9804,
     "good_units": 4902,
     "retries": 13,
     "recovered_by_retry": 13,
     "good_units_per_hour": 469.24584535115275,
     "bottleneck": "S2",
     "class_lost": 1,
     "station_lost": 75,
     "station_lost_before": 151,
     "rises": [
      {
       "station": "S4",
       "class": "hook_overstrain",
       "label": "Hook overstrain (crack risk)",
       "units": 2
      },
      {
       "station": "S5",
       "class": "gap_uneven",
       "label": "Gap uneven",
       "units": 2
      }
     ]
    },
    {
     "change": "parts.base.outline.diameter.tol=*0.5",
     "kind": "tolerance",
     "driver": "base diameter",
     "factor": "parts.base.outline.diameter",
     "evidence": "SYNTHETIC",
     "from": "29.80 \u00b10.08 mm",
     "to": "29.80 \u00b10.04 mm",
     "first_pass_yield": 0.9736,
     "first_pass_good": 4868,
     "final_yield": 0.9762,
     "good_units": 4881,
     "retries": 13,
     "recovered_by_retry": 13,
     "good_units_per_hour": 467.23561223153337,
     "bottleneck": "S2",
     "class_lost": 15,
     "station_lost": 96,
     "station_lost_before": 151,
     "rises": [
      {
       "station": "S5",
       "class": "gap_uneven",
       "label": "Gap uneven",
       "units": 2
      }
     ]
    },
    {
     "change": "parts.cover.outline.inner_diameter=-0.04",
     "kind": "design nominal",
     "driver": "cover inner diameter",
     "factor": "parts.cover.outline.inner_diameter",
     "evidence": "SYNTHETIC",
     "from": "30.10 \u00b10.08 mm",
     "to": "30.06 \u00b10.08 mm",
     "first_pass_yield": 0.976,
     "first_pass_good": 4880,
     "final_yield": 0.9786,
     "good_units": 4893,
     "retries": 13,
     "recovered_by_retry": 13,
     "good_units_per_hour": 468.38431687131583,
     "bottleneck": "S2",
     "class_lost": 3,
     "station_lost": 84,
     "station_lost_before": 151,
     "rises": [
      {
       "station": "S4",
       "class": "hook_overstrain",
       "label": "Hook overstrain (crack risk)",
       "units": 1
      },
      {
       "station": "S5",
       "class": "gap_uneven",
       "label": "Gap uneven",
       "units": 2
      }
     ]
    },
    {
     "change": "parts.cover.outline.inner_diameter=-0.08",
     "kind": "design nominal",
     "driver": "cover inner diameter",
     "factor": "parts.cover.outline.inner_diameter",
     "evidence": "SYNTHETIC",
     "from": "30.10 \u00b10.08 mm",
     "to": "30.02 \u00b10.08 mm",
     "first_pass_yield": 0.9778,
     "first_pass_good": 4889,
     "final_yield": 0.9804,
     "good_units": 4902,
     "retries": 13,
     "recovered_by_retry": 13,
     "good_units_per_hour": 469.24584535115275,
     "bottleneck": "S2",
     "class_lost": 1,
     "station_lost": 75,
     "station_lost_before": 151,
     "rises": [
      {
       "station": "S4",
       "class": "hook_overstrain",
       "label": "Hook overstrain (crack risk)",
       "units": 2
      },
      {
       "station": "S5",
       "class": "gap_uneven",
       "label": "Gap uneven",
       "units": 2
      }
     ]
    },
    {
     "change": "parts.cover.outline.inner_diameter.tol=*0.5",
     "kind": "tolerance",
     "driver": "cover inner diameter",
     "factor": "parts.cover.outline.inner_diameter",
     "evidence": "SYNTHETIC",
     "from": "30.10 \u00b10.08 mm",
     "to": "30.10 \u00b10.04 mm",
     "first_pass_yield": 0.9744,
     "first_pass_good": 4872,
     "final_yield": 0.977,
     "good_units": 4885,
     "retries": 13,
     "recovered_by_retry": 13,
     "good_units_per_hour": 467.6185137781276,
     "bottleneck": "S2",
     "class_lost": 11,
     "station_lost": 92,
     "station_lost_before": 151,
     "rises": [
      {
       "station": "S5",
       "class": "gap_uneven",
       "label": "Gap uneven",
       "units": 2
      }
     ]
    },
    {
     "change": "parts.base.features.hooks.undercut.tol=*0.5",
     "kind": "tolerance",
     "driver": "base hooks undercut",
     "factor": "parts.base.features.hooks.undercut",
     "evidence": "SYNTHETIC",
     "from": "0.45 \u00b10.04 mm",
     "to": "0.45 \u00b10.02 mm",
     "first_pass_yield": 0.969,
     "first_pass_good": 4845,
     "final_yield": 0.9716,
     "good_units": 4858,
     "retries": 13,
     "recovered_by_retry": 13,
     "good_units_per_hour": 465.0339283386168,
     "bottleneck": "S2",
     "class_lost": 39,
     "station_lost": 120,
     "station_lost_before": 151,
     "rises": [
      {
       "station": "S5",
       "class": "gap_uneven",
       "label": "Gap uneven",
       "units": 1
      }
     ]
    }
   ],
   "not_tried": [],
   "first_build": {
    "check": "Measure hook-face diameter and window position on first shots; record press curves.",
    "owner": "design and tooling supplier"
   },
   "figure_anchor": {
    "part": "base",
    "feature": "outline"
   },
   "seed_range": [
    55,
    70
   ]
  },
  {
   "rank": 2,
   "id": "R2",
   "station": "S4",
   "class": "jam_misalignment",
   "label": "Jam / misalignment",
   "meaning": "The cover's lead-in does not capture the base, or a hook lands outside its window along the rim.",
   "units_lost": 61,
   "share": 0.0122,
   "units_flagged": 61,
   "drivers": [
    {
     "factor": "sequence.press_cover.effector.part_offset",
     "name": "S4 gripper part offset",
     "kind": "station",
     "value": "\u00b10.10 mm",
     "evidence": "ASSUMPTION",
     "flagged_if_nominal": 3,
     "corr": -0.47334875441157936,
     "direction": "smaller is safer"
    },
    {
     "factor": "sequence.press_cover.effector.rotation_offset",
     "name": "S4 gripper rotation offset",
     "kind": "station",
     "value": "\u00b10.30 deg",
     "evidence": "ASSUMPTION",
     "flagged_if_nominal": 9,
     "corr": 0.01163345310246099,
     "direction": "spread only"
    },
    {
     "factor": "pallet.locating_error",
     "name": "pallet locating error",
     "kind": "station",
     "value": "\u00b10.05 mm",
     "evidence": "ASSUMPTION",
     "flagged_if_nominal": 32,
     "corr": -0.11758725621093132,
     "direction": "smaller is safer"
    }
   ],
   "fix": {
    "change": "station.press_cover.effector.part_offset_mm=*0.5",
    "kind": "station spec",
    "driver": "S4 gripper part offset",
    "factor": "sequence.press_cover.effector.part_offset",
    "evidence": "ASSUMPTION",
    "from": "\u00b10.10 mm",
    "to": "\u00b10.05 mm",
    "first_pass_yield": 0.9726,
    "first_pass_good": 4863,
    "final_yield": 0.9752,
    "good_units": 4876,
    "retries": 13,
    "recovered_by_retry": 13,
    "good_units_per_hour": 466.7569852982906,
    "bottleneck": "S2",
    "class_lost": 13,
    "station_lost": 103,
    "station_lost_before": 151,
    "rises": [],
    "gain_units": 48,
    "ties": []
   },
   "candidates": [
    {
     "change": "station.press_cover.effector.part_offset_mm=*0.5",
     "kind": "station spec",
     "driver": "S4 gripper part offset",
     "factor": "sequence.press_cover.effector.part_offset",
     "evidence": "ASSUMPTION",
     "from": "\u00b10.10 mm",
     "to": "\u00b10.05 mm",
     "first_pass_yield": 0.9726,
     "first_pass_good": 4863,
     "final_yield": 0.9752,
     "good_units": 4876,
     "retries": 13,
     "recovered_by_retry": 13,
     "good_units_per_hour": 466.7569852982906,
     "bottleneck": "S2",
     "class_lost": 13,
     "station_lost": 103,
     "station_lost_before": 151,
     "rises": []
    },
    {
     "change": "station.press_cover.effector.rotation_offset_deg=*0.5",
     "kind": "station spec",
     "driver": "S4 gripper rotation offset",
     "factor": "sequence.press_cover.effector.rotation_offset",
     "evidence": "ASSUMPTION",
     "from": "\u00b10.30 deg",
     "to": "\u00b10.15 deg",
     "first_pass_yield": 0.9716,
     "first_pass_good": 4858,
     "final_yield": 0.9742,
     "good_units": 4871,
     "retries": 13,
     "recovered_by_retry": 13,
     "good_units_per_hour": 466.27835836504795,
     "bottleneck": "S2",
     "class_lost": 18,
     "station_lost": 108,
     "station_lost_before": 151,
     "rises": []
    }
   ],
   "not_tried": [
    "pallet locating error"
   ],
   "first_build": {
    "check": "Measure cover pose on the gripper and base pose on the pallet separately.",
    "owner": "manufacturing engineering"
   },
   "figure_anchor": {
    "part": "cover",
    "feature": "top"
   },
   "seed_range": [
    54,
    63
   ]
  },
  {
   "rank": 3,
   "id": "R3",
   "station": "S4",
   "class": "stack_interference",
   "label": "Stack interference",
   "meaning": "A cover rib presses on the stack below it (cell or board) by more than its allowed crush, so the cover cannot seat.",
   "units_lost": 20,
   "share": 0.004,
   "units_flagged": 20,
   "drivers": [
    {
     "factor": "parts.cell.outline.height",
     "name": "cell height",
     "kind": "product",
     "value": "2.9 to 3.2 mm",
     "evidence": "TYPICAL",
     "flagged_if_nominal": 0,
     "corr": -0.8956182290337666,
     "direction": "smaller is safer"
    },
    {
     "factor": "parts.pcba.outline.thickness",
     "name": "pcba thickness",
     "kind": "product",
     "value": "1.00 \u00b10.08 mm",
     "evidence": "ASSUMPTION",
     "flagged_if_nominal": 1,
     "corr": -0.24399858276841377,
     "direction": "smaller is safer"
    },
    {
     "factor": "parts.cover.features.cell_ribs.reach",
     "name": "cover cell ribs reach",
     "kind": "product",
     "value": "1.60 \u00b10.04 mm",
     "evidence": "SYNTHETIC",
     "flagged_if_nominal": 12,
     "corr": -0.11769850000411017,
     "direction": "smaller is safer"
    }
   ],
   "fix": {
    "change": "parts.cover.features.cell_ribs.reach=-0.04",
    "kind": "design nominal",
    "driver": "cover cell ribs reach",
    "factor": "parts.cover.features.cell_ribs.reach",
    "evidence": "SYNTHETIC",
    "from": "1.60 \u00b10.04 mm",
    "to": "1.56 \u00b10.04 mm",
    "first_pass_yield": 0.968,
    "first_pass_good": 4840,
    "final_yield": 0.9706,
    "good_units": 4853,
    "retries": 13,
    "recovered_by_retry": 13,
    "good_units_per_hour": 464.55530140537417,
    "bottleneck": "S2",
    "class_lost": 0,
    "station_lost": 131,
    "station_lost_before": 151,
    "rises": [],
    "gain_units": 25,
    "ties": []
   },
   "candidates": [
    {
     "change": "parts.pcba.outline.thickness.tol=*0.5",
     "kind": "tolerance",
     "driver": "pcba thickness",
     "factor": "parts.pcba.outline.thickness",
     "evidence": "ASSUMPTION",
     "from": "1.00 \u00b10.08 mm",
     "to": "1.00 \u00b10.04 mm",
     "first_pass_yield": 0.9662,
     "first_pass_good": 4831,
     "final_yield": 0.9688,
     "good_units": 4844,
     "retries": 13,
     "recovered_by_retry": 13,
     "good_units_per_hour": 463.69377292553725,
     "bottleneck": "S2",
     "class_lost": 4,
     "station_lost": 135,
     "station_lost_before": 151,
     "rises": []
    },
    {
     "change": "parts.cover.features.cell_ribs.reach=-0.02",
     "kind": "design nominal",
     "driver": "cover cell ribs reach",
     "factor": "parts.cover.features.cell_ribs.reach",
     "evidence": "SYNTHETIC",
     "from": "1.60 \u00b10.04 mm",
     "to": "1.58 \u00b10.04 mm",
     "first_pass_yield": 0.966,
     "first_pass_good": 4830,
     "final_yield": 0.9686,
     "good_units": 4843,
     "retries": 13,
     "recovered_by_retry": 13,
     "good_units_per_hour": 463.5980475388888,
     "bottleneck": "S2",
     "class_lost": 5,
     "station_lost": 136,
     "station_lost_before": 151,
     "rises": []
    },
    {
     "change": "parts.cover.features.cell_ribs.reach=-0.04",
     "kind": "design nominal",
     "driver": "cover cell ribs reach",
     "factor": "parts.cover.features.cell_ribs.reach",
     "evidence": "SYNTHETIC",
     "from": "1.60 \u00b10.04 mm",
     "to": "1.56 \u00b10.04 mm",
     "first_pass_yield": 0.968,
     "first_pass_good": 4840,
     "final_yield": 0.9706,
     "good_units": 4853,
     "retries": 13,
     "recovered_by_retry": 13,
     "good_units_per_hour": 464.55530140537417,
     "bottleneck": "S2",
     "class_lost": 0,
     "station_lost": 131,
     "station_lost_before": 151,
     "rises": []
    },
    {
     "change": "parts.cover.features.cell_ribs.reach.tol=*0.5",
     "kind": "tolerance",
     "driver": "cover cell ribs reach",
     "factor": "parts.cover.features.cell_ribs.reach",
     "evidence": "SYNTHETIC",
     "from": "1.60 \u00b10.04 mm",
     "to": "1.60 \u00b10.02 mm",
     "first_pass_yield": 0.9636,
     "first_pass_good": 4818,
     "final_yield": 0.9662,
     "good_units": 4831,
     "retries": 13,
     "recovered_by_retry": 13,
     "good_units_per_hour": 462.4493428991062,
     "bottleneck": "S2",
     "class_lost": 17,
     "station_lost": 148,
     "station_lost_before": 151,
     "rises": []
    }
   ],
   "not_tried": [
    "cell height"
   ],
   "first_build": {
    "check": "Measure the seated board and cell stack and the rib reach on first-shot covers.",
    "owner": "mechanical design"
   },
   "figure_anchor": {
    "part": "cover",
    "feature": "cell_ribs"
   },
   "seed_range": [
    15,
    20
   ]
  },
  {
   "rank": 4,
   "id": "R4",
   "station": "S5",
   "class": "gap_uneven",
   "label": "Gap uneven",
   "meaning": "The camera's cover-to-base gap varies around the part by more than the spread limit.",
   "units_lost": 20,
   "share": 0.004,
   "units_flagged": 29,
   "drivers": [
    {
     "factor": "parts.base.features.hooks.catch_depth",
     "name": "base hooks catch depth",
     "kind": "product",
     "value": "2.20 \u00b10.06 mm",
     "evidence": "SYNTHETIC",
     "flagged_if_nominal": 6,
     "corr": 0.0032578464120780848,
     "direction": "spread only"
    },
    {
     "factor": "parts.cover.features.windows.latch_depth",
     "name": "cover windows latch depth",
     "kind": "product",
     "value": "2.30 \u00b10.06 mm",
     "evidence": "SYNTHETIC",
     "flagged_if_nominal": 6,
     "corr": 0.004370951599738832,
     "direction": "spread only"
    },
    {
     "factor": "sequence.press_cover.effector.pick_loss",
     "name": "S4 gripper pick loss",
     "kind": "event",
     "value": "1 in 1,000 units",
     "evidence": "HYPOTHESIS",
     "flagged_if_nominal": 23,
     "corr": -0.2394567607097646,
     "direction": "smaller is safer"
    }
   ],
   "fix": {
    "change": "parts.base.features.hooks.catch_depth.tol=*0.5",
    "kind": "tolerance",
    "driver": "base hooks catch depth",
    "factor": "parts.base.features.hooks.catch_depth",
    "evidence": "SYNTHETIC",
    "from": "2.20 \u00b10.06 mm",
    "to": "2.20 \u00b10.03 mm",
    "first_pass_yield": 0.9672,
    "first_pass_good": 4836,
    "final_yield": 0.9698,
    "good_units": 4849,
    "retries": 13,
    "recovered_by_retry": 13,
    "good_units_per_hour": 464.17239985878,
    "bottleneck": "S2",
    "class_lost": 0,
    "station_lost": 0,
    "station_lost_before": 20,
    "rises": [],
    "gain_units": 21,
    "ties": []
   },
   "candidates": [
    {
     "change": "parts.base.features.hooks.catch_depth.tol=*0.5",
     "kind": "tolerance",
     "driver": "base hooks catch depth",
     "factor": "parts.base.features.hooks.catch_depth",
     "evidence": "SYNTHETIC",
     "from": "2.20 \u00b10.06 mm",
     "to": "2.20 \u00b10.03 mm",
     "first_pass_yield": 0.9672,
     "first_pass_good": 4836,
     "final_yield": 0.9698,
     "good_units": 4849,
     "retries": 13,
     "recovered_by_retry": 13,
     "good_units_per_hour": 464.17239985878,
     "bottleneck": "S2",
     "class_lost": 0,
     "station_lost": 0,
     "station_lost_before": 20,
     "rises": []
    },
    {
     "change": "parts.cover.features.windows.latch_depth.tol=*0.5",
     "kind": "tolerance",
     "driver": "cover windows latch depth",
     "factor": "parts.cover.features.windows.latch_depth",
     "evidence": "SYNTHETIC",
     "from": "2.30 \u00b10.06 mm",
     "to": "2.30 \u00b10.03 mm",
     "first_pass_yield": 0.9664,
     "first_pass_good": 4832,
     "final_yield": 0.969,
     "good_units": 4845,
     "retries": 13,
     "recovered_by_retry": 13,
     "good_units_per_hour": 463.7894983121858,
     "bottleneck": "S2",
     "class_lost": 4,
     "station_lost": 4,
     "station_lost_before": 20,
     "rises": []
    },
    {
     "change": "station.press_cover.effector.pick_loss_rate=*0.5",
     "kind": "station spec",
     "driver": "S4 gripper pick loss",
     "factor": "sequence.press_cover.effector.pick_loss",
     "evidence": "HYPOTHESIS",
     "from": "1 in 1,000 units",
     "to": "1 in 2,000 units",
     "first_pass_yield": 0.9636,
     "first_pass_good": 4818,
     "final_yield": 0.9656,
     "good_units": 4828,
     "retries": 10,
     "recovered_by_retry": 10,
     "good_units_per_hour": 462.1621667391606,
     "bottleneck": "S2",
     "class_lost": 20,
     "station_lost": 20,
     "station_lost_before": 20,
     "rises": []
    }
   ],
   "not_tried": [],
   "first_build": {
    "check": "Measure the gap at each hook on samples, compare with the camera, and gauge it.",
    "owner": "quality and design"
   },
   "figure_anchor": {
    "part": "base",
    "feature": "hooks"
   },
   "seed_range": [
    18,
    39
   ]
  },
  {
   "rank": 5,
   "id": "R5",
   "station": "S3",
   "class": "cell_not_seated",
   "label": "Cell not seated",
   "meaning": "The retainer fingers do not snap over the cell's top edge.",
   "units_lost": 1,
   "share": 0.0002,
   "units_flagged": 1,
   "drivers": [
    {
     "factor": "parts.pcba.components.retainer.features.fingers.undercut",
     "name": "pcba retainer fingers undercut",
     "kind": "product",
     "value": "0.45 \u00b10.03 mm",
     "evidence": "ASSUMPTION",
     "flagged_if_nominal": 0,
     "corr": 0.0066850994513066265,
     "direction": "spread only"
    },
    {
     "factor": "parts.pcba.components.retainer.features.fingers.span_diameter",
     "name": "pcba retainer fingers span diameter",
     "kind": "product",
     "value": "20.05 \u00b10.04 mm",
     "evidence": "ASSUMPTION",
     "flagged_if_nominal": 0,
     "corr": 0.017011140052068458,
     "direction": "spread only"
    },
    {
     "factor": "parts.cell.outline.diameter",
     "name": "cell diameter",
     "kind": "product",
     "value": "19.7 to 20 mm",
     "evidence": "TYPICAL",
     "flagged_if_nominal": 0,
     "corr": 0.014692209552308471,
     "direction": "spread only"
    }
   ],
   "fix": null,
   "candidates": [],
   "not_tried": [],
   "first_build": {
    "check": "Check the retainer fingers snap over inserted cells; measure contact force.",
    "owner": "manufacturing and supplier"
   },
   "fix_skipped": "fewer than 5 units lost, below the search threshold, so no fix was searched",
   "figure_anchor": {
    "part": "board",
    "feature": "retainer"
   },
   "seed_range": [
    0,
    1
   ]
  }
 ],
 "combined": {
  "changes": [
   {
    "risk": "R1",
    "change": "parts.base.outline.diameter=+0.08",
    "driver": "base diameter",
    "from": "29.80 \u00b10.08 mm",
    "to": "29.88 \u00b10.08 mm",
    "kind": "design nominal",
    "to_approve": "A tool-change quote and plan for the new nominal, then a dimensional check"
   },
   {
    "risk": "R2",
    "change": "station.press_cover.effector.part_offset_mm=*0.5",
    "driver": "S4 gripper part offset",
    "from": "\u00b10.10 mm",
    "to": "\u00b10.05 mm",
    "kind": "station spec",
    "to_approve": "A capability run that measures the station's real spread"
   },
   {
    "risk": "R3",
    "change": "parts.cover.features.cell_ribs.reach=-0.04",
    "driver": "cover cell ribs reach",
    "from": "1.60 \u00b10.04 mm",
    "to": "1.56 \u00b10.04 mm",
    "kind": "design nominal",
    "to_approve": "A tool-change quote and plan for the new nominal, then a dimensional check"
   },
   {
    "risk": "R4",
    "change": "parts.base.features.hooks.catch_depth.tol=*0.5",
    "driver": "base hooks catch depth",
    "from": "2.20 \u00b10.06 mm",
    "to": "2.20 \u00b10.03 mm",
    "kind": "tolerance",
    "to_approve": "Supplier capability at the tighter tolerance, and a gauge study"
   }
  ],
  "first_pass_yield": 0.9946,
  "first_pass_good": 4973,
  "final_yield": 0.9972,
  "good_units": 4986,
  "retries": 13,
  "recovered_by_retry": 13,
  "good_units_per_hour": 477.2867778296302,
  "bottleneck": "S2",
  "station_lost": {
   "S4": 13,
   "S3": 1
  },
  "class_lost": [
   {
    "station": "S4",
    "class": "jam_misalignment",
    "label": "Jam / misalignment",
    "units": 13
   },
   {
    "station": "S3",
    "class": "cell_not_seated",
    "label": "Cell not seated",
    "units": 1
   }
  ],
  "sum_of_single_gains": 168
 },
 "product_view": {
  "roles": {
   "base": "base",
   "board": "pcba",
   "cell": "cell",
   "screw": "screw",
   "cover": "cover"
  },
  "base": {
   "d": 29.8,
   "h": 7.0,
   "hooks": {
    "feature": "hooks",
    "angles": [
     90.0,
     210.0,
     330.0
    ],
    "width": 3.0,
    "length": 4.5,
    "head_height": 1.2,
    "catch_depth": 2.2
   },
   "pocket_d": 27.6,
   "seat_depth": 5.6
  },
  "cover": {
   "inner_d": 30.1,
   "wall": 1.0,
   "top": 1.0,
   "skirt": 5.0,
   "windows": {
    "feature": "windows",
    "angles": [
     90.0,
     210.0,
     330.0
    ],
    "width": 3.3,
    "height": 1.6,
    "latch_depth": 2.3
   },
   "ribs": [
    {
     "feature": "cell_ribs",
     "points": [
      [
       0.0,
       0.0
      ]
     ],
     "reach": 1.6
    },
    {
     "feature": "board_ribs",
     "points": [
      [
       0.0,
       12.5
      ]
     ],
     "reach": 4.45
    }
   ]
  },
  "board": {
   "d": 27.2,
   "t": 1.0,
   "holes": [
    {
     "at": [
      0.0,
      11.0
     ],
     "d": 2.1
    },
    {
     "at": [
      0.0,
      -11.0
     ],
     "d": 2.1
    }
   ],
   "retainer": {
    "component": "retainer",
    "angles": [
     0.0,
     180.0
    ],
    "span_d": 20.05,
    "height": 3.9
   }
  },
  "cell": {
   "d": 19.85,
   "h": 3.05
  },
  "screw": {
   "at": [
    [
     0.0,
     11.0
    ],
    [
     0.0,
     -11.0
    ]
   ],
   "d": 2.0,
   "length": 4.5,
   "head_d": 3.8
  },
  "order": [
   "base",
   "board",
   "screw",
   "cell",
   "cover"
  ],
  "op_part": {
   "place_board": "board",
   "drive_screws": "screw",
   "insert_cell": "cell",
   "press_cover": "cover"
  }
 },
 "uncertainty": {
  "seeds": [
   42,
   43,
   44,
   45,
   46
  ],
  "first_pass_yield_range": [
   0.9614,
   0.9674
  ],
  "final_yield_range": [
   0.965,
   0.9696
  ],
  "top_station": "S4",
  "top_station_held": 5,
  "top_risk": "R1",
  "top_risk_held": 3,
  "inspection": [
   {
    "op": "inspect_gap",
    "station": "S5",
    "escapes": 4,
    "false_rejects": 5
   }
  ],
  "sources": {
   "product": 75,
   "station": 26,
   "event": 6
  },
  "drivers_assumed": 5,
  "drivers_shown": 12,
  "mujoco_cross_check": false
 },
 "out_of_scope": [
  "re-driving into formed threads",
  "antenna and RF performance",
  "cosmetic defects",
  "drop",
  "water ingress",
  "cell aging"
 ],
 "replicates": [
  {
   "seed": 43,
   "first_pass_yield": 0.9652,
   "first_pass_good": 4826,
   "final_yield": 0.9684,
   "good_units": 4842,
   "retries": 16,
   "recovered_by_retry": 16,
   "good_units_per_hour": 463.9967436870735,
   "bottleneck": "S2",
   "risk_lost": {
    "R1": 55,
    "R2": 62,
    "R3": 17,
    "R4": 24,
    "R5": 0
   },
   "station_lost": {
    "S1": 0,
    "S2": 0,
    "S3": 0,
    "S4": 134,
    "S5": 24
   }
  },
  {
   "seed": 44,
   "first_pass_yield": 0.9646,
   "first_pass_good": 4823,
   "final_yield": 0.9678,
   "good_units": 4839,
   "retries": 17,
   "recovered_by_retry": 16,
   "good_units_per_hour": 463.5049779235157,
   "bottleneck": "S2",
   "risk_lost": {
    "R1": 64,
    "R2": 54,
    "R3": 15,
    "R4": 24,
    "R5": 0
   },
   "station_lost": {
    "S1": 0,
    "S2": 0,
    "S3": 0,
    "S4": 133,
    "S5": 28
   }
  },
  {
   "seed": 45,
   "first_pass_yield": 0.9674,
   "first_pass_good": 4837,
   "final_yield": 0.9696,
   "good_units": 4848,
   "retries": 11,
   "recovered_by_retry": 11,
   "good_units_per_hour": 464.4079422068255,
   "bottleneck": "S2",
   "risk_lost": {
    "R1": 59,
    "R2": 56,
    "R3": 19,
    "R4": 18,
    "R5": 0
   },
   "station_lost": {
    "S1": 0,
    "S2": 0,
    "S3": 0,
    "S4": 134,
    "S5": 18
   }
  },
  {
   "seed": 46,
   "first_pass_yield": 0.9614,
   "first_pass_good": 4807,
   "final_yield": 0.965,
   "good_units": 4825,
   "retries": 20,
   "recovered_by_retry": 18,
   "good_units_per_hour": 462.1669742544328,
   "bottleneck": "S2",
   "risk_lost": {
    "R1": 58,
    "R2": 63,
    "R3": 15,
    "R4": 39,
    "R5": 0
   },
   "station_lost": {
    "S1": 0,
    "S2": 0,
    "S3": 0,
    "S4": 136,
    "S5": 39
   }
  }
 ]
}
