5769c1cd22
- Auto-Registration-Bug behoben (register_project/get_project_id/resolve_project Trennung) - 25 Tests gruen (Pytest) - block_compactor-Tool refactored (Option B: Soft-Check statt Hard-Block) - 4 Restbaustellen gefixt - DB-Schema: plugin_settings-Tabelle hinzugefuegt - 3 Schattenprojekte aus DB geloescht - Plan v3 + Refactor-Plan + Worklog dokumentiert
173 lines
6.1 KiB
Markdown
173 lines
6.1 KiB
Markdown
# 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).
|