feat(plating): per-step compliance gates + backfill — 0 CRITICAL gaps

Per-step audit caught real enforcement bugs across all 9 WO kinds.
Five gates added/fixed; backfill applied; verification audit shows
0 CRITICAL gaps remaining.

**1. Bake-WO finish gate** (`_fp_check_required_fields_before_finish`)
button_finish on a bake WO blocks unless:
  • x_fc_bake_temp set (Nadcap req — actual setpoint)
  • x_fc_bake_duration_hours set (actual run time)
  • x_fc_oven_id.chart_recorder_ref set on the oven
    (so the chart for THIS run can be retrieved by an auditor)

**2. Rack-WO start gate** added to button_start.

**3. Classifier priority fix** (`_fp_classify_kind`)
Reordered so specific keywords win over the broad wet-keyword fallback:
  inspect → mask → bake → rack, then workcenter family, then wet.
"Post-plate Inspection" now → inspect (was wrongly → wet).
"Oven bake (Post de-rack)" now → bake (was wrongly → rack).

**4. Auto-populate** target_thickness + dwell_time at WO generation.
Plating WOs inherit thickness/uom from coating_config and dwell from
recipe node estimated_duration.

**5. Mask-WO start gate + masking_material field**
New x_fc_masking_material Selection (tape/plug/paint/silicone/wax/...).
Required to start mask/de-mask WO. Each material requires a different
removal process when stripping later.

**View** — Process Details tab branches by kind:
  wet → Bath/Tank/Rack/Thickness/Dwell
  bake → Oven/Temp/Duration
  rack → Rack/Fixture
  mask → Masking Material
  inspect/other → informational alerts

**Backfill** (`scripts/fp_backfill.py`) — idempotent catch-up:
  • chart_recorder_ref on every oven (1)
  • rack_id on existing rack/de-rack WOs (91)
  • bake_temp + bake_duration 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 the OLD
    wet-keyword classifier had wrongly tagged.

**Per-step audit** (`scripts/fp_per_step_audit.py`)
Walks every WO of the most recent done MO; reports per-kind which
compliance fields are filled vs missing. Re-runnable for regressions.

**Final verification** on freshly-run MO:
  • 0 CRITICAL gaps across all 9 WO steps
  • 2 IMPORTANT (dwell_time + rack_id on E-Nickel Plating — both
    inherited from recipe node data, not enforcement bugs)
  • Classifier correct for all 9 step types

12 negative tests still passing.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
gsinghpal
2026-04-19 11:42:12 -04:00
parent c7ecd90982
commit 7fa54d8fc9
7 changed files with 483 additions and 134 deletions

View File

@@ -168,18 +168,15 @@
</xpath>
<!-- 5b. Process Details tab — content adapts to WO kind so
operators see only the equipment fields that matter for
their step (bath/tank for wet, oven for bake, etc.). -->
operators see only the equipment fields that matter. -->
<xpath expr="//notebook/page[@name='time_tracking']" position="after">
<page string="Process Details" name="plating_details">
<!-- Always-visible: facility (set everywhere) -->
<group>
<group string="Where">
<field name="x_fc_facility_id"/>
</group>
</group>
<!-- Wet / bath WOs (plating, etch, rinse, strip, ...) -->
<!-- Wet / bath WOs -->
<group invisible="x_fc_wo_kind != 'wet'">
<group string="Bath &amp; Tank">
<field name="x_fc_bath_id"
@@ -195,52 +192,42 @@
<field name="x_fc_dwell_time_minutes"/>
</group>
</group>
<!-- Bake / cure WOs -->
<group invisible="x_fc_wo_kind != 'bake'">
<group string="Oven">
<field name="x_fc_oven_id"
required="x_fc_requires_oven"/>
</group>
<group string="Bake Parameters">
<group string="Bake Parameters (required at finish)">
<field name="x_fc_bake_temp"/>
<field name="x_fc_bake_duration_hours"/>
</group>
</group>
<!-- Rack / de-rack WOs -->
<group invisible="x_fc_wo_kind != 'rack'">
<group string="Rack">
<field name="x_fc_rack_id"/>
<field name="x_fc_rack_id" required="1"/>
<field name="x_fc_rack_ref"/>
</group>
</group>
<!-- Mask / De-mask WOs — workcenter is the bench;
no extra equipment fields, just a hint -->
<!-- Mask / De-mask WOs -->
<group invisible="x_fc_wo_kind != 'mask'">
<div class="alert alert-info" role="alert">
Masking / de-masking — work centre identifies
the bench. Use chatter for any per-job notes
on tape pattern, masking material, etc.
</div>
<group string="Masking">
<field name="x_fc_masking_material" required="1"/>
</group>
</group>
<!-- Inspection / QC WOs -->
<!-- Inspection -->
<group invisible="x_fc_wo_kind != 'inspect'">
<div class="alert alert-info" role="alert">
Inspection — record Fischerscope readings via
the Tablet Station (calibration std + n
measurements per part). Readings auto-link
to the CoC at MO done.
the Tablet Station. Cal-std + n measurements
per part. Readings auto-link to the CoC.
</div>
</group>
<!-- Generic WOs that don't fit any bucket -->
<group invisible="x_fc_wo_kind != 'other'">
<div class="alert alert-light text-muted" role="alert">
Generic operation — equipment is identified
by the work centre. Use chatter for job notes.
by the work centre.
</div>
</group>
</page>