Per-step audit caught real enforcement bugs across all 9 WO kinds in
the recipe (Masking, Racking, Plating, De-Masking, Oven baking, etc.).
Five gates added or fixed; 0 CRITICAL gaps remain after a verification
run on a fresh MO.
**1. Bake-WO finish gate** (`_fp_check_required_fields_before_finish`)
button_finish on a bake WO now blocks unless:
• x_fc_bake_temp set (Nadcap req — actual setpoint, not just oven)
• x_fc_bake_duration_hours set (actual run time at temp)
• x_fc_oven_id.chart_recorder_ref set (so the chart for THIS run
can be retrieved by an auditor — required for AS9100/Nadcap)
Run-time data lives at FINISH, not START — operators don't know
temp/duration until the bake is done.
**2. Rack-WO start gate** added to the existing button_start gate.
Per-rack life tracking + which physical fixture handled the parts.
**3. Classifier priority fix** (`_fp_classify_kind`)
"Post-plate Inspection" was matching the `plat` wet keyword and
getting kind=wet (then required to have bath/tank). Reordered:
1. Explicit equipment links (bath_id/oven_id)
2. Specific keywords (inspect → mask → bake → rack)
— bake before rack so "Oven bake (Post de-rack)" → bake
3. Workcenter wet families
4. Wet name keywords as last fallback
**4. Auto-populate target_thickness + dwell_time** at recipe→WO
generation. Plating WOs inherit:
• thickness_target from coating_config.thickness_max
• thickness_uom from coating_config.thickness_uom
• dwell_time_minutes from recipe node's estimated_duration
So aerospace QC has the spec target on every WO without paper.
**5. Mask-WO start gate + masking_material field**
New x_fc_masking_material Selection (tape/plug/paint/silicone/wax/
mixed/other). Required to start a mask WO. Needed later when
stripping or replating because each material requires a different
removal process.
**View** (`mrp_workorder_views.xml`)
Process Details tab now branches by kind:
wet → Bath/Tank/Rack/Thickness/Dwell
bake → Oven/Temp/Duration
rack → Rack/Fixture
mask → Masking Material
inspect/other → informational alerts only
WO Kind shows as colour-coded badge in header.
**Backfill** (`scripts/fp_backfill.py`)
Idempotent script that catches up existing data:
• chart_recorder_ref on every oven
• rack_id on existing rack/de-rack WOs (91 backfilled)
• bake_temp + bake_duration_hours on existing bake WOs (33)
• masking_material on existing mask WOs (62)
• thickness/dwell on existing plating WOs (38)
• Cleared 7 legacy bath/tank from inspection WOs that had been
misclassified by the OLD wet-keyword classifier.
**Per-step audit** (`scripts/fp_per_step_audit.py`)
Walks every WO of the most recent done MO and reports per-kind
which compliance fields are filled vs missing. Re-runnable to
catch regressions.
**Final state on freshly-run MO 00049:**
• 0 CRITICAL gaps
• 2 IMPORTANT gaps (dwell_time + rack_id on E-Nickel Plating —
both inherited from recipe node data, not enforcement bugs)
Negative tests still passing (12 total).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>