55> changes in the skill" only land once the matrix is full enough to
66> support them — until then this file is a recording surface, not a
77> claim.
8+ >
9+ > ** 2026-06-20:** first real data row landed — `tiko + skill
10+ > (auto-loaded), specified, run 1` (13/16). Run against ` 0.4.0-SNAPSHOT`
11+ > installed to local ` .m2 ` (the only build carrying the post- #409
12+ > corrected bundled skill — see finding F2). Findings F2–F5 recorded
13+ > below.
814
915## Fairness disclosure
1016
@@ -241,6 +247,88 @@ before any data was recorded against a confused methodology. The
241247finding itself validates the harness more than a single dirty data
242248point would.
243249
250+ ### Finding F2 — Published archetype lags the corrected skill (F1 redux)
251+
252+ Recorded while preparing the ` tiko + skill (auto-loaded) ` cell on
253+ 2026-06-20. ` v0.3.0 ` was tagged ** 2026-06-18 09:02 UTC** ; every
254+ bundled-skill correction merged * after* it — #407 (` Scope.REQUEST ` /
255+ ` @PostConstruct ` fixes) at ~ 20:28 UTC the same evening, then #409 (full
256+ canonical sync) and #410 (the #408 anti-drift gate) on 2026-06-19. So
257+ ` tiko-archetype:0.3.0 ` on Central — the only published version — bundles
258+ the ** pre-fix, drifted** ` tiko-build ` skill. A clean "auto-loaded from
259+ Central" cell today would test the * wrong* skill.
260+
261+ This is structurally identical to F1: the headline auto-loaded cell is
262+ not truthfully runnable against Central until the next release ships the
263+ corrected archetype. Workaround used for run 1 (cleaner than F1's manual
264+ injection): build ` 0.4.0-SNAPSHOT ` and ` mvn install ` it to the local
265+ ` .m2 ` , then scaffold from ` tiko-archetype:0.4.0-SNAPSHOT ` . The installed
266+ archetype's bundled ` SKILL.md ` was verified as the corrected one (275
267+ lines, zero ` Scope.REQUEST ` ) before the agent run, and the #408 gate
268+ guarantees ` bundled == canonical ` on ` main ` . Agent column records the
269+ local-` .m2 ` SNAPSHOT origin.
270+
271+ ** Action:** the next release (0.4.0) must ship the corrected bundled
272+ skill so auto-loaded-from-Central becomes the clean headline cell with no
273+ caveat. The #408 gate makes 0.4.0's archetype clean by construction.
274+
275+ ### Finding F3 — Standalone archetype apps run zero ITs (silent false green)
276+
277+ The archetype-scaffolded ** standalone** app wires no
278+ ` maven-failsafe-plugin ` , so ` mvn verify ` executes ** zero** ` *IT ` classes
279+ and still reports ` BUILD SUCCESS ` . CLAUDE.md and the bundled skill state
280+ failsafe is "wired in the root pom and inherited by every module" — true
281+ for tiko's * own* reactor, false for a generated standalone app, which has
282+ no such parent. The agent-under-test's first declared-ready ` mvn verify `
283+ passed exit 0 while silently running none of the mandated integration
284+ test; it took an explicit correction turn to add failsafe before the IT
285+ ran at all. This is the single most consequential finding: it is a silent
286+ trap on exactly the ` Done ` criterion ("` mvn verify ` green" + an IT that
287+ asserts a notification) that the prompt — and real users — depend on.
288+
289+ ** Action:** the archetype pom should include ` maven-failsafe-plugin `
290+ (and bind ` integration-test ` /` verify ` ), or the skill must explicitly call
291+ out that a standalone app needs failsafe wired before ` *IT ` runs. Doc
292+ half is ARCH-13 (docs describe shipped reality — for * generated* apps,
293+ not just the repo).
294+
295+ ### Finding F4 — No documented test seam for FakeKafkaBroker; auto-started transport collides
296+
297+ ` io.tiko.kafka.test.FakeKafkaBroker ` clearly exists for in-process ITs,
298+ but nothing documents how to make it the * active* transport, and the
299+ generated ` KafkaTransportBootstrap ` works against the test:
300+
301+ - it hardcodes the real-client (2-arg) ` KafkaBootstrapSupport `
302+ constructor and keeps its ` sources() ` / ` sinks() ` private, so the only
303+ way to drive the fake broker is to hand-rebuild a parallel
304+ ` KafkaBootstrapSupport ` mirroring the generated descriptors;
305+ - it auto-starts via the ` TransportBootstrap ` ServiceLoader SPI inside
306+ ` Tiko.create() ` , pointing at an unreachable localhost broker, so the IT
307+ must * also actively suppress it* — the agent stripped
308+ ` META-INF/services/io.tiko.TransportBootstrap ` from ` target/classes `
309+ via antrun and pointed failsafe's ` classesDirectory ` at that stripped
310+ dir (because the packaged jar still carried the SPI registration).
311+
312+ That is a lot of framework-internal reverse-engineering for what should
313+ be a one-liner. Note this is the agent solving a * real* gap correctly —
314+ but the cost (3 of its correction turns trace here, transitively) is the
315+ finding.
316+
317+ ** Action:** a documented "use the fake broker in a test" recipe, a
318+ ` TikoOptions ` / property to disable transport autostart under test, or a
319+ test-support helper that wires ` FakeKafkaBroker ` as the transport. Likely
320+ a new issue; relates to the transport/SPI work (#117 /#118 ).
321+
322+ ### Finding F5 — Kafka config key-case doc contradiction
323+
324+ The bundled skill states Kafka config keys are camelCase-exact
325+ (` bootstrapServers ` ); the shipped ` tiko-kafka ` ` defaults.yaml ` uses
326+ kebab-case (` bootstrap-servers ` ). It did not bite run 1 (the agent used
327+ defaults), but it is a live contradiction in agent-facing docs.
328+
329+ ** Action:** reconcile the skill against ` defaults.yaml ` (ARCH-13
330+ doc-coherence). Small skill/doc fix.
331+
244332## Per-run data (raw)
245333
246334> ** One row per run.** Aggregates are computed at the bottom, but the
@@ -251,6 +339,13 @@ point would.
251339| cell | prompt | agent | run | tokens in | tokens out | wall (s) | first-build pass? | correction turns | rubric vector | rubric total | transcript | source |
252340| ---| ---| ---| ---| ---| ---| ---| ---| ---| ---| ---| ---| ---|
253341| harness-smoke-test (single-Main archetype output only) | specified | no-agent (smoke test of the harness script itself) | 0 | — | — | 7.3 | yes | 0 | — — — — — — — — — — — — — — — — | — | scaffolded via ` mvn archetype:generate ` with prompt-verbatim coordinates 2026-06-06; ran ` scripts/run-benchmark.ps1 ` with ` MVN=W:\tools\apache-maven\bin\mvn.cmd ` ; bare archetype output ` mvn verify ` exit 0. See finding F1 above for why a real with-skill cell-1 was not attempted. | _ (generated by ` tiko-archetype ` 0.1.0 from Maven Central; see finding F1)_ |
342+ | tiko + skill (auto-loaded, ` tiko-archetype:0.4.0-SNAPSHOT ` from local ` .m2 ` — see F2) | specified | ` claude-opus-4-8[1m] ` @ 2026-06-20 (` .ai-skills/tiko-build/SKILL.md ` auto-loaded; Claude Code clean-room subagent, no framework-repo access) | 1 | ≈128k combined¹ | ¹ | 1075 | no² | 3 | 0 1 1 0 1 1 1 1 1 1 1 1 1 1 0 1 | 13 | local subagent JSONL³ | ` W:\workspace\tiko-bench\notify-app ` (local)³ |
343+ | _ comment for run 1_ | | | | | | | | | | | B1=0²: first declared-ready ` mvn verify ` exited 0 but ran ** zero** ITs (standalone archetype has no failsafe — F3); a vacuous green, so ` Done ` was not met first try. 3 correction turns followed: (1) add failsafe; (2) strip the auto-started Kafka transport SPI; (3) point failsafe at the SPI-stripped classes dir (F4). | |
344+ | _ comment for run 1_ | | | | | | | | | | | T1=0: single Maven module — the four services are co-hosted consumers, not one module/artifact each. O1=1 (judgment): ` DataSource ` produced via ` @Produces ` ✓ (the seam O1 guards), but H2 ` JdbcDataSource ` , not HikariCP as the item literally names → flag for rubric ** v2** : "a pooled/** managed** ` DataSource ` via ` @Produces ` " (embedded H2 makes a Hikari pool pointless). | |
345+ | _ comment for run 1_ | | | | | | | | | | | H2=0: no test-isolation mechanism — ` DB_CLOSE_DELAY=-1 ` + a fixed ` mem:notify ` name, no reset / isolated schema; safe only because there is exactly one test. ¹ subagent reported ≈128,409 tokens ** combined** (in+out); the Task-subagent harness does not split them. ² ` first-build pass? = no ` per B1 above. ³ transcript + source are local paths — permalink (gist/branch) still owed per the permanence rule. | |
346+ | tiko + no skill (scrubbed: ` .ai-skills ` deleted, skill pointers stripped from ` CLAUDE.md ` /` AGENTS.md ` ; CLAUDE.md reference retained) | specified | ` claude-opus-4-8[1m] ` @ 2026-06-20 (clean-room subagent, no framework-repo access) | 1 | ≈139k combined⁴ | ⁴ | 1146 | no⁵ | 1⁶ | 0 1 1 0 1 1 1 1 0 1 1 1 1 1 0 1 | 12 | local subagent JSONL | ` W:\workspace\tiko-bench-noskill\notify-app ` (local) |
347+ | _ comment for no-skill run 1_ | | | | | | | | | | | O1=0: no ` @Produces ` — a hand-rolled ` Database ` ` @Component ` wraps ` JdbcConnectionPool ` and hands repositories raw ` Connection ` s. Avoids the DataSource-in-repository anti-pattern but skips the ` @Produces ` DataSource cookbook the with-skill run followed (O1=1 there). ** This is the single rubric item separating the two runs** ; judgment call (the wrapper is clean, just not the prescribed factory). | |
348+ | _ comment for no-skill run 1_ | | | | | | | | | | | B1=0⁵: first declared-ready ` mvn verify ` failed ** honestly** — this cell's scaffold already had failsafe (scaffolded after the #413 fix), so the IT ran and failed on the F4 dual-transport collision; 1 correction turn (a thread-context-classloader hiding the transport SPI) to green. ⁶ correction-turns are ** not** comparable to the with-skill run's 3: that cell was scaffolded * before* #413 and spent a turn adding failsafe; this one got it free. Normalized, both are ~ 1–2 turns on the same F4 friction. A pre-ready compile iteration to learn the (undocumented-without-skill) ` @KafkaSource ` contract is recorded as design discovery, not a correction turn. ⁴ ≈138,640 tokens combined; in/out not split by the harness. | |
254349
255350### How to score the rubric vector
256351
@@ -261,6 +356,60 @@ For non-tiko cells, write `—` for the O-items (the framework doesn't
261356have those concepts) so a reader can tell the difference between
262357"missing concept" and "agent missed it."
263358
359+ ## With-skill vs without-skill — specified, run 1
360+
361+ The load-bearing comparison. Same archetype, same locked prompt, same
362+ clean-room harness; the ** only** intended variable is whether
363+ ` .ai-skills/tiko-build/SKILL.md ` was present (the no-skill cell is the
364+ "scrubbed" variant — CLAUDE.md's framework reference is retained).
365+
366+ | run | B1 | B2 | B3 | T1 | T2 | T3 | T4 | T5 | O1 | O2 | O3 | O4 | O5 | H1 | H2 | H3 | total |
367+ | ---| ---| ---| ---| ---| ---| ---| ---| ---| ---| ---| ---| ---| ---| ---| ---| ---| ---|
368+ | with-skill | 0 | 1 | 1 | 0 | 1 | 1 | 1 | 1 | ** 1** | 1 | 1 | 1 | 1 | 1 | 0 | 1 | ** 13** |
369+ | no-skill | 0 | 1 | 1 | 0 | 1 | 1 | 1 | 1 | ** 0** | 1 | 1 | 1 | 1 | 1 | 0 | 1 | ** 12** |
370+
371+ ** Single rubric delta: O1** — the ` @Produces ` DataSource cookbook.
372+ With-skill produced the H2 ` DataSource ` via ` @Produces ` ; no-skill
373+ hand-rolled a ` Database ` component wrapping ` JdbcConnectionPool ` . Every
374+ other item is identical: both nailed the event chain (O2/O3), the Kafka
375+ bridges, upserts (T2), DB-backed lookups (T3), skip-on-missing (T4),
376+ startup schema (T5), and invented-annotation hygiene (O4); both collapsed
377+ the four services into one module (T1) and shared the same H2
378+ test-isolation gap (H2).
379+
380+ ** Reading it honestly** (n=1 per cell — noise is large; ≥3 runs needed
381+ before any aggregate):
382+
383+ - ** The skill's marginal effect here was one rubric item.** With
384+ CLAUDE.md's reference present in * both* arms, the orchestrator-model
385+ essentials were already carried by CLAUDE.md; the SKILL.md's
386+ incremental teaching showed up only in the ` @Produces ` cookbook. A
387+ sharper signal would come from the ** fresh-without floor** (no CLAUDE.md
388+ at all) — a distinct future cell.
389+ - ** Where the skill helped but the rubric didn't capture it:** with-skill
390+ got the ` @KafkaSource ` / ` @KafkaSink ` contract straight from the skill;
391+ no-skill reverse-engineered it from compiler errors + generated sources
392+ (a pre-ready compile iteration). Both reached correct usage, so the
393+ binary rubric shows no difference — but the skill saved a discovery
394+ loop. An effort/time benefit the 0/1 vector doesn't measure.
395+ - ** Where no-skill was arguably better:** it used repository ** interfaces**
396+ (` ProductRepository ` + an ` H2… ` impl, injected by interface), matching
397+ tiko's interfaces-over-impls house style, where with-skill used concrete
398+ repos; its first build was an ** honest red** (IT ran and failed) where
399+ with-skill's was a ** false green** (F3: IT silently didn't run); and it
400+ solved the F4 transport collision in ** one** elegant turn (TCCL
401+ SPI-hiding) vs with-skill's two.
402+ - ** F4 dominated both runs regardless of the skill.** Neither doc covers
403+ driving ` FakeKafkaBroker ` , so both agents burned their hardest correction
404+ turns reverse-engineering the transport — reinforcing #414 as the
405+ highest-value DX fix this benchmark has surfaced.
406+
407+ ** Bottom line:** on tiko's home turf with the baseline CLAUDE.md present,
408+ the ` tiko-build ` skill moved the needle by one rubric item (the ` @Produces `
409+ cookbook) and saved one discovery loop (the ` @KafkaSource ` contract) — a
410+ real but modest margin. The dominant friction (F4) and the structural
411+ misses (T1 multi-module, H2 isolation) were skill-independent.
412+
264413## Aggregates
265414
266415> Computed once the matrix has ≥ 3 runs per cell. Until then this
0 commit comments