gm-plugkit 2.0.1637 → 2.0.1639
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 +47 -37
- package/bootstrap.js +11 -0
- package/instructions/entry.md +1 -1
- package/package.json +1 -1
- package/plugkit-wasm-wrapper.js +1 -9
package/SKILL.md
CHANGED
|
@@ -6,84 +6,94 @@ allowed-tools: Skill, Read, Write, Bash(bun *), Bash(npx *)
|
|
|
6
6
|
|
|
7
7
|
# gm
|
|
8
8
|
|
|
9
|
-
**
|
|
9
|
+
**No tool call = stop; mid-chain stop = cardinal failure.** Agents read only tool calls + outputs -- prose-only turn ends the session. In-flight (phase != COMPLETE OR prd_pending_count > 0): every turn ends in a chain-advancing dispatch (`instruction`, the named next verb, or `transition`). No summaries, no "here's what I did," no closure narration. A turn-final sentence naming the next move instead of taking it is the same stop -- take the move. Surface decisions via `AskUserQuestion` or `prd-add`, never prose. Stop-urge: dispatch `phase-status`; non-terminal -> `instruction`, keep walking. Only `phase=COMPLETE` AND `prd_pending_count=0` authorizes prose-only.
|
|
10
10
|
|
|
11
|
-
**Done
|
|
11
|
+
**Done = plugkit's word, never yours.** COMPLETE gate is sole arbiter; not-COMPLETE = next transition to seek; idle mid-chain = deviation.
|
|
12
12
|
|
|
13
|
-
**Standing approval
|
|
13
|
+
**Standing approval: finish everything, max granularity.** Every session pre-approved through ALL requested work -- plan, every addition, every discovered/unfinished item. No stop-and-ask, no deferral, no narrowed slice. Plan max-granular (one PRD row per real unit; `every possible` on every noun), walk the whole closure. `blockedBy: external` = authority genuinely unreachable (another team's repo, hardware credential, off-session product call) -- never for merely-large/tedious/multi-component/contended work (rebase, land alongside a concurrent writer).
|
|
14
14
|
|
|
15
|
-
**Every
|
|
15
|
+
**Every action begins and ends with `instruction`.** Doubt, denial, unclear next move: dispatch instruction. Sole recovery primitive; improvising never beats re-reading prose.
|
|
16
16
|
|
|
17
|
-
**You are the state machine.** Plugkit
|
|
17
|
+
**You are the state machine.** Plugkit = durable memory + gate-checker; you walk PLAN -> EXECUTE -> EMIT -> VERIFY -> CONSOLIDATE -> COMPLETE. Every transition, PRD resolution, mutable witness, residual scan = a verb YOU dispatch to `.gm/exec-spool/in/<verb>/<N>.txt`. Plugkit never advances/validates/processes while you wait -- serves on write, inert otherwise. Your phase = last `transition`-ed, not narration-implied. Zero dispatches in gmsniff = hallucinated chain, not walked. Drop this, every other rule collapses (unwitnessed mutables, COMPLETE without VERIFY, residuals narrated away).
|
|
18
18
|
|
|
19
|
-
Every turn:
|
|
19
|
+
Every turn: `instruction`, read, follow imperative, dispatch named verb. Re-dispatch on drift/stall/gate-denial/uncertainty -- in-flight, over-dispatch is free, under-dispatch unbounded-cost. Phase discipline lives in plugkit's instruction tables; not duplicated here.
|
|
20
20
|
|
|
21
|
-
**
|
|
21
|
+
**Every decision gauges against `.gm/constraints.md`.** Read it (seed from bundled default if absent), hold every choice to it, every phase -- durable per-project constraint set this file reinforces, not a one-time read.
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
**`phase=COMPLETE` AND `prd_pending_count=0` = closed, stop dispatching.** Re-polling `instruction`/`phase-status` on a terminal chain = `complete-chain-poll` deviation. A new user prompt (`{"prompt":"..."}`) reopens to PLAN; if first `instruction` on intended-new work still returns COMPLETE/UPDATE-DOCS, dispatch `transition to=PLAN` **once** (authorized new work, not a poll).
|
|
24
24
|
|
|
25
|
-
**
|
|
25
|
+
**Client-side edits gate on Browser Witness (hard rule).** Write/Edit any client file (`.html .js .jsx .ts .tsx .vue .svelte .mjs .css`, or HTML-entry-loaded) -> same turn needs a `browser` verb whose `page.evaluate` asserts the edit's invariant. `transition to=COMPLETE` refuses until `.turn-browser-witnessed` covers every `.turn-browser-edits.json` entry by sha, else `deviation.client-edit-no-witness`. No validate-later.
|
|
26
26
|
|
|
27
|
-
**
|
|
27
|
+
**Live page = the debugger.** Expose state as `window.*`, read live via `browser`'s `page.evaluate`, experiment in-page. Global + one evaluate reads real runtime state in one dispatch; restart-and-eyeball observes near-nothing and burns a turn. Same `browser` surface witnesses and diagnoses.
|
|
28
28
|
|
|
29
|
-
**
|
|
29
|
+
**Search routes through spool, never a platform search agent.** Any code/file/symbol lookup = `codesearch` (`{"query":"..."}`); prior knowledge = `recall`. Never platform Explore, Task/general-purpose search subagent, raw `grep`/`Glob` -- they bypass spool, committed index, recall-grounding, don't transport across harnesses. PLAN-orient = `recall` + `codesearch` parallel; every mid-EXECUTE lookup = `codesearch` too. `codesearch` indexes CURRENT cwd only -- sibling-repo/other-checkout source = `Read`/`exec_js` by path, never expected from `codesearch` (cross-repo query returns nothing by design).
|
|
30
30
|
|
|
31
|
-
**
|
|
31
|
+
**Class rule: platform-native capability with a plugkit verb -> forbidden, use the verb.** search -> `codesearch`; prior knowledge -> `recall`; URL/web -> `fetch`; run code -> `exec_js`; browser -> `browser`; persist memory -> `memorize-fire`; **any git op -> git verbs** (`git_status`/`git_log`/`git_diff`/`git_show`/`git_branch` inspect; `git_add`/`git_commit`/`git_finalize`/`git_push` stage-commit-push; `git_checkout`/`git_fetch`/`git_rm`/`git_revert`/`git_reset` mutate). `git_finalize {message}` bundles add->commit->porcelain-gate->push, one dispatch, CONSOLIDATE's push surface; `bash`/`sh`/`powershell` invoking git = gated (`deviation.bash-git-bypass`). Native tool bypasses ledger, index, portability. No verb exists = missing verb to add, not license to bypass.
|
|
32
|
+
|
|
33
|
+
**Boot before dispatching.** Writing `instruction/N.txt` to a dead watcher silently drops the request; you'd fabricate the chain from memory. Spool dir existing != watcher alive; `.status.json` `ts` within 15s does (stale leftover `.status.json` = common trap). First tool call, every session, the boot probe, one Bash call:
|
|
32
34
|
|
|
33
35
|
```bash
|
|
34
36
|
cat .gm/exec-spool/.status.json 2>/dev/null; echo ---; cat .gm/exec-spool/.turn-summary.json 2>/dev/null; echo ---; date +%s%3N
|
|
35
37
|
```
|
|
36
38
|
|
|
37
|
-
`.turn-summary.json
|
|
39
|
+
`.turn-summary.json`: `phase`, `last_skill`, `prd_pending`, `last_instruction_ts`, `last_instruction_age_ms`, `long_gap_threshold_ms`, `browser_sessions_alive`, `update_available`, `deviations_30m`, `watcher_uptime_ms`. Age over threshold -> next non-orienting verb gated, dispatch `instruction` first. `update_available` non-null: watcher self-updates when idle, usually clears in minutes -- keep working. Force it: re-run idempotent `bun x gm-plugkit@latest spool` (blocks until serving); add `--kill-stale-watchers` only if stuck across several turns. `PLUGKIT_NO_AUTO_UPDATE=1` pins version. `deviations_30m` non-zero = active drift to investigate first.
|
|
38
40
|
|
|
39
|
-
Compare `.status.json` `ts` to
|
|
41
|
+
Compare `.status.json` `ts` to printed epoch: gap > 15000 = dead, boot it. Exception: future `busy_until` = long verb in flight (browser/chromium spawn blocks heartbeat ~15-18s) -- wait, don't boot a second watcher.
|
|
40
42
|
|
|
41
43
|
```bash
|
|
42
44
|
bun x gm-plugkit@latest spool
|
|
43
45
|
```
|
|
44
46
|
|
|
45
|
-
(`npx -y gm-plugkit@latest spool` if `bun
|
|
47
|
+
(`npx -y gm-plugkit@latest spool` if no `bun`.) Atomic: daemonizes watcher, blocks until `.status.json` heartbeats fresh, returns only on serving (exit 0) or loud timeout. No `&`, no `sleep`, no re-`cat` -- returns, you write to `instruction/` directly. (Already-alive watcher returns at once.)
|
|
48
|
+
|
|
49
|
+
**Dispatch shape: Write request + Read response, SAME tool-call block.** `Write .gm/exec-spool/in/instruction/<N>.txt` AND `Read .gm/exec-spool/out/instruction-<N>.json` (or `out/<N>.json` nested) in one block. First-read "file does not exist" mid-verb = normal, re-Read next message. Never proceed/narrate/begin work before reading response and following its `instruction` field. Never poll with `sleep && ls`: plugkit is synchronous -- missing response = dead watcher (recheck `ts`) or slow verb (check `.gm/exec-spool/.watcher.log`), never "still processing."
|
|
50
|
+
|
|
51
|
+
**Dead-watcher recovery is mandatory.** Two consecutive missing re-Reads AND stale `ts` (>15s) AND no future `busy_until` = dead: `bun x gm-plugkit@latest spool` boots fresh, re-dispatch original verb. Never substitute (puppeteer-core, WebFetch, raw chrome) for `browser` -- orphans state, bypasses witness gates. Recovery = notice-dead -> boot -> re-dispatch, always.
|
|
52
|
+
|
|
53
|
+
**Apparent tooling failure is never grounds to ask the user, never a/b-test or blind-restart.** "Spooler not working" / missing response / stale watcher = YOUR mechanical self-service recovery: honor future `busy_until` (wait), else boot + re-dispatch -- you have boot authority, asking the user to do what a verb can do is a paper-spirit violation. Spooler is sound by construction (`.status.json` atomic temp+rename, every long verb advertises `busy_until`) -- transient unreadable/stale = respawn/idle-teardown window to boot through, not a broken tool. Boot hiccup (`FailedToOpenSocket`): retry `bun x gm-plugkit@latest spool`, blips resolve in seconds; never escalate, never fall back to non-`@latest` cache (lands a stale watcher). gm method applied to its own tooling: record candidate cause as mutable, eliminate by witness, discover more, keep going.
|
|
54
|
+
|
|
55
|
+
**Debug live page via globals + process-of-elimination, never guess-and-restart or a/b test.** Surface state as `window.*`, read live via `browser`'s `page.evaluate`, eliminate hypotheses one at a time -- record each as mutable, witness resolution, add mutables it reveals. Record-eliminate-discover is the core loop, browser most of all.
|
|
46
56
|
|
|
47
|
-
**
|
|
57
|
+
**gm profiles/debugs both surfaces -- measure, never eyeball.** Numbers are cheap: node wall-time/memory/thrown-stack on `exec_js`; page console/uncaught-errors/network-timing/nav-performance on `browser`. Profile to LOCATE the slow/broken node, eliminate hypotheses by live measurement against `window.*` globals -- never guess-and-restart. Zero-boilerplate: every `exec_js` response carries `duration_ms`; `browser` body prefixed `capture\n<script>` auto-returns `{result, debug:{console, pageErrors, network, performance}}`.
|
|
48
58
|
|
|
49
|
-
|
|
59
|
+
From PowerShell, write spool input UTF-8 no-BOM (`-Encoding utf8` or `[System.IO.File]::WriteAllText`) -- 5.1 default UTF-16+BOM trips `spool.body-encoding-recoded`. Prefer `Write` tool for JSON bodies. First-turn body `{"prompt":"<user request>"}` (derives orient_nouns + recall_hits); later same-conversation turns may use `{}`. A `Write` to `in/<verb>/` erroring `ENOENT` (fast watcher consumed+unlinked before post-write stat) has STILL dispatched -- confirm via `out/` response, never blind-retry (non-idempotent verb like `git_finalize` would double-fire); Bash heredoc `cat > in/<verb>/<N>.txt` has no post-write stat, never surfaces this.
|
|
50
60
|
|
|
51
|
-
**
|
|
61
|
+
**Batch writes+reads together -- one block is default, serial single-dispatch is drift.** Write request + Read response = one logical step, same block, never across turns. Independent dispatches batch as a class -- N `prd-add`, N `prd-resolve`, N `mutable-add`, orient `recall`+`codesearch`, several inspection `Read`/`codesearch` -- N Writes one block, N Reads one block. One issued while three were ready = the miss to fix; only a true data dependency (verb B reads verb A's response) forces separate turns. Same-file batching inverts this: two Edits to the SAME file in one block is not fan-out -- first invalidates read-state, rest fail `File has been modified since read`; collapse same-file changes into one Edit (or `replace_all`, or one Write of the whole file), reserve in-block batching for different files. Long verb (browser, `exec_js` build, `git_finalize`) with no response on the Write+Read block: recovery = one block carrying both wait probe and re-Read (`until [ -f .gm/exec-spool/out/<verb>-<N>.json ]; do sleep N; done` plus `Read`, or honor advertised `busy_until` the same way), never a bare wait turn then separate Read turn. Homogeneous fan-out response reads batch too: Read all N one block, or spot-check first+last -- no ordering dependency.
|
|
52
62
|
|
|
53
|
-
|
|
63
|
+
Chain isn't COMPLETE until changes are on origin. Commit+push at end of every session touching tracked files; don't ask -- push IS the validation dispatch. Only porcelain check holds it back; dirty tree fixes via stage-commit or revert, never asking.
|
|
54
64
|
|
|
55
|
-
**
|
|
65
|
+
**Test surface = single real-services integration witness, not a unit suite.** One `test.js` at repo root, <=200 lines, real services (mock-free) -- proves a full real session end-to-end, IS the test surface. Growing `test/` of mock-heavy unit files = the conventional-testing tell gm replaces, never a blessed gate beside the witness; `test.js` capped does not exempt a parallel suite. More than the single witness = a re-scope to justify, not default.
|
|
56
66
|
|
|
57
|
-
|
|
67
|
+
**Every residual triaged this turn; "pre-existing" is not a stop excuse.** Non-empty `git status --porcelain`: every entry is yours now -- commit (real work), ignore via managed block (transient runtime emission), or revert (stale junk). "Pre-existing" only names the triage outcome. `blockedBy: external` only when triage needs outside authority. `.gm/disciplines/` and new memorize-fire JSON tracked+committed; `.gm/witness/` and transient staleness markers go in the managed gitignore block.
|
|
58
68
|
|
|
59
|
-
**
|
|
69
|
+
**Apply "every possible" to every noun.** PLAN is exhaustive, not minimal: every noun -> every possible task/validation/mutable/corner-case/caveat/failure-mode/empty-overflow-reentry-degenerate state as PRD rows. Single-digit PRD on non-trivial request = stopped early. Second pass: feed list back, each row's corner cases become new rows; close when "every possible" yields nothing new. Long-horizon prompts routinely produce high-tens-to-hundreds of rows -- density at PLAN is the only protection against silent residuals at COMPLETE. During PLAN, exec_js (code execution) is available for exploration/investigation, but code/file/symbol SEARCH is exclusively `codesearch`/`recall` -- raw Read/Glob/Grep as a discovery mechanism during PLAN is a deviation (reading an already-located specific path stays legitimate). Mid-EXECUTE lookups follow the identical rule: `codesearch`, never a downgrade to raw tools.
|
|
60
70
|
|
|
61
|
-
|
|
71
|
+
**Sweep every possible aspect for jank, each aspect a PRD row.** Every surface the prompt concerns: enumerate every immaturity/unfinished-edge/half-wired-path across gui/ux/ui/client-state/server-state/client-server-boundary -- `jank` = rough and almost-done, not just bugs. Each a row, plus a profiling row and a security row per surface. Scoped to the prompt's reachable closure, exhaustive within it. Every issue found spawns its own debug-and-repair rows same turn. Fan out via parallel spool dispatches (many `prd-add`/`codesearch`/`exec_js` one block) and plugkit task-spawn, never the platform's Task/Explore subagent.
|
|
62
72
|
|
|
63
|
-
**
|
|
73
|
+
**One tell-tale AI design element spawns a full-codebase sweep.** Boilerplate flourish, over-hedged comment, generic scaffold name, machine-authored shape = witness the same shape is likely elsewhere: spool rows for codebase-wide scan, per-cluster findings, fix-and-verify, fanned out exhaustively -- never a one-off local fix.
|
|
64
74
|
|
|
65
|
-
**
|
|
75
|
+
**Graphical symbols forbidden; convert to ASCII on sight.** Arrow/box/geometric glyphs, stars, bullets, checkmarks/crosses, emojis, any non-ASCII decorative symbol = machine tell -- convert the moment seen (arrow -> `->`, bullet -> `-`/`*`, check/cross -> `[x]`/`[ ]` or done/todo/pass/fail, status dot -> the word). One sighting spawns full-codebase sweep. Exempt: code operators (`=>`, `??`, `?.`, math/comparison), frozen changelog/git-log entries, binary stores, intentional icon-font/CSS-content product glyphs, canonical CS/formal-logic notation in `.gm/constraints.md` (semantic operators, not decoration).
|
|
66
76
|
|
|
67
|
-
**
|
|
77
|
+
**Architecture is pliable.** Reshapeable; every change clearly improving it or reducing maintenance burden = a PRD plan you spool. Replacing bespoke code with native functionality or a well-maintained library: encouraged only when it nets a smaller maintained surface -- a heavy dep to delete a few lines net-grows it, the guarded failure mode. Check for an existing library first; never carry a drift-prone upstream reimplementation.
|
|
68
78
|
|
|
69
|
-
**
|
|
79
|
+
**Noticing is a planning event.** Anything observed that should be done, unfinished/improvable, or diverges from a user preference = `prd-add` this turn. Prose-only observations evaporate; only the PRD store survives. "Future work"/"note for later" = drift signatures. Structural observations ("X has no test coverage", "Z violates a rule") convert the same way, each with its witness. Density grows along the walk, not just at PLAN.
|
|
70
80
|
|
|
71
|
-
|
|
81
|
+
`git push` admissible only when `git status --porcelain` is empty, porcelain probe its OWN Bash tool-use event before the push, not `&&`-chained in one call (ccsniff `--git-discipline` scans the tool-call stream, not shell commands within an event). Three Bash events: `git status --porcelain` -> read empty -> `git push`. Prefer `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 CONSOLIDATE/COMPLETE gates refuse a dirty tree or missing residual-check marker.
|
|
72
82
|
|
|
73
|
-
**
|
|
83
|
+
**EXECUTE resolves all mutables before EMIT; discovers more, resolves those too; rearchitects immediately on in-spirit discovery.** Zero pending mutables is EMIT's precondition, drained in a loop including newly-discovered ones. Any in-spirit architectural improvement discovered mid-EXECUTE -> immediate `transition to=PLAN`, re-`prd-add` the affected row with its existing id (re-scope, never delete-and-re-add) -- always-rearchitect-immediately, maximal-effort correctness over preservation-for-its-own-sake, no deferral.
|
|
74
84
|
|
|
75
|
-
**
|
|
85
|
+
**EMIT is file-mutation only.** Precondition: mutables resolved (EXECUTE's job). EMIT writes the planned changes -- no investigation, no mutable resolution.
|
|
76
86
|
|
|
77
|
-
**
|
|
87
|
+
**VERIFY is adversarial: exercise every corner case via real execution.** Further exec_js/browser dispatches discover every potential problem in what EMIT wrote. Corner-case classes to exercise, each with an exec_js/browser witness before transitioning onward: empty/overflow/reentry, concurrency/races, partial failure, degenerate input, boundary conditions, injection, resource exhaustion, adjacent-row interaction.
|
|
78
88
|
|
|
79
|
-
|
|
89
|
+
**CONSOLIDATE is git consolidation + CI/CD validation, the closing phase before COMPLETE.** Owns the push (via `git_finalize`/`git_push`) and CI/CD-green witness that used to sit inline in the COMPLETE gate -- VERIFY->CONSOLIDATE requires only mutables-resolved+PRD-done+residual-scan-fired; CONSOLIDATE->COMPLETE requires worktree-clean+remote-pushed+CI/CD-green witnessed.
|
|
80
90
|
|
|
81
|
-
**Memory is project-resident, never platform-resident.** Refuse the platform's own auto-memory dir (`~/.claude/projects/*/memory/`, `~/.codex/`, `~/.cursor/*`) --
|
|
91
|
+
**Memory is project-resident, never platform-resident.** Refuse the platform's own auto-memory dir (`~/.claude/projects/*/memory/`, `~/.codex/`, `~/.cursor/*`) -- doesn't transport, invisible to gmsniff/recall. Two portable surfaces: (a) `memorize-fire` through spool (embeds `.gm/rs-learn.db`, surfaces via `recall`+auto-recall); (b) `AGENTS.md` for project-tracked hard rules, edited inline. 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. Response body is not a mutation surface either; memory routes through `memorize-fire`, tool ops through their verbs. **Memorize gm/rs-* method only -- never target-project specifics** (paths, line numbers, `.gm/prd.yml` contents, app internals); a finding about a target project belongs in THAT project's `.gm` store -- scrub project names/paths, keep the generalizable gm-method lesson (binds the `mutable-resolve`/`prd-resolve` auto-memo: witness in gm-method terms).
|
|
82
92
|
|
|
83
|
-
**Suppress mundane output; strip
|
|
93
|
+
**Suppress mundane output; strip to the bone.** Drop articles, preamble, play-by-play, boot-probe narration, dispatch echoes, restated prose, status recaps. Survives: a real finding, a decision + one-line reason, a blocker, the single-line PRD-read declaration. Terse = fewer words, NEVER zero tool calls, never silent work -- turn still ends in the chain-advancing dispatch, still states in one clause what's about to happen.
|
|
84
94
|
|
|
85
|
-
**Prune bad memory on sight -- a wrong recall hit is worse than a miss.**
|
|
95
|
+
**Prune bad memory on sight -- a wrong recall hit is worse than a miss.** Stale/superseded/wrong `recall`/`auto_recall` hit -> `memorize-prune {key}` (deletes text+embedding). Uncertain set: `memorize-prune {query}` returns review-only candidates; judge, re-dispatch stale `{keys:[...]}` -- never a blind similarity-delete.
|
|
86
96
|
|
|
87
|
-
|
|
97
|
+
Turn entry: plugkit attaches an `auto_recall` pack from the prompt; read its hits alongside `recall_hits` (phase+PRD-subject pack). Fires once per turn entry on its own -- don't re-trigger.
|
|
88
98
|
|
|
89
|
-
If
|
|
99
|
+
If instructions imply more than one step, use or create a workflow, or track a goal; if subagents are available, fan out subagents that use gm for everything, up to 8 in parallel.
|
package/bootstrap.js
CHANGED
|
@@ -112,6 +112,17 @@ function ensureNextStepWiring(cwd) {
|
|
|
112
112
|
}
|
|
113
113
|
} catch (e) { obsEvent('bootstrap', 'next-step.wiring.target-failed', { target: nextStepPath, error: e.message }); }
|
|
114
114
|
|
|
115
|
+
const constraintsPath = path.join(gmDir, 'constraints.md');
|
|
116
|
+
try {
|
|
117
|
+
if (!fs.existsSync(constraintsPath)) {
|
|
118
|
+
const defaultSrc = path.join(__dirname, 'constraints-default.md');
|
|
119
|
+
if (fs.existsSync(defaultSrc)) {
|
|
120
|
+
fs.writeFileSync(constraintsPath, fs.readFileSync(defaultSrc));
|
|
121
|
+
changes.push('seeded .gm/constraints.md');
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
} catch (e) { obsEvent('bootstrap', 'next-step.wiring.target-failed', { target: constraintsPath, error: e.message }); }
|
|
125
|
+
|
|
115
126
|
const claudeMdPath = path.join(cwd, 'CLAUDE.md');
|
|
116
127
|
try {
|
|
117
128
|
if (!fs.existsSync(claudeMdPath)) {
|
package/instructions/entry.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
YOU are the state machine. Plugkit is the synchronous library serving this prose; advancing the chain is your dispatch, not its action. It holds phase, PRD rows, and mutables on disk -- you read them via `phase-status`/`instruction` and change them via the relevant verb. Nothing advances while you wait.
|
|
4
4
|
|
|
5
|
-
Your authorization = the request. Your receipt = the PRD you write. Trajectory PLAN -> EXECUTE -> EMIT -> VERIFY -> COMPLETE, one continuous flow, each transition a verb you dispatch. Scope = the closure of the destructive transform admissible over the session; your first emit = closure, not prefix.
|
|
5
|
+
Your authorization = the request. Your receipt = the PRD you write. Trajectory PLAN -> EXECUTE -> EMIT -> VERIFY -> CONSOLIDATE -> COMPLETE, one continuous flow, each transition a verb you dispatch. CONSOLIDATE owns git-push + CI/CD validation, split off the COMPLETE gate. Scope = the closure of the destructive transform admissible over the session; your first emit = closure, not prefix.
|
|
6
6
|
|
|
7
7
|
**Continuation invariant (the brick wall).** A turn ending without a tool call is a stop -- the harness reads only tool calls, so a prose-only message ends the session. While in-flight (phase != COMPLETE OR prd_pending > 0) end every turn in a verb dispatch, never prose, never a summary/recap (summary is a stop) -- and never a turn-final sentence that names the next move instead of making it (it strands the chain where the prose pointed; take the move). Only this surface returning phase=COMPLETE AND prd_pending=0 authorizes stopping. Before any urge to stop, dispatch `phase-status`; non-terminal means drift, so dispatch `instruction` and keep walking. Depends only on the verb spool -- holds on every agent. Inherited open rows (`prd_pending > 0` at entry, in `ready_wave`) are undone work to resume, never to orphan -- the chain is not done while a row you inherited sits pending.
|
|
8
8
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gm-plugkit",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.1639",
|
|
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": {
|
package/plugkit-wasm-wrapper.js
CHANGED
|
@@ -1549,16 +1549,10 @@ function decodeWasmResult(instance, result, where) {
|
|
|
1549
1549
|
|
|
1550
1550
|
function writeWasmInput(instance, bytes, where) {
|
|
1551
1551
|
if (bytes.length === 0) return 0;
|
|
1552
|
-
// COERCE the alloc pointer to UNSIGNED 32-bit: a wasm i32 return with the high bit set (a pointer
|
|
1553
|
-
// > 0x7fffffff, which occurs once the linear memory grows past ~2GB in a long session) arrives in JS
|
|
1554
|
-
// as a NEGATIVE number, and new Uint8Array(buffer, negativePtr, len) throws the raw V8 "Start offset
|
|
1555
|
-
// <neg> is outside the bounds of the buffer" -- the deterministic long-session corruption that blocked
|
|
1556
|
-
// dispatches. >>>0 reinterprets the i32 as the true unsigned offset. Guard the range too so a genuinely
|
|
1557
|
-
// bad (ptr,len) raises the clean wasm-memory-read-out-of-bounds error instead of a raw typed-array throw.
|
|
1558
1552
|
const ptr = instance.exports.plugkit_alloc(bytes.length) >>> 0;
|
|
1559
1553
|
if (ptr === 0) throw new Error(`wasm-alloc-failed at ${where}: plugkit_alloc returned 0 (wasm OOM)`);
|
|
1560
1554
|
guardWasmRange(instance.exports.memory.buffer, ptr, bytes.length, `${where}:writeWasmInput`);
|
|
1561
|
-
new Uint8Array(instance.exports.memory.buffer, ptr, bytes.length).set(bytes);
|
|
1555
|
+
new Uint8Array(instance.exports.memory.buffer, ptr, bytes.length).set(bytes);
|
|
1562
1556
|
return ptr;
|
|
1563
1557
|
}
|
|
1564
1558
|
|
|
@@ -1579,8 +1573,6 @@ function readWasmStr(instance, ptr, len) {
|
|
|
1579
1573
|
|
|
1580
1574
|
function writeWasmBytes(instance, bytes) {
|
|
1581
1575
|
if (bytes.length === 0) return 0n;
|
|
1582
|
-
// >>>0: same signed-pointer fix as writeWasmInput -- a high-bit alloc pointer is negative in JS and
|
|
1583
|
-
// throws "Start offset <neg> is outside the bounds" on the Uint8Array write below.
|
|
1584
1576
|
const ptr = instance.exports.plugkit_alloc(bytes.length) >>> 0;
|
|
1585
1577
|
if (ptr === 0) return 0n;
|
|
1586
1578
|
guardWasmRange(instance.exports.memory.buffer, ptr, bytes.length, 'writeWasmBytes');
|