@pennixrv/trellis 0.7.0-beta.6 → 0.7.0-beta.8
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/migrations/manifests/0.7.0-beta.7.json +9 -0
- package/dist/migrations/manifests/0.7.0-beta.8.json +9 -0
- package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-task-lifecycle.md +1 -0
- package/dist/templates/common/bundled-skills/trellis-session-insight/SKILL.md +1 -1
- package/dist/templates/common/bundled-skills/trellis-session-insight/references/cli-quick-reference.md +1 -1
- package/dist/templates/common/commands/continue.md +2 -0
- package/dist/templates/common/skills/brainstorm.md +5 -5
- package/dist/templates/copilot/prompts/brainstorm.prompt.md +5 -5
- package/dist/templates/shared-hooks/inject-shell-session-context.py +3 -3
- package/dist/templates/trellis/config.yaml +2 -0
- package/dist/templates/trellis/scripts/common/active_task.py +2 -2
- package/dist/templates/trellis/scripts/task.py +77 -0
- package/dist/templates/trellis/workflow.md +6 -3
- package/package.json +2 -2
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "0.7.0-beta.7",
|
|
3
|
+
"description": "Pennix v0.7 beta release verification normalization",
|
|
4
|
+
"breaking": false,
|
|
5
|
+
"recommendMigrate": false,
|
|
6
|
+
"changelog": "**Bug Fixes:**\n- Normalize npm's single-item JSON array response during local and CI visibility verification.",
|
|
7
|
+
"migrations": [],
|
|
8
|
+
"notes": "Run `npm install -g @pennixrv/trellis@beta` then `trellis update`. No `--migrate` required."
|
|
9
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "0.7.0-beta.8",
|
|
3
|
+
"description": "Pennix v0.7 beta decision-chain replanning",
|
|
4
|
+
"breaking": false,
|
|
5
|
+
"recommendMigrate": false,
|
|
6
|
+
"changelog": "**Features:**\n- Add an auditable same-task replan transition for material implementation-time decisions.\n- Preserve every planning interval in `trellis mem --phase brainstorm`.",
|
|
7
|
+
"migrations": [],
|
|
8
|
+
"notes": "Run `npm install -g @pennixrv/trellis@beta` then `trellis update`. No `--migrate` required."
|
|
9
|
+
}
|
|
@@ -17,6 +17,7 @@ Task lifecycle includes creation, start, context configuration, finish, archive,
|
|
|
17
17
|
| --- | --- |
|
|
18
18
|
| Automatically sync an external system after task creation | `hooks.after_create` in `.trellis/config.yaml`. |
|
|
19
19
|
| Automatically update status after task start | `hooks.after_start` in `.trellis/config.yaml`. |
|
|
20
|
+
| Return an in-progress task to planning | `hooks.after_replan` in `.trellis/config.yaml`. |
|
|
20
21
|
| Run a script after task finish | `hooks.after_finish` in `.trellis/config.yaml`. |
|
|
21
22
|
| Clean external resources after archive | `hooks.after_archive` in `.trellis/config.yaml`. |
|
|
22
23
|
| Change default task fields | `.trellis/scripts/common/task_store.py`. |
|
|
@@ -68,7 +68,7 @@ trellis mem list --cwd <project-path>
|
|
|
68
68
|
trellis mem projects # → list active project cwds, then narrow
|
|
69
69
|
```
|
|
70
70
|
|
|
71
|
-
Phase slicing (`--phase brainstorm|implement|all`) cuts the session at `task.py create` and `task.py start` boundaries. For a finish-work review of the current task, `--phase brainstorm` recovers the planning discussion and `--phase implement` recovers the execution loop. Default is `all`.
|
|
71
|
+
Phase slicing (`--phase brainstorm|implement|all`) cuts the session at `task.py create`/`replan` and `task.py start` boundaries. For a finish-work review of the current task, `--phase brainstorm` recovers the planning discussion and `--phase implement` recovers the execution loop. Default is `all`.
|
|
72
72
|
|
|
73
73
|
## Triggering patterns
|
|
74
74
|
|
|
@@ -23,7 +23,7 @@ Full flag reference for the five subcommands. Pin this as the authoritative sour
|
|
|
23
23
|
| `--cwd <path>` | list / search | Force a specific project cwd instead of inferring from where you are. |
|
|
24
24
|
| `--limit N` | list / search | Cap output rows. Default `50`. |
|
|
25
25
|
| `--grep KW` | extract / context | Filter turns by keyword. Multi-token AND when whitespace-separated. |
|
|
26
|
-
| `--phase brainstorm\|implement\|all` | extract | Slice session by Trellis task boundaries. `brainstorm` = `[task.py create, task.py start)`. `implement` = turns outside brainstorm windows. Default `all`. |
|
|
26
|
+
| `--phase brainstorm\|implement\|all` | extract | Slice session by Trellis task boundaries. `brainstorm` = `[task.py create/replan, task.py start)`. `implement` = turns outside brainstorm windows. Default `all`. |
|
|
27
27
|
| `--turns N` | context | Number of hit turns to return. Default `3`. |
|
|
28
28
|
| `--around N` | context | Surrounding turns to include per hit. Default `1`. |
|
|
29
29
|
| `--max-chars N` | context | Total character budget. Default `6000` (~1500 tokens). |
|
|
@@ -26,6 +26,8 @@ Shows the Phase Index (Plan / Execute / Finish) with routing + skill mapping.
|
|
|
26
26
|
|
|
27
27
|
- `status=planning` + `task.json.meta.delivery_mode = "analysis_only"` → complete the PRD's bounded evidence work, verify its acceptance criteria and no-change boundary, then commit task artifacts and archive directly. Do not run `task.py start`; a protected-target change requires a separate change-bearing task.
|
|
28
28
|
- `status=planning` + no `prd.md` → **1.1** (load `trellis-brainstorm`)
|
|
29
|
+
- `status=planning` + a recorded `decision-needed` or unsealed decision chain → return to the planning frontier and load `pennix-decision-gates` when independent material questions can be batched.
|
|
30
|
+
- `status=in_progress` + a material unresolved decision → record the reason and run `task.py replan <task> "<reason>"`; do not ask a native question during implementation.
|
|
29
31
|
- `status=planning` + `prd.md` only → decide whether the task is lightweight or complex. Lightweight can move to **1.4** review; complex returns to **1.1** to add `design.md` + `implement.md`.
|
|
30
32
|
- `status=planning` + complex artifacts complete + sub-agent jsonl not curated (empty, or only a legacy `_example` placeholder row) → **1.3**
|
|
31
33
|
- `status=planning` + required artifacts complete + required jsonl curated or inline mode → **1.4** (ask for start review; only run `task.py start` after user confirms)
|
|
@@ -6,7 +6,7 @@ A request to build, implement, fix, refactor, or "go ahead" is not approval to l
|
|
|
6
6
|
|
|
7
7
|
For every non-trivial task, the user must respond at least once after the initial request before implementation begins. If no clarification is needed, that response must approve the final planning summary described below.
|
|
8
8
|
|
|
9
|
-
While any user-owned product, scope, UX, compatibility, risk, or acceptance decision remains unresolved,
|
|
9
|
+
While any user-owned product, scope, UX, compatibility, risk, or acceptance decision remains unresolved, keep the task in planning. First inventory evidence and decision dependencies. If at least two independent material decisions remain and `pennix-decision-gates` is available, delegate one bounded batch of up to three frontier questions; otherwise ask the single highest-value question. Do not edit product code, dispatch implementation, or run `task.py start` until the decision chain is sealed.
|
|
10
10
|
|
|
11
11
|
## Analysis-Only Exception
|
|
12
12
|
|
|
@@ -54,18 +54,18 @@ Use a concise title from the user's request. Both the title and `--description`
|
|
|
54
54
|
- product intent still needed from the user
|
|
55
55
|
- scope or risk decisions still needed from the user
|
|
56
56
|
- likely out-of-scope items
|
|
57
|
-
4. If
|
|
58
|
-
5. After each
|
|
57
|
+
4. If user-owned decisions remain, calculate the independent frontier. Use `pennix-decision-gates` for a bounded batch when two or more independent material decisions are ready; otherwise ask the single highest-value question. Include recommendation and trade-off, then stop the turn for native input.
|
|
58
|
+
5. After each answer batch, update `prd.md`, record the selected decisions, recheck evidence and conflicts, and repeat from step 2. Do not create a second Trellis lifecycle for the same decision chain.
|
|
59
59
|
6. When no user-owned decision remains, create or update `design.md` and `implement.md` for complex tasks.
|
|
60
60
|
7. Run the requirement convergence gate, then the PRD convergence pass.
|
|
61
61
|
8. Present the final planning summary and stop. Do not run `task.py start` or edit product code in the same turn.
|
|
62
|
-
9. Only a subsequent user message that explicitly approves the latest planning summary authorizes `task.py start` and implementation. If
|
|
62
|
+
9. Only a subsequent user message that explicitly approves the latest planning summary authorizes `task.py start` and implementation. If implementation reveals a material unresolved decision, record `decision-needed`, run `task.py replan <task> "<reason>"`, and return through this planning flow; do not open a popup during implementation.
|
|
63
63
|
|
|
64
64
|
Do not invent a project-specific product/spec hierarchy. If the repository already has product, domain, or spec docs, use them. If it does not, proceed with the evidence that exists.
|
|
65
65
|
|
|
66
66
|
## Question Rules
|
|
67
67
|
|
|
68
|
-
Ask
|
|
68
|
+
Ask one bounded batch per message: include up to three independent material frontier questions. Ask exactly one question only when it is the sole remaining material decision or later decisions depend on its answer.
|
|
69
69
|
|
|
70
70
|
Each question must include:
|
|
71
71
|
|
|
@@ -10,7 +10,7 @@ A request to build, implement, fix, refactor, or "go ahead" is not approval to l
|
|
|
10
10
|
|
|
11
11
|
For every non-trivial task, the user must respond at least once after the initial request before implementation begins. If no clarification is needed, that response must approve the final planning summary described below.
|
|
12
12
|
|
|
13
|
-
While any user-owned product, scope, UX, compatibility, risk, or acceptance decision remains unresolved,
|
|
13
|
+
While any user-owned product, scope, UX, compatibility, risk, or acceptance decision remains unresolved, keep the task in planning. First inventory evidence and decision dependencies. If at least two independent material decisions remain and `pennix-decision-gates` is available, delegate one bounded batch of up to three frontier questions; otherwise ask the single highest-value question. Do not edit product code, dispatch implementation, or run `task.py start` until the decision chain is sealed.
|
|
14
14
|
|
|
15
15
|
## Non-Negotiable Evidence Rule
|
|
16
16
|
|
|
@@ -52,18 +52,18 @@ Use a concise title from the user's request. Both the title and `--description`
|
|
|
52
52
|
- product intent still needed from the user
|
|
53
53
|
- scope or risk decisions still needed from the user
|
|
54
54
|
- likely out-of-scope items
|
|
55
|
-
4. If
|
|
56
|
-
5. After each
|
|
55
|
+
4. If user-owned decisions remain, calculate the independent frontier. Use `pennix-decision-gates` for a bounded batch when two or more independent material decisions are ready; otherwise ask the single highest-value question. Include recommendation and trade-off, then stop the turn for native input.
|
|
56
|
+
5. After each answer batch, update `prd.md`, record the selected decisions, recheck evidence and conflicts, and repeat from step 2. Do not create a second Trellis lifecycle for the same decision chain.
|
|
57
57
|
6. When no user-owned decision remains, create or update `design.md` and `implement.md` for complex tasks.
|
|
58
58
|
7. Run the requirement convergence gate, then the PRD convergence pass.
|
|
59
59
|
8. Present the final planning summary and stop. Do not run `task.py start` or edit product code in the same turn.
|
|
60
|
-
9. Only a subsequent user message that explicitly approves the latest planning summary authorizes `task.py start` and implementation. If
|
|
60
|
+
9. Only a subsequent user message that explicitly approves the latest planning summary authorizes `task.py start` and implementation. If implementation reveals a material unresolved decision, record `decision-needed`, run `task.py replan <task> "<reason>"`, and return through this planning flow; do not open a popup during implementation.
|
|
61
61
|
|
|
62
62
|
Do not invent a project-specific product/spec hierarchy. If the repository already has product, domain, or spec docs, use them. If it does not, proceed with the evidence that exists.
|
|
63
63
|
|
|
64
64
|
## Question Rules
|
|
65
65
|
|
|
66
|
-
Ask
|
|
66
|
+
Ask one bounded batch per message: include up to three independent material frontier questions. Ask exactly one question only when it is the sole remaining material decision or later decisions depend on its answer.
|
|
67
67
|
|
|
68
68
|
Each question must include:
|
|
69
69
|
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
No researched platform exports a session id into its shell tool's child
|
|
5
5
|
process, but every hook-capable one puts that id on hook stdin. So the hook
|
|
6
6
|
that fires just before a shell command writes a short-lived runtime ticket
|
|
7
|
-
whenever the pending command calls `task.py start/current/finish`, and the
|
|
7
|
+
whenever the pending command calls `task.py start/replan/current/finish`, and the
|
|
8
8
|
task script consumes it when it has no native session environment.
|
|
9
9
|
|
|
10
10
|
Registered on whichever pre-shell event the host provides — Cursor's
|
|
@@ -35,7 +35,7 @@ if callable(_stdin_reconfigure):
|
|
|
35
35
|
DIR_WORKFLOW = ".trellis"
|
|
36
36
|
DIR_RUNTIME = ".runtime"
|
|
37
37
|
DIR_SHELL_TICKETS = "shell-tickets"
|
|
38
|
-
SESSION_SUBCOMMANDS = {"start", "current", "finish"}
|
|
38
|
+
SESSION_SUBCOMMANDS = {"start", "replan", "current", "finish"}
|
|
39
39
|
TICKET_TTL_SECONDS = 30
|
|
40
40
|
CONTEXT_IDENTITY_KEYS = (
|
|
41
41
|
"session_id",
|
|
@@ -177,7 +177,7 @@ def _extract_task_subcommands(command: str) -> list[dict[str, str]]:
|
|
|
177
177
|
if name not in SESSION_SUBCOMMANDS:
|
|
178
178
|
continue
|
|
179
179
|
item = {"name": name}
|
|
180
|
-
if name
|
|
180
|
+
if name in {"start", "replan"} and index + 2 < len(tokens):
|
|
181
181
|
item["task_ref"] = tokens[index + 2]
|
|
182
182
|
subcommands.append(item)
|
|
183
183
|
return subcommands
|
|
@@ -33,7 +33,7 @@ DIR_SHELL_TICKETS = "shell-tickets"
|
|
|
33
33
|
# platform that works today.
|
|
34
34
|
DIR_LEGACY_CURSOR_SHELL_TICKETS = "cursor-shell"
|
|
35
35
|
SHELL_TICKET_TTL_SECONDS = 30
|
|
36
|
-
TASK_SESSION_COMMANDS = {"start", "current", "finish"}
|
|
36
|
+
TASK_SESSION_COMMANDS = {"start", "replan", "current", "finish"}
|
|
37
37
|
|
|
38
38
|
_SESSION_KEYS = ("session_id", "sessionId", "sessionID")
|
|
39
39
|
_CONVERSATION_KEYS = ("conversation_id", "conversationId", "conversationID")
|
|
@@ -425,7 +425,7 @@ def _pending_ticket_matches_args(ticket: dict[str, Any], repo_root: Path) -> boo
|
|
|
425
425
|
continue
|
|
426
426
|
if _string_value(subcommand.get("name")) != command_name:
|
|
427
427
|
continue
|
|
428
|
-
if command_name
|
|
428
|
+
if command_name not in {"start", "replan"}:
|
|
429
429
|
return True
|
|
430
430
|
task_ref = args[1] if len(args) > 1 else None
|
|
431
431
|
if _task_refs_match(_string_value(subcommand.get("task_ref")), task_ref, repo_root):
|
|
@@ -9,6 +9,7 @@ Usage:
|
|
|
9
9
|
python3 task.py validate <dir> # Validate jsonl files
|
|
10
10
|
python3 task.py list-context <dir> # List jsonl entries
|
|
11
11
|
python3 task.py start <dir> # Set active task, record current branch
|
|
12
|
+
python3 task.py replan <dir> "<reason>" # Return an in-progress task to planning
|
|
12
13
|
python3 task.py current [--source] [--json] # Show active task
|
|
13
14
|
python3 task.py ownership <operation> ... # Manage formal handoff task ownership
|
|
14
15
|
python3 task.py finish # Clear active task
|
|
@@ -29,7 +30,9 @@ from __future__ import annotations
|
|
|
29
30
|
|
|
30
31
|
import argparse
|
|
31
32
|
import json
|
|
33
|
+
import os
|
|
32
34
|
import sys
|
|
35
|
+
from datetime import datetime, timezone
|
|
33
36
|
from pathlib import Path
|
|
34
37
|
|
|
35
38
|
from common.log import Colors, colored
|
|
@@ -301,6 +304,74 @@ def cmd_start(args: argparse.Namespace) -> int:
|
|
|
301
304
|
return 1
|
|
302
305
|
|
|
303
306
|
|
|
307
|
+
def cmd_replan(args: argparse.Namespace) -> int:
|
|
308
|
+
"""Return an in-progress task to planning without losing its binding."""
|
|
309
|
+
repo_root = get_repo_root()
|
|
310
|
+
full_path = resolve_task_dir(args.dir, repo_root)
|
|
311
|
+
if full_path is None or not full_path.is_dir():
|
|
312
|
+
print(colored(f"Error: Task not found: {args.dir}", Colors.RED), file=sys.stderr)
|
|
313
|
+
return 1
|
|
314
|
+
|
|
315
|
+
try:
|
|
316
|
+
assert_task_mutation_allowed(repo_root, full_path)
|
|
317
|
+
except (OwnershipError, OSError) as exc:
|
|
318
|
+
print(colored(f"Error: {exc}", Colors.RED), file=sys.stderr)
|
|
319
|
+
return 2
|
|
320
|
+
|
|
321
|
+
reason = " ".join(args.reason).strip()
|
|
322
|
+
if not reason:
|
|
323
|
+
print(colored("Error: replan reason must not be empty", Colors.RED), file=sys.stderr)
|
|
324
|
+
return 1
|
|
325
|
+
|
|
326
|
+
task_json_path = full_path / FILE_TASK_JSON
|
|
327
|
+
data, read_reason = read_json_checked(task_json_path)
|
|
328
|
+
if data is None:
|
|
329
|
+
problem, hint = describe_json_read_failure(task_json_path, read_reason)
|
|
330
|
+
print(colored(f"Error: {problem}", Colors.RED), file=sys.stderr)
|
|
331
|
+
print(hint, file=sys.stderr)
|
|
332
|
+
return 1
|
|
333
|
+
if data.get("status") != "in_progress":
|
|
334
|
+
print(
|
|
335
|
+
colored(
|
|
336
|
+
f"Error: replan requires status=in_progress (found {data.get('status')!r})",
|
|
337
|
+
Colors.RED,
|
|
338
|
+
),
|
|
339
|
+
file=sys.stderr,
|
|
340
|
+
)
|
|
341
|
+
return 1
|
|
342
|
+
|
|
343
|
+
event = {
|
|
344
|
+
"timestamp": datetime.now(timezone.utc).isoformat().replace("+00:00", "Z"),
|
|
345
|
+
"task": full_path.relative_to(repo_root).as_posix(),
|
|
346
|
+
"from_status": "in_progress",
|
|
347
|
+
"reason": reason,
|
|
348
|
+
"branch": data.get("branch"),
|
|
349
|
+
}
|
|
350
|
+
context_key = resolve_context_key()
|
|
351
|
+
if context_key:
|
|
352
|
+
event["session"] = context_key
|
|
353
|
+
|
|
354
|
+
replans_path = full_path / "replans.jsonl"
|
|
355
|
+
try:
|
|
356
|
+
with replans_path.open("a", encoding="utf-8") as handle:
|
|
357
|
+
handle.write(json.dumps(event, ensure_ascii=False) + "\n")
|
|
358
|
+
handle.flush()
|
|
359
|
+
os.fsync(handle.fileno())
|
|
360
|
+
except OSError as exc:
|
|
361
|
+
print(colored(f"Error: could not record replan: {exc}", Colors.RED), file=sys.stderr)
|
|
362
|
+
return 1
|
|
363
|
+
|
|
364
|
+
data["status"] = "planning"
|
|
365
|
+
if not write_json(task_json_path, data):
|
|
366
|
+
print(colored("Error: replan event recorded but task status was not changed", Colors.RED), file=sys.stderr)
|
|
367
|
+
return 1
|
|
368
|
+
|
|
369
|
+
print(colored(f"✓ Task returned to planning: {full_path.relative_to(repo_root)}", Colors.GREEN))
|
|
370
|
+
print("Reason:", reason)
|
|
371
|
+
run_task_hooks("after_replan", task_json_path, repo_root)
|
|
372
|
+
return 0
|
|
373
|
+
|
|
374
|
+
|
|
304
375
|
def cmd_finish(args: argparse.Namespace) -> int:
|
|
305
376
|
"""Clear active task."""
|
|
306
377
|
repo_root = get_repo_root()
|
|
@@ -900,6 +971,11 @@ def main() -> int:
|
|
|
900
971
|
help="Start even when implement.jsonl / check.jsonl have no curated entries",
|
|
901
972
|
)
|
|
902
973
|
|
|
974
|
+
# replan
|
|
975
|
+
p_replan = subparsers.add_parser("replan", help="Return an in-progress task to planning")
|
|
976
|
+
p_replan.add_argument("dir", help="Task directory")
|
|
977
|
+
p_replan.add_argument("reason", nargs="+", help="Material reason for returning to planning")
|
|
978
|
+
|
|
903
979
|
# current
|
|
904
980
|
p_current = subparsers.add_parser("current", help="Show active task")
|
|
905
981
|
p_current.add_argument("--source", action="store_true",
|
|
@@ -1047,6 +1123,7 @@ def main() -> int:
|
|
|
1047
1123
|
"validate": cmd_validate,
|
|
1048
1124
|
"list-context": cmd_list_context,
|
|
1049
1125
|
"start": cmd_start,
|
|
1126
|
+
"replan": cmd_replan,
|
|
1050
1127
|
"current": cmd_current,
|
|
1051
1128
|
"continuity": cmd_continuity,
|
|
1052
1129
|
"ownership": cmd_ownership,
|
|
@@ -45,6 +45,7 @@ Every task has its own directory under `.trellis/tasks/{MM-DD-name}/` holding `t
|
|
|
45
45
|
# Task lifecycle
|
|
46
46
|
python3 ./.trellis/scripts/task.py create "<title>" [--slug <name>] [--parent <dir>]
|
|
47
47
|
python3 ./.trellis/scripts/task.py start <name> # set active task (session-scoped when available)
|
|
48
|
+
python3 ./.trellis/scripts/task.py replan <name> "<reason>" # return material ambiguity to planning
|
|
48
49
|
python3 ./.trellis/scripts/task.py current --source # show active task and source
|
|
49
50
|
python3 ./.trellis/scripts/task.py finish # clear active task (triggers after_finish hooks)
|
|
50
51
|
python3 ./.trellis/scripts/task.py archive <name> # move to archive/{year-month}/
|
|
@@ -229,7 +230,7 @@ Preserve existing task fields and artifacts. If the correct status cannot be det
|
|
|
229
230
|
[workflow-state:planning]
|
|
230
231
|
Load `trellis-brainstorm`; stay in planning.
|
|
231
232
|
If `task.json.meta.delivery_mode = "analysis_only"` exactly, complete the declared evidence work now. Do not wait for a start review or run `task.py start`; when the PRD boundary and acceptance evidence pass, commit task artifacts and archive directly. A protected-target recommendation requires a separate change-bearing task.
|
|
232
|
-
Lightweight: `prd.md` can be enough. Complex: finish `prd.md`, `design.md`, and `implement.md`; ask for review before `task.py start`.
|
|
233
|
+
Lightweight: `prd.md` can be enough. Complex: finish `prd.md`, `design.md`, and `implement.md`; ask for review before `task.py start`. If `decision-needed` items or an unsealed decision graph remain, load `pennix-decision-gates`, batch only independent frontier questions, and stay in planning.
|
|
233
234
|
Multi-deliverable scope: consider a parent task plus independently verifiable child tasks; dependencies must be written in child artifacts, not implied by tree position.
|
|
234
235
|
Sub-agent mode: curate `implement.jsonl` and `check.jsonl` as spec/research manifests before start.
|
|
235
236
|
[/workflow-state:planning]
|
|
@@ -243,7 +244,7 @@ Sub-agent mode: curate `implement.jsonl` and `check.jsonl` as spec/research mani
|
|
|
243
244
|
[workflow-state:planning-inline]
|
|
244
245
|
Load `trellis-brainstorm`; stay in planning.
|
|
245
246
|
If `task.json.meta.delivery_mode = "analysis_only"` exactly, complete the declared evidence work now. Do not wait for a start review or run `task.py start`; when the PRD boundary and acceptance evidence pass, commit task artifacts and archive directly. A protected-target recommendation requires a separate change-bearing task.
|
|
246
|
-
Lightweight: `prd.md` can be enough. Complex: finish `prd.md`, `design.md`, and `implement.md`; ask for review before `task.py start`.
|
|
247
|
+
Lightweight: `prd.md` can be enough. Complex: finish `prd.md`, `design.md`, and `implement.md`; ask for review before `task.py start`. If `decision-needed` items or an unsealed decision graph remain, load `pennix-decision-gates`, batch only independent frontier questions, and stay in planning.
|
|
247
248
|
Multi-deliverable scope: consider a parent task plus independently verifiable child tasks; dependencies must be written in child artifacts, not implied by tree position.
|
|
248
249
|
Inline mode: skip jsonl curation; Phase 2 reads artifacts/specs via `trellis-before-dev`.
|
|
249
250
|
[/workflow-state:planning-inline]
|
|
@@ -262,6 +263,7 @@ Inline mode: skip jsonl curation; Phase 2 reads artifacts/specs via `trellis-bef
|
|
|
262
263
|
Sub-agent dispatch protocol applies to all platforms and all sub-agents, including native Codex `SubagentStart` context injection with child-side pull fallback, class-2 Gemini/Qoder/Copilot/Reasonix/Trae/Grok/Kimi Code/DeepSeek Harness, hook-backed ZCode/Snow, and `trellis-research`: every dispatch prompt starts with `Active task: <task path from task.py current>` before role-specific instructions. On Grok Build, use `spawn_subagent` with `subagent_type` set to the Trellis agent name (e.g. `trellis-implement`). On Kimi Code, dispatch the built-in `coder` / `explore` sub-agent with the matching `.kimi-code/skills/trellis-<role>/SKILL.md` instructions. On DeepSeek Harness, tell the child to load the matching `.dsh/skills/trellis-agent-<role>/SKILL.md` exactly once, then choose the synchronization path by capability. If the optional companion plugin exposes `trellis_wait`, dispatch `subagent` in its default continuable background mode, continue independent work, and call `trellis_wait` once per dependent child id when a dependent gate is next; each call returns only after DSH has queued that child's native settlement notice. Without `trellis_wait`, dispatch each child with `run_in_background: false` from the outset so no dependent gate can overtake it. Never simulate waiting with shell sleep, polling loops, `job_output`, repeated `list_agents`, or another long-running command, and never leave a background child without an event-driven wait path.
|
|
263
264
|
|
|
264
265
|
[workflow-state:in_progress]
|
|
266
|
+
If implementation discovers a material unresolved decision, record `decision-needed`, run `task.py replan <task> "<reason>"`, and return to the planning frontier; do not ask a native question during implementation.
|
|
265
267
|
Tools: `trellis-implement` / `trellis-research` name sub-agent roles dispatched through your platform's sub-agent mechanism, not skills the main session loads itself (on Claude Code: use the Task/Agent tool, never the Skill tool). `trellis-update-spec` is a skill. `trellis-check` exists as both; prefer the Agent/role form when verifying after code changes.
|
|
266
268
|
On DeepSeek Harness, role instructions ship as collision-free `trellis-agent-implement` / `trellis-agent-check` / `trellis-agent-research` skills under `.dsh/skills/`. The main session must not load them itself: tell the child to load the matching role skill exactly once. If `trellis_wait` is available, use the default background mode, do independent work, then call `trellis_wait` once per dependent child id and consume each native settlement notice before entering the dependent gate. If it is unavailable, dispatch every child with `run_in_background: false` from the outset. Do not poll, sleep, or start a background child without an event-driven wait path.
|
|
267
269
|
Flow: `trellis-implement` -> `trellis-check` -> `trellis-update-spec` -> commit (Phase 3.4) -> `/trellis:finish-work`.
|
|
@@ -276,6 +278,7 @@ Dispatch prompt starts with `Active task: <task path from task.py current>`. Rea
|
|
|
276
278
|
|
|
277
279
|
[workflow-state:in_progress-inline]
|
|
278
280
|
Flow: `trellis-before-dev` -> edit -> `trellis-check` -> validation -> `trellis-update-spec` -> commit (Phase 3.4) -> `/trellis:finish-work`.
|
|
281
|
+
If implementation discovers a material unresolved decision, record `decision-needed`, run `task.py replan <task> "<reason>"`, and return to the planning frontier; native questions are planning-only.
|
|
279
282
|
Do not dispatch implement/check sub-agents in inline mode.
|
|
280
283
|
Read context: `prd.md` -> `design.md if present` -> `implement.md if present`, plus relevant spec/research loaded by skills.
|
|
281
284
|
[/workflow-state:in_progress-inline]
|
|
@@ -379,7 +382,7 @@ Load the `trellis-brainstorm` skill and explore requirements interactively with
|
|
|
379
382
|
For an eligible analysis-only task, converge the PRD boundary, then perform the declared research, audit, or design work in this phase. It does not need a start review or `task.py start`; after acceptance evidence is recorded, continue directly to Phase 3.3.
|
|
380
383
|
|
|
381
384
|
The brainstorm skill will guide you to:
|
|
382
|
-
-
|
|
385
|
+
- Batch up to three independent material frontier questions; ask one only when dependency ordering requires it
|
|
383
386
|
- Prefer researching over asking the user
|
|
384
387
|
- Prefer offering options over open-ended questions
|
|
385
388
|
- Update `prd.md` immediately after each user answer
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pennixrv/trellis",
|
|
3
|
-
"version": "0.7.0-beta.
|
|
3
|
+
"version": "0.7.0-beta.8",
|
|
4
4
|
"description": "AI capabilities grow like ivy — Trellis provides the structure to guide them along a disciplined path",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"inquirer": "^9.3.7",
|
|
35
35
|
"undici": "^6.21.0",
|
|
36
36
|
"zod": "^4.4.2",
|
|
37
|
-
"@pennixrv/trellis-core": "0.7.0-beta.
|
|
37
|
+
"@pennixrv/trellis-core": "0.7.0-beta.8"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
40
|
"@eslint/js": "^9.18.0",
|