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 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.6.0**.
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
  ]
@@ -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.6.0"
5
+ "version": "4.7.0"
6
6
  }
@@ -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), `worktree remove --force`/`-f`
94
- // (can discard an uncommitted worktree), `reflog expire` and `gc --prune=now` (delete the
95
- // reflog/dangling-commit safety net recovery depends on), and `push :branch`/`push --delete`
96
- // (deletes a remote branch — the colon form needs a space before the `:` so `push origin
97
- // HEAD:main`, an ordinary refspec, is not caught).
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)|worktree\b[^\n]*\bremove\b[^\n]*(?:-[a-zA-Z]*f\b|--force\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/;
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
@@ -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); `worktree remove -f`/`--force` (both
107
- * flag-then-path and path-then-flag order); `reflog expire`; `gc --prune` (matched bare, since
108
- * a `--prune` with no `=now` still eventually prunes); and `push *--delete*` / `push * :*` (a
109
- * literal space before the colon, so `push origin HEAD:main`, an ordinary refspec, does not
110
- * match).
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.6.0",
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",