Files
crossbar/docs/plans/v0/README.md
T
kyleandClaude Fable 5.1 89e47d83f8 v0 plan: AGENTS.md, gate, five task files with given tests, run-plan driver
Tests were run against a private reference implementation: gate ok after every
task in order, smoke ok (stream spread ~1000 ms). The reference is not in the
repository.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-25 01:51:53 -07:00

3.4 KiB

v0 implementation plan: static routing, health, streaming proxy

For the implementing model: do not work from this file. The owner gives you one task file at a time (01-… to 05-…). This file is the index for the owner and the reviewer.

Goal: a crossbar binary that reads a TOML file, polls each host's /health and /v1/models, and forwards /{route}/v1/* to the first healthy host on that route's preference list, streaming responses chunk by chunk, marking a host down when a proxied request fails, and showing the health table at /_crossbar/hosts. This is PLAN.md §10 v0: no leases, no SQLite, no /slots, no queueing.

Architecture: four small packages under internal/ — config (TOML + validation), health (poller + table), proxy (route → host → httputil.ReverseProxy), admin (read-only JSON) — and two binaries under cmd/: crossbar and the given fakeupstream. Behaviour is pinned by the tests in files/, which were run against a private reference implementation at each task's end state; the reference is not in this repository and the implementer must not look for it.

Tech stack: Go 1.26, standard library, github.com/BurntSushi/toml v1.6.0. Nothing else.

Global constraints

  • Everything in AGENTS.md.
  • Branch v0. One task, one fresh OpenCode session, one commit. gofmt -w before the gate.
  • No source file over 400 lines. Library code never panics on input, never logs a body.
  • The given files are copied and never edited. If a copied test fails, the code is wrong.

Tasks

# File Delivers Tests that define it
01 01-module-gate-config.md go.mod, the gate, internal/config internal/config/config_test.go + testdata/
02 02-health.md internal/health: poller and table internal/health/health_test.go
03 03-proxy.md internal/proxy: routing reverse proxy internal/proxy/proxy_test.go
04 04-admin-main.md internal/admin, cmd/crossbar, the given cmd/fakeupstream internal/admin/admin_test.go, a start/stop check
05 05-smoke-readme-deploy.md tools/smoke.sh run, README.md, deploy/crossbar.service make smoke

At the end: make gate prints gate: ok, make smoke prints smoke: ok (stream spread N ms).

For the owner: running a task

From a clean checkout on master:

tools/run-plan.sh docs/plans/v0          # all tasks, each in a fresh `opencode run` session
tools/run-plan.sh docs/plans/v0 03       # from task 03

The default model is llama.cpp/ornith-1.5-35b-a3b (override with CROSSBAR_MODEL). The driver stops at the first task that does not end with a commit, a clean tree and a done row in docs/implementer-log.md. Keep the OpenCode TUI closed while it runs.

For the reviewer: after task 05

  1. git log --oneline master..v0: five commits with the Implemented-By trailer.
  2. Copied files are unchanged: for f in $(cd docs/plans/v0/files && find . -type f); do cmp "docs/plans/v0/files/$f" "$f"; done
  3. git diff master..v0 --stat -- PLAN.md AGENTS.md docs/plans is empty.
  4. make gate and make smoke on straylight.
  5. Read every source file against its task. Probe from outside with inputs the tests do not contain: a route with query strings and encoded characters, a host that hangs after headers, a 3 MB request body, /_crossbar/hosts while a poll is in flight, SIGTERM during a stream.
  6. Write findings under "Reviews" in docs/implementer-log.md.