design 005 wants an amendment: three premises did not survive implementation (S1's 1.8x, the phase ordering, S10's trigger) nf-gyu ← Beads

open priority 2 task unassigned

Twinned from https://github.com/cfsh/ninefold/issues/755 by tools/beads/import_github.py's reconcile pass.

Design 005 is accepted and the implementation is under way (#686). Three of its premises did not survive measurement during that implementation. No mainline suggestion changes — every one of S1–S18 still ships — but the doc's cost/trust reasoning and its phase ordering are wrong in ways a later round would inherit.

design_docs/** is Tier 2 and needs @aedanpope, so this is an issue proposing the amendment rather than a PR making it. All three are recorded with full evidence on the issues that own them; this collects them so a later round does not have to find them.

---

1. S1's 1.8× is retracted. The import cache is a correctness fix, not a cost win

The doc calls a warm import cache *"the single largest per-probe win, ~1.8×"* (§0, §2.2's table, S1, §5.5, option D). Six paired alternating runs of tonapse-home on nf-dev-sg, each pair back to back so drifting box load cancels:

| pair | warm | cold | |---|---|---| | 1 | 9.25 | 8.84 | | 2 | 9.39 | 8.99 | | 3 | 13.29 | 10.76 | | 4 | 9.74 | 9.00 | | 5 | 10.13 | 9.58 | | 6 | 11.86 | 9.43 |

Warm is slower in 6 of 6, by 0.4–2.4 s — a warm run loads 222 MB of resources where a cold one fails fast. Two candidate explanations for the doc's 21.6 s → 11.8 s were tested and both refuted: there is no first-run project-setup penalty (three runs after wiping .godot but for mono/: 9.57 / 9.00 / 8.84 s, flat), and dotnet build is only ~3 s of a warm probe.py. Load alone swung identical runs between 8.8 s and 13.3 s, which is wider than the effect claimed.

S1 still ships and still matters — it closes #619, where probes render with no textures and no audio and exit 0. Cold-vs-warm tonapse-home differs by 1014 / 3210 / 1488 px across its three shots. Three dev worktrees on this box were in that state.

*What to amend:* §0's bullet, §2.2's table row, S1's "highest value" ranking, §5.5.5, and option D's arithmetic (1.8× × 1.63× × 43% ≈ 5.5×, which loses a term).

Evidence: #738, PR #739, and the correction comment on #686.

---

2. ⚠️ Cost is gated on trust, not parallel to it. §6's phase ordering is wrong

§5.5 says cost and trust dominate selection *"and in that order"*, and §6 then runs them as parallel tracks — cost is Phase 1, trust is Phase 2. They are not parallel. The worker pool (S2, piece 2) cannot ship until the flake work (S9, piece 5) lands, because parallelism falsifies the assertions.

Full 34-probe sweeps, same tree, same commit, concurrency as the only variable:

| workers | load at start | result | failing set | |---|---|---|---| | 8 | 11.35 | 28 / 6 | butterbar-gate, explore-walk, focus-grammar, playhead-song, playtest-capture, sound-modal | | 6 | 1.16 | 32 / 2 | butterbar-gate, focus-grammar | | 2 | 3.63 | 33 / 1 | row-label-wrap | | 1 | 17.76 | 34 / 0 | — |

A different failing set at each level is the signature of contention. Re-running the six 8-way failures one at a time on the same box: all six passed. The harness printed the cause itself — *"the 2-frame wait and the steps bracketing it took 1501 ms against a 300 ms budget … that is this host's frame rate, NOT the UI"*.

§2.2 already says *"on a shared box adding workers cannot recover what contention takes"*. This is the other half: they can actively destroy the signal.

A load-aware pool (cores − loadavg) was tried and is not enough — the load average is a lagging indicator and cannot see the load the sweep itself creates; at load 1.16 it chose 6 workers and still manufactured a failure.

*What to amend:* §6's Phase 1/Phase 2 framing, and S2's status, which should carry the trigger "after piece 5".

⚠️ The 2.19× is real and still collectable — 70 s → 31 s across 8 probes, three clean rounds on an idle box, better than §2.2's 1.63× because that was measured at 4-way on a box that now reports 8 cores.

Evidence: #746 (full write-up and the reversal), corroborated on #620 and #598.

---

3. A serial sweep came back 34/34. S10's trigger has not fired, and piece 5b's premise needs re-reading

§6 Phase 2 is explicit: *"Fix the three, re-sweep, and if Linux comes back 34/34 then S10 is dead weight and should not be built."*

It came back 34/34 — under load 17.76 — without any of the three being touched. butterbar-gate, focus-ring and playhead-song all passed.

Two consequences:

⚠️ One clean sweep is not proof, and the post-merge gate runs on a box whose load nobody controls. But the next person should reproduce serially on a quiet box before treating any of the three as broken.

*What to amend:* S10's status line, and piece 5b's description in §8.

Evidence: #700, and the 5b discussion on #686.

---

What is NOT affected

Refs #686 · Refs #738 · Refs #746 · Refs #700 · Refs #619 · Refs #620

Dependencies

None.

Comments

No comments.

Add a comment