@techgoblin/gobstack 0.5.0-beta.8 → 0.6.0-alpha.1
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/CHANGELOG.md +38 -0
- package/README.md +112 -124
- package/VERSION +1 -1
- package/automations/drift-audit.sh +4 -4
- package/bans/layer-check.sh +10 -8
- package/bin/goblin +61 -58
- package/bin/goblin-audit +11 -13
- package/bin/goblin-bans +11 -11
- package/bin/goblin-init +275 -713
- package/bin/goblin-install +160 -114
- package/bin/goblin-lib.sh +234 -1
- package/bin/goblin-map +226 -21
- package/bin/goblin-mcp.js +492 -0
- package/bin/goblin-model +4 -4
- package/bin/goblin-upgrade +1 -1
- package/bin/goblin-verify +159 -145
- package/bin/goblin.js +33 -51
- package/docs/ADOPTION.md +15 -15
- package/docs/CONTRACTS.md +16 -15
- package/docs/DESIGN.md +1 -1
- package/docs/ENFORCEMENT.md +89 -90
- package/docs/FLOWS.md +1 -1
- package/docs/GLOSSARY.md +3 -3
- package/docs/GUARDRAILS.md +5 -5
- package/docs/GUIDE.md +167 -177
- package/docs/INTEGRATION.md +1 -1
- package/docs/LIMITS.md +25 -0
- package/docs/LOOP.md +12 -12
- package/docs/RE-PLAYBOOK.md +3 -3
- package/docs/ROLES.md +5 -5
- package/manifest/bans.tsv +8 -8
- package/manifest/classes.tsv +3 -3
- package/manifest/enforcement.tsv +40 -40
- package/manifest/glossary.tsv +3 -3
- package/manifest/playbooks.tsv +1 -1
- package/package.json +1 -1
- package/presets/electron-overlay.yaml +2 -2
- package/presets/fleet.yaml +8 -7
- package/presets/game.yaml +1 -1
- package/presets/research.yaml +1 -1
- package/presets/service.yaml +1 -1
- package/presets/software.yaml +1 -1
- package/skills/goblin-bootstrap/SKILL.md +2 -2
- package/templates/AGENTS.md.tmpl +8 -18
- package/templates/HANDOFF.md.tmpl +5 -5
- package/templates/agents-block.tmpl +45 -0
- package/templates/audit-waiver.tsv.tmpl +2 -2
- package/templates/boundary-waivers.tmpl +1 -1
- package/templates/checks/gate.sh.tmpl +6 -6
- package/templates/install-hooks.allowlist.tmpl +1 -1
- package/templates/ci/goblin-gate.yml.tmpl +0 -46
- package/templates/goblin.yaml.tmpl +0 -146
- package/templates/loop/decisions.tsv.tmpl +0 -1
- package/templates/loop/predicate.tmpl +0 -16
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,44 @@
|
|
|
3
3
|
One line per released version. `goblin-install --upgrade` prints the delta between the
|
|
4
4
|
version recorded in a target's `.goblin/installed.json` and the source `VERSION`.
|
|
5
5
|
|
|
6
|
+
## 0.6.0-alpha.1
|
|
7
|
+
|
|
8
|
+
The v2 breaking release: rules-first. The rules a repo is judged by move from a config file the
|
|
9
|
+
installer generated into the file a new session already reads, the folder the engine is vendored
|
|
10
|
+
into gets a name that cannot collide with the global one, and every command a reader could not
|
|
11
|
+
reach is cut from the surface rather than shipped half-wired. Nothing here is additive — a repo
|
|
12
|
+
on 0.5.x does not silently keep working through this version; run `gob init` again in the repo.
|
|
13
|
+
|
|
14
|
+
- **`goblin.yaml` is gone. AGENTS.md frontmatter is the single source of truth.** The gates, the
|
|
15
|
+
bans enablement and the model mapping all read the frontmatter block of the root `AGENTS.md`
|
|
16
|
+
(flat `gate_<name>_cmd:` keys beside the prose a teammate reads anyway). There is no second
|
|
17
|
+
config file to drift out of sync with the prose, and the file a new session reads first is the
|
|
18
|
+
file the rules live in. `gob init` prints the agent brief plus a proposal schema and the agent
|
|
19
|
+
fills the frontmatter; `--write` installs the validated result.
|
|
20
|
+
- **`.goblin/` is renamed `.gob/`.** The vendored engine payload (`.gob/bin/`,
|
|
21
|
+
`.gob/manifest/`, `.gob/installed.json`) sits one level deep under a short name, and the
|
|
22
|
+
global `~/.goblin` tree no longer shares a prefix with it.
|
|
23
|
+
- **The CI lane is cut.** No shipped workflow file, no CI toggle in the config — the gate hook
|
|
24
|
+
and `gob verify` are the enforcement paths.
|
|
25
|
+
- **The surface is six verbs: `init`, `map`, `verify`, `bans`, `mcp`, `uninstall`.** The dispatcher
|
|
26
|
+
refuses everything else with exit 2 — `doctor`, `audit`, `upgrade`, `emit`, `sync` and
|
|
27
|
+
`install` are unwired (their code is deleted or unreachable; see `docs/LIMITS.md` #54 for the
|
|
28
|
+
engine-dir decision the upgrade command used to serve). `gob init` replaces `gob install`
|
|
29
|
+
entirely.
|
|
30
|
+
- **npx-first, no global install.** The documented entry is
|
|
31
|
+
`npx @techgoblin/gobstack init`; `uninstall` is the npm one-liner. Nothing asks for `-g`.
|
|
32
|
+
- **Remedy per FAIL.** A `FAIL` row prints its one-line `remedy:` at the point of failure and
|
|
33
|
+
again under the summary payload, so a red run says what to do next without a docs trip. The
|
|
34
|
+
mascot sign-off is a GREEN-run line only: a red run ends on
|
|
35
|
+
`start with the first FAIL above — its remedy line says the fix.` — the verdict IS the FAIL
|
|
36
|
+
list, and mascot noise on the run's one actionable moment is noise.
|
|
37
|
+
- **Framed for the new teammate.** The docs lead with what a person joining the repo reads
|
|
38
|
+
first (`AGENTS.md`, `HANDOFF.md`), not with the toolchain that maintains them.
|
|
39
|
+
|
|
40
|
+
`VERSION`, `package.json` and all six `GOBLIN_*_VERSION` constants in `bin/` are this version.
|
|
41
|
+
No id, verdict or matrix cell moved in this release; the counts the docs quote are the ones
|
|
42
|
+
measured on this tree.
|
|
43
|
+
|
|
6
44
|
## 0.4.4
|
|
7
45
|
|
|
8
46
|
The five findings an independent verification of 0.4.3 left open (AB3). The blocker is the species
|
package/README.md
CHANGED
|
@@ -1,142 +1,140 @@
|
|
|
1
1
|
# gobstack
|
|
2
2
|
|
|
3
3
|
**gobstack** (npm: [`@techgoblin/gobstack`](https://www.npmjs.com/package/@techgoblin/gobstack))
|
|
4
|
-
installs an **executable rule manifest**, a
|
|
5
|
-
**
|
|
6
|
-
|
|
4
|
+
installs an **executable rule manifest**, a **vendored verifier**, and an **AGENTS.md-frontmatter
|
|
5
|
+
config** into any project — so that an AI coding session never re-improvises, and a rule that
|
|
6
|
+
cannot be checked is counted rather than asserted.
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
Start here — `init` is the first verb, and it needs no global install:
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
npx @techgoblin/gobstack@beta init # or the one-shot: run the wizard, install nothing globally
|
|
10
|
+
npx @techgoblin/gobstack init # the agent brief + proposal schema; --write installs it
|
|
12
11
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
**Global, not local.** gobstack is a CLI with zero runtime dependencies. Install it once per
|
|
16
|
-
machine:
|
|
17
|
-
|
|
18
|
-
npm install -g @techgoblin/gobstack@beta
|
|
12
|
+
or install the CLI globally (it is a CLI, not a library):
|
|
19
13
|
|
|
20
|
-
|
|
14
|
+
npm install -g @techgoblin/gobstack # gives you the `gob` CLI (`goblin` remains as a legacy alias)
|
|
21
15
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
**Do NOT add it to an app project's `package.json`.** A `npm install @techgoblin/gobstack` (or a
|
|
25
|
-
`package.json` dependency) inside your app pollutes the app's lockfile with a package the app
|
|
26
|
-
never imports, and can fail resolution outright with `ERESOLVE` when the app's own peer
|
|
27
|
-
dependencies disagree with npm's. If you see `ERESOLVE` after a local install, remove the
|
|
28
|
-
dependency from `package.json` and install globally instead.
|
|
16
|
+
## Install
|
|
29
17
|
|
|
30
|
-
**The
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
18
|
+
**The v2 flow is `init`-first.** `gob init` prints an AGENT BRIEF — a structured prompt telling
|
|
19
|
+
whichever agent is already running in the repo exactly what to scan (package.json, routes, tests,
|
|
20
|
+
CI configs) and what to decide (class, branch, owner email, the first gate command) — plus the
|
|
21
|
+
schema of the proposal file the agent writes back. `gob init --write <proposal>` validates the
|
|
22
|
+
proposal and installs. The heuristic detector (`--heuristic`) is a fallback that appends
|
|
23
|
+
pre-scanned hints to the brief; it never decides.
|
|
36
24
|
|
|
37
|
-
|
|
25
|
+
npx @techgoblin/gobstack init # print the brief + schema (the agent does the scan)
|
|
26
|
+
npx @techgoblin/gobstack init --write .gob-init-proposal.md --yes
|
|
27
|
+
# validate + install
|
|
38
28
|
|
|
39
|
-
|
|
29
|
+
`--write` installs into the repo: AGENTS.md (a rendered body plus the `<!-- gob:begin --> …
|
|
30
|
+
<!-- gob:end -->` config block in its frontmatter), `.gob/` (the vendored engine — verifier,
|
|
31
|
+
manifest, ban probes), `HANDOFF.md`, the `checks/` scaffold and the `.gitignore` block. That
|
|
32
|
+
vendored layer is why an initialized repo keeps working on machines with **no gobstack installed
|
|
33
|
+
at all**: the engine lives in the repo, and `bash .gob/bin/goblin-verify` on a plain `git` +
|
|
34
|
+
`bash` box is the only runtime the repo's gate needs.
|
|
40
35
|
|
|
41
36
|
The installer writes only paths it records, hash-compares before writing, and prints `no-op` on a
|
|
42
37
|
second run with the same arguments. It never overwrites `HANDOFF.md`, `AGENTS.md`, a `*-SPEC.md`,
|
|
43
|
-
`reviews/`, the `.gitignore` block
|
|
38
|
+
`reviews/`, or the `.gitignore` block. Full option list and the three kinds
|
|
44
39
|
of file it manages: `docs/CONTRACTS.md`.
|
|
45
40
|
|
|
46
41
|
A repo that already has its own `HANDOFF.md` exits 1 on the refusal. That is the contract, not a
|
|
47
42
|
failure: reconcile the file rather than forcing over it — `docs/ADOPTION.md`.
|
|
48
43
|
|
|
49
|
-
|
|
44
|
+
**The config is the AGENTS.md frontmatter.** There is no separate config file in v2: every knob
|
|
45
|
+
the harness reads — class, branch, gates, ratchet, bans, replay, opt-outs — is a `key: value`
|
|
46
|
+
line inside the `<!-- gob:begin --> … <!-- gob:end -->` marker block at the top of `AGENTS.md`.
|
|
47
|
+
Edit it in place; the parser reads only that block, and the installer never rewrites it after the
|
|
48
|
+
first install.
|
|
49
|
+
|
|
50
|
+
**`class:` picks the preset**: **software** (the default — shipped features, PRs, review gates),
|
|
50
51
|
**service** (backend jobs, config, unattended runs), **game** (playable builds, perf budgets),
|
|
51
52
|
**research** (specs, replays, reference corpora) and **fleet** (config-of-the-agent repos).
|
|
52
53
|
The single letters `A`–`E` are accepted aliases. What each preset turns on is the matrix in
|
|
53
|
-
`docs/ADOPTION.md
|
|
54
|
+
`docs/ADOPTION.md`.
|
|
54
55
|
|
|
55
56
|
After installing, in this order:
|
|
56
57
|
|
|
57
58
|
cd <target> && git add -A && git commit # the install is a change like any other
|
|
58
|
-
gob
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
`
|
|
72
|
-
manifest, no lockfile and no audit record to read; `PF-01` has no measured perf baseline;
|
|
73
|
-
`BN-01`/`BN-02`/`BN-05` have no `src/` for a ban to read, and `BN-03` plus the four electron bans
|
|
74
|
-
`BN-06`/`BN-07`/`BN-08`/`BN-09` are not in this class's `bans:` list (`bans: [BN-01, BN-02, BN-05]`),
|
|
75
|
-
so they skip as *not enabled* rather than as *unread*; `FM-01`/`FM-02`/`VA-01`
|
|
76
|
-
have no feature map and no declared `verify_doctor:` yet; `RC-01`..`RC-04` have no reference corpus
|
|
77
|
-
declared and no lab `manifests/` to read; and `JG-01` with `LP-01`..`LP-05`
|
|
78
|
-
have no loop record, because no loop has run in this repo yet). **Two** rows do **not** skip: `PG-05`
|
|
79
|
-
and `PG-06`, the CI lane's. This class installs `.github/workflows/goblin-gate.yml`, so the two of
|
|
80
|
-
them read it and pass. Two, not four — the four electron bans named above are among the skips. Two of
|
|
81
|
-
the eleven advisories
|
|
82
|
-
are new with the judge lane: `JG-02` reports that the judge lane resolves to no profile on this
|
|
83
|
-
fleet (it prints the one-line remedy and never fails a repo for a fleet's routing), and `JG-03`
|
|
84
|
-
is the counted row the advisory ceiling had left for it. The parts
|
|
59
|
+
.gob/bin/goblin-verify # or gob verify, anywhere in the target
|
|
60
|
+
|
|
61
|
+
**A default software-class install verifies green — `37 passed, 0 failed, 11 advisory,
|
|
62
|
+
34 skipped`, exit 0 — once `HANDOFF.md` names a commit that exists. Before that edit the
|
|
63
|
+
scaffold's `0000000` placeholder is the one expected red.** Thirty-four rows skip: the five
|
|
64
|
+
skill rows (`SK-01`..`SK-04`, `AU-04`) skip on the `playbooks` opt-out a skills-free install
|
|
65
|
+
records, then the not-yet rows (`HS-02` has no pinned pre-change commit yet; `AU-02`/`AU-03`
|
|
66
|
+
have no report to audit; `SC-06`–`SC-08` have no dependency manifest to read; `PF-01` has no
|
|
67
|
+
measured perf baseline; `BN-01`/`BN-02`/`BN-05` have no `src/` for a ban to read, and the four
|
|
68
|
+
electron bans `BN-06`–`BN-09` are not in this class's `bans:` list
|
|
69
|
+
(`bans: [BN-01, BN-02, BN-05]`), so they skip as *not enabled* rather than as *unread*;
|
|
70
|
+
`FM-01`/`FM-02`/`VA-01` have no feature map; `RC-01`..`RC-04` have no reference corpus; `JG-01`
|
|
71
|
+
with `LP-01`..`LP-05` have no loop record, because no loop has run in this repo yet; and
|
|
72
|
+
`PG-06` — v2 installs no CI, so there is no workflow for its probe to read). The parts
|
|
85
73
|
that only a round can produce — a first review note, a gate that is not the shipped floor — pass
|
|
86
74
|
*vacuously* rather than failing, and `P8` (`goblin-bootstrap`) still walks them as work to do.
|
|
87
75
|
The measurement and the vacuous-pass reading are in `docs/CONTRACTS.md`.
|
|
88
76
|
|
|
89
77
|
## The `gob` CLI
|
|
90
78
|
|
|
79
|
+
The v2 surface is six verbs. Everything else — audit, doctor, emit/sync, upgrade, install —
|
|
80
|
+
is unwired in this alpha: the shim refuses the verb by name and prints the usage.
|
|
81
|
+
|
|
91
82
|
| command | what it does |
|
|
92
83
|
|---|---|
|
|
84
|
+
| `gob init` | the first step: print the AGENT BRIEF + proposal schema; `--heuristic` appends scanned hints as a fallback; `--write <proposal> [--yes]` validates the proposal and installs; `--target <dir>` aims elsewhere; `--dry-run` validates without writing |
|
|
85
|
+
| `gob map` | the feature-map prompt + schema (`--heuristic [target]` runs the starter scanner); `--write <dir> [--force]` validates an agent-written map and installs it; never clobbers — an existing map refuses until `--force` |
|
|
93
86
|
| `gob verify` | run the rule matrix against the current repo — `PASS`/`FAIL`/`SKIP` per row, exit 0 pass · 1 a check failed · 2 could not run · 3 the manifest is broken |
|
|
94
87
|
| `gob bans` | run the ban list (per-pattern red lines over the source tree) |
|
|
95
|
-
| `gob
|
|
96
|
-
| `gob install` | install the harness into a target repo: manifest, verifier, gates, HANDOFF — no agent skills (those are an opt-in: `gob sync --platform <p>`, or `--skills yes`); `--ci-gate yes|no` opts the CI lane in or out (default: the class decides) |
|
|
88
|
+
| `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 |
|
|
97
89
|
| `gob uninstall` | remove everything an install wrote, byte-exactly (`gob install --target <dir> --uninstall` is the same job) |
|
|
98
|
-
| `gob upgrade` | migrate a repo to the shared global engine at `~/.goblin/engine` — 8 steps, two commits, one report |
|
|
99
|
-
| `gob doctor` | one run across the platforms below: DETECTED / NOT-DETECTED / DRIFT per platform |
|
|
100
|
-
| `gob emit` | write the skills + context block for one platform (`--scope project` or `global`); `--unshadow` removes a hermes project skill whose hash equals the source; `gob sync` is the same command under its friendlier name — both spellings work |
|
|
101
|
-
| `gob sync` | the emit verb, renamed (wizard v2): same engine, same flags, same exit contract; `gob emit --help` and `gob sync --help` are byte-identical apart from the verb name |
|
|
102
|
-
| `gob init` | the first-run wizard: detect → class → identity → health check → ci → sync → done, one screen per question; every question has a flag (`--class software --branch main --email a@b.c --gate 'cmd' --emit hermes`), so CI runs it with zero prompts; the ci step defaults to no — nothing under .github/ unless you opt in (`--ci-gate yes|no` overrides); `--no-verify` skips the closing health check; `--dry-run` prints the plan and writes nothing |
|
|
103
|
-
| `gob map` | generate a starter feature map for this repo (standalone; no install needed): scans Next.js app/pages router, Nuxt, route files, or top-level src/lib modules and writes `features/README.md` + one file per detected feature; never clobbers — an existing map refuses until `--force`, which regenerates the index only |
|
|
104
90
|
|
|
105
91
|
`goblin` remains as a legacy alias for every command above — existing scripts keep working, but
|
|
106
92
|
new commands and docs use `gob`.
|
|
107
93
|
|
|
108
|
-
##
|
|
94
|
+
## Register the harness with your agent (MCP)
|
|
109
95
|
|
|
110
|
-
`gob
|
|
96
|
+
`gob mcp` is a **local MCP tool server**: JSON-RPC 2.0 over stdin/stdout, hand-rolled, no SDK
|
|
97
|
+
and no network — it calls no API and spawns nothing but the repo's vendored verifier. It
|
|
98
|
+
exposes three tools:
|
|
111
99
|
|
|
112
|
-
|
|
|
100
|
+
| tool | what it does |
|
|
113
101
|
|---|---|
|
|
114
|
-
| `
|
|
115
|
-
| `
|
|
116
|
-
| `
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
102
|
+
| `gob_verify` | run the project discipline gate in the repo the agent has open — `PASS`/`FAIL` per row, each FAIL carrying its remedy line. The description is the trigger: *call this before reporting any coding task complete* |
|
|
103
|
+
| `gob_map_status` | read `features/` and the `feature_map:` key: which features exist, their `verified:` dates, and whether each declared entry path still resolves (the read-only half of `FM-02`) |
|
|
104
|
+
| `gob_init_status` | is this repo under the harness — the `AGENTS.md` gob block, its class and gates, the engine version |
|
|
105
|
+
|
|
106
|
+
Register it one of three ways:
|
|
107
|
+
|
|
108
|
+
# 1. per-user, Claude Code:
|
|
109
|
+
claude mcp add gob -- npx -y @techgoblin/gobstack mcp
|
|
110
|
+
|
|
111
|
+
# 2. per-user, Cursor — .cursor/mcp.json:
|
|
112
|
+
{ "mcpServers": { "gob": { "command": "npx", "args": ["-y", "@techgoblin/gobstack", "mcp"] } } }
|
|
113
|
+
|
|
114
|
+
# 3. repo-distributed (Claude Code and Cursor auto-detect a repo-root .mcp.json):
|
|
115
|
+
gob init --with-mcp-config
|
|
116
|
+
|
|
117
|
+
`--with-mcp-config` is ask-once: it writes the generated `.mcp.json`, states a no-op if the
|
|
118
|
+
generated bytes are already there, and **refuses** a file that carries anything else — a
|
|
119
|
+
registration you customized is the project's, never overwritten. `gob uninstall` removes it
|
|
120
|
+
only when it still matches the generated bytes, by the same hash-compare the decision records
|
|
121
|
+
get.
|
|
122
|
+
|
|
123
|
+
## Agent skills
|
|
124
|
+
|
|
125
|
+
**Agent skills are opt-in, and the per-platform emit surface returns in a later alpha.** An
|
|
126
|
+
`init --write` installs the neutral harness only — `.gob/`, `AGENTS.md`, `HANDOFF.md`, the
|
|
127
|
+
checks and the `.gitignore` block; no skills directory, and no files belonging to any coding
|
|
128
|
+
agent. The proposal schema's `sync_platforms:` line is where the platform choice is recorded
|
|
129
|
+
when that surface lands.
|
|
133
130
|
|
|
134
131
|
## What it is not
|
|
135
132
|
|
|
136
133
|
Not a rules document (every rule carries a runnable check or is explicitly counted as
|
|
137
134
|
advisory). Not a Cursor-plugin port (`subagent_type`, `/loop`, `/goal`, cloud agents and
|
|
138
135
|
vendored plugin paths do not exist here). Not a replacement for a project standard — it
|
|
139
|
-
**references** one by path and pins its hash, and carries none of its text.
|
|
136
|
+
**references** one by path and pins its hash, and carries none of its text. And in this alpha,
|
|
137
|
+
not a CI product: nothing is installed under `.github/`, ever.
|
|
140
138
|
|
|
141
139
|
## Read this on GitHub
|
|
142
140
|
|
|
@@ -146,7 +144,7 @@ below is the reference material the guide points into, so the two do not compete
|
|
|
146
144
|
|
|
147
145
|
| file | what it decides |
|
|
148
146
|
|---|---|
|
|
149
|
-
| `docs/GUIDE.md` | **read this first**: the first week, in order —
|
|
147
|
+
| `docs/GUIDE.md` | **read this first**: the first week, in order — init, the first verify, the REPLAY habit |
|
|
150
148
|
| `docs/DESIGN.md` | the thesis, the three load-bearing decisions, and every rejected alternative |
|
|
151
149
|
| `docs/FLOWS.md` | the 15 playbooks, with the 11 cuts and a reason for each |
|
|
152
150
|
| `docs/GUARDRAILS.md` | the security and perf rows (`SC-01`..`SC-09`, `PF-01`), the rung ladder, and what they cannot see |
|
|
@@ -155,10 +153,9 @@ below is the reference material the guide points into, so the two do not compete
|
|
|
155
153
|
| `docs/CONTRACTS.md` | the installer/verifier interface, exit codes, idempotency, uninstall |
|
|
156
154
|
| `docs/INTEGRATION.md` | the board, cron, the skills precedence order, the referenced standard |
|
|
157
155
|
| `docs/RISKS.md` | the risk register, the advisory rows named, the non-goals |
|
|
158
|
-
| `docs/CI.md` | the CI lane: what makes a workflow a gate, the four settings a repository cannot set, and the electron opt-in |
|
|
159
156
|
| `docs/LOOP.md` | the judge role and the loop contract: what a goal-mode loop actually does, the record, and what neither can see |
|
|
160
157
|
| `docs/RECORD-NOTES.md` | the wave codes the changelog and the matrix parentheticals use, one line each |
|
|
161
|
-
| `docs/GLOSSARY.md` | every term of art in one table (rendered from the shipped `.
|
|
158
|
+
| `docs/GLOSSARY.md` | every term of art in one table (rendered from the shipped `.gob/manifest/glossary.tsv`) |
|
|
162
159
|
| `docs/ADOPTION.md` | the five classes, the preset matrix, the adoption order |
|
|
163
160
|
| `docs/LIMITS.md` | where this is weaker than its sources, and what is unproven |
|
|
164
161
|
|
|
@@ -178,60 +175,51 @@ run · `3` the manifest is broken. Every run prints what it cannot see.
|
|
|
178
175
|
bash tests/run-tests.sh
|
|
179
176
|
|
|
180
177
|
Runs the source-scope rules (PR-01..PR-05) and the test scripts, including `t-verify-red.sh` —
|
|
181
|
-
one control per target-scope row (
|
|
182
|
-
restored
|
|
183
|
-
|
|
178
|
+
one control per target-scope row (156 over 80 target rows), each required to go RED and then
|
|
179
|
+
restored. **A verifier that only ever prints GREEN is a failure**, so that file is the one that
|
|
180
|
+
matters most.
|
|
184
181
|
|
|
185
182
|
## Uninstall
|
|
186
183
|
|
|
187
|
-
gobstack lives in
|
|
184
|
+
gobstack lives in layers. Each is removed by its own command, and removing one never
|
|
188
185
|
touches the others.
|
|
189
186
|
|
|
190
187
|
**(a) The global CLI** — the npm package itself:
|
|
191
188
|
|
|
192
189
|
npm uninstall -g @techgoblin/gobstack
|
|
193
190
|
|
|
194
|
-
This removes the `gob` (and legacy `goblin`) commands from the machine and nothing else: no
|
|
195
|
-
repo, no `.
|
|
196
|
-
fully — the engine is vendored into each repo's `.
|
|
197
|
-
capability
|
|
198
|
-
the machine-level skills the CLI wrote).
|
|
191
|
+
This removes the `gob` (and legacy `goblin`) commands from the machine and nothing else: no
|
|
192
|
+
project, no repo, no `.gob/` directory anywhere is touched. Repos you already initialized keep
|
|
193
|
+
working fully — the engine is vendored into each repo's `.gob/`, so the CLI's absence removes no
|
|
194
|
+
capability.
|
|
199
195
|
|
|
200
|
-
**(b) A project's harness** — the `.
|
|
196
|
+
**(b) A project's harness** — the `.gob/` tree an install created in one repo:
|
|
201
197
|
|
|
202
198
|
gob uninstall --target .
|
|
203
199
|
|
|
204
200
|
(equivalently `gob install --target . --uninstall` — through the legacy alias, spell it `goblin`
|
|
205
201
|
instead of `gob`). The uninstall is **byte-exact**: it removes exactly the files
|
|
206
202
|
`installed.json` records — hash-compared preimages, so a file you edited after install is
|
|
207
|
-
reported and kept, never clobbered — then every directory that leaves empty
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
**(c) Global agent skills** — the machine-level skills an `emit --scope global` wrote outside any
|
|
214
|
-
repo:
|
|
215
|
-
|
|
216
|
-
gob emit --undo --platform <p> --scope global
|
|
217
|
-
|
|
218
|
-
(`--undo` is the same byte-exact reversal as `--uninstall`, under its friendlier name). By hand,
|
|
219
|
-
the same job is deleting the platform's anchor entries: `~/.claude/skills/goblin-*` (and the
|
|
220
|
-
equivalents under `~/.hermes`, `~/.copilot`, `~/.cursor`, `~/.config/opencode`, `~/.codex`,
|
|
221
|
-
`~/.gemini` — `gob doctor` lists which platforms were detected).
|
|
203
|
+
reported and kept, never clobbered — then every directory that leaves empty, and it strips the
|
|
204
|
+
`<!-- gob:begin --> … <!-- gob:end -->` block out of `AGENTS.md` (the body prose stays). After
|
|
205
|
+
it, the repo has zero harness files; only the project's own record (`HANDOFF.md`, `AGENTS.md`'s
|
|
206
|
+
prose, `reviews/`, the `.gitignore` block) survives, because that is the project's, not the
|
|
207
|
+
harness's to delete. And because the engine is vendored, the repo needs no gobstack installed to
|
|
208
|
+
run this — it is self-contained until the moment you remove it.
|
|
222
209
|
|
|
223
|
-
The short version, for a full removal from a machine and its repos: (
|
|
224
|
-
|
|
210
|
+
The short version, for a full removal from a machine and its repos: (b) in each initialized
|
|
211
|
+
repo, then (a).
|
|
225
212
|
|
|
226
213
|
## Re-pin the referenced standard
|
|
227
214
|
|
|
228
215
|
gob install --target <dir> --re-pin
|
|
229
216
|
|
|
230
|
-
`practice_sha256:` pins the referenced standard and `IN-02`
|
|
231
|
-
— a legitimate, intended edit — reds `IN-02` in every
|
|
232
|
-
one line and prints the old and new hash; `IN-02`
|
|
233
|
-
|
|
234
|
-
whole contract: `docs/CONTRACTS.md`,
|
|
217
|
+
`practice_sha256:` in the AGENTS.md gob block pins the referenced standard and `IN-02`
|
|
218
|
+
re-checks it, so editing that standard — a legitimate, intended edit — reds `IN-02` in every
|
|
219
|
+
installed repo. `--re-pin` re-records that one line and prints the old and new hash; `IN-02`
|
|
220
|
+
then reports `practice pin ok`. Nothing re-pins automatically, not even a re-install, and the
|
|
221
|
+
`practice EDITED` failure prints this command. The whole contract: `docs/CONTRACTS.md`,
|
|
222
|
+
"An edited standard is not a dead end".
|
|
235
223
|
|
|
236
224
|
## Dependencies
|
|
237
225
|
|
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.
|
|
1
|
+
0.6.0-alpha.1
|
|
@@ -72,17 +72,17 @@ DETAIL=""
|
|
|
72
72
|
for d in $ROOT_GLOB; do
|
|
73
73
|
[ -d "$d" ] || continue
|
|
74
74
|
TARGETS=$((TARGETS + 1))
|
|
75
|
-
if [ ! -f "$d/.
|
|
75
|
+
if [ ! -f "$d/.gob/goblin.yaml" ] && [ ! -f "$d/AGENTS.md" ]; then
|
|
76
76
|
SKIPPED="$SKIPPED $(basename "$d")"
|
|
77
77
|
continue
|
|
78
78
|
fi
|
|
79
|
-
if [ ! -f "$d/.
|
|
79
|
+
if [ ! -f "$d/.gob/bin/goblin-verify" ]; then
|
|
80
80
|
SKIPPED="$SKIPPED $(basename "$d")(no-verifier)"
|
|
81
81
|
continue
|
|
82
82
|
fi
|
|
83
83
|
# --only IN-02,HP-05 rather than a full run: both are builtins that write no runtime state,
|
|
84
84
|
# so the audit never edits the tree it is auditing (design rule 2 of the honesty section).
|
|
85
|
-
OUT=$( cd "$d" && bash .
|
|
85
|
+
OUT=$( cd "$d" && bash .gob/bin/goblin-verify --json --only IN-02,HP-05 2>/dev/null )
|
|
86
86
|
RC=$?
|
|
87
87
|
case "$RC" in
|
|
88
88
|
0|1) ;;
|
|
@@ -91,7 +91,7 @@ for d in $ROOT_GLOB; do
|
|
|
91
91
|
FAILED=$(printf '%s' "$OUT" | grep -o '"id":"[A-Z][A-Z0-9-]*","status":"FAIL"' | sed 's/"id":"//; s/","status":"FAIL"//')
|
|
92
92
|
for id in $FAILED; do
|
|
93
93
|
DRIFT="$DRIFT $d/$id"
|
|
94
|
-
DETAIL="$DETAIL$d $id cd $d && bash .
|
|
94
|
+
DETAIL="$DETAIL$d $id cd $d && bash .gob/bin/goblin-verify --only $id
|
|
95
95
|
"
|
|
96
96
|
done
|
|
97
97
|
done
|
package/bans/layer-check.sh
CHANGED
|
@@ -10,16 +10,18 @@
|
|
|
10
10
|
|
|
11
11
|
set -uo pipefail
|
|
12
12
|
SELF_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
|
|
13
|
-
ROOT=$(cd "$SELF_DIR/../.." && pwd) # .
|
|
14
|
-
CONFIG="$ROOT
|
|
13
|
+
ROOT=$(cd "$SELF_DIR/../.." && pwd) # .gob/bans/ -> repo root
|
|
14
|
+
CONFIG="$ROOT/AGENTS.md"
|
|
15
15
|
[ -f "$CONFIG" ] || { echo "layer-check: no $CONFIG" >&2; exit 2; }
|
|
16
16
|
|
|
17
|
-
layers
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
17
|
+
# v2 config shape: the `layers:` flat key INSIDE the `<!-- gob:begin --> ... <!-- gob:end -->`
|
|
18
|
+
# marker block, one `[from1 to1, from2 to2]` array (each item a from/to pair). The block-bounded
|
|
19
|
+
# sed is the same reader g_agents_gates uses in goblin-lib.sh; a line outside the markers is
|
|
20
|
+
# prose and is never read.
|
|
21
|
+
block=$(sed -n "/^<!-- gob:begin/,/^<!-- gob:end/p" "$CONFIG" | sed '1d;$d')
|
|
22
|
+
layers=$(printf '%s\n' "$block" | sed -n 's/^layers:[[:space:]]*//p' | tr ',' '\n' \
|
|
23
|
+
| sed 's/^[[:space:]]*//; s/[[:space:]]*$//; s/^\[//; s/\]$//' | grep -v '^$' || true)
|
|
24
|
+
[ -n "$layers" ] || { echo "no layers declared in $CONFIG - declare layers: in the gob block to turn BN-05 on"; exit 3; }
|
|
23
25
|
|
|
24
26
|
bad=""
|
|
25
27
|
while read -r from to; do
|