docs(protocol): state at PROTOCOL_VERSION when it moves

`CONTROL_VERSION` carries a long comment on what it is and what happened the
time it did not move. `PROTOCOL_VERSION` had none at all, and the rule for it
is not the obvious one: adding a `#[serde(default)]` field deliberately does
*not* bump it, because this number gates the remote handshake and bumping
would turn away every older `tty7-server` over a field it could safely
ignore.

That reasoning existed, twice, but only as asides — on
`AuthPromptKind::KeyPassphrase::rejected` four hundred lines down, and again
in the test that pins both directions of it. Someone changing a message reads
the constant, not the field that once raised the question.

So it is said where the decision gets made: additive-with-default does not
move it, removing or renaming or retyping a field does, and a new variant
depends on whether the sender can know the peer is new — if it cannot, bump.
No behaviour change.
This commit is contained in:
l0ng-ai
2026-08-23 03:58:05 +08:00
parent 9ca4b27ec9
commit 7368872e04
+20
View File
@@ -5,6 +5,26 @@ use serde::{Deserialize, Serialize};
pub const MAX_FRAME: usize = 64 * 1024 * 1024;
/// The pane dialect GUI↔daemon and GUI↔remote `tty7-server` speak.
///
/// When to move it, because the answer is not "whenever a message changes"
/// and the two worked examples are buried far below:
///
/// Adding a field with `#[serde(default)]` does **not** move it. serde ignores
/// fields it does not know and fills in the ones it is not sent, so a peer on
/// either side of the change reads the message fine — and this number gates the
/// remote handshake, so bumping would turn away every older `tty7-server` over
/// a field it could safely ignore. `AuthPromptKind::KeyPassphrase::rejected`
/// is that case, with a test pinning both directions.
///
/// Removing a field, renaming one, changing its type, retagging an enum, or
/// changing what a message *means* does move it. Those a peer cannot read
/// past, and the handshake is the only place it can say so — better a refusal
/// naming the version than a link that connects and then misbehaves.
///
/// A new message variant sits between the two: an old peer will not send it
/// and will fail to decode it, so whether it needs a bump depends on whether
/// the sender knows the peer is new. If it cannot know, bump.
pub const PROTOCOL_VERSION: u32 = 5;
pub const FEATURE_PANE_OWNER: &str = "pane-owner";