Add persistent offline-safe StarIntel operation outbox #18

Merged
lost-rob0t merged 12 commits from agent/persistent-operation-outbox into master 2026-08-16 13:59:54 +00:00
lost-rob0t commented 2026-08-16 05:42:43 +00:00 (Migrated from github.com)

Summary

Implements #12 as a durable operation-local outbox layered on the existing Tek9 store and StarIntel HTTP ingest boundary.

Persistence and idempotency

  • outbox records live in the operation Tek9 environment under named DB outbox
  • enqueue persists before any network call
  • deterministic outbox ID uses canonical StarIntel document ID + serialized payload digest
  • repeated byte-identical document/version enqueue collapses to one record
  • StarIntel projection now carries Hackmode's persisted timestamps, preventing repeated projection alone from changing the wire payload

State machine

Durable states:

  • queued
  • sending
  • retry
  • acknowledged
  • failed
  • quarantined

ack-kind :ingest-accepted explicitly means the StarIntel HTTP boundary validated and published the document to its ingest broker. It does not claim CouchDB persistence has already completed.

Retry / poison handling

  • bounded deterministic exponential backoff
  • retries transport failures, 408, 425, 429, and 5xx
  • permanent 4xx becomes inspectable quarantined
  • retry exhaustion becomes inspectable failed
  • sending is recoverable after process death, so a crash between send-start and response does not strand the record

Transport

make-starintel-http-transport reuses the existing server route:

POST /new/document/:dtype

No RabbitMQ credentials or second message transport are added to Hackmode. Credentials/headers, if needed, are supplied by a callback immediately before HTTP request and are never persisted in the outbox record.

Async actor

Adds a Sento outbox actor with a dedicated dispatcher:

  • start-outbox-actor
  • drain-outbox-async

Interactive clients can queue a drain and return immediately instead of performing network I/O on the REPL/Emacs thread.

Tests

Extends the real clean-runner asdf:test-system :hackmode suite for:

  • stable repeated StarIntel projection
  • enqueue dedupe
  • queued record survives Tek9 close/reopen
  • offline transport -> retry/backoff
  • operation asset writes continue while sync is failing
  • restored transport -> same record acknowledged
  • 400 -> quarantined
  • bounded retry exhaustion -> failed
  • asynchronous Sento actor drain -> acknowledged

No live StarIntel server is required; transport behavior is deterministic/fake in tests.

Closes #12 when both core and monorepo workflows pass.

## Summary Implements #12 as a durable operation-local outbox layered on the existing Tek9 store and StarIntel HTTP ingest boundary. ### Persistence and idempotency - outbox records live in the operation Tek9 environment under named DB `outbox` - enqueue persists before any network call - deterministic outbox ID uses canonical StarIntel document ID + serialized payload digest - repeated byte-identical document/version enqueue collapses to one record - StarIntel projection now carries Hackmode's persisted timestamps, preventing repeated projection alone from changing the wire payload ### State machine Durable states: - `queued` - `sending` - `retry` - `acknowledged` - `failed` - `quarantined` `ack-kind :ingest-accepted` explicitly means the StarIntel HTTP boundary validated and published the document to its ingest broker. It does **not** claim CouchDB persistence has already completed. ### Retry / poison handling - bounded deterministic exponential backoff - retries transport failures, 408, 425, 429, and 5xx - permanent 4xx becomes inspectable `quarantined` - retry exhaustion becomes inspectable `failed` - `sending` is recoverable after process death, so a crash between send-start and response does not strand the record ### Transport `make-starintel-http-transport` reuses the existing server route: `POST /new/document/:dtype` No RabbitMQ credentials or second message transport are added to Hackmode. Credentials/headers, if needed, are supplied by a callback immediately before HTTP request and are never persisted in the outbox record. ### Async actor Adds a Sento outbox actor with a dedicated dispatcher: - `start-outbox-actor` - `drain-outbox-async` Interactive clients can queue a drain and return immediately instead of performing network I/O on the REPL/Emacs thread. ### Tests Extends the real clean-runner `asdf:test-system :hackmode` suite for: - stable repeated StarIntel projection - enqueue dedupe - queued record survives Tek9 close/reopen - offline transport -> retry/backoff - operation asset writes continue while sync is failing - restored transport -> same record acknowledged - 400 -> quarantined - bounded retry exhaustion -> failed - asynchronous Sento actor drain -> acknowledged No live StarIntel server is required; transport behavior is deterministic/fake in tests. Closes #12 when both `core` and `monorepo` workflows pass.
Sign in to join this conversation.
No description provided.