pi-herdr-agents 1.6.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +5 -5
- package/CHANGELOG.md +55 -1
- package/CONTEXT.md +71 -0
- package/README.md +96 -31
- package/RELEASING.md +1 -1
- package/agents/adversarial-reviewer.md +3 -1
- package/config.json.example +5 -3
- package/docs/README.md +1 -0
- package/docs/adr/0002-agent-workflow-skill-runtime-taxonomy.md +1 -1
- package/docs/adr/0003-installable-role-packs.md +2 -2
- package/docs/adr/0011-explicit-worktree-cleanup.md +74 -0
- package/docs/worktree-subagents.md +25 -13
- package/package.json +2 -2
- package/pi-extension/subagents/config-path.ts +22 -0
- package/pi-extension/subagents/herdr.ts +259 -51
- package/pi-extension/subagents/index.ts +416 -43
- package/pi-extension/subagents/launch.ts +30 -5
- package/pi-extension/subagents/model-config.ts +202 -41
- package/pi-extension/subagents/pane-config.ts +49 -18
- package/pi-extension/subagents/persistent-config.ts +6 -11
- package/pi-extension/subagents/plan-skill.md +2 -2
- package/pi-extension/subagents/role-config.ts +6 -8
- package/pi-extension/subagents/runtime-routing.ts +95 -3
- package/pi-extension/subagents/session.ts +106 -0
- package/pi-extension/subagents/status.ts +6 -8
- package/pi-extension/subagents/supervision-config.ts +33 -16
- package/pi-extension/subagents/terminal.ts +16 -3
- package/pi-extension/subagents/worktree-cleanup.ts +789 -0
- package/skills/orchestrate/SKILL.md +3 -1
package/AGENTS.md
CHANGED
|
@@ -4,7 +4,7 @@ These instructions apply to humans and coding agents changing `pi-herdr-agents`.
|
|
|
4
4
|
|
|
5
5
|
## What this package is
|
|
6
6
|
|
|
7
|
-
`pi-herdr-agents` (Pi Herdr Agents) is a Pi extension that launches asynchronous Pi child agents exclusively in Herdr. Ordinary runs
|
|
7
|
+
`pi-herdr-agents` (Pi Herdr Agents) is a Pi extension that launches asynchronous Pi child agents exclusively in Herdr. Ordinary runs group child panes in extension-owned `Agents` tabs by default. Writing tasks may opt into one isolated Herdr-managed Git worktree per branch. Legacy role definitions that request an external CLI fail before Herdr creates resources.
|
|
8
8
|
|
|
9
9
|
The extension is fire-and-forget: `subagent` returns an acknowledgement, and completion is delivered to the parent automatically. Never add polling guidance that tells callers to sleep, tail sessions, or repeatedly check status.
|
|
10
10
|
|
|
@@ -22,7 +22,7 @@ Bundled role prompts live in [`agents/`](agents/). The native `/skill:orchestrat
|
|
|
22
22
|
## Code map
|
|
23
23
|
|
|
24
24
|
- `pi-extension/subagents/index.ts` — public tools/commands, agent discovery, launch/watch lifecycle, completion delivery, worktree manifests and handoffs
|
|
25
|
-
- `pi-extension/subagents/herdr.ts` — Herdr CLI
|
|
25
|
+
- `pi-extension/subagents/herdr.ts` — Herdr CLI calls, response parsing, and ID-based Agents tab placement and capacity
|
|
26
26
|
- `pi-extension/subagents/terminal.ts` — terminal adapter used by the lifecycle
|
|
27
27
|
- `pi-extension/subagents/lifecycle.ts`, `status.ts`, `activity.ts` — process/turn state and widget projection
|
|
28
28
|
- `pi-extension/subagents/wake.ts`, `supervision.ts`, `supervision-config.ts` — file wake-ups, shared pane reconciliation, polling fallback, and supervision configuration
|
|
@@ -48,7 +48,7 @@ Preserve these invariants when changing worktree behavior:
|
|
|
48
48
|
6. Herdr creates the workspace without stealing focus; launch targets the returned root pane explicitly.
|
|
49
49
|
7. Successful, failed, and help-requesting runs retain their worktree workspace.
|
|
50
50
|
8. Completion reports reviewable Git state; inspection failures are unknown, never guessed clean or conflict-free.
|
|
51
|
-
9. The extension does not push, create PRs, merge, cherry-pick, switch the parent checkout, or remove worktrees
|
|
51
|
+
9. The extension does not push, create PRs, merge, cherry-pick, switch the parent checkout, or remove worktrees automatically. Explicit parent-owned cleanup uses cwd containment and fail-closed eligibility; branches are never deleted.
|
|
52
52
|
10. Ordinary non-worktree subagent behavior remains unchanged.
|
|
53
53
|
|
|
54
54
|
Read [`docs/worktree-subagents.md`](docs/worktree-subagents.md) before changing any of these semantics.
|
|
@@ -105,8 +105,8 @@ Use `PI_TEST_MODEL="openai-codex/gpt-5.6-luna" PI_TEST_TIMEOUT=180000 npm run te
|
|
|
105
105
|
Before committing:
|
|
106
106
|
|
|
107
107
|
- inspect `git status` and the final diff;
|
|
108
|
-
- confirm the package preview includes `CHANGELOG.md`, `skills/orchestrate/SKILL.md`, `skills/orchestrate/adversarial-review.md`, and `skills/orchestrate/adversarial-review-example.js`, while excluding `pi-extension/subagents/workflow-worker.js`, plans, journals, sessions, prototypes, generated evidence,
|
|
109
|
-
- run `npm pack --dry-run` when package contents or documentation paths changed;
|
|
108
|
+
- confirm the package preview includes `CHANGELOG.md`, `skills/orchestrate/SKILL.md`, `skills/orchestrate/adversarial-review.md`, and `skills/orchestrate/adversarial-review-example.js`, while excluding `pi-extension/subagents/workflow-worker.js`, plans, journals, sessions, prototypes, generated evidence, local config, and `openspec/`;
|
|
109
|
+
- run `npm pack --dry-run` when package contents or documentation paths changed; durable configuration is `$PI_CODING_AGENT_DIR/herdr-agents/config.json`, never package-root `config.json` (move old files manually or re-run `/subagents-init`);
|
|
110
110
|
- confirm that no generated plans, journals, sessions, provider configuration, test scripts, or review artifacts are staged; and
|
|
111
111
|
- confirm that no accidental empty directory exists at the repository root:
|
|
112
112
|
|
package/CHANGELOG.md
CHANGED
|
@@ -7,7 +7,59 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
|
9
9
|
|
|
10
|
-
## [
|
|
10
|
+
## [v2.0.0](https://github.com/giuseppecrj/pi-herdr-agents/compare/v1.7.0...v2.0.0)
|
|
11
|
+
|
|
12
|
+
### Breaking
|
|
13
|
+
|
|
14
|
+
- Move durable subagent configuration to `$PI_CODING_AGENT_DIR/herdr-agents/config.json`; package-root `config.json` is ignored. Add ordered `models.tasks` routing through whole-value `task:<category>` references and parent-only `/subagents-init` setup. Migrate by moving your existing `config.json` or running `/subagents-init`.
|
|
15
|
+
|
|
16
|
+
### Added
|
|
17
|
+
|
|
18
|
+
- Parent-only managed worktree inventory and explicit cleanup, including cwd-contained cross-session orphans, fail-closed eligibility, opt-in WIP preservation, retained branches, and inspect-only session-start counts.
|
|
19
|
+
|
|
20
|
+
### Fixed
|
|
21
|
+
|
|
22
|
+
- Unreadable individual process details now produce warnings without an override flag, and inspection continues to detect other holders. Inventory and removal results disclose permission-limited same-user inspection and missing other-user coverage: a protected process could hold the checkout undetected. Known live children, leases, detected holders, unsupported platforms, and failed global enumeration still block removal.
|
|
23
|
+
- Hardened explicit cleanup with cross-session same-user process checks, symlink-ancestor support, ignored-file disclosure, failed-commit index restoration, bounded command timeouts, and accurate preservation/removal reporting.
|
|
24
|
+
- Recreated checkouts no longer inherit removed manifests. Detached HEAD explicitly blocks cleanup, and child sessions retain their existing worktree list and handoff commands.
|
|
25
|
+
|
|
26
|
+
### Merged
|
|
27
|
+
|
|
28
|
+
- feat(subagents): task-category model routing, durable global config, and /subagents-init [`#49`](https://github.com/giuseppecrj/pi-herdr-agents/pull/49)
|
|
29
|
+
- feat(subagents): managed worktree inventory and explicit cleanup [`#50`](https://github.com/giuseppecrj/pi-herdr-agents/pull/50)
|
|
30
|
+
|
|
31
|
+
### Commits
|
|
32
|
+
|
|
33
|
+
- feat(subagents): explicit worktree cleanup (astra build) [`76736b2`](https://github.com/giuseppecrj/pi-herdr-agents/commit/76736b23f661331d028c56f95541c5b859b0f6e2)
|
|
34
|
+
- fix(subagents): verify cleanup safety and disclose process visibility [`5ec8631`](https://github.com/giuseppecrj/pi-herdr-agents/commit/5ec86310bb4a33c737557cb1664fda669a971ff8)
|
|
35
|
+
- add openspec [`7a73e0c`](https://github.com/giuseppecrj/pi-herdr-agents/commit/7a73e0c9cd3fadfaae941fabd6c71e07226f8214)
|
|
36
|
+
- fix(subagents): harden worktree cleanup after adversarial review [`d3c7e7f`](https://github.com/giuseppecrj/pi-herdr-agents/commit/d3c7e7f732b88b895077e8a8c2a946d5f616562c)
|
|
37
|
+
- feat(subagents): add task model routing [`07fce0d`](https://github.com/giuseppecrj/pi-herdr-agents/commit/07fce0d10febce30d21db862c2ae91f435f627de)
|
|
38
|
+
- fix(subagents): repair task model routing review findings [`912ac78`](https://github.com/giuseppecrj/pi-herdr-agents/commit/912ac78fadbb5ab2011f6b9ec680ffb51ad7f9d5)
|
|
39
|
+
- docs(openspec): propose task-model-routing change [`6b97fc7`](https://github.com/giuseppecrj/pi-herdr-agents/commit/6b97fc73bd9cf68dce2275db4882622d1fcee6e2)
|
|
40
|
+
- docs(openspec): address adversarial review of task-model-routing [`7942440`](https://github.com/giuseppecrj/pi-herdr-agents/commit/7942440c0fe21b8900f56aba2563f57330037e82)
|
|
41
|
+
- test(integration): harden cleanup test against wrap and holder races [`635c79b`](https://github.com/giuseppecrj/pi-herdr-agents/commit/635c79b5fe4f5cda35ad46be9575144ed7f9bf7a)
|
|
42
|
+
- docs(openspec): check off 5.2 after live /subagents-init verification [`879438d`](https://github.com/giuseppecrj/pi-herdr-agents/commit/879438d50b1944631c42cec6009bab9ba8226a6c)
|
|
43
|
+
|
|
44
|
+
## [v1.7.0](https://github.com/giuseppecrj/pi-herdr-agents/compare/v1.6.0...v1.7.0) - 2026-09-09
|
|
45
|
+
|
|
46
|
+
### Merged
|
|
47
|
+
|
|
48
|
+
- feat(subagents): checkout-aware Agents tabs and safe cleanup (#33) [`#43`](https://github.com/giuseppecrj/pi-herdr-agents/pull/43)
|
|
49
|
+
- feat: no-progress advisories for active subagents (#40) [`#41`](https://github.com/giuseppecrj/pi-herdr-agents/pull/41)
|
|
50
|
+
- fix(subagents): measure recovered hang duration and track outstanding tool calls [`#40`](https://github.com/giuseppecrj/pi-herdr-agents/pull/40)
|
|
51
|
+
|
|
52
|
+
### Commits
|
|
53
|
+
|
|
54
|
+
- feat(subagents): group agents by checkout with safe pane cleanup (#33) [`59a1075`](https://github.com/giuseppecrj/pi-herdr-agents/commit/59a10756722e7cce3b2ded07db6e1adb04abb0ab)
|
|
55
|
+
- fix(subagents): preserve delivery cleanup and live caller identity (#33) [`26987c5`](https://github.com/giuseppecrj/pi-herdr-agents/commit/26987c58a2c882f31a0d935d7e97ce9dd8c4cce8)
|
|
56
|
+
- feat(subagents): no-progress hang advisories for active children (#40) [`1ebf356`](https://github.com/giuseppecrj/pi-herdr-agents/commit/1ebf356521dd46dd6ee035fe3ebba0262992f399)
|
|
57
|
+
- fix(subagents): keep no-progress recovery guidance evidence-based (#40) [`9cbf155`](https://github.com/giuseppecrj/pi-herdr-agents/commit/9cbf155e291c063f70ef86800ef3bfe3c742c6c6)
|
|
58
|
+
- test(integration): hang advisory coverage (#40) [`075f4fe`](https://github.com/giuseppecrj/pi-herdr-agents/commit/075f4feb17938df28a92fa00851d606e5a83b258)
|
|
59
|
+
- fix(subagents): preserve boundary-aligned records in bounded session tails (#40) [`f096fdb`](https://github.com/giuseppecrj/pi-herdr-agents/commit/f096fdb681921e9ab460610d53e456758802725f)
|
|
60
|
+
- chore: release v1.7.0 [`371265e`](https://github.com/giuseppecrj/pi-herdr-agents/commit/371265e74fb7485afbfbc7c028d60dc4f98d2779)
|
|
61
|
+
|
|
62
|
+
## [v1.6.0](https://github.com/giuseppecrj/pi-herdr-agents/compare/v1.5.1...v1.6.0) - 2026-09-08
|
|
11
63
|
|
|
12
64
|
### Merged
|
|
13
65
|
|
|
@@ -34,11 +86,13 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
|
|
34
86
|
- fix(subagents): scope pane snapshots to registered owners and confirm absence (#29) [`c73a132`](https://github.com/giuseppecrj/pi-herdr-agents/commit/c73a13211f743dc881c506226f457c6a5045e41b)
|
|
35
87
|
- feat(subagents): persistent specialist docs, glossary, and integration coverage (#32) [`e0f052d`](https://github.com/giuseppecrj/pi-herdr-agents/commit/e0f052da7b717a9c4c21ae1d83172acb1a27452c)
|
|
36
88
|
- fix(subagents): guard terminal evidence against racing semantic records (#29) [`f2e41f7`](https://github.com/giuseppecrj/pi-herdr-agents/commit/f2e41f74f185c13a89b49301e226e04948d4c088)
|
|
89
|
+
- chore: release v1.6.0 [`8a18189`](https://github.com/giuseppecrj/pi-herdr-agents/commit/8a181890479f46d5955d4f1bac3be759a2d39010)
|
|
37
90
|
- fix(subagents): type-safe validation for persistent sidecar, ledger, and config parsing [`fe81be5`](https://github.com/giuseppecrj/pi-herdr-agents/commit/fe81be5ca76eba504ff59fcf46ba3e9499753a70)
|
|
38
91
|
- fix(orchestrate): parse review reports out of wrapped public delivery [`9f11918`](https://github.com/giuseppecrj/pi-herdr-agents/commit/9f11918a407be39388999feeee16970e9d888105)
|
|
39
92
|
- fix(subagents): close stopped persistent specialist panes (#32) [`8d0b6e7`](https://github.com/giuseppecrj/pi-herdr-agents/commit/8d0b6e7e9703fd7416e8ddc0ffb97dc26d48ab6b)
|
|
40
93
|
- docs(context): define child wake-up signal and result delivery terms [`a3c159e`](https://github.com/giuseppecrj/pi-herdr-agents/commit/a3c159e2056d13be5697494a13bcb84bdcf92bab)
|
|
41
94
|
- docs(subagents): clarify persistent help requests (#32) [`16e9363`](https://github.com/giuseppecrj/pi-herdr-agents/commit/16e9363180cf49b5e03003f5ea1e57b38ac8adbd)
|
|
95
|
+
- docs(release): require workflow-worker.js absence in the pack preview (#31) [`9d40cc0`](https://github.com/giuseppecrj/pi-herdr-agents/commit/9d40cc0f3aa08ce203a720947bf097a4b66c9357)
|
|
42
96
|
|
|
43
97
|
## [v1.5.1](https://github.com/giuseppecrj/pi-herdr-agents/compare/v1.5.0...v1.5.1) - 2026-09-05
|
|
44
98
|
|
package/CONTEXT.md
CHANGED
|
@@ -18,6 +18,12 @@ The parent-facing handoff of a child run's observed outcome and available
|
|
|
18
18
|
evidence. Receiving it does not establish that the work is correct or accepted.
|
|
19
19
|
_Avoid_: Wake-up signal, acceptance
|
|
20
20
|
|
|
21
|
+
**No-progress advisory**:
|
|
22
|
+
An internal warning that an active child shows no durable progress in its session
|
|
23
|
+
JSONL or activity snapshot. It is advisory only and never changes the child's
|
|
24
|
+
outcome or triggers recovery.
|
|
25
|
+
_Avoid_: Hang verdict, automatic recovery, stall replacement
|
|
26
|
+
|
|
21
27
|
**Legacy external CLI role**:
|
|
22
28
|
An old role definition that contains `cli`. Discovery reports a migration
|
|
23
29
|
diagnostic, and launch fails before Herdr creates a pane or worktree. Remove
|
|
@@ -76,7 +82,72 @@ The append-only evidence record of persistent task dispatch and terminal
|
|
|
76
82
|
outcomes for one session generation.
|
|
77
83
|
_Avoid_: Work queue, mutable task list
|
|
78
84
|
|
|
85
|
+
**Agents tab**:
|
|
86
|
+
An extension-owned Herdr tab grouping delegated child panes in an existing
|
|
87
|
+
checkout workspace. Ownership comes from returned IDs, not its display label.
|
|
88
|
+
The pane cap includes every live pane; overflow creates another tab, not a
|
|
89
|
+
workspace. Separate parent processes own separate groups.
|
|
90
|
+
_Avoid_: Agent workspace, label-based ownership, automatic rearrangement
|
|
91
|
+
|
|
92
|
+
**Retained checkout shell**:
|
|
93
|
+
The interactive shell in a managed worktree's root pane, preserved after the
|
|
94
|
+
child Pi process exits. Temporary review panes can close without deleting this
|
|
95
|
+
surface or its checkout.
|
|
96
|
+
_Avoid_: Completed agent process, disposable pane, automatic worktree cleanup
|
|
97
|
+
|
|
79
98
|
**Worktree lease**:
|
|
80
99
|
The lifetime-exclusive binding between a persistent specialist generation and
|
|
81
100
|
one managed worktree, when that specialist writes in a worktree.
|
|
82
101
|
_Avoid_: Rebindable checkout, shared worktree ownership
|
|
102
|
+
|
|
103
|
+
**Worktree inventory**:
|
|
104
|
+
An inspect-only view joining managed checkout discovery, Git registration/state,
|
|
105
|
+
Herdr workspace association, and reachable owned manifests, including orphans.
|
|
106
|
+
_Avoid_: Session-only resource list, cleanup action
|
|
107
|
+
|
|
108
|
+
**Cwd containment**:
|
|
109
|
+
Cleanup authorization requiring the canonical source repository root to equal or
|
|
110
|
+
be a descendant of the invoking session's canonical cwd.
|
|
111
|
+
_Avoid_: Managed-path containment, manifest ownership authorization
|
|
112
|
+
|
|
113
|
+
**Cleanup eligibility**:
|
|
114
|
+
Fresh evidence of cwd containment, registered checkout identity, a named branch,
|
|
115
|
+
no detected process holder, known live child, or persistent lease, and clean Git
|
|
116
|
+
state. Only Herdr-confirmed idle retained shells are exempt from process checks,
|
|
117
|
+
never runtimes at the same PID. Ignored files and individual process-visibility
|
|
118
|
+
gaps are disclosed, not blockers. Other unknown evidence blocks removal.
|
|
119
|
+
_Avoid_: Guessed idle, presumed clean
|
|
120
|
+
|
|
121
|
+
**Process-inspection warning**:
|
|
122
|
+
Non-blocking disclosure of incomplete same-user process visibility, separate
|
|
123
|
+
from cleanup blockers and requiring no override flag. Scanning continues after
|
|
124
|
+
unreadable details; detected holders still block. Other-user processes are not
|
|
125
|
+
inspected, and a protected process could hold the checkout undetected. Failed
|
|
126
|
+
global enumeration and unsupported platforms remain blockers.
|
|
127
|
+
_Avoid_: Proven unrelated, machine-wide inactivity, bypass permission
|
|
128
|
+
|
|
129
|
+
**Explicit worktree removal**:
|
|
130
|
+
A parent-requested removal of one named managed checkout and its open workspace,
|
|
131
|
+
with absence verification and retained branch history. Never automatic reaping.
|
|
132
|
+
_Avoid_: Branch deletion, completion cleanup
|
|
133
|
+
|
|
134
|
+
**Dirty-state preservation**:
|
|
135
|
+
Explicit opt-in staging and WIP commitment of a worktree's uncommitted and
|
|
136
|
+
untracked files on its retained branch before rechecking removal eligibility.
|
|
137
|
+
Ignored files are not captured. Commit failure restores the original index.
|
|
138
|
+
_Avoid_: Implicit commit, stash, discard
|
|
139
|
+
|
|
140
|
+
**Task-category model preference**:
|
|
141
|
+
An ordered authenticated model shortlist in `models.tasks` for `coding`,
|
|
142
|
+
`review`, `recon`, `qa`, `architecture`, or `docs`. Recon maps to scouts,
|
|
143
|
+
architecture to planning and diagnosis, coding to workers, review to reviewers,
|
|
144
|
+
QA to software runners, and docs to documentation workers. `task:<category>`
|
|
145
|
+
is tool-only deterministic routing; reviews use exact IDs when author-family
|
|
146
|
+
exclusion is needed.
|
|
147
|
+
_Avoid_: Generic tier, reviewer-family enforcement
|
|
148
|
+
|
|
149
|
+
**Loop template**:
|
|
150
|
+
A future reusable orchestration definition beside `models`, describing stages,
|
|
151
|
+
task categories, and a termination/report contract. Loop templates are not
|
|
152
|
+
implemented by task-model routing.
|
|
153
|
+
_Avoid_: Current executable workflow
|
package/README.md
CHANGED
|
@@ -83,7 +83,7 @@ Use ordinary panes for read-only agents. A single or sequential writer can work
|
|
|
83
83
|
|
|
84
84
|

|
|
85
85
|
|
|
86
|
-
A `subagent` call
|
|
86
|
+
A `subagent` call selects the target checkout, reuses its Herdr workspace, and gives the child a pane in an extension-owned `Agents` tab. Four panes fit in each tab by default; overflow opens another tab in the same workspace. A worktree is created only when explicitly requested for checkout isolation. The call launches a child Pi session and returns `started`. The parent watcher combines Herdr process state with child activity details and projects the result into a live widget:
|
|
87
87
|
|
|
88
88
|
```text
|
|
89
89
|
╭─ Subagents ──────────────────── 1 active · 1 open ─╮
|
|
@@ -92,7 +92,7 @@ A `subagent` call creates a dedicated Herdr pane or worktree, launches a child P
|
|
|
92
92
|
╰────────────────────────────────────────────────────╯
|
|
93
93
|
```
|
|
94
94
|
|
|
95
|
-
When the child completes, the parent receives one bounded `subagent_result` message and starts a new turn with that result in context. Callers never need to poll, tail session files, or wait in a shell loop.
|
|
95
|
+
When the child completes, the parent receives one bounded `subagent_result` message and starts a new turn with that result in context. Disposable ordinary panes close after result delivery; Herdr removes a tab when its last pane closes. Persistent specialists keep their pane between tasks, and managed worktree roots return to retained interactive shells. Callers never need to poll, tail session files, or wait in a shell loop.
|
|
96
96
|
|
|
97
97
|
## Troubleshooting completion delivery
|
|
98
98
|
|
|
@@ -119,7 +119,7 @@ Subagent tabs, panes, and worktree workspaces are created without stealing keybo
|
|
|
119
119
|
|
|
120
120
|
### Extensions
|
|
121
121
|
|
|
122
|
-
**Subagents** —
|
|
122
|
+
**Subagents** — 9 parent-session tools + 7 commands, plus 2 child-only tools:
|
|
123
123
|
|
|
124
124
|
| Tool | Description |
|
|
125
125
|
| -------------------- | ------------------------------------------------------------------------------------------- |
|
|
@@ -128,7 +128,10 @@ Subagent tabs, panes, and worktree workspaces are created without stealing keybo
|
|
|
128
128
|
| `subagent_send` | Deliver a follow-up task to an idle persistent specialist |
|
|
129
129
|
| `subagent_stop` | Gracefully stop a persistent specialist after its active task settles |
|
|
130
130
|
| `subagents_list` | List available agent definitions |
|
|
131
|
+
| `worktree_list` | Parent-only inspect-only inventory of managed worktrees and cleanup blockers |
|
|
132
|
+
| `worktree_remove` | Parent-only explicit removal by `target` path, branch, or workspace ID; optional `preserve: true` commits dirty state first |
|
|
131
133
|
| `subagent_resume` | Resume a previous Pi-backed sub-agent session in a new ordinary pane (async) |
|
|
134
|
+
| `subagents_write_task_models` | Parent-only internal tool that validates and atomically writes `models.tasks` preferences |
|
|
132
135
|
|
|
133
136
|
| Pi child-only tool | Description |
|
|
134
137
|
| ---------------- | ------------------------------------------------------------------------- |
|
|
@@ -143,6 +146,7 @@ Subagent tabs, panes, and worktree workspaces are created without stealing keybo
|
|
|
143
146
|
| `/btw-close` | Close the current BTW session |
|
|
144
147
|
| `/worktree <name> [task]` | Continue this session in a new managed worktree (`/worktree list` lists them) |
|
|
145
148
|
| `/subagent <agent> <task>` | Spawn a named agent directly (`/subagent list` lists available agents) |
|
|
149
|
+
| `/subagents-init` | Draft task-category model preferences from the authenticated registry |
|
|
146
150
|
|
|
147
151
|
### Taxonomy and discovery
|
|
148
152
|
|
|
@@ -271,20 +275,13 @@ A fixed internal watchdog marks a run as `stalled` when pane inspection fails or
|
|
|
271
275
|
|
|
272
276
|
#### Configuration
|
|
273
277
|
|
|
274
|
-
The
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
-
|
|
280
|
-
-
|
|
281
|
-
|
|
282
|
-
Project-local installs use the corresponding `.pi/npm/` or `.pi/git/` root.
|
|
283
|
-
From the actual package root, copy the example when you want local overrides:
|
|
284
|
-
|
|
285
|
-
```bash
|
|
286
|
-
cp config.json.example config.json
|
|
287
|
-
```
|
|
278
|
+
The durable user configuration is `$PI_CODING_AGENT_DIR/herdr-agents/config.json`,
|
|
279
|
+
defaulting to `~/.pi/agent/herdr-agents/config.json`. It is not read from the
|
|
280
|
+
installed package root, so npm and git package upgrades do not overwrite it.
|
|
281
|
+
Create it by copying the installed package's `config.json.example`, or run
|
|
282
|
+
`/subagents-init` to seed and draft model task preferences. This is a breaking
|
|
283
|
+
migration: manually move an existing package-local `config.json` to this path,
|
|
284
|
+
or re-run `/subagents-init`.
|
|
288
285
|
|
|
289
286
|
```json
|
|
290
287
|
{
|
|
@@ -301,11 +298,13 @@ cp config.json.example config.json
|
|
|
301
298
|
"maxAgents": 3
|
|
302
299
|
},
|
|
303
300
|
"supervision": {
|
|
304
|
-
"forcePolling": false
|
|
301
|
+
"forcePolling": false,
|
|
302
|
+
"hangWarningMinutes": 15
|
|
305
303
|
},
|
|
306
304
|
"panes": {
|
|
307
|
-
"mode": "
|
|
308
|
-
"direction": "right"
|
|
305
|
+
"mode": "grouped",
|
|
306
|
+
"direction": "right",
|
|
307
|
+
"maxPerTab": 4
|
|
309
308
|
}
|
|
310
309
|
}
|
|
311
310
|
```
|
|
@@ -325,11 +324,34 @@ exact IDs from your authenticated model catalog:
|
|
|
325
324
|
"agents": {
|
|
326
325
|
"scout": "your-provider/your-fast-model",
|
|
327
326
|
"reviewer": "your-provider/your-review-model"
|
|
327
|
+
},
|
|
328
|
+
"tasks": {
|
|
329
|
+
"coding": ["your-provider/your-coding-model"],
|
|
330
|
+
"review": ["your-provider/your-review-model"],
|
|
331
|
+
"recon": ["your-provider/your-fast-model"],
|
|
332
|
+
"qa": ["your-provider/your-qa-model"],
|
|
333
|
+
"architecture": ["your-provider/your-architecture-model"],
|
|
334
|
+
"docs": ["your-provider/your-docs-model"]
|
|
335
|
+
},
|
|
336
|
+
"tasksMeta": {
|
|
337
|
+
"generatedAt": "2026-09-17T00:00:00Z",
|
|
338
|
+
"method": "research"
|
|
328
339
|
}
|
|
329
340
|
}
|
|
330
341
|
}
|
|
331
342
|
```
|
|
332
343
|
|
|
344
|
+
`models.tasks` candidates are ordered exact authenticated IDs. Use
|
|
345
|
+
`task:<category>` only in the `subagent` tool's `model` argument; it is not
|
|
346
|
+
valid in frontmatter or model defaults. For review when the authoring family is
|
|
347
|
+
known, choose an exact shortlist ID from a different family rather than
|
|
348
|
+
`task:review`; this is guidance, not extension enforcement.
|
|
349
|
+
|
|
350
|
+
Run `/subagents-init` to inspect the authenticated registry, research current
|
|
351
|
+
task fit when search is available, write a validated draft, and show its table
|
|
352
|
+
and generation metadata. It reports `registry-only` when research is unavailable.
|
|
353
|
+
Run `/reload` (or start a new session) after it writes the draft.
|
|
354
|
+
|
|
333
355
|
Set `persistent.maxAgents` to the maximum concurrently retained persistent specialists. It defaults to `3`; a persistent spawn at the cap is rejected before Herdr creates a pane or workspace, and no specialist is evicted.
|
|
334
356
|
|
|
335
357
|
Set `roles.bundled` to `false` to exclude this package's bundled role definitions from listing and exact-name launch. It defaults to `true`. Registered role packs remain available, and global and project definitions keep their existing precedence. A role-pack name collides with a bundled role only while that bundled layer is enabled; when it is disabled, the role pack can supply that name.
|
|
@@ -342,11 +364,39 @@ collection; it never establishes a result by itself. If the watcher or shared
|
|
|
342
364
|
pane inspection becomes unavailable, supervision quietly returns to the legacy
|
|
343
365
|
one-second polling cadence. No caller action is required.
|
|
344
366
|
|
|
345
|
-
Set `supervision.forcePolling` to `true` in the
|
|
367
|
+
Set `supervision.forcePolling` to `true` in the durable user `config.json` to
|
|
346
368
|
disable wake-ups and use that legacy cadence deliberately. The setting is read
|
|
347
369
|
when the coordinator is created, so run `/reload` after changing it.
|
|
348
370
|
`subagents_list` reports the active transport mode (`wake+batch`,
|
|
349
371
|
`polling(forced)`, or `polling(fallback)`) and watcher count.
|
|
372
|
+
|
|
373
|
+
`supervision.hangWarningMinutes` defaults to `15`; set it to `0` to disable
|
|
374
|
+
no-progress advisories. For example, this keeps the default transport and sets
|
|
375
|
+
a 30-minute advisory budget:
|
|
376
|
+
|
|
377
|
+
```json
|
|
378
|
+
{
|
|
379
|
+
"supervision": {
|
|
380
|
+
"forcePolling": false,
|
|
381
|
+
"hangWarningMinutes": 30
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
While a child projects active or blocked, the parent compares durable session
|
|
387
|
+
JSONL and activity-snapshot updates against this budget. An advisory is warning-only, fires once per no-progress episode, and
|
|
388
|
+
never interrupts, kills, retries, or restarts a child. It identifies `blocked-tool` (an outstanding tool call may still complete),
|
|
389
|
+
`truncated-turn` (an observed `toolUse` stop with no tool call; its cause is unknown), or
|
|
390
|
+
`generic-no-progress` when neither condition is established, then
|
|
391
|
+
includes the session path and manual recovery options. Ordinary children can be
|
|
392
|
+
interrupted or, after manual termination, resumed or newly spawned. Persistent
|
|
393
|
+
ordinary-pane specialists can be interrupted or stopped with `subagent_stop` and
|
|
394
|
+
replaced; they cannot be resumed. Managed-worktree children, including persistent
|
|
395
|
+
ones, retain their workspace and continue there only after the previous process
|
|
396
|
+
has exited; do not use `subagent_resume` or start a concurrent writer. Interactive children stay
|
|
397
|
+
quiet just as they do for stalled/recovered notices; their widget state still
|
|
398
|
+
updates. A later durable update clears the episode and sends the corresponding
|
|
399
|
+
recovered notice for non-interactive children.
|
|
350
400
|
`polling(fallback)` means at least one tracked child is using per-child polling;
|
|
351
401
|
other children can still use wake+batch.
|
|
352
402
|
|
|
@@ -359,7 +409,13 @@ was 4.82 s. The benchmark measures `/proc` CPU ticks for the supervisor and
|
|
|
359
409
|
isolated Herdr tree, not parent-model latency; raw samples are written to
|
|
360
410
|
`/tmp/issue29-bench/` by `test/bench/supervision-bench.mjs`.
|
|
361
411
|
|
|
362
|
-
|
|
412
|
+
`panes.mode` defaults to `"grouped"` when omitted. Ordinary public `subagent` and `subagent_resume` launches, including bare forks and `/iterate`, fill extension-owned `Agents`, `Agents 2`, etc. tabs in the target checkout's existing workspace. `panes.maxPerTab` is a positive safe integer, defaults to `4`, and counts all live panes in each owned tab, including user-added panes and retained shells. Overlapping launches in one parent respect this cap. It is independent of `persistent.maxAgents`.
|
|
413
|
+
|
|
414
|
+
Checkout matching uses Herdr's canonical `worktree.checkout_path` and includes descendant directories. Shell working directories do not establish workspace ownership. If no checkout matches (including non-Git directories), placement uses the caller's workspace; overflow never creates a workspace. A reviewer with `cwd` set to a managed checkout joins that workspace without creating another worktree. Resume placement uses the saved session's cwd.
|
|
415
|
+
|
|
416
|
+
Explicit `panes.mode: "tab"` preserves one new tab per ordinary child in the caller's workspace. Explicit `"split"` preserves splits of the stable parent pane. `panes.direction` is `"right"` (default) or `"down"` and applies to grouped and legacy splits. `maxPerTab` does not affect these legacy modes. Managed worktrees retain their separate workspaces, while `/btw` keeps its existing tab behavior.
|
|
417
|
+
|
|
418
|
+
Ownership is tracked by returned pane/tab/workspace IDs, never labels. Separate parent processes own separate groups; `/reload` preserves a parent's in-memory ownership, but a full restart does not adopt old tabs. Placement never moves existing panes or renames user tabs. Background launches preserve focus; Herdr may resize sibling panes when splitting or closing. User-added panes are never closed by automatic tab cleanup. An owned tab remains reusable while user panes remain, even after all child panes close.
|
|
363
419
|
|
|
364
420
|
Run `/reload` after changing role, model, or pane settings.
|
|
365
421
|
|
|
@@ -369,7 +425,9 @@ Run `/reload` after changing role, model, or pane settings.
|
|
|
369
425
|
followed by agent frontmatter, per-agent config, the global default, and finally
|
|
370
426
|
the parent model. Model values must be exact authenticated `provider/model-id`
|
|
371
427
|
references. A value can contain an ordered comma-separated fallback list, for
|
|
372
|
-
example `provider/preferred, provider/fallback`. The
|
|
428
|
+
example `provider/preferred, provider/fallback`. The tool argument also accepts
|
|
429
|
+
`task:<category>` as its complete value (not in a list), for configured
|
|
430
|
+
`coding`, `review`, `recon`, `qa`, `architecture`, or `docs` preferences. The extension validates every
|
|
373
431
|
candidate before launch, then launches later candidates only after the selected
|
|
374
432
|
child settles with a provider/agent error. Pi owns any automatic transient
|
|
375
433
|
retrying inside that child; the extension does not infer retry counts or
|
|
@@ -389,10 +447,9 @@ claim a permanent failure or a retry count that Pi has not exposed. Reliable
|
|
|
389
447
|
structured permanence and retry counts require an upstream Pi/ExtensionAPI
|
|
390
448
|
diagnostics seam for final provider errors and retry outcomes.
|
|
391
449
|
|
|
392
|
-
`config.json` is
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
status, model, role, and pane configuration are loaded when the extension starts.
|
|
450
|
+
`config.json` is durable user state under the Pi agent directory and is loaded
|
|
451
|
+
when the extension starts. Run `/reload` after changing it. Package-root
|
|
452
|
+
`config.json` files are ignored; move them manually or re-run `/subagents-init`.
|
|
396
453
|
|
|
397
454
|
---
|
|
398
455
|
|
|
@@ -432,7 +489,7 @@ subagent({
|
|
|
432
489
|
| `fork` | boolean | `false` | Force the full-context fork mode for this spawn, overriding any agent `session-mode` frontmatter |
|
|
433
490
|
| `persistent` | boolean | `false` | Keep one specialist session alive for sequential tasks; follow-ups use `subagent_send` only |
|
|
434
491
|
| `interactive` | boolean | derived | Mark this spawn as interactive (don't wake the parent on stall/recovery). Defaults to the agent's `interactive` frontmatter, otherwise the inverse of `auto-exit`. |
|
|
435
|
-
| `model` | string | configured or parent | Exact authenticated `provider/model-id`,
|
|
492
|
+
| `model` | string | configured or parent | Exact authenticated `provider/model-id`, ordered fallback list, or whole-value `task:<category>` (coding, review, recon, qa, architecture, docs). Task routing is tool-only; worktrees use its first authenticated candidate. Resolution is tool argument → agent frontmatter → per-agent config → global config → parent |
|
|
436
493
|
| `thinking` | string | parent level | Pick the model tier first, then set thinking within that model's range: minimal/low for bounded mechanical work, medium for ordinary implementation or review, high+ for architecture, security, or hard diagnosis. Omitting still inherits the parent level; this is a discouraged fallback for orchestrated children. |
|
|
437
494
|
| `systemPrompt` | string | — | Role/system-prompt text for a bare spawn; named agents keep their definition body |
|
|
438
495
|
| `skills` | string | — | Comma-separated skill names |
|
|
@@ -457,7 +514,7 @@ A launch with `worktree` and an effective bundled `scout`, `reviewer`, or `adver
|
|
|
457
514
|
|
|
458
515
|
The child starts at the returned worktree root. Tell writing agents to test and commit when you want a commit-based handoff, and tell them not to push, merge, switch branches, or remove the worktree. The parent owns review and integration.
|
|
459
516
|
|
|
460
|
-
Successful, failed, and help-requesting runs retain their workspace. Completion includes the worktree path, Herdr workspace, branch, base/head SHAs, commits ahead, changed and untracked files, and clean/dirty/conflicted state. Here, `clean` means no uncommitted files; the branch may still contain commits. If Git inspection fails, state is reported as unknown rather than guessed.
|
|
517
|
+
Successful, failed, and help-requesting worktree runs retain their workspace and root shell. A reviewer's disposable pane can close without closing that root, tab, or checkout. Completion includes the worktree path, Herdr workspace, branch, base/head SHAs, commits ahead, changed and untracked files, and clean/dirty/conflicted state. Here, `clean` means no uncommitted files; the branch may still contain commits. If Git inspection fails, state is reported as unknown rather than guessed.
|
|
461
518
|
|
|
462
519
|
An ownership manifest is written under the parent session's `artifacts/<session-id>/worktree-runs/` directory before Herdr creates resources. V1 does not automatically recover watchers after a full process restart, and `subagent_resume` does not reattach the managed worktree lifecycle.
|
|
463
520
|
|
|
@@ -568,7 +625,7 @@ Phase 5: Integrate → Parent reviews and integrates worktree branches on
|
|
|
568
625
|
Phase 6: Review → Reviewer subagent checks the integrated changes
|
|
569
626
|
```
|
|
570
627
|
|
|
571
|
-
The parent workspace and tab names stay unchanged. Subagents
|
|
628
|
+
The parent workspace and tab names stay unchanged. Subagents use the configured placement policy; grouped mode reuses available space in owned Agents tabs.
|
|
572
629
|
|
|
573
630
|
---
|
|
574
631
|
|
|
@@ -600,10 +657,18 @@ BTW shares the current working directory. It treats inherited work as reference
|
|
|
600
657
|
|
|
601
658
|
## The `/worktree` Workflow
|
|
602
659
|
|
|
603
|
-
`/worktree <worktree> [task]` creates a Herdr-managed worktree from the current committed branch and launches a new interactive Pi session there with the active conversation branch. The original session remains available. Use `/worktree list` to
|
|
660
|
+
`/worktree <worktree> [task]` creates a Herdr-managed worktree from the current committed branch and launches a new interactive Pi session there with the active conversation branch. The original session remains available. Use `/worktree list` or `worktree_list({})` to inspect managed worktrees, including cross-session orphans, whose canonical source repositories are inside the session's cwd subtree. This is a new-process handoff, not an in-place move of the existing shell or Pi process.
|
|
604
661
|
|
|
605
662
|
---
|
|
606
663
|
|
|
664
|
+
### Explicit worktree cleanup
|
|
665
|
+
|
|
666
|
+
Parent sessions can call `worktree_remove({ target: "<path|branch|workspace-id>", preserve: true })` or `/worktree remove <target> [--preserve]`. Preservation is optional and never implied: dirty work is blocked unless explicitly committed first or preserved as a WIP commit. The result reports its SHA even if removal later fails or is refused. A failed preservation commit restores the pre-preservation index and never proceeds to removal. Inventory and removal reports disclose exact ignored-file counts: enumeration is streamed rather than buffered as one listing. Ignored files do not block cleanup and are not captured by preservation; failed counting still blocks removal.
|
|
667
|
+
|
|
668
|
+
Eligibility is rechecked at removal time: canonical source-repository cwd containment, registered linked checkout, no detected process holder, known live child, or persistent lease, and clean Git state with no untracked files or conflicts. Unknown inspection, identity disagreements, detached HEAD, locked checkouts, and initialized submodules block removal. Out-of-scope repositories are never eligible. Open workspaces use Herdr removal; orphans use Git removal and registration pruning after checkout absence is verified. Owned reachable manifests are marked `removed`; manifests from other sessions are not required or rewritten. Stale removed manifests never govern a recreated checkout. Missing or dangling manifest paths do not affect unrelated checkouts; undecidable or conflicting manifest identity still blocks removal. A failed manifest update after removal is reported as a warning. Symlinked ancestors are supported; checkout symlinks escaping the canonical managed root are blocked. Process inspection covers observable same-user processes across sessions, regardless of runtime name, exempting only Herdr-confirmed idle retained shells, never runtimes at the same PID. Unreadable individual process details produce non-blocking warnings without an override flag; scanning continues so another observable holder still blocks removal. Human and structured inventory/removal results disclose incomplete coverage, including warnings seen before a later recheck or failure. Same-user inspection is permission-limited, and other-user processes are not inspected: a protected process could hold the checkout undetected. Warnings aggregate counts and bounded PID samples, not commands or environments. Linux uses `/proc`; macOS uses same-user `lsof` cwd records and warns for unreadable individual records. Unsupported platforms, failed global enumeration (including a failed `lsof` with partial output), and other unverifiable eligibility evidence still block removal. Cleanup Git and Herdr calls have 30-second timeouts.
|
|
669
|
+
|
|
670
|
+
Cleanup never deletes or rewrites branches, uses force flags, or runs automatically. Session start only reports retained-worktree counts. Child sessions retain `/worktree list` and `/worktree <name>`, but receive neither cleanup tools nor the remove subcommand. Their repository-local listing labels detached entries `(detached HEAD)`; a detached sibling does not prevent inspection of named branches. See [cleanup and recovery](docs/worktree-subagents.md#cleanup) for details.
|
|
671
|
+
|
|
607
672
|
## Custom Agents
|
|
608
673
|
|
|
609
674
|
Custom agent roles are the package's primary extension mechanism. Create one
|
package/RELEASING.md
CHANGED
|
@@ -41,7 +41,7 @@ The optional live-provider smoke test is not a release gate:
|
|
|
41
41
|
PI_TEST_MODEL="openai-codex/gpt-5.6-luna" PI_TEST_TIMEOUT=180000 npm run test:integration:live
|
|
42
42
|
```
|
|
43
43
|
|
|
44
|
-
Do not release from skipped Herdr tests. Confirm the package preview includes `README.md`, `CHANGELOG.md`, `AGENTS.md`, `docs/`, `agents/`, `skills/orchestrate/SKILL.md`, `skills/orchestrate/adversarial-review.md`, `skills/orchestrate/adversarial-review-example.js`, and excludes `pi-extension/subagents/workflow-worker.js`. Confirm it excludes plans, journals, sessions, prototypes, generated evidence,
|
|
44
|
+
Do not release from skipped Herdr tests. Confirm the package preview includes `README.md`, `CHANGELOG.md`, `AGENTS.md`, `docs/`, `agents/`, `skills/orchestrate/SKILL.md`, `skills/orchestrate/adversarial-review.md`, `skills/orchestrate/adversarial-review-example.js`, and excludes `pi-extension/subagents/workflow-worker.js`. Confirm it excludes plans, journals, sessions, prototypes, generated evidence, local `config.json` and `openspec/`, and that the worktree integration tests leave no test workspace behind. Durable user configuration is `$PI_CODING_AGENT_DIR/herdr-agents/config.json`; package-root configuration is ignored, so users must move an older file manually or re-run `/subagents-init`.
|
|
45
45
|
|
|
46
46
|
## npm authentication
|
|
47
47
|
|
|
@@ -40,7 +40,9 @@ identify missing evidence.
|
|
|
40
40
|
`fork: false` does not override role `session-mode: fork`. Stop for a
|
|
41
41
|
non-standalone or unknown mode so no reviewer inherits coordinator context.
|
|
42
42
|
4. Use the model-catalog source identified by the `subagent` tool guidance or
|
|
43
|
-
another project-approved source.
|
|
43
|
+
another project-approved source. Curated task shortlists can inform selection,
|
|
44
|
+
but review must name an exact ID and exclude known author families; never use
|
|
45
|
+
`task:review` when that exclusion is required. Record that source, how authentication was
|
|
44
46
|
confirmed, eligible distinct exact IDs, and only IDs actually considered but
|
|
45
47
|
omitted, with reasons. Never guess unknown catalog entries. Identify every
|
|
46
48
|
provider/model family that authored the reviewed material, or confirm that it
|
package/config.json.example
CHANGED
|
@@ -12,10 +12,12 @@
|
|
|
12
12
|
"maxAgents": 3
|
|
13
13
|
},
|
|
14
14
|
"supervision": {
|
|
15
|
-
"forcePolling": false
|
|
15
|
+
"forcePolling": false,
|
|
16
|
+
"hangWarningMinutes": 15
|
|
16
17
|
},
|
|
17
18
|
"panes": {
|
|
18
|
-
"mode": "
|
|
19
|
-
"direction": "right"
|
|
19
|
+
"mode": "grouped",
|
|
20
|
+
"direction": "right",
|
|
21
|
+
"maxPerTab": 4
|
|
20
22
|
}
|
|
21
23
|
}
|
package/docs/README.md
CHANGED
|
@@ -41,6 +41,7 @@ uses an isolated Herdr server and writes uncommitted raw samples to
|
|
|
41
41
|
| [`0008`](adr/0008-adopt-pi-only-subagent-execution.md) | Accepted; implemented | Remove the external CLI adapter and make subagent execution Pi-only. |
|
|
42
42
|
| [`0009`](adr/0009-remove-workflow-subsystem.md) | Accepted | Remove the workflow subsystem; use public subagent fan-out and parent synthesis. |
|
|
43
43
|
| [`0010`](adr/0010-persistent-specialists-as-session-generations.md) | Accepted | Define persistent specialists as logical identities with policy-bound session generations. |
|
|
44
|
+
| [`0011`](adr/0011-explicit-worktree-cleanup.md) | Accepted | Authorize explicit worktree cleanup by cwd containment; retain branches and reject automatic reaping. |
|
|
44
45
|
|
|
45
46
|
## Historical material
|
|
46
47
|
|
|
@@ -143,7 +143,7 @@ Apply these rules:
|
|
|
143
143
|
|
|
144
144
|
1. Prefer per-invocation `model` and `thinking` for a workflow's deliberate
|
|
145
145
|
diversity or cost/quality policy.
|
|
146
|
-
2. Use
|
|
146
|
+
2. Use `$PI_CODING_AGENT_DIR/herdr-agents/config.json` for a person's durable role preferences; package-root configuration is ignored, so move an older file manually or re-run `/subagents-init`.
|
|
147
147
|
3. Leave bundled role `model` unset unless a particular model is a functional
|
|
148
148
|
prerequisite.
|
|
149
149
|
4. State runtime prerequisites before launch and fail closed when a required
|
|
@@ -81,7 +81,7 @@ Within the package layer:
|
|
|
81
81
|
|
|
82
82
|
- bundled roles are protected fallbacks while enabled;
|
|
83
83
|
- a role pack colliding with an enabled bundled name is rejected;
|
|
84
|
-
- copying `config.json.example` to
|
|
84
|
+
- copying the packaged `config.json.example` to `$PI_CODING_AGENT_DIR/herdr-agents/config.json` and setting `roles.bundled` to `false` removes only the bundled layer; registered role packs remain package roles and may supply those names; package-root configuration is ignored, so manually move older files or re-run `/subagents-init`;
|
|
85
85
|
- a name contributed by multiple role packs is disabled;
|
|
86
86
|
- collisions never resolve through incidental extension load order.
|
|
87
87
|
|
|
@@ -95,7 +95,7 @@ before Herdr creates a pane or worktree.
|
|
|
95
95
|
## Reload and security
|
|
96
96
|
|
|
97
97
|
Role files are read on each list or launch, so editing Markdown does not require
|
|
98
|
-
`/reload`. Changing
|
|
98
|
+
`/reload`. Changing durable user role configuration, installing, removing,
|
|
99
99
|
updating, or changing a role-pack extension uses Pi's normal reload flow.
|
|
100
100
|
Contributor `session_shutdown` cleanup removes the
|
|
101
101
|
old event listener before replacement extensions register. Already-running
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# ADR-0011: Authorize explicit worktree cleanup by cwd containment
|
|
2
|
+
|
|
3
|
+
- **Status:** Accepted
|
|
4
|
+
- **Date:** 2026-09-17
|
|
5
|
+
- **Scope:** Managed subagent worktree cleanup (issue #45)
|
|
6
|
+
|
|
7
|
+
## Decision
|
|
8
|
+
|
|
9
|
+
A parent may explicitly remove one managed worktree when its canonical source
|
|
10
|
+
repository is within the session's canonical cwd subtree. This supersedes the
|
|
11
|
+
session-manifest-only ownership policy discussed in issue #45, per its
|
|
12
|
+
2026-09-17 scope update: ended sessions leave orphans whose manifests are no
|
|
13
|
+
longer reachable. A reachable owned manifest enriches inventory and is marked
|
|
14
|
+
removed after successful cleanup, but is not the authorization boundary.
|
|
15
|
+
|
|
16
|
+
Discovery joins the managed filesystem root, Git registration and working-tree
|
|
17
|
+
state, live Herdr workspace state, and current-session manifests. Unknown or
|
|
18
|
+
conflicting eligibility evidence blocks removal, subject to the approved
|
|
19
|
+
individual process-visibility exception below. Detected same-user process
|
|
20
|
+
holders, known live children, and persistent leases block removal; process
|
|
21
|
+
names are not a runtime allowlist. Only Herdr-confirmed idle retained shell
|
|
22
|
+
PIDs are exempt, never active runtimes at those PIDs. Dirty work requires an
|
|
23
|
+
explicit WIP preservation commit on the retained branch; detached HEAD,
|
|
24
|
+
conflicts, locks, and initialized submodules cannot be bypassed.
|
|
25
|
+
|
|
26
|
+
The approved process-visibility policy treats unreadable individual process
|
|
27
|
+
details as non-blocking warnings, without an override flag. Inspection continues
|
|
28
|
+
so one hidden process cannot mask an observable holder. Inventory and removal
|
|
29
|
+
results report incomplete coverage separately from blockers, retaining warnings
|
|
30
|
+
through rechecks, preservation, and failures when available. Reports use counts
|
|
31
|
+
and bounded PID samples, not commands or environments. Linux uses `/proc`;
|
|
32
|
+
macOS uses same-user `lsof` cwd records and warns for individual unreadable
|
|
33
|
+
records. Unsupported platforms and failed global enumeration remain blockers;
|
|
34
|
+
partial output from a failed `lsof` is not successful enumeration.
|
|
35
|
+
|
|
36
|
+
Paths are canonicalized, so symlinked ancestors are supported while checkout
|
|
37
|
+
symlinks escaping the managed root are blocked. Ignored files are counted and
|
|
38
|
+
disclosed, but do not block removal and are not captured by preservation. A
|
|
39
|
+
failed preservation commit restores the original index. A created preservation
|
|
40
|
+
SHA remains in the report even when subsequent removal fails.
|
|
41
|
+
|
|
42
|
+
Removed manifests are no-op evidence only and never classify a recreated
|
|
43
|
+
checkout. Post-removal manifest-write failures are warnings, not removal
|
|
44
|
+
failures. Cleanup Git and Herdr calls have bounded 30-second timeouts. Child
|
|
45
|
+
sessions retain their existing `/worktree list` and `/worktree <name>` surfaces;
|
|
46
|
+
only the cleanup tools and removal subcommand are parent-only.
|
|
47
|
+
|
|
48
|
+
Open workspaces are removed through Herdr. Git-only orphans use Git removal,
|
|
49
|
+
verify checkout absence, and then prune stale registrations. Branches and their
|
|
50
|
+
commits are retained. Session start only reports inventory counts.
|
|
51
|
+
|
|
52
|
+
## Rejected alternatives
|
|
53
|
+
|
|
54
|
+
- Session-only ownership cannot recover cross-session orphans.
|
|
55
|
+
- Global authorization would allow one project to remove another's review state.
|
|
56
|
+
- Automatic reaping at completion, shutdown, or on a timer erases the parent's
|
|
57
|
+
opportunity to review retained work.
|
|
58
|
+
- Force removal and branch deletion are outside this feature's authority.
|
|
59
|
+
- Repo-global stashes make preserved work less visible than retained commits.
|
|
60
|
+
- Recursive filesystem deletion to bypass submodule protection is not supported.
|
|
61
|
+
|
|
62
|
+
## Consequences
|
|
63
|
+
|
|
64
|
+
Broad cwd values authorize broad repository subtrees, so callers must choose cwd
|
|
65
|
+
deliberately. Worktrees are not sandboxes. Fresh eligibility checks reduce but
|
|
66
|
+
cannot eliminate races with external writers; underlying refusals are surfaced,
|
|
67
|
+
not overridden. Same-user process inspection is permission-limited, and
|
|
68
|
+
other-user processes are not inspected. A protected process could hold the
|
|
69
|
+
checkout undetected; unreadability is not proof that it is unrelated. This
|
|
70
|
+
accepted blind spot replaces the earlier strict individual-unreadability
|
|
71
|
+
blocker, not the global enumeration or identity guards. Restart inventory does
|
|
72
|
+
not reattach watchers or rewrite other sessions' manifests.
|
|
73
|
+
|
|
74
|
+
See the [operating guide](../worktree-subagents.md#cleanup) for the shipped API.
|