Portability audit — all platform-specific concerns moved to adapter layer:
- Gate Approval UX (Resolved Mechanics): rewritten as platform-agnostic.
Core: runner writes gate_pending, calls notify_adapter.send(), polls
blackboard for gate_approved. Universal path: agency CLI writes directly
to blackboard. Adapter handles its own inbound response bridge internally.
- pending_gates.json removed from core directory structure and runner
responsibilities — adapter-internal state, not a core concern.
- 'User → Hans → team_runner.start()' → 'User → team_runner.start()'
Core has no dependency on a specific caller.
- 'notify_adapter.send(...to Andrew via Hans)' → 'notify_adapter.send()'
throughout design.md and buildspec.md.
- anthropic.py description: 'via OpenClaw or direct API' → 'direct API'
(anthropic adapter never goes via OpenClaw)
- Output/review decision: 'Hans messages Andrew' → 'notify_adapter.send()'
- Run visibility decision: 'Andrew via Hans' → 'via notify_adapter.send()'
- Decisions log: gate approval and visibility entries rewritten accordingly
Adapter layer correctly unchanged:
adapters/notify/openclaw.py — OpenClaw-specific, owns its inbound bridge
adapters/runtime/openclaw.py — OpenClaw sessions_spawn, correctly isolated
team.yaml example config — adapter selection is config, not core
- Spawn calls: runner owns all runtime_adapter.spawn() calls; tiers write
status=pending briefs to blackboard, runner's spawn loop acts on them.
Gate logic lives in the spawn loop — no gate plumbing needed in agents.
- Gate approval UX: Signal reply via Hans + direct CLI both supported.
Both write gate_approved to blackboard; runner doesn't care which path.
Hans uses pending_gates.json for multi-run disambiguation.
- T3 mesh timeout: escalate to T2 (domain boundary problem). If T2 also
exhausts retry budget, normal escalation ladder handles it. No force-commit.
Add pending_gates.json to directory structure and buildspec.
Update runner step in build order with full spawn loop responsibilities.
Adapters implemented:
- adapters/llm/anthropic.py — Anthropic Claude SDK, capability-based model selection,
max_tokens + temperature configurable via team.yaml, lazy SDK import
- adapters/vcs/github.py — GitHub PR/branch operations via gh CLI
- adapters/notify/openclaw.py — OpenClaw system event notifications
- adapters/runtime/openclaw.py — OpenClaw sessions_spawn for agent execution
- adapters/runtime/claude_code.py — Claude Code CLI for T4/T5 coding tasks
All adapters follow the abstract base interfaces from Phase 1.
Config-driven model selection via capability_map in team.yaml.