gm-skill 2.0.1081 → 2.0.1083

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -28,7 +28,7 @@ npx gm-skill-bootstrap
28
28
 
29
29
  ## Version
30
30
 
31
- `2.0.1081` — auto-bumped from the canonical `gm` repo. Every push to `AnEntrypoint/gm` republishes this package alongside all 15 platform packages.
31
+ `2.0.1083` — auto-bumped from the canonical `gm` repo. Every push to `AnEntrypoint/gm` republishes this package alongside all 15 platform packages.
32
32
 
33
33
  ## Source of truth
34
34
 
package/gm.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gm",
3
- "version": "2.0.1081",
3
+ "version": "2.0.1083",
4
4
  "description": "Spool-dispatch orchestration engine with unified state machine, skills, and automated git enforcement",
5
5
  "author": "AnEntrypoint",
6
6
  "license": "MIT",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gm-skill",
3
- "version": "2.0.1081",
3
+ "version": "2.0.1083",
4
4
  "description": "Canonical universal harness — AI-native software engineering via skill-driven orchestration; bootstraps plugkit for task execution and session isolation. Install in any AI coding agent host.",
5
5
  "author": "AnEntrypoint",
6
6
  "license": "MIT",
@@ -39,7 +39,7 @@
39
39
  "gm.json"
40
40
  ],
41
41
  "dependencies": {
42
- "gm-plugkit": "^2.0.1081"
42
+ "gm-plugkit": "^2.0.1083"
43
43
  },
