Add open verb system to unified sexp protocol spec
Verbs are no longer limited to HTTP's fixed seven methods — any symbol is a valid verb. Domain-specific actions (reserve, publish, vote, bid) read as natural language. Verb behaviour declared via schema endpoint. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -108,26 +108,77 @@ Every expression on the wire is one of these forms:
|
|||||||
|
|
||||||
#### Requests (client → server)
|
#### Requests (client → server)
|
||||||
|
|
||||||
|
The head symbol is the verb. **Any symbol is a valid verb.** There is no fixed set like HTTP's seven methods. The verb describes the intent; the path is the noun:
|
||||||
|
|
||||||
```scheme
|
```scheme
|
||||||
(GET "/markets/"
|
;; Reads
|
||||||
:auth "bearer tok_abc123"
|
(GET "/markets/")
|
||||||
:have "sha3-a1b2c3"
|
(GET "/markets/" :have "sha3-a1b2c3" :have-components ("sha3-aaa" "sha3-bbb"))
|
||||||
:have-components ("sha3-aaa" "sha3-bbb"))
|
(GET "/feed/" :stream #t)
|
||||||
|
|
||||||
(POST "/like/"
|
;; Writes (HTTP-style, but you're not limited to these)
|
||||||
:auth "bearer tok_abc123"
|
(POST "/users/" :body (:name "alice" :email "alice@example.com"))
|
||||||
:body (:post-id 123))
|
(DELETE "/posts/draft-123/")
|
||||||
|
|
||||||
(POST "/submit/"
|
;; Domain verbs — describe what's actually happening
|
||||||
|
(publish "/posts/draft-123/")
|
||||||
|
(reserve "/events/saturday-market/" :tickets 2)
|
||||||
|
(subscribe "/newsletters/weekly/")
|
||||||
|
(unsubscribe "/newsletters/weekly/")
|
||||||
|
(pin "/posts/important-announcement/")
|
||||||
|
(refund "/orders/ord-789/" :reason "damaged")
|
||||||
|
(schedule "/calendar/saturday/" :slot 3 :name "Pottery Workshop")
|
||||||
|
(rsvp "/events/annual-meeting/" :attending #t :guests 2)
|
||||||
|
(transfer "/inventory/sourdough/" :from "stall-a" :to "stall-b" :quantity 5)
|
||||||
|
(bid "/auctions/vintage-table/" :amount 45.00)
|
||||||
|
|
||||||
|
;; Cooperative governance
|
||||||
|
(propose "/governance/" :title "New market hours"
|
||||||
|
:body (p "I suggest we open at 8am..."))
|
||||||
|
(second "/governance/proposals/42/")
|
||||||
|
(vote "/governance/proposals/42/" :choice :approve)
|
||||||
|
(ratify "/governance/proposals/42/")
|
||||||
|
|
||||||
|
;; Compute mesh
|
||||||
|
(render :recipe "bafyrecipe..." :input "bafyinput..." :requirements (:min-vram 8))
|
||||||
|
(transcode :input "bafyvideo..." :format "h265" :quality 28)
|
||||||
|
|
||||||
|
;; File uploads — structured, not multipart MIME
|
||||||
|
(POST "/upload/"
|
||||||
:body (
|
:body (
|
||||||
:username "alice"
|
:username "alice"
|
||||||
:email "alice@example.com"
|
|
||||||
:avatar (file :name "photo.jpg" :type "image/jpeg" :data <binary>)))
|
:avatar (file :name "photo.jpg" :type "image/jpeg" :data <binary>)))
|
||||||
|
|
||||||
;; Streaming request — keep connection open for pushes
|
|
||||||
(GET "/feed/" :stream #t)
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
`(reserve "/events/saturday-market/" :tickets 2)` reads as English. An AI agent doesn't need API documentation to understand what that does. The URL is the noun, the verb is the verb — no more `POST /api/users/123/send-password-reset-email` where the action is buried in the URL because HTTP doesn't have the right verb.
|
||||||
|
|
||||||
|
**Verb behaviour is declared in the schema**, not assumed by convention:
|
||||||
|
|
||||||
|
```scheme
|
||||||
|
(GET "/__schema/")
|
||||||
|
|
||||||
|
(ok
|
||||||
|
(schema
|
||||||
|
(verb GET :idempotent #t :auth :optional
|
||||||
|
:description "Retrieve a resource")
|
||||||
|
(verb reserve :idempotent #f :auth :required
|
||||||
|
:params (:tickets int)
|
||||||
|
:returns (reservation)
|
||||||
|
:description "Reserve tickets for an event")
|
||||||
|
(verb cancel-reservation :idempotent #t :auth :required
|
||||||
|
:params (:reservation-id str)
|
||||||
|
:returns (ok)
|
||||||
|
:description "Cancel a ticket reservation")
|
||||||
|
(verb publish :idempotent #t :auth :admin
|
||||||
|
:description "Publish a draft post")
|
||||||
|
(verb vote :idempotent #t :auth :member
|
||||||
|
:params (:choice (enum :approve :reject :abstain))
|
||||||
|
:returns (ok)
|
||||||
|
:description "Vote on a governance proposal")))
|
||||||
|
```
|
||||||
|
|
||||||
|
No more arguing about whether `PATCH` should be idempotent. The schema says what each verb does, what it takes, what it returns, and who can call it. AI agents read the schema and know the full API surface — including domain-specific verbs they've never seen before.
|
||||||
|
|
||||||
#### Responses (server → client)
|
#### Responses (server → client)
|
||||||
|
|
||||||
```scheme
|
```scheme
|
||||||
|
|||||||
Reference in New Issue
Block a user