opencode-gbuild 0.8.0 → 0.9.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 +66 -27
- package/agents/gbuild-implementer.md +186 -0
- package/agents/gbuild-reviewer.md +113 -53
- package/cypher/brief.cypher +39 -0
- package/cypher/check-result.cypher +19 -0
- package/cypher/dispatch.cypher +8 -25
- package/cypher/node.cypher +4 -3
- package/cypher/record.cypher +81 -28
- package/cypher/schema.cypher +19 -0
- package/cypher/status.cypher +9 -4
- package/cypher/symbols.cypher +9 -0
- package/cypher/validate.cypher +20 -5
- package/index.ts +19 -11
- package/package.json +1 -1
- package/reference/cypher.md +29 -19
- package/reference/graph-format.md +54 -14
- package/reference/queries.md +4 -0
- package/skills/plan/SKILL.md +3 -3
- package/skills/run/SKILL.md +145 -108
- package/skills/status/SKILL.md +16 -8
package/skills/run/SKILL.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: Executes a gbuild graph
|
|
2
|
+
description: Executes a gbuild graph as dataflow — each node starts the moment its own dependencies complete and runs its own implement → review → land → record pipeline in background subagents (each file-touching node in its own git worktree), handing agents only slugs and paths, recording a node complete only after gbuild-reviewer passes it, and resuming only the remaining frontier on re-invocation. Use after /gbuild:plan has charted the graph.
|
|
3
3
|
---
|
|
4
4
|
|
|
5
5
|
Run the graph for the feature `$ARGUMENTS` (the slug; step 0 resolves `DB`, the store — the feature
|
|
@@ -7,21 +7,26 @@ branch lives in its own worktree, so this skill never changes the branch of the
|
|
|
7
7
|
|
|
8
8
|
**CRITICAL: this skill must run in the main context, not inside a forked agent.** It dispatches its own
|
|
9
9
|
subagents per node; a subagent cannot itself fan out further subagents reliably. It is also the store's
|
|
10
|
-
**only writer**:
|
|
11
|
-
|
|
10
|
+
**only writer**: agents read their brief from the store themselves and leave their result in the inbox;
|
|
11
|
+
this skill passes them slugs and paths, reads their one-line replies, and records.
|
|
12
12
|
|
|
13
13
|
## Store rules
|
|
14
14
|
|
|
15
15
|
- `cypherlite --version` first. If it's missing, stop: gbuild needs it
|
|
16
16
|
(`curl -sSfL https://neo4j-labs.github.io/cypherlite/install.sh | bash`).
|
|
17
|
-
-
|
|
17
|
+
- You are the only writer: `dispatch`, `set-status` and `record` run only here, one `cypherlite` command
|
|
18
|
+
at a time against `DB` — never parallel tool calls on it. Subagents may run `cypherlite` only with
|
|
19
|
+
`--read-only` (a read opens beside the writer); their agent files say what they read.
|
|
18
20
|
- Always `--mode jsonl`: one JSON object per row, no output = no rows. Every `--param` value is JSON,
|
|
19
|
-
single-quoted for the shell (`--param 'slugs=["a","b"]'`)
|
|
20
|
-
- Pure reads (validate, attention, progress below) open the store `--read-only`; the writes
|
|
21
|
-
set-status, record) stay writable — the CLI checkpoints a writable store on exit itself.
|
|
22
|
-
- `storage locked` → another
|
|
23
|
-
Exit code 1 = failure; read stderr. Anything beyond the scripts below:
|
|
24
|
-
|
|
21
|
+
single-quoted for the shell (`--param 'slugs=["a","b"]'`); write a `'` inside it as `\u0027`.
|
|
22
|
+
- Pure reads (validate, attention, progress below) open the store `--read-only`; the writes
|
|
23
|
+
(dispatch, set-status, record) stay writable — the CLI checkpoints a writable store on exit itself.
|
|
24
|
+
- `storage locked` (exit 5) → another writer holds the store: wait a few seconds, retry up to 3 times,
|
|
25
|
+
then stop. Exit code 1 = failure; read stderr. Anything beyond the scripts below:
|
|
26
|
+
`${CLAUDE_PLUGIN_ROOT}/reference/cypher.md`.
|
|
27
|
+
- Hold only what routes: dispatch rows, one reply line per agent, record rows. Never open a result file,
|
|
28
|
+
a review file or a diff, and never type acceptance text or output values — the store and the inbox
|
|
29
|
+
carry them.
|
|
25
30
|
|
|
26
31
|
## Step 0: Establish VCS facts, then check and recover
|
|
27
32
|
|
|
@@ -40,6 +45,8 @@ Default to `git`. Resolve these facts first, absolute paths, and reuse them thro
|
|
|
40
45
|
4. Else → stop: there is no feature branch for `$ARGUMENTS` — chart it with `/gbuild:plan` first.
|
|
41
46
|
- `DB` = `WT/db` — the feature's store, beside the worktree: machine-local, never committed (a gbuild ≤ 0.7.1
|
|
42
47
|
store needs the move in `${CLAUDE_PLUGIN_ROOT}/reference/cypher.md`).
|
|
48
|
+
- `INBOX` = `WT/inbox` — beside `DB`, outside every worktree: each implementer writes `<slug>.json`
|
|
49
|
+
there and each reviewer `<slug>.review.json`; only `record.cypher` reads them, on your behalf.
|
|
43
50
|
|
|
44
51
|
Then check and recover:
|
|
45
52
|
|
|
@@ -61,30 +68,40 @@ cypherlite query --read-only --database DB --mode jsonl < ${CLAUDE_PLUGIN_ROOT}/
|
|
|
61
68
|
< ${CLAUDE_PLUGIN_ROOT}/cypher/set-status.cypher
|
|
62
69
|
```
|
|
63
70
|
|
|
64
|
-
- Sweep the worktree root `WT` for leaks from an interruption that struck mid-cleanup: any
|
|
65
|
-
under `WT`
|
|
66
|
-
not
|
|
67
|
-
(`git worktree remove --force`) and delete its branch (`git branch -D`). An unmerged
|
|
68
|
-
unaccepted work, which must never land — that is what the isolation is for.
|
|
71
|
+
- Sweep the worktree root `WT` for leaks from an interruption that struck mid-cleanup: any registered
|
|
72
|
+
worktree under `WT` (`git worktree list --porcelain` — `db/` and `inbox/` are not worktrees) — **except
|
|
73
|
+
`FT` itself (`WT/tree`)** — whose slug is *not* among the slugs just reset does not belong to live
|
|
74
|
+
work — remove it (`git worktree remove --force`) and delete its branch (`git branch -D`). An unmerged
|
|
75
|
+
branch is unaccepted work, which must never land — that is what the isolation is for.
|
|
76
|
+
- Create the inbox empty. This discards the files of the nodes just reset — an interrupted attempt is
|
|
77
|
+
never recorded; they re-dispatch from scratch on top of their surviving worktrees:
|
|
78
|
+
|
|
79
|
+
```
|
|
80
|
+
mkdir -p WT/inbox
|
|
81
|
+
find WT/inbox -type f -delete
|
|
82
|
+
```
|
|
69
83
|
|
|
70
84
|
## Step 1: Pick a backend
|
|
71
85
|
|
|
72
86
|
**Workflow tool**, if this session has opted into multi-agent orchestration (ultracode, or the user
|
|
73
|
-
asked for a workflow explicitly) —
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
**Fallback** (default — no opt-in required, and always what step 2 below assumes):
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
87
|
+
asked for a workflow explicitly) — one `pipeline()` per claimed node: its implement `agent()`, then its
|
|
88
|
+
`gbuild-reviewer` `agent()`, prompted exactly as in step 2.2 and read as in step 2.3, so a review starts
|
|
89
|
+
the moment its implementer finishes and no node waits on another. Nodes use the worktrees step 2.2
|
|
90
|
+
creates (no `isolation` option: the prompt names the worktree). Controlled-cycle clusters become a
|
|
91
|
+
bounded `while` loop per `${CLAUDE_PLUGIN_ROOT}/reference/shapes.md`'s round cap. Route
|
|
92
|
+
`model_tier: strong` nodes via `opts.model` where the harness supports an override. The script never
|
|
93
|
+
touches the store: as each pipeline returns, land and record that node from the main context (steps
|
|
94
|
+
2.4–2.6), then claim again (step 3) and start pipelines for the new rows.
|
|
95
|
+
|
|
96
|
+
**Fallback** (default — no opt-in required, and always what step 2 below assumes): one background
|
|
97
|
+
subagent call per agent. When several nodes become ready at once, dispatch them all in a single
|
|
98
|
+
message — never one per message, which is exactly the serial behavior this plugin replaces.
|
|
99
|
+
|
|
100
|
+
## Step 2: One node's pipeline
|
|
101
|
+
|
|
102
|
+
Every claimed node runs this pipeline on its own — implement → review → land → record — and different
|
|
103
|
+
nodes are at different steps at the same time. Handle each completion the moment it arrives; never hold
|
|
104
|
+
a node back for another.
|
|
88
105
|
|
|
89
106
|
1. **CLAIM.**
|
|
90
107
|
|
|
@@ -92,103 +109,122 @@ behavior this plugin replaces.
|
|
|
92
109
|
cypherlite query --database DB --mode jsonl < ${CLAUDE_PLUGIN_ROOT}/cypher/dispatch.cypher
|
|
93
110
|
```
|
|
94
111
|
|
|
95
|
-
It moves
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
says where to find it), and `outputs`. **No rows** → nothing is ready: go to step 4.
|
|
112
|
+
It moves every pending node whose dependencies are all completed or cancelled to `in_progress` and
|
|
113
|
+
prints one routing row per claimed node: `slug`, `type`, `model_tier`, `failure_policy`. That is all
|
|
114
|
+
you need — agents read the rest themselves. **No rows** → nothing newly ready (step 3).
|
|
99
115
|
|
|
100
|
-
2. **IMPLEMENT.**
|
|
101
|
-
|
|
102
|
-
work (`research`/`decision` nodes touch no files and get no worktree):
|
|
116
|
+
2. **IMPLEMENT.** A `code`/`test`/`chore` node first gets its own worktree (`research`/`decision`/`verify`
|
|
117
|
+
nodes edit no files and get none) — idempotent, so a reset or re-dispatched node keeps its earlier work:
|
|
103
118
|
|
|
104
119
|
```
|
|
105
|
-
mkdir -p WT
|
|
106
120
|
git worktree list --porcelain | grep -q "^worktree .*/<slug>$" \
|
|
107
121
|
|| git worktree add WT/<slug> -b gbuild/<feature>/<slug> BRANCH 2>/dev/null \
|
|
108
122
|
|| git worktree add WT/<slug> gbuild/<feature>/<slug>
|
|
109
123
|
```
|
|
110
124
|
|
|
111
|
-
(
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
- actually do the work — for `code`/`test`/`chore` nodes make the change **in its worktree**
|
|
116
|
-
(`WT/<slug>`), never the main working tree: every edit, every check, and every git command runs
|
|
117
|
-
there, and it commits on the node branch, message `<feature>/<slug>: <what changed>`. A worktree
|
|
118
|
-
is a fresh checkout — if the project needs installed dependencies to build or test
|
|
119
|
-
(`node_modules`, `.venv`, …), install or symlink them in the worktree first;
|
|
120
|
-
- before finishing, run the checks relevant to its change — anything the node's `acceptance` names,
|
|
121
|
-
and for `code`/`test` nodes the tests covering the files it touched — and leave them green. The
|
|
122
|
-
per-node review will not re-run these; the full suite runs in the end-of-feature audit;
|
|
123
|
-
- produce a value for every output field: a scalar or a list of scalars, JSON-encoding anything
|
|
124
|
-
nested into a string;
|
|
125
|
-
- record its own UTC start and finish (`date -u +%Y-%m-%dT%H:%M:%SZ`) and end its final message with
|
|
126
|
-
`{"started_at": "...", "completed_at": "...", "outputs": {...}}`;
|
|
127
|
-
- **not** run `cypherlite` or touch the store.
|
|
128
|
-
|
|
129
|
-
3. **REVIEW.** Once IMPLEMENT returns, spawn a `gbuild-reviewer` per node, again all in one message
|
|
130
|
-
(`agents/gbuild-reviewer.md` — this plugin's own copy, gbuild does not depend on hone-ai being
|
|
131
|
-
installed). Give it the node's row, the agent's reported outputs, and where the diff is — for a
|
|
132
|
-
worktree'd node that is its branch, `git diff BRANCH...gbuild/<feature>/<slug>`, plus the worktree
|
|
133
|
-
path so it can run just the checks `acceptance` names there (the worktree still exists at this
|
|
134
|
-
point). Never let the implementing agent review its own work.
|
|
135
|
-
|
|
136
|
-
4. **LAND.** For each `pass` verdict on a `code`/`test`/`chore` node, merge its branch into the
|
|
137
|
-
feature branch — in the feature worktree `FT`, never the user's checkout — and clean up:
|
|
125
|
+
(reuse an existing worktree; else fork a fresh branch off `BRANCH`, or attach the branch an earlier
|
|
126
|
+
attempt left — nothing is redone). Then dispatch the implementer — `Agent` tool, `subagent_type`
|
|
127
|
+
`gbuild-implementer` / `gbuild-reviewer` (`gbuild:`-prefixed when namespaced), description
|
|
128
|
+
`implement <slug>` / `review <slug>`, `run_in_background: true` — with this one prompt for both agents:
|
|
138
129
|
|
|
139
130
|
```
|
|
140
|
-
|
|
141
|
-
&& git worktree remove --force WT/<slug> \
|
|
142
|
-
&& git branch -d gbuild/<feature>/<slug>
|
|
131
|
+
gbuild node `<slug>`. Store: <DB>. Worktree: <worktree>. Feature branch: <BRANCH>. Agent file: ${CLAUDE_PLUGIN_ROOT}/agents/gbuild-<implementer|reviewer>.md.
|
|
143
132
|
```
|
|
144
133
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
(
|
|
149
|
-
|
|
150
|
-
|
|
134
|
+
`<DB>`, `<BRANCH>` are `DB`, `BRANCH`; `<implementer|reviewer>` names the agent; `<worktree>` is
|
|
135
|
+
`WT/<slug>` for `code`/`test`/`chore` and `FT` (read-only) otherwise — every path absolute. The
|
|
136
|
+
implementer gets a model per its `model_tier` where the harness offers one
|
|
137
|
+
(`${CLAUDE_PLUGIN_ROOT}/reference/cost-model.md`).
|
|
138
|
+
Append nothing — no acceptance, inputs, outputs, notes, failed criteria or agent-file text. Retries,
|
|
139
|
+
repairs and fallbacks use the same prompt: the agent's brief carries the failed criteria.
|
|
140
|
+
|
|
141
|
+
3. **REVIEW.** The implementer replies with one line; read nothing else:
|
|
142
|
+
- `done <slug>` and `test -s INBOX/<slug>.json` → dispatch its reviewer right away with the same
|
|
143
|
+
prompt naming `gbuild-reviewer.md` — a fresh agent, never the implementer.
|
|
144
|
+
- `done <slug>` but no file → no review; record a fail: `["implementer reported done but <slug>.json is missing"]`.
|
|
145
|
+
- `failed <slug>: <reason>` → no review; record a fail: `["implementer failed: <reason>"]`.
|
|
146
|
+
|
|
147
|
+
The reviewer replies `VERDICT: pass`, or `VERDICT: fail` plus one `[fail] <criterion> — <reason>`
|
|
148
|
+
line per failed check. It is a pass only with a line exactly `VERDICT: pass` and no `[fail]` lines;
|
|
149
|
+
`failed_criteria` is the text after `[fail] ` on each line, verbatim and in order. No `VERDICT` line
|
|
150
|
+
→ re-dispatch that reviewer once in the foreground (no background flag); still none →
|
|
151
|
+
`["reviewer returned no verdict"]`. A `[fail] CONTRADICTS <upstream-slug>` line also hands that
|
|
152
|
+
upstream node to its own `failure_policy` (step 2.6). The verdict comes only from this reply — never
|
|
153
|
+
from `INBOX/<slug>.review.json`.
|
|
154
|
+
|
|
155
|
+
4. **LAND.** A `pass` on a `code`/`test`/`chore` node merges its branch into the feature worktree `FT`,
|
|
156
|
+
never the user's checkout — one merge at a time, never two in parallel:
|
|
151
157
|
|
|
152
|
-
|
|
153
|
-
|
|
158
|
+
```
|
|
159
|
+
git -C FT merge --no-ff gbuild/<feature>/<slug>
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
A conflict means two supposedly independent nodes touched the same lines: list them
|
|
163
|
+
(`git -C FT diff --name-only --diff-filter=U`), `git -C FT merge --abort`, and record a fail instead:
|
|
164
|
+
`["merge conflict with BRANCH in <path>[, <path>] — rebase gbuild/<feature>/<slug> onto BRANCH and resolve"]`.
|
|
165
|
+
|
|
166
|
+
5. **RECORD** — one call per node, as soon as its verdict is settled:
|
|
154
167
|
|
|
155
168
|
```
|
|
156
|
-
cypherlite query --database DB --mode jsonl
|
|
157
|
-
{"slug":
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
]' < ${CLAUDE_PLUGIN_ROOT}/cypher/record.cypher
|
|
169
|
+
cypherlite query --database DB --mode jsonl \
|
|
170
|
+
--param 'verdict={"slug":"<slug>","verdict":"pass","failed_criteria":[]}' \
|
|
171
|
+
--fetch-params result=INBOX/<slug>.json --fetch-params review=INBOX/<slug>.review.json \
|
|
172
|
+
< ${CLAUDE_PLUGIN_ROOT}/cypher/record.cypher
|
|
161
173
|
```
|
|
162
174
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
175
|
+
`verdict` is all you type: `pass`, or `fail` with `failed_criteria` — the reviewer's `[fail]` lines
|
|
176
|
+
or one of the fixed lines in steps 2.3–2.4, never your own words. Bind `result` from its file only on
|
|
177
|
+
a pass (`--param 'result={}'` on every fail), and `review` from its file whenever `test -s` finds it
|
|
178
|
+
(else `--param 'review={}'`) — all three are always bound. record.cypher takes the outputs, times,
|
|
179
|
+
notes and symbols from the file itself.
|
|
180
|
+
|
|
181
|
+
No row, or another slug → it wasn't recorded (the node wasn't `in_progress`) — find out why. Exit 1
|
|
182
|
+
or 6 → re-run once with `--param 'review={}'`; still failing → re-run with `--param 'result={}'
|
|
183
|
+
--param 'review={}'` and verdict `fail`,
|
|
184
|
+
`["result file rejected by record.cypher: <error.kind>: <error.message, first 120 chars>"]`, which
|
|
185
|
+
can't fail. Then `rm -f INBOX/<slug>.*` and:
|
|
186
|
+
- `completed: true` → for a worktree'd node `git worktree remove --force WT/<slug>` and
|
|
187
|
+
`git branch -d gbuild/<feature>/<slug>` — only now, so a pass downgraded after its merge repairs in
|
|
188
|
+
place. Non-empty `unselected` (a router's unchosen branches) → cancel them with
|
|
189
|
+
`set-status.cypher`. Then claim again (step 3).
|
|
190
|
+
- `completed: false` (a failed review, a merge conflict, a failed implementer, or a pass downgraded
|
|
191
|
+
because `missing_outputs` is non-empty) → step 2.6.
|
|
192
|
+
|
|
193
|
+
6. **FAILURES.** Apply the node's `failure_policy` (`${CLAUDE_PLUGIN_ROOT}/reference/failure-policies.md`),
|
|
194
|
+
using its `attempt` as the count:
|
|
195
|
+
- `retry` / `repair` → back to step 2.2 with the same prompt, reusing the node's existing worktree
|
|
196
|
+
and branch — the next attempt builds on them, it does not start over. Bounded: 2 attempts.
|
|
197
|
+
- `fallback` → remove the failed attempt's worktree and branch first (`git worktree remove --force`,
|
|
198
|
+
`git branch -D`), then step 2.2 — a fresh branch off `BRANCH`; the brief names the alternate
|
|
199
|
+
approach.
|
|
176
200
|
- `skip` → `cancelled`; `escalate` (or an exhausted retry/repair) → `failed`, its dependents stay
|
|
177
|
-
blocked while
|
|
178
|
-
`set-status.cypher
|
|
179
|
-
status gets cleaned up: `git worktree remove --force WT/<slug>` and
|
|
201
|
+
blocked while everything else keeps going; `stop` → `failed` and halt the run. Set it with
|
|
202
|
+
`set-status.cypher`, then clean up a worktree'd node: `git worktree remove --force WT/<slug>` and
|
|
180
203
|
`git branch -D gbuild/<feature>/<slug>` — its work was never accepted, so it never lands.
|
|
181
|
-
- A completed router (`decision` choosing a branch) → cancel the unselected branches with
|
|
182
|
-
`set-status.cypher` before the next claim.
|
|
183
204
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
205
|
+
Then claim again (step 3) — except after `stop`: claim nothing more, finish the pipelines in flight,
|
|
206
|
+
then step 4.
|
|
207
|
+
|
|
208
|
+
## Step 3: Claim again
|
|
209
|
+
|
|
210
|
+
After every `record.cypher` and `set-status.cypher` call, run dispatch.cypher (step 2.1) again and start
|
|
211
|
+
step 2.2 for every row it returns. That is the dataflow: a node starts the moment its own dependencies
|
|
212
|
+
complete, while unrelated slower nodes are still running. Between claims, wait for completion
|
|
213
|
+
notifications and handle each as it arrives.
|
|
214
|
+
|
|
215
|
+
A node is claimed only once everything it depends on has completed, so nodes in flight together never
|
|
216
|
+
read each other's outputs, and every file-touching node works in its own worktree — concurrency is safe
|
|
217
|
+
by construction. Your store calls and the merges into `FT` are the only serialized points; `FT` belongs
|
|
218
|
+
to this feature alone, so no other checkout can race them.
|
|
188
219
|
|
|
189
|
-
|
|
220
|
+
**Lost notifications.** Claude Code can drop a completion notification when 3 or more background agents
|
|
221
|
+
run at once. When an agent stays silent well past ones started after it, or you wake with nothing new to
|
|
222
|
+
handle, check instead of waiting: an implementer whose `INBOX/<slug>.json` exists counts as
|
|
223
|
+
`done <slug>` (it writes `.tmp` then renames, so presence means complete); otherwise, and for a
|
|
224
|
+
reviewer, fetch the reply by task id (`TaskOutput`) where the harness offers it. A reviewer whose reply
|
|
225
|
+
still can't be had is re-dispatched once in the foreground (step 2.3). Never take a verdict from a file.
|
|
190
226
|
|
|
191
|
-
|
|
227
|
+
Stop when a claim returns no rows and no agent is in flight: step 4.
|
|
192
228
|
|
|
193
229
|
## Step 4: Report and stop
|
|
194
230
|
|
|
@@ -211,6 +247,7 @@ Report: which nodes ran this invocation, which passed review outright vs. needed
|
|
|
211
247
|
## Resuming
|
|
212
248
|
|
|
213
249
|
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
|
|
215
|
-
commits on their branches survive — the re-dispatch reuses them
|
|
216
|
-
the remaining frontier. Nothing needs to be told what already finished —
|
|
250
|
+
resolved or re-attached, nodes an interrupted run left `in_progress` are reset (their worktrees and any
|
|
251
|
+
commits on their branches survive — the re-dispatch reuses them; their inbox files are discarded), and
|
|
252
|
+
the next claim picks up exactly the remaining frontier. Nothing needs to be told what already finished —
|
|
253
|
+
the store is the memory.
|
package/skills/status/SKILL.md
CHANGED
|
@@ -14,9 +14,9 @@ the feature is gone (or was never charted here); say so.
|
|
|
14
14
|
(`curl -sSfL https://neo4j-labs.github.io/cypherlite/install.sh | bash`).
|
|
15
15
|
- One `cypherlite` command at a time — never parallel tool calls on the same store.
|
|
16
16
|
- Always `--read-only`: status never writes, and a missing store fails fast instead of being created.
|
|
17
|
+
It takes no lock, so it reads beside a running `/gbuild:run`.
|
|
17
18
|
- Always `--mode jsonl`: one JSON object per row, no output = no rows.
|
|
18
|
-
-
|
|
19
|
-
seconds, retry up to 3 times, then say so. Anything else: `${CLAUDE_PLUGIN_ROOT}/reference/cypher.md`.
|
|
19
|
+
- Any error: `${CLAUDE_PLUGIN_ROOT}/reference/cypher.md`.
|
|
20
20
|
|
|
21
21
|
## Mode
|
|
22
22
|
|
|
@@ -38,7 +38,7 @@ cypherlite query --read-only --database DB --mode jsonl < ${CLAUDE_PLUGIN_ROOT}/
|
|
|
38
38
|
|
|
39
39
|
One call after the other. `status.cypher` gives one row per node with its derived `state`
|
|
40
40
|
(`frontier` / `blocked` / `in_progress` / `completed` / `cancelled` / `failed`), `wave`, `waiting_on`,
|
|
41
|
-
review summary and
|
|
41
|
+
review summary, timestamps and `last_dependency_at` — don't re-derive any of these by hand.
|
|
42
42
|
|
|
43
43
|
### 2. Render the graph
|
|
44
44
|
|
|
@@ -61,16 +61,24 @@ attempts. For `failed` nodes, `last_failed_criteria` verbatim — this is what a
|
|
|
61
61
|
|
|
62
62
|
### 4. Concurrency evidence
|
|
63
63
|
|
|
64
|
-
|
|
65
|
-
`
|
|
66
|
-
|
|
67
|
-
|
|
64
|
+
`run` schedules as dataflow: a node is claimed the moment its last dependency completes, not when its
|
|
65
|
+
wave does. Nodes sharing a `wave` need not overlap — a short chain can finish before a slow node beside
|
|
66
|
+
it — so don't judge by overlap; check dispatch timing instead, from the `status.cypher` rows of step 1.
|
|
67
|
+
|
|
68
|
+
For each node with both `started_at` and `last_dependency_at` (the latest `completed_at` among its
|
|
69
|
+
completed dependencies), report the gap from `last_dependency_at` to `started_at`. A few minutes is
|
|
70
|
+
the dependency's review, merge and record — dataflow working. A much longer gap, e.g. a start that
|
|
71
|
+
waited for an unrelated slower node to complete, means the node sat ready while something else held it
|
|
72
|
+
back (`run` driven wave by wave, or a lost completion notification) — a bug in how `run` was driven,
|
|
73
|
+
not a graph problem. A node with repair attempts (`review_attempts` > 1) started late by design: its
|
|
74
|
+
times are the passing attempt's. Nodes with no dependencies should have started together at the
|
|
75
|
+
beginning of the run.
|
|
68
76
|
|
|
69
77
|
### 5. Next action
|
|
70
78
|
|
|
71
79
|
One priority-ordered list: what `/gbuild:run <feature>` would do next (the current frontier), and
|
|
72
80
|
anything needing a human decision first (`failed` nodes, an empty frontier with incomplete nodes
|
|
73
|
-
remaining, `in_progress` nodes when no run is active —
|
|
81
|
+
remaining, `in_progress` nodes when no run is active — interrupted work `run` will reset).
|
|
74
82
|
|
|
75
83
|
### 6. Invariant checks
|
|
76
84
|
|