1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
//! **The version preface** (yog's `docs/REMOTE.md` §3): *"each end writes one
//! frame, `{"protocol": <integer>}`, before it reads the peer's."* Both write
//! before either reads, so neither waits on the other and there is no ordering
//! rule to remember.
//!
//! **This is why the seat exists as a separate program and it is not
//! decoration.** Until the four-component split one crate shipped both ends of
//! every connection and the wire could not skew. A seat is installed on the
//! operator's own laptop or phone and upgraded on that device's schedule,
//! while the engine it dials is upgraded on the server's — so the day the two
//! disagree about what a frame means is a day that will arrive, and it must
//! arrive as a sentence rather than as a gesture answered wrongly.
//!
//! **The seat writes and confirms; it never admits.** A seat dials and is
//! never dialled, so there is exactly one half of the exchange here. The
//! engine's half — refusing a peer in band on the connection it opened — is
//! the server's, and a seat that carried it would be a seat that listens.
//!
//! **The frame carries a second key and it can refuse nothing** (REMOTE §3.2).
//! `protocol` is now a MAJOR — it moves only on a break, and additions ship
//! under it stamped with an EDITION instead — so each end states what it can
//! SPELL beside what it must AGREE about. The major is answered by equality;
//! the edition is answered by [`super::edition::spells`], which greys one
//! control rather than refusing one connection. An end that states no edition
//! is at the floor, which is the least an engine of this major can be.
//!
//! **A mismatch is fail-closed and the refusal names both versions**, which is
//! REMOTE §3's requirement rather than a nicety: the sentence *is* the upgrade
//! prompt, so it must name a number an operator can act on. There is no
//! negotiation, no version list and no compat shim — negotiation is the
//! mechanism that makes every later version carry every earlier one's shape
//! forever, and the operator who installed both ends can upgrade the older one.
use ;
use json;
use ;
/// **The per-bump ledger and the constant it re-exports** (bl-c515). Split out
/// because the two grow for different reasons: this file is what the preface
/// DOES and has not changed in five versions, and that one is the record of
/// every version it has carried — one entry longer after every bump, forever.
pub use PROTOCOL;
/// The preface's discriminating key: the MAJOR, and the whole of what a
/// mismatch refuses on.
const KEY: &str = "protocol";
/// The preface's second key: what each end can SPELL (yog's `docs/REMOTE.md`
/// §3.2, [`edition`]).
///
/// **It never refuses anything.** The major is the compatibility question and
/// it is answered by strict equality; the edition is a capability question and
/// it is answered by greying one control. An end that states no edition is at
/// the [`edition::FLOOR`] — every path of this major stamped at or below it is
/// required, so the floor is not a guess, it is the least an engine of this
/// major can be.
const EDITION: &str = "edition";
/// What a peer that stated no version is called in the sentence. An unversioned
/// build, a frame that is not an object, a frame without the key and a
/// terminator where a preface belongs are one case on purpose: none of them can
/// be served, and four sentences for one outcome is four sentences.
///
/// **A peer this end could not read at all is no longer among them** (bl-3969).
/// It was, and the collapse was right about the sentence and wrong about the
/// recovery: the other four are a peer speaking, so nothing crossed, where an
/// unreadable preface is a broken connection with this end's request already on
/// it. See [`confirm`] — the sentence is still one per outcome; there are now
/// two outcomes.
const UNSTATED: &str = "no version";
/// Write this build's preface. Called before this end reads, which is what
/// makes the exchange deadlock-free without an ordering rule.
/// Read the engine's preface, refuse a mismatch — as the one [`Reach`] every
/// other thing that can go wrong with this transport already arrives as, so
/// nothing above here carries a case for it — and answer what the engine can
/// SPELL.
///
/// **The classification splits where the four collapsed cases do not.** A peer
/// that STATED something — another version, a frame that is not an object, a
/// frame without the key, a terminator where a preface belongs — refused this
/// end before adjudicating anything (REMOTE §3: a request of a version this
/// build does not speak *"is never adjudicated"*), so nothing crossed and one
/// sentence still serves all four. A preface this end could not READ is the
/// fifth case and is not about a version at all: the request went out in the
/// same breath as this end's preface, so the connection broke with the gesture
/// already at the far end and an act on it is IN DOUBT (REMOTE §3, bl-3969). It
/// says so in the transport's own words rather than borrowing a sentence about
/// a number nobody stated.
/// **What the engine can spell**, off a preface this end has already agreed
/// the major of.
///
/// Absent, unstated and out of range are one answer — [`edition::FLOOR`] — and
/// they are one answer because they are one fact: an engine of this major that
/// said nothing about editions is an engine of this major, and this major
/// requires every path at or below the floor. There is nothing here to refuse
/// on, which is the whole difference between the two keys.
/// The refusal: both versions, and what to do about it.