7.5 KiB
| id | slug | title | status | kind | priority | labels | created_at | updated_at | assignee | legacy_ticket | ||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 20260529-205540-spawnpod-profile-tool-description | spawnpod-profile-tool-description | SpawnPod profile selection and templated tool description | open | feature | P2 |
|
2026-05-29T20:55:40Z | 2026-05-29T20:55:40Z | null | null |
Background
SpawnPod is becoming the main mechanism for hierarchical orchestration. The workflow model now distinguishes role-specific child Pods: lower orchestrators, coder Pods, and external reviewer Pods. These roles should be selectable by profile, but the current SpawnPod tool has no profile field and no LLM-visible route to discover profile selectors.
A separate ListProfiles tool would expose mostly static or semi-static affordance information as another model action. The desired design is instead to make profile choices part of the SpawnPod tool's own guidance: render the available profile selectors into the tool description, and repeat the same selector list in invalid/ambiguous/no-default diagnostics.
Current implementation notes:
- Tool metadata is defined by
llm_worker::tool::ToolMeta;ToolDefinitionfactories return(ToolMeta, Arc<dyn Tool>)andToolServerHandle::flush_pending()materializes them before request construction. - Tool descriptions are currently hard-coded strings/doc comments in each tool factory.
crates/pod/src/spawn/tool.rshas a staticDESCRIPTIONandSpawnPodInputonly containsname,instruction,task, andscope. SpawnPodcurrently builds an internalPodManifestConfigdirectly from the parent model, optional instruction override, and delegated scope, then launches the child with hidden--spawn-config-json. It does not use profile resolution.- Prompt assets are centralized under
resources/prompts; Pod-owned prompt injection strings are represented byPodPromptand rendered byPromptCatalogthrough minijinja.resources/prompts/internal.tomlhas build-time coverage againstPodPromptvariants. - Profile discovery/resolution already exists in
manifest:ProfileDiscovery::for_cwd,ProfileRegistry,ProfileSelector,NixProfileResolver, and source-qualified selectors such asproject:coder,project:reviewer, andbuiltin:default.
Requirements
- Add an optional
profilefield toSpawnPodInput. - Make
SpawnPod's LLM-facing tool description include the currently discoverable profile selectors and the effective default profile. - Do not add a separate
ListProfilestool for this feature. - The profile list in the tool description must come from the same builtin/user/project profile discovery rules used by the profile launcher path.
- If profile discovery fails, the tool should still be registered with a clear diagnostic in its description rather than making Pod startup fail solely because the description could not list profiles.
- If
profileis omitted,SpawnPodresolves the effective default profile. With the builtin default profile present, ordinary omission should keep working. - If
profileis invalid, ambiguous, unsupported, or omitted while no default can be resolved, the tool error must include a compact available-profile list and source-qualified suggestions. SpawnPod.profileshould initially accept registry/default selectors only:default,builtin:<name>,user:<name>,project:<name>, and unqualified names only when unambiguous. Raw path selectors,path:<path>, relative paths, absolute paths, and.nixpath-like values are rejected for the tool path.SpawnPod.scoperemains the only delegated capability. A profile selected throughSpawnPodmust not be able to expandscope.allowbeyond the explicit tool argument.SpawnPod.namealways overridespod.namein the resolved child manifest.SpawnPod.instruction, if present, is a typed override for the resolved profile'sworker.instructiononly; it must not replace the whole profile.- Profile-selected spawn should preserve profile-owned role configuration such as model, worker settings, tools/memory/web policy, and prompt pack where applicable, subject to the explicit
nameandscopeoverrides. - Existing hidden
--spawn-config-jsonremains the internal launch handoff.SpawnPodresolves/merges profile data in the parent process and passes the resulting manifest config/snapshot to the child; it should not simply execinsomnia-pod --profile. - Documentation/workflows should show
SpawnPod(profile = "project:coder"),SpawnPod(profile = "project:reviewer"), and optionallyproject:orchestratoras role selectors, while keeping scope authority separate from profile role selection.
Tool description templating direction
Use the existing prompt infrastructure rather than scattering another large hard-coded string.
Acceptable implementation shape:
- Add a Pod-owned prompt/catalog entry for the
SpawnPodtool description, e.g.spawn_pod_tool_description, with minijinja variables such asavailable_profiles,default_profile, andprofile_diagnostic. - Render this prompt when registering
SpawnPodinregister_pod_tools, using the Pod cwd as the profile discovery base. - Keep the rendered description as
ToolMeta.description; the tool metadata still remains session-scoped after registration. - The same formatter used for the description should be reusable by error diagnostics so invalid profile errors repeat the available selectors.
If a more general tool-description catalog is introduced, keep the initial scope narrow: it must support SpawnPod without forcing every built-in tool to migrate in the same ticket.
Acceptance criteria
SpawnPodschema exposes optionalprofilewith clear field docs.SpawnPodtool description includes a compact available-profile block and default-profile guidance.SpawnPodinvalid/ambiguous/no-default profile errors include the same compact selector list and tell the model to use a listed selector.SpawnPod(profile = "project:reviewer")resolves the project reviewer profile and applies its role config while replacingpod.nameandscope.allowwith the explicitSpawnPodvalues.SpawnPodwith omitted profile resolves the effective default profile.SpawnPod(profile = "./reviewer.nix"),SpawnPod(profile = "path:./reviewer.nix"), and absolute profile paths are rejected with an explanation that the tool accepts registry/default selectors only.- Ambiguous unqualified profile names fail closed with source-qualified suggestions.
- A profile's
scope.allowcannot grant access not present inSpawnPod.scope. - Existing
SpawnPodbehavior that matters for lifecycle remains intact: registry reservation/rollback, scope revocation from the spawner, callback wiring, child socket wait, and initialMethod::Runconfirmation. - Unit/integration tests cover description rendering, selector formatting, omitted default resolution, invalid selector diagnostics, profile config application, explicit instruction override, and scope authority replacement.
- Documentation and
.insomnia/workflow/references explain profile-based coder/reviewer/orchestrator spawning without introducing aListProfilestool.
Non-goals
- Do not introduce an LLM-callable
ListProfilestool. - Do not enable arbitrary profile path evaluation through
SpawnPod. - Do not revive manifest cascade or generic overlay layers.
- Do not redesign prompt-loader source selection for
$user/$workspaceprofile prompt refs in this ticket unless it is required to keep current behavior correct. - Do not implement encrypted secret storage; profiles may still contain unresolved typed secret refs as currently documented.