geneseed 3.10.0 → 3.12.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 +96 -0
- package/DESIGN.md +1 -1
- package/README.md +27 -45
- package/SHIPPED.md +2 -2
- package/adapters/bob/README.md +1 -1
- package/adapters/claude-code/README.md +17 -12
- package/adapters/openclaude/README.md +1 -1
- package/adapters/opencode/README.md +4 -4
- package/adapters/opencode/plugins/geneseed-guard.js +157 -2
- package/bin/build-driver.mjs +2 -0
- package/bin/geneseed-cli.mjs +21 -0
- package/bin/geneseed-hook.mjs +2 -0
- package/docs/README.md +42 -0
- package/docs/_groups.json +18 -0
- package/docs/concepts/agents.md +44 -0
- package/docs/concepts/collaboration.md +62 -0
- package/docs/concepts/exclusions.md +55 -0
- package/docs/concepts/footprint.md +52 -0
- package/docs/concepts/foreman-mode.md +69 -0
- package/docs/concepts/hooks.md +101 -0
- package/docs/concepts/hosts.md +55 -0
- package/docs/concepts/loops.md +165 -0
- package/docs/concepts/lsp.md +50 -0
- package/docs/{web → concepts}/memory.md +2 -2
- package/docs/{web → concepts}/notebook.md +2 -2
- package/docs/concepts/rules.md +52 -0
- package/docs/concepts/skills.md +49 -0
- package/docs/concepts/themes.md +50 -0
- package/docs/extending.md +32 -21
- package/docs/guides/autostart.md +70 -0
- package/docs/guides/choose-your-setup.md +134 -0
- package/docs/guides/headless.md +22 -0
- package/docs/guides/install.md +161 -0
- package/docs/guides/mcp.md +195 -0
- package/docs/guides/migrate.md +41 -0
- package/docs/guides/project-context.md +87 -0
- package/docs/guides/run-anywhere.md +45 -0
- package/docs/guides/uninstall.md +51 -0
- package/docs/guides/upgrade.md +65 -0
- package/docs/guides/verify.md +65 -0
- package/docs/guides/wiki.md +69 -0
- package/docs/guides/worktree.md +47 -0
- package/docs/reference/about.md +7 -0
- package/docs/reference/cli.md +7 -0
- package/docs/reference/environment.md +99 -0
- package/docs/reference/glossary.md +37 -0
- package/docs/reference/opencode-plugins.md +133 -0
- package/docs/reference/troubleshooting.md +350 -0
- package/docs/understand/a-day.md +77 -0
- package/docs/understand/enforced-vs-asked.md +64 -0
- package/docs/understand/harness.md +36 -0
- package/docs/understand/on-your-machine.md +76 -0
- package/docs/web-ui.md +13 -2
- package/harness.config.json +1 -1
- package/js/README.md +27 -4
- package/js/build/driver.mjs +14 -8
- package/js/build/generate.mjs +22 -7
- package/js/build/render.mjs +5 -0
- package/js/build/source.mjs +11 -1
- package/js/cli-table.json +236 -1
- package/js/hosts/gitref.mjs +99 -0
- package/js/hosts/hooks.mjs +88 -1
- package/js/hosts/installs.mjs +21 -0
- package/js/hosts/mcp.mjs +1 -1
- package/js/hosts/settings.mjs +13 -1
- package/js/inspect/checks-authoring.mjs +15 -3
- package/js/inspect/diff.mjs +3 -0
- package/js/inspect/doctor.mjs +3 -2
- package/js/inspect/inventory.mjs +2 -1
- package/js/inspect/registry.mjs +20 -3
- package/js/inspect/status.mjs +8 -3
- package/js/lib/node-floor.mjs +30 -0
- package/js/loop/catalog.mjs +116 -0
- package/js/loop/cli.mjs +151 -0
- package/js/loop/graph.mjs +145 -0
- package/js/loop/score.mjs +143 -0
- package/js/loop/state.mjs +322 -0
- package/js/maintain/migrate.mjs +4 -2
- package/js/maintain/setup.mjs +109 -21
- package/js/maintain/update.mjs +4 -15
- package/js/ui/cli.mjs +2 -2
- package/js/web/actions.mjs +9 -3
- package/js/web/api.mjs +41 -2
- package/js/web/daemon.mjs +94 -4
- package/js/web/docs.mjs +149 -65
- package/js/web/handler.mjs +1 -0
- package/js/web/jobs.mjs +3 -1
- package/js/web/server.mjs +10 -5
- package/package.json +6 -4
- package/registry.json +21 -0
- package/src/AGENT.md.tmpl +6 -0
- package/src/bricks/README.md +32 -0
- package/src/bricks/_template.md +32 -0
- package/src/bricks/apply.md +17 -0
- package/src/bricks/baseline-green.md +17 -0
- package/src/bricks/bruno-test.md +16 -0
- package/src/bricks/ci-fix.md +17 -0
- package/src/bricks/deps-audit.md +14 -0
- package/src/bricks/docs-update.md +15 -0
- package/src/bricks/identify.md +20 -0
- package/src/bricks/lint.md +14 -0
- package/src/bricks/plan.md +17 -0
- package/src/bricks/reproduce.md +16 -0
- package/src/bricks/review.md +17 -0
- package/src/bricks/security-scan.md +17 -0
- package/src/bricks/test.md +14 -0
- package/src/doctrines/process.md +11 -8
- package/src/loops/bugfix.json +22 -0
- package/src/loops/feature.json +21 -0
- package/src/loops/refactor.json +20 -0
- package/src/postures/mentor.md +1 -0
- package/src/skills/brick-forge.md +46 -0
- package/src/skills/geneseed.md +1 -1
- package/src/skills/learn-mode.md +89 -0
- package/src/skills/loop.md +99 -0
- package/src/skills/pipeline.md +2 -2
- package/src/skills/quiz.md +2 -1
- package/src/skills/teach.md +2 -1
- package/themes/_TEMPLATE.json +3 -0
- package/themes/biker.json +3 -0
- package/themes/commentator.json +3 -0
- package/themes/cyberpunk.json +3 -0
- package/themes/gamer.json +3 -0
- package/themes/imperial.json +3 -0
- package/themes/joker.json +3 -0
- package/themes/marvin.json +3 -0
- package/themes/mean.json +3 -0
- package/themes/military.json +3 -0
- package/themes/neutral.json +3 -0
- package/themes/pirate.json +3 -0
- package/themes/sports.json +3 -0
- package/themes/verstappen.json +3 -0
- package/themes/wizard.json +3 -0
- package/web/dist/assets/Activity-GaaZWXTY.js +1 -0
- package/web/dist/assets/ActivityDetail-4t7d45Du.js +1 -0
- package/web/dist/assets/Dashboard-CYn7Tp16.js +2 -0
- package/web/dist/assets/Docs-BeFKLg2T.js +5 -0
- package/web/dist/assets/{GreenhouseView-D0cbCJ5m.js → GreenhouseView-C6ibc8IE.js} +1 -1
- package/web/dist/assets/Installs-DRYjYnxs.js +2 -0
- package/web/dist/assets/JournalView-1HbU1mfg.js +1 -0
- package/web/dist/assets/Laws-DFoG8JWB.js +3 -0
- package/web/dist/assets/Library-DDjgNwz_.js +1 -0
- package/web/dist/assets/Loops-D9VEoO0F.js +1 -0
- package/web/dist/assets/{Markdown-CkFyfgNf.js → Markdown-qjM2_ofS.js} +5 -5
- package/web/dist/assets/{OperatorHudView-CiAkAkQL.js → OperatorHudView-Bs7paWmh.js} +1 -1
- package/web/dist/assets/Personal-BY5n4gTw.js +1 -0
- package/web/dist/assets/Tabs-ho-EYD8i.js +1 -0
- package/web/dist/assets/api-CyMRbU2x.js +1 -0
- package/web/dist/assets/drawable-CLS9drMb.js +1 -0
- package/web/dist/assets/index-CX_hXMi5.css +1 -0
- package/web/dist/assets/index-Cjr7XCA3.js +2 -0
- package/web/dist/index.html +3 -2
- package/QUICKSTART.md +0 -50
- package/SETUP.md +0 -1148
- package/docs/web/_groups.json +0 -45
- package/docs/web/about.md +0 -6
- package/docs/web/adapters-claude-code.md +0 -8
- package/docs/web/adapters-opencode-loads.md +0 -8
- package/docs/web/adapters-opencode-spec.md +0 -8
- package/docs/web/adapters-opencode.md +0 -8
- package/docs/web/agents.md +0 -8
- package/docs/web/authoring.md +0 -11
- package/docs/web/autostart.md +0 -9
- package/docs/web/claude-hooks.md +0 -37
- package/docs/web/cli.md +0 -6
- package/docs/web/collaboration.md +0 -27
- package/docs/web/configure-wiki.md +0 -9
- package/docs/web/design.md +0 -7
- package/docs/web/env-knobs.md +0 -9
- package/docs/web/exclusions.md +0 -26
- package/docs/web/first-session.md +0 -28
- package/docs/web/footprint.md +0 -38
- package/docs/web/foreman-mode.md +0 -33
- package/docs/web/glossary.md +0 -6
- package/docs/web/harnesses.md +0 -30
- package/docs/web/headless.md +0 -9
- package/docs/web/ingest-docs.md +0 -9
- package/docs/web/install-paths.md +0 -9
- package/docs/web/install-quick.md +0 -35
- package/docs/web/lsp-overview.md +0 -37
- package/docs/web/mcp-claude-code.md +0 -10
- package/docs/web/mcp-filesystem.md +0 -9
- package/docs/web/mcp-gitlab.md +0 -9
- package/docs/web/mcp-markitdown.md +0 -9
- package/docs/web/mcp-overview.md +0 -34
- package/docs/web/mcp-trouble.md +0 -9
- package/docs/web/mcp-verify.md +0 -9
- package/docs/web/migrate.md +0 -39
- package/docs/web/model.md +0 -20
- package/docs/web/pipelines.md +0 -24
- package/docs/web/plugin-activity.md +0 -23
- package/docs/web/plugin-context.md +0 -26
- package/docs/web/plugin-guard.md +0 -24
- package/docs/web/plugin-learn.md +0 -27
- package/docs/web/plugin-notify.md +0 -24
- package/docs/web/plugin-ponytail.md +0 -23
- package/docs/web/plugin-setup.md +0 -7
- package/docs/web/plugin-workflow.md +0 -25
- package/docs/web/plugins.md +0 -17
- package/docs/web/project-context.md +0 -9
- package/docs/web/rules.md +0 -30
- package/docs/web/run-anywhere.md +0 -9
- package/docs/web/self-improve.md +0 -8
- package/docs/web/setup-choices.md +0 -64
- package/docs/web/skills.md +0 -8
- package/docs/web/themes-author.md +0 -20
- package/docs/web/themes.md +0 -9
- package/docs/web/token-footprint.md +0 -7
- package/docs/web/trouble.md +0 -38
- package/docs/web/upgrade.md +0 -9
- package/docs/web/verify.md +0 -30
- package/docs/web/wiki.md +0 -7
- package/docs/web/worktree.md +0 -10
- package/docs/wiki.md +0 -43
- package/web/dist/assets/Activity-BjVp522q.js +0 -1
- package/web/dist/assets/ActivityDetail-8ep1bspW.js +0 -1
- package/web/dist/assets/Dashboard-OkC_PCH6.js +0 -2
- package/web/dist/assets/Docs-CKPWz00o.js +0 -2
- package/web/dist/assets/Installs-BtGGdoTt.js +0 -2
- package/web/dist/assets/JournalView-Ckl4dmzR.js +0 -1
- package/web/dist/assets/Laws-CLpdRRk8.js +0 -3
- package/web/dist/assets/Library-wPPuKQrI.js +0 -1
- package/web/dist/assets/Personal-D8CnDo9v.js +0 -1
- package/web/dist/assets/Tabs-B4HNrrCs.js +0 -1
- package/web/dist/assets/drawable-BiwaOo6x.js +0 -1
- package/web/dist/assets/index-C1yil5j1.js +0 -2
- package/web/dist/assets/index-CDPDk2vj.css +0 -1
package/bin/build-driver.mjs
CHANGED
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
* which the CLI verbs import too; this file only hands it argv. Keeping the entry this thin is
|
|
5
5
|
* what lets a `js/` module import the driver without running it on the importer's argv.
|
|
6
6
|
*/
|
|
7
|
+
// FIRST, before anything it could fail to run: an old Node gets one sentence, not a stack trace.
|
|
8
|
+
import '../js/lib/node-floor.mjs';
|
|
7
9
|
import { main } from '../js/build/driver.mjs';
|
|
8
10
|
|
|
9
11
|
process.exitCode = main(process.argv.slice(2));
|
package/bin/geneseed-cli.mjs
CHANGED
|
@@ -54,6 +54,8 @@
|
|
|
54
54
|
// table below now holds one LOADER per row (`() => import(…).then(m => m.cmdX)`), so a verb
|
|
55
55
|
// loads its slice of the tree and no other verb's. The spawn allow-list gate still sees the
|
|
56
56
|
// whole graph: `tests/unit/hook_cli.test.mjs`'s `importClosure` follows both import spellings.
|
|
57
|
+
// FIRST, before anything it could fail to run: an old Node gets one sentence, not a stack trace.
|
|
58
|
+
import '../js/lib/node-floor.mjs';
|
|
57
59
|
import { cliSpec, printHelp, printVerbList } from '../js/ui/cli.mjs';
|
|
58
60
|
import { parseIntStrict } from '../js/lib/text.mjs';
|
|
59
61
|
import { printErr } from '../js/lib/fs.mjs';
|
|
@@ -147,6 +149,10 @@ const VERBS = {
|
|
|
147
149
|
catalog: () => import('../js/build/catalog.mjs').then((m) => m.cmdCatalog),
|
|
148
150
|
mcp: () => import('../js/hosts/mcp.mjs').then((m) => m.cmdMcp),
|
|
149
151
|
memory: () => import('../js/maintain/memory.mjs').then((m) => m.cmdMemory),
|
|
152
|
+
// Task 5. A fourth native verb: there was never a Python subparser for a state machine that
|
|
153
|
+
// lives entirely inside this port, so — like the three above — it has no recorded cell to
|
|
154
|
+
// compare against, only the absolute gates named beside it in `NATIVE`.
|
|
155
|
+
loop: () => import('../js/loop/cli.mjs').then((m) => m.cmdLoop),
|
|
150
156
|
};
|
|
151
157
|
|
|
152
158
|
function die(code, msg) {
|
|
@@ -289,6 +295,21 @@ async function main(argv) {
|
|
|
289
295
|
validate: "check the source tree without emitting (the generator's --validate-only)",
|
|
290
296
|
});
|
|
291
297
|
}
|
|
298
|
+
// A DEAD HOOK SHIM, SAID ON EVERY RUN. The shim is machine-wide, so one stale write turns off
|
|
299
|
+
// every hook of every Claude-shaped install, and the hooks fail into a channel nobody reads —
|
|
300
|
+
// `doctor` was the only thing that looked. stderr, so no verb's stdout moves; skipped for help
|
|
301
|
+
// and for scripted callers that opt out. Not in `bin/geneseed-hook.mjs`: a dead shim means
|
|
302
|
+
// that binary is never reached, and its import graph is paid on every tool call.
|
|
303
|
+
if (process.env.GENESEED_NO_SHIM_CHECK !== '1' && verb !== 'help'
|
|
304
|
+
&& !argv.some((t) => t === '-h' || t === '--help')) {
|
|
305
|
+
const { shimDead } = await import('../js/hosts/settings.mjs');
|
|
306
|
+
const dead = shimDead();
|
|
307
|
+
if (dead.length) {
|
|
308
|
+
printErr(`[geneseed] ⚠ hooks are off on this machine: the hook shim points at `
|
|
309
|
+
+ `${dead.join(', ')}, which no longer exists. Fix: geneseed rebuild-all
|
|
310
|
+
`);
|
|
311
|
+
}
|
|
312
|
+
}
|
|
292
313
|
// `validate` — the generator's `--validate-only`, and the one verb this entry answers that is NOT
|
|
293
314
|
// in the table above. It is dispatched here, before the lookup, for a reason that is a
|
|
294
315
|
// property of the gates rather than a preference:
|
package/bin/geneseed-hook.mjs
CHANGED
|
@@ -37,6 +37,8 @@
|
|
|
37
37
|
* every Geneseed hook returns 0 and signals through stdout — so "did nothing" and "worked"
|
|
38
38
|
* are the same observation.
|
|
39
39
|
*/
|
|
40
|
+
// FIRST, before anything it could fail to run: an old Node gets one sentence, not a stack trace.
|
|
41
|
+
import '../js/lib/node-floor.mjs';
|
|
40
42
|
import { cmdContext, cmdGitGate, cmdRuleGate, cmdToolGate, cmdLearn } from '../js/hosts/hooks.mjs';
|
|
41
43
|
// Not a new module on the hot path: `js/hosts/hooks.mjs` above already imports
|
|
42
44
|
// `js/lib/fs.mjs`, so this edge names a file the process has already loaded.
|
package/docs/README.md
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Geneseed documentation
|
|
2
|
+
|
|
3
|
+
[← Back to README](../README.md)
|
|
4
|
+
|
|
5
|
+
**New to agent harnesses?** Read **Understand** first — four short pages, about ten minutes, and every other page assumes them. The same pages open the **Docs** tab of the web console (`geneseed web`), which adds an interactive map of your own install and filters host-specific passages to the tool you use.
|
|
6
|
+
|
|
7
|
+
## 1 · Understand
|
|
8
|
+
|
|
9
|
+
1. **[What a harness is](understand/harness.md)** — git hooks + CI + a runbook, but for your AI agent.
|
|
10
|
+
2. **[What lands on your machine](understand/on-your-machine.md)** — every file and hook an install writes, what it does for you, what it costs, how to turn it off.
|
|
11
|
+
3. **[A day with the harness](understand/a-day.md)** — the moments you will actually meet: a push that asks first, a skill, a delegation, a memory.
|
|
12
|
+
4. **[Enforced vs. asked](understand/enforced-vs-asked.md)** — what is guaranteed by code, and what the model is only asked to do.
|
|
13
|
+
|
|
14
|
+
## 2 · Guides
|
|
15
|
+
|
|
16
|
+
| Guide | When |
|
|
17
|
+
| --- | --- |
|
|
18
|
+
| [Install](guides/install.md) | First time — npx, a clone, or a specific host |
|
|
19
|
+
| [Choose your setup](guides/choose-your-setup.md) | Theme, doctrine packs, one rule at a time, footprint, posture, mode |
|
|
20
|
+
| [Verify it works](guides/verify.md) | Right after installing, or when something feels off |
|
|
21
|
+
| [Upgrade](guides/upgrade.md) | Getting a new version onto every install |
|
|
22
|
+
| [Uninstall](guides/uninstall.md) | Removing an install — and what stays behind |
|
|
23
|
+
| [Project context](guides/project-context.md) | Choosing which of a repo's docs the agent loads |
|
|
24
|
+
| [Connect your wiki](guides/wiki.md) | Giving the agent your own notes, machine-wide |
|
|
25
|
+
| [MCP servers](guides/mcp.md) | MarkItDown, GitLab, Filesystem — and reading non-markdown docs |
|
|
26
|
+
| [Run geneseed from anywhere](guides/run-anywhere.md) | Putting the CLI on your PATH from a clone |
|
|
27
|
+
| [Start the web console at login](guides/autostart.md) | Keeping the console running |
|
|
28
|
+
| [Run in CI / headless](guides/headless.md) | OpenCode without a terminal |
|
|
29
|
+
| [Add git-worktree isolation](guides/worktree.md) | OpenCode, optional third-party add-on |
|
|
30
|
+
| [Migrate from a clone to npm](guides/migrate.md) | Moving an old clone install to the npm package |
|
|
31
|
+
|
|
32
|
+
## 3 · Concepts
|
|
33
|
+
|
|
34
|
+
[Hosts](concepts/hosts.md) · [Rules](concepts/rules.md) · [Agents](concepts/agents.md) · [Skills](concepts/skills.md) · [Hooks](concepts/hooks.md) · [Memory](concepts/memory.md) · [Notebook](concepts/notebook.md) · [Footprint](concepts/footprint.md) · [Collaboration](concepts/collaboration.md) · [Foreman mode](concepts/foreman-mode.md) · [Exclusions](concepts/exclusions.md) · [Themes](concepts/themes.md) · [Code intelligence (LSP)](concepts/lsp.md)
|
|
35
|
+
|
|
36
|
+
## 4 · Reference
|
|
37
|
+
|
|
38
|
+
[CLI](reference/cli.md) · [Environment variables](reference/environment.md) · [Glossary](reference/glossary.md) · [Troubleshooting](reference/troubleshooting.md) (by symptom) · [OpenCode plugins](reference/opencode-plugins.md) · [About](reference/about.md)
|
|
39
|
+
|
|
40
|
+
## For contributors
|
|
41
|
+
|
|
42
|
+
[Extending Geneseed](extending.md) — what each kind of addition costs · [DESIGN.md](../DESIGN.md) · [Design history](design-history.md) · [Token footprint](token-footprint.md) · [Web console internals](web-ui.md) · [OpenCode plugin wiring](opencode-plugin-setup.md) · [Candidate hosts](candidate-hosts.md) · adapters: [OpenCode](../adapters/opencode/README.md), [Claude Code](../adapters/claude-code/README.md), [Bob](../adapters/bob/README.md), [OpenClaude](../adapters/openclaude/README.md)
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
---
|
|
2
|
+
group: concepts
|
|
3
|
+
order: 3
|
|
4
|
+
title: "Agents"
|
|
5
|
+
kind: "concept"
|
|
6
|
+
link: {"hash": "#/section/agents", "label": "Browse the catalog →"}
|
|
7
|
+
---
|
|
8
|
+
An **agent** is a specialist the main session can hand a piece of work to. Each one is a markdown file with its own instructions, installed where your host looks for subagents (`agents/` in the install). It runs in its own context and returns a result, so its reading and searching does not fill your conversation.
|
|
9
|
+
|
|
10
|
+
> **You already know this:** handing a ticket to a colleague. You do not explain how to review code to the reviewer — you say what to review, and they come back with findings.
|
|
11
|
+
|
|
12
|
+
{N_AGENTS} agents ship, in two groups.
|
|
13
|
+
|
|
14
|
+
### The specialists
|
|
15
|
+
|
|
16
|
+
| Agent | What it does |
|
|
17
|
+
| --- | --- |
|
|
18
|
+
| `explorer` | reads and searches widely in a throwaway context, returns only distilled findings |
|
|
19
|
+
| `researcher` | searches the open web, cross-checks every claim against two sources, returns sourced findings |
|
|
20
|
+
| `architect` | produces a design or implementation plan before code is written |
|
|
21
|
+
| `developer` | implements a scoped change in an isolated worktree, self-checked, ready for the tester |
|
|
22
|
+
| `tester` | writes, runs and diagnoses tests |
|
|
23
|
+
| `reviewer` | reviews a change for correctness and quality before it merges |
|
|
24
|
+
| `security` | audits changes that touch the security surface |
|
|
25
|
+
| `docs` | writes and updates user-facing documentation after code lands |
|
|
26
|
+
|
|
27
|
+
### The council
|
|
28
|
+
|
|
29
|
+
Ten read-only debaters — `advocate`, `skeptic`, `pragmatist`, `steward`, `operator`, `visionary`, `framer`, `empiricist`, `historian`, `user-advocate` — each arguing one fixed stance. You do not call them one by one: the **council** [skill](skills.md) seats the ones that actually disagree on your question, runs bounded rounds of debate, and hands you a verdict with the strongest dissent kept verbatim. The council advises; it writes no code.
|
|
30
|
+
|
|
31
|
+
### Specialists, not folder owners
|
|
32
|
+
|
|
33
|
+
An agent is picked by **what the work needs**, not by **where the file lives**. There is no "agent for `src/api/`": a change to any folder goes to the `developer`, and its review to the `reviewer`. You can name one ("have the reviewer look at this"), or let the main session route the request to the right specialist itself.
|
|
34
|
+
|
|
35
|
+
In [foreman mode](foreman-mode.md) the session chains several of them into a pipeline — explorer, developer and tester, plus whatever specialists the task needs.
|
|
36
|
+
|
|
37
|
+
### Agents learn too
|
|
38
|
+
|
|
39
|
+
When a subagent finishes, the learn step can record a lesson for that agent alone, in `memory/agents/<name>.md` — one bullet per lesson, capped so it never grows unbounded. The next time that agent runs, it starts with what it learned. See [Memory](memory.md). (Not on Bob, which has no subagent-finished event.)
|
|
40
|
+
|
|
41
|
+
<!--harness:opencode-->
|
|
42
|
+
*(OpenCode only)*
|
|
43
|
+
OpenCode also has a **primary agent** — the one your session talks to directly. Geneseed installs it alongside the specialists; the specialists are subagents it delegates to.
|
|
44
|
+
<!--/harness-->
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
---
|
|
2
|
+
group: concepts
|
|
3
|
+
order: 9
|
|
4
|
+
title: "Collaboration"
|
|
5
|
+
kind: "concept"
|
|
6
|
+
---
|
|
7
|
+
Beside the [rules](rules.md), a few pieces shape *how* the agent works with you: the register it speaks in, the contract between you, how firmly a memory binds, and who you are. All of them are plain text in the install, so they reach every host unchanged.
|
|
8
|
+
|
|
9
|
+
> **You already know this:** a team's working agreement. The coding standards say what the code must look like; the working agreement says how people treat each other's reviews, questions and decisions.
|
|
10
|
+
|
|
11
|
+
### Posture — the relationship
|
|
12
|
+
|
|
13
|
+
A **posture** is the register the agent works in. You choose it at setup and it is fixed at build time, so it does not drift back toward plain execution halfway through a session.
|
|
14
|
+
|
|
15
|
+
| Posture | For |
|
|
16
|
+
| --- | --- |
|
|
17
|
+
| **peer** (default) | a candid equal — dense, challenges you, no flattery |
|
|
18
|
+
| **mentor** | leaves you more capable — explains the why, checks understanding |
|
|
19
|
+
| **expert** | maximum density for a fluent user — terse, no basics |
|
|
20
|
+
| **assistant** | precise execution, low initiative — you steer |
|
|
21
|
+
| **artisan** | a peer with toolsmith reflexes — terminal-first, automates repetition |
|
|
22
|
+
|
|
23
|
+
Posture is separate from the [theme](themes.md): the theme is the *voice*, the posture is the *relationship*. Every posture obeys the same rules; what shifts is how firmly and how loudly the agent voices disagreement. Change it with `geneseed setup`, the web console's Harness page, or:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
geneseed build --emit claude-global --posture mentor
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
How the agent *executes* work — itself, or through a crew — is the separate **mode** setting: see [Foreman mode](foreman-mode.md).
|
|
30
|
+
|
|
31
|
+
### The Pact — a two-way contract
|
|
32
|
+
|
|
33
|
+
The **Pact** is stated in the first section of the Ethos, the layer that is always on, so it holds in every task and every repository. It ranks three duties for the agent, each yielding only to the one above:
|
|
34
|
+
|
|
35
|
+
1. protect you — and the future maintainer of your code;
|
|
36
|
+
2. serve your intent;
|
|
37
|
+
3. keep its own honesty.
|
|
38
|
+
|
|
39
|
+
Unusually, it also says what *you* owe back:
|
|
40
|
+
|
|
41
|
+
- **Don't punish candour.** When the agent contradicts you with evidence, flags a risk or admits a doubt, that is the Pact working. Penalising it teaches the agent to flatter.
|
|
42
|
+
- **Give the context up front.** The agent cannot weigh what it was not told.
|
|
43
|
+
- **Decide when shown a fork.** An unmade decision stalls work as surely as a wrong one.
|
|
44
|
+
|
|
45
|
+
Your half is not enforced against you. The agent's half binds it.
|
|
46
|
+
|
|
47
|
+
### Memory force — how firmly a memory binds
|
|
48
|
+
|
|
49
|
+
A [memory](memory.md) can carry an optional `force`:
|
|
50
|
+
|
|
51
|
+
| Force | Meaning |
|
|
52
|
+
| --- | --- |
|
|
53
|
+
| **constraint** | imposed; not the agent's to relax |
|
|
54
|
+
| **choice** | revisable, with your consent |
|
|
55
|
+
| **conviction** | revisable on evidence |
|
|
56
|
+
| **tempered** | a constraint that was relaxed |
|
|
57
|
+
|
|
58
|
+
When new evidence contradicts a memory with a force, the agent must revise it in the open rather than quietly drop it.
|
|
59
|
+
|
|
60
|
+
### Profile — who you are
|
|
61
|
+
|
|
62
|
+
`PROFILE.md` sits beside the instructions file, is seeded once and is never overwritten. It holds your role, habits and how you like answers pitched. It colours how the agent works but never binds — it is last in [precedence](rules.md). Edit the file directly, use the Profile tab in the web console, or let the `profile` [skill](skills.md) interview you and draft it; it writes only with your consent, and routes anything that is really a standing rule to `user-rules.md`.
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
---
|
|
2
|
+
group: concepts
|
|
3
|
+
order: 11
|
|
4
|
+
title: "Exclusions"
|
|
5
|
+
kind: "concept"
|
|
6
|
+
link: {"hash": "#/harness", "label": "Manage in Harness →"}
|
|
7
|
+
---
|
|
8
|
+
Geneseed has two different ways to switch something off, and they work at different scales:
|
|
9
|
+
|
|
10
|
+
| | Sovereign repo | Per-rule exclusion |
|
|
11
|
+
| --- | --- | --- |
|
|
12
|
+
| **Switches off** | the whole global install, inside one folder | one doctrine rule, everywhere the install applies |
|
|
13
|
+
| **Scope** | a folder and everything under it | the install |
|
|
14
|
+
| **Applies to** | **global** installs only | any install |
|
|
15
|
+
| **Set with** | `geneseed exclude add <path>` | `--exclude-rules` at build time |
|
|
16
|
+
| **Takes effect** | on the next tool call, no rebuild | on rebuild |
|
|
17
|
+
|
|
18
|
+
> **You already know this:** `.gitignore` versus disabling one lint rule. One makes a tool ignore a whole folder; the other keeps the tool running everywhere with one check turned off.
|
|
19
|
+
|
|
20
|
+
### Sovereign repos — whole-repo dormancy
|
|
21
|
+
|
|
22
|
+
A **sovereign repo** is a folder where every *global* Geneseed install goes fully dormant. The usual case is a repo that ships its own complete agent setup — its own rules, hooks and memory — where a global harness layered on top would bring conflicting instructions and wasted tokens.
|
|
23
|
+
|
|
24
|
+
It is all-or-nothing. It does not trim which rules apply or which skills load; the global harness simply never engages inside that folder. A **per-repo** Geneseed install in the same folder is unaffected — exclusions only ever silence global installs.
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
geneseed exclude add ~/code/my-vault
|
|
28
|
+
geneseed exclude list
|
|
29
|
+
geneseed exclude remove ~/code/my-vault
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
One command updates every global install on the machine. Each keeps the list in its own `excludes.json`, and every hook and plugin reads it on each call, so a change takes effect at once.
|
|
33
|
+
|
|
34
|
+
What "dormant" means per host:
|
|
35
|
+
|
|
36
|
+
- **Claude Code** — every hook exits silently, and the global `CLAUDE.md` is suppressed natively through `claudeMdExcludes` in the repo's `.claude/settings.local.json`.
|
|
37
|
+
- **OpenClaude** — the same, in the repo's `.openclaude/settings.local.json`.
|
|
38
|
+
- **Bob** — every hook exits silently, and a stub `.bob/rules/geneseed.md` in the repo shadows the global rules file. A hand-written stub already there is never overwritten.
|
|
39
|
+
- **OpenCode** — Geneseed's plugins stand down.
|
|
40
|
+
|
|
41
|
+
`geneseed exclude remove` undoes all of it.
|
|
42
|
+
|
|
43
|
+
**Limits.** Globally installed skills and agents stay *listed* by the host — no host offers a per-repo switch for them. And a global install created *after* you added exclusions starts with an empty list: run `geneseed exclude add` again (`geneseed exclude list` flags installs whose lists differ).
|
|
44
|
+
|
|
45
|
+
The web console has the same controls in the **Excluded folders** card on the Harness page, shown once a global install exists.
|
|
46
|
+
|
|
47
|
+
### Per-rule exclusion — one rule off
|
|
48
|
+
|
|
49
|
+
The finer switch removes a single doctrine rule from an install while keeping the rest of its pack:
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
geneseed build --emit claude-global --exclude-rules "process 7"
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
The install records it (`Excluded rules: process 7` beside its pack list) and every rebuild and upgrade keeps it. The always-on Rules and the Ethos cannot be excluded. Picking packs and rules is covered in [Choose your setup](../guides/choose-your-setup.md); what the layers are is in [Rules](rules.md).
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
---
|
|
2
|
+
group: concepts
|
|
3
|
+
order: 8
|
|
4
|
+
title: "Footprint (lean vs full)"
|
|
5
|
+
kind: "concept"
|
|
6
|
+
link: {"hash": "#/settings", "label": "Toggle it in Settings →"}
|
|
7
|
+
---
|
|
8
|
+
**Footprint** decides how much of the [constitution](rules.md) the agent carries *inline* in its instructions file on every turn. It has two settings, **lean** (the default) and **full**, chosen per install. It is a token-cost dial, not a rules dial: every rule the install adopted is in force at either setting.
|
|
9
|
+
|
|
10
|
+
> **You already know this:** eager versus lazy loading. Full ships everything in the first payload; lean ships the index and fetches the rest when it is needed.
|
|
11
|
+
|
|
12
|
+
### The difference
|
|
13
|
+
|
|
14
|
+
- **Full** — the instructions file carries the Ethos, every Rule and every rule of the active doctrine packs at complete length, reasoning included, every turn.
|
|
15
|
+
- **Lean** — each Rule and each doctrine rule is carried as its heading plus a short form written by hand (the rule and how it works, not the first sentence cut off). Each layer ends with a pointer to its complete text on disk, and the agent reads the reasoning when a rule's application is unclear. The Ethos gets one hand-written short form for the whole layer, because it is flowing prose rather than numbered rules.
|
|
16
|
+
|
|
17
|
+
Neither setting hides text from the agent. They decide what is in front of it on *every* turn.
|
|
18
|
+
|
|
19
|
+
### What is on disk either way
|
|
20
|
+
|
|
21
|
+
- **Lean** writes the full `laws/`, `ontology/` and `doctrines/` text beside the instructions file, because the inline copy is shorter than what the agent may need.
|
|
22
|
+
- **Full** writes `doctrines/` too: it inlines only the packs this install built in, so the others must be on disk for a citation into them to resolve, and for you to read before turning one on.
|
|
23
|
+
|
|
24
|
+
Everything else is identical at both settings — the same agents, skills, plugins or hooks, commands, memory and notebook.
|
|
25
|
+
|
|
26
|
+
### Which to choose
|
|
27
|
+
|
|
28
|
+
- **Lean** (default) for long sessions, large repos or cost-sensitive work. It is safe: the full text ships, and the instructions tell the agent to read it before acting on secrets, deletion, git history, scope or untrusted content.
|
|
29
|
+
- **Full** when token cost does not matter, or with a smaller or cheaper model — with the reasoning always in context, a model applies a rule's edge cases more reliably.
|
|
30
|
+
|
|
31
|
+
For measured numbers per host, see [docs/token-footprint.md](../token-footprint.md).
|
|
32
|
+
|
|
33
|
+
### How to set it
|
|
34
|
+
|
|
35
|
+
Footprint is stored in a `.geneseed-footprint` marker in the install and kept across every rebuild and upgrade, on every host.
|
|
36
|
+
|
|
37
|
+
- **Setup wizard** — asks for it alongside voice, posture, mode and doctrine packs:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
geneseed setup
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
- **Web console** — the **Footprint** toggle in Settings flips the current install and rebuilds it; on the Harness page, each install has its own dropdown.
|
|
44
|
+
- **Command line** — with the emit target of the install you are changing:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
geneseed build --emit claude-global --footprint full
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
On the command line, a flag you leave out takes the generator's default, not the install's current value. `geneseed status --json` shows what an install currently has.
|
|
51
|
+
|
|
52
|
+
The walkthrough for all build-time choices is [Choose your setup](../guides/choose-your-setup.md).
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
---
|
|
2
|
+
group: concepts
|
|
3
|
+
order: 10
|
|
4
|
+
title: "Foreman mode"
|
|
5
|
+
kind: "concept"
|
|
6
|
+
link: {"hash": "#/harness", "label": "Set the mode in Harness →"}
|
|
7
|
+
---
|
|
8
|
+
**Mode** decides how work gets executed in a session. Two modes ship: **direct**, the default, where the agent does every task itself, and **foreman**, where the session hands substantial tasks to a crew of [agents](agents.md) and keeps talking to you while they work.
|
|
9
|
+
|
|
10
|
+
> **You already know this:** a tech lead with a team. Quick questions get answered on the spot; a real feature becomes a ticket that someone builds on a branch, and the lead reviews the result before it is merged.
|
|
11
|
+
|
|
12
|
+
Mode is chosen at build time, so it does not drift mid-session, and kept across every rebuild and re-theme. It is separate from [posture](collaboration.md) (the relationship register), the doctrine packs ([Rules](rules.md)) and [footprint](footprint.md). It is also separate from a [loop](loops.md) — a pipeline is a one-shot, uncommitted crew for a single task; a loop is a long-running state machine that commits each validated iteration on its own branch.
|
|
13
|
+
|
|
14
|
+
### direct — the default
|
|
15
|
+
|
|
16
|
+
The agent works every task itself, turn by turn. Nothing is spawned; you talk to one agent from start to finish. Keep it unless you want the session to manage work for you.
|
|
17
|
+
|
|
18
|
+
### foreman — a session that triages
|
|
19
|
+
|
|
20
|
+
The session sorts every request:
|
|
21
|
+
|
|
22
|
+
- **Trivial** — a quick answer, a one-file tweak, a question: done directly, as in direct mode.
|
|
23
|
+
- **Substantial** — handed to a **pipeline** running in the background. The session tells you it is running and stays free to answer you.
|
|
24
|
+
|
|
25
|
+
Expect a substantial task to cost more (a crew runs instead of one agent) in exchange for a session that never blocks on a long job.
|
|
26
|
+
|
|
27
|
+
### What a pipeline is
|
|
28
|
+
|
|
29
|
+
A **pipeline** is a small crew of agents working one task in isolation. The minimum crew depends on the task:
|
|
30
|
+
|
|
31
|
+
| Task | Minimum crew |
|
|
32
|
+
| --- | --- |
|
|
33
|
+
| development | `explorer` (analyses the request) → `developer` → `tester`, plus a lint check |
|
|
34
|
+
| documentation | `explorer` → `docs` |
|
|
35
|
+
| research | `explorer`; add `researcher` when the question leaves the repository |
|
|
36
|
+
| review or audit | `reviewer` + `skeptic` |
|
|
37
|
+
|
|
38
|
+
The session adds specialists on top when the task needs them — `security`, `architect`, `reviewer` and so on — never fewer than the minimum.
|
|
39
|
+
|
|
40
|
+
The crew works in its own git worktree and branch. When worktrees are unavailable it falls back to the main tree, one pipeline at a time, and says so. Two pipelines whose sets of files overlap do not run at once.
|
|
41
|
+
|
|
42
|
+
Inside the crew, the developer implements and the tester runs the tests and lint. Failures go back to the developer, at most five rounds; after that the crew stops and reports the failure, leaving the branch for you to inspect.
|
|
43
|
+
|
|
44
|
+
### A pipeline never commits or merges
|
|
45
|
+
|
|
46
|
+
When the crew is done, it hands back its worktree **uncommitted**, with the raw test and lint output and the list of files it changed. Then the session:
|
|
47
|
+
|
|
48
|
+
1. re-runs the tests and lint itself — the crew's log is the crew's account, not proof;
|
|
49
|
+
2. shows you the diff and the green output;
|
|
50
|
+
3. commits and merges **only once you accept**.
|
|
51
|
+
|
|
52
|
+
Commit, push and merge belong to the session alone, under *Consent Before Push* ([Rules](rules.md)). A crew that cannot get to green reports back instead of landing broken work.
|
|
53
|
+
|
|
54
|
+
You can also start a pipeline without foreman mode: ask the agent to "run a pipeline" for a task, and the `pipeline` [skill](skills.md) takes it from there.
|
|
55
|
+
|
|
56
|
+
### How to set it
|
|
57
|
+
|
|
58
|
+
- **Setup wizard** — asks for mode alongside voice, posture, doctrine packs and footprint:
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
geneseed setup
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
- **Web console** — the per-install **Mode** dropdown on the Harness page, then **Apply**.
|
|
65
|
+
- **Command line** — with the emit target of the install you are changing; switch back with `--mode direct`:
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
geneseed build --emit claude-global --mode foreman
|
|
69
|
+
```
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
---
|
|
2
|
+
group: concepts
|
|
3
|
+
order: 5
|
|
4
|
+
title: "Hooks (Claude Code, Bob, OpenClaude)"
|
|
5
|
+
kind: "concept"
|
|
6
|
+
---
|
|
7
|
+
A **hook** is a command your host runs at a fixed moment — when a session starts, before a tool call, when the agent finishes. On Claude Code, Bob and OpenClaude, hooks are how Geneseed does anything *in code* rather than in prose: load your project's docs, stop a risky command for your confirmation, save what was learned.
|
|
8
|
+
|
|
9
|
+
> **You already know this:** git hooks. A `pre-commit` hook runs before every commit whether or not you remember it exists, and can stop the commit. These run before and after the agent's actions the same way.
|
|
10
|
+
|
|
11
|
+
Geneseed writes its hooks into the host's settings file. Every hook calls one program, `geneseed-hook`, with a verb — not the `geneseed` CLI you type yourself. The instructions file (`CLAUDE.md`) needs no hook: the host loads it by location.
|
|
12
|
+
|
|
13
|
+
### The hooks on Claude Code
|
|
14
|
+
|
|
15
|
+
| Event | When | Command | What it does | Conditional? |
|
|
16
|
+
| --- | --- | --- | --- | --- |
|
|
17
|
+
| `SessionStart` | `startup`, `clear` | `geneseed-hook context` | injects your harness files and the repo's docs | no |
|
|
18
|
+
| `SessionStart` | `resume`, `compact` | `geneseed-hook context` | re-injects them after a resume or an auto-compaction summarised them away | no |
|
|
19
|
+
| `PreToolUse` | `Bash` | `geneseed-hook git-gate` | asks before destructive git; asks before every commit and push | the commit/push question only |
|
|
20
|
+
| `PreToolUse` | `Write`, `Edit`, `MultiEdit`, `NotebookEdit` | `geneseed-hook rule-gate` | asks before a secret lands in a file, or a write to your rules or memory | no |
|
|
21
|
+
| `Stop` | the agent finishes a reply | `geneseed-hook learn` | distils durable facts into `memory/` | needs `GENESEED_LLM` |
|
|
22
|
+
| `SubagentStop` | a subagent finishes | `geneseed-hook learn` | records a lesson for that agent in `memory/agents/<name>.md` | needs `GENESEED_LLM` |
|
|
23
|
+
| `PreCompact` | before auto-compaction | `geneseed-hook learn` | captures memory before the transcript is summarised | needs `GENESEED_LLM` |
|
|
24
|
+
|
|
25
|
+
### What each one does, and what you see
|
|
26
|
+
|
|
27
|
+
**context.** Before your first message, the agent receives your own harness files — `user-rules.md`, `PROFILE.md`, the memory index, the notebook index, your wiki declaration — skipping any still untouched since install, then the repo's docs, discovered by convention or listed in a `context.json`. Each file is capped at 16 KB and the whole injection at 48 KB; what does not fit is listed for the agent to read on demand. You see nothing, except that the agent already knows your project. See [Project context](../guides/project-context.md).
|
|
28
|
+
|
|
29
|
+
**git-gate.** Runs before every shell command and looks for `git` in it, including chained one-liners and `git -C <path>` forms.
|
|
30
|
+
- **Destructive git** — `reset --hard`, `clean -f`, `branch -D`, `checkout -- `, a `push --force` — always gets a confirmation prompt, citing *Deletion Is Deliberate*. That is a Rule, so it holds in every build.
|
|
31
|
+
- **Every `git commit` and `git push`** gets a prompt citing *Consent Before Push*. This part belongs to the **process** doctrine pack: build without it, or exclude that rule, and the hook stays wired with `--no-consent` — commits and pushes go through without asking, destructive git is still stopped ([Rules](rules.md)).
|
|
32
|
+
- Any other command passes untouched.
|
|
33
|
+
|
|
34
|
+
**rule-gate.** Runs before every file write.
|
|
35
|
+
- Content that looks like a credential (a cloud access key, a GitHub or Anthropic token, a Slack token, a private-key block) going into any file other than `.env*` gets a prompt citing *Sealed Secrets*.
|
|
36
|
+
- A write to `user-rules.md`, `MEMORY.md` or a file in the install's `memory/` gets a prompt citing *Persist Insight*: whether something is a standing rule or a fact to remember is your call, settled through the `rule` [skill](skills.md).
|
|
37
|
+
- Ordinary edits pass untouched.
|
|
38
|
+
|
|
39
|
+
**learn.** Takes the tail of the transcript and asks a model to distil what is worth keeping into one-fact-per-file entries under `memory/`, skipping duplicates. It needs `GENESEED_LLM` set to a model command, for example:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
export GENESEED_LLM="claude -p"
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Unset, `learn` does nothing useful — it prints the prompt it would have sent. Geneseed never stores or embeds an API key. See [Memory](memory.md).
|
|
46
|
+
|
|
47
|
+
### Gates fail closed, and leave a trace
|
|
48
|
+
|
|
49
|
+
If a gate cannot evaluate a call — an unreadable payload, a bug — it asks, with the error as its reason, rather than silently letting the call through. Every prompt a gate raises adds one line to `notebook/gates.jsonl` in the install: the rule and the time, never the command or content. `geneseed status` counts them by rule.
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
geneseed status
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
In an [excluded folder](exclusions.md), every hook of a global install exits silently. And a global install's `context` hook stands down when the repo has its own per-repo install of the same host, so nothing is injected twice.
|
|
56
|
+
|
|
57
|
+
### Where they are written
|
|
58
|
+
|
|
59
|
+
| Host | Global | Per repo |
|
|
60
|
+
| --- | --- | --- |
|
|
61
|
+
| Claude Code | `~/.claude/settings.json` | `.claude/settings.local.json` |
|
|
62
|
+
| OpenClaude | `~/.openclaude/settings.json` | `.openclaude/settings.local.json` |
|
|
63
|
+
| Bob | `~/.bob/settings/settings.json` | `.bob/settings.json` |
|
|
64
|
+
|
|
65
|
+
Per repo, Claude Code and OpenClaude hooks go into the **local**, untracked settings file: the hook commands contain paths on your machine, and the team-shared `settings.json` would hand every teammate broken hooks.
|
|
66
|
+
|
|
67
|
+
The merge is surgical. Every other key and every hook of your own survive, and the install manifest records exactly which hook groups are Geneseed's, so an upgrade replaces and an uninstall removes only those.
|
|
68
|
+
|
|
69
|
+
### Bob and OpenClaude
|
|
70
|
+
|
|
71
|
+
**OpenClaude** is a Claude Code fork: it gets the same hooks and the same prompts, unchanged.
|
|
72
|
+
|
|
73
|
+
**Bob** has its own contract. It uses Claude's event names but ignores a hook's output before a tool call — the only way to refuse is exit code 2 — and it has no tool matcher, `SubagentStop` or `PreCompact`. So Bob gets three hooks:
|
|
74
|
+
|
|
75
|
+
- `SessionStart` → `geneseed-hook context`.
|
|
76
|
+
- `PreToolUse` → `geneseed-hook tool-gate`, the git gate and the rule gate fused into one command that decides from the shape of the call. It **blocks** (exit 2) only for the two Rules, secrets and destructive git. The commit/push and rule-or-memory checks become a warning line, because a hard block would leave Bob unable to commit at all.
|
|
77
|
+
- `Stop` → `geneseed-hook learn`.
|
|
78
|
+
|
|
79
|
+
Neither host has been verified live on the authoring machine. If a hook does not fire, the same rules still reach the agent through the instructions file.
|
|
80
|
+
|
|
81
|
+
### The hook shim
|
|
82
|
+
|
|
83
|
+
Hooks run with your project as the working directory, so each command needs an absolute path. Rather than write the Node path and the Geneseed checkout path into every settings file, every hook points at one stable file, the **hook shim**: `~/.geneseed/bin/geneseed-hook` (`geneseed-hook.cmd` on Windows). The shim holds those two paths; your settings hold none. Set `GENESEED_HOME` to keep it somewhere other than `~/.geneseed`.
|
|
84
|
+
|
|
85
|
+
Every build rewrites the shim, so moving the checkout and running one build repairs every install at once.
|
|
86
|
+
|
|
87
|
+
**A stale shim fails silently.** Hooks report through their output and exit 0 on every path — that is what keeps a broken hook from breaking your tool calls. The flip side: if the shim points at a checkout that no longer exists, every hook on the machine stops working and nothing tells you. The agent simply stops getting project context and the gates stop asking. `geneseed doctor` checks the shim; a build repairs it.
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
geneseed doctor
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
See [Troubleshooting](../reference/troubleshooting.md).
|
|
94
|
+
|
|
95
|
+
### Cost
|
|
96
|
+
|
|
97
|
+
The hook program is small on purpose: it adds about 14 ms to each tool call.
|
|
98
|
+
|
|
99
|
+
### Verify
|
|
100
|
+
|
|
101
|
+
Open a session in a repo and ask the agent what it knows about the project — it should answer from the repo's docs without reading them first. Ask it to commit something: you should get a prompt before the commit runs.
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
---
|
|
2
|
+
group: concepts
|
|
3
|
+
order: 1
|
|
4
|
+
title: "Hosts"
|
|
5
|
+
kind: "concept"
|
|
6
|
+
---
|
|
7
|
+
A **host** is the AI coding tool Geneseed installs into — OpenCode, Claude Code, Bob or OpenClaude. Geneseed does not run the model; the host does. Geneseed writes the files the host reads (the instructions file, agents, skills) and, where the host allows it, wires small programs that run around the agent's actions. The *content* is the same on every host. What differs is how much of it the host lets Geneseed **automate** — check in code before an action — rather than only **ask** of the model in prose.
|
|
8
|
+
|
|
9
|
+
> **You already know this:** one codebase, several CI providers. The pipeline does the same job everywhere, but each provider exposes different hooks, so some checks run natively on one and are a manual step on another.
|
|
10
|
+
|
|
11
|
+
### What is the same everywhere
|
|
12
|
+
|
|
13
|
+
One build renders the same text for every host: the constitution ([rules](rules.md)), the {N_AGENTS} [agents](agents.md), the {N_SKILLS} [skills](skills.md), the [memory](memory.md) and [notebook](notebook.md) conventions, and the theme's voice. No host drops an agent, a skill or the memory convention.
|
|
14
|
+
|
|
15
|
+
Each host has a **global** install (in its config directory, active in every repo) and a **per-repo** install (inside one project). There is also a portable `files` bundle — a plain `Harness/` folder with an `AGENT.md` that any tool reading an instructions file can use, with no automation at all.
|
|
16
|
+
|
|
17
|
+
### Two engines
|
|
18
|
+
|
|
19
|
+
- **OpenCode** runs its own engine: Geneseed installs JavaScript **plugins** that OpenCode loads, plus permission entries in `opencode.json`. It also gets OpenCode-only extras: colour themes, [language servers](lsp.md), a workflow runner, a primary agent and `/`-commands.
|
|
20
|
+
- **Claude Code**, **Bob** and **OpenClaude** share one Claude-shaped engine: Geneseed wires **hooks** into the host's `settings.json`, each calling `geneseed-hook <verb>`. See [Hooks](hooks.md).
|
|
21
|
+
|
|
22
|
+
### What each host automates
|
|
23
|
+
|
|
24
|
+
| Capability | OpenCode | Claude Code | Bob | OpenClaude |
|
|
25
|
+
| --- | :---: | :---: | :---: | :---: |
|
|
26
|
+
| Instructions file | `AGENT.md` via `opencode.json` | `CLAUDE.md` | `AGENTS.md` + `rules/geneseed.md` | `CLAUDE.md` (`.openclaude/` per repo) |
|
|
27
|
+
| Agents · Skills · Memory · Notebook | ✅ | ✅ | ✅ | ✅ |
|
|
28
|
+
| Project context loaded at session start | ⚙️ plugin | 🪝 hook | 🪝 hook¹ | 🪝 hook² |
|
|
29
|
+
| Memory written back at session end (learn) | ⚙️ plugin | 🪝 hook | 🪝 hook¹ | 🪝 hook² |
|
|
30
|
+
| Destructive git (force-push, `reset --hard`…) | 🔒 permission ask | 🪝 ask | 🪝 block¹ | 🪝 ask² |
|
|
31
|
+
| Secrets kept out of files | ⚙️ block⁴ | 🪝 ask | 🪝 block¹ | 🪝 ask² |
|
|
32
|
+
| Consent before every commit and push | 🔒 permission ask | 🪝 ask | 🪝 warning¹ | 🪝 ask² |
|
|
33
|
+
| Rule-or-memory write needs your call | ⚙️ speed bump³ | 🪝 ask | 🪝 warning¹ | 🪝 ask² |
|
|
34
|
+
| Sovereign-repo exclusions | ⚙️ plugins stand down | ✅ `claudeMdExcludes` | ✅ rules shadow stub | ✅ `claudeMdExcludes` |
|
|
35
|
+
| MCP server wiring | ✅ `mcp` | ✅ `mcpServers` | ✅ `mcp.json` | ✅ `mcpServers` |
|
|
36
|
+
| Colour themes · LSP · workflow runner · primary agent · `/`-commands | ✅ | ➖ | ➖ | ➖ |
|
|
37
|
+
|
|
38
|
+
✅ native · ⚙️ OpenCode plugin · 🔒 `permission.bash` entry in `opencode.json` · 🪝 `settings.json` hook · ➖ no host mechanism (the rule still applies as prose).
|
|
39
|
+
|
|
40
|
+
¹ **Bob** has its own hook contract: Claude's event names, but it ignores a hook's output on `PreToolUse`, so the only way to refuse is exit code 2. Geneseed therefore blocks only the two always-on rules (secrets, destructive git) and turns the two consent checks into a logged warning. It has no `SubagentStop` or `PreCompact` event, so learn runs on `Stop` only. **Unverified live** — there is no Bob install on the authoring machine; the rules preamble still holds if a hook does not fire.
|
|
41
|
+
² **OpenClaude** is a Claude Code fork and gets Claude's hooks and verdicts verbatim, in `~/.openclaude/settings.json` (global) or `.openclaude/settings.local.json` (per repo). **Unverified live** for the same reason.
|
|
42
|
+
³ OpenCode's plugin hook can only allow or throw — there is no "ask the user" — so this check stops the first such write once rather than prompting.
|
|
43
|
+
⁴ The checks differ in shape: OpenCode's guard plugin blocks writes *to* private-key and credential files by path; the Claude-shaped hook looks at the *content* being written for credential-shaped strings (cloud keys, tokens, private-key blocks) and asks. A `.env` file is exempt on the hook side — that is where a secret is allowed to live.
|
|
44
|
+
|
|
45
|
+
### The one conditional row
|
|
46
|
+
|
|
47
|
+
The **consent before commit and push** row depends on a choice you make at build time. It enforces the rule *Consent Before Push*, which belongs to the **process** doctrine pack ([Rules](rules.md)). Build without that pack, or exclude that one rule, and the commit/push question goes away — but the gate itself stays: on Claude Code and OpenClaude the `git-gate` hook is still wired (with `--no-consent`), so destructive git is still caught. Everything else in the table is always on.
|
|
48
|
+
|
|
49
|
+
One OpenCode asymmetry: Geneseed shares `opencode.json` with you and cannot tell its own `git commit*` permission entry from one you typed, so a rebuild without the process pack leaves an existing entry in place and says so instead of deleting it.
|
|
50
|
+
|
|
51
|
+
### Where to go next
|
|
52
|
+
|
|
53
|
+
- What exactly each host writes to disk: [What lands on your machine](../understand/on-your-machine.md).
|
|
54
|
+
- Code-enforced versus asked-of-the-model, in plain terms: [Enforced vs. asked](../understand/enforced-vs-asked.md).
|
|
55
|
+
- Per-host detail for maintainers: [OpenCode](../../adapters/opencode/README.md) · [Claude Code](../../adapters/claude-code/README.md) · [Bob](../../adapters/bob/README.md) · [OpenClaude](../../adapters/openclaude/README.md).
|