Files
lda-wf/docs/superpowers/specs/2026-06-28-draft-remove-commands.md
T

134 lines
4.7 KiB
Markdown

# Draft Remove Commands Design
## Status
Planned.
## Problem
Draft workspaces now support focused constructive edits: create a draft, add a
capability step, bind inputs/outputs, branch routes, handle outcomes, and
compile. The missing mirror operation is safe removal. In challenge runs, agents
recover from bad edits by switching to raw-plan import or by writing JSON Patch
directly, because there is no simple command for undoing one bad draft element.
The immediate recovery cases are:
- A wrong route target was added and should be removed before re-routing.
- A wrong capability step was added and should be removed.
- A wrong input or output binding was added and should be removed.
Generic `wf draft patch` can already express these changes, but it forces agents
to know JSON Pointer paths and the exact draft document shape. These focused
commands keep the public surface aligned with the draft authoring model.
## Scope
Add three semantic remove operations:
```text
wf draft remove-route <workspace_id> --revision N --step STEP --outcome OUTCOME
wf draft remove-step <workspace_id> --revision N --step STEP
wf draft remove-binding <workspace_id> --revision N --step STEP --input LOCAL
wf draft remove-binding <workspace_id> --revision N --step STEP --output LOCAL
```
`remove-binding` may accept repeated `--input` and `--output` flags in one call.
The names refer to local capability fields:
- `--input message` removes input bindings whose local target is `message`.
- `--output content` removes output bindings whose local source is `content`.
## Semantics
Remove commands use the same revision-checked draft workspace mutation path as
`branch`, `handle`, `bind`, and `add-step`.
If the requested element exists:
- the edit is persisted,
- the workspace revision increments,
- the returned status may be `valid` or `invalid`,
- diagnostics are returned when the removal leaves dangling control-flow or
schema/binding issues.
If the requested element does not exist:
- the operation is a no-op,
- the revision does not increment,
- the current workspace summary is returned.
This mirrors current no-op behavior in `branch`/`handle` and makes cleanup
commands idempotent enough for agents to retry safely.
## Step Removal Policy
`remove-step` removes:
- `steps[STEP]`
- `routes[STEP]`, if present
It does not remove inbound routes from other steps to `STEP`.
Reason: automatic inbound cleanup hides control-flow decisions. If removing a
step breaks the graph, validation should report `unknown_edge_destination` so
the agent can explicitly route the predecessor somewhere else with
`wf draft handle` or `wf draft branch`.
## Binding Removal Policy
`remove-binding` edits only the selected step's binding list:
- input mode removes entries from `/steps/{step}/input` where `target` equals
the provided local field.
- output mode removes entries from `/steps/{step}/output` where `source` equals
the provided local field.
It does not delete input/state/output schema fields. Schema deletion is a
separate problem because schema fields may still be referenced by other steps,
workflow outputs, or future edits. Validation diagnostics should surface unused
or broken paths; the first remove slice should not infer schema garbage
collection.
## Transport/API Shape
The API surface should add semantic methods on the draft authoring API:
```python
remove_draft_route(workspace_id, revision, step_id, outcome)
remove_draft_step(workspace_id, revision, step_id)
remove_draft_binding(workspace_id, revision, step_id, inputs, outputs)
```
Expose them through:
- `WorkflowApi` facade
- `WorkflowDraftSurface` protocol
- JSON-RPC methods under `workflow.draft_workspaces.*`
- RPC client mixin
- MCP workflow surface tools
- `wf draft` CLI commands
## Non-Goals
- Do not implement revision forking.
- Do not add a nested `wf draft step ...` namespace in this slice.
- Do not delete schema fields.
- Do not infer replacement routes.
- Do not make `remove-step` recursively delete dependent steps.
- Do not change strict `draft save` / `draft compile` boundaries.
## Acceptance Criteria
- `wf draft remove-route` removes an existing route and persists the resulting
draft, even if validation becomes invalid.
- `wf draft remove-step` removes the step and its outgoing route map, leaves
inbound routes untouched, and returns diagnostics if the graph now points at a
missing step.
- `wf draft remove-binding --input` removes matching input bindings.
- `wf draft remove-binding --output` removes matching output bindings.
- Missing elements are no-op operations that do not advance revision.
- All commands are exposed over API, RPC, MCP, and CLI.
- Docs and skills explain that remove commands may return `status: invalid` and
should be followed by `wf draft validate`.