Initial commit: a0_software_orchestrator v1.0
- 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
This commit is contained in:
@@ -0,0 +1,172 @@
|
||||
# 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).
|
||||
Reference in New Issue
Block a user