geneseed 3.4.0 → 3.5.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.
Files changed (164) hide show
  1. package/CHANGELOG.md +283 -0
  2. package/DESIGN.md +11 -14
  3. package/QUICKSTART.md +3 -1
  4. package/README.md +51 -42
  5. package/SETUP.md +25 -27
  6. package/SHIPPED.md +26 -32
  7. package/adapters/bob/README.md +12 -9
  8. package/adapters/copilot/README.md +26 -25
  9. package/adapters/opencode/GLOBAL-HARNESS-SPEC.md +1 -1
  10. package/adapters/opencode/README.md +2 -2
  11. package/adapters/opencode/plugins/geneseed-context.js +5 -3
  12. package/adapters/opencode/plugins/geneseed-workflow.js +30 -3
  13. package/adapters/opencode/workflows/_runtime.js +97 -7
  14. package/bin/build-driver.mjs +5 -1248
  15. package/bin/geneseed-cli.mjs +11 -6
  16. package/bin/geneseed-hook.mjs +4 -2
  17. package/docs/candidate-hosts.md +1 -1
  18. package/docs/design-history.md +37 -37
  19. package/docs/extending.md +45 -24
  20. package/docs/token-footprint.md +52 -26
  21. package/docs/web/claude-hooks.md +3 -2
  22. package/docs/web/collaboration.md +2 -2
  23. package/docs/web/first-session.md +1 -1
  24. package/docs/web/footprint.md +2 -2
  25. package/docs/web/harnesses.md +1 -1
  26. package/docs/web/model.md +1 -1
  27. package/docs/web/plugin-workflow.md +1 -0
  28. package/docs/web/rules.md +3 -3
  29. package/docs/web/setup-choices.md +2 -2
  30. package/docs/web/themes-author.md +1 -1
  31. package/docs/web-ui.md +18 -10
  32. package/harness.config.json +1 -1
  33. package/js/README.md +6 -5
  34. package/js/build/driver.mjs +1191 -0
  35. package/js/build/emit-claude.mjs +17 -10
  36. package/js/build/emit-common.mjs +4 -4
  37. package/js/build/generate.mjs +1 -1
  38. package/js/build/render.mjs +48 -44
  39. package/js/build/stubs.mjs +1 -1
  40. package/js/build/themes.mjs +4 -4
  41. package/js/build/version.mjs +12 -0
  42. package/js/cli-table.json +21 -6
  43. package/js/hosts/hooks.mjs +89 -74
  44. package/js/hosts/hosts.mjs +19 -2
  45. package/js/hosts/mcp.mjs +14 -20
  46. package/js/hosts/native.mjs +23 -17
  47. package/js/hosts/settings.mjs +52 -104
  48. package/js/inspect/checks-authoring.mjs +117 -3
  49. package/js/inspect/diff.mjs +1 -1
  50. package/js/inspect/doctor.mjs +1 -1
  51. package/js/inspect/excludes.mjs +1 -1
  52. package/js/inspect/scan.mjs +3 -14
  53. package/js/inspect/status.mjs +2 -2
  54. package/js/inspect/validate.mjs +1 -1
  55. package/js/lib/fs.mjs +23 -8
  56. package/js/lib/json.mjs +7 -1
  57. package/js/lib/proc.mjs +6 -4
  58. package/js/maintain/migrate.mjs +1 -1
  59. package/js/maintain/setup.mjs +1 -1
  60. package/js/maintain/uninstall.mjs +17 -15
  61. package/js/ui/cli.mjs +19 -0
  62. package/js/ui/menu.mjs +1 -1
  63. package/js/web/actions.mjs +4 -4
  64. package/js/web/activity.mjs +4 -4
  65. package/js/web/api.mjs +14 -11
  66. package/js/web/daemon.mjs +1 -1
  67. package/js/web/docs.mjs +12 -12
  68. package/js/web/handler.mjs +12 -5
  69. package/js/web/jobs.mjs +1 -1
  70. package/package.json +1 -1
  71. package/src/AGENT.md.tmpl +69 -36
  72. package/src/agents/developer.md +2 -2
  73. package/src/agents/reviewer.md +5 -2
  74. package/src/doctrines/README.md +26 -3
  75. package/src/doctrines/craft.md +78 -5
  76. package/src/doctrines/ops.md +62 -0
  77. package/src/doctrines/process.md +91 -4
  78. package/src/doctrines/rigor.md +40 -0
  79. package/src/laws/universal.md +27 -21
  80. package/src/memory/README.md +4 -2
  81. package/src/modes/foreman.md +5 -5
  82. package/src/notebook/README.md +2 -1
  83. package/src/ontology/universal.md +71 -67
  84. package/src/postures/peer.md +3 -0
  85. package/src/skills/bruno-collection-generator.md +1 -1
  86. package/src/skills/bruno-test-writer.md +2 -2
  87. package/src/skills/daydream/LICENSE +21 -0
  88. package/src/skills/daydream/VENDOR.md +3 -1
  89. package/src/skills/geneseed-code-review.md +6 -2
  90. package/src/skills/parallel-agents.md +3 -3
  91. package/src/skills/pipeline.md +4 -4
  92. package/src/skills/react-view-transitions/VENDOR.md +7 -1
  93. package/src/skills/workflow.md +12 -4
  94. package/themes/_TEMPLATE.json +6 -4
  95. package/themes/biker.json +5 -3
  96. package/themes/commentator.json +5 -3
  97. package/themes/cyberpunk.json +5 -3
  98. package/themes/gamer.json +5 -3
  99. package/themes/imperial.json +5 -3
  100. package/themes/joker.json +5 -3
  101. package/themes/marvin.json +5 -3
  102. package/themes/mean.json +5 -3
  103. package/themes/military.json +5 -3
  104. package/themes/neutral.json +6 -4
  105. package/themes/opencode/README.md +2 -2
  106. package/themes/pirate.json +5 -3
  107. package/themes/sports.json +5 -3
  108. package/themes/verstappen.json +5 -3
  109. package/themes/wizard.json +5 -3
  110. package/web/dist/assets/Activity-Flgf4kHy.js +1 -0
  111. package/web/dist/assets/ActivityDetail-DIpr85nh.js +1 -0
  112. package/web/dist/assets/CatalogRow-CjyLjaLb.js +1 -0
  113. package/web/dist/assets/Diff-Deisdha8.js +2 -0
  114. package/web/dist/assets/Docs-DGUdY4l4.js +2 -0
  115. package/web/dist/assets/Doctor-F74lJ69P.js +1 -0
  116. package/web/dist/assets/FilterInput-BakJLvaV.js +1 -0
  117. package/web/dist/assets/GreenhouseView-D072lBiD.js +2 -0
  118. package/web/dist/assets/Harness-DNRP2Va7.js +1 -0
  119. package/web/dist/assets/JournalView-DWFqZ0Iw.js +1 -0
  120. package/web/dist/assets/Laws-BN6g3HU7.js +3 -0
  121. package/web/dist/assets/Library-CDOv4emM.js +1 -0
  122. package/web/dist/assets/Markdown-BQAvN8xx.js +38 -0
  123. package/web/dist/assets/OperatorHudView-CwNIUVX8.js +2 -0
  124. package/web/dist/assets/Profile-CpP9BTne.js +1 -0
  125. package/web/dist/assets/Rules-DFXsUCB7.js +1 -0
  126. package/web/dist/assets/Settings-BqZVUtJ5.js +1 -0
  127. package/web/dist/assets/Skills-Cu6kBgfF.js +1 -0
  128. package/web/dist/assets/StatusBadge-Cg6j-NJL.js +1 -0
  129. package/web/dist/assets/activity-iWaWVtsR.js +1 -0
  130. package/web/dist/assets/drawable-BgfrEBer.js +1 -0
  131. package/web/dist/assets/index-CAqrWhKl.js +2 -0
  132. package/web/dist/assets/index-Ruh93A3A.css +1 -0
  133. package/web/dist/assets/jobBuckets-Dbq8ZlWW.js +1 -0
  134. package/web/dist/assets/lawCats-BLgxl151.js +1 -0
  135. package/web/dist/assets/react-DbkvxWG5.js +8 -0
  136. package/web/dist/assets/rolldown-runtime-CbXtAM7H.js +1 -0
  137. package/web/dist/index.html +4 -3
  138. package/web/src/pages/Laws.jsx +22 -8
  139. package/src/skills/react-view-transitions/README.md +0 -42
  140. package/web/dist/assets/Activity-DMGhhjQc.js +0 -1
  141. package/web/dist/assets/ActivityDetail-CeQcDA7e.js +0 -1
  142. package/web/dist/assets/CatalogRow-CnSbDPyg.js +0 -1
  143. package/web/dist/assets/Diff-D_ksMBD1.js +0 -5
  144. package/web/dist/assets/Doctor-Brb3_oCT.js +0 -1
  145. package/web/dist/assets/FilterInput-DbRWPhtT.js +0 -1
  146. package/web/dist/assets/GreenhouseView-F3VNFr73.js +0 -2
  147. package/web/dist/assets/Harness-DJSwfYeF.js +0 -1
  148. package/web/dist/assets/JournalView-BLRYRnB3.js +0 -1
  149. package/web/dist/assets/Laws-CKYns9qe.js +0 -3
  150. package/web/dist/assets/Library-BK0YloSv.js +0 -1
  151. package/web/dist/assets/Markdown-BzTRzc7a.js +0 -46
  152. package/web/dist/assets/OperatorHudView-D3OQSGp5.js +0 -2
  153. package/web/dist/assets/Profile-CPA2u_0g.js +0 -1
  154. package/web/dist/assets/Rules-Lukel-Ru.js +0 -1
  155. package/web/dist/assets/Skills-BKRLHH7m.js +0 -1
  156. package/web/dist/assets/StatusBadge-DI3weRKd.js +0 -1
  157. package/web/dist/assets/activity-C_H2Bx1P.js +0 -1
  158. package/web/dist/assets/index-B7_Wga23.js +0 -2
  159. package/web/dist/assets/index-DzdQjvM1.css +0 -1
  160. package/web/dist/assets/index-N8dTrVro.js +0 -1
  161. package/web/dist/assets/index-Py_IQjgK.js +0 -10
  162. package/web/dist/assets/jobBuckets-DfTUJUxR.js +0 -1
  163. package/web/dist/assets/lawCats-DUS9UTH4.js +0 -1
  164. package/web/dist/assets/react-DOpiTn5v.js +0 -32
