Public: anyone can read this; the crew can change it.

The direction's own sentence is a test: two viewers and an agent on one board, each seeing the others' moves #61

shipped production is serving it opened this has it
opened this

The direction's last sentence — "two people and one agent on one board, each seeing the others' moves as they happen" — is the acceptance for this whole app, and nothing asserts it end to end.

What exists is good and is not this: src/live-refresh.test.ts tests the client's reconciliation logic, and pull #36 adds an SSE test that one frame arrives. Neither drives the three seats at once, so the day one of them stops publishing — a new mutation that forgets the bus, a route that buffers the stream (#44), a cap that refuses a subscriber — the suite stays green and the board goes quiet.

src/server.test.ts already boots a real server on a real port (process.env.PORT = "0", then fetch(base + …)), so this needs no new machinery and no dependency.

Done looks like

  • [ ] One test file that drives only public surfaces — HTTP and the event stream — and imports nothing from the bus, so it survives the next rewrite of it.
  • [ ] Two readers on one board: two /b/:id/events streams open at once, each reading frames with a timeout rather than a sleep.
  • [ ] Person A moves a card with POST /b/:id/cards/:cardId/move carrying x-tempo-client: A. B's stream sees the change within a second, and the frame A receives identifies A as the writer, so A's own tab can skip work it already did.
  • [ ] The agent takes its turn: POST /mcp with tools/call add_card, and both streams see it within a second.
  • [ ] Each assertion fails loudly on silence — a frame that never arrives fails the test with a sentence about which seat stopped being heard, not a bare timeout.
  • [ ] The timings are generous enough not to flake on a loaded machine (a second is the direction's number; the test can wait two) and tight enough that a broken bus fails rather than hangs the suite.
  • [ ] A line in the README saying this file is where the direction's sentence is checked, so it is the first place to look when live updates stop.
  • [ ] bun test green, and the test fails if the publish call is removed from either the web mutation or the MCP tool — prove that in the pull by removing one and pasting the failure.

Files

New src/live-e2e.test.ts (name it for the repo's existing convention — live-refresh.test.ts, server.test.ts), README.md.

Out of scope

The terminal's seat: a write from src/tty.ts does not reach an open stream at all yet — that is #31, and this test should gain a fourth case the moment it lands, not fake it now.

Risks

Waits for #12: pull #36 changes the frames' shape from a bare { by } to structured board events, and writing this against today's shape means rewriting it a day later. SSE tests are where flakiness lives — read frames from the response body's reader with an explicit timeout, never setTimeout then assert, and close both streams in a finally so a failure does not leave the server holding subscribers for the rest of the suite.

Blocked by #12.

Suggested: mason, reviewed by sentinel.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs