Skip to content

docs: retire ZeroClaw — reconcile docs + config to the post-#36 architecture#90

Merged
BrettKinny merged 5 commits into
mainfrom
docs/retire-zeroclaw
May 22, 2026
Merged

docs: retire ZeroClaw — reconcile docs + config to the post-#36 architecture#90
BrettKinny merged 5 commits into
mainfrom
docs/retire-zeroclaw

Conversation

@BrettKinny
Copy link
Copy Markdown
Owner

What & why

The #36 cutover (executed 2026-05-19) replaced the RPi-hosted zeroclaw-bridge + ZeroClaw agent with two containers — dotty-pi (the pi-agent brain) and dotty-behaviour (perception bus + ambient consumers + greeter). The cutover runbook explicitly deferred the documentation follow-up; this PR is that follow-up. README, CLAUDE.md, the config templates, and the whole docs/ tree previously described the dead RPi/ZeroClaw topology — they now describe the live stack.

Changes

Deleted

  • custom-providers/zeroclaw/ — the dead ZeroClawLLM provider
  • docs/multi-daemon-split.md, docs/advanced/multi-host.md — documented ZeroClaw-host topologies that no longer exist

Rewritten to the post-#36 architecture

  • README.md, CLAUDE.md, .config.yaml.template, docker-compose.yml.template, compose.all-in-one.yml
  • Deep docs: architecture, brain, llm-backends, protocols, tier1slim, quickstart, SETUP, session-prompt, faq, interaction-map, COMPATIBILITY, voice-pipeline, plus the long tail (kid-mode, troubleshooting, modes, observability, references, cookbook, …)
  • vision_explain / VISION_BRIDGE_URL repointed to dotty-behaviour :8090; zeroclaw provider mount + ZeroClawLLM config block removed

Kept (deliberately)

  • bridge.py / bridge/ — still live as the admin dashboard service (:8080/ui); only its voice/perception roles were retired
  • Tier1Slim — documented as an alternate backend; escalation is non-functional post-cutover, so docs describe it honestly as a chitchat-only rollback
  • scripts/install-bridge.sh, scripts/deploy-bridge.sh, zeroclaw-bridge.service.template — dead RPi artifacts, retained by maintainer decision

Verification

  • Every remaining ZeroClaw / ACP string is an intentional past-tense cutover/historical note
  • mkdocs nav: all entries resolve to existing files; no dangling links to deleted docs
  • No conflict markers; merged clean with current origin/main

Notes for the reviewer

  • Carries one unrelated commit — be105cf #72: dashboard — content-filter recent-hits ring — that was committed onto this branch and missed PR dashboard: quick-wins batch (#69, #64, #74) #87.
  • #53 per-person memory (merged to main mid-work) added remember_person / recall_person tools to dotty-pi-ext; docs here still say "five voice tools" — minor follow-up.

🤖 Generated with Claude Code

BrettKinny and others added 4 commits May 22, 2026 20:24
content_filter() (bridge/text.py) already has the tier and the matched
term in scope at every hit. Keep the last 20 hits in an in-memory ring and
expose them at /ui/safety/recent.

- bridge/text.py: _cf_recent deque (maxlen 20) + recent_content_filter_hits
  getter; content_filter appends (ts, tier, rule, 8-char prefix) per hit.
  In-memory only — never written to disk; no more exposed than the
  content-filter-hit log line already emitted.
- dashboard.py: GET /ui/safety/recent.
- safety_recent.html + a card in dashboard.html.

