geneseed 2.0.0 → 2.1.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 +109 -5
- package/DESIGN.md +54 -1282
- package/README.md +8 -10
- package/SETUP.md +15 -7
- package/SHIPPED.md +3 -3
- package/adapters/opencode/opencode.json +0 -9
- package/bin/geneseed.mjs +2 -2
- package/docs/declined.md +53 -2
- package/docs/design-history.md +1290 -0
- package/docs/extending.md +563 -0
- package/docs/limits.md +141 -82
- package/docs/web/agents.md +1 -1
- package/docs/web/rules.md +1 -1
- package/geneseed +0 -0
- package/harness.config.json +1 -1
- package/js/cli-table.json +1 -1
- package/js/doctor.mjs +67 -22
- package/js/inventory.mjs +2 -1
- package/js/lib/fs.mjs +6 -2
- package/js/mcp.mjs +3 -15
- package/js/render.mjs +6 -4
- package/js/settings.mjs +79 -1
- package/js/themes.mjs +1 -1
- package/js/tui.mjs +2 -2
- package/js/uninstall.mjs +5 -5
- package/js/web/actions.mjs +20 -4
- package/js/web/server.mjs +53 -2
- package/package.json +1 -1
- package/src/laws/universal.md +35 -0
- package/themes/_TEMPLATE.json +3 -0
- package/themes/biker.json +3 -0
- package/themes/commentator.json +3 -0
- package/themes/cyberpunk.json +3 -0
- package/themes/gamer.json +3 -0
- package/themes/imperial.json +3 -0
- package/themes/joker.json +3 -0
- package/themes/marvin.json +3 -0
- package/themes/mean.json +3 -0
- package/themes/military.json +3 -0
- package/themes/neutral.json +3 -0
- package/themes/pirate.json +3 -0
- package/themes/sports.json +3 -0
- package/themes/verstappen.json +3 -0
- package/themes/wizard.json +3 -0
- package/web/dist/assets/{About-DX1-VTBP.js → About-BYXlmbyo.js} +1 -1
- package/web/dist/assets/{Activity-Dp9NaXOn.js → Activity-us5MPf4u.js} +1 -1
- package/web/dist/assets/{ActivityDetail-HpOBtrXS.js → ActivityDetail-CiaQXUk2.js} +1 -1
- package/web/dist/assets/{Diff-Ct4G3Se8.js → Diff-Bh0qbZ2s.js} +1 -1
- package/web/dist/assets/{Doctor-DGjkZFuA.js → Doctor-BIlQME45.js} +1 -1
- package/web/dist/assets/{Graph-b8o-S6kv.js → Graph-4dYD1dPG.js} +1 -1
- package/web/dist/assets/Harnesses-PzYZ3LOC.js +1 -0
- package/web/dist/assets/Laws-DtZweXal.js +1 -0
- package/web/dist/assets/{Library-BEZscyaQ.js → Library-CjMbksJW.js} +1 -1
- package/web/dist/assets/{Markdown-k_LSLBGq.js → Markdown-Bk81c3aZ.js} +1 -1
- package/web/dist/assets/{Profile-DydukTxP.js → Profile-Curui_-j.js} +1 -1
- package/web/dist/assets/{Rules-CIRG4Ldt.js → Rules-Bm283wdv.js} +1 -1
- package/web/dist/assets/{Skills-Buoi1IBr.js → Skills-gruqYuhl.js} +1 -1
- package/web/dist/assets/{StatusBadge-CE_AJttl.js → StatusBadge-EiM_FPqv.js} +1 -1
- package/web/dist/assets/{Themes-CI4o3gJC.js → Themes-DU99j4Hr.js} +1 -1
- package/web/dist/assets/{activity-BCW7e6Cy.js → activity-0rvQ6Vra.js} +1 -1
- package/web/dist/assets/{index-B1PIx7RM.js → index-0b2hobOo.js} +1 -1
- package/web/dist/assets/index-D5VY3TY_.js +12 -0
- package/web/dist/assets/{index-Ck2iCdaC.js → index-IiGFmCW_.js} +1 -1
- package/web/dist/index.html +1 -1
- package/web/src/pages/Laws.jsx +3 -0
- package/web/dist/assets/Harnesses-gr3-aHBF.js +0 -1
- package/web/dist/assets/Laws-DTwF5tTC.js +0 -1
- package/web/dist/assets/index-BnTQUSUz.js +0 -12
package/README.md
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
**A portable, theme-able harness you implant once and use everywhere to grow a disciplined AI coding agent.**
|
|
6
6
|
|
|
7
|
+
[](https://www.npmjs.com/package/geneseed)
|
|
7
8
|
[](https://github.com/Arylmera/Geneseed/actions/workflows/ci.yml)
|
|
8
9
|
[](LICENSE)
|
|
9
10
|
[](package.json)
|
|
@@ -11,7 +12,7 @@
|
|
|
11
12
|
[](themes/)
|
|
12
13
|
[](src/skills/)
|
|
13
14
|
[](src/agents/)
|
|
14
|
-
[](src/laws/universal.md)
|
|
15
16
|
[](adapters/opencode/plugins/)
|
|
16
17
|
[](#-supported-harnesses)
|
|
17
18
|
|
|
@@ -50,7 +51,7 @@ geneseed-build --theme imperial # Warhammer 40k voice, identical structure
|
|
|
50
51
|
|
|
51
52
|
### ⚡ The short way — `npx`
|
|
52
53
|
|
|
53
|
-
One command, nothing cloned, nothing else to install. The only prerequisite is **Node ≥ 22.3**.
|
|
54
|
+
The harness is published on npm as **[`geneseed`](https://www.npmjs.com/package/geneseed)** — three commands (`geneseed`, `geneseed-hook`, `geneseed-build`), zero dependencies. One command, nothing cloned, nothing else to install. The only prerequisite is **Node ≥ 22.3**.
|
|
54
55
|
|
|
55
56
|
```bash
|
|
56
57
|
npx geneseed setup # the guided wizard
|
|
@@ -88,13 +89,11 @@ cd Geneseed
|
|
|
88
89
|
|
|
89
90
|
Both launchers are thin shims over the Node CLI: they need `node` (22.3+) on `PATH`, and nothing else. Set `GENESEED_NODE` to an absolute path if `node` is not on `PATH` — under a version manager that only patches interactive shells, say. The wizard is plain text prompts on every console, old or new.
|
|
90
91
|
|
|
91
|
-
**Already installed from a clone?** `geneseed migrate` moves every install you have onto the npm shape in one pass, all-or-nothing, without touching hooks or login items it did not write. Your old clone keeps working for a full release — there is no cliff. See [Migrate an existing install](docs/web/migrate.md).
|
|
92
|
-
|
|
93
92
|
### 🟩 One runtime — Node, and nothing else
|
|
94
93
|
|
|
95
|
-
Node ≥ 22.3 is the entire dependency list. Every subcommand, all four hooks, every web-console endpoint and both generators run from it, and
|
|
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.)
|
|
96
95
|
|
|
97
|
-
- **0 commands have no Node twin**: 25 of the 25 subcommands, and all four hook verbs, answer from the Node entry points. `catalog`, `mcp` and `memory` are Node-native faces the CLI table declares on top of that roster. 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
|
|
96
|
+
- **0 commands have no Node twin**: 25 of the 25 subcommands, and all four hook verbs, answer from the Node entry points. `catalog`, `mcp` and `memory` are Node-native faces the CLI table declares on top of that roster. 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.
|
|
98
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.
|
|
99
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.
|
|
100
99
|
|
|
@@ -153,7 +152,7 @@ The harness ships as a small set of layers, mirrored one-for-one in the web cons
|
|
|
153
152
|
|
|
154
153
|
| Layer | What it is |
|
|
155
154
|
| --- | --- |
|
|
156
|
-
| **🛡️ Rules** (`laws/`) |
|
|
155
|
+
| **🛡️ Rules** (`laws/`) | 40 universal laws the agent obeys — secrets, scope, verify-before-assert, surface-failures, context economy, load-the-docs, tool-discovery, non-interactive-shell, untrusted-content, least-privilege, external-gate, root-cause, idempotency, calibrated-honesty, source-over-surface, restart-is-not-reload, total-teardown, cover-and-verify, prove-the-gate, answer-shape, stable-reference-codes… |
|
|
157
156
|
| **🤖 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` |
|
|
158
157
|
| **🛠 Skills** (47) | repeatable workflows: brainstorm · **clarify** · plan · **codebase-design** · **domain-modeling** · **wayfinder** · **tickets** · tdd · **develop** · debug · **prototype** · refactor · **ponytail** · **forge-mcp** · 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** |
|
|
159
158
|
| **🔌 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 |
|
|
@@ -261,7 +260,8 @@ Geneseed/
|
|
|
261
260
|
│ └── notebook/ the agent's own freeform space — convention + index
|
|
262
261
|
├── themes/ voice token maps (14 themes shipped)
|
|
263
262
|
├── web/ Vite + React UI source; the committed web/dist/ build is what ships
|
|
264
|
-
├── tests/ Node test suites + the
|
|
263
|
+
├── tests/ Node test suites + the pure-function/help recordings they replay
|
|
264
|
+
│ (tests/__snapshots__/ — the emit/cli/web corpora retired 2026-08-17)
|
|
265
265
|
├── docs/ guides (web-ui, wiki, …) + docs/web/ (the console's Docs pages);
|
|
266
266
|
│ specs/, reviews/, superpowers/ are local working docs — git-ignored
|
|
267
267
|
├── adapters/ per-host glue (opencode/, claude-code/, bob/, copilot/)
|
|
@@ -294,8 +294,6 @@ geneseed rebuild-all # re-render every registered install in its own theme + m
|
|
|
294
294
|
./geneseed upgrade # just the content refresh (remembers theme + emit mode)
|
|
295
295
|
```
|
|
296
296
|
|
|
297
|
-
**Moving from a clone to npm** — `geneseed migrate` re-emits every install you already have onto the npm shape, all-or-nothing, and reports (never rewrites) the hooks and login items it did not write. `--dry-run` prints the plan first. See [Migrate an existing install](docs/web/migrate.md).
|
|
298
|
-
|
|
299
297
|
**Local edits survive.** The self-improvement loops let the agent refine its deployed agent/skill files in place. Before setup, re-theme, or upgrade overwrites them, any drift is auto-exported to a markdown **improvements file** under `improvements/` *inside the deployed harness dir* (e.g. `~/.config/opencode/improvements/` for the global install) — beside the install it describes, untouched by rebuilds and uninstall. Hand it to an agent in this repo to back-port the changes into `src/`. On demand: `./geneseed diff --out FILE`, or the **Changes** page in the web console.
|
|
300
298
|
|
|
301
299
|
Details and precedence rules: [SETUP.md → Upgrade](SETUP.md#upgrade).
|
package/SETUP.md
CHANGED
|
@@ -100,9 +100,11 @@ hand? Pick a path below.
|
|
|
100
100
|
> **Every `geneseed-build …` below is the generator.** `npm install -g geneseed` puts it
|
|
101
101
|
> on your `PATH`; without installing anything, `npx -p geneseed geneseed-build --emit
|
|
102
102
|
> opencode-global` is the same command. From a checkout it is
|
|
103
|
-
> `node bin/geneseed.mjs` with the same flags.
|
|
104
|
-
>
|
|
105
|
-
>
|
|
103
|
+
> `node bin/geneseed.mjs` with the same flags. Every commit re-emits with it across every
|
|
104
|
+
> theme × host × footprint combination and checks the result with `doctor --all`, on Linux
|
|
105
|
+
> and Windows both. Until 2026-08-17 that output was also compared byte for byte against
|
|
106
|
+
> recordings taken from the Python implementation; those were retired, and `docs/limits.md`
|
|
107
|
+
> says why and what it cost.
|
|
106
108
|
|
|
107
109
|
---
|
|
108
110
|
|
|
@@ -602,7 +604,9 @@ command serves gitlab.com and any private instance.
|
|
|
602
604
|
scopes `api` and `read_repository`. Treat it like a password.
|
|
603
605
|
|
|
604
606
|
**2. Register one entry per instance** — same command, different `GITLAB_API_URL`
|
|
605
|
-
and token. Two instances (e.g. gitlab.com plus a self-hosted server) → two entries
|
|
607
|
+
and token. Two instances (e.g. gitlab.com plus a self-hosted server) → two entries.
|
|
608
|
+
The MCP screen ships a one-click row for the **first** entry only; a second instance is a
|
|
609
|
+
hand-added copy of that block, which is all it ever was:
|
|
606
610
|
|
|
607
611
|
<!--harness:opencode-->
|
|
608
612
|
On OpenCode, under the `mcp` key of `opencode.json`:
|
|
@@ -642,6 +646,11 @@ The entry key is just a label — name them `gitlab` / `gitlab-2`, or after each
|
|
|
642
646
|
(`gitlab`, `gitlab-acme`). What separates the two is the `GITLAB_API_URL` + token pair;
|
|
643
647
|
keep the `/api/v4` suffix on the URL.
|
|
644
648
|
|
|
649
|
+
**Don't know where this file lives?** Run `geneseed web`, open **Harnesses**, and expand an
|
|
650
|
+
active install — each MCP target prints the full path of the config file it writes, right
|
|
651
|
+
above its server rows. That is the file the token and the URL go into. From the terminal,
|
|
652
|
+
`geneseed mcp` prints the same paths without starting anything.
|
|
653
|
+
|
|
645
654
|
#### Filesystem
|
|
646
655
|
|
|
647
656
|
Give the agent scoped file access via
|
|
@@ -981,9 +990,8 @@ anything, naming the `npm install -g` line above instead.
|
|
|
981
990
|
**Installed from a clone:**
|
|
982
991
|
|
|
983
992
|
```
|
|
984
|
-
./geneseed upgrade # track
|
|
985
|
-
./geneseed upgrade
|
|
986
|
-
./geneseed upgrade main imperial # force a theme
|
|
993
|
+
./geneseed upgrade # track the checkout's current branch; keep theme + emit mode
|
|
994
|
+
./geneseed upgrade imperial # force a theme
|
|
987
995
|
```
|
|
988
996
|
|
|
989
997
|
It git-pulls the install's own origin (fast-forward only), validates it (a blocking
|
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: **2.
|
|
23
|
+
> string. Current label: **2.1.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,7 +35,7 @@ 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** |
|
|
38
|
+
| **Laws / Agents / Skills / Memory / Notebook** | 40 laws, 17 agents, 47 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
39
|
| **`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) |
|
|
40
40
|
| **`diff` + improvements export** | Deployed-vs-source drift report; export an `improvements.md` back-port | [improvements-export](docs/specs/2026-06-12-improvements-export.md) |
|
|
41
41
|
| **`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) |
|
|
@@ -48,7 +48,7 @@ Every row below is present in the tree today; "Spec" links the design record.
|
|
|
48
48
|
| **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) |
|
|
49
49
|
| **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. Law VI 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) |
|
|
50
50
|
| **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) |
|
|
51
|
-
| **Node runtime + npm package** | The whole harness runs from Node: every command `js/cli-table.json` declares, all four hook verbs, every web-console endpoint (the OS-native folder picker excepted, and declined on purpose) and both generators.
|
|
51
|
+
| **Node runtime + npm package** | The whole harness runs from Node: every command `js/cli-table.json` declares, all four 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) |
|
|
52
52
|
| **Runtime awareness** | MCP discovery, web research, tool-call batching, review discipline baked into the laws | [runtime-awareness](docs/specs/2026-06-07-runtime-awareness-and-review-discipline.md) |
|
|
53
53
|
| **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) |
|
|
54
54
|
|
|
@@ -26,15 +26,6 @@
|
|
|
26
26
|
},
|
|
27
27
|
"enabled": false
|
|
28
28
|
},
|
|
29
|
-
"gitlab-2": {
|
|
30
|
-
"type": "local",
|
|
31
|
-
"command": ["npx", "-y", "@zereight/mcp-gitlab"],
|
|
32
|
-
"environment": {
|
|
33
|
-
"GITLAB_PERSONAL_ACCESS_TOKEN": "",
|
|
34
|
-
"GITLAB_API_URL": "https://gitlab.example.com/api/v4"
|
|
35
|
-
},
|
|
36
|
-
"enabled": false
|
|
37
|
-
},
|
|
38
29
|
"filesystem": {
|
|
39
30
|
"type": "local",
|
|
40
31
|
"command": ["npx", "-y", "@modelcontextprotocol/server-filesystem", "/path/to/allowed/dir"],
|
package/bin/geneseed.mjs
CHANGED
|
@@ -387,7 +387,7 @@ function warnBobGlobalOverProject() {
|
|
|
387
387
|
+ "(doubled context) unless Bob's workspace rules truly shadow the global "
|
|
388
388
|
+ "one there. Review and remove what you don't want:\n");
|
|
389
389
|
for (const root of survivors) {
|
|
390
|
-
process.stderr.write(` - ${root} ->
|
|
390
|
+
process.stderr.write(` - ${root} -> geneseed uninstall --target "${root}"\n`);
|
|
391
391
|
}
|
|
392
392
|
}
|
|
393
393
|
|
|
@@ -501,7 +501,7 @@ function warnCopilotGlobalOverProject() {
|
|
|
501
501
|
+ '(doubled context): Copilot stacks ~/.copilot/copilot-instructions.md on top '
|
|
502
502
|
+ "of a repo's own AGENTS.md. Review and remove what you don't want:\n");
|
|
503
503
|
for (const root of survivors) {
|
|
504
|
-
process.stderr.write(` - ${root} ->
|
|
504
|
+
process.stderr.write(` - ${root} -> geneseed uninstall --target "${root}"\n`);
|
|
505
505
|
}
|
|
506
506
|
}
|
|
507
507
|
|
package/docs/declined.md
CHANGED
|
@@ -8,6 +8,16 @@ The reference has been deleted, so "the reference does X" is no longer an argume
|
|
|
8
8
|
re-run. What is recorded in `tests/__snapshots__/` is the reference's answer, frozen; what is
|
|
9
9
|
listed here is where this implementation answers differently on purpose.
|
|
10
10
|
|
|
11
|
+
**The recording is smaller than it was.** On **2026-08-17** the emit, cli and web corpora were
|
|
12
|
+
retired — 1381 cells, produced by an implementation that no longer exists and re-recordable by
|
|
13
|
+
nothing, so they reddened on every deliberate content change while saying nothing about a defect
|
|
14
|
+
that happened to be stable. What licensed it was a measurement: all five mutations whose only
|
|
15
|
+
declared gate was a corpus replay are killed by `tests/unit/` alone. `docs/limits.md` carries the
|
|
16
|
+
full argument and what it cost. **The consequence for this page is narrow and worth stating: an
|
|
17
|
+
entry whose "how it stays honest" half named one of those three corpora now names a weaker gate, or
|
|
18
|
+
none.** The help fixtures under `tests/__snapshots__/help/`, which most of this page rests on, are
|
|
19
|
+
untouched.
|
|
20
|
+
|
|
11
21
|
---
|
|
12
22
|
|
|
13
23
|
## `--help`: the prog is `geneseed`, not `harness`
|
|
@@ -101,8 +111,14 @@ entry above and readers keep finding it separately.
|
|
|
101
111
|
|
|
102
112
|
argparse printed a usage block around every parse failure and prefixed it `harness: error:`; both
|
|
103
113
|
entries state the fault on one line prefixed `geneseed: error:` / `geneseed-hook: error:`. See
|
|
104
|
-
`bin/geneseed-cli.mjs`'s `parse` docblock.
|
|
105
|
-
|
|
114
|
+
`bin/geneseed-cli.mjs`'s `parse` docblock.
|
|
115
|
+
|
|
116
|
+
**What used to be gated beside it no longer is.** Every error a command's own body raises was in
|
|
117
|
+
the recorded CLI corpus, replayed cell by cell; that corpus was retired on 2026-08-17 and the
|
|
118
|
+
per-verb error texts are now covered only where `tests/unit/` happens to drive the verb. The
|
|
119
|
+
divergence declared here is unchanged — the port has never reproduced argparse's wording and does
|
|
120
|
+
not start now — but the *neighbouring* claim, that the rest of the error surface is pinned byte for
|
|
121
|
+
byte, has expired.
|
|
106
122
|
|
|
107
123
|
---
|
|
108
124
|
|
|
@@ -147,3 +163,38 @@ docblock this as "argparse's own rule". It is not — that generalised from `dif
|
|
|
147
163
|
which works only because an UNKNOWN option is deferred to the end of `parse_known_args`. Two of
|
|
148
164
|
that test's four cases are cases where the reference errors instead, so the test pins a
|
|
149
165
|
divergence; its docblock now says which cases those are and points here.
|
|
166
|
+
|
|
167
|
+
## A verb that postdates the recorder is exempted from the cell matrix by name
|
|
168
|
+
|
|
169
|
+
**Status:** ACCEPTED, 2026-08-19. This widens an existing exemption rather than minting a second
|
|
170
|
+
one, and it changes a TEST, not the product.
|
|
171
|
+
|
|
172
|
+
**What differs.** `tests/unit/hook_cli.test.mjs`'s `the matrix covers every verb each entry
|
|
173
|
+
claims` asserted a strict equality between the hook verbs `tests/helpers/matrix/cli.*.json`
|
|
174
|
+
covers and the verbs `bin/geneseed-hook.mjs` carries. The CLI half of the same test already
|
|
175
|
+
exempted a named `NATIVE` list; the hook half exempted nothing. Both halves now filter through
|
|
176
|
+
the same list.
|
|
177
|
+
|
|
178
|
+
**Why the recording could not be kept as the whole answer.** The matrix was exported by the
|
|
179
|
+
reference implementation, which was deleted on 2026-08-17 along with every recorder that could
|
|
180
|
+
write a cell. So the covered set is frozen at four hook verbs for good. A fifth hook verb —
|
|
181
|
+
wired in `js/settings.mjs`, carried in `bin/geneseed-hook.mjs`, declared in `js/cli-table.json` —
|
|
182
|
+
would fail this equality with **no green path**: the corpus cannot grow, and the failure message
|
|
183
|
+
correctly forbids deleting cells to pass. The gate had become a wall, and a wall that stops a
|
|
184
|
+
legitimate change is not protection, it is an accident of when the recorder died.
|
|
185
|
+
|
|
186
|
+
The reason the three CLI verbs were exempted in the first place — *the reference had nothing to
|
|
187
|
+
compare against, and authoring one would be recording a copy of the value under test* — is
|
|
188
|
+
exactly the reason a verb that postdates the reference has no cell. Same reason, same exemption.
|
|
189
|
+
|
|
190
|
+
**What was lost, measured.** Nothing that another gate does not already hold. The only property
|
|
191
|
+
the frozen hook half carried beyond `NATIVE` was *"a hook verb cannot be removed by a coordinated
|
|
192
|
+
edit of three files"* — and `tests/unit/hook_cli.test.mjs`'s own literal (`sorted(wired)` against
|
|
193
|
+
the four names) plus its `verbsOf(HOOK) === wired` equality are two editable copies of that same
|
|
194
|
+
set, twelve lines above. `tests/mutate.mjs`'s M8 plants the one-file removal and is killed there,
|
|
195
|
+
not here.
|
|
196
|
+
|
|
197
|
+
**How it stays honest.** The exemption is a NAMED list, not a containment: a new verb has to be
|
|
198
|
+
written into `NATIVE` deliberately, in two files that read each other's source, and the reverse
|
|
199
|
+
check refuses an exemption for a verb neither entry point carries. So the next new verb still
|
|
200
|
+
fails loudly until someone decides about it — which is the whole point of the original design.
|