- 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
6.1 KiB
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):
- Stage 1 (default): token-bounded package =
summary+ last N turns + decisions + artifacts. Cost ≈ 1 500 – 4 000 tokens. - Stage 2 (opt-in): specialist calls
request_full_history()for the full chat context, capped at 50 000 tokens with automatic compaction. - 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
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_orchestratorcodebase_explorerimplementation_engineerquality_reviewerrelease_auditorrequirements_analystruntime_devops_engineersecurity_data_engineersolution_architecttest_debug_engineerhacker
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:
{
"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
summaryargument. - ❌ Does not update the
state_store. A future phase will add astate_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
🖌️ Designerstyle 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 = 3to 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).