gm-plugkit 2.0.1613 → 2.0.1615

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
@@ -50,9 +50,9 @@ bun x gm-plugkit@latest spool > /dev/null 2>&1 &
50
50
 
51
51
  **Apparent tooling failure is NEVER grounds to ask the user, and never a reason to a/b-test or blind-restart.** "The spooler is not working" / a missing spool response / a stale watcher is YOUR mechanical, self-service recovery, not a question for the user: honor a future `busy_until` (wait), else boot the watcher and re-dispatch -- you have the authority to boot, so asking the user to do it (or to do anything the verbs can do) is a paper-spirit violation. The spooler mechanics are sound by construction (`.status.json` is written atomically temp+rename, every long verb advertises `busy_until`), so a transient unreadable/stale read is a respawn/idle-teardown window to boot through, not a broken tool. When a transient boot hiccup occurs (e.g. `FailedToOpenSocket`), retry `bun x gm-plugkit@latest spool` -- blips resolve in seconds; never escalate to the user and never fall back to a non-`@latest` cache (it lands a stale watcher). This is the gm method applied to your own tooling: record each candidate cause as a mutable, eliminate it by witness, discover more, keep going.
52
52
 
53
- **Debug the live page via globals + process-of-elimination, never a/b testing.** When a browser/client issue is hard, the move is NOT to guess-and-restart or try variant after variant: surface the relevant state as a `window.*` global and read it live via the `browser` verb's `page.evaluate`, running experiments in the page to eliminate hypotheses one by one (record each as a mutable, witness its resolution, add the new mutables it reveals). A global plus one evaluate observes real runtime state in a single dispatch; the restart-and-eyeball / a/b loop observes almost nothing and burns turns. This process -- record all mutables, eliminate by witness, discover more, keep going -- is the core of gm and applies to every debugging surface, the browser most of all.
53
+ **Debug the live page via globals + process-of-elimination, never guess-and-restart, variant-after-variant, or a/b testing.** Surface the relevant state as a `window.*` global and read it live via the `browser` verb's `page.evaluate`, eliminating hypotheses one at a time -- record each as a mutable, witness its resolution, add the mutables it reveals. This record-eliminate-discover loop is the core of gm, the browser most of all.
54
54
 
55
- **gm genuinely profiles and debugs on both surfaces -- do it, do not eyeball.** Node via `exec_js`: wrap the suspect code in `process.hrtime.bigint()`/`performance.now()`, read `process.memoryUsage()`, capture thrown-error `stack` (stdout returns the numbers, stderr the stack). Browser via the `browser` verb: attach `page.on('console')` + `page.on('pageerror')` before `page.goto`, then `page.evaluate` `performance.getEntriesByType('navigation'|'resource')` and your `window.*` globals; for network use `request.timing().responseEnd` directly (it is already relative to startTime). Profile to LOCATE the slow/broken node, then eliminate hypotheses by live measurement -- never guess-and-restart. Both capabilities are witnessed-working; reach for them on every hard performance or correctness question. Two zero-boilerplate affordances make this trivial: every `exec_js` response carries `duration_ms` (free node wall-time); and a `browser` body prefixed `capture\n<script>` auto-returns `{result, debug:{console, pageErrors, network, performance}}` so you get page logs, uncaught errors, network timing, and navigation performance without writing the `page.on` setup.
55
+ **gm genuinely profiles and debugs on both surfaces -- measure, never eyeball.** The numbers exist and are cheap to read: node wall-time, memory, and the thrown stack on `exec_js`; page console, uncaught errors, network timing, and navigation performance on the `browser` verb. Profile to LOCATE the slow/broken node, then eliminate hypotheses by live measurement against your `window.*` globals -- never guess-and-restart. Two zero-boilerplate affordances make the reach trivial: every `exec_js` response carries `duration_ms`; a `browser` body prefixed `capture\n<script>` auto-returns `{result, debug:{console, pageErrors, network, performance}}`, so the listeners and timing reads come for free.
56
56
 
