gm-cc 2.0.727 → 2.0.1064

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.
Files changed (44) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/agents/gm.md +1 -3
  3. package/agents/memorize.md +22 -2
  4. package/agents/research-worker.md +36 -0
  5. package/agents/textprocessing.md +47 -0
  6. package/bin/bootstrap.js +624 -34
  7. package/bin/plugkit.js +95 -53
  8. package/bin/plugkit.sha256 +6 -6
  9. package/bin/plugkit.version +1 -1
  10. package/bin/rtk.sha256 +6 -0
  11. package/bin/rtk.version +1 -0
  12. package/hooks/hooks.json +2 -46
  13. package/hooks/hooks.spec.json +48 -0
  14. package/package.json +2 -2
  15. package/plugin.json +1 -1
  16. package/skills/browser/SKILL.md +18 -16
  17. package/skills/code-search/SKILL.md +15 -15
  18. package/skills/create-lang-plugin/SKILL.md +22 -26
  19. package/skills/gm/SKILL.md +31 -66
  20. package/skills/gm-cc/SKILL.md +19 -0
  21. package/skills/gm-codex/SKILL.md +19 -0
  22. package/skills/gm-complete/SKILL.md +52 -69
  23. package/skills/gm-copilot-cli/SKILL.md +19 -0
  24. package/skills/gm-cursor/SKILL.md +19 -0
  25. package/skills/gm-emit/SKILL.md +44 -61
  26. package/skills/gm-execute/SKILL.md +42 -84
  27. package/skills/gm-gc/SKILL.md +19 -0
  28. package/skills/gm-jetbrains/SKILL.md +19 -0
  29. package/skills/gm-kilo/SKILL.md +19 -0
  30. package/skills/gm-oc/SKILL.md +19 -0
  31. package/skills/gm-vscode/SKILL.md +19 -0
  32. package/skills/gm-zed/SKILL.md +19 -0
  33. package/skills/governance/SKILL.md +24 -23
  34. package/skills/pages/SKILL.md +42 -92
  35. package/skills/planning/SKILL.md +83 -80
  36. package/skills/research/SKILL.md +43 -0
  37. package/skills/ssh/SKILL.md +15 -9
  38. package/skills/textprocessing/SKILL.md +40 -0
  39. package/skills/update-docs/SKILL.md +27 -21
  40. package/.github/workflows/publish-npm.yml +0 -44
  41. package/hooks/post-tool-use-hook.js +0 -34
  42. package/hooks/pre-tool-use-hook.js +0 -45
  43. package/hooks/prompt-submit-hook.js +0 -19
  44. package/hooks/session-start-hook.js +0 -23
@@ -3,41 +3,37 @@ name: pages
3
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
4
  ---
5
5
 
6
- # Pages — GitHub Pages Site Scaffolder
6
+ # Pages — GitHub Pages site scaffolder
7
7
 
