aboutsummaryrefslogtreecommitdiff
path: root/skills/command-composition-rules.md
diff options
context:
space:
mode:
authorAgando <roduccomm@gmail.com>2026-10-23 18:27:26 +0200
committerAgando <roduccomm@gmail.com>2026-10-23 18:27:26 +0200
commit87f44c42aeb763e2aaf3da159d60b252dca9aa53 (patch)
tree8a2718d191504d694ac187d47e7cdc77a5695d45 /skills/command-composition-rules.md
parent9c27d3790b594c94430015675c91ce618c61be1d (diff)
docs(newos4): merge the two shell-composition skills into one seeded skill (v4.6.65)
Packet 9. `terminal-commands-silently-failing` and `command-composition-rules` described the same bug family from two angles, and since v4.6.58 both were describing behaviour that is now refused outright. - new seeded skill `command-composition-rules` in skill-pack-core's _buildSkills(): the rule, why the refusal exists (with the 42-42 / 34k-a measurement), what works (one command per call, wc multi-path, interactive-only pipes, quoted operators), how to verify a plausible-looking result, and the pitfalls - its History section names both retired skills so a reader arriving from either search finds the surviving one - mirrored onto disk as skills/command-composition-rules.md + .json and added to skills/index.json (18 entries) so the repo copy matches what sessions receive Verified live on v4.6.65: seeding reported 15 skills (was 14), the file and index entry exist in the fresh VFS, and the natural-language query "does the terminal have a shell and what is refused" returns command-composition-rules first (13.78, 3/4).
Diffstat (limited to 'skills/command-composition-rules.md')
-rw-r--r--skills/command-composition-rules.md54
1 files changed, 54 insertions, 0 deletions
diff --git a/skills/command-composition-rules.md b/skills/command-composition-rules.md
new file mode 100644
index 0000000..aa218e7
--- /dev/null
+++ b/skills/command-composition-rules.md
@@ -0,0 +1,54 @@
+---
+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
+---
+## The rule
+
+This terminal does not spawn a shell. The line is split into argv and handed to **one** command
+handler. \`;\`, \`&&\`, \`||\` and redirection are not interpreted. Since v4.6.58 they are refused:
+
+ wc -l file && grep -c pattern file
+ -> warning: No shell here — \`&&\` is not interpreted. Run one command per line.
+
+## Why the refusal exists
+
+Before v4.6.58 \`&&\` failed silently: the right-hand tokens were appended to the left command's
+argv, unknown tokens were dropped, and valid flags were absorbed.
+
+ wc -l f && grep -c x f -> "42 42" (grep's -c became a wc flag)
+ wc -l f && grep -n x f -> "42" (-n is not a wc flag, so it was dropped)
+ wc -c a b -> "34138 a" (second path dropped, exit code 0)
+
+The worst case was an empty pattern: \`grep "" file\` matches every line and returns a plausible
+count. A clean exit code is not evidence that the command did what you asked.
+
+## What works
+
+- One command per call. Two files means two calls, unless the command documents multiple paths.
+- \`wc\` accepts multiple paths since v4.6.58: \`wc -c a b\` prints one line per file plus \`total\`.
+- A single \`cmd | cmd\` pipeline works in the **interactive** terminal. It does **not** work through
+ the AI \`run_command\` tool, which bypasses the pipe splitter — there \`|\` is refused too.
+- Operators inside quotes are untouched: \`echo "a && b"\` prints \`a && b\`.
+
+## Verifying your own result
+
+- Ask for two things, count that you got two lines back.
+- A suspiciously round or empty count means a broken probe, not a clean system.
+- \`ls\` prints text since v4.6.57 (it used to render chips only, so captured output was empty);
+ \`list_files\` remains the reliable enumerator.
+- An invalid \`grep\` pattern now returns \`grep: invalid pattern: …\` and does not enter the error
+ ledger — if you see a pattern exception, something regressed.
+
+## Pitfalls
+
+- A refusal is not a failed command: nothing ran. Split it and run both halves.
+- \`;\` used to fail loudly ("No such file: x;"). That loudness is gone in favour of an explicit
+ refusal — do not "fix" a refusal by re-joining the commands differently.
+- \`>\` is handled by \`echo\` only (\`echo hi > file\`). It is not a general redirect.
+
+## History
+
+Replaces \`terminal-commands-silently-failing\` and \`command-composition-rules\`, merged 2026-10-23
+after the behaviour itself was fixed in v4.6.58. \ No newline at end of file