pi-herdr-agents 2.0.4 → 3.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 +20 -14
- package/CHANGELOG.md +63 -1
- package/CONTEXT.md +86 -32
- package/README.md +262 -141
- package/RELEASING.md +4 -2
- package/config.json.example +0 -3
- package/docs/README.md +38 -15
- package/docs/adr/0001-btw-ephemeral-side-questions.md +1 -1
- package/docs/adr/0002-agent-workflow-skill-runtime-taxonomy.md +1 -1
- package/docs/adr/0003-installable-role-packs.md +21 -13
- package/docs/adr/0009-remove-workflow-subsystem.md +1 -1
- package/docs/adr/0011-explicit-worktree-cleanup.md +1 -1
- package/docs/adr/0012-adopt-maestro-seams-in-repo.md +45 -0
- package/docs/adr/0013-pack-neutral-execution-host.md +63 -0
- package/docs/adr/0014-operator-cancel-terminal-intent.md +134 -0
- package/docs/worktree-subagents.md +10 -6
- package/maestro/adapters/fake/fake-harness-adapter.ts +263 -0
- package/{pi-extension/subagents/activity.ts → maestro/adapters/pi/activity-file.ts} +15 -72
- package/{pi-extension/subagents → maestro/adapters/pi/child}/subagent-done.ts +30 -3
- package/{pi-extension/subagents → maestro/adapters/pi}/completion.ts +4 -4
- package/{pi-extension/subagents → maestro/adapters/pi}/launch.ts +388 -285
- package/maestro/adapters/pi/model-registry.ts +46 -0
- package/maestro/adapters/pi/pi-harness-adapter.ts +701 -0
- package/maestro/adapters/pi/process-identity.ts +303 -0
- package/{pi-extension/subagents → maestro/adapters/pi}/session.ts +1 -13
- package/maestro/adapters/pi/task-model-init.ts +55 -0
- package/maestro/core/activity.ts +29 -0
- package/maestro/core/config/model-config.ts +473 -0
- package/{pi-extension/subagents → maestro/core/config}/pane-config.ts +4 -6
- package/{pi-extension/subagents → maestro/core/config}/persistent-config.ts +4 -6
- package/{pi-extension/subagents → maestro/core/config}/role-config.ts +15 -10
- package/{pi-extension/subagents → maestro/core/config}/supervision-config.ts +4 -6
- package/{pi-extension/subagents → maestro/core/config}/task-model-init.ts +45 -58
- package/maestro/core/config/task-model-types.ts +22 -0
- package/maestro/core/harness-adapter.ts +117 -0
- package/maestro/core/index.ts +3 -0
- package/{pi-extension/subagents → maestro/core}/lifecycle.ts +27 -126
- package/maestro/core/roles/discovery.ts +555 -0
- package/{pi-extension/subagents/runtime-routing.ts → maestro/core/routing.ts} +36 -43
- package/maestro/core/shell.ts +3 -0
- package/{pi-extension/subagents → maestro/core}/status.ts +3 -7
- package/{pi-extension/subagents → maestro/core}/supervision.ts +1 -1
- package/maestro/core/surface-provider.ts +185 -0
- package/maestro/core/types.ts +449 -0
- package/maestro/core/worktree-cleanup.ts +374 -0
- package/maestro/core/worktree.ts +93 -0
- package/maestro/runtime/index.ts +44 -0
- package/maestro/runtime/pi-run-session.ts +1210 -0
- package/maestro/runtime/run-session.ts +801 -0
- package/maestro/runtime/surface-retention.ts +6 -0
- package/maestro/runtime/task-model-init.ts +22 -0
- package/maestro/runtime/worktree-operations.ts +627 -0
- package/maestro/surfaces/fake/fake-surface-provider.ts +311 -0
- package/maestro/surfaces/herdr/herdr-surface-provider.ts +200 -0
- package/{pi-extension/subagents → maestro/surfaces/herdr}/herdr.ts +65 -14
- package/{pi-extension/subagents → maestro/surfaces/herdr}/terminal.ts +7 -5
- package/package.json +10 -9
- package/pi-extension/subagents/config-path.ts +5 -1
- package/pi-extension/subagents/index.ts +848 -1805
- package/pi-extension/subagents/model-registry.ts +46 -0
- package/skills/pi-herdr-agents/SKILL.md +276 -0
- package/agents/adversarial-reviewer.md +0 -153
- package/agents/planner.md +0 -87
- package/agents/poteto.md +0 -32
- package/agents/reviewer.md +0 -132
- package/agents/scout.md +0 -105
- package/agents/visual-tester.md +0 -234
- package/agents/worker.md +0 -121
- package/docs/review-evaluation.md +0 -183
- package/pi-extension/subagents/model-config.ts +0 -305
- package/pi-extension/subagents/plan-skill.md +0 -280
- package/pi-extension/subagents/worktree-cleanup.ts +0 -789
- package/skills/orchestrate/SKILL.md +0 -91
- package/skills/orchestrate/adversarial-review-example.js +0 -400
- package/skills/orchestrate/adversarial-review.md +0 -87
- /package/{pi-extension/subagents → maestro/core/config}/type-guards.ts +0 -0
- /package/{pi-extension/subagents → maestro/core}/wake.ts +0 -0
package/RELEASING.md
CHANGED
|
@@ -6,7 +6,9 @@ The published version must be unique on npm.
|
|
|
6
6
|
|
|
7
7
|
## Public versioning
|
|
8
8
|
|
|
9
|
-
`0.0.1` was a manual bootstrap publication that established the npm package. `0.0.2` is the first release published through the trusted GitHub Actions workflow
|
|
9
|
+
`0.0.1` was a manual bootstrap publication that established the npm package. `0.0.2` is the first release published through the trusted GitHub Actions workflow; every later release uses trusted publishing.
|
|
10
|
+
|
|
11
|
+
`3.0.0` is the pack-neutral baseline. It is a major release because it removes the bundled roles, `/plan`, `/skill:orchestrate`, `/iterate`, `/btw`, and `/btw-close`, and makes `roles.bundled` a deprecated no-op. Its hand-written breaking changes and migration notes are in the README [Release notes](README.md#release-notes) section, because `npm version` regenerates `CHANGELOG.md` and would discard hand edits there. Record later breaking-release notes in the same section.
|
|
10
12
|
|
|
11
13
|
Do not design a release that creates a GitHub Release without a successful npm publish for a new version. The workflow publishes first, then tags and creates the GitHub Release.
|
|
12
14
|
|
|
@@ -41,7 +43,7 @@ The optional live-provider smoke test is not a release gate:
|
|
|
41
43
|
PI_TEST_MODEL="openai-codex/gpt-5.6-luna" PI_TEST_TIMEOUT=180000 npm run test:integration:live
|
|
42
44
|
```
|
|
43
45
|
|
|
44
|
-
Do not release from skipped Herdr tests. Confirm the package preview includes `README.md`, `CHANGELOG.md`, `AGENTS.md`, `docs/`, `
|
|
46
|
+
Do not release from skipped Herdr tests. Confirm the package preview includes `README.md`, `CHANGELOG.md`, `AGENTS.md`, `docs/`, `config.json.example`, and `examples/role-pack/`, contains no `agents/` resources, no `skills/` resources other than the host-owned `skills/pi-herdr-agents/SKILL.md`, and no `pi-extension/subagents/plan-skill.md`, 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
47
|
|
|
46
48
|
## npm authentication
|
|
47
49
|
|
package/config.json.example
CHANGED
package/docs/README.md
CHANGED
|
@@ -9,43 +9,66 @@ are evidence, not shipped contracts, when a later ADR supersedes them.
|
|
|
9
9
|
- [`../README.md`](../README.md) — installation, public tools, configuration,
|
|
10
10
|
lifecycle, and role authoring.
|
|
11
11
|
- [`../CONTEXT.md`](../CONTEXT.md) — orchestration glossary.
|
|
12
|
-
- [`../skills/orchestrate/SKILL.md`](../skills/orchestrate/SKILL.md) — public
|
|
13
|
-
subagent review fan-out and parent synthesis procedure.
|
|
14
|
-
- [`../skills/orchestrate/adversarial-review.md`](../skills/orchestrate/adversarial-review.md)
|
|
15
|
-
— adversarial topology, finding records, and incomplete-coverage policy.
|
|
16
12
|
- [`worktree-subagents.md`](worktree-subagents.md) — worktree operation,
|
|
17
13
|
review, recovery, and cleanup.
|
|
18
14
|
|
|
19
|
-
The package
|
|
20
|
-
worktrees for writing tasks
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
15
|
+
The package is a pack-neutral execution host: it launches asynchronous Pi
|
|
16
|
+
children in Herdr and supports managed worktrees for writing tasks, but ships no
|
|
17
|
+
agent roles, planning or review workflows, or skills. Roles come from project or
|
|
18
|
+
global definitions and installed role packs; workflows such as `/plan` and
|
|
19
|
+
`/skill:orchestrate` belong to those packs
|
|
20
|
+
([ADR-0013](adr/0013-pack-neutral-execution-host.md)). Role frontmatter tool
|
|
21
|
+
allowlists are the available enforcement boundary; `read,bash` is not
|
|
22
|
+
read-only. Automated package
|
|
24
23
|
acceptance covers unit tests, lint, and `npm pack --dry-run`. Deterministic
|
|
25
24
|
Herdr integration is a manual release gate run from inside Herdr. The manual
|
|
26
25
|
supervision transport benchmark is `../test/bench/supervision-bench.mjs`; it
|
|
27
26
|
uses an isolated Herdr server and writes uncommitted raw samples to
|
|
28
27
|
`/tmp/issue29-bench/`.
|
|
29
28
|
|
|
29
|
+
## Architecture and code map
|
|
30
|
+
|
|
31
|
+
[ADR-0012](adr/0012-adopt-maestro-seams-in-repo.md) records the accepted seams
|
|
32
|
+
decision. The [migration design](superpowers/specs/2026-10-02-maestro-seams-design.md)
|
|
33
|
+
is implemented in the feature branch, with local unit and deterministic
|
|
34
|
+
integration gates passed and the implementation checkpoint signed. It is not
|
|
35
|
+
yet a shipped contract.
|
|
36
|
+
|
|
37
|
+
- `../maestro/core/` — harness-neutral interfaces, domain rules, roles, and config.
|
|
38
|
+
- `../maestro/adapters/pi/` — Pi harness and child protocol.
|
|
39
|
+
- `../maestro/surfaces/herdr/` — Herdr provider and CLI driver.
|
|
40
|
+
- `../maestro/runtime/` — run ownership and real Pi/Herdr composition.
|
|
41
|
+
- `../pi-extension/subagents/index.ts` — Pi host entry point;
|
|
42
|
+
`model-registry.ts` and `config-path.ts` remain permanent host-local owners.
|
|
43
|
+
- `../test/maestro/` — seam conformance and dependency-rule tests; real
|
|
44
|
+
conformance runs in `../test/integration/`.
|
|
45
|
+
|
|
46
|
+
See the [full code map](../README.md#code-map). Pi and Herdr remain the only
|
|
47
|
+
real implementations; in-memory fakes are conformance fixtures only.
|
|
48
|
+
|
|
30
49
|
## ADRs
|
|
31
50
|
|
|
32
51
|
| ADR | Status | Decision |
|
|
33
52
|
| --- | --- | --- |
|
|
34
|
-
| [`0001`](adr/0001-btw-ephemeral-side-questions.md) |
|
|
35
|
-
| [`0002`](adr/0002-agent-workflow-skill-runtime-taxonomy.md) | Partially superseded by 0009 | Keep agent execution, skills, and Pi runtimes distinct. |
|
|
36
|
-
| [`0003`](adr/0003-installable-role-packs.md) | Accepted | Define installable role-pack discovery and collision rules. |
|
|
53
|
+
| [`0001`](adr/0001-btw-ephemeral-side-questions.md) | Superseded by 0013 | Historical `/btw` side-question decision; the command was removed. |
|
|
54
|
+
| [`0002`](adr/0002-agent-workflow-skill-runtime-taxonomy.md) | Partially superseded by 0009 and 0013 | Keep agent execution, skills, and Pi runtimes distinct. |
|
|
55
|
+
| [`0003`](adr/0003-installable-role-packs.md) | Accepted; bundled layer superseded by 0013 | Define installable role-pack discovery and collision rules. |
|
|
37
56
|
| [`0004`](adr/0004-require-active-user-approval-for-workflow-execution.md) | Superseded by 0009 | Historical exact-script approval decision. |
|
|
38
57
|
| [`0005`](adr/0005-parent-owns-workflow-script-authority.md) | Superseded by 0009 | Historical workflow-script authority decision. |
|
|
39
58
|
| [`0006`](adr/0006-limit-v1-execution-effects-to-isolated-worktrees.md) | Partially superseded by 0009 | Historical runner effect boundary; managed worktree rules remain. |
|
|
40
59
|
| [`0007`](adr/0007-require-fresh-review-for-workflow-scripts.md) | Superseded by 0009 | Historical workflow-review decision. |
|
|
41
|
-
| [`0008`](adr/0008-adopt-pi-only-subagent-execution.md) |
|
|
42
|
-
| [`0009`](adr/0009-remove-workflow-subsystem.md) | Accepted | Remove the workflow subsystem; use public subagent fan-out and parent synthesis. |
|
|
60
|
+
| [`0008`](adr/0008-adopt-pi-only-subagent-execution.md) | Partially superseded by 0012 | Keep Pi-only execution; 0012 supersedes only the adapter-seam restriction. |
|
|
61
|
+
| [`0009`](adr/0009-remove-workflow-subsystem.md) | Accepted; skill ownership moved by 0013 | Remove the workflow subsystem; use public subagent fan-out and parent synthesis. |
|
|
43
62
|
| [`0010`](adr/0010-persistent-specialists-as-session-generations.md) | Accepted | Define persistent specialists as logical identities with policy-bound session generations. |
|
|
44
63
|
| [`0011`](adr/0011-explicit-worktree-cleanup.md) | Accepted | Authorize explicit worktree cleanup by cwd containment; retain branches and reject automatic reaping. |
|
|
64
|
+
| [`0012`](adr/0012-adopt-maestro-seams-in-repo.md) | Accepted | Adopt in-repo seams and conformance fakes; keep one package, Pi-only execution, and Herdr-only surfaces. |
|
|
65
|
+
| [`0013`](adr/0013-pack-neutral-execution-host.md) | Accepted | Ship a pack-neutral execution host; roles and workflows move to optional packs, and `/iterate` and `/btw` are removed. |
|
|
66
|
+
| [`0014`](adr/0014-operator-cancel-terminal-intent.md) | Accepted | Operator cancel records terminal intent before owned termination: no fallback, one confirmed cancelled result, unconfirmed runs stay live. |
|
|
45
67
|
|
|
46
68
|
## Historical material
|
|
47
69
|
|
|
48
70
|
- [`orchestrated-review-workflow-plan.md`](orchestrated-review-workflow-plan.md)
|
|
49
|
-
— superseded workflow design, retained as history.
|
|
71
|
+
— superseded workflow design, retained as history. Its `skills/orchestrate`
|
|
72
|
+
and review-evaluation paths now belong to the `pi-herdr-roles` pack.
|
|
50
73
|
- [`research/`](research/) — background evidence and alternatives, not shipped
|
|
51
74
|
behavior.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# ADR-0001: Add `/btw` as an ephemeral side-question child
|
|
2
2
|
|
|
3
|
-
- **Status:**
|
|
3
|
+
- **Status:** Superseded by [ADR-0013](0013-pack-neutral-execution-host.md); `/btw` and `/btw-close` were removed, not relocated
|
|
4
4
|
- **Date:** 2026-07-31
|
|
5
5
|
- **Decision owners:** `acrnm`
|
|
6
6
|
- **Scope:** `giuseppecrj/pi-herdr-agents`
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# ADR-0002: Adopt the agent, workflow, skill, and runtime taxonomy
|
|
2
2
|
|
|
3
|
-
**Status:** Partially superseded by ADR-0009 for workflow-runner taxonomy; retained for agent, skill, and runtime terminology.
|
|
3
|
+
**Status:** Partially superseded by ADR-0009 for workflow-runner taxonomy and by [ADR-0013](0013-pack-neutral-execution-host.md) for shipped roles and workflows; retained for agent, skill, and runtime terminology. The role and workflow mapping below is historical: this package no longer ships those roles, `/plan`, `/iterate`, `/btw`, or `orchestrate`.
|
|
4
4
|
|
|
5
5
|
- **Status:** Accepted in part; external CLI provisions superseded
|
|
6
6
|
- **Date:** 2026-08-02
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# ADR-0003: Discover installable role packs through Pi's event bus
|
|
2
2
|
|
|
3
|
-
- **Status:** Accepted
|
|
4
|
-
- **Date:** 2026-08-02
|
|
3
|
+
- **Status:** Accepted; bundled-role provisions superseded by [ADR-0013](0013-pack-neutral-execution-host.md)
|
|
4
|
+
- **Date:** 2026-08-02 (bundled layer retired 2026-10-05)
|
|
5
5
|
- **Decision owners:** `acrnm`
|
|
6
6
|
- **Scope:** `giuseppecrj/pi-herdr-agents`
|
|
7
7
|
|
|
@@ -62,10 +62,9 @@ leaving stale roles.
|
|
|
62
62
|
|
|
63
63
|
Listing and exact-name launch use one resolved catalog. Collection order is:
|
|
64
64
|
|
|
65
|
-
1.
|
|
66
|
-
2.
|
|
67
|
-
3.
|
|
68
|
-
4. project definitions.
|
|
65
|
+
1. registered role-pack definitions;
|
|
66
|
+
2. global definitions;
|
|
67
|
+
3. project definitions.
|
|
69
68
|
|
|
70
69
|
Effective precedence remains:
|
|
71
70
|
|
|
@@ -73,18 +72,27 @@ Effective precedence remains:
|
|
|
73
72
|
project > global > package
|
|
74
73
|
```
|
|
75
74
|
|
|
76
|
-
Role-pack definitions
|
|
77
|
-
version, and path provenance. Global and project definitions can
|
|
78
|
-
override them.
|
|
75
|
+
Role-pack definitions form the entire `package` source layer and add package
|
|
76
|
+
name, version, and path provenance. Global and project definitions can
|
|
77
|
+
intentionally override them. The host ships no roles, so an empty catalog is
|
|
78
|
+
valid.
|
|
79
79
|
|
|
80
80
|
Within the package layer:
|
|
81
81
|
|
|
82
|
-
-
|
|
83
|
-
|
|
84
|
-
-
|
|
85
|
-
|
|
82
|
+
- registered packs have no priority over one another, and no pack is a
|
|
83
|
+
privileged default;
|
|
84
|
+
- a name contributed by multiple role packs is disabled with a diagnostic naming
|
|
85
|
+
every contributor;
|
|
86
86
|
- collisions never resolve through incidental extension load order.
|
|
87
87
|
|
|
88
|
+
Earlier versions collected an enabled bundled layer first, rejected role packs
|
|
89
|
+
that collided with it, and let `roles.bundled: false` remove it. ADR-0013
|
|
90
|
+
retires that layer. Valid `roles.bundled` booleans in
|
|
91
|
+
`$PI_CODING_AGENT_DIR/herdr-agents/config.json` are now accepted as deprecated
|
|
92
|
+
no-ops with one parent-session warning per extension load; malformed values and
|
|
93
|
+
unknown `roles` keys remain errors, and the file is never rewritten. Package-root
|
|
94
|
+
configuration is still ignored.
|
|
95
|
+
|
|
88
96
|
Invalid registrations do not suppress unrelated roles. Listing surfaces report
|
|
89
97
|
concise diagnostics, and an exact-name launch reports the matching diagnostic
|
|
90
98
|
instead of treating an invalid contribution as a bare agent. An invalid
|
|
@@ -47,7 +47,7 @@ only the cleanup tools and removal subcommand are parent-only.
|
|
|
47
47
|
|
|
48
48
|
Open workspaces are removed through Herdr. Git-only orphans use Git removal,
|
|
49
49
|
verify checkout absence, and then prune stale registrations. Branches and their
|
|
50
|
-
commits are retained. Session
|
|
50
|
+
commits are retained. Session startup does not scan worktree inventory, avoiding blocking Pi initialization; use `/worktree list` or `worktree_list` for an explicit inventory.
|
|
51
51
|
|
|
52
52
|
## Rejected alternatives
|
|
53
53
|
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# ADR-0012: Adopt maestro seams in-repo
|
|
2
|
+
|
|
3
|
+
- **Status:** Accepted
|
|
4
|
+
- **Date:** 2026-10-04
|
|
5
|
+
- **Scope:** `giuseppecrj/pi-herdr-agents`
|
|
6
|
+
- **Supersedes:** Only ADR-0008's restriction on adding a runtime adapter seam without a second real execution path
|
|
7
|
+
|
|
8
|
+
## Decision
|
|
9
|
+
|
|
10
|
+
Adopt explicit `HarnessAdapter`, `SurfaceProvider`, and `RunSession` interfaces
|
|
11
|
+
under `maestro/` in this repository. Keep one npm package and the existing
|
|
12
|
+
`pi-extension/subagents/index.ts` Pi extension entry point.
|
|
13
|
+
|
|
14
|
+
Pi remains the sole real harness and Herdr the sole real surface provider.
|
|
15
|
+
In-memory fakes provide conformance coverage, not supported execution paths.
|
|
16
|
+
Runtime composition wires the real adapter and provider; the Pi host calls
|
|
17
|
+
runtime operations and core modules without importing adapters or surfaces
|
|
18
|
+
directly. A dependency-rule test enforces the directory boundaries.
|
|
19
|
+
|
|
20
|
+
Preserve the existing public tools, commands, role-pack protocol, completion
|
|
21
|
+
evidence and delivery, worktree invariants, and persistent-specialist semantics.
|
|
22
|
+
Do not add adapter registries, name-based runtime dispatch, or a second real
|
|
23
|
+
harness or provider.
|
|
24
|
+
|
|
25
|
+
## Why
|
|
26
|
+
|
|
27
|
+
Conformance fakes make run ownership and orchestration testable without real
|
|
28
|
+
Pi or Herdr resources. Explicit boundaries also prepare `maestro/` for later
|
|
29
|
+
extraction without maintaining a second implementation. These needs justify
|
|
30
|
+
the seam without a second real execution path.
|
|
31
|
+
|
|
32
|
+
## Consequences
|
|
33
|
+
|
|
34
|
+
The Pi launch module still owns each launch transaction; the run session owns
|
|
35
|
+
run coordination, retries, observation, and delivery-gated cleanup. Pi-specific
|
|
36
|
+
protocol code lives in `maestro/adapters/pi/`, Herdr operations in
|
|
37
|
+
`maestro/surfaces/herdr/`, and harness-neutral rules in `maestro/core/`.
|
|
38
|
+
|
|
39
|
+
The rest of [ADR-0008](0008-adopt-pi-only-subagent-execution.md) remains in
|
|
40
|
+
force, including Pi-only execution and rejection of legacy external CLI roles.
|
|
41
|
+
[ADR-0003](0003-installable-role-packs.md) continues to govern role packs.
|
|
42
|
+
This decision does not extract or publish a new package, promise another
|
|
43
|
+
harness, or establish that migration verification is complete. See the
|
|
44
|
+
[design and migration status](../superpowers/specs/2026-10-02-maestro-seams-design.md)
|
|
45
|
+
and [code map](../../README.md#code-map).
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# ADR-0013: Ship a pack-neutral execution host
|
|
2
|
+
|
|
3
|
+
- **Status:** Accepted
|
|
4
|
+
- **Date:** 2026-10-05
|
|
5
|
+
- **Scope:** `giuseppecrj/pi-herdr-agents`
|
|
6
|
+
- **Supersedes:** [ADR-0001](0001-btw-ephemeral-side-questions.md); the bundled-role
|
|
7
|
+
provisions of [ADR-0003](0003-installable-role-packs.md); the shipped role and
|
|
8
|
+
workflow mapping in [ADR-0002](0002-agent-workflow-skill-runtime-taxonomy.md)
|
|
9
|
+
and the bundled-skill provision of [ADR-0009](0009-remove-workflow-subsystem.md)
|
|
10
|
+
|
|
11
|
+
## Decision
|
|
12
|
+
|
|
13
|
+
`pi-herdr-agents` is an execution host. It owns child execution, supervision,
|
|
14
|
+
sessions, persistence, worktrees, model routing, role parsing and discovery, and
|
|
15
|
+
parent delivery. It ships no agent roles and no planning or review workflows.
|
|
16
|
+
The only Pi skill it ships is `pi-herdr-agents`, a general operating guide to its
|
|
17
|
+
own control tools; methodology and workflow skills stay in separate packs.
|
|
18
|
+
|
|
19
|
+
- The seven formerly bundled roles move to separately installed role packs:
|
|
20
|
+
`scout`, `planner`, `worker`, `reviewer`, `adversarial-reviewer`, and
|
|
21
|
+
`visual-tester` to the optional general-purpose `pi-herdr-roles` pack, and
|
|
22
|
+
`poteto` to `pi-herdr-pstack`. Neither pack has privileged discovery status.
|
|
23
|
+
- `/plan`, its plan prompt, and the top-level `orchestrate` skill with its
|
|
24
|
+
supporting resources and evaluation corpus move to `pi-herdr-roles`.
|
|
25
|
+
- `/iterate`, `/btw`, and `/btw-close` are removed, not relocated, together with
|
|
26
|
+
their exclusive session snapshot, surface, and launch code. Direct
|
|
27
|
+
`subagent({ fork: true, interactive: true, ... })` launches, resume,
|
|
28
|
+
persistent specialists, and `/worktree` handoff remain.
|
|
29
|
+
- Registered role packs are the entire package layer. Effective precedence stays
|
|
30
|
+
project > global > package. An empty catalog is valid; bare launches need no
|
|
31
|
+
role; a missing or invalid named role fails before Herdr creates resources.
|
|
32
|
+
- Existing valid `roles.bundled` booleans are accepted as deprecated no-ops. A
|
|
33
|
+
parent session reports one warning per extension load and never rewrites the
|
|
34
|
+
file. Malformed values and unknown `roles` keys remain errors.
|
|
35
|
+
- The bundled-role worktree warning table is removed. The host keeps only
|
|
36
|
+
role-independent worktree guidance and does not infer write capability from
|
|
37
|
+
a `tools` allowlist.
|
|
38
|
+
- Host guidance describes model-selection mechanics, not named pack workflows.
|
|
39
|
+
- `PI_SUBAGENT_ID` is documented as a child-context hint: set for fresh and
|
|
40
|
+
resumed children, absent from `/worktree` handoffs, inherited by nested
|
|
41
|
+
processes, and not a security boundary. No new parent/child protocol is added.
|
|
42
|
+
|
|
43
|
+
## Why
|
|
44
|
+
|
|
45
|
+
Bundled roles were privileged fallbacks that blocked same-named pack roles, and
|
|
46
|
+
the bundled workflows made one methodology the default for every installation.
|
|
47
|
+
Separate packs let users choose the generic roles, pstack, another pack, their
|
|
48
|
+
own definitions, or bare launches, and let packs release independently.
|
|
49
|
+
|
|
50
|
+
The existing v1 role-pack event already supports independently installed packs,
|
|
51
|
+
so no new contribution registry is needed. `/iterate` and `/btw` were unused in
|
|
52
|
+
production and duplicated generic fork and session behavior.
|
|
53
|
+
|
|
54
|
+
## Consequences
|
|
55
|
+
|
|
56
|
+
- This is a breaking product change. Users install the packs they want; nothing
|
|
57
|
+
is installed or migrated automatically, and user role files are not edited.
|
|
58
|
+
- Older hosts that still bundle the roles, `/plan`, or `orchestrate` collide with
|
|
59
|
+
the replacement packs. `roles.bundled: false` on an older host removes only the
|
|
60
|
+
role layer. Replacement packs must not claim compatibility with those hosts.
|
|
61
|
+
- Lifecycle tests use test-only role fixtures instead of production roles.
|
|
62
|
+
- The release version, deprecation removal date, and published compatibility
|
|
63
|
+
ranges are decided at release planning, not by this ADR.
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
# ADR-0014: Operator cancel records terminal intent before termination
|
|
2
|
+
|
|
3
|
+
- **Status:** Accepted
|
|
4
|
+
- **Date:** 2026-10-05
|
|
5
|
+
- **Scope:** Public `subagent_cancel` for ordinary managed Pi subagents
|
|
6
|
+
|
|
7
|
+
## Context
|
|
8
|
+
|
|
9
|
+
An operator could interrupt a turn (`subagent_interrupt`) but not end a run.
|
|
10
|
+
`subagent_stop` is the persistent-specialist graceful stop and rejects ordinary
|
|
11
|
+
children. Closing a child's pane by hand made the watcher report "pane
|
|
12
|
+
disappeared" as a provider/agent error, which the run session treated as a
|
|
13
|
+
retryable failure and launched the next configured fallback model. Wrapping the
|
|
14
|
+
existing primitives does not fix this: `suppress` drops delivery entirely, and
|
|
15
|
+
`kill` alone produces exactly that fallback-eligible error.
|
|
16
|
+
|
|
17
|
+
## Decision
|
|
18
|
+
|
|
19
|
+
`RunSession.cancel(taskId)` is the one cancellation path, owned by the existing
|
|
20
|
+
kernel producer, adapter, and finalization. It is not a second engine.
|
|
21
|
+
|
|
22
|
+
1. **Terminal intent first.** The call records the cancel intent synchronously,
|
|
23
|
+
before any abort, kill, or await. Every later decision reads it: no fallback,
|
|
24
|
+
acquisition, retry, or recovery starts after it.
|
|
25
|
+
2. **Settle point.** The producer's synchronous check after an attempt's wait
|
|
26
|
+
settles decides the race. Intent recorded before it makes the run cancelled,
|
|
27
|
+
even if natural evidence (including the kill's own pane-loss evidence)
|
|
28
|
+
arrived first. A natural result that cannot start a fallback, taken before
|
|
29
|
+
the intent, stays authoritative and cancel reports `already-terminal`. A
|
|
30
|
+
cancel during a fallback-eligible attempt's finalization still wins because
|
|
31
|
+
that result was not terminal.
|
|
32
|
+
3. **Owned termination.** The kernel calls the owning adapter's `kill` for the
|
|
33
|
+
current attempt, one kill at a time; concurrent cancels join it. Only a
|
|
34
|
+
resolved kill confirms termination, and only then is the producer's wait
|
|
35
|
+
aborted, so a failed kill leaves the run supervised.
|
|
36
|
+
4. **Pending acquisition.** With an acquisition in flight, cancel reports
|
|
37
|
+
`requested`. The acquired owner is registered as usual, so it is never
|
|
38
|
+
leaked, and killed immediately; no later candidate is attempted. The
|
|
39
|
+
kernel projects the cancel state (`requested`, then each kill's outcome,
|
|
40
|
+
including kills it starts itself) onto whichever owner is current, so a
|
|
41
|
+
transferred owner's unconfirmed kill is visible. A cancel
|
|
42
|
+
before any acquisition rejects the launch without acquiring anything. If
|
|
43
|
+
the in-flight acquisition fails, the settled previous attempt is still owned
|
|
44
|
+
and is terminated before delivery. Once every fallback launch has failed,
|
|
45
|
+
the natural failure is terminal before its delivery starts, so a later
|
|
46
|
+
cancel reports `already-terminal`.
|
|
47
|
+
5. **One result.** A confirmed cancel is finalized once by the attempt that owns
|
|
48
|
+
it and delivered once with the existing `killed` outcome and a
|
|
49
|
+
`cancellation` record (`requestedAt`, `termination`, `confirmedAt`). Pi
|
|
50
|
+
presents it with its existing "Subagent cancelled." summary and `cancelled`
|
|
51
|
+
error marker, never as a provider failure.
|
|
52
|
+
6. **Unconfirmed is not terminal.** A failed kill reports `unconfirmed` with the
|
|
53
|
+
error. The run keeps its live ownership, watcher, row, and panes; nothing is
|
|
54
|
+
delivered, retired, or released. A retry repeats the kill and keeps the first
|
|
55
|
+
`requestedAt`. If the wait later settles on its own, the producer makes one
|
|
56
|
+
kill attempt itself, then waits for an operator retry or shutdown
|
|
57
|
+
suppression, which settles without delivery and is not a cancellation:
|
|
58
|
+
a worktree manifest records what a plain shutdown would, never
|
|
59
|
+
`cancelled`.
|
|
60
|
+
7. **Surface ownership.** Pi `kill` closes an ordinary pane and confirms its
|
|
61
|
+
absence through Herdr; a close error on an already-absent pane is still
|
|
62
|
+
confirmed by that absence. A managed-worktree root pane is the retained
|
|
63
|
+
review workspace, and Herdr refuses to close it. For that child, `kill`
|
|
64
|
+
acts only on the child's **process identity**, established at launch from
|
|
65
|
+
immutable kernel facts, never from command-line text: Pi assigns
|
|
66
|
+
`process.title`, which rewrites `/proc/<pid>/cmdline` and erases
|
|
67
|
+
`--session`, and Herdr lists foreground processes only.
|
|
68
|
+
- *Capture.* The child protocol extension records its own PID, `/proc`
|
|
69
|
+
start time, boot ID, and PID-namespace link into a once-only sidecar
|
|
70
|
+
beside its session (`<session>.process.json`). In the background after
|
|
71
|
+
launch, the parent accepts the record only for this run and session,
|
|
72
|
+
only while that PID is alive with that start time on this boot in the
|
|
73
|
+
parent's own PID namespace (also proven by `/proc/self` naming the
|
|
74
|
+
parent), and only as Herdr's pane shell or a descendant of it. The
|
|
75
|
+
identity lives on the run record. A shell PID merely existing locally is
|
|
76
|
+
not namespace evidence; the recorded namespace link is.
|
|
77
|
+
- *Signal.* SIGTERM goes only to that identity, re-read (PID and start
|
|
78
|
+
time) immediately before `kill(2)`; a mismatch or read error is never
|
|
79
|
+
signalled. Node exposes no pidfd signal, so the kernel could still reuse
|
|
80
|
+
the PID between that read and the signal; this needs the Pi to exit and
|
|
81
|
+
its PID to be recycled within that window. There is no SIGKILL.
|
|
82
|
+
- *Confirm.* Confirmed only when that identity no longer exists (PID
|
|
83
|
+
absent, or a zombie), or when the pane is gone while the identity is not
|
|
84
|
+
known alive; an identity captured during that pane check is judged
|
|
85
|
+
before confirming. A live identity (including a suspended Pi with
|
|
86
|
+
SIGTERM pending) stays unconfirmed. An identity not captured (no record,
|
|
87
|
+
capture still pending at the kill deadline, a non-Linux host, a handoff
|
|
88
|
+
or resumed child), unreadable, from another boot or PID namespace, or
|
|
89
|
+
whose PID now has another start time is not signalled and is
|
|
90
|
+
unconfirmed unless pane absence confirms termination.
|
|
91
|
+
- *Bound.* Every provider await (Herdr process info during capture, pane
|
|
92
|
+
inspection during cancel) is bounded by the remaining capture or kill
|
|
93
|
+
deadline, so `unconfirmed` is reported on time; a late answer is
|
|
94
|
+
dropped and never flips a reported outcome. A cancel after the launch
|
|
95
|
+
capture expired starts one fresh capture bounded by that cancel's own
|
|
96
|
+
deadline, so a retry can pick up a sidecar written late.
|
|
97
|
+
|
|
98
|
+
The manifest records `cancelled` only for
|
|
99
|
+
confirmed termination, and the handoff is captured as for any completion.
|
|
100
|
+
There is no Git cleanup.
|
|
101
|
+
8. **Persistent specialists are rejected** before any kill; `subagent_stop`
|
|
102
|
+
keeps its graceful v1 semantics.
|
|
103
|
+
|
|
104
|
+
## Consequences
|
|
105
|
+
|
|
106
|
+
- Cancel never confirms more than its evidence: ordinary confirmation is Herdr
|
|
107
|
+
pane absence, which terminates the pane's PTY, not an OS PID check. Worktree
|
|
108
|
+
confirmation is the launch-captured process identity ceasing to exist; a
|
|
109
|
+
stopped Pi keeps SIGTERM pending and stays unconfirmed until it is resumed
|
|
110
|
+
or exits. The identity is the child's own report, trusted like its other
|
|
111
|
+
sidecars and bounded by liveness, namespace, and pane-ancestry checks at
|
|
112
|
+
capture.
|
|
113
|
+
- Worktree cancel is Linux-only in effect: elsewhere no identity is captured,
|
|
114
|
+
nothing is signalled, and only a gone pane confirms.
|
|
115
|
+
- An unconfirmed cancel can leave a live row indefinitely until a retry, the
|
|
116
|
+
child's exit, manual pane closure, or parent shutdown.
|
|
117
|
+
- Late callbacks after delivery change nothing: the retired ID answers
|
|
118
|
+
`already-terminal`.
|
|
119
|
+
|
|
120
|
+
## Rejected alternatives
|
|
121
|
+
|
|
122
|
+
- **Boolean flag plus gate around `kill`:** it misses pending acquisitions, the
|
|
123
|
+
abort-before-confirmation race, and finalization provenance.
|
|
124
|
+
- **`suppress` then `kill`:** it drops the one result the parent is waiting for.
|
|
125
|
+
- **Deliver `unconfirmed` and retire:** it would release live ownership whose
|
|
126
|
+
process may still be writing.
|
|
127
|
+
- **Close the worktree root pane:** it would discard the retained review
|
|
128
|
+
workspace that worktree runs promise to keep.
|
|
129
|
+
- **Match the owned process by argv (`--session`):** Pi's process-title
|
|
130
|
+
rewrite erases it, so a live Pi looked exited.
|
|
131
|
+
- **Treat a visible pane-shell PID as a shared PID namespace:** an unrelated
|
|
132
|
+
local process can hold the same number.
|
|
133
|
+
- **Escalate to SIGKILL automatically:** an operator retry repeats the bounded
|
|
134
|
+
SIGTERM check instead; forced escalation stays outside this decision.
|
|
@@ -4,7 +4,7 @@ This guide is the operational reference for running writing agents in isolated G
|
|
|
4
4
|
|
|
5
5
|
## Quick start
|
|
6
6
|
|
|
7
|
-
Run Pi inside Herdr from a Git checkout, then give each independent writing task a unique branch
|
|
7
|
+
Run Pi inside Herdr from a Git checkout, then give each independent writing task a unique branch. The examples name `worker`, `scout`, and `reviewer` roles; `pi-herdr-agents` ships no roles, so those names must come from an installed role pack or a project/global definition. Omit `agent` for a bare child.
|
|
8
8
|
|
|
9
9
|
```typescript
|
|
10
10
|
subagent({
|
|
@@ -36,17 +36,19 @@ subagent({
|
|
|
36
36
|
});
|
|
37
37
|
```
|
|
38
38
|
|
|
39
|
+
Omit `worktree` for an ordinary pane. If a generated tool client requires every declared property, pass `worktree: null`; the extension treats it exactly like omission and starts the child in `cwd` without calling `herdr worktree create`.
|
|
40
|
+
|
|
39
41
|
Worktrees isolate checkouts, indexes, and `HEAD`. They are **not security sandboxes**: worktrees still share the repository's object database and most refs, and the child process has the same host permissions as Pi.
|
|
40
42
|
|
|
41
43
|
## Launch contract
|
|
42
44
|
|
|
43
45
|
For a worktree launch:
|
|
44
46
|
|
|
45
|
-
- `cwd` selects the source Git repository. A relative tool argument is resolved from the parent Pi process's current directory.
|
|
47
|
+
- `cwd` selects the source Git repository. A relative tool argument is resolved from the parent Pi process's current directory. When `cwd` is a linked checkout, Herdr provisioning uses its principal checkout while the requested checkout supplies the base SHA and manifest provenance.
|
|
46
48
|
- `worktree.branch` is a new, unique branch name. Git/Herdr rejects a branch that cannot be created or is already checked out elsewhere.
|
|
47
49
|
- `worktree.base` may be any revision that resolves to a commit in the source repository. It defaults to committed `HEAD`.
|
|
48
50
|
- The extension resolves `base` to an exact SHA, writes an ownership manifest, then calls `herdr worktree create --no-focus`.
|
|
49
|
-
- The child starts at the root of the returned worktree, in that workspace's retained root pane and newly owned `Agents` tab. Finishing Pi returns to the interactive checkout shell; it does not close the root pane.
|
|
51
|
+
- The child starts at the root of the returned worktree, in that workspace's retained root pane and newly owned `Agents` tab. Finishing Pi returns to the interactive checkout shell; it does not close the root pane. A successful launch from a linked checkout does not itself authorize cleanup there: cleanup checks the canonical principal/source repository under the invoking parent session's cwd, not `manifest.sourceCwd` or shared Git identity. Start the parent Pi session rooted at the principal checkout or an ancestor containing it, then use normal explicit cleanup; changing directories inside an existing Pi session does not change its session cwd.
|
|
50
52
|
- Uncommitted and untracked files from the parent checkout are not copied. Commit anything the child must see before spawning it, or pass the needed context in the task.
|
|
51
53
|
- Worktree creation does not steal terminal focus.
|
|
52
54
|
|
|
@@ -112,6 +114,7 @@ Possible states are:
|
|
|
112
114
|
| `ready_for_review` | Child exited successfully; workspace retained |
|
|
113
115
|
| `needs_help` | Child called `caller_ping`; workspace retained |
|
|
114
116
|
| `failed` | Creation, launch, or execution failed; any created workspace is retained |
|
|
117
|
+
| `cancelled` | The parent cancelled the run with `subagent_cancel` and the exit of the child's launch-verified Pi process identity was confirmed; workspace, checkout, and commits retained |
|
|
115
118
|
| `removed` | Explicit parent cleanup verified checkout absence; branch and manifest retained |
|
|
116
119
|
|
|
117
120
|
The manifest supports ownership and inspection; v1 does not provide automatic reconciliation after a full Pi/Herdr restart. Do not edit manifests by hand.
|
|
@@ -146,7 +149,7 @@ For parallel read-only review, prepare one stable existing checkout of the pull
|
|
|
146
149
|
|
|
147
150
|
A `read,bash` tool allowlist does not enforce read-only behavior because Bash can mutate the checkout. Tell public reviewers to use only safe inspection, avoid artifact-generating verification, and consume supplied mechanical evidence. Public completion reports above 16,000 characters are abbreviated; when a completed report is needed, retrieve its final assistant message once from the supplied session path with bounded output. This is evidence retrieval, not live-session polling.
|
|
148
151
|
|
|
149
|
-
|
|
152
|
+
Review workflows supplied by role packs, such as `/skill:orchestrate` in `pi-herdr-roles`, build on this public-child pattern and document their own methodology. The host provides no review runner and creates no private review checkout. Reviewers read a head checkout, so the parent must materialize the changed-file inventory and unified diff, or complete before/after excerpts, because head-checkout reads cannot recover deleted or base-only blobs. Effective tools are the resolved role allowlist and deny rules.
|
|
150
153
|
|
|
151
154
|
```typescript
|
|
152
155
|
subagent({
|
|
@@ -191,6 +194,7 @@ The extension never pushes, creates a PR, merges, cherry-picks, or changes the p
|
|
|
191
194
|
- **Creation failure:** the manifest is marked failed. If Herdr created the branch but returned an incomplete response, the extension reconciles a unique branch match through `/worktree list` and records any recovered workspace/path.
|
|
192
195
|
- **Launch failure after creation:** the manifest is marked failed and the workspace, forked session, and path are retained. The destination is not focused unless Pi startup is confirmed.
|
|
193
196
|
- **Worker failure:** summary and available Git state are returned; the workspace remains open. Auto-exit waits until Pi is fully settled, so a transient provider error followed by automatic compaction or retry does not end the worker early.
|
|
197
|
+
- **Operator cancel:** `subagent_cancel` never closes the retained root pane or workspace. At launch, the child's protocol extension records its own process identity (PID, `/proc` start time, boot ID, and PID-namespace link) in `<session>.process.json`, and the parent accepts it only while that process is alive in the parent's PID namespace as the Herdr pane shell or a descendant of it. Cancel sends SIGTERM only to that identity, re-verified (PID and start time) immediately before the signal, then confirms that the identity no longer exists, or that the pane is gone while it is not known alive. Command-line text and Herdr's foreground list are never evidence: Pi rewrites its process title, and Herdr lists foreground processes only. A live identity (such as a suspended Pi with SIGTERM pending), or one whose SIGTERM fails while it is still alive, leaves termination `unconfirmed` even if the pane is gone. An identity that was not captured (including on non-Linux hosts), is unreadable, belongs to another boot or PID namespace, or whose PID now has another start time is never signalled and also leaves it `unconfirmed` unless pane absence confirms termination. The PID could still be reused between the final check and the signal, because Node has no pidfd signal. Every Herdr query is bounded by the cancel deadline, and an answer that arrives after the deadline, even before the timer runs, never changes the reported outcome. The run stays live, and retrying `subagent_cancel` re-checks; if the launch capture expired, the retry captures the identity again within its own deadline. On confirmation, the manifest is marked `cancelled` and the normal Git handoff is delivered once. A parent shutdown while termination is unconfirmed records the plain shutdown state, never `cancelled`. No Git cleanup, branch change, or removal happens.
|
|
194
198
|
- **`caller_ping`:** the child exits with `needs_help`; continue worktree-bound follow-up in the retained workspace rather than through `subagent_resume`. Public `subagent_resume` rejects managed-worktree child sessions before creating a pane so it cannot silently lose worktree ownership or policy.
|
|
195
199
|
- **Parent `/reload`, `/new`, `/resume`, or `/fork`:** active in-memory watchers transfer to the replacement parent session.
|
|
196
200
|
- **Full process restart or crash:** the worktree remains, but v1 does not automatically rediscover and resume its watcher.
|
|
@@ -217,7 +221,7 @@ Parent sessions have an inspect-only inventory and an explicit removal surface:
|
|
|
217
221
|
|
|
218
222
|
The equivalent tools are `worktree_list({})` and `worktree_remove({ target, preserve?: true })`. Use the exact path when a branch name is ambiguous. Children are not offered these tools or `/worktree remove`. Their existing `/worktree list` (repository-local Herdr listing) and `/worktree <name>` handoff remain available. Detached entries are labeled `(detached HEAD)` in the child listing and do not prevent cleanup inspection of named-branch siblings; the detached checkout itself remains blocked.
|
|
219
223
|
|
|
220
|
-
Authorization uses **cwd containment**: the canonical source repository root must equal or descend from the canonical session cwd. It does not use the managed checkout's location or require a current-session manifest. Discovery scans `~/.herdr/worktrees/*/*/`, joins Git registration and Herdr workspace state, and includes orphans from ended sessions. Out-of-scope entries are never removable; unregistered residue and failed probes are unknown, not clean. Inventory includes path, branch, source, workspace, Git state, manifest presence, concrete blockers, and separate process-inspection warnings. The managed root, source, and cwd are canonicalized: symlinked ancestors work normally, but a checkout symlink escaping the managed root is blocked.
|
|
224
|
+
Authorization uses **cwd containment**: the canonical source repository root must equal or descend from the canonical session cwd. For linked checkouts, this means the canonical principal/source repository under the invoking parent session's cwd; a successful launch does not itself authorize cleanup, and authorization does not use `manifest.sourceCwd` or shared Git identity. Start the parent Pi session rooted at the principal checkout or an ancestor containing it, then use normal explicit cleanup; changing directories inside an existing Pi session does not change its session cwd. It does not use the managed checkout's location or require a current-session manifest. Discovery scans `~/.herdr/worktrees/*/*/`, joins Git registration and Herdr workspace state, and includes orphans from ended sessions. Out-of-scope entries are never removable; unregistered residue and failed probes are unknown, not clean. Inventory includes path, branch, source, workspace, Git state, manifest presence, concrete blockers, and separate process-inspection warnings. The managed root, source, and cwd are canonicalized: symlinked ancestors work normally, but a checkout symlink escaping the managed root is blocked.
|
|
221
225
|
|
|
222
226
|
Removal rechecks containment, Git registration, no detected process holder, known live child, or persistent-specialist lease, and no uncommitted, untracked, or conflicted files. Liveness checks observable same-user processes from any session with a cwd inside the checkout, regardless of runtime name (including thread-suffixed Node names). Only Herdr-confirmed idle retained shell PIDs are exempt; an active runtime at the same PID is not. Detached HEAD, locked checkouts, initialized submodules, and conflicting identity evidence block removal. For initialized submodules, deinitialize them deliberately or use operator removal. No force option is provided.
|
|
223
227
|
|
|
@@ -231,7 +235,7 @@ Ignored files do not block cleanup. Inventory shows their exact file count, and
|
|
|
231
235
|
|
|
232
236
|
Open workspaces are removed through Herdr. Git-only orphans use `git worktree remove`, verify checkout absence, and then prune stale Git registrations. Failed removal is reported, never forced. A reachable owned manifest is merge-updated to `removed` with `workspaceRemovedAt` only after success; absent cross-session manifests are reported and are not rewritten. A manifest update failure after removal is a removed-with-warning result, not a failed removal. Removed manifests provide already-removed no-op evidence only; a new checkout at the same path is classified independently. Missing and dangling manifest paths are non-matches. Permission errors, symlink loops, and other undecidable manifest identities remain blockers, as do genuine identity disagreements. Cleanup Git and Herdr calls have 30-second timeouts; a timed-out operation fails closed rather than proceeding with removal.
|
|
233
237
|
|
|
234
|
-
Branches and their commits are always retained: cleanup never deletes, force-updates, or rewrites a branch. It never runs on completion, shutdown, or a timer.
|
|
238
|
+
Branches and their commits are always retained: cleanup never deletes, force-updates, or rewrites a branch. It never runs on completion, shutdown, or a timer. Session startup skips worktree inventory to avoid blocking Pi initialization; use `/worktree list` or `worktree_list` for an explicit inventory. Outside Herdr, explicit inventory tools remain available and report unavailable inspection as unknown. Unsupported platforms or failed global process enumeration block removal; individual visibility gaps are disclosed warnings, never proof that an orphan is idle.
|
|
235
239
|
|
|
236
240
|
## Current limits
|
|
237
241
|
|