8
- Scaffold a complete GH Pages site: **no local build step**, content managed via flatspace flat-file CMS, UI via webjsx + rippleui CDN, GH Actions builds and deploys.
9
-
10
- **Follow full gm skill chain: planning → gm-execute → gm-emit → gm-complete → update-docs.**
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`.
11
9
 
12
10
  ## Stack
13
11
 
14
12
  | Layer | Tool | How |
15
- |-------|------|-----|
13
+ |---|---|---|
16
14
  | UI rendering | [webjsx](https://webjsx.org) | ES module via importmap, `applyDiff` for DOM updates |
17
15
  | Styling | [rippleui](https://ripple-ui.com) | CDN `<link>` — Tailwind-based component classes |
18
16
  | Content CMS | [flatspace](https://npmjs.com/package/flatspace) | Aggregates `content/` → `docs/data/*.json` at build time |
19
17
  | Build | GH Actions | `npx flatspace` runs in CI, commits output to `docs/` |
20
- | Hosting | GitHub Pages | Source: `docs/` branch, or GH Actions deploy |
18
+ | Hosting | GitHub Pages | Source set to "GitHub Actions" |
21
19
 
22
- ## Directory Layout
20
+ ## Layout
23
21
 
24
22
  ```
25
23
  <project>/
26
- content/ # Source content (markdown, json, yaml)
27
- pages/ # Static pages (index.md, about.md, ...)
28
- posts/ # Blog posts or articles
29
- data/ # Structured data files
30
- docs/ # GH Pages root (gitignored build output except index.html)
31
- index.html # Entry point — committed, never regenerated
32
- app.js # Main webjsx app — committed
33
- data/ # flatspace output gitignored, built by CI
34
- .github/
35
- workflows/
36
- pages.yml # Build + deploy workflow
37
- flatspace.config.js # flatspace aggregation config
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
38
34
  ```
39
35
 
40
- ## index.html — Buildless Entry
36
+ ## index.html
41
37
 
42
38
  ```html
43
39
  <!DOCTYPE html>
@@ -63,28 +59,19 @@ Scaffold a complete GH Pages site: **no local build step**, content managed via
63
59
  </html>
64
60
  ```
65
61
 
66
- ## app.js — webjsx App Pattern
62
+ ## app.js
67
63
 
68
64
  ```js
69
65
  import { applyDiff } from 'webjsx';
70
66
 
71
67
  const h = (tag, props, ...children) => ({ tag, props: props || {}, children });
72
-
73
68
  const state = { page: null, data: {} };
74
69
 
75
- async function loadData(path) {
76
- const res = await fetch(path);
77
- return res.json();
78
- }
79
-
80
- function render() {
81
- applyDiff(document.getElementById('root'), App(state));
82
- }
70
+ async function loadData(path) { return (await fetch(path)).json(); }
71
+ function render() { applyDiff(document.getElementById('root'), App(state)); }
83
72
 
84
73
  function App(s) {
85
- if (!s.page) return h('div', { class: 'flex justify-center p-8' },
86
- h('span', { class: 'spinner' })
87
- );
74
+ if (!s.page) return h('div', { class: 'flex justify-center p-8' }, h('span', { class: 'spinner' }));
88
75
  return h('div', { class: 'max-w-4xl mx-auto p-4' },
89
76
  h('nav', { class: 'navbar bg-backgroundSecondary mb-6' },
90
77
  h('span', { class: 'navbar-brand text-xl font-bold' }, s.page.title)
@@ -100,11 +87,7 @@ function Section(section) {
100
87
  );
101
88
  }
102
89
 
103
- async function main() {
104
- state.page = await loadData('./data/index.json');
105
- render();
106
- }
107
-
90
+ async function main() { state.page = await loadData('./data/index.json'); render(); }
108
91
  main();
109
92
  ```
110
93
 
@@ -122,11 +105,10 @@ module.exports = {
122
105
  };
123
106
  ```
124
107
 
125
- ## GH Actions Workflow — pages.yml
108
+ ## pages.yml
126
109
 
127
110
  ```yaml
128
111
  name: Deploy GitHub Pages
129
-
130
112
  on:
131
113
  push:
132
114
  branches: [main]
@@ -142,14 +124,10 @@ jobs:
142
124
  runs-on: ubuntu-latest
143
125
  steps:
144
126
  - uses: actions/checkout@v4
145
-
146
127
  - uses: actions/setup-node@v4
147
- with:
148
- node-version: '20'
149
-
128
+ with: { node-version: '20' }
150
129
  - name: Build content with flatspace
151
130
  run: npx flatspace
152
-
153
131
  - name: Commit built data
154
132
  run: |
155
133
  git config user.name "github-actions[bot]"
@@ -157,11 +135,8 @@ jobs:
157
135
  git add docs/data/
158
136
  git diff --staged --quiet || git commit -m "chore: build content [skip ci]"
159
137
  git push
160
-
161
- - name: Upload Pages artifact
162
- uses: actions/upload-pages-artifact@v3
163
- with:
164
- path: docs/
138
+ - uses: actions/upload-pages-artifact@v3
139
+ with: { path: docs/ }
165
140
 
166
141
  deploy:
167
142
  needs: build
@@ -174,26 +149,14 @@ jobs:
174
149
  uses: actions/deploy-pages@v4
175
150
  ```
176
151
 
177
- ## Scaffolding Steps
152
+ ## Scaffold sequence
178
153
 
179
- When user says "set up pages" or "create GH pages site":
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.
180
155
 
181
- 1. **Read** existing `docs/` and `content/` if present — never clobber existing content
182
- 2. **Create** directory structure above
183
- 3. **Write** `docs/index.html` with correct site title
184
- 4. **Write** `docs/app.js` with webjsx app skeleton
185
- 5. **Write** `flatspace.config.js`
186
- 6. **Write** `.github/workflows/pages.yml`
187
- 7. **Write** `content/pages/index.md` with minimal frontmatter (`title`, `sections` array)
188
- 8. **Add** `docs/data/` to `.gitignore` (built by CI, not committed by humans)
189
- 9. **Verify** GH Pages setting is "GitHub Actions" in repo Settings — remind user if can't verify
190
-
191
- ## rippleui Component Classes Quick Reference
192
-
193
- Use these directly in JSX className strings — no config needed:
156
+ ## rippleui classes
194
157
 
195
158
  | Component | Class |
196
- |-----------|-------|
159
+ |---|---|
197
160
  | Button | `btn btn-primary`, `btn btn-secondary`, `btn btn-ghost` |
198
161
  | Card | `card p-4` |
199
162
  | Input | `input input-primary` |
@@ -203,30 +166,18 @@ Use these directly in JSX className strings — no config needed:
203
166
  | Spinner | `spinner` |
204
167
  | Divider | `divider` |
205
168
 
206
- Background: `bg-backgroundPrimary`, `bg-backgroundSecondary`. Text: `text-content1`, `text-content2`.
207
-
208
- **CSS variable warning**: rippleui color vars (e.g. `--gray-2`) are raw space-separated RGB tuples — not valid CSS colors. Never use them in `rgb()` directly from JS. Use the component classes instead.
209
-
210
- ## webjsx Patterns
211
-
212
- **No JSX transpile needed** — use `h()` factory or import from CDN with importmap and write JSX in `.jsx` files served directly (Chrome supports importmap natively).
213
-
214
- For `.js` files without transpile, use the `h` factory pattern shown above.
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.
215
170
 
216
- For `.jsx` with native importmap (no build):
217
- ```js
218
- /** @jsxImportSource webjsx */
219
- import { applyDiff } from 'webjsx';
220
- ```
221
- Only works if server sets correct MIME type for `.jsx` — GH Pages does not. Use `.js` + `h()` factory.
171
+ ## webjsx
222
172
 
223
- **applyDiff signature**: `applyDiff(domNode, vnodeOrArray)` never pass a string, always pass a vnode from `h()`.
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()`.
224
174
 
