diff options
| author | Agando <roduccomm@gmail.com> | 2026-10-23 18:27:26 +0200 |
|---|---|---|
| committer | Agando <roduccomm@gmail.com> | 2026-10-23 18:27:26 +0200 |
| commit | 87f44c42aeb763e2aaf3da159d60b252dca9aa53 (patch) | |
| tree | 8a2718d191504d694ac187d47e7cdc77a5695d45 | |
| parent | 9c27d3790b594c94430015675c91ce618c61be1d (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).
| -rw-r--r-- | main.html | 6 | ||||
| -rw-r--r-- | modules/core/module-loader.js | 2 | ||||
| -rw-r--r-- | modules/ext/skill-pack-core.js | 52 | ||||
| -rw-r--r-- | skills/command-composition-rules.json | 15 | ||||
| -rw-r--r-- | skills/command-composition-rules.md | 54 | ||||
| -rw-r--r-- | skills/index.json | 38 |
6 files changed, 138 insertions, 29 deletions
@@ -1349,13 +1349,13 @@ </script> <!-- v4.5.63: A2A scratchpad fixes + agent-register arg fix --> -<script src="modules/core/core-bundle.js?v=v4.6.64"></script> +<script src="modules/core/core-bundle.js?v=v4.6.65"></script> <!-- Async dependency-ordered module loader now only initializes terminal and loads optional ext modules --> -<script src="modules/core/module-loader.js?v=v4.6.64"></script> +<script src="modules/core/module-loader.js?v=v4.6.65"></script> <!-- Critical ext bundle loads AFTER webx11 exists so registerModule calls work --> -<script src="modules/ext/critical-ext-bundle.js?v=v4.6.64"></script> +<script src="modules/ext/critical-ext-bundle.js?v=v4.6.65"></script> <script> // ═══ ONE TRUE VERSION SOURCE ═══ diff --git a/modules/core/module-loader.js b/modules/core/module-loader.js index abc1a86..e3905ee 100644 --- a/modules/core/module-loader.js +++ b/modules/core/module-loader.js @@ -4,7 +4,7 @@ // Core module bundle loaded synchronously in main.html. // This loader only handles version cache-busting, splash, terminal init, and optional ext modules. - const LATEST_VER = 'v4.6.64'; + const LATEST_VER = 'v4.6.65'; const CACHE = '?v=' + LATEST_VER; const stored = localStorage.getItem('webx11_cache_ver'); if (stored !== LATEST_VER) { diff --git a/modules/ext/skill-pack-core.js b/modules/ext/skill-pack-core.js index 5c317a4..c3c643b 100644 --- a/modules/ext/skill-pack-core.js +++ b/modules/ext/skill-pack-core.js @@ -55,6 +55,58 @@ class SkillPackCoreModule { }); return [ + // v4.6.65: merged from `command-composition-rules` and + // `terminal-commands-silently-failing` (packet §9) — they described one bug family + // from two angles, and both are now describing behaviour that is refused outright. + sk('command-composition-rules', 'The terminal has no shell: what is refused, what works, and how to verify a result that looks plausible', ['terminal', 'shell', 'composition', 'safety', 'agent'], '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.`), s('navigating-the-terminal', 'How to explore the WebX11 terminal, find commands, check status, and navigate the filesystem', ['terminal', 'navigation', 'help', 'filesystem'], 'system', `1. **Get an overview of available commands:** - Type "help" for a full command list sorted by category 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 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 diff --git a/skills/index.json b/skills/index.json index 5f8d78a..4bce206 100644 --- a/skills/index.json +++ b/skills/index.json @@ -108,7 +108,7 @@ }, "module-editing-workflow": { "name": "module-editing-workflow", - "description": "Step-by-step procedure for editing a WebX11 module: view → edit → test → keep or reload", + "description": "Step-by-step procedure for editing a WebX11 module: view \u2192 edit \u2192 test \u2192 keep or reload", "tags": [ "modules", "editing", @@ -121,7 +121,7 @@ }, "vfs-content-search": { "name": "vfs-content-search", - "description": "Find files in the VFS by semantic concept (NVFS) or by content keyword (grep) — decision table", + "description": "Find files in the VFS by semantic concept (NVFS) or by content keyword (grep) \u2014 decision table", "tags": [ "vfs", "search", @@ -148,7 +148,7 @@ }, "vfs-path-normalize": { "name": "vfs-path-normalize", - "description": "Strip trailing slashes from VFS paths before API calls — prevents /skills/ vs /skills resolution failures", + "description": "Strip trailing slashes from VFS paths before API calls \u2014 prevents /skills/ vs /skills resolution failures", "tags": [ "vfs", "utility", @@ -223,30 +223,18 @@ "created": "2026-06-05T22:10:06.670Z", "updated": "2026-06-05T22:13:42.539Z" }, - "skills-system-guide": { - "name": "skills-system-guide", - "description": "How to use the skills system: load, create, patch, list, and audit skills for persistent procedural memory", - "tags": [ - "skills", - "system", - "meta" - ], - "category": "system", - "created": "2026-06-05T22:10:06.669Z", - "updated": "2026-06-05T22:13:42.539Z" - }, - "webdav-operations": { - "name": "webdav-operations", - "description": "How to use WebDAV cloud storage for backup, file sync, and remote file access", + "command-composition-rules": { + "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": [ - "webdav", - "cloud", - "backup", - "sync", - "storage" + "terminal", + "shell", + "composition", + "safety", + "agent" ], "category": "system", - "created": "2026-06-05T22:10:06.670Z", - "updated": "2026-06-05T22:13:42.539Z" + "created": "2026-10-23T16:27:07.000Z", + "updated": "2026-10-23T16:27:07.000Z" } }
\ No newline at end of file |