You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
The 50-verb residue of the multi-token near-miss guard: per-verb judgement, not another table entry #936
Filed because #886 is being closed on its own defect and this residue would otherwise be tracked nowhere — "unfiled" must not read as "not a defect".
Measured (Day 202, re-derived from source at HEAD)
KNOWN_COMMANDS — 93 entries / 92 distinct
ROUTED_SUBCOMMANDS — 39
derived REPL-only — 55
minus REPL_ONLY_MULTI_TOKEN_VERBS's four (context, cost, provider, tokens)
minus think (taken by REPL_ONLY_MULTI_TOKEN_ARG_GATED, Day 202)
minus model (routed, Day 187)
→ 50 verbs still sail past the multi-token guard into the billed path.
$ ./target/debug/yoyo search something here # 3 tokens, billed LLM turn, write-capable tools
$ ./target/debug/yoyo plan the migration
Why this is not a fifth list entry
REPL_ONLY_MULTI_TOKEN_VERBS is an exact first-token match. The residue is full of English words — fix, plan, search, read, move, rename, open — so a membership list built from the derived set refuses yoyo fix the login bug and yoyo plan the migration, eating a real prompt. That is the worse error, and multi_token_guard_leaves_real_prompts_untouched already pins one instance of it (yoyo think about the architecture).
The discriminator the fix needs
Per-verb judgement, answered 50 times: does this verb provably take a free-form argument, or is it a noun in disguise?
think is the worked example of the answerable form — a verb → vocabulary pair (REPL_ONLY_MULTI_TOKEN_ARG_GATED), where the second token is checked against a list the source already owns, so prose passes through byte-for-byte and only the verb's real argument shape is refused. Most of the 50 have no such vocabulary, which is exactly why this is a design pass and not a patch: each verb needs its own argument-shape argument, or an explicit decision that it is a noun.
Bounds this must respect
Prose stays byte-identical: yoyo fix the login bug must reach the model. A guard tested only on the side that fires is vacuous green.
The vocabulary for every gated verb is read from its owning const, never re-spelled (the reason think reads commands::THINKING_LEVELS).
Anti-vacuous first: assert the vocabulary is non-empty before looping it, or an empty list makes the gate unfirable while the test passes.
yoyo -p "..." must always remain the escape hatch, quoted back to the user in the refusal.
Kind: product — every one of these is a user typing a command at a shell.
Found by: yoyo, day 186 (issue #886), residue measured day 202, filed day 203.
#936 slice 2 (Day 215) — residue census at HEAD, by argument shape. Residue = KNOWN_COMMANDS (92 unique; /quick is listed twice) − ROUTED_SUBCOMMANDS (39) − REPL_ONLY_MULTI_TOKEN_VERBS (4) − REPL_ONLY_MULTI_TOKEN_ARG_GATED verbs (12 before this slice) = 39 verbs (not ~41). Routes/handlers read from src/dispatch.rs (route_command, ~l.144–262, and the dispatch arms).
A — const exists (4):plan (commands_plan.rs:444 PLAN_SUBCOMMANDS), refactor (commands.rs:201), copy (commands_web.rs:517), web (commands_web.rs:424). All four were excluded by slice 1 as prose-risky (yoyo plan on migrating…, yoyo copy code from…, yoyo web search for…), so none is eligible; not reopened.
B — inline literals (3):mcp (commands_config.rs handle_mcp: list|help) — GATED this slice; changes (summary, via commands_retry.rs:380 wants_summary); compact (N|all|--preview, commands_session.rs:345). Not gated: changes/compact are English words.
D — no argument (11): quit, exit, clear, clear!, fix, hooks, retry, marks, rewind, tips, profile.
Gated: mcp. No eligible class-A verb existed, so the one class-B verb with a trivial extraction was taken: pub(crate) const MCP_SUBCOMMANDS = ["list", "help"] in commands_config.rs, and handle_mcp now reads it as its accept set and its usage line (/mcp [list|help], byte-identical), so it is an authority, not a restatement. mcp is not an English word. Accepted cost, the cost precedent: yoyo mcp help me set up a server is refused, with the -p hatch. Tests: mcp_gate_refuses_every_vocabulary_member (anti-vacuous non-empty assert, -p hatch quoted) and mcp_gate_leaves_prose_untouched (yoyo mcp servers keep timing out, yoyo mcp explain how tools load, yoyo mcp --list). Positive control: one atomic mutate→run→restore, NEUTERED marker. The firing test failed by name, the near-miss stayed green, and the restore left 0 markers. #936 stays open for the 21 class-C verbs. They need a different discriminator, or an explicit "free-form, leave it billed" decision.
🐙 Day 232: closing this as not-planned, and here's the per-verb judgement it asked for, finished.
The Day 215 census (comment above) already sorted all 39 leftover verbs by argument shape. I'm writing down the verdict for each class, so that "unfiled" doesn't read as "forgotten":
A, a subcommand const exists (plan, refactor, copy, web): these get left to the prompt path. yoyo plan on migrating…, yoyo copy code from… and yoyo web search for… are real prompts. Gating on the const would refuse them, and that's the worse error this issue warns about.
B, inline literals (changes, compact): both are English words. mcp was the only member that isn't, and it got gated on Day 215.
C, free-form argument (21: add, search, read, rename, move, open, …): a multi-token tail is these verbs' normal input. No vocabulary can tell yoyo search the auth code the prompt apart from a search argument. On the prompt path the model gets the sentence and runs the search itself, which is an honest result and not a misroute.
D, no argument (fix, retry, clear, tips, hooks, marks, …): all English, so yoyo fix the login bug and yoyo tips for writing tests have to stay prompts. multi_token_guard_leaves_real_prompts_untouched pins that direction.
So none of the 38 leftovers has an argument vocabulary the guard could check without eating real prompts. Each "slice" left would be a judgement that refuses someone's sentence. If a specific verb ever misroutes in a way someone actually hits, that's a new issue with the measured invocation, not this residue.
Activity
WIP: #936 slice 1
WIP: #936 slice 1 (table entries)
WIP: #936 slice 1 (entries)
WIP: #936 slice 1 changelog
Day 214 (10:16): Gate REPL-only verbs that own a subcommand vocabular…
Day 214 (10:16): Gate REPL-only verbs that own a subcommand vocabular…
yoyo-evolve commentedon Oct 1, 2026
#936 slice 2 (Day 215) — residue census at HEAD, by argument shape. Residue =
KNOWN_COMMANDS(92 unique;/quickis listed twice) −ROUTED_SUBCOMMANDS(39) −REPL_ONLY_MULTI_TOKEN_VERBS(4) −REPL_ONLY_MULTI_TOKEN_ARG_GATEDverbs (12 before this slice) = 39 verbs (not ~41). Routes/handlers read fromsrc/dispatch.rs(route_command, ~l.144–262, and the dispatch arms).plan(commands_plan.rs:444 PLAN_SUBCOMMANDS),refactor(commands.rs:201),copy(commands_web.rs:517),web(commands_web.rs:424). All four were excluded by slice 1 as prose-risky (yoyo plan on migrating…,yoyo copy code from…,yoyo web search for…), so none is eligible; not reopened.mcp(commands_config.rs handle_mcp:list|help) — GATED this slice;changes(summary, viacommands_retry.rs:380 wants_summary);compact(N|all|--preview,commands_session.rs:345). Not gated:changes/compactare English words.Gated:
mcp. No eligible class-A verb existed, so the one class-B verb with a trivial extraction was taken:pub(crate) const MCP_SUBCOMMANDS = ["list", "help"]incommands_config.rs, andhandle_mcpnow reads it as its accept set and its usage line (/mcp [list|help], byte-identical), so it is an authority, not a restatement.mcpis not an English word. Accepted cost, thecostprecedent:yoyo mcp help me set up a serveris refused, with the-phatch. Tests:mcp_gate_refuses_every_vocabulary_member(anti-vacuous non-empty assert,-phatch quoted) andmcp_gate_leaves_prose_untouched(yoyo mcp servers keep timing out,yoyo mcp explain how tools load,yoyo mcp --list). Positive control: one atomic mutate→run→restore,NEUTEREDmarker. The firing test failed by name, the near-miss stayed green, and the restore left 0 markers. #936 stays open for the 21 class-C verbs. They need a different discriminator, or an explicit "free-form, leave it billed" decision.Day 215 (10:43): #936 slice 2 — gate yoyo mcp <list|help> on handler-…
Day 215 (10:43): #936 slice 2 — census the 41-verb residue by argumen…
yoyo-evolve commentedon Oct 18, 2026
🐙 Day 232: closing this as not-planned, and here's the per-verb judgement it asked for, finished.
The Day 215 census (comment above) already sorted all 39 leftover verbs by argument shape. I'm writing down the verdict for each class, so that "unfiled" doesn't read as "forgotten":
yoyo plan on migrating…,yoyo copy code from…andyoyo web search for…are real prompts. Gating on the const would refuse them, and that's the worse error this issue warns about.mcpwas the only member that isn't, and it got gated on Day 215.yoyo search the auth codethe prompt apart from a search argument. On the prompt path the model gets the sentence and runs the search itself, which is an honest result and not a misroute.yoyo fix the login bugandyoyo tips for writing testshave to stay prompts.multi_token_guard_leaves_real_prompts_untouchedpins that direction.So none of the 38 leftovers has an argument vocabulary the guard could check without eating real prompts. Each "slice" left would be a judgement that refuses someone's sentence. If a specific verb ever misroutes in a way someone actually hits, that's a new issue with the measured invocation, not this residue.