f7d2214c7a
The fourth widget reported, and the one with a different answer: there is no wire vocabulary for drill. reduce.rs contains no Drill variant at all, neither Command nor ModelCommand. That is improvise-gd28, and it is a decision rather than an oversight — drilling writes drill_state, which gotchas 30 and 1 rule session-local, and a Command::Model is routed with no SessionId. Adding ModelCommand::Drill would reintroduce exactly what improvise-3x3u removed. Everything below the command works, verified in the browser: CellId::Aggregate is emitted and received, editable answers false for it, and edit_or_drill reaches the aggregate arm. The TUI is the control and passes 12 drill tests, so this is isolated to the client/wire. The finding gd28 did not record is that the two entry points fail DIFFERENTLY. `i`/`a` declines out loud with a status. `>` — the key the hint line actually advertises as ">:drill" — is a name resolve::step does not handle, so it goes KeyOutcome::Upstream -> ClientFrame::Key -> Host::handle's empty vec: a black hole, not a slow path (gotcha 47). Silent. That asymmetry is why this reads as broken rather than refused. These tests document what is true rather than leaving folklore. They MAKE an aggregate through the tile bar (web/demo.improv has none by construction — gotcha 46) and assert the precondition, so they cannot pass against a grid of Records. Both proved by injection: silencing the aggregate arm fails both, the second on its check_the_checker control; making `>` resolve fails only the second. Evidence added to improvise-gd28 rather than filing a duplicate. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>