gm-skill 2.0.1530 → 2.0.1532

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/AGENTS.md CHANGED
@@ -28,7 +28,7 @@ This repo IS the published `gm-skill` npm package. The repo root is the package
28
28
 
29
29
  The plugkit stack runs as a wasm cdylib loaded by `plugkit-wasm-wrapper.js` under Node/bun. No native binaries are built, downloaded, or published. The shipped `plugkit.wasm` (~149MB, embeds bge-small-en-v1.5 for offline in-wasm embeddings) is fetched at bootstrap from `plugkit-wasm` npm / `plugkit-bin` gh-releases, sha256-pinned, not bundled in `gm-skill`. Full size/embedding mechanics in rs-learn (`recall: WASM-only plugkit size mechanics`).
30
30
 
31
- **Every wasm host-import `extern "C"` block carries `#[link(wasm_import_module = "env")]`.** The host provides every possible host fn (host_kv_get/put/query, host_vec_search, host_git, host_log, host_now_ms, host_fs_*, host_env_get, host_exec_js, host_random_fill, ...) under the `env` import module (`plugkit-wasm-wrapper.js` `importObject.env`). A bare `extern "C"` block links only because lenient linkers tolerate the unresolved module; the strict Linux release `rust-lld` in CI errors `undefined symbol: host_*` and Build-WASM fails. This holds in rs-plugkit AND every dep crate linked into the cdylib (rs-learn) AND any sibling that builds wasm (rs-exec, rs-search). The trap: `cargo check` and even `cargo build --release` on a non-Linux host both pass while CI fails -- the linker differs by host, so the only reproduction is a Linux release link; the CI job log is admin-gated, so Build-WASM echoes `::error::` annotations to surface the lld error publicly. Add a host import anywhere and the block carries the attribute or the cascade goes dark. Full incident in rs-learn (`recall: cascade outage wasm import module link`).
31
+ **Every wasm host-import `extern "C"` block carries `#[link(wasm_import_module = "env")]`.** Holds in rs-plugkit AND every dep crate linked into the cdylib (rs-learn) AND any sibling that builds wasm (rs-exec, rs-search) -- add a host import anywhere and the block carries the attribute or the cascade goes dark. The trap (bare block links on non-Linux hosts so `cargo check`/`build --release` pass while strict Linux `rust-lld` in CI fails `undefined symbol: host_*`; only a Linux release link reproduces) + the full host-fn `env` enumeration live in rs-learn (`recall: cascade outage wasm import module link`).
32
32
 
33
33
  **`plugkit-wasm-wrapper.js` is ESM; import node builtins at module scope, never inline `require()` (throws silently under bun's ESM inside `catch(_){}`).** Full incident in rs-learn (`recall: wrapper require not defined under bun`).
34
34
 
@@ -178,7 +178,7 @@ Orchestration state is tracked via marker files in `.gm/` instead of hook events
178
178
 
179
179
  **A stop-hook firing on a terminal chain does not authorize re-polling**: when a stop-hook or unsatisfiable condition fires while the chain is already at `phase=COMPLETE` AND `prd_pending_count=0`, re-dispatching `instruction` or `phase-status` to "re-confirm" terminality is itself a deviation, it emits `deviation.complete-chain-poll` (`instructions/mod.rs`) and marks the agent as polling a closed chain. COMPLETE already authorizes the prose-only turn; the hook cannot be satisfied by more poll dispatches over elapsed work, and re-running already-committed work to manufacture skill-driven activity is the fabrication `Nothing Fake` forbids. Two admissible responses only: (a) a prose-only turn (the COMPLETE pronouncement is in hand), or (b) genuinely new planned work opened with a FRESH `{"prompt":...}` body, which resets phase to PLAN and is driven through the skill from inception. Repeatedly answering the same already-acknowledged hook is a loop; state the terminal facts once and stop, or open new work.
180
180
 
181
- **Session lifecycle**: Session-end kills background tasks via `killSessionTasks` RPC on real-exit reasons (clear/logout/prompt_input_exit). Every possible browser session and background task persists across turn-stops, cleanup happens exclusively on real-exit reasons. Residual-scan fires when PRD is empty/missing AND no open browser sessions AND no running tasks; agent either expands PRD with in-spirit residuals or explicitly states none.
181
+ **Session lifecycle**: background tasks + browser sessions persist across turn-stops; cleanup fires only on real-exit reasons; residual-scan fires when PRD empty AND no open browser sessions AND no running tasks. Detail in rs-learn (`recall: session lifecycle killSessionTasks residual-scan`).
182
182
 
183
183
  ## Spool observability surface
184
184
 
@@ -188,11 +188,7 @@ Three persistent diagnostic files at `.gm/exec-spool/` root are updated by the r
188
188
 
189
189
  ## Site Build & Documentation
190
190
 
191
- **Navigation**: `site/content/globals/navigation.yaml` uses grouped entry format, each item is either `{label, href}` (single link) or `{label, group: [{label, href}, ...]}` (dropdown menu). Dropdowns render via `<details>/<summary>` through the flatspace `C.Topbar` primitive invoked in `site/theme.mjs`; no JS required. In-page topbars in docs/paper*.html et al. render directly on file open and must be kept in sync with the same markup.
192
-
193
- **Landing page renderer**: the deployed `/` route on https://anentrypoint.github.io/gm/ is rendered by `site/theme.mjs` from `site/content/pages/home.yaml` via flatspace. `site/index.html` + `site/main.js` build `docs/bundle.js` for non-flatspace standalone preview only. Landing edits go through `site/theme.mjs` (Hero) and `site/content/pages/home.yaml` (content), never `site/index.html`.
194
-
195
- **Mermaid render, generated docs/styles.css, and the docs/made-with.html static showcase** detail lives in rs-learn (`recall: gm site build details`).
191
+ **Site build is single-surface detail in rs-learn** (`recall: gm site build details`): navigation.yaml grouped-entry format + flatspace `C.Topbar` dropdowns, the `site/theme.mjs`+`home.yaml` landing renderer (never `site/index.html`), in-page topbar sync, Mermaid render, generated `docs/styles.css`, and the `docs/made-with.html` showcase.
196
192
 
197
193
 
198
194
  @.gm/next-step.md
@@ -282,6 +282,30 @@ function checkWatcherHealth() {
282
282
  severity: 'info',
283
283
  });
284
284
  killChild('supervisor-killed-wrapper-sha-drift');
285
+ return;
286
+ }
287
+ // The watcher reads the wasm's embedded instance_version at load and compares it to the
288
+ // plugkit.version text file (file_version), exposing version_drifted when they disagree.
289
+ // This catches a bumped version text sitting next to a stale wasm build (text claims 635
290
+ // while the binary embeds 634), which ensureReady's text-only drift check never re-downloads.
291
+ // Evict the stale cached wasm so the next bootstrap fails isReady() and redownloads, then recycle.
292
+ if (status.version_drifted === true) {
293
+ logEvent('supervisor.version-drift', {
294
+ watcher_pid: currentChildPid,
295
+ instance_version: status.instance_version || null,
296
+ file_version: status.file_version || null,
297
+ severity: 'critical',
298
+ });
299
+ try {
300
+ const home = process.env.USERPROFILE || process.env.HOME || os.homedir();
301
+ const gmTools = fs.existsSync(path.join(home, '.gm-tools'))
302
+ ? path.join(home, '.gm-tools')
303
+ : path.join(home, '.claude', 'gm-tools');
304
+ for (const f of ['plugkit.wasm', 'plugkit.version', 'plugkit.wasm.sha256']) {
305
+ try { fs.unlinkSync(path.join(gmTools, f)); } catch (_) {}
306
+ }
307
+ } catch (_) {}
308
+ killChild('supervisor-killed-version-drift');
285
309
  }
286
310
  }
287
311
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gm-plugkit",
3
- "version": "2.0.1530",
3
+ "version": "2.0.1532",
4
4
  "description": "Bootstrap and daemon-spawn tool for gm plugkit binary. Downloads the correct platform binary, verifies SHA256, and starts the spool watcher daemon. Includes plugkit-wasm-wrapper for WASM-based spool watching.",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -298,6 +298,35 @@ function checkWatcherHealth() {
298
298
  if (process.platform === 'win32') {
299
299
  try { spawnSync('taskkill', ['/F', '/T', '/PID', String(currentChildPid)], { stdio: 'ignore', windowsHide: true, timeout: 3000 }); } catch (_) {}
300
300
  }
301
+ return;
302
+ }
303
+ // The watcher reads the wasm's embedded instance_version at load and compares it to the
304
+ // plugkit.version text file (file_version), exposing version_drifted when they disagree.
305
+ // This catches the case where the version text was bumped (e.g. ensureReady's remote-latest
306
+ // override) but the cached plugkit.wasm bytes are a different build -- the text claims 635
307
+ // while the binary embeds 634, so ensureReady's text-only drift check never re-downloads.
308
+ // On that drift, evict the stale cached wasm so the next bootstrap fails isReady() and
309
+ // redownloads the correct build, then recycle the child to load it.
310
+ if (status.version_drifted === true) {
311
+ logEvent('supervisor.version-drift', {
312
+ watcher_pid: currentChildPid,
313
+ instance_version: status.instance_version || null,
314
+ file_version: status.file_version || null,
315
+ severity: 'critical',
316
+ });
317
+ try {
318
+ const home = process.env.USERPROFILE || process.env.HOME || require('os').homedir();
319
+ const gmTools = fs.existsSync(path.join(home, '.gm-tools'))
320
+ ? path.join(home, '.gm-tools')
321
+ : path.join(home, '.claude', 'gm-tools');
322
+ for (const f of ['plugkit.wasm', 'plugkit.version', 'plugkit.wasm.sha256']) {
323
+ try { fs.unlinkSync(path.join(gmTools, f)); } catch (_) {}
324
+ }
325
+ } catch (_) {}
326
+ try { process.kill(currentChildPid, 'SIGTERM'); } catch (_) {}
327
+ if (process.platform === 'win32') {
328
+ try { spawnSync('taskkill', ['/F', '/T', '/PID', String(currentChildPid)], { stdio: 'ignore', windowsHide: true, timeout: 3000 }); } catch (_) {}
329
+ }
301
330
  }
302
331
  }
303
332
 
package/gm.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gm",
3
- "version": "2.0.1530",
3
+ "version": "2.0.1532",
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.1530",
3
+ "version": "2.0.1532",
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",