(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)}))))
