gm-skill 2.0.1401 → 2.0.1403
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +5 -7
- package/bin/plugkit.version +1 -1
- package/bin/plugkit.wasm.sha256 +1 -1
- package/gm-plugkit/package.json +1 -1
- package/gm-plugkit/plugkit-wasm-wrapper.js +29 -18
- package/gm.json +2 -2
- package/package.json +1 -1
- package/skills/gm-skill/SKILL.md +1 -1
package/AGENTS.md
CHANGED
|
@@ -78,11 +78,9 @@ Every possible skill's `allowed-tools:` frontmatter is reduced to `Skill, Read,
|
|
|
78
78
|
|
|
79
79
|
## Core Rules
|
|
80
80
|
|
|
81
|
-
**Shared memory & search index are tracked, never ignored**: `.gm/rs-learn.db` and `.gm/code-search/` are committed so memory and index state shares across every possible machine, session, and CI run. Tooling, scripts, and every possible agent editing `.gitignore` must NEVER add `.gm/`, `.gm/rs-learn.db`, `.gm/code-search/`, or legacy `.code-search/` to ignore rules. Per the gitignore parent-re-include caveat (re-including a path past an ignored parent dir is impossible), individual `.gm/*` entries (prd-state.json, lastskill, turn-state.json, trajectory-drafts/, ingest-drafts/, rslearn-counter.json) are listed one-by-one between `# >>> gm managed` markers, leaving `.gm/rs-learn.db` and `.gm/code-search/` un-ignored.
|
|
81
|
+
**Shared memory & search index are tracked, never ignored**: `.gm/rs-learn.db` and `.gm/code-search/` are committed so memory and index state shares across every possible machine, session, and CI run. Tooling, scripts, and every possible agent editing `.gitignore` must NEVER add `.gm/`, `.gm/rs-learn.db`, `.gm/code-search/`, or legacy `.code-search/` to ignore rules. Per the gitignore parent-re-include caveat (re-including a path past an ignored parent dir is impossible), individual `.gm/*` entries (prd-state.json, lastskill, turn-state.json, trajectory-drafts/, ingest-drafts/, rslearn-counter.json) are listed one-by-one between `# >>> gm managed` markers, leaving `.gm/rs-learn.db` and `.gm/code-search/` un-ignored. The gm-managed gitignore entries (written by `gm-plugkit/plugkit-wasm-wrapper.js::ensureGitignored(cwd, entry)`) must not include any of those paths. Every possible project-local persistent state (chunk index, DB, embeddings) must write under `.gm/<name>/`, never to a top-level dotfile/dotdir.
|
|
82
82
|
|
|
83
|
-
**Disciplines are isolated knowledge stores**: per-project, at `<project>/.gm/disciplines/<name>/{rs-learn.db, code-search/}`. Every possible discipline owns its own rs-learn DB and code-search index. When a `@<name>` sigil is present in the request, isolation is strict — cross-discipline reads are forbidden. Without a sigil, reads (recall/codesearch) fan across `default` plus every possible enabled discipline (one per line in `<project>/.gm/disciplines/enabled.txt`) and merge-rank results with `[discipline:<name>]` prefixes; writes (memorize/ingest/index) without a sigil go to `default` only. Disciplines are tracked in git, never ignored — `
|
|
84
|
-
|
|
85
|
-
**Clean build required**: `cleanBuildDir()` must delete the entire output dir before regenerating. Skipping causes stale files to silently shadow new ones.
|
|
83
|
+
**Disciplines are isolated knowledge stores**: per-project, at `<project>/.gm/disciplines/<name>/{rs-learn.db, code-search/}`. Every possible discipline owns its own rs-learn DB and code-search index. When a `@<name>` sigil is present in the request, isolation is strict — cross-discipline reads are forbidden. Without a sigil, reads (recall/codesearch) fan across `default` plus every possible enabled discipline (one per line in `<project>/.gm/disciplines/enabled.txt`) and merge-rank results with `[discipline:<name>]` prefixes; writes (memorize/ingest/index) without a sigil go to `default` only. Disciplines are tracked in git, never ignored — `ensureGitignored` and any gm-managed gitignore entry must not list `.gm/disciplines` or any subpath. The gm-skill harness and every possible spool verb propagate the `@<name>` sigil verbatim through their dispatch chain.
|
|
86
84
|
|
|
87
85
|
**Nothing fake in source the user runs**: every possible stub, mock, placeholder return, fixture-only path, demo-mode short-circuit, and "TODO: implement" body is forbidden in shipped code. Scaffolds and shims are permitted only when they delegate to real behavior (real upstream API, real subprocess, real disk). Before adding a shim, check whether a published library or tool already provides that surface — maintaining a local reimplementation of an upstream solution drifts and ages. Detection is behavioral, not by keyword: code that always succeeds, returns the same value regardless of input, or short-circuits a real call to satisfy a type signature is a stub. Acceptance is real input through real code into real output, witnessed; every possible degradation from that leaves the mutable open.
|
|
88
86
|
|
|
@@ -102,7 +100,7 @@ Every possible skill's `allowed-tools:` frontmatter is reduced to `Skill, Read,
|
|
|
102
100
|
|
|
103
101
|
**Push is part of COMPLETE, never optional, never asked**: every possible session that mutates tracked files ends with commit + push to origin. Asking the user "do you want me to push?" is a deviation — the push IS the validation dispatch (`verify.rs`: "The push you make IS the validation dispatch"). The chain is not COMPLETE until the remote reflects HEAD. ccsniff `--git-discipline` and a pending `deviation.complete-without-push` event flag sessions that close without pushing.
|
|
104
102
|
|
|
105
|
-
**Push requires clean worktree witnessed in its own tool-use event**: `git push` is admissible only when `git status --porcelain` returns empty, and the porcelain probe must be its own Bash tool-use event before the push — a separate `Bash(...)` call, not a `&&`-chained shell command within the push event. ccsniff `--git-discipline` scans the last 20 Bash **tool-use events** (not shell commands inside those events) for an explicit porcelain probe; `add && commit && push` in one Bash call counts as one event with no porcelain witness even when the worktree is clean by construction. A push from a dirty tree orphans the unstaged delta and breaks the next session's first read. Enforced in `lib/spool-dispatch.js::
|
|
103
|
+
**Push requires clean worktree witnessed in its own tool-use event**: `git push` is admissible only when `git status --porcelain` returns empty, and the porcelain probe must be its own Bash tool-use event before the push — a separate `Bash(...)` call, not a `&&`-chained shell command within the push event. ccsniff `--git-discipline` scans the last 20 Bash **tool-use events** (not shell commands inside those events) for an explicit porcelain probe; `add && commit && push` in one Bash call counts as one event with no porcelain witness even when the worktree is clean by construction. A push from a dirty tree orphans the unstaged delta and breaks the next session's first read. Enforced in `lib/spool-dispatch.js::checkDispatchGates(sessionId, 'git', {...})` which runs the porcelain probe via `spawnSync('git', ['status', '--porcelain'])` and refuses dirty trees; the rs-plugkit `gates.rs` COMPLETE branch enforces the same invariant for the transition-to-COMPLETE path; instruction prose (`verify.rs`, `update_docs.rs`) restates it imperatively; `residual.rs` skips the scan when dirty so the four-observation window cannot be claimed past an unwitnessed delta. ccsniff `--git-discipline` flags the deviation post-hoc — true positives now that ccsniff 1.1.8+ strips quoted commit-message bodies before regex match.
|
|
106
104
|
|
|
107
105
|
**memorize dispatch manages CLAUDE.md / AGENTS.md**: Do not inline-edit. Dispatch via spool: write `.gm/exec-spool/in/memorize/<N>.txt` with the fact text; the wasm orchestrator embeds and persists it. Classifier rejects changelog-shaped facts from AGENTS.md ingestion (rs-learn store still accepts them).
|
|
108
106
|
|
|
@@ -112,7 +110,7 @@ Every possible skill's `allowed-tools:` frontmatter is reduced to `Skill, Read,
|
|
|
112
110
|
|
|
113
111
|
**Sync-before-emit (codeinsight + search)**: outputs must come from freshly-completed indices. Cache serves only on digest match (mtime sum + git HEAD + dirty-tree marker). Default invocation runs fresh. `--read-cache` permitted only when `.codeinsight.digest` matches; mismatch auto-refreshes. rs-search runs scan + embed + sweep before first result; emits `[index fully synced: …]`. Unverified-index emit = stale ground truth.
|
|
114
112
|
|
|
115
|
-
**Auto-recall on
|
|
113
|
+
**Auto-recall on turn entry**: the `instruction` verb attaches an `auto_recall` pack `{query, hits, fired_at, turn_entry:true}` to its response on the first dispatch after a >30s idle gap or session-start. Query is derived from `.gm/last-prompt.txt` / `.gm/turn-state.json`; hits are the top recall results plugkit pulled before serving the instruction. Wasm-side `wasm_hooks::prompt_submit` exports exist for legacy hook-host integration but the current spool watcher does not invoke them — orientation comes through the instruction verb's response pack instead.
|
|
116
114
|
|
|
117
115
|
**Skill SKILL.md frontmatter `allowed-tools:` is harness-enforced**: If a skill omits `allowed-tools` or does not list `Skill`, the model loses the ability to invoke downstream skills that turn. The shipped surface is a single skill (`gm-skill`); this rule governs every possible future skill that participates in a chain.
|
|
118
116
|
|
|
@@ -164,7 +162,7 @@ Three persistent diagnostic files at `.gm/exec-spool/` root are updated by the r
|
|
|
164
162
|
|
|
165
163
|
**Mermaid integration**: `theme.mjs` (articleClient + landingClient) dynamic-imports mermaid from cdn.jsdelivr.net after `applyDiff` and calls `mermaid.run()` on `.mermaid` blocks. `startOnLoad` must be false—the parse happens before article injection, so `startOnLoad` would miss injected blocks. Theme auto-detects color scheme via `prefers-color-scheme`.
|
|
166
164
|
|
|
167
|
-
**Navigation**: `site/content/globals/navigation.yaml` uses grouped entry format—each item is either `{label, href}` (single link) or `{label, group: [{label, href}, ...]}` (dropdown menu). Dropdowns render via `<details>/<summary>` in `theme.mjs
|
|
165
|
+
**Navigation**: `site/content/globals/navigation.yaml` uses grouped entry format—each item is either `{label, href}` (single link) or `{label, group: [{label, href}, ...]}` (dropdown menu). Dropdowns render via `<details>/<summary>` through the flatspace `C.Topbar` primitive invoked in `site/theme.mjs`; no JS required. In-page topbars in docs/paper*.html et al. render directly on file open and must be kept in sync with the same markup.
|
|
168
166
|
|
|
169
167
|
**Landing page renderer**: the deployed `/` route on https://anentrypoint.github.io/gm/ is rendered by `site/theme.mjs` from `site/content/pages/home.yaml` via flatspace. `site/index.html` + `site/main.js` build `docs/bundle.js` for non-flatspace standalone preview only. Landing edits go through `site/theme.mjs` (Hero) and `site/content/pages/home.yaml` (content), never `site/index.html`.
|
|
170
168
|
|
package/bin/plugkit.version
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.1.
|
|
1
|
+
0.1.553
|
package/bin/plugkit.wasm.sha256
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
c780906b4ca15a51a4a9943fb40759422e42b116af064ada4bc74e0223e41bbc plugkit.wasm
|
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.1403",
|
|
4
4
|
"description": "Bootstrap and daemon-spawn tool for gm plugkit binary. Downloads the correct platform binary, verifies SHA256, and starts the spool watcher daemon. Includes plugkit-wasm-wrapper for WASM-based spool watching.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|
|
@@ -288,29 +288,39 @@ function mergeAutoRecallIntoInstructionResponse(resultStr, autoRecall) {
|
|
|
288
288
|
return JSON.stringify(parsed);
|
|
289
289
|
}
|
|
290
290
|
|
|
291
|
+
function endTurn(sess, t, idleSpanned) {
|
|
292
|
+
logEvent('plugkit', 'turn.end', {
|
|
293
|
+
sess, turn_idx: t.idx, dur_ms: t.lastTs - t.startTs,
|
|
294
|
+
dispatches: t.dispatches, verbs: Object.fromEntries(t.verbs),
|
|
295
|
+
phases_walked: [...t.phases], deviations: t.deviations,
|
|
296
|
+
ended_in_phase: t.lastPhase || null,
|
|
297
|
+
idle_spanned: !!idleSpanned,
|
|
298
|
+
});
|
|
299
|
+
}
|
|
300
|
+
|
|
291
301
|
function turnTick(sess, verb, taskBase, phase) {
|
|
292
302
|
const key = sess || '(no-session)';
|
|
293
303
|
const now = Date.now();
|
|
294
304
|
let t = _turns.get(key);
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
305
|
+
// Any verb arriving after an idle gap closes the stale turn — not just instruction.
|
|
306
|
+
// Otherwise a non-instruction verb (prd-add, mutable-resolve, transition) landing
|
|
307
|
+
// after an overnight sleep stamps t.lastTs forward without splitting, and dur_ms
|
|
308
|
+
// (lastTs - startTs) balloons to wall-clock-with-sleep instead of active work time.
|
|
309
|
+
if (t && (now - t.lastTs) > TURN_IDLE_MS) {
|
|
310
|
+
endTurn(sess, t, true);
|
|
311
|
+
_turns.delete(key);
|
|
312
|
+
t = null;
|
|
313
|
+
}
|
|
314
|
+
if (!t) {
|
|
315
|
+
// Only an instruction dispatch opens a new turn; a stray non-instruction verb after
|
|
316
|
+
// idle is recorded against no turn (the next instruction starts the real turn).
|
|
317
|
+
if (verb !== 'instruction') return;
|
|
318
|
+
const idx = ((_turns.get(key + ':lastIdx') || 0) + 1);
|
|
319
|
+
_turns.set(key + ':lastIdx', idx);
|
|
320
|
+
t = { idx, startTs: now, lastTs: now, dispatches: 0, verbs: new Map(), phases: new Set(), deviations: 0, lastPhase: phase };
|
|
321
|
+
_turns.set(key, t);
|
|
322
|
+
logEvent('plugkit', 'turn.start', { sess, turn_idx: idx, phase: phase || null });
|
|
312
323
|
}
|
|
313
|
-
if (!t) return;
|
|
314
324
|
t.lastTs = now;
|
|
315
325
|
t.dispatches++;
|
|
316
326
|
t.verbs.set(verb, (t.verbs.get(verb) || 0) + 1);
|
|
@@ -824,6 +834,7 @@ function startManagedBrowser(pw, profileDir) {
|
|
|
824
834
|
'--no-first-run',
|
|
825
835
|
'--no-default-browser-check',
|
|
826
836
|
'--disable-default-apps',
|
|
837
|
+
'--disable-gpu-process-crash-limit',
|
|
827
838
|
];
|
|
828
839
|
if (headless) args.push('--headless=new');
|
|
829
840
|
const chromeLogPath = path.join(profileDir, '.chrome-launch.log');
|
package/gm.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gm",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.1403",
|
|
4
4
|
"description": "Spool-dispatch orchestration engine with unified state machine, skills, and automated git enforcement",
|
|
5
5
|
"author": "AnEntrypoint",
|
|
6
6
|
"license": "MIT",
|
|
@@ -17,5 +17,5 @@
|
|
|
17
17
|
"publishConfig": {
|
|
18
18
|
"access": "public"
|
|
19
19
|
},
|
|
20
|
-
"plugkitVersion": "0.1.
|
|
20
|
+
"plugkitVersion": "0.1.553"
|
|
21
21
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gm-skill",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.1403",
|
|
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",
|
package/skills/gm-skill/SKILL.md
CHANGED
|
@@ -60,7 +60,7 @@ The chain is not COMPLETE until your changes are on origin. Commit and push at t
|
|
|
60
60
|
|
|
61
61
|
`git push` is admissible only when `git status --porcelain` reads empty, and the porcelain probe must be its own Bash **tool-use event** before the push — a separate `Bash(...)` invocation, not a `&&`-chained command within one Bash call. ccsniff `--git-discipline` scans the last 20 Bash tool-use events (not shell commands within those events) for an explicit `git status --porcelain` (or `-s`); putting `add && commit && push` into one Bash call counts as one event with no porcelain witness, even though `git push` is technically the third shell command. The witness lives in the tool-call stream, not the shell stream. The discipline is **three Bash tool-use events** visible in the transcript: `Bash(git status --porcelain)` → read empty → `Bash(git push)`. You dispatch the `git_push` verb (not raw Bash) when possible — it gates on the porcelain probe internally, refuses dirty, and emits `deviation.push-dirty`. A raw `git push` Bash event without a preceding porcelain-probe Bash event is itself a deviation, regardless of how clean the worktree is by construction. Witness clean via `git_status`; witness pushed-to-remote via `branch_status` (ahead==0). The residual-scan and COMPLETE gate both refuse a dirty tree or a missing residual-check marker.
|
|
62
62
|
|
|
63
|
-
**Memory is project-resident, never platform-resident.** The agent platform may advertise its own auto-memory directory (`~/.claude/projects/*/memory/`, `~/.codex/memory/`, `~/.cursor/*`, etc.) and prompt you to write facts there. **Refuse**. Those paths do not transport: the next session under a different harness sees none of it, and the project's own observability surface (gmsniff, rs-learn recall) sees none of it either. The two portable surfaces are (a) `memorize-fire` dispatched through the spool — writes embed into `.gm/rs-learn.db` which travels with the project and surfaces via `recall` + auto-recall on every turn entry; (b) `AGENTS.md` for project-tracked rules,
|
|
63
|
+
**Memory is project-resident, never platform-resident.** The agent platform may advertise its own auto-memory directory (`~/.claude/projects/*/memory/`, `~/.codex/memory/`, `~/.cursor/*`, etc.) and prompt you to write facts there. **Refuse**. Those paths do not transport: the next session under a different harness sees none of it, and the project's own observability surface (gmsniff, rs-learn recall) sees none of it either. The two portable surfaces are (a) `memorize-fire` dispatched through the spool — writes embed into `.gm/rs-learn.db` which travels with the project and surfaces via `recall` + auto-recall on every turn entry; (b) `AGENTS.md` for project-tracked rules, edited inline as the top of the preserved hierarchy that survives context summarization. memorize-fire and inline-AGENTS.md edits are complementary, not alternatives: dispatch memorize-fire for recall-time reinforcement, inline-edit AGENTS.md for the hard rule. If you find yourself about to `Write` into a path under `~/.claude/`, `~/.codex/`, `~/.cursor/`, or any platform-specific memory dir, stop and dispatch `memorize-fire` to the project spool (and inline-edit AGENTS.md if the fact is structural). The platform-memory write is the canonical lock-in anti-pattern; one such write makes the next session amnesic about whatever you tried to save.
|
|
64
64
|
|
|
65
65
|
Response body is not a mutation surface either. Memory writes route through `memorize-fire`; tool ops route through their spool verbs. Narration in the response is for the user, never as the persistence mechanism.
|
|
66
66
|
|