Migrate cal's internal posta implementation to pkg/posta #3

Closed
opened 2026-05-13 18:44:12 +02:00 by arne · 0 comments
Owner

What to build

Cal currently carries ~1000 LOC under `internal/posta` that re-implements the Posta wire protocol (envelope, actor, sign/verify, canonical URL, replay, client, outbound). All of this is now available in `code.bas.es/posta/spec/pkg/posta` and should be imported instead of duplicated.

Cal's remaining application-layer needs after migration:

  • An in-memory replay/dedup store → `posta.NewMemoryStore(ttl)`
  • A single-peer ACL → small wrapper that returns `false` from `HandlerOptions.ACLAllows` for any sender whose URL host doesn't match `CAL_POSTA_PEER`
  • The dispatch glue (parse `posta.text/v1` body, route to the calendar command parser, send a signed reply) → `posta.Attempt(ctx, …)` for the reply

Net effect: drop roughly ~900 LOC from cal; pkg/posta becomes the single source of truth for the wire format across cal, posta-server, and posta-web.

Acceptance criteria

  • `internal/posta` is removed; cal imports `code.bas.es/posta/spec/pkg/posta`
  • The single-peer ACL behaviour is preserved (foreign senders rejected with `403 forbidden` per pkg/posta's ACL hook)
  • Replay protection uses `posta.MemoryStore`; duplicate `(sender, id)` returns `409 duplicate-id`
  • Sending replies uses `posta.Attempt`; the `Posta-Signature` header matches the published key
  • All existing cal tests pass; new tests cover the migration boundary (request → dispatch → reply) end-to-end
  • go.mod gains a dependency on `code.bas.es/posta/spec`; cal's binary still builds CGO-free for the Alpine deployment

Blocked by

## What to build Cal currently carries ~1000 LOC under \`internal/posta\` that re-implements the Posta wire protocol (envelope, actor, sign/verify, canonical URL, replay, client, outbound). All of this is now available in \`code.bas.es/posta/spec/pkg/posta\` and should be imported instead of duplicated. Cal's remaining application-layer needs after migration: - An in-memory replay/dedup store → \`posta.NewMemoryStore(ttl)\` - A single-peer ACL → small wrapper that returns \`false\` from \`HandlerOptions.ACLAllows\` for any sender whose URL host doesn't match \`CAL_POSTA_PEER\` - The dispatch glue (parse \`posta.text/v1\` body, route to the calendar command parser, send a signed reply) → \`posta.Attempt(ctx, …)\` for the reply Net effect: drop roughly ~900 LOC from cal; pkg/posta becomes the single source of truth for the wire format across cal, posta-server, and posta-web. ## Acceptance criteria - [ ] \`internal/posta\` is removed; cal imports \`code.bas.es/posta/spec/pkg/posta\` - [ ] The single-peer ACL behaviour is preserved (foreign senders rejected with \`403 forbidden\` per pkg/posta's ACL hook) - [ ] Replay protection uses \`posta.MemoryStore\`; duplicate \`(sender, id)\` returns \`409 duplicate-id\` - [ ] Sending replies uses \`posta.Attempt\`; the \`Posta-Signature\` header matches the published key - [ ] All existing cal tests pass; new tests cover the migration boundary (request → dispatch → reply) end-to-end - [ ] go.mod gains a dependency on \`code.bas.es/posta/spec\`; cal's binary still builds CGO-free for the Alpine deployment ## Blocked by - posta/spec#1 (needs \`MemoryStore\` in pkg/posta)
arne closed this issue 2026-05-13 22:16:31 +02:00
Sign in to join this conversation.
No labels
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
arne/cal#3
No description provided.