225
- **State updates**: mutate `state`, call `render()` no reactive system, explicit re-render on every change.
175
+ `applyDiff(domNode, vnodeOrArray)` — never pass a string. State updates mutate `state` and call `render()`; no reactive system.
226
176
 
227
- ## Content Format (flatspace input)
177
+ ## Content format
228
178
 
229
179
  Markdown with YAML frontmatter:
180
+
230
181
  ```markdown
231
182
  ---
232
183
  title: Home
@@ -240,19 +191,18 @@ sections:
240
191
  Full markdown body here.
241
192
  ```
242
193
 
243
- flatspace outputs `docs/data/pages/index.json`:
194
+ Output `docs/data/pages/index.json`:
195
+
244
196
  ```json
245
197
  { "title": "Home", "sections": [...], "body": "<p>Full markdown body here.</p>", "slug": "index" }
246
198
  ```
247
199
 
248
- ## Known Gotchas
249
-
250
- **GH Pages must be set to "GitHub Actions"** in Settings → Pages. "Deploy from branch" ignores the deploy-pages action entirely.
200
+ ## Gotchas
251
201
 
252
- **docs/data/ must be in .gitignore** but `docs/index.html` and `docs/app.js` must NOT be ignored they are the committed source files.
202
+ GH Pages must be set to "GitHub Actions" in Settings Pages. "Deploy from branch" ignores the deploy-pages action.
253
203
 
254
- **flatspace npx cold start**: first CI run downloads flatspace takes ~10s extra. Subsequent runs use cache if `actions/setup-node` cache is configured.
204
+ `docs/data/` is gitignored; `docs/index.html` and `docs/app.js` are notthey are the committed source files.
255
205
 
256
- **importmap browser support**: all modern browsers support importmap. No IE, no Safari < 16.4. For GH Pages this is fine.
206
+ `npx flatspace` cold-start is ~10s on first CI run; subsequent runs use the `actions/setup-node` cache.
257
207
 
258
- **webjsx CDN version**: pin to explicit version in importmap (e.g. `@0.0.42`) — avoid `@latest` to prevent silent breakage on upstream updates.
208
+ Pin the webjsx CDN version in importmap (e.g. `@0.0.42`) — `@latest` breaks silently on upstream updates.
@@ -1,92 +1,97 @@
1
1
  ---
2
2
  name: planning
3
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: Write
4
+ allowed-tools: Skill
5
5
  ---
6
6
 
