gm-skill 2.0.2575 → 2.0.2576
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 +1 -1
- package/gm-plugkit/package.json +1 -1
- package/gm.json +1 -1
- package/package.json +1 -1
- package/scripts/scan-supply-chain-tells.mjs +30 -9
package/AGENTS.md
CHANGED
|
@@ -47,7 +47,7 @@ Wasm host-import link-module rule (`#[link(wasm_import_module="env")]` on every
|
|
|
47
47
|
Dispatch = Write `.gm/exec-spool/in/<verb>/<N>.txt`, Read `.gm/exec-spool/out/<verb>-<N>.json` (nested) or `out/<N>.json` (root). `<N>` is session-id-prefixed (`<session_id>-<local-counter>`), never a bare small integer -- the shared daemon claims and answers in-files by the literal `(verb, N)` pair with no per-session partition, so unprefixed sequential ids collide across concurrent sessions on the same project (recall: `gm spool dispatch id collision cross-session crosstalk`). Wasm orchestrator services every verb; harness never executes side effects directly.
|
|
48
48
|
|
|
49
49
|
- **Orchestrator verbs**: `instruction`, `transition`, `phase-status`, `mutable-resolve`, `mutable-add`, `mutable-list`, `memorize-fire`, `memorize-continue`, `discipline-note`, `residual-scan`, `auto-recall`, `prd-add`, `prd-resolve`, `prd-list`, `task-spawn`, `task-list`, `task-stop`, `task-output`, `fsm-vendor`, `fsm-validate`, `fsm-propose-override`, `claim-audit`, `submodule-check`.
|
|
50
|
-
- **`fsm-propose-override`**: session-authored `.gm/instructions` override, gated two-phase (`{proposed:true,requires_confirmation:true}` first, real write only on a second dispatch carrying `user_confirmed:true`). `kind:"graph"` additionally requires `confirmation_witness` citing an `AskUserQuestion` dispatch -- graph overrides grant execution authority (hooks) per Section 4. Body: `{kind:"prose"|"graph"|"config", key, proposed_text, reason, witness}`. Validates the proposed graph/config before ever proposing it; a `stuck-loop-escalation` gate denial also emits `self-reconfig-candidate` as the machine-readable trigger for when a proposal is worth authoring.
|
|
50
|
+
- **`fsm-propose-override`**: session-authored `.gm/instructions` override, gated two-phase (`{proposed:true,requires_confirmation:true}` first, real write only on a second dispatch carrying `user_confirmed:true`). `kind:"graph"` additionally requires `confirmation_witness` citing an `AskUserQuestion` dispatch -- graph overrides grant execution authority (hooks) per Section 4. Body: `{kind:"prose"|"graph"|"config", key, proposed_text, reason, witness}`. Validates the proposed graph/config before ever proposing it; a `stuck-loop-escalation` gate denial also emits `self-reconfig-candidate` as the machine-readable trigger for when a proposal is worth authoring. Its `kind:"prose"` content-shape rule (attributed anchors, mermaid backreference graphs, no external catalog citation) is served content, not local doc -- it lives in `gm-config/prose/entry.md` (every project reaches it), never here alone.
|
|
51
51
|
- **Wasm-direct verbs**: fs/kv/exec/fetch/env, recall, codesearch, memorize, memorize-prune, memorize-vacuum, memorize-retention, health, filter, full git verb family. Enumeration in the recall store (`recall: wasm-direct plugkit verbs full list`).
|
|
52
52
|
- **Host-native verb**: `background-convert` (`{verb, task}`) detaches an already-in-flight dispatch so the daemon worker stops waiting on it -- agent-initiated only, never routed to gm.wasm. Detail: `.gm/daemon-config-reference.md`.
|
|
53
53
|
- **memorize-prune**: prune bad/superseded memories; two-mode spec (key-remove vs query-review) in the recall store (`recall: memorize-prune verb two-mode spec`). **memorize-vacuum**/**memorize-retention**: compaction and retention-policy enforcement over the same memory store; both also accept underscore-form aliases (`memorize_vacuum`/`memorize_retention`), matching every `memorize-*` verb's hyphen/underscore dual registration.
|
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.2576",
|
|
4
4
|
"description": "Bootstrap and daemon-spawn tool for gm plugkit binary. Downloads the correct platform wasm, verifies SHA256, and launches agentplug-runner (the native wasm host) as the spool watcher daemon.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|
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.2576",
|
|
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",
|
|
@@ -125,6 +125,13 @@ const SUSPICIOUS_UNICODE = [
|
|
|
125
125
|
{ cp: 0x0421, name: 'CYRILLIC CAPITAL С (looks like Latin C)' },
|
|
126
126
|
{ cp: 0x0441, name: 'CYRILLIC SMALL с (looks like Latin c)' },
|
|
127
127
|
]
|
|
128
|
+
const SUSPICIOUS_UNICODE_MAP = new Map(SUSPICIOUS_UNICODE.map(u => [u.cp, u.name]))
|
|
129
|
+
// Single regex alternation, scanned natively by the engine in one pass --
|
|
130
|
+
// the previous per-character for-loop with an inner .find() was O(n) work
|
|
131
|
+
// PER CHARACTER (n = codepoint list length) and made a multi-MB minified
|
|
132
|
+
// bundle file (a real case: a 3.3MB single-line webpack chunk) take minutes
|
|
133
|
+
// instead of milliseconds.
|
|
134
|
+
const SUSPICIOUS_UNICODE_RE = new RegExp('[' + SUSPICIOUS_UNICODE.map(u => '\\u' + u.cp.toString(16).padStart(4, '0')).join('') + ']', 'g')
|
|
128
135
|
|
|
129
136
|
// A file whose non-ASCII payload is almost entirely \uXXXX-style JS escape
|
|
130
137
|
// sequences decoding to plain ASCII is itself a tell (deliberate obfuscation
|
|
@@ -205,25 +212,39 @@ function scanFile(filePath) {
|
|
|
205
212
|
}
|
|
206
213
|
|
|
207
214
|
if (CODE_EXT.has(path.extname(filePath))) {
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
215
|
+
const matches = text.match(SUSPICIOUS_UNICODE_RE)
|
|
216
|
+
if (matches && matches.length) {
|
|
217
|
+
// Line numbers computed via one pass over newline offsets (not a fresh
|
|
218
|
+
// split() per hit) -- still correct even on a huge single-line file,
|
|
219
|
+
// just no longer quadratic.
|
|
220
|
+
let newlineOffsets = null
|
|
221
|
+
const lineOf = (idx) => {
|
|
222
|
+
if (!newlineOffsets) {
|
|
223
|
+
newlineOffsets = []
|
|
224
|
+
for (let i = 0; i < text.length; i++) if (text.charCodeAt(i) === 10) newlineOffsets.push(i)
|
|
225
|
+
}
|
|
226
|
+
let lo = 0, hi = newlineOffsets.length
|
|
227
|
+
while (lo < hi) { const mid = (lo + hi) >> 1; if (newlineOffsets[mid] < idx) lo = mid + 1; else hi = mid }
|
|
228
|
+
return lo + 1
|
|
229
|
+
}
|
|
230
|
+
const seen = new Set()
|
|
231
|
+
SUSPICIOUS_UNICODE_RE.lastIndex = 0
|
|
232
|
+
let m
|
|
233
|
+
while ((m = SUSPICIOUS_UNICODE_RE.exec(text)) !== null) {
|
|
234
|
+
const cp = m[0].codePointAt(0)
|
|
235
|
+
const line = lineOf(m.index)
|
|
216
236
|
const key = cp + ':' + line
|
|
217
237
|
if (seen.has(key)) continue
|
|
218
238
|
seen.add(key)
|
|
219
239
|
findings.push({
|
|
220
240
|
filePath,
|
|
221
241
|
kind: 'unicode',
|
|
222
|
-
name:
|
|
242
|
+
name: SUSPICIOUS_UNICODE_MAP.get(cp),
|
|
223
243
|
codepoint: '0x' + cp.toString(16),
|
|
224
244
|
line,
|
|
225
245
|
why: 'invisible or confusable Unicode codepoint inside a code file — used to hide code from visual review or disguise an identifier/URL as something else',
|
|
226
246
|
})
|
|
247
|
+
if (SUSPICIOUS_UNICODE_RE.lastIndex === m.index) SUSPICIOUS_UNICODE_RE.lastIndex++
|
|
227
248
|
}
|
|
228
249
|
}
|
|
229
250
|
}
|