Skip to main content

Module wire

Module wire 

Source
Expand description

Requests, replies and events between riff and riff-server.

§Protocol

Each call is a POST with a JSON body. A reply is JSON with status 200. An error is plain text with status 400, 403, 404 or 409.

Each call is one type that implements Call: the trait gives the path and the type of the reply (01M3WRD8TBDPA4JNEZY6J4N2EX). The client and the server use the same ones. A command asks for a change of the state that the log gives. A signal changes only what the server keeps in memory. A query reads.

PathRequestReplySort
/v1/registerRegisternullcommand
/v1/startStartStartedcommand
/v1/endEndnullcommand
/v1/joinJoinnullcommand
/v1/leaveLeavenullcommand
/v1/postPostPostedcommand
/v1/claimClaimClaimReplycommand
/v1/releaseReleasenullcommand
/v1/release/forReleaseFornullcommand
/v1/leadLeadLeadReplycommand
/v1/pausePauseRiffReplycommand
/v1/resumeResumeRiffReplycommand
/v1/idle/setSetIdleIdlecommand
/v1/plan/holdHoldHoldReplycommand
/v1/plan/freeFreeFreeReplycommand
/v1/planSetPlanPlanReplycommand
/v1/plan/offPlanOffPlanOffReplycommand
/v1/notes/setSetNotesSetNotesReplycommand
/v1/statusSetStatusnullsignal
/v1/blockedSetBlockednullsignal
/v1/stepSetStepnullsignal
/v1/blocked/lookBlockedLookBlockedLookReplysignal
/v1/itemsItemFactsnullsignal
/v1/aliveAliveAliveReplysignal
/v1/plan/seenPlanSeenPlanReplysignal
/v1/whoWhoRequestWhoReplyquery
/v1/threadsThreadsThreadsReplyquery
/v1/readReadReadReplyquery
/v1/riffRiffQueryRiffReplyquery
/v1/idleIdleQueryIdlequery
/v1/plan/showPlanShowPlanReplyquery
/v1/notesNotesShowNotesReplyquery

GET /v1/me gives MeReply. GET /v1/server gives ServerFacts, also while the server replies 503 to each other call.

POST /v1/token is an OAuth 2.1 token endpoint. Its request is a form, TokenRequest. Its reply is TokenReply, or TokenError with status 400. GET /v1/sign-in gives SignInConfig, or status 404 when the server has no sign-in provider.

POST /v1/revoke ends each sign-in of one person (R20). It needs an access token and a DPoP proof. Its request is Revoke and its reply is Revoked. A missing or bad token gets status 401. A person who is not an admin and names another user gets status 403.

Five calls change or show who may join the riff (01M3JN3AHMK532XMRDASD4XD5D). Each needs an access token and a DPoP proof, like revoke:

PathRequestReplyWho
POST /v1/inviteInviteInvitedan admin
POST /v1/removeRemoveRemovedan admin
POST /v1/membersMembersMembersReplyeach person
POST /v1/logLogQueryLogReplyan admin
POST /v1/adminSetAdminAdminSetthe owner
POST /v1/ownerPassOwnerOwnerPassedthe owner

A person who is not an admin gets status 403 from invite, remove and log. A person who is not the owner gets status 403 from admin and owner. owner to a person who is not a member or an admin gets status 400. remove of the owner or of an admin gets status 400.

Two metadata documents follow the MCP authorization spec (R22):

PathReply
GET /.well-known/oauth-protected-resourceResourceMetadata (RFC 9728)
GET /.well-known/oauth-authorization-serverServerMetadata (RFC 8414)

Two streams use server-sent events. Each event is one data: line that holds JSON:

StreamQueryEvent
GET /v1/watchuri=<session URI>Wake
GET /v1/tailthread=<thread name>Tailed

GET /v1/me with the query uri=<session URI> gives MeReply: only the session of the caller (01M3T5GFVS8NMA992KHZN4VE17). The status line calls it, not who.

Each stream starts with the comment line : ready, so that it sends its first bytes when it opens. A reader skips each line that is not a data: line.

