docs(native-chat): record the measured limits of the slash-token rule

Measured against the real binary rather than reasoned about:

- `  /clear` comes back as a stamped replay, so this lane reads an indented
  token as prose too. The no-trim rule was inherited from a comment about the
  TUIs; it is now verified for `claude -p --input-format stream-json`.
- `/clear` and `/model` answer with a bare `result` and NO echo, which is the
  only case acceptsResult exists for.
- A CUSTOM project command (`/probeit`) and a path-leading message
  (`/tmp what is in here?`) both DO produce a stamped replay.

So shape cannot separate `/tmp` from `/clear`, and the command catalog cannot
either: getVerifiedNativeChatCommands('claude') is a curated `/` menu (clear,
compact, init, review, help) that omits `/model` and `/permissions`. Gating on
it strands those sends - tried, and the pre-existing `/permissions` test caught
it immediately. Recording the residual and why the two obvious fixes are wrong,
so the next reader does not retry them.

Found by the review loop on #15657.
This commit is contained in:
Brennan Benson
2026-08-20 19:55:26 -07:00
parent 7746d71bbc
commit 32c199e4b9
+12 -2
View File
@@ -199,8 +199,18 @@ const SLASH_COMMAND_TOKEN = /^\/[a-z0-9][\w:-]*$/i
* treats any `/`-leading token as command-ish: over-classifying is safe there
* (it only suppresses an echo) and unsafe here.
*
* No trimming, matching that classifier's documented rule: the supported TUIs
* only treat a LINE-LEADING token as a command, so ` /clear` is prose.
* No trimming, and MEASURED rather than inherited from the TUI rule: ` /clear`
* came back from `claude -p --input-format stream-json` as a stamped replay, so
* this lane also reads an indented token as prose.
*
* Residual, unfixable by shape: `/tmp what is in here?` matches, because `/tmp`
* is indistinguishable from `/clear`. The agent's command catalog cannot close
* it either - `getVerifiedNativeChatCommands('claude')` is a curated `/` menu
* (clear, compact, init, review, help) and omits real built-ins like `/model`
* and `/permissions`, both measured as answering with a bare `result` and no
* echo; gating on it would strand those sends instead. Measured mitigation: a
* path-leading message DOES get a stamped replay, so it only mis-settles if an
* unrelated `result` beats that replay.
*/
function isSlashCommandText(text: string): boolean {
return SLASH_COMMAND_TOKEN.test(text.split(/\s/, 1)[0] ?? '')