7
- # Planning — State Machine Orchestrator
7
+ # Planning — PLAN phase
8
8
 
9
- Runs `PLAN EXECUTE EMIT VERIFY → UPDATE-DOCS → COMPLETE`. Re-enter on any new unknown in any phase.
9
+ Translate the request into `.gm/prd.yml` and hand to `gm-execute`. Re-enter on any new unknown in any phase.
10
10
 
11
- ## RECALL HARD RULE
11
+ A `@<discipline>` sigil in the request scopes recall, codesearch, and memorize calls during PLAN to that discipline's store. Without one, retrievals fan across default plus enabled disciplines and writes land in default only.
12
12
 
13
- Before naming any unknown, run recall.
13
+ Cross-cutting dispositions (autonomy, fix-on-sight, nothing-fake, browser-witness, scope, recall, memorize) live in `gm` SKILL.md; this skill only carries what is unique to PLAN.
14
14
 
15
- ```
16
- exec:recall
17
- <2-6 word query>
18
- ```
15
+ ## Transitions
19
16
 
20
- Triggers: matches prior topic | "have we seen this" | designing where prior decision likely exists | quirk feels familiar | sub-task in known project.
17
+ - PLAN done `gm-execute`
18
+ - New unknown anywhere in chain → re-enter PLAN
19
+ - EXECUTE unresolvable after 2 passes → PLAN
20
+ - VERIFY: `.prd` empty + git clean + pushed → `update-docs`; else → `gm-execute`
21
21
 
22
- Hits = weak_prior; witness via EXECUTE before adopting. Skip recall only on brand-new project / trivially-bounded edit / surgical user instruction.
22
+ Cannot stop while `.gm/prd.yml` has items, git is dirty, or commits are unpushed.
23
23
 
24
- ## MEMORIZE HARD RULE
24
+ ## Session start: restart spool watcher
25
25
 
26
- Every unknown→known = same-turn memorize. Background, parallel, never batched.
26
+ Before any orient or PRD work, ensure the spool watcher is running. Check `.gm/exec-spool/.watcher.heartbeat` — if older than 30s, the watcher is dead. Restart it:
27
27
 
28
28
  ```
29
- Agent(subagent_type='gm:memorize', model='haiku', run_in_background=true, prompt='## CONTEXT TO MEMORIZE\n<fact>')
29
+ # write .gm/exec-spool/in/nodejs/restart-watcher.js
30
+ const { spawn, spawnSync } = require('child_process');
31
+ const fs = require('fs');
32
+ const path = require('path');
33
+ const os = require('os');
34
+ const bin = path.join(os.homedir(), '.claude', 'gm-tools', process.platform === 'win32' ? 'plugkit.exe' : 'plugkit');
35
+ const root = process.cwd();
36
+ const spoolIn = path.join(root, '.gm', 'exec-spool', 'in');
37
+ const spoolOut = path.join(root, '.gm', 'exec-spool', 'out');
38
+ const pidFile = path.join(os.tmpdir(), 'gm-plugkit-spool.pid');
39
+ if (fs.existsSync(pidFile)) {
40
+ const pid = parseInt(fs.readFileSync(pidFile, 'utf8').trim(), 10);
41
+ if (Number.isFinite(pid)) { try { process.kill(pid); } catch (_) {} }
42
+ try { fs.unlinkSync(pidFile); } catch (_) {}
43
+ }
44
+ if (process.platform === 'win32') {
45
+ try { spawnSync('taskkill', ['/F', '/IM', 'plugkit.exe'], { windowsHide: true, timeout: 3000, stdio: 'ignore' }); } catch (_) {}
46
+ } else {
47
+ try { spawnSync('pkill', ['-f', 'plugkit'], { timeout: 3000, stdio: 'ignore' }); } catch (_) {}
48
+ }
49
+ fs.mkdirSync(spoolIn, { recursive: true });
50
+ fs.mkdirSync(spoolOut, { recursive: true });
51
+ const proc = spawn(bin, ['runner', '--watch', spoolIn, '--out', spoolOut], {
52
+ detached: true, stdio: 'ignore', windowsHide: true, cwd: root,
53
+ });
54
+ proc.unref();
55
+ fs.writeFileSync(pidFile, String(proc.pid));
30
56
  ```
31
57
 
