aboutsummaryrefslogtreecommitdiff
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
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).
-rw-r--r--main.html6
-rw-r--r--modules/core/module-loader.js2
-rw-r--r--modules/ext/skill-pack-core.js52
-rw-r--r--skills/command-composition-rules.json15
-rw-r--r--skills/command-composition-rules.md54
-rw-r--r--skills/index.json38
6 files changed, 138 insertions, 29 deletions
diff --git a/main.html b/main.html
index 79c9b71..57017c5 100644
--- a/main.html
+++ b/main.html
@@ -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