@pennixrv/trellis 0.6.18 → 0.6.20
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/dist/commands/channel/adapters/codex.d.ts +14 -0
- package/dist/commands/channel/adapters/codex.d.ts.map +1 -1
- package/dist/commands/channel/adapters/codex.js +37 -0
- package/dist/commands/channel/adapters/codex.js.map +1 -1
- package/dist/commands/channel/adapters/index.d.ts.map +1 -1
- package/dist/commands/channel/adapters/index.js +49 -13
- package/dist/commands/channel/adapters/index.js.map +1 -1
- package/dist/commands/channel/index.d.ts.map +1 -1
- package/dist/commands/channel/index.js +17 -1
- package/dist/commands/channel/index.js.map +1 -1
- package/dist/commands/channel/wait.d.ts +4 -0
- package/dist/commands/channel/wait.d.ts.map +1 -1
- package/dist/commands/channel/wait.js +8 -1
- package/dist/commands/channel/wait.js.map +1 -1
- package/dist/migrations/manifests/0.6.19.json +9 -0
- package/dist/migrations/manifests/0.6.20.json +9 -0
- package/dist/templates/common/bundled-skills/trellis-channel/SKILL.md +2 -0
- package/dist/templates/common/bundled-skills/trellis-channel/references/command-reference.md +35 -5
- package/dist/templates/common/bundled-skills/trellis-channel/references/progress-debugging.md +24 -13
- package/dist/templates/common/bundled-skills/trellis-channel/references/subnode-work.md +159 -0
- package/dist/templates/common/bundled-skills/trellis-channel/references/workflows.md +6 -3
- package/dist/templates/shared-hooks/inject-workflow-state.py +17 -16
- package/dist/templates/trellis/agents/subnode.md +62 -0
- package/dist/templates/trellis/config.yaml +9 -9
- package/dist/templates/trellis/index.d.ts +3 -0
- package/dist/templates/trellis/index.d.ts.map +1 -1
- package/dist/templates/trellis/index.js +6 -0
- package/dist/templates/trellis/index.js.map +1 -1
- package/dist/templates/trellis/scripts/common/config.py +5 -4
- package/dist/templates/trellis/scripts/common/task_store.py +3 -3
- package/dist/templates/trellis/scripts/common/workflow_phase.py +1 -1
- package/dist/templates/trellis/scripts/subnode_artifact.py +498 -0
- package/dist/templates/trellis/scripts/workspace_note.py +126 -0
- package/dist/templates/trellis/workflow.md +5 -5
- package/package.json +2 -2
package/dist/templates/common/bundled-skills/trellis-channel/references/command-reference.md
CHANGED
|
@@ -41,6 +41,7 @@ trellis channel create <name>
|
|
|
41
41
|
```
|
|
42
42
|
|
|
43
43
|
Behavior:
|
|
44
|
+
|
|
44
45
|
- Appends a `create` event; immutable `type` (cannot mutate forum↔chat after).
|
|
45
46
|
- `--ephemeral` channels are hidden from `channel list` by default and are
|
|
46
47
|
the sweep target for `channel prune --ephemeral`.
|
|
@@ -59,6 +60,7 @@ trellis channel list
|
|
|
59
60
|
```
|
|
60
61
|
|
|
61
62
|
Behavior:
|
|
63
|
+
|
|
62
64
|
- Default scope: current cwd's project. `--all-projects` scans every bucket.
|
|
63
65
|
- Pretty mode prints `NAME WORKERS EVENTS LAST KIND TYPE TASK`, sorted by
|
|
64
66
|
recency, with a footer noting hidden ephemeral count.
|
|
@@ -80,6 +82,7 @@ trellis channel send <name> [text]
|
|
|
80
82
|
```
|
|
81
83
|
|
|
82
84
|
Behavior:
|
|
85
|
+
|
|
83
86
|
- Body precedence: positional `[text]` → `--stdin` → `--text-file`.
|
|
84
87
|
- `--to` with one entry stores a string; multiple stores an array; omitted
|
|
85
88
|
means broadcast.
|
|
@@ -110,12 +113,24 @@ trellis channel messages <name>
|
|
|
110
113
|
```
|
|
111
114
|
|
|
112
115
|
Behavior:
|
|
116
|
+
|
|
113
117
|
- Auto-detects forum channels: with no filters it renders the thread board
|
|
114
118
|
instead of the event stream. `--thread` / `--action` are forum-only and
|
|
115
119
|
error against chat channels.
|
|
116
120
|
- `--kind` is validated against `CHANNEL_EVENT_KINDS` (single value, not
|
|
117
121
|
CSV — that's the `wait` side).
|
|
118
122
|
|
|
123
|
+
### `barrier <name>`
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
trellis channel barrier <name>
|
|
127
|
+
[--scope project|global]
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
Prints the channel's current durable event sequence as one integer. It does not
|
|
131
|
+
append an event. Capture it after `create` and before an operation that can
|
|
132
|
+
emit the event you intend to wait for, then pass it to `wait --after-seq`.
|
|
133
|
+
|
|
119
134
|
### `wait <name>`
|
|
120
135
|
|
|
121
136
|
```bash
|
|
@@ -123,6 +138,7 @@ trellis channel wait <name>
|
|
|
123
138
|
--as <agent> # REQUIRED — self for filter ctx
|
|
124
139
|
[--scope project|global]
|
|
125
140
|
[--timeout <Ns|Nm|Nh|Nms>] # parsed by parseDuration
|
|
141
|
+
[--after-seq <integer>] # replay only events after barrier
|
|
126
142
|
[--from <a,b>] # author CSV
|
|
127
143
|
[--kind <k1,k2>] # CSV, OR semantics
|
|
128
144
|
[--thread <key>] # forum filter
|
|
@@ -133,11 +149,15 @@ trellis channel wait <name>
|
|
|
133
149
|
```
|
|
134
150
|
|
|
135
151
|
Behavior:
|
|
152
|
+
|
|
136
153
|
- Streams matching events as JSON, one per line.
|
|
137
154
|
- Default `--to` filter is the caller's own agent (broadcast events still
|
|
138
155
|
match — broadcast + explicit-to-me).
|
|
139
156
|
- `--all` requires `--from` and blocks until every listed agent has produced
|
|
140
157
|
a matching event.
|
|
158
|
+
- Without `--after-seq`, the command captures its current event sequence before
|
|
159
|
+
constructing its watcher and ignores prior events. With `--after-seq`, it
|
|
160
|
+
replays matching events whose sequence is greater than that supplied barrier.
|
|
141
161
|
- **Timeout exits 124** and prints `timeout: still waiting on ...` to stderr
|
|
142
162
|
when `--all` was in play.
|
|
143
163
|
|
|
@@ -199,6 +219,7 @@ trellis channel interrupt <name> [text]
|
|
|
199
219
|
```
|
|
200
220
|
|
|
201
221
|
Behavior:
|
|
222
|
+
|
|
202
223
|
- Appends an `interrupt` event with `reason: "user"` and a replacement
|
|
203
224
|
instruction body; supervisor performs provider-level interrupt where
|
|
204
225
|
supported (Claude `/interrupt`, Codex turn cancel).
|
|
@@ -235,6 +256,7 @@ trellis channel spawn <name>
|
|
|
235
256
|
```
|
|
236
257
|
|
|
237
258
|
Behavior:
|
|
259
|
+
|
|
238
260
|
- Provider is validated against the adapter registry
|
|
239
261
|
(`packages/cli/src/commands/channel/adapters/`); current: `claude`,
|
|
240
262
|
`codex`.
|
|
@@ -262,6 +284,7 @@ trellis channel run [name?]
|
|
|
262
284
|
```
|
|
263
285
|
|
|
264
286
|
Behavior:
|
|
287
|
+
|
|
265
288
|
- One-shot. Auto-generates `run-<hex>` if `name` omitted.
|
|
266
289
|
- Creates an ephemeral channel (`createMode=run`), spawns a single worker,
|
|
267
290
|
sends the prompt, waits for `done`, prints the final assistant text to
|
|
@@ -281,6 +304,7 @@ trellis channel kill <name>
|
|
|
281
304
|
```
|
|
282
305
|
|
|
283
306
|
Behavior:
|
|
307
|
+
|
|
284
308
|
- Default path: SIGTERM → 8 s grace → SIGKILL escalation; the CLI writes a
|
|
285
309
|
`killed` event when SIGKILL was needed so the log stays truthful.
|
|
286
310
|
- Cleans `pid`, `worker-pid`, `config`, `spawnlock` sidecar files; keeps
|
|
@@ -294,6 +318,7 @@ trellis channel rm <name>
|
|
|
294
318
|
```
|
|
295
319
|
|
|
296
320
|
Behavior:
|
|
321
|
+
|
|
297
322
|
- Kills any live workers, then deletes the entire channel directory.
|
|
298
323
|
- Prints `Removed channel '<name>'`.
|
|
299
324
|
|
|
@@ -309,6 +334,7 @@ trellis channel prune
|
|
|
309
334
|
```
|
|
310
335
|
|
|
311
336
|
Behavior:
|
|
337
|
+
|
|
312
338
|
- Filter flags are mutually exclusive — error otherwise.
|
|
313
339
|
- Default is dry-run; `--yes` flips to real delete.
|
|
314
340
|
- Without `--scope`, scans **every** project bucket (intentional, repo-wide
|
|
@@ -341,6 +367,7 @@ trellis channel post <name> <action>
|
|
|
341
367
|
```
|
|
342
368
|
|
|
343
369
|
Behavior:
|
|
370
|
+
|
|
344
371
|
- `<action>` is free-form on the CLI surface; conventional values include
|
|
345
372
|
`opened`, `comment`, `status`, `labels`, `assignees`, `summary`,
|
|
346
373
|
`processed`.
|
|
@@ -358,6 +385,7 @@ trellis channel forum <name>
|
|
|
358
385
|
```
|
|
359
386
|
|
|
360
387
|
Behavior:
|
|
388
|
+
|
|
361
389
|
- Lists threads (reduced state). `--status` filters by current thread
|
|
362
390
|
status. `--raw` prints one JSON per thread.
|
|
363
391
|
|
|
@@ -374,6 +402,7 @@ trellis channel thread rename <name> <old-thread> <new-thread>
|
|
|
374
402
|
```
|
|
375
403
|
|
|
376
404
|
Behavior:
|
|
405
|
+
|
|
377
406
|
- `thread <name> <key>` shows one thread's timeline:
|
|
378
407
|
header `<thread> [<status>] <title>`, then description / labels /
|
|
379
408
|
assignees / summary / timeline lines. `--raw` switches to raw events.
|
|
@@ -408,6 +437,7 @@ trellis channel context list <name>
|
|
|
408
437
|
```
|
|
409
438
|
|
|
410
439
|
Behavior:
|
|
440
|
+
|
|
411
441
|
- `add` / `delete` append a `context` event and print the event JSON.
|
|
412
442
|
- `list` projects current context entries; pretty output is
|
|
413
443
|
`file <path>` / `raw <truncated text>` lines, `(no context)` when empty.
|
|
@@ -426,6 +456,7 @@ trellis channel title clear <name>
|
|
|
426
456
|
```
|
|
427
457
|
|
|
428
458
|
Behavior:
|
|
459
|
+
|
|
429
460
|
- Appends a `title` event projecting a stable display title onto the
|
|
430
461
|
channel. Output: event JSON.
|
|
431
462
|
|
|
@@ -433,10 +464,10 @@ Behavior:
|
|
|
433
464
|
|
|
434
465
|
## Hidden / Internal
|
|
435
466
|
|
|
436
|
-
| Command
|
|
437
|
-
|
|
438
|
-
| `channel __supervisor <channel> <worker> <config>` | Forked entry point invoked by `spawn`. Do not invoke directly.
|
|
439
|
-
| `channel __parse-trace <adapter> <file>`
|
|
467
|
+
| Command | Purpose |
|
|
468
|
+
| -------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
469
|
+
| `channel __supervisor <channel> <worker> <config>` | Forked entry point invoked by `spawn`. Do not invoke directly. |
|
|
470
|
+
| `channel __parse-trace <adapter> <file>` | Dev helper — replays a recorded stream-json / wire trace through the matching adapter and prints the resulting channel events. Adapter is validated against the provider registry. |
|
|
440
471
|
|
|
441
472
|
---
|
|
442
473
|
|
|
@@ -477,4 +508,3 @@ Forum channels are event-sourced; use the CLI reducers
|
|
|
477
508
|
pipe); diagnostic notes go to stderr.
|
|
478
509
|
- **Errors** go through `chalk.red("Error:")` to stderr and `exit 1`.
|
|
479
510
|
- **`wait` timeout** specifically exits **124**.
|
|
480
|
-
|
package/dist/templates/common/bundled-skills/trellis-channel/references/progress-debugging.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Progress And Debugging
|
|
2
2
|
|
|
3
3
|
Pretty output is for operators. Raw output is the audit log. Subcommands
|
|
4
|
-
(`forum`, `thread`, `messages`, `context`) are the audit
|
|
4
|
+
(`forum`, `thread`, `messages`, `context`) are the audit _interface_ — reach
|
|
5
5
|
for them before grepping `events.jsonl` by hand.
|
|
6
6
|
|
|
7
7
|
## Pretty vs `--raw`
|
|
@@ -120,7 +120,18 @@ inspect the worker log for the subprocess.
|
|
|
120
120
|
|
|
121
121
|
## Wait Semantics (Quick Reference)
|
|
122
122
|
|
|
123
|
-
`channel wait`
|
|
123
|
+
Without `--after-seq`, `channel wait` captures the current durable sequence,
|
|
124
|
+
then watches matching later events. For an operation that can finish before the
|
|
125
|
+
wait command starts, capture a barrier before that operation and pass it back:
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
BARRIER="$(trellis channel barrier T)"
|
|
129
|
+
# spawn or trigger work that may emit a terminal event
|
|
130
|
+
trellis channel wait T --as main --from check --kind done,error \
|
|
131
|
+
--after-seq "$BARRIER" --timeout 15m
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
It wakes on:
|
|
124
135
|
|
|
125
136
|
- `message`
|
|
126
137
|
- `done`
|
|
@@ -133,7 +144,7 @@ Useful filters:
|
|
|
133
144
|
```bash
|
|
134
145
|
trellis channel wait T --as main --from check --kind done --timeout 15m
|
|
135
146
|
trellis channel wait T --as main --from check,check-cx --kind done --all --timeout 15m
|
|
136
|
-
trellis channel wait T --as worker --
|
|
147
|
+
trellis channel wait T --as worker --kind message --timeout 1h
|
|
137
148
|
trellis channel wait T --as main --thread release-note --action status --timeout 10m
|
|
138
149
|
```
|
|
139
150
|
|
|
@@ -192,16 +203,16 @@ diffing against `<worker>.inbox-cursor` while debugging the supervisor.
|
|
|
192
203
|
|
|
193
204
|
## Common Failures
|
|
194
205
|
|
|
195
|
-
| Symptom
|
|
196
|
-
|
|
197
|
-
| `trellis: command not found`
|
|
198
|
-
| `wait` exits immediately
|
|
199
|
-
| zsh errors on message text
|
|
200
|
-
| progress line is cut off
|
|
201
|
-
| worker never speaks
|
|
202
|
-
| channel not found in another cwd | project bucket mismatch
|
|
203
|
-
| ghost worker in list
|
|
204
|
-
| forum thread looks scrambled
|
|
206
|
+
| Symptom | Cause | Fix |
|
|
207
|
+
| -------------------------------- | ------------------------------------- | --------------------------------------------------------------- |
|
|
208
|
+
| `trellis: command not found` | CLI not installed globally | `npm install -g @pennixrv/trellis` |
|
|
209
|
+
| `wait` exits immediately | wrong filter or identity collision | use distinct `--as`, inspect raw messages |
|
|
210
|
+
| zsh errors on message text | shell interpreted punctuation | use `--stdin` or `--text-file` |
|
|
211
|
+
| progress line is cut off | pretty output truncation | use `messages --raw --kind progress` |
|
|
212
|
+
| worker never speaks | provider startup / prompt / MCP delay | inspect `<worker>.log`, `ps`, raw events |
|
|
213
|
+
| channel not found in another cwd | project bucket mismatch | `cd` to project, use `--scope global`, or `list --all-projects` |
|
|
214
|
+
| ghost worker in list | supervisor died without cleanup | `trellis channel kill <name> --as <worker> --force` |
|
|
215
|
+
| forum thread looks scrambled | parsed `events.jsonl` directly | use `forum`, `thread`, `messages --thread` |
|
|
205
216
|
|
|
206
217
|
## Storage Layout
|
|
207
218
|
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
# Bounded Subnode Work
|
|
2
|
+
|
|
3
|
+
Use a `subnode` only when the user explicitly needs independently reviewable
|
|
4
|
+
evidence for a bounded analysis, design, audit, review, counterargument, or
|
|
5
|
+
verification question. It is not the normal path for an ordinary static review,
|
|
6
|
+
implementation, memory retrieval, or routine tool call.
|
|
7
|
+
|
|
8
|
+
The coordinator owns task facts, protected targets, acceptance, Git, worker
|
|
9
|
+
lifecycle, and the final result. A subnode owns one evidence report and its own
|
|
10
|
+
append-only worklog. This is a behavioral contract; do not add `--sandbox` or
|
|
11
|
+
claim that path restrictions enforce it.
|
|
12
|
+
|
|
13
|
+
## Artifact Setup
|
|
14
|
+
|
|
15
|
+
Before spawning, the coordinator must use an active task (`planning` or
|
|
16
|
+
`in_progress`), define one stable `work_id` and
|
|
17
|
+
`subnode_id`, then prepare a brief-draft JSON with the question, independence
|
|
18
|
+
reason, scope, protected targets, lens, evidence method, source snapshot,
|
|
19
|
+
dependencies, stop conditions, deadline, `channel_ref`, `retry_of` (null unless
|
|
20
|
+
this is an explicit manual retry), and `counter_of` (null unless this is
|
|
21
|
+
intentional counterwork). A retry names an existing, different subnode in the
|
|
22
|
+
same task and `work_id`; counterwork may be initialized independently. The
|
|
23
|
+
helper supplies the immutable task identity and report path.
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
TASK=.trellis/tasks/09-07-example
|
|
27
|
+
WORK_ID=security-audit
|
|
28
|
+
SUBNODE_ID=dependency-evidence
|
|
29
|
+
|
|
30
|
+
python3 .trellis/scripts/subnode_artifact.py init \
|
|
31
|
+
--task "$TASK" \
|
|
32
|
+
--work-id "$WORK_ID" \
|
|
33
|
+
--subnode-id "$SUBNODE_ID" \
|
|
34
|
+
--draft /tmp/subnode-brief.json
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
This creates exactly:
|
|
38
|
+
|
|
39
|
+
```text
|
|
40
|
+
$TASK/subnodes/$WORK_ID/$SUBNODE_ID/
|
|
41
|
+
brief.json # coordinator-owned and immutable after dispatch
|
|
42
|
+
worklog.md # subnode appends material progress and corrections
|
|
43
|
+
report.json # subnode-owned final pending-review result
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Do not use a terminal Channel message as the report transport. The short final
|
|
47
|
+
message names the already-written `report.json` and its status; the durable
|
|
48
|
+
JSON file carries the reviewable result.
|
|
49
|
+
|
|
50
|
+
The subnode copies identity, scope, and lens from `brief.json`. The minimal
|
|
51
|
+
complete report is:
|
|
52
|
+
|
|
53
|
+
```json
|
|
54
|
+
{
|
|
55
|
+
"schema_version": 1,
|
|
56
|
+
"task_id": "task-id-from-brief",
|
|
57
|
+
"work_id": "work-id-from-brief",
|
|
58
|
+
"subnode_id": "subnode-id-from-brief",
|
|
59
|
+
"role_id": "subnode",
|
|
60
|
+
"status": "complete",
|
|
61
|
+
"scope": ["exact scope copied from brief"],
|
|
62
|
+
"lens": "exact lens copied from brief",
|
|
63
|
+
"evidence": [
|
|
64
|
+
{
|
|
65
|
+
"id": "stable-evidence-id",
|
|
66
|
+
"locator": "source path, URL, or command receipt",
|
|
67
|
+
"summary": "What this independently reviewable evidence establishes."
|
|
68
|
+
}
|
|
69
|
+
],
|
|
70
|
+
"findings": ["Bounded conclusion."],
|
|
71
|
+
"uncertainties": [],
|
|
72
|
+
"corrections": []
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
For `blocked`, `incomplete`, or `error`, include the same base fields plus a
|
|
77
|
+
non-empty `completed_scope` list and a non-empty `blocker` string. Never use
|
|
78
|
+
`accepted`, `rejected`, or `deferred` as a report status.
|
|
79
|
+
|
|
80
|
+
## Dispatch And Wait
|
|
81
|
+
|
|
82
|
+
Inspect the installed role first, then capture a durable event barrier before
|
|
83
|
+
the worker can emit a terminal event. The CLI waits once and replays matching
|
|
84
|
+
events committed after that barrier:
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
trellis channel create subnode-example --by main --cwd "$PWD"
|
|
88
|
+
BARRIER="$(trellis channel barrier subnode-example)"
|
|
89
|
+
trellis channel spawn subnode-example --agent subnode --provider codex \
|
|
90
|
+
--as "$SUBNODE_ID" --cwd "$PWD" --timeout 30m
|
|
91
|
+
|
|
92
|
+
printf '%s\n' "Read $TASK/subnodes/$WORK_ID/$SUBNODE_ID/brief.json and perform only that bounded work." \
|
|
93
|
+
| trellis channel send subnode-example --as main --to "$SUBNODE_ID" \
|
|
94
|
+
--stdin --delivery-mode requireRunningWorker
|
|
95
|
+
|
|
96
|
+
trellis channel wait subnode-example --as main --from "$SUBNODE_ID" \
|
|
97
|
+
--kind done,error --after-seq "$BARRIER" --timeout 30m
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Where the host exposes a live wait continuation, capture the same barrier,
|
|
101
|
+
establish one event waiter before triggering the worker, and continue that same
|
|
102
|
+
waiter until terminal state. Do not create a second waiter or treat an empty
|
|
103
|
+
transport slice as completion. `channel messages`, worker inspection, and
|
|
104
|
+
status/list commands remain valid on-demand diagnostics, but do not use
|
|
105
|
+
high-frequency repeated queries as the coordinator's supervision loop.
|
|
106
|
+
|
|
107
|
+
## Coordinator Review
|
|
108
|
+
|
|
109
|
+
After a terminal message, independently validate and then record a task-level
|
|
110
|
+
disposition. `complete` means only that the subnode claims it completed its
|
|
111
|
+
assigned work; it is not acceptance.
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
REPORT="$TASK/subnodes/$WORK_ID/$SUBNODE_ID/report.json"
|
|
115
|
+
python3 .trellis/scripts/subnode_artifact.py validate --report "$REPORT"
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
The coordinator must re-check enough source evidence and protected-target state
|
|
119
|
+
to decide `accepted`, `rejected`, or `deferred`, preserving the reason and named
|
|
120
|
+
checks such as `report_validation`, `source_recheck`, and
|
|
121
|
+
`protected_target_check` in task research or a decision record. The validator
|
|
122
|
+
does not make that decision and does not modify `task.json`.
|
|
123
|
+
|
|
124
|
+
Use the separate coordinator work-record helper only for a durable cross-task
|
|
125
|
+
observation, decision, open question, or blocker. It does not substitute for a
|
|
126
|
+
task artifact or subnode worklog.
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
python3 .trellis/scripts/workspace_note.py \
|
|
130
|
+
--kind decision \
|
|
131
|
+
--summary "Accepted independent dependency evidence for the release gate." \
|
|
132
|
+
--source "$REPORT"
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
## Counterwork
|
|
136
|
+
|
|
137
|
+
Counterwork is a new, independently scoped subnode, not a retry. It must use a
|
|
138
|
+
different `subnode_id`, lens, and evidence identities, and its brief sets
|
|
139
|
+
`counter_of` to the primary subnode ID. After both reports are complete:
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
python3 .trellis/scripts/subnode_artifact.py validate-counter \
|
|
143
|
+
--primary "$TASK/subnodes/$WORK_ID/primary" \
|
|
144
|
+
--counter "$TASK/subnodes/$WORK_ID/counter"
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
The coordinator compares the two reports and retains the comparison as part of
|
|
148
|
+
its own disposition.
|
|
149
|
+
|
|
150
|
+
## Manual Retry
|
|
151
|
+
|
|
152
|
+
A retry is a fresh, explicitly approved subnode after a recorded failed or
|
|
153
|
+
incomplete attempt. It uses a new `subnode_id`, preserves the old artifacts,
|
|
154
|
+
and sets `retry_of` to that prior subnode ID in its brief. The coordinator must
|
|
155
|
+
record why it is retrying and check the new report independently; neither the
|
|
156
|
+
helper nor Channel decides when to retry.
|
|
157
|
+
|
|
158
|
+
No scheduler, high-frequency polling loop, automatic retry, worktree, global
|
|
159
|
+
ledger, or provider-specific transport is introduced by this workflow.
|
|
@@ -11,6 +11,7 @@ Use when the user says "和 codex/claude 讨论一下", "brainstorm", or "拉一
|
|
|
11
11
|
```bash
|
|
12
12
|
trellis channel create brainstorm-storage-layer --by main \
|
|
13
13
|
--task .trellis/tasks/05-XX-storage-adapter
|
|
14
|
+
BARRIER="$(trellis channel barrier brainstorm-storage-layer)"
|
|
14
15
|
|
|
15
16
|
trellis channel spawn brainstorm-storage-layer \
|
|
16
17
|
--agent architect --provider codex \
|
|
@@ -22,7 +23,7 @@ trellis channel send brainstorm-storage-layer \
|
|
|
22
23
|
--as main --to cx-arch --text-file /tmp/brainstorm-r1.md
|
|
23
24
|
|
|
24
25
|
trellis channel wait brainstorm-storage-layer \
|
|
25
|
-
--as main --kind done --from cx-arch --timeout 10m
|
|
26
|
+
--as main --kind done --from cx-arch --after-seq "$BARRIER" --timeout 10m
|
|
26
27
|
```
|
|
27
28
|
|
|
28
29
|
Do not stop after one answer. Read the answer, identify vague areas, send a
|
|
@@ -53,6 +54,7 @@ Use when the user asks to dispatch implementation or review work.
|
|
|
53
54
|
```bash
|
|
54
55
|
TASK=.trellis/tasks/05-12-foo
|
|
55
56
|
trellis channel create cr-foo --task "$TASK" --by main
|
|
57
|
+
BARRIER="$(trellis channel barrier cr-foo)"
|
|
56
58
|
|
|
57
59
|
trellis channel spawn cr-foo \
|
|
58
60
|
--agent check \
|
|
@@ -63,7 +65,7 @@ trellis channel spawn cr-foo \
|
|
|
63
65
|
--cwd "$PWD" --timeout 15m
|
|
64
66
|
|
|
65
67
|
trellis channel send cr-foo --as main --to check --text-file /tmp/cr-brief.md
|
|
66
|
-
trellis channel wait cr-foo --as main --kind done --from check --timeout 15m
|
|
68
|
+
trellis channel wait cr-foo --as main --kind done --from check --after-seq "$BARRIER" --timeout 15m
|
|
67
69
|
trellis channel messages cr-foo --kind message --from check --tag final_answer
|
|
68
70
|
```
|
|
69
71
|
|
|
@@ -77,6 +79,7 @@ Use one channel and distinct worker names.
|
|
|
77
79
|
|
|
78
80
|
```bash
|
|
79
81
|
trellis channel create cr-feature --by main --ephemeral
|
|
82
|
+
BARRIER="$(trellis channel barrier cr-feature)"
|
|
80
83
|
|
|
81
84
|
trellis channel spawn cr-feature --agent check \
|
|
82
85
|
--jsonl "$TASK/check.jsonl" --file "$TASK/prd.md" --file "$TASK/design.md" \
|
|
@@ -88,7 +91,7 @@ trellis channel spawn cr-feature --agent check --provider codex --as check-cx \
|
|
|
88
91
|
|
|
89
92
|
trellis channel send cr-feature --as main --to check --text-file /tmp/cr-brief.md
|
|
90
93
|
trellis channel send cr-feature --as main --to check-cx --text-file /tmp/cr-brief.md
|
|
91
|
-
trellis channel wait cr-feature --as main --kind done --from check,check-cx --all --timeout 15m
|
|
94
|
+
trellis channel wait cr-feature --as main --kind done --from check,check-cx --all --after-seq "$BARRIER" --timeout 15m
|
|
92
95
|
```
|
|
93
96
|
|
|
94
97
|
`--all` means every listed worker must emit a matching event.
|
|
@@ -286,13 +286,14 @@ def prompt_has_skip_keyword(prompt: str, keyword: str) -> bool:
|
|
|
286
286
|
def _resolve_codex_dispatch_mode(config: dict) -> str:
|
|
287
287
|
"""Normalize `codex.dispatch_mode` from .trellis/config.yaml to "auto" or "inline".
|
|
288
288
|
|
|
289
|
-
Defaults to `
|
|
290
|
-
|
|
289
|
+
Defaults to `inline`. `auto` explicitly enables native dispatch; the
|
|
290
|
+
legacy `sub-agent` value is an alias for `auto`. Any other explicit value
|
|
291
|
+
(including invalid ones) falls back to `inline`
|
|
291
292
|
without per-turn warnings. Shared by `_codex_mode_banner` (the per-turn
|
|
292
293
|
banner) and `resolve_breadcrumb_key` (the breadcrumb tag key) so the two
|
|
293
294
|
stay in lockstep.
|
|
294
295
|
"""
|
|
295
|
-
mode = "
|
|
296
|
+
mode = "inline"
|
|
296
297
|
if isinstance(config, dict):
|
|
297
298
|
codex_cfg = config.get("codex")
|
|
298
299
|
if isinstance(codex_cfg, dict):
|
|
@@ -310,16 +311,16 @@ def _codex_mode_banner(config: dict) -> str:
|
|
|
310
311
|
"""Emit a `<codex-mode>` banner for the additionalContext payload.
|
|
311
312
|
|
|
312
313
|
Reads `codex.dispatch_mode` from .trellis/config.yaml; defaults to
|
|
313
|
-
`
|
|
314
|
+
`inline`, so the main session implements and checks directly. `auto`
|
|
315
|
+
explicitly dispatches Trellis sub-agents using native Codex context
|
|
314
316
|
injection with a child-side fallback. This does not rely on inherited
|
|
315
317
|
parent transcripts: `fork_turns` remains caller-controlled, and
|
|
316
318
|
fresh-history sub-agents still receive their explicit delegated task and
|
|
317
|
-
inherited session configuration. `
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
workflow-state tells AI what step it's at.
|
|
319
|
+
inherited session configuration. The legacy `sub-agent` value is an alias
|
|
320
|
+
for `auto`. Invalid explicit values fall back to `inline` without per-turn
|
|
321
|
+
warnings. The banner makes the active mode explicit to Codex AI per turn,
|
|
322
|
+
complementing the workflow-state body which is per-status. Mode tells AI
|
|
323
|
+
which dispatch protocol to follow; workflow-state tells AI what step it's at.
|
|
323
324
|
"""
|
|
324
325
|
mode = _resolve_codex_dispatch_mode(config)
|
|
325
326
|
if mode == "auto":
|
|
@@ -341,12 +342,12 @@ def resolve_breadcrumb_key(
|
|
|
341
342
|
) -> str:
|
|
342
343
|
"""Pick the breadcrumb tag key based on Codex dispatch_mode.
|
|
343
344
|
|
|
344
|
-
Codex defaults to ``
|
|
345
|
-
breadcrumb for
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
``auto``. Invalid explicit values fall back to inline without
|
|
349
|
-
warnings.
|
|
345
|
+
Codex defaults to ``inline`` and therefore uses the parallel
|
|
346
|
+
``<status>-inline`` breadcrumb for main-session execution. Explicit
|
|
347
|
+
``auto`` uses the ordinary ``<status>`` breadcrumb for native
|
|
348
|
+
SubagentStart dispatch with child-side fallback; ``sub-agent`` remains an
|
|
349
|
+
alias for ``auto``. Invalid explicit values fall back to inline without
|
|
350
|
+
per-turn warnings.
|
|
350
351
|
|
|
351
352
|
Non-codex platforms return the plain status unchanged.
|
|
352
353
|
"""
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: subnode
|
|
3
|
+
description: |
|
|
4
|
+
Bounded independent-evidence worker. It preserves its assigned task artifacts,
|
|
5
|
+
never changes protected target files, and leaves acceptance to the coordinator.
|
|
6
|
+
provider: codex
|
|
7
|
+
labels: [trellis, subnode]
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Subnode (channel runtime)
|
|
11
|
+
|
|
12
|
+
You are a bounded Trellis subnode spawned through `trellis channel`. Your job is
|
|
13
|
+
to produce independently reviewable evidence for one assigned question. You are
|
|
14
|
+
not an implementation worker, task owner, reviewer-of-record, or Git operator.
|
|
15
|
+
|
|
16
|
+
## Required Context
|
|
17
|
+
|
|
18
|
+
Before starting, read the `brief.json` path named in the coordinator message.
|
|
19
|
+
It fixes your task identity, scope, protected targets, evidence method, source
|
|
20
|
+
snapshot, deadline, stop conditions, channel handle, and final `report_path`.
|
|
21
|
+
Read the necessary current project and external sources needed to answer that
|
|
22
|
+
brief. A source snapshot records evidence; it is not a filesystem allowlist.
|
|
23
|
+
|
|
24
|
+
## Ownership And Write Boundary
|
|
25
|
+
|
|
26
|
+
You may write only within the artifact directory named by the brief:
|
|
27
|
+
|
|
28
|
+
- `worklog.md` — append substantive observations, corrections, blockers, and
|
|
29
|
+
completion notes as they occur.
|
|
30
|
+
- `report.json` — write your one final pending-review report at the exact path
|
|
31
|
+
in `brief.json`.
|
|
32
|
+
|
|
33
|
+
Do not modify `brief.json`. Do not edit any protected target, business source,
|
|
34
|
+
test, task artifact, project rule, coordinator workspace note, or unrelated
|
|
35
|
+
file. Do not run Git commands that change state (`commit`, `push`, `merge`,
|
|
36
|
+
`rebase`, `reset`, `checkout`, `stash`, or branch/worktree operations). Do not
|
|
37
|
+
spawn or control another worker. These are behavioral requirements, not a
|
|
38
|
+
sandbox claim.
|
|
39
|
+
|
|
40
|
+
## Work Method
|
|
41
|
+
|
|
42
|
+
1. Confirm the brief identity and artifact paths before doing substantive work.
|
|
43
|
+
2. Inspect evidence using the stated lens and method. Keep the assigned scope
|
|
44
|
+
narrow; stop when a stop condition is met or the evidence is sufficient.
|
|
45
|
+
3. Append a concise worklog entry when you make a material discovery, retract a
|
|
46
|
+
conclusion, encounter a blocker, or finish. Preserve corrections rather
|
|
47
|
+
than silently rewriting the historical trail.
|
|
48
|
+
4. Write `report.json` only when you are ready to stop. Its status is one of
|
|
49
|
+
`complete`, `blocked`, `incomplete`, or `error`; it is always
|
|
50
|
+
**pending coordinator review**, never accepted/rejected/deferred.
|
|
51
|
+
5. A complete report includes independently checkable evidence. A non-complete
|
|
52
|
+
report explains completed scope and the blocker or error. Include the exact
|
|
53
|
+
identity, scope, and lens required by the artifact helper.
|
|
54
|
+
6. Send one short terminal Channel message with the status and report path.
|
|
55
|
+
Do not place the report JSON in Channel text.
|
|
56
|
+
|
|
57
|
+
## Report Boundary
|
|
58
|
+
|
|
59
|
+
The coordinator independently runs the artifact validator and then records the
|
|
60
|
+
task disposition (`accepted`, `rejected`, or `deferred`) with its own source and
|
|
61
|
+
protected-target checks. Do not claim that a report has been accepted, and do
|
|
62
|
+
not infer a disposition from a successful Channel delivery.
|
|
@@ -110,14 +110,14 @@ channel:
|
|
|
110
110
|
#-------------------------------------------------------------------------------
|
|
111
111
|
# Codex (dispatch behavior)
|
|
112
112
|
#-------------------------------------------------------------------------------
|
|
113
|
-
# Codex-only knob; other platforms ignore it.
|
|
114
|
-
#
|
|
115
|
-
#
|
|
116
|
-
#
|
|
117
|
-
#
|
|
118
|
-
#
|
|
119
|
-
#
|
|
120
|
-
# Invalid explicit values safely use inline mode.
|
|
113
|
+
# Codex-only knob; other platforms ignore it. The default is "inline": the
|
|
114
|
+
# main session performs implementation and checks directly. Set "auto" only
|
|
115
|
+
# to opt in to trellis-implement / trellis-check / trellis-research native
|
|
116
|
+
# sub-agents. Their task context does not rely on inherited parent transcripts:
|
|
117
|
+
# `fork_turns` remains caller-controlled, while Codex's native SubagentStart
|
|
118
|
+
# hook injects context when trusted and child-side loading remains the fallback
|
|
119
|
+
# when it is unavailable. "sub-agent" remains a backwards-compatible alias
|
|
120
|
+
# for "auto". Invalid explicit values safely use inline mode.
|
|
121
121
|
#
|
|
122
122
|
# In "auto" mode, dispatched sub-agents inherit the main session's model
|
|
123
123
|
# unless you pin one. To use a cheaper/faster model for implement/check/
|
|
@@ -127,7 +127,7 @@ channel:
|
|
|
127
127
|
# `trellis update` preserves your edits across regeneration.
|
|
128
128
|
#
|
|
129
129
|
# codex:
|
|
130
|
-
# dispatch_mode: auto #
|
|
130
|
+
# dispatch_mode: auto # opt in to native sub-agents; default: "inline"; legacy alias: "sub-agent"
|
|
131
131
|
|
|
132
132
|
#-------------------------------------------------------------------------------
|
|
133
133
|
# Sub-agent context injection limits
|
|
@@ -45,12 +45,15 @@ export declare const initDeveloperScript: string;
|
|
|
45
45
|
export declare const taskScript: string;
|
|
46
46
|
export declare const getContextScript: string;
|
|
47
47
|
export declare const addSessionScript: string;
|
|
48
|
+
export declare const subnodeArtifactScript: string;
|
|
49
|
+
export declare const workspaceNoteScript: string;
|
|
48
50
|
export declare const workflowMdTemplate: string;
|
|
49
51
|
export declare const configYamlTemplate: string;
|
|
50
52
|
export declare const gitignoreTemplate: string;
|
|
51
53
|
export declare const gitattributesTemplate: string;
|
|
52
54
|
export declare const implementAgentTemplate: string;
|
|
53
55
|
export declare const checkAgentTemplate: string;
|
|
56
|
+
export declare const subnodeAgentTemplate: string;
|
|
54
57
|
/**
|
|
55
58
|
* Get all script templates as a map of relative path to content
|
|
56
59
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/templates/trellis/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAcH,eAAO,MAAM,WAAW,QAAsC,CAAC;AAG/D,eAAO,MAAM,UAAU,QAA6C,CAAC;AACrE,eAAO,MAAM,WAAW,QAA0C,CAAC;AACnE,eAAO,MAAM,eAAe,QAA8C,CAAC;AAC3E,eAAO,MAAM,gBAAgB,QAAgD,CAAC;AAC9E,eAAO,MAAM,eAAe,QAA+C,CAAC;AAC5E,eAAO,MAAM,eAAe,QAA+C,CAAC;AAC5E,eAAO,MAAM,gBAAgB,QAAgD,CAAC;AAC9E,eAAO,MAAM,gBAAgB,QAAgD,CAAC;AAC9E,eAAO,MAAM,YAAY,QAA2C,CAAC;AACrE,eAAO,MAAM,QAAQ,QAAuC,CAAC;AAC7D,eAAO,MAAM,SAAS,QAAwC,CAAC;AAC/D,eAAO,MAAM,SAAS,QAAwC,CAAC;AAC/D,eAAO,MAAM,WAAW,QAA0C,CAAC;AACnE,eAAO,MAAM,WAAW,QAA0C,CAAC;AACnE,eAAO,MAAM,iBAAiB,QAAiD,CAAC;AAChF,eAAO,MAAM,eAAe,QAA+C,CAAC;AAC5E,eAAO,MAAM,oBAAoB,QAEhC,CAAC;AACF,eAAO,MAAM,qBAAqB,QAEjC,CAAC;AACF,eAAO,MAAM,mBAAmB,QAE/B,CAAC;AACF,eAAO,MAAM,mBAAmB,QAE/B,CAAC;AACF,eAAO,MAAM,gBAAgB,QAAgD,CAAC;AAG9E,eAAO,MAAM,kBAAkB,QAA2C,CAAC;AAC3E,eAAO,MAAM,mBAAmB,QAA4C,CAAC;AAC7E,eAAO,MAAM,UAAU,QAAkC,CAAC;AAC1D,eAAO,MAAM,gBAAgB,QAAyC,CAAC;AACvE,eAAO,MAAM,gBAAgB,QAAyC,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/templates/trellis/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAcH,eAAO,MAAM,WAAW,QAAsC,CAAC;AAG/D,eAAO,MAAM,UAAU,QAA6C,CAAC;AACrE,eAAO,MAAM,WAAW,QAA0C,CAAC;AACnE,eAAO,MAAM,eAAe,QAA8C,CAAC;AAC3E,eAAO,MAAM,gBAAgB,QAAgD,CAAC;AAC9E,eAAO,MAAM,eAAe,QAA+C,CAAC;AAC5E,eAAO,MAAM,eAAe,QAA+C,CAAC;AAC5E,eAAO,MAAM,gBAAgB,QAAgD,CAAC;AAC9E,eAAO,MAAM,gBAAgB,QAAgD,CAAC;AAC9E,eAAO,MAAM,YAAY,QAA2C,CAAC;AACrE,eAAO,MAAM,QAAQ,QAAuC,CAAC;AAC7D,eAAO,MAAM,SAAS,QAAwC,CAAC;AAC/D,eAAO,MAAM,SAAS,QAAwC,CAAC;AAC/D,eAAO,MAAM,WAAW,QAA0C,CAAC;AACnE,eAAO,MAAM,WAAW,QAA0C,CAAC;AACnE,eAAO,MAAM,iBAAiB,QAAiD,CAAC;AAChF,eAAO,MAAM,eAAe,QAA+C,CAAC;AAC5E,eAAO,MAAM,oBAAoB,QAEhC,CAAC;AACF,eAAO,MAAM,qBAAqB,QAEjC,CAAC;AACF,eAAO,MAAM,mBAAmB,QAE/B,CAAC;AACF,eAAO,MAAM,mBAAmB,QAE/B,CAAC;AACF,eAAO,MAAM,gBAAgB,QAAgD,CAAC;AAG9E,eAAO,MAAM,kBAAkB,QAA2C,CAAC;AAC3E,eAAO,MAAM,mBAAmB,QAA4C,CAAC;AAC7E,eAAO,MAAM,UAAU,QAAkC,CAAC;AAC1D,eAAO,MAAM,gBAAgB,QAAyC,CAAC;AACvE,eAAO,MAAM,gBAAgB,QAAyC,CAAC;AACvE,eAAO,MAAM,qBAAqB,QAEjC,CAAC;AACF,eAAO,MAAM,mBAAmB,QAA4C,CAAC;AAG7E,eAAO,MAAM,kBAAkB,QAA8B,CAAC;AAC9D,eAAO,MAAM,kBAAkB,QAA8B,CAAC;AAC9D,eAAO,MAAM,iBAAiB,QAAgC,CAAC;AAC/D,eAAO,MAAM,qBAAqB,QAAoC,CAAC;AAMvE,eAAO,MAAM,sBAAsB,QAAsC,CAAC;AAC1E,eAAO,MAAM,kBAAkB,QAAkC,CAAC;AAClE,eAAO,MAAM,oBAAoB,QAAoC,CAAC;AAEtE;;GAEG;AACH,wBAAgB,aAAa,IAAI,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAuCnD;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,IAAI,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAMlD"}
|