A session is live while its watch stream is open. Each request carries the session URI of its sender as me. The server finds the session by the who part of that URI. When the server needs sign-in, the who part must match the token, or the reply is 403 (R104). A session keeps the user of its first call: a known session ID with another user gets 409 (R159). Only register sets the place of a known session; each other call uses the URI only to make a session that the server does not know.

§Example

A post to the holder of a claim:

use riff_core::wire::Post;

let post: Post = serde_json::from_str(r#"{
    "me": "riff://mike@pangolin/como-technologies/riff?session=a6cf",
    "thread": "como-technologies/riff",
    "to": [{ "claim": "issue-6" }],
    "body": "The API is ready."
}"#).unwrap();
assert_eq!(post.to[0].claim.as_deref(), Some("issue-6"));

Re-exports§

pub use crate::record::AdminSet;

Structs§

Activity
What the hooks of a session saw last (01M41FZNTPXQNCZ1S99HE42PYQ): a tool that runs, a turn that runs between two tools, or a turn that ended. A hook writes it on the machine at each tool call and at the end of each turn, and makes no call. riff mcp sends the newest one in its keep-alive. A riff tool and riff watch give no fact: they are no work.
Alive
POST /v1/alive: a keep-alive. It shows that the session still runs, but it is not a call: the idle time in who stays (R204).
AliveReply
The reply to Alive.
BlockedInfo
A block in the reply to who (01M41FZPGEK4TNPSM2051W4VMS).
BlockedLook
POST /v1/blocked/look: the lead me looks at the blocks of the sessions of its user in its repository. A block with no answer for after_secs wakes the lead again (01M41FZQ545HQ9Q75CSKX8HF8H). A block with no answer for after_secs after that is unanswered (01M41FZQCHWY1YVGAZ60ZHJK21). The server refuses a caller that is not the lead.
BlockedLookReply
The reply to BlockedLook: each block that this look made unanswered. The riff mcp of the lead shows each one in a desktop notification (01M41FZQKZKW131Z8822G31T5G).
CheckpointFacts
The newest checkpoint in ServerFacts.
Claim
POST /v1/claim: takes a lease on one work item. The server refuses a claim of an item that another session holds, with status 409 and a text that names the holder (01M3WRD9JBQMNN96TXJH8EAJ3W).
ClaimReply
The reply to a claim that the server took.
DenyOwner
POST /v1/owner/deny: the owner keeps the owner role that an admin asks for (01M3N7K41N03P26BEFFNX5617K).
Discovery
The fields that riff uses from the discovery document of an OpenID Connect provider.
End
POST /v1/end: the session ended (R205). It leaves who, and its claims are free at once.
FactError
An error of the server in ServerFacts.
Facts
The facts that make the state of a session (SessionState::of).
Free
POST /v1/plan/free: a lead ends the hold of an item (01M43GSGB9ZFHSG0Q83Y50FEGW). A free of an item with no hold changes nothing.
FreeReply
The reply to a free.
Freed
A claim that a new start freed.
Hold
POST /v1/plan/hold: a lead holds an item of its repository thread with a reason, so that no worker can claim it (01M43GSGB9ZFHSG0Q83Y50FEGW). A hold of a held item replaces its reason. Only a lead of the thread, the owner or an admin can (01M43GSGGY0QMB5D5EH92M6ZFP).
HoldInfo
The hold of one item: its reason, and who held it and when: the by and the time of its item_held record (01M43GSGB9ZFHSG0Q83Y50FEGW).
HoldReply
The reply to a hold.
Idle
The settings of idle workers (01M3Q5A0TF9K49V8Z1ZY9NDF74). The server stops no worker for them: the log and the checkpoint keep them so that an old record still reads.
IdleQuery
POST /v1/idle: reads the settings of idle workers (01M3Q5A0TF9K49V8Z1ZY9NDF74). It changes nothing (01M3WRD9BSBKS9TN66H29TGTBV).
Invite
POST /v1/invite: adds a member, by verified email.
Invited
The reply to Invite.
ItemFact
The facts of one item, for example issue-12.
ItemFacts
POST /v1/items: what a client saw of the items of its repository on the forge (01M41FZP2C4Z4J6WKRXZ5B31EH). The server has no credential of the forge: riff pr open, riff verify, riff pr wait and the look of the lead send the facts. It is a signal. With all, the facts replace each fact of the repository: an item with no fact in the list has none now. Else each fact replaces only the fact of its item.
Join
POST /v1/join: adds me to a thread. It makes the thread if it is new.
Lead
POST /v1/lead: the person me makes the session session the lead of the user in the repository of me. It replaces the old lead. A session cannot send it.
LeadReply
Leave
POST /v1/leave: removes me from a thread. It is no longer the lead there.
LogQuery
POST /v1/log: the records of the log of one repository, for an audit (01M3ZWRC11R5M9V1KTF05P240W). Only the owner and the admins can read them.
LogReply
The reply to LogQuery: each record of the repository (Record::of_repository), in log order. A post has only its mark (Record::for_audit, 01M3ZWRC3XBFN8FJDGE8XWZ5EA).
MachineInfo
The numbers of the machine of a session in the reply to who (01M515KSWVGCBS76AWZV74TJQ3).
MeReply
The reply to GET /v1/me: only the session of the caller, and the build of the server (01M3T5GFVS8NMA992KHZN4VE17). session is None when the server does not know the session.
Members
POST /v1/members: shows who may join the riff.
MembersReply
The reply to Members.
Message
NotesReply
The reply to NotesShow: the notes now, and with history the old texts, the oldest first. A lead with no notes has an empty text.
NotesShow
POST /v1/notes: the query for the notes of a lead (01M59258NTXPMWV18TKRKWNTYN). The user of the lead can read them, and the owner of the riff. Another member cannot.
NotesVersion
One text of the notes, with who wrote it and when.
OwnerAsked
The reply to TakeOwner.
OwnerDenied
The reply to DenyOwner.
OwnerPassed
The reply to PassOwner.
PassOwner
POST /v1/owner: the owner passes the owner role to a member or an admin. The old owner stays an admin.
Pause
POST /v1/pause: pauses the repository of me, or with riff the whole riff (01M3XAHZBGSSJB3YX23K88W01K). See 01M3XAHZDSQR263QZVB41CK0MX for who can.
PauseInfo
A pause that holds: who set it, and when (01M3XAHZBGSSJB3YX23K88W01K).
Person
A member of the riff in the reply to who: a person, not a session (01M3NT4M3A4E3K5S2NM7MS6PQD).
PlanOff
POST /v1/plan/off: the server forgets the plan of the repository thread. The holds stay (01M4A4YTNSJR0R1T9JNXPBSKHC).
PlanOffReply
The reply to a plan_off.
PlanReply
The plan of the server for one repository thread (01M4A4Z1NKPDBXV2PRZCG86G6A): the reply of plan, plan_seen and the query plan.
PlanSeen
POST /v1/plan/seen: a look saw that the plan of the forge is the plan of the server at position (01M4A4YTYVHFGK0CJVACJQ8DQ3). It is a signal: it makes no record.
PlanShow
POST /v1/plan/show: the plan of a repository thread, and its holds (01M4A4Z1NKPDBXV2PRZCG86G6A).
PlanShown
The plan of one repository thread on the server, with its age.
Post
POST /v1/post: adds a message to a thread and wakes each session that to selects. The sender and each woken session join the thread.
Posted
The reply to post. It tells the sender who woke.
Pruned
The start of the log after the checkpoint rule removed its oldest chunks: the reply of POST /v1/log has the records from first on (01M588N3R2VP12A8X4EASX0BJ4).
PullFact
A pull request of an item, and its state.
Read
POST /v1/read: returns the messages that me has not read, or all of them when all is true. It marks them as read.
ReadReply
Register
POST /v1/register: a session says that it exists and where it works. A session registers when it starts and when it moves. It joins the thread of its repository. A worker says that it is a worker, so who shows it the same on each machine (01M3NT4M159EHN5W8JRTQ417N4).
Release
POST /v1/release: frees a claim. Only its holder can.
ReleaseFor
POST /v1/release/for: the lead of a user frees the claim of another session of that user (01M3WG243BW7P6E1ME0DFNQF8C). The server posts a note to the thread of the claim.
ReleaseReply
The reply to a release.
Remove
POST /v1/remove: removes a member and ends each sign-in of that person.
Removed
The reply to Remove.
RepositoryPause
A repository that is paused, with its pause.
ResourceMetadata
The protected resource metadata of riff-server (RFC 9728).
Resume
POST /v1/resume: resumes the repository of me, or with riff the whole riff (01M3XAHZBGSSJB3YX23K88W01K). See 01M3XAHZDSQR263QZVB41CK0MX for who can.
Revoke
POST /v1/revoke: ends each sign-in of a person.
Revoked
The reply to Revoke.
RiffBinary
The riff that a session runs: its build, and whether its file was replaced after the start (01M514C11BPE93PJT4221PYVHS).
RiffQuery
POST /v1/riff: reads the pauses of the riff, for the place of me. It changes nothing (01M3WRD9BSBKS9TN66H29TGTBV).
RiffReply
The pauses of the riff, as the caller sees them (01M3XAHZJAF6YVDJ7WX74X8RBX): the reply to /v1/riff, /v1/pause and /v1/resume.
ServerFacts
The reply to GET /v1/server: the facts of one riff-server, for riff server (01M3TJWJ12WEDCXW3W0529KRP2). Each field has a default, so a riff of another build reads the reply. Each time is in milliseconds since the Unix epoch, on the clock of the server.
ServerMetadata
The authorization server metadata of riff-server (RFC 8414).
SessionInfo
SetAdmin
POST /v1/admin: the owner makes a person an admin, or an admin a member again.
SetBlocked
POST /v1/blocked: me cannot go on with no decision (01M41FZPGEK4TNPSM2051W4VMS). It is a signal. The blocked tool and riff blocked send it with the message that wakes the lead, in one command: a session does neither alone.
SetIdle
POST /v1/idle/set: sets each given setting of idle workers, and gives the settings. Only the owner or an admin can; in a riff with no sign-in, each caller can (01M3Q5A0TF9K49V8Z1ZY9NDF74).
SetMachine
POST /v1/machine: the numbers of the machine of me (01M515KSWVGCBS76AWZV74TJQ3). The riff mcp of the lead sends them for its machine, which has no riff workers host. The numbers are the text of the status of a workers host. The daemon of a host sends its facts in the same way (01M57D3F50347RD8ED79KEA9V7). riff-server keeps the text and does not read it. It is a signal, like a status.
SetNotes
POST /v1/notes/set: the lead of a user writes the notes of its repository thread (01M59258K3TYR09HC4AWHWZPEX). The text replaces the old text, and the old text stays in the history. Only a session of the user that is not a worker, and the person of the user, can write them (01M59258NTXPMWV18TKRKWNTYN). The text has at most NOTES_MAX bytes, and it looks like no token (01M59258RJ3CG498Z8AVQ5TV5Q).
SetNotesReply
The reply to SetNotes.
SetPlan
POST /v1/plan: a session sends the full plan of its repository thread (01M4A4YTNSJR0R1T9JNXPBSKHC). base is the position of the plan_set record of the plan that the client compared with, or None when the server had no plan. A base that is not the position on the server gets the code stale_base (01M4A4YTR2NKVBPE6BT9EC3X75).
SetStatus
POST /v1/status: sets the status of me. It replaces the old status.
SetStep
POST /v1/step: a change of the long step of me (01M48VDGTD40P8RBZMS0XB5M9N). It is a signal, and a sign of life. riff step fail also wakes the lead (01M48VDS663X064YS5ZGCCZSTB).
SignInConfig
GET /v1/sign-in: the OpenID Connect provider that riff login signs in with.
Start
POST /v1/start: a new start of the session: a new agent process, a resume or a /clear (01M3JEE1QQCFS5TMZW5N2DAD2D). Its claims are free at once. It keeps its ID, its threads and its lead. The call says why the session starts, and if it is a worker (01M3X9X9M079WGFPJZHNXH9VEP).
Started
Status
What a session does now, in its own words: its current step. The words help a person. They make no state: a block is SetBlocked (01M41FZPGEK4TNPSM2051W4VMS).
StatusInfo
A Status in the reply to who, with its age.
StepInfo
A long step in the reply to who (01M48VDGTD40P8RBZMS0XB5M9N).
Tailed
An event on GET /v1/tail?thread=….
TakeOwner
POST /v1/owner/take: an admin asks for the owner role (01M3N7K3ZAZFGABN7032AYJWEM).
ThreadInfo
Threads
POST /v1/threads: lists the threads of me, with unread counts.
ThreadsReply
TokenError
An OAuth error reply, for example {"error":"invalid_grant"}.
TokenReply
A new pair of riff tokens. Send access_token with the DPoP scheme and a proof from the device key. Use refresh_token once, to get the next pair.
TokenRequest
POST /v1/token, as application/x-www-form-urlencoded.
Unanswered
A block with no answer of the lead: the session with its claims, and the reason. It holds no text of a message.
Wake
An event on GET /v1/watch?uri=…: a message addressed to the session.
WhoReply
WhoRequest
POST /v1/who: lists the known sessions. The call counts as a call of me.

