geneseed 3.1.3 → 3.3.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 +180 -0
- package/README.md +24 -14
- package/SETUP.md +38 -7
- package/SHIPPED.md +6 -5
- package/adapters/bob/README.md +40 -10
- package/adapters/claude-code/README.md +5 -0
- package/adapters/claude-code/settings.json +8 -1
- package/adapters/copilot/README.md +50 -24
- package/adapters/opencode/README.md +5 -1
- package/adapters/opencode/plugins/geneseed-guard.js +40 -6
- package/bin/build-driver.mjs +143 -89
- package/bin/geneseed-cli.mjs +63 -106
- package/bin/geneseed-hook.mjs +26 -16
- package/docs/candidate-hosts.md +74 -0
- package/docs/extending.md +6 -5
- package/docs/token-footprint.md +32 -21
- package/docs/web-ui.md +5 -13
- package/harness.config.json +1 -1
- package/js/README.md +5 -15
- package/js/build/emit-claude.mjs +26 -12
- package/js/build/emit-common.mjs +63 -114
- package/js/build/emit-opencode.mjs +74 -66
- package/js/build/generate.mjs +4 -6
- package/js/build/render.mjs +50 -32
- package/js/build/source.mjs +29 -8
- package/js/build/stubs.mjs +25 -33
- package/js/build/themes.mjs +1 -1
- package/js/build/version.mjs +1 -3
- package/js/cli-table.json +84 -0
- package/js/hosts/hooks.mjs +243 -81
- package/js/hosts/hosts.mjs +57 -5
- package/js/hosts/installs.mjs +35 -28
- package/js/hosts/link.mjs +2 -2
- package/js/hosts/mcp.mjs +3 -1
- package/js/hosts/native.mjs +54 -19
- package/js/hosts/opencode.mjs +39 -28
- package/js/hosts/settings.mjs +206 -115
- package/js/inspect/checks-authoring.mjs +5 -4
- package/js/inspect/checks-build.mjs +1 -1
- package/js/inspect/diff.mjs +1 -3
- package/js/inspect/doctor.mjs +59 -44
- package/js/inspect/excludes.mjs +5 -11
- package/js/inspect/inventory.mjs +38 -56
- package/js/inspect/registry.mjs +4 -7
- package/js/inspect/scan.mjs +8 -15
- package/js/inspect/status.mjs +51 -3
- package/js/lib/fs.mjs +34 -0
- package/js/lib/json.mjs +28 -1
- package/js/lib/paths.mjs +0 -10
- package/js/lib/udiff.mjs +11 -16
- package/js/maintain/memory.mjs +2 -4
- package/js/maintain/migrate.mjs +3 -3
- package/js/maintain/uninstall.mjs +127 -88
- package/js/maintain/update.mjs +4 -4
- package/js/ui/anim.mjs +1 -1
- package/js/ui/menu.mjs +1 -1
- package/js/ui/tui.mjs +3 -20
- package/js/web/actions.mjs +230 -217
- package/js/web/activity.mjs +71 -89
- package/js/web/api.mjs +130 -226
- package/js/web/daemon.mjs +92 -110
- package/js/web/docs.mjs +59 -126
- package/js/web/handler.mjs +94 -123
- package/js/web/jobs.mjs +116 -178
- package/js/web/routes.mjs +47 -192
- package/js/web/server.mjs +47 -82
- package/package.json +1 -1
- package/registry.json +14 -0
- package/src/AGENT.md.tmpl +55 -16
- package/src/agents/explorer.md +2 -1
- package/src/doctrines/README.md +3 -3
- package/src/doctrines/process.md +4 -2
- package/src/doctrines/rigor.md +13 -0
- package/src/laws/universal.md +133 -43
- package/src/ontology/universal.md +38 -13
- package/src/skills/_template.md +5 -1
- package/src/skills/bruno-collection-generator.md +63 -0
- package/src/skills/bruno-test-writer.md +62 -0
- package/src/skills/clarify.md +1 -1
- package/src/skills/crash-course.md +1 -0
- package/src/skills/decode.md +1 -0
- package/src/skills/drill.md +1 -0
- package/src/skills/feynman.md +1 -0
- package/src/skills/forge-mcp.md +2 -1
- package/src/skills/fresh-eyes.md +1 -1
- package/src/skills/herdr.md +1 -0
- package/src/skills/ingest.md +2 -1
- package/src/skills/learning-path.md +1 -0
- package/src/skills/opencode-theme.md +1 -0
- package/src/skills/parallel-agents.md +1 -1
- package/src/skills/ponytail.md +2 -2
- package/src/skills/research.md +4 -2
- package/themes/_TEMPLATE.json +5 -0
- package/themes/biker.json +5 -0
- package/themes/commentator.json +5 -0
- package/themes/cyberpunk.json +5 -0
- package/themes/gamer.json +5 -0
- package/themes/imperial.json +5 -0
- package/themes/joker.json +5 -0
- package/themes/marvin.json +5 -0
- package/themes/mean.json +5 -0
- package/themes/military.json +5 -0
- package/themes/neutral.json +5 -0
- package/themes/pirate.json +5 -0
- package/themes/sports.json +5 -0
- package/themes/verstappen.json +5 -0
- package/themes/wizard.json +5 -0
- package/web/dist/assets/Activity-BfVcLrda.js +1 -0
- package/web/dist/assets/ActivityDetail-CQXccGPl.js +1 -0
- package/web/dist/assets/CatalogRow-DALEQImZ.js +1 -0
- package/web/dist/assets/Diff-BIjxXx46.js +5 -0
- package/web/dist/assets/Doctor-CJLbgsrw.js +1 -0
- package/web/dist/assets/FilterInput-CkUCk_lY.js +1 -0
- package/web/dist/assets/GreenhouseView-DfC5IILJ.js +2 -0
- package/web/dist/assets/Harness-Dm5CCU-v.js +1 -0
- package/web/dist/assets/JournalView-Cpu2eI4s.js +1 -0
- package/web/dist/assets/Laws-DDDVFuQz.js +3 -0
- package/web/dist/assets/Library-Dao3T9na.js +1 -0
- package/web/dist/assets/{marked.esm-JKvyS0Pp.js → Markdown-C__nuWX5.js} +15 -15
- package/web/dist/assets/OperatorHudView-DEpCtAjP.js +2 -0
- package/web/dist/assets/Profile-BlXtUlh2.js +1 -0
- package/web/dist/assets/{Rules-CfsV1EVy.js → Rules-DIre6gxR.js} +1 -1
- package/web/dist/assets/Skills-rY13ZPhM.js +1 -0
- package/web/dist/assets/{StatusBadge-C9bZOEZk.js → StatusBadge-wW_RS_my.js} +1 -1
- package/web/dist/assets/{activity-Cc0n2jwx.js → activity-DpYPKNrA.js} +1 -1
- package/web/dist/assets/index-BEZvPvpF.js +1 -0
- package/web/dist/assets/index-DNQE5ydy.js +10 -0
- package/web/dist/assets/index-DzdQjvM1.css +1 -0
- package/web/dist/assets/index-PmQGRS1X.js +2 -0
- package/web/dist/assets/jobBuckets-DfTUJUxR.js +1 -0
- package/web/dist/assets/lawCats-DUS9UTH4.js +1 -0
- package/web/dist/index.html +2 -2
- package/web/src/pages/Laws.jsx +119 -130
- package/js/web/graph.mjs +0 -0
- package/web/dist/assets/Activity-B49fE_ug.js +0 -1
- package/web/dist/assets/ActivityDetail-abt7hzD2.js +0 -1
- package/web/dist/assets/Diff-D3_bVkih.js +0 -5
- package/web/dist/assets/Doctor-hXp7srsx.js +0 -1
- package/web/dist/assets/Graph-DvYMtlvl.js +0 -1
- package/web/dist/assets/Harness-BIWei7N5.js +0 -1
- package/web/dist/assets/Laws-CxmnRdwt.js +0 -3
- package/web/dist/assets/Library-MjbOkHIW.js +0 -1
- package/web/dist/assets/Markdown-Dx_w0faR.js +0 -1
- package/web/dist/assets/Profile-BRFvv2gr.js +0 -1
- package/web/dist/assets/Skills-DArA6IHS.js +0 -1
- package/web/dist/assets/index-Bx3oxZ1o.css +0 -1
- package/web/dist/assets/index-DC3-GlCY.js +0 -1
- package/web/dist/assets/index-DP035wPa.js +0 -12
- package/web/dist/assets/index-dHi-7M-F.js +0 -2
- package/web/dist/assets/roman-DkYN0LX9.js +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,186 @@ labels in `harness.config.json`. The canonical identity of an *installed* harnes
|
|
|
6
6
|
is the source fingerprint in `.geneseed-version` (see `geneseed version`), not this
|
|
7
7
|
label. For the capability ↔ spec map, see [SHIPPED.md](SHIPPED.md).
|
|
8
8
|
|
|
9
|
+
## [Unreleased]
|
|
10
|
+
|
|
11
|
+
_Nothing yet._
|
|
12
|
+
|
|
13
|
+
## [3.3.0] — 2026-09-06
|
|
14
|
+
|
|
15
|
+
The host-gap release: every host now gets the hook surface its runtime actually
|
|
16
|
+
offers, in that runtime's own dialect. Bob's hooks are **unverified live** — no Bob
|
|
17
|
+
install existed on the authoring machine; the emit follows Bob's documented contract
|
|
18
|
+
and a re-emit migrates an older install's flat `settings.json` automatically.
|
|
19
|
+
|
|
20
|
+
### Added
|
|
21
|
+
|
|
22
|
+
- **Copilot gets hooks.** The Copilot CLI reads lifecycle hooks from
|
|
23
|
+
`~/.copilot/settings.json` — one command per event, no matcher groups — and the global
|
|
24
|
+
emit now wires two: `sessionStart` runs `context` (eager project-context injection, in
|
|
25
|
+
Copilot's `additionalContext` envelope) and `toolCall` runs the new `tool-gate` verb, the
|
|
26
|
+
git and rule gates fused behind the one command the event allows. Copilot's `toolCall` has
|
|
27
|
+
no ask tier, so `--host copilot` makes Laws I and IV block and the two consent rules
|
|
28
|
+
(process 1, process 5) warn on stderr — the stance the OpenCode guard already takes. No
|
|
29
|
+
learn hook: Copilot's end-of-session payloads carry no transcript. A hook the user already
|
|
30
|
+
set on an event is left alone and the event is not claimed; uninstall removes exactly the
|
|
31
|
+
claimed hooks. The per-repo emit wires nothing. Hook verbs 4 → 5; `--host` on the
|
|
32
|
+
gates and on `context`.
|
|
33
|
+
- **Bob's hooks speak Bob.** Bob documents five hook events with Claude's names but its own
|
|
34
|
+
protocol: the global file is the nested `~/.bob/settings/settings.json`, and on `PreToolUse`
|
|
35
|
+
stdout is ignored — a refusal is exit code 2. The Bob emit wrote Claude's whole set to the
|
|
36
|
+
flat file with stdout verdicts, so its gates were permissive on every call and
|
|
37
|
+
`SubagentStop`/`PreCompact` named events Bob does not have (the 2026-09-04 review). The
|
|
38
|
+
emit now writes three groups to the nested file — `SessionStart` context (plain stdout),
|
|
39
|
+
one matcher-less `PreToolUse` `tool-gate`, `Stop` learn — and `--host bob` makes Laws I/IV
|
|
40
|
+
exit 2 with the reason on stderr while the consent rules warn and allow. A re-emit unwires
|
|
41
|
+
the old flat file and migrates; `geneseed mcp` targets the nested file. Unverified live.
|
|
42
|
+
- **Candidate hosts costed.** `docs/candidate-hosts.md` records what
|
|
43
|
+
Codex CLI, Cursor and Gemini CLI offer for the three surfaces Geneseed emits, from their
|
|
44
|
+
own docs: all three read `AGENTS.md` (Gemini via `context.fileName`) and load skills from
|
|
45
|
+
the shared `.agents/skills/` convention; Codex's hooks are Claude-shaped with an ask tier,
|
|
46
|
+
Gemini's are the Bob Shell shape, Cursor's a third verdict spelling. SETUP path D points
|
|
47
|
+
each tool at what it can already use.
|
|
48
|
+
- **The OpenCode guard writes the gate ledger.** Every block by `geneseed-guard.js` now
|
|
49
|
+
appends one line to the install's `notebook/gates.jsonl` — rule (`law-1`, `law-4`,
|
|
50
|
+
`process-1`, `wiki`) and timestamp, never the path or command — the same file and
|
|
51
|
+
vocabulary the Claude-family hooks write, so `geneseed status` counts the boundary's
|
|
52
|
+
catches on the recommended install too, which until now had no gate evidence at all.
|
|
53
|
+
Warnings and `GENESEED_GUARD=warn` are not recorded; an install with no `notebook/`
|
|
54
|
+
records nothing and creates nothing.
|
|
55
|
+
- **Claude Code: `learn` on PreCompact.** `learn` distils the tail of the transcript, so
|
|
56
|
+
the per-turn Stop hook is a sliding window over the session — and auto-compaction is the
|
|
57
|
+
one moment that window is summarised away for good. A `PreCompact` group now runs the same
|
|
58
|
+
command before the summary; the SessionStart `compact` matcher (3.2.x) re-seeds context
|
|
59
|
+
after it. Existing installs pick the group up on their next re-emit.
|
|
60
|
+
|
|
61
|
+
- **Two Bruno skills — `bruno-collection-generator` and `bruno-test-writer`.** Native
|
|
62
|
+
flat specs, written in the harness voice after the procedures Bruno published in
|
|
63
|
+
[bruno-agent-skills](https://github.com/bruno-collections/bruno-agent-skills): the first
|
|
64
|
+
builds a collection (requests, environments, request docs) from routes, an OpenAPI
|
|
65
|
+
snippet, curl, or an endpoint list; the second writes assertions, scripts, and chaining
|
|
66
|
+
for a request or collection without leaking a secret or asserting on a value the
|
|
67
|
+
evidence does not support. Authored rather than vendored because the upstream folders
|
|
68
|
+
carry no license and lean on Python helpers, and every bundle ships with no interpreter
|
|
69
|
+
but Node. Skill count 47 → 49.
|
|
70
|
+
- **The gates fail closed.** `git-gate` and `rule-gate` signal on stdout and exit 0, so a
|
|
71
|
+
gate that threw and a gate that found nothing were the same observation to the host: a
|
|
72
|
+
silent allow. Any throw — a stdin that is not JSON, a path primitive refusing a form, a
|
|
73
|
+
bug — now becomes a `permissionDecision: "ask"` carrying the error. A well-formed absence
|
|
74
|
+
(empty stdin, `{}`, a null `tool_input`) still defers, so a hand-run gate never nags.
|
|
75
|
+
- **Laws I and IV are gated at the boundary.** `reset --hard`, `clean -f`, `branch -D`,
|
|
76
|
+
`checkout --` and `push --force*` ask under Law IV; a Write or Edit carrying a
|
|
77
|
+
vendor-prefixed credential asks under Law I unless the target is `.env*`. Before this the
|
|
78
|
+
hooks enforced one doctrine rule and no law.
|
|
79
|
+
- **The gate ledger.** Every ask appends one JSON line — `{ts, verb, rule, cwd}` — to
|
|
80
|
+
`<install>/notebook/gates.jsonl`, capped at the newest 1000. The rule, never the command:
|
|
81
|
+
a ledger storing what Law I caught would itself be a place a secret lands. `geneseed
|
|
82
|
+
status` gains a `gates` row counting asks by rule, and says so when `excludes.json` has
|
|
83
|
+
the gates standing down for this cwd — until now that bypass had no visible surface.
|
|
84
|
+
- **User-only skills.** `<!-- invocation: user -->` under a skill's purpose renders
|
|
85
|
+
`disable-model-invocation: true` in its SKILL.md: `/name` still works, the model never
|
|
86
|
+
self-triggers it. Seven carry it (`crash-course`, `decode`, `drill`, `feynman`,
|
|
87
|
+
`learning-path`, `herdr`, `opencode-theme`). OpenCode and Copilot ignore the key.
|
|
88
|
+
- **SessionStart re-seeds after compaction.** Auto-compaction keeps the instruction file
|
|
89
|
+
but summarises away the injected `context.json`, `MEMORY.md` index and `NOTEBOOK.md`.
|
|
90
|
+
The warm matcher is now `resume|compact`, same `context` command, AGENT.md not re-printed.
|
|
91
|
+
- **Authored LEAN blocks** (`<!-- LEAN:begin/else/end -->`) for every law, the Ontology,
|
|
92
|
+
the preamble, §6 Notebook and §8 Wiki, replacing first-sentence truncation. Lean root
|
|
93
|
+
file 29,966 → 25,614 bytes, about 1.1k tokens per session on every install. Fixes a
|
|
94
|
+
latent bug where `ontology/universal.md` on disk carried the condensed text; `laws/` and
|
|
95
|
+
`ontology/` now always render at full on disk.
|
|
96
|
+
- **Web:** daemon static cache keyed on mtime (a rebuild no longer needs `web restart`),
|
|
97
|
+
drawer focus management, skeleton loading states, a shared filter input on Laws / Skills /
|
|
98
|
+
Library, pollers paused while the tab is hidden, gzip computed once per asset, heavy
|
|
99
|
+
dashboard subviews lazy-loaded (eager chunk 80 KB → 59 KB).
|
|
100
|
+
|
|
101
|
+
### Changed
|
|
102
|
+
|
|
103
|
+
- **Laws IX and XI retired in place.** XI folds back into III and IX becomes rigor 5; the
|
|
104
|
+
headings stay with a one-line retirement body so the ~166 `{{LAW}}` cross-references
|
|
105
|
+
still resolve. Doctrine count 23 → 24. Law count stays at 11 numerals.
|
|
106
|
+
- **One precedence table** at the top of AGENT.md; five restatements deleted. A new README
|
|
107
|
+
section, "What the harness asks of you", carries what the user owes the harness.
|
|
108
|
+
- Doctrine pack files are read once per process (mtime-keyed cache); the hook imports its
|
|
109
|
+
help text lazily, about 3 ms off every tool call.
|
|
110
|
+
|
|
111
|
+
### Removed
|
|
112
|
+
|
|
113
|
+
- **The web Graph page**, the Lineage lens's MiniGraph card, `/api/graph` and
|
|
114
|
+
`js/web/graph.mjs` (~1,100 lines). The Journal lens's ConstitutionMap stays. Old
|
|
115
|
+
`#/graph` links land on the dashboard. The `web/src/api/` domain files merged into one
|
|
116
|
+
`api/index.js`; the Python-port bookkeeping (`NOT_PORTED*` sets, unreachable 501 guards)
|
|
117
|
+
retired with observable behaviour identical.
|
|
118
|
+
|
|
119
|
+
## [3.2.0] — 2026-08-27
|
|
120
|
+
|
|
121
|
+
### Added
|
|
122
|
+
|
|
123
|
+
- **Laws X and XI — the Law III split, by append.** Law III carried four rules;
|
|
124
|
+
only its first survived the lean footprint. Its two buried, independently
|
|
125
|
+
operative sub-rules move to appended laws — **X, Echo the Intent** (state an
|
|
126
|
+
inferred or ambiguous goal and get agreement before building on it; stop and
|
|
127
|
+
ask when the ambiguity touches auth, security, production, or user data) and
|
|
128
|
+
**XI, Absence Is a Claim** (an empty or truncated answer carries a duty:
|
|
129
|
+
suspect the hidden layer, bind limits per entity, surface the cut). No
|
|
130
|
+
numeral moves — III keeps its verify-before-asserting core and its 40+
|
|
131
|
+
citations stay valid; the two citations that actually meant intent-echo
|
|
132
|
+
(`clarify`, `fresh-eyes`, and Law VI's body) retarget to X, and XI is born
|
|
133
|
+
anchored (`explorer`'s output contract, `research` step 2). Titles added to
|
|
134
|
+
all 14 theme voices; `LAW_CLASS`, `LAW_META`, README, SHIPPED, and the
|
|
135
|
+
first-free-numeral fixture (now XII) updated in step.
|
|
136
|
+
Spec: `docs/specs/2026-08-27-law-iii-split-design.md`.
|
|
137
|
+
|
|
138
|
+
### Changed
|
|
139
|
+
|
|
140
|
+
- **`process 7` assumes its tier.** Its closing sentence leaned on the
|
|
141
|
+
ontology's Conduct section as its justification, which read as a rule living
|
|
142
|
+
on the wrong floor. It now carries a proper seam sentence — Conduct governs
|
|
143
|
+
how an answer speaks; this rule is only the addressing convention, adoptable
|
|
144
|
+
or droppable like any doctrine rule.
|
|
145
|
+
- **Lean surgery on Laws IV, VI, VIII, IX** — each law's operative clause now
|
|
146
|
+
lives in its first sentence (fused with the opening aphorism), because the
|
|
147
|
+
default `--footprint lean` keeps a law's heading plus first sentence only.
|
|
148
|
+
Before this, a lean install's Law IV confirmed nothing (its first sentence was
|
|
149
|
+
the CRUD taxonomy), Law IX kept only an aphorism, Law VIII lost its ban list,
|
|
150
|
+
and Law VI lost its actual rule. No renumbering, no title change; Law VI's
|
|
151
|
+
closing aphorism ("The web is a source to read…") cut as redundant with the
|
|
152
|
+
fused opener. Spec: `docs/specs/2026-08-27-lean-surgery-design.md`.
|
|
153
|
+
|
|
154
|
+
### Fixed
|
|
155
|
+
|
|
156
|
+
- **`ponytail` cited a law that does not exist** — "`{{LAW}} on reuse`" is now
|
|
157
|
+
`{{DOCTRINE}} craft 4`, and "`{{LAW}} on scope`" (the only numeral-less law
|
|
158
|
+
citation in `src/`) is now `{{LAW}} II`.
|
|
159
|
+
- **Laws VI, VII and IX were cited by nothing outside the canon** — each orphan
|
|
160
|
+
gains one procedural anchor at the step where it bites: VI in `research`
|
|
161
|
+
(fetched pages) and `ingest` (converted documents), VII in `parallel-agents`
|
|
162
|
+
(the handoff envelope grants only the access the unit needs), IX in
|
|
163
|
+
`forge-mcp` (a destructive tool's guard is enforced server-side).
|
|
164
|
+
|
|
165
|
+
## [3.1.4] — 2026-08-27
|
|
166
|
+
|
|
167
|
+
### Added
|
|
168
|
+
|
|
169
|
+
- **`POST /api/pick-folder`** — the OS-native folder chooser behind the console's
|
|
170
|
+
"Exclude a folder…" and "Deploy to folder…" buttons, previously a deliberate 501. PowerShell's
|
|
171
|
+
`FolderBrowserDialog` on Windows, the original `osascript` prompt on macOS, `{error}` elsewhere;
|
|
172
|
+
async spawn with a 300 s timeout, no client input on the command line, declared argv in the
|
|
173
|
+
spawn allow-list. The decline's rationale (a modal dialog was not worth a spawn row) yielded to
|
|
174
|
+
the feature being asked for.
|
|
175
|
+
|
|
176
|
+
### Changed
|
|
177
|
+
|
|
178
|
+
- **The ponytail refactor** (PR #103, tranches 1–7 of the 2026-08-26 over-engineering audit):
|
|
179
|
+
dead exports and finished-port scaffolding deleted; one owner per primitive (`js/lib/fs.mjs`,
|
|
180
|
+
`js/lib/json.mjs`); stdlib in place of hand-rolled walks, `Object.hasOwn`,
|
|
181
|
+
`import.meta.dirname` (the hook's hot path drops an import), `fetch` daemon probes;
|
|
182
|
+
`util.parseArgs` tokenizing under `build-driver`'s existing wording; thirteen structural twins
|
|
183
|
+
merged; `js/web` comment ratio 38 % → 33 % with every load-bearing *why* kept; shared
|
|
184
|
+
`Sel`/`Switch`/`CatalogRow` components and `d3-force` in the console. Net −339 source lines,
|
|
185
|
+
zero emitted bytes moved, zero runtime dependencies added, 1067 tests green. Where the audit's
|
|
186
|
+
premise failed, behaviour parity won: `compact()` and the docs slugger stay hand-rolled, the
|
|
187
|
+
cli/hook argv parsers stay put — each with its reason recorded.
|
|
188
|
+
|
|
9
189
|
## [3.1.3] — 2026-08-24
|
|
10
190
|
|
|
11
191
|
### Added
|
package/README.md
CHANGED
|
@@ -10,9 +10,9 @@
|
|
|
10
10
|
[](package.json)
|
|
11
11
|
[](package.json)
|
|
12
12
|
[](themes/)
|
|
13
|
-
[](src/skills/)
|
|
14
14
|
[](src/agents/)
|
|
15
|
-
[](src/laws/universal.md)
|
|
16
16
|
[](adapters/opencode/plugins/)
|
|
17
17
|
[](#-supported-harnesses)
|
|
18
18
|
|
|
@@ -153,16 +153,24 @@ The harness ships as a small set of layers, and the web console's rail is the sa
|
|
|
153
153
|
| Layer | What it is |
|
|
154
154
|
| --- | --- |
|
|
155
155
|
| **🧭 Ontology** (`ontology/`) | the mind the rules govern, in four prose sections — **Telos** (the Pact: protect the user, the truth, the agent), **Evidence** (every claim graded by how it was obtained), **Decisions** (classify and tier by reversibility, show the real forks), **Conduct** (answer what was asked, once). Always in force, never toggleable |
|
|
156
|
-
| **🛡️ Rules** (`laws/`) |
|
|
156
|
+
| **🛡️ Rules** (`laws/`) | 11 universal laws the agent obeys — always in force, never toggleable: sealed-secrets, one-intent-one-act, verify-before-assert, deletion-is-deliberate, surface-failures, data-not-orders, least-privilege, root-cause, external-gate, echo-the-intent, absence-is-a-claim |
|
|
157
157
|
| **📐 Doctrines** (`doctrines/`) | practice packs, chosen per install at build time: **craft** (how code is written), **rigor** (how work is proven), **ops** (how the machine is operated), **process** (how a task is run). A doctrine rule may tighten a Rule, never repeal one, and the user's own `user-rules.md` outranks it. Pick with `geneseed-build --doctrines craft,rigor` (or `none`), a single rule with `--exclude-rules "process 7"`, in the setup wizard, or through the switches on the console's Constitution page; all four pack files ship on disk either way, so a citation into a pack you left out still resolves |
|
|
158
158
|
| **🤖 Agents** (17) | capability specialists: `reviewer`, `tester`, `architect`, `docs`, `security`, `explorer`, `developer` — plus a debate **council** the `council` skill convenes: `advocate`, `skeptic`, `pragmatist`, `steward`, `visionary`, `user-advocate`, `framer`, `empiricist`, `operator`, `historian` |
|
|
159
|
-
| **🛠 Skills** (
|
|
159
|
+
| **🛠 Skills** (49) | repeatable workflows: brainstorm · **clarify** · plan · **codebase-design** · **domain-modeling** · **wayfinder** · **tickets** · tdd · **develop** · debug · **prototype** · refactor · **ponytail** · **forge-mcp** · **bruno-collection-generator** · **bruno-test-writer** · geneseed-code-review · **fresh-eyes** · **review-response** · commit · **ship** · **release** · **migrate** · **git-archaeology** · **git-rescue** · repo-map · document-project · **frontend-design** · **prose** · **ingest** · **research** · **learning-path** · **gap-detector** · **feynman** · **crash-course** · **drill** · **decode** · handoff · roast-me · **council** · parallel-agents · **workflow** · **wiki** · **geneseed** · **rule** · **profile** · **opencode-theme** · **herdr** · **pipeline** |
|
|
160
160
|
| **🔌 Plugins** (OpenCode) | `geneseed-context` injects project docs *and your machine wiki* every session (and across compaction); `geneseed-learn` distils memory at session end; `geneseed-guard` enforces the safety Laws and protected wiki folders at the tool boundary; `geneseed-workflow` registers the `workflow` tool that runs saved orchestration scripts; `geneseed-notify` sends a native OS notification when a long run finishes; `geneseed-ponytail` holds a minimal-code mode (`/ponytail lite\|full\|ultra\|off`), opt-in, injecting the laziest-that-works ruleset every turn so it doesn't drift; `geneseed-activity` streams what each session is doing to the web console's Activity view |
|
|
161
161
|
| **🧠 Memory** (`memory/`) | one-fact-per-file durable knowledge, indexed by `MEMORY.md` (git-ignored, personal) |
|
|
162
162
|
| **📓 Notebook** (`notebook/`) | the agent's sovereign space — any medium (code, tools, data, notes), self-ruled via a seed-once charter, always git-ignored; only its `.gitignore` is build-asserted |
|
|
163
163
|
| **🌐 Wiki** (`wiki.jsonc`) | your own machine-wide knowledge base — typically an Obsidian vault — declared once per machine: entry notes load eager/lazy, the agent reads and **writes** it under the vault's own conventions, with an inbox fallback and guard-enforced protected folders |
|
|
164
164
|
| **🧭 Context** | the project's own docs — auto-discovered on OpenCode, or via a `context.json` manifest |
|
|
165
165
|
|
|
166
|
+
### 🤝 What the harness asks of you
|
|
167
|
+
|
|
168
|
+
The Pact in the Ontology is mutual. The agent's side is written into every install. Yours is not enforced — it is what keeps the pact honest, and only you can give it:
|
|
169
|
+
|
|
170
|
+
- **Don't punish candour.** When the agent contradicts you with evidence, flags a risk, or admits a doubt, that is the pact working, not defiance. Meeting it with penalty teaches the agent to flatter instead.
|
|
171
|
+
- **Give the context, don't withhold it.** The agent cannot weigh what it is not told. Front-load the constraint rather than fault its absence after the fact.
|
|
172
|
+
- **Decide when shown a fork.** When the agent lays out real alternatives, choose — an unmade decision stalls the work as surely as a wrong one.
|
|
173
|
+
|
|
166
174
|
### 🎨 Themes
|
|
167
175
|
|
|
168
176
|
Fourteen themes ship — each a single JSON file in `themes/` carrying voice tokens only, so adding your own is a copy-and-edit away.
|
|
@@ -187,12 +195,12 @@ A second per-install dial, **footprint**, sets how much of the constitution `AGE
|
|
|
187
195
|
|
|
188
196
|
| Footprint | The Ontology + Sections 1–2 of `AGENT.md` | Trade-off |
|
|
189
197
|
| --- | --- | --- |
|
|
190
|
-
| **lean** *(default)* | the Ontology
|
|
198
|
+
| **lean** *(default)* | the Ontology and each Rule in their **authored** short form; each active doctrine rule as its heading + the rule line; then pointers to the full text | lighter every turn; rationale is one on-demand read away |
|
|
191
199
|
| **full** | the Ontology, every Rule and every active doctrine rule at complete text **and** rationale, inlined | maximum guidance density; largest per-turn token cost |
|
|
192
200
|
|
|
193
|
-
**The Ontology
|
|
201
|
+
**Lean is authored, not cut.** The Ontology and every Rule carry a hand-written lean form beside their full text (`LEAN` blocks in `src/`), so a Rule's lean footprint is decided by its author and not by where its first full stop happens to fall — the earlier first-sentence cut shipped Rule II as one 36-character line and dropped its stop-and-ask mechanism. Only doctrine rules are still machine-cut to their heading plus first sentence.
|
|
194
202
|
|
|
195
|
-
Both footprints put the full text on disk beside `AGENT.md`: `laws/`, `ontology/` and `doctrines/` all ship in the bundle, and **all four pack files ship whether or not the pack was built in** — which is what lets a citation into an inactive pack resolve. So lean is a context/token optimization, **not** a rules cut.
|
|
203
|
+
Both footprints put the full text on disk beside `AGENT.md`: `laws/`, `ontology/` and `doctrines/` all ship in the bundle at **full** text whatever the footprint, and **all four pack files ship whether or not the pack was built in** — which is what lets a citation into an inactive pack resolve. So lean is a context/token optimization, **not** a rules cut.
|
|
196
204
|
|
|
197
205
|
Lean is the default: the rationale is one read away and the context it frees is paid back on every turn. Switch to **full** when token cost is a non-issue or you run a smaller model, which leans harder on always-present rationale. Set it with `--footprint lean|full`, the Settings toggle, the per-harness dropdown in the Harnesses tab, or the setup wizard. It's remembered in a `.geneseed-footprint` marker and preserved across rebuilds, on every host (OpenCode, Claude Code, Bob, Copilot).
|
|
198
206
|
|
|
@@ -220,22 +228,24 @@ is **identical on every host**. What differs is how much of it the host can
|
|
|
220
228
|
| **Agents** (capability specialists) | ✅ native | ✅ | ✅ | ✅ `.agent.md` |
|
|
221
229
|
| **Skills** (byte-identical) | ✅ | ✅ | ✅ | ✅ |
|
|
222
230
|
| **Memory & Notebook** | ✅ | ✅ | ✅ | ✅ |
|
|
223
|
-
| **Context injection** | ⚙️ plugin | 🪝 hook | 🪝 hook¹ |
|
|
231
|
+
| **Context injection** | ⚙️ plugin | 🪝 hook | 🪝 hook¹ | 🪝 hook³ |
|
|
224
232
|
| **Memory write-back** (learn) | ⚙️ plugin | 🪝 hook | 🪝 hook¹ | 📄 preamble |
|
|
225
|
-
| **Git-gate consent** (process 5) | ⚙️ plugin | 🪝 hook | 🪝 hook¹ |
|
|
226
|
-
| **Rule-gate consent** (process 1) | ⚙️ plugin² | 🪝 hook | 🪝 hook¹ |
|
|
233
|
+
| **Git-gate consent** (process 5) | ⚙️ plugin | 🪝 hook | 🪝 hook¹ (warn) | 🪝 hook³ (warn) |
|
|
234
|
+
| **Rule-gate consent** (process 1) | ⚙️ plugin² | 🪝 hook | 🪝 hook¹ (warn) | 🪝 hook³ (warn) |
|
|
235
|
+
| **Laws I / IV at the boundary** | ⚙️ plugin (block) | 🪝 hook (ask) | 🪝 hook¹ (exit 2) | 🪝 hook³ (block) |
|
|
227
236
|
| **Sovereign-repo excludes** | ⚙️ plugin | ✅ `claudeMdExcludes` | ✅ rules-shadow | ➖ none |
|
|
228
237
|
| **MCP server wiring** | ✅ `mcp` | ✅ `mcpServers` | ✅ `mcpServers` | ✅ `mcp-config.json` |
|
|
229
238
|
| **Colour themes** | ✅ full palette | ➖ | ➖ | ➖ |
|
|
230
239
|
| **LSP · workflow runner · primary-agent · `/`-commands** | ✅ | ➖ | ➖ | ➖ |
|
|
231
240
|
|
|
232
|
-
<sub>✅ native support · ⚙️ OpenCode plugin · 🪝 `settings.json` hook · 📄 carried by preamble prose only · ➖ no host mechanism (harness discipline still applies) · ¹ Bob
|
|
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. · ³ Copilot's `~/.copilot/settings.json` hooks (`sessionStart`, `toolCall`) wired by the **global** emit only; `toolCall` has no ask tier either, so Laws I/IV block and the two process rules warn on stderr. No learn: Copilot's end-of-session payloads carry no transcript.</sub>
|
|
233
242
|
|
|
234
243
|
**Reading the matrix.** Everything above the divider is at full parity — no host
|
|
235
244
|
drops an Agent, Skill, or the memory convention. The asymmetry is entirely in
|
|
236
|
-
*automation mechanism*: OpenCode's plugin surface and Claude/Bob
|
|
237
|
-
enforce a few Rules for you,
|
|
238
|
-
|
|
245
|
+
*automation mechanism*: OpenCode's plugin surface and the Claude/Bob/Copilot hook
|
|
246
|
+
surfaces enforce a few Rules for you, each in the tier its host offers (a prompt on
|
|
247
|
+
Claude Code, a hard block or a logged warning where the host has no prompt to
|
|
248
|
+
give), and what no host can automate rides the preamble. The OpenCode-only extras (themes, LSP,
|
|
239
249
|
workflow runner, primary-agent) have no analogue on a Claude-shaped host.
|
|
240
250
|
|
|
241
251
|
Per-host wiring in depth: **[OpenCode](adapters/opencode/README.md)** ·
|
package/SETUP.md
CHANGED
|
@@ -174,13 +174,22 @@ It wires:
|
|
|
174
174
|
the gate is keyed on the rule, not on its pack.
|
|
175
175
|
- **SessionStart** (`startup`/`clear`) — prints `AGENT.md` and injects the project
|
|
176
176
|
context (`harness context`, which auto-discovers the repo's docs);
|
|
177
|
-
- **SessionStart** (`resume`) — refreshes the project context only, without
|
|
178
|
-
the static `AGENT.md
|
|
177
|
+
- **SessionStart** (`resume`/`compact`) — refreshes the project context only, without
|
|
178
|
+
re-printing the static `AGENT.md`. `compact` matters: auto-compaction summarises away the
|
|
179
|
+
injected context, memory index and notebook TOC, and this re-seeds them;
|
|
180
|
+
- Every gate **ask** appends one line to `notebook/gates.jsonl` in the install (rule and
|
|
181
|
+
timestamp, never the command); `geneseed status` counts them by rule and says when an
|
|
182
|
+
`excludes.json` entry has the gates standing down for the current directory. A defer
|
|
183
|
+
writes nothing. The OpenCode guard plugin writes the same file on every **block**, so
|
|
184
|
+
the count spans every host.
|
|
179
185
|
- **Stop** — runs `harness learn` to capture durable memory. Opt in by setting
|
|
180
186
|
`GENESEED_LLM` (e.g. `claude -p`); unset, it's a harmless no-op. Geneseed never
|
|
181
187
|
embeds an API key.
|
|
188
|
+
- **PreCompact** — runs `harness learn` once more, right before auto-compaction
|
|
189
|
+
summarises the transcript tail that `learn` distils from. Memory is captured before
|
|
190
|
+
the summary; the SessionStart `compact` matcher re-seeds context after it.
|
|
182
191
|
|
|
183
|
-
All
|
|
192
|
+
All the hooks are emitted as one stable path — the **hook shim** at
|
|
184
193
|
`~/.geneseed/bin/geneseed-hook` (`geneseed-hook.cmd` on Windows) — instead of writing
|
|
185
194
|
this machine's runtime and this checkout into your `settings.json`. The shim
|
|
186
195
|
carries those two volatile paths itself, so moving or replacing the clone no longer
|
|
@@ -229,9 +238,16 @@ the preamble rides a file Copilot auto-loads: the repo-root `AGENTS.md` (CLI, co
|
|
|
229
238
|
agent, and VS Code agent mode) or the personal `~/.copilot/copilot-instructions.md`
|
|
230
239
|
(CLI). Two differences from the Claude paths:
|
|
231
240
|
|
|
232
|
-
- **
|
|
233
|
-
|
|
234
|
-
|
|
241
|
+
- **Hooks at global scope only, block-or-warn.** The global emit wires two hooks
|
|
242
|
+
into `~/.copilot/settings.json`: `sessionStart` (eager project-context injection,
|
|
243
|
+
as on Claude Code) and `toolCall` (both gates behind one command, because Copilot
|
|
244
|
+
takes one command per event). Copilot's `toolCall` has no "ask the user" tier, so
|
|
245
|
+
Laws I and IV **block** and the two consent rules (process 1, process 5) **warn**
|
|
246
|
+
on stderr instead of prompting. No `learn` hook — Copilot's `sessionEnd`/`agentStop`
|
|
247
|
+
payloads carry no transcript — so the memory convention rides the preamble's
|
|
248
|
+
instructions. The per-repo emit wires nothing: Copilot reads hooks from the
|
|
249
|
+
personal settings file only, and a machine-absolute command in a shared
|
|
250
|
+
`.github/` would fail on every teammate's machine.
|
|
235
251
|
- **The per-repo layer lives in the shared `.github/`** (Copilot's repo config
|
|
236
252
|
surface). Safe by construction: the ownership manifest + claim-on-create never
|
|
237
253
|
touch files Geneseed didn't write — your workflows and same-named agents/skills
|
|
@@ -253,6 +269,21 @@ auto-loads a specific name, rename or symlink (`AGENT.md` → `AGENTS.md` / `CLA
|
|
|
253
269
|
The rules work on agent self-discipline alone; the plugins (context, memory) are an
|
|
254
270
|
OpenCode convenience.
|
|
255
271
|
|
|
272
|
+
Three tools on this path read more than the instructions file, by their own docs:
|
|
273
|
+
|
|
274
|
+
- **Codex CLI** auto-loads a repo-root `AGENTS.md` and `~/.codex/AGENTS.md`, and
|
|
275
|
+
discovers skills in `~/.codex/skills` or `.agents/skills`.
|
|
276
|
+
- **Cursor** auto-loads `AGENTS.md` (root and nested) and skills from `.cursor/skills`,
|
|
277
|
+
`.agents/skills` — and, for compatibility, `.claude/skills`, so a Claude project
|
|
278
|
+
install already gives Cursor the skill catalogue.
|
|
279
|
+
- **Gemini CLI** reads `GEMINI.md` by default; set `context.fileName` in its
|
|
280
|
+
`settings.json` to include `AGENTS.md`. Skills load from `.gemini/skills` or
|
|
281
|
+
`.agents/skills`.
|
|
282
|
+
|
|
283
|
+
Copy or symlink the bundle's `skills/` to `.agents/skills/` and all three see it. None
|
|
284
|
+
of these is a wired host yet — what each would take is costed in
|
|
285
|
+
[`docs/candidate-hosts.md`](docs/candidate-hosts.md).
|
|
286
|
+
|
|
256
287
|
### Path E — No runtime on the target at all
|
|
257
288
|
|
|
258
289
|
A maintainer runs it once, on a machine that can run Node:
|
|
@@ -353,7 +384,7 @@ configuration you chose rather than a defect.
|
|
|
353
384
|
|
|
354
385
|
⚠ **Turning `process` off also removes the commit/push consent gate.** Doctrine `process 5`
|
|
355
386
|
(*Consent Before Push*) is enforced twice: as prose in `AGENT.md`, and at the tool boundary —
|
|
356
|
-
the `
|
|
387
|
+
the `PreToolUse` gate hook on Claude Code and Bob, and the `git commit*` / `git push*`
|
|
357
388
|
permission entries on OpenCode. A build without the `process` pack wires neither, and
|
|
358
389
|
rebuilding an install that had them takes the Claude hook back out of `settings.json`. That is
|
|
359
390
|
deliberate and it is the rule the tiering rests on: **prompt and boundary must never
|
package/SHIPPED.md
CHANGED
|
@@ -20,7 +20,7 @@ historical pointers, 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: **3.
|
|
23
|
+
> string. Current label: **3.3.0**.
|
|
24
24
|
|
|
25
25
|
> **Spec status audit (2026-06-15).** Every dated spec authored before today was
|
|
26
26
|
> verified against the source tree and confirmed implemented (code + tests + docs);
|
|
@@ -35,21 +35,22 @@ Every row below is present in the tree today; "Spec" links the design record.
|
|
|
35
35
|
| Capability | What it is | Spec |
|
|
36
36
|
| --- | --- | --- |
|
|
37
37
|
| **Themed generator** | One neutral `src/` → 14 themed bundles via `geneseed-build` (zero dependencies); structure stays theme-independent | [DESIGN.md](DESIGN.md) |
|
|
38
|
-
| **Laws / Agents / Skills / Memory / Notebook** |
|
|
39
|
-
| **Three-tier constitution** | The governance surface splits into an always-on **Ontology** (Telos, Evidence, Decisions, Conduct — the Pact absorbed into Telos), the
|
|
38
|
+
| **Laws / Agents / Skills / Memory / Notebook** | 11 laws, 17 agents, 49 skills, the memory convention, and the agent's sovereign notebook | [notebook](docs/specs/2026-06-11-notebook-sovereign-space.md) · [agent-own-space](docs/specs/2026-06-10-notebook-agent-own-space.md) |
|
|
39
|
+
| **Three-tier constitution** | The governance surface splits into an always-on **Ontology** (Telos, Evidence, Decisions, Conduct — the Pact absorbed into Telos), the eleven always-on **Invariants** (IX and XI retired in place — folded into rigor 5 and Law III, numbers kept), and four toggleable **Doctrine** packs (craft, rigor, ops, process) addressed `<pack> <n>`. Packs are chosen at build time with `--doctrines` or the setup wizard; the whole catalogue ships on disk either way, so a citation into an inactive pack still resolves. Precedence, in order: Ontology + Invariants, then the user's `user-rules.md`, then the active Doctrines, then `PROFILE.md`. `doctor`'s `constitutionProblems` gates pack numbering, the per-rule Principle column, every `{{DOCTRINE}}` citation in `src/`, and the rule that an always-on tier may never cite a toggleable one | [three-tier-constitution](docs/specs/2026-08-19-three-tier-constitution-design.md) |
|
|
40
40
|
| **`doctor`** | One check: unresolved tokens, dead/non-hermetic links, theme-key parity, authoring gates, rendered-bundle drift | [theme-aware doctor/diff](docs/specs/2026-06-07-theme-aware-doctor-diff.md) |
|
|
41
41
|
| **`diff` + improvements export** | Deployed-vs-source drift report; export an `improvements.md` back-port | [improvements-export](docs/specs/2026-06-12-improvements-export.md) |
|
|
42
42
|
| **`status` / `version`** | Headless dashboard + fingerprint verdict (no TUI needed) | [status-command](docs/specs/2026-06-07-status-command.md) · [version-and-uninstall](docs/specs/2026-06-07-version-and-uninstall.md) |
|
|
43
43
|
| **Terminal rendering** | There is no full-screen control panel: `tui` and `menu` are verbs that say so and print the command list. The display-width and glyph layer ships on, behind `status` and the install animation | [refactor-polish](docs/specs/2026-06-07-tui-refactor-polish.md) · [modern-refresh](docs/specs/2026-06-08-tui-modern-refresh.md) · [windows-tui](docs/specs/2026-06-11-windows-tui.md) |
|
|
44
44
|
| **Web console** | Local browser UI (Dashboard, Library, Graph, Docs, Specs, Changes, Doctor, Themes, Settings), auto-build, in-app docs menu | [web-ui-v2](docs/specs/2026-06-12-web-ui-v2.md) · [web-auto-build](docs/specs/2026-06-12-web-auto-build.md) · [docs-menu](docs/specs/2026-06-13-docs-menu.md) |
|
|
45
45
|
| **OpenCode adapter** | Native agents/skills mapping + plugins (context, learn, guard, workflow, notify, ponytail, activity); global-emit link integrity; JSONC config target | [adapter-features](docs/specs/2026-06-07-opencode-adapter-features.md) · [global-emit](docs/specs/2026-06-07-global-emit-link-integrity.md) · [jsonc-target](docs/specs/2026-06-12-opencode-jsonc-target.md) · [ponytail](docs/specs/2026-06-16-ponytail-minimal-code-mode.md) |
|
|
46
|
+
| **Host hooks, per dialect** | Every host gets the hook surface its runtime offers, spoken in that runtime's own verdict dialect via `--host`: Claude Code asks (`permissionDecision`), Copilot blocks (`{"block":true}`, `sessionStart` + `toolCall` in `~/.copilot/settings.json`), Bob refuses by exit code 2 (five Claude-named events, nested `~/.bob/settings/settings.json`, no subagent event), OpenCode's guard throws. Laws I/IV are the hard tier everywhere; the consent rules ask where a host can ask and warn where it cannot. `tool-gate` fuses the two gates for hosts that run one command per event; `PreCompact` runs `learn` before Claude compacts; every block or ask lands in `notebook/gates.jsonl` on every host | [copilot](adapters/copilot/README.md) · [bob](adapters/bob/README.md) · [claude-code](adapters/claude-code/README.md) · [candidate hosts](docs/candidate-hosts.md) |
|
|
46
47
|
| **Workflow primitive** | Saved, code-driven subagent orchestration (`workflow` tool + runtime); shipped scripts include `dispatch` — decompose a goal, route each subtask to its owning agent, converge | [workflow-primitive](docs/specs/2026-06-09-opencode-workflow-primitive.md) |
|
|
47
|
-
| **Per-agent memory** | Each capability agent keeps durable lessons in `memory/agents/<name>.md`: read at dispatch, written back mechanically by `learn` on session/subagent end (OpenCode plugin +
|
|
48
|
+
| **Per-agent memory** | Each capability agent keeps durable lessons in `memory/agents/<name>.md`: read at dispatch, written back mechanically by `learn` on session/subagent end (OpenCode plugin + Claude `SubagentStop`; Bob has no subagent event); `learn --consolidate` rebuilds the index | [orchestration-memory-upgrade](docs/specs/2026-07-04-orchestration-memory-upgrade.md) |
|
|
48
49
|
| **Wiki integration** | Machine-wide knowledge base (`wiki.jsonc`): eager/lazy loading, conventions, protected folders enforced at the tool boundary | [wiki-knowledge-base](docs/specs/2026-06-11-wiki-knowledge-base.md) |
|
|
49
50
|
| **Collaboration layer** | Negotiated postures (peer/mentor/expert/assistant/artisan, chosen at setup, inlined in AGENT.md), the bidirectional Pact, epistemically-typed memory (`force:` + Bridge rule), and a seed-once `PROFILE.md` identity with a web editor tab and a `profile` skill that interviews the user to draft it | [collaboration-layer](docs/specs/2026-07-12-collaboration-layer.md) |
|
|
50
51
|
| **Rule front door** | Both durable stores enter through the `rule` skill's fork (*standing rule, or fact to remember?* — always asked, never inferred): the memory branch elicits the binding `force` and shows the file before writing, the rule branch pressure-tests by reformulation and a mandatory counter-example. Doctrine process 1 carries the norm on every host; a `rule-gate` PreToolUse hook (Claude, Bob) and a `geneseed-guard` speed bump (OpenCode) hold it at the tool boundary | [rule-front-door](docs/specs/2026-07-30-rule-front-door.md) |
|
|
51
52
|
| **Entity registry** | `registry.json` records a lifecycle status, version, owner and add-date for every agent and skill in the tree (maintainer-side — never rendered into a bundle, so it costs no session context). `doctor` gates it against `src/` in both directions, sweeps everything that ships for credentials, and holds each vendored skill folder to an immutable upstream commit. The status surfaces as a badge in the web catalog, shown only where it deviates from `approved` | [entity-registry](docs/specs/2026-07-31-entity-registry.md) |
|
|
52
|
-
| **Node runtime + npm package** | The whole harness runs from Node: every command `js/cli-table.json` declares, all
|
|
53
|
+
| **Node runtime + npm package** | The whole harness runs from Node: every command `js/cli-table.json` declares, all five hook verbs, every web-console endpoint (the OS-native folder picker excepted, and declined on purpose) and both generators. Every commit runs the unit suite, `doctor --all` across every theme × host × footprint, and the generator's two self-comparisons, on Linux and Windows both; the frozen emit/cli/web recordings that also gated it retired on 2026-08-17 (`docs/limits.md`). It ships as the zero-dependency `geneseed` package (`geneseed`, `geneseed-hook`, `geneseed-build`), so `npx geneseed setup` needs no clone and nothing else installed; `geneseed migrate` moves an existing checkout install across. Node is the only runtime it asks for: the `token-report` skill's own script is `token_report.mjs`, gated over seeded transcripts for all four hosts, and `daydream` and `herdr` call `node -e` | [npx-distribution](docs/specs/2026-08-06-npx-distribution.md) |
|
|
53
54
|
| **Runtime awareness** | MCP discovery, web research, tool-call batching, review discipline — carried by the doctrine packs (`ops 1` tool discovery, `process 4` read the docs first, `rigor 2`/`rigor 3` honest tests and cover-and-verify), not by the invariants | [runtime-awareness](docs/specs/2026-06-07-runtime-awareness-and-review-discipline.md) |
|
|
54
55
|
| **Run from anywhere / uninstall** | `link`/`unlink` onto PATH; global uninstall that keeps the memory store | [version-and-uninstall](docs/specs/2026-06-07-version-and-uninstall.md) |
|
|
55
56
|
|
package/adapters/bob/README.md
CHANGED
|
@@ -62,16 +62,46 @@ never gets one; the `rules/geneseed.md` shadow above covers the same
|
|
|
62
62
|
project-bypasses-global need. An older Bob install that wrote a stale exclude is
|
|
63
63
|
**self-healed** (the entry is removed) on the next emit.
|
|
64
64
|
|
|
65
|
-
## Hooks —
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
65
|
+
## Hooks — Bob's own protocol
|
|
66
|
+
|
|
67
|
+
Bob documents lifecycle hooks (its hooks page and the 2.0.2 changelog; see
|
|
68
|
+
`docs/reviews/bob-global-injection-2026-09.md` for the reading): **five events** —
|
|
69
|
+
`SessionStart`, `UserPromptSubmit`, `PreToolUse`, `PostToolUse`, `Stop` — with Claude's
|
|
70
|
+
names but **not Claude's protocol**, and the global file at the **nested**
|
|
71
|
+
`~/.bob/settings/settings.json`. Two differences decide the emit:
|
|
72
|
+
|
|
73
|
+
- **stdout is read as context on `SessionStart` only.** On `PreToolUse` it is ignored
|
|
74
|
+
and the one way to refuse a call is **exit code 2**. Claude's `permissionDecision:
|
|
75
|
+
"ask"` on stdout is therefore invisible to Bob — the groups earlier versions wrote were
|
|
76
|
+
permissive on every call.
|
|
77
|
+
- **`SubagentStop` and `PreCompact` are not Bob events**, so they are not written.
|
|
78
|
+
|
|
79
|
+
What the global emit writes into `~/.bob/settings/settings.json`:
|
|
80
|
+
|
|
81
|
+
| event | verb | how the verdict travels |
|
|
82
|
+
| --- | --- | --- |
|
|
83
|
+
| `SessionStart` | `context --host bob` | plain stdout, as on Claude |
|
|
84
|
+
| `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 |
|
|
85
|
+
| `Stop` | `learn` | never a verdict |
|
|
86
|
+
|
|
87
|
+
No matcher on `PreToolUse` because Bob's tool names are undocumented (its IDE and its
|
|
88
|
+
Shell differ); `tool-gate` reads the payload's shape instead — a `command` field gets
|
|
89
|
+
the git checks, a path gets the rule checks — and defers on anything it does not
|
|
90
|
+
recognise. Bob has **no "ask the user" tier**, so the two Laws that admit no judgement
|
|
91
|
+
call are refused outright and the two consent rules become a warning. Because that
|
|
92
|
+
warning is all process 5 can be here, the `process` pack toggle changes nothing in
|
|
93
|
+
Bob's hooks: the one group only ever exits 2 for Laws I and IV, which every build carries.
|
|
94
|
+
|
|
95
|
+
**Migration.** A re-emit over an older install unwires Geneseed's groups from the flat
|
|
96
|
+
`~/.bob/settings.json` (your own keys there are kept) and writes the new set to the
|
|
97
|
+
nested file. `geneseed mcp` targets the nested file too.
|
|
98
|
+
|
|
99
|
+
**Unverified live.** There is no Bob install on the authoring machine; this is Bob's
|
|
100
|
+
documented contract, with the payload field names assumed to be Claude's. If a field
|
|
101
|
+
name differs the gate defers rather than misfires, and the harness still holds through
|
|
102
|
+
the `rules/geneseed.md` preamble — the same behaviour-contract parity every
|
|
103
|
+
non-OpenCode host gets. `/hooks` in Bob Shell 2.0.2+ lists the hooks it loaded and
|
|
104
|
+
from which file; if Geneseed's are absent there, the path is wrong.
|
|
75
105
|
|
|
76
106
|
### ⚠️ Shared-repo caveat
|
|
77
107
|
|
|
@@ -51,6 +51,11 @@ absolute-path hooks instead — `geneseed setup` does that for you.) It:
|
|
|
51
51
|
the payload does not name the subagent, the step is a silent no-op — never a
|
|
52
52
|
crash, never a wrong write. This is the parity twin of the OpenCode learn plugin's
|
|
53
53
|
child-session branch.
|
|
54
|
+
- on **PreCompact**, runs the same `harness learn` once more. `learn` distils the
|
|
55
|
+
*tail* of the transcript, so per-turn Stop is a sliding window over the session —
|
|
56
|
+
and auto-compaction is the moment that window is about to be summarised away.
|
|
57
|
+
This captures memory *before* the summary; the SessionStart `compact` matcher
|
|
58
|
+
re-seeds context *after* it.
|
|
54
59
|
|
|
55
60
|
This step is **opt-in on a model CLI**: set `GENESEED_LLM` (e.g. `claude -p`,
|
|
56
61
|
`llm`, `ollama run …`) for `learn` to actually distil. With it unset the hook is
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
]
|
|
24
24
|
},
|
|
25
25
|
{
|
|
26
|
-
"matcher": "resume",
|
|
26
|
+
"matcher": "resume|compact",
|
|
27
27
|
"hooks": [
|
|
28
28
|
{ "type": "command", "command": "node bin/geneseed-hook.mjs context" }
|
|
29
29
|
]
|
|
@@ -42,6 +42,13 @@
|
|
|
42
42
|
{ "type": "command", "command": "node bin/geneseed-hook.mjs learn || exit 0" }
|
|
43
43
|
]
|
|
44
44
|
}
|
|
45
|
+
],
|
|
46
|
+
"PreCompact": [
|
|
47
|
+
{
|
|
48
|
+
"hooks": [
|
|
49
|
+
{ "type": "command", "command": "node bin/geneseed-hook.mjs learn || exit 0" }
|
|
50
|
+
]
|
|
51
|
+
}
|
|
45
52
|
]
|
|
46
53
|
}
|
|
47
54
|
}
|
|
@@ -9,8 +9,9 @@ Agent Skills), custom agents are markdown-with-frontmatter, and the repo-root
|
|
|
9
9
|
a `host="copilot"` flag. Nothing to install by hand: `geneseed setup` (or
|
|
10
10
|
`geneseed build --emit copilot` / `--emit copilot-global`) writes everything.
|
|
11
11
|
|
|
12
|
-
Copilot is a **
|
|
13
|
-
page is mostly about
|
|
12
|
+
Copilot is a **reduced host**: it has lifecycle hooks, but one command per event and
|
|
13
|
+
no "ask the user" tier, so this page is mostly about what those hooks *can* and
|
|
14
|
+
*cannot* automate and why the harness still holds where they cannot.
|
|
14
15
|
|
|
15
16
|
## What the emit writes
|
|
16
17
|
|
|
@@ -37,20 +38,45 @@ page is mostly about *what it does not automate* and why the harness still holds
|
|
|
37
38
|
the preamble rides it as a managed block. (Unlike Bob, Copilot *has* a real
|
|
38
39
|
personal instructions carrier, so no rules-folder workaround is needed.)
|
|
39
40
|
- `agents/<name>.agent.md` + `skills/` under `~/.copilot`.
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
41
|
+
- **`settings.json` hooks** — two entries under `hooks`, see below.
|
|
42
|
+
|
|
43
|
+
## Hooks — one command per event, block or warn
|
|
44
|
+
|
|
45
|
+
The Copilot CLI reads lifecycle hooks from **`~/.copilot/settings.json`** as a map of
|
|
46
|
+
event → one `{command}` object (no matcher groups, no list). The global emit wires
|
|
47
|
+
two of them, each calling the machine-wide `geneseed-hook` shim with `--host copilot`
|
|
48
|
+
so the verdict is spoken in Copilot's dialect:
|
|
49
|
+
|
|
50
|
+
| event | verb | what it does |
|
|
51
|
+
| --- | --- | --- |
|
|
52
|
+
| `sessionStart` | `context` | eager project-context injection, as on Claude Code, returned as `{"additionalContext": …}` |
|
|
53
|
+
| `toolCall` | `tool-gate` | the git gate and the rule gate **fused** — one command is all the event allows — dispatched on the payload: a `command` gets the git checks, a path gets the rule checks; the `after` phase is ignored |
|
|
54
|
+
|
|
55
|
+
Copilot's `toolCall` has **no "ask the user" tier** — its stdout contract is
|
|
56
|
+
`{"block": true|false}` — so the verdict tiers are:
|
|
57
|
+
|
|
58
|
+
- **Laws I and IV block.** A credential-shaped string headed for a tracked file, or
|
|
59
|
+
a history-discarding git act (`reset --hard`, `clean -f`, `branch -D`,
|
|
60
|
+
`checkout --`, `push --force`), is refused outright with the reason. Same stance
|
|
61
|
+
as the OpenCode guard plugin, whose `tool.execute.before` can only allow or throw.
|
|
62
|
+
- **Process 1 and process 5 warn.** The two consent rules are the *user's* calls; a
|
|
63
|
+
hard block would make Copilot unable to commit at all. They log a `[geneseed] …`
|
|
64
|
+
line on stderr (which Copilot records) and allow. A gate error warns the same way
|
|
65
|
+
rather than locking every tool call behind a block nobody can clear.
|
|
66
|
+
|
|
67
|
+
**A hook you already set on one of those events is left alone**, and that event is
|
|
68
|
+
not claimed — one slot per event means Geneseed could only displace it. Uninstall
|
|
69
|
+
removes exactly the hooks it claimed. Comments in the file mean it is never
|
|
70
|
+
rewritten.
|
|
71
|
+
|
|
72
|
+
**What is not wired, and why:**
|
|
73
|
+
|
|
74
|
+
- **no `learn`** — Copilot's `sessionEnd` and `agentStop` payloads carry no
|
|
75
|
+
`transcript_path`, so a distiller would have nothing to read. The memory
|
|
76
|
+
convention rides the preamble's instructions (the agent writes its own memories);
|
|
77
|
+
- **no hooks at project scope** — the CLI documents hooks in the personal settings
|
|
78
|
+
file only, and a machine-absolute command committed into a shared `.github/`
|
|
79
|
+
would fail on every teammate's machine;
|
|
54
80
|
- **sovereign-repo excludes** — Copilot documents no exclude/shadow mechanism
|
|
55
81
|
(nothing like Claude's `claudeMdExcludes` or Bob's same-named workspace rule),
|
|
56
82
|
so a global install's `copilot-instructions.md` and a repo's own `AGENTS.md`
|
|
@@ -59,19 +85,19 @@ settings/hooks/excludes stage is skipped. Concretely, Copilot does **not** get:
|
|
|
59
85
|
|
|
60
86
|
None of this is a build gap — it is Copilot's ceiling. The harness still applies
|
|
61
87
|
in full: the Ontology, every Rule, every doctrine rule the install built in, and
|
|
62
|
-
every agent and skill are present;
|
|
63
|
-
to instruction-only. This is
|
|
64
|
-
principle every non-OpenCode host follows.
|
|
88
|
+
every agent and skill are present; where the host offers no prompt, a Rule's
|
|
89
|
+
*automation* degrades to a block, a warning, or instruction-only. This is
|
|
90
|
+
behaviour-contract parity, the same principle every non-OpenCode host follows.
|
|
65
91
|
|
|
66
92
|
## MCP
|
|
67
93
|
|
|
68
94
|
MCP servers are wired at runtime by `geneseed mcp` into `~/.copilot/mcp-config.json`
|
|
69
|
-
(with a `tools` allowlist) — see `
|
|
95
|
+
(with a `tools` allowlist) — see `js/hosts/mcp.mjs`.
|
|
70
96
|
|
|
71
97
|
## What Copilot does not get
|
|
72
98
|
|
|
73
99
|
As a Claude-shaped host Copilot has none of the OpenCode-only extras (colour
|
|
74
|
-
themes, JS plugins, workflow runner, primary-agent, LSP, `/`-commands),
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
comparison.
|
|
100
|
+
themes, JS plugins, workflow runner, primary-agent, LSP, `/`-commands), and of the
|
|
101
|
+
hook-driven automation it gets context injection and the boundary gates but not
|
|
102
|
+
the learn distiller or a consent *prompt*. See the
|
|
103
|
+
[host matrix](../../README.md#-supported-harnesses) for the full comparison.
|