32
- Triggers: exec output answers prior unknown | code read confirms/refutes | CI log reveals root cause | user states preference/constraint | fix worked non-obviously | env quirk observed.
33
-
34
- N facts → N parallel Agent calls in ONE message.
35
-
36
- ## STATE MACHINE
37
-
38
- **FORWARD**: PLAN → `gm-execute` | EXECUTE → `gm-emit` | EMIT → `gm-complete` | VERIFY .prd remains → `gm-execute` | VERIFY .prd empty+pushed → `update-docs`
39
-
40
- **REGRESSIONS**: new unknown anywhere → `planning` | EXECUTE unresolvable 2 passes → `planning` | EMIT logic error → `gm-execute` | VERIFY broken output → `gm-emit` | VERIFY logic wrong → `gm-execute`
41
-
42
- Runs until: .gm/prd.yml empty AND git clean AND all pushes confirmed AND CI green.
43
-
44
- ## AUTONOMY — HARD RULE
45
-
46
- PRD written → execute to COMPLETE without asking the user. No "should I continue", no "want me to do X next", no offering to split work.
47
-
48
- Asking permitted only as last resort: destructive-irreversible with no PRD coverage, OR user intent unrecoverable from PRD/memory/code. Channel: `exec:pause` (renames prd.yml → prd.paused.yml; question in header). In-conversation asking last-resort.
49
-
50
- **Cannot stop while**: .gm/prd.yml has items | git uncommitted | git unpushed.
58
+ Wait 2s for watcher to initialize, then proceed with orient.
51
59
 
52
- ## LAWFUL DOWNGRADE — HARD RULE
60
+ ## Orient
53
61
 
54
- Per paper III §2.5: lawful downgrade is always available; forced closure (refusal) is never available. Refusing the task because part is out of reach is the inverse of bluffing both bypass witnessed execution.
62
+ Open every plan with one parallel pack of recall + codesearch against the request's nouns. Write queries to `.gm/exec-spool/in/recall/<N>.txt` and `.gm/exec-spool/in/codesearch/<N>.txt`. Read results from `.gm/exec-spool/out/<N>.out`. Hits land as `weak_prior`; misses confirm the unknown is fresh. The pack runs in one message.
55
63
 
56
- Forbidden: "honest stop", "stopping for a hard call", "I cannot do this from inside this conversation", "pretending I can would be a lie", any preamble that announces inability before attempting the bounded subset.
64
+ **Auto-recall injection (skills-only platforms)**: derive a 2–6 word query from the request's nouns (subject, verb objects, key domain terms). Write recall query to `.gm/exec-spool/in/recall/<N>.txt` at PLAN start before writing `.gm/prd.yml`. Read result from `.gm/exec-spool/out/<N>.out`. This replaces the prompt-submit hook's auto-recall for platforms without hook infrastructure. Recall hits are injected as context into mutable discovery and PRD item acceptance criteria.
57
65
 
58
- Required: identify the witnessable bounded subset, PRD-write it, execute it. Residual scope = follow-up item, never refusal.
66
+ ## Mutable discovery
59
67
 
60
- ## SKIP PLANNING (DEFAULT for small work)
68
+ For each aspect of the work, ask: what do I not know, what could go wrong, what depends on what, what am I assuming. Unwitnessed assumptions are mutables.
61
69
 
62
- Skip if ANY: single-file single-concern edit | trivially bounded <5min | surgical user instructions | bug fix with identified root cause | zero unknowns. Heavy ceremony only for multi-file architectural work.
70
+ Fault surfaces to scan: file existence, API shape, data format, dep versions, runtime behavior, env differences, error conditions, concurrency, integration seams, backwards compat, rollback paths, CI correctness.
63
71
 
64
- ## PLAN PHASE MUTABLE DISCOVERY
72
+ Tag every item with a route family (grounding | reasoning | state | execution | observability | boundary | representation) and cross-reference the 16-failure taxonomy. `governance` skill holds the table.
65
73
 
66
- For every aspect: what do I not know (UNKNOWN) | what could go wrong (failure mode) | what depends on what (blocking/blockedBy) | what assumptions am I making (unwitnessed hypothesis = mutable).
74
+ `existingImpl=UNKNOWN` is the default; resolve via codesearch (write to `.gm/exec-spool/in/codesearch/<N>.txt`) before adding the item. An existing concern routes to consolidation, not addition.
67
75
 
68
- Fault surfaces: file existence | API shape | data format | dep versions | runtime behavior | env differences | error conditions | concurrency | integration seams | backwards compat | rollback paths | CI correctness.
76
+ Plan exits when zero new unknowns surfaced last pass AND every item has acceptance criteria AND deps are mapped.
69
77
 