package/CHANGELOG.md CHANGED
@@ -10,6 +10,289 @@ label. For the capability ↔ spec map, see [SHIPPED.md](SHIPPED.md).
10
10
 
11
11
  _Nothing yet._
12
12
 
13
+ ## [3.5.0] — 2026-09-25
14
+
15
+ **Upgrading:** re-emit (or `geneseed rebuild-all`) after installing. Copilot installs need it most:
16
+ the re-emit replaces the legacy `toolCall` hook, which Copilot no longer fires, with the gates
17
+ listed under *Fixed — hosts and core*.
18
+
19
+ ### Added — web console motion
20
+
21
+ - **The dashboard moves where motion carries meaning** (anime.js 4, bundled into `web/dist` like
22
+ React; the Node package stays zero-dependency). The germination ring's arc, bezel ticks and
23
+ percentage now run off one tween instead of an arc transition under a number that had already
24
+ jumped. KPI, genome and run counters count up, and count from the old value on a refresh, so a
25
+ change is seen moving. The Greenhouse donuts sweep clockwise, each arc taking its share of the
26
+ time. The Journal lens's constitution map enters hub, spokes, tiers, then governed nodes, once
27
+ per page load and only when scrolled into view. The toast and confirm dialog enter via CSS
28
+ `@starting-style`. Every JS animation checks `prefers-reduced-motion` (the global CSS rule cannot
29
+ reach inline styles) and completes on a timer where rAF never fires. Shell bundle +13 KB gzip.
30
+ - **Motion as feedback across the console.** The console strip carries a scanning bar while a
31
+ job runs and flashes green or red when a watched job ends; a successful build sways the rail's
32
+ sprout. The rail's active-page highlight and every segmented control's pill are now one element
33
+ that glides to the new selection. Dashboard tabs settle in; Doctor's checks rise in one after
34
+ another with their status dots popping; law, rule, check, manifest and MCP panels grow open;
35
+ live Activity sessions slide into place on each poll (FLIP); search results cascade in once and
36
+ mark the matched text. A flavour swap crossfades through the View Transitions API.
37
+
38
+ ### Added — constitution
39
+
40
+ - **Process 8, one writer per file.** When several agents share code — sub-agents, a pipeline
41
+ crew, a workflow fan-out, another session in the same checkout — each file has one writer at a
42
+ time: every unit gets a write set, overlaps run in sequence or get one owner, shared append
43
+ files (registries, lockfiles, generated bundles) stay with the integrator, reviewers never edit,
44
+ and a change you did not make is merged or stops you, never overwritten. Borrowed from Orca's
45
+ task-spec contract (ownership + acceptance) and Claude Workflow's per-agent worktree isolation.
46
+ `parallel-agents`, `pipeline` and `workflow` carry the write set in their handoff envelopes and
47
+ check changed files against it on the way back; `workflow` lists Orca as a coordination host.
48
+ The `full` carrier ceiling moves 55_500 → 57_000 for the rule's text; `lean` does not move.
49
+ - **OpenCode workflows take `isolation: "worktree"`**, like Claude Code's Workflow: each such
50
+ agent runs on its own branch and worktree; an unchanged one is released, a changed one is kept,
51
+ and the summary names every kept branch and every file two agents changed (`rt.overlaps()`).
52
+ Nothing is merged for you, and without git the agent fails rather than run in the shared tree.
53
+ - **Ops 7, serialize against a rationed resource.** A rate-limited API, a quota or a single
54
+ gateway is called in sequence, never fanned out: budget the quota across its callers before any
55
+ parallelism, back off on refusal within a retry cap set first, and treat a refusal that repeats
56
+ unchanged as a hard limit to report, never a batch to re-send. It names the calls process 3's
57
+ "batch independent calls" must not batch.
58
+ - **Craft 7, one writer per value.** A value held by hand in several places — a version, a count,
59
+ a name, a threshold — gets one home as its sole writer; every other copy is derived from it or
60
+ gated against it, the homes are counted before the gate is trusted, and a tool that updates one
61
+ home is not trusted to have updated the rest. Distinct from process 8, which gives a *file* one
62
+ writer across agents; this gives a *value* one writer across files.
63
+ The carrier ceilings move `full` 57_500 → 59_500 and `lean` 38_900 → 39_500 for the two rules.
64
+
65
+ ### Added — doctor
66
+
67
+ - **A `leanBlockProblems` doctor arm** over `src/laws/universal.md` and every pack: exactly one
68
+ `LEAN` block per rule, neither half blank. `resolveLean` is a replace over a marker pair and
69
+ therefore a no-op on markerless text, so a rule that lost its block would inline its full
70
+ body at the default footprint in silence, with every other gate in the tree green. Nothing
71
+ in `js/inspect/` read a LEAN marker before this — not for the packs, and not for the laws.
72
+
73
+ ### Changed — tests and maintainer docs
74
+
75
+ - **CLI-matrix faults are edits of the real file, not copies of it.** Six `doctor` cells held
76
+ whole copies of `Laws.jsx`, `cyberpunk.json` and `registry.json` to change one line each; every
77
+ new rule, theme key or spec had to be carried into them by hand, and the `Laws.jsx` copies had
78
+ already drifted from the real file. A fault may now be `{ "edit": [[find, replace]] }`, applied
79
+ to the copied checkout; a `find` that does not match exactly once fails the cell.
80
+ - **`docs/extending.md` lists the seven CI commands** (`golden --cli` was missing), names the
81
+ craft-specific fixtures §2a skipped, and drops typed figures that had gone stale (the ceiling
82
+ headroom, a line number). `DESIGN.md` and §2c now say `I..XI` / `LEX_I..LEX_XI`, and the claim
83
+ that `LEX_I` is frozen in a recording is gone — the recordings were retired.
84
+
85
+ ### Changed — toolchain
86
+
87
+ - **Web console toolchain on current majors** (dev-only; React stays 18): vite 5 → 8, vitest
88
+ 2 → 5, jsdom 24 → 29, `@vitejs/plugin-react` 4 → 6, eslint / `@eslint/js` 9 → 10 and globals
89
+ 15 → 17 (the root's majors), `eslint-plugin-react-hooks` 5 → 7. `npm audit` in `web/`: 12
90
+ dev-only advisories (1 critical, in vitest 2) → 0. The React-Compiler rules that v7 brings
91
+ flagged setState-in-effect prop resets in five places; they now adjust state during render,
92
+ so a fresh payload never paints once with the previous one's selection. `web/dist` rebuilt
93
+ (gzip js+css ~144.6 → ~142.0 KB).
94
+ - **Vendored skills carry their license text.** `daydream` now ships upstream's MIT `LICENSE`.
95
+ `react-view-transitions` has none to copy — upstream declares MIT in its README only, which
96
+ its `VENDOR.md` now says. Its upstream repo `README.md` is no longer copied into every install;
97
+ its `AGENTS.md` stays, because the skill's `SKILL.md` points the agent at it.
98
+
99
+ ### Changed — architecture
100
+
101
+ - **The generator driver lives in `js/build/driver.mjs`.** Flag parsing, the nine emit targets
102
+ and the per-host emit orchestration were in `bin/build-driver.mjs`, so nine `js/` modules
103
+ (setup, migrate, doctor, diff, validate, uninstall, generate, the web actions) imported upward
104
+ from a binary. `bin/build-driver.mjs` is now a three-line entry. The unreachable `PORTED`
105
+ refusal (it equalled `EMITS`, which the parser already enforces) is gone, and the driver asks
106
+ `hostCatalogsNatively` instead of keeping its own copy of that table.
107
+
108
+ ### Changed — code cleanup
109
+
110
+ - 24 exports nothing imported are module-private now; `GATE_LEDGER` has one owner
111
+ (`js/hosts/hosts.mjs`) instead of a hard-coded copy in `status`; `hooks.mjs` imports
112
+ `resolvePath` instead of keeping a third copy; `within` has one owner (`js/lib/paths.mjs`).
113
+ - Docblocks that contradicted the code are corrected: the hide-window rule for inheriting
114
+ spawns, the JSONC trailing-comma pass (it is string-aware), the deleted `emit.mjs`, and two
115
+ package-manifest reasons (a false "js/web/docs.mjs serves ROOT/docs", hand-typed sizes).
116
+
117
+ ### Changed — the Ethos (#130)
118
+
119
+ - **The Pact is three ranked laws**, in Asimov's shape: protect the user first, serve their
120
+ intent second where it does not break the first, keep the agent's own honesty third. The
121
+ user now includes whoever maintains the code after the session — code its next reader cannot
122
+ follow is harm, like a false claim.
123
+ - **A coding evidence ladder.** Evidence grades the rungs a coding agent stands on: a green test
124
+ is a claim about the test, a clean type check a claim about the types. The absence and
125
+ truncation passage moved out — Law III already carries it.
126
+ - **The irreversible set is named.** Decisions lists the acts version control cannot undo — a
127
+ push to a shared branch, a schema or data migration, a deletion of data or history, a
128
+ published release, a secret, a call that reaches an external service or person; every other
129
+ edit runs freely.
130
+
131
+ ### Changed — footprint (#129)
132
+
133
+ - **The root file is paid once.** The context hook and the OpenCode plugin no longer re-inject
134
+ the root file the host already loads natively (`CLAUDE.md`, `AGENTS.md`, `AGENT.md`) — about
135
+ 8k tokens per session. The 16 KB/file, 48 KB/session eager budget the docs promised is now
136
+ enforced by the hook too, cutting at a line break with a marker.
137
+ - **Shorter skill descriptions**: purpose plus the first trigger sentence, capped at 320
138
+ characters (was 900).
139
+ - **Authored lean halves for AGENT.md §5–§10**, the tool-agnostic paragraph and the
140
+ readiness-sigil paragraph.
141
+ - **The native-catalogue flag is per kind** (`{ skills, agents }`): Bob keeps the §3 Agents
142
+ table and drops the §4 Skills table it already catalogues natively.
143
+
144
+ ### Changed — review output (#127)
145
+
146
+ - **Review findings are Conventional Comments** in `geneseed-code-review` and the `reviewer`
147
+ agent — `issue (blocking): file:line — …` — so a line pastes into an MR comment and the
148
+ verdict follows from the decorations. Process 7's D/O/F/R/Q/A codes are unchanged.
149
+
150
+ ### Changed — docs
151
+
152
+ - **The README leads with the engineering pitch** — enforced laws, one source for five hosts,
153
+ measured costs — above an animated demo (`docs/assets/demo.svg`); `CONTRIBUTING.md` points
154
+ GitHub at the contributing notes (#126).
155
+ - **Docs sweep**: five hook verbs (not four) wherever they are counted; the README's rail table,
156
+ laws row (nine in force, IX and XI retired), layout tree and test command match the tree;
157
+ dead links to `docs/limits.md`, `docs/specs/` and root-relative paths in
158
+ `docs/design-history.md` fixed; Copilot's hooks described where docs said it had none;
159
+ `GENESEED_STACK_GLOBAL` documented; bare `geneseed` described the same way everywhere.
160
+ - **The skills badge counts folder skills** (`daydream`, `react-view-transitions`,
161
+ `token-report`): doctor's count and README-list gates now read every skill that ships, not
162
+ only the flat `src/skills/*.md` ones.
163
+
164
+ ### Changed — performance
165
+
166
+ - **Rendering reads each source file once per operation, and hashes the source tree once.**
167
+ `doctor` re-read the same partials again and again (91% of its reads were repeats) and every
168
+ emit re-hashed the whole tree for the fingerprint. Measured A/B under the same load: one emit
169
+ ~324 → ~222 ms, `doctor --theme neutral` ~2.45 → ~1.63 s, `doctor --all` (which gates every
170
+ `geneseed update`) roughly halved. Both caches live on the per-operation `cfg`, not the
171
+ process — the web daemon renders in-process for days and must see an edited source.
172
+
173
+ ### Changed — tests and CI
174
+
175
+ - **`golden.mjs --jobs` works.** It was parsed and ignored; cells now fan out over `--shard`
176
+ children — the 261-cell run goes from ~74 s to ~16 s.
177
+ - **`golden.mjs --cli`** runs the CLI/hook matrix (317 cells) against the expectations written in
178
+ each cell, in CI. Nothing had run them since the corpus replayer was retired; 27 had drifted.
179
+ Six doctor cells planted months-old whole-file copies — re-based onto today's files, keeping
180
+ exactly their fault. The rest followed deliberate changes (the status box's wider label
181
+ column, `harness` → `geneseed`, gates that fail closed, the root file no longer re-injected),
182
+ and three messages still said `harness` — fixed.
183
+ - **Release hardening**: actions pinned to commit SHAs; npm pinned to 11 (not `latest`) in both
184
+ the release and its CI mirror; publish runs from `main` or a `v*` tag only, and refuses a
185
+ commit CI has not passed. CI: read-only token, pushes to `main` only (PRs no longer run
186
+ twice), superseded runs cancelled, Node 24 on Linux beside 22, the test-count floor computed
187
+ from the written tests (it was a fixed 500 against 1100), and the no-interpreter package job
188
+ fails when the web daemon never reports ready. A weekly workflow runs the full mutation
189
+ matrix.
190
+ - The 30-second fetch-timeout test has its own file, so it overlaps the rest of the suite.
191
+
192
+ ### Changed — the constitution
193
+
194
+ - **Law IV**: a durable authorization the user gave counts, alongside per-act confirmation (the
195
+ full text said "never a standing yes, unless already durably authorized", the lean text
196
+ dropped the exception). And "deletion" narrows to *deletion of what version control cannot
197
+ restore*, matching the Ontology's named irreversible set (#130): an edit or delete git can
198
+ undo runs freely.
199
+ - **Law V**: inside a loop with a stated bound (fix until green, at most N rounds), the expected
200
+ failure is the loop's input and the bound is the stop — a red test in a debug loop no longer
201
+ reads as a violation.
202
+ - **Law X**: echo the inferred goal back when a request admits readings that would lead to
203
+ different work — not for every request, which contradicted the Expert and Peer postures.
204
+ - **Law I (lean)** keeps secrets out of logs and output again; **rigor 3 (lean)** keeps "stop
205
+ rather than ship untested behaviour in silence (Law VIII)".
206
+ - **Memory is written through the rule skill** (process 1) everywhere — AGENT.md §6 and §7, the
207
+ memory and notebook READMEs told the agent to write it on its own. The `learn` hook is the
208
+ one automatic writer, named as such.
209
+ - **Pipelines: the parent owns the commit.** A crew hands back its worktree uncommitted with its
210
+ proof; the parent re-runs the proof itself, shows the user, and commits and merges once the
211
+ user accepts. Foreman merged on the crew's own logs, and the developer spec named a tester
212
+ commit that never happened.
213
+ - The bruno skills cited retired Laws IX and XI (now IV and III); **doctor now refuses a
214
+ citation of any retired law**, read off the canon. Themes title IX and XI "(retired)"; the
215
+ dead `EPI_PACT` key is gone. Prose outside the catalogue blocks no longer points at a table
216
+ the Claude emit does not render.
217
+
218
+ ### Changed — doctrine lean forms (#128)
219
+
220
+ - **Doctrine rules inline an authored lean form.** All 24 rules across the four packs now
221
+ carry a `LEAN` block with both halves written by hand, the way the invariants and the
222
+ Ontology already did; `doctrinesBody` picks the half through `resolveLean` and the
223
+ first-sentence cut (`terseBlocks`) is gone. It was cutting eleven of the 24 rules down to a
224
+ maxim with no verb an agent could act on — *Make actions safe to run twice.*, *Change as
225
+ little as the task requires.*, and eight words of process 5's 213-word consent protocol.
226
+ The Doctrines section grows 4,096 → 9,635 characters at `lean` on neutral, which is the
227
+ point of the change rather than a cost of it; `CEILING.lean` moves 37,500 → 41,300 and
228
+ `CEILING.full` does not move, because not one full half was edited.
229
+ - **`doctrines/` ships at full text under both footprints,** joining `laws/` and `ontology/`
230
+ in `renderAll`'s on-disk exemption. It shipped whole before only because a pack file had no
231
+ markers for `resolveLean` to act on — by accident, where the Doctrines section's own pointer
232
+ promises it by contract.
233
+
234
+ ### Fixed — blank web console on a non-canonical checkout path
235
+
236
+ - **`geneseed web` served a blank page when the checkout was reached by a path that is not its
237
+ real one** (a symlink, a Windows junction, a `subst` or mapped drive, an 8.3 short name). The
238
+ static route realpathed each requested file but compared it against an unresolved `web/dist`,
239
+ so every asset failed the "under dist" check and was answered with `index.html` at `text/html`;
240
+ the browser refused the module script and nothing was logged. `dist` is now resolved once in
241
+ `makeHandler`, and `tests/unit/web_server.test.mjs` serves an asset through a linked `dist`.
242
+
243
+ ### Fixed — web console
244
+
245
+ - **A failed first load no longer hangs on the splash.** The boot splash waited on the overview
246
+ and the error toast rendered beneath it; a failure now lifts the splash and the dashboard shows
247
+ the error with a Retry.
248
+ - **Search stays current**: the Spotlight index is dropped on every data revision (a build, a
249
+ deleted fact, an install switch) and on a docs-host change. MCP results open the Harness page,
250
+ where MCP wiring lives, not Settings.
251
+ - **A refused Profile save keeps your draft** (it was replaced by the disk copy), the next Save
252
+ carries the new fingerprint, and leaving with unsaved edits asks first.
253
+ - Blocked `sessionStorage` no longer stops the app mounting.
254
+ - **Contrast**: `--text-3` clears WCAG AA (4.5:1) against its background and surface in every
255
+ skin — 19 of them were below it, the default dark skin at 3.9:1.
256
+ - **Keyboard**: voice picks are buttons (Esc closes the list), and the dashboard's section rows
257
+ carry a real link.
258
+ - The Docs host follows the deployed install when nothing is stored (Bob and Copilot read the
259
+ Claude Code pages). The unused `d3-force` dependency is gone; `docs/web-ui.md` describes the
260
+ rail as it is (no Specs view).
261
+
262
+ ### Fixed — hosts and core
263
+
264
+ - **Copilot's hooks match Copilot's current schema.** The global emit wired a single-object
265
+ `toolCall` hook answered with `{"block": true}`; Copilot no longer has that event, so no
266
+ Copilot gate ever ran. It now adds array entries to `sessionStart`, `preToolUse`
267
+ (`tool-gate --host copilot`, answering a top-level `permissionDecision: "ask"` — every rule
268
+ asks, as on Claude Code), and `agentStop` + `preCompact` (`learn`, from `transcriptPath`).
269
+ `toolArgs` is read as an object or a JSON string. The claim moves to `settings_hooks`, so one
270
+ merge serves Claude, Bob and Copilot; a re-emit (or reactivate) unwires the legacy claims.
271
+ - **Bob global hooks name the install, not the settings folder.** `--root`/`--memory` came from
272
+ the nested settings file's parent (`~/.bob/settings`): memory was learned where nothing read
273
+ it, excludes were missed, and a global install never stood down for a project one.
274
+ - **Claude keeps Law IV with process 5 off.** `--doctrines` without `process` (or
275
+ `--exclude-rules process.5`) dropped the whole git-gate group, and the destructive-git check
276
+ went with it — on Claude only. The group now stays with `--no-consent`, which skips only the
277
+ commit/push ask.
278
+ - **Bob MCP servers go where Bob reads them**: `.bob/mcp.json` / `~/.bob/settings/mcp.json`,
279
+ not `settings.json`.
280
+ - **OpenCode asks on the same destructive git verbs as the other hosts** (`reset --hard`,
281
+ `clean -f`, `branch -D`, `checkout --`), which it only logged before.
282
+ - **`agents/_template.md` no longer ships** into an install's agents folder, where hosts
283
+ loaded it as a phantom `_template` agent. A Bob project emit's `.bob/.gitignore` now lists
284
+ the machine-specific `settings.json`.
285
+ - **`isDict` no longer says yes to a number.** `parseJson` wraps numbers, and the wrapper passed
286
+ the object check — `"permission": 5` in an `opencode.json` read as a dict the merge wrote its
287
+ git gate into, then serialised back as `5`. `mcp.mjs` and `native.mjs` drop their own copies.
288
+ - **One malformed `wiki.jsonc` no longer fails `/api/status`**: an `entries` that is not a list
289
+ is skipped instead of throwing.
290
+ - **`geneseed --help` lists the commands** (it died asking for a verb), and a bare `geneseed`
291
+ from an npm install runs `home` as both launchers already did.
292
+ - **`.gitignore`**: `notebook/` is anchored to the root — unanchored, it also ignored new files
293
+ under `src/notebook/`. `.claude/worktrees/` and `.claude/settings.local.json` are ignored for
294
+ every clone, not only through the maintainer's global excludes.
295
+
13
296
  ## [3.4.0] — 2026-09-06
14
297
 
15
298
  ### Added
package/DESIGN.md CHANGED
@@ -44,7 +44,7 @@ vault or a specific tool's hooks.
44
44
  and the prose words the docs use: the core nouns `LAW(S)`/`DOCTRINE(S)`/`ONTOLOGY`/
45
45
  `AGENT(S)`/`SKILL(S)`/`MEMORY`/`NOTEBOOK`/`VAULT`/`WIKI`, plus `TAGLINE`,
46
46
  `LOADED_SIGIL`, `EPI_*`, `BENEDICTION`, `DESC_*`, `ROAST_PERSONA`, the invariant
47
- titles `LEX_I`..`LEX_IX`, the 23 doctrine-rule titles `DOC_<PACK>_<n>`, the four pack
47
+ titles `LEX_I`..`LEX_XI`, the 27 doctrine-rule titles `DOC_<PACK>_<n>`, the four pack
48
48
  names `PACK_CRAFT`/`PACK_RIGOR`/`PACK_OPS`/`PACK_PROCESS`, and the section intros
49
49
  `INTRO_*`. Each theme defines its own nouns; **neutral keeps the plain words** (Rule,
50
50
  Doctrine, Agent, Skill, Memory, Workspace), so neutral output is unchanged.
@@ -98,8 +98,9 @@ vault or a specific tool's hooks.
98
98
  and tier by reversibility; show the real forks), **Conduct** (answer what was asked,
99
99
  once). It absorbed the Pact, which is now stated *inside* Telos rather than standing
100
100
  as a peer of the rules.
101
- - **Invariants** (`src/laws/universal.md`) — *what is never traded*. Nine numbered
102
- Rules, `I`..`IX`, headed `### {{LAW}} <roman> — {{LEX_<roman>}}`.
101
+ - **Invariants** (`src/laws/universal.md`) — *what is never traded*. Eleven numbered
102
+ Rules, `I`..`XI`, nine in force — IX and XI are retired in place, their numbers kept so
103
+ existing citations resolve — headed `### {{LAW}} <roman> — {{LEX_<roman>}}`.
103
104
  - **Doctrines** (`src/doctrines/{craft,rigor,ops,process}.md`) — *how work is done
104
105
  here*. Practice rules addressed by pack and number, cited as `Doctrine process 5`.
105
106
  `PACK_ORDER` (`js/build/source.mjs`) fixes the order craft → rigor → ops → process, which
@@ -163,20 +164,17 @@ vault or a specific tool's hooks.
163
164
  Almost all of it is gated, across six named checks in `js/inspect/checks-build.mjs` —
164
165
  `themeParityProblems` (key parity across the voices), `lawMetaProblems` and
165
166
  `doctrineMetaProblems` (the console's Principle column, in both directions),
166
- `constitutionProblems` (pack numbering and filing, `LEX_I..LEX_IX` as an *equality*, the
167
+ `constitutionProblems` (pack numbering and filing, `LEX_I..LEX_XI` as an *equality*, the
167
168
  `DOC_*` vocabulary, and every `{{DOCTRINE}}` citation in `src/`), and
168
169
  `countTableProblems` / `proseMirrorProblems` (badges and prose). So `geneseed doctor
169
170
  --all` is the check; the table above only says what it will ask for. `CHANGELOG.md` has
170
171
  no gate and never has.
171
172
 
172
173
  Two things the table cannot tell you, and `docs/extending.md` can: the default footprint
173
- is **lean**, which keeps an invariant's or a doctrine rule's heading and its *first
174
- sentence* only — so an amendment written into the second paragraph does not exist for
175
- most installs — and `LEX_I` is one of seven theme keys frozen byte-for-byte in a
176
- recording nothing can re-make, so Rule I's themed titles are the one part of this list
177
- that cannot be edited. The Ontology is exempt from the truncation: it ships whole at
178
- both footprints, because four flowing sections cut to their first sentences would read
179
- as four orphan sentences.
174
+ is **lean**, which inlines the authored `LEAN:else` half of each invariant and each
175
+ doctrine rule (and of the Ontology) rather than the full body — so an amendment written
176
+ into one half only does not exist for most installs. Nothing is machine-cut any more:
177
+ `leanBlockProblems` refuses a rule whose block is missing or whose lean half is blank.
180
178
 
181
179
  ## 🧩 Components
182
180
 
@@ -202,7 +200,7 @@ theme file defines a `DIR_*` key, so `laws/` is `laws/` in all fourteen voices.
202
200
  | Generator | `bin/build-driver.mjs` (`geneseed-build`) | — | substitution + `<!-- INCLUDE: -->` inlining, and the nine `--emit` targets |
203
201
  | CLI, as data | `js/cli-table.json` | — | the owned document the entry point parses its own argv from |
204
202
  | Automation | `bin/geneseed-cli.mjs` (`geneseed`) | — | 25 verbs — `build` / `doctor` / `status` / `prompt` / `diff` / `setup` / `web` / `upgrade` / … |
205
- | Hooks | `bin/geneseed-hook.mjs` (`geneseed-hook`) | — | the four verbs an emitted `settings.json` invokes: `context` / `git-gate` / `rule-gate` / `learn` |
203
+ | Hooks | `bin/geneseed-hook.mjs` (`geneseed-hook`) | — | the five verbs an emitted hook config invokes: `context` / `git-gate` / `rule-gate` / `tool-gate` / `learn` |
206
204
  | Adapters | `adapters/` | — | optional per-tool glue (hooks, OpenCode plugins) |
207
205
 
208
206
  ## ⚙️ Generator contract
@@ -247,8 +245,7 @@ caught, and the reasoning behind every deliberate divergence — lives in
247
245
  this project had two implementations and every byte either one wrote was compared. Read it to
248
246
  understand *why* a seam is where it is; read the contract above to know *what* it is today.
249
247
 
250
- See also [docs/extending.md](docs/extending.md) — what one addition costs, and which gate says
251
- so — and [docs/limits.md](docs/limits.md) — what this tool does not prove about itself.
248
+ See also [docs/extending.md](docs/extending.md) — what one addition costs, and which gate says so.
252
249
  ## 🚫 Explicitly out of scope
253
250
 
254
251
  Graph/index generation, web-clipping pipelines, session-classification capture,
package/QUICKSTART.md CHANGED
@@ -27,7 +27,9 @@ should print `ok`.
27
27
 
28
28
  ## 3 · Optional niceties
29
29
 
30
- - **Browse it:** `npx geneseed web` opens the local web console.
30
+ - **Browse it:** `npx geneseed web` opens the local web console — and once installed,
31
+ bare `geneseed` does the same when it can (else it prints the command list).
32
+ `geneseed --help` lists every command.
31
33
  - **No full-screen TUI:** `tui` and `menu` are verbs that say the panel is not here and
32
34
  print the command list instead. The web console is the visual front end.
33
35
 
package/README.md CHANGED
@@ -10,7 +10,7 @@
10
10
  [![Node >= 22.3](https://img.shields.io/badge/node-%3E%3D22.3-5fa04e)](package.json)
11
11
  [![zero dependencies](https://img.shields.io/badge/deps-zero-success)](package.json)
12
12
  [![Themes](https://img.shields.io/badge/themes-14-9cf)](themes/)
13
- [![Skills](https://img.shields.io/badge/skills-49-blueviolet)](src/skills/)
13
+ [![Skills](https://img.shields.io/badge/skills-52-blueviolet)](src/skills/)
14
14
  [![Agents](https://img.shields.io/badge/agents-18-orange)](src/agents/)
15
15
  [![Laws](https://img.shields.io/badge/laws-11-critical)](src/laws/universal.md)
16
16
  [![Plugins](https://img.shields.io/badge/plugins-7-teal)](adapters/opencode/plugins/)
@@ -22,7 +22,24 @@
22
22
 
23
23
  ---
24
24
 
25
- Geneseed distils an agent operating system into a generic harness built around a single `AGENT.md`. Point your tool at it and the agent inherits a set of operating **rules**, a roster of capability **agents**, native **skills**, a **memory** convention, and — on OpenCode — 7 **plugins** that auto-load your project's docs, capture durable memory, enforce the safety laws, run saved workflows, ping you when a long run finishes, hold a minimal-code mode when you ask for one, and stream what each session is doing to the web console. One source builds it; it follows you into every repo.
25
+ <p align="center"><img src="docs/assets/demo.svg" alt="geneseed setup, then two laws catching a force-push and a credential at the tool boundary" width="760"></p>
26
+
27
+ **Geneseed compiles your agent's rules instead of asking you to write them.** One source in `src/` renders into a ready-made harness for OpenCode, Claude Code, Bob, Copilot, or any `AGENT.md` tool: a constitution of laws and doctrines, a roster of capability agents, native skills, a memory convention — and, wherever the host has a hook surface, gates that *enforce* the laws at the tool boundary instead of hoping the model remembers them.
28
+
29
+ ```bash
30
+ npx geneseed setup
31
+ ```
32
+
33
+ Want to read what it leaves behind before installing anything? [**geneseed-demo**](https://github.com/Arylmera/geneseed-demo) is a repository exactly as the plain bundle emits it — nothing hand-written.
34
+
35
+ ### Why not just a CLAUDE.md?
36
+
37
+ A hand-written instructions file is prose the model may or may not honour, copied into every repo and drifting in each one. Geneseed is a build, and that changes four things:
38
+
39
+ - **Laws are enforced, not suggested.** A force-push, a `reset --hard`, or a credential written into a tracked file is caught by a hook *before* the tool runs, in the host's own dialect — a prompt on Claude Code and Copilot, a hard block on OpenCode, exit 2 on Bob. The gates fail closed, and every catch is one line in a ledger that `geneseed status` counts.
40
+ - **One source, five targets.** Skills are byte-identical on every host; only the wiring differs. Every commit renders all 261 emit configurations, and a second emit into the same tree must change nothing.
41
+ - **Costs are measured, not guessed.** Zero runtime dependencies. The hook path loads in about 14 ms per tool call. The default *lean* footprint keeps the always-on context small and puts the full rationale one read away — the numbers are in [docs/token-footprint.md](docs/token-footprint.md).
42
+ - **It follows you.** Install once, globally; every repo inherits it. One `git pull` or `npm install -g geneseed@latest` rebuilds every active install.
26
43
 
27
44
  This page is the overview. Four parts: **why** it exists, how to **set it up**, the two ways to **drive it** (web console & command line), and **what you get**. For every install path, configuration knob, and troubleshooting step, read the full [Setup guide](SETUP.md).
28
45
 
@@ -75,7 +92,7 @@ Cloning still works and is what you want if you intend to *change* the harness r
75
92
  ```bash
76
93
  git clone https://github.com/Arylmera/Geneseed.git
77
94
  cd Geneseed
78
- ./geneseed setup # the wizard — or bare `./geneseed` for the main menu
95
+ ./geneseed setup # the wizard — bare `./geneseed` opens the web console
79
96
  ```
80
97
 
81
98
  **Windows** — native, no bash, WSL, curl, or unzip; works from cmd or PowerShell:
@@ -83,7 +100,7 @@ cd Geneseed
83
100
  ```powershell
84
101
  git clone https://github.com/Arylmera/Geneseed.git
85
102
  cd Geneseed
86
- .\geneseed.cmd setup # the wizard — or bare .\geneseed.cmd for the main menu
103
+ .\geneseed.cmd setup # the wizard — bare .\geneseed.cmd opens the web console
87
104
  # PowerShell runs a .cmd directly, so this is the PowerShell spelling too
88
105
  ```
89
106
 
@@ -91,13 +108,7 @@ Both launchers are thin shims over the Node CLI: they need `node` (22.3+) on `PA
91
108
 
92
109
  ### 🟩 One runtime — Node, and nothing else
93
110
 
94
- Node ≥ 22.3 is the entire dependency list. Every subcommand, all four hooks, every web-console endpoint and both generators run from it, and every commit runs the whole unit suite plus `doctor --all` across every theme × host × footprint, on Linux and Windows both. So an install needs no second interpreter — not for the harness, and not for anything it ships. (Until 2026-08-17 the generator's output was also replayed byte for byte against recordings taken from the Python implementation. Those were retired — see [`docs/limits.md`](docs/limits.md) for the measurement that licensed it and the coverage it cost.)
95
-
96
- - **One runtime, no second one to install**: every command and all four hook verbs answer from the Node entry points. `catalog`, `mcp` and `memory` are console-facing verbs the CLI table declares alongside them. There is no full-screen browse panel — `geneseed tui` and `geneseed menu` are verbs that refuse it by name and print the command list instead, off a terminal as well as on one.
97
- - **Nothing you install needs an interpreter.** The `token-report` skill is a script rather than prose, and it ships as `scripts/token_report.mjs`, run with `node`; `daydream` and `herdr` hand their inline code to `node -e`. So **every bundle carries** nothing that needs one: no Python file, and no skill that shells out to an interpreter, on any host, theme or footprint. Three tests freeze that — one scans every tracked file for inline code handed to an interpreter, one globs the bundle source, and one replays the report script over seeded transcripts for all four hosts and compares the bytes.
98
- - **`upgrade` / `update` / `sync-self` / `bootstrap` are for a git checkout.** They `git pull` the install's own origin. From an npm install they stop before touching anything and name `npm install -g geneseed@latest` as the update instead.
99
-
100
- One more honest edge, in the web console rather than the CLI: the **"browse…" folder picker** would open an OS-native dialog on the machine running the daemon, and this server declines to. The button reports that it is unavailable and the field beside it stays editable — type or paste the path.
111
+ Node ≥ 22.3 is the entire dependency list — every command, all five hook verbs, the web console and both generators run from it, and nothing any bundle ships needs a second interpreter. The details, and the few honest edges, are in [SETUP.md → One runtime](SETUP.md#-one-runtime--node-and-nothing-else).
101
112
 
102
113
  ### ✅ After installing
103
114
 
@@ -128,21 +139,20 @@ geneseed web status # is it running, and where
128
139
 
129
140
  The left rail mirrors the harness's own shape:
130
141
 
131
- | Group | What's there |
142
+ | Group | Views |
132
143
  | --- | --- |
133
- | **🧬 Harness** | **Dashboard** — live readout of what's deployed (voice, capabilities, drift, recent jobs) · **Library** — browse Laws, Agents, Skills, Memory, Notebook · **Graph** — cross-link constellation across the whole harness |
134
- | **📚 Learn** | **Docs** — rendered markdown + concept pages + CLI reference + glossary, grouped into Get started / Core concepts / How-to / MCP servers / Plugins / Reference / Deeper · **Specs** — dated implementation specs with design rationale |
135
- | **🔧 Maintain** | **Changes** — diff between the deployed harness and the source, export an `improvements.md` back-port · **Doctor** — health check across themes, links, parity, and authoring gates |
136
- | **🎨 Configure** | **Themes** — preview and switch the deployed voice live · **Settings** — MCP servers, server controls |
137
- | **ℹ️ About** | project + creator credits, source link |
144
+ | *(ungrouped)* | **Dashboard** — live readout of what's deployed (voice, capabilities, drift, recent jobs) |
145
+ | **📖 Codex** | **Constitution** · **Rules** · **Profile** · **Skills** · **Agents** · **Library** (Memory, Notebook, the wiki) · **Docs** |
146
+ | **🩺 Care** | **Activity** · **Changes** — diff against the source, export an `improvements.md` · **Doctor** — health check across themes, links, parity and authoring gates |
147
+ | **🎨 Setup** | **Harness** — installs, theme, footprint · **Settings** — MCP servers, server controls |
138
148
 
139
- It binds to `127.0.0.1` only and runs entirely offline — no npm needed at runtime; the UI build ships in `web/dist/`. Mutating actions run in the background and report back as toasts (fire-and-notify), guarded by a per-session token so other sites can't trigger them. A global **Spotlight** search in the topbar jumps to any agent, skill, law, doc, or spec. Rebuild the UI after changing anything under `web/src/` with `cd web && npm install && npm run build`. If `web/dist/` is missing (fresh clone, never built), `geneseed web` offers to run that build for you — answer `Y` and it installs, builds, and starts the server; in non-interactive shells it prints the manual recipe instead.
149
+ It binds to `127.0.0.1` only and runs entirely offline — no npm needed at runtime; the UI build ships in `web/dist/`. Mutating actions run in the background and report back as toasts (fire-and-notify), guarded by a per-session token so other sites can't trigger them. A global **Spotlight** search in the topbar jumps to any agent, skill, rule, doc, or MCP server. Rebuild the UI after changing anything under `web/src/` with `cd web && npm install && npm run build`. If `web/dist/` is missing (fresh clone, never built), `geneseed web` offers to run that build for you — answer `Y` and it installs, builds, and starts the server; in non-interactive shells it prints the manual recipe instead.
140
150
 
141
151
  Full reference — every view, the launch/daemon/PWA surface, the security model: **[docs/web-ui.md](docs/web-ui.md)**.
142
152
 
143
153
  ### ⌨️ Terminal — `geneseed`
144
154
 
145
- No browser? Every action the console offers is also a verb: `build`, `doctor`, `diff`, `rebuild-all`, `status`, `memory`, `catalog`, `exclude`, `mcp`, `link`/`unlink`, `uninstall` (global **or** per-repo). `geneseed setup` runs the install wizard — plain text prompts, every console, every OS; see [Setup](#-2--setup) above for the walkthrough. `geneseed --help` lists the rest. There is no full-screen panel: `tui` and `menu` are verbs that say so and print the command list.
155
+ No browser? Every action the console offers is also a verb: `build`, `doctor`, `diff`, `rebuild-all`, `status`, `memory`, `catalog`, `exclude`, `mcp`, `link`/`unlink`, `uninstall` (global **or** per-repo). `geneseed setup` runs the install wizard — plain text prompts, every console, every OS; see [Setup](#-2--setup) above for the walkthrough. `geneseed --help` lists every command, and bare `geneseed` (or `./geneseed`) opens the web console when it can, else prints the command list. There is no full-screen panel: `tui` and `menu` are verbs that say so and print the command list.
146
156
 
147
157
  ---
148
158
 
@@ -152,11 +162,11 @@ The harness ships as a small set of layers, and the web console's rail is the sa
152
162
 
153
163
  | Layer | What it is |
154
164
  | --- | --- |
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/`) | 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 |
165
+ | **🧭 Ethos** (`ontology/`) | the mind the rules govern, in four prose sections — **Telos** (the Pact: three ranked laws — protect the user, serve their intent, keep your own honesty), **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 |
166
+ | **🛡️ Rules** (`laws/`) | 11 universal laws, nine of them in force — always, never toggleable: sealed-secrets, one-intent-one-act, verify-before-assert, deletion-is-deliberate, surface-failures, data-not-orders, least-privilege, root-cause, echo-the-intent. Laws IX and XI are retired, their numbers kept so old references resolve |
157
167
  | **📐 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
168
  | **🤖 Agents** (18) | capability specialists: `reviewer`, `tester`, `architect`, `docs`, `security`, `explorer`, `researcher`, `developer` — plus a debate **council** the `council` skill convenes: `advocate`, `skeptic`, `pragmatist`, `steward`, `visionary`, `user-advocate`, `framer`, `empiricist`, `operator`, `historian` |
159
- | **🛠 Skills** (49) | repeatable workflows: brainstorm · plan · **codebase-design** · **domain-modeling** · **wayfinder** · **tickets** · **develop** · **worktree** · debug · **prototype** · refactor · **ponytail** · **forge-mcp** · **bruno-collection-generator** · **bruno-test-writer** · geneseed-code-review · **fresh-eyes** · **security-audit** · **ci-fix** · **deps-audit** · **review-response** · commit · **ship** · **release** · **migrate** · **git-archaeology** · **git-rescue** · repo-map · document-project · **frontend-design** · **prose** · **ingest** · **research** · **teach** · **quiz** · handoff · roast-me · **council** · parallel-agents · **workflow** · **wiki** · **geneseed** · **rule** · **profile** · **consolidate-memory** · **skill-forge** · **opencode-theme** · **herdr** · **pipeline** |
169
+ | **🛠 Skills** (52) | repeatable workflows: brainstorm · plan · **codebase-design** · **domain-modeling** · **wayfinder** · **tickets** · **develop** · **worktree** · debug · **prototype** · refactor · **ponytail** · **forge-mcp** · **bruno-collection-generator** · **bruno-test-writer** · geneseed-code-review · **fresh-eyes** · **security-audit** · **ci-fix** · **deps-audit** · **review-response** · commit · **ship** · **release** · **migrate** · **git-archaeology** · **git-rescue** · repo-map · document-project · **frontend-design** · **prose** · **ingest** · **research** · **teach** · **quiz** · handoff · roast-me · **council** · parallel-agents · **workflow** · **wiki** · **geneseed** · **rule** · **profile** · **consolidate-memory** · **skill-forge** · **opencode-theme** · **herdr** · **pipeline** · **daydream** · **react-view-transitions** · **token-report** |
160
170
  | **🔌 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
171
  | **🧠 Memory** (`memory/`) | one-fact-per-file durable knowledge, indexed by `MEMORY.md` (git-ignored, personal) |
162
172
  | **📓 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 |
@@ -165,7 +175,7 @@ The harness ships as a small set of layers, and the web console's rail is the sa
165
175
 
166
176
  ### 🤝 What the harness asks of you
167
177
 
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:
178
+ The Pact in the Ethos 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
179
 
170
180
  - **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
181
  - **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.
@@ -191,14 +201,14 @@ Pick with `--theme NAME` or via the setup wizard. The theme is remembered in a `
191
201
 
192
202
  ### 🪶 Footprint (lean vs full)
193
203
 
194
- A second per-install dial, **footprint**, sets how much of the constitution `AGENT.md` carries *inline* every turn — a token-cost knob, not a change to which Rules apply (every Rule is always in force, and so is the whole of the Ontology).
204
+ A second per-install dial, **footprint**, sets how much of the constitution `AGENT.md` carries *inline* every turn — a token-cost knob, not a change to which Rules apply (every Rule is always in force, and so is the whole of the Ethos).
195
205
 
196
- | Footprint | The Ontology + Sections 1–2 of `AGENT.md` | Trade-off |
206
+ | Footprint | The Ethos + Sections 1–2 of `AGENT.md` | Trade-off |
197
207
  | --- | --- | --- |
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 |
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 |
208
+ | **lean** *(default)* | the Ethos, each Rule and each active doctrine rule in their **authored** short form; then pointers to the full text | lighter every turn; rationale is one on-demand read away |
209
+ | **full** | the Ethos, every Rule and every active doctrine rule at complete text **and** rationale, inlined | maximum guidance density; largest per-turn token cost |
200
210
 
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.
211
+ **Lean is authored, not cut.** The Ethos, every Rule and every doctrine 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, and shipped a doctrine rule like *Change as little as the task requires.* as six words with no verb to act on.
202
212
 
203
213
  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.
204
214
 
@@ -229,16 +239,16 @@ is **identical on every host**. What differs is how much of it the host can
229
239
  | **Skills** (byte-identical) | ✅ | ✅ | ✅ | ✅ |
230
240
  | **Memory & Notebook** | ✅ | ✅ | ✅ | ✅ |
231
241
  | **Context injection** | ⚙️ plugin | 🪝 hook | 🪝 hook¹ | 🪝 hook³ |
232
- | **Memory write-back** (learn) | ⚙️ plugin | 🪝 hook | 🪝 hook¹ | 📄 preamble |
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) |
242
+ | **Memory write-back** (learn) | ⚙️ plugin | 🪝 hook | 🪝 hook¹ | 🪝 hook³ |
243
+ | **Git-gate consent** (process 5) | ⚙️ plugin | 🪝 hook | 🪝 hook¹ (warn) | 🪝 hook³ |
244
+ | **Rule-gate consent** (process 1) | ⚙️ plugin² | 🪝 hook | 🪝 hook¹ (warn) | 🪝 hook³ |
245
+ | **Laws I / IV at the boundary** | ⚙️ plugin (block) | 🪝 hook (ask) | 🪝 hook¹ (exit 2) | 🪝 hook³ (ask) |
236
246
  | **Sovereign-repo excludes** | ⚙️ plugin | ✅ `claudeMdExcludes` | ✅ rules-shadow | ➖ none |
237
- | **MCP server wiring** | ✅ `mcp` | ✅ `mcpServers` | ✅ `mcpServers` | ✅ `mcp-config.json` |
247
+ | **MCP server wiring** | ✅ `mcp` | ✅ `mcpServers` | ✅ `mcp.json` | ✅ `mcp-config.json` |
238
248
  | **Colour themes** | ✅ full palette | ➖ | ➖ | ➖ |
239
249
  | **LSP · workflow runner · primary-agent · `/`-commands** | ✅ | ➖ | ➖ | ➖ |
240
250
 
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>
251
+ <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`, `preToolUse`, `agentStop`, `preCompact`) wired by the **global** emit only; `preToolUse` has an ask tier, so every rule asks as on Claude Code. Unverified live (no Copilot CLI on the authoring machine).</sub>
242
252
 
243
253
  **Reading the matrix.** Everything above the divider is at full parity — no host
244
254
  drops an Agent, Skill, or the memory convention. The asymmetry is entirely in
@@ -259,11 +269,11 @@ Token cost per host: **[docs/token-footprint.md](docs/token-footprint.md)**.
259
269
  Geneseed/
260
270
  ├── package.json the npm package: three commands, zero dependencies
261
271
  ├── bin/ the Node entry points — geneseed-cli.mjs (the CLI), geneseed-hook.mjs
262
- │ (the four hook verbs), geneseed.mjs (the generator driver)
272
+ │ (the five hook verbs), build-driver.mjs (the generator driver)
263
273
  ├── js/ the Node harness — generator, hooks, web server, doctor, installs
264
- │ (js/cli-table.json is the CLI as data; both runtimes read it)
274
+ │ (js/cli-table.json is the CLI as data; the CLI reads it)
265
275
  ├── geneseed launcher (bash): a shim over bin/geneseed-cli.mjs — bare `./geneseed`
266
- │ = interactive main menu; + every subcommand the CLI carries
276
+ │ = the web console (else the command list); + every subcommand
267
277
  │ (`./geneseed link` puts it on PATH so `geneseed` runs from anywhere)
268
278
  ├── geneseed.cmd the same shim for cmd.exe / PowerShell — no bash needed
269
279
  ├── harness.config.json default theme + metadata (the one owner of the version)
@@ -280,8 +290,7 @@ Geneseed/
280
290
  │ └── notebook/ the agent's own freeform space — convention + index
281
291
  ├── themes/ voice token maps (14 themes shipped)
282
292
  ├── web/ Vite + React UI source; the committed web/dist/ build is what ships
283
- ├── tests/ Node test suites + the pure-function/help recordings they replay
284
- │ (tests/__snapshots__/ — the emit/cli/web corpora retired 2026-08-17)
293
+ ├── tests/ Node test suites, golden.mjs (every emit config) and mutate.mjs
285
294
  ├── docs/ guides (web-ui, wiki, …) + docs/web/ (the console's Docs pages);
286
295
  │ specs/, reviews/, superpowers/ are local working docs — git-ignored
287
296
  ├── adapters/ per-host glue (opencode/, claude-code/, bob/, copilot/)
@@ -292,7 +301,7 @@ Geneseed/
292
301
 
293
302
  ```bash
294
303
  node bin/geneseed-cli.mjs doctor # every theme + parity + authoring + drift
295
- node --test "tests/**/*.test.mjs" # the test suites (node expands the glob)
304
+ node --test --test-reporter=tap "tests/**/*.test.mjs" # the suites (node expands the glob)
296
305
  ```
297
306
 
298
307
  `doctor` checks each theme for unresolved tokens, dead/non-hermetic links, theme-key parity, author-time gates (every spec has a purpose line, the plugins parse, the learn-prompt literal stays extractable), and that a committed bundle still matches a fresh render of `src/`. CI (`.github/workflows/ci.yml`) runs both on every push and PR, on both Linux and Windows. Publishing is a separate, manually-triggered workflow (`.github/workflows/publish.yml`) — see [Contributing](#-contributing).
@@ -335,7 +344,7 @@ Details and precedence rules: [SETUP.md → Upgrade](SETUP.md#upgrade).
335
344
  | ⤷ [HOW-OPENCODE-LOADS.md](adapters/opencode/HOW-OPENCODE-LOADS.md) | Why a file shows up twice; plugin loading |
336
345
  | **[adapters/claude-code/](adapters/claude-code/README.md)** | The Claude Code hook adapter |
337
346
  | **[adapters/bob/](adapters/bob/README.md)** | The IBM Bob adapter — Claude-shaped, rules-file preamble |
338
- | **[adapters/copilot/](adapters/copilot/README.md)** | The GitHub Copilot adapter — reduced host, no hooks |
347
+ | **[adapters/copilot/](adapters/copilot/README.md)** | The GitHub Copilot adapter — global hooks (`sessionStart`, `preToolUse`, `agentStop`, `preCompact`) |
339
348
  | **[src/memory/README.md](src/memory/README.md)** | The memory convention |
340
349
  | **[src/notebook/README.md](src/notebook/README.md)** | The agent's own freeform-space convention |
341
350
 
@@ -345,7 +354,7 @@ Issues and PRs welcome at [github.com/Arylmera/Geneseed](https://github.com/Aryl
345
354
 
346
355
  Three things that bite when you don't know them:
347
356
 
348
- - **`js/cli-table.json` IS the CLI.** The argument parser is data, and that file is the owned document — not a generated one. `bin/geneseed-cli.mjs` cannot parse a single verb without it, `bin/geneseed-hook.mjs` renders `--help` from it, and the console's `cli` docs page is a filtered view of it. What holds it honest is `tests/unit/cli_table.test.mjs` plus the recorded help texts under `tests/__snapshots__/help/`, which every verb's `--help` is rendered against — so change a flag here and the fixture for that verb is what tells you. Those recordings are frozen and cannot be re-taken; a red one is a finding, not a re-bless.
357
+ - **`js/cli-table.json` IS the CLI.** The argument parser is data, and that file is the owned document — not a generated one. `bin/geneseed-cli.mjs` cannot parse a single verb without it, `bin/geneseed-hook.mjs` renders `--help` from it, and the console's `cli` docs page is a filtered view of it. What holds it honest is `tests/unit/cli_table.test.mjs` — change a flag here and that suite is what tells you.
349
358
  - **The version has one owner: `harness.config.json`.** `package.json` mirrors it and a test fails the fork. Never `npm version` — it edits one of the two.
350
359
  - **Publishing is deliberate and manual.** `.github/workflows/publish.yml` uses npm trusted publishing (OIDC); there is no `NPM_TOKEN` in this repository and there must not be one. It runs only from Actions → publish → Run workflow, and the npm-side trusted publisher is keyed on that workflow's **filename** — renaming the file breaks publishing with no local symptom, which is why the file names itself in its own header and a test asserts the two agree.
351
360