gm-skill 2.0.1794 → 2.0.1795
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 +46 -46
- package/gm-plugkit/package.json +1 -1
- package/gm-plugkit/plugkit-wasm-wrapper.js +60 -5
- package/gm.json +1 -1
- package/package.json +1 -1
package/AGENTS.md
CHANGED
|
@@ -22,27 +22,27 @@ Skills encode environment-specific constraints that override general knowledge.
|
|
|
22
22
|
|
|
23
23
|
# Architecture & Philosophy
|
|
24
24
|
|
|
25
|
-
Repo root = package root = published `gm-skill` npm package; no factory, no separate build-output dir. Entry: `skills/gm/SKILL.md`. Orchestration lives in rs-plugkit, served on-demand via `instruction`. Agent-facing prose (phase instruction, gate/residual text) externalizes to editable `gm-plugkit/instructions/`: prose edits = gm-plugkit republish, zero Rust rebuild. Mechanism (prose.rs per-key fallback to compiled const; sync-instruction-consts.mjs byte-aligns .md<->rs-plugkit consts) in
|
|
25
|
+
Repo root = package root = published `gm-skill` npm package; no factory, no separate build-output dir. Entry: `skills/gm/SKILL.md`. Orchestration lives in rs-plugkit, served on-demand via `instruction`. Agent-facing prose (phase instruction, gate/residual text) externalizes to editable `gm-plugkit/instructions/`: prose edits = gm-plugkit republish, zero Rust rebuild. Mechanism (prose.rs per-key fallback to compiled const; sync-instruction-consts.mjs byte-aligns .md<->rs-plugkit consts) in the recall store (`recall: string-externalization project`).
|
|
26
26
|
|
|
27
27
|
## WASM-only
|
|
28
28
|
|
|
29
|
-
Plugkit = wasm cdylib, loaded by `plugkit-wasm-wrapper.js` under Node/bun; zero native binaries built/downloaded/published. `plugkit.wasm` fetched at bootstrap from `plugkit-wasm` npm / `plugkit-bin` gh-releases, sha256-pinned. Size + embedded-model (offline in-wasm embeddings) mechanics:
|
|
29
|
+
Plugkit = wasm cdylib, loaded by `plugkit-wasm-wrapper.js` under Node/bun; zero native binaries built/downloaded/published. `plugkit.wasm` fetched at bootstrap from `plugkit-wasm` npm / `plugkit-bin` gh-releases, sha256-pinned. Size + embedded-model (offline in-wasm embeddings) mechanics: the recall store (`recall: WASM-only plugkit size mechanics`).
|
|
30
30
|
|
|
31
|
-
Wasm host-import link-module rule (`#[link(wasm_import_module="env")]` on every host-import extern block, every dep crate):
|
|
31
|
+
Wasm host-import link-module rule (`#[link(wasm_import_module="env")]` on every host-import extern block, every dep crate): the recall store (`recall: wasm host-import link-module trap`).
|
|
32
32
|
|
|
33
|
-
**`plugkit-wasm-wrapper.js` is ESM; import node builtins at module scope, never inline `require()`** (
|
|
33
|
+
**`plugkit-wasm-wrapper.js` is ESM; import node builtins at module scope, never inline `require()`** (recall store: `recall: wrapper require not defined under bun`).
|
|
34
34
|
|
|
35
|
-
**Every single-instance/lock guard is atomic** (O_EXCL / atomic-rename), never check-then-act (
|
|
35
|
+
**Every single-instance/lock guard is atomic** (O_EXCL / atomic-rename), never check-then-act (recall store: `recall: supervisor churn TOCTOU atomic guard`).
|
|
36
36
|
|
|
37
37
|
## Spool dispatch ABI
|
|
38
38
|
|
|
39
39
|
Dispatch = Write `.gm/exec-spool/in/<verb>/<N>.txt`, Read `.gm/exec-spool/out/<verb>-<N>.json` (nested) or `out/<N>.json` (root). Wasm orchestrator services every verb; harness never executes side effects directly.
|
|
40
40
|
|
|
41
41
|
- **Orchestrator verbs**: `instruction`, `transition`, `phase-status`, `mutable-resolve`, `memorize-fire`, `residual-scan`, `auto-recall`.
|
|
42
|
-
- **Wasm-direct verbs**: fs/kv/exec/fetch/env, recall, codesearch, memorize(+prune), health, filter, full git verb family. Enumeration in
|
|
43
|
-
- **memorize-prune**: prune bad/superseded memories; two-mode spec (key-delete vs query-review) in
|
|
44
|
-
- **git verbs**: git is a first-class spool surface, never a shell command; `git_finalize {message}` is the bundled COMPLETE-phase push surface, `git_push` the only admissible raw push (porcelain-gated, rebase-retry). A git-dominant `bash`/`powershell` body is gated (`deviation.bash-git-bypass`). Per-verb shapes + host_git `.exe` resolution in
|
|
45
|
-
- **filter**: pure stdout -> compact-stdout transform, in-wasm. Spec + usage (pipe raw command output through it before context) in
|
|
42
|
+
- **Wasm-direct verbs**: fs/kv/exec/fetch/env, recall, codesearch, memorize(+prune), health, filter, full git verb family. Enumeration in the recall store (`recall: wasm-direct plugkit verbs full list`).
|
|
43
|
+
- **memorize-prune**: prune bad/superseded memories; two-mode spec (key-delete vs query-review) in the recall store (`recall: memorize-prune verb two-mode spec`).
|
|
44
|
+
- **git verbs**: git is a first-class spool surface, never a shell command; `git_finalize {message}` is the bundled COMPLETE-phase push surface, `git_push` the only admissible raw push (porcelain-gated, rebase-retry). A git-dominant `bash`/`powershell` body is gated (`deviation.bash-git-bypass`). Per-verb shapes + host_git `.exe` resolution in the recall store (`recall: git verbs rs-plugkit spool surface`).
|
|
45
|
+
- **filter**: pure stdout -> compact-stdout transform, in-wasm. Spec + usage (pipe raw command output through it before context) in the recall store (`recall: filter verb rs-plugkit spool spec`).
|
|
46
46
|
|
|
47
47
|
## Documentation Policy
|
|
48
48
|
|
|
@@ -50,37 +50,37 @@ Record only non-obvious multi-run-cost caveats; prune stale; never document the
|
|
|
50
50
|
|
|
51
51
|
**No changelog history in AGENTS.md.** Every entry is a present-tense rule about what must/must-not be the case in code now. Forbidden: `(FIXED)` markers, commit hashes, dated audit entries, `## Learning audit` sections, "(added 2026-...)" annotations, "we used to X, now Y". History belongs in `git log` and `CHANGELOG.md`.
|
|
52
52
|
|
|
53
|
-
**Detail-heavy caveats live in
|
|
53
|
+
**Detail-heavy caveats live in the recall store (`.gm/memories/` corpus), not here.** Per-crate/OS/hook/workflow fact-base -> `recall`; AGENTS.md keeps top-level gm-repo-governing rules only. Cross-cutting policy stays; single-crate/single-platform mechanism drains.
|
|
54
54
|
|
|
55
|
-
**gm's recall store (`.gm/
|
|
55
|
+
**gm's recall store (`.gm/memories/` project corpus) holds gm/rs-* method/tooling/invariants ONLY -- never target-project specifics.** A finding ABOUT a project gm merely drives ON (its paths, line numbers, `.gm/prd.yml`/`mutables.yml` contents, app internals, versions) belongs in THAT project's own `.gm` store -- pollutes every gm session's recall otherwise. Using gm != working on the driven project: scrub names/paths/state, keep only the generalizable gm-method lesson. Binds `mutable-resolve`/`prd-resolve` auto-memo too -- witness in gm-method terms, never by quoting foreign tree. (Code-side classifier reject rejected as too brittle -- false-rejects legit `.gm/prd.yml` mechanism citations -- so discipline + on-sight `memorize-prune` of foreign-specific memos is the enforcement.)
|
|
56
56
|
|
|
57
57
|
**Every memorize run also drains AGENTS.md -- bidirectional migration, deflation is the back-pressure.** Inward-only flow bloats past budget: every `memorize-fire` session ALSO exfiltrates a few detail-heavy/single-crate/single-platform entries -- fire substance to default namespace, compress paragraph to one-line pointer, same commit. Witness: store gains fact, byte-count drops. Few per run, never wholesale; top-level rules stay, recall-reachable detail drains. `test.js checkAgentsMdBudget()` = structural byte-ceiling backstop (`recall: AGENTS.md byte-ceiling guard looper bloat`).
|
|
58
58
|
|
|
59
59
|
## Coding Style
|
|
60
60
|
|
|
61
|
-
**No synthetic/unit test files, ever -- manual legwork through real code execution is the only test surface.** No `*.test.*`/`*.spec.*` files, no `test/`/`__tests__/`/`spec/` directories, no jest/mocha/vitest/pytest/unittest/junit or any assertion/mocking library, in this repo or any repo gm drives work in. Verification is running the real thing and reading the real output -- `exec_js`/`browser` witnessing a live invariant, or an addition to the single root `test.js` (<=200 lines, real services, mock-free, defined in `skills/gm/SKILL.md`). A PRD row for "add validation"/"handle edge case X" is closed by exercising that case live, never by authoring a test case that exercises it later. Rationale + measured impact on coder throughput:
|
|
61
|
+
**No synthetic/unit test files, ever -- manual legwork through real code execution is the only test surface.** No `*.test.*`/`*.spec.*` files, no `test/`/`__tests__/`/`spec/` directories, no jest/mocha/vitest/pytest/unittest/junit or any assertion/mocking library, in this repo or any repo gm drives work in. Verification is running the real thing and reading the real output -- `exec_js`/`browser` witnessing a live invariant, or an addition to the single root `test.js` (<=200 lines, real services, mock-free, defined in `skills/gm/SKILL.md`). A PRD row for "add validation"/"handle edge case X" is closed by exercising that case live, never by authoring a test case that exercises it later. Rationale + measured impact on coder throughput: the recall store (`recall: synthetic-test-file coder-performance regression`). Full phase-level enforcement (PLAN's edge-case rows, EXECUTE's hard rule, VERIFY's `deviation.synthetic-test-file` gate) lives in rs-plugkit's served `instruction` prose, not duplicated here.
|
|
62
62
|
|
|
63
63
|
**No comments in code** -- no inline, block, or JSDoc comments anywhere (source, generated output, hooks, scripts). `test.js checkNoComments()` is the structural guard (fails on any leading `//` over tracked `.js/.mjs/.cjs`); one sighting spawns the full-tree sweep.
|
|
64
64
|
|
|
65
|
-
**No UTF-8 BOM in any tracked source file** -- always `-Encoding utf8` (no BOM) or the `Write` tool; PowerShell defaults betray this. `test.js checkNoBom()` is the structural guard; one sighting spawns the full-tree sweep. Cause + breakage mechanics in
|
|
65
|
+
**No UTF-8 BOM in any tracked source file** -- always `-Encoding utf8` (no BOM) or the `Write` tool; PowerShell defaults betray this. `test.js checkNoBom()` is the structural guard; one sighting spawns the full-tree sweep. Cause + breakage mechanics in the recall store (`recall: BOM regression incident`).
|
|
66
66
|
|
|
67
67
|
**No graphical symbols; convert to industry-standard text on sight.** Any non-ASCII decorative glyph (arrows, box/geometric glyphs, stars, dots, bullets, checks/crosses, emojis) is forbidden in all output and source -- convert it to its plain-ASCII equivalent the same turn (the word, `->`, `-`/`*`, `[x]`/`[ ]`, done/todo/pass/fail). Tell-tale-AI class: one sighting spawns the full-codebase sweep, never a one-off edit. Exempt: functional code operators (`=>`, `??`, `?.`, comparison/math), frozen changelog/git-log entries, binary stores, intentional icon-font/CSS-content product glyphs, and canonical CS/formal-logic notation in `.gm/constraints.md` / `gm-plugkit/constraints-default.md` (`.`, `->` as function-space, `|-`, set/quantifier symbols) -- these are semantic operators in a formal constraints spec, not decorative flourish. `ccsniff --glyph-discipline` flags decorative glyphs post-hoc (run each audit, like `--git-discipline`/`--search-discipline`).
|
|
68
68
|
|
|
69
|
-
**Implicit, not explicit, in skill prose**: skill files elicit, never describe -- terse imperatives, no recipes/citations/manuals; boot-edge ABI (spool paths, JSON fields, verb names, deviation ids, gate names) stays explicit; SKILL.md keeps only invocation syntax, transition markers, gate conditions, constraints, exact-usage examples. Full criteria:
|
|
69
|
+
**Implicit, not explicit, in skill prose**: skill files elicit, never describe -- terse imperatives, no recipes/citations/manuals; boot-edge ABI (spool paths, JSON fields, verb names, deviation ids, gate names) stays explicit; SKILL.md keeps only invocation syntax, transition markers, gate conditions, constraints, exact-usage examples. Full criteria: the recall store (`recall: implicit-not-explicit skill prose criteria`).
|
|
70
70
|
|
|
71
71
|
## Build
|
|
72
72
|
|
|
73
73
|
No build step; repo root = published artifact. `npm publish` from root ships `gm-skill` (permanent npm id; skill DIR is `skills/gm`, command is `/gm`). `package.json` `files:` pins shipped paths. `AnEntrypoint/gm-skill` = back-compat mirror, receives only `skills/gm/SKILL.md` per release.
|
|
74
74
|
|
|
75
|
-
`bin/install.js` = canonical installer (no npx `skills` lib, no marketplace); landed dir name IS the `/command`; `test.js checkRenameAndInstaller()` = structural guard. Copy-target, four non-interactive Claude Code settings, reasoning-in-code framing, guard assertions:
|
|
75
|
+
`bin/install.js` = canonical installer (no npx `skills` lib, no marketplace); landed dir name IS the `/command`; `test.js checkRenameAndInstaller()` = structural guard. Copy-target, four non-interactive Claude Code settings, reasoning-in-code framing, guard assertions: the recall store (`recall: gm installer detail`).
|
|
76
76
|
|
|
77
77
|
## The agent is the orchestrator; plugkit is the brain it drives
|
|
78
78
|
|
|
79
|
-
Plugkit = stateful library the agent drives by verb dispatch -- never autonomous, never background-advances phases, never validates while agent waits. State change = verb written to `.gm/exec-spool/in/<verb>/<N>.txt`; dispatch ledger is ground truth, so zero-dispatch narrated PLAN->COMPLETE = fabricated. PLAN -> EXECUTE -> EMIT -> VERIFY -> CONSOLIDATE -> COMPLETE lives natively in rs-plugkit (phase/mutables/memorize/transition-legality as data + gate checks); agent triggers every op, plugkit synchronous from agent's view -- polling output dir instead of reading response = canonical misuse. CONSOLIDATE owns git-push + CI/CD validation, split off COMPLETE gate so COMPLETE checks only the consolidated result. File paths + verb enumeration:
|
|
79
|
+
Plugkit = stateful library the agent drives by verb dispatch -- never autonomous, never background-advances phases, never validates while agent waits. State change = verb written to `.gm/exec-spool/in/<verb>/<N>.txt`; dispatch ledger is ground truth, so zero-dispatch narrated PLAN->COMPLETE = fabricated. PLAN -> EXECUTE -> EMIT -> VERIFY -> CONSOLIDATE -> COMPLETE lives natively in rs-plugkit (phase/mutables/memorize/transition-legality as data + gate checks); agent triggers every op, plugkit synchronous from agent's view -- polling output dir instead of reading response = canonical misuse. CONSOLIDATE owns git-push + CI/CD validation, split off COMPLETE gate so COMPLETE checks only the consolidated result. File paths + verb enumeration: the recall store (`recall: rs-plugkit state-machine internals`).
|
|
80
80
|
|
|
81
81
|
## gm is the canonical universal harness
|
|
82
82
|
|
|
83
|
-
`skills/gm/SKILL.md` = single source of truth; one skill shipped, legacy 15-platform fanout retired. Install: `bun x skills add AnEntrypoint/gm`. Detail:
|
|
83
|
+
`skills/gm/SKILL.md` = single source of truth; one skill shipped, legacy 15-platform fanout retired. Install: `bun x skills add AnEntrypoint/gm`. Detail: the recall store (`recall: legacy gm-skill variants retired`).
|
|
84
84
|
|
|
85
85
|
## Tool surface is plugkit-only
|
|
86
86
|
|
|
@@ -90,13 +90,13 @@ Every skill's `allowed-tools:` reduced to `Skill, Read, Write` (plus SKILL.md bo
|
|
|
90
90
|
|
|
91
91
|
## Core Rules
|
|
92
92
|
|
|
93
|
-
**Memory is human-readable md, tracked; derived stores are transient, never tracked**: canonical memory = `.gm/memories/<key>.md` (project facts) + `.gm/disciplines/<name>/memories/<key>.md` (transferable discipline knowledge), frontmatter `key/ns/created/updated`, UTF-8 no BOM, LF -- text shares cross-machine/session/CI as reviewable diffs.
|
|
93
|
+
**Memory is human-readable md, tracked; derived stores are transient, never tracked**: canonical memory = `.gm/memories/<key>.md` (project facts) + `.gm/disciplines/<name>/memories/<key>.md` (transferable discipline knowledge), frontmatter `key/ns/created/updated`, UTF-8 no BOM, LF -- text shares cross-machine/session/CI as reviewable diffs. The md read path is live (recall serves the md-derived index once a project's corpus digest converges); legacy flat-JSON KV (`.gm/disciplines/<ns>/*.json`) is a frozen fallback + embedding-reuse source, tracked until the flat-write-removal follow-up retires it. Derived state (embeddings/`*-vec`, codeinsight manifests/digests, local sqlite/index dbs) is rebuildable-from-corpus, listed one-by-one between managed gitignore markers (parent-re-include caveat). Entry list + `ensureGitignored` mechanics: the recall store (`recall: gm managed-gitignore mechanics`). Project-local persistent state -> `.gm/<name>/`, never top-level dotfile/dotdir.
|
|
94
94
|
|
|
95
95
|
**Disciplines are isolated knowledge stores**: per-project `<project>/.gm/disciplines/<name>/{memories/, code-search/}`, own corpus+index each; memorize-time routing auto-creates a not-previously-known discipline's store rather than mixing it into project memories. `@<name>` sigil = strict isolation (cross-discipline reads forbidden). Sigil-less reads (recall/codesearch) fan across `default` + every `enabled.txt` line, merge-ranked `[discipline:<name>]`-prefixed; sigil-less writes -> project store only. Tracked, never ignored (`ensureGitignored` excludes `.gm/disciplines`); derived per-discipline caches follow the transient rule above. Harness + every spool verb propagate `@<name>` verbatim.
|
|
96
96
|
|
|
97
97
|
**Nothing fake in source the user runs**: stub/mock/placeholder-return/fixture-only-path/demo-mode-short-circuit/"TODO: implement" forbidden in shipped code. Scaffolds/shims permitted only delegating to real behavior (upstream API, subprocess, disk); check for an existing library before adding a shim. Detection = behavioral: always-succeeds, input-invariant, or type-signature-satisfying short-circuit = stub. Acceptance = real input through real code into real output, witnessed.
|
|
98
98
|
|
|
99
|
-
**Spool dispatch gates**: denials surface reason as imperative instruction, never mutate args. Implementation + marker semantics:
|
|
99
|
+
**Spool dispatch gates**: denials surface reason as imperative instruction, never mutate args. Implementation + marker semantics: the recall store (`recall: spool dispatch gates marker files`).
|
|
100
100
|
|
|
101
101
|
**Done is plugkit's pronouncement, never the agent's claim**: COMPLETE only when `transition to=COMPLETE` returns COMPLETE phase, on-disk state reflects it. COMPLETE gate (gates.rs) = sole arbiter -- refuses on PRD-open, mutables-unresolved, dirty worktree, missing residual-scan marker. Agent drives into gate-allowing state, dispatches, reads response; every alternative is narration.
|
|
102
102
|
|
|
@@ -106,7 +106,7 @@ Every skill's `allowed-tools:` reduced to `Skill, Read, Write` (plus SKILL.md bo
|
|
|
106
106
|
|
|
107
107
|
**Every possible aspect checkable for jank is a PRD row; architecture is pliable**: at PLAN, every prompt-concerned surface -> enumerate every `jank` (immaturity/unfinished-edge/half-wired-path) across gui/ux/ui/client-state/server-state/boundary + reached surfaces, each its own row plus a per-surface profiling row and security row. `jank` = rough/unpolished/almost-done, not just bugs. Scoped to prompt's reachable closure, exhaustive within it. Every found issue spawns its own debug-repair plan same turn; every quick win spooled too. `pliable`: architectural change clearly reducing maintenance burden = spooled plan -- swap bespoke code for native/well-maintained-library ONLY when it nets a SMALLER maintained surface (heavy dep for a few lines = guarded failure mode). Fan-out = spool-native (parallel `prd-add`/`codesearch`/`exec_js`, plugkit task-spawn), never platform Task/Explore. One AI-tell design element (boilerplate flourish, over-hedged comment, generic scaffold name) spawns full-codebase sweep -- scan/per-cluster/fix-verify rows, exhaustive, never one-off.
|
|
108
108
|
|
|
109
|
-
**Client-side debugging exposes globals and evaluates in-browser, never blind-restarts**: live page = the debugger (
|
|
109
|
+
**Client-side debugging exposes globals and evaluates in-browser, never blind-restarts**: live page = the debugger (recall store: `recall: client-side-debug-globals-live-page`).
|
|
110
110
|
|
|
111
111
|
**Mundane user-facing output is suppressed or stripped to the bone**: drop articles/preamble/play-by-play/boot-probe narration/dispatch echoes/restated-prose/status recaps. Survives: real finding, decision+one-line-reason, blocker, single-line PRD-read declaration. Terse = fewer words, NEVER zero tool calls, never silent work -- turn still ends chain-advancing.
|
|
112
112
|
|
|
@@ -122,73 +122,73 @@ Every skill's `allowed-tools:` reduced to `Skill, Read, Write` (plus SKILL.md bo
|
|
|
122
122
|
|
|
123
123
|
**Direct-push to main, never a branch, never a PR**: every gm/rs-* change -> straight `main` commit+push; git verbs (`git_finalize`/`git_push`) already target `main`, cascade ships from `main`. Branch/PR/fork = deviation, no review-gate exists. Sibling repo with open PR: merge to `main`, push, delete branch. Only admissible remote refs: `main`, `gh-pages` -- `git_push {repo, branch:"main"}` for siblings too.
|
|
124
124
|
|
|
125
|
-
**Push requires clean worktree witnessed in its own tool-use event**: `git push` only on empty `git status --porcelain`, probed its OWN Bash event before push (never `&&`-chained). Prefer `git_push`/`git_finalize` (internal gate). Enforcement locations:
|
|
125
|
+
**Push requires clean worktree witnessed in its own tool-use event**: `git push` only on empty `git status --porcelain`, probed its OWN Bash event before push (never `&&`-chained). Prefer `git_push`/`git_finalize` (internal gate). Enforcement locations: the recall store (`recall: push clean worktree enforcement locations`).
|
|
126
126
|
|
|
127
|
-
**AGENTS.md / CLAUDE.md are inline-edited AND dual-written to the store**: inline-edit for structural rules (only doc surviving context summarization), AND `memorize-fire` the same rule for `recall`/`auto_recall` surfacing -- complementary, not either/or. Never `namespace:"AGENTS.md"`; load-bearing rules -> default namespace. Mechanics:
|
|
127
|
+
**AGENTS.md / CLAUDE.md are inline-edited AND dual-written to the store**: inline-edit for structural rules (only doc surviving context summarization), AND `memorize-fire` the same rule for `recall`/`auto_recall` surfacing -- complementary, not either/or. Never `namespace:"AGENTS.md"`; load-bearing rules -> default namespace. Mechanics: the recall store (`recall: memorize-fire ingestion classifier`).
|
|
128
128
|
|
|
129
129
|
**A memorized workaround is a tool defect; transform it, never accumulate it**: using gm != working on gm, so a workaround/known-limitation-framed `recall` memo is tribal knowledge that surprises a fresh user/LLM -- surprises forbidden, everything must be predictable at face value. Resolve: (a) already in standing prose -> prune; (b) prose-worthy, absent -> add then prune; (c) genuinely surprising -> fix code predictable then prune.
|
|
130
130
|
|
|
131
|
-
**Behavioral discipline lives in plugkit's `instruction` verb**: dispatch `instruction` for live phase-specific prose (Three-Layer Admission Filter, maturity-first emit, closure anti-shapes, code invariants); not duplicated here. Enumeration:
|
|
131
|
+
**Behavioral discipline lives in plugkit's `instruction` verb**: dispatch `instruction` for live phase-specific prose (Three-Layer Admission Filter, maturity-first emit, closure anti-shapes, code invariants); not duplicated here. Enumeration: the recall store (`recall: instruction-verb behavioral discipline invariants`).
|
|
132
132
|
|
|
133
|
-
**The agent IS the LLM
|
|
133
|
+
**The agent IS the LLM the recall pipeline calls**: no separate judge model; decisions inline via spool. Internals: the recall store (`recall: rs-learn self-report core internals`).
|
|
134
134
|
|
|
135
|
-
**Idempotency contract (f∘f≡f)**: spool dispatch is at-least-once; correctness rests on per-verb convergence (content-hash dedup, nothing-to-commit gates, digest gates); read-only verbs recompute, never cache. Per-verb enumeration:
|
|
135
|
+
**Idempotency contract (f∘f≡f)**: spool dispatch is at-least-once; correctness rests on per-verb convergence (content-hash dedup, nothing-to-commit gates, digest gates); read-only verbs recompute, never cache. Per-verb enumeration: the recall store (`recall: idempotency contract per-verb convergence`).
|
|
136
136
|
|
|
137
|
-
**host_exec_js is synchronous**: real per-call `timeoutMs` required (zero/missing = hard error). Detail:
|
|
137
|
+
**host_exec_js is synchronous**: real per-call `timeoutMs` required (zero/missing = hard error). Detail: the recall store (`recall: host_exec_js synchronous`).
|
|
138
138
|
|
|
139
|
-
**Sync-before-emit (codeinsight + search)**: output must come from this-invocation freshly-synced index (cache serves only on digest match). Mechanics:
|
|
139
|
+
**Sync-before-emit (codeinsight + search)**: output must come from this-invocation freshly-synced index (cache serves only on digest match). Mechanics: the recall store (`recall: sync-before-emit codeinsight search`).
|
|
140
140
|
|
|
141
|
-
**Auto-recall on turn entry**: `instruction` attaches `auto_recall` pack on first dispatch after >30s idle gap / session-start. Detail:
|
|
141
|
+
**Auto-recall on turn entry**: `instruction` attaches `auto_recall` pack on first dispatch after >30s idle gap / session-start. Detail: the recall store (`recall: auto-recall on turn entry`).
|
|
142
142
|
|
|
143
|
-
**Skill SKILL.md frontmatter `allowed-tools:` is harness-enforced**: must list `Skill` (+`Read`/`Write`, Write only for spool dispatch) or loses downstream-skill invocation that turn. Detail:
|
|
143
|
+
**Skill SKILL.md frontmatter `allowed-tools:` is harness-enforced**: must list `Skill` (+`Read`/`Write`, Write only for spool dispatch) or loses downstream-skill invocation that turn. Detail: the recall store (`recall: SKILL.md frontmatter allowed-tools`).
|
|
144
144
|
|
|
145
|
-
**
|
|
145
|
+
**Recall observability**: pipeline state changes emit `evt:` lines to `.gm/exec-spool/.watcher.log` + gm-log; recall replies carry per-hit scoring fields. Taxonomy: the recall store (`recall: rs-learn observability taxonomy`).
|
|
146
146
|
|
|
147
|
-
**Bootstrap contract**: `ensureReady` inits wasm hook-free, sha256-rewrites stale installed SKILL.md, seeds per-project `CLAUDE.md`/`.gm/next-step.md`. Detail:
|
|
147
|
+
**Bootstrap contract**: `ensureReady` inits wasm hook-free, sha256-rewrites stale installed SKILL.md, seeds per-project `CLAUDE.md`/`.gm/next-step.md`. Detail: the recall store (`recall: skill-initiated bootstrap contract`, `recall: SKILL.md auto-refresh`).
|
|
148
148
|
|
|
149
149
|
## Cascade pipeline
|
|
150
150
|
|
|
151
|
-
Push to any rs-* sibling -> `cascade.yml` -> rs-plugkit `release.yml` -> single `plugkit.wasm` (npm `plugkit-wasm` + `plugkit-bin` Releases) -> auto-bump `gm.json::plugkitVersion` -> `publish.yml` ships gm-skill+gm-plugkit+SKILL.md mirror. Step sequence + PUBLISHER_TOKEN:
|
|
151
|
+
Push to any rs-* sibling -> `cascade.yml` -> rs-plugkit `release.yml` -> single `plugkit.wasm` (npm `plugkit-wasm` + `plugkit-bin` Releases) -> auto-bump `gm.json::plugkitVersion` -> `publish.yml` ships gm-skill+gm-plugkit+SKILL.md mirror. Step sequence + PUBLISHER_TOKEN: the recall store (`recall: cascade pipeline`).
|
|
152
152
|
|
|
153
|
-
**Repos involved (push to any triggers cascade):** `AnEntrypoint/{rs-exec, rs-codeinsight, rs-search, rs-plugkit, rs-learn,
|
|
153
|
+
**Repos involved (push to any triggers cascade):** `AnEntrypoint/{rs-exec, rs-codeinsight, rs-search, rs-plugkit, gm}`. rs-learn is retired (crate removed from rs-plugkit, repo cascade/publish workflows deleted, README points at rs-plugkit). Roles, npm package names, legacy-retirement detail: the recall store (`recall: cascade repos involved roles`, `recall: legacy gm-skill variants retired`).
|
|
154
154
|
|
|
155
155
|
**To update every possible thing**: push to the relevant repo. No manual version bumps, no local `cargo update`/`cargo build` -- push, let CI build.
|
|
156
156
|
|
|
157
157
|
## Spool-dispatch architecture replaces hooks
|
|
158
158
|
|
|
159
|
-
Orchestration state tracked via `.gm/` marker files, not hook events; CLI's `checkDispatchGates()` gates Write/Edit/git pre-execution. Marker set + SpoolDispatcher mechanism:
|
|
159
|
+
Orchestration state tracked via `.gm/` marker files, not hook events; CLI's `checkDispatchGates()` gates Write/Edit/git pre-execution. Marker set + SpoolDispatcher mechanism: the recall store (`recall: gate enforcement layer`, `recall: spool dispatch gates marker files`).
|
|
160
160
|
|
|
161
|
-
**gm tool-use sequencing**: `Skill(skill="gm")` clears needs-gm gate. One shipped skill, no subagent variant. Marker mechanics:
|
|
161
|
+
**gm tool-use sequencing**: `Skill(skill="gm")` clears needs-gm gate. One shipped skill, no subagent variant. Marker mechanics: the recall store (`recall: gm-skill tool-use sequencing mechanics`).
|
|
162
162
|
|
|
163
163
|
**The skill is the driver, not a post-hoc witness**: standing instruction to use gm skill (every `/loop` fire, any `/gm` prompt) -> FIRST action is `Skill(skill="gm")`, skill prose drives PLAN->COMPLETE. Direct spool verbs without entering the skill first = work executed outside the requested driver; end-only entry to confirm terminal state does NOT satisfy the instruction. Boot probe (`cat .gm/exec-spool/.status.json` ...) may precede invocation; every state mutation happens inside the skill-driven session.
|
|
164
164
|
|
|
165
|
-
**Dead-watcher recovery uses `bun x gm-plugkit@latest spool`, never direct-node boot** (mechanism:
|
|
165
|
+
**Dead-watcher recovery uses `bun x gm-plugkit@latest spool`, never direct-node boot** (mechanism: recall store `recall: dead-watcher recovery bun x not direct-node`).
|
|
166
166
|
|
|
167
|
-
**Starting the spool is one atomic blocking call**: `bun x gm-plugkit@latest spool` daemonizes AND blocks until `.status.json` heartbeats fresh (exit 0 only when serving). Cli-side wait mechanics:
|
|
167
|
+
**Starting the spool is one atomic blocking call**: `bun x gm-plugkit@latest spool` daemonizes AND blocks until `.status.json` heartbeats fresh (exit 0 only when serving). Cli-side wait mechanics: the recall store (`recall: atomic spool boot cli-side wait`).
|
|
168
168
|
|
|
169
|
-
**Apparent tooling failure is mechanical self-recovery, NEVER a question for the user and never an a/b-test/blind-restart.** Missing spool response / stale watcher = agent's own job: honor future `busy_until` else boot+re-dispatch -- spooler is sound by construction, asking the user to do what a verb can do is a paper-spirit violation. Recovery mechanics (atomic `.status.json`, `FailedToOpenSocket` retry, debug-via-`window.*`-globals):
|
|
169
|
+
**Apparent tooling failure is mechanical self-recovery, NEVER a question for the user and never an a/b-test/blind-restart.** Missing spool response / stale watcher = agent's own job: honor future `busy_until` else boot+re-dispatch -- spooler is sound by construction, asking the user to do what a verb can do is a paper-spirit violation. Recovery mechanics (atomic `.status.json`, `FailedToOpenSocket` retry, debug-via-`window.*`-globals): the recall store (`recall: spooler self-recovery mechanics`).
|
|
170
170
|
|
|
171
|
-
**Process-of-elimination is the debugging paradigm EVERYWHERE, and manual real-services witness is the verification paradigm EVERYWHERE** -- both stated in `instructions/execute.md` (served EXECUTE prose). Detail:
|
|
171
|
+
**Process-of-elimination is the debugging paradigm EVERYWHERE, and manual real-services witness is the verification paradigm EVERYWHERE** -- both stated in `instructions/execute.md` (served EXECUTE prose). Detail: the recall store (`recall: process-of-elimination manual-real-services-witness paradigm`).
|
|
172
172
|
|
|
173
|
-
**The first verb after a genuine multi-minute IDLE is `instruction`, to reset the long-gap clock**: only spool verbs reset it, so long platform-tool investigation trips false stall -- interleave `instruction`/`prd-add` to stay warm, dispatch `instruction` BEFORE any predictable blocking wait. Threshold + exception:
|
|
173
|
+
**The first verb after a genuine multi-minute IDLE is `instruction`, to reset the long-gap clock**: only spool verbs reset it, so long platform-tool investigation trips false stall -- interleave `instruction`/`prd-add` to stay warm, dispatch `instruction` BEFORE any predictable blocking wait. Threshold + exception: the recall store (`recall: first verb after multi-minute wait instruction long-gap`).
|
|
174
174
|
|
|
175
|
-
**A stop-hook firing on a terminal chain does not authorize re-polling** (`deviation.complete-chain-poll`): prose-only turn or fresh `{"prompt":...}` only. Detail:
|
|
175
|
+
**A stop-hook firing on a terminal chain does not authorize re-polling** (`deviation.complete-chain-poll`): prose-only turn or fresh `{"prompt":...}` only. Detail: the recall store (`recall: complete-chain-poll stop-hook responses`).
|
|
176
176
|
|
|
177
|
-
Session lifecycle (task/browser persistence across turn-stops, residual-scan trigger conditions):
|
|
177
|
+
Session lifecycle (task/browser persistence across turn-stops, residual-scan trigger conditions): the recall store (`recall: session lifecycle killSessionTasks residual-scan`).
|
|
178
178
|
|
|
179
|
-
Browser session state roots at the git common dir, never `process.cwd()` (worktree fan-out shares one chromium, not N):
|
|
179
|
+
Browser session state roots at the git common dir, never `process.cwd()` (worktree fan-out shares one chromium, not N): the recall store (`recall: browser session state worktree common-dir rooting`).
|
|
180
180
|
|
|
181
181
|
**Per-project `.gm/constraints.md` is the standing decision arbiter**: seed-if-absent (bootstrap copies the bundled CS-constraints default only when missing), never overwrite on re-seed -- it is user-editable mutable config, same contract as `.gm/next-step.md`. Every design/code decision the agent makes gauges against it; the pointer rule lives in SKILL.md, this is only the existence/mechanism note. `test.js` witnesses both the seed and the no-clobber idempotency.
|
|
182
182
|
|
|
183
183
|
## Spool observability surface
|
|
184
184
|
|
|
185
|
-
One-shot system-state probe: dispatch `plugkit health` before assuming any component broken; runtime diagnostic files at `.gm/exec-spool/` root readable directly via Read (runtime-data exception). File list + health fields:
|
|
185
|
+
One-shot system-state probe: dispatch `plugkit health` before assuming any component broken; runtime diagnostic files at `.gm/exec-spool/` root readable directly via Read (runtime-data exception). File list + health fields: the recall store (`recall: spool runtime diagnostic files`, `recall: plugkit health verb fields`).
|
|
186
186
|
|
|
187
187
|
## Site Build & Documentation
|
|
188
188
|
|
|
189
|
-
Site build + landing render: single-surface detail, drained to
|
|
189
|
+
Site build + landing render: single-surface detail, drained to the recall store (`recall: gm site build details`).
|
|
190
190
|
|
|
191
|
-
**The site consumes the `anentrypoint-design` SDK pro-rata, never overriding it.** Every visual change lands in the SDK repo, never local CSS; local `<style>` = render-mode plumbing only. Mechanism + repo pointers:
|
|
191
|
+
**The site consumes the `anentrypoint-design` SDK pro-rata, never overriding it.** Every visual change lands in the SDK repo, never local CSS; local `<style>` = render-mode plumbing only. Mechanism + repo pointers: the recall store (`recall: design SDK pro-rata consumption`).
|
|
192
192
|
|
|
193
193
|
|
|
194
194
|
@.gm/next-step.md
|
package/gm-plugkit/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gm-plugkit",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.1795",
|
|
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": {
|
|
@@ -89,6 +89,11 @@ function pidIsPlugkitProcess(pid) {
|
|
|
89
89
|
return /plugkit-wasm-wrapper\.js|plugkit-supervisor\.js|gm-plugkit[\\\/]supervisor\.js/i.test(pidCommandLineForKillGuard(pid));
|
|
90
90
|
}
|
|
91
91
|
|
|
92
|
+
function pidIsManagedChromium(pid) {
|
|
93
|
+
const cmd = pidCommandLineForKillGuard(pid).toLowerCase().replace(/\\/g, '/');
|
|
94
|
+
return cmd.includes('browser-profile') && cmd.includes('--remote-debugging-port');
|
|
95
|
+
}
|
|
96
|
+
|
|
92
97
|
function writeKillAttribution(targetSpoolDir, info) {
|
|
93
98
|
try {
|
|
94
99
|
fs.mkdirSync(targetSpoolDir, { recursive: true });
|
|
@@ -1380,10 +1385,14 @@ function gracefulCloseBrowser(entry, reason) {
|
|
|
1380
1385
|
} catch (_) {}
|
|
1381
1386
|
}
|
|
1382
1387
|
if (Number.isFinite(pid) && pid > 0) {
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1388
|
+
if (isProcessAliveSync(pid) && !pidIsManagedChromium(pid)) {
|
|
1389
|
+
try { logEvent('plugkit', 'browser.kill-skipped-pid-reused', { pid, reason: reason || 'close' }); } catch (_) {}
|
|
1390
|
+
} else {
|
|
1391
|
+
const deadline = Date.now() + 1500;
|
|
1392
|
+
try { process.kill(pid, 'SIGTERM'); } catch (_) {}
|
|
1393
|
+
while (Date.now() < deadline && isProcessAliveSync(pid)) sleepSyncMs(Math.min(150, deadline - Date.now()));
|
|
1394
|
+
if (isProcessAliveSync(pid)) killPidQuiet(pid);
|
|
1395
|
+
}
|
|
1387
1396
|
}
|
|
1388
1397
|
purgeProfileLockFiles(profileDir);
|
|
1389
1398
|
try { logEvent('plugkit', 'browser.closed', { reason: reason || 'closed', pid, port, profileDir }); } catch (_) {}
|
|
@@ -1450,7 +1459,11 @@ function resolveExistingBrowserEntry(cwd, claudeSessionId, pw, portsFile, sessio
|
|
|
1450
1459
|
if (typeof gracefulCloseBrowser === 'function') {
|
|
1451
1460
|
try { gracefulCloseBrowser(existing, `collision:${reason}`); } catch (_) {}
|
|
1452
1461
|
} else if (pidOk && Number.isFinite(existing.pid)) {
|
|
1453
|
-
|
|
1462
|
+
if (pidIsManagedChromium(existing.pid)) {
|
|
1463
|
+
try { killPidQuiet(existing.pid); } catch (_) {}
|
|
1464
|
+
} else {
|
|
1465
|
+
try { logEvent('plugkit', 'browser.kill-skipped-pid-reused', { pid: existing.pid, reason: 'collision' }); } catch (_) {}
|
|
1466
|
+
}
|
|
1454
1467
|
}
|
|
1455
1468
|
purgeProfileLockFiles(existing.profileDir);
|
|
1456
1469
|
delete ports[claudeSessionId];
|
|
@@ -4650,14 +4663,56 @@ async function selfHealFromGithubReleases() {
|
|
|
4650
4663
|
});
|
|
4651
4664
|
}
|
|
4652
4665
|
|
|
4666
|
+
function writeHealBusyStatus() {
|
|
4667
|
+
try {
|
|
4668
|
+
const spoolDir = spoolDirForSentinel();
|
|
4669
|
+
fs.mkdirSync(spoolDir, { recursive: true });
|
|
4670
|
+
fs.writeFileSync(path.join(spoolDir, '.status.json'), JSON.stringify({ pid: process.pid, ts: Date.now(), healing: true, busy_until: Date.now() + 60_000 }));
|
|
4671
|
+
} catch (_) {}
|
|
4672
|
+
}
|
|
4673
|
+
|
|
4674
|
+
function restoreWasmFromLocalCache() {
|
|
4675
|
+
try {
|
|
4676
|
+
const root = path.join(process.env.LOCALAPPDATA || path.join(os.homedir(), '.cache'), 'plugkit', 'bin');
|
|
4677
|
+
const dirs = fs.readdirSync(root).filter(d => /^v\d+\.\d+\.\d+$/.test(d));
|
|
4678
|
+
dirs.sort((a, b) => {
|
|
4679
|
+
const pa = a.slice(1).split('.').map(Number), pb = b.slice(1).split('.').map(Number);
|
|
4680
|
+
return (pb[0] - pa[0]) || (pb[1] - pa[1]) || (pb[2] - pa[2]);
|
|
4681
|
+
});
|
|
4682
|
+
for (const d of dirs) {
|
|
4683
|
+
const wasm = path.join(root, d, 'plugkit.wasm');
|
|
4684
|
+
if (!fs.existsSync(wasm) || !fs.existsSync(path.join(root, d, '.ok'))) continue;
|
|
4685
|
+
const target = path.join(GM_TOOLS_ROOT, 'plugkit.wasm');
|
|
4686
|
+
const tmp = `${target}.partial-${process.pid}`;
|
|
4687
|
+
fs.copyFileSync(wasm, tmp);
|
|
4688
|
+
try { fs.renameSync(tmp, target); }
|
|
4689
|
+
catch (_) { try { fs.unlinkSync(target); } catch (_) {} fs.renameSync(tmp, target); }
|
|
4690
|
+
fs.writeFileSync(path.join(GM_TOOLS_ROOT, 'plugkit.version'), d.slice(1));
|
|
4691
|
+
return d.slice(1);
|
|
4692
|
+
}
|
|
4693
|
+
} catch (_) {}
|
|
4694
|
+
return null;
|
|
4695
|
+
}
|
|
4696
|
+
|
|
4653
4697
|
async function selfHeal(reason) {
|
|
4654
4698
|
console.error(`[plugkit-wasm] self-heal: ${reason}`);
|
|
4699
|
+
writeHealBusyStatus();
|
|
4700
|
+
const healBusy = setInterval(writeHealBusyStatus, 5000);
|
|
4655
4701
|
try {
|
|
4702
|
+
if (/not installed/.test(reason)) {
|
|
4703
|
+
const restored = restoreWasmFromLocalCache();
|
|
4704
|
+
if (restored) {
|
|
4705
|
+
console.error(`[plugkit-wasm] self-heal: restored v${restored} from local install cache`);
|
|
4706
|
+
return true;
|
|
4707
|
+
}
|
|
4708
|
+
}
|
|
4656
4709
|
const r = await selfHealFromGithubReleases();
|
|
4657
4710
|
console.error(`[plugkit-wasm] self-heal: installed v${r.version} from GH Releases`);
|
|
4658
4711
|
return true;
|
|
4659
4712
|
} catch (e) {
|
|
4660
4713
|
console.error(`[plugkit-wasm] self-heal GH fetch failed: ${e.message}`);
|
|
4714
|
+
} finally {
|
|
4715
|
+
clearInterval(healBusy);
|
|
4661
4716
|
}
|
|
4662
4717
|
console.error('[plugkit-wasm] self-heal: run `bun x gm-plugkit@latest spool` to recover manually');
|
|
4663
4718
|
return false;
|
package/gm.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gm-skill",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.1795",
|
|
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",
|