pkg/posta: add Kind field to ActorDoc, KeyFile reader, MemoryStore #1

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

What to build

Three small additions to pkg/posta that unblock the /feedback room work in posta-web and the cal migration.

1. Kind field on ActorDoc. SPEC.md §5.2.2 lists kind as an optional display field, but the Go struct in pkg/posta/actor.go is missing it. Add Kind string \json:"kind,omitempty"`and a max-64-char validation inDecodeActorDoc. Optional on the wire; conventional values include "person", "room", "agent"`.

2. KeyFile reader. Lift posta-server/internal/keys/keys.go up to pkg/posta so both posta-server and posta-web can share it. Surface: Load(path) (*KeyFile, error), (*KeyFile).Current() *Key, and a Sign(data []byte) ([]byte, error) convenience method. Read-only (generation stays in the CLI).

3. MemoryStore. New in-memory MessageStore impl. NewMemoryStore(ttl time.Duration) MessageStore. Internal map of (sender, id) → time.Time; sweep entries older than ttl on each StoreInbound. Returns *Error{ErrDuplicateID} for repeats. Primarily for embedders that don't need persistence (cal-style responders); also useful for tests.

Acceptance criteria

  • ActorDoc.Kind round-trips through encode/decode; omitted from JSON when empty; rejected when >64 chars
  • KeyFile.Load parses the existing posta-server keys.json format; Current() returns the most-recent key by createdAt
  • KeyFile.Sign produces signatures verifiable via posta.Verify against the corresponding public key
  • MemoryStore.StoreInbound returns *Error{ErrDuplicateID} on a repeat (sender, id) within the TTL window; allows the same id after TTL elapses
  • Unit tests cover all three modules; existing pkg/posta tests still pass
  • posta-server/internal/keys is updated to import from pkg/posta (or marked deprecated with a follow-up)

Blocked by

None - can start immediately.

## What to build Three small additions to `pkg/posta` that unblock the /feedback room work in posta-web and the cal migration. **1. `Kind` field on `ActorDoc`.** SPEC.md §5.2.2 lists `kind` as an optional display field, but the Go struct in `pkg/posta/actor.go` is missing it. Add `Kind string \`json:"kind,omitempty"\`` and a max-64-char validation in `DecodeActorDoc`. Optional on the wire; conventional values include `"person"`, `"room"`, `"agent"`. **2. `KeyFile` reader.** Lift `posta-server/internal/keys/keys.go` up to `pkg/posta` so both posta-server and posta-web can share it. Surface: `Load(path) (*KeyFile, error)`, `(*KeyFile).Current() *Key`, and a `Sign(data []byte) ([]byte, error)` convenience method. Read-only (generation stays in the CLI). **3. `MemoryStore`.** New in-memory `MessageStore` impl. `NewMemoryStore(ttl time.Duration) MessageStore`. Internal map of `(sender, id) → time.Time`; sweep entries older than `ttl` on each `StoreInbound`. Returns `*Error{ErrDuplicateID}` for repeats. Primarily for embedders that don't need persistence (cal-style responders); also useful for tests. ## Acceptance criteria - [ ] `ActorDoc.Kind` round-trips through encode/decode; omitted from JSON when empty; rejected when >64 chars - [ ] `KeyFile.Load` parses the existing posta-server `keys.json` format; `Current()` returns the most-recent key by `createdAt` - [ ] `KeyFile.Sign` produces signatures verifiable via `posta.Verify` against the corresponding public key - [ ] `MemoryStore.StoreInbound` returns `*Error{ErrDuplicateID}` on a repeat `(sender, id)` within the TTL window; allows the same id after TTL elapses - [ ] Unit tests cover all three modules; existing pkg/posta tests still pass - [ ] `posta-server/internal/keys` is updated to import from `pkg/posta` (or marked deprecated with a follow-up) ## Blocked by None - can start immediately.
arne closed this issue 2026-05-13 21:32:21 +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
posta/spec#1
No description provided.