gm-skill 2.0.1483 → 2.0.1485
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 +6 -8
- package/gm-plugkit/package.json +1 -1
- package/gm-plugkit/plugkit-wasm-wrapper.js +23 -3
- package/gm.json +1 -1
- package/package.json +1 -1
package/AGENTS.md
CHANGED
|
@@ -88,7 +88,7 @@ Every possible skill's `allowed-tools:` frontmatter is reduced to `Skill, Read,
|
|
|
88
88
|
|
|
89
89
|
**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.
|
|
90
90
|
|
|
91
|
-
**Spool dispatch gates**: `lib/spool-dispatch.js
|
|
91
|
+
**Spool dispatch gates**: `lib/spool-dispatch.js::checkDispatchGates(sessionId, operation)` reads `.gm/` marker files and returns `{allowed, reason}`; denials surface the reason to the model as imperative instruction, never mutate args. Marker list + per-marker semantics in rs-learn (`recall: spool dispatch gates marker files`).
|
|
92
92
|
|
|
93
93
|
**Done is plugkit's pronouncement, never the agent's claim**: the chain is COMPLETE only when `transition to=COMPLETE` returns COMPLETE phase and plugkit's on-disk state file reflects it. "I think we're done" is not done. "The user seems satisfied" is not done. The COMPLETE gate (gates.rs) is the single arbiter, it refuses on PRD-open, mutables-unresolved, dirty worktree, or missing residual-scan marker. The agent's job is to drive the chain into a state where the gate allows, then dispatch the verb, then read the response. Every possible alternative is narration.
|
|
94
94
|
|
|
@@ -116,11 +116,11 @@ Every possible skill's `allowed-tools:` frontmatter is reduced to `Skill, Read,
|
|
|
116
116
|
|
|
117
117
|
**host_exec_js is synchronous**: pass a real per-call `timeoutMs` (zero/missing is a hard error); long subprocesses block the watcher; no async/background exec under wasm. Mechanism detail in rs-learn (`recall: host_exec_js synchronous`).
|
|
118
118
|
|
|
119
|
-
**Sync-before-emit (codeinsight + search)**:
|
|
119
|
+
**Sync-before-emit (codeinsight + search)**: codeinsight/search output must come from a freshly-synced index this invocation (cache serves only on digest match); unverified-index emit = stale ground truth. Digest/cache mechanics in rs-learn (`recall: sync-before-emit codeinsight search`).
|
|
120
120
|
|
|
121
|
-
**Auto-recall on turn entry**: the `instruction` verb attaches an `auto_recall` pack
|
|
121
|
+
**Auto-recall on turn entry**: the `instruction` verb attaches an `auto_recall` pack to its response on the first dispatch after a >30s idle gap or session-start; orientation comes through that pack, not legacy hooks. Mechanism detail in rs-learn (`recall: auto-recall on turn entry`).
|
|
122
122
|
|
|
123
|
-
**Skill SKILL.md frontmatter `allowed-tools:` is harness-enforced**:
|
|
123
|
+
**Skill SKILL.md frontmatter `allowed-tools:` is harness-enforced**: a skill must list `Skill` (and `Read`/`Write`, Write only for spool dispatch) or it loses downstream-skill invocation that turn. Detail in rs-learn (`recall: SKILL.md frontmatter allowed-tools`).
|
|
124
124
|
|
|
125
125
|
**rs-learn observability**: every learning-pipeline state change emits a structured `evt:{event,sess,ts,...}` line into `.gm/exec-spool/.watcher.log` + gm-log; recall replies carry `mode`/`namespace`/`derived_query`/per-hit `score`; gmsniff/ccsniff expose the taxonomy. Learning quality is observable, not a black box. Full event taxonomy + flag list in rs-learn (`recall: rs-learn observability taxonomy`).
|
|
126
126
|
|
|
@@ -130,7 +130,7 @@ Every possible skill's `allowed-tools:` frontmatter is reduced to `Skill, Read,
|
|
|
130
130
|
|
|
131
131
|
## Cascade pipeline
|
|
132
132
|
|
|
133
|
-
Push to
|
|
133
|
+
Push to any rs-* sibling triggers `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 + the SKILL.md mirror. Full step sequence + PUBLISHER_TOKEN setup in rs-learn (`recall: cascade pipeline`).
|
|
134
134
|
|
|
135
135
|
Three npm packages publish from this repo: `gm-skill` (the skill harness), `gm-plugkit` (bootstrap + watcher), `plugkit-wasm` (wasm binary). publish.yml + the rs-plugkit cascade ships all three on every version-bump commit. The legacy 15 downstream repos (gm-cc, gm-gc, gm-oc, gm-kilo, gm-codex, gm-qwen, gm-copilot-cli, gm-hermes, gm-thebird, gm-vscode, gm-cursor, gm-zed, gm-jetbrains, gm-antigravity, gm-windsurf) are archived on GitHub, no further releases, no orphan-commit publish step.
|
|
136
136
|
|
|
@@ -144,8 +144,6 @@ Three npm packages publish from this repo: `gm-skill` (the skill harness), `gm-p
|
|
|
144
144
|
|
|
145
145
|
**To update every possible thing**: push to the relevant repo. No manual version bumps, no local cargo builds. Never run `cargo update` or `cargo build` locally, push and let CI build.
|
|
146
146
|
|
|
147
|
-
**PUBLISHER_TOKEN required** in `rs-exec`, `rs-codeinsight`, `rs-search` for cascade.yml to trigger rs-plugkit. Set with: `gh secret set PUBLISHER_TOKEN --repo AnEntrypoint/<repo>`.
|
|
148
|
-
|
|
149
147
|
**Timeout enforcement**: every possible `exec_js` dispatch carries a positive `timeoutMs`. The host treats missing or zero as a hard error.
|
|
150
148
|
|
|
151
149
|
## Spool-dispatch architecture replaces hooks
|
|
@@ -154,7 +152,7 @@ Orchestration state is tracked via marker files in `.gm/` instead of hook events
|
|
|
154
152
|
|
|
155
153
|
**Marker files**: `.gm/prd.yml` (existence triggers needs-gm gate), `.gm/mutables.yml` (every possible unresolved entry blocks Write/Edit/git), `.gm/needs-gm` (written by bootstrap, read by dispatcher), `.gm/gm-fired-<sessionId>` (written by gm skill/agent, cleared at turn start), `.gm/residual-check-fired` (ensures one-shot residual-scan per stop window).
|
|
156
154
|
|
|
157
|
-
**Gate enforcement**: CLI layer
|
|
155
|
+
**Gate enforcement**: the CLI layer calls `checkDispatchGates()` before tool execution; marker-driven dispatch replaces the hook event pump entirely. Detail in rs-learn (`recall: gate enforcement layer`).
|
|
158
156
|
|
|
159
157
|
**gm-skill tool-use sequencing**: Invoking `Skill(skill="gm-skill")` writes `.gm/gm-fired-<sessionId>` to clear the needs-gm gate. The marker is cleared at turn start to reset the gate. There is one shipped skill; no subagent variant exists.
|
|
160
158
|
|
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.1485",
|
|
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": {
|
|
@@ -2757,6 +2757,16 @@ async function runSpoolWatcher(instance, spoolDir) {
|
|
|
2757
2757
|
const relPath = path.relative(inDir, filePath);
|
|
2758
2758
|
const dir = path.dirname(relPath);
|
|
2759
2759
|
const verb = dir === '.' ? path.basename(filePath, path.extname(filePath)) : dir;
|
|
2760
|
+
// Defense-in-depth beyond walkDir's dot-dir skip: a real verb is a single clean
|
|
2761
|
+
// segment (e.g. instruction, prd-resolve). A derived verb containing a path
|
|
2762
|
+
// separator or a dot-segment means the file lives under a stray nested spool
|
|
2763
|
+
// (in/prd-resolve/.gm/exec-spool/…); dispatching it builds a bogus verb+outName
|
|
2764
|
+
// and ENOENT-storms every tick. Skip + unmark so it never re-enters the loop.
|
|
2765
|
+
if (/[\\/]/.test(verb) || verb.split(/[\\/]/).some(seg => seg.startsWith('.'))) {
|
|
2766
|
+
try { logEvent('plugkit', 'spool.skip-nested-verb', { rel: relPath, derived_verb: verb }); } catch (_) {}
|
|
2767
|
+
unmarkProcessed(key);
|
|
2768
|
+
return;
|
|
2769
|
+
}
|
|
2760
2770
|
let body = content.trim() || '{}';
|
|
2761
2771
|
const taskBase = path.basename(filePath, path.extname(filePath));
|
|
2762
2772
|
|
|
@@ -2876,18 +2886,24 @@ async function runSpoolWatcher(instance, spoolDir) {
|
|
|
2876
2886
|
}
|
|
2877
2887
|
};
|
|
2878
2888
|
|
|
2879
|
-
function walkDir(dir) {
|
|
2889
|
+
function walkDir(dir, depth = 0) {
|
|
2880
2890
|
const files = [];
|
|
2881
2891
|
try {
|
|
2882
2892
|
for (const entry of fs.readdirSync(dir)) {
|
|
2883
2893
|
if (/\.tmp\.\d+(\.|$)/.test(entry)) continue;
|
|
2894
|
+
// The verb tree is in/<verb>/[<sub>/]<N>.<ext> — at most two levels deep. A
|
|
2895
|
+
// dot-prefixed dir (e.g. a stray nested .gm/exec-spool/ created by a misfire)
|
|
2896
|
+
// is never a verb dir; recursing into it derives a bogus verb like
|
|
2897
|
+
// `prd-resolve\.gm\exec-spool` and dispatch-errors on every tick forever.
|
|
2898
|
+
// Skip dot-dirs and cap depth so a spool-inside-spool cannot wedge the watcher.
|
|
2899
|
+
if (entry.startsWith('.')) continue;
|
|
2884
2900
|
const fullPath = path.join(dir, entry);
|
|
2885
2901
|
let stat;
|
|
2886
2902
|
try { stat = fs.statSync(fullPath); } catch (_) { continue; }
|
|
2887
2903
|
if (stat.isFile()) {
|
|
2888
2904
|
files.push(fullPath);
|
|
2889
|
-
} else if (stat.isDirectory()) {
|
|
2890
|
-
files.push(...walkDir(fullPath));
|
|
2905
|
+
} else if (stat.isDirectory() && depth < 2) {
|
|
2906
|
+
files.push(...walkDir(fullPath, depth + 1));
|
|
2891
2907
|
}
|
|
2892
2908
|
}
|
|
2893
2909
|
} catch (e) {
|
|
@@ -3329,6 +3345,10 @@ async function runSpoolWatcher(instance, spoolDir) {
|
|
|
3329
3345
|
watch(inDir, { recursive: true }, (eventType, filename) => {
|
|
3330
3346
|
if (!filename) return;
|
|
3331
3347
|
if (/\.tmp\.\d+(\.|$)/.test(filename)) return;
|
|
3348
|
+
// Skip any path with a dot-prefixed segment (e.g. a stray nested
|
|
3349
|
+
// prd-resolve/.gm/exec-spool/…): it is not a real verb dispatch and walking it
|
|
3350
|
+
// derives a bogus verb that dispatch-errors on every tick. Matches walkDir's guard.
|
|
3351
|
+
if (filename.split(/[\\/]/).some(seg => seg.startsWith('.'))) return;
|
|
3332
3352
|
const fullPath = path.join(inDir, filename);
|
|
3333
3353
|
markActivity('watch');
|
|
3334
3354
|
|
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.1485",
|
|
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",
|