cross-domain slice 1: events as a fed-sx peer + allocate-a-post-to-a-calendar (LIVE)
The first cross-domain federated workflow — behaviors defined by TYPES, across domains. - events.rose-ash.com is now a fed-sx PEER: a lib/host instance with SX_DOMAIN=events whose 'calendar' TYPE declares an on-allocate behavior. Replaces the Python events service (no strangler). serve.sh gates domain types/behaviors on SX_DOMAIN (blog=article publish/digest; events=calendar+allocate). - DIRECTED cross-domain delivery: an activity with :to <peer-base> is delivered to that peer's inbox (∪ followers). The wire gains 'to'. So 'allocate' targets the events peer specifically. - host/blog--allocate-activity/allocate! + POST /:slug/allocate?calendar=<id>; the events calendar type's allocate-link DAG (an execute-fold effect) fires on receipt. - docker-compose: the sx_events service (own store, shared SX_FED_SECRET, externalnet for a future events.rose-ash.com Caddy route). LIVE PROOF: publish 'Gig Night' on blog.rose-ash.com → POST /gig-night/allocate?calendar=main → the events peer RECEIVES the directed, signed activity (/activities: 'allocate article gig-night') and its calendar type's on-allocate behavior FIRES (/flows: 'linked gig-night'). blog 218/218, full conformance green. NEXT: events runs lib/events (real calendars/recurrence/ticketing); link event→post; shop (lib/commerce) sells tickets — same federated, type-declared shape. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -148,6 +148,16 @@
|
||||
:relation kind :target dst
|
||||
:delta (str verb " " kind " " dst)
|
||||
:id (str verb ":" src ":" kind ":" dst)}))
|
||||
;; ── CROSS-DOMAIN (events): allocate a post to a calendar — a DIRECTED activity (:to the events peer).
|
||||
;; It federates to events, whose calendar type declares an on-allocate behavior that links it.
|
||||
(define host/blog--events-base "") ;; the events peer base URL (serve-set from SX_EVENTS_BASE)
|
||||
(define host/blog--set-events-base! (fn (b) (set! host/blog--events-base b)))
|
||||
(define host/blog--allocate-activity
|
||||
(fn (post calendar)
|
||||
{:verb "allocate" :actor host/blog--actor
|
||||
:object post :object-type (host/blog--post-type post) :slug post
|
||||
:target calendar :to host/blog--events-base
|
||||
:delta (str "allocate to " calendar) :id (str "allocate:" post ":" calendar)}))
|
||||
;; MARSHAL the canonical activity → next/'s Erlang proplist shape, for the Erlang runner adapter
|
||||
;; (RA). The seam activity is canonical; each runner adapter maps it to its substrate. Unused until
|
||||
;; RA, defined + tested here so the reconcile is complete and RA has its bridge ready.
|
||||
@@ -173,7 +183,8 @@
|
||||
;; the ctx a publish activity presents to the publish-DAG (string keys — preds read ctx by key).
|
||||
;; Reads the canonical activity's top-level :category + :slug (P0.4).
|
||||
(define host/blog--publish-ctx
|
||||
(fn (activity) {"category" (get activity :category) "slug" (get activity :slug)}))
|
||||
(fn (activity) {"category" (get activity :category) "slug" (get activity :slug)
|
||||
"target" (get activity :target) "verb" (get activity :verb)}))
|
||||
|
||||
;; ── P1: types DECLARE behavior; the runner is DERIVED from the DAG's capabilities ──────
|
||||
;; A type-post carries :behavior = a list of flat string-keyed bindings {"verb" "type" "dag"} (like
|
||||
@@ -346,11 +357,13 @@
|
||||
(define host/blog--outbox-persist! (fn () (persist/backend-kv-put host/blog-store host/blog--outbox-key host/blog--outbox)))
|
||||
(define host/blog--enqueue-outbox!
|
||||
(fn (a)
|
||||
(begin
|
||||
(for-each (fn (base) (set! host/blog--outbox
|
||||
(concat host/blog--outbox (list {"peer" base "wire" (host/ta--serialize a)}))))
|
||||
(host/blog--delivery-bases))
|
||||
(host/blog--outbox-persist!))))
|
||||
(let ((targets (host/flow--uniq-concat (host/blog--delivery-bases)
|
||||
(if (and (get a :to) (not (= (get a :to) ""))) (list (get a :to)) (list)))))
|
||||
(begin
|
||||
(for-each (fn (base) (set! host/blog--outbox
|
||||
(concat host/blog--outbox (list {"peer" base "wire" (host/ta--serialize a)}))))
|
||||
targets)
|
||||
(host/blog--outbox-persist!)))))
|
||||
;; guarded, SIGNED delivery: POST the wire; a connection failure returns false (item kept), never raises.
|
||||
(define host/blog--try-deliver
|
||||
(fn (peer wire) (guard (e (true false)) (begin (host/blog--fed-post peer wire) true))))
|
||||
@@ -386,6 +399,8 @@
|
||||
;; a relation change → an Add/Remove activity (edge referenced, no CID shift).
|
||||
(define host/blog--emit-relation!
|
||||
(fn (verb src kind dst) (host/blog--emit! (host/blog--relation-activity verb src kind dst))))
|
||||
;; CROSS-DOMAIN: allocate a post to a calendar on the events peer (directed :to → federates to events).
|
||||
(define host/blog--allocate! (fn (post calendar) (host/blog--emit! (host/blog--allocate-activity post calendar))))
|
||||
|
||||
;; ── render ──────────────────────────────────────────────────────────
|
||||
;; A post's sx_content is SX element markup -> HTML via render-page (which supplies
|
||||
@@ -3022,10 +3037,19 @@
|
||||
(host/require-login resolve)
|
||||
(host/require-permission "edit" (fn (req) "blog")))
|
||||
h)))
|
||||
;; POST /<slug>/allocate?calendar=<id> — allocate a post to a calendar on the events peer. Emits a
|
||||
;; directed "allocate" activity that federates to events, whose calendar type reacts (P1 behavior).
|
||||
(define host/blog-allocate
|
||||
(fn (req)
|
||||
(let ((post (dream-param req "slug")) (calendar (or (dream-query-param req "calendar") "main")))
|
||||
(begin
|
||||
(when (not (= host/blog--events-base "")) (host/blog--allocate! post calendar))
|
||||
(dream-redirect (str "/" post "/"))))))
|
||||
(define host/blog-write-routes
|
||||
(fn (resolve)
|
||||
(list
|
||||
(dream-post "/new" (host/blog--protect-html resolve host/blog-form-submit))
|
||||
(dream-post "/:slug/allocate" (host/blog--protect-html resolve host/blog-allocate))
|
||||
(dream-get "/:slug/edit" (host/blog--protect-html resolve host/blog-edit-form))
|
||||
(dream-post "/:slug/edit" (host/blog--protect-html resolve host/blog-edit-submit))
|
||||
(dream-post "/:slug/blocks/add" (host/blog--protect-html resolve host/blog-block-add-submit))
|
||||
|
||||
Reference in New Issue
Block a user