(define request-fields (quote ((:verb "Symbol — the action to perform (required)") (:path "String — resource path (required)") (:headers "Dict — structured request metadata (optional)") (:cookies "Dict — client state, values can be any SX type (optional)") (:params "Dict — query parameters as typed values (optional)") (:capabilities "List — capabilities this request requires (optional)") (:body "Any SX value — request payload (optional)")))) (define response-fields (quote ((:status "Symbol or condition — result status (required)") (:headers "Dict — structured response metadata (optional)") (:set-cookie "Dict — cookies to set, values are dicts with :value :max-age :path (optional)") (:body "Any SX value — response payload (optional)") (:stream "Boolean — if true, body is a sequence of chunks (optional)")))) (define core-verbs (quote ((navigate "Retrieve a page for display — analogous to GET for documents") (fetch "Retrieve data — analogous to GET for APIs") (query "Structured query — body contains a query expression") (mutate "Change state — analogous to POST/PUT/PATCH") (create "Create a new resource — analogous to POST") (delete "Remove a resource — analogous to DELETE") (subscribe "Open a streaming channel for real-time updates") (inspect "Retrieve metadata about a resource (capabilities, schema)") (ping "Liveness check — server responds with (response :status ok)")))) (define standard-headers (quote ((:accept "List of acceptable response types") (:language "String or list — preferred languages") (:if-match "String — content hash for conditional requests") (:capabilities "List — capabilities the client holds") (:origin "String — requesting origin for CORS-like checks") (:content-type "String — always text/sx in pure SXTP") (:content-hash "String — SHA3-256 of the body expression") (:cache "Symbol — :immutable, :revalidate, :none") (:vary "List of header keys that affect caching") (:link "Dict — related resources")))) (define cookie-options (quote ((:value "Any SX value — the cookie payload (required)") (:max-age "Number — seconds until expiry (optional)") (:path "String — path scope (optional, default /)") (:domain "String — domain scope (optional)") (:secure "Boolean — require secure transport (optional)") (:same-site "Symbol — :strict, :lax, or :none (optional)") (:delete "Boolean — if true, remove this cookie (optional)")))) (define status-symbols (quote ((ok "Success — body contains the result") (created "Resource created — body contains the new resource") (accepted "Request accepted for async processing") (no-content "Success with no body") (redirect "See :headers :location for target") (not-modified "Cached version is current based on :if-match") (error "General error — see :body for condition") (not-found "Resource does not exist") (forbidden "Insufficient capabilities") (invalid "Malformed request or invalid params") (conflict "State conflict — concurrent edit") (unavailable "Service temporarily unavailable")))) (define condition-fields (quote ((:type "Symbol — condition type (required)") (:message "String — human-readable description (optional)") (:path "String — resource that caused the error (optional)") (:retry "Boolean — whether retrying may succeed (optional)") (:detail "Any SX value — domain-specific detail (optional)")))) (define chunk-fields (quote ((:seq "Number — sequence index for ordered chunks") (:body "Any SX value — the chunk content") (:done "Boolean — signals end of stream")))) (define event-fields (quote ((:type "Symbol — event type (required)") (:id "String — event or resource identifier (optional)") (:body "Any SX value — event payload (optional)") (:time "Number — unix timestamp (optional)")))) (define example-navigate (quote ((request :verb navigate :path "/geography/capabilities" :headers {:host "sx.rose-ash.com" :accept "text/sx"}) (response :status ok :headers {:content-type "text/sx" :content-hash "sha3-9f2a"} :body (page :title "Capabilities" (h1 "Geography Capabilities") (~capability-list :domain "geography")))))) (define example-query (quote ((request :verb query :path "/events" :capabilities (fetch db:read) :params {:after "2026-03-01" :limit 10} :body (filter (events) (fn (e) (> (:attendees e) 50)))) (response :status ok :headers {:cache :revalidate} :body ((event :id "evt-42" :title "Jazz Night" :attendees 87) (event :id "evt-55" :title "Art Walk" :attendees 120)))))) (define example-mutate (quote ((request :verb create :path "/blog/posts" :capabilities (mutate blog:publish) :cookies {:session "tok_abc123"} :body {:tags ("protocol" "sx" "web") :body (article (h1 "SXTP") (p "Everything is SX.")) :title "SXTP Protocol"}) (response :status created :headers {:location "/blog/posts/sxtp-protocol" :content-hash "sha3-ff01"} :body {:created-at 1711612800 :id "post-789" :path "/blog/posts/sxtp-protocol"})))) (define example-subscribe (quote ((request :verb subscribe :path "/events/live" :capabilities (fetch) :headers {:host "events.rose-ash.com"}) (response :status ok :stream true) (event :type new-event :id "evt-99" :body (div :class "event-card" (h3 "Poetry Slam"))) (event :type heartbeat :time 1711612860)))) (define example-error (quote ((request :verb fetch :path "/blog/nonexistent") (response :status not-found :body (condition :type resource-not-found :path "/blog/nonexistent" :message "No such post" :retry false))))) (define example-inspect (quote ((request :verb inspect :path "/cart/checkout") (response :status ok :body {:available-verbs (inspect mutate) :params-schema {:payment-method "symbol" :shipping-address "dict"} :required-capabilities (mutate cart:checkout)}))))