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:
@@ -290,13 +290,22 @@ the flow instance Id is the resume handle.
|
||||
behavior/pump delivers + processes it → B's engine fires ITS behavior on A's activity; DIRECTIONAL
|
||||
(B re-emits to its own outbox, not back into the inbox — no loop). This is "everything works over
|
||||
fed-sx" proven at the seam. Full host conformance green.
|
||||
- [ ] **TA-LIVE (deferred — same shape as RA-live).** Swap the mem-wire for the REAL next/ delivery
|
||||
wire (outbox → http_server → peer inbox). Needs: (a) a PERSISTENT next/ kernel process (gen_servers
|
||||
don't survive across erlang-eval-ast calls — the RA-live finding; next/ outbox/http_server are the
|
||||
persistent side); (b) the ACTOR MODEL real (:actor is a "site" placeholder — peer_actors /
|
||||
follower_graph / per-author identity decide WHO the out-wire delivers to); (c) push /activities
|
||||
(the P2 event source) onto the out-wire. RISK: next/ delivery M2 blockers (er-scheduler context).
|
||||
The transport contract + serialization + the loop are proven; TA-live is the wire impl + placement.
|
||||
- [x] **TA-LIVE DONE + LIVE-VERIFIED 2026-07-02 (real two-instance A→B federation over HTTP).** The
|
||||
wire is the HOST's own http-request (not next/ delivery — simpler + already persistent). host/ta--
|
||||
{post, make-http-wire, federate}; the host gains a POST /inbox (host/blog-inbox → host/blog--receive!
|
||||
→ process locally, does NOT re-federate). A DURABLE OUTBOX (host/blog--outbox, persisted) gives fed-
|
||||
sx RELIABILITY: emit! processes locally (always succeeds), QUEUES per-peer, and delivers best-effort
|
||||
— a peer being DOWN does not fail the local publish (delivery is guarded; failed items stay queued +
|
||||
retry on next emit / on boot / manual /flows?flush=1). serve.sh: SX_PEERS → host/blog--set-peers!,
|
||||
boot load+flush. docker-compose: a 2nd host `sx_host_b` (its own store, no peers) as peer B.
|
||||
LIVE PROOF: (1) a peer POSTs a create/article to blog.rose-ash.com/inbox → A fires validate+notify.
|
||||
(2) publish on A → federates to B → B's /flows fires validate+notify on A's activity; B's /activities
|
||||
shows the received create. (3) RESILIENCE — publish with B DOWN → A returns 303 (was 500), activity
|
||||
queued; start B + flush → B receives the backlog + fires. blog 218/218, conformance green.
|
||||
NOTE on placement/domains: A = blog.rose-ash.com (Caddy/externalnet); B = sx_host_b, internal-only
|
||||
(docker DNS, no public domain) — a real peer would get its own Caddy subdomain. FUTURE: the actor
|
||||
model (:actor "site" placeholder → follower_graph decides WHO to deliver to); a background delivery
|
||||
loop (currently retry is opportunistic on emit/boot/flush, not a timer); signature verification on /inbox.
|
||||
|
||||
## AX — artdag GROWS control-flow (business logic MIGRATES to artdag) [DEMAND-DRIVEN]
|
||||
Today artdag is pure dataflow and the execute-fold is the synchronous control-flow runner. That's
|
||||
@@ -325,6 +334,14 @@ covers everything until a DAG's cost/latency/placement forces the substrate.
|
||||
activities), so business logic can change state, which federates, which triggers more flows.
|
||||
|
||||
## Progress log (newest first)
|
||||
- 2026-07-02 — RA-LIVE + TA-LIVE DONE + LIVE-VERIFIED. (1) sx_kernel container (durable-execution
|
||||
service) deployed; the host's RA kernel-runner drives it over HTTP — editing a newsletter article →
|
||||
durable Update → kernel SUSPENDS (pending) → /flows?resume → done. (2) TA federation: host POST
|
||||
/inbox receives peers' activities + fires; a 2nd instance sx_host_b (peer B) — publish on A →
|
||||
federates to B → B fires ITS behaviors on A's activity. (3) DURABLE OUTBOX for fed-sx reliability
|
||||
(user-driven): B down → A's publish still succeeds (303, was 500) + queues; B up + flush → backlog
|
||||
delivers. The whole distributed half is LIVE. Remaining polish: actor model, background delivery
|
||||
timer, /inbox signature verify, expose B on a public domain.
|
||||
- 2026-07-02 — the REAL KERNEL SERVICE built (next/kernel/host_kernel.erl + serve.sh + tests/
|
||||
host_kernel.sh, 4/4 over HTTP). A persistent durable-execution service: flow_store + named-flow
|
||||
registry, parameterised flow routes (GET /flow/start/<category> → "<id>:<status>", GET
|
||||
|
||||
Reference in New Issue
Block a user