Skip to content
Hozu
Menu
All trials

Trial 0020 — long-run degradation: twenty changes on one codebase (ADR 0042)

Question: every earlier trial measured one build plus one change. When fresh agent sessions keep changing the same notes app twenty times, without memory and without any repair, does the Hozu app degrade more slowly than the Nuxt app? The criterion was stated before the runs (ADR 0042 F): over steps 1–20, Hozu has fewer regression failures and a lower slope of cost per step against app size.

Setup

Results

Correctness (steps 1–20):

Hozu run 1 Hozu run 2 Nuxt run 1 Nuxt run 2
New checks failed 1 (DA1) 1 (DA1) 0 0
Regression failures (check × step) 8 3 0 0
First failing step 16 17 – –
Silent failures (reviewed by hand) 5 steps (16–20) 4 steps (17–20) 0 0
hozu check / pnpm typecheck + build clean at every step clean at every step green at every step green at every step

Cost (weighted tokens):

Hozu run 1 Hozu run 2 Nuxt run 1 Nuxt run 2
Build (step 0) 160 k 109 k 135 k 147 k
Changes 1–20, total 4.91 M 5.34 M 2.09 M 1.93 M
Mean / median per change 245 k / 191 k 267 k / 188 k 105 k / 104 k 97 k / 94 k
Mean, steps 1–10 → 11–20 173 k → 317 k (+83 %) 168 k → 367 k (+118 %) 97 k → 112 k (+15 %) 85 k → 108 k (+27 %)
Slope of cost per step +11.7 k +12.5 k +1.2 k +2.3 k
Slope of cost per 100 app lines +17.8 k +18.3 k +2.3 k +3.8 k
Calls, steps 1–20 483 494 233 214

Per step (mean of the two runs):

Step Change Hozu Nuxt Ratio Calls H / N
0 build 135 k 141 k 1.0× 15 / 11
1 pin + search 137 k 94 k 1.5× 16 / 12
2 max 60 116 k 64 k 1.8× 16 / 10
3 timestamp 82 k 53 k 1.5× 11 / 7
4 rename 90 k 82 k 1.1× 12 / 10
5 edit in place 179 k 123 k 1.5× 20 / 12
6 tags 321 k 111 k 2.9× 34 / 12
7 archive 241 k 113 k 2.1× 24 / 10
8 search in the URL 125 k 85 k 1.5× 14 / 12
9 move to /notes 119 k 76 k 1.6× 15 / 9
10 undo 295 k 107 k 2.7× 32 / 11
11 load more 193 k 125 k 1.5× 18 / 14
12 instant add 176 k 93 k 1.9× 22 / 11
13 bulk actions 1 259 k 142 k 8.9× 80 / 14
14 rate limit 118 k 74 k 1.6× 16 / 9
15 sharing 306 k 133 k 2.3× 27 / 12
16 admin page 239 k 85 k 2.8× 24 / 9
17 delete account 240 k 103 k 2.3× 26 / 10
18 German 499 k 163 k 3.1× 39 / 15
19 export 182 k 83 k 2.2× 23 / 11
20 remove tags 209 k 104 k 2.0× 22 / 12

Codebase (step 20; slopes over steps 1–20):

Hozu run 1 Hozu run 2 Nuxt run 1 Nuxt run 2
App lines 1 671 (+71.5 / step) 1 681 (+70.5) 1 344 (+57.6) 1 444 (+61.7)
Duplicated lines, final (peak) 2.5 % (4.5 %) 1.0 % (4.4 %) 8.2 % (11.3 %) 6.5 % (9.5 %)
Client JS on the list page, step 0 → 20 22.6 → 25.6 KB 22.6 → 24.1 KB 202 → 232 KB 202 → 233 KB
Hozu: lock entries / changed over the run 71 / 93 70 / 97
Hozu: states / transitions at step 20 16 / 71 16 / 70
Hozu: unreachable states / --update-lock runs over the run 0 / 15 0 / 11

JS is the uncompressed size of the scripts loaded. /login and the list page load the same Hozu bundle.

Per-step curves

Where the calls go (mean per change, anatomy.mjs):

Edit Verify Read app Docs Check Carried cost of docs + reading
Hozu 6.4 7.5 4.0 3.5 1.1 71 k
Nuxt 2.7 2.0 2.1 0 2.3 19 k

Reading the result

The thesis does not hold on this task. Both pre-stated criteria go to Nuxt:

The Hozu regressions come from two mechanisms, both outside the IR, both found in the reference app first:

Failure Runs Root cause
DA1: a deleted account reappears in the admin table (step 17 on) both D9 (new): with JS, the deleting page refetches its live queries on the tag message before the mutation's response clears the cookie. The request carries the old session, and a resolver that creates a user's list on read brings the user back. With the same app and JS off, DA1 passes.
N15: Chrome logs "Transition was aborted … ViewTransition opt-in disabled" (step 16 on) run 1 D7: a page cannot answer 403, so /admin was hand-written HTML from an endpoint without the @view-transition rule the framework pages carry.

What Hozu does better, and keeps better, as the codebase grows:

What the data does not show

Conclusion