Translate posta.text/v1 at the wire boundary #21

Merged
arne merged 2 commits from wire-text-v1 into main 2026-05-13 21:34:44 +02:00
Owner

Summary

  • Server wraps {"text":"hi"} to {"kind":"posta.text/v1","body":"hi"} before the outbox loop signs it, so the wire payload is the canonical SPEC §13.2 form.
  • renderMessage (REST list, search) and publishInbound (SSE) unwrap posta.text/v1 back to {"text":"hi"}, so TUI/iOS see the shape they already render.
  • Legacy {"text":"hi"} rows and unknown wire kinds pass through unchanged — Wrap/Unwrap are deliberately tolerant so existing data is unaffected and peers running ahead of us on §13 stay readable.

Test plan

  • go test ./...
  • Outbound test asserts PendingOutbound[0].Payload == {"kind":"posta.text/v1","body":"hi"} after POST /api/v1/messages.
  • Inbound test stores a canonical posta.text/v1 envelope and asserts GET /messages returns {"text":"hello"} in the DTO.
  • Round-trip + idempotency unit tests in internal/payload.

🤖 Generated with Claude Code

## Summary - Server wraps `{"text":"hi"}` to `{"kind":"posta.text/v1","body":"hi"}` before the outbox loop signs it, so the wire payload is the canonical SPEC §13.2 form. - `renderMessage` (REST list, search) and `publishInbound` (SSE) unwrap `posta.text/v1` back to `{"text":"hi"}`, so TUI/iOS see the shape they already render. - Legacy `{"text":"hi"}` rows and unknown wire kinds pass through unchanged — Wrap/Unwrap are deliberately tolerant so existing data is unaffected and peers running ahead of us on §13 stay readable. ## Test plan - [x] `go test ./...` - [x] Outbound test asserts `PendingOutbound[0].Payload == {"kind":"posta.text/v1","body":"hi"}` after `POST /api/v1/messages`. - [x] Inbound test stores a canonical `posta.text/v1` envelope and asserts `GET /messages` returns `{"text":"hello"}` in the DTO. - [x] Round-trip + idempotency unit tests in `internal/payload`. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
The client API keeps its ergonomic {"text":"hi"} shape, but
posta-server now signs the canonical SPEC §13.2 form
{"kind":"posta.text/v1","body":"hi"} on outbound and unwraps the
matching kind back to {"text":"hi"} when building client DTOs (REST
list, search, SSE inbound). Legacy rows and future kinds pass
through unchanged, so existing data and any peer running ahead of
us on §13 stay readable.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Without migration 7 the FTS5 index for posta.text/v1 rows would
contain the wrapper tokens (posta, kind, body, v1), so searching for
any of them would match every text message. The new triggers (and a
one-shot reindex on upgrade) index COALESCE(json_extract($.body),
payload), preserving legacy {"text":"hi"} rows while restoring useful
search for the dominant text case.

The SSE inbound publish path also unwraps now (daemon/runner.go) but
wasn't exercised by tests; TestPublishInboundUnwrapsTextV1 closes the
gap.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
arne merged commit 9302a5a362 into main 2026-05-13 21:34:44 +02:00
arne deleted branch wire-text-v1 2026-05-13 21:34:44 +02:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
posta/server!21
No description provided.