# A2UI Express test programme: approach, results, caveats (for checking)

Tables were generated by a script from the raw result files; prose is hand-written. Run dates 2026-10-28 and 2026-10-29. The figures are small-sample measurements (six briefs, one to three repeats).

## 1. What this is
Google published A2UI Express and the SDK's swappable inference formats on 27 Oct 2026 ([post](https://developers.googleblog.com/fast-reliable-a2ui/), [Express proposal](https://a2ui.org/specification/proposals/express/a2ui_express/)). We tested, on our own catalogue (557 atoms) and six briefs (T1-T6, the same briefs as our earlier plain-agent and Jev / A2UI routing tests, so results can be compared across them): (a) Express vs Direct JSON, (b) catalogue pruning ("slices") per agent class, (c) a decision-model chooser (Jev, Clef) in front of the writer model, (d) a one-line repair loop.

## 2. Approach
- **Briefs and keys.** T1 Learning, T2 Data display, T3 Marketing/commerce, T4 Data display, T5 Marketing/commerce, T6 Learning. Scored by set-F1 of atoms used vs answer key v2; key v3 differs only by also accepting `filterable_list` on T4. The comparison was pre-registered.
- **Conditions.** A whole catalogue; B rule-based family slice; C oracle slice for 3 agent types and D oracle for 6 (both built from the answer key, so they are a ceiling); E wrong-domain slice; F random; G blind purpose/capability tags. Slices are written as separate catalogue files with their own catalogId, served through the SDK's `ComponentPruningTransformer` / `CatalogConfig`; the compiler rejects atoms outside the slice.
- **Formats.** Express = `ExpressFormatFactory`; Direct JSON = `DirectJsonFormatFactory` (a2ui-agent-sdk 0.9.0). A reply "compiled" if `parse_response` accepted the whole reply.
- **Models and sampling.** Haiku 4.5 at temperature 0 (it then returns the same or one of two replies per brief across repeats, so n is closer to 6 briefs than 18). Haiku 5.5, Sonnet 5.5, Opus 5.5 and the Gemini models reject a temperature setting, so they ran at default sampling. Gemini 3.5 Flash-Lite via the Developer API (free tier); Gemini 3.5 Flash via a Vertex AI Express key.
- **Hints.** `hints_v1.txt` and `hints_v2.txt` were written after seeing failures on these same briefs (post hoc).
- **Repair.** One attempt with the rules, the signatures of the components used and the parser error; coarser than the proposal's per-line micro-refinement. One bad line fails the whole reply in the SDK as we used it.
- **Choosers.** Jev and Clef-flash pick an atom per slot from the slice (Clef through Cloudflare's REST API, one request per pick, no retries); A second step then narrows the catalogue to the picks and lets the writer model produce Express.
- **Plain-agent baseline.** Haiku 4.5 as an agent with search tools: F1 0.774 (key v2) / 0.941 (v3), 18/18 rendered, 4.7 turns, $0.0222 per brief.
- **Prices.** Haiku 5.5: $0.10 in / $0.50 out per M tokens for prompts up to 100,000 tokens, $0.50 / $2.50 above (the whole catalogue is about 108K tokens, so it pays the higher tier). Confirmed on the [Anthropic pricing page](https://platform.claude.com/docs/en/about-claude/pricing) on 2026-10-28. No prompt caching is assumed.

## 3. Results
### 3.1 Express vs Direct JSON, by model (slice C, all replies)
| Model | Express compiled | JSON compiled | Output tokens/reply (Express / JSON) | Token ratio | Seconds/reply (Express / JSON) | Time ratio |
|---|---|---|---|---|---|---|
| Haiku 4.5 (T=0) | 9/18 | 18/18 | 449 / 1213 | 2.70x | 4.7 / 10.8 | 2.28x |
| Haiku 5.5 | 16/18 | 15/18 | 1791 / 2553 | 1.43x | 8.7 / 11.5 | 1.32x |
| Sonnet 5.5 | 18/18 | 15/18 | 928 / 1985 | 2.14x | 7.6 / 15.1 | 2.00x |
| Opus 5.5 | 18/18 | 14/18 | 1184 / 1873 | 1.58x | 12.4 / 17.6 | 1.42x |
| Gemini 3.5 Flash-Lite (rerun) | 18/18 | 17/18 | 527 / 788 | 1.50x | 2.3 / 2.9 | 1.30x |
| Gemini 3.5 Flash (Vertex Express) | 15/18 | 14/18 | 4752 / 6591 | 1.39x | about 18 / 24 (thinking on, 29 Oct first re-run) | 1.19x paired, n=11, range 0.72-3.11x (thinking on: not established) |
| Gemini 3.5 Flash, thinking off (re-run 2026-10-29, tag R) | 15/18 | 18/18 | 648 / 1102 (median) | 1.71x (paired median) | 3.8 / 5.1 (median) | 1.24x paired (n=15, range 0.91-1.67; Express faster in 12 of 15) |

Notes: Gemini output tokens include thinking tokens (the adapter adds `thoughtsTokenCount`; Gemini 3.5 Flash's 4,752 tokens per reply is probably mostly thinking, and Google ran thinking off in its eval). Haiku 4.5's Express compile rate is low (see 3.4), and the ratios count its failed replies. Google says up to 3x fewer tokens and up to 3x lower latency; the proposal says 55-70% fewer output tokens.

### 3.2 Pruning (Haiku 5.5, Express)
| Condition (Haiku 5.5, Express) | Atoms shown | Prompt chars | Input tokens | Cost/brief (tiered) | Cost/brief (flat $0.10/$0.50) | F1 (key v2 / v3) | Compiled |
|---|---|---|---|---|---|---|---|
| A: whole catalogue | 557 | 294,155 | 107,820 | $0.0576 | $0.0115 | 0.50 / 0.67 | 18/18 |
| B: rule-based family slice | 207 | 98,257 | 35,413 | $0.0044 | $0.0044 | 0.59 / 0.76 | 18/18 |
| G: blind purpose/capability tags | 284 | 138,594 | 50,121 | $0.0058 | $0.0058 | 0.66 / 0.83 | 18/18 |
| C: oracle slice, 3 agent types | 31 | 16,676 | 6,010 | $0.0015 | $0.0015 | 0.68 / 0.68 | 16/18 |

Narrowest oracle slice (D, Haiku 4.5 runs): 17 atoms on average, 10,700 characters per prompt (whole catalogue: 294,155 characters). Ratio whole catalogue / rule slice B: about 13x tiered, about 2.6x flat-priced (whole catalogue / oracle slice C is about 38x tiered, because the oracle slice is tiny). The F1 gain from slicing is mostly one brief (T5) and is not statistically significant (bootstrap over 6 briefs, independent audit).

### 3.3 Decision-model choosers (same saved needs; only the chooser differs)
| Slice | Jev F1 | Clef-flash F1 | Clef (full) F1 | Jev and Clef-flash identical picks |
|---|---|---|---|---|
| B rule-based | 0.516 | 0.513 | 0.573 | 1/6 |
| C oracle (3 types) | 0.792 | 0.793 | 0.724 | 0/6 |
| D oracle (6 types) | 0.791 | 0.801 | 0.757 | 2/6 |
| G blind tags | 0.555 | 0.726 | 0.560 | 0/6 |

Times are not comparable (Clef reuses Jev's decomposer output). The full Clef model scored below Clef-flash and Jev on the oracle slices (C, D) and a little above on the rule-based slice B; six briefs, so these differences are small.

### 3.4 Haiku 4.5 groups
| Haiku 4.5 group (6 briefs x 3 repeats, T=0 unless noted) | Compiled before repair | Compiled after repair | F1 (key v2) | Cost/brief | Secs/reply |
|---|---|---|---|---|---|
| Express, oracle D, default temperature | 50% | 50% | 0.38 | $0.0057 | 5.6 |
| Express, oracle D, T=0 | 33% | 33% | 0.29 | $0.0055 | 4.9 |
| Express, oracle C, T=0 | 50% | 50% | 0.44 | $0.0070 | 4.7 |
| Express, rule slice B, T=0 | 50% | 50% | 0.34 | $0.0308 | 5.9 |
| D + hints v1 (post hoc) | 83% | 83% | 0.59 | $0.0060 | 5.3 |
| D + hints v2 (post hoc) | 83% | 83% | 0.67 | $0.0056 | 5.1 |
| D + hints v2 + one repair | 83% | 100% | 0.79 | $0.0069 | 5.1 |
| Cascade: rule slice + Jev picks + hints v2 + repair (Jev cost assumed: $0.042/M input, output unpriced) | 67% | 100% | 0.64 | $0.0144 | 5.9 |
| Direct JSON, oracle C, T=0 | 100% | 100% | 0.72 | $0.0149 | 10.8 |
| Direct JSON, oracle D, T=0 | 100% | 100% | 0.60 | $0.0118 | 10.6 |

### 3.5 Elemental (HTML-like format), slice C, all replies
| Model | Format | Compiled | Output tokens/reply | Input tokens | Seconds/reply | F1 (key v2) |
|---|---|---|---|---|---|---|
| Haiku 5.5 | Express | 16/18 | 1791 | 6010 | 8.7 | 0.68 |
| Haiku 5.5 | Direct JSON | 15/18 | 2553 | 12074 | 11.5 | 0.61 (re-walked) |
| Haiku 5.5 | Elemental | 18/18 | 1673 | 6607 | 7.8 | 0.81 |
| Sonnet 5.5 | Express | 18/18 | 928 | 6010 | 7.6 | 0.69 |
| Sonnet 5.5 | Direct JSON | 15/18 | 1985 | 12074 | 15.1 | 0.53 (re-walked) |
| Sonnet 5.5 | Elemental | 18/18 | 1555 | 6607 | 12.1 | 0.76 |
| Gemini 3.5 Flash-Lite (rerun) | Express | 18/18 | 527 | 4580 | 2.3 | 0.67 |
| Gemini 3.5 Flash-Lite (rerun) | Direct JSON | 17/18 | 788 | 7721 | 2.9 | 0.66 (re-walked) |
| Gemini 3.5 Flash-Lite (rerun) | Elemental | 17/18 | 642 | 4900 | 2.4 | 0.65 |

Elemental: the model writes HTML-shaped markup (`<ui-hero ...>`), the SDK compiles it to A2UI JSON, and our renderer turns that into HTML. It needed a capitalised-name copy of each slice catalogue (section 4.2). Failures seen: an object literal inside an attribute, and a plain `<items>` tag (only `ui-*` tags are allowed). One repair call per failed reply (Gemini 3.5 Flash-Lite,): the object-literal reply then compiled; the `<items>` reply was rewritten with an unknown `ui-box` tag and still failed. So 17 of 18 compiled after one repair attempt (small n; originals untouched). Experimental in SDK 0.9.0; one model-run set per model.

### 3.6 The 80x test: Jev decides the layout
Google's post: Jev answers about 30 typed layout questions per screen, code builds the components, a small model writes only the text; "up to 80x". Our minimal version: 3 fixed layouts (lesson, dashboard, landing); ONE Jev request per brief with 3 typed questions (which layout, how many items, call-to-action yes/no); code builds the Express screen from the answers (about 0.2 ms); Gemini 3.5 Flash-Lite writes only the text fields as JSON; the SDK compiles the result against the brief's slice. 6 briefs x 3 repeats = 18 screens, all compiled; Jev chose the right layout for every brief and gave the same answers on every repeat.

Pipeline per screen (mean): Jev request 0.18 s + writer 1.39 s + code build 0.0002 s = **1.57 s**; writer tokens 200 in / 201 out; Jev tokens 598 in / 101 out.

| Whole-screen baseline | Secs/reply | Pipeline speed-up | Comparison |
|---|---|---|---|
| Flash-Lite, whole screen, Express | 2.26 | 1.4x | same model, different task (no catalogue, fixed templates) |
| Flash-Lite, whole screen, Direct JSON | 2.94 | 1.9x | same model, different task (no catalogue, fixed templates) |
| Flash-Lite, whole screen, Elemental | 2.36 | 1.5x | same model, different task (no catalogue, fixed templates) |
| Haiku 4.5, whole screen, Direct JSON | 10.79 | 6.9x | different (larger) model |
| Sonnet 5.5, whole screen, Express | 7.58 | 4.8x | different (larger) model |
| Sonnet 5.5, whole screen, Direct JSON | 15.14 | 9.6x | different (larger) model |
| Opus 5.5, whole screen, Direct JSON | 17.62 | 11.2x | different (larger) model |

Reading it: Jev's own request took about 0.18 s (inside the 100-300 ms Google quotes for its requests) and the writer about 1.4 s. **Time to complete screen:** about 1.6 s, the same order as the 0.8-1.7 s Google reports for complete screens; against the same Flash-Lite model writing the whole screen it is about 1.4x (Express) to 1.9x (Direct JSON) faster, against larger models' whole-screen replies 4.8x to 11.2x. **Time to layout** (Jev + code, before any text exists): 0.18 s, which is Flash-Lite Express 12x, Flash-Lite Direct JSON 16x, Flash-Lite Elemental 13x faster than whole-screen replies (the largest ratios, 59x to 96x, are against larger models' Direct JSON). Google does not say what its 80x is measured against, so we can neither confirm nor refute it; ratios of this size appear only on the time-to-layout view. **Quality:** the pipeline's screens score atom F1 0.31 (key v2; per brief {'T1': 0.55, 'T2': 0.57, 'T3': 0.75, 'T4': 0, 'T5': 0, 'T6': 0}) against 0.67 for whole-screen Flash-Lite Express, because the three fixed templates do not satisfy the briefs (0.00 on T4, T5, T6); Jev choosing the layout that matches the brief's domain is not the same as the template covering the brief. We ask 3 questions where Google asks about 30. 'Same model' means the same writer model, not the same task: the writer here sees about 200 input tokens and no catalogue.

### 3.7 Content check (first reviewer, 2026-10-29; 72 cells = 12 run sets x 6 briefs, repeat 1 only, viewed at 640 px)
Each cell was graded twice: **rendered** (what a viewer sees) and **payload** (the model's own output against the brief, ignoring harness and renderer defects). Good / minor / major / fail.

| Format | n | Rendered g/mi/ma/f | Payload g/mi/ma/f | Good or minor, rendered -> payload |
|---|---|---|---|---|
| Express | 30 | 13/5/8/4 | 21/5/0/4 | 18 -> 26 |
| Elemental | 18 | 3/9/5/1 | 11/6/0/1 | 12 -> 17 |
| Direct JSON | 18 | 1/2/6/9 | 7/3/2/6 | 3 -> 10 |
| Jev layout pipeline | 6 | 1/0/2/3 | 1/0/2/3 | 1 -> 1 |

What it shows: where the model's own payload is judged, 54 of 72 cells are good or minor; no factual errors were found in the lessons or definitions, and the numbers checked were right. The rendered grades are much lower (27 cells worse than the payload), mostly from renderer defects (17 cells) and test-harness defects (9). Real model failures: Direct JSON from Haiku 4.5 and Flash-Lite left components unreachable from the root in 8 cells (the Opus 5.5 replies never did); Express `root = [list]` in 3 cells; one Elemental syntax error. The 3-layout Jev pipeline cannot express 5 of the 6 briefs.

Defects found and what we did: (a) renderer: the pricing card shows a recommended tier only through `is_highlighted` while models write `recommended`/`badge`, a default `$` is prepended to any price, `stat_card` overlaps at 640 px in a 4-column grid, `progress_circle` value text is near-white on the light theme (listed in content-check/REPORT.md; none fixed in the catalogue at the time of the check); (b) harness, fixed for rendering: Elemental field names renamed by the catalogue copy, data-model updates at a path other than "/", surfaces merged into one, the `$$` price, one-column layouts; (c) harness, **not fixable without re-running models**: the catalogue build typed 18 list/boolean fields as strings, so Direct JSON models obeyed the schema and sent strings (this disadvantages Direct JSON in this sample), and the SDK Direct JSON validator rejected two valid Opus replies while passing orphaned ones. Direct JSON results are therefore weaker evidence than the Express ones.

A second reviewer (from a different model family, shown only the brief, the visible text and a screenshot of the top 1100 px, with no model labels and blind to the first reviewer's grades) agreed on good-or-minor versus not for 64 of 67 comparable cells and was within one grade in 66; it was more generous in 15 cells and stricter in 4. It cannot see payloads, so its cause labels are not used; its one two-grade gap came from the screenshot cutting off the lower sections.

Reviewer independence is limited: the first reviewer saw set labels naming the model that wrote each cell and graded cells that include replies written by its own model family; the second reviewer saw no model labels but graded cells that include replies written by its own model family (both families are among the measured subjects). We did not test whether either grades its own family differently.

Not supported: any ranking of formats or models, anything about interactivity (no filter or progress control is wired), anything about wide-screen layout, anything about stability across repeats (r2 and r3 were not reviewed).
### 3.8 Same payloads, better renderer (what the content check also showed)
The saved payloads were generated once and never regenerated. Rendered with the Oct 10 public-repo renderer (rounds 1 and 2) and with origin/main as of 27 Oct (17 days of changes later; the catalogue's first commit is 5 July 2026, under four months old) they look very different: more atoms render, flashcards and nested blocks appear, prices and one-column layouts are right. The model output is identical, so the improvement is the renderer and the catalogue contracts, not the models. The same holds in reverse: our own catalogue build typed 18 list and boolean fields as strings, and the pricing atom documents tiers only as "array", so models followed the schema or guessed field names the renderer ignores, and every model looked worse for it. A payload outlives the renderer that first showed it; catalogue and renderer quality is part of the result, in both directions. Evidence: the same saved payloads (Sonnet 5.5, Express, slice C, repeat 1; five cells) rendered by the 10 Oct snapshot and by origin/main of 27 Oct under the same test harness, so only the renderer differs. Three cells differ visibly (a chart with a legend and correct axis instead of a grey chart with wrong axis labels; the flashcard deck that the old snapshot did not render at all; a list styled as cards with status chips) and two look the same (a lesson page and a pricing table), so not every cell improved. An earlier comparison that mixed in our harness fixes overstated the effect (the price shown as $$9 was a harness workaround) and is withdrawn. A small worked case is T4 (a list of eight items filterable by status): no atom could filter a list until filterable_list was added to close the gap the brief exposed, and where a model's slice contained it, the models chose it (every valid T4 reply in the conditions that carried it). That is by design, not a finding about model skill: the gain belongs to the catalogue. In the content check, about 31 of the 54 weak rendered cells had a renderer or test-harness cause as the main cause rather than the model (MODEL 23, RENDERER 17, HARNESS 14; one repeat, one reviewer). This shows the effect on this sample only; it is not a measured rate of improvement.
## 4. What the results support
- Express produced fewer output tokens than Direct JSON on every model tested (1.3x to 2.7x, Haiku 4.5 at the top) and reduced time per reply by 1.3x to 2.3x on the four Anthropic models and by 1.3x on Gemini 3.5 Flash-Lite (request-only timing); on Gemini 3.5 Flash with thinking off the median paired time ratio is 1.24x (n=15, range 0.91-1.67x; see caveat 10), and Express compiled 15 of 18 against 18 of 18 for JSON.
- Slicing the catalogue cuts prompt size and cost sharply; most of the "13x" is the 100K-token price tier.
- A slice enforces what an agent class may use: a reply for the Marketing class compiled against the Learning slice is rejected ("Unknown component 'feature_grid' not defined in catalog ...c-learning.json"). One case, offline.
- Jev and Clef-flash pick atoms with about the same F1 on slices B, C, D.
- The cascade (rule slice + Jev + hints v2 + one repair) compiled 100% after repair (67% before) at F1 0.64, $0.0144 per brief (Jev only, Haiku 4.5).

### 4.1 A pattern worth exploring: catalogue routing by agent role
The SDK lets you hand different agents different catalogue slices. Choosing the slice by the agent's role (a support agent gets one slice, a finance agent another) would turn pruning into an entitlement control as well as a cost control. What we tested: a reply written for the Marketing class compiles against the Marketing slice and is rejected by the Learning slice ("Unknown component 'feature_grid' not defined in catalog ...c-learning.json"), so the compile step enforces the slice (one case, offline, `demo` conditions C/D). What we did not test: how an agent is identified and classified; how the registered catalogue ids are filtered before an agent names one (in the SDK flow the client names the catalogue ids); whether enforcement holds against a model that tries to bypass it. This is a design to explore, not a result.

### 4.2 Elemental (HTML-like inference format): offline smoke test, no model calls
The SDK's `ElementalFormatFactory` (experimental, a2ui-agent-sdk 0.9.0) asks a model for HTML5-like markup (`<a2ui><body><ui-columns id="root">...`). Findings on our Marketing/commerce slice: (1) with our native lowercase snake_case atom names every tag is rejected, even in-slice atoms ("Unknown component 'GradientHero' for tag 'ui-gradient-hero'"; the parser capitalises the first letter of the tag name, and the prompt itself shows tags such as `ui-gradient_hero`, which map to `Gradient_hero`); (2) against a copy of the slice whose component names start with a capital letter, a nested reply (columns containing a hero and a CTA) compiled, and an out-of-slice atom was still rejected. So Elemental works with our catalogue only through a name-mapped catalogue copy. One hand-written reply, offline; the model runs are in section 3.5. (3) Nesting: Elemental links a nested child tag to its parent only if the parent's schema declares a `children` property. Our `columns` atom keeps its children in `items:[{blocks}]`, so the first render of every Elemental reply was blank: the compile succeeded but the parent-child links were silently dropped. The models had followed the contract correctly (they only nested inside `columns`, 19 links). The capitalised catalogue copies now add a `children` property to `Columns`, and for rendering the compiled `children` are mapped back to the atom's `items`. A compile pass therefore does not prove the structure survived; check the compiled links as well. Two more render-side causes were found the same way: (4) models used Elemental data bindings (`{$/kpis/0/value}`), so the compiled components hold `{"path": ...}` references and the values sit in a separate `update_data_model` message, which the renderer must resolve like an A2UI client would; (5) several replies had more than one top-level element, which Elemental accepts silently (the Direct JSON validator rejects unreachable components as errors), so the render shows the root plus any unlinked top-level components. After these three render fixes every compiled Elemental reply shows content. Visible content issues remain, for example a price written as `$9` inside an atom that already adds `$` renders as `$$9`.

## 5. What they do not support (caveats to carry into any publication)
1. **Atom choice only.** F1 scores which components were used, not what they say. A content check was added on 2026-10-29 (section 3.7): one repeat, one reviewer, 72 cells, so it describes this sample and ranks nothing.
2. **Haiku 4.5 is the only model with the 2.7x / 2.3x figures**, at temperature 0, and only 3 of its 6 briefs compiled unaided on slice C (T2, T3, T5; 2 of 6 on slice D), so the other briefs have no render. On the replies that did compile the ratio is 2.6x tokens / 2.3x time. The public artefacts therefore lead with Sonnet 5.5 (18/18 compiled): 2.1x fewer tokens, 2.0x faster. On the other models time gains are 1.3-2.0x (Flash-Lite 1.3x, request-only timing).
3. **Oracle slices are a ceiling.** C and D were built from the answer key.
4. **Hints were tuned on the test briefs**, and hints v2 after v1's failures.
5. **Some Direct JSON failures are SDK 0.9.0 validator false positives** (e.g. a text property equal to its own component id raises a self-reference error). The stored `produced`/`score` fields for JSON runs also miss nested components, so JSON F1 values in the raw files are wrong; a report script re-walks them.
6. **Headline on key v2: the plain agent is level with the Express setups.** On key v2 it scores 0.774 against 0.64-0.79 for the Express setups (the best, oracle slice D with hints and repair, scores 0.79). On key v3 it scores 0.941, but the two keys differ only by T4 also accepting `filterable_list`, an atom built on 2026-09-25 because the T4 brief could not be met with the static atoms then in the catalogue. The oracle slices C and D were built from key v2 and do not contain that atom, so Express could not pick it there; the plain agent had the full catalogue. The v3 gain is the catalogue gaining an atom, not a model improving, and a v3 figure must not be compared with a v2 figure. It costs $0.022 a brief against $0.007-$0.014.
7. **The repair call is not in the time figures** (time is per model reply).
8. **Jev's "up to 80x" was tested only in a minimal form (section 3.6) and not confirmed in our tests.** Google's post describes layouts defined in advance, a decision model answering about 30 typed questions, code building the components, and a small model writing the text; the SDK "doesn't include a decision model inference format yet". Google's layouts are defined in advance and the decision model answers about 30 typed questions at request time (100-300 ms per request in the post); code instantiates the components. Our cascade uses Jev or Clef to pick atoms and an LLM to write the whole screen in Express: a different, cheaper-to-build design, so it can neither confirm nor refute 80x.
9. **Gemini 3.5 Flash JSON** needed three runs because of Vertex quota stops (429); the final set is 18/18 replies.
10. **Timing history.** Gemini times recorded before 2026-10-29 included the adapter's rate-limit wait and were wrong (medians of about 20 s); Flash-Lite was re-measured with request-only timing (tag `L` runs). Gemini 3.5 Flash (Vertex Express) was measured twice on 2026-10-29. First run, thinking on: replies took about 18-24 s because hidden reasoning counts toward the output budget, 6 of 18 Direct JSON replies were cut off at 8,192 tokens, and the paired median time ratio was 1.19x (range 0.72-3.11x): not established. Second run (the position we hold), thinking off (thinkingBudget 0, accepted by the API), max output 32,768 tokens, slice C, 6 briefs x 3 repeats x 2 formats, Express and JSON interleaved and swapped each repeat, request-only timing, one request per call, no retries: median 3.8 s per Express reply against 5.1 s for Direct JSON; on the 15 briefs valid in both formats the median per-pair time ratio is 1.24x (range 0.91-1.67x, Express faster in 12 of 15) and the median output-token ratio 1.71x. Compile rates: Express 15 of 18 replies, Direct JSON 18 of 18, so on this model Express was faster but compiled less reliably (three failures: a syntax error, a property type error, a missing root). The first 11 calls of the second run were sent about 6 s apart (the adapter pause did not carry across processes; no errors; timing is request-only). Small sample, one slice. Anthropic times were never affected.
11. **No claim is made about error isolation** (the proposal describes it; we did not see it).
12. **B and G are not fully zero-shot.** Each brief's domain (Learning, Data display, Marketing/commerce) was assigned by hand (`conditions.DOM`) and G's domain definitions were written by someone who knew the tasks. A production router would need its own classifier; only the 207-atom rule slice is close to realistic, and it still knows the domain.
13. **Small sample.** Six briefs, one run set per model. Google's post reports its four-format comparison on a "51-task eval on gemini-3.5-flash" (thinking on and off) and its Jev numbers on 11 prompts, which it calls "a first look, since the sample is small"; ours is six briefs, so it should be read the same way.
14. **The cause of Haiku 4.5's Express failures was not diagnosed.** We observed whole-reply compile failures (for example a missing `root`); we do not claim why a small model fails.

## 6. Google claims and our tests
| Google (quote) | Our result |
|---|---|
| "up to 3x fewer tokens" / "reduce latency by up to 3x" | 2.7x tokens, 2.3x time on Haiku 4.5; 1.3-2.1x tokens on other models |
| "inference formats are swappable" | Express and Direct JSON both run on six models |
| "a format can't describe a component or property that your catalog lacks" | A slice rejected an out-of-slice atom (offline, one case) |
| "up-to 80x using decision models like Jev" | Minimal pipeline built (section 3.6): complete screen in about 1.6 s (Google: 0.8-1.7 s), 1.4-1.9x faster than the same model writing the whole screen, 12-96x faster to layout than whole-screen replies; templated screens score F1 0.31. Neither confirmed nor refuted (Google's baseline is unstated) |
Note: the post does not mention pruning; the SDK ships `ComponentPruningTransformer` (a2ui/catalog_transformers/pruning.py).

## 8. Where the files are
See index.html in this folder: every file, how it was measured and its evidence label.