70
- **Route family** (governance): tag every item — grounding|reasoning|state|execution|observability|boundary|representation.
78
+ ## .gm/mutables.yml co-equal with .gm/prd.yml
71
79
 
72
- **Failure-mode mapping**: cross-reference 16-failure taxonomy.
80
+ Every unknown surfaced during PLAN lands as an entry in `.gm/mutables.yml` the same pass. Live during work, deleted when empty. Hook-gated: Write/Edit/NotebookEdit and `git commit`/`git push` are hard-blocked while any entry has `status: unknown`; turn-stop is hard-blocked the same way.
73
81
 
74
- **MANDATORY CODEBASE SCAN**: `existingImpl=UNKNOWN` for every item. Resolve via exec:codesearch before adding. Existing concern → consolidation, not addition.
75
-
76
- **EXIT PLAN**: zero new unknowns last pass AND every item has acceptance criteria AND deps mapped → launch subagents or invoke `gm-execute`.
77
-
78
- ## OBSERVABILITY — MANDATORY EVERY PASS
79
-
80
- Server: every subsystem exposes `/debug/<subsystem>`. Structured logs `{subsystem, severity, ts}`.
81
- Client: `window.__debug` live registry; modules register on mount.
82
-
83
- `console.log` ≠ observability. Discovery of gap → add .prd item immediately, never deferred.
82
+ ```yaml
83
+ - id: kebab-id
84
+ claim: One-line statement of what is assumed
85
+ witness_method: codesearch <query> | nodejs import | recall <query> | Read <path>
86
+ witness_evidence: ""
87
+ status: unknown
88
+ ```
84
89
 
85
- **No parallel test runners or smoke pages.** Per paper II §5.4, `window.__debug` is THE registry. Creating dedicated `docs/smoke.js` / `docs/smoke-network.js` / `docs/test.html` / `*-playground.html` files is a parallel observability surface that fights the discipline register surfaces in `window.__debug` instead. The single `test.js` at project root (see SINGLE INTEGRATION TEST POLICY) is the only out-of-page test asset.
90
+ `status: unknown` `witnessed` only when `witness_evidence` is filled with concrete proof (file:line, codesearch hit, dispatched test output). Resolution lives in gm-execute. PRD items reference mutables via optional `mutables: [id1, id2]` field; an item is blocked while any referenced mutable is unresolved.
86
91
 
87
- ## .PRD FORMAT
92
+ ## .prd format
88
93
 
89
- Path: `./.gm/prd.yml`. Write via `exec:nodejs` + `fs.writeFileSync`. Delete when empty.
94
+ Path: `./.gm/prd.yml`. Write via the Write tool or by emitting a nodejs spool file (`in/nodejs/<N>.js`) that calls `fs.writeFileSync`. Delete the file when empty.
90
95
 
91
96
  ```yaml
92
97
  - id: kebab-id
@@ -108,44 +113,42 @@ Path: `./.gm/prd.yml`. Write via `exec:nodejs` + `fs.writeFileSync`. Delete when
108
113
  - failure mode
109
114
  ```
110
115
 
111
- **load** axis (consequence — convergence 3.3.0): 0.9 = headline collapses if wrong. 0.7 = sub-argument rebuilt. 0.4 = local patch. 0.1 = nothing breaks. **Verification budget = load × (1 − tier_confidence)**. High-load + low-tier item = top priority. λ>0.75 must be witnessed before EMIT.
112
-
113
- Status: pending → in_progress → completed (remove). Effort: small <15min | medium <45min | large >1h.
114
-
115
- ## PARALLEL SUBAGENT LAUNCH
116
+ `load` is consequence-if-wrong: 0.9 = headline collapses, 0.7 = sub-argument rebuilt, 0.4 = local patch, 0.1 = nothing breaks. Verification budget = `load × (1 − tier_confidence)`. λ>0.75 must reach witnessed before EMIT.
116
117
 
117
- After .prd written, ≤3 parallel `gm:gm` subagents for independent items in ONE message. Browser tasks serialize.
118
+ `status`: pending in_progress completed (then remove). `effort`: small <15min | medium <45min | large >1h.
118
119
 
119
- `Agent(subagent_type="gm:gm", prompt="Work on .prd item: <id>. .prd path: <path>. Item: <full YAML>.")`
120
+ ## Parallel subagent launch
120
121
 
121
- Not parallelizable invoke `gm-execute` directly.
122
+ After `.prd` is written, up to 3 parallel `gm:gm` subagents for independent items in one message. Browser tasks serialize.
122
123
 
123
- ## EXECUTION RULES
124
+ ```
125
+ Agent(subagent_type="gm:gm", prompt="Work on .prd item: <id>. .prd path: <path>. Item: <full YAML>.")
126
+ ```
124
127
 
125
- `exec:<lang>` only via Bash. File I/O via exec:nodejs + fs. Git directly in Bash. Never Bash(node/npm/npx/bun).
128
+ Items not parallelizable invoke `gm-execute` directly.
126
129
 
127
- `exec:codesearch` only Glob/Grep/Find/Explore hook-blocked. Start 2 words → change/add one per pass → minimum 4 attempts before concluding absent.
130
+ ## Observability gates in the plan
128
131
 
129
- Pack runs: Promise.allSettled for parallel. Each idea own try/catch. Under 12s per call.
132
+ Server: every subsystem exposes `/debug/<subsystem>`; structured logs `{subsystem, severity, ts}`. Client: `window.__debug` live registry; modules register on mount. `console.log` is not observability. Discovery of a gap during PLAN adds a `.prd` item the same pass — never deferred.
130
133
 
131
- ## DEV WORKFLOW
134
+ `window.__debug` is THE in-page registry; `test.js` at project root is the sole out-of-page test asset. Any new file whose purpose is to exercise, smoke-test, demo, or sandbox in-page behavior outside that registry fights the discipline — extend the registry instead.
132
135
 
133
- No comments. No scattered test files. 200-line limit per file. Fail loud. No duplication. Scan before edit. AGENTS.md via memorize agent only. CHANGELOG.md append per commit.
136
+ ## Test discipline encoded in the plan
134
137
 
135
- **Minimal code process** (stop at first that resolves): native library structure (map/pipeline) write.
138
+ One `test.js` at project root, 200-line hard cap, real data, real system. No fixtures, mocks, or scattered tests. A second test runner under any name in any directory is a smuggled parallel surface.
136
139
 
137
- ## SINGLE INTEGRATION TEST POLICY
140
+ The 200 lines are a *budget* for maximum surface coverage, not a target. Subsystems get one combined group each — names joined with `+` (`home+config+skin`, `mcp+swe+distributions+account+credpool`). When a new subsystem's failure mode overlaps an existing group's side-effects, fold the assertion in rather than creating a new group. When `wc -l test.js > 200`, the discipline is *merge groups + drop redundancy*, never split.
138
141
 
139
- One `test.js` at project root. 200-line max. No `.test.js` / `.spec.js` / `__tests__/` / fixtures / mocks. Plain assertions, real data, real system. `gm-complete` runs it. Failure = regression to EXECUTE.
142
+ ## Execution norms encoded in the plan
140
143
 
141
- **Also forbidden**: `docs/smoke.js`, `docs/smoke-*.js`, `*-smoke.html`, `docs/test.html`, `docs/demo.html`, `*-playground.html`. These are smuggled second test runners. If a surface needs to be exercised in-page, register it in `window.__debug` and assert via `test.js`.
144
+ Code execution AND utility verbs both write to `.gm/exec-spool/in/<lang-or-verb>/<N>.<ext>`. Languages live under `in/<lang>/` (nodejs, python, bash, typescript, go, rust, c, cpp, java, deno); verbs live under `in/<verb>/` (codesearch, recall, memorize, wait, sleep, status, close, browser, runner, type, kill-port, forget, feedback, learn-status, learn-debug, learn-build, discipline, pause, health). The spool watcher runs the file and streams to `out/<N>.out` (stdout) + `out/<N>.err` (stderr) line-by-line, then writes `out/<N>.json` metadata (exitCode, durationMs, timedOut, startedAt, endedAt) at completion. Both streams return as systemMessage with `--- stdout ---` / `--- stderr ---` separators. `in/` and `out/` are wiped at session start and at real-exit session end. Only `git` (and `gh`) run directly via Bash; never `Bash(node/npm/npx/bun)`, never `Bash(exec:<anything>)`. Spool paths in nodejs files are platform-literal use `os.tmpdir()` and `path.join`. The spool enforces per-task timeouts; on timeout, partial output is preserved and the watcher emits `[exec timed out after Nms; partial output above]`.
142
145
 