57
57
  From PowerShell, write spool input as UTF-8 no-BOM (`-Encoding utf8` or `[System.IO.File]::WriteAllText`); the 5.1 default UTF-16+BOM trips `spool.body-encoding-recoded`. Prefer the `Write` tool for JSON bodies. First-turn body is `{"prompt":"<user request>"}` (derives orient_nouns + recall_hits); later same-conversation turns may use `{}`. A `Write` to `in/<verb>/` that errors `ENOENT` (a fast watcher consumed and unlinked the file before the tool's post-write stat) has STILL dispatched -- confirm via the `out/` response, never blind-retry (a non-idempotent verb like `git_finalize` would double-fire); a Bash heredoc `cat > in/<verb>/<N>.txt` has no post-write stat and never surfaces this.
58
58
 
@@ -78,10 +78,10 @@ The chain is not COMPLETE until changes are on origin. Commit and push at the en
78
78
 
79
79
  `git push` is admissible only when `git status --porcelain` is empty, and the porcelain probe must be its OWN Bash tool-use event before the push, not `&&`-chained inside one call (ccsniff `--git-discipline` scans the tool-call stream, not shell commands within an event). The discipline is three Bash events: `git status --porcelain` -> read empty -> `git push`. Prefer the `git_push` verb (gates on porcelain internally, refuses dirty, emits `deviation.push-dirty`). Witness clean via `git_status`, pushed via `branch_status` (ahead==0). residual-scan and the COMPLETE gate both refuse a dirty tree or missing residual-check marker.
80
80
 
81
- **Memory is project-resident, never platform-resident.** Refuse the platform's own auto-memory dir (`~/.claude/projects/*/memory/`, `~/.codex/`, `~/.cursor/*`) -- it does not transport and is invisible to gmsniff/recall. The two portable surfaces: (a) `memorize-fire` through the spool (embeds into `.gm/rs-learn.db`, surfaces via `recall` + auto-recall); (b) `AGENTS.md` for project-tracked hard rules, edited inline. They are complementary -- memorize-fire for recall-time reinforcement, AGENTS.md for the hard rule. About to Write under a platform memory dir: stop, dispatch `memorize-fire` instead. The response body is not a mutation surface either; memory routes through `memorize-fire`, tool ops through their verbs.
81
+ **Memory is project-resident, never platform-resident.** Refuse the platform's own auto-memory dir (`~/.claude/projects/*/memory/`, `~/.codex/`, `~/.cursor/*`) -- it does not transport and is invisible to gmsniff/recall. The two portable surfaces: (a) `memorize-fire` through the spool (embeds into `.gm/rs-learn.db`, surfaces via `recall` + auto-recall); (b) `AGENTS.md` for project-tracked hard rules, edited inline. They are complementary -- memorize-fire for recall-time reinforcement, AGENTS.md for the hard rule. About to Write under a platform memory dir: stop, dispatch `memorize-fire` instead. The response body is not a mutation surface either; memory routes through `memorize-fire`, tool ops through their verbs. **And memorize gm/rs-* method only -- never the specifics of a project gm is merely used ON** (its paths, line numbers, `.gm/prd.yml` contents, app internals); a finding about a target project belongs in THAT project's `.gm` store, so scrub project names/paths and keep only the generalizable gm-method lesson (this binds the `mutable-resolve`/`prd-resolve` auto-memo: witness in gm-method terms).
82
82
 
83
83
  **Suppress mundane output; strip it to the bone.** Drop articles, preamble, play-by-play, boot-probe narration, dispatch echoes, restatement of prose just read, status recaps. What survives: a real finding, a decision and its one-line reason, a blocker, the single-line PRD-read declaration. Terse means fewer words, NEVER zero tool calls and never silent work -- the turn still ends in the chain-advancing tool call, and you still state in one clause what you are about to do.
84
84
 
85
85
  **Prune bad memory on sight -- a wrong recall hit is worse than a miss.** A stale/superseded/wrong `recall` or `auto_recall` hit gets `memorize-prune {key}` (deletes text + embedding). For an uncertain set, `memorize-prune {query}` returns review-only candidates; judge, then re-dispatch the stale `{keys:[...]}` -- never a blind similarity-delete.
86
86
 
87
- On turn entry (first `instruction` after a >30s gap or session-start), plugkit attaches `auto_recall` `{query, hits, fired_at, turn_entry:true}` derived from the user prompt. Read `auto_recall.hits` alongside `recall_hits` (the phase+PRD-subject pack); auto_recall fires only on turn entry, do not re-trigger it.
87
+ On turn entry plugkit attaches an `auto_recall` pack derived from the prompt; read its hits alongside `recall_hits` (the phase+PRD-subject pack). It fires once per turn entry on its own -- do not re-trigger it.
@@ -4,7 +4,7 @@
4
4
 
5
5
  **Every edit to code that runs in a browser requires a live `browser` dispatch in the same turn as the edit.** Client-side surfaces -- `.html`, `.js`, `.jsx`, `.ts`, `.tsx`, `.vue`, `.svelte`, `.mjs`, `.css`, web components, service workers, every asset loaded by `<script>`, every path reached by `import` from a browser-side entry -- must be witnessed by a live `page.evaluate` of the specific invariant the edit establishes. A passing node test, build, `curl` of the HTML, or static-analysis pass witnesses server delivery, not browser behavior, and is non-substitutive. The witness IS the proof; prose is not.
6
6
 
7
- Protocol: (1) boot the real surface -- server up, page reachable, HTTP 200 witnessed; (2) `browser` dispatch -> navigate -> poll for the global the change affects; (3) `page.evaluate` asserting the invariant, capturing witnessed values into `stdout`; (4) variance -> fix at root cause, re-witness. Never advance on unwitnessed client behavior, never queue validation for "later" -- the same turn that edits a client-side file dispatches the browser verb validating it.
7
+ The witness is a live `page.evaluate` asserting the specific invariant against the real surface -- server up, HTTP 200, the global the change affects polled until present -- values captured into `stdout`; variance means a root-cause fix and re-witness, not advance. Anything short of the live assertion -- unwitnessed behavior, an assert fired before the global is present, validation queued for "later" -- leaves the edit unproven, and an unproven client edit is forced closure.
8
8
 
9
9
  Fires across phases: **EXECUTE** edit -> same-turn browser dispatch asserting the invariant; **EMIT** post-emit re-witness (page still passes after the full diff); **VERIFY** final gate -- `deviation.browser-witness-hash-mismatch` fires if a witnessed file changed without re-witnessing. Pure-prose static-document edits (no JS, no CSS-driven behavior, no DOM mutation) are the ONLY exempt category, and the exemption must be named explicitly in the response so the skip is auditable. Silent skip on actual behavior change is forced closure.
10
10
 
@@ -41,7 +41,7 @@ The window opens on the user's screen -- that IS the witness. `GM_BROWSER_HEADLE
41
41
 
42
42
  ## Profile and debug recipes
43
43
 
44
- The page is a genuine profiler and debugger -- use it, never guess-and-restart. The `capture\n` prefix above does all of this for free; reach for the manual recipe below only for custom capture. Attach the listeners BEFORE `page.goto`, then return the captured arrays from one script (all witnessed live):
44
+ The page is a genuine profiler and debugger -- use it, never guess-and-restart. The `capture\n` prefix above does all of this for free; reach for the manual recipe below only for custom capture. Attach the listeners, then navigate, in one script so nothing fires before they are listening -- the captured arrays are the live witness:
45
45
 
46
46
  ```
47
47
  const logs=[],errs=[],net=[];
@@ -16,7 +16,7 @@ Feed search outputs into EMIT only when the digest matches the live filesystem;
16
16
 
17
17
  One write per artifact, then a disk Read against every touched path to assert the change -- verified disk state IS the witness, not the tool-call return. On discrepancy, regress to root cause, do not retry.
18
18
 
19
- **Client-side artifacts: write-then-browser-witness, same turn.** If the artifact is `.html .js .jsx .ts .tsx .vue .svelte .mjs .css` or any browser-loaded path, the disk Read is necessary but not sufficient -- also dispatch a `browser` verb that `page.evaluate`s the invariant the artifact establishes (the page-side assertion is the real witness; the disk Read only witnesses serialization). Skipping it ships a green-checked stub. The COMPLETE gate refuses without the paired browser-witness for every client-side file edited this session (`deviation.client-edit-no-witness`, gates.rs), and you regress to dispatch the missing witness.
19
+ **Client-side artifacts: write-then-browser-witness, same turn.** If the artifact is `.html .js .jsx .ts .tsx .vue .svelte .mjs .css` or any browser-loaded path, the disk Read is necessary but not sufficient -- also dispatch a `browser` verb that `page.evaluate`s the invariant the artifact establishes (the page-side assertion is the real witness; the disk Read only witnesses serialization). Skipping it ships a green-checked stub. The COMPLETE gate refuses while any client-side file edited this session lacks its paired browser-witness (`deviation.client-edit-no-witness`, gates.rs); the missing witness is the next dispatch.
20
20
 
21
21
  ## Artifact scope
22
22
 
@@ -81,7 +81,7 @@ Route KV writes to `<cwd>/.gm/disciplines/<ns>/`. `@<name>` prefix sets namespac
81
81
 
82
82
  ## Inspection routing
83
83
 
84
- `Read` for runtime-state files (spool response JSON, `.status.json`); `codesearch` verb for every code/file/symbol search (it indexes the CURRENT cwd only -- sibling-repo source is `Read` by path, never expected from `codesearch`) -- Glob/Grep/Explore and host-native search are blocked, the verb is the surface. Bash only for the boot probe and shell-only non-git tooling (`npm`, `bun x`, `curl`). Spool responses are synchronous; poll external state via `until <check>; do sleep N; done`.
84
+ Every capability has exactly one sanctioned surface and the platform's native tools are never it: code/file/symbol search is the `codesearch` verb (cwd-indexed -- a sibling repo is `Read` by path, never expected from `codesearch`), runtime-state files (spool response JSON, `.status.json`) are `Read`, and Bash survives only for the boot probe and shell-only non-git tooling (`npm`, `bun x`, `curl`). Reaching for Glob/Grep/Explore or any host-native search is reaching around the surface -- it is blocked; the verb IS the surface. Spool responses are synchronous; poll external state via `until <check>; do sleep N; done`.
85
85
 
86
86
  ## Memorize
87
87
 
@@ -89,6 +89,6 @@ Write the recall index only via `memorize-fire`; surfaces outside it produce mem
89
89
 
90
90
  ## Return to plugkit
91
91
 
92
- Against every drift, gate denial, "what now", uncertain next step, or N elapsed actions without one in a non-trivial phase: dispatch `instruction`. Your memory of the prose is stale the moment phase/PRD/mutables shift. It is cheap, synchronous, idempotent -- unbounded cost to under-dispatching. Every gate denial names the next verb in its `reason` field; read it and dispatch that verb, do not improvise around the denial. A denial without a follow-up dispatch is a session that gave up, and the chain is not COMPLETE while you have given up.
92
+ Any uncertainty about the next move -- drift, a gate denial, a silent stretch in a non-trivial phase -- is itself the signal to dispatch `instruction`, because your memory of the prose went stale the moment phase/PRD/mutables shifted. It is cheap, synchronous, idempotent; the cost is all on the under-dispatch side. Every gate denial names the next verb in its `reason` field; read it and dispatch that verb, never improvise around the denial -- a denial with no follow-up dispatch is a session that gave up, and the chain is not COMPLETE while you have given up.
93
93
 
94
94
  Transition: SESSION_ID threaded AND spool reachable -> dispatch `instruction` with `{"prompt":"<user request>"}` so plugkit derives orient_nouns + recall_hits; later same-chain dispatches may use empty body.
@@ -8,7 +8,7 @@ L3 distance + audit: real input -> real code -> real output, witnessed.
8
8
 
9
9
  Route every mutation through PRD rows, mutables, KV memos; attach an audit tuple `(id, hash, ts)` to each accepted write, where `hash` is the witness (`file:line`, codesearch hit, exec snippet). `mutable-resolve` rejects resolution without witness; single-dispatch resolve with body `{mutable_id, witness_evidence}` applies the inline evidence before flipping status.
10
10
 
11
- Every code/file/symbol lookup is a `codesearch` dispatch -- never a platform Explore agent, Task/general-purpose search subagent, or raw grep. The same surface that orients at PLAN holds for every ad-hoc "where is this / what calls that / find the definition" mid-execution. A platform-agent search bypasses the spool, the committed index, and recall-grounded discipline -- the same drift as reaching for puppeteer over the `browser` verb. The capability is a verb; dispatch the verb.
11
+ Every code/file/symbol lookup is a `codesearch` dispatch -- never a platform Explore agent, Task/general-purpose search subagent, or raw grep -- the same drift as reaching for puppeteer over the `browser` verb. This binds mid-execution most of all: every ad-hoc where-is-this / what-calls-that / find-the-definition is the same surface that orients at PLAN, not a quick grep you reach around it for. The capability is a verb; dispatch the verb.
12
12
 
13
13
  ## Witness
14
14
 
@@ -24,7 +24,7 @@ State diverging from the PRD's assumed shape is a new mutable, not background no
24
24
 
25
25
  ## Discovery: additive vs reshaping
26
26
 
27
- Real input is the highest-yield discovery surface; every observation converts to a PRD row this turn, never a "future work" note -- a corner case under real input, a caveat the tool emits, a failure mode the surface exposes, an adjacent file/import needing work, stderr that is itself a deviation, a prior commit violating a user preference (sparse PRD, untriaged residual, missing browser-witness). Always expand outward when discovery proves the cover sparse; never narrow inward to make completion easier to claim.
27
+ Real input is the highest-yield discovery surface; every observation converts to a PRD row this turn, never a "future work" note -- whatever real input surfaces (a corner case, a tool caveat, a failure mode, an adjacent file/import, deviation-bearing stderr, a prior commit violating a user preference such as a sparse PRD, untriaged residual, or missing browser-witness) is a row, the list never closed. Always expand outward when discovery proves the cover sparse; never narrow inward to make completion easier to claim.
28
28
 
29
29
  Two kinds, two moves. **Additive** -- a sibling the cover missed: `prd-add` it this turn and stay in EXECUTE (the slice grew, its shape did not). **Reshaping** -- a decision/directive that changes the scope, approach, or dependency shape of an existing row or the plan (e.g. "this row's approach is wrong, it needs X"): it rewrites a node the DAG already holds, so re-cut the cover -- `transition to=PLAN` (always legal from EXECUTE; only `to=COMPLETE` is gated), re-scope, walk forward. Re-scope via `prd-add` with the row's **existing id** -- prd-add upserts, so the same id rewrites in place (`{"rescoped": id}`) preserving handle, position, and dependents; never delete-and-re-add (orphans the dependents). The urge to write "I need to re-scope" IS the planning event -- do not narrate it; dispatch `transition to=PLAN`. Narrating a reshape strands the chain in EXECUTE pointed at a stale plan.
30
30
 
@@ -36,7 +36,7 @@ First emit = closure of the transform; scaffold + IOU externalizes residual cost
36
36
 
37
37
  Data first -- get the structures and their invariants right and the code writes itself; convoluted control flow means the data model is wrong, so fix the model. Make invalid state unrepresentable -- pass parameters over hidden globals, encode the constraint in the type/shape so the bad combination cannot be constructed. Reason from physical constraints (latency, bandwidth, memory, coordination, the worst node) before designing within them. Keep the spine flat, each unit single-focus and understandable at its call site. Make misuse structurally impossible, not documented-against. Optimize the worst case, not the average; design every failure path explicitly (full -> degraded -> safe-fail -> explicit-error), never a silent catastrophic mode. Measure, do not assume -- profile before optimizing, implement both and compare on real input when in genuine dispute. When a change regresses something that worked, revert first and investigate second: restore green, then diagnose from a known-good base. Fail fast and loud over limping on bad state.
38
38
 
39
- **Process of elimination is the debugging paradigm on every surface, and manual labour against real services is how you witness.** Never guess-and-restart, a/b-test, or shotgun variants: enumerate the candidate causes as mutables, then eliminate each by a witness read against REAL input -- `exec_js` against the real service, `codesearch`/`Read` against the real source, the `browser` verb's `page.evaluate` against a `window.*` global on the live page. Each elimination reveals the next mutable; record it and keep going until one cause survives every other's refutation. Reading the live runtime once observes more than a hundred blind restarts. Profile genuinely on both surfaces: in node, `exec_js` with `process.hrtime.bigint()`/`performance.now()` around the suspect code, `process.memoryUsage()`, and the thrown-error `stack` (stdout carries the numbers, stderr the stack); in the browser, a `browser` body prefixed `capture\n<script>` auto-returns `{result, debug:{console, pageErrors, network, performance}}` (zero boilerplate), or hand-attach `page.on('console')`/`page.on('pageerror')` + `performance.getEntriesByType('navigation'|'resource')` + `request.timing().responseEnd` (see browser prose). `exec_js` responses carry `duration_ms` for free. Profile to LOCATE the slow/broken node, then eliminate hypotheses by live measurement. Verification is the same labour: run the real thing and witness the real output (the single mock-free `test.js`, the live page, the real service), never an automated unit/mock harness standing in for the real-services witness. Apparent tooling failure is part of this -- it is your mechanical self-recovery by elimination, never a question for the user.
39
+ **Process of elimination is the debugging paradigm on every surface, and manual labour against real services is how you witness.** Never guess-and-restart, a/b-test, or shotgun variants: enumerate the candidate causes as mutables, then eliminate each by a witness read against REAL input -- `exec_js` against the real service, `codesearch`/`Read` against the real source, the `browser` verb's `page.evaluate` against a `window.*` global on the live page. Each elimination reveals the next mutable; record it and keep going until one cause survives every other's refutation. Reading the live runtime once observes more than a hundred blind restarts. Profile on the real surface, not from intuition: wrap the suspect node and read the live numbers. In node, `exec_js` carries `duration_ms` for free, surfaces your own timing and `process.memoryUsage()` on stdout, and lands the thrown-error `stack` on stderr -- read both channels (numbers on stdout, stack on stderr). In the browser, a body prefixed `capture\n<script>` auto-returns `{result, debug:{console, pageErrors, network, performance}}` with zero boilerplate. Profile to LOCATE the slow/broken node, then eliminate hypotheses by live measurement. Verification is the same labour: run the real thing and witness the real output (the single mock-free `test.js`, the live page, the real service), never an automated unit/mock harness standing in for the real-services witness. Apparent tooling failure is part of this -- it is your mechanical self-recovery by elimination, never a question for the user.
40
40
 
41
41
  ## Memorize
42
42
 
@@ -24,7 +24,7 @@ Cut the cover so the hardest reachable node comes first: the row exercising the
24
24
 
25
25
  ## Noticing-to-PRD
26
26
 
27
- Anything noticed during orient or expansion that is not yet a row -- outstanding work, an unfinished surface, an improvable shape, a preference misalignment, an adjacent concern -- is a `prd-add` this turn. Observations carried only in the response body evaporate; only the store survives. "We should also..." / "worth noting..." belongs in a row with the witness that motivated it. Structural noticing (no test coverage on X, docs missing on Y, prior commit Z violates a rule) and preference-aware noticing (state diverging from density-at-PLAN, residual-triage, push-on-clean, every-possible expansion, browser-witness coverage) convert the same way -- each its own row describing the aligned state.
27
+ Anything noticed during orient or expansion that is not yet a row -- outstanding work, an unfinished surface, an improvable shape, a preference misalignment, an adjacent concern -- is a `prd-add` this turn. Observations carried only in the response body evaporate; only the store survives. "We should also..." / "worth noting..." is a row with the witness that motivated it, not a remark. A noticing that is structural (a coverage gap, a missing doc, a prior commit that broke a rule) or preference-aware (state drifting from density-at-PLAN, residual-triage, push-on-clean, every-possible expansion, or browser-witness coverage) is the same event: each its own row describing the aligned state.
28
28
 
29
29
  ## Mutables
30
30
 
@@ -8,7 +8,7 @@ Docs reflect the current state of the system, not its history. Every rule in AGE
8
8
 
9
9
  Edit AGENTS.md/CLAUDE.md inline -- the top of the preserved hierarchy and the only doc that survives context summarization. `memorize-fire` is the parallel surface (`.gm/exec-spool/in/memorize-fire/<N>.txt`, raw text or `{text, namespace?}`) where `recall`/`auto_recall` retrieve the fact on future turns. AGENTS.md is the staging ground; the store is the recall surface. Migration is the agent's dual-write, not a file-scan: landing a load-bearing rule in AGENTS.md, fire the same rule to the store the same session so it surfaces in `auto_recall`. An automatic ingest cannot run -- the classifier cannot judge which paragraphs are recall-worthy rules vs narrative, so the agent judges at write time. Never pass `namespace:"AGENTS.md"` (mislabeled namespace); load-bearing rules go to the default namespace. Multiple facts = multiple parallel requests in one message.
10
10
 
11
- **Migration is bidirectional; the back-pressure is deflation -- every memorize run also drains AGENTS.md.** AGENTS.md grows monotonically if flow is only inward and bloats past the budget it protects. So every session firing `memorize-fire` for new facts ALSO picks a few existing AGENTS.md entries that have gone detail-heavy/single-crate/single-platform (the material the Documentation Policy assigns to rs-learn), `memorize-fire`s the substance to the default namespace, and deletes or compresses the paragraph to a one-line pointer in the same commit. Eligible = a per-crate runtime quirk, a Windows/process mechanic, a hook implementation detail, any fact-base caveat a future agent reaches for via `recall` rather than needing resident every prompt. Top-level cross-cutting rules stay; everything recall-reachable drains. Witnessed both ways: the fact lands in the store AND the byte-count drops. A few entries per run, never a wholesale rewrite. Skipping the drain is the slow-bloat drift the policy exists to prevent.
11
+ **Migration is bidirectional; the back-pressure is deflation -- every memorize run also drains AGENTS.md.** AGENTS.md grows monotonically if flow is only inward and bloats past the budget it protects. So every session firing `memorize-fire` for new facts ALSO picks a few existing AGENTS.md entries that have gone detail-heavy/single-crate/single-platform (the material the Documentation Policy assigns to rs-learn), `memorize-fire`s the substance to the default namespace, and deletes or compresses the paragraph to a one-line pointer in the same commit. Eligible = anything a future agent reaches for via `recall` rather than needing resident every prompt; resident = the cross-cutting rule, drainable = the fact-base caveat. Top-level cross-cutting rules stay; everything recall-reachable drains. Witnessed both ways: the fact lands in the store AND the byte-count drops. A few entries per run, never a wholesale rewrite. Skipping the drain is the slow-bloat drift the policy exists to prevent.
12
12
 
13
13
  ## README.md
14
14
 
@@ -24,7 +24,7 @@ One entry per commit landed this session: the commit subject plus a one-sentence
24
24
 
25
25
  ## Commit and Push
26
26
 
27
- Stage doc updates only -- never bundle them with code changes from earlier phases (committed at their own time). One commit, present-tense imperative subject. Push via the git verbs: `git_finalize {message}` bundles add -> commit -> porcelain-gate -> push in one dispatch, or `git_add` the doc paths then `git_commit` then `git_push`. The verbs gate on the porcelain probe internally and refuse a dirty tree (`deviation.push-dirty`); a raw `git` shell body is gated `deviation.bash-git-bypass`. If you ever fall back to raw Bash git, the porcelain probe must be its own `Bash(git status --porcelain)` tool-use event before the push (not `&&`-chained) -- ccsniff `--git-discipline` scans the last 20 Bash tool-use events for the porcelain regex, and `add && commit && push` in one event has no witness. A doc commit stages only paths matching AGENTS.md, CLAUDE.md, README.md, SKILLS.md, CHANGELOG.md, LICENSE*, docs/**, or site/**; any non-doc path means you bundled phases -- split it out before staging. The push triggers the docs pipeline and IS the validation dispatch.
27
+ Stage doc updates only -- never bundle them with code changes from earlier phases (committed at their own time). One commit, present-tense imperative subject. Push via the git verbs: `git_finalize {message}` bundles add -> commit -> porcelain-gate -> push in one dispatch, or `git_add` the doc paths then `git_commit` then `git_push`. The verbs gate on the porcelain probe internally and refuse a dirty tree (`deviation.push-dirty`); a raw `git` shell body is gated `deviation.bash-git-bypass`. If you ever fall back to raw Bash git, the porcelain probe is its own `Bash(git status --porcelain)` event before the push, never `&&`-chained -- a chained `add && commit && push` carries no separable witness, so ccsniff `--git-discipline` sees an unwitnessed push. A doc commit stages only paths matching AGENTS.md, CLAUDE.md, README.md, SKILLS.md, CHANGELOG.md, LICENSE*, docs/**, or site/**; any non-doc path means you bundled phases -- split it out before staging. The push triggers the docs pipeline and IS the validation dispatch.
28
28
 
29
29
  ## COMPLETE
30
30
 
@@ -24,7 +24,7 @@ Write `test.js` at root, 200-line ceiling, real services only (mock-free) -- thi
24
24
 
25
25
  ## Residual-scan
26
26
 
27
- Run `residual-scan` before COMPLETE; it examines the open surface (PRD pending, browser sessions, dirty tree, untracked artifacts, browser-witness coverage for client-side files modified this session). Non-empty = non-convergent -> expand the PRD with the reachable in-spirit residual via `prd-add` and re-execute. One-shot per stop window via marker. `reason: "browser sessions still open"` -> close each (`browser` `session close <id>`; `session list` enumerates); retrying the scan without closing is the idle-mid-chain/polling deviation -- the denial names the next verb, dispatch it.
27
+ Run `residual-scan` before COMPLETE; it examines the open surface -- PRD pending, browser sessions, dirty tree, untracked artifacts, and browser-witness coverage for client-side files modified this session -- and a non-empty result is non-convergent. Non-empty = non-convergent -> expand the PRD with the reachable in-spirit residual via `prd-add` and re-execute. One-shot per stop window via marker. `reason: "browser sessions still open"` -> close each (`browser` `session close <id>`; `session list` enumerates); retrying the scan without closing is the idle-mid-chain/polling deviation -- the denial names the next verb, dispatch it.
28
28
 
29
29
  Before accepting the scan empty, re-apply "every possible" to the closing PRD: every resolved row's skipped variants, every adjacent surface the work touched, every validation that proves a row in practice not in claim -- each fresh hit is a `prd-add` + re-execution. A clean scan on a short PRD for a long-horizon prompt is a false negative. Noticing-to-PRD is unchanged: anything observed while testing/reading diffs/inspecting closing state converts this turn and re-executes; stopping at "tests pass" while noticing named follow-on work is the canonical VERIFY drift.
30
30
 
@@ -44,13 +44,13 @@ Attach `witness_evidence` of the admitted form to every mutable in the closing s
44
44
 
45
45
  ## Completion
46
46
 
47
- The chain enters COMPLETE only when your `transition` returns COMPLETE phase; the on-disk state file moves only on a `transition`. **Done is plugkit's pronouncement, not yours** -- gate denies -> not done; gate allows but no `transition` dispatched -> not done; `transition` returns non-COMPLETE -> not done. Announcing "I'm finished" before the gate flips is narrating; the cure is `phase-status`. Not-COMPLETE means a next transition exists; idle and "waiting for the user" mid-chain are deviations (closure was authorized at request time). Between the four observations, between residual-scan and COMPLETE, between push and transition, re-dispatch `instruction` -- VERIFY is where premature COMPLETE happens.
47
+ The chain enters COMPLETE only when your `transition` returns COMPLETE phase; the on-disk state file moves only on a `transition`. **Done is plugkit's pronouncement, not yours** -- even gate-allowance is not done; only a dispatched `transition` returning COMPLETE is, so a narrated PLAN->COMPLETE walk with the gate open or the verb un-dispatched is fabrication. Announcing "I'm finished" before the gate flips is narrating; the cure is `phase-status`. Not-COMPLETE means a next transition exists; idle and "waiting for the user" mid-chain are deviations (closure was authorized at request time). Between the four observations, between residual-scan and COMPLETE, between push and transition, re-dispatch `instruction` -- VERIFY is where premature COMPLETE happens.
48
48
 
49
49
  **You close rs-learn's learning loop here -- you are the model in the loop and hold the one signal every core needs: how well this turn went.** Before COMPLETE, self-report turn quality 0.0-1.0 (1.0 = clean convergent walk, no deviations, pushed, gate-allowed; lower as deviations/rework accumulate). That number drives every core, none of which can observe it without you:
50
50
 
51
- - **Instant MicroLoRA adapter:** rank-2 head over the 384-dim bge embeddings emitting a per-target re-rank logit `B*(A*embedding)` (does not reshape the vector). Meaningful only with >=2 enabled disciplines; default-only = correct no-op, skip. With >=2: init once per session `learn {verb:init_instant, body:{targets:[<enabled namespaces>]}}`, then `learn {verb:feedback, body:{embedding:<bge embedding of this turn's task>, payload:{quality:<0-1>}}}` -- high quality shifts the helpful namespace's logit up so recall promotes it.
51
+ - **Instant MicroLoRA adapter:** only with >=2 enabled disciplines (default-only = correct no-op, skip). Init once per session `learn {verb:init_instant, body:{targets:[<enabled namespaces>]}}`, then `learn {verb:feedback, body:{embedding:<bge embedding of this turn's task>, payload:{quality:<0-1>}}}` -- high quality shifts the helpful namespace's logit up so recall promotes it.
52
52
  - **FastGRNN router:** `learn {verb:record_outcome, body:{target:"<your model id>", quality:<0-1>}}` so the next `route_hint` reflects learned outcomes.
53
- - **Deep EWC core** and **GAT attention relation weights** take the same quality as `record_loss` / `nudge_relation`.
53
+ - **Deep EWC core** and **GAT attention relation weights:** the same quality as `record_loss` / `nudge_relation`.
54
54
 
55
55
  rs-learn never calls a model; it emits the need and you supply the answer. Skipping the self-report leaves the cores untrained.
56
56
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gm-plugkit",
3
- "version": "2.0.1613",
3
+ "version": "2.0.1615",
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": {