# Quality scorecard (the ratchet) Cheap to measure (`grep -c`, `wc -l`, `clj-kondo`), recorded **before/after each migration** in the commit message and in the results table below. **No metric may regress for the touched modal** without a written exception in `gotchas.md`. These are directional evidence, not targets to game — always paired with the e2e parity gate. ## Heuristics | # | Heuristic | Measure | Target | |---|-----------|---------|--------| | 1 | Faked cursor positions (not cursors themselves) | `grep -cE 'with-cursor\|MapCursor\.'` re-roots + `grep -c 'defn.*-no-cursor'` | → 0 (top-rooted cursors are fine) | | 2 | Implicit state merges (snapshot/cursor) | count merge sites | → 0 (forms); explicit `put-step` only (wizards) | | 3 | Branching complexity | `clj-kondo`, or count `cond`/`condp`/`case`/nested `if` + max depth | net ↓ | | 4 | Lines of code | `wc -l` on the modal's file(s) | net ↓ | | 5 | Reuse / cross-form similarity | cookbook components reused; duplicated-block count | reuse ↑, dup ↓ | | 6 | Route count | count routes for the modal | → 2 (+1 for add-row) | | 7 | OOB swaps | `grep -c hx-swap-oob` | → 0 unless a justified disjoint-region case is documented | | 8 | Attribute consistency | mixed `:x-`/`"x-"` encodings in migrated template | → 0 | ## How to measure (copy/paste) ```bash F=src/clj/auto_ap/ssr/.clj echo "LOC $(wc -l < $F)" echo "no-cursor twins $(grep -c 'defn.*-no-cursor' $F)" echo "faked-cursor roots $(grep -cE 'with-cursor|MapCursor\.' $F)" echo "snapshot merges $(grep -c ':multi-form-state :snapshot' $F)" echo "branch forms $(grep -cE '\(cond |\(condp |\(case |\(when-not ' $F)" echo "hx-swap-oob $(grep -c 'hx-swap-oob' $F)" echo "mixed string hx- $(grep -cE '\"hx-[a-z]' $F)" # route count: count this modal's entries in src/cljc/auto_ap/routes/*.cljc ``` ## Results Each migration appends one row (after-numbers), referencing the before in the diff. | Phase | Modal | LOC | Routes | no-cursor twins | faked roots | snapshot merges | OOB | mixed hx- | cookbook reused / added | |-------|-------|-----|--------|-----------------|-------------|-----------------|-----|-----------|-------------------------| | 1 (baseline) | Transaction Edit `transaction/edit.clj` | 1608 | ~12 | 1 | 2 | ~75 | 0 | 8 | — / seeded 7 entries | > Phase 1 is distillation only — no app code changed. The Transaction Edit row is the > **before** baseline that Phase 2 must beat (target: routes → ~3, no-cursor → 0, faked > roots → 0, snapshot merges → 0, LOC ↓, mixed hx- → 0). The `0` OOB is already achieved > by the merged reference and must not regress.