Files
a0_software_orchestrator/help/handover/help.md
T

173 lines
6.1 KiB
Markdown
Raw Normal View History

# handover_to_specialist Tool Documentation
> **Status:** Phase 1 (read-only spike). The tool prepares a stage-1 handover
> package and appends a per-specialist briefing file. It does **not** yet
> invoke the subagent the orchestrator follows up with `call_subordinate()`.
---
## Purpose
The Software-Orchestrator plugin exposes a single specialist hand-off tool
that follows the **3-stage context-transfer pattern** documented in
`/usr/workdir/handover-spike.md` (sections 4 and 5):
1. **Stage 1 (default):** token-bounded package = `summary` + last N turns +
decisions + artifacts. Cost ≈ 1 500 4 000 tokens.
2. **Stage 2 (opt-in):** specialist calls `request_full_history()` for the
full chat context, capped at 50 000 tokens with automatic compaction.
3. **Stage 3 (persistent):** briefing file in
`<project_root>/.a0proj/handover/<specialist>-<topic>-<date>.md`,
append-only Markdown, readable on demand by the specialist.
The goal is to give the user the experience of talking to a named specialist
(frontend designer, planner, architect, …) while keeping token usage low and
context safe.
---
## Tool signature
```python
handover_to_specialist(
specialist_profile: str, # required, must be in the allow-list
topic: str, # required, short slug for the briefing file
summary: str, # LLM-curated summary of the older turns
recent_turns: list[str], # verbatim last turns (auto-trimmed to N)
decisions: list[str], # decisions made so far
artifacts: list[str], # paths / references to relevant files
return_condition: str, # when the specialist should hand back
handover_reason: str, # logged into the briefing file
project_root: str, # absolute path to the project root
max_context_tokens: int, # default 3000; warning if exceeded
include_recent_turns: int, # default 5
)
```
### Argument notes
| Argument | Required | Notes |
|----------|----------|-------|
| `specialist_profile` | ✅ | One of the 11 known profiles (see below). |
| `topic` | ✅ | Short slug. Used in the briefing filename. |
| `summary` | recommended | LLM-curated; max 300 tokens recommended. |
| `recent_turns` | optional | Auto-trimmed to `include_recent_turns`. |
| `decisions` | optional | Free-form bullet points. |
| `artifacts` | optional | File paths or other references. |
| `return_condition` | optional | Default `user_request`. |
| `handover_reason` | optional | Logged in the briefing. |
| `project_root` | ✅ | Must be absolute. Used for the briefing file path. |
| `max_context_tokens` | optional | Default 3000. |
| `include_recent_turns` | optional | Default 5. |
---
## Known specialist profiles
The tool accepts only the following profile names. This is an explicit
allow-list (defence-in-depth): a typo in the profile name produces a clear
`ERROR` response, not a silent miss.
- `a0_software_orchestrator`
- `codebase_explorer`
- `implementation_engineer`
- `quality_reviewer`
- `release_auditor`
- `requirements_analyst`
- `runtime_devops_engineer`
- `security_data_engineer`
- `solution_architect`
- `test_debug_engineer`
- `hacker`
`frontend_designer` is **not** a known profile in Phase 1. It is on the
roadmap for Phase 2.
---
## Return value
The tool returns a JSON object with three top-level keys:
```json
{
"status": "ok",
"persona_marker": "[frontend designer]",
"package": {
"specialist": "frontend_designer",
"topic": "landing-page-hero",
"summary": "...",
"briefing_file": "/abs/path/.a0proj/handover/frontend-designer-landing-page-hero-2026-06-05.md",
"estimated_tokens": 2143,
"max_context_tokens": 3000,
"oversize_warning": false
},
"briefing": {
"path": "/abs/path/.a0proj/handover/frontend-designer-landing-page-hero-2026-06-05.md",
"existed_before": false,
"newly_created": true,
"size_bytes": 1789
},
"next_step": "Orchestrator: review the package, then call_subordinate(...)"
}
```
If the package exceeds `max_context_tokens`, a `WARNING:` line is appended
to the response so the orchestrator can decide whether to truncate.
---
## Errors
The tool never raises an unhandled exception. All error paths return a
`Response(message="ERROR: …", error=True)` so the orchestrator can decide
how to react.
Common error cases:
| Error | Cause |
|-------|-------|
| `specialist_profile is required` | missing or empty |
| `unknown specialist profile` | not in the allow-list |
| `topic is required` | missing or empty |
| `project_root is required` | missing or empty |
| `project_root must be absolute` | relative path |
| `max_context_tokens must be positive` | ≤ 0 |
| `failed to append briefing file` | OSError (permissions, disk full, …) |
---
## What the tool does NOT do (Phase 1 limits)
- ❌ Does **not** call `call_subordinate()`. The orchestrator is expected to
do that in a follow-up reasoning step.
- ❌ Does **not** LLM-summarise the older turns. The orchestrator must pass a
pre-computed `summary` argument.
- ❌ Does **not** update the `state_store`. A future phase will add a
`state_store.snapshot()` call before the briefing is written.
- ❌ Does **not** modify the chat loop or any framework core.
- ❌ Does **not** expose a UI persona marker yet. Phase 3 will add the
`🖌️ Designer` style marker to the chat output.
---
## Phase-2 plan (forward-looking)
- `request_full_history()` tool for specialists (stage 2).
- `call_subordinate()` wired into the orchestrator flow with persona marker.
- Loop guard: `max_handover_depth = 3` to prevent bouncing.
- Integration with `state_store.snapshot()` for crash safety.
- Add `frontend_designer` (and any other missing) profile to the allow-list.
- UI persona marker in the webui chat output.
---
## Related files
- Helper: `helpers/handover_protocol.py`
- Helper: `helpers/briefing_file.py`
- Tool: `tools/handover_to_specialist.py`
- Spike design doc: `/usr/workdir/handover-spike.md`
- Memory-protection rules: enforced inside `handover_protocol.py`
(no mid-subagent compaction, no overwrite, briefing ≠ chat history).