Skip to main content

brain_db_sdk/wire/
opcode.rs

1//! Wire-protocol opcodes (u16, big-endian on the wire).
2//!
3//! High byte is the namespace (`0x00` substrate / connection / admin,
4//! `0x01` typed-graph). Within a namespace the low byte's high bit
5//! selects direction: `< 0x80` server-bound request, `>= 0x80`
6//! client-bound response. The table is the full v1 set: the handshake
7//! (HELLO/WELCOME/AUTH/AUTH_OK/BYE), keepalive (PING/PONG + server
8//! heartbeat), the cognitive verbs (ENCODE/RECALL/PLAN/REASON/FORGET/LINK
9//! and friends), server-push subscriptions, transactions, capability
10//! introspection, ERROR, and the `0x01xx` typed-graph ops the conformance
11//! corpus exercises (entity / statement / relation / schema CRUD, history,
12//! and traversal).
13
14// The types below mirror the server's wire structs one-for-one: same names,
15// same field names, same order. Their documentation is the protocol itself —
16// `conformance/protocol.json` carries every field's type and serde attributes,
17// and the corpus pins the bytes. A doc comment on each of ~2000 fields would
18// restate the field name and nothing more, and the ones that DO carry meaning
19// beyond their name (written below) would be lost in the noise.
20#![allow(missing_docs)]
21
22/// Wire-protocol opcode.
23#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
24#[repr(u16)]
25pub enum Opcode {
26    // Connection management.
27    Hello = 0x0001,
28    Welcome = 0x0081,
29    Auth = 0x0002,
30    AuthOk = 0x0082,
31    Bye = 0x001F,
32
33    // Keepalive. PING/PONG are client-initiated RTT probes; SERVER_PING is
34    // the server's idle-timer heartbeat that the client MUST answer with
35    // CLIENT_PONG or the server closes the connection.
36    Ping = 0x0010,
37    Pong = 0x0090,
38    ClientPong = 0x0011,
39    ServerPing = 0x0091,
40    // Stream control. CANCEL_STREAM targets an in-flight stream by id; the
41    // server answers CANCEL_STREAM_ACK on the SAME stream and stops emitting.
42    CancelStream = 0x0050,
43    CancelStreamAck = 0x00D0,
44
45    // v1 cognitive verbs.
46    EncodeReq = 0x0020,
47    EncodeResp = 0x00A0,
48    RecallReq = 0x0021,
49    RecallResp = 0x00A1,
50    PlanReq = 0x0022,
51    PlanResp = 0x00A2,
52    ReasonReq = 0x0023,
53    ReasonResp = 0x00A3,
54    ForgetReq = 0x0024,
55    ForgetResp = 0x00A4,
56    LinkReq = 0x0025,
57    LinkResp = 0x00A5,
58    UnlinkReq = 0x0026,
59    UnlinkResp = 0x00A6,
60    MemoryListReq = 0x0027,
61    MemoryListResp = 0x00A7,
62    MemoryInspectReq = 0x0028,
63    MemoryInspectResp = 0x00A8,
64    EncodeVectorDirectReq = 0x002A,
65    EncodeVectorDirectResp = 0x00AA,
66
67    // Subscriptions (server push).
68    SubscribeReq = 0x0030,
69    SubscribeEvent = 0x00B0,
70    UnsubscribeReq = 0x0031,
71    UnsubscribeResp = 0x00B1,
72
73    // Transactions.
74    TxnBegin = 0x0040,
75    TxnBeginResp = 0x00C0,
76    TxnCommit = 0x0041,
77    TxnCommitResp = 0x00C1,
78    TxnAbort = 0x0042,
79    TxnAbortResp = 0x00C2,
80
81    // Space registry (per-tenant isolation unit).
82    SpaceCreateReq = 0x0070,
83    SpaceCreateResp = 0x00F0,
84    SpaceListReq = 0x0071,
85    SpaceListResp = 0x00F1,
86    SpaceDeleteReq = 0x0072,
87    SpaceDeleteResp = 0x00F2,
88
89    // Session registry (conversation/run grouping within a space).
90    SessionCreateReq = 0x0073,
91    SessionCreateResp = 0x00F3,
92    SessionListReq = 0x0074,
93    SessionListResp = 0x00F4,
94    SessionDeleteReq = 0x0075,
95    SessionDeleteResp = 0x00F5,
96
97    // Error.
98    Error = 0x00FF,
99
100    // Capability introspection.
101    GetCapabilitiesReq = 0x0032,
102    GetCapabilitiesResp = 0x00B2,
103
104    // Typed-graph ops exercised by the corpus.
105    SchemaUploadReq = 0x0120,
106    SchemaUploadResp = 0x01A0,
107    SchemaGetReq = 0x0121,
108    SchemaGetResp = 0x01A1,
109    SchemaListReq = 0x0122,
110    SchemaListResp = 0x01A2,
111    SchemaValidateReq = 0x0123,
112    SchemaValidateResp = 0x01A3,
113    // Surgical narrow of a single declared predicate / relation_type. The
114    // per-type counterpart to the namespace-wide SCHEMA_REPLACE; see Brain
115    // spec §03.05.
116    SchemaDropReq = 0x0125,
117    SchemaDropResp = 0x01A5,
118    // Destructive namespace swap. Separate from SCHEMA_UPLOAD because it drops
119    // every declared row in the namespace before the new document lands; see
120    // Brain spec §03.05.
121    SchemaReplaceReq = 0x0127,
122    SchemaReplaceResp = 0x01A7,
123    // Extractor introspection (read-only; extraction is always-on).
124    ExtractorListReq = 0x0124,
125    ExtractorListResp = 0x01A4,
126    EntityCreateReq = 0x0130,
127    EntityCreateResp = 0x01B0,
128    EntityGetReq = 0x0131,
129    EntityGetResp = 0x01B1,
130    EntityResolveReq = 0x0136,
131    EntityResolveResp = 0x01B6,
132    EntityListReq = 0x0137,
133    EntityListResp = 0x01B7,
134    // Entity mutation: an entity accretes detail (update/rename), consolidates
135    // duplicates (merge/unmerge), and retires (tombstone) over its lifetime.
136    EntityUpdateReq = 0x0132,
137    EntityUpdateResp = 0x01B2,
138    EntityRenameReq = 0x0133,
139    EntityRenameResp = 0x01B3,
140    EntityMergeReq = 0x0134,
141    EntityMergeResp = 0x01B4,
142    EntityUnmergeReq = 0x0135,
143    EntityUnmergeResp = 0x01B5,
144    EntityTombstoneReq = 0x0138,
145    EntityTombstoneResp = 0x01B8,
146    StatementCreateReq = 0x0140,
147    StatementCreateResp = 0x01C0,
148    StatementGetReq = 0x0141,
149    StatementGetResp = 0x01C1,
150    StatementListReq = 0x0146,
151    StatementListResp = 0x01C6,
152    // Statement lifecycle: a claim is revised (supersede), walked back
153    // (retract), retired (tombstone), or inspected across versions (history).
154    StatementSupersedeReq = 0x0142,
155    StatementSupersedeResp = 0x01C2,
156    StatementTombstoneReq = 0x0143,
157    StatementTombstoneResp = 0x01C3,
158    StatementRetractReq = 0x0144,
159    StatementRetractResp = 0x01C4,
160    StatementHistoryReq = 0x0145,
161    StatementHistoryResp = 0x01C5,
162    RelationCreateReq = 0x0150,
163    RelationCreateResp = 0x01D0,
164    RelationListFromReq = 0x0154,
165    RelationListFromResp = 0x01D4,
166    RelationListToReq = 0x0155,
167    RelationListToResp = 0x01D5,
168    // Relation lifecycle + traversal: fetch one (get), revise (supersede),
169    // retire (tombstone), or walk the graph from an entity (traverse).
170    RelationGetReq = 0x0151,
171    RelationGetResp = 0x01D1,
172    RelationSupersedeReq = 0x0152,
173    RelationSupersedeResp = 0x01D2,
174    RelationTombstoneReq = 0x0153,
175    RelationTombstoneResp = 0x01D3,
176    RelationTraverseReq = 0x0156,
177    RelationTraverseResp = 0x01D6,
178    // Query introspection debug surface: the plan (explain) and execution trace.
179    QueryExplainReq = 0x0161,
180    QueryExplainResp = 0x01E1,
181    QueryTraceReq = 0x0162,
182    QueryTraceResp = 0x01E2,
183    GraphFetchReq = 0x0163,
184    GraphFetchResp = 0x01E3,
185    MaterializeProceduralReq = 0x0164,
186    MaterializeProceduralResp = 0x01E4,
187}
188
189impl Opcode {
190    /// Numeric value as it appears in the frame header.
191    #[inline]
192    #[must_use]
193    pub fn as_u16(self) -> u16 {
194        self as u16
195    }
196}
197
198#[cfg(test)]
199mod tests {
200    use super::*;
201
202    #[test]
203    fn spec_pinned_values() {
204        assert_eq!(Opcode::Hello.as_u16(), 0x0001);
205        assert_eq!(Opcode::Welcome.as_u16(), 0x0081);
206        assert_eq!(Opcode::Auth.as_u16(), 0x0002);
207        assert_eq!(Opcode::AuthOk.as_u16(), 0x0082);
208        assert_eq!(Opcode::Bye.as_u16(), 0x001F);
209        assert_eq!(Opcode::Ping.as_u16(), 0x0010);
210        assert_eq!(Opcode::Pong.as_u16(), 0x0090);
211        assert_eq!(Opcode::ClientPong.as_u16(), 0x0011);
212        assert_eq!(Opcode::ServerPing.as_u16(), 0x0091);
213        assert_eq!(Opcode::EncodeReq.as_u16(), 0x0020);
214        assert_eq!(Opcode::EncodeResp.as_u16(), 0x00A0);
215        assert_eq!(Opcode::RecallReq.as_u16(), 0x0021);
216        assert_eq!(Opcode::RecallResp.as_u16(), 0x00A1);
217        assert_eq!(Opcode::PlanReq.as_u16(), 0x0022);
218        assert_eq!(Opcode::PlanResp.as_u16(), 0x00A2);
219        assert_eq!(Opcode::ReasonReq.as_u16(), 0x0023);
220        assert_eq!(Opcode::ReasonResp.as_u16(), 0x00A3);
221        assert_eq!(Opcode::ForgetReq.as_u16(), 0x0024);
222        assert_eq!(Opcode::ForgetResp.as_u16(), 0x00A4);
223        assert_eq!(Opcode::LinkReq.as_u16(), 0x0025);
224        assert_eq!(Opcode::LinkResp.as_u16(), 0x00A5);
225        assert_eq!(Opcode::UnlinkReq.as_u16(), 0x0026);
226        assert_eq!(Opcode::UnlinkResp.as_u16(), 0x00A6);
227        assert_eq!(Opcode::MemoryListReq.as_u16(), 0x0027);
228        assert_eq!(Opcode::MemoryListResp.as_u16(), 0x00A7);
229        assert_eq!(Opcode::EncodeVectorDirectReq.as_u16(), 0x002A);
230        assert_eq!(Opcode::Error.as_u16(), 0x00FF);
231        assert_eq!(Opcode::MaterializeProceduralReq.as_u16(), 0x0164);
232
233        // Space + session registry.
234        assert_eq!(Opcode::SpaceCreateReq.as_u16(), 0x0070);
235        assert_eq!(Opcode::SpaceCreateResp.as_u16(), 0x00F0);
236        assert_eq!(Opcode::SpaceListReq.as_u16(), 0x0071);
237        assert_eq!(Opcode::SpaceListResp.as_u16(), 0x00F1);
238        assert_eq!(Opcode::SpaceDeleteReq.as_u16(), 0x0072);
239        assert_eq!(Opcode::SpaceDeleteResp.as_u16(), 0x00F2);
240        assert_eq!(Opcode::SessionCreateReq.as_u16(), 0x0073);
241        assert_eq!(Opcode::SessionCreateResp.as_u16(), 0x00F3);
242        assert_eq!(Opcode::SessionListReq.as_u16(), 0x0074);
243        assert_eq!(Opcode::SessionListResp.as_u16(), 0x00F4);
244        assert_eq!(Opcode::SessionDeleteReq.as_u16(), 0x0075);
245        assert_eq!(Opcode::SessionDeleteResp.as_u16(), 0x00F5);
246
247        // Subscriptions.
248        assert_eq!(Opcode::SubscribeReq.as_u16(), 0x0030);
249        assert_eq!(Opcode::SubscribeEvent.as_u16(), 0x00B0);
250        assert_eq!(Opcode::UnsubscribeReq.as_u16(), 0x0031);
251        assert_eq!(Opcode::UnsubscribeResp.as_u16(), 0x00B1);
252
253        // Transactions.
254        assert_eq!(Opcode::TxnBegin.as_u16(), 0x0040);
255        assert_eq!(Opcode::TxnBeginResp.as_u16(), 0x00C0);
256        assert_eq!(Opcode::TxnCommit.as_u16(), 0x0041);
257        assert_eq!(Opcode::TxnCommitResp.as_u16(), 0x00C1);
258        assert_eq!(Opcode::TxnAbort.as_u16(), 0x0042);
259        assert_eq!(Opcode::TxnAbortResp.as_u16(), 0x00C2);
260
261        // Read-side typed-graph + capability ops.
262        assert_eq!(Opcode::GetCapabilitiesReq.as_u16(), 0x0032);
263        assert_eq!(Opcode::GetCapabilitiesResp.as_u16(), 0x00B2);
264        assert_eq!(Opcode::SchemaGetReq.as_u16(), 0x0121);
265        assert_eq!(Opcode::SchemaGetResp.as_u16(), 0x01A1);
266        assert_eq!(Opcode::SchemaListReq.as_u16(), 0x0122);
267        assert_eq!(Opcode::SchemaListResp.as_u16(), 0x01A2);
268        assert_eq!(Opcode::SchemaValidateReq.as_u16(), 0x0123);
269        assert_eq!(Opcode::SchemaValidateResp.as_u16(), 0x01A3);
270        assert_eq!(Opcode::ExtractorListReq.as_u16(), 0x0124);
271        assert_eq!(Opcode::ExtractorListResp.as_u16(), 0x01A4);
272        assert_eq!(Opcode::EntityGetReq.as_u16(), 0x0131);
273        assert_eq!(Opcode::EntityGetResp.as_u16(), 0x01B1);
274        assert_eq!(Opcode::EntityResolveReq.as_u16(), 0x0136);
275        assert_eq!(Opcode::EntityResolveResp.as_u16(), 0x01B6);
276        assert_eq!(Opcode::EntityListReq.as_u16(), 0x0137);
277        assert_eq!(Opcode::EntityListResp.as_u16(), 0x01B7);
278        assert_eq!(Opcode::StatementGetReq.as_u16(), 0x0141);
279        assert_eq!(Opcode::StatementGetResp.as_u16(), 0x01C1);
280        assert_eq!(Opcode::StatementListReq.as_u16(), 0x0146);
281        assert_eq!(Opcode::StatementListResp.as_u16(), 0x01C6);
282        assert_eq!(Opcode::RelationListFromReq.as_u16(), 0x0154);
283        assert_eq!(Opcode::RelationListFromResp.as_u16(), 0x01D4);
284        assert_eq!(Opcode::RelationListToReq.as_u16(), 0x0155);
285        assert_eq!(Opcode::RelationListToResp.as_u16(), 0x01D5);
286    }
287}