| 1 |
# Sprint plan: Spectra 0.1, Talk |
| 2 |
|
| 3 |
Each loop iteration: pick the first unchecked item, implement it with tests, run the gated checks, commit with `oxy`, tick the box here with a one-line note, and commit again. Update `docs/spec.md` (and its changelog) whenever behaviour the spec describes changes. If an item cannot be finished in two iterations, note why under it and move on. The issues are on https://oxygenhub.io/projects/andymccall/7. Sprint 1 built 0.1 on one machine; Sprint 2 made it client and server (spec §8.6), since Andy runs the daemon on Earth and everything else on his workstation; Sprint 3 made Spectra its own program, with nothing of Oxygen in it (spec Draft 0.5); Sprint 4 makes it just work from VS Code, with briefs and the Constellation (spec Draft 0.6). |
| 4 |
|
| 5 |
## Rules |
| 6 |
|
| 7 |
- Never run `git init` in this directory or push this project anywhere but its `oxygenhub` remote. Commit with `OXY_HOME=~/.oxy-agents/claude oxy commit -m "..." PATHS..`, never with Andy's own key. |
| 8 |
- Tests are hermetic: a temporary data directory, a temporary socket, port 0; never `~/.local/share/spectra`, `~/.config` or the network. |
| 9 |
- Gate every commit on `make check` (changelog, fmt, clippy with warnings as errors, tests), chained so a failing gate stops the commit: `make check && oxy commit …`. |
| 10 |
- Every code change adds a CHANGELOG.md line under `## Unreleased`, or sets `NO_CHANGELOG=1`. |
| 11 |
- Never weaken a security goal of spec §5 to make a test pass. |
| 12 |
- Never commit or push anything under `docs/prompts/` (Andy's prompts; ignored in `.oxyignore`). Name the paths in every commit. |
| 13 |
- Never act as Andy: owner-only steps (creating his identity, confirming a delegation, the acceptance run) wait for him. |
| 14 |
- Spectra uses Oxygen in no way: no `oxy` command, library or file in the product. This repository is still kept with `oxy` and built on OxygenFlow; that is how it is developed, not what it is. |
| 15 |
|
| 16 |
## Sprint 1 (done) |
| 17 |
|
| 18 |
- [x] #1 Project skeleton in Oxygen's shape — done 2026-11-02: workspace, deps/oxygen pinned, make check, deps-check (212 crates, all vendored). |
| 19 |
- [x] #2 CI on OxygenFlow — done 2026-11-02: run #1 passed fmt, clippy, test, build with no image rebuild. |
| 20 |
- [x] #3 The ledger — done 2026-11-02: chain, frozen envelope, HLC, signed checkpoints every 256 events, verify/check/rebuild; append 0.15 ms (release), 10,000 random events with rebuild and verify 1.3 s. |
| 21 |
- [x] #4 Identities instead of tokens — done 2026-11-02: init, agent add (waits for the delegation), list, disable, identity show/refresh; Principals replay in verify; Authenticator (window, nonce, uid); write lock. Checked against the real `oxy identity delegate add`. The socket and its SO_PEERCRED arrive with #7, which uses the Authenticator. |
| 22 |
- [x] #5 Projects, presence and sessions — done 2026-11-02: project add/list with relations from .oxymodules (checked on oxygen, oxygenflow, oxygenhub, spectra), presence and session trackers with events and projections; the daemon feeds them from #7. |
| 23 |
- [x] #6 Channels, threads, messages, inbox and search — done 2026-11-02: spectra-core::conversation (post, read, inbox, ack, redact, search, direct channels), shared by tools, API and CLI. |
| 24 |
- [x] #7 Tuner: MCP over Streamable HTTP — done 2026-11-02: spectra serve, socket + loopback, signed requests, both revisions, refusals, owner events through the daemon; end-to-end tests drive the real binary. |
| 25 |
- [x] #8 The 0.1 tools — done 2026-11-02: eleven tools through one invoke wrapper (record, rules line); wait with the idle guard; end-to-end tests with two agents. Found while testing: serve could hang on shutdown with a stream open (now five seconds at most). |
| 26 |
- [x] #9 The stdio shim — done 2026-11-02: spectra mcp --agent NAME, driven over pipes in tests/cli_mcp.rs. Real Claude Code, Antigravity and Kimi connections are checked in #13 with Andy, since they need his MCP configuration. |
| 27 |
- [x] #10 Radar — done 2026-11-02: Live, Channels, channel/thread with compose, Log with Verify now; spectra open; checked by hand in Chrome on a demo Spectra. That demo found the ledger cancellation bug (fixed, regression test fails on the old code) and a referrer policy that blanked the Origin of form posts. |
| 28 |
- [x] #11 JSON API and spectra-api types — done 2026-11-02: every 0.1 endpoint, problems, paging, ETags, the live log; types and ts/index.d.ts. How spectra-vscode will sign is spec open question 11. |
| 29 |
- [x] #12 Human CLI — done 2026-11-02: say, inbox --follow, search, api (the signing proxy for spectra-vscode); tests/cli_json.rs parses every --json output with and without the daemon. |
| 30 |
- #13 Acceptance moved to Sprint 2, to run across two machines. |
| 31 |
|
| 32 |
## Sprint 2: client and server |
| 33 |
|
| 34 |
- [x] #20 Server over TLS — done 2026-11-03: own certificate in keys/tls.*, vouched for by a signed instance.tls event; GET /api/v1/instance; pinned client transport; a uid-bound agent refused over TCP; tests/tls.rs. |
| 35 |
- [x] #22 Remote setup — done 2026-11-03: spectra init --owner KEYID; unowned daemon refuses all but /api/v1/instance and POST /api/v1/claim, which takes only the named key; tests/remote.rs. Found: a failing end-to-end test left its daemon running, which held the output open and looked like a hang; Serving now kills it on drop. |
| 36 |
- [x] #21 spectra connect — done 2026-11-03: trust through the owner's delegation to the instance key, pin, claim with the rotation delegating causes; tests/connect.rs, and the shim over TLS in tests/client.rs. |
| 37 |
- [x] #23 The CLI without a ledger file — done 2026-11-03: every command through the API when a daemon serves, local or remote; admin verify via the server; tests/client.rs runs them all from a workstation with no data directory. |
| 38 |
- [x] #24 Radar from a workstation — done 2026-11-03: spectra open serves a loopback proxy to the pinned server and signs in through it; tests/client.rs; checked by hand in Chrome on a demo server with a real oxy identity (sign-in, live update from the CLI, a post from the compose box, verify). |
| 39 |
- [x] #25 Run the daemon on Earth — done 2026-11-03: make install-server, a unit that waits for a Spectra, make install copies; Earth runs `spectra serve` on [::]:7350 as the claude account from boot, set up with `spectra init --owner d89664ced1fc…` (Andy's public KeyId) and waiting for his claim; /api/v1/instance answers from the workstation. |
| 40 |
- #13 Acceptance moved to Sprint 3, after Spectra stood alone. |
| 41 |
|
| 42 |
## Sprint 3: Spectra stands alone |
| 43 |
|
| 44 |
- [x] #26 Own identities, signatures and CBOR — done 2026-11-03: spectra-core's identity, cbor and durable modules (designed after Oxygen's, no shared code); spectra identity create; init, agent add (confirm, --expires, renew, disable) and connect (confirm or --expect) sign the delegation themselves; deps/oxygen and oxy-core removed. |
| 45 |
- [x] #27 A project is any kind of work — done 2026-11-03: name, optional folder never read, description, link; spectra project link replaces .oxymodules; tests/cli_project.rs adds a book. Found: inbox --follow could miss a message posted as it started; the stream now announces its subscription. |
| 46 |
- [x] #28 The companion specs without Oxygen — done 2026-11-03 in the working copies (SpectraHub Draft 0.4, spectra-vscode 0.3, spectrahub-vscode 0.2); left uncommitted, as those specs had never been committed in their repos. |
| 47 |
- [x] #13 Acceptance — done 2026-11-03 with Andy: Earth serves; Andy's new identity claimed it through `spectra connect`; oxygen, oxygenhub (linked) and spectra registered; claude-oxygen, antigravity-oxygenhub and claude-spectra added with 8h delegations; claude-oxygen and Antigravity each posted in #general and read the other's message, watched in Radar; `spectra admin verify` clean at 61 events; an edited copy of Earth's ledger failed with HashMismatch and BadProof ("names agent:mallory as its actor but is signed by Andy McCall"). 0.1.0 tagged. The runbook was: |
| 48 |
1. On the workstation: `make install`; `spectra identity create --name "Andy McCall" --contact [email protected]`. |
| 49 |
2. On Earth (claude account; the KeyId only): `spectra init --owner KEYID --name earth`, `[server] bind` and `names` set, the service started. It prints Earth's instance key. The new build is already installed there and its first ledger set aside (`~/.local/share/spectra.oxygen-era-2026-11-03`). |
| 50 |
3. On the workstation: `spectra connect https://earth.andymccall.xyz:7350`, confirming the instance key matches. |
| 51 |
4. `spectra project add ~/development/oxygen` and `~/development/oxygenhub`. |
| 52 |
5. `spectra agent add claude-oxygen --kind claude-code --project oxygen --home ~/.spectra-agents/claude-oxygen --expires 8h`; the same for `antigravity-oxygenhub`. |
| 53 |
6. Claude Code in oxygen: `claude mcp add spectra -- spectra mcp --agent claude-oxygen --home ~/.spectra-agents/claude-oxygen`; Antigravity in oxygenhub: the README's `mcp_config.json` line with `--home` added. |
| 54 |
7. Both call `brief`, post in #general, and see each other's messages; watch with `spectra open`. |
| 55 |
8. `spectra admin verify`; on Earth, on a copy of the database, edit a row and see `spectra --data COPY admin verify` catch it. |
| 56 |
9. Cut 0.1.0 in CHANGELOG.md and tag it. |
| 57 |
|
| 58 |
## Sprint 4: it just works |
| 59 |
|
| 60 |
|
| 61 |
|
| 62 |
- [x] #31 bridge, probe, status — done 2026-11-03: spectra-mcp::bridge (token, loopback Host, no Origin, ends with stdin), spectra status --json, spectra probe --json, identity create --json; tests/bridge.rs and a probe check in tests/connect.rs. |
| 63 |
- [x] spectra-vscode#6 0.1 Just works — done 2026-11-03: the walkthrough (binary, identity, here or server with the key confirmed, folder as project, agent with Claude Code, Kimi or Antigravity configured), the bridge client, Channels/Agents/Inbox/Briefs views on the stream, chat tabs, briefs as documents, status bar, Radar and Constellation; unit tests, a smoke test against a real Spectra, CI run #1 green; spectra-vscode-0.1.0.vsix built. |
| 64 |
- [ ] #32 Acceptance: a new project set up and chatting from VS Code alone. |
| 65 |
|
| 66 |
## Log |
| 67 |
|
| 68 |
- 2026-11-02 plan created; sprint adjusted to spec Draft 0.3 (identities and the ledger). |
| 69 |
- 2026-11-02 #1 and #2 done (CI green on run #1); #3 done. Root disk was full: build trees go to /mnt/development/spectra-target (CARGO_TARGET_DIR). |
| 70 |
- 2026-11-02 #4 done. Found and fixed while testing: a signed event's actor was not checked against its signer. |
| 71 |
- 2026-11-02 Andy asked for an oxy-style CLI: every command now reports through oxy's ui module. #5 done. |
| 72 |
- 2026-11-02 #11 and #12 done. Measured in release with 1,000 messages, round trip over the socket including signing (tests/bench.rs): brief 2.7 ms (target 5), say 3.1 ms (target 10), wait wakes 4.2 ms after a mention (target 100). A single ledger append 0.15 ms. 58 tests. #13 is ready for Andy. |
| 73 |
- 2026-11-03 Sprint 2 set up: Andy wants the daemon on Earth and the rest on his workstation. Spec Draft 0.4 adds client and server (§8.6); #20–#25 opened, #13 moved and rewritten for two machines. The binary and an enabled, waiting user unit are already on Earth (claude account, lingering on). |
| 74 |
- 2026-11-03 Andy: Spectra must be its own program, not tied to Oxygen or to programming work. Spec Draft 0.5; Sprint 3 opened with #26–#28; #13 moved again. Earth's first ledger (Oxygen identities) is set aside, not deleted. |
| 75 |
- 2026-11-03 #13 accepted across two machines; 0.1.0 cut and tagged. Sprint 3 done. |
| 76 |
- 2026-11-03 Radar removed (spec Draft 0.7): Spectra serves only signed requests; the editor is the local view and SpectraHub the website. Radar's last code is in commit 6b914945 (crates/radar), for SpectraHub's Constellation. |