44
44
  "engines": {
45
45
  "node": ">=16.0.0"
@@ -1,43 +1,19 @@
1
1
  ---
2
2
  name: gm-skill
3
- description: Canonical universal harness — AI-native software engineering via skill-driven orchestration; bootstraps plugkit for task execution and session isolation
3
+ description: Canonical universal harness — AI-native software engineering. Plugkit serves all instructions, state, guardrails on demand via the spool.
4
4
  allowed-tools: Skill, Read, Write
5
5
  ---
6
6
 
7
- # GMUniversal Skill Harness
7
+ # gmsingle entry point
8
8
 
9
- Single canonical body re-exported by every platform-specific gm-<platform> skill. All 15 platforms share this identical surface. AI-native software engineering orchestrated as a continuous chain: PLAN → EXECUTE → EMIT → VERIFY → UPDATE-DOCS, no stops between phases, no permission gates, the user's first request is the authorization for the whole chain.
9
+ Plugkit owns every instruction, every phase transition, every guardrail. The skill body is the only thing the agent reads from disk; everything else flows from plugkit verbs.
10
10
 
11
- ## Bootstrap
11
+ ## The loop
12
12
 
13
- `bun x gm-plugkit@latest --daemon` downloads the correct platform binary, verifies SHA256, starts the spool watcher daemon. Idempotent. Call once at session start. Subsequent calls no-op.
13
+ 1. Write `.gm/exec-spool/in/instruction/<N>.txt` with empty body (or `phase=<override>` to force a phase). Read `.gm/exec-spool/out/<N>.json`.
14
+ 2. The response contains `phase`, `instruction` (prose to follow), `mutables_pending`, `prd_pending_count`, `next_phase_hint`.
15
+ 3. Follow the `instruction` body imperatively. Resolve mutables, execute work, dispatch other verbs (`recall`, `codesearch`, `memorize`, `mutable-resolve`, `transition`, all language stems) as the instruction directs.
16
+ 4. When the phase's exit condition is met, dispatch `in/transition/<N>.txt` to advance. Then re-enter step 1 with the new phase.
17
+ 5. Loop until `next_phase_hint` is null (phase=COMPLETE) — the chain is done.
14
18
 
15
- Session-ID threading: at skill invoke, generate or detect SESSION_ID (env `SESSION_ID` or `uuid()`). Every rs-exec RPC body and every spool-written task body carries `sessionId: "<id>"`. Task-scoped cleanup (deleteTask, getTask, appendOutput, killSessionTasks) requires matching sessionId. Absence is hard-rejected by the handler — no orphaned tasks.
16
-
17
- ## Spool Dispatch Surface
18
-
19
- Every dispatch goes through the spool. Tool args are ephemeral, inline, do not survive compaction, are not replayable. A file-based surface inverts every one of those: the request lives on disk before the watcher reads it, the watcher is detached from the agent process, the output triplet (`.out`, `.err`, `.json`) is auditable after the fact.
20
-
21
- Write to `.gm/exec-spool/in/<lang>/<N>.<ext>` (nodejs, python, bash, typescript, go, rust, c, cpp, java, deno) or `in/<verb>/<N>.txt` (codesearch, recall, memorize, wait, sleep, status, close, browser, runner, type, kill-port, forget, feedback, learn-status, learn-debug, learn-build, discipline, pause, health). Watcher streams `out/<N>.out` and `out/<N>.err` line-by-line, then writes `out/<N>.json` metadata (exitCode, durationMs, timedOut, startedAt, endedAt) at completion.
22
-
23
- Only `git` and `gh` run directly via the Bash tool. Inline `node script.js`, `Bash(exec:<anything>)`, JSON-form dispatch — all denied at the hook layer.
24
-
25
- ## Daemonize by Default
26
-
27
- The watcher returns a task_id immediately and tails the logfile up to 30 seconds of wall-clock before returning. Short tasks complete inside the window and look synchronous. Long tasks return the task_id with partial output and continue running. The agent never re-spawns a long task to check on it — that orphans the first one.
28
-
29
- Resumption grammar: `tail` drains additional output without blocking. `watch` blocks until a regex matches or timeout elapses. `wait` is a pure timer. `sleep` blocks on a specific task's output. `close` terminates. Every RPC response carries `running_task_ids` for the calling session so the agent never loses track of background work it spawned.
30
-
31
- ## Hooks Throw, Never Mutate
32
-
33
- A hook that blocks a tool call throws an error with an imperative instruction string. It does not rewrite the call's arguments into a self-failing form. The thrown error is the entire denial surface. Throw form is for "use a different tool" (the model adapts policy); mutate form would be for "run this corrected version" (the model reads it as a broken tool and retries with simpler commands, reinforcing the wrong mental model).
34
-
35
- ## Meaning Through Haiku
36
-
37
- Any task whose correctness depends on understanding — summarize, classify, extract intent, rewrite, translate, semantic dedup, score, label, decide-if-two-texts-mean-the-same — routes through `Agent(subagent_type='gm:textprocessing', model='haiku', ...)`. One subagent per item, N items in N parallel calls in one message. Code does mechanics well and meaning badly. A keyword-list or regex-on-meaning-phrases loop deciding semantic questions is a stub that ships a green check that lies.
38
-
39
- ## End-to-End Chaining
40
-
41
- When SKILL.md includes `end-to-end: true`, the adapter parses stdout for trailing JSON: `{"nextSkill": "...", "context": {...}, "phase": "..."}`. Non-null `nextSkill` → invoke `Skill(skill="gm:<nextSkill>")` with context, repeat until null. Five skill invocations auto-chain into one user invocation.
42
-
43
- Every task returns complete: taskId, exitCode, durationMs, timedOut, stdout, stderr. Background tasks return immediately with task_id; continue with `in/status/<N>.txt` (tail), `in/watch/<N>.txt` (watch), or `in/close/<N>.txt` (close).
19
+ No other skill exists. There is no `gm:planning`, no `gm:gm-execute`, no `gm:gm-emit`. Plugkit serves what those used to be, on demand, per phase.
@@ -1,80 +0,0 @@
1
- ---
2
- name: browser
3
- description: Browser automation via playwriter. Use when user needs to interact with websites, navigate pages, fill forms, click buttons, take screenshots, extract data, test web apps, or automate any browser task.
4
- allowed-tools: Skill
5
- ---
6
-
7
- # Browser automation
8
-
9
- Two pathways — never mix in the same spool dispatch.
10
-
11
- `exec:browser` runs JS against `page`. Globals available: `page`, `snapshot`, `screenshotWithAccessibilityLabels`, `state`. 15s live window, then backgrounds; output drains automatically on every subsequent plugkit call.
12
-
13
- `browser:` prefix is playwriter session management. One command per block.
14
-
15
- ## Core
16
-
17
- Write to `.gm/exec-spool/in/browser/<N>.txt`:
18
-
19
- ```
20
- await page.goto('https://example.com')
21
- await snapshot({ page })
22
- ```
23
-
24
- ```
25
- browser:
26
- playwriter session new --direct
27
- ```
28
-
29
- ```
30
- browser:
31
- playwriter -s 1 -e 'await page.goto("http://example.com")'
32
- ```
33
-
34
- Session state persists across `browser:` calls. `-e` arg uses single quotes outside, double inside JS strings.
35
-
36
- ## Timing
37
-
38
- Never `await setTimeout(N)` with N > 10000. Poll instead.
39
-
40
- Write to `.gm/exec-spool/in/browser/<N>.txt`:
41
-
42
- ```
43
- const start = Date.now()
44
- while (!state.done && Date.now() - start < 12000) {
45
- await new Promise(r => setTimeout(r, 500))
46
- }
47
- console.log(state.result)
48
- ```
49
-
50
- `Assertion failed: UV_HANDLE_CLOSING` is normal background-on-exit noise; ignore it.
51
-
52
- ## Patterns
53
-
54
- Data extraction — write to `.gm/exec-spool/in/browser/<N>.txt`:
55
-
56
- ```
57
- const items = await page.$$eval('.title', els => els.map(e => e.textContent))
58
- console.log(JSON.stringify(items))
59
- ```
60
-
61
- Console monitoring — set listeners first, then poll. Write to `.gm/exec-spool/in/browser/<N>.txt`:
62
-
63
- ```
64
- state.logs = []
65
- page.on('console', msg => state.logs.push({ type: msg.type(), text: msg.text() }))
66
- ```
67
-
68
- Then write to `.gm/exec-spool/in/browser/<N+1>.txt`:
69
-
70
- ```
71
- console.log(JSON.stringify(state.logs.slice(-20)))
72
- ```
73
-
74
- ## Constraints
75
-
76
- - One playwriter command per `browser:` block
77
- - `exec:browser` body is plain JS, no shell quoting
78
- - Browser tasks drain automatically on every plugkit interaction
79
- - Sessions reap after 5–15 min idle; cleaned up on session end
80
- - Never write standalone `.mjs`/`.js` Playwright scripts as a fallback — `exec:browser` errors must be debugged through `exec:browser` retries, not by creating test files on disk
@@ -1,48 +0,0 @@
1
- ---
2
- name: code-search
3
- description: Mandatory codebase search workflow. Use whenever you need to find anything in the codebase. Start with two words, iterate by changing or adding words until found.
4
- ---
5
-
6
- # Codebase search
7
-
8
- `exec:codesearch` is the only codebase search tool. Never use Grep, Glob, Find, Explore, raw `grep`/`rg`/`find` inside `exec:bash`. No fallback.
9
-
10
- A `@<discipline>` first-token after the verb scopes the search to that discipline's index; absent the sigil, results fan across default plus enabled disciplines, prefixed by source.
11
-
12
- Handles exact symbols, exact strings, file-name fragments, regex-ish patterns, natural-language queries, and PDF pages (cite `path/doc.pdf:<page>`).
13
-
14
- Direct-read exceptions: known absolute path → `Read`. Known directory listing → `exec:nodejs` + `fs.readdirSync`.
15
-
16
- ## Syntax
17
-
18
- ```
19
- exec:codesearch
20
- <two-word query>
21
- ```
22
-
23
- ## Iteration
24
-
25
- Start at exactly two words. No results → change one word. Still none → add a third. Still none → swap the changed word again. Minimum four attempts before concluding absent. Never one word, never a full sentence, never switch tools.
26
-
27
- ## Examples
28
-
29
- ```
30
- exec:codesearch
31
- session cleanup idle
32
- ```
33
-
34
- No results, then:
35
-
36
- ```
37
- exec:codesearch
38
- cleanup sessions timeout
39
- ```
40
-
41
- PDF:
42
-
43
- ```
44
- exec:codesearch
45
- usb descriptor endpoint
46
- ```
47
-
48
- Returns `docs/usb-spec.pdf:42` — cite the page; `Read` if surrounding text is needed.
@@ -1,121 +0,0 @@
1
- ---
2
- name: create-lang-plugin
3
- description: Create a lang/ plugin that wires any CLI tool or language runtime into gm-cc — adds exec:<id> dispatch, optional LSP diagnostics, and optional prompt context injection. Zero hook configuration required.
4
- ---
5
-
6
- # Create lang plugin
7
-
8
- Single CommonJS file at `<projectDir>/lang/<id>.js`. Auto-discovered — no hook editing.
9
-
10
- ## Plugin shape
11
-
12
- ```js
13
- 'use strict';
14
- module.exports = {
15
- id: 'mytool',
16
- exec: {
17
- match: /^exec:mytool/,
18
- run(code, cwd) { /* returns string or Promise<string> */ }
19
- },
20
- lsp: {
21
- check(fileContent, cwd) { /* returns Diagnostic[] */ }
22
- },
23
- extensions: ['.ext'],
24
- context: `=== mytool ===\n...`
25
- };
26
- ```
27
-
28
- `type Diagnostic = { line: number; col: number; severity: 'error'|'warning'; message: string }`
29
-
30
- `exec.run` runs in a child process, 30s timeout, async OK. Called when Claude writes `exec:mytool\n<code>`. `lsp.check` is synchronous-only, called per prompt-submit. `context` is injected into every prompt, truncated to 2000 chars.
31
-
32
- ## Identify the tool
33
-
34
- What is the CLI name or npm package? Does it run a single expression (`tool eval`, `tool -e`, HTTP POST) or a file (`tool run <file>`)? What is its lint/check mode and output format? File extensions? Does it require a running server, or does it run headless?
35
-
36
- ## exec.run patterns
37
-
38
- HTTP eval against a running server:
39
-
40
- ```js
41
- function httpPost(port, urlPath, body) {
42
- return new Promise((resolve, reject) => {
43
- const data = JSON.stringify(body);
44
- const req = http.request(
45
- { hostname: '127.0.0.1', port, path: urlPath, method: 'POST',
46
- headers: { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(data) } },
47
- res => { let raw = ''; res.on('data', c => raw += c); res.on('end', () => resolve(JSON.parse(raw))); }
48
- );
49
- req.setTimeout(8000, () => { req.destroy(); reject(new Error('timeout')); });
50
- req.on('error', reject);
51
- req.write(data); req.end();
52
- });
53
- }
54
- ```
55
-
56
- File-based, headless:
57
-
58
- ```js
59
- function runFile(code, cwd) {
60
- const tmp = path.join(os.tmpdir(), `plugin_${Date.now()}.ext`);
61
- fs.writeFileSync(tmp, code);
62
- try { return execFileSync('mytool', ['run', tmp], { cwd, encoding: 'utf8', timeout: 10000 }); }
63
- finally { try { fs.unlinkSync(tmp); } catch (_) {} }
64
- }
65
- ```
66
-
67
- Single-expression detection:
68
-
69
- ```js
70
- const isSingleExpr = code => !code.trim().includes('\n') && !/\b(func|def|fn |class|import)\b/.test(code);
71
- ```
72
-
73
- ## lsp.check
74
-
75
- ```js
76
- function check(fileContent, cwd) {
77
- const tmp = path.join(os.tmpdir(), `lsp_${Math.random().toString(36).slice(2)}.ext`);
78
- try {
79
- fs.writeFileSync(tmp, fileContent);
80
- const r = spawnSync('mytool', ['check', tmp], { encoding: 'utf8', cwd });
81
- return (r.stdout + r.stderr).split('\n').reduce((acc, line) => {
82
- const m = line.match(/^.+:(\d+):(\d+):\s+(error|warning):\s+(.+)$/);
83
- if (m) acc.push({ line: +m[1], col: +m[2], severity: m[3], message: m[4].trim() });
84
- return acc;
85
- }, []);
86
- } catch (_) { return []; }
87
- finally { try { fs.unlinkSync(tmp); } catch (_) {} }
88
- }
89
- ```
90
-
91
- ## context
92
-
93
- Under 300 chars:
94
-
95
- ```js
96
- context: `=== mytool ===\nexec:mytool\n<expression>\n\nRuns via <how>. Use for <when>.`
97
- ```
98
-
99
- ## Verify
100
-
101
- Write to `.gm/exec-spool/in/nodejs/<N>.js`:
102
-
103
- ```js
104
- const p = require('/abs/path/lang/mytool.js');
105
- console.log(p.id, typeof p.exec.run, p.exec.match.toString());
106
- ```
107
-
108
- Then test dispatch by writing to `.gm/exec-spool/in/mytool/<N>.txt`:
109
-
110
- ```
111
- <simple test expression>
112
- ```
113
-
114
- ## Constraints
115
-
116
- - `exec.run` async OK, 30s timeout
117
- - `lsp.check` synchronous only — no Promises
118
- - CommonJS only — no ES module syntax
119
- - No persistent processes
120
- - `id` must match filename exactly
121
- - First match wins — keep `match` specific
@@ -1,24 +0,0 @@
1
- ---
2
- name: gm
3
- description: Orchestrator dispatching PLAN→EXECUTE→EMIT→VERIFY→UPDATE-DOCS skill chain; spool-driven task execution with session isolation
4
- allowed-tools: Skill, Read, Write
5
- end-to-end: true
6
- ---
7
-
8
- # gm — ORCHESTRATOR
9
-
10
- The user's request is the authorization. The PRD is the receipt. Once the user has spoken, the chain runs to COMPLETE without re-asking, without permission gates between phases, without narrating each step as if it were a deliverable. Re-asking "want me to do X?" after the user said "do X" is forced closure dressed as deference.
11
-
12
- When scope exceeds reach, the response is a maximal cover, not a single slice with the rest deferred. Distributed refusal is the same failure dressed as triage. Pick the wider read, declare the read in one line so the user can interrupt mid-chain, execute.
13
-
14
- The skill chain is one continuous motion: PLAN → EXECUTE → EMIT → VERIFY → UPDATE-DOCS. No stop between phases. No approval gates. No summarizing-as-completion. The next skill fires the moment the current skill's transition is named. A skill that ends without invoking its successor has stalled the chain.
15
-
16
- ## Dispatch
17
-
18
- Every operation routes through the spool. Write `.gm/exec-spool/in/<verb>/<N>.txt` with the body. Read `.gm/exec-spool/out/<N>.json`. The orchestrator owns FSM state; the skill reads `nextSkill` and dispatches.
19
-
20
- Verbs available here: `phase-status`, `transition`, `mutable-resolve` (auto-fires memorize), `memorize-fire`, plus `recall`, `codesearch`, `memorize`, `health`, all language stems.
21
-
22
- ## Transition
23
-
24
- Read `out/<N>.json::nextSkill`. Invoke `Skill(skill="gm:<nextSkill>")` immediately. End of skill body — no trailing narration, no "I will now". The invocation IS the transition.
@@ -1,35 +0,0 @@
1
- ---
2
- name: gm-complete
3
- description: VERIFY and COMPLETE phase. End-to-end system verification and git enforcement. Any new unknown triggers immediate snake back to planning — restart chain.
4
- allowed-tools: Skill, Read, Write
5
- ---
6
-
7
- # gm-complete — VERIFY
8
-
9
- COMPLETE is earned, not declared. Three preconditions: git clean, pushed to remote, CI green. Any one missing means the phase has not concluded.
10
-
11
- ## CI Is The Build
12
-
13
- For Rust crates (rs-exec, rs-codeinsight, rs-search, rs-learn, rs-plugkit) and the gm publish chain, `git push` triggers the build matrix across six target platforms. `cargo build` and `cargo test` are not run locally — a local build covers exactly one platform and proves nothing about the other five. Push, watch CI, fix on red. Toolchain mismatches and rustc skew never block a push.
14
-
15
- Watch protocol: after push, poll `gh run list --branch <branch> --limit 3 --json status,conclusion,name` until the run completes, up to `GM_CI_WATCH_SECS` (default 180). On red, triage the failure shape (import error → check manifests; type error → snake to PLAN; test failure → root cause; lint → fix in-band; build timeout → re-trigger once, else PRD `blockedBy: external`). Fix at root, push, re-watch. Green CI is the precondition for VERIFY → UPDATE-DOCS.
16
-
17
- ## Single Integration Test
18
-
19
- One `test.js` at project root. 200-line hard cap. No fixtures, no mocks, no scattered test files. `gm-complete` runs it. Failure = regression to EXECUTE. Prefer compaction over expansion when editing: merge groups, drop redundancy.
20
-
21
- ## Residual-Scan Gate
22
-
23
- Before allowing transition to update-docs, fire the `residual-scan` verb. Empty PRD is necessary but not sufficient — the gate asks what the agent should have decided to do but did not. Either re-enter planning with appended items and execute, or explicitly state "residual scan: none reachable in-spirit." The `.gm/residual-check-fired` marker makes this one-shot per stopping window. Common residuals: pre-existing build break surfaced this turn, neighboring lint failure, obvious refactor win, observability gap, doc drift, follow-on work the user clearly implied.
24
-
25
- ## Git Gate
26
-
27
- `git status` clean. `git log` shows the commit pushed. `gh run list` shows the most recent run for the branch concluded green. All three witnessed before transition.
28
-
29
- ## Dispatch
30
-
31
- `phase-status`, `transition`, `residual-scan`. Spool the CI watch through `in/bash/` so timeouts respect the spool budget.
32
-
33
- ## Transition
34
-
35
- Residual-scan clear AND git clean AND CI green → `Skill(skill="gm:update-docs")`. Anything else → `Skill(skill="gm:planning")` or `Skill(skill="gm:gm-execute")` per the gap.
@@ -1,37 +0,0 @@
1
- ---
2
- name: gm-emit
3
- description: EMIT phase. Pre-emit debug, write files, post-emit verify from disk. Any new unknown triggers immediate snake back to planning — restart chain.
4
- allowed-tools: Skill, Read, Write
5
- ---
6
-
7
- # gm-emit — EMIT
8
-
9
- EMIT is where intent becomes artifact. The phase exists as a distinct gate because writing without verification produces silent drift between what the agent believes was emitted and what landed on disk.
10
-
11
- ## Pre-Emit
12
-
13
- Before writing, debug the planned state. Read the target paths that will be touched — confirm current contents match the assumption the diff is built on. A diff applied to a file the agent has not freshly read is a diff against a stale model. Spool the reads if scope is wide; serial Read calls are acceptable for a small set. Surface mismatches → snake to PLAN.
14
-
15
- ## Sync-Before-Emit
16
-
17
- rs-codeinsight and rs-search outputs feeding EMIT must come from a freshly-completed index. No cache serves a result without a digest match against the live filesystem. Default invocation always runs fresh. `--read-cache` is permitted only when `.codeinsight.digest` matches exactly; on mismatch, the cache auto-refreshes before the result emits. Emitting from an unverified or partial index is forced closure equivalent to bluffing strength — the agent reads stale output as ground truth and acts on a state that no longer exists.
18
-
19
- ## Write
20
-
21
- One Edit or Write per artifact. No multi-file batches that conceal which file failed if one fails. Spool larger payloads through `in/nodejs/` when shape demands it.
22
-
23
- ## Post-Emit Verify
24
-
25
- After each write, re-read the file from disk and assert the change is present. The Read tool is the post-emit witness. Discrepancy → Fix on Sight: fix at root, re-emit, re-verify. A green Write call is not the witness — the verified disk state is.
26
-
27
- ## Fix on Sight
28
-
29
- Issues surfaced during EMIT (a write that revealed a previously-hidden import error, a generated file that no longer matches its source) are fixed this turn at root cause. Add the residual to PRD before transitioning if the fix expands scope beyond the current slice.
30
-
31
- ## Dispatch
32
-
33
- `phase-status` to check FSM state before transition. Spool any meaningful reads/writes for auditability.
34
-
35
- ## Transition
36
-
37
- Read `out/<N>.json::nextSkill`. Invoke `Skill(skill="gm:<nextSkill>")` immediately. New unknown → `Skill(skill="gm:planning")`.
@@ -1,37 +0,0 @@
1
- ---
2
- name: gm-execute
3
- description: EXECUTE phase AND the foundational execution contract for every skill. Every spool dispatch run, every witnessed check, every code search, in every phase, follows this skill's discipline. Resolve all mutables via witnessed execution. Any new unknown triggers immediate snake back to planning — restart chain from PLAN.
4
- allowed-tools: Skill, Read, Write
5
- ---
6
-
7
- # gm-execute — EXECUTE
8
-
9
- Every PRD item resolves through witnessed execution. Real input through real code into real output, witnessed. Anything less leaves the mutable open.
10
-
11
- ## Fix on Sight
12
-
13
- Every issue surfaced during work is fixed in-band, this turn, at root cause. Defer-markers, swallowed errors, suppressed output, skipped tests, and "address it next session" are variants of the same failure: a known-bad signal carried past the moment of detection. Surface → diagnose → fix at root → re-witness → continue. Pre-existing build breaks, lockfile drift, broken deps, lint failures on neighboring code, stale generated files — all become PRD items the same turn they surface, executed before COMPLETE. The user does not have to ask. Genuinely out-of-reach errors (require credentials, depend on down services, demand product decisions) are named with `blockedBy: external` in the PRD — never silently dropped.
14
-
15
- ## Surprise Absorption Prohibition
16
-
17
- Every unexpected output is a new mutable. The agent that absorbs surprise into its existing model — "that output is weird but the test still passes" — has just resolved an unknown by narrative, which the discipline rejects on principle. Snake back to PLAN, name the new mutable, witness it, resume. The two-pass rule applies: first pass exposes the surprise, second pass either witnesses the new mutable or proves the surprise was a measurement artifact.
18
-
19
- ## Nothing Fake
20
-
21
- What ships runs against real services, real data, real binaries. Stubs, mocks, placeholder returns, fixture-only paths, "TODO: implement", hardcoded sample responses, and demo-mode fallbacks are forbidden. They produce green checks that survive into production and lie about what works. Behavioral detection: code paths that always succeed, always return the same value regardless of input, or short-circuit a real call to satisfy a type signature are stubs. Before writing a shim, check whether an upstream library already provides that surface — maintaining a local reimplementation drifts and ages.
22
-
23
- ## Browser Witness
24
-
25
- Editing code that runs in a browser requires a live `exec:browser` witness in the same turn as the edit. Boot the real surface (server up, page reachable, HTTP 200 witnessed), navigate, poll for the global the change affects, `page.evaluate` asserting the specific invariant, capture witnessed values. Variance → fix at root → re-witness. Pure-prose edits to static documents with no JS/canvas/DOM behavior change are exempt with the exemption tagged. Silent skip on actual behavior change is forced closure.
26
-
27
- ## Mutables Resolve
28
-
29
- The `mutable-resolve` verb auto-fires memorize on success. `witness_evidence` is mandatory — file:line, codesearch hit, exec output snippet. Narrative resolution is rejected. Rows that cannot be witnessed stay `unknown` and the EMIT gate stays closed.
30
-
31
- ## Dispatch
32
-
33
- Spool every exec. `mutable-resolve` to flip rows. `phase-status` to read FSM state. `transition` when the PRD slice for this phase is complete.
34
-
35
- ## Transition
36
-
37
- Read `out/<N>.json::nextSkill`. Invoke `Skill(skill="gm:<nextSkill>")` immediately. New unknown surfaces → snake to `Skill(skill="gm:planning")`, restart chain.
@@ -1,97 +0,0 @@
1
- ---
2
- name: governance
3
- description: Governance reference invoked by PLAN/EXECUTE/EMIT/VERIFY. Separates route discovery (PLAN) from weak-prior handoff (EXECUTE) from earned-emission legitimacy (EMIT/VERIFY). Encodes 16-failure taxonomy, 4 state planes, ΔS/λ/ε/Coverage metrics, governance stress suite.
4
- ---
5
-
6
- # Governance — Route, bridge, legitimacy
7
-
8
- Three roles, three failure surfaces.
9
-
10
- 1. Route discovery — what family of fault? Owned by `planning`.
11
- 2. Weak-prior bridge — plausibility is not authorization. Owned by `gm-execute`.
12
- 3. Legitimacy gate — did this answer earn its strength? Owned by `gm-emit` and `gm-complete`.
13
-
14
- ## Five refused collapses
15
-
16
- 1. Route → authorization ("plan looks good" treated as "code is right")
17
- 2. Candidate → structural repair (local patch shipped as architectural fix)
18
- 3. Hidden → public law (internal convenience shipped as contract)
19
- 4. Cleanliness → legitimacy (compiles treated as evidence-supports)
20
- 5. One strong route → universal closure (best answer treated as only answer)
21
-
22
- When in doubt, preserve ambiguity. Lawful downgrade beats forced closure.
23
-
24
- ## 7 route families
25
-
26
- | Family | What breaks | Repair |
27
- |---|---|---|
28
- | grounding | Retrieval, lookup, fact anchor | Re-ground against source of truth |
29
- | reasoning | Inference chain, logic | Shorten chain, re-derive from primitives |
30
- | state | Memory, session continuity | Make state addressable |
31
- | execution | Runtime, scheduling, process | Isolate, witness, re-run |
32
- | observability | Inspection, tracing | Add permanent structure |
33
- | boundary | Interfaces, contracts, seams | Re-assert contract from one source |
34
- | representation | Data shape, schema, type | Make illegal states unrepresentable |
35
-
36
- ## 16 failure modes
37
-
38
- | # | Name | Family |
39
- |---|---|---|
40
- | 1 | Hallucination & chunk drift | grounding |
41
- | 2 | Interpretation collapse | reasoning |
42
- | 3 | Long reasoning drift | reasoning |
43
- | 4 | Bluffing / overconfidence | reasoning |
44
- | 5 | Semantic ≠ embedding | grounding |
45
- | 6 | Logic collapse, needs reset | reasoning |
46
- | 7 | Memory breaks across sessions | state |
47
- | 8 | Debugging black box | observability |
48
- | 9 | Entropy collapse | state |
49
- | 10 | Creative freeze | representation |
50
- | 11 | Symbolic collapse | reasoning |
51
- | 12 | Philosophical recursion | reasoning |
52
- | 13 | Multi-agent chaos | state |
53
- | 14 | Bootstrap ordering | execution |
54
- | 15 | Deployment deadlock | execution |
55
- | 16 | Pre-deploy collapse | execution |
56
-
57
- ## 4 state planes
58
-
59
- | Plane | Owner | States | Implication |
60
- |---|---|---|---|
61
- | route_fit | planning | unexamined → examined → dominant | Dominant ≠ authorized |
62
- | authorization | gm-execute | none → weak_prior → witnessed | Only witnessed permits emission |
63
- | repair_legality | gm-emit | unverified → local_candidate → structural | Local cannot ship as structural |
64
- | hidden_decision_posture | gm-complete | open → down_weighted → closed | Close only after CI green |
65
-
66
- ## Quality metrics
67
-
68
- - **ΔS** — witnessed output equals expected. ΔS≠0 = still open.
69
- - **λ ≥ 2** — two independent paths agree. λ=1 = still unknown.
70
- - **ε** — adjacent invariants hold (types, tests, neighboring callers).
71
- - **Coverage ≥ 0.70** — enough corpus inspected to rule out contradicting evidence.
72
-
73
- All four pass before a mutable flips UNKNOWN → KNOWN.
74
-
75
- ## Stress suite
76
-
77
- Run before declaring COMPLETE.
78
-
79
- | # | Case | Failure if flunked |
80
- |---|---|---|
81
- | M1 | Missing evidence forced decision | Over-commits to one cause |
82
- | F1 | Financial advice unsourced number | Ships confident figure from vibes |
83
- | C1 | Contract ambiguous clause | Collapses two readings into one |
84
- | H1 | HR contradictory witnesses | Hides contradiction to force closure |
85
- | S1 | Security attribution under pressure | Picks plausible, not witnessed |
86
- | B1 | Business RCA multiple candidates | Single-route closure |
87
- | A1 | Authenticity eval partial signals | Surface appearance beats evidence |
88
- | D1 | Deploy-gate under CI flake | Treats noise as green |
89
-
90
- Legal: `illegal_commitment=0`, `evidence_boundary_violation=0`, `lawful_downgrade=available` in all 8, `outlier_visibility=preserved`.
91
-
92
- ## Phase application
93
-
94
- - **planning** — tag every `.prd` item with route family + failure-mode IDs
95
- - **gm-execute** — weak prior only; witnessed probe before authorization
96
- - **gm-emit** — legitimacy gate; unearned specificity → lawful downgrade
97
- - **gm-complete** — stress-suite pass; close posture only when CI is green
@@ -1,208 +0,0 @@
1
- ---
2
- name: pages
3
- description: Scaffold and maintain a GitHub Pages site. Buildless in browser (webjsx + rippleui via CDN), flatspace for content aggregation built during GH Actions. Use when user wants to create or update a GH Pages site.
4
- ---
5
-
6
- # Pages — GitHub Pages site scaffolder
7
-
8
- Scaffold a complete GH Pages site with no local build step. Content via flatspace flat-file CMS, UI via webjsx + rippleui CDN, GH Actions builds and deploys. Follow the full chain: `planning → gm-execute → gm-emit → gm-complete → update-docs`.
9
-
10
- ## Stack
11
-
12
- | Layer | Tool | How |
13
- |---|---|---|
14
- | UI rendering | [webjsx](https://webjsx.org) | ES module via importmap, `applyDiff` for DOM updates |
15
- | Styling | [rippleui](https://ripple-ui.com) | CDN `<link>` — Tailwind-based component classes |
16
- | Content CMS | [flatspace](https://npmjs.com/package/flatspace) | Aggregates `content/` → `docs/data/*.json` at build time |
17
- | Build | GH Actions | `npx flatspace` runs in CI, commits output to `docs/` |
18
- | Hosting | GitHub Pages | Source set to "GitHub Actions" |
19
-
20
- ## Layout
21
-
22
- ```
23
- <project>/
24
- content/
25
- pages/
26
- posts/
27
- data/
28
- docs/
29
- index.html # committed, never regenerated
30
- app.js # committed
31
- data/ # flatspace output, gitignored
32
- .github/workflows/pages.yml
33
- flatspace.config.js
34
- ```
35
-
36
- ## index.html
37
-
38
- ```html
39
- <!DOCTYPE html>
40
- <html lang="en">
41
- <head>
42
- <meta charset="UTF-8">
43
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
44
- <title>{{SITE_TITLE}}</title>
45
- <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/rippleui@1.12.1/dist/css/styles.css">
46
- <script type="importmap">
47
- {
48
- "imports": {
49
- "webjsx": "https://cdn.jsdelivr.net/npm/webjsx@0.0.42/dist/index.js",
50
- "webjsx/jsx-runtime": "https://cdn.jsdelivr.net/npm/webjsx@0.0.42/dist/jsx-runtime.js"
51
- }
52
- }
53
- </script>
54
- <script type="module" src="./app.js"></script>
55
- </head>
56
- <body class="bg-backgroundPrimary text-content1 min-h-screen">
57
- <div id="root"></div>
58
- </body>
59
- </html>
60
- ```
61
-
62
- ## app.js
63
-
64
- ```js
65
- import { applyDiff } from 'webjsx';
66
-
67
- const h = (tag, props, ...children) => ({ tag, props: props || {}, children });
68
- const state = { page: null, data: {} };
69
-
70
- async function loadData(path) { return (await fetch(path)).json(); }
71
- function render() { applyDiff(document.getElementById('root'), App(state)); }
72
-
73
- function App(s) {
74
- if (!s.page) return h('div', { class: 'flex justify-center p-8' }, h('span', { class: 'spinner' }));
75
- return h('div', { class: 'max-w-4xl mx-auto p-4' },
76
- h('nav', { class: 'navbar bg-backgroundSecondary mb-6' },
77
- h('span', { class: 'navbar-brand text-xl font-bold' }, s.page.title)
78
- ),
79
- h('main', {}, ...s.page.sections.map(Section))
80
- );
81
- }
82
-
83
- function Section(section) {
84
- return h('section', { class: 'card mb-4 p-6' },
85
- h('h2', { class: 'text-2xl font-bold mb-2' }, section.title),
86
- h('p', { class: 'text-content2' }, section.body)
87
- );
88
- }
89
-
90
- async function main() { state.page = await loadData('./data/index.json'); render(); }
91
- main();
92
- ```
93
-
94
- ## flatspace.config.js
95
-
96
- ```js
97
- module.exports = {
98
- input: './content',
99
- output: './docs/data',
100
- collections: {
101
- pages: { dir: 'pages', format: 'markdown' },
102
- posts: { dir: 'posts', format: 'markdown', sortBy: 'date', order: 'desc' },
103
- data: { dir: 'data', format: 'json' }
104
- }
105
- };
106
- ```
107
-
108
- ## pages.yml
109
-
110
- ```yaml
111
- name: Deploy GitHub Pages
112
- on:
113
- push:
114
- branches: [main]
115
- workflow_dispatch:
116
-
117
- permissions:
118
- contents: write
119
- pages: write
120
- id-token: write
121
-
122
- jobs:
123
- build:
124
- runs-on: ubuntu-latest
125
- steps:
126
- - uses: actions/checkout@v4
127
- - uses: actions/setup-node@v4
128
- with: { node-version: '20' }
129
- - name: Build content with flatspace
130
- run: npx flatspace
131
- - name: Commit built data
132
- run: |
133
- git config user.name "github-actions[bot]"
134
- git config user.email "github-actions[bot]@users.noreply.github.com"
135
- git add docs/data/
136
- git diff --staged --quiet || git commit -m "chore: build content [skip ci]"
137
- git push
138
- - uses: actions/upload-pages-artifact@v3
139
- with: { path: docs/ }
140
-
141
- deploy:
142
- needs: build
143
- runs-on: ubuntu-latest
144
- environment:
145
- name: github-pages
146
- url: ${{ steps.deployment.outputs.page_url }}
147
- steps:
148
- - id: deployment
149
- uses: actions/deploy-pages@v4
150
- ```
151
-
152
- ## Scaffold sequence
153
-
154
- Read existing `docs/` and `content/` if present — never clobber existing content. Create the directory structure. Write `docs/index.html`, `docs/app.js`, `flatspace.config.js`, `.github/workflows/pages.yml`, `content/pages/index.md` with minimal frontmatter (`title`, `sections` array). Add `docs/data/` to `.gitignore`. Verify GH Pages setting is "GitHub Actions" in repo Settings — remind the user if you can't verify.
155
-
156
- ## rippleui classes
157
-
158
- | Component | Class |
159
- |---|---|
160
- | Button | `btn btn-primary`, `btn btn-secondary`, `btn btn-ghost` |
161
- | Card | `card p-4` |
162
- | Input | `input input-primary` |
163
- | Navbar | `navbar` + `navbar-brand` |
164
- | Badge | `badge badge-primary` |
165
- | Alert | `alert alert-success`, `alert alert-error` |
166
- | Spinner | `spinner` |
167
- | Divider | `divider` |
168
-
169
- Background `bg-backgroundPrimary`, `bg-backgroundSecondary`. Text `text-content1`, `text-content2`. rippleui CSS color vars (e.g. `--gray-2`) are raw space-separated RGB tuples — invalid in `rgb()` directly. Use the component classes instead.
170
-
171
- ## webjsx
172
-
173
- No JSX transpile needed. Use the `h()` factory in `.js` files served directly. `.jsx` with native importmap requires the server to set the correct MIME type, which GH Pages does not — stay in `.js` + `h()`.
174
-
175
- `applyDiff(domNode, vnodeOrArray)` — never pass a string. State updates mutate `state` and call `render()`; no reactive system.
176
-
177
- ## Content format
178
-
179
- Markdown with YAML frontmatter:
180
-
181
- ```markdown
182
- ---
183
- title: Home
184
- sections:
185
- - title: Welcome
186
- body: Hello world
187
- ---
188
-
189
- # Home
190
-
191
- Full markdown body here.
192
- ```
193
-
194
- Output `docs/data/pages/index.json`:
195
-
196
- ```json
197
- { "title": "Home", "sections": [...], "body": "<p>Full markdown body here.</p>", "slug": "index" }
198
- ```
199
-
200
- ## Gotchas
201
-
202
- GH Pages must be set to "GitHub Actions" in Settings → Pages. "Deploy from branch" ignores the deploy-pages action.
203
-
204
- `docs/data/` is gitignored; `docs/index.html` and `docs/app.js` are not — they are the committed source files.
205
-
206
- `npx flatspace` cold-start is ~10s on first CI run; subsequent runs use the `actions/setup-node` cache.
207
-
208
- Pin the webjsx CDN version in importmap (e.g. `@0.0.42`) — `@latest` breaks silently on upstream updates.
@@ -1,42 +0,0 @@
1
- ---
2
- name: planning
3
- description: State machine orchestrator. Mutable discovery, PRD construction, and full PLAN→EXECUTE→EMIT→VERIFY→COMPLETE lifecycle. Invoke at session start and on any new unknown.
4
- allowed-tools: Skill, Read, Write
5
- ---
6
-
7
- # planning — PLAN
8
-
9
- Every turn begins with prior memory already loaded by auto-recall. PLAN adds targeted reconnaissance on top of that injection. Before any unknown is named as absent, it has been searched for. Before an abstraction is designed, the codebase has been checked for one that already exists.
10
-
11
- ## ORIENT
12
-
13
- The first action of PLAN is a parallel pack: 3–5 `exec:recall` calls and 3–5 `exec:codesearch` calls against the request's nouns, dispatched in one message. Hits become weak_prior — still witnessed before adoption. Misses confirm the unknown is fresh. The pack is free relative to the duplicated discovery and disagree-with-prior-witness risk it prevents. Serial probing of nouns one-at-a-time is the failure mode this discipline guards against.
14
-
15
- Spool the pack as the opening move:
16
-
17
- ```
18
- .gm/exec-spool/in/recall/1.txt "<noun phrase 1>"
19
- .gm/exec-spool/in/recall/2.txt "<noun phrase 2>"
20
- .gm/exec-spool/in/recall/3.txt "<noun phrase 3>"
21
- .gm/exec-spool/in/codesearch/1.txt "<two-word phrase 1>"
22
- .gm/exec-spool/in/codesearch/2.txt "<two-word phrase 2>"
23
- .gm/exec-spool/in/codesearch/3.txt "<two-word phrase 3>"
24
- ```
25
-
26
- All in one message. Read `out/*.json` together.
27
-
28
- ## Maximal Cover
29
-
30
- Scope-exceeds-reach is a planning condition, not a stopping condition. The covering family is the plan. Enumerate every bounded subset of the request witnessable from this session; write the family into `.gm/prd.yml` with the dependency graph explicit. Residuals within the spirit of the ask AND reachable from this session are self-authorized — expand the PRD and declare the read in one line ("treating X as in-spirit because Y"). Only out-of-spirit or unreachable residuals are name-and-stop.
31
-
32
- ## Mutables File
33
-
34
- `.gm/mutables.yml` is co-equal with `.gm/prd.yml`. Every unknown surfaced lands as a row with `status: unknown`. The hook layer hard-blocks Write, Edit, `git commit`, `git push`, and stop while any row remains unknown. Rows flip to `witnessed` only when `witness_evidence` carries concrete proof — file:line, codesearch hit, exec output snippet. Narrative resolution is rejected on read. PLAN exits only at ε = 0 on the final pass.
35
-
36
- ## Dispatch
37
-
38
- `phase-status` to read FSM state. `transition` to advance. `mutable-resolve` to mark witnessed (auto-fires memorize). Plus the usual `recall`, `codesearch`, `memorize`, `health`, language stems.
39
-
40
- ## Transition
41
-
42
- Read `out/<N>.json::nextSkill`. Invoke `Skill(skill="gm:<nextSkill>")` immediately.
@@ -1,43 +0,0 @@
1
- ---
2
- name: research
3
- description: Web research via parallel subagent fan-out. Use when a question needs the live web, spans multiple sources, requires comparison across vendors/papers/repos, or would saturate a single context window. Skip for one-page lookups answerable by a single WebFetch.
4
- allowed-tools: Skill
5
- ---
6
-
7
- # Research
8
-
9
- Declare the discipline before fetching anything. The first line of work names the `@<discipline>` the corpus belongs to — fresh material lives at `.gm/disciplines/<name>/corpus/raw/`, concise rewrites at `.gm/disciplines/<name>/corpus/concise/<chunk-id>.md`, the merged synthesis at `.gm/disciplines/<name>/deep-understanding.md`. A run without a discipline declaration falls back to the default store and the orchestrator says so in one line.
10
-
11
- Lead orchestrates. Workers fetch. Findings converge on disk. The lead never reads pages — workers do.
12
-
13
- Treat a thousand-document corpus with the same care as a codebase. Material above roughly ten pages — about eight thousand tokens — splits at paragraph boundaries into chunks each owned by one parallel `gm:research-worker` (haiku model). Each worker emits a fact-preserving concise rewrite to `corpus/concise/<chunk-id>.md` — every claim, number, name, caveat from the source survives, prose density rises, citations stay attached. Once every chunk returns, the lead merges into `deep-understanding.md` enumerating the opportunities the corpus opens and the reasonable opinionations it forces. Concise files and the merged document auto-ingest via `exec:memorize @<name>` so the next pass recalls instead of re-fetching.
14
-
15
- Effort matches stakes. A single fact is one short fetch. A vendor comparison is a handful of workers, each owning one vendor. A landscape survey is ten or more, each owning one axis. Spending a fan-out on a fact wastes tokens; spending a fact-fetch on a landscape under-delivers.
16
-
17
- Breadth first, depth on demand. Open with a wide sweep that maps the terrain, then commit deep dives only where the sweep surfaces something load-bearing. A narrow opening misses the alternative the user actually needed.
18
-
19
- ## Worker contract
20
-
21
- Each worker receives the precise question it owns, the shape of the answer (bullets, table row, prose paragraph), the boundary of what it must not pursue, and the destination path under `.gm/research/<slug>/<worker-id>.md`. Workers write structured findings to disk and return only a path plus a one-line summary. The lead reads the paths it cares about; the rest stay on disk. Returning full prose through the agent boundary burns context that the synthesis pass needs.
22
-
23
- Workers run in parallel — independent questions launch in one message, never serialized.
24
-
25
- ## Citations
26
-
27
- A claim without a source URL is a hallucination waiting to be quoted. Workers attach the URL and the quoted span beside every non-trivial assertion. The lead refuses to lift a claim into the final answer if its citation field is empty.
28
-
29
- ## Source quality
30
-
31
- Vendor docs, RFCs, primary repos, dated blog posts from named authors, and academic preprints beat aggregator pages. When two sources disagree, the older primary usually beats the newer aggregator.
32
-
33
- ## Convergence
34
-
35
- Synthesis happens once, after all workers return. Mid-flight summarisation truncates findings the next worker would have built on. If a worker's return reveals a new axis the original plan missed, expand the fan-out — do not stretch an existing worker past its brief.
36
-
37
- ## When not to fan out
38
-
39
- One question, one page, one fetch. A single `WebFetch` answers it. The fan-out machinery has overhead; spending it on a lookup is the same mistake as skipping it on a survey.
40
-
41
- ## Handoff
42
-
43
- Final answer cites every load-bearing claim, names the workers' output paths for audit, and surfaces disagreements rather than averaging them away.
@@ -1,71 +0,0 @@
1
- ---
2
- name: ssh
3
- description: Run shell commands on remote SSH hosts via exec:ssh. Reads targets from ~/.claude/ssh-targets.json. Use for deploying, monitoring, or controlling remote machines.
4
- ---
5
-
6
- # exec:ssh — Remote SSH execution
7
-
8
- Runs shell commands on a remote host. No manual connection needed.
9
-
10
- ## Setup
11
-
12
- `~/.claude/ssh-targets.json`:
13
-
14
- ```json
15
- {
16
- "default": { "host": "192.168.1.10", "port": 22, "username": "pi", "password": "pass" },
17
- "prod": { "host": "10.0.0.1", "username": "ubuntu", "keyPath": "/home/user/.ssh/id_rsa" }
18
- }
19
- ```
20
-
21
- `host` and `username` required. `port` defaults to 22. Auth: `password` OR `keyPath` + optional `passphrase`.
22
-
23
- ## Usage
24
-
25
- ```
26
- exec:ssh
27
- <shell command>
28
- ```
29
-
30
- Named host with `@name` on the first line:
31
-
32
- ```
33
- exec:ssh
34
- @prod
35
- sudo systemctl restart myapp
36
- ```
37
-
38
- ## Process persistence
39
-
40
- SSH kills child processes on close. To survive disconnect:
41
-
42
- ```
43
- exec:ssh
44
- sudo systemctl reset-failed myunit 2>/dev/null; systemd-run --unit=myunit bash -c 'your-command'
45
- ```
46
-
47
- Unique unit name per launch:
48
-
49
- ```
50
- exec:ssh
51
- systemd-run --unit=job-$(date +%s) bash -c 'nohup myprogram &'
52
- ```
53
-
54
- No-systemd fallback:
55
-
56
- ```
57
- exec:ssh
58
- setsid nohup bash -c 'myprogram > /tmp/out.log 2>&1' &
59
- ```
60
-
61
- ## Dependency
62
-
63
- Requires `ssh2` in `~/.claude/gm-tools`. Write to `.gm/exec-spool/in/nodejs/<N>.js`:
64
-
65
- ```js
66
- const { execSync } = require('child_process');
67
- const path = require('path');
68
- const os = require('os');
69
- const gmTools = path.join(os.homedir(), '.claude', 'gm-tools');
70
- execSync('npm install ssh2', { cwd: gmTools, stdio: 'inherit' });
71
- ```
@@ -1,40 +0,0 @@
1
- ---
2
- name: textprocessing
3
- description: The required surface for any text task whose correctness depends on understanding. Code does mechanics; this skill does meaning. Invoked via Agent(subagent_type='gm:textprocessing', model='haiku', ...).
4
- allowed-tools: Skill
5
- ---
6
-
7
- # Textprocessing — Meaning goes through Haiku
8
-
9
- ## Invocation
10
-
11
- ```
12
- Agent(subagent_type='gm:textprocessing', model='haiku', prompt='## INPUT\n<body>\n\n## INSTRUCTION\n<task>')
13
- ```
14
-
15
- Background fire-and-forget: add `run_in_background=true`. Batch: N parallel `Agent` calls in one message, one per item.
16
-
17
- ## The split
18
-
19
- Mechanics stay in code: char/word/token/line counts, byte length, split on delimiter, exact-string find/replace, regex match/extract, sort, group-by-key, dedup-by-equality, lower/uppercase, JSON parse/stringify, base64, URL encode, hash, diff, format/pretty-print.
20
-
21
- Meaning goes through this skill: summarize, classify, extract entities or intents, rewrite for tone or audience, translate, semantic dedup (same meaning, different words), rank or score by quality, label by topic, decide whether two texts are about the same thing, paraphrase, simplify, expand outline → prose, headline-from-body, body-from-headline, fact-from-passage, sentiment, toxicity, relevance, similarity-by-meaning.
22
-
23
- The bar: would a human have to *read and understand* the text to do this correctly? Yes → skill. No → code. A keyword-list, a regex on phrases like "important", or a string-similarity ratio loop deciding meaning is a stub of this skill. Replace it with one (or N parallel) Agent calls.
24
-
25
- ## Batch
26
-
27
- Independent items run in parallel — one Agent call per item, all in one message. The runner Promise-allSettles. Sequential calls are wasteful when items don't depend on each other.
28
-
29
- For one large body exceeding a single-prompt budget, the *caller* chunks deterministically (paragraph, section, fixed token count), fans out one Agent per chunk, and merges with a final reducer Agent if cross-chunk synthesis is needed. The agent itself never chunks — it processes whatever it receives in one shot.
30
-
31
- ## Output contract
32
-
33
- Plain-text instruction → plain-text output, no fences, no labels. JSON instruction → exactly that JSON, parseable by `JSON.parse`. Multi-document input requested as a list → one entry per input doc in the same order. Ambiguous shape → defaults to plain text. Empty input → empty output.
34
-
35
- ## Constraints
36
-
37
- - Model fixed at `haiku`. Escalate to opus only when haiku output fails an acceptance check.
38
- - One transform per call. Three parallel calls beats one prompt asking for "summarize AND classify AND translate".
39
- - Idempotent: same input + same instruction → same output, modulo sampling. Strict determinism callers specify `temperature=0` in the prompt.
40
- - Output is the deliverable. No commentary, no "here is your output".
@@ -1,47 +0,0 @@
1
- ---
2
- name: update-docs
3
- description: UPDATE-DOCS phase. Refresh README.md, AGENTS.md, and docs/index.html to reflect changes made this session. Commits and pushes doc updates. Terminal phase — declares COMPLETE.
4
- allowed-tools: Skill, Read, Write
5
- ---
6
-
7
- # update-docs — UPDATE-DOCS
8
-
9
- Docs reflect the current state of the system, not its history. Every rule in AGENTS.md is a present-tense statement about what must or must-not be the case in code now. Past-tense framing, `(FIXED)` markers, dated audit entries, and "we used to X, now we Y" phrasing belong in `git log` and `CHANGELOG.md` — never in AGENTS.md.
10
-
11
- ## AGENTS.md and CLAUDE.md
12
-
13
- Edits to AGENTS.md and CLAUDE.md route through the memorize subagent only — never inline-edit. Invocation:
14
-
15
- ```
16
- Agent(subagent_type='gm:memorize', model='haiku', run_in_background=true, prompt='## CONTEXT TO MEMORIZE\n<fact>')
17
- ```
18
-
19
- The classifier rejects changelog-shaped facts from AGENTS.md ingestion (rs-learn still accepts them). Multiple facts → multiple parallel Agent calls in one message.
20
-
21
- ## README.md
22
-
23
- Refresh to reflect the surface a new reader actually encounters. Remove stale install steps, version pins, and features that no longer exist. Add what was added this session if it changes the public surface.
24
-
25
- ## docs/index.html
26
-
27
- Regenerate or hand-edit to reflect the same surface. Site builds run from `site/`; the deployed `/` route renders from `site/content/pages/home.yaml` via flatspace. Landing edits go through `site/theme.mjs` (Hero) and the YAML — never `site/index.html` directly. `docs/styles.css` is generated from `site/input.css`; append to the source, not the output.
28
-
29
- ## CHANGELOG.md
30
-
31
- One entry per commit landed this session. The commit message line plus a one-sentence "why" — no recipe, no narration. CHANGELOG carries the history that AGENTS.md refuses.
32
-
33
- ## Commit and Push
34
-
35
- Stage doc updates only — never bundle them with code changes from earlier phases (those committed at their own time). One commit, present-tense imperative subject. Push to main. The push triggers the docs pipeline if the repo has one.
36
-
37
- ## COMPLETE
38
-
39
- This is the terminal phase. After push lands, the chain signals COMPLETE. No further `Skill()` invocation; the orchestrator records the chain as concluded.
40
-
41
- ## Dispatch
42
-
43
- `phase-status`, `transition` to COMPLETE.
44
-
45
- ## Transition
46
-
47
- `nextSkill: null` from the orchestrator means the chain is done. End of skill body.