geneseed 3.19.0 → 4.0.0
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 +41 -0
- package/README.md +9 -1
- package/SHIPPED.md +1 -1
- package/adapters/bob/README.md +31 -12
- package/adapters/claude-code/README.md +24 -17
- package/adapters/claude-code/settings.json +4 -6
- package/adapters/openclaude/README.md +13 -5
- package/adapters/opencode/plugins/geneseed-guard.js +291 -174
- package/bin/geneseed-hook.mjs +36 -5
- package/docs/README.md +3 -1
- package/docs/candidate-hosts.md +0 -8
- package/docs/concepts/enforcement-table.md +66 -0
- package/docs/concepts/hook-gates.md +2 -2
- package/docs/concepts/hooks.md +6 -6
- package/docs/concepts/host-matrix.md +4 -3
- package/docs/concepts/loop-branch.md +6 -1
- package/docs/concepts/loops.md +4 -3
- package/docs/concepts/rules.md +1 -1
- package/docs/design-history.md +59 -0
- package/docs/extending.md +11 -3
- package/docs/guides/install-opencode.md +1 -1
- package/docs/guides/loop-running.md +1 -1
- package/docs/reference/env-context.md +3 -2
- package/docs/reference/environment.md +2 -1
- package/docs/reference/plugin-guard.md +3 -3
- package/docs/reference/troubleshoot-hooks.md +34 -0
- package/docs/understand/design-choices-engineering.md +29 -0
- package/docs/understand/design-choices-gates.md +23 -0
- package/docs/understand/design-choices-hosts.md +21 -0
- package/docs/understand/design-choices-install.md +19 -0
- package/docs/understand/design-choices-shape.md +21 -0
- package/docs/understand/design-choices.md +34 -0
- package/docs/understand/enforced-vs-asked.md +5 -4
- package/docs/understand/machine-bob.md +1 -1
- package/docs/understand/machine-opencode.md +2 -2
- package/harness.config.json +1 -1
- package/js/build/driver.mjs +42 -16
- package/js/build/emit-claude.mjs +24 -8
- package/js/build/emit-opencode.mjs +33 -15
- package/js/build/generate.mjs +38 -9
- package/js/build/source.mjs +39 -0
- package/js/build/stubs.mjs +2 -1
- package/js/cli-table.json +6 -6
- package/js/hosts/gitref.mjs +3 -3
- package/js/hosts/hooks-context.mjs +13 -31
- package/js/hosts/hooks-learn.mjs +89 -8
- package/js/hosts/hooks.mjs +212 -18
- package/js/hosts/hosts.mjs +217 -13
- package/js/hosts/installs.mjs +259 -46
- package/js/hosts/native.mjs +48 -12
- package/js/hosts/opencode.mjs +47 -17
- package/js/hosts/settings.mjs +366 -42
- package/js/hosts/shim.mjs +37 -0
- package/js/inspect/checks-authoring.mjs +81 -1
- package/js/inspect/checks-constitution.mjs +2 -1
- package/js/inspect/checks-repo.mjs +68 -4
- package/js/inspect/doctor.mjs +40 -9
- package/js/inspect/scan.mjs +5 -4
- package/js/inspect/status.mjs +62 -12
- package/js/lib/text.mjs +23 -0
- package/js/loop/catalog.mjs +7 -2
- package/js/loop/state.mjs +2 -2
- package/js/maintain/migrate.mjs +42 -5
- package/js/maintain/uninstall.mjs +150 -38
- package/js/maintain/update.mjs +22 -2
- package/js/web/actions.mjs +28 -10
- package/js/web/api.mjs +5 -3
- package/js/web/catalog.mjs +1 -1
- package/js/web/state.mjs +28 -15
- package/package.json +1 -1
- package/src/agents/_template.md +1 -1
- package/src/bricks/_template.md +1 -1
- package/src/bricks/apply.md +1 -1
- package/src/bricks/test.md +1 -1
- package/src/doctrines/ops.md +9 -7
- package/src/doctrines/process.md +3 -3
- package/src/laws/universal.md +1 -1
- package/src/loops/api-endpoint.json +1 -1
- package/src/loops/bugfix.json +1 -1
- package/src/loops/ci-repair.json +1 -1
- package/src/loops/deps-upgrade.json +1 -1
- package/src/loops/enforce-architecture-rule.json +1 -1
- package/src/loops/feature.json +1 -1
- package/src/loops/fix-flaky-tests.json +1 -1
- package/src/loops/legacy-refactor.json +1 -1
- package/src/loops/legacy-tests.json +1 -1
- package/src/loops/refactor.json +1 -1
- package/src/loops/remove-dead-code.json +1 -1
- package/src/loops/spec-first-feature.json +1 -1
- package/src/loops/tdd.json +1 -1
- package/src/loops/update-contract.json +1 -1
- package/src/skills/_template.md +3 -3
- package/src/skills/herdr.md +1 -1
- package/web/dist/assets/{Activity-IbwdHHyx.js → Activity-BCtqxjfy.js} +1 -1
- package/web/dist/assets/{ActivityDetail-B5uivdWI.js → ActivityDetail-Ba3Oo4dE.js} +1 -1
- package/web/dist/assets/{Dashboard-v6WQ37bD.js → Dashboard-DpHza68-.js} +2 -2
- package/web/dist/assets/{Docs-CypIfDBX.js → Docs-Bw_-UK0O.js} +1 -1
- package/web/dist/assets/{GreenhouseView-ClxP0hQG.js → GreenhouseView-DnJ1Ggp1.js} +1 -1
- package/web/dist/assets/{Installs-CPkQeFjO.js → Installs-CWoNKFBk.js} +1 -1
- package/web/dist/assets/{JournalView-BeEInhUf.js → JournalView-g6-bw4c8.js} +1 -1
- package/web/dist/assets/{Laws-Ds6U5xBQ.js → Laws-DkVWR1tb.js} +1 -1
- package/web/dist/assets/{Library-BraUKPyQ.js → Library-CK9HZzjV.js} +1 -1
- package/web/dist/assets/{Loops-DWcy3mwK.js → Loops-BP98SMOH.js} +1 -1
- package/web/dist/assets/{OperatorHudView-CQyrJQ9m.js → OperatorHudView-DI_n12M9.js} +1 -1
- package/web/dist/assets/{Personal-YWqs6qFL.js → Personal-Bk89f13a.js} +1 -1
- package/web/dist/assets/{Tabs-EhzEC-Xh.js → Tabs-3WuYIE1b.js} +1 -1
- package/web/dist/assets/{drawable-CEKPNV7X.js → drawable-oCUeq9e5.js} +1 -1
- package/web/dist/assets/{index-CPi22b7y.js → index-CiXwChvf.js} +2 -2
- package/web/dist/index.html +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -8,6 +8,47 @@ label. For the capability ↔ spec map, see [SHIPPED.md](SHIPPED.md).
|
|
|
8
8
|
|
|
9
9
|
## [Unreleased]
|
|
10
10
|
|
|
11
|
+
## [4.0.0] — 2026-10-11
|
|
12
|
+
|
|
13
|
+
Major: a host-compatibility pass against the current IBM Bob, Claude Code, OpenCode and OpenClaude docs (#240), the host opportunities and a root-scan guard (#241), and author notes kept out of what the agent reads (#242). It is a major because three behaviours change visibly: Claude Code gates now block when they cannot run, OpenCode no longer falls back to `~/.claude/CLAUDE.md`, and the silent *process 8* migration is gone.
|
|
14
|
+
|
|
15
|
+
### Upgrade notes
|
|
16
|
+
- Run `geneseed rebuild-all` once after updating: nothing on a machine changes until an install is re-emitted.
|
|
17
|
+
- An install built before the comms pack (3.7.0) is now skipped by `rebuild-all`, `migrate` and `upgrade`; run `geneseed setup` for it.
|
|
18
|
+
- If a Claude Code session suddenly refuses every Bash or Write call, the machine-wide hook shim is missing or stale: run `! geneseed rebuild-all` (see docs/reference/troubleshoot-hooks.md).
|
|
19
|
+
|
|
20
|
+
### Added
|
|
21
|
+
- A Claude Code plugin marketplace: `/plugin marketplace add Arylmera/Geneseed`, then `/plugin install geneseed@geneseed`. The plugin carries one skill, `/geneseed:setup`, which asks for scope and theme and runs the published CLI (`npm install -g geneseed`, `geneseed build --emit claude-global` or `--emit claude`). It carries no harness of its own, so nothing in it can drift from the build.
|
|
22
|
+
- Bob gets `/`-commands: each skill alias and each user-only skill is a `.bob/commands/<name>.md`, and a user-only skill writes no SKILL.md on Bob, so the model cannot start it there.
|
|
23
|
+
- OpenCode hides user-only skills from the model: each one gets a `permission.skill` deny in `opencode.json`, and `/name` still runs it. Geneseed records the denies it writes in its manifest (`skill_denies`); a rebuild removes a recorded deny once the skill is no longer user-only, and uninstall takes the recorded ones back. A deny you set yourself, even on a Geneseed skill, is never touched.
|
|
24
|
+
- A root-scan check in the shell gate: a recursive scan whose argument is a whole filesystem root (`find /`, `du -sh /`, `grep -r foo /`, `rg x C:\`, `Get-ChildItem C:\ -Recurse`) now asks on Claude Code and OpenClaude and is refused on Bob and by the OpenCode guard plugin, citing *Commands Must Return* (ops 2), which gains a sentence saying so in both halves. In Git Bash `/` mounts every drive and share: a `find / … | head -5` ran for 3.5 hours on 2026-10-10. A deeper path, `ls /` without `-R`, a quoted argument, a comment, and the remote half of an `ssh` command pass. It runs inside `git-gate`/`tool-gate`, so no emitted hook command changes. Separators inside quotes and heredoc bodies are data, so a commit message that names such a scan is not one.
|
|
25
|
+
- A dedicated author-note prefix: an HTML comment in `src/` whose body starts with `note:` (`<!-- note: ... -->`, single or multi-line) is stripped before any render sees it — `resolveRuleIds` in `js/build/source.mjs` is the one function every text file threads through (and `parseBrick` in `js/loop/catalog.mjs` calls the same `stripAuthorNotes` directly, since a brick body is handed to the model raw and never goes through `resolveRuleIds` at all), so the strip covers the carrier, the on-disk `laws/`/`doctrines/` copies, every skill, and every brick alike. A comment shown only as a literal example — inside a fenced code block or an inline code span — is left un-stripped, via `blankCodeSpans` (`js/lib/text.mjs`, shared with the doctor arm below so the two can never disagree about what counts as "shown as an example"). Maintainer-only prose that used to ship verbatim (`src/laws/universal.md`'s "Amend BOTH halves", `src/skills/herdr.md`'s "Authoring note") is migrated to the prefix and no longer reaches the agent; the full carrier gains ~176 characters of headroom against its ceiling (unchanged, not lowered), lean is unaffected. `js/inspect/checks-authoring.mjs`'s new `authorNoteProblems` (wired into `doctor --all`) flags any other bare HTML comment in `src/` that is not the `note:` prefix and not a known functional marker (`LEAN:`/`CATALOG:`/`INCLUDE:`, `invocation: user`, `aliases:`, `webfetch: allow`, `harness:` followed by one or more of OpenCode/Claude Code/OpenClaude/Bob's ids, `bash: allow`), the same fence/code-span exemption applied, and separately refuses a `note:` comment whose own prose quotes a literal `<!--`/`-->` — HTML comments do not nest, so such a comment closes at its own inner marker and leaks the rest as live text (the landmine `src/skills/_template.md` hit once, fixed there by rewording the example to prose).
|
|
26
|
+
|
|
27
|
+
### Changed
|
|
28
|
+
- Claude Code gates now block the tool call when the gate itself fails: `git-gate` and `rule-gate` carry `onFailure: "block"`, so a dead or missing shim, a gate process that crashes or a timeout refuses every Bash, PowerShell, Write, Edit and NotebookEdit call instead of letting it through. This needs Claude Code v2.1.295 or later; whether an older version ignores the key or rejects the settings file is unverified. `doctor` and `status` now report a deleted shim. To recover from inside a blocked session, see [Troubleshoot hooks](docs/reference/troubleshoot-hooks.md). OpenClaude and Bob are unchanged.
|
|
29
|
+
|
|
30
|
+
### Removed
|
|
31
|
+
- The automatic *process 8* migration. An install built before the comms pack (3.7.0, 2026-09-27) used to be silently rewritten on every rebuild: `doctrinesOfDir` added `comms` so the codes rule it carried inside `process` was not lost, and `excludedRulesOfDir` re-addressed any `process 7`/`process 8` exclusion. Both relied on sniffing `process 8` in the rendered carrier, which breaks the day the process pack ever regains an eighth rule for an unrelated reason — it would then fire on a current install and rewrite data nobody asked rewritten. 4.0.0 removes the rewrite: a pre-comms carrier is now read exactly as written, and reading it (`doctor`, `diff`, `status`, `uninstall`) prints a warning on stderr instead, once per process. `rebuild-all` (and `upgrade`, which shells into it) now **skips** a pre-comms install entirely rather than re-emitting it — re-emitting would have written a fresh carrier that still drops `comms` and still carries unaddressed `process 7`/`process 8` exclusions, except now permanently, with no `process 8` text left for anything to ever catch again. **Upgrading:** if your install predates 3.7.0 and still names `process 8` in its carrier, run `geneseed setup` for it — `rebuild-all`/`upgrade` will skip it and name it in their summary until you do.
|
|
32
|
+
|
|
33
|
+
### Fixed
|
|
34
|
+
- Bob gates read Bob's own payload (`{event, tool, input}`); they used to read only `tool_input`, so on Bob no gate ever fired. Bob also scans `apply_diff` and `search_and_replace` bodies.
|
|
35
|
+
- The Claude Code and OpenClaude git gate also matches the PowerShell tool (`Bash|PowerShell`); on Windows a destructive git command run through PowerShell used to pass unchecked. Read-only agents deny PowerShell too.
|
|
36
|
+
- A hook argv error never exits 2: a stale machine-wide shim handed a newer flag used to block every tool call.
|
|
37
|
+
- Windows without Git Bash: Claude Code runs hooks under PowerShell, where the emitted command was a parse error. The emit now detects Git Bash and writes a PowerShell form when it is absent; `doctor` and `status` warn when the machine changes after the emit.
|
|
38
|
+
- `CLAUDE_CONFIG_DIR` is honoured. A global hook stands down only for a live project install in `$CLAUDE_PROJECT_DIR` whose settings file still runs the same hook, never for a parent folder, another global install, a deactivated install or a manifest alone.
|
|
39
|
+
- The destructive-git gate also covers `clean --force`, `restore`, `push --delete` and `:branch`, `checkout -f`, `switch -f`, `stash drop/clear`, `worktree remove --force`, `reflog expire` and `gc --prune`, in the hook, the OpenCode guard and OpenCode's permissions.
|
|
40
|
+
- OpenCode: the guard checks every path an `apply_patch` touches (the only edit tool of gpt-* models) and scans written content for secrets; per-repo builds honour `--footprint lean`; plugins, workflows and themes are claimed on create, so a same-named user file survives emit and uninstall; a one-line managed `AGENTS.md` stops OpenCode loading the harness a second time through `~/.claude/CLAUDE.md`; a shadowed install under `OPENCODE_CONFIG_DIR` is reported. The dead `permission.ask` loop exemption is removed; pushes to `loop/*` are allowed by a static rule, and force, delete, an extra refspec and commits still ask.
|
|
41
|
+
- Settings are read back per host, so `rebuild-all`, `upgrade` and the console keep an OpenClaude per-repo install's theme, posture, packs and exclusions, also in a repo shared with another host.
|
|
42
|
+
- Uninstalling one host from a shared repo hands the root marker to the surviving host instead of deleting it; `migrate` reads the settings file the install really wired.
|
|
43
|
+
- `learn` cannot recurse through `claude -p`, reads nothing when `GENESEED_LLM` is unset, and returns at once on Bob, which sends no transcript.
|
|
44
|
+
- `learn` on `SubagentStop` reads the subagent's own transcript (`agent_transcript_path`); it used to distil a lesson from the main session's. When the transcript cannot be read, or lags behind the final turn, it falls back to or appends `last_assistant_message`.
|
|
45
|
+
|
|
46
|
+
## [3.20.0] — 2026-10-09
|
|
47
|
+
|
|
48
|
+
### Changed
|
|
49
|
+
- Loops repair twice before giving up: the test repair rings (`apply-test`, `fix-test`, `write-run`, `stabilise`) now allow two repairs instead of one, then the attempt is discarded for one fresh try, then the loop stops for you. The first revision carries most of the gain, but a second still lands fixes the first missed. Bound the Loop, the `apply` and `test` bricks and the loops concept page say two. Review rings are unchanged.
|
|
50
|
+
- The fallback to the old wiki manifest name (`wiki.jsonc`) stays for now, against the 3.18.0 note that it would go in the next release: nothing yet reports an install that missed the rename, so removing it could drop a wiki in silence.
|
|
51
|
+
|
|
11
52
|
## [3.19.0] — 2026-10-09
|
|
12
53
|
|
|
13
54
|
### Added
|
package/README.md
CHANGED
|
@@ -90,6 +90,14 @@ npm install -g geneseed # then plain `geneseed <command>` from any directo
|
|
|
90
90
|
npm install -g geneseed@latest # …and that is also the update
|
|
91
91
|
```
|
|
92
92
|
|
|
93
|
+
Already in Claude Code? Add the plugin marketplace and let Claude run the install:
|
|
94
|
+
|
|
95
|
+
```
|
|
96
|
+
/plugin marketplace add Arylmera/Geneseed
|
|
97
|
+
/plugin install geneseed@geneseed
|
|
98
|
+
/geneseed:setup
|
|
99
|
+
```
|
|
100
|
+
|
|
93
101
|
Every other route (Claude Code, Bob, OpenClaude, plain `AGENT.md`, per-repo installs) is in the **[install guide](docs/guides/install.md)**.
|
|
94
102
|
|
|
95
103
|
### 🧬 The long way — a git checkout
|
|
@@ -238,7 +246,7 @@ is **identical on every host**. What differs is how much of it the host can
|
|
|
238
246
|
| **Colour themes** | ✅ full palette | ➖ | ➖ | ➖ |
|
|
239
247
|
| **LSP · workflow runner · primary-agent · `/`-commands** | ✅ | ➖ | ➖ | ➖ |
|
|
240
248
|
|
|
241
|
-
<sub>✅ native support · ⚙️ OpenCode plugin · 🪝 `settings.json` hook · 📄 carried by preamble prose only · ➖ no host mechanism (harness discipline still applies) · ¹ Bob's own hook contract: global hooks in `~/.bob/settings/settings.json`, Claude's event names but stdout ignored on `PreToolUse` — a refusal is **exit code 2**. So Laws I/IV exit 2, the consent rules are a stderr line, `SessionStart` context is plain stdout, `Stop` runs learn; `SubagentStop`/`PreCompact` are not Bob events and are not written. Unverified live (no Bob install on the authoring machine); the harness still holds via the rules preamble. · ² OpenCode's `tool.execute.before` can only allow or throw, with no "ask the user" tier, so the rule gate is a one-shot speed bump there rather than a prompt. · ³ OpenClaude is a Claude Code fork: Claude's hook groups and verdicts verbatim, in `~/.openclaude/settings.json` (global) or `.openclaude/settings.local.json` (per repo). Unverified live (no OpenClaude install on the authoring machine).</sub>
|
|
249
|
+
<sub>✅ native support · ⚙️ OpenCode plugin · 🪝 `settings.json` hook · 📄 carried by preamble prose only · ➖ no host mechanism (harness discipline still applies) · ¹ Bob's own hook contract: global hooks in `~/.bob/settings/settings.json`, Claude's event names but stdout ignored on `PreToolUse` — a refusal is **exit code 2**. So Laws I/IV, rigor-5 (External Gate) and ops-2 (a recursive scan of a whole filesystem) exit 2, the consent rules are a stderr line, `SessionStart` context is plain stdout, `Stop` runs learn; `SubagentStop`/`PreCompact` are not Bob events and are not written. Unverified live (no Bob install on the authoring machine); the harness still holds via the rules preamble. · ² OpenCode's `tool.execute.before` can only allow or throw, with no "ask the user" tier, so the rule gate is a one-shot speed bump there rather than a prompt. · ³ OpenClaude is a Claude Code fork: Claude's hook groups and verdicts verbatim, in `~/.openclaude/settings.json` (global) or `.openclaude/settings.local.json` (per repo). Unverified live (no OpenClaude install on the authoring machine).</sub>
|
|
242
250
|
|
|
243
251
|
**Reading the matrix.** Everything above the divider is at full parity — no host
|
|
244
252
|
drops an Agent, Skill, or the memory convention. The asymmetry is entirely in
|
package/SHIPPED.md
CHANGED
|
@@ -20,7 +20,7 @@ historical references, not files distributed with the repo.
|
|
|
20
20
|
> **On version numbers.** [`harness.config.json`](harness.config.json)'s `version` is a
|
|
21
21
|
> human-readable label only. The canonical identity of an installed harness is the
|
|
22
22
|
> **source fingerprint** stamped in `.geneseed-version` (see `geneseed version`), not the
|
|
23
|
-
> string. Current label: **
|
|
23
|
+
> string. Current label: **4.0.0**.
|
|
24
24
|
|
|
25
25
|
## Capabilities
|
|
26
26
|
|
package/adapters/bob/README.md
CHANGED
|
@@ -99,16 +99,22 @@ What the global emit writes into `~/.bob/settings/settings.json`:
|
|
|
99
99
|
| event | verb | how the verdict travels |
|
|
100
100
|
| --- | --- | --- |
|
|
101
101
|
| `SessionStart` | `context --host bob` | plain stdout, as on Claude |
|
|
102
|
-
| `PreToolUse` | `tool-gate --host bob` — one group, no matcher | Laws I/IV: **exit 2**, reason on stderr; process 1/5: a stderr line, exit 0 |
|
|
102
|
+
| `PreToolUse` | `tool-gate --host bob` — one group, no matcher | Laws I/IV, rigor-5 and ops-2: **exit 2**, reason on stderr; process 1/5: a stderr line, exit 0 |
|
|
103
103
|
| `Stop` | `learn` | never a verdict |
|
|
104
104
|
|
|
105
|
-
No matcher on `PreToolUse
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
105
|
+
No matcher on `PreToolUse`, deliberately: Bob's tools page already drifts from its own
|
|
106
|
+
changelog (`web_fetch`, the 2.1.0 Office/IBM-docs tools are undocumented there), so an
|
|
107
|
+
allow-list built from it would fail open on the next tool Bob adds, and a deny-list needs a
|
|
108
|
+
regex dialect (lookahead) the docs never confirm — bob-verdict.md O1 rates the matcher's own
|
|
109
|
+
upside "low, performance only", not worth either risk. `tool-gate` reads the payload's shape
|
|
110
|
+
instead — a `command` field gets the git checks, a path gets the rule checks — and defers on
|
|
111
|
+
anything it does not recognise. Bob has **no "ask the user" tier**, so the Laws and checks
|
|
112
|
+
that admit no judgement call — Laws I and IV, rigor-5 (External Gate, when a project
|
|
113
|
+
opts in) and ops-2 (Commands Must Return: a recursive scan rooted at a whole filesystem) —
|
|
114
|
+
are refused outright, and the two consent rules become a warning. Because that
|
|
115
|
+
warning is all process 5 can be here, the `process` pack toggle changes nothing in Bob's
|
|
116
|
+
hooks: the one group only ever exits 2 for Laws I and IV, rigor-5 and ops-2, which every build
|
|
117
|
+
carries.
|
|
112
118
|
|
|
113
119
|
**Migration.** A re-emit over an older install unwires Geneseed's groups from the flat
|
|
114
120
|
`~/.bob/settings.json` (your own keys there are kept) and writes the new set to the
|
|
@@ -140,10 +146,23 @@ MCP servers are wired at runtime (web console, listed by `geneseed mcp`) into th
|
|
|
140
146
|
`~/.bob/settings/mcp.json` global — never `settings.json`, which Bob does not read
|
|
141
147
|
servers from ([Bob docs](https://bob.ibm.com/docs/ide/configuration/mcp/mcp-in-bob)).
|
|
142
148
|
|
|
149
|
+
## Slash commands
|
|
150
|
+
|
|
151
|
+
Bob documents `.bob/commands/*.md` (project) and `~/.bob/commands/*.md` (global), with
|
|
152
|
+
`description` frontmatter (bob-docs.md §6 — no use for `argument-hint` yet: no Geneseed
|
|
153
|
+
skill takes positional arguments). Geneseed writes one command per merged skill's OLD name
|
|
154
|
+
(`/old-name`, the same alias problem OpenCode's `command/` layer solves) and one per
|
|
155
|
+
genuinely user-only skill (host-compat O2/R1): Bob's skills page documents only
|
|
156
|
+
`name`/`description`, no model-invocation key, so a user-only skill gets **no** SKILL.md on
|
|
157
|
+
Bob at all — `/its-name` is the only way to run it, and the model never sees it in its
|
|
158
|
+
`use_skill` catalogue. Claim-on-create and manifest-owned like every other native file;
|
|
159
|
+
uninstall removes them the same way.
|
|
160
|
+
|
|
143
161
|
## What Bob does not get
|
|
144
162
|
|
|
145
163
|
Bob rides the Claude engine, so — like Claude — it has no OpenCode-only extras:
|
|
146
|
-
colour themes, JS plugins, the saved-workflow runner, the primary-agent
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
164
|
+
colour themes, JS plugins, the saved-workflow runner, the primary-agent orchestrator,
|
|
165
|
+
LSP enablement, or OpenCode's full `/`-command layer (`COMMAND_SET`, `/ponytail`) — only
|
|
166
|
+
the narrow alias/user-only-skill commands above. Those capabilities have no analogue on a
|
|
167
|
+
Claude-shaped host; the harness discipline is carried by the preamble and skills instead.
|
|
168
|
+
See the [host matrix](../../README.md#-supported-harnesses).
|
|
@@ -14,7 +14,7 @@ bin/geneseed-hook.mjs …` — so at user scope they would fire and fail in ever
|
|
|
14
14
|
repo that doesn't vendor the harness. A generated global install wires
|
|
15
15
|
absolute-path hooks instead — `geneseed setup` does that for you.) It:
|
|
16
16
|
|
|
17
|
-
- on **PreToolUse** (matcher `Bash`), runs `geneseed-hook git-gate` — the tool-boundary
|
|
17
|
+
- on **PreToolUse** (matcher `Bash|PowerShell`), runs `geneseed-hook git-gate` — the tool-boundary
|
|
18
18
|
half of Doctrine process 5 (*consent before every commit and push*) and of the
|
|
19
19
|
destructive-git Rule. Drop the `process` pack (or exclude process 5) and the hook stays,
|
|
20
20
|
wired with `--no-consent`: commits and pushes pass without asking, while the
|
|
@@ -27,22 +27,27 @@ absolute-path hooks instead — `geneseed setup` does that for you.) It:
|
|
|
27
27
|
next time regardless. Every other Bash command (and any unreadable payload) is
|
|
28
28
|
deferred to the normal permission flow — the hook never blocks unrelated work.
|
|
29
29
|
|
|
30
|
-
**Caveat — the GitHub MCP vector.** The hook matches the `Bash`
|
|
31
|
-
session has the GitHub MCP server, an agent can commit/push via
|
|
32
|
-
`create_or_update_file` / `merge_pull_request`, which bypass
|
|
33
|
-
widen the matcher to `"Bash|mcp__github__.*"` —
|
|
34
|
-
doesn't recognise as a commit/push, so
|
|
35
|
-
-
|
|
30
|
+
**Caveat — the GitHub MCP vector.** The hook matches the `Bash` and `PowerShell` tools
|
|
31
|
+
only. If your session has the GitHub MCP server, an agent can commit/push via
|
|
32
|
+
`push_files` / `create_or_update_file` / `merge_pull_request`, which bypass both. To
|
|
33
|
+
gate those too, widen the matcher to `"Bash|PowerShell|mcp__github__.*"` —
|
|
34
|
+
`git-gate` ignores any payload it doesn't recognise as a commit/push, so
|
|
35
|
+
over-matching the tool surface is harmless.
|
|
36
|
+
- on **PreToolUse** (matcher `Write|Edit|NotebookEdit`), runs
|
|
36
37
|
`geneseed-hook rule-gate` — refuses a write that would put a credential into a tracked
|
|
37
38
|
file, and asks first on the first write to `user-rules.md` or a memory file (whether
|
|
38
39
|
something you want kept is a rule or a fact is your call). Ordinary edits pass.
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
is
|
|
40
|
+
(`MultiEdit` is not a Claude Code tool and is not in the matcher; the gate reads
|
|
41
|
+
`edits[].new_string` as a cheap guard regardless.)
|
|
42
|
+
- on **SessionStart**, every source (`startup`, `resume`, `clear`, `compact`, `fork`), runs
|
|
43
|
+
`geneseed-hook context` to **inject the project context** directly into the session — so
|
|
44
|
+
the project-context load is by the hook, not left to the agent to remember (lazy entries
|
|
45
|
+
are only listed). This is one matcher-less group, exactly as a generated install wires it:
|
|
46
|
+
a matcher list is one more place to miss a source (`fork` once was). A second group,
|
|
47
|
+
`startup`/`clear` only — a fresh context — prints `AGENT.md` so the vendored harness is in
|
|
48
|
+
context from the first turn. A generated install has no such group: its root file is
|
|
49
|
+
`CLAUDE.md`, which Claude Code loads by itself. A resumed or forked conversation already
|
|
50
|
+
carries the harness, so re-printing the static file there is pure token waste;
|
|
46
51
|
- on **Stop**, runs `geneseed-hook learn` over the session to capture durable memories.
|
|
47
52
|
Claude Code pipes the hook payload (with the session's `transcript_path`) to the
|
|
48
53
|
command on stdin; `learn` reads that, flattens the transcript, distils new
|
|
@@ -59,12 +64,14 @@ absolute-path hooks instead — `geneseed setup` does that for you.) It:
|
|
|
59
64
|
- on **PreCompact**, runs the same `geneseed-hook learn` once more. `learn` distils the
|
|
60
65
|
*tail* of the transcript, so per-turn Stop is a sliding window over the session —
|
|
61
66
|
and auto-compaction is the moment that window is about to be summarised away.
|
|
62
|
-
This captures memory *before* the summary; the SessionStart `
|
|
63
|
-
re-seeds context *after* it.
|
|
67
|
+
This captures memory *before* the summary; the SessionStart `context` hook (which
|
|
68
|
+
also fires on the `compact` source) re-seeds context *after* it.
|
|
64
69
|
|
|
65
70
|
This step is **opt-in on a model CLI**: set `GENESEED_LLM` (e.g. `claude -p`,
|
|
66
71
|
`llm`, `ollama run …`) for `learn` to actually distil. With it unset the hook is
|
|
67
|
-
a harmless no-op
|
|
72
|
+
a harmless no-op — it returns immediately rather than reading the transcript for
|
|
73
|
+
nothing; running `learn` by hand with notes piped in still prints the prompt it
|
|
74
|
+
would have sent. Geneseed never embeds an API key.
|
|
68
75
|
If your bundle's `memory/` is not at `./memory` or `./Harness/memory`, point at
|
|
69
76
|
it with `GENESEED_MEMORY=/abs/path/to/memory`.
|
|
70
77
|
|
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
"hooks": {
|
|
3
3
|
"PreToolUse": [
|
|
4
4
|
{
|
|
5
|
-
"matcher": "Bash",
|
|
5
|
+
"matcher": "Bash|PowerShell",
|
|
6
6
|
"hooks": [
|
|
7
7
|
{ "type": "command", "command": "node bin/geneseed-hook.mjs git-gate" }
|
|
8
8
|
]
|
|
9
9
|
},
|
|
10
10
|
{
|
|
11
|
-
"matcher": "Write|Edit|
|
|
11
|
+
"matcher": "Write|Edit|NotebookEdit",
|
|
12
12
|
"hooks": [
|
|
13
13
|
{ "type": "command", "command": "node bin/geneseed-hook.mjs rule-gate" }
|
|
14
14
|
]
|
|
@@ -16,16 +16,14 @@
|
|
|
16
16
|
],
|
|
17
17
|
"SessionStart": [
|
|
18
18
|
{
|
|
19
|
-
"matcher": "startup|clear",
|
|
20
19
|
"hooks": [
|
|
21
|
-
{ "type": "command", "command": "node -e \"process.stdout.write(require('fs').readFileSync('AGENT.md','utf8'))\"" },
|
|
22
20
|
{ "type": "command", "command": "node bin/geneseed-hook.mjs context" }
|
|
23
21
|
]
|
|
24
22
|
},
|
|
25
23
|
{
|
|
26
|
-
"matcher": "
|
|
24
|
+
"matcher": "startup|clear",
|
|
27
25
|
"hooks": [
|
|
28
|
-
{ "type": "command", "command": "node
|
|
26
|
+
{ "type": "command", "command": "node -e \"process.stdout.write(require('fs').readFileSync('AGENT.md','utf8'))\"" }
|
|
29
27
|
]
|
|
30
28
|
}
|
|
31
29
|
],
|
|
@@ -12,14 +12,21 @@ There is nothing to install by hand: `geneseed setup` (or `geneseed-build --emit
|
|
|
12
12
|
openclaude` / `--emit openclaude-global`) writes everything.
|
|
13
13
|
|
|
14
14
|
**OpenClaude never reads `~/.claude`, a project `.claude/`, or `$CLAUDE_CONFIG_DIR`.**
|
|
15
|
-
A Claude Code install is invisible to it, so it gets its own
|
|
16
|
-
|
|
15
|
+
A Claude Code install is invisible to it, so it gets its own, and neither emit
|
|
16
|
+
overwrites the other's files. On one machine the two coexist cleanly. In one
|
|
17
|
+
repo they do not fully: OpenClaude also reads the root `CLAUDE.md`/`AGENTS.md`
|
|
18
|
+
a Claude Code or Bob per-repo install already wrote there, on top of its own
|
|
19
|
+
`.openclaude/CLAUDE.md` — both harnesses load, and there is no clean exclusion
|
|
20
|
+
(excluding the root file would hide your own content in it too). `geneseed status`
|
|
21
|
+
and `geneseed doctor` warn when this is happening in your repo.
|
|
17
22
|
|
|
18
23
|
## What the emit writes
|
|
19
24
|
|
|
20
25
|
### Per-repo (`--emit openclaude`)
|
|
21
26
|
|
|
22
|
-
Everything lives under **`.openclaude
|
|
27
|
+
Everything lives under **`.openclaude/`**, except the `.geneseed-emit`/
|
|
28
|
+
`.geneseed-footprint` markers and `.mcp.json` below, which the driver writes at the
|
|
29
|
+
repo root like every other host.
|
|
23
30
|
|
|
24
31
|
- `CLAUDE.md`: the harness preamble as a delimited **managed block**. OpenClaude
|
|
25
32
|
loads the root `AGENTS.md`, or the root `CLAUDE.md` only when `AGENTS.md` is
|
|
@@ -47,8 +54,9 @@ global config file.
|
|
|
47
54
|
|
|
48
55
|
## Hooks
|
|
49
56
|
|
|
50
|
-
The Claude group set, unchanged: `PreToolUse` (git gate on `Bash`, rule gate on
|
|
51
|
-
writes), `SessionStart` (context on
|
|
57
|
+
The Claude group set, unchanged: `PreToolUse` (git gate on `Bash|PowerShell`, rule gate on
|
|
58
|
+
writes), `SessionStart` (context on every source — one matcher-less group covers
|
|
59
|
+
`startup`, `resume`, `clear`, `compact` and `fork` alike), `Stop`,
|
|
52
60
|
`SubagentStop` and `PreCompact` (learn). OpenClaude reads Claude's
|
|
53
61
|
`hookSpecificOutput.permissionDecision`, so the gates **ask** where Claude asks.
|
|
54
62
|
The context hook carries `--host openclaude` for one reason. It tells the hook
|