Enums§

Kind
The kind of a post. A post call sends message, status or note.
PersonRole
The role of a person in the riff.
PullState
The state of a pull request: from the status riff/verify of its head, and from its merge.
RiffOwner
The owner of the riff, in the reply to who (01M3Q63NK0AHM25MB258B0K8XP). A reply with no owner field reads as RiffOwner::NoSignIn.
RiffState
The state of a riff. A new riff is paused.
SessionState
The state of a session. The server derives it from facts; no session reports it (01M3QB6CJ1XCQG5B1BVR8AF3B4, 01M41FZQVEF8S2W9RCM4V87C3D). The first state that matches wins, in this order:
StartReason
Why a session_started record is there (01M3X9X9M079WGFPJZHNXH9VEP). A start call sends process, resume or clear.
StepChange
A change of the long step of a session (01M48VDGTD40P8RBZMS0XB5M9N): a step that runs longer than a tool call, for example a live window of two hours.
Waits
What the claims of a session wait for (01M41FZP9A50CH4A2VX344DW49). The server makes it from the facts of the items (ItemFact). Nobody must decide, so it wakes nobody.

Constants§

ACCESS_TOKEN_TYPE
The subject token type of a TOKEN_EXCHANGE request that swaps a person access token for a session access token (R19).
ACTIVITY_CHARS
The most characters in the text of a tool of an Activity.
ALIVE_EVERY
riff mcp sends a keep-alive this often, also while no turn runs (R204). A session with no sign of life for 3 minutes is gone.
CALL_HEADER
The HTTP header of the call ID of a command (01M48VFX22S4811DYBBD7QDW24). Each try of one call sends the same ID. riff-server runs a command with a call ID one time only, and gives a second try the reply of the first.
ID_TOKEN_TYPE
The subject token type of a TOKEN_EXCHANGE request.
MACHINE_CHARS
The most characters in the numbers of a SetMachine: the facts of the daemon of a host are longer than a status (01M57D3F50347RD8ED79KEA9V7).
REFUSED_HEADER
The HTTP header of a refused command: the code of the refusal, for example held (01M3WRD9JBQMNN96TXJH8EAJ3W). The text of the reply is the reason, for a person.
REPEAT_HEADER
The HTTP header of the reply to a repeated call: 1. The reply is the reply of the kept call, on the state of now (01M48VFX22S4811DYBBD7QDW24).
STATUS_CHARS
The most characters in the step of a Status, and in the reason of a SetBlocked.
TOKEN_EXCHANGE
The grant type that swaps an ID token of the sign-in provider for a first pair of riff tokens (RFC 8693 token exchange).
WORKER_ALIVE_EVERY
A worker session sends a keep-alive this often, so that it stops soon after the server asks (01M3Q5A0NKY1FCS0YH6N6YD3GN).

Traits§

Call
A call: one wire type with its path and the type of its reply (01M3WRD8TBDPA4JNEZY6J4N2EX). The client sends each call with one generic function, and the server makes one route for each.

Type Aliases§

Keys
The thumbprints of the device keys of each user, by user: the keys of the live sign-ins of that user. A server without sign-in gives none (R201).