geneseed 4.6.0 → 4.7.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 +11 -0
- package/SHIPPED.md +1 -1
- package/adapters/opencode/plugins/geneseed-guard.js +0 -1
- package/harness.config.json +1 -1
- package/js/hosts/hooks.mjs +9 -6
- package/js/hosts/settings.mjs +10 -7
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -8,6 +8,17 @@ label. For the capability ↔ spec map, see [SHIPPED.md](SHIPPED.md).
|
|
|
8
8
|
|
|
9
9
|
## [Unreleased]
|
|
10
10
|
|
|
11
|
+
## [4.7.0] — 2026-10-17
|
|
12
|
+
|
|
13
|
+
Minor: the Deletion Is Deliberate gate stops asking on worktree removal.
|
|
14
|
+
|
|
15
|
+
### Upgrade notes
|
|
16
|
+
- Run `geneseed rebuild-all` once after updating so installed hooks and OpenCode plugins pick up the change.
|
|
17
|
+
- 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.
|
|
18
|
+
|
|
19
|
+
### Changed
|
|
20
|
+
- **`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.
|
|
21
|
+
|
|
11
22
|
## [4.6.0] — 2026-10-17
|
|
12
23
|
|
|
13
24
|
Minor: a refactor and cleanup pass over everything since 3.15.0, and the nine gate and counter bugs it turned up.
|
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.7.0**.
|
|
24
24
|
|
|
25
25
|
## Capabilities
|
|
26
26
|
|
|
@@ -228,7 +228,6 @@ const SHELL_WARN_RE = [
|
|
|
228
228
|
/\bgit\s+switch\b[^\n]*\s(-[a-zA-Z]*f\b|--force\b|--discard-changes\b)/,
|
|
229
229
|
/\bgit\s+restore\b(?:(?![^\n]*--staged\b)|(?=[^\n]*--staged\b)(?=[^\n]*--worktree\b))/,
|
|
230
230
|
/\bgit\s+stash\s+(drop|clear)\b/,
|
|
231
|
-
/\bgit\s+worktree\b[^\n]*\bremove\b[^\n]*(-[a-zA-Z]*f\b|--force\b)/,
|
|
232
231
|
/\bgit\s+reflog\b[^\n]*\bexpire\b/,
|
|
233
232
|
/\bgit\s+gc\b[^\n]*--prune\b/,
|
|
234
233
|
]
|
package/harness.config.json
CHANGED
|
@@ -2,5 +2,5 @@
|
|
|
2
2
|
"_comment": "version is a human-readable release label only; the canonical identity of an installed harness is the source fingerprint stamped in .geneseed-version (see `harness version`), not this string.",
|
|
3
3
|
"theme": "neutral",
|
|
4
4
|
"product": "Geneseed",
|
|
5
|
-
"version": "4.
|
|
5
|
+
"version": "4.7.0"
|
|
6
6
|
}
|
package/js/hosts/hooks.mjs
CHANGED
|
@@ -90,11 +90,14 @@ const GIT_GATE_RE = /\bgit\b[^\n]*\b(?:commit|push)\b/;
|
|
|
90
90
|
// chase — add them if a probe ever shows one in real use), `checkout -f`/`--force` and
|
|
91
91
|
// `switch -f`/`--force`/`--discard-changes`
|
|
92
92
|
// (git's own `-h` lists `-f, --force` AND a separate `--discard-changes` for switch — both
|
|
93
|
-
// discard uncommitted work the same way `checkout --` does), `
|
|
94
|
-
// (
|
|
95
|
-
//
|
|
96
|
-
//
|
|
97
|
-
//
|
|
93
|
+
// discard uncommitted work the same way `checkout --` does), `reflog expire` and `gc
|
|
94
|
+
// --prune=now` (delete the reflog/dangling-commit safety net recovery depends on), and `push
|
|
95
|
+
// :branch`/`push --delete` (deletes a remote branch — the colon form needs a space before the
|
|
96
|
+
// `:` so `push origin HEAD:main`, an ordinary refspec, is not caught).
|
|
97
|
+
//
|
|
98
|
+
// `worktree remove --force`/`-f` is deliberately NOT here (user decision, 2026-10-17): removing
|
|
99
|
+
// a worktree is routine agent housekeeping, so it passes like a plain `worktree remove`. The
|
|
100
|
+
// OpenCode guard's `SHELL_WARN_RE` and `LAW_IV_BASH` (js/hosts/settings.mjs) dropped it too.
|
|
98
101
|
//
|
|
99
102
|
// `restore` and `stash drop`/`stash clear` are carved OUT of the shared `\bgit\b[^\n]*\b(…)`
|
|
100
103
|
// wrapper above and anchored to the verb position instead (`git`, an optional `-C <path>`, then
|
|
@@ -106,7 +109,7 @@ const GIT_GATE_RE = /\bgit\b[^\n]*\b(?:commit|push)\b/;
|
|
|
106
109
|
// combination DOES discard working-tree changes, unlike `--staged` alone) while still deferring
|
|
107
110
|
// on `--staged` alone.
|
|
108
111
|
const DESTRUCTIVE_GIT_RE =
|
|
109
|
-
/\bgit\b[^\n]*\b(?:reset\b[^\n]*\s--hard\b|clean\b[^\n]*\s(?:-[a-zA-Z]*f|--force\b)|branch\b[^\n]*\s(?:-D\b|--delete\b[^\n]*--force\b|--force\b[^\n]*--delete\b)|checkout\s+--\s|checkout\b[^\n]*\s(?:-[a-zA-Z]*f\b|--force\b)|switch\b[^\n]*\s(?:-[a-zA-Z]*f\b|--force\b|--discard-changes\b)|
|
|
112
|
+
/\bgit\b[^\n]*\b(?:reset\b[^\n]*\s--hard\b|clean\b[^\n]*\s(?:-[a-zA-Z]*f|--force\b)|branch\b[^\n]*\s(?:-D\b|--delete\b[^\n]*--force\b|--force\b[^\n]*--delete\b)|checkout\s+--\s|checkout\b[^\n]*\s(?:-[a-zA-Z]*f\b|--force\b)|switch\b[^\n]*\s(?:-[a-zA-Z]*f\b|--force\b|--discard-changes\b)|reflog\b[^\n]*\bexpire\b|gc\b[^\n]*--prune\b|push\b[^\n]*(?:\s--force|\s-[a-zA-Z]*f\b|\s\+\S|\s--delete\b|\s:\S))|\bgit(?:\s+-C\s+\S+)*\s+restore\b(?:(?![^\n]*--staged\b)|(?=[^\n]*--staged\b)(?=[^\n]*--worktree\b))|\bgit(?:\s+-C\s+\S+)*\s+stash\s+(?:drop|clear)\b/;
|
|
110
113
|
|
|
111
114
|
// `loopExempt` — a WHITELIST, not the blacklist this replaced. A false ask costs one prompt; a
|
|
112
115
|
// false allow publishes. So the exemption holds only when the ENTIRE command is built from
|
package/js/hosts/settings.mjs
CHANGED
|
@@ -103,11 +103,16 @@ const consentRuleOn = (d, excluded = []) =>
|
|
|
103
103
|
* like `-d`, so it is deliberately NOT a key here; `-D --force`/`--delete -f`/`-d --force`/
|
|
104
104
|
* `-df` are the same act again and are a known ceiling this does not chase); `checkout
|
|
105
105
|
* -f`/`--force` and `switch -f`/`--force`/`--discard-changes` (git's own `switch -h` lists
|
|
106
|
-
* `-f, --force` and `--discard-changes` as two separate options); `
|
|
107
|
-
*
|
|
108
|
-
*
|
|
109
|
-
*
|
|
110
|
-
*
|
|
106
|
+
* `-f, --force` and `--discard-changes` as two separate options); `reflog expire`; `gc
|
|
107
|
+
* --prune` (matched bare, since a `--prune` with no `=now` still eventually prunes); and `push
|
|
108
|
+
* *--delete*` / `push * :*` (a literal space before the colon, so `push origin HEAD:main`, an
|
|
109
|
+
* ordinary refspec, does not match).
|
|
110
|
+
*
|
|
111
|
+
* `git worktree remove -f`/`--force` was a key here and was REMOVED (user decision, 2026-10-17:
|
|
112
|
+
* worktree removal is routine housekeeping, not a Law IV deletion). Removal from this list also
|
|
113
|
+
* removes the four globs from `OWNED_BASH`, so an `opencode.json` written before keeps them —
|
|
114
|
+
* neither taken back nor reported as stranded, since Geneseed no longer claims them. Its user
|
|
115
|
+
* deletes them by hand (the CHANGELOG upgrade note says so).
|
|
111
116
|
*
|
|
112
117
|
* `git restore` is DELIBERATELY NOT HERE. Its rule is "ask unless `--staged` appears ALONE" —
|
|
113
118
|
* `--staged --worktree` together still discards the working tree — and a glob has no negation,
|
|
@@ -128,8 +133,6 @@ const LAW_IV_BASH = ['git push --force*', 'git push -f*', 'git push *--force*',
|
|
|
128
133
|
'git checkout -f*', 'git checkout * -f*', 'git checkout --force*', 'git checkout * --force*',
|
|
129
134
|
'git switch -f*', 'git switch * -f*', 'git switch --force*', 'git switch * --force*',
|
|
130
135
|
'git switch --discard-changes*', 'git switch * --discard-changes*',
|
|
131
|
-
'git worktree remove -f*', 'git worktree remove --force*',
|
|
132
|
-
'git worktree remove * -f*', 'git worktree remove * --force*',
|
|
133
136
|
'git reflog expire*', 'git gc --prune*', 'git gc * --prune*',
|
|
134
137
|
'git stash drop*', 'git stash clear*',
|
|
135
138
|
'git push *--delete*', 'git push * :*'];
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"//": "Every field here is argued and gated in tests/unit/package_manifest.test.mjs. `files`, `bin` and `engines` each have a test that fails when reality drifts from this file; `version` mirrors harness.config.json and is gated too. Read that docblock before editing this one.",
|
|
3
3
|
"name": "geneseed",
|
|
4
|
-
"version": "4.
|
|
4
|
+
"version": "4.7.0",
|
|
5
5
|
"description": "A portable, theme-able harness you implant once and use everywhere to grow a disciplined AI coding agent.",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"ai",
|