TA-live: real A→B federation over HTTP + a durable outbox (LIVE-VERIFIED)

Step 3 — federation, live-verified with TWO real host instances.

- host/ta.sx: host/ta--post/make-http-wire/federate (POST a serialized activity to a peer's /inbox
  over real HTTP). host/blog.sx: POST /inbox (host/blog-inbox → receive! → process locally, does NOT
  re-federate — no loops).
- DURABLE OUTBOX (fed-sx reliability, after the user asked 'if B is down does it still work?'):
  emit! processes locally (always succeeds), QUEUES per-peer to a persisted outbox, delivers
  best-effort. A peer being DOWN no longer fails the publish — delivery is GUARDED (SX guard catches
  the http-request connection error), failed items stay queued and retry on next emit / on boot /
  manual /flows?flush=1. /flows shows the outbox depth.
- serve.sh: SX_PEERS → peers; boot load+flush of the outbox. docker-compose: a 2nd host sx_host_b
  (peer B, own store, no peers).

LIVE PROOF: (1) a peer POSTs create/article to blog.rose-ash.com/inbox → A fires validate+notify.
(2) publish on A → federates to B → B fires ITS behaviors on A's activity (B's /flows + /activities).
(3) RESILIENCE: publish with B DOWN → A returns 303 (was 500) + queues; start B + flush → B receives
the backlog + fires. blog 218/218 (+TA receive test), full host conformance green.

A = blog.rose-ash.com (public/Caddy); B = sx_host_b (internal docker DNS only, no public domain).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-02 19:47:07 +00:00
parent cb0d866002
commit afb9ce5e90
6 changed files with 155 additions and 11 deletions

View File

@@ -1243,6 +1243,13 @@
(begin (set! host/blog--activity-log (list)) (host/blog-load-activitylog!)
(list before (len host/blog--activity-log)))))
(list 1 1))
;; TA-live: a RECEIVED activity (a peer's, arriving via /inbox) fires OUR behaviors through the engine.
(host-bl-test "TA-live: a received create/article activity fires our on-create behavior"
(begin
(set! host/blog--flow-log (list))
(host/blog--receive! {:verb "create" :object-type "article" :category "urgent" :slug "remote1" :id "create:remote1"})
(map (fn (e) (get e "verb")) host/blog--flow-log))
(list "validate" "notify"))
;; P0.2: the publish WORKFLOW as an execute-fold DAG — branches on category, needs {effect,branch},
;; binds to the synchronous execute-fold runner (derived, not chosen).
(host-bl-test "publish-DAG: category branch (newsletter→digest) via the execute-fold"