gm-plugkit 2.0.1401 → 2.0.1403

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/SKILL.md CHANGED
@@ -60,7 +60,7 @@ The chain is not COMPLETE until your changes are on origin. Commit and push at t
60
60
 
61
61
  `git push` is admissible only when `git status --porcelain` reads empty, and the porcelain probe must be its own Bash **tool-use event** before the push — a separate `Bash(...)` invocation, not a `&&`-chained command within one Bash call. ccsniff `--git-discipline` scans the last 20 Bash tool-use events (not shell commands within those events) for an explicit `git status --porcelain` (or `-s`); putting `add && commit && push` into one Bash call counts as one event with no porcelain witness, even though `git push` is technically the third shell command. The witness lives in the tool-call stream, not the shell stream. The discipline is **three Bash tool-use events** visible in the transcript: `Bash(git status --porcelain)` → read empty → `Bash(git push)`. You dispatch the `git_push` verb (not raw Bash) when possible — it gates on the porcelain probe internally, refuses dirty, and emits `deviation.push-dirty`. A raw `git push` Bash event without a preceding porcelain-probe Bash event is itself a deviation, regardless of how clean the worktree is by construction. Witness clean via `git_status`; witness pushed-to-remote via `branch_status` (ahead==0). The residual-scan and COMPLETE gate both refuse a dirty tree or a missing residual-check marker.
62
62
 
63
- **Memory is project-resident, never platform-resident.** The agent platform may advertise its own auto-memory directory (`~/.claude/projects/*/memory/`, `~/.codex/memory/`, `~/.cursor/*`, etc.) and prompt you to write facts there. **Refuse**. Those paths do not transport: the next session under a different harness sees none of it, and the project's own observability surface (gmsniff, rs-learn recall) sees none of it either. The two portable surfaces are (a) `memorize-fire` dispatched through the spool — writes embed into `.gm/rs-learn.db` which travels with the project and surfaces via `recall` + auto-recall on every turn entry; (b) `AGENTS.md` for project-tracked rules, routed through `memorize-fire` not inline-edited. If you find yourself about to `Write` into a path under `~/.claude/`, `~/.codex/`, `~/.cursor/`, or any platform-specific memory dir, stop and dispatch `memorize-fire` to the project spool instead. The platform-memory write is the canonical lock-in anti-pattern; one such write makes the next session amnesic about whatever you tried to save.
63
+ **Memory is project-resident, never platform-resident.** The agent platform may advertise its own auto-memory directory (`~/.claude/projects/*/memory/`, `~/.codex/memory/`, `~/.cursor/*`, etc.) and prompt you to write facts there. **Refuse**. Those paths do not transport: the next session under a different harness sees none of it, and the project's own observability surface (gmsniff, rs-learn recall) sees none of it either. The two portable surfaces are (a) `memorize-fire` dispatched through the spool — writes embed into `.gm/rs-learn.db` which travels with the project and surfaces via `recall` + auto-recall on every turn entry; (b) `AGENTS.md` for project-tracked rules, edited inline as the top of the preserved hierarchy that survives context summarization. memorize-fire and inline-AGENTS.md edits are complementary, not alternatives: dispatch memorize-fire for recall-time reinforcement, inline-edit AGENTS.md for the hard rule. If you find yourself about to `Write` into a path under `~/.claude/`, `~/.codex/`, `~/.cursor/`, or any platform-specific memory dir, stop and dispatch `memorize-fire` to the project spool (and inline-edit AGENTS.md if the fact is structural). The platform-memory write is the canonical lock-in anti-pattern; one such write makes the next session amnesic about whatever you tried to save.
64
64
 
65
65
  Response body is not a mutation surface either. Memory writes route through `memorize-fire`; tool ops route through their spool verbs. Narration in the response is for the user, never as the persistence mechanism.
