| Labels/divider tilts jump to wrong compartments after merge/split | Remap from normalizeIdsWithRemap not threaded through a parallel array | Remap every array in the same set(); copy paramSlice.ts mergeCells |
| Sync/share returns 400 for designs that work locally | Client enum/range added without the server mirror | Grep api/lib for the field; extend VALID_* / CONSTRAINTS |
New param round-trips as undefined through share/sync | pickAllowedParams strips keys not in ALLOWED_PARAM_KEYS | Add the key in api/lib/designerValidation.ts |
| Preview never updates (or regenerates on lock/hide clicks) | Setter skipped pushHistoryEntry, or cosmetic prop defaulted to affectsGeometry: true | Fix the setter in paramSlice.ts; see store/helpers.ts |
| Error banner right after a compartment edit | useGeneration pre-flight validateCompartmentSizes rejected (cell < MIN_COMPARTMENT_SIZE 5mm) | Expected — surface via helpers in utils/validation.ts, never bypass |
| Engraving lands on the wrong "Comp. N" | Indexed compartmentTexts by display number instead of ID | Map through getCompartmentReadingOrder only at the display layer |
Front tab missing in edges: 'both' with no error | Builder drops it when 2·depth + 2·inset > compartment depth | By design — the useLabelTabsSection warning is the signal |
| One text edit re-runs every engraved-text solid | textSolidCache keys serialize the WHOLE compartmentTexts array | By design — don't assume per-entry caching |
| Duplicate history entries / worker re-runs on identical text | No-op guards removed from setCompartmentText / setCompartmentDividerHeight | Keep the guards; inputs commit on both idle-flush and blur |
Persisted JSON gains dividerHeight: 'auto' noise | 'auto' and undefined are the same state | setCompartmentDividerHeight omits the field for 'auto'; keep it that way |