Skip to content
Hozu
Menu
All trials

Trial 0002 — Is Tenon actually easier for an AI to write and maintain? (before Phase 6)

Question from the user: confirm that Tenon really helps AI authoring and maintenance before building more. Method: the same page exists twice, examples/showcase (Tenon) and bench/parity/nuxt (Nuxt 4.5, pixel identical, docs/benchmarks/0002). Twelve mistakes that AI agents commonly make were injected one at a time into the equivalent spot of each version. Each version was then checked with its standard tooling:

Caveat: this measures what the toolchains catch, not how well a fresh agent learns the API.

Mistake injection

# Mistake Tenon Nuxt
M1 typo in a state value: compare tab with 'desing' ✖ missed ✔ TS2367
M2 invalid value sent: SelectTab { tab: 'desing' } (payload is an enum) ✖ missed ✔ TS2820
M3 misspelled Tailwind class font-semibld ✔ TN026 ✖
M4 img without width/height (layout shift) ✔ TN028 ✖
M5 user input rendered as HTML (XSS) ✔ TN030 ✖
M6 link to a route that does not exist, written as a plain string '/abuot' ✖ ✖
M7 misspelled attribute minlenght ✔ TS2561 + TN014 ✖
M8 wrong prop type passed to a widget ✔ TS2322 ✖
M9 list key that does not exist ✔ TS2345 + TN008 ✔ TS2339
M10 stale read after renaming a state field ✔ TS2339 + TN008 ✔ TS2339
M11 behaviour changed silently ("reverse" no longer reverses) ✔ TN018 ✖ (no tests)
M12 invalid enumerated attribute value type: 'sumbit' ✖ missed ✔ TS2820

Totals:

Tenon Nuxt
Mistakes caught 8 / 12 5 / 12
Caught only by this toolchain M3, M4, M5, M7, M8, M11 M1, M2, M12

Both toolchains missed M6.

What Tenon misses, and why

Tenon misses mistakes in the most common AI error class, typos inside string literals. Here plain Vue is stricter.

Diagnostics and reading cost

Writing cost (output tokens)

Tenon Nuxt
Source for the same page 23.3 KB (views 15.5, machine 1.8, contracts 1.2, schemas/events 1.4, widgets and effects 3.4) 13.4 KB (index.vue 10.6, Widget.vue 1.3, about 1.1, config 0.4)

Tenon costs about 1.7× the output for the same page. Part of that buys verification: contracts, schemas and typed events. The rest is syntax: ui.div({ class }, [ … ]) is longer than HTML.

Learning cost: Nuxt is in every model's training data. Tenon is not, so each session must read CLAUDE.md (7.5 KB) plus examples. This trial does not measure that. A fresh-context A/B trial is the only honest test.

Verdict

Proposed before Phase 6

  1. Close the literal holes:

    • op.eq/neq with NoInfer on the right side
    • typed ui.send payloads
    • typed enumerated attributes
    • a validator rule that checks every literal against its JSON Schema (enum, const, type), so hand-edited IR is caught too
    • internal href strings starting with / must use ui.link

    Re-run this injection until Tenon catches ≥ 11 / 12.

  2. Fresh-agent A/B trial: agents with no Tenon context build the same small app and then apply the same change request, once in Tenon and once in Nuxt. Measure tokens read and written, turns, defects left (hidden acceptance checks) and the time to a correct change.

    • Decide Phase 6 from that result.
    • This spends model tokens, so it needs approval.
  3. Reduce syntax overhead only if (2) shows it matters. Candidates are shorter builders for text-only elements, decided by an ADR.

Follow-up: step 1 done (ADR 0012)

Re-running the same injection:

Tenon Nuxt
Mistakes caught 12 / 12 5 / 12
# Caught now by
M1 TS2345 + TN031
M2 TS2345 + TN031
M6 TN032
M12 TS2820 + TN031

Caveat: these twelve mistakes were known when the fix was written. Step 2 (the fresh-agent trial) is the test that was not tuned for this result.

Correction after review

The injected mistakes were modelled on human typing errors, and AI agents rarely make those. The checks from step 1 still matter, because they catch any value outside the schema: an invented enum member, React/Vue attribute names such as className, a guessed route path, or a stale field name. But they do not measure AI failure modes. Trial 0003 replaced this proxy with fresh agents building a real app. In that trial no agent produced an out-of-schema literal.