feat: disable model invocation for deprecated DSP dispatcher skills (#2) #13

Merged
steve merged 2 commits from issue-2-disableorarchivedeprecatedmodel-invokedskills into master 2026-06-27 23:36:42 -04:00
11 changed files with 38 additions and 195 deletions
+1 -1
View File
@@ -32,7 +32,7 @@ A collection of agent skills (slash commands and behaviors) loaded into Steve Be
- [resolving-merge-conflicts](common/engineering/resolving-merge-conflicts/SKILL.md) — Resolve an in-progress git merge/rebase conflict.
- [tdd](common/engineering/tdd/SKILL.md) — Test-driven development.
**Deprecated / model-invoked:**
**Deprecated / user-invoked:**
- [audio-product-dsp](common/deprecated/audio-production-dispatcher/SKILL.md) — Dispatch audio product DSP hardware/software engineering requests to the best specialist workflow with measurable product-focused outputs.
- [dsp-research-engineering](common/deprecated/dsp-research-dispatcher/SKILL.md) — Route DSP hardware and software research-engineering requests to the best specialist workflow and return a unified, decision-ready output.
- [forge-gitea](common/deprecated/forge-gitea/SKILL.md) — Work with Gitea repositories, issues, pull requests, releases, and CI.
+1 -1
View File
@@ -31,7 +31,7 @@ Skills that work in all CLI agents.
- [resolving-merge-conflicts](engineering/resolving-merge-conflicts/SKILL.md) — Resolve an in-progress git merge/rebase conflict.
- [tdd](engineering/tdd/SKILL.md) — Test-driven development.
**Deprecated / model-invoked:**
**Deprecated / user-invoked:**
- [audio-product-dsp](deprecated/audio-production-dispatcher/SKILL.md) — Dispatch audio product DSP hardware/software engineering requests to the best specialist workflow with measurable product-focused outputs.
- [dsp-research-engineering](deprecated/dsp-research-dispatcher/SKILL.md) — Route DSP hardware and software research-engineering requests to the best specialist workflow and return a unified, decision-ready output.
- [forge-gitea](deprecated/forge-gitea/SKILL.md) — Work with Gitea repositories, issues, pull requests, releases, and CI.
+1 -2
View File
@@ -4,8 +4,7 @@
- [forge-router](forge-router/SKILL.md) — High-level guidance for choosing the right forge skill.
## Model-invoked
**Deprecated / user-invoked:**
- [audio-product-dsp](audio-production-dispatcher/SKILL.md) — Dispatch audio product DSP hardware/software engineering requests to the best specialist workflow with measurable product-focused outputs.
- [dsp-research-engineering](dsp-research-dispatcher/SKILL.md) — Route DSP hardware and software research-engineering requests to the best specialist workflow and return a unified, decision-ready output.
- [forge-gitea](forge-gitea/SKILL.md) — Work with Gitea repositories, issues, pull requests, releases, and CI.
@@ -1,4 +1,5 @@
---
disable-model-invocation: true
name: audio-product-dsp
description: Dispatch audio product DSP hardware/software engineering requests to the best specialist workflow with measurable product-focused outputs
---
@@ -1,4 +1,5 @@
---
disable-model-invocation: true
name: research-engineering
description: Route DSP hardware and software research-engineering requests to the best specialist workflow and return a unified, decision-ready output
---
+24 -21
View File
@@ -13,11 +13,10 @@ The issue tracker conventions live in [`docs/agents/issue-tracker.md`](../../../
## Invocation
```
/skill:implement-issue <N> [--agent <name>] [--base <branch>] [--force]
/skill:implement-issue <N> [--base <branch>] [--force]
```
- `<N>` — required, the issue number
- `--agent <name>` — **DEPRECATED**: this argument is ignored. The agent CLI is read from `docs/agents/agent-cli.md`, which is set up by `/setup-skills` Section E. Rerun `/setup-skills` to change the agent.
- `--base <branch>` — optional, target base branch (default: repo default branch).
- `--force` — optional, allow overwriting an existing worktree.
@@ -119,7 +118,7 @@ Stop.
#### 2a. Label the issue `in-progress`
Apply the `in-progress` triage label.
Change the issue triage labels to `in-progress`
#### 2b. Create the worktree
@@ -131,7 +130,7 @@ git worktree add -b <branch-name> ../<repo-name>-issue-<N> <base>
Assemble a single prompt that the child agent will receive. Include:
- **Issue body** — the full markdown body from `tea issue <N> -o json`
- **Issue body** — the full markdown body of the issue.
- **Comments** — all comments, if any
- **Standing instruction**: "Implement using TDD: write a failing test first, make it pass, refactor. Explore the codebase before writing code. Respect ADRs and the project domain glossary. Set up the project (install dependencies, build) before starting. The issue body may contain Implementation Decisions and Testing Decisions sections — treat these as constraints."
- **Context**: "Base branch: `<base>`. Target your PR at `<base>`. Branch name: `<branch-name>`."
@@ -143,9 +142,10 @@ Assemble a single prompt that the child agent will receive. Include:
5. Commit with conventional commits (`feat:` for enhancement, `fix:` for bug) referencing `(#<N>)`
6. Push the branch: `git push origin <branch-name>`
7. Create a PR with: link to the issue, one-sentence summary, short key-changes list
8. Comment on the issue with the PR link: `tea comment <N> "PR opened: <url>"`
9. Change the issue label to `needs-review`: `tea issues edit <N> --add-labels "needs-review" --remove-labels "in-progress"`
10. Print `DONE — issue #<N>`
8. Comment on the issue with the PR link: `"PR opened: <url>"`
9. Change the issue triage label to `needs-review`
10. remove the prompt file from `/tmp` (the child may have already read it)
11. Print `DONE — issue #<N>`
- **Failure instruction**: "If any step fails, report where you stopped and what remains for manual recovery. Print the exact commands needed."
Write the full prompt to a temp file:
@@ -170,46 +170,49 @@ If available, use `mise x --allow-env='*' --` as the runner prefix. Otherwise, f
#### 4b. Compose the agent command
Substitute `@{prompt}` in the configured `args` with the absolute path to the temp prompt file:
Substitute `{prompt}` in the configured `args` with the absolute path to the temp prompt file. The prompt file path is `/tmp/issue-<N>-prompt.md`:
- If `args` is non-empty: the agent command is `<binary> <substituted-args>`
- If `args` is empty (stdin-piping agents): the agent command is `cat <prompt-file> | <binary>`
```bash
prompt_file="/tmp/issue-<N>-prompt.md"
substituted_args="${args//\{prompt\}/$prompt_file}"
```
- If `args` was non-empty: the agent command is `<binary> $substituted_args`
- If `args` was empty (stdin-piping agents): the agent command is `cat $prompt_file | <binary>`
#### 4c. Compose the full tmux command
Use `$substituted_args` from step 4b:
```bash
tmux new-window -n "issue-<N>-<repo-slug>" -c <absolute-worktree-path> "<runner-prefix> <agent-command>"
tmux new-window -n "issue-<N>-<repo-slug>" -c <absolute-worktree-path> "<runner-prefix> <binary> $substituted_args"
```
**With mise:**
```bash
tmux new-window -n "issue-<N>-<repo>" -c /path/to/worktree "mise x --allow-env='*' -- <binary> <args-with-prompt-subbed>"
tmux new-window -n "issue-<N>-<repo>" -c /path/to/worktree "mise x --allow-env='*' -- $binary $substituted_args"
```
**Without mise (fallback):**
```bash
tmux new-window -n "issue-<N>-<repo>" -c /path/to/worktree "$SHELL -c '<binary> <args-with-prompt-subbed>'"
tmux new-window -n "issue-<N>-<repo>" -c /path/to/worktree "$SHELL -c '$binary $substituted_args'"
```
For stdin-piping agents (empty args), wrap the pipe command:
For stdin-piping agents (empty args), use the pipe form:
**With mise:**
```bash
tmux new-window -n "issue-<N>-<repo>" -c /path/to/worktree "mise x --allow-env='*' -- sh -c 'cat <prompt-file> | <binary>'"
tmux new-window -n "issue-<N>-<repo>" -c /path/to/worktree "mise x --allow-env='*' -- sh -c 'cat $prompt_file | $binary'"
```
**Without mise:**
```bash
tmux new-window -n "issue-<N>-<repo>" -c /path/to/worktree "$SHELL -c 'cat <prompt-file> | <binary>'"
tmux new-window -n "issue-<N>-<repo>" -c /path/to/worktree "$SHELL -c 'cat $prompt_file | $binary'"
```
The window stays open after the child completes so the user can review the output.
After tmux launches, clean up the temp file:
```bash
rm /tmp/issue-<N>-prompt.md
```
Do not remove the prompt file immediately — the child agent may not have read it yet. The file will be read from `/tmp` and cleaned up by the OS or the child after use.
### 5. Print summary
@@ -1,161 +0,0 @@
# Agent CLI Tests for implement-issue
These tests verify the tmux command composition logic in `implement-issue`. They intercept the generated shell command string rather than the tmux invocation itself.
The seam being tested: given a `docs/agents/agent-cli.md` config and a `mise` availability state, `implement-issue` must compose the correct tmux launch command.
## Test fixtures
### Fixture: pi agent config (stdin-piped via @{prompt})
```yaml
# docs/agents/agent-cli.md
selected: pi
binary: pi
args: "-p @{prompt}"
```
### Fixture: opencode agent config
```yaml
# docs/agents/agent-cli.md
selected: opencode
binary: opencode
args: "run -f @{prompt}"
```
### Fixture: codex agent config (empty args = stdin pipe)
```yaml
# docs/agents/agent-cli.md
selected: codex
binary: codex
args: ""
```
### Fixture: missing binary config
```yaml
# docs/agents/agent-cli.md
selected: missing-agent
binary: totally-not-on-path
args: ""
```
## Test cases
### Test: composes correct tmux command for pi with mise available
**Given:**
- `docs/agents/agent-cli.md` contains the pi fixture
- `command -v mise` succeeds
**When:** `implement-issue` composes the tmux launch command
**Then:** the generated command string is:
```
tmux new-window -n "issue-42-ws-sjb-skills" -c /home/sjb/Projects/personal/ws-sjb-skills/ws-sjb-skills-issue-42 "mise x --allow-env='*' -- pi -p /tmp/issue-42-prompt.md"
```
**Notes:**
- `@{prompt}` is substituted with the actual temp file path
- Window name includes issue number and repo slug
- Worktree path is absolute
- `mise x --allow-env='*'` is prepended when mise is available
---
### Test: composes correct tmux command for pi without mise (fallback to $SHELL -c)
**Given:**
- `docs/agents/agent-cli.md` contains the pi fixture
- `command -v mise` fails (no mise on PATH)
**When:** `implement-issue` composes the tmux launch command
**Then:** the generated command string is:
```
tmux new-window -n "issue-42-ws-sjb-skills" -c /home/sjb/Projects/personal/ws-sjb-skills/ws-sjb-skills-issue-42 "$SHELL -c 'pi -p /tmp/issue-42-prompt.md'"
```
**Notes:**
- Falls back to `$SHELL -c` when mise is absent
- The agent command is wrapped inside `$SHELL -c '...'`
---
### Test: composes correct tmux command for codex (stdin piping, no @{prompt})
**Given:**
- `docs/agents/agent-cli.md` contains the codex fixture (args: "")
- `command -v mise` succeeds
**When:** `implement-issue` composes the tmux launch command
**Then:** the generated command string is:
```
tmux new-window -n "issue-42-ws-sjb-skills" -c /home/sjb/Projects/personal/ws-sjb-skills/ws-sjb-skills-issue-42 "mise x --allow-env='*' -- sh -c 'cat /tmp/issue-42-prompt.md | codex'"
```
**Notes:**
- When args is empty, prompt is piped via `cat <prompt> | <binary>`
- The pipe syntax is always `cat <prompt> | <binary>` for stdin-based agents
---
### Test: fails fast with clear message when binary not on PATH
**Given:**
- `docs/agents/agent-cli.md` contains the missing binary fixture
- `command -v totally-not-on-path` fails
**When:** `implement-issue` validates the binary at invocation time
**Then:** it fails immediately with:
```
Agent 'totally-not-on-path' not found on PATH — rerun /setup-skills to reconfigure.
```
**Notes:**
- Validation happens before any tmux launch
- Error message directs user to re-run setup-skills
---
### Test: reads selected agent from docs/agents/agent-cli.md
**Given:**
- `docs/agents/agent-cli.md` exists and contains valid YAML with `selected`, `binary`, and `args` fields
**When:** `implement-issue` reads the config at invocation time
**Then:** it parses the three fields correctly and uses them for dispatch
**Notes:**
- Does not use hardcoded dispatch table
- Does not run detection scripts
- Reads directly from the repo-side config file
---
### Test: @{prompt} placeholder substitution
**Given:**
- `docs/agents/agent-cli.md` contains opencode fixture (args: "run -f @{prompt}")
- `command -v mise` succeeds
**When:** `implement-issue` composes the tmux launch command with prompt file at `/tmp/issue-99-prompt.md`
**Then:** the generated command contains:
```
opencode run -f /tmp/issue-99-prompt.md
```
**Notes:**
- `@{prompt}` in args is replaced with the absolute path to the temp prompt file
- Works regardless of where `@{prompt}` appears in the args string
@@ -9,7 +9,7 @@ agents:
- name: pi
binary: pi
args: "@{prompt}"
description: "My primary agent harness. Accepts prompt file via @{prompt}."
description: "My primary agent harness. Accepts prompt file via {prompt}."
- name: opencode
binary: opencode
@@ -26,7 +26,7 @@ agents:
- name: codex
binary: codex
args: "@{prompt}"
description: "OpenAI Codex. Accepts prompt file via @{prompt}."
description: "OpenAI Codex. Accepts prompt file via {prompt}."
- name: claude
binary: claude
@@ -41,6 +41,6 @@ agents:
|-------|-------------|
| `name` | Display name used in menus and `--agent` flag |
| `binary` | Command name expected on PATH |
| `args` | Static arguments appended after the binary. May include `@{prompt}` which is substituted at invocation time with the absolute path to the prompt file. Empty string means stdin piping (prompt is piped via `cat`). |
| `args` | Static arguments appended after the binary. May include `{prompt}` which is substituted at invocation time with the absolute path to the prompt file. Empty string means stdin piping (prompt is piped via `cat`). |
| `description` | Short human-readable description for the setup menu |
| `note` | Optional additional context |
@@ -1,6 +1,6 @@
# Triage Labels
The skills speak in terms of five canonical triage roles. This file maps those roles to the actual label strings used in this repo's issue tracker.
The skills speak in terms of seven canonical triage roles. This file maps those roles to the actual label strings used in this repo's issue tracker.
| Label in skills | Label in our tracker | Meaning |
| -------------------------- | -------------------- | ---------------------------------------- |
@@ -12,6 +12,6 @@ The skills speak in terms of five canonical triage roles. This file maps those r
| `in-progress` | `in-progress` | Being actively worked on by a human or agents |
| `wontfix` | `wontfix` | Will not be actioned |
When a skill mentions a role (e.g. "apply the AFK-ready triage label"), use the corresponding label string from this table.
When a skill mentions a role (e.g. "apply the AFK-ready triage label"), use the corresponding label string from this table. Only one triage label should be active.
Edit the right-hand column to match whatever vocabulary you actually use.
+2 -2
View File
@@ -1,6 +1,6 @@
# Agent CLI Configuration
The CLI agent used by `/implement-issue` for spawning child agents in isolated git worktrees.
The CLI agent used for spawning child agents in isolated git worktrees.
## Configuration
@@ -16,7 +16,7 @@ args: "@{prompt}"
|-------|-------------|
| `selected` | Display name of the selected agent |
| `binary` | Command name expected on PATH |
| `args` | Static arguments. `@{prompt}` is substituted with the prompt file path at invocation time. Empty means stdin piping via `cat`. |
| `args` | Static arguments. `{prompt}` is substituted with the prompt file path at invocation time. Empty means stdin piping via `cat`. |
## Changing the agent
+2 -2
View File
@@ -1,6 +1,6 @@
# Triage Labels
The skills speak in terms of five canonical triage roles. This file maps those roles to the actual label strings used in this repo's issue tracker.
The skills speak in terms of seven canonical triage roles. This file maps those roles to the actual label strings used in this repo's issue tracker.
| Label in skills | Label in our tracker | Meaning |
| -------------------------- | -------------------- | ---------------------------------------- |
@@ -12,4 +12,4 @@ The skills speak in terms of five canonical triage roles. This file maps those r
| `in-progress` | `in-progress` | Being actively worked on by a human or agents |
| `wontfix` | `wontfix` | Will not be actioned |
When a skill mentions a role (e.g. "apply the AFK-ready triage label"), use the corresponding label string from this table.
When a skill mentions a role (e.g. "apply the AFK-ready triage label"), use the corresponding label string from this table. Only one triage label should be active.