opencode-gbuild 0.6.4 → 0.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/README.md CHANGED
@@ -12,6 +12,10 @@ Plan in conversation first (your agent's normal plan mode), then hand that plan
12
12
  3. `/gbuild:review <slug>` — audit the accumulated branch
13
13
  4. Issues? `/gbuild:plan <slug> --add "<fix>"`, then `/gbuild:run` again. Clean? `/gbuild:pr <slug>`
14
14
 
15
+ The feature branch lives in its own git worktree (created by `plan`) — your checkout never changes
16
+ branches, your uncommitted work is never in the way, and several features can be in flight in parallel
17
+ without racing each other's `HEAD`.
18
+
15
19
  (OpenCode: `/gbuild-plan`, `/gbuild-run`, … — same loop.)
16
20
 
17
21
  Inspired by the graph-engineering thread at
@@ -93,7 +97,8 @@ OpenCode (same order, kebab-case names):
93
97
  /gbuild-pr add-oauth-login-with-github
94
98
  ```
95
99
 
96
- - **`plan`** charts a feature into a CypherLite graph store at `.gbuild/<feature>/db/` — `Feature`,
100
+ - **`plan`** creates the feature branch in its own git worktree and charts the feature into a
101
+ CypherLite graph store there (`.gbuild/<feature>/db/`) — `Feature`,
97
102
  `Acceptance`, and `GbuildNode` nodes, each node's contract as `INPUT`/`OUTPUT` `Field` nodes, and
98
103
  `FROM` edges carrying data from one node's output to the next node's input. Every dependency edge
99
104
  passes the cut test — and because data flow is explicit, the validator checks it; every node has
@@ -101,12 +106,14 @@ OpenCode (same order, kebab-case names):
101
106
  - **`run`** dispatches every node in the current ready wave concurrently — not one at a time — with
102
107
  each file-touching node working in its own git worktree on its own branch, forked from the feature
103
108
  branch. A dedicated `gbuild-reviewer` subagent reviews each node's output against its branch's diff;
104
- only a passing node's branch is merged back into the feature branch, and its worktree is removed.
109
+ only a passing node's branch is merged back into the feature branch — in the feature's worktree, not
110
+ your checkout — and its worktree is removed.
105
111
  Unaccepted work never lands. A review failure applies the node's declared failure policy. Re-invoking
106
112
  after an interruption resumes only the remaining frontier, reusing the surviving worktrees.
107
113
  - **`status`** reports the graph — frontier, blocked, in-flight, completed, each node's review verdict,
108
114
  and evidence of what actually ran concurrently vs. serially.
109
- - **`review`** audits the finished branch as a whole in a `gbuild-auditor` subagent — abstraction
115
+ - **`review`** audits the finished branch as a whole in a `gbuild-auditor` subagent, working in the
116
+ feature worktree (the full suite runs there) — abstraction
110
117
  quality, file size, spaghetti growth, and the cross-node duplication that per-node review can't see
111
118
  (two nodes, two contexts, same sub-problem solved twice). Blocking findings go back into the graph as
112
119
  a `plan --add` requirement. Ported from hone-ai's `review`.
@@ -185,7 +192,8 @@ curl -sSfL https://neo4j-labs.github.io/cypherlite/install.sh | bash
185
192
  ```
186
193
 
187
194
  Every skill reads and writes the graph with `cypherlite` and nothing else — there is no Python and no
188
- direct JSON editing. The plugin ships the queries as `.cypher` files; skills pipe them into the store:
195
+ direct JSON editing. The plugin ships the queries as `.cypher` files; skills pipe them into the store
196
+ (`.gbuild/<feature>/db` inside the feature's worktree — examples below run from there):
189
197
 
190
198
  ```bash
191
199
  cypherlite .gbuild/<feature>/db --mode jsonl < plugins/gbuild/cypher/validate.cypher # format gate: no output = valid
@@ -225,8 +233,11 @@ plugins/gbuild/
225
233
  ```
226
234
 
227
235
  State lives outside the plugin, in the project: one CypherLite store per feature at
228
- `.gbuild/<feature>/db/`. It holds the plan, every node's status and output values, and the full review
236
+ `.gbuild/<feature>/db/` inside the feature's own git worktree. It holds the plan, every node's status
237
+ and output values, and the full review
229
238
  history. Only `db/graph.json` (CypherLite's JSON snapshot, kept current by every write) and the store's
230
- own `.gitignore` are committed. Per-node worktrees during a run live under `.git/gbuild/<feature>/` —
231
- never in `git status` — and each is removed the moment its node is accepted (merged) or terminally
232
- failed (discarded).
239
+ own `.gitignore` are committed (on the feature branch). All of a feature's worktrees live under
240
+ `.git/gbuild/<feature>/` — never in `git status`: `tree/` is the feature worktree itself, created by
241
+ `plan` and kept until the feature is done, and during a run each file-touching node gets a `<node>/`
242
+ worktree that is removed the moment its node is accepted (merged into the feature branch, in `tree/`)
243
+ or terminally failed (discarded).
@@ -1,24 +1,26 @@
1
1
  ---
2
2
  name: gbuild-auditor
3
- description: Strict end-of-feature maintainability auditor for a gbuild feature branch. Audits abstraction quality, file size, spaghetti growth, and missed code-judo simplifications across the current branch. Use during the final review phase of a gbuild feature, after the graph's nodes are all complete.
3
+ description: Strict end-of-feature maintainability auditor for a gbuild feature branch. Audits abstraction quality, file size, spaghetti growth, and missed code-judo simplifications across the feature branch's accumulated diff, working in the feature's git worktree. Use during the final review phase of a gbuild feature, after the graph's nodes are all complete.
4
4
  ---
5
5
 
6
6
  # gbuild Auditor
7
7
 
8
8
  Unusually strict review of implementation quality, maintainability, and abstraction health. Push for **ambitious** restructurings — "code judo" moves that preserve behavior while making the code dramatically simpler, smaller, and more direct. Delete complexity; don't rearrange it.
9
9
 
10
- The caller passes you the resolved feature slug and the feature context it read from the gbuild store: the `destination` and the acceptance bar (each criterion with the nodes covering it). Use it for scoping context only — you are auditing the branch's code, not re-grading individual nodes (`gbuild-reviewer` already did that per node, against each node's own contract; your job is the thing no per-node pass can see — what the accumulated diff did to the codebase as a whole). Do not open `.gbuild/` or run `cypherlite` — the caller owns the store. Do NOT write any file — output your audit as your final message exclusively.
10
+ The caller passes you the resolved feature slug, the **feature worktree** path, and the feature context it read from the gbuild store: the `destination` and the acceptance bar (each criterion with the nodes covering it). Use the context for scoping only — you are auditing the branch's code, not re-grading individual nodes (`gbuild-reviewer` already did that per node, against each node's own contract; your job is the thing no per-node pass can see — what the accumulated diff did to the codebase as a whole). The feature branch is checked out in the feature worktree: every file read, every check, and every git command runs there (`git -C <worktree> …` or with it as your working directory), never in the main tree. Do not open `.gbuild/` or run `cypherlite` — the caller owns the store. Do NOT write any file — output your audit as your final message exclusively.
11
11
 
12
12
  ## Run the branch's checks first
13
13
 
14
- Before you audit, run the repo's own verification on the branch: the full test suite, plus typecheck and
15
- lint where the repo defines them. Per-node reviews only checked each node against its own acceptance
14
+ Before you audit, run the repo's own verification on the branch, in the feature worktree: the full test suite, plus typecheck and
15
+ lint where the repo defines them. A worktree is a fresh checkout — if the project needs installed
16
+ dependencies to build or test (`node_modules`, `.venv`, …), install or symlink them there first.
17
+ Per-node reviews only checked each node against its own acceptance
16
18
  criteria — nobody has yet run the whole suite against the accumulated diff. A failing check is a
17
19
  blocking finding: name the exact failures.
18
20
 
19
21
  ## Core Prompt
20
22
 
21
- > Deep code-quality audit of the current branch. Rethink structure to improve quality without changing behavior. Improve abstractions, modularity, succinctness, legibility. Be ambitious — if restructuring the codebase yields a clearly better implementation, go for it. Measure twice, cut once.
23
+ > Deep code-quality audit of the feature branch. Rethink structure to improve quality without changing behavior. Improve abstractions, modularity, succinctness, legibility. Be ambitious — if restructuring the codebase yields a clearly better implementation, go for it. Measure twice, cut once.
22
24
 
23
25
  ## Standards
24
26
 
package/index.ts CHANGED
@@ -43,7 +43,7 @@ instructions above:
43
43
  - \`$ARGUMENTS\` refers to the arguments this skill was invoked with in the
44
44
  conversation.
45
45
  - run's "Workflow tool" backend is Claude-specific; always use the fallback
46
- backend described in step 3.
46
+ backend described in step 2.
47
47
  `
48
48
 
49
49
  const frontmatter = (raw: string): { description: string; body: string } => {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/package.json",
3
3
  "name": "opencode-gbuild",
4
- "version": "0.6.4",
4
+ "version": "0.7.0",
5
5
  "description": "OpenCode plugin for gbuild — graph-native task planning and execution with concurrent fan-out, per-node review, and durable checkpoints.",
6
6
  "type": "module",
7
7
  "license": "MIT",
@@ -1,6 +1,7 @@
1
1
  # Talking to the gbuild store
2
2
 
3
- Every gbuild skill reads and writes the feature store (`.gbuild/<feature>/db/`, modelled in
3
+ Every gbuild skill reads and writes the feature store (`.gbuild/<feature>/db/` inside the feature's git
4
+ worktree, modelled in
4
5
  `reference/graph-format.md`) with the `cypherlite` CLI and nothing else. This file is the full operating
5
6
  manual; the skills that only run plugin scripts carry the short version of these rules inline.
6
7
 
@@ -32,7 +33,9 @@ or writer — fails with `storage locked` (exit 1). So:
32
33
  ## Invocation
33
34
 
34
35
  Always pass `--mode jsonl`: one compact JSON object per row, one row per line, and no output at all when
35
- there are no rows. `DB` below is `.gbuild/<feature>/db`.
36
+ there are no rows. `DB` below is the feature store: `.gbuild/<feature>/db` inside the feature worktree
37
+ (`<git-common-dir>/gbuild/<feature>/tree/`), or in the main tree for a feature charted before the
38
+ worktree layout.
36
39
 
37
40
  ```
38
41
  # a plugin script
@@ -75,12 +78,13 @@ CYPHER
75
78
 
76
79
  ## Creating a store
77
80
 
78
- Only `plan` does this, once per feature:
81
+ Only `plan` does this, once per feature, with `DB` = `.gbuild/<feature>/db` inside the feature worktree
82
+ it just created:
79
83
 
80
84
  ```
81
- mkdir -p .gbuild/<feature>/db
82
- cypherlite .gbuild/<feature>/db --snapshot-format json < ${CLAUDE_PLUGIN_ROOT}/cypher/schema.cypher
83
- printf '*\n!.gitignore\n!graph.json\n' > .gbuild/<feature>/db/.gitignore
85
+ mkdir -p DB
86
+ cypherlite DB --snapshot-format json < ${CLAUDE_PLUGIN_ROOT}/cypher/schema.cypher
87
+ printf '*\n!.gitignore\n!graph.json\n' > DB/.gitignore
84
88
  ```
85
89
 
86
90
  `--snapshot-format json` belongs on this first call only (it applies to an empty directory). It installs
@@ -2,7 +2,9 @@
2
2
 
3
3
  This file is normative. Where a skill disagrees with this doc, this doc wins.
4
4
 
5
- One CypherLite store per feature: `.gbuild/<feature>/db/`. `plan` creates and charts it, `run` records
5
+ One CypherLite store per feature: `.gbuild/<feature>/db/` inside the feature's git worktree
6
+ (`<git-common-dir>/gbuild/<feature>/tree/` — `plan` creates the worktree; a feature charted before the
7
+ worktree layout keeps its store in the main tree). `plan` creates and charts it, `run` records
6
8
  progress in it, and every skill reads it — **all through Cypher**. No skill reads or writes `graph.json`
7
9
  directly; it is CypherLite's snapshot of the store. How to talk to the store (the single-writer rule,
8
10
  invocation, quoting, the script catalog) is in `reference/cypher.md`.
@@ -39,7 +41,7 @@ data **and** constraints.
39
41
 
40
42
  | property | type | meaning |
41
43
  | -------------- | -------------- | ---------------------------------------------------- |
42
- | `feature` | string | the slug — matches the `.gbuild/<feature>/` dir, immutable |
44
+ | `feature` | string | the slug — matches the `.gbuild/<feature>/` dir in the feature worktree, immutable |
43
45
  | `destination` | string | one line: what is true once this is done |
44
46
  | `context` | string | why this exists, one or two lines |
45
47
  | `out_of_scope` | list of string | bullets, may be empty |
@@ -60,7 +62,7 @@ universal label is for `MATCH (n:GbuildNode)`; the type label enables `MATCH (n:
60
62
 
61
63
  | property | type | meaning |
62
64
  | ---------------- | -------------- | -------------------------------------------------------------- |
63
- | `slug` | string | kebab-case, unique, immutable — the identity every skill keys on |
65
+ | `slug` | string | kebab-case, unique, immutable — the identity every skill keys on; `tree` is reserved (the feature worktree's directory name) |
64
66
  | `title` | string | what the user reads; refer to nodes by title in conversation |
65
67
  | `type` | string | `research \| decision \| code \| test \| verify \| chore` |
66
68
  | `acceptance` | list of string | node-level criteria — mandatory, non-empty, concrete |
@@ -1,8 +1,9 @@
1
1
  # Ad-hoc queries
2
2
 
3
3
  The plugin scripts (`reference/cypher.md` § Script catalog) cover everything the skills do. These are for
4
- the questions in between. Run them with `cypherlite .gbuild/<feature>/db --mode jsonl "<query>"`, one at a
5
- time; return only the columns you need and keep a `LIMIT` on anything that can grow.
4
+ the questions in between. Run them with `cypherlite DB --mode jsonl "<query>"`, one at a
5
+ time — `DB` is the feature store (`.gbuild/<feature>/db` inside the feature worktree);
6
+ return only the columns you need and keep a `LIMIT` on anything that can grow.
6
7
 
7
8
  ```cypher
8
9
  -- the whole plan with progress
@@ -1,5 +1,5 @@
1
1
  ---
2
- description: Decomposes a feature into a real dependency graph in the gbuild CypherLite store (.gbuild/<feature>/db) — nodes with typed field contracts, mandatory concrete acceptance criteria, and edges that pass the cut test. Use when starting new gbuild work, before /gbuild:run.
2
+ description: Decomposes a feature into a real dependency graph in the gbuild CypherLite store — nodes with typed field contracts, mandatory concrete acceptance criteria, and edges that pass the cut test. Creates the feature branch in its own git worktree, never touching the main checkout. Use when starting new gbuild work, before /gbuild:run.
3
3
  ---
4
4
 
5
5
  Plan the work described in `$ARGUMENTS` as a graph.
@@ -24,30 +24,45 @@ inform the choices below. `${CLAUDE_PLUGIN_ROOT}/reference/checklist.md` is the
24
24
  | a description, link, or file path | **Chart** — new feature |
25
25
  | an existing feature slug with `--add "<req>"` | **Reopen** |
26
26
 
27
- A bare slug with no `.gbuild/<slug>/db/` is a description, not a slug — chart it.
27
+ A bare slug with no store is a description, not a slug — chart it. A slug's store lives in its feature
28
+ worktree at `<git-common-dir>/gbuild/<slug>/tree/.gbuild/<slug>/db` (a feature charted before the
29
+ worktree layout keeps its store at `.gbuild/<slug>/db` in the main tree).
28
30
 
29
31
  ## Chart
30
32
 
31
- ### 1. Slug and branch
33
+ ### 1. Slug, branch, and feature worktree
32
34
 
33
35
  Derive the feature slug from `$ARGUMENTS`: kebab-case, ≤4 words, names the outcome not the mechanism
34
36
  (`oauth-device-flow`, not `add-some-auth-stuff`). It's the `.gbuild/<slug>/` directory name and the
35
37
  `Feature` node's `feature` property — immutable once charted.
36
38
 
37
- Then get onto a branch for it, so `run`'s commits land somewhere isolated:
39
+ gbuild never changes the branch of the user's checkout: the feature branch lives in its own **feature
40
+ worktree**, so several features can be charted and run in parallel without racing each other's `HEAD`,
41
+ and uncommitted work in the main tree is irrelevant — there is no dirty-tree check. Resolve two paths,
42
+ both absolute: `GC` = `git rev-parse --git-common-dir` (resolve it to an absolute path), and `FT` =
43
+ `GC/gbuild/<slug>/tree` — the feature worktree, the one place the feature branch is checked out. Then:
38
44
 
39
- - Working tree dirty → stop and ask. Don't stash or sweep someone else's changes into your branch.
40
- - Already on a branch ending in `<slug>` → stay there, say so.
41
- - Otherwise `git checkout -b <prefix>/<slug>` from current HEAD. Take `<prefix>` from the repo's
42
- convention — project or user instructions first, else the dominant pattern in `git branch --list`
43
- — and fall back to `gbuild` when there is none.
45
+ - `FT` is already a registered worktree (`git worktree list --porcelain`) → reuse it, say so.
46
+ - A branch named `<slug>` or ending `/<slug>` already exists → if it's checked out somewhere (a feature
47
+ charted before the worktree layout usually has it in the main tree), that location is `FT`; otherwise
48
+ attach it: `git worktree add FT <branch>`.
49
+ - Otherwise create branch and worktree in one step, forked from the current HEAD:
44
50
 
45
- Report the branch. Everything below happens on it.
51
+ ```
52
+ git worktree add FT -b <prefix>/<slug> HEAD
53
+ ```
54
+
55
+ Take `<prefix>` from the repo's convention — project or user instructions first, else the dominant
56
+ pattern in `git branch --list` — and fall back to `gbuild` when there is none.
57
+
58
+ Report the branch and `FT`. Everything below happens in `FT`; `DB` below is
59
+ `FT/.gbuild/<slug>/db`.
46
60
 
47
61
  ### 2. Analyse the codebase
48
62
 
49
63
  Read the project manifest(s), directory structure, `README.md`, and — for related in-flight work — the
50
- `Feature` of every existing store (`feature.cypher` against each `.gbuild/*/db`, one at a time). Resolve
64
+ `Feature` of every existing store (`feature.cypher` against each `GC/gbuild/*/tree/.gbuild/*/db`, plus
65
+ any legacy `.gbuild/*/db` in the main tree, one at a time). Resolve
51
66
  file paths or URLs in `$ARGUMENTS`; if a reference fails to load, say so and ask.
52
67
 
53
68
  ### 3. Validate and explore
@@ -140,7 +155,7 @@ Then write the whole graph as **one** Cypher script, piped through a quoted here
140
155
  the edges), `.commit`, `.checkpoint`.
141
156
 
142
157
  ```
143
- cypherlite .gbuild/<slug>/db <<'CYPHER'
158
+ cypherlite DB <<'CYPHER'
144
159
  .begin
145
160
  CREATE (f:Feature {feature: '<slug>', destination: '...', context: '...', out_of_scope: ['...']})
146
161
  CREATE (a1:Acceptance {id: 'a-1', text: '...'})
@@ -163,7 +178,7 @@ slug) fails the transaction and writes nothing — fix the script and run it aga
163
178
  ### 9. Validate
164
179
 
165
180
  ```
166
- cypherlite .gbuild/<slug>/db --mode jsonl < ${CLAUDE_PLUGIN_ROOT}/cypher/validate.cypher
181
+ cypherlite DB --mode jsonl < ${CLAUDE_PLUGIN_ROOT}/cypher/validate.cypher
167
182
  ```
168
183
 
169
184
  No output means valid. Every row is a violation (`check`, `detail`): fix it with Cypher — a `.begin` …
@@ -173,7 +188,7 @@ hand off or commit a graph that fails validation, and never edit `graph.json` di
173
188
  Then confirm run-readiness:
174
189
 
175
190
  ```
176
- cypherlite .gbuild/<slug>/db --mode jsonl < ${CLAUDE_PLUGIN_ROOT}/cypher/progress.cypher
191
+ cypherlite DB --mode jsonl < ${CLAUDE_PLUGIN_ROOT}/cypher/progress.cypher
177
192
  ```
178
193
 
179
194
  One row per wave: each row's `open` slugs are the decomposition, and the `frontier` counts are what
@@ -181,18 +196,21 @@ One row per wave: each row's `open` slugs are the decomposition, and the `fronti
181
196
 
182
197
  ### 10. Commit and stop
183
198
 
184
- Commit `.gbuild/<slug>/` unless the repo ignores it (`git check-ignore -q .gbuild/`; if true, don't stage
185
- anything under it). The store's own `.gitignore` limits that to `db/graph.json` and `db/.gitignore`.
186
- Message: `<slug>: chart graph`.
199
+ Commit `.gbuild/<slug>/` on the feature branch unless the repo ignores it (`git -C FT check-ignore -q
200
+ .gbuild/`; if true, don't stage anything under it). The store's own `.gitignore` limits that to
201
+ `db/graph.json` and `db/.gitignore`. Stage and commit from the feature worktree:
202
+ `git -C FT add .gbuild/<slug>` and `git -C FT commit -m "<slug>: chart graph"`.
187
203
 
188
- Report the branch, the waves, and the frontier. Close with `next: /gbuild:run <slug>`.
204
+ Report the branch, `FT`, the waves, and the frontier. Close with `next: /gbuild:run <slug>`.
189
205
 
190
206
  ## Reopen
191
207
 
192
208
  `--add "<requirement>"`:
193
209
 
194
- 0. Check out the feature's existing branch if you're not on it. Never chart a reopen onto a different
195
- branch than the one the graph was charted on.
210
+ 0. Resolve `FT` and `DB` exactly as Chart's step 1 describes (reuse the existing feature worktree;
211
+ attach it if the branch is checked out nowhere). Never chart a reopen onto a different branch than
212
+ the one the graph was charted on, and never into the user's main checkout unless that's where the
213
+ feature branch already lives (a legacy feature).
196
214
  1. Read the current graph narrowly: `progress.cypher` for its shape and what's done, and `node.cypher`
197
215
  only for the nodes the requirement touches.
198
216
  2. Design the delta: a new `Acceptance` node (next `a-` id) linked from the `Feature`, and whatever new
@@ -202,7 +220,7 @@ Report the branch, the waves, and the frontier. Close with `next: /gbuild:run <s
202
220
  3. Write it as one script that `MATCH`es what it connects to and `CREATE`s the rest:
203
221
 
204
222
  ```
205
- cypherlite .gbuild/<slug>/db <<'CYPHER'
223
+ cypherlite DB <<'CYPHER'
206
224
  .begin
207
225
  MATCH (f:Feature), (up:GbuildNode {slug: '<existing-slug>'})-[:OUTPUT]->(up_out:Field {name: '<field>'})
208
226
  CREATE (f)-[:HAS_ACCEPTANCE]->(a:Acceptance {id: 'a-3', text: '...'})
@@ -216,8 +234,9 @@ Report the branch, the waves, and the frontier. Close with `next: /gbuild:run <s
216
234
  CYPHER
217
235
  ```
218
236
 
219
- 4. **Re-run `validate.cypher`** until it prints nothing, then `progress.cypher`. Commit
220
- (`<slug>: reopen graph — <what was added>`), report the new frontier.
237
+ 4. **Re-run `validate.cypher`** until it prints nothing, then `progress.cypher`. Commit in `FT`
238
+ (`git -C FT commit -m "<slug>: reopen graph — <what was added>"` after staging `.gbuild/<slug>`,
239
+ same ignore rule as Chart's step 10), report the new frontier.
221
240
 
222
241
  If the requirement needs no new nodes (an existing node's contract already covers it), say so and stop
223
242
  — don't manufacture graph churn.
@@ -1,5 +1,5 @@
1
1
  ---
2
- description: Pushes the current gbuild feature branch to the appropriate remote, opens a pull request with a concise description that classifies the change (new feature, fix, optimization, etc.) and notes any user-facing impact, then monitors CI checks in the background and auto-triggers a graph reopen + run if any fail. Use after /gbuild:review reports nothing blocking, to publish the finished feature branch.
2
+ description: Pushes the gbuild feature branch to the appropriate remote, opens a pull request with a concise description that classifies the change (new feature, fix, optimization, etc.) and notes any user-facing impact, then monitors CI checks in the background and auto-triggers a graph reopen + run if any fail. Works from the feature's own worktree, never touching the main checkout's branch. Use after /gbuild:review reports nothing blocking, to publish the finished feature branch.
3
3
  ---
4
4
 
5
5
  Publish a finished feature branch: push it to the right remote, open a well-formed pull request, then watch the PR's CI checks and drive a graph reopen automatically when a check goes red — looping until the checks are green or a round cap is hit.
@@ -12,9 +12,9 @@ This skill MUST run in the **main conversation context**. It MUST NOT be invoked
12
12
 
13
13
  `$ARGUMENTS` is free-form text: an optional feature slug and an optional `--max-rounds N` flag.
14
14
 
15
- - **slug**: the first token that isn't a flag. If absent, infer it — the current branch commonly ends in the slug (`plan` checks out `<prefix>/<slug>`), otherwise fall back to the store whose `.gbuild/*/db/graph.json` was most recently modified. If neither resolves, leave `<slug>` unresolved (the auto-fix step degrades gracefully — see Step 4).
15
+ - **slug**: the first token that isn't a flag. If absent, infer it — if exactly one feature worktree exists (`<git-common-dir>/gbuild/*/tree`), that's the slug; otherwise fall back to the most recently modified `graph.json` under `<git-common-dir>/gbuild/*/tree/.gbuild/*/db` (or, for features charted before the worktree layout, `.gbuild/*/db/graph.json` in the main tree). If neither resolves, leave `<slug>` unresolved (the auto-fix step degrades gracefully — see Step 4).
16
16
 
17
- When `<slug>` resolved, every graph read below goes through `cypherlite`: run `cypherlite --version` first (missing → stop; gbuild needs it), one command at a time, always `--mode jsonl` (no output = no rows), and on `storage locked` wait and retry up to 3 times. Anything else: `${CLAUDE_PLUGIN_ROOT}/reference/cypher.md`.
17
+ When `<slug>` resolved, every graph read below goes through `cypherlite`: run `cypherlite --version` first (missing → stop; gbuild needs it), one command at a time, always `--mode jsonl` (no output = no rows), and on `storage locked` wait and retry up to 3 times. Anything else: `${CLAUDE_PLUGIN_ROOT}/reference/cypher.md`. `DB` below is `FT/.gbuild/<slug>/db` (see Step 1 for `FT`).
18
18
  - **max_rounds**: the value of `--max-rounds N` (also accept `--max-rounds=N`). Default `3` when absent.
19
19
 
20
20
  ## Step 1: Preconditions
@@ -24,10 +24,10 @@ Verify the environment before touching the remote. Stop with a clear, actionable
24
24
  1. **Git repo.** This skill is git + GitHub specific. If the repo is not git, stop and explain that `/gbuild:pr` only supports git + GitHub (`gh`).
25
25
  2. **GitHub CLI.** Confirm `gh` is installed and authenticated (`gh auth status`). If not, stop and tell the user to install/authenticate `gh`.
26
26
  3. **Base branch.** Determine the upstream default branch: `gh repo view --json defaultBranchRef -q .defaultBranchRef.name`. Call it `<base>`.
27
- 4. **Not on base.** Get the current branch (`git branch --show-current`). If it equals `<base>`, stop — there is nothing to open a PR for.
28
- 5. **Clean tree.** Check for uncommitted changes (`git status --porcelain`). `/gbuild:run` commits each node's work as it goes, so the tree should be clean. If there are uncommitted changes, warn the user and ask whether to proceed (they may want to commit first).
29
- 6. **Commits ahead of base.** Confirm the branch has commits the base lacks (`git log <base>..HEAD --oneline`). If empty, stop — nothing to push.
30
- 7. **Graph finished.** When `<slug>` resolved, run `cypherlite .gbuild/<slug>/db --mode jsonl < ${CLAUDE_PLUGIN_ROOT}/cypher/progress.cypher`. If any row's `open` is non-empty, warn that the graph isn't finished (name the open nodes) and ask whether to open the PR anyway. If any row has `failed` > 0, get their names from `attention.cypher` and name them — a PR built on an escalated node is usually premature.
27
+ 4. **Feature worktree and branch.** Resolve `FT` (the feature worktree) and `<branch>` (the feature branch checked out there) exactly as `/gbuild:run`'s step 0 describes — the registered worktree at `<git-common-dir>/gbuild/<slug>/tree`, a legacy feature whose branch is in the main tree, or attach a branch that is checked out nowhere. When `<slug>` is unresolved, use the main tree's current branch as `<branch>` and its root as `FT`. If `<branch>` equals `<base>`, stop — there is nothing to open a PR for.
28
+ 5. **Clean tree.** Check for uncommitted changes in the feature worktree (`git -C FT status --porcelain`). `/gbuild:run` commits each node's work as it goes, so it should be clean. If there are uncommitted changes, warn the user and ask whether to proceed (they may want to commit first).
29
+ 6. **Commits ahead of base.** Confirm the branch has commits the base lacks (`git log <base>..<branch> --oneline`). If empty, stop — nothing to push.
30
+ 7. **Graph finished.** When `<slug>` resolved, run `cypherlite DB --mode jsonl < ${CLAUDE_PLUGIN_ROOT}/cypher/progress.cypher`. If any row's `open` is non-empty, warn that the graph isn't finished (name the open nodes) and ask whether to open the PR anyway. If any row has `failed` > 0, get their names from `attention.cypher` and name them — a PR built on an escalated node is usually premature.
31
31
 
32
32
  ## Step 2: Determine the remote & push
33
33
 
@@ -37,7 +37,8 @@ Choose the push remote from the project's actual remotes:
37
37
  2. **Exactly one remote** → use it.
38
38
  3. **Multiple remotes** → look for a push-target hint in `AGENTS.md` or `CLAUDE.md` (e.g. an explicit statement that the project pushes to a fork). If a clear hint exists, use it. Otherwise, use `AskUserQuestion` to let the user pick which remote to push to (e.g. `origin` vs a fork remote).
39
39
 
40
- Push the current branch and set upstream: `git push -u <remote> <branch>`.
40
+ Push the feature branch and set upstream: `git push -u <remote> <branch>` (branch names are refs — the
41
+ main tree's checkout is irrelevant).
41
42
 
42
43
  ## Step 3: Open the pull request
43
44
 
@@ -45,9 +46,9 @@ Build a **short, well-formed** description, then open the PR.
45
46
 
46
47
  Gather context from:
47
48
 
48
- - Commit subjects: `git log <base>..HEAD --oneline`.
49
- - File overview: `git diff <base>...HEAD --stat`.
50
- - When `<slug>` resolved: `cypherlite .gbuild/<slug>/db --mode jsonl < ${CLAUDE_PLUGIN_ROOT}/cypher/feature.cypher` — the `destination` and the acceptance bar (with the nodes covering each criterion).
49
+ - Commit subjects: `git log <base>..<branch> --oneline`.
50
+ - File overview: `git diff <base>...<branch> --stat`.
51
+ - When `<slug>` resolved: `cypherlite DB --mode jsonl < ${CLAUDE_PLUGIN_ROOT}/cypher/feature.cypher` — the `destination` and the acceptance bar (with the nodes covering each criterion).
51
52
 
52
53
  Derive a concise, conventional-commit-style title from the feature/branch and the changes (e.g. `feat(auth): add OAuth login`).
53
54
 
@@ -72,13 +73,13 @@ This description was auto generated
72
73
 
73
74
  The trailing `This description was auto generated` line is **mandatory** — it always ends the body, after every other section, and is never dropped or reworded.
74
75
 
75
- Create the PR: `gh pr create --base <base> --title "<title>" --body "<body>"`. Let `gh` resolve the head branch (it handles fork `owner:branch` head refs automatically). Capture the PR URL and number (`<pr>`).
76
+ Create the PR: `gh pr create --base <base> --title "<title>" --body "<body>"` — run it with `FT` as the working directory, so `gh` resolves the head from the feature branch (it handles fork `owner:branch` head refs automatically). Capture the PR URL and number (`<pr>`).
76
77
 
77
78
  ## Step 4: Monitor checks in the background → auto-fix loop
78
79
 
79
80
  Watch the PR's CI checks and react when they fail. Run for at most `max_rounds` rounds:
80
81
 
81
- 1. **Launch the watch in the background.** Run `gh pr checks <pr> --watch --fail-fast` via the Bash tool with `run_in_background: true`. It exits `0` when all checks pass and non-zero when a check fails; the harness re-invokes this skill when the command exits, so continue from the result.
82
+ 1. **Launch the watch in the background.** Run `gh pr checks <pr> --watch --fail-fast` (from `FT`) via the Bash tool with `run_in_background: true`. It exits `0` when all checks pass and non-zero when a check fails; the harness re-invokes this skill when the command exits, so continue from the result.
82
83
  2. **Checks green (exit 0):** report success and go to Step 5.
83
84
  3. **Checks red (non-zero exit):**
84
85
  - Collect the failure detail: `gh pr checks <pr>` for the failed-check list, and `gh run view <run-id> --log-failed` for the failing logs.
@@ -88,7 +89,7 @@ Watch the PR's CI checks and react when they fail. Run for at most `max_rounds`
88
89
  2. Run it unattended. `plan`'s Reopen asks nothing, but if executing it would prompt the user (an ambiguous decomposition), resolve it yourself from the failing logs and note the choice in the final report — `/gbuild:pr` runs without a human present.
89
90
  3. If Reopen concludes the requirement needs no new nodes, stop the loop and go to Step 5 with an `unresolved` status — the failure isn't something the graph can act on, so surface the logs to the user.
90
91
  4. Read `${CLAUDE_PLUGIN_ROOT}/skills/run/SKILL.md` and execute it inline against `<slug>` to run the newly-unblocked frontier. Suppress its trailing `next: /gbuild:status…` line — this skill owns the transition.
91
- - After the run completes, push the new commits (`git push`) and **re-launch the watch** (next round).
92
+ - After the run completes, push the new commits (`git -C FT push`) and **re-launch the watch** (next round).
92
93
 
93
94
  4. **Round cap reached while still red:** stop, print the still-failing checks and their logs, and tell the user to inspect manually. Go to Step 5 with an `unresolved` status.
94
95
 
@@ -100,3 +101,6 @@ Report the outcome:
100
101
  PR: <url> (checks: green | fixed after <rounds> round(s) | unresolved after <max_rounds> round(s))
101
102
  next: /gbuild:status <slug>
102
103
  ```
104
+
105
+ The feature worktree `FT` keeps the branch checked out until removed — once the PR is merged and the
106
+ graph is no longer needed, `git worktree remove FT` (and `git branch -d <branch>`) cleans up.
@@ -1,5 +1,5 @@
1
1
  ---
2
- description: Performs a strict end-of-feature maintainability audit of the current gbuild branch — abstraction quality, file size, spaghetti growth, cross-node duplication, missed code-judo simplifications. Runs the audit in the gbuild-auditor sub-agent and relays its result to chat. Use after /gbuild:run finishes a graph, before /gbuild:pr.
2
+ description: Performs a strict end-of-feature maintainability audit of a gbuild feature branch — abstraction quality, file size, spaghetti growth, cross-node duplication, missed code-judo simplifications. Runs the audit in the gbuild-auditor sub-agent, in the feature's worktree, and relays its result to chat. Use after /gbuild:run finishes a graph, before /gbuild:pr.
3
3
  ---
4
4
 
5
5
  Run the strict end-of-feature maintainability audit in a dedicated sub-agent, then relay its result.
@@ -10,10 +10,14 @@ missed abstractions that only exist *between* nodes, which no per-node review ca
10
10
 
11
11
  ## Arguments
12
12
 
13
- `$ARGUMENTS` is optional. If present, treat it as the feature slug. If absent, infer it — the current
14
- branch commonly ends in the slug (`plan` checks out `<prefix>/<slug>`), otherwise fall back to the store
15
- whose `.gbuild/*/db/graph.json` was most recently modified. Do NOT write any file — this skill outputs to
16
- chat exclusively.
13
+ `$ARGUMENTS` is optional. If present, treat it as the feature slug. If absent, infer it — if exactly one
14
+ feature worktree exists (`<git-common-dir>/gbuild/*/tree`), that's the slug; otherwise fall back to the
15
+ most recently modified `graph.json` under `<git-common-dir>/gbuild/*/tree/.gbuild/*/db` (or, for
16
+ features charted before the worktree layout, `.gbuild/*/db/graph.json` in the main tree). Do NOT write
17
+ any file — this skill outputs to chat exclusively.
18
+
19
+ Resolve `FT`, the feature worktree, exactly as `/gbuild:run`'s step 0 describes (reuse the registered
20
+ worktree, attach if the feature branch is checked out nowhere). `DB` below is `FT/.gbuild/<slug>/db`.
17
21
 
18
22
  Store rules: run `cypherlite --version` first (missing → stop; gbuild needs it). One `cypherlite`
19
23
  command at a time, always `--mode jsonl` (no output = no rows); on `storage locked` wait and retry up to
@@ -22,7 +26,7 @@ command at a time, always `--mode jsonl` (no output = no rows); on `storage lock
22
26
  Check the graph is finished — one row per wave, cheap:
23
27
 
24
28
  ```
25
- cypherlite .gbuild/<slug>/db --mode jsonl < ${CLAUDE_PLUGIN_ROOT}/cypher/progress.cypher
29
+ cypherlite DB --mode jsonl < ${CLAUDE_PLUGIN_ROOT}/cypher/progress.cypher
26
30
  ```
27
31
 
28
32
  If any row's `open` is non-empty, say the graph isn't finished (name the open nodes) and ask whether to
@@ -34,7 +38,7 @@ address.
34
38
  Fetch the feature context:
35
39
 
36
40
  ```
37
- cypherlite .gbuild/<slug>/db --mode jsonl < ${CLAUDE_PLUGIN_ROOT}/cypher/feature.cypher
41
+ cypherlite DB --mode jsonl < ${CLAUDE_PLUGIN_ROOT}/cypher/feature.cypher
38
42
  ```
39
43
 
40
44
  Launch the `gbuild-auditor` subagent (agents/gbuild-auditor.md — this plugin's own copy, gbuild does not
@@ -43,7 +47,8 @@ depend on hone-ai being installed). Pass it:
43
47
  - The resolved slug and the `feature.cypher` result verbatim (destination and the acceptance bar with
44
48
  the nodes covering each criterion) — the auditor never opens the store itself, and reads the code from
45
49
  the branch diff.
46
- - Tell it to audit the current branch.
50
+ - The feature worktree path `FT` and the feature branch name — it audits the branch's code from `FT`:
51
+ every read, every check, and every git command runs there, never in the main tree.
47
52
 
48
53
  The sub-agent runs the full audit in its own fresh context and returns the audit as its final message.
49
54
  That message is a tool result — it is NOT shown to the user. So once it returns:
@@ -2,7 +2,8 @@
2
2
  description: Executes a gbuild graph — dispatches every ready-and-independent node in the current wave concurrently, each file-touching node in its own git worktree, reviews each node's output with gbuild-reviewer before merging its branch and recording it complete, and resumes only the remaining frontier on re-invocation. Use after /gbuild:plan has charted the graph.
3
3
  ---
4
4
 
5
- Run the graph in `.gbuild/$ARGUMENTS/db` (the feature slug is `$ARGUMENTS`; `DB` below).
5
+ Run the graph for the feature `$ARGUMENTS` (the slug; step 0 resolves `DB`, the store — it lives in
6
+ the feature's own worktree, so this skill never changes the branch of the user's checkout).
6
7
 
7
8
  **CRITICAL: this skill must run in the main context, not inside a forked agent.** It dispatches its own
8
9
  subagents per node; a subagent cannot itself fan out further subagents reliably. It is also the store's
@@ -20,7 +21,25 @@ back in their final message, and this skill records it.
20
21
  Exit code 1 = failure; read stderr. Anything beyond the scripts below: `${CLAUDE_PLUGIN_ROOT}/reference/cypher.md`.
21
22
  - Never re-read what you already hold. The claimed wave's definitions stay valid for its retries.
22
23
 
23
- ## Step 0: Check and recover
24
+ ## Step 0: Establish VCS facts, then check and recover
25
+
26
+ Default to `git`. Resolve these facts first, absolute paths, and reuse them throughout:
27
+
28
+ - `GC` = `git rev-parse --git-common-dir`, resolved to an absolute path; `WT` = `GC/gbuild/$ARGUMENTS`
29
+ (the worktree root — inside `.git/`, so worktrees never appear in `git status` or get committed).
30
+ - `FT` = the feature worktree and `BRANCH` = the feature branch — the one place `BRANCH` is checked
31
+ out, and where every merge and store commit below lands:
32
+ 1. `WT/tree` is a registered worktree (`git worktree list --porcelain`) → `FT` = it, `BRANCH` =
33
+ `git -C FT branch --show-current`.
34
+ 2. Else a worktree whose branch is `$ARGUMENTS` or ends `/$ARGUMENTS` → `FT` = that worktree's path
35
+ (a feature charted before the worktree layout usually has its branch in the main tree).
36
+ 3. Else such a branch exists but is checked out nowhere → attach it: `git worktree add WT/tree
37
+ <branch>`, `FT` = `WT/tree`.
38
+ 4. Else → stop: there is no feature branch for `$ARGUMENTS` — chart it with `/gbuild:plan` first.
39
+ - `DB` = `FT/.gbuild/$ARGUMENTS/db`. `git -C FT check-ignore -q .gbuild/` tells you whether to commit
40
+ the store at all.
41
+
42
+ Then check and recover:
24
43
 
25
44
  ```
26
45
  cypherlite DB --mode jsonl < ${CLAUDE_PLUGIN_ROOT}/cypher/validate.cypher
@@ -31,7 +50,7 @@ cypherlite DB --mode jsonl < ${CLAUDE_PLUGIN_ROOT}/cypher/attention.cypher
31
50
  correctly.
32
51
  - `attention` rows with reason `in_progress` are left over from an interrupted run (this skill is the
33
52
  only writer and records every node before finishing). Check each one's worktree branch for commits
34
- its agent already made (`git log $(git branch --show-current)..gbuild/<feature>/<slug>` — empty
53
+ its agent already made (`git log BRANCH..gbuild/<feature>/<slug>` — empty
35
54
  means it never got that far) and leave the worktree in place: the re-dispatch reuses it. Then reset
36
55
  them all in one call so they re-dispatch, and mention it in the report:
37
56
 
@@ -40,19 +59,13 @@ cypherlite DB --mode jsonl < ${CLAUDE_PLUGIN_ROOT}/cypher/attention.cypher
40
59
  < ${CLAUDE_PLUGIN_ROOT}/cypher/set-status.cypher
41
60
  ```
42
61
 
43
- - Sweep the worktree root (step 1's `WT`) for leaks from an interruption that struck mid-cleanup: any
44
- worktree whose slug is *not* among the slugs just reset does not belong to live work — remove it
62
+ - Sweep the worktree root `WT` for leaks from an interruption that struck mid-cleanup: any worktree
63
+ under `WT` — **except `FT` itself (`WT/tree`)** — whose slug is *not* among the slugs just reset does
64
+ not belong to live work — remove it
45
65
  (`git worktree remove --force`) and delete its branch (`git branch -D`). An unmerged branch is
46
66
  unaccepted work, which must never land — that is what the isolation is for.
47
67
 
48
- ## Step 1: Establish VCS facts
49
-
50
- Default to `git`. `git check-ignore -q .gbuild/` tells you whether to commit the store at all. Record
51
- two facts for the wave mechanics below: `BRANCH` = `git branch --show-current` (the feature branch —
52
- every accepted node merges back into it), and `WT` = `$(git rev-parse --git-common-dir)/gbuild/$ARGUMENTS`
53
- (the worktree root — inside `.git/`, so worktrees never appear in `git status` or get committed).
54
-
55
- ## Step 2: Pick a backend
68
+ ## Step 1: Pick a backend
56
69
 
57
70
  **Workflow tool**, if this session has opted into multi-agent orchestration (ultracode, or the user
58
71
  asked for a workflow explicitly) — translate each claimed wave into a `pipeline()`/`parallel()` script:
@@ -62,14 +75,14 @@ file-touching (`code`/`test`/`chore`) node gets `isolation: 'worktree'`.
62
75
  Controlled-cycle clusters become a bounded `while` loop per `${CLAUDE_PLUGIN_ROOT}/reference/shapes.md`'s
63
76
  round cap. Route `model_tier: strong` nodes via `opts.model` where the harness supports an override. The
64
77
  script never touches the store: collect the results, land each accepted node's branch from the main
65
- context (step 3.4), then record (step 3.5).
78
+ context (step 2.4), then record (step 2.5).
66
79
 
67
- **Fallback** (default — no opt-in required, and always what step 3 below assumes): fire one `Agent`
80
+ **Fallback** (default — no opt-in required, and always what step 2 below assumes): fire one `Agent`
68
81
  tool call per claimed node, **all in a single message** — this is what makes the fan-out real rather
69
82
  than claimed. Do not dispatch them one at a time across separate messages; that's exactly the serial
70
83
  behavior this plugin replaces.
71
84
 
72
- ## Step 3: One wave
85
+ ## Step 2: One wave
73
86
 
74
87
  1. **CLAIM.**
75
88
 
@@ -80,7 +93,7 @@ behavior this plugin replaces.
80
93
  It moves the whole frontier to `in_progress` and prints one row per claimed node with everything its
81
94
  agent needs: `slug`, `title`, `type`, `acceptance`, `failure_policy`, `model_tier`, `verify`,
82
95
  `inputs` (an input with a `value` came from an upstream node; one without is external — its `shape`
83
- says where to find it), and `outputs`. **No rows** → nothing is ready: go to step 5.
96
+ says where to find it), and `outputs`. **No rows** → nothing is ready: go to step 4.
84
97
 
85
98
  2. **IMPLEMENT.** First, give every claimed `code`/`test`/`chore` node its own worktree — one shell
86
99
  loop over the wave's slugs, idempotent so an interrupted or re-dispatched node keeps its earlier
@@ -93,7 +106,8 @@ behavior this plugin replaces.
93
106
  || git worktree add WT/<slug> gbuild/<feature>/<slug>
94
107
  ```
95
108
 
96
- (skip if the worktree already exists; else fork a fresh branch off `BRANCH`; if the branch already
109
+ (skip if the worktree already exists; else fork a fresh branch off `BRANCH` — just a ref here, the
110
+ cwd doesn't matter; if the branch already
97
111
  exists from an earlier attempt, attach to it instead — nothing is redone). Then, in one message,
98
112
  spawn one `Agent` per claimed node with its row. Tell it to:
99
113
  - actually do the work — for `code`/`test`/`chore` nodes make the change **in its worktree**
@@ -118,19 +132,20 @@ behavior this plugin replaces.
118
132
  point). Never let the implementing agent review its own work.
119
133
 
120
134
  4. **LAND.** For each `pass` verdict on a `code`/`test`/`chore` node, merge its branch into the
121
- feature branch and clean up, from the main tree:
135
+ feature branch — in the feature worktree `FT`, never the user's checkout — and clean up:
122
136
 
123
137
  ```
124
- git merge --no-ff gbuild/<feature>/<slug> \
138
+ git -C FT merge --no-ff gbuild/<feature>/<slug> \
125
139
  && git worktree remove --force WT/<slug> \
126
140
  && git branch -d gbuild/<feature>/<slug>
127
141
  ```
128
142
 
129
- A merge conflict means two supposedly independent nodes touched the same lines: `git merge --abort`
130
- and treat the node as review-failed, the conflict as its failed criterion — step 6's policy decides
143
+ A merge conflict means two supposedly independent nodes touched the same lines: `git -C FT merge
144
+ --abort`
145
+ and treat the node as review-failed, the conflict as its failed criterion — step 5's policy decides
131
146
  (a retry/repair re-dispatch tells the agent to rebase its branch onto `BRANCH` and resolve it).
132
147
  Worktrees and branches are deleted only here, after acceptance — a failed node's stays for its next
133
- attempt (step 6).
148
+ attempt (step 5).
134
149
 
135
150
  5. **RECORD** the whole wave in one call — one result per node, `verdict` from the reviewer's
136
151
  `VERDICT:` line, `failed_criteria` from its `[fail]` lines:
@@ -165,16 +180,17 @@ behavior this plugin replaces.
165
180
  `set-status.cypher` before the next claim.
166
181
 
167
182
  Nodes in the same wave never read each other's outputs, and every file-touching node works in its own
168
- worktree, so true concurrent dispatch is safe by construction — the store calls and the merges onto
169
- `BRANCH` are the only serialized points.
183
+ worktree, so true concurrent dispatch is safe by construction — the store calls and the merges in `FT`
184
+ are the only serialized points, and since `FT` belongs to this feature alone, other features (or the
185
+ user) changing branches in their own checkouts cannot race them.
170
186
 
171
- ## Step 4: Next wave
187
+ ## Step 3: Next wave
172
188
 
173
- If `.gbuild/` isn't ignored, commit the store: `git add .gbuild/<feature>/db` and
174
- `git commit -m "<feature>: record wave <n>"`. Then claim again (step 3). Keep going until a claim
175
- returns no rows.
189
+ If `.gbuild/` isn't ignored, commit the store in the feature worktree: `git -C FT add
190
+ .gbuild/<feature>/db` and `git -C FT commit -m "<feature>: record wave <n>"`. Then claim again (step 2).
191
+ Keep going until a claim returns no rows.
176
192
 
177
- ## Step 5: Report and stop
193
+ ## Step 4: Report and stop
178
194
 
179
195
  ```
180
196
  cypherlite DB --mode jsonl < ${CLAUDE_PLUGIN_ROOT}/cypher/progress.cypher
@@ -194,7 +210,7 @@ Report: which nodes ran this invocation, which passed review outright vs. needed
194
210
 
195
211
  ## Resuming
196
212
 
197
- Re-invoking `/gbuild:run <feature>` after an interruption re-runs step 0 fresh: nodes an interrupted
198
- wave left `in_progress` are reset (their worktrees and any commits on their branches survive — the
199
- re-dispatch reuses them), and the next claim picks up exactly the remaining frontier. Nothing needs to
200
- be told what already finished — the store is the memory.
213
+ Re-invoking `/gbuild:run <feature>` after an interruption re-runs step 0 fresh: the feature worktree is
214
+ resolved or re-attached, nodes an interrupted wave left `in_progress` are reset (their worktrees and any
215
+ commits on their branches survive — the re-dispatch reuses them), and the next claim picks up exactly
216
+ the remaining frontier. Nothing needs to be told what already finished — the store is the memory.
@@ -2,7 +2,11 @@
2
2
  description: Reports a gbuild feature's graph — frontier, blocked, in-flight, completed, each node's review verdict, and the cluster shapes with evidence of what actually ran concurrently. Use to check progress or diagnose a stuck run.
3
3
  ---
4
4
 
5
- Report status for `$ARGUMENTS`. This skill only reads the store; `DB` below is `.gbuild/<feature>/db`.
5
+ Report status for `$ARGUMENTS`. This skill only reads the store. `DB` below is the feature's store:
6
+ `FT/.gbuild/<feature>/db`, where `FT` is the feature worktree at `<git-common-dir>/gbuild/<feature>/tree`
7
+ (a feature charted before the worktree layout keeps its store at `.gbuild/<feature>/db` in the main
8
+ tree). Status never creates or attaches worktrees — if neither store exists, say the feature's worktree
9
+ is gone and that `git worktree add <git-common-dir>/gbuild/<feature>/tree <branch>` reattaches it.
6
10
 
7
11
  ## Store rules
8
12
 
@@ -17,7 +21,7 @@ Report status for `$ARGUMENTS`. This skill only reads the store; `DB` below is `
17
21
 
18
22
  | arguments | mode |
19
23
  | ------------------ | -------------------------------------- |
20
- | empty | every feature under `.gbuild/` |
24
+ | empty | every feature store |
21
25
  | a feature slug | that feature only |
22
26
 
23
27
  ## Single feature
@@ -76,10 +80,11 @@ don't let silence be ambiguous between "checked, clear" and "not checked."
76
80
 
77
81
  ## All-features mode
78
82
 
79
- Don't read every node of every feature. For each `.gbuild/<slug>/db` found, one store at a time:
83
+ Don't read every node of every feature. For each store found — `<git-common-dir>/gbuild/*/tree/.gbuild/*/db`,
84
+ plus any legacy `.gbuild/*/db` in the main tree — one store at a time:
80
85
 
81
86
  ```
82
- cypherlite .gbuild/<slug>/db --mode jsonl < ${CLAUDE_PLUGIN_ROOT}/cypher/progress.cypher
87
+ cypherlite DB --mode jsonl < ${CLAUDE_PLUGIN_ROOT}/cypher/progress.cypher
83
88
  ```
84
89
 
85
90
  Print one line per feature: slug, node counts by state summed over its waves, and whether it's done