@techgoblin/gobstack 0.6.0-alpha.2 → 0.6.0-alpha.4
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/README.md +15 -4
- package/VERSION +1 -1
- package/bin/goblin-audit +1 -1
- package/bin/goblin-bans +1 -1
- package/bin/goblin-extras +37 -14
- package/bin/goblin-init +50 -1
- package/bin/goblin-install +29 -8
- package/bin/goblin-lib.sh +17 -11
- package/bin/goblin-map +18 -10
- package/bin/goblin-mcp.js +28 -2
- package/bin/goblin-upgrade +1 -1
- package/bin/goblin-verify +6 -6
- package/docs/CONTRACTS.md +6 -3
- package/docs/ENFORCEMENT.md +1 -1
- package/docs/GUIDE.md +10 -5
- package/extras-catalogue/catalogue.tsv +42 -42
- package/manifest/enforcement.tsv +1 -1
- package/package.json +1 -1
- package/skills/goblin-bootstrap/SKILL.md +1 -1
package/README.md
CHANGED
|
@@ -87,7 +87,7 @@ is unwired in this alpha: the shim refuses the verb by name and prints the usage
|
|
|
87
87
|
| `gob bans` | run the ban list (per-pattern red lines over the source tree) |
|
|
88
88
|
| `gob extras` | the curated extras catalogue: `list [category]` / `show <id>` / `install <id...> [-target <dir>] [--platform <id>] [--with-mcp-config]` — init only SUGGESTS; installs come from the catalogue (the allowlist rule), never the web |
|
|
89
89
|
| `gob mcp` | serve the harness to your coding agent over MCP stdio — three tools (`gob_verify`, `gob_map_status`, `gob_init_status`), local only, no SDK, no network |
|
|
90
|
-
| `gob uninstall` | remove everything an install wrote, byte-exactly (`
|
|
90
|
+
| `gob uninstall` | remove everything an install wrote, byte-exactly (the same job as `goblin-install --target <dir> --uninstall` from the checkout/install tree) |
|
|
91
91
|
|
|
92
92
|
`goblin` remains as a legacy alias for every command above — existing scripts keep working, but
|
|
93
93
|
new commands and docs use `gob`.
|
|
@@ -146,6 +146,14 @@ The verdict decides what each row can do: `RECOMMEND` rows are pre-ticked when `
|
|
|
146
146
|
suggests, `MAYBE` rows are listed but never pre-ticked, and a `SKIP` row refuses install —
|
|
147
147
|
it stays visible so the curation history is readable, but the curator declined it.
|
|
148
148
|
|
|
149
|
+
**The license gate is hard.** A verdict alone never installs anything: every row carries a
|
|
150
|
+
`license_status` (verified | pending | proprietary-confirmed-ok) and the date it was checked.
|
|
151
|
+
Only `verified` installs. A row whose license is not yet resolved carries verdict
|
|
152
|
+
`LICENSE-PENDING` — it is never pre-ticked at init, and `gob extras install` refuses it with
|
|
153
|
+
`license pending verification` until a curator verifies the license and flips the row's data
|
|
154
|
+
in `catalogue.tsv`. The gate reads the data, not the code: flipping a row installable is a
|
|
155
|
+
catalogue edit (a new `license_status` + `license_check_date`), never an engine change.
|
|
156
|
+
|
|
149
157
|
**The catalogue is the allowlist.** An id that is not a row in `catalogue.tsv` is refused by
|
|
150
158
|
name; nothing is ever installed from a URL, a repo name, or a web search. Installs are
|
|
151
159
|
offline by contract: skill and workflow rows copy from the vendored payload the curator
|
|
@@ -246,14 +254,17 @@ capability.
|
|
|
246
254
|
|
|
247
255
|
gob uninstall --target .
|
|
248
256
|
|
|
249
|
-
(
|
|
257
|
+
(the same job as `goblin-install --target . --uninstall` — through the legacy alias, spell it `goblin`
|
|
250
258
|
instead of `gob`). The uninstall is **byte-exact**: it removes exactly the files
|
|
251
259
|
`installed.json` records — hash-compared preimages, so a file you edited after install is
|
|
252
260
|
reported and kept, never clobbered — then every directory that leaves empty, and it strips the
|
|
253
261
|
`<!-- gob:begin --> … <!-- gob:end -->` block out of `AGENTS.md` (the body prose stays). After
|
|
254
262
|
it, the repo has zero harness files; only the project's own record (`HANDOFF.md`, `AGENTS.md`'s
|
|
255
263
|
prose, `reviews/`, the `.gitignore` block) survives, because that is the project's, not the
|
|
256
|
-
harness's to delete.
|
|
264
|
+
harness's to delete. Two residues are left **by design, and named in the output**: the
|
|
265
|
+
`.gitignore` ignore-rules block stays (removing it could eat a line the project added inside
|
|
266
|
+
it — delete that block by hand if you want it gone), and prose that named `.gob/` paths
|
|
267
|
+
(HANDOFF, the AGENTS.md body, SPECs) now points at removed files. And because the engine is vendored, the repo needs no gobstack installed to
|
|
257
268
|
run this — it is self-contained until the moment you remove it.
|
|
258
269
|
|
|
259
270
|
The short version, for a full removal from a machine and its repos: (b) in each initialized
|
|
@@ -261,7 +272,7 @@ repo, then (a).
|
|
|
261
272
|
|
|
262
273
|
## Re-pin the referenced standard
|
|
263
274
|
|
|
264
|
-
|
|
275
|
+
goblin-install --target <dir> --re-pin # from the gobstack checkout / install tree
|
|
265
276
|
|
|
266
277
|
`practice_sha256:` in the AGENTS.md gob block pins the referenced standard and `IN-02`
|
|
267
278
|
re-checks it, so editing that standard — a legitimate, intended edit — reds `IN-02` in every
|
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.6.0-alpha.
|
|
1
|
+
0.6.0-alpha.4
|
package/bin/goblin-audit
CHANGED
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
# because an empty record reads to SC-07 as "clean" and that would be a fabricated pass
|
|
24
24
|
set -uo pipefail
|
|
25
25
|
|
|
26
|
-
GOBLIN_AUDIT_VERSION="0.6.0-alpha.
|
|
26
|
+
GOBLIN_AUDIT_VERSION="0.6.0-alpha.4"
|
|
27
27
|
|
|
28
28
|
usage() { sed -n '2,/^$/p' "${BASH_SOURCE[0]}" | sed 's/^# \{0,1\}//'; }
|
|
29
29
|
|
package/bin/goblin-bans
CHANGED
package/bin/goblin-extras
CHANGED
|
@@ -14,6 +14,11 @@
|
|
|
14
14
|
#
|
|
15
15
|
# Verdicts: RECOMMEND rows install; MAYBE rows install (an explicit choice, never
|
|
16
16
|
# pre-ticked at init); SKIP rows refuse — the curator's verdict is the contract.
|
|
17
|
+
# THE LICENSE GATE (W-license, hard): verdict RECOMMEND|MAYBE alone is not enough —
|
|
18
|
+
# a row installs only when its catalogue license_status is `verified`. Rows with an
|
|
19
|
+
# unresolved license carry verdict LICENSE-PENDING (never pre-ticked at init) and
|
|
20
|
+
# refuse install with `license pending verification` until the curator flips the
|
|
21
|
+
# DATA (license_status + license_check_date), never this file.
|
|
17
22
|
#
|
|
18
23
|
# NO NETWORK. Skill and workflow installs copy from a VENDORED PAYLOAD the curator
|
|
19
24
|
# maintains under extras-catalogue/payload/<id>/ (payload/README.md is the layout
|
|
@@ -49,7 +54,7 @@ usage() { sed -n '2,/^$/p' "${BASH_SOURCE[0]}" | sed 's/^# \{0,1\}//'; }
|
|
|
49
54
|
CATALOGUE="${GOB_EXTRAS_CATALOGUE:-$SRC/extras-catalogue/catalogue.tsv}"
|
|
50
55
|
PAYLOAD="${GOB_EXTRAS_PAYLOAD:-$SRC/extras-catalogue/payload}"
|
|
51
56
|
|
|
52
|
-
die() { g_err "extras:
|
|
57
|
+
die() { local msg="$1"; shift; g_err "extras: $msg"; exit "${1:-2}"; }
|
|
53
58
|
|
|
54
59
|
# catalogue_row <id> — the whole data row (tab-separated), empty when absent.
|
|
55
60
|
catalogue_row() {
|
|
@@ -100,15 +105,15 @@ cmd_list() {
|
|
|
100
105
|
fi
|
|
101
106
|
local total
|
|
102
107
|
total=$(catalogue_ids | wc -l | tr -d ' ')
|
|
103
|
-
g_info "gob extras — the curated catalogue ($total rows; RECOMMEND pre-ticks at init, MAYBE is visible but never pre-ticked, SKIP refuses install)"
|
|
108
|
+
g_info "gob extras — the curated catalogue ($total rows; RECOMMEND pre-ticks at init, MAYBE is visible but never pre-ticked, SKIP refuses install; LICENSE-PENDING rows refuse install until their license is verified)"
|
|
104
109
|
g_info "install: gob extras install <id...> · one row: gob extras show <id>"
|
|
105
110
|
local cat
|
|
106
111
|
for cat in $(category_order); do
|
|
107
112
|
[ -z "$want" ] || [ "$cat" = "$want" ] || continue
|
|
108
113
|
printf '\n[%s]\n' "$cat"
|
|
109
|
-
printf ' %-34s %-8s %-7s %-24s %-10s %s\n' "id" "kind" "stars" "license" "verdict" "matches"
|
|
114
|
+
printf ' %-34s %-8s %-7s %-24s %-10s %-16s %s\n' "id" "kind" "stars" "license" "verdict" "lic-status" "matches"
|
|
110
115
|
awk -F'\t' -v cat="$cat" 'NR>1 && $2==cat {
|
|
111
|
-
printf " %-34s %-8s %-7s %-24s %-10s %s\n", $1, $3, $9, $8, $15, $11
|
|
116
|
+
printf " %-34s %-8s %-7s %-24s %-10s %-16s %s\n", $1, $3, $9, $8, $15, $18, $11
|
|
112
117
|
}' "$CATALOGUE"
|
|
113
118
|
done
|
|
114
119
|
return 0
|
|
@@ -124,10 +129,10 @@ cmd_show() {
|
|
|
124
129
|
[ -n "$row" ] || die "unknown id '$id' — gob extras list names the catalogue" 2
|
|
125
130
|
local labels=(id category kind name source_repo path_within_repo has_skill_md license
|
|
126
131
|
stars last_push matches conflicts requires install_hint verdict
|
|
127
|
-
reviewed_by reviewed_date)
|
|
132
|
+
reviewed_by reviewed_date license_status license_check_date)
|
|
128
133
|
local i
|
|
129
|
-
for i in $(seq 1
|
|
130
|
-
printf '%-
|
|
134
|
+
for i in $(seq 1 19); do
|
|
135
|
+
printf '%-18s %s\n' "${labels[$((i-1))]}:" "$(catalogue_field "$row" "$i")"
|
|
131
136
|
done
|
|
132
137
|
return 0
|
|
133
138
|
}
|
|
@@ -162,22 +167,35 @@ parse_install() {
|
|
|
162
167
|
fi
|
|
163
168
|
}
|
|
164
169
|
|
|
165
|
-
# resolve_one <id> — validates against the ALLOWLIST
|
|
166
|
-
# the row. Every install path goes through here: no row, no
|
|
167
|
-
# allowlist rule
|
|
170
|
+
# resolve_one <id> — validates against the ALLOWLIST, the curator's verdicts and the
|
|
171
|
+
# LICENSE GATE; prints the row. Every install path goes through here: no row, no
|
|
172
|
+
# install; no verified license, no install. That is the whole allowlist rule plus the
|
|
173
|
+
# hard gate, in one gate.
|
|
168
174
|
resolve_one() {
|
|
169
|
-
local id="$1" row verdict
|
|
175
|
+
local id="$1" row verdict lic
|
|
170
176
|
row=$(catalogue_row "$id")
|
|
171
177
|
# Captured, not piped (pipefail + grep -q early-exit trap — see cmd_list).
|
|
172
178
|
if [ -n "$row" ]; then
|
|
173
179
|
verdict=$(catalogue_field "$row" 15)
|
|
180
|
+
lic=$(catalogue_field "$row" 18)
|
|
174
181
|
else
|
|
175
182
|
die "unknown id '$id' — nothing outside catalogue.tsv is ever installed (gob extras list names the allowlist)" 2
|
|
176
183
|
fi
|
|
177
184
|
case "$verdict" in
|
|
178
|
-
RECOMMEND|MAYBE) ;;
|
|
185
|
+
RECOMMEND|MAYBE|LICENSE-PENDING) ;;
|
|
179
186
|
SKIP) die "id '$id' carries verdict SKIP — the curator declined it; it stays visible in the catalogue but refuses install" 1 ;;
|
|
180
|
-
*) die "id '$id' carries verdict '$verdict' — not an installable verdict (RECOMMEND|MAYBE|SKIP)" 2 ;;
|
|
187
|
+
*) die "id '$id' carries verdict '$verdict' — not an installable verdict (RECOMMEND|MAYBE|SKIP|LICENSE-PENDING)" 2 ;;
|
|
188
|
+
esac
|
|
189
|
+
# THE LICENSE GATE (hard, data-driven): a row whose catalogue says its license is
|
|
190
|
+
# not verified never installs — the verdict alone is not consulted. A curator flips
|
|
191
|
+
# a row to installable by fixing the data (license_status=verified + a check date),
|
|
192
|
+
# never by touching this file.
|
|
193
|
+
case "$lic" in
|
|
194
|
+
verified) ;;
|
|
195
|
+
pending|proprietary-confirmed-ok|"")
|
|
196
|
+
die "id '$id' refuses install: license pending verification — see catalogue.tsv license_check_date" 1 ;;
|
|
197
|
+
*)
|
|
198
|
+
die "id '$id' carries license_status '$lic' — not a known status (verified|pending|proprietary-confirmed-ok)" 2 ;;
|
|
181
199
|
esac
|
|
182
200
|
printf '%s\n' "$row"
|
|
183
201
|
}
|
|
@@ -232,7 +250,12 @@ install_skill() {
|
|
|
232
250
|
[ -d "$d" ] || continue
|
|
233
251
|
name=$(basename "$d")
|
|
234
252
|
n=$((n + 1))
|
|
235
|
-
|
|
253
|
+
# QA fix (v2-qa issue 9): the display path must carry exactly one separator between
|
|
254
|
+
# $dst_root and $name — the old single format printed `.gob/extras` + `taste` as
|
|
255
|
+
# `.gob/extrastaste/` (files landed in the right place, only the LOG lied). The
|
|
256
|
+
# platform branch normalizes $dst_root to end in /, the standalone branch does not,
|
|
257
|
+
# so the trailing slashes are stripped at print time and one / is always inserted.
|
|
258
|
+
printf 'extras: skill %s -> %s/%s/\n' "$name" "${dst_root%/}" "$name"
|
|
236
259
|
copy_tree "$d" "$dst_root/$name"
|
|
237
260
|
done
|
|
238
261
|
[ "$n" -gt 0 ] || die "payload for '$id' holds no skill dirs ($src_root/*/ with SKILL.md each) — see extras-catalogue/payload/README.md" 2
|
package/bin/goblin-init
CHANGED
|
@@ -133,6 +133,10 @@ back one proposal file. Do this now:
|
|
|
133
133
|
found in step 1 — react, vue, playwright, godot, unity, node, postgres, …);
|
|
134
134
|
- RECOMMEND rows are pre-ticked (write `- id` with `[x]`); MAYBE rows are
|
|
135
135
|
listed but NOT pre-ticked (`[ ]`) — they are visible choices, never defaults;
|
|
136
|
+
- a row with NO vendored payload (no `extras-catalogue/payload/<id>/` directory)
|
|
137
|
+
must NOT be pre-ticked even when RECOMMEND — print it as `[ ]` instead;
|
|
138
|
+
`--write` installs through `gob extras install`, which refuses a
|
|
139
|
+
payload-missing id and fails the whole --write;
|
|
136
140
|
- a row whose `conflicts:` names an id you also picked: pick at most one of them;
|
|
137
141
|
- SKIP rows are never suggested and refuse install; leave them out entirely.
|
|
138
142
|
|
|
@@ -226,13 +230,21 @@ print_heuristic() {
|
|
|
226
230
|
# files). The SAME matches column the agent brief reads — the fallback suggests from
|
|
227
231
|
# the catalogue, never from its own private list. Verdicts are respected: only
|
|
228
232
|
# RECOMMEND rows pre-tick; MAYBE rows print unticked; SKIP rows never appear.
|
|
233
|
+
# QA fix (v2-qa): a row pre-ticks ONLY when its vendored payload exists —
|
|
234
|
+
# extras-catalogue/payload/<id>/ — because --write installs through
|
|
235
|
+
# `gob extras install`, which refuses a payload-missing row and fails the whole
|
|
236
|
+
# --write after everything else was already written. A RECOMMEND row with no
|
|
237
|
+
# payload prints as a visible, unticked `[ ]` choice instead. (41 researched rows,
|
|
238
|
+
# 1 vendored payload: the old pre-tick turned a day-one init into a guaranteed
|
|
239
|
+
# exit 2 halfway through writing.)
|
|
229
240
|
if [ -f "$CATALOGUE_TSV" ]; then
|
|
230
241
|
local scan
|
|
231
242
|
scan=$(cat "$TARGET/package.json" "$TARGET"/*.lock "$TARGET"/pnpm-lock.yaml \
|
|
232
243
|
"$TARGET"/vue.config.* "$TARGET"/nuxt.config.* "$TARGET"/godot/project.godot \
|
|
233
244
|
"$TARGET"/unity/ProjectSettings/ProjectVersion.txt 2>/dev/null | tr 'A-Z' 'a-z')
|
|
234
245
|
if [ -n "$scan" ]; then
|
|
235
|
-
local ticked="" maybe=""
|
|
246
|
+
local ticked="" maybe="" payload_root
|
|
247
|
+
payload_root="${GOB_EXTRAS_PAYLOAD:-$SRC/extras-catalogue/payload}"
|
|
236
248
|
while IFS=$'\t' read -r cid ccat ckind cname crepo cpath chmd clic cstars cpush \
|
|
237
249
|
cmatches cconf creq chint cverdict cby cdate; do
|
|
238
250
|
[ -n "$cid" ] || continue
|
|
@@ -242,6 +254,12 @@ print_heuristic() {
|
|
|
242
254
|
case "$scan" in *"$tok"*) hit=1; break ;; esac
|
|
243
255
|
done
|
|
244
256
|
[ "$hit" -eq 1 ] || continue
|
|
257
|
+
if [ ! -d "$payload_root/$cid" ]; then
|
|
258
|
+
# no vendored payload: the row stays visible but never pre-ticks —
|
|
259
|
+
# a tick --write cannot honour is a refusal waiting to happen
|
|
260
|
+
maybe="$maybe - [ ] $cid # matches this repo, NO VENDORED PAYLOAD yet (gob extras install would refuse — vendor it under extras-catalogue/payload/$cid/ first)"$'\n'
|
|
261
|
+
continue
|
|
262
|
+
fi
|
|
245
263
|
case "$cverdict" in
|
|
246
264
|
RECOMMEND) ticked="$ticked - [x] $cid # matches this repo ($cmatches)"$'\n' ;;
|
|
247
265
|
MAYBE) maybe="$maybe - [ ] $cid # matches, verdict MAYBE (not pre-ticked)"$'\n' ;;
|
|
@@ -326,6 +344,37 @@ SYNC_SEL=$(g_agents_list "$PROP" sync_platforms | tr '\n' ' ')
|
|
|
326
344
|
# cannot install anything the catalogue does not carry.
|
|
327
345
|
EXTRAS_SEL=$(sed -n '/catalogue_suggestions:/,/^[^ -]/{s/^[[:space:]]*-[[:space:]]*\[x\][[:space:]]*\([A-Za-z0-9_-]*\).*/\1/p;}' "$PROP" | sort -u | tr '\n' ' ')
|
|
328
346
|
|
|
347
|
+
# ---------------------------------------------------------------- pre-flight ---
|
|
348
|
+
# QA fix (v2-qa issue 1b): the TICKED extras are validated BEFORE anything is written.
|
|
349
|
+
# The old order installed the harness first and ran `gob extras install` last, so a
|
|
350
|
+
# missing vendored payload refused AFTER 23 files were already in the tree (the day-one
|
|
351
|
+
# exit 2 with the repo half-initialized). Here every ticked id is resolved through the
|
|
352
|
+
# same allowlist path goblin-extras uses (row exists, verdict installable, license gate,
|
|
353
|
+
# vendored payload present) while the target is still untouched; a refusal names the id
|
|
354
|
+
# and the fix and exits before the first write.
|
|
355
|
+
if [ -n "$EXTRAS_SEL" ] && [ "$DRYRUN" -eq 0 ]; then
|
|
356
|
+
PAYLOAD_ROOT="${GOB_EXTRAS_PAYLOAD:-$SRC/extras-catalogue/payload}"
|
|
357
|
+
for xid in $EXTRAS_SEL; do
|
|
358
|
+
row=$(awk -F'\t' -v id="$xid" 'NR>1 && $1==id { print; exit }' "$CATALOGUE_TSV" 2>/dev/null)
|
|
359
|
+
[ -n "$row" ] || { g_err "pre-flight: catalogue has no row '$xid' — fix the proposal's catalogue_suggestions (gob extras list names the allowlist)"; exit 2; }
|
|
360
|
+
verdict=$(printf '%s' "$row" | awk -F'\t' '{print $15}')
|
|
361
|
+
lic=$(printf '%s' "$row" | awk -F'\t' '{print $18}')
|
|
362
|
+
case "$verdict" in
|
|
363
|
+
RECOMMEND|MAYBE) ;;
|
|
364
|
+
*) g_err "pre-flight: '$xid' carries verdict '$verdict' — untick it in the proposal's catalogue_suggestions"; exit 2 ;;
|
|
365
|
+
esac
|
|
366
|
+
# the same license gate goblin-extras enforces, read before any write
|
|
367
|
+
case "$lic" in
|
|
368
|
+
verified) ;;
|
|
369
|
+
*) g_err "pre-flight: '$xid' refuses install: license pending verification — untick it in the proposal's catalogue_suggestions"; exit 2 ;;
|
|
370
|
+
esac
|
|
371
|
+
[ -d "$PAYLOAD_ROOT/$xid" ] || {
|
|
372
|
+
g_err "pre-flight: no vendored payload for '$xid' at $PAYLOAD_ROOT/$xid — untick it in the proposal's catalogue_suggestions, or vendor the payload there first";
|
|
373
|
+
exit 2;
|
|
374
|
+
}
|
|
375
|
+
done
|
|
376
|
+
fi
|
|
377
|
+
|
|
329
378
|
if [ "$DRYRUN" -eq 1 ]; then
|
|
330
379
|
g_info "gob init --write --dry-run: validated OK (class $CLASS, branch $BRANCH, owner $EMAIL, 1+ gate)"
|
|
331
380
|
g_info " sync: ${SYNC_SEL:-none}"
|
package/bin/goblin-install
CHANGED
|
@@ -1,19 +1,23 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
2
|
# goblin-install — drop the harness into a target repo, idempotently.
|
|
3
3
|
#
|
|
4
|
-
# Usage:
|
|
4
|
+
# Usage: bash bin/goblin-install --target <dir> [options] # checkout-only; `gob init --write` is the user surface
|
|
5
5
|
# --target <dir> required; the repo root to install into
|
|
6
6
|
# --class <name> required unless --uninstall or --re-pin; one of
|
|
7
7
|
# software|service|game|research|fleet, or the aliases A-E / app / agent
|
|
8
8
|
# / desktop (desktop/F => software + --electron); anything else is refused
|
|
9
9
|
# --electron the electron opt-in overlay over the software class (electron: true):
|
|
10
10
|
# the app_bundle_bytes ratchet, BN-06..09 bans, the host-gate declaration
|
|
11
|
-
# --models <path> model mapping file (default: $GOBLIN_MODELS
|
|
12
|
-
#
|
|
11
|
+
# --models <path> model mapping file (default: $GOBLIN_MODELS; unset = rendered as an
|
|
12
|
+
# empty models_file: the repo's machine-specific input, never a path
|
|
13
|
+
# from the machine the installer ran on)
|
|
14
|
+
# --practice <path> the referenced standard (default: $GOBLIN_PRACTICE; unset = empty
|
|
15
|
+
# practice: pin — a named path that is absent is reported, never
|
|
16
|
+
# silently dropped)
|
|
13
17
|
# --parts <list> comma list to install; default = every part the class requires
|
|
14
18
|
# --archive mark the project archive: verify requires no HANDOFF and no gates
|
|
15
19
|
# --skills yes|no install agent skills under .hermes/skills (default no; opt in per
|
|
16
|
-
#
|
|
20
|
+
# catalogue row with: gob extras install <id>)
|
|
17
21
|
# --dry-run print the plan; write nothing
|
|
18
22
|
# --upgrade re-install at the current version; report created/updated/unchanged/skipped
|
|
19
23
|
# --opt-out <part> record the part in disabled: so its required checks are skipped
|
|
@@ -31,7 +35,7 @@
|
|
|
31
35
|
|
|
32
36
|
set -uo pipefail
|
|
33
37
|
|
|
34
|
-
GOBLIN_INSTALL_VERSION="0.6.0-alpha.
|
|
38
|
+
GOBLIN_INSTALL_VERSION="0.6.0-alpha.4"
|
|
35
39
|
SELF_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
|
|
36
40
|
SRC=$(cd "$SELF_DIR/.." && pwd)
|
|
37
41
|
# shellcheck source=goblin-lib.sh
|
|
@@ -39,8 +43,16 @@ SRC=$(cd "$SELF_DIR/.." && pwd)
|
|
|
39
43
|
|
|
40
44
|
TARGET=""
|
|
41
45
|
CLASS=""
|
|
42
|
-
|
|
43
|
-
|
|
46
|
+
# QA fix (v2-qa issue 4): the old defaults were $HOME/projects/fleet-model.yaml and
|
|
47
|
+
# $HOME/projects/PROJECT-PRACTICE.md - the MAINTAINER's home layout baked into every
|
|
48
|
+
# rendered config on every machine, including a fresh contributor's (their rendered
|
|
49
|
+
# AGENTS.md pointed at a file that does not exist on their machine). The neutral default
|
|
50
|
+
# is EMPTY: no --models / no GOBLIN_MODELS renders an empty models_file: line, and the
|
|
51
|
+
# practice pin stays empty (verify already treats both as the legitimate no-mapping /
|
|
52
|
+
# no-standard state). A machine that HAS a fleet mapping exports GOBLIN_MODELS (or
|
|
53
|
+
# passes --models) and gets the same rendering as before.
|
|
54
|
+
MODELS="${GOBLIN_MODELS:-}"
|
|
55
|
+
PRACTICE="${GOBLIN_PRACTICE:-}"
|
|
44
56
|
# W5-3: `--practice <path>` naming a file that is not there used to be IGNORED IN SILENCE -
|
|
45
57
|
# exit 0, `practice: ~`, `practice_sha256: ~`, and not one line about it in the install log.
|
|
46
58
|
# The empty pin is a legitimate state (a repo may reference no standard, and the default path is
|
|
@@ -220,6 +232,15 @@ if [ "$UNINSTALL" -eq 1 ]; then
|
|
|
220
232
|
printf '.goblin\n.gob/bin\n.gob/manifest\n.gob/bans\n.hermes\n.hermes/skills\n'
|
|
221
233
|
} | awk 'NF' | awk -F/ '{print NF " " $0}' | sort -rn | cut -d' ' -f2- | awk '!seen[$0]++')
|
|
222
234
|
g_info "removed $n file(s) and $nd empty director(y|ies). Left in place: HANDOFF.md, AGENTS.md, ROUND-000-SPEC.md, reviews/, the .gitignore block${KEPT:+, and the decision record(s) you edited:$KEPT}."
|
|
235
|
+
# QA fix (v2-qa issue 10): honesty about what the uninstall leaves UNTOUCHED. Two
|
|
236
|
+
# by-design residues a reader could otherwise read as a clean sweep:
|
|
237
|
+
# - the .gitignore block the install appended stays (removing it could eat a
|
|
238
|
+
# line the project added inside the block; the preimage is untracked text),
|
|
239
|
+
# - prose in kept files (HANDOFF.md, AGENTS.md body, SPECs) may still name
|
|
240
|
+
# now-deleted paths (.gob/bin/goblin-verify, checks/) — those references are
|
|
241
|
+
# dead after this command.
|
|
242
|
+
g_info " note: the .gitignore ignore-rules block stays (by design: it may carry lines the project added; remove it by hand if you want it gone)"
|
|
243
|
+
g_info " note: prose that names .gob/ paths (HANDOFF.md, AGENTS.md body, SPECs) now points at removed files — those references are dead"
|
|
223
244
|
exit 0
|
|
224
245
|
fi
|
|
225
246
|
|
|
@@ -852,7 +873,7 @@ if [ "$DRY_RUN" -eq 0 ]; then
|
|
|
852
873
|
if [ "$SKILLS" = "yes" ]; then
|
|
853
874
|
g_info " 4. hermes skills trust $TARGET # one-time, so the project-tier skills load"
|
|
854
875
|
else
|
|
855
|
-
g_info " 4. agent skills are opt-in: gob
|
|
876
|
+
g_info " 4. agent skills are opt-in: gob extras install <id...> # gob extras list shows the catalogue"
|
|
856
877
|
fi
|
|
857
878
|
g_info ""
|
|
858
879
|
g_info "automations (optional; neither writes outside this repo, and A-02 has no agent in it):"
|
package/bin/goblin-lib.sh
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
# - name: typecheck four-space-indented second member of a list entry
|
|
17
17
|
# cmd: npx tsc --noEmit
|
|
18
18
|
|
|
19
|
-
GOBLIN_LIB_VERSION="0.6.0-alpha.
|
|
19
|
+
GOBLIN_LIB_VERSION="0.6.0-alpha.4"
|
|
20
20
|
|
|
21
21
|
# ---------------------------------------------------------------- output -----
|
|
22
22
|
# g_trunc <width> <text> — fold a long detail to one line at <width> columns, keeping the
|
|
@@ -31,6 +31,9 @@ g_trunc() {
|
|
|
31
31
|
# <indent> (the cannot-see footer shape). Byte-safe: awk length on bytes approximates
|
|
32
32
|
# columns for ASCII prose, which is all this text is.
|
|
33
33
|
g_fold() {
|
|
34
|
+
# QA fix (v2-qa issue 9): the rest-assignment used to inline substr() as sub()'s third
|
|
35
|
+
# parameter — not a changeable lvalue, a hard error on gawk 5.2+ (the helper had never
|
|
36
|
+
# been exercised until the remedy fold called it). A temp variable is portable awk.
|
|
34
37
|
awk -v w="$1" -v ind="$2" '
|
|
35
38
|
{
|
|
36
39
|
line = $0
|
|
@@ -39,10 +42,9 @@ g_fold() {
|
|
|
39
42
|
while (cut > 1 && substr(line, cut, 1) != " ") cut--
|
|
40
43
|
if (cut <= 1) cut = w
|
|
41
44
|
print substr(line, 1, cut)
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
line = ind line
|
|
45
|
+
rest = substr(line, cut + 1)
|
|
46
|
+
sub(/^[ ]+/, "", rest)
|
|
47
|
+
line = ind rest
|
|
46
48
|
}
|
|
47
49
|
print line
|
|
48
50
|
}'
|
|
@@ -71,12 +73,16 @@ g_fail() {
|
|
|
71
73
|
case "$rem" in
|
|
72
74
|
—*) return 0 ;; # an em-dash cell: history and blindness, never a remedy
|
|
73
75
|
esac
|
|
74
|
-
#
|
|
75
|
-
#
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
[
|
|
76
|
+
# QA fix (v2-qa issue 9): a remedy is an instruction, not a detail line — truncating it
|
|
77
|
+
# with a ~ cut the command the operator had to type (measured: 'git -c user.ema~').
|
|
78
|
+
# The remedy is now WORD-FOLDED to continuation lines at the report width in every
|
|
79
|
+
# mode (whole text either way); --verbose keeps the single-line form it always had.
|
|
80
|
+
if [ -n "$rem" ]; then
|
|
81
|
+
if [ "${GOB_VERIFY_VERBOSE:-0}" -eq 1 ]; then
|
|
82
|
+
printf 'remedy: %s\n' "$rem"
|
|
83
|
+
else
|
|
84
|
+
printf 'remedy: %s\n' "$rem" | g_fold "${GOB_REPORT_COLS:-100}" " "
|
|
85
|
+
fi
|
|
80
86
|
fi
|
|
81
87
|
}
|
|
82
88
|
g_remedy() {
|
package/bin/goblin-map
CHANGED
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
#
|
|
46
46
|
# Never-clobber contract:
|
|
47
47
|
# features/ absent (or empty of .md) -> generate README + one file per slug, exit 0
|
|
48
|
-
# features/ already a map, no --force ->
|
|
48
|
+
# features/ already a map, no --force -> validate only; the index is kept (never rewritten)
|
|
49
49
|
# --force -> regenerate ONLY README.md (indexing every existing
|
|
50
50
|
# feature file too) and add files for NEW slugs;
|
|
51
51
|
# existing feature files are never touched, exit 0
|
|
@@ -129,8 +129,9 @@ Notes:
|
|
|
129
129
|
human pass has actually driven the feature once.
|
|
130
130
|
- entry_paths tokens must be repo-relative paths that EXIST, and should occur in
|
|
131
131
|
source text (a route literal, an import) so FM-02 can grep for them.
|
|
132
|
-
-
|
|
133
|
-
|
|
132
|
+
- --write validates and never rewrites: your hand-written README index is KEPT
|
|
133
|
+
(pass --force only if you want the index REGENERATED from the feature files);
|
|
134
|
+
existing feature files are never touched either way.
|
|
134
135
|
|
|
135
136
|
== FEATURE-FILE SCHEMA =========================================================
|
|
136
137
|
|
|
@@ -201,13 +202,15 @@ if [ -n "$WRITE_DIR" ]; then
|
|
|
201
202
|
WDIR=$(cd "$WRITE_DIR" && pwd) || { g_err "cannot enter: $WRITE_DIR"; exit 2; }
|
|
202
203
|
# A map, for --write purposes, is the README index: --write never writes feature
|
|
203
204
|
# files (they are its INPUT), so the only thing it could clobber is the index.
|
|
205
|
+
# QA fix (v2-qa issue 5): an existing index used to be a refusal ("pass --force") —
|
|
206
|
+
# but the AGENT BRIEF itself tells the agent to WRITE features/README.md before
|
|
207
|
+
# running --write, so the first --write of the brief's own prescribed flow demanded
|
|
208
|
+
# the scary flag. The coherent contract: --write VALIDATES and never rewrites the
|
|
209
|
+
# index without --force; an existing index is the author's own output and is kept,
|
|
210
|
+
# named in the done line. (The never-clobber promise is unchanged: --write still
|
|
211
|
+
# writes NOTHING without --force — the refusal was protecting an empty write.)
|
|
204
212
|
HAVE_WMAP=0
|
|
205
213
|
if [ -f "$WDIR/README.md" ]; then HAVE_WMAP=1; fi
|
|
206
|
-
if [ "$HAVE_WMAP" -eq 1 ] && [ "$FORCE" -ne 1 ]; then
|
|
207
|
-
g_err "refusing to overwrite an existing feature map: $WDIR"
|
|
208
|
-
printf 'error: map: pass --force to regenerate the README index and add NEW files only; existing files are never rewritten\n' >&2
|
|
209
|
-
exit 1
|
|
210
|
-
fi
|
|
211
214
|
# Validation: the frontmatter + H2 + verified contract, per file, fail closed.
|
|
212
215
|
BAD=0; N=0
|
|
213
216
|
for f in "$WDIR"/*.md; do
|
|
@@ -264,7 +267,10 @@ if [ -n "$WRITE_DIR" ]; then
|
|
|
264
267
|
for f in "$WDIR"/*.md; do
|
|
265
268
|
[ -f "$f" ] || continue
|
|
266
269
|
slug=$(basename "$f"); slug=${slug%.md}
|
|
267
|
-
|
|
270
|
+
# QA fix (v2-qa issue 6): $slug is the STEM (README, not README.md) — the old
|
|
271
|
+
# pattern compared README against README.md, never matched, and the regenerated
|
|
272
|
+
# index listed the index itself as a feature.
|
|
273
|
+
case "$slug" in README) continue ;; esac
|
|
268
274
|
printf '%s\t%s\n' "$slug" "$(printf '%s' "${f#"$WDIR"/}" | sed 's#^#./#')" >> "$SLUGS_TSV"
|
|
269
275
|
done
|
|
270
276
|
TODAY=$(date +%F)
|
|
@@ -509,7 +515,9 @@ MID
|
|
|
509
515
|
for f in "$FEAT"/*.md; do
|
|
510
516
|
[ -f "$f" ] || continue
|
|
511
517
|
slug=$(basename "$f"); slug=${slug%.md}
|
|
512
|
-
|
|
518
|
+
# QA fix (v2-qa issue 6): stem comparison, same bug as the --write index loop —
|
|
519
|
+
# the slug is README after .md is stripped, so the old README.md pattern never fired.
|
|
520
|
+
case "$slug" in README) continue ;; esac
|
|
513
521
|
awk -F'\t' -v s="$slug" '$1 == s { found=1 } END { exit !found }' "$SLUGS_TSV" && continue
|
|
514
522
|
title=$(file_title "$f" "$slug")
|
|
515
523
|
printf '%s\n' "- [${title}](./${slug}.md) covers TODO — existing feature file kept by --force (not re-described)"
|
package/bin/goblin-mcp.js
CHANGED
|
@@ -211,7 +211,29 @@ function remedyMap(root) {
|
|
|
211
211
|
}
|
|
212
212
|
|
|
213
213
|
function toolGobVerify(args) {
|
|
214
|
-
|
|
214
|
+
// QA fix (v2-qa issue 7): the tool honours an explicit `target` — an agent calling from
|
|
215
|
+
// an installed repo with a different repo named as target used to get the CWD's matrix
|
|
216
|
+
// with the bogus target silently dropped (wrong-repo-as-verified). Resolution rules:
|
|
217
|
+
// - target absent/empty -> process.cwd() (the documented default)
|
|
218
|
+
// - target relative -> resolved against process.cwd()
|
|
219
|
+
// - resolved dir carries no .gob/engine and no AGENTS.md gob block -> REFUSAL (the
|
|
220
|
+
// exact resolved path is named), never a silent fall-back to the CWD's matrix
|
|
221
|
+
// The result's first line names the verified path, so the agent sees WHICH repo was judged.
|
|
222
|
+
const cwd = process.cwd();
|
|
223
|
+
let root = cwd;
|
|
224
|
+
const target = args && typeof args.target === "string" ? args.target.trim() : "";
|
|
225
|
+
if (target) {
|
|
226
|
+
root = path.resolve(cwd, target);
|
|
227
|
+
if (!fs.existsSync(root) || !fs.statSync(root).isDirectory()) {
|
|
228
|
+
return errText("gob_verify: target is not a directory: " + root);
|
|
229
|
+
}
|
|
230
|
+
const blockText = readBlock(path.join(root, "AGENTS.md"));
|
|
231
|
+
if (!fs.existsSync(path.join(root, ".gob", "bin", "goblin-verify")) && !blockText) {
|
|
232
|
+
return errText(
|
|
233
|
+
"gob_verify: target is not a gobstack repo (no .gob/bin/goblin-verify, no AGENTS.md gob block): " + root
|
|
234
|
+
);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
215
237
|
const engine = path.join(root, ".gob", "bin", "goblin-verify");
|
|
216
238
|
if (!fs.existsSync(engine)) {
|
|
217
239
|
return errText(
|
|
@@ -235,7 +257,9 @@ function toolGobVerify(args) {
|
|
|
235
257
|
const verdict = parsed.failed === 0 && r.status === 0 ? "PASS" : "FAIL";
|
|
236
258
|
const lines = [];
|
|
237
259
|
lines.push(
|
|
238
|
-
|
|
260
|
+
// the resolved repo is named first: the consumer sees WHICH tree was judged
|
|
261
|
+
"verified: " + root +
|
|
262
|
+
"\ngate: " + verdict + " — " + parsed.passed + " passed, " + parsed.failed + " failed, " +
|
|
239
263
|
parsed.advisory + " advisory, " + parsed.skipped + " skipped (exit " + r.status + ")"
|
|
240
264
|
);
|
|
241
265
|
for (const row of parsed.rows) {
|
|
@@ -358,7 +382,9 @@ const TOOLS = [
|
|
|
358
382
|
type: "object",
|
|
359
383
|
properties: {
|
|
360
384
|
only: { type: "string", description: "optional comma-separated rule ids to run (e.g. FM-01,FM-02)" },
|
|
385
|
+
target: { type: "string", description: "optional repo root to verify (absolute, or relative to the CWD); defaults to the current working directory" },
|
|
361
386
|
},
|
|
387
|
+
additionalProperties: false,
|
|
362
388
|
},
|
|
363
389
|
},
|
|
364
390
|
{
|
package/bin/goblin-upgrade
CHANGED
package/bin/goblin-verify
CHANGED
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
|
|
20
20
|
set -uo pipefail
|
|
21
21
|
|
|
22
|
-
GOBLIN_VERIFY_VERSION="0.6.0-alpha.
|
|
22
|
+
GOBLIN_VERIFY_VERSION="0.6.0-alpha.4"
|
|
23
23
|
SELF_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
|
|
24
24
|
# shellcheck source=goblin-lib.sh
|
|
25
25
|
. "$SELF_DIR/goblin-lib.sh"
|
|
@@ -276,9 +276,9 @@ if [ ! -f "$CONFIG" ]; then
|
|
|
276
276
|
if [ "$ROOT" != "$PWD" ]; then
|
|
277
277
|
g_err "not installed: $CONFIG is absent — and $PWD is not the installed repo ($ROOT)."
|
|
278
278
|
g_err "fix: cd to your project repo, then re-run gob verify."
|
|
279
|
-
g_err " (installing here would initialize $PWD:
|
|
279
|
+
g_err " (installing here would initialize $PWD: npx @techgoblin/gobstack init)"
|
|
280
280
|
else
|
|
281
|
-
g_err "not installed: $CONFIG is absent. Run:
|
|
281
|
+
g_err "not installed: $CONFIG is absent. Run: npx @techgoblin/gobstack init # or: gob init, inside $ROOT"
|
|
282
282
|
fi
|
|
283
283
|
exit 2
|
|
284
284
|
fi
|
|
@@ -484,7 +484,7 @@ check_in_01() {
|
|
|
484
484
|
# IN-01 recovery line (review 1, scope 4): the record is corrupt or missing; name the two
|
|
485
485
|
# restores. The matrix's remedy: line rides under the payload via g_fail.
|
|
486
486
|
printf 'installed.json is absent or records no version\n'
|
|
487
|
-
printf 'recover:
|
|
487
|
+
printf 'recover: git checkout -- .gob/installed.json, or re-run npx @techgoblin/gobstack init --write to re-install\n'
|
|
488
488
|
return 1
|
|
489
489
|
}
|
|
490
490
|
|
|
@@ -609,7 +609,7 @@ check_in_02() {
|
|
|
609
609
|
# catch a SILENT edit, so re-pinning is a deliberate act: one explicit command, which
|
|
610
610
|
# prints the old and new hash (docs/CONTRACTS.md, "An edited standard is not a dead end").
|
|
611
611
|
printf ' if the edit is yours and intended, re-pin it deliberately:\n'
|
|
612
|
-
printf ' goblin-install --target %s --re-pin\n' "$ROOT"
|
|
612
|
+
printf ' goblin-install --target %s --re-pin # from the gobstack checkout/install tree\n' "$ROOT"
|
|
613
613
|
bad=1; pin=" | practice EDITED"
|
|
614
614
|
else
|
|
615
615
|
pin=" | practice pin ok"
|
|
@@ -626,7 +626,7 @@ check_in_02() {
|
|
|
626
626
|
# naming the drifted file the payload above reported. Sits between the row's own lines and
|
|
627
627
|
# the summary; g_fail appends the matrix's remedy: line under the whole payload.
|
|
628
628
|
if [ "$bad" -ne 0 ] && [ -n "$DRIFTED" ]; then
|
|
629
|
-
printf 'recover: git checkout -- %s, or
|
|
629
|
+
printf 'recover: git checkout -- %s, or re-run npx @techgoblin/gobstack init --write to re-install\n' "$DRIFTED"
|
|
630
630
|
fi
|
|
631
631
|
[ "$bad" -eq 0 ]
|
|
632
632
|
}
|
package/docs/CONTRACTS.md
CHANGED
|
@@ -13,12 +13,15 @@ same way the fleet's own tool reads it. Everything else is line-oriented shell.
|
|
|
13
13
|
software · service · game · research · fleet. The letters A-E and the
|
|
14
14
|
older names app (software), agent (fleet) and desktop/F (software + the
|
|
15
15
|
electron opt-in) are read-time aliases.
|
|
16
|
-
--models <path> model mapping file (default: $GOBLIN_MODELS
|
|
17
|
-
|
|
16
|
+
--models <path> model mapping file (default: $GOBLIN_MODELS; unset = an empty
|
|
17
|
+
models_file: the repo's machine-specific input, set per machine)
|
|
18
|
+
--practice <path> the referenced standard (default: $GOBLIN_PRACTICE; unset = no
|
|
19
|
+
practice pin; a named path that is absent is reported, never
|
|
20
|
+
silently dropped)
|
|
18
21
|
--parts <list> comma list to install; default = every part the class requires
|
|
19
22
|
--archive mark the project archive: verify requires no HANDOFF and no gates
|
|
20
23
|
--skills yes|no install agent skills under .hermes/skills (default no — the harness is
|
|
21
|
-
neutral; opt in per
|
|
24
|
+
neutral; opt in per catalogue row with: gob extras install <id...>). On a repo whose
|
|
22
25
|
record already has skills installed, an OMITTED flag keeps them; an explicit
|
|
23
26
|
--skills no removes them.
|
|
24
27
|
--dry-run print the plan; write nothing
|
package/docs/ENFORCEMENT.md
CHANGED
|
@@ -31,7 +31,7 @@ Measured shape of this table: **87 rows** - 82 target, 5 source; advisory 10, ga
|
|
|
31
31
|
| id | scope | enforced by | rule | check | if it cannot be enforced, why |
|
|
32
32
|
|---|---|---|---|---|---|
|
|
33
33
|
| `IN-01` | target | script | The install exists and records its version + every file's hash. | goblin-verify --only IN-01 | — (W1: the check is a builtin so the engine.mode=global clause can run — a global, declaration-only repo has no install record and SKIPs with `global engine mode — no per-repo install record`; the vendored clauses are the old one-liner: the record exists and names its version) |
|
|
34
|
-
| `IN-02` | target | script | Every installed file still matches its recorded hash. | goblin-verify --only IN-02 | recover:
|
|
34
|
+
| `IN-02` | target | script | Every installed file still matches its recorded hash. | goblin-verify --only IN-02 | recover: git checkout -- .gob/installed.json (or re-run `npx @techgoblin/gobstack init --write` to re-install); for a file it names drifted: git checkout -- <path> (if the edit is yours and intended, re-pin it: `goblin-install --target <dir> --re-pin` from the checkout/install tree) |
|
|
35
35
|
| `IN-03` | target | script | The verifier's own manifest is complete: every rule has a check or is advisory. | goblin-verify --only IN-03 | — (this row is the reason the matrix cannot rot; the second clause is D6's shape in general: a row that carries no check must be labelled advisory, or it claims verification it does not perform. The third clause is Z1-5: `enforced_by` is documented as a closed enum in docs/ENFORCEMENT.md and was read by NOTHING, so a typo in that cell changed nothing - `script\|lint\|gate\|advisory` plus `test`, the source-scope value whose check is tests/run-tests.sh. W1: the check runs against whichever manifest the engine actually resolved (the chain in bin/goblin-verify), no longer the hardcoded per-repo path — the rule's meaning is untouched, only the path input follows the engine) |
|
|
36
36
|
| `IN-04` | target | script | No file goblin-stack did not create has been overwritten. | goblin-verify --only IN-04 | Detects a file the installer recorded as pre-existing (a `refused` entry) that has since vanished, or that is listed as installed anyway. The second clause is an internal-consistency guard: with correct code a refused path is never written, so it fires only if the installer regresses. The negative control exercises the vanished branch. |
|
|
37
37
|
| `HP-01` | target | gate | HANDOFF.md exists at the root. | test -f HANDOFF.md | — |
|
package/docs/GUIDE.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
A step-by-step guide for your first week. **Read this before the README.** The README tells you
|
|
4
4
|
what the pieces are; this tells you what to *do*, in order, and what you should see when it works.
|
|
5
5
|
|
|
6
|
-
Version: `0.6.0-alpha.
|
|
6
|
+
Version: `0.6.0-alpha.4` · Last measured: 2026-10-09 · Every command and every output below was run on a
|
|
7
7
|
real repository while writing this guide.
|
|
8
8
|
|
|
9
9
|
---
|
|
@@ -267,7 +267,8 @@ Open it. The keys that matter on day one:
|
|
|
267
267
|
branch: main # DECLARED, never assumed
|
|
268
268
|
owner_email: you@example.com # the commit identity this repo expects
|
|
269
269
|
practice: /path/to/your-standard.md # optional: your own house rules, hash-pinned
|
|
270
|
-
models_file: /path/to/fleet-model.yaml # the ONE machine-specific input
|
|
270
|
+
models_file: /path/to/fleet-model.yaml # the ONE machine-specific input (per machine; a
|
|
271
|
+
# fresh install without --models leaves it empty)
|
|
271
272
|
gate_<name>_cmd: <one command> # YOUR real commands, one line each
|
|
272
273
|
|
|
273
274
|
**The single most valuable edit you will make:** replace the gate line(s) with the commands you
|
|
@@ -290,7 +291,7 @@ repos follow an old version.
|
|
|
290
291
|
|
|
291
292
|
When *you* legitimately edit your own standard:
|
|
292
293
|
|
|
293
|
-
|
|
294
|
+
goblin-install --target . --re-pin # from the gobstack checkout / install tree
|
|
294
295
|
|
|
295
296
|
It re-records the hash and prints the old and new value. Nothing re-pins automatically — not even
|
|
296
297
|
a re-install — an edited standard is never a silent no-op.
|
|
@@ -528,8 +529,8 @@ same commands are available outside any repo through the npm CLI: `gob init` / `
|
|
|
528
529
|
|
|
529
530
|
.gob/bin/goblin-verify [--only <id[,id...]>] [--json] [--list]
|
|
530
531
|
.gob/bin/goblin-bans # run the ban list
|
|
531
|
-
gob
|
|
532
|
-
|
|
532
|
+
gob uninstall --target <dir> # the uninstall job
|
|
533
|
+
goblin-install --target <dir> --re-pin # the deliberate re-pin (from the checkout/install tree)
|
|
533
534
|
bin/goblin-model <role> # checkout-only; resolve a role to a profile (docs/ROLES.md)
|
|
534
535
|
|
|
535
536
|
### Register the harness with your agent (MCP)
|
|
@@ -586,6 +587,10 @@ The one rule to hold onto: **init suggests, the catalogue allows, you install.**
|
|
|
586
587
|
|
|
587
588
|
Verdicts: a `RECOMMEND` row is pre-ticked when `gob init` suggests; a `MAYBE` row is listed
|
|
588
589
|
but never pre-ticked; a `SKIP` row refuses install (visible history, declined candidate).
|
|
590
|
+
The license gate rides on top, hard: a row installs only when its `license_status` is
|
|
591
|
+
`verified` — a `LICENSE-PENDING` row (license unresolved) is never pre-ticked and
|
|
592
|
+
`gob extras install` refuses it with `license pending verification` until the curator flips
|
|
593
|
+
the row's data in `catalogue.tsv`.
|
|
589
594
|
Nothing installs at init — `gob init --write` honours only the rows your proposal ticks, and
|
|
590
595
|
it installs them by calling `gob extras install`, so the allowlist is one code path. An id
|
|
591
596
|
that is not in the catalogue is refused; installs copy from the vendored payload in the
|
|
@@ -1,42 +1,42 @@
|
|
|
1
|
-
id category kind name source_repo path_within_repo has_skill_md license stars last_push matches conflicts requires install_hint verdict reviewed_by reviewed_date
|
|
2
|
-
taste-skill frontend skill taste-skill Leonxlnx/taste-skill . yes MIT 93730 2026-10-07 react nextjs vue nuxt frontend ui design - none copy-folder RECOMMEND harvey 2026-10-08
|
|
3
|
-
vercel-agent-skills frontend skill vercel-labs agent skills (react pack) vercel-labs/agent-skills skills/ skill none (verify per-skill) 32078 2026-08-28 react nextjs frontend ui design - none copy-folder
|
|
4
|
-
anthropic-frontend-design frontend skill frontend-design (anthropics/skills) anthropics/skills frontend-design yes none (verify per-skill) 180150 2026-10-05 frontend ui react vue design - none copy-folder
|
|
5
|
-
vuejs-skills frontend skill vuejs-ai skills (vue 3 pack) vuejs-ai/skills skills/ skill MIT 2889 2026-05-30 vue nuxt frontend - none copy-folder RECOMMEND harvey 2026-10-08
|
|
6
|
-
ux-ui-agent-skills frontend skill ux-ui agent skills (design tokens, WCAG) plugin87/ux-ui-agent-skills skills/ skill MIT 1551 2026-10-08 frontend ui design accessibility - none copy-folder RECOMMEND harvey 2026-10-08
|
|
7
|
-
impeccable frontend skill impeccable (design language) pbakaus/impeccable .dotagent-dir/ skill Apache-2.0 78552 2026-10-07 frontend ui design - none copy-folder RECOMMEND harvey 2026-10-08
|
|
8
|
-
playwright-mcp testing mcp Playwright MCP (Microsoft, official) microsoft/playwright-mcp - no Apache-2.0 37929 2026-10-08 playwright e2e testing browser automation - node >= 18 npx @playwright/mcp@latest RECOMMEND harvey 2026-10-08
|
|
9
|
-
chrome-devtools-mcp testing mcp Chrome DevTools MCP (official) ChromeDevTools/chrome-devtools-mcp - no Apache-2.0 53117 2026-10-08 browser debugging cdp e2e performance - node >= 18 npx chrome-devtools-mcp@latest RECOMMEND harvey 2026-10-08
|
|
10
|
-
playwright-skill testing skill playwright-skill (no MCP registration) lackeyjb/playwright-skill . yes MIT 3180 2026-10-01 playwright e2e testing - playwright installed copy-folder RECOMMEND harvey 2026-10-08
|
|
11
|
-
webapp-testing testing skill webapp-testing (anthropics/skills) anthropics/skills webapp-testing yes none (verify per-skill) 180150 2026-10-05 e2e testing browser playwright - playwright installed copy-folder
|
|
12
|
-
godot-ai game mcp Godot AI (hi-godot) hi-godot/godot-ai - no MIT 2862 2026-10-08 godot game - see repo README see repo README RECOMMEND harvey 2026-10-08
|
|
13
|
-
godot-mcp game mcp Godot MCP (community default) Coding-Solo/godot-mcp - no MIT 5976 2026-04-16 godot game godot-ai see repo README see repo README RECOMMEND harvey 2026-10-08
|
|
14
|
-
godotprompter game skill GodotPrompter (66 godot skills) jame581/GodotPrompter skills/ skill MIT 798 2026-10-06 godot game - none copy-folder RECOMMEND harvey 2026-10-08
|
|
15
|
-
unity-mcp game mcp Unity MCP (CoplayDev) CoplayDev/unity-mcp - no MIT 14767 2026-10-07 unity game - unity editor + see repo README see repo README RECOMMEND harvey 2026-10-08
|
|
16
|
-
awesome-gamedev-skills game skill awesome gamedev agent skills (74 skills, harvest source) gamedev-skills/awesome-gamedev-agent-skills skills/ skill Apache-2.0 1365 2026-09-27 game godot unity unreal phaser threejs bevy pygame - none copy-folder RECOMMEND harvey 2026-10-08
|
|
17
|
-
supabase-agent-skills node skill Supabase agent skills (official) supabase/agent-skills skills/ skill MIT 2708 2026-10-02 node backend supabase database auth - none copy-folder RECOMMEND harvey 2026-10-08
|
|
18
|
-
pg-aiguide node mcp pg-aiguide (Timescale, postgres) timescale/pg-aiguide - no Apache-2.0 1860 2026-10-07 node postgres database backend - see repo README see repo README RECOMMEND harvey 2026-10-08
|
|
19
|
-
hono-skills node skill Hono agent skills (official) honojs/skills skills/ skill MIT 13 2026-10-08 node hono backend api - none copy-folder RECOMMEND harvey 2026-10-08
|
|
20
|
-
superdesign-skill frontend skill superdesign-skill (design iteration loop) superdesigndev/superdesign-skill . yes MIT 633 2026-08-21 frontend ui design taste-skill vercel-agent-skills none copy-folder MAYBE harvey 2026-10-08
|
|
21
|
-
garden-skills frontend skill garden-skills (collection, harvest source) ConardLi/garden-skills skills/ skill MIT 12771 2026-07-12 frontend ui design - none copy-folder MAYBE harvey 2026-10-08
|
|
22
|
-
dev-browser testing skill dev-browser (general web browser skill) SawyerHood/dev-browser . yes MIT 6656 2026-09-05 browser e2e testing playwright-mcp none copy-folder MAYBE harvey 2026-10-08
|
|
23
|
-
currents-playwright-best-practices testing skill playwright best practices (Currents.dev) currents-dev/playwright-best-practices-skill . yes MIT 393 2026-07-21 playwright e2e testing testdino-playwright-skill none copy-folder MAYBE harvey 2026-10-08
|
|
24
|
-
testdino-playwright-skill testing skill playwright best practices (TestDino) testdino-hq/playwright-skill . yes MIT 389 2026-09-06 playwright e2e testing currents-playwright-best-practices none copy-folder MAYBE harvey 2026-10-08
|
|
25
|
-
unity-mcp-alt game mcp Unity-MCP (IvanMurzak, skills + CLI) IvanMurzak/Unity-MCP - no Apache-2.0 4400 2026-10-04 unity game unity-mcp unity editor + see repo README see repo README MAYBE harvey 2026-10-08
|
|
26
|
-
cc-game-studios game workflow Game-Studios mega-pack (49 agents, 72 skills) Donchitos/Cc-S-B . skill MIT 25900 2026-10-08 game godot unity - none copy-folder MAYBE harvey 2026-10-08
|
|
27
|
-
godot-ui-integration game skill godot-ui-integration (design to godot UI) zimo-xiao-zheng/godot-ui-integration . yes MIT 275 2026-08-23 godot game ui - none copy-folder MAYBE harvey 2026-10-08
|
|
28
|
-
agent-nestjs-skills node skill NestJS agent skills Kadajett/agent-nestjs-skills skills/ skill none (verify) 289 2026-07-23 node nestjs backend api - none copy-folder
|
|
29
|
-
openapi-to-skills node skill openapi-to-skills (spec to skills generator) neutree-ai/openapi-to-skills . skill Apache-2.0 342 2026-06-23 node api openapi - none copy-folder MAYBE harvey 2026-10-08
|
|
30
|
-
do-app-platform-skills node skill DigitalOcean App Platform skills digitalocean-labs/do-app-platform-skills skills/ skill MIT 37 2026-10-04 node deployment database - none copy-folder MAYBE harvey 2026-10-08
|
|
31
|
-
agent-skills-standard node skill agent-skills-standard (per-framework best practice) HoangNguyen0403/agent-skills-standard skills/ skill MIT 572 2026-10-08 node backend typescript - none copy-folder MAYBE harvey 2026-10-08
|
|
32
|
-
frontend-design-toolkit frontend workflow Frontend-Design-Toolkit (list, harvest source) wilwaldon/cc-frontend-design-toolkit . skill none 1176 2026-04-11 frontend ui design - none copy-folder SKIP harvey 2026-10-08
|
|
33
|
-
nuxt-skills frontend skill nuxt-skills (vue/nuxt/nuxthub) onmax/nuxt-skills skills/ skill none 719 2026-10-06 vue nuxt frontend - none copy-folder SKIP harvey 2026-10-08
|
|
34
|
-
design-audit frontend skill design-audit (UI/UX checklist) wonjyou/design-audit . yes none 8 2026-03-28 frontend ui design - none copy-folder SKIP harvey 2026-10-08
|
|
35
|
-
vibe-coded-website-review frontend skill vibe-coded-website-review (YC design review) zuocharles/vibe-coded-website-review . yes none 0 2026-03-29 frontend ui design - none copy-folder SKIP harvey 2026-10-08
|
|
36
|
-
qa-skills testing workflow qa-skills (e2e generation pipeline) neonwatty/qa-skills . skill MIT 33 2026-05-03 e2e testing - none copy-folder SKIP harvey 2026-10-08
|
|
37
|
-
agentmantis-test-skills testing skill test-skills (playwright e2e pack) agentmantis/test-skills skills/ skill MIT 12 2026-04-08 playwright e2e testing - none copy-folder SKIP harvey 2026-10-08
|
|
38
|
-
invisible-playwright-mcp testing mcp invisible_playwright_mcp (anti-detect) feder-cr/invisible_playwright_mcp - no none 2660 2026-10-08 browser e2e playwright - see repo README see repo README SKIP harvey 2026-10-08
|
|
39
|
-
mcp-unity game mcp mcp-unity (CoderGamester, superseded) CoderGamester/mcp-unity - no MIT 1922 2026-09-03 unity game unity-mcp unity editor + see repo README see repo README SKIP harvey 2026-10-08
|
|
40
|
-
godot-mcp-native game mcp Godot-MCP-Native (duplicate function) yurineko73/Godot-MCP-Native - no MIT 836 2026-08-03 godot game godot-mcp see repo README see repo README SKIP harvey 2026-10-08
|
|
41
|
-
fastify-skills node skill fastify-skills (undocumented) TheCodePace/fastify-skills skills/ skill none 12 2026-10-08 node fastify backend - none copy-folder SKIP harvey 2026-10-08
|
|
42
|
-
drizzle-orm-skill node skill drizzle-orm-skill (no credible alternative exists) oldirty/drizzle-orm-skill . yes none 0 2026-02-24 node drizzle orm database - none copy-folder SKIP harvey 2026-10-08
|
|
1
|
+
id category kind name source_repo path_within_repo has_skill_md license stars last_push matches conflicts requires install_hint verdict reviewed_by reviewed_date license_status license_check_date
|
|
2
|
+
taste-skill frontend skill taste-skill Leonxlnx/taste-skill . yes MIT 93730 2026-10-07 react nextjs vue nuxt frontend ui design - none copy-folder RECOMMEND harvey 2026-10-08 verified 2026-10-09
|
|
3
|
+
vercel-agent-skills frontend skill vercel-labs agent skills (react pack) vercel-labs/agent-skills skills/ skill none (verify per-skill) 32078 2026-08-28 react nextjs frontend ui design - none copy-folder LICENSE-PENDING harvey 2026-10-08 pending 2026-10-09
|
|
4
|
+
anthropic-frontend-design frontend skill frontend-design (anthropics/skills) anthropics/skills frontend-design yes none (verify per-skill) 180150 2026-10-05 frontend ui react vue design - none copy-folder LICENSE-PENDING harvey 2026-10-08 pending 2026-10-09
|
|
5
|
+
vuejs-skills frontend skill vuejs-ai skills (vue 3 pack) vuejs-ai/skills skills/ skill MIT 2889 2026-05-30 vue nuxt frontend - none copy-folder RECOMMEND harvey 2026-10-08 verified 2026-10-09
|
|
6
|
+
ux-ui-agent-skills frontend skill ux-ui agent skills (design tokens, WCAG) plugin87/ux-ui-agent-skills skills/ skill MIT 1551 2026-10-08 frontend ui design accessibility - none copy-folder RECOMMEND harvey 2026-10-08 verified 2026-10-09
|
|
7
|
+
impeccable frontend skill impeccable (design language) pbakaus/impeccable .dotagent-dir/ skill Apache-2.0 78552 2026-10-07 frontend ui design - none copy-folder RECOMMEND harvey 2026-10-08 verified 2026-10-09
|
|
8
|
+
playwright-mcp testing mcp Playwright MCP (Microsoft, official) microsoft/playwright-mcp - no Apache-2.0 37929 2026-10-08 playwright e2e testing browser automation - node >= 18 npx @playwright/mcp@latest RECOMMEND harvey 2026-10-08 verified 2026-10-09
|
|
9
|
+
chrome-devtools-mcp testing mcp Chrome DevTools MCP (official) ChromeDevTools/chrome-devtools-mcp - no Apache-2.0 53117 2026-10-08 browser debugging cdp e2e performance - node >= 18 npx chrome-devtools-mcp@latest RECOMMEND harvey 2026-10-08 verified 2026-10-09
|
|
10
|
+
playwright-skill testing skill playwright-skill (no MCP registration) lackeyjb/playwright-skill . yes MIT 3180 2026-10-01 playwright e2e testing - playwright installed copy-folder RECOMMEND harvey 2026-10-08 verified 2026-10-09
|
|
11
|
+
webapp-testing testing skill webapp-testing (anthropics/skills) anthropics/skills webapp-testing yes none (verify per-skill) 180150 2026-10-05 e2e testing browser playwright - playwright installed copy-folder LICENSE-PENDING harvey 2026-10-08 pending 2026-10-09
|
|
12
|
+
godot-ai game mcp Godot AI (hi-godot) hi-godot/godot-ai - no MIT 2862 2026-10-08 godot game - see repo README see repo README RECOMMEND harvey 2026-10-08 verified 2026-10-09
|
|
13
|
+
godot-mcp game mcp Godot MCP (community default) Coding-Solo/godot-mcp - no MIT 5976 2026-04-16 godot game godot-ai see repo README see repo README RECOMMEND harvey 2026-10-08 verified 2026-10-09
|
|
14
|
+
godotprompter game skill GodotPrompter (66 godot skills) jame581/GodotPrompter skills/ skill MIT 798 2026-10-06 godot game - none copy-folder RECOMMEND harvey 2026-10-08 verified 2026-10-09
|
|
15
|
+
unity-mcp game mcp Unity MCP (CoplayDev) CoplayDev/unity-mcp - no MIT 14767 2026-10-07 unity game - unity editor + see repo README see repo README RECOMMEND harvey 2026-10-08 verified 2026-10-09
|
|
16
|
+
awesome-gamedev-skills game skill awesome gamedev agent skills (74 skills, harvest source) gamedev-skills/awesome-gamedev-agent-skills skills/ skill Apache-2.0 1365 2026-09-27 game godot unity unreal phaser threejs bevy pygame - none copy-folder RECOMMEND harvey 2026-10-08 verified 2026-10-09
|
|
17
|
+
supabase-agent-skills node skill Supabase agent skills (official) supabase/agent-skills skills/ skill MIT 2708 2026-10-02 node backend supabase database auth - none copy-folder RECOMMEND harvey 2026-10-08 verified 2026-10-09
|
|
18
|
+
pg-aiguide node mcp pg-aiguide (Timescale, postgres) timescale/pg-aiguide - no Apache-2.0 1860 2026-10-07 node postgres database backend - see repo README see repo README RECOMMEND harvey 2026-10-08 verified 2026-10-09
|
|
19
|
+
hono-skills node skill Hono agent skills (official) honojs/skills skills/ skill MIT 13 2026-10-08 node hono backend api - none copy-folder RECOMMEND harvey 2026-10-08 verified 2026-10-09
|
|
20
|
+
superdesign-skill frontend skill superdesign-skill (design iteration loop) superdesigndev/superdesign-skill . yes MIT 633 2026-08-21 frontend ui design taste-skill vercel-agent-skills none copy-folder MAYBE harvey 2026-10-08 verified 2026-10-09
|
|
21
|
+
garden-skills frontend skill garden-skills (collection, harvest source) ConardLi/garden-skills skills/ skill MIT 12771 2026-07-12 frontend ui design - none copy-folder MAYBE harvey 2026-10-08 verified 2026-10-09
|
|
22
|
+
dev-browser testing skill dev-browser (general web browser skill) SawyerHood/dev-browser . yes MIT 6656 2026-09-05 browser e2e testing playwright-mcp none copy-folder MAYBE harvey 2026-10-08 verified 2026-10-09
|
|
23
|
+
currents-playwright-best-practices testing skill playwright best practices (Currents.dev) currents-dev/playwright-best-practices-skill . yes MIT 393 2026-07-21 playwright e2e testing testdino-playwright-skill none copy-folder MAYBE harvey 2026-10-08 verified 2026-10-09
|
|
24
|
+
testdino-playwright-skill testing skill playwright best practices (TestDino) testdino-hq/playwright-skill . yes MIT 389 2026-09-06 playwright e2e testing currents-playwright-best-practices none copy-folder MAYBE harvey 2026-10-08 verified 2026-10-09
|
|
25
|
+
unity-mcp-alt game mcp Unity-MCP (IvanMurzak, skills + CLI) IvanMurzak/Unity-MCP - no Apache-2.0 4400 2026-10-04 unity game unity-mcp unity editor + see repo README see repo README MAYBE harvey 2026-10-08 verified 2026-10-09
|
|
26
|
+
cc-game-studios game workflow Game-Studios mega-pack (49 agents, 72 skills) Donchitos/Cc-S-B . skill MIT 25900 2026-10-08 game godot unity - none copy-folder MAYBE harvey 2026-10-08 verified 2026-10-09
|
|
27
|
+
godot-ui-integration game skill godot-ui-integration (design to godot UI) zimo-xiao-zheng/godot-ui-integration . yes MIT 275 2026-08-23 godot game ui - none copy-folder MAYBE harvey 2026-10-08 verified 2026-10-09
|
|
28
|
+
agent-nestjs-skills node skill NestJS agent skills Kadajett/agent-nestjs-skills skills/ skill none (verify) 289 2026-07-23 node nestjs backend api - none copy-folder LICENSE-PENDING harvey 2026-10-08 pending 2026-10-09
|
|
29
|
+
openapi-to-skills node skill openapi-to-skills (spec to skills generator) neutree-ai/openapi-to-skills . skill Apache-2.0 342 2026-06-23 node api openapi - none copy-folder MAYBE harvey 2026-10-08 verified 2026-10-09
|
|
30
|
+
do-app-platform-skills node skill DigitalOcean App Platform skills digitalocean-labs/do-app-platform-skills skills/ skill MIT 37 2026-10-04 node deployment database - none copy-folder MAYBE harvey 2026-10-08 verified 2026-10-09
|
|
31
|
+
agent-skills-standard node skill agent-skills-standard (per-framework best practice) HoangNguyen0403/agent-skills-standard skills/ skill MIT 572 2026-10-08 node backend typescript - none copy-folder MAYBE harvey 2026-10-08 verified 2026-10-09
|
|
32
|
+
frontend-design-toolkit frontend workflow Frontend-Design-Toolkit (list, harvest source) wilwaldon/cc-frontend-design-toolkit . skill none 1176 2026-04-11 frontend ui design - none copy-folder SKIP harvey 2026-10-08 pending 2026-10-09
|
|
33
|
+
nuxt-skills frontend skill nuxt-skills (vue/nuxt/nuxthub) onmax/nuxt-skills skills/ skill none 719 2026-10-06 vue nuxt frontend - none copy-folder SKIP harvey 2026-10-08 pending 2026-10-09
|
|
34
|
+
design-audit frontend skill design-audit (UI/UX checklist) wonjyou/design-audit . yes none 8 2026-03-28 frontend ui design - none copy-folder SKIP harvey 2026-10-08 pending 2026-10-09
|
|
35
|
+
vibe-coded-website-review frontend skill vibe-coded-website-review (YC design review) zuocharles/vibe-coded-website-review . yes none 0 2026-03-29 frontend ui design - none copy-folder SKIP harvey 2026-10-08 pending 2026-10-09
|
|
36
|
+
qa-skills testing workflow qa-skills (e2e generation pipeline) neonwatty/qa-skills . skill MIT 33 2026-05-03 e2e testing - none copy-folder SKIP harvey 2026-10-08 verified 2026-10-09
|
|
37
|
+
agentmantis-test-skills testing skill test-skills (playwright e2e pack) agentmantis/test-skills skills/ skill MIT 12 2026-04-08 playwright e2e testing - none copy-folder SKIP harvey 2026-10-08 verified 2026-10-09
|
|
38
|
+
invisible-playwright-mcp testing mcp invisible_playwright_mcp (anti-detect) feder-cr/invisible_playwright_mcp - no none 2660 2026-10-08 browser e2e playwright - see repo README see repo README SKIP harvey 2026-10-08 pending 2026-10-09
|
|
39
|
+
mcp-unity game mcp mcp-unity (CoderGamester, superseded) CoderGamester/mcp-unity - no MIT 1922 2026-09-03 unity game unity-mcp unity editor + see repo README see repo README SKIP harvey 2026-10-08 verified 2026-10-09
|
|
40
|
+
godot-mcp-native game mcp Godot-MCP-Native (duplicate function) yurineko73/Godot-MCP-Native - no MIT 836 2026-08-03 godot game godot-mcp see repo README see repo README SKIP harvey 2026-10-08 verified 2026-10-09
|
|
41
|
+
fastify-skills node skill fastify-skills (undocumented) TheCodePace/fastify-skills skills/ skill none 12 2026-10-08 node fastify backend - none copy-folder SKIP harvey 2026-10-08 pending 2026-10-09
|
|
42
|
+
drizzle-orm-skill node skill drizzle-orm-skill (no credible alternative exists) oldirty/drizzle-orm-skill . yes none 0 2026-02-24 node drizzle orm database - none copy-folder SKIP harvey 2026-10-08 pending 2026-10-09
|
package/manifest/enforcement.tsv
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
id scope rule enforced_by artifact check if_not_why
|
|
2
2
|
IN-01 target The install exists and records its version + every file's hash. script .gob/installed.json goblin-verify --only IN-01 — (W1: the check is a builtin so the engine.mode=global clause can run — a global, declaration-only repo has no install record and SKIPs with `global engine mode — no per-repo install record`; the vendored clauses are the old one-liner: the record exists and names its version)
|
|
3
|
-
IN-02 target Every installed file still matches its recorded hash. script .gob/installed.json goblin-verify --only IN-02 recover:
|
|
3
|
+
IN-02 target Every installed file still matches its recorded hash. script .gob/installed.json goblin-verify --only IN-02 recover: git checkout -- .gob/installed.json (or re-run npx @techgoblin/gobstack init --write to re-install); for a file it names drifted: git checkout -- <path> (if the edit is yours and intended, re-pin it: goblin-install --target <dir> --re-pin from the checkout/install tree)
|
|
4
4
|
IN-03 target The verifier's own manifest is complete: every rule has a check or is advisory. script manifest/enforcement.tsv goblin-verify --only IN-03 — (this row is the reason the matrix cannot rot; the second clause is D6's shape in general: a row that carries no check must be labelled advisory, or it claims verification it does not perform. The third clause is Z1-5: `enforced_by` is documented as a closed enum in docs/ENFORCEMENT.md and was read by NOTHING, so a typo in that cell changed nothing - `script|lint|gate|advisory` plus `test`, the source-scope value whose check is tests/run-tests.sh. W1: the check runs against whichever manifest the engine actually resolved (the chain in bin/goblin-verify), no longer the hardcoded per-repo path — the rule's meaning is untouched, only the path input follows the engine)
|
|
5
5
|
IN-04 target No file goblin-stack did not create has been overwritten. script .gob/installed.json goblin-verify --only IN-04 Detects a file the installer recorded as pre-existing (a `refused` entry) that has since vanished, or that is listed as installed anyway. The second clause is an internal-consistency guard: with correct code a refused path is never written, so it fires only if the installer regresses. The negative control exercises the vanished branch.
|
|
6
6
|
HP-01 target HANDOFF.md exists at the root. gate HANDOFF.md test -f HANDOFF.md —
|
package/package.json
CHANGED
|
@@ -13,7 +13,7 @@ Use when adopting goblin-stack in a repo, or starting one.
|
|
|
13
13
|
with the electron bans and a host gate, not a sixth class. The letters `A`-`E` and the older
|
|
14
14
|
names are read-time aliases.
|
|
15
15
|
2. **`goblin-install --target <dir> --class <x>`** — the default install is a NEUTRAL harness:
|
|
16
|
-
no agent skills. Opt in per
|
|
16
|
+
no agent skills. Opt in per catalogue row afterwards with `gob extras install <id>` (or vendor the
|
|
17
17
|
Hermes project tier with `--skills yes`).
|
|
18
18
|
3. **`goblin-verify`** — a default software-class install (no agent skills) verifies green:
|
|
19
19
|
`37 passed, 0 failed, 11 advisory, 34 skipped`, exit 0, once `HANDOFF.md` names a commit that
|