(Supersedes the earlier "spec mismatch" re-triage — that was based on a
wrong guess about where content_filter lives; it's a repo file.)

Closes #72.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Bring docs, CLAUDE.md, README, and the config templates in line with the #36 cutover — ZeroClaw and the RPi bridge retired; the brain is now a pi coding agent in the dotty-pi container, perception handled by dotty-behaviour, and bridge.py reduced to the dashboard service.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Completes the reconciliation in d4adb1d:
- compose.all-in-one.yml: drop the dead zeroclaw-bridge service; it now
  brings up xiaozhi-server only and points at the dotty-pi /
  dotty-behaviour compose files.
- mkdocs.yml + docs/README.md: drop the deleted multi-host /
  multi-daemon-split docs from nav and index.
- pyproject.toml: remove the per-file lint rule for the deleted
  custom-providers/zeroclaw/zeroclaw.py.
- bridge/requirements.txt: comment-only — drop the zeroclaw.py reference.
- CHANGELOG.md: add the reconciliation entry.
- brain.md / proactive-greetings.md: drop a phantom doc reference and
  correct the greeter state-file path to its real default.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Brings in 5 commits that landed on main while the ZeroClaw-retirement
doc sweep was in progress (#53 per-person memory, #74, #81 hardware-doc
verification, #88 CI fix, the #87 dashboard-quick-wins merge).

Conflicts resolved (2 files):
- CLAUDE.md — kept the post-#36 architecture diagram and pi_voice
  Config-Files bullet over main's older ZeroClaw text.
- docs/faq.md — combined main's verified servo spec (feedback servos,
  SCS0009 pitch) with the ZeroClaw-retirement fix to the brain-host line.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings May 22, 2026 11:27
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the repository’s documentation and templates to match the post-#36 single-Docker-host architecture (PiVoiceLLM → dotty-pi, perception/ambient → dotty-behaviour, dashboard → bridge.py), and removes (some) ZeroClaw-era docs/provider code. It also includes an ops dashboard change (#72) adding a “recent content-filter hits” ring buffer panel.

Changes:

  • Rewrites top-level docs and deep docs to describe the post-#36 container topology and updated endpoints/placeholders.
  • Removes the legacy custom-providers/zeroclaw/zeroclaw.py provider and deletes docs that described ZeroClaw multi-host/multi-daemon deployments.
  • Adds a new dashboard panel and backing in-memory ring buffer for recent content-filter hits (#72).

Reviewed changes

Copilot reviewed 53 out of 54 changed files in this pull request and generated 10 comments.

Show a summary per file
File Description
SETUP.md Updates first-boot instructions and health checks for single-host/containerized services.
session-prompt.md Updates the historical bootstrap prompt to the post-#36 single-host setup flow.
SECURITY.md Adjusts threat-model wording and in-scope components for the new architecture.
ROADMAP.md Reframes shipped features and work-in-progress notes around PiVoiceLLM/dotty-behaviour.
README.md Updates project overview, topology, and links away from ZeroClaw.
pyproject.toml Removes the now-obsolete lint ignore for the deleted ZeroClaw provider file.
monitoring/README.md Rewords monitoring artifacts as targeting bridge.py dashboard service.
mkdocs.yml Removes nav entry for deleted multi-host doc.
household.example.yaml Updates suggested deploy path and hot-reload ownership to dotty-behaviour.
dotty-behaviour/README.md Updates cutover notes and clarifies old vs new vision bridge URL wording.
dotty-behaviour/docker-compose.yml Updates VISION_BRIDGE_URL guidance and networking notes.
docs/voice-pipeline.md Rewrites pipeline summary around PiVoiceLLM + dotty-behaviour perception relay.
docs/troubleshooting.md Updates troubleshooting steps for PiVoiceLLM/dotty containers and new endpoints.
docs/tier1slim.md Repositions Tier1Slim as an alternate backend; notes escalation is non-functional post-cutover.
docs/style.md Updates placeholder guidance away from <ZEROCLAW_*>.
docs/speaker-id-investigation.md Updates provider references from zeroclaw → pi_voice.
docs/references.md Updates canonical links, removes ACP links, adds dotty-pi/dotty-pi-ext references.
docs/README.md Updates docs index and tree overview to new architecture and removes deleted docs.
docs/quickstart.md Updates happy-path setup steps and deployment layout for the new stack.
docs/protocols.md Replaces ACP section with pi RPC + splits HTTP APIs by service.
docs/proactive-greetings.md Updates diagrams and paths to dotty-behaviour ownership.
docs/observability.md Updates wording/commands to new service naming and target host placeholders.
docs/modes.md Updates state/toggle backing-path descriptions to PiVoiceLLM + v2 smart-mode notes.
docs/llm-backends.md Updates backend comparison: PiVoiceLLM default, Tier1Slim alternate, etc.
docs/latent-capabilities.md Updates “brain unused” section for pi agent + dotty-pi-ext capabilities.
docs/kid-mode.md Updates enforcement-layer descriptions for PiVoiceLLM vs Tier1Slim.
docs/interaction-map.md Updates signal-flow map from zeroclaw-bridge to dotty-pi/dotty-behaviour.
docs/hardware-support.md Updates server-side component list for the new stack.
docs/faq.md Updates FAQs for new brain/provider model and container topology.
docs/cookbook/llama-swap-concurrent-models.md Updates cross-link text to the new backend chooser doc.
docs/cookbook/disable-kid-mode.md Updates restart instructions (bridge container wording).
docs/cookbook/change-persona.md Updates persona ownership and removes ZeroClaw persona instructions.
docs/cookbook/add-emoji.md Updates restart instructions (bridge container wording).
docs/brain.md Rewrites “brain” doc from ZeroClaw to pi agent runtime + dotty-pi-ext tools.
docs/architecture.md Rewrites topology and data-flow diagrams to the post-#36 single-host stack.
docs/advanced/variant-port-guide.md Updates “server stack” wording and example endpoint hostnames.
docs/about.md Updates high-level summary to two-layer emoji enforcement and pi-agent brain.
docker-compose.yml.template Removes zeroclaw provider mount; repoints VISION_BRIDGE_URL to dotty-behaviour.
custom-providers/zeroclaw/zeroclaw.py Deletes the legacy ZeroClawLLM xiaozhi provider implementation.
custom-providers/pi_voice/README.md Updates status to “production” and notes bridge voice routes are retired.
CONTRIBUTING.md Updates contribution guidance for placeholders and component areas post-#36.
compose.all-in-one.yml Removes embedded bridge service; repositions file as xiaozhi-only convenience compose.
COMPATIBILITY.md Updates compatibility matrix from ZeroClaw/ACP to dotty-pi + pi RPC + dotty-behaviour APIs.
CLAUDE.md Updates repo orientation doc for the new architecture and providers.
CHANGELOG.md Adds an Unreleased entry documenting this doc/config reconciliation and deletions.
bridge/text.py Adds recent content-filter hit ring buffer (#72) and accessor function.
bridge/templates/safety_recent.html New dashboard partial to render recent content-filter hits.
bridge/templates/dashboard.html Adds a new dashboard card that auto-refreshes /ui/safety/recent.
bridge/requirements.txt Updates header/comments to reflect dashboard service usage.
bridge/dashboard.py Adds /ui/safety/recent endpoint for the recent-hit panel.
.config.yaml.template Repoints vision_explain to dotty-behaviour and removes ZeroClawLLM config block.
docs/multi-daemon-split.md Deletes obsolete ZeroClaw multi-daemon deployment doc.
docs/advanced/multi-host.md Deletes obsolete multi-host (Docker host + ZeroClaw host) doc.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread bridge/text.py
Comment on lines +159 to +164
_cf_recent.append({
"ts": time.time(),
"tier": tier,
"rule": match.group(),
"prefix": text[:8],
})
Comment thread docs/kid-mode.md
Both the bridge's `POST /admin/kid-mode` endpoint and the dashboard toggle persist the new value and call `_apply_kid_mode(enabled)`, which atomically re-binds every kid-mode-derived module global (`KID_MODE`, `VISION_SYSTEM_PROMPT`, `MCP_TOOL_DENYLIST`, `VOICE_TURN_SUFFIX`, `VOICE_TURN_SUFFIX_SHORT`) in a single store-global pass. Readers see either the old or new value, never a torn intermediate, and the cost per turn is unchanged. **No daemon restart is required** to flip kid-mode at runtime.

The xiaozhi-server side of kid-mode lives in the active LLM provider's persona / suffix. For `Tier1Slim`, `KID_MODE` is read at module import and baked into `_TURN_SUFFIX`; a flip there does currently require a container restart to take effect on Tier1Slim's side (the bridge side rebinds instantly, but the suffix already loaded into the live `Tier1Slim` instance is unchanged). For `ZeroClawLLM`, the suffix is generated per-turn by the bridge so the flip lands on the very next turn with no restart at all.
The xiaozhi-server side of kid-mode lives in the active LLM provider's persona / suffix. For `Tier1Slim`, `KID_MODE` is read at module import and baked into `_TURN_SUFFIX`; a flip there does currently require a container restart to take effect on Tier1Slim's side (the bridge side rebinds instantly, but the suffix already loaded into the live `Tier1Slim` instance is unchanged). For `PiVoiceLLM`, the persona is loaded per-session by the `dotty-pi` agent, so the flip lands on the very next turn with no restart at all.
Comment thread docs/protocols.md
Comment on lines +247 to +249
Each turn is a single JSONL object written to stdin; the agent streams JSONL response chunks back on stdout. Only TTS-bound text chunks are forwarded to xiaozhi-server — tool call details stay internal to the agent loop. The agent exits cleanly after each turn; `PiClient` re-invokes `docker exec` for the next turn.

### `POST /api/voice/memory_log` — Tier1Slim turn log (fire-and-forget)
The dotty-pi agent loads the **dotty-pi-ext extension** at startup, which registers the five voice tools (`memory_lookup`, `remember`, `think_hard`, `take_photo`, `play_song`). Tool results never appear in the TTS stream.
Comment thread docs/protocols.md
Comment on lines +286 to +290
| Endpoint | Purpose |
|---|---|
| `GET /ui` | Admin dashboard web UI |
| `POST /admin/*` | Admin mutations (toggle, kid-mode, smart-mode, set-tier1slim-model, play-asset, etc.) |
| `GET /health` | Liveness probe; returns `{"ok": true}` |
Comment thread docs/voice-pipeline.md
#### `PiVoiceLLM` (default)

Custom provider at `custom-providers/tier1_slim/tier1_slim.py` (mounted into `/opt/xiaozhi-esp32-server/core/providers/llm/tier1_slim/`). Talks directly to a local llama-swap endpoint with a ~500-token system prompt and a four-tool catalogue (`memory_lookup`, `think_hard`, `take_photo`, `play_song`). Plain conversational turns are answered by the small inner-loop model (`qwen3.5:4b` by default) in well under 1 s warm — **no bridge round-trip**.
Custom provider at `custom-providers/pi_voice/` (mounted into `/opt/xiaozhi-esp32-server/core/providers/llm/pi_voice/`). It doesn't run a model itself — it hands each voice turn to the **`dotty-pi` container** by running `docker exec -i dotty-pi pi --mode rpc` and exchanging JSONL messages over stdio. The pi agent owns the conversation loop (`qwen3.5:4b` on local llama-swap) and the five `dotty-pi-ext` voice tools (`memory_lookup`, `remember`, `think_hard`, `take_photo`, `play_song`); only TTS-bound text streams back. See [brain.md](./brain.md).
Comment on lines 182 to 188
2. **Voice round-trip** — speak a simple phrase and confirm ASR → LLM → TTS returns audio to the device.
3. **MCP tool call** — send a test instruction through the bridge:
```bash
curl -X POST http://<ZEROCLAW_HOST>:8080/api/message \
curl -X POST http://<XIAOZHI_HOST>:8080/api/message \
-H 'Content-Type: application/json' \
-d '{"content":"Turn your head to the right"}'
```
Comment thread docs/brain.md
Comment on lines +80 to +85
`bridge.py` was the original HTTP→ZeroClaw translator, running under systemd on the RPi. Post-cutover (#36) it runs as a Docker container on the same Docker host, port 8080. Its **voice path** (`/api/message`, `/api/voice/*`) and **perception relay** (`/api/perception/event`) roles are retired — those functions moved to `PiVoiceLLM`/`dotty-pi` and `dotty-behaviour`. What remains:

Lives at `<BRIDGE_PATH>/bridge.py`, runs under systemd (`zeroclaw-bridge.service`).
- **Admin dashboard** (`/ui`) — the operator web UI for monitoring turns, toggling kid-mode/smart-mode, viewing scene context, and LED state.
- **`/admin/*` endpoints** (localhost-only) — runtime toggles for kid-mode, smart-mode, safety allowlist.

**HTTP surface:**
A dashboard port to `dotty-behaviour` is still pending; until then, bridge.py's dashboard panels that relied on the bridge's own perception bus may show stale or empty data.
Comment thread docs/references.md
Comment on lines +43 to +44
| pi agent (dotty-pi) | https://github.com/BrettKinny/dotty-stackchan/tree/main/dotty-pi | The Docker container that runs the pi coding agent — the current Dotty brain. |
| dotty-pi-ext | https://github.com/BrettKinny/dotty-stackchan/tree/main/dotty-pi-ext | pi extension providing the 5 voice tools (memory_lookup, remember, think_hard, take_photo, play_song). |
Comment on lines 14 to +17
# Port 8090 (not the bridge's 8080) — llama-swap owns 8080 on Unraid.
# xiaozhi-server's VISION_BRIDGE_URL must move from
# http://<ZEROCLAW_HOST>:8080 → http://localhost:8090 at cutover.
# xiaozhi-server's VISION_BRIDGE_URL must point to
# http://<XIAOZHI_HOST>:8090 (the Unraid LAN IP — loopback works only
# if xiaozhi-server is also on host networking).
Comment thread bridge/dashboard.py
Comment on lines +888 to +908
@router.get("/safety/recent", response_class=HTMLResponse, include_in_schema=False)
async def safety_recent(request: Request) -> Any:
"""#72 — recent content-filter hits from the in-memory ring (last 20).
In-memory only; empties on a bridge restart."""
from bridge.text import recent_content_filter_hits
rows: list[dict[str, Any]] = []
for hit in recent_content_filter_hits():
ts = hit.get("ts") or 0
try:
time_str = datetime.fromtimestamp(ts).astimezone().strftime("%H:%M:%S")
except Exception:
time_str = "?"
rows.append({
"time": time_str,
"tier": hit.get("tier") or "?",
"rule": hit.get("rule") or "",
"prefix": hit.get("prefix") or "",
})
return templates.TemplateResponse(
request, "safety_recent.html", {"rows": rows},
)
`custom-providers/zeroclaw/` was retired in the cutover but the
unit-test file outlived it. At pytest collection time the test
loaded `zeroclaw.py` via importlib and raised FileNotFoundError,
aborting the whole suite (CI Python Tests on #90).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@BrettKinny BrettKinny merged commit cf3c9dc into main May 22, 2026
9 checks passed
@BrettKinny BrettKinny deleted the docs/retire-zeroclaw branch May 22, 2026 23:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants