@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.
Files changed (35) hide show
  1. package/dist/commands/channel/adapters/codex.d.ts +14 -0
  2. package/dist/commands/channel/adapters/codex.d.ts.map +1 -1
  3. package/dist/commands/channel/adapters/codex.js +37 -0
  4. package/dist/commands/channel/adapters/codex.js.map +1 -1
  5. package/dist/commands/channel/adapters/index.d.ts.map +1 -1
  6. package/dist/commands/channel/adapters/index.js +49 -13
  7. package/dist/commands/channel/adapters/index.js.map +1 -1
  8. package/dist/commands/channel/index.d.ts.map +1 -1
  9. package/dist/commands/channel/index.js +17 -1
  10. package/dist/commands/channel/index.js.map +1 -1
  11. package/dist/commands/channel/wait.d.ts +4 -0
  12. package/dist/commands/channel/wait.d.ts.map +1 -1
  13. package/dist/commands/channel/wait.js +8 -1
  14. package/dist/commands/channel/wait.js.map +1 -1
  15. package/dist/migrations/manifests/0.6.19.json +9 -0
  16. package/dist/migrations/manifests/0.6.20.json +9 -0
  17. package/dist/templates/common/bundled-skills/trellis-channel/SKILL.md +2 -0
  18. package/dist/templates/common/bundled-skills/trellis-channel/references/command-reference.md +35 -5
  19. package/dist/templates/common/bundled-skills/trellis-channel/references/progress-debugging.md +24 -13
  20. package/dist/templates/common/bundled-skills/trellis-channel/references/subnode-work.md +159 -0
  21. package/dist/templates/common/bundled-skills/trellis-channel/references/workflows.md +6 -3
  22. package/dist/templates/shared-hooks/inject-workflow-state.py +17 -16
  23. package/dist/templates/trellis/agents/subnode.md +62 -0
  24. package/dist/templates/trellis/config.yaml +9 -9
  25. package/dist/templates/trellis/index.d.ts +3 -0
  26. package/dist/templates/trellis/index.d.ts.map +1 -1
  27. package/dist/templates/trellis/index.js +6 -0
  28. package/dist/templates/trellis/index.js.map +1 -1
  29. package/dist/templates/trellis/scripts/common/config.py +5 -4
  30. package/dist/templates/trellis/scripts/common/task_store.py +3 -3
  31. package/dist/templates/trellis/scripts/common/workflow_phase.py +1 -1
  32. package/dist/templates/trellis/scripts/subnode_artifact.py +498 -0
  33. package/dist/templates/trellis/scripts/workspace_note.py +126 -0
  34. package/dist/templates/trellis/workflow.md +5 -5
  35. package/package.json +2 -2
@@ -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 | Purpose |
437
- |---|---|
438
- | `channel __supervisor <channel> <worker> <config>` | Forked entry point invoked by `spawn`. Do not invoke directly. |
439
- | `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. |
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
-
@@ -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 *interface* — reach
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` watches `events.jsonl` from EOF and wakes on:
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 --tag interrupt --timeout 1h
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 | Cause | Fix |
196
- |---|---|---|
197
- | `trellis: command not found` | CLI not installed globally | `npm install -g @pennixrv/trellis` |
198
- | `wait` exits immediately | wrong filter or identity collision | use distinct `--as`, inspect raw messages |
199
- | zsh errors on message text | shell interpreted punctuation | use `--stdin` or `--text-file` |
200
- | progress line is cut off | pretty output truncation | use `messages --raw --kind progress` |
201
- | worker never speaks | provider startup / prompt / MCP delay | inspect `<worker>.log`, `ps`, raw events |
202
- | channel not found in another cwd | project bucket mismatch | `cd` to project, use `--scope global`, or `list --all-projects` |
203
- | ghost worker in list | supervisor died without cleanup | `trellis channel kill <name> --as <worker> --force` |
204
- | forum thread looks scrambled | parsed `events.jsonl` directly | use `forum`, `thread`, `messages --thread` |
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 `auto`. The legacy `sub-agent` value is an alias for `auto`.
290
- Any other explicit value (including invalid ones) falls back to `inline`
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 = "auto"
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
- `auto`, which dispatches Trellis sub-agents using native Codex context
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. `inline` is an explicit opt-out; the
318
- legacy `sub-agent` value is an alias for `auto`. Invalid explicit values
319
- fall back to `inline` without per-turn warnings. The banner makes the
320
- active mode explicit to Codex AI per turn, complementing the workflow-state
321
- body which is per-status. Mode tells AI which dispatch protocol to follow;
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 ``auto`` and therefore uses the ordinary ``<status>``
345
- breadcrumb for native SubagentStart dispatch with child-side fallback;
346
- it does not depend on an inherited parent transcript. ``inline`` selects
347
- the parallel ``<status>-inline`` tag; ``sub-agent`` remains an alias for
348
- ``auto``. Invalid explicit values fall back to inline without per-turn
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. Default ("auto") dispatches
114
- # trellis-implement / trellis-check / trellis-research sub-agents. This does
115
- # not rely on inherited parent transcripts: `fork_turns` remains
116
- # caller-controlled, while Codex's native SubagentStart hook injects task
117
- # context when trusted and child-side loading remains the fallback when it is
118
- # unavailable. Set to "inline" only to keep implementation and checks in the
119
- # main session. "sub-agent" remains a backwards-compatible alias for "auto".
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 # or "inline"; legacy alias: "sub-agent"
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;AAGvE,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;AAElE;;GAEG;AACH,wBAAgB,aAAa,IAAI,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAqCnD;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,IAAI,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAKlD"}
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"}