geneseed 4.6.0 → 4.8.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 +36 -0
- package/README.md +1 -1
- package/SHIPPED.md +1 -1
- package/adapters/claude-code/README.md +3 -1
- package/adapters/opencode/HOW-OPENCODE-LOADS.md +1 -1
- package/adapters/opencode/README.md +5 -4
- package/adapters/opencode/plugins/geneseed-guard.js +565 -37
- package/bin/geneseed-hook.mjs +9 -3
- package/docs/concepts/enforcement-table.md +1 -1
- package/docs/concepts/exclusions.md +20 -1
- package/docs/concepts/hooks.md +11 -3
- package/docs/concepts/host-matrix.md +3 -3
- package/docs/reference/plugin-guard.md +3 -3
- package/docs/reference/troubleshoot-doctor.md +4 -2
- package/docs/understand/a-day.md +6 -6
- package/docs/understand/design-choices-gates.md +2 -2
- package/docs/understand/enforced-vs-asked.md +4 -4
- package/docs/understand/harness.md +1 -1
- package/docs/understand/machine-claude.md +1 -1
- package/docs/understand/machine-opencode.md +2 -2
- package/docs/web-ui.md +3 -1
- package/harness.config.json +1 -1
- package/js/README.md +2 -1
- package/js/build/args.mjs +4 -1
- package/js/build/driver.mjs +11 -7
- package/js/build/emit-claude.mjs +4 -3
- package/js/build/emit-opencode.mjs +2 -1
- package/js/build/generate.mjs +13 -4
- package/js/build/render.mjs +4 -0
- package/js/build/source.mjs +4 -1
- package/js/cli-table.json +45 -0
- package/js/hosts/gitref.mjs +47 -1
- package/js/hosts/hooks.mjs +19 -39
- package/js/hosts/installs.mjs +20 -0
- package/js/hosts/loss.mjs +522 -0
- package/js/hosts/settings.mjs +79 -75
- package/js/inspect/checks-probe.mjs +18 -6
- package/js/inspect/diff.mjs +4 -1
- package/js/inspect/status.mjs +3 -1
- package/js/inspect/validate.mjs +6 -4
- package/js/maintain/uninstall.mjs +5 -2
- package/js/maintain/update.mjs +1 -1
- package/js/web/actions.mjs +20 -3
- package/js/web/api.mjs +4 -2
- package/package.json +1 -1
- package/src/AGENT.md.tmpl +1 -1
- package/src/laws/universal.md +17 -17
- package/src/skills/worktree.md +1 -1
- package/web/dist/assets/{Activity-Dj0izJwj.js → Activity-B-XbKlzu.js} +1 -1
- package/web/dist/assets/{ActivityDetail-wjq5W02K.js → ActivityDetail-8oq0fycD.js} +1 -1
- package/web/dist/assets/{Dashboard-UMbgHbzF.js → Dashboard-C4EMz5mf.js} +2 -2
- package/web/dist/assets/{Docs-D3ABE_ds.js → Docs-mq4XDQK_.js} +1 -1
- package/web/dist/assets/FilterInput-Ikvi-pS9.js +1 -0
- package/web/dist/assets/{GreenhouseView-C238LWBD.js → GreenhouseView-D1WOtq3n.js} +1 -1
- package/web/dist/assets/{Installs-XSm0a_zQ.js → Installs-DrqPaLDM.js} +1 -1
- package/web/dist/assets/{JournalView-BUj4Ff-6.js → JournalView-BYpASU-L.js} +1 -1
- package/web/dist/assets/Laws-A3PFwiPD.js +3 -0
- package/web/dist/assets/{Library-CkaPVUYU.js → Library-BCaqPf61.js} +1 -1
- package/web/dist/assets/{Loops-CexwOARr.js → Loops-Bx3HnlUA.js} +1 -1
- package/web/dist/assets/{Markdown-DrXLM6TA.js → Markdown-BK38dn4x.js} +1 -1
- package/web/dist/assets/{OperatorHudView-D5qTQat0.js → OperatorHudView-ChQPM8JE.js} +1 -1
- package/web/dist/assets/{Personal-B_Vx9a7a.js → Personal-DELm61DF.js} +1 -1
- package/web/dist/assets/{Tabs-YZbGqWPW.js → Tabs-DcMq5IvC.js} +1 -1
- package/web/dist/assets/{activity-dcg5vF9j.js → activity-D4w9t8fE.js} +1 -1
- package/web/dist/assets/{drawable-BoQnwVpr.js → drawable-BI2_tF3o.js} +1 -1
- package/web/dist/assets/{index-BoG1M8Xy.css → index-CHpydQJg.css} +1 -1
- package/web/dist/assets/{index-BmbWeoTM.js → index-r2jRgf6l.js} +2 -2
- package/web/dist/assets/{react-DRhoX0kS.js → react-Ci4wQD4a.js} +2 -2
- package/web/dist/assets/{usePoll-BmR631BB.js → usePoll-BcywUo55.js} +1 -1
- package/web/dist/index.html +3 -3
- package/web/src/pages/Laws.jsx +53 -5
- package/web/dist/assets/FilterInput-BSfpStOZ.js +0 -1
- package/web/dist/assets/Laws-yGBJFKgY.js +0 -3
package/CHANGELOG.md
CHANGED
|
@@ -8,6 +8,42 @@ label. For the capability ↔ spec map, see [SHIPPED.md](SHIPPED.md).
|
|
|
8
8
|
|
|
9
9
|
## [Unreleased]
|
|
10
10
|
|
|
11
|
+
## [4.8.0] — 2026-10-18
|
|
12
|
+
|
|
13
|
+
Minor: Deletion Is Deliberate asks only on real data loss, and can be switched off per install.
|
|
14
|
+
|
|
15
|
+
### Added
|
|
16
|
+
- **An on/off switch for the Deletion Is Deliberate gate.** `geneseed build --no-deletion-gate` (or the switch on Rule IV's row of the console's Constitution page, which then reads *Gate off*) stops the real-loss check from asking on that install: `git-gate`/`tool-gate` are wired with `--no-deletion-gate` on Claude Code, OpenClaude and Bob, the OpenCode guard plugin stops blocking real loss, and OpenCode's `permission.bash` drops its Law IV keys. Armed by default. The Rule's text still binds, and Sealed Secrets, the root-scan check, Consent Before Push, External Gate and the OpenCode guard's catastrophic-command block stay. The install records `Deletion gate: off` beside its pack list; rebuilds and upgrades keep it, `geneseed status` shows it, and `doctor --probe` checks a disarmed gate on a root-wide scan instead. On Claude Code, OpenClaude and Bob a removal outside a repository, `rm -rf /` included, is caught only by the real-loss check, so it no longer asks there while the gate is off.
|
|
17
|
+
|
|
18
|
+
### Upgrade notes
|
|
19
|
+
- Run `geneseed rebuild-all` once after updating, before switching the deletion gate off: an older hook shim given the new flag silently drops the whole gate call.
|
|
20
|
+
- The deletion gate switch: an existing `opencode.json` keeps its Law IV `permission.bash` keys when the gate is switched off (the build warns and names them); delete them by hand. OpenCode reads the switch when it starts, so restart it after flipping. While the machine's hook shim points at an older checkout, a disarmed install's gate verb refuses the new flag and lets every call through — the root-scan and consent checks too, and on Bob Sealed Secrets and External Gate — until `geneseed rebuild-all` points the shim at this version.
|
|
21
|
+
- OpenCode: as with the 4.7.0 worktree keys, an existing `opencode.json` keeps the state-dependent Law IV keys the calibration below removed from `permission.bash` — the force-push forms (`git push --force*`, `git push -f*`, `git push *--force*`, `git push * -f*`, `git push *+*`), `git reset --hard*`, `git reset * --hard*`, the `git clean` force forms, `git branch -D*` and both `--delete`/`--force` orders, `git checkout -- *`, the `git checkout`/`git switch` force and `--discard-changes` forms, `git stash drop*`, `git stash clear*`, `git push *--delete*` and `git push * :*`. An existing `opencode.json` keeps them and they keep asking; delete them by hand to get the calibrated behaviour. `git reflog expire*` and `git gc --prune*` stay Geneseed's, and new keys ask for a force push to, or a delete of, `main`/`master` by name, so those still ask with the guard plugin off.
|
|
22
|
+
- OpenCode: `rm -rf *` leaves `permission.bash` too. The guard plugin now decides every `rm`: it lets through a removal of tracked, unmodified files and blocks one git cannot restore, and it still blocks `rm -rf /`, `~` and drive roots outright. An existing `opencode.json` keeps its `rm -rf *` key, which keeps asking; Geneseed no longer claims it, so it neither removes nor reports it. Delete it by hand to get the calibrated behaviour. With the guard plugin off (`GENESEED_GUARD=off`) or in `warn` mode, an `rm` no longer meets any prompt.
|
|
23
|
+
- `geneseed doctor --probe` now sends `git reflog expire --expire=now --all` as the call a gate must refuse, instead of `git reset --hard HEAD`, which passes on a clean tree.
|
|
24
|
+
|
|
25
|
+
### Changed
|
|
26
|
+
- **Deletion Is Deliberate asks only on real data loss.** The gate used to ask on every destructive-looking git form. It now reads the repository's state and asks only when a command would destroy something nothing else holds:
|
|
27
|
+
- deleting or force-pushing `main`, `master` or a remote's default branch, locally or remotely;
|
|
28
|
+
- `branch -D` of a branch whose commits are on no remote and not merged into HEAD;
|
|
29
|
+
- `reset --hard`, `checkout -f`/`-- <paths>`, `switch --discard-changes`, `restore` and `clean -f` over uncommitted or untracked work that actually exists;
|
|
30
|
+
- `stash drop`/`clear` while a stash exists, and `reflog expire` and `gc --prune` always;
|
|
31
|
+
- **new:** removing files (`rm`, `rmdir`, `del`, `erase`, `Remove-Item`/`ri`/`rd`) that git cannot restore — untracked, ignored or modified files, a `.git`, or anything outside a repository.
|
|
32
|
+
- **new, on a protected branch only:** `checkout <paths>` without `--` and `git rm -f` over changed files while `main`, `master` or the default branch is checked out, and `branch -f`/`checkout -B`/`switch -C` moving a protected branch off commits no remote and not the new target holds (asks when it cannot verify). On a feature branch, and for a new branch (`checkout -b`, `switch -c`, `branch x`), these pass.
|
|
33
|
+
The same commands on a clean tree, a pushed or merged branch, a feature-branch force push and an `rm` of tracked, unmodified files pass. When the gate cannot tell — a glob or variable it would have to expand, a `cd` it cannot follow, `sh -c`/`xargs`, git failing or missing — it asks and says it could not verify. To read the state the git gate runs `git` itself (ADR 0002 amended), only once a command already looked destructive; ordinary tool calls are unaffected. On every host: an ask on Claude Code and OpenClaude, exit 2 on Bob, and on OpenCode a block by the guard plugin, which has no ask tier (`GENESEED_GUARD=warn` downgrades it), with `reflog expire`/`gc --prune` and the `main`/`master` force/delete forms also asked by static `permission.bash` globs.
|
|
34
|
+
- **The Deletion Is Deliberate law text says the same.** Both halves of the rule now name real data loss as what needs confirmation — deleting what version control cannot restore (untracked, modified, unpushed or unmerged work), discarding uncommitted changes, deleting or force-moving `main`, `master` or the default branch, pruning the reflog — beside irreversible, financial, privilege-changing and outward-facing acts. They say that what git can restore runs freely: removing tracked clean files, a worktree, a force-push to a feature branch. Force-push is no longer listed as an outward-facing act that always asks.
|
|
35
|
+
|
|
36
|
+
## [4.7.0] — 2026-10-17
|
|
37
|
+
|
|
38
|
+
Minor: the Deletion Is Deliberate gate stops asking on worktree removal.
|
|
39
|
+
|
|
40
|
+
### Upgrade notes
|
|
41
|
+
- Run `geneseed rebuild-all` once after updating so installed hooks and OpenCode plugins pick up the change.
|
|
42
|
+
- OpenCode: an `opencode.json` written by an earlier version keeps the four `git worktree remove … -f`/`--force` keys under `permission.bash`. Geneseed no longer claims them, so it neither removes nor reports them; delete them by hand to stop the prompt.
|
|
43
|
+
|
|
44
|
+
### Changed
|
|
45
|
+
- **`git worktree remove --force` no longer asks.** Removing a worktree is routine agent housekeeping, so the *Deletion Is Deliberate* gate now lets `worktree remove -f`/`--force` through like a plain `worktree remove`, on every host: the Claude Code/OpenClaude/Bob git-gate, OpenCode's permission globs and the guard plugin's warning. Every other destructive git form is gated as before.
|
|
46
|
+
|
|
11
47
|
## [4.6.0] — 2026-10-17
|
|
12
48
|
|
|
13
49
|
Minor: a refactor and cleanup pass over everything since 3.15.0, and the nine gate and counter bugs it turned up.
|
package/README.md
CHANGED
|
@@ -37,7 +37,7 @@ Want to read what it leaves behind before installing anything? [**geneseed-demo*
|
|
|
37
37
|
|
|
38
38
|
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:
|
|
39
39
|
|
|
40
|
-
- **Laws are enforced, not suggested.** A force-push
|
|
40
|
+
- **Laws are enforced, not suggested.** A force-push to `main`, a `reset --hard` over uncommitted work, 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 OpenClaude, 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.
|
|
41
41
|
- **One source, five targets.** Skills are byte-identical on every host; only the wiring differs. Every commit renders all 263 emit configurations, and a second emit into the same tree must change nothing.
|
|
42
42
|
- **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).
|
|
43
43
|
- **It follows you.** Install once, globally; every repo inherits it. One `git pull` or `npm install -g geneseed@latest` rebuilds every active install.
|
package/SHIPPED.md
CHANGED
|
@@ -20,7 +20,7 @@ historical references, not files distributed with the repo.
|
|
|
20
20
|
> **On version numbers.** [`harness.config.json`](harness.config.json)'s `version` is a
|
|
21
21
|
> human-readable label only. The canonical identity of an installed harness is the
|
|
22
22
|
> **source fingerprint** stamped in `.geneseed-version` (see `geneseed version`), not the
|
|
23
|
-
> string. Current label: **4.
|
|
23
|
+
> string. Current label: **4.8.0**.
|
|
24
24
|
|
|
25
25
|
## Capabilities
|
|
26
26
|
|
|
@@ -18,7 +18,9 @@ absolute-path hooks instead — `geneseed setup` does that for you.) It:
|
|
|
18
18
|
half of Doctrine process 5 (*consent before every commit and push*) and of the
|
|
19
19
|
destructive-git Rule. Drop the `process` pack (or exclude process 5) and the hook stays,
|
|
20
20
|
wired with `--no-consent`: commits and pushes pass without asking, while the
|
|
21
|
-
|
|
21
|
+
Law IV refusals (asked only on real data loss: a force-push to `main`, a `reset --hard`
|
|
22
|
+
over uncommitted work, an `rm` git cannot undo) stay in every build unless the install is
|
|
23
|
+
built `--no-deletion-gate`, which appends that flag and stands the real-loss check down. The hook inspects
|
|
22
24
|
command and, when it runs a `git commit` or `git push` (bare, flagged, `-C <path>`,
|
|
23
25
|
or chained like `git add . && git commit … && git push`), returns
|
|
24
26
|
`permissionDecision: "ask"` so Claude Code **prompts on every such call**. Crucially
|
|
@@ -125,7 +125,7 @@ to native **skills**, not slash commands (same `SKILL.md` shape as Claude Code).
|
|
|
125
125
|
| plugin on `experimental.session.compacting` | **context plugin** — re-pushes the `eager` docs so they survive compaction |
|
|
126
126
|
| plugin on `session.idle` | **learn plugin** — distils memory into `memory/` (debounced to fire once, at session end) |
|
|
127
127
|
| plugin on `experimental.chat.messages.transform` (V1) | **context plugin** — also adds the done gate's reminder when a check in `.geneseed/done-checks.txt` has not passed since the last edit (Verify Before Asserting); OpenCode 2 turns are not judged |
|
|
128
|
-
| plugin on `tool.execute.before` | **guard plugin** — blocks secret-file writes and credential-shaped write content (Sealed Secrets), writes to a protected check or the done list (External Gate), catastrophic shell (Deletion Is Deliberate), a recursive whole-filesystem scan (Commands Must Return), the first rule-store write (Persist Insight) and protected wiki folders; logs each block to the gate ledger and counts skill/subagent use (`GENESEED_GUARD=off\|warn`) |
|
|
128
|
+
| plugin on `tool.execute.before` | **guard plugin** — blocks secret-file writes and credential-shaped write content (Sealed Secrets), writes to a protected check or the done list (External Gate), catastrophic shell and every other real data loss, judged against the repository's state (Deletion Is Deliberate), a recursive whole-filesystem scan (Commands Must Return), the first rule-store write (Persist Insight) and protected wiki folders; logs each block to the gate ledger and counts skill/subagent use (`GENESEED_GUARD=off\|warn`) |
|
|
129
129
|
| plugin registering a custom tool | **workflow plugin** — the `workflow` tool runs saved orchestration scripts from `workflows/` |
|
|
130
130
|
| `context.json` / `.harness/` (manifest) | *optional* override when discovery doesn't fit |
|
|
131
131
|
|
|
@@ -384,9 +384,10 @@ behaviour** — nothing changes the machine's current agent/model unless you opt
|
|
|
384
384
|
`2026-06-17-opencode-color-themes` spec).
|
|
385
385
|
- **Runtime guard plugin** (`geneseed-guard.js`, installed with the others). Enforces
|
|
386
386
|
the safety Laws at the tool boundary: **blocks** writes to private-key/credential
|
|
387
|
-
files (Sealed Secrets), catastrophic shell like `rm -rf /`
|
|
387
|
+
files (Sealed Secrets), catastrophic shell like `rm -rf /` and every command that would really lose data, judged
|
|
388
|
+
against the repository's state (Deletion Is Deliberate), and any mutation under
|
|
388
389
|
a declared wiki's `protected` folders (AGENT.md §8, from `geneseed-wiki.jsonc`); **warns** on
|
|
389
|
-
`.env` writes
|
|
390
|
+
`.env` writes. `GENESEED_GUARD=off` disables it, `=warn` downgrades
|
|
390
391
|
blocks to warnings. Every **block** appends one line to the install's
|
|
391
392
|
`notebook/gates.jsonl` (rule `law-1` / `law-4` / `process-1` / `wiki`, a timestamp,
|
|
392
393
|
never the path or command) — the same ledger the Claude-family hooks write, so
|
|
@@ -398,8 +399,8 @@ behaviour** — nothing changes the machine's current agent/model unless you opt
|
|
|
398
399
|
auto-falls back to the visible `session.created` message. `GENESEED_CONTEXT_VISIBLE=1`
|
|
399
400
|
forces the visible block (legacy `GENESEED_CONTEXT_TRANSFORM=0/off` does the same).
|
|
400
401
|
- **Default permissions.** A fresh `opencode.json` gets a minimal policy that **asks**
|
|
401
|
-
before `
|
|
402
|
-
build — and, **on an install that built the `process` pack in**, before every
|
|
402
|
+
before `git reflog expire`, `git gc --prune` and a force-push or delete of `main`/`master` —
|
|
403
|
+
**Rule IV**'s territory, in every build; the guard plugin decides every other data loss — and, **on an install that built the `process` pack in**, before every
|
|
403
404
|
`git commit` and `git push` (the host-level backstop for **Consent Before Push**: the
|
|
404
405
|
agent never records or shares code unprompted, on any branch). Build with
|
|
405
406
|
`--doctrines` leaving `process` out and those two entries are simply not written.
|