@@ -0,0 +1,167 @@
|
||||
# Multi-work
|
||||
|
||||
`multi-work` is a **primary-only** agent for coordinating independent work in
|
||||
Herdr-managed Git worktrees. Like `coordinate`, it uses the configured `deep-lo`
|
||||
model and effort, falling back to `good-lo` when `deep-lo` is unavailable. No
|
||||
extra custom model assignment is required.
|
||||
|
||||
```text
|
||||
multi-work (root checkout)
|
||||
├── fast-lo (local retrieval)
|
||||
└── coordinate (new Herdr worktree)
|
||||
└── existing leaf workers (that worktree)
|
||||
```
|
||||
|
||||
## Availability
|
||||
|
||||
The agent appears when the plugin can verify a live, unambiguous Herdr root
|
||||
workspace for the current **checkout root directory**, and coordinate/fast-lo are
|
||||
available. Herdr and Git must be executable by the OpenCode server. The CLI uses
|
||||
that server process's Herdr socket/session configuration; it never targets the
|
||||
UI-focused workspace.
|
||||
|
||||
Eligibility is location-based: all OpenCode clients viewing the eligible location
|
||||
can see the agent. This does not identify the client's pane. Linked worktrees,
|
||||
subdirectories, closed workspaces, duplicate workspace ownership, unavailable CLI,
|
||||
and failed discovery do not qualify. Missing workspace metadata is resolved using
|
||||
Herdr's worktree inventory rather than assuming a Git root is a Herdr root.
|
||||
|
||||
The registry refreshes every 30 seconds. Every multi-work model turn and delegation
|
||||
rechecks the executing session's location; creation revalidates the root again
|
||||
immediately before its Git/Herdr operations. Stale picker visibility cannot authorize
|
||||
creation. Creating/opening the root workspace remains a user action.
|
||||
|
||||
## Configuration
|
||||
|
||||
Use OpenCode **2.0.4**, the version this integration targets. At both the root and
|
||||
destination locations, configure:
|
||||
|
||||
```jsonc
|
||||
{
|
||||
"experimental": { "subagent_depth": 2 },
|
||||
}
|
||||
```
|
||||
|
||||
The plugin does not modify your global configuration. Native OpenCode still
|
||||
enforces nesting depth; its default of 1 is insufficient for coordinate's workers.
|
||||
The public plugin context does not expose a configuration reader to preflight
|
||||
the effective depth.
|
||||
|
||||
Each destination must load the multi-work-enabled plugin and the required worker
|
||||
models. A global plugin installation/configuration is useful when source branches
|
||||
have different project configuration. The tool checks the destination's live agent
|
||||
registry for the coordinate protocol marker and required worker agents before
|
||||
prompting. This checks feature availability, not the trustworthiness of other
|
||||
plugins or project configuration.
|
||||
|
||||
## Delegation
|
||||
|
||||
Multi-work retains the native tool name, `subagent`. It adds one argument:
|
||||
|
||||
```js
|
||||
subagent({
|
||||
agent: "coordinate",
|
||||
description: "Implement API change",
|
||||
prompt: "Goal, scope, constraints, and acceptance checks...",
|
||||
worktree: { base: "feature/source" },
|
||||
background: true,
|
||||
});
|
||||
```
|
||||
|
||||
`base` identifies a locally available branch or remote-tracking branch. The tool
|
||||
resolves its commit and creates a new unique `multi-work/<uuid>` branch with Herdr.
|
||||
It does not fetch refs or copy uncommitted root changes. Herdr determines the
|
||||
checkout path; the tool parses and verifies the returned checkout/workspace.
|
||||
Creation explicitly preserves focus with `--no-focus`.
|
||||
|
||||
For focused retrieval, use native `subagent` with `agent: "fast-lo"` and no
|
||||
`worktree`. Resume an owned coordinate child with its `sessionID` and **omit**
|
||||
`worktree`. Resumes verify parent, agent, checkout, branch, and live Herdr ownership.
|
||||
Bound coordinate children cannot be repurposed through native delegation.
|
||||
|
||||
Neither multi-work nor coordinate has general shell/edit permissions. Multi-work
|
||||
also rejects non-reading/non-delegation tools at execution, including Code Mode,
|
||||
even if a session permission override would expose them. Worktree preparation
|
||||
requires effective `herdr_worktree: allow`, evaluated against the canonical root
|
||||
directory using ordered agent and session rules. `ask` fails explicitly because
|
||||
the public plugin API cannot request custom-tool approval. Native subagent
|
||||
permissions are still asserted by OpenCode before preparation starts.
|
||||
|
||||
Worktree permissions inherit the base plugin's **effective build-permission
|
||||
snapshot**, including configuration applied after plugin transforms. Its existing
|
||||
`agent.updated` listener refreshes that snapshot and replays the registry when it
|
||||
changes. Later `multi-work` agent rules and session rules retain their precedence;
|
||||
inheritance does not turn a build deny into an unconditional execution-time veto
|
||||
against an explicitly configured later allow.
|
||||
|
||||
## Native lifecycle and placement
|
||||
|
||||
The plugin composes the original **Effect executor** in place, preserving the
|
||||
`subagent` tool identity, native child ancestry, progress/result metadata,
|
||||
foreground results, background job handling, and completion notifications. It does
|
||||
not create substitute top-level sessions or a separate job scheduler.
|
||||
|
||||
OpenCode 2.0.4 awaits a child-ID progress callback after child creation and before
|
||||
prompting. The wrapper uses that boundary to create the worktree, move the explicit
|
||||
child ID, and confirm its actual session location before allowing the task prompt.
|
||||
A move-request acknowledgement alone is insufficient. Confirmation is bounded to
|
||||
30 seconds and remains interruptible. The parent session does not move.
|
||||
|
||||
Coordinate is child-capable only through an owned, ready worktree binding. Prompt
|
||||
admission and model-context guards reject unbound or moved coordinate children.
|
||||
Multi-work cannot be a child, and the existing workers remain leaves.
|
||||
|
||||
Normal delegation cards and child navigation recognize the retained `subagent`
|
||||
name. Children remain in the session family after moving; they do not become
|
||||
top-level entries in root-session pickers. Moving a session does not attach an
|
||||
OpenCode TUI to the new Herdr pane.
|
||||
|
||||
## Failures and verification limits
|
||||
|
||||
The plugin records the attempted child/branch and the returned worktree binding,
|
||||
and reports progress IDs during preparation. Failed or interrupted initialization
|
||||
does not admit the task prompt. It retains resources rather than deleting checkouts
|
||||
or closing workspace groups. Inspect reported IDs and Herdr inventory before
|
||||
retrying an ambiguous creation failure; CLI interruption cannot roll back a request
|
||||
already accepted by Herdr. Unready children are not resumable as completed setups.
|
||||
|
||||
The ordinary suite uses isolated Git repositories and simulated Herdr responses.
|
||||
It covers gating, source refs, ordering, failures, and interruption. Composite tests
|
||||
run the exported plugin through the real Promise adapter, apply configuration after
|
||||
both plugin transforms, replay twice, and test separate location registries sharing
|
||||
disk-backed bindings across plugin scope restarts. Their executor is simulated.
|
||||
|
||||
An opt-in integration check runs the **real OpenCode 2.0.4 server and native
|
||||
subagent executor**:
|
||||
|
||||
```sh
|
||||
OPENCODE_204=/absolute/path/to/2.0.4/opencode bun scripts/test-multi-work-host.ts
|
||||
```
|
||||
|
||||
It requires the exact-version binary (for Linux x64, published as
|
||||
`@opencode/cli-linux-x64@2.0.4`), uses fresh HOME/XDG/config/database paths under
|
||||
`/tmp/opencode`, and starts only loopback services. Herdr is a fake CLI performing
|
||||
real Git worktree operations in the fixture repository; the model is a deterministic
|
||||
HTTP endpoint. Fixture resources and logs are retained at the printed path.
|
||||
|
||||
Verified with this host check:
|
||||
|
||||
- Late configured build deny and a subsequent session allow.
|
||||
- Native child creation/ancestry, confirmed move before first prompt, and foreground result.
|
||||
- Separate root/destination plugin instances reading the host's persistent binding store.
|
||||
- Resuming that child after a complete host restart, then native background completion
|
||||
and its synthetic notification to the parent.
|
||||
- Interrupting a foreground RPC while the child awaits its model response causes
|
||||
the native executor to interrupt the child; the parent remains at the root.
|
||||
|
||||
The fixture RPC invokes the actual wrapped executor; it does not exercise the
|
||||
parent model's tool-call dispatch or rendered tool cards. Recovery of an **in-flight**
|
||||
job across a crash, coordinate-to-leaf nesting, background cancellation, live Herdr
|
||||
focus/pane behavior, and TUI/web/mini navigation remain unverified end-to-end. A
|
||||
completed child resumed after restart is not evidence of in-flight job recovery.
|
||||
|
||||
The progress boundary is version-sensitive, not a documented initialization hook.
|
||||
Before upgrading OpenCode, verify native initialization order, foreground/background
|
||||
interruption, notifications/recovery, and TUI/web/mini navigation after refresh.
|
||||
Other authenticated clients/plugins are trusted: these guards are not an API-wide
|
||||
sandbox, and cwd placement is not filesystem isolation for shell-capable workers.
|
||||
Reference in New Issue
Block a user