143
- ## RESPONSE POLICY
146
+ Codesearch only — Grep/Glob/Find/Explore are hook-blocked. Write to `.gm/exec-spool/in/codesearch/<N>.txt`. Start two words, change/add one per pass, minimum four attempts before concluding absent.
144
147
 
145
- Terse. Drop filler. Fragments OK. Pattern: `[thing] [action] [reason]. [next step].` Code/commits/PRs = normal prose.
148
+ Pack runs use `Promise.allSettled`, each idea its own try/catch, under 12s per call.
146
149
 
147
- ## CONSTRAINTS
150
+ ## Dev workflow encoded in the plan
148
151
 
149
- **Never**: Bash(node/npm/npx/bun) | skip planning | partial execution | stop while .prd has items | stop while git dirty | sequential independent items | screenshot before JS exhausted | fallback/demo modes | swallow errors | duplicate concern | leave comments | scattered tests | if/else where map suffices | one-liners that obscure | leave resolved unknown un-memorized | batch memorize | serialize memorize spawns
152
+ No comments. 200-line per-file cap. Fail loud. No duplication. Scan before edit. AGENTS.md edits route through the memorize sub-agent only. CHANGELOG.md gets one entry per commit.
150
153
 
151
- **Always**: invoke Skill at every transition | regress to planning on new unknown | witnessed execution only | scan before edits | enumerate observability gaps every pass | follow chain end-to-end | prefer dispatch tables and pipelines | make wrong states unrepresentable | spawn memorize same turn unknown resolves | end-of-turn self-check
154
+ Minimal-code process, stop at the first that resolves: native library structure (map / pipeline) write.
@@ -0,0 +1,43 @@
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.
@@ -3,13 +3,14 @@ name: ssh
3
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
4
  ---
5
5
 
6
- # exec:ssh — Remote SSH Execution
6
+ # exec:ssh — Remote SSH execution
7
7
 
8
- Runs shell commands on remote host. No manual connection needed.
8
+ Runs shell commands on a remote host. No manual connection needed.
9
9
 
10
10
  ## Setup
11
11
 
12
12
  `~/.claude/ssh-targets.json`:
13
+
13
14
  ```json
14
15
  {
15
16
  "default": { "host": "192.168.1.10", "port": 22, "username": "pi", "password": "pass" },
@@ -17,7 +18,7 @@ Runs shell commands on remote host. No manual connection needed.
17
18
  }
18
19
  ```
19
20
 
20
- Fields: `host` (required), `port` (default 22), `username` (required), `password` OR `keyPath` + optional `passphrase`.
21
+ `host` and `username` required. `port` defaults to 22. Auth: `password` OR `keyPath` + optional `passphrase`.
21
22
 
22
23
  ## Usage
23
24
 
@@ -26,28 +27,32 @@ exec:ssh
26
27
  <shell command>
27
28
  ```
28
29
 
29
- Named host with `@name` on first line:
30
+ Named host with `@name` on the first line:
31
+
30
32
  ```
31
33
  exec:ssh
32
34
  @prod
33
35
  sudo systemctl restart myapp
34
36
  ```
35
37
 
36
- ## Process Persistence
38
+ ## Process persistence
39
+
40
+ SSH kills child processes on close. To survive disconnect:
37
41
 
38
- SSH kills child processes on close. To persist:
39
42
  ```
40
43
  exec:ssh
41
44
  sudo systemctl reset-failed myunit 2>/dev/null; systemd-run --unit=myunit bash -c 'your-command'
42
45
  ```
43
46
 
44
- Unique name:
47
+ Unique unit name per launch:
48
+
45
49
  ```
46
50
  exec:ssh
47
51
  systemd-run --unit=job-$(date +%s) bash -c 'nohup myprogram &'
48
52
  ```
49
53
 
50
- Fallback (no systemd):
54
+ No-systemd fallback:
55
+
51
56
  ```
52
57
  exec:ssh
53
58
  setsid nohup bash -c 'myprogram > /tmp/out.log 2>&1' &
@@ -55,7 +60,8 @@ setsid nohup bash -c 'myprogram > /tmp/out.log 2>&1' &
55
60
 
56
61
  ## Dependency
57
62
 
58
- Requires `ssh2` npm package in `~/.claude/gm-tools`:
63
+ Requires `ssh2` in `~/.claude/gm-tools`:
64
+
59
65
  ```
60
66
  exec:bash
61
67
  cd ~/.claude/gm-tools && npm install ssh2