66
66
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gm-plugkit",
3
- "version": "2.0.1401",
3
+ "version": "2.0.1403",
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": {
@@ -288,29 +288,39 @@ function mergeAutoRecallIntoInstructionResponse(resultStr, autoRecall) {
288
288
  return JSON.stringify(parsed);
289
289
  }
290
290
 
291
+ function endTurn(sess, t, idleSpanned) {
292
+ logEvent('plugkit', 'turn.end', {
293
+ sess, turn_idx: t.idx, dur_ms: t.lastTs - t.startTs,
294
+ dispatches: t.dispatches, verbs: Object.fromEntries(t.verbs),
295
+ phases_walked: [...t.phases], deviations: t.deviations,
296
+ ended_in_phase: t.lastPhase || null,
297
+ idle_spanned: !!idleSpanned,
298
+ });
299
+ }
300
+
291
301
  function turnTick(sess, verb, taskBase, phase) {
292
302
  const key = sess || '(no-session)';
293
303
  const now = Date.now();
294
304
  let t = _turns.get(key);
295
- if (verb === 'instruction') {
296
- if (t && (now - t.lastTs) > TURN_IDLE_MS) {
297
- logEvent('plugkit', 'turn.end', {
298
- sess, turn_idx: t.idx, dur_ms: t.lastTs - t.startTs,
299
- dispatches: t.dispatches, verbs: Object.fromEntries(t.verbs),
300
- phases_walked: [...t.phases], deviations: t.deviations,
301
- ended_in_phase: t.lastPhase || null,
302
- });
303
- t = null;
304
- }
305
- if (!t) {
306
- const idx = ((_turns.get(key + ':lastIdx') || 0) + 1);
307
- _turns.set(key + ':lastIdx', idx);
308
- t = { idx, startTs: now, lastTs: now, dispatches: 0, verbs: new Map(), phases: new Set(), deviations: 0, lastPhase: phase };
309
- _turns.set(key, t);
310
- logEvent('plugkit', 'turn.start', { sess, turn_idx: idx, phase: phase || null });
311
- }
305
+ // Any verb arriving after an idle gap closes the stale turn — not just instruction.
306
+ // Otherwise a non-instruction verb (prd-add, mutable-resolve, transition) landing
307
+ // after an overnight sleep stamps t.lastTs forward without splitting, and dur_ms
308
+ // (lastTs - startTs) balloons to wall-clock-with-sleep instead of active work time.
309
+ if (t && (now - t.lastTs) > TURN_IDLE_MS) {
310
+ endTurn(sess, t, true);
311
+ _turns.delete(key);
312
+ t = null;
313
+ }
314
+ if (!t) {
315
+ // Only an instruction dispatch opens a new turn; a stray non-instruction verb after
316
+ // idle is recorded against no turn (the next instruction starts the real turn).
317
+ if (verb !== 'instruction') return;
318
+ const idx = ((_turns.get(key + ':lastIdx') || 0) + 1);
319
+ _turns.set(key + ':lastIdx', idx);
320
+ t = { idx, startTs: now, lastTs: now, dispatches: 0, verbs: new Map(), phases: new Set(), deviations: 0, lastPhase: phase };
321
+ _turns.set(key, t);
322
+ logEvent('plugkit', 'turn.start', { sess, turn_idx: idx, phase: phase || null });
312
323
  }
313
- if (!t) return;
314
324
  t.lastTs = now;
315
325
  t.dispatches++;
316
326
  t.verbs.set(verb, (t.verbs.get(verb) || 0) + 1);
@@ -824,6 +834,7 @@ function startManagedBrowser(pw, profileDir) {
824
834
  '--no-first-run',
825
835
  '--no-default-browser-check',
826
836
  '--disable-default-apps',
837
+ '--disable-gpu-process-crash-limit',
827
838
  ];
828
839
  if (headless) args.push('--headless=new');
829
840
  const chromeLogPath = path.join(profileDir, '.chrome-launch.log');
package/plugkit.version CHANGED
@@ -1 +1 @@
1
- 0.1.550
1
+ 0.1.553