diff options
Diffstat (limited to 'skills/command-composition-rules.json')
| -rw-r--r-- | skills/command-composition-rules.json | 15 |
1 files changed, 15 insertions, 0 deletions
diff --git a/skills/command-composition-rules.json b/skills/command-composition-rules.json new file mode 100644 index 0000000..4120cbd --- /dev/null +++ b/skills/command-composition-rules.json @@ -0,0 +1,15 @@ +{ + "name": "command-composition-rules", + "description": "The terminal has no shell: what is refused, what works, and how to verify a result that looks plausible", + "tags": [ + "terminal", + "shell", + "composition", + "safety", + "agent" + ], + "category": "system", + "created": "2026-10-23T16:27:07.000Z", + "updated": "2026-10-23T16:27:07.000Z", + "content": "---\nname: command-composition-rules\ndescription: The terminal has no shell: what is refused, what works, and how to verify a result that looks plausible\ntags: [terminal, shell, composition, safety, agent]\ncategory: system\n---\n## The rule\n\nThis terminal does not spawn a shell. The line is split into argv and handed to **one** command\nhandler. \\`;\\`, \\`&&\\`, \\`||\\` and redirection are not interpreted. Since v4.6.58 they are refused:\n\n wc -l file && grep -c pattern file\n -> warning: No shell here \u2014 \\`&&\\` is not interpreted. Run one command per line.\n\n## Why the refusal exists\n\nBefore v4.6.58 \\`&&\\` failed silently: the right-hand tokens were appended to the left command's\nargv, unknown tokens were dropped, and valid flags were absorbed.\n\n wc -l f && grep -c x f -> \"42 42\" (grep's -c became a wc flag)\n wc -l f && grep -n x f -> \"42\" (-n is not a wc flag, so it was dropped)\n wc -c a b -> \"34138 a\" (second path dropped, exit code 0)\n\nThe worst case was an empty pattern: \\`grep \"\" file\\` matches every line and returns a plausible\ncount. A clean exit code is not evidence that the command did what you asked.\n\n## What works\n\n- One command per call. Two files means two calls, unless the command documents multiple paths.\n- \\`wc\\` accepts multiple paths since v4.6.58: \\`wc -c a b\\` prints one line per file plus \\`total\\`.\n- A single \\`cmd | cmd\\` pipeline works in the **interactive** terminal. It does **not** work through\n the AI \\`run_command\\` tool, which bypasses the pipe splitter \u2014 there \\`|\\` is refused too.\n- Operators inside quotes are untouched: \\`echo \"a && b\"\\` prints \\`a && b\\`.\n\n## Verifying your own result\n\n- Ask for two things, count that you got two lines back.\n- A suspiciously round or empty count means a broken probe, not a clean system.\n- \\`ls\\` prints text since v4.6.57 (it used to render chips only, so captured output was empty);\n \\`list_files\\` remains the reliable enumerator.\n- An invalid \\`grep\\` pattern now returns \\`grep: invalid pattern: \u2026\\` and does not enter the error\n ledger \u2014 if you see a pattern exception, something regressed.\n\n## Pitfalls\n\n- A refusal is not a failed command: nothing ran. Split it and run both halves.\n- \\`;\\` used to fail loudly (\"No such file: x;\"). That loudness is gone in favour of an explicit\n refusal \u2014 do not \"fix\" a refusal by re-joining the commands differently.\n- \\`>\\` is handled by \\`echo\\` only (\\`echo hi > file\\`). It is not a general redirect.\n\n## History\n\nReplaces \\`terminal-commands-silently-failing\\` and \\`command-composition-rules\\`, merged 2026-10-23\nafter the behaviour itself was fixed in v4.6.58." +}
\ No newline at end of file |