docs(broker): describe packages by current behaviour
- commit
- fa913e1a71494d3346b79d8e3dcf0974c71ff9ca
- author
- brice · · 2026-09-23 12:28 UTC
- parent
- ce90900
- signature
- GPG Verified
CD88F9E564E0102646FB6077A1A07C7C7C3E349D· arch-gpg Verified for the committer email
82 files · +177 -445
M internal/adapters/brokerconfig/config.go +3 -3
| @@ -1,5 +1,5 @@ | |||
| 1 | 1 | // Package brokerconfig owns the strict, isolated offline broker sandbox | |
| 2 | - | // configuration (Plan 001 P3.4 slice C). | |
| 2 | + | // configuration. | |
| 3 | 3 | // | |
| 4 | 4 | // It is deliberately not production composition: nothing in internal/app or | |
| 5 | 5 | // main consults it for ordinary daemon operation. It resolves one caller- | |
| @@ -236,7 +236,7 @@ type Registration struct { | |||
| 236 | 236 | } | |
| 237 | 237 | ||
| 238 | 238 | // LocalBinding is the broker-owned binding for the broker's own machine | |
| 239 | - | // daemon (Plan 001 P5.3a). Unlike a remote Registration it carries no | |
| 239 | + | // daemon. Unlike a remote Registration it carries no | |
| 240 | 240 | // registration: the local daemon is not a configured host, so a local stream | |
| 241 | 241 | // request is fenced only against this binding's identity, policy, and route. | |
| 242 | 242 | // The identity and policy are authoritative here and are the exact source of | |
| @@ -260,7 +260,7 @@ type LocalBinding struct { | |||
| 260 | 260 | } | |
| 261 | 261 | ||
| 262 | 262 | // pooledIdentity is the exact (authenticated identity, policy) pair the broker | |
| 263 | - | // pool keys one physical transport by. The pool deliberately ignores the opaque | |
| 263 | + | // pool keys one physical transport by the exact identity and policy pair. The pool deliberately ignores the opaque | |
| 264 | 264 | // route address, so two registrations that share a pair share one pooled | |
| 265 | 265 | // transport and must therefore agree on the single route that transport dials. | |
| 266 | 266 | type pooledIdentity struct { | |
| @@ -1,5 +1,5 @@ | |||||
| 1 | // Package brokerconfig owns the strict, isolated offline broker sandbox | 1 | // Package brokerconfig owns the strict, isolated offline broker sandbox | ||
| 2 | - | // configuration (Plan 001 P3.4 slice C). | 2 | + | // configuration. |
| 3 | // | 3 | // | ||
| 4 | // It is deliberately not production composition: nothing in internal/app or | 4 | // It is deliberately not production composition: nothing in internal/app or | ||
| 5 | // main consults it for ordinary daemon operation. It resolves one caller- | 5 | // main consults it for ordinary daemon operation. It resolves one caller- | ||
| @@ -236,7 +236,7 @@ type Registration struct { | |||||
| 236 | } | 236 | } | ||
| 237 | 237 | ||||
| 238 | // LocalBinding is the broker-owned binding for the broker's own machine | 238 | // LocalBinding is the broker-owned binding for the broker's own machine | ||
| 239 | - | // daemon (Plan 001 P5.3a). Unlike a remote Registration it carries no | 239 | + | // daemon. Unlike a remote Registration it carries no |
| 240 | // registration: the local daemon is not a configured host, so a local stream | 240 | // registration: the local daemon is not a configured host, so a local stream | ||
| 241 | // request is fenced only against this binding's identity, policy, and route. | 241 | // request is fenced only against this binding's identity, policy, and route. | ||
| 242 | // The identity and policy are authoritative here and are the exact source of | 242 | // The identity and policy are authoritative here and are the exact source of | ||
| @@ -260,7 +260,7 @@ type LocalBinding struct { | |||||
| 260 | } | 260 | } | ||
| 261 | 261 | ||||
| 262 | // pooledIdentity is the exact (authenticated identity, policy) pair the broker | 262 | // pooledIdentity is the exact (authenticated identity, policy) pair the broker | ||
| 263 | - | // pool keys one physical transport by. The pool deliberately ignores the opaque | 263 | + | // pool keys one physical transport by the exact identity and policy pair. The pool deliberately ignores the opaque |
| 264 | // route address, so two registrations that share a pair share one pooled | 264 | // route address, so two registrations that share a pair share one pooled | ||
| 265 | // transport and must therefore agree on the single route that transport dials. | 265 | // transport and must therefore agree on the single route that transport dials. | ||
| 266 | type pooledIdentity struct { | 266 | type pooledIdentity struct { | ||
M internal/adapters/brokerconfig/route.go +1 -1
| @@ -18,7 +18,7 @@ import ( | |||
| 18 | 18 | "github.com/bnema/vev/internal/ports" | |
| 19 | 19 | ) | |
| 20 | 20 | ||
| 21 | - | // Bounded route variants (Plan 001 P3.4 slice E). | |
| 21 | + | // Bounded route variants. | |
| 22 | 22 | // | |
| 23 | 23 | // A registration's route is the transport the offline broker dials for that | |
| 24 | 24 | // endpoint. It is an explicit, bounded tagged union, never a caller-supplied | |
| @@ -18,7 +18,7 @@ import ( | |||||
| 18 | "github.com/bnema/vev/internal/ports" | 18 | "github.com/bnema/vev/internal/ports" | ||
| 19 | ) | 19 | ) | ||
| 20 | 20 | ||||
| 21 | - | // Bounded route variants (Plan 001 P3.4 slice E). | 21 | + | // Bounded route variants. |
| 22 | // | 22 | // | ||
| 23 | // A registration's route is the transport the offline broker dials for that | 23 | // A registration's route is the transport the offline broker dials for that | ||
| 24 | // endpoint. It is an explicit, bounded tagged union, never a caller-supplied | 24 | // endpoint. It is an explicit, bounded tagged union, never a caller-supplied | ||
M internal/adapters/brokeripc/client.go +2 -2
| @@ -14,9 +14,9 @@ import ( | |||
| 14 | 14 | "github.com/bnema/vev/internal/protocol/wire" | |
| 15 | 15 | ) | |
| 16 | 16 | ||
| 17 | - | // Broker IPC client (P3.3). | |
| 17 | + | // Broker IPC client. | |
| 18 | 18 | // | |
| 19 | - | // Dial connects to one per-user broker endpoint through the P3.2 private IPC | |
| 19 | + | // Dial connects to one per-user broker endpoint through the private IPC | |
| 20 | 20 | // carriage (same-user kernel peer credentials on dial), completes the broker | |
| 21 | 21 | // preamble, sends exactly one Register, adopts the scope the listener assigned | |
| 22 | 22 | // in the Registered answer, and then runs one reader for the connection. The | |
| @@ -14,9 +14,9 @@ import ( | |||||
| 14 | "github.com/bnema/vev/internal/protocol/wire" | 14 | "github.com/bnema/vev/internal/protocol/wire" | ||
| 15 | ) | 15 | ) | ||
| 16 | 16 | ||||
| 17 | - | // Broker IPC client (P3.3). | 17 | + | // Broker IPC client. |
| 18 | // | 18 | // | ||
| 19 | - | // Dial connects to one per-user broker endpoint through the P3.2 private IPC | 19 | + | // Dial connects to one per-user broker endpoint through the private IPC |
| 20 | // carriage (same-user kernel peer credentials on dial), completes the broker | 20 | // carriage (same-user kernel peer credentials on dial), completes the broker | ||
| 21 | // preamble, sends exactly one Register, adopts the scope the listener assigned | 21 | // preamble, sends exactly one Register, adopts the scope the listener assigned | ||
| 22 | // in the Registered answer, and then runs one reader for the connection. The | 22 | // in the Registered answer, and then runs one reader for the connection. The | ||
M internal/adapters/brokeripc/doc.go +12 -57
| @@ -1,58 +1,13 @@ | |||
| 1 | - | // Package brokeripc is the Plan 001 P3.3 private local broker IPC adapter. | |
| 2 | - | // | |
| 3 | - | // It exposes the client and server halves of one per-user Unix endpoint: a | |
| 4 | - | // client adapter that implements ports.BrokerService over the brokerwire | |
| 5 | - | // conversation, and a listener adapter that implements ports.BrokerListener by | |
| 6 | - | // accepting same-user client connections and running one brokerwire session per | |
| 7 | - | // accepted connection. The wire contract is exactly P3.1's brokerwire preamble | |
| 8 | - | // and directional codec over the shared streamframe carriage; this package adds | |
| 9 | - | // no message, tag, or preamble of its own. | |
| 10 | - | // | |
| 11 | - | // The carriage itself is the P3.2 private AF_UNIX carriage in | |
| 12 | - | // internal/adapters/ipc: the endpoint lives in an owner-only (0700) directory | |
| 13 | - | // created or validated by pkg/safedir.EnsurePrivate, the bound socket is | |
| 14 | - | // tightened to 0600, a stale socket left by a dead owner is recovered | |
| 15 | - | // race-safely, a live owner is reported instead of evicted, and a path that is | |
| 16 | - | // not a socket is refused without being removed. Both accept and dial verify | |
| 17 | - | // the connected peer's kernel credentials (SO_PEERCRED on Linux) and fail | |
| 18 | - | // closed on a platform or build without that check, so no admission decision | |
| 19 | - | // rests on filesystem permissions or an X11-style "the directory is private" | |
| 20 | - | // assumption. | |
| 21 | - | // | |
| 22 | - | // One endpoint is one brokerwire conversation. The server assigns the | |
| 23 | - | // connection scope at accept, answers the preamble with the negotiated | |
| 24 | - | // ceilings, and waits for exactly one Register before admitting subscription, | |
| 25 | - | // operation, or stream work; every later frame must carry the assigned epoch | |
| 26 | - | // and connection identity or it is refused as stale without touching session | |
| 27 | - | // state. Setup is fully bounded on both halves. The client dialer bounds the | |
| 28 | - | // Unix dial, the preamble exchange, the Register send, and the wait for | |
| 29 | - | // Registered with one context/deadline; a context cannot interrupt blocking | |
| 30 | - | // framing I/O, so a setup step closes the carriage on expiry and joins its | |
| 31 | - | // worker, which is what stops a peer that stalls after a successful preamble, | |
| 32 | - | // and a connection that registered detaches from the setup context. Symmetrically | |
| 33 | - | // the server requires the client's Register within the same accept-time | |
| 34 | - | // handshake budget that bounded the preamble and admission, so a same-user peer | |
| 35 | - | // cannot complete the preamble, take an admitted core lease, and then hold that | |
| 36 | - | // lease and its listener slot indefinitely by staying silent. Bounds are | |
| 37 | - | // explicit: accepted clients are capped per listener, stream | |
| 38 | - | // inbound queues are bounded per stream, pending operations are capped per | |
| 39 | - | // connection, and the brokerwire per-connection trackers bound streams and | |
| 40 | - | // completed-operation dedup. Every accepted connection owns its own reader, | |
| 41 | - | // publisher, and stream relays, so a slow or stalled client blocks only its own | |
| 42 | - | // connection. | |
| 43 | - | // | |
| 44 | - | // A malformed or oversize outer envelope, a wrong-direction payload, and a | |
| 45 | - | // frame for an identity that was never allocated are protocol violations and | |
| 46 | - | // settle that connection alone. Disconnect cleanup is deterministic: the | |
| 47 | - | // session cancels its context, terminates every bridged stream against the | |
| 48 | - | // admitted broker service, closes the carriage, and joins every worker before | |
| 49 | - | // Close returns. | |
| 50 | - | // | |
| 51 | - | // Like the brokerwire codec (P3.1) and the daemonmux carriage (P3.2), this | |
| 52 | - | // adapter is not activated by production composition: no ordinary command, | |
| 53 | - | // path, or factory constructs it. P3.4 composes the broker use case, its | |
| 54 | - | // stores, and this listener behind the hidden `_broker-serve` sandbox entry | |
| 55 | - | // point, and slice D adds the hidden `_broker-launcher` and `_broker-status` | |
| 56 | - | // detached connect-or-spawn helpers over the same private root; P7 performs the | |
| 57 | - | // coordinated production cutover. | |
| 1 | + | // Package brokeripc adapts the per-user broker service to private Unix IPC. | |
| 2 | + | // | |
| 3 | + | // The client and listener exchange brokerwire messages over a shared framed | |
| 4 | + | // carriage. Each endpoint admits only same-user peers: the socket resides in | |
| 5 | + | // an owner-only directory, is restricted to mode 0600, and both dial and accept | |
| 6 | + | // verify kernel peer credentials. A live socket owner is never evicted. | |
| 7 | + | // | |
| 8 | + | // Each accepted connection has its own epoch, identity, bounded handshake, | |
| 9 | + | // queues, operation tracking, and stream relays. Frames with stale identities | |
| 10 | + | // are refused without touching broker state; malformed envelopes terminate | |
| 11 | + | // only their own connection. Disconnect closes bridged streams and joins all | |
| 12 | + | // workers before returning. | |
| 58 | 13 | package brokeripc | |
| @@ -1,58 +1,13 @@ | |||||
| 1 | - | // Package brokeripc is the Plan 001 P3.3 private local broker IPC adapter. | 1 | + | // Package brokeripc adapts the per-user broker service to private Unix IPC. |
| 2 | - | // | 2 | + | // |
| 3 | - | // It exposes the client and server halves of one per-user Unix endpoint: a | 3 | + | // The client and listener exchange brokerwire messages over a shared framed |
| 4 | - | // client adapter that implements ports.BrokerService over the brokerwire | 4 | + | // carriage. Each endpoint admits only same-user peers: the socket resides in |
| 5 | - | // conversation, and a listener adapter that implements ports.BrokerListener by | 5 | + | // an owner-only directory, is restricted to mode 0600, and both dial and accept |
| 6 | - | // accepting same-user client connections and running one brokerwire session per | 6 | + | // verify kernel peer credentials. A live socket owner is never evicted. |
| 7 | - | // accepted connection. The wire contract is exactly P3.1's brokerwire preamble | 7 | + | // |
| 8 | - | // and directional codec over the shared streamframe carriage; this package adds | 8 | + | // Each accepted connection has its own epoch, identity, bounded handshake, |
| 9 | - | // no message, tag, or preamble of its own. | 9 | + | // queues, operation tracking, and stream relays. Frames with stale identities |
| 10 | - | // | 10 | + | // are refused without touching broker state; malformed envelopes terminate |
| 11 | - | // The carriage itself is the P3.2 private AF_UNIX carriage in | 11 | + | // only their own connection. Disconnect closes bridged streams and joins all |
| 12 | - | // internal/adapters/ipc: the endpoint lives in an owner-only (0700) directory | 12 | + | // workers before returning. |
| 13 | - | // created or validated by pkg/safedir.EnsurePrivate, the bound socket is | |||
| 14 | - | // tightened to 0600, a stale socket left by a dead owner is recovered | |||
| 15 | - | // race-safely, a live owner is reported instead of evicted, and a path that is | |||
| 16 | - | // not a socket is refused without being removed. Both accept and dial verify | |||
| 17 | - | // the connected peer's kernel credentials (SO_PEERCRED on Linux) and fail | |||
| 18 | - | // closed on a platform or build without that check, so no admission decision | |||
| 19 | - | // rests on filesystem permissions or an X11-style "the directory is private" | |||
| 20 | - | // assumption. | |||
| 21 | - | // | |||
| 22 | - | // One endpoint is one brokerwire conversation. The server assigns the | |||
| 23 | - | // connection scope at accept, answers the preamble with the negotiated | |||
| 24 | - | // ceilings, and waits for exactly one Register before admitting subscription, | |||
| 25 | - | // operation, or stream work; every later frame must carry the assigned epoch | |||
| 26 | - | // and connection identity or it is refused as stale without touching session | |||
| 27 | - | // state. Setup is fully bounded on both halves. The client dialer bounds the | |||
| 28 | - | // Unix dial, the preamble exchange, the Register send, and the wait for | |||
| 29 | - | // Registered with one context/deadline; a context cannot interrupt blocking | |||
| 30 | - | // framing I/O, so a setup step closes the carriage on expiry and joins its | |||
| 31 | - | // worker, which is what stops a peer that stalls after a successful preamble, | |||
| 32 | - | // and a connection that registered detaches from the setup context. Symmetrically | |||
| 33 | - | // the server requires the client's Register within the same accept-time | |||
| 34 | - | // handshake budget that bounded the preamble and admission, so a same-user peer | |||
| 35 | - | // cannot complete the preamble, take an admitted core lease, and then hold that | |||
| 36 | - | // lease and its listener slot indefinitely by staying silent. Bounds are | |||
| 37 | - | // explicit: accepted clients are capped per listener, stream | |||
| 38 | - | // inbound queues are bounded per stream, pending operations are capped per | |||
| 39 | - | // connection, and the brokerwire per-connection trackers bound streams and | |||
| 40 | - | // completed-operation dedup. Every accepted connection owns its own reader, | |||
| 41 | - | // publisher, and stream relays, so a slow or stalled client blocks only its own | |||
| 42 | - | // connection. | |||
| 43 | - | // | |||
| 44 | - | // A malformed or oversize outer envelope, a wrong-direction payload, and a | |||
| 45 | - | // frame for an identity that was never allocated are protocol violations and | |||
| 46 | - | // settle that connection alone. Disconnect cleanup is deterministic: the | |||
| 47 | - | // session cancels its context, terminates every bridged stream against the | |||
| 48 | - | // admitted broker service, closes the carriage, and joins every worker before | |||
| 49 | - | // Close returns. | |||
| 50 | - | // | |||
| 51 | - | // Like the brokerwire codec (P3.1) and the daemonmux carriage (P3.2), this | |||
| 52 | - | // adapter is not activated by production composition: no ordinary command, | |||
| 53 | - | // path, or factory constructs it. P3.4 composes the broker use case, its | |||
| 54 | - | // stores, and this listener behind the hidden `_broker-serve` sandbox entry | |||
| 55 | - | // point, and slice D adds the hidden `_broker-launcher` and `_broker-status` | |||
| 56 | - | // detached connect-or-spawn helpers over the same private root; P7 performs the | |||
| 57 | - | // coordinated production cutover. | |||
| 58 | package brokeripc | 13 | package brokeripc | ||
M internal/adapters/brokeripc/emit.go +2 -2
| @@ -8,9 +8,9 @@ import ( | |||
| 8 | 8 | "github.com/bnema/vev/internal/protocol/catalogue" | |
| 9 | 9 | ) | |
| 10 | 10 | ||
| 11 | - | // Snapshot publication (P3.3). | |
| 11 | + | // Snapshot publication. | |
| 12 | 12 | // | |
| 13 | - | // A broker publication travels as the exact multipart transfer the P3.1 | |
| 13 | + | // A broker publication travels as the exact multipart transfer the brokerwire | |
| 14 | 14 | // assembler accepts: Begin(index 0, element counts), then every daemon part in | |
| 15 | 15 | // daemon-index order immediately followed by that daemon's session parts in | |
| 16 | 16 | // session-index order, then the tombstones, then End at the final index. The | |
| @@ -8,9 +8,9 @@ import ( | |||||
| 8 | "github.com/bnema/vev/internal/protocol/catalogue" | 8 | "github.com/bnema/vev/internal/protocol/catalogue" | ||
| 9 | ) | 9 | ) | ||
| 10 | 10 | ||||
| 11 | - | // Snapshot publication (P3.3). | 11 | + | // Snapshot publication. |
| 12 | // | 12 | // | ||
| 13 | - | // A broker publication travels as the exact multipart transfer the P3.1 | 13 | + | // A broker publication travels as the exact multipart transfer the brokerwire |
| 14 | // assembler accepts: Begin(index 0, element counts), then every daemon part in | 14 | // assembler accepts: Begin(index 0, element counts), then every daemon part in | ||
| 15 | // daemon-index order immediately followed by that daemon's session parts in | 15 | // daemon-index order immediately followed by that daemon's session parts in | ||
| 16 | // session-index order, then the tombstones, then End at the final index. The | 16 | // session-index order, then the tombstones, then End at the final index. The | ||
M internal/adapters/brokeripc/mutation.go +1 -1
| @@ -9,7 +9,7 @@ import ( | |||
| 9 | 9 | "github.com/bnema/vev/internal/ports" | |
| 10 | 10 | ) | |
| 11 | 11 | ||
| 12 | - | // Snapshot publication and mutating operations (P3.3, server side). | |
| 12 | + | // Snapshot publication and mutating operations. | |
| 13 | 13 | // | |
| 14 | 14 | // A Subscribe frame starts one publisher goroutine for exactly that connection | |
| 15 | 15 | // and generation. The publisher waits on the admitted core service's coalescing | |
| @@ -9,7 +9,7 @@ import ( | |||||
| 9 | "github.com/bnema/vev/internal/ports" | 9 | "github.com/bnema/vev/internal/ports" | ||
| 10 | ) | 10 | ) | ||
| 11 | 11 | ||||
| 12 | - | // Snapshot publication and mutating operations (P3.3, server side). | 12 | + | // Snapshot publication and mutating operations. |
| 13 | // | 13 | // | ||
| 14 | // A Subscribe frame starts one publisher goroutine for exactly that connection | 14 | // A Subscribe frame starts one publisher goroutine for exactly that connection | ||
| 15 | // and generation. The publisher waits on the admitted core service's coalescing | 15 | // and generation. The publisher waits on the admitted core service's coalescing | ||
M internal/adapters/brokeripc/preamble.go +1 -1
| @@ -11,7 +11,7 @@ import ( | |||
| 11 | 11 | "github.com/bnema/vev/internal/protocol/wire" | |
| 12 | 12 | ) | |
| 13 | 13 | ||
| 14 | - | // Broker preamble exchange (P3.3). | |
| 14 | + | // Broker preamble exchange. | |
| 15 | 15 | // | |
| 16 | 16 | // The first client frame on a broker connection is always the broker | |
| 17 | 17 | // PreambleRequest (role 3) and the first server frame is always the broker | |
| @@ -11,7 +11,7 @@ import ( | |||||
| 11 | "github.com/bnema/vev/internal/protocol/wire" | 11 | "github.com/bnema/vev/internal/protocol/wire" | ||
| 12 | ) | 12 | ) | ||
| 13 | 13 | ||||
| 14 | - | // Broker preamble exchange (P3.3). | 14 | + | // Broker preamble exchange. |
| 15 | // | 15 | // | ||
| 16 | // The first client frame on a broker connection is always the broker | 16 | // The first client frame on a broker connection is always the broker | ||
| 17 | // PreambleRequest (role 3) and the first server frame is always the broker | 17 | // PreambleRequest (role 3) and the first server frame is always the broker | ||
M internal/adapters/brokeripc/server.go +3 -3
| @@ -19,9 +19,9 @@ import ( | |||
| 19 | 19 | "github.com/bnema/vev/internal/protocol/wire" | |
| 20 | 20 | ) | |
| 21 | 21 | ||
| 22 | - | // Broker IPC listener and per-connection session (P3.3). | |
| 22 | + | // Broker IPC listener and per-connection session. | |
| 23 | 23 | // | |
| 24 | - | // The listener owns one per-user AF_UNIX endpoint through the P3.2 private IPC | |
| 24 | + | // The listener owns one per-user AF_UNIX endpoint through the private IPC | |
| 25 | 25 | // carriage: owner-only directory and 0600 socket, same-user kernel peer | |
| 26 | 26 | // credentials on accept, race-safe stale-socket recovery, foreign-path refusal, | |
| 27 | 27 | // and idempotent Close that unlinks only the socket inode it created. It caps | |
| @@ -49,7 +49,7 @@ import ( | |||
| 49 | 49 | // authority is the ports.BrokerAuthority admission seam: the listener calls | |
| 50 | 50 | // AdmitClient once per accepted connection under the handshake budget and binds | |
| 51 | 51 | // the returned service to exactly that connection. That service's ConnectionID | |
| 52 | - | // is the identity the session stamps on every frame; the P3.4 broker use case | |
| 52 | + | // is the identity the session stamps on every frame; the broker use case | |
| 53 | 53 | // supplies the implementation, and this adapter consumes it without | |
| 54 | 54 | // constructing a broker itself. See ports.BrokerAuthority for the | |
| 55 | 55 | // admission-context contract. | |
| @@ -19,9 +19,9 @@ import ( | |||||
| 19 | "github.com/bnema/vev/internal/protocol/wire" | 19 | "github.com/bnema/vev/internal/protocol/wire" | ||
| 20 | ) | 20 | ) | ||
| 21 | 21 | ||||
| 22 | - | // Broker IPC listener and per-connection session (P3.3). | 22 | + | // Broker IPC listener and per-connection session. |
| 23 | // | 23 | // | ||
| 24 | - | // The listener owns one per-user AF_UNIX endpoint through the P3.2 private IPC | 24 | + | // The listener owns one per-user AF_UNIX endpoint through the private IPC |
| 25 | // carriage: owner-only directory and 0600 socket, same-user kernel peer | 25 | // carriage: owner-only directory and 0600 socket, same-user kernel peer | ||
| 26 | // credentials on accept, race-safe stale-socket recovery, foreign-path refusal, | 26 | // credentials on accept, race-safe stale-socket recovery, foreign-path refusal, | ||
| 27 | // and idempotent Close that unlinks only the socket inode it created. It caps | 27 | // and idempotent Close that unlinks only the socket inode it created. It caps | ||
| @@ -49,7 +49,7 @@ import ( | |||||
| 49 | // authority is the ports.BrokerAuthority admission seam: the listener calls | 49 | // authority is the ports.BrokerAuthority admission seam: the listener calls | ||
| 50 | // AdmitClient once per accepted connection under the handshake budget and binds | 50 | // AdmitClient once per accepted connection under the handshake budget and binds | ||
| 51 | // the returned service to exactly that connection. That service's ConnectionID | 51 | // the returned service to exactly that connection. That service's ConnectionID | ||
| 52 | - | // is the identity the session stamps on every frame; the P3.4 broker use case | 52 | + | // is the identity the session stamps on every frame; the broker use case |
| 53 | // supplies the implementation, and this adapter consumes it without | 53 | // supplies the implementation, and this adapter consumes it without | ||
| 54 | // constructing a broker itself. See ports.BrokerAuthority for the | 54 | // constructing a broker itself. See ports.BrokerAuthority for the | ||
| 55 | // admission-context contract. | 55 | // admission-context contract. | ||
M internal/adapters/brokeripc/stream.go +1 -1
| @@ -11,7 +11,7 @@ import ( | |||
| 11 | 11 | "github.com/bnema/vev/internal/ports" | |
| 12 | 12 | ) | |
| 13 | 13 | ||
| 14 | - | // Logical stream bridging (P3.3). | |
| 14 | + | // Logical stream bridging. | |
| 15 | 15 | // | |
| 16 | 16 | // One brokerwire logical stream carries the typed session protocol between a | |
| 17 | 17 | // client and the daemon behind the broker. The broker terminates both hops: the | |
| @@ -11,7 +11,7 @@ import ( | |||||
| 11 | "github.com/bnema/vev/internal/ports" | 11 | "github.com/bnema/vev/internal/ports" | ||
| 12 | ) | 12 | ) | ||
| 13 | 13 | ||||
| 14 | - | // Logical stream bridging (P3.3). | 14 | + | // Logical stream bridging. |
| 15 | // | 15 | // | ||
| 16 | // One brokerwire logical stream carries the typed session protocol between a | 16 | // One brokerwire logical stream carries the typed session protocol between a | ||
| 17 | // client and the daemon behind the broker. The broker terminates both hops: the | 17 | // client and the daemon behind the broker. The broker terminates both hops: the | ||
M internal/adapters/brokerwire/codec.go +2 -2
| @@ -1,6 +1,6 @@ | |||
| 1 | 1 | package brokerwire | |
| 2 | 2 | ||
| 3 | - | // Directional envelope adaptation (P3.1). | |
| 3 | + | // Directional envelope adaptation. | |
| 4 | 4 | // | |
| 5 | 5 | // EncodeClient wraps one adapter-local client value in its directional | |
| 6 | 6 | // BrokerClientEnvelope; DecodeClient unwraps and validates. EncodeServer | |
| @@ -12,7 +12,7 @@ package brokerwire | |||
| 12 | 12 | // environment/policy, chunks, and snapshot parts. | |
| 13 | 13 | // | |
| 14 | 14 | // The codecs are stateless: no connection state, multipart assembler, | |
| 15 | - | // operation tracker, stream lifecycle, socket, framing pump, or P3.2 | |
| 15 | + | // operation tracker, stream lifecycle, socket, framing pump, or | |
| 16 | 16 | // transport lives here. Envelope sizes ride under the caller's negotiated | |
| 17 | 17 | // ceiling; stream chunks ride under the negotiated chunk ceiling. | |
| 18 | 18 | ||
| @@ -1,6 +1,6 @@ | |||||
| 1 | package brokerwire | 1 | package brokerwire | ||
| 2 | 2 | ||||
| 3 | - | // Directional envelope adaptation (P3.1). | 3 | + | // Directional envelope adaptation. |
| 4 | // | 4 | // | ||
| 5 | // EncodeClient wraps one adapter-local client value in its directional | 5 | // EncodeClient wraps one adapter-local client value in its directional | ||
| 6 | // BrokerClientEnvelope; DecodeClient unwraps and validates. EncodeServer | 6 | // BrokerClientEnvelope; DecodeClient unwraps and validates. EncodeServer | ||
| @@ -12,7 +12,7 @@ package brokerwire | |||||
| 12 | // environment/policy, chunks, and snapshot parts. | 12 | // environment/policy, chunks, and snapshot parts. | ||
| 13 | // | 13 | // | ||
| 14 | // The codecs are stateless: no connection state, multipart assembler, | 14 | // The codecs are stateless: no connection state, multipart assembler, | ||
| 15 | - | // operation tracker, stream lifecycle, socket, framing pump, or P3.2 | 15 | + | // operation tracker, stream lifecycle, socket, framing pump, or |
| 16 | // transport lives here. Envelope sizes ride under the caller's negotiated | 16 | // transport lives here. Envelope sizes ride under the caller's negotiated | ||
| 17 | // ceiling; stream chunks ride under the negotiated chunk ceiling. | 17 | // ceiling; stream chunks ride under the negotiated chunk ceiling. | ||
| 18 | 18 | ||||
M internal/adapters/brokerwire/convert.go +1 -1
| @@ -1,6 +1,6 @@ | |||
| 1 | 1 | package brokerwire | |
| 2 | 2 | ||
| 3 | - | // Shared semantic converters (P3.1). | |
| 3 | + | // Shared semantic converters. | |
| 4 | 4 | // | |
| 5 | 5 | // Conversion mirrors the port, domain, and catalogue types losslessly and | |
| 6 | 6 | // validates every narrowing numeric cast before it happens. Wire uint32 | |
| @@ -1,6 +1,6 @@ | |||||
| 1 | package brokerwire | 1 | package brokerwire | ||
| 2 | 2 | ||||
| 3 | - | // Shared semantic converters (P3.1). | 3 | + | // Shared semantic converters. |
| 4 | // | 4 | // | ||
| 5 | // Conversion mirrors the port, domain, and catalogue types losslessly and | 5 | // Conversion mirrors the port, domain, and catalogue types losslessly and | ||
| 6 | // validates every narrowing numeric cast before it happens. Wire uint32 | 6 | // validates every narrowing numeric cast before it happens. Wire uint32 | ||
M internal/adapters/brokerwire/doc.go +7 -15
| @@ -1,17 +1,9 @@ | |||
| 1 | - | // Package brokerwire adapts typed broker messages to Protobuf envelopes. | |
| 1 | + | // Package brokerwire owns the broker conversation's directional Protobuf codec. | |
| 2 | 2 | // | |
| 3 | - | // The broker is a separate conversation from the session protocol: client | |
| 4 | - | // tags 101-113 and server tags 201-210 are disjoint from every session tag, | |
| 5 | - | // and each direction is its own closed oneof union. Every connection starts | |
| 6 | - | // with the bounded broker preamble (roles 3/4); magic, epoch, exact | |
| 7 | - | // protocol version, and negotiated limits are validated before application | |
| 8 | - | // messages. | |
| 9 | - | // | |
| 10 | - | // This package is stateful only where P3.1 requires it: connection state, | |
| 11 | - | // multipart snapshot assembly, operation tracking, and stream lifecycle | |
| 12 | - | // live in snapshot.go and state.go. EncodeClient/DecodeClient and | |
| 13 | - | // EncodeServer/DecodeServer remain stateless, converting one complete | |
| 14 | - | // serialized envelope at a time using strict wire.ScanEnvelope before | |
| 15 | - | // generated unmarshal. There is no socket, framing pump, or P3.2 transport | |
| 16 | - | // here. | |
| 3 | + | // Client and server envelopes are disjoint closed unions, separate from the | |
| 4 | + | // session protocol. Every connection validates a bounded preamble with exact | |
| 5 | + | // version and role matching before application traffic. The codec strictly | |
| 6 | + | // scans each complete envelope before unmarshalling; connection state tracks | |
| 7 | + | // multipart snapshots, operations, and stream lifecycle. Socket ownership and | |
| 8 | + | // framing pumps belong to the transport adapters, not this package. | |
| 17 | 9 | package brokerwire | |
| @@ -1,17 +1,9 @@ | |||||
| 1 | - | // Package brokerwire adapts typed broker messages to Protobuf envelopes. | 1 | + | // Package brokerwire owns the broker conversation's directional Protobuf codec. |
| 2 | // | 2 | // | ||
| 3 | - | // The broker is a separate conversation from the session protocol: client | 3 | + | // Client and server envelopes are disjoint closed unions, separate from the |
| 4 | - | // tags 101-113 and server tags 201-210 are disjoint from every session tag, | 4 | + | // session protocol. Every connection validates a bounded preamble with exact |
| 5 | - | // and each direction is its own closed oneof union. Every connection starts | 5 | + | // version and role matching before application traffic. The codec strictly |
| 6 | - | // with the bounded broker preamble (roles 3/4); magic, epoch, exact | 6 | + | // scans each complete envelope before unmarshalling; connection state tracks |
| 7 | - | // protocol version, and negotiated limits are validated before application | 7 | + | // multipart snapshots, operations, and stream lifecycle. Socket ownership and |
| 8 | - | // messages. | 8 | + | // framing pumps belong to the transport adapters, not this package. |
| 9 | - | // | |||
| 10 | - | // This package is stateful only where P3.1 requires it: connection state, | |||
| 11 | - | // multipart snapshot assembly, operation tracking, and stream lifecycle | |||
| 12 | - | // live in snapshot.go and state.go. EncodeClient/DecodeClient and | |||
| 13 | - | // EncodeServer/DecodeServer remain stateless, converting one complete | |||
| 14 | - | // serialized envelope at a time using strict wire.ScanEnvelope before | |||
| 15 | - | // generated unmarshal. There is no socket, framing pump, or P3.2 transport | |||
| 16 | - | // here. | |||
| 17 | package brokerwire | 9 | package brokerwire | ||
M internal/adapters/brokerwire/limits.go +2 -2
| @@ -1,6 +1,6 @@ | |||
| 1 | 1 | package brokerwire | |
| 2 | 2 | ||
| 3 | - | // Stateless bound refusals (P3.1). | |
| 3 | + | // Stateless bound refusals. | |
| 4 | 4 | // | |
| 5 | 5 | // The broker preamble negotiates one immutable pair of ceilings per | |
| 6 | 6 | // connection: MaxReceiveEnvelopeBytes bounds every envelope this side | |
| @@ -56,7 +56,7 @@ type Ceilings struct { | |||
| 56 | 56 | } | |
| 57 | 57 | ||
| 58 | 58 | // brokerCeilings is the in-package alias for Ceilings. It exists only so | |
| 59 | - | // P3.1's tests keep their short spelling; production code uses Ceilings. | |
| 59 | + | // The codec tests keep their short spelling; production code uses Ceilings. | |
| 60 | 60 | type brokerCeilings = Ceilings | |
| 61 | 61 | ||
| 62 | 62 | // defaultBrokerCeilings advertises the local broker receive policy: the | |
| @@ -1,6 +1,6 @@ | |||||
| 1 | package brokerwire | 1 | package brokerwire | ||
| 2 | 2 | ||||
| 3 | - | // Stateless bound refusals (P3.1). | 3 | + | // Stateless bound refusals. |
| 4 | // | 4 | // | ||
| 5 | // The broker preamble negotiates one immutable pair of ceilings per | 5 | // The broker preamble negotiates one immutable pair of ceilings per | ||
| 6 | // connection: MaxReceiveEnvelopeBytes bounds every envelope this side | 6 | // connection: MaxReceiveEnvelopeBytes bounds every envelope this side | ||
| @@ -56,7 +56,7 @@ type Ceilings struct { | |||||
| 56 | } | 56 | } | ||
| 57 | 57 | ||||
| 58 | // brokerCeilings is the in-package alias for Ceilings. It exists only so | 58 | // brokerCeilings is the in-package alias for Ceilings. It exists only so | ||
| 59 | - | // P3.1's tests keep their short spelling; production code uses Ceilings. | 59 | + | // The codec tests keep their short spelling; production code uses Ceilings. |
| 60 | type brokerCeilings = Ceilings | 60 | type brokerCeilings = Ceilings | ||
| 61 | 61 | ||||
| 62 | // defaultBrokerCeilings advertises the local broker receive policy: the | 62 | // defaultBrokerCeilings advertises the local broker receive policy: the | ||
M internal/adapters/brokerwire/preamble.go +6 -6
| @@ -1,6 +1,6 @@ | |||
| 1 | 1 | package brokerwire | |
| 2 | 2 | ||
| 3 | - | // Broker preamble (P3.1). | |
| 3 | + | // Broker preamble. | |
| 4 | 4 | // | |
| 5 | 5 | // The first client frame on a broker connection is always PreambleRequest; | |
| 6 | 6 | // the first server frame is always PreambleResponse. The broker reuses the | |
| @@ -8,7 +8,7 @@ package brokerwire | |||
| 8 | 8 | // client, 4 names the broker server. Magic must equal wire.PreambleMagic, | |
| 9 | 9 | // epoch must equal wire.ProtocolEpoch, and version must exactly equal | |
| 10 | 10 | // protocol.Version. Capability bits must be zero: the broker negotiates no | |
| 11 | - | // optional capabilities in P3.1. | |
| 11 | + | // optional capabilities here. | |
| 12 | 12 | // | |
| 13 | 13 | // The preamble negotiates immutable per-connection ceilings once: the | |
| 14 | 14 | // advertised envelope ceiling (1 MiB..16 MiB) rides in | |
| @@ -20,7 +20,7 @@ package brokerwire | |||
| 20 | 20 | // preamble, 7 limit refused. Code 6 is reserved for the connection | |
| 21 | 21 | // dispatcher: out-of-order application frames are a framing-order failure | |
| 22 | 22 | // that this stateless codec never observes. Nonzero capability bits have no | |
| 23 | - | // dedicated code in P3.1 and are refused as code 7 (limit refused), since | |
| 23 | + | // dedicated code and are refused as code 7 (limit refused), since | |
| 24 | 24 | // the broker negotiates no optional capabilities. | |
| 25 | 25 | ||
| 26 | 26 | import ( | |
| @@ -53,7 +53,7 @@ const ( | |||
| 53 | 53 | // owns framing-order detection. The stateless codec never emits it. | |
| 54 | 54 | RejectionOutOfOrder uint32 = 6 | |
| 55 | 55 | // RejectionLimitRefused reports an unnegotiable limit advertisement. It | |
| 56 | - | // also covers nonzero capability bits: P3.1 negotiates no optional | |
| 56 | + | // also covers nonzero capability bits: the protocol negotiates no optional | |
| 57 | 57 | // capabilities, so any capability bit is an unnegotiable advertisement. | |
| 58 | 58 | RejectionLimitRefused uint32 = 7 | |
| 59 | 59 | ) | |
| @@ -172,7 +172,7 @@ func DecodePreambleResponse(message *wire.PreambleResponse) (BrokerPreambleRespo | |||
| 172 | 172 | // RejectionCodeFor maps a preamble validation failure to its precise | |
| 173 | 173 | // refusal code. Limit, magic, epoch, version, and role failures each carry | |
| 174 | 174 | // their own code; nonzero capability bits are refused as | |
| 175 | - | // RejectionLimitRefused because P3.1 negotiates no capabilities; unknown | |
| 175 | + | // RejectionLimitRefused because the protocol negotiates no capabilities; unknown | |
| 176 | 176 | // scan failures are limit refusals. Code 6 is never returned here: the | |
| 177 | 177 | // dispatcher owns out-of-order framing. | |
| 178 | 178 | func RejectionCodeFor(request *wire.PreambleRequest, err error) uint32 { | |
| @@ -193,7 +193,7 @@ func RejectionCodeFor(request *wire.PreambleRequest, err error) uint32 { | |||
| 193 | 193 | return RejectionWrongRole | |
| 194 | 194 | } | |
| 195 | 195 | if request.GetCapabilityBits() != 0 { | |
| 196 | - | // No capability is negotiable in P3.1, so any bit is a refused | |
| 196 | + | // No capability is negotiable here, so any bit is a refused | |
| 197 | 197 | // limit advertisement (code 7), documented explicitly. | |
| 198 | 198 | return RejectionLimitRefused | |
| 199 | 199 | } | |
| @@ -1,6 +1,6 @@ | |||||
| 1 | package brokerwire | 1 | package brokerwire | ||
| 2 | 2 | ||||
| 3 | - | // Broker preamble (P3.1). | 3 | + | // Broker preamble. |
| 4 | // | 4 | // | ||
| 5 | // The first client frame on a broker connection is always PreambleRequest; | 5 | // The first client frame on a broker connection is always PreambleRequest; | ||
| 6 | // the first server frame is always PreambleResponse. The broker reuses the | 6 | // the first server frame is always PreambleResponse. The broker reuses the | ||
| @@ -8,7 +8,7 @@ package brokerwire | |||||
| 8 | // client, 4 names the broker server. Magic must equal wire.PreambleMagic, | 8 | // client, 4 names the broker server. Magic must equal wire.PreambleMagic, | ||
| 9 | // epoch must equal wire.ProtocolEpoch, and version must exactly equal | 9 | // epoch must equal wire.ProtocolEpoch, and version must exactly equal | ||
| 10 | // protocol.Version. Capability bits must be zero: the broker negotiates no | 10 | // protocol.Version. Capability bits must be zero: the broker negotiates no | ||
| 11 | - | // optional capabilities in P3.1. | 11 | + | // optional capabilities here. |
| 12 | // | 12 | // | ||
| 13 | // The preamble negotiates immutable per-connection ceilings once: the | 13 | // The preamble negotiates immutable per-connection ceilings once: the | ||
| 14 | // advertised envelope ceiling (1 MiB..16 MiB) rides in | 14 | // advertised envelope ceiling (1 MiB..16 MiB) rides in | ||
| @@ -20,7 +20,7 @@ package brokerwire | |||||
| 20 | // preamble, 7 limit refused. Code 6 is reserved for the connection | 20 | // preamble, 7 limit refused. Code 6 is reserved for the connection | ||
| 21 | // dispatcher: out-of-order application frames are a framing-order failure | 21 | // dispatcher: out-of-order application frames are a framing-order failure | ||
| 22 | // that this stateless codec never observes. Nonzero capability bits have no | 22 | // that this stateless codec never observes. Nonzero capability bits have no | ||
| 23 | - | // dedicated code in P3.1 and are refused as code 7 (limit refused), since | 23 | + | // dedicated code and are refused as code 7 (limit refused), since |
| 24 | // the broker negotiates no optional capabilities. | 24 | // the broker negotiates no optional capabilities. | ||
| 25 | 25 | ||||
| 26 | import ( | 26 | import ( | ||
| @@ -53,7 +53,7 @@ const ( | |||||
| 53 | // owns framing-order detection. The stateless codec never emits it. | 53 | // owns framing-order detection. The stateless codec never emits it. | ||
| 54 | RejectionOutOfOrder uint32 = 6 | 54 | RejectionOutOfOrder uint32 = 6 | ||
| 55 | // RejectionLimitRefused reports an unnegotiable limit advertisement. It | 55 | // RejectionLimitRefused reports an unnegotiable limit advertisement. It | ||
| 56 | - | // also covers nonzero capability bits: P3.1 negotiates no optional | 56 | + | // also covers nonzero capability bits: the protocol negotiates no optional |
| 57 | // capabilities, so any capability bit is an unnegotiable advertisement. | 57 | // capabilities, so any capability bit is an unnegotiable advertisement. | ||
| 58 | RejectionLimitRefused uint32 = 7 | 58 | RejectionLimitRefused uint32 = 7 | ||
| 59 | ) | 59 | ) | ||
| @@ -172,7 +172,7 @@ func DecodePreambleResponse(message *wire.PreambleResponse) (BrokerPreambleRespo | |||||
| 172 | // RejectionCodeFor maps a preamble validation failure to its precise | 172 | // RejectionCodeFor maps a preamble validation failure to its precise | ||
| 173 | // refusal code. Limit, magic, epoch, version, and role failures each carry | 173 | // refusal code. Limit, magic, epoch, version, and role failures each carry | ||
| 174 | // their own code; nonzero capability bits are refused as | 174 | // their own code; nonzero capability bits are refused as | ||
| 175 | - | // RejectionLimitRefused because P3.1 negotiates no capabilities; unknown | 175 | + | // RejectionLimitRefused because the protocol negotiates no capabilities; unknown |
| 176 | // scan failures are limit refusals. Code 6 is never returned here: the | 176 | // scan failures are limit refusals. Code 6 is never returned here: the | ||
| 177 | // dispatcher owns out-of-order framing. | 177 | // dispatcher owns out-of-order framing. | ||
| 178 | func RejectionCodeFor(request *wire.PreambleRequest, err error) uint32 { | 178 | func RejectionCodeFor(request *wire.PreambleRequest, err error) uint32 { | ||
| @@ -193,7 +193,7 @@ func RejectionCodeFor(request *wire.PreambleRequest, err error) uint32 { | |||||
| 193 | return RejectionWrongRole | 193 | return RejectionWrongRole | ||
| 194 | } | 194 | } | ||
| 195 | if request.GetCapabilityBits() != 0 { | 195 | if request.GetCapabilityBits() != 0 { | ||
| 196 | - | // No capability is negotiable in P3.1, so any bit is a refused | 196 | + | // No capability is negotiable here, so any bit is a refused |
| 197 | // limit advertisement (code 7), documented explicitly. | 197 | // limit advertisement (code 7), documented explicitly. | ||
| 198 | return RejectionLimitRefused | 198 | return RejectionLimitRefused | ||
| 199 | } | 199 | } | ||
M internal/adapters/brokerwire/snapshot.go +2 -2
| @@ -1,4 +1,4 @@ | |||
| 1 | - | // Stateful multipart snapshot assembly (P3.1). | |
| 1 | + | // Stateful multipart snapshot assembly. | |
| 2 | 2 | // | |
| 3 | 3 | // SnapshotAssembler stages one multipart SnapshotPart publication and | |
| 4 | 4 | // publishes it atomically only after full validation. It builds on the | |
| @@ -44,7 +44,7 @@ | |||
| 44 | 44 | // transfer is in flight. Scope fencing is exact: every part must carry the | |
| 45 | 45 | // assembler's epoch and connection. | |
| 46 | 46 | // | |
| 47 | - | // There is no I/O, socket, pump, or P3.2 transport here. The owning | |
| 47 | + | // There is no I/O, socket, pump, or transport here. The owning | |
| 48 | 48 | // Connection discards staging on generation advance, unsubscribe, or close. | |
| 49 | 49 | package brokerwire | |
| 50 | 50 | ||
| @@ -1,4 +1,4 @@ | |||||
| 1 | - | // Stateful multipart snapshot assembly (P3.1). | 1 | + | // Stateful multipart snapshot assembly. |
| 2 | // | 2 | // | ||
| 3 | // SnapshotAssembler stages one multipart SnapshotPart publication and | 3 | // SnapshotAssembler stages one multipart SnapshotPart publication and | ||
| 4 | // publishes it atomically only after full validation. It builds on the | 4 | // publishes it atomically only after full validation. It builds on the | ||
| @@ -44,7 +44,7 @@ | |||||
| 44 | // transfer is in flight. Scope fencing is exact: every part must carry the | 44 | // transfer is in flight. Scope fencing is exact: every part must carry the | ||
| 45 | // assembler's epoch and connection. | 45 | // assembler's epoch and connection. | ||
| 46 | // | 46 | // | ||
| 47 | - | // There is no I/O, socket, pump, or P3.2 transport here. The owning | 47 | + | // There is no I/O, socket, pump, or transport here. The owning |
| 48 | // Connection discards staging on generation advance, unsubscribe, or close. | 48 | // Connection discards staging on generation advance, unsubscribe, or close. | ||
| 49 | package brokerwire | 49 | package brokerwire | ||
| 50 | 50 | ||||
M internal/adapters/brokerwire/state.go +2 -2
| @@ -1,4 +1,4 @@ | |||
| 1 | - | // Per-connection broker state (P3.1). | |
| 1 | + | // Per-connection broker state. | |
| 2 | 2 | // | |
| 3 | 3 | // Connection walks one exact lifecycle: New is entered when the listener | |
| 4 | 4 | // assigns the connection scope, one locally validated preamble moves it to | |
| @@ -16,7 +16,7 @@ | |||
| 16 | 16 | // commits. Operation and stream state is scoped to exactly this connection | |
| 17 | 17 | // and epoch. | |
| 18 | 18 | // | |
| 19 | - | // There is no I/O, socket, pump, or P3.2 transport here. | |
| 19 | + | // There is no I/O, socket, pump, or transport here. | |
| 20 | 20 | package brokerwire | |
| 21 | 21 | ||
| 22 | 22 | import ( | |
| @@ -1,4 +1,4 @@ | |||||
| 1 | - | // Per-connection broker state (P3.1). | 1 | + | // Per-connection broker state. |
| 2 | // | 2 | // | ||
| 3 | // Connection walks one exact lifecycle: New is entered when the listener | 3 | // Connection walks one exact lifecycle: New is entered when the listener | ||
| 4 | // assigns the connection scope, one locally validated preamble moves it to | 4 | // assigns the connection scope, one locally validated preamble moves it to | ||
| @@ -16,7 +16,7 @@ | |||||
| 16 | // commits. Operation and stream state is scoped to exactly this connection | 16 | // commits. Operation and stream state is scoped to exactly this connection | ||
| 17 | // and epoch. | 17 | // and epoch. | ||
| 18 | // | 18 | // | ||
| 19 | - | // There is no I/O, socket, pump, or P3.2 transport here. | 19 | + | // There is no I/O, socket, pump, or transport here. |
| 20 | package brokerwire | 20 | package brokerwire | ||
| 21 | 21 | ||||
| 22 | import ( | 22 | import ( | ||
M internal/adapters/daemonmux/aggregate.go +1 -1
| @@ -1,4 +1,4 @@ | |||
| 1 | - | // Aggregate listener over multiple physical listeners (P3.2). | |
| 1 | + | // Aggregate listener over multiple physical listeners. | |
| 2 | 2 | // | |
| 3 | 3 | // AggregateListener is the daemon's global ports.ServerListener over several | |
| 4 | 4 | // physical daemonmux connections. The daemon's shared accept loop must not stop | |
| @@ -1,4 +1,4 @@ | |||||
| 1 | - | // Aggregate listener over multiple physical listeners (P3.2). | 1 | + | // Aggregate listener over multiple physical listeners. |
| 2 | // | 2 | // | ||
| 3 | // AggregateListener is the daemon's global ports.ServerListener over several | 3 | // AggregateListener is the daemon's global ports.ServerListener over several | ||
| 4 | // physical daemonmux connections. The daemon's shared accept loop must not stop | 4 | // physical daemonmux connections. The daemon's shared accept loop must not stop | ||
M internal/adapters/daemonmux/carrier.go +1 -1
| @@ -1,4 +1,4 @@ | |||
| 1 | - | // Raw-carrier bridge (P3.2b). | |
| 1 | + | // Raw-carrier bridge. | |
| 2 | 2 | // | |
| 3 | 3 | // One daemonmux physical connection rides an existing raw framed transport: | |
| 4 | 4 | // IPC, QUIC, or SSH stdio, each of which already owns vev's shared 4-byte | |
| @@ -1,4 +1,4 @@ | |||||
| 1 | - | // Raw-carrier bridge (P3.2b). | 1 | + | // Raw-carrier bridge. |
| 2 | // | 2 | // | ||
| 3 | // One daemonmux physical connection rides an existing raw framed transport: | 3 | // One daemonmux physical connection rides an existing raw framed transport: | ||
| 4 | // IPC, QUIC, or SSH stdio, each of which already owns vev's shared 4-byte | 4 | // IPC, QUIC, or SSH stdio, each of which already owns vev's shared 4-byte | ||
M internal/adapters/daemonmux/codec.go +1 -1
| @@ -1,6 +1,6 @@ | |||
| 1 | 1 | package daemonmux | |
| 2 | 2 | ||
| 3 | - | // Directional envelope adaptation (P3.2). | |
| 3 | + | // Directional envelope adaptation. | |
| 4 | 4 | // | |
| 5 | 5 | // EncodeClient wraps one adapter-local client value in its directional | |
| 6 | 6 | // MuxClientEnvelope; DecodeClient unwraps and validates. EncodeServer and | |
| @@ -1,6 +1,6 @@ | |||||
| 1 | package daemonmux | 1 | package daemonmux | ||
| 2 | 2 | ||||
| 3 | - | // Directional envelope adaptation (P3.2). | 3 | + | // Directional envelope adaptation. |
| 4 | // | 4 | // | ||
| 5 | // EncodeClient wraps one adapter-local client value in its directional | 5 | // EncodeClient wraps one adapter-local client value in its directional | ||
| 6 | // MuxClientEnvelope; DecodeClient unwraps and validates. EncodeServer and | 6 | // MuxClientEnvelope; DecodeClient unwraps and validates. EncodeServer and | ||
M internal/adapters/daemonmux/connector.go +1 -1
| @@ -1,4 +1,4 @@ | |||
| 1 | - | // Broker endpoint connector and physical connection (P3.2c). | |
| 1 | + | // Broker endpoint connector and physical connection. | |
| 2 | 2 | // | |
| 3 | 3 | // EndpointConnector is the broker-side bridge between the transport-neutral | |
| 4 | 4 | // ports.BrokerEndpointConnector contract and the daemonmux multiplexer. It owns | |
| @@ -1,4 +1,4 @@ | |||||
| 1 | - | // Broker endpoint connector and physical connection (P3.2c). | 1 | + | // Broker endpoint connector and physical connection. |
| 2 | // | 2 | // | ||
| 3 | // EndpointConnector is the broker-side bridge between the transport-neutral | 3 | // EndpointConnector is the broker-side bridge between the transport-neutral | ||
| 4 | // ports.BrokerEndpointConnector contract and the daemonmux multiplexer. It owns | 4 | // ports.BrokerEndpointConnector contract and the daemonmux multiplexer. It owns | ||
M internal/adapters/daemonmux/convert.go +1 -1
| @@ -1,6 +1,6 @@ | |||
| 1 | 1 | package daemonmux | |
| 2 | 2 | ||
| 3 | - | // Shared semantic converters (P3.2). | |
| 3 | + | // Shared semantic converters. | |
| 4 | 4 | // | |
| 5 | 5 | // Conversion mirrors the port, domain, and protocol types losslessly and | |
| 6 | 6 | // validates every narrowing numeric cast before it happens. Wire uint32 | |
| @@ -1,6 +1,6 @@ | |||||
| 1 | package daemonmux | 1 | package daemonmux | ||
| 2 | 2 | ||||
| 3 | - | // Shared semantic converters (P3.2). | 3 | + | // Shared semantic converters. |
| 4 | // | 4 | // | ||
| 5 | // Conversion mirrors the port, domain, and protocol types losslessly and | 5 | // Conversion mirrors the port, domain, and protocol types losslessly and | ||
| 6 | // validates every narrowing numeric cast before it happens. Wire uint32 | 6 | // validates every narrowing numeric cast before it happens. Wire uint32 | ||
M internal/adapters/daemonmux/doc.go +17 -223
| @@ -1,226 +1,20 @@ | |||
| 1 | - | // Package daemonmux is the Plan 001 P3.2 daemon transport adapter. | |
| 2 | - | // | |
| 3 | - | // daemonmux will own one pooled physical connection to an authenticated | |
| 4 | - | // daemon and the independently cancellable logical streams multiplexed over | |
| 5 | - | // it: carriage framing, per-stream identity and bounded queues, admission, and | |
| 6 | - | // the terminal publication that fences every affected stream. Like the | |
| 7 | - | // brokerwire codec (P3.1) and the broker pool core (P2.2), it is not yet | |
| 8 | - | // activated by production composition. | |
| 9 | - | // | |
| 10 | - | // The stateless wire adaptation is additively complete: the private | |
| 11 | - | // directional codec over the daemonmux Protobuf envelopes (codec.go), its | |
| 12 | - | // bounded ceilings (limits.go), its adapter-local message values | |
| 13 | - | // (messages.go), the lossless conversions (convert.go), and the physical | |
| 14 | - | // preamble that negotiates the per-connection ceilings, the authenticated | |
| 15 | - | // daemon identity, and the accepted policy once (preamble.go). The negotiated | |
| 16 | - | // effective minima are exported as MuxCeilings and are the seam the engine and | |
| 17 | - | // scheduler constructors consume (NewStreamEngineWithCeilings, | |
| 18 | - | // NewSchedulerWithCeilings); the default constructors delegate with the | |
| 19 | - | // package policy. Encode and decode operate on one complete serialized | |
| 20 | - | // envelope at a time over strict wire.ScanEnvelope. The in-memory stream | |
| 21 | - | // table, admission, bounded inbound queues, and terminal publication live in | |
| 22 | - | // engine_state.go. No socket, framing engine, or composition is introduced | |
| 23 | - | // here. | |
| 24 | - | // | |
| 25 | - | // The daemon-side physical binding (binding.go) and the stateful physical | |
| 26 | - | // preamble handshake (handshake.go) are the connection's authority layer. A | |
| 27 | - | // ServerBinding is a validated, immutable (identity, incarnation) value over a | |
| 28 | - | // non-empty closed set of distinct provisioned policy admissions, each naming | |
| 29 | - | // the exact policy for one carriage shape and its locality (ServerPolicyAdmission). | |
| 30 | - | // The broker-side handshake verifies the accepted response against the | |
| 31 | - | // independently resolved endpoint identity and policy, the nonzero | |
| 32 | - | // incarnation, and the ceilings it offered; the daemon-side handshake enforces | |
| 33 | - | // the immutable binding instead of echoing the requested policy, resolves the | |
| 34 | - | // accepted member (policy plus origin), negotiates | |
| 35 | - | // the element-wise minima, and refuses with the precise shared rejection code. | |
| 36 | - | // One caller-supplied context or deadline bounds the single request/response | |
| 37 | - | // exchange, and every failure closes the carrier; a success leaves it open for | |
| 38 | - | // the pump its owner starts afterwards. Neither file starts a pump, admits a | |
| 39 | - | // stream, or introduces a socket, framing engine, or production composition. | |
| 40 | - | // | |
| 41 | - | // The private terminal-state primitive (terminal.go) is a deliberate engine | |
| 42 | - | // foundation, not a stateless-codec concern: it introduces the publish-once | |
| 43 | - | // terminal outcome that backs Done, Err, and FailureKind on a physical | |
| 44 | - | // connection and on every stream, because that contract is the engine's | |
| 45 | - | // foundation and defining it up front keeps the multiplexer carriage layered | |
| 46 | - | // on top without changing it. It carries no framing, streams, queues, or | |
| 47 | - | // socket. | |
| 48 | - | // | |
| 49 | - | // The outbound fair scheduler (scheduler.go) is the engine's outbound half: it | |
| 50 | - | // owns one bounded, independently cancellable FIFO queue per admitted stream | |
| 51 | - | // and orders already-encoded envelopes with byte-deficit round robin, a small | |
| 52 | - | // bounded control priority, and immediate per-stream discard on Reset. It | |
| 53 | - | // performs no I/O and owns no goroutine; the physical writer that drains it is | |
| 54 | - | // pump.go. No socket, framing engine, listener, or composition is introduced | |
| 55 | - | // here. | |
| 56 | - | // | |
| 57 | - | // The physical pump (pump.go) is the connection's carriage half: it composes | |
| 58 | - | // the stateless directional codec, the stream engine, the fair scheduler, and | |
| 59 | - | // the publish-once terminal state over the private FramedCarrier abstraction | |
| 60 | - | // with exactly one reader and one writer goroutine. The reader strict-decodes | |
| 61 | - | // each inbound direction and applies the engine; the writer drains the | |
| 62 | - | // scheduler's fairly ordered immutable envelopes; a coalescing wake channel | |
| 63 | - | // keeps the writer from polling or sleeping. A malformed outer envelope or a | |
| 64 | - | // carrier Receive/Send error publishes the physical terminal outcome before | |
| 65 | - | // every stream is terminalized, a stream-local semantic, reference, or queue | |
| 66 | - | // refusal schedules exactly one Reset without touching siblings, and | |
| 67 | - | // cancellation is an orderly close. An inbound Open that duplicates or replays | |
| 68 | - | // an identity the engine already owns is ignored, so it never disturbs the | |
| 69 | - | // live or retired stream it names; a fresh Open the engine refuses for | |
| 70 | - | // capacity, a closed connection, or an invalid authority is answered with | |
| 71 | - | // exactly one typed Mux Refused carrying its admission code and records no | |
| 72 | - | // stream. An outbound queue overflow is settled the same way: the overflowing | |
| 73 | - | // stream's engine record is reset and its one Reset is scheduled, and an | |
| 74 | - | // inbound Close or Reset retires the matching scheduler record and discards | |
| 75 | - | // its queued outbound frames. An orderly inbound Close preserves the inbound | |
| 76 | - | // data that was already accepted: the stream moves to closing, accepts no new | |
| 77 | - | // data, and stays readable until Take drains the last queued chunk, which is | |
| 78 | - | // when it terminalizes and releases its slot; a Reset always discards the | |
| 79 | - | // preserved queue at once. Flush is the explicit write barrier for callers that | |
| 80 | - | // must publish a final frame before closing; Close itself cancels the writer | |
| 81 | - | // and does not drain. Close unblocks the carrier through the adapter | |
| 82 | - | // prompt-close contract and joins both goroutines. The carrier stays an | |
| 83 | - | // abstract, testable seam: no socket, listener, streamframe, sessionwire, or | |
| 84 | - | // ports physical implementation is introduced here. | |
| 85 | - | // | |
| 86 | - | // The raw-carrier bridge (carrier.go) is the connection's framing boundary: it | |
| 87 | - | // adapts an existing raw framed transport - IPC, QUIC, or SSH stdio, each a | |
| 88 | - | // wire.BoundedTransport - to the private FramedCarrier the pump and the | |
| 89 | - | // preamble handshake drive. Send is synchronous; Receive is bounded to | |
| 90 | - | // wire.PreambleLimit until the explicit, one-way Negotiate transition records | |
| 91 | - | // the negotiated daemonmux envelope ceiling, so no receive allocates a body a | |
| 92 | - | // peer did not bound. Close is idempotent and concurrent-safe, interrupts a | |
| 93 | - | // blocked read or write, and joins every worker. It reuses the shared | |
| 94 | - | // streamframe framing and introduces no socket, listener, sessionwire, or frame | |
| 95 | - | // format of its own. | |
| 96 | - | // | |
| 97 | - | // The typed server-side listener (listener.go) is the daemon half of one | |
| 98 | - | // physical connection: the pump's reader admits each incoming MuxOpen and | |
| 99 | - | // notifies the listener through the pump's narrow admission-observer seam, the | |
| 100 | - | // listener queues admitted streams in a bounded FIFO accept queue (at most | |
| 101 | - | // MaxAcceptQueue, 128), and Accept hands each one back as an independent typed | |
| 102 | - | // ports.ServerConnection built with sessionwire over that mux stream. Every | |
| 103 | - | // stream carries one absolute local handshake deadline fixed at Open admission | |
| 104 | - | // (protocol.HandshakeTimeout) that queue delay and the session handshake share; | |
| 105 | - | // the deadline and the handshake completion signal are exposed to the daemon | |
| 106 | - | // through the narrow optional HandshakePlumbing interface, so the daemon adopts | |
| 107 | - | // this one deadline instead of starting a second one. Every admitted connection | |
| 108 | - | // is stamped with the provisioned admission its listener accepted - the exact | |
| 109 | - | // accepted policy and carriage origin plus the peer's declared purpose, closed | |
| 110 | - | // admission variant, name, exact target, and bounded environment - and exposes | |
| 111 | - | // it through the optional ports.SessionAdmissionProvider so a daemon use case | |
| 112 | - | // consumes the accepting side's authority rather than the peer's Open. An Open | |
| 113 | - | // whose declared locality contradicts the accepted origin (a liar Local) or that | |
| 114 | - | // fails the closed admission contract is refused on its own stream. A stream that reaches its | |
| 115 | - | // deadline, is refused because the accept queue is full, or is reset by the | |
| 116 | - | // peer is settled on its own: exactly one mux Reset, its admission slot | |
| 117 | - | // released, and no effect on a sibling or on the physical connection. An | |
| 118 | - | // admission whose absolute deadline elapsed is settled by Accept itself, even | |
| 119 | - | // before the watchdog observes it, and a connection whose inner session | |
| 120 | - | // carriage closes on its own during the handshake (a sessionwire preamble | |
| 121 | - | // failure) is settled by its terminal watcher with exactly one stream-local | |
| 122 | - | // Reset, so no consumer Close is needed. Accept | |
| 123 | - | // therefore never fails for a stream-local failure; it fails only when the | |
| 124 | - | // listener was closed or when the one physical connection reached its terminal | |
| 125 | - | // outcome, which is exactly when the shared daemon accept loop must stop. Close | |
| 126 | - | // unblocks Accept, drains every admitted-but-unaccepted stream through its one | |
| 127 | - | // stream-local Reset (releasing each slot and unblocking the broker's pending | |
| 128 | - | // Open), and joins the deadline watchdog without closing the pooled physical | |
| 129 | - | // pump. The listener is constructed before its pump starts: it registers the | |
| 130 | - | // pump's single admission observer, which the pump refuses after Start. No | |
| 131 | - | // socket, framing engine, or composition is introduced here. | |
| 132 | - | // | |
| 133 | - | // The aggregate listener (aggregate.go) is the daemon's global | |
| 134 | - | // ports.ServerListener over several physical listeners: it owns one forwarding | |
| 135 | - | // goroutine per registered child, delivers each child's independently accepted | |
| 136 | - | // typed connection through one bounded FIFO, and isolates a child's terminal | |
| 137 | - | // Accept failure - a lost or closed physical carriage - instead of surfacing it | |
| 138 | - | // as the aggregate's own error. So the loss of one physical daemonmux transport | |
| 139 | - | // never stops the daemon's shared accept loop while another or a newly | |
| 140 | - | // registered child can still serve. Register and Remove take and release | |
| 141 | - | // ownership of a child; Close unblocks Accept, closes every owned child, joins | |
| 142 | - | // every forwarder, and closes every accepted-but-unaccepted connection. The | |
| 143 | - | // aggregate consumes the typed ports.ServerListener/ports.ServerConnection | |
| 144 | - | // contracts only, so it composes with the daemonmux Listener, the sessionwire | |
| 145 | - | // listener, or any later physical listener. No socket, framing engine, or | |
| 146 | - | // production composition is introduced here. | |
| 147 | - | // | |
| 148 | - | // The broker endpoint connector (connector.go) is the broker half of one | |
| 149 | - | // pooled physical connection: EndpointConnector takes an injected narrow | |
| 150 | - | // authenticated raw-carrier dial function, runs the physical preamble over the | |
| 151 | - | // FramedCarrierBridge with the resolved endpoint's identity and policy as the | |
| 152 | - | // authoritative values, negotiates the effective ceilings, and hands the live | |
| 153 | - | // pump and LogicalConnector to a PhysicalConnection. One caller-supplied setup | |
| 154 | - | // context or deadline bounds dial and handshake together; a successful | |
| 155 | - | // connection is deliberately detached from it, so cancelling or expiring the | |
| 156 | - | // setup context never stops a pooled physical connection, which Close alone | |
| 157 | - | // owns. PhysicalConnection reports the immutable accepted identity, | |
| 158 | - | // incarnation, and policy, delegates Done, Err, and FailureKind to the pump's | |
| 159 | - | // publish-once terminal authority, exact-policy-checks every OpenStream before | |
| 160 | - | // delegating to the LogicalConnector, and tears the pump and carrier down | |
| 161 | - | // exactly once. | |
| 162 | - | // | |
| 163 | - | // The server supervisor (supervisor.go) is the daemon's owner of accepted raw | |
| 164 | - | // physical carriage: Adopt bounds concurrent handshakes and admissions, | |
| 165 | - | // completes the physical preamble against the immutable ServerBinding, | |
| 166 | - | // restricts the pump's engine to the accepted physical policy so every inbound | |
| 167 | - | // Open is checked before fresh stream admission, builds the typed Listener | |
| 168 | - | // before the pump starts, and registers one owned child - which closes | |
| 169 | - | // listener, pump, and carrier together - with the AggregateListener. One | |
| 170 | - | // reaper per child closes and deregisters it on its own terminal outcome, | |
| 171 | - | // isolating a lost or failed physical child from every sibling and from the | |
| 172 | - | // aggregate, and Close tears every owned child down and joins the reapers | |
| 173 | - | // without closing the caller-owned aggregate. The carriage stays an injected, | |
| 174 | - | // abstract seam: daemonmux never dials, listens, authenticates, or inspects a | |
| 175 | - | // socket, and no identity persistence or production activation is introduced | |
| 176 | - | // here. | |
| 177 | - | // | |
| 178 | - | // The private Unix carriage (P3.2d) lives in internal/adapters/ipc, not here: | |
| 179 | - | // ListenMux and DialMuxContext bind and connect a caller-supplied isolated | |
| 180 | - | // AF_UNIX path (never the live daemon.sock) and return a raw bounded transport | |
| 181 | - | // the EndpointConnector and ServerSupervisor consume unmodified. Listener setup | |
| 182 | - | // creates or validates an owner-only parent and socket, recovers race-safely | |
| 183 | - | // from a stale socket, refuses a foreign non-socket path, and both accept and | |
| 184 | - | // dial verify same-user kernel peer credentials (SO_PEERCRED on Linux), failing | |
| 185 | - | // closed on a platform or build without the check. Close unblocks Accept and | |
| 186 | - | // I/O and unlinks only the socket inode the listener created. daemonmux gains | |
| 187 | - | // no socket, dial/listen, or peer-credential code from this slice. | |
| 188 | - | // | |
| 189 | - | // The private QUIC carriage (P3.2e) lives in internal/adapters/quic, not here: | |
| 190 | - | // quic.DialMuxContext and quic.Server.AcceptMux reuse the existing | |
| 191 | - | // authenticated bootstrap contracts unchanged - the ephemeral certificate and | |
| 192 | - | // its exact SHA-256 pin, the single-use 32-byte token, and the single-use | |
| 193 | - | // nonce - and hand the connection's one bidirectional stream to the same | |
| 194 | - | // EndpointConnector and ServerSupervisor as a raw bounded transport | |
| 195 | - | // (wire.BoundedTransport). One QUIC connection is therefore one physical | |
| 196 | - | // daemonmux connection and exactly one native QUIC stream: logical attachments | |
| 197 | - | // are multiplexed inside that stream and are never mapped to native QUIC | |
| 198 | - | // streams, the one-stream guard stays in force for the whole connection | |
| 199 | - | // lifetime, and one freshly minted bootstrap server admits exactly one | |
| 200 | - | // authenticated carriage. The caller's setup context bounds the credential | |
| 201 | - | // wait, the pinned dial, the bounded auth record, and the physical preamble | |
| 202 | - | // the connector runs afterwards; a refused pin, token, or nonce closes the | |
| 203 | - | // carriage and hands nothing out, and a successful carriage detaches from the | |
| 204 | - | // setup context exactly as the Unix and in-memory carriages do. daemonmux | |
| 205 | - | // gains no socket, dial, TLS, or credential code from this slice. | |
| 206 | - | // | |
| 207 | - | // The private SSH stdio carriage lives in internal/adapters/sshstdio, not here: | |
| 208 | - | // sshstdio.DialMuxContext starts one caller-supplied explicit command over a | |
| 209 | - | // local ssh child process whose stdin/stdout are the raw bounded carriage, and | |
| 210 | - | // sshstdio.NewStdioTransport is its helper half over the remote process' own | |
| 211 | - | // stdio. The command is supplied by the caller, never the `vev _stdio` session | |
| 212 | - | // command, so a mux carriage cannot become a second navigation path to a | |
| 213 | - | // session; host-key and authentication policy stay owned by the target's | |
| 214 | - | // effective OpenSSH configuration, and the carriage requests no remote PTY | |
| 215 | - | // (`-T`). One child process is one physical daemonmux connection, exactly like | |
| 216 | - | // the Unix and QUIC carriages: every logical attachment is multiplexed inside | |
| 217 | - | // its stdio stream and is never mapped to another process. The caller's setup | |
| 218 | - | // context bounds subprocess start and the physical preamble the connector runs | |
| 219 | - | // afterwards together; a successful carriage detaches from it, and Close | |
| 220 | - | // terminates and joins the subprocess. The child's stderr is captured bounded | |
| 221 | - | // and sanitized, and a non-clean exit surfaces a typed sanitized error, never | |
| 222 | - | // raw remote stderr. daemonmux gains no process, pipe, or framing code from | |
| 223 | - | // this slice. | |
| 1 | + | // Package daemonmux multiplexes typed session connections over one authenticated | |
| 2 | + | // physical daemon carriage. | |
| 3 | + | // | |
| 4 | + | // Its directional codec strictly scans bounded envelopes; the physical | |
| 5 | + | // handshake binds an immutable daemon identity, incarnation, accepted policy, | |
| 6 | + | // and negotiated ceilings. The stream engine enforces admission, per-stream | |
| 7 | + | // identity, bounded queues, and terminal publication. A fair scheduler drains | |
| 8 | + | // independently cancellable streams through one reader and one writer; a | |
| 9 | + | // stream-local refusal does not terminate its siblings, while physical failure | |
| 10 | + | // settles every stream before the connection reports completion. | |
| 11 | + | // | |
| 12 | + | // Broker connectors and daemon listeners adapt injected raw framed transports | |
| 13 | + | // into logical typed connections. Accepted streams share one absolute session | |
| 14 | + | // handshake deadline from admission through the daemon handshake. The aggregate | |
| 15 | + | // listener isolates physical child failures so other transports keep serving. | |
| 16 | + | // Unix IPC, QUIC, and SSH stdio carriage and authentication live in their own | |
| 17 | + | // adapters; this package neither opens sockets nor owns session state. | |
| 224 | 18 | package daemonmux | |
| 225 | 19 | ||
| 226 | 20 | import "path/filepath" | |
| @@ -1,226 +1,20 @@ | |||||
| 1 | - | // Package daemonmux is the Plan 001 P3.2 daemon transport adapter. | 1 | + | // Package daemonmux multiplexes typed session connections over one authenticated |
| 2 | - | // | 2 | + | // physical daemon carriage. |
| 3 | - | // daemonmux will own one pooled physical connection to an authenticated | 3 | + | // |
| 4 | - | // daemon and the independently cancellable logical streams multiplexed over | 4 | + | // Its directional codec strictly scans bounded envelopes; the physical |
| 5 | - | // it: carriage framing, per-stream identity and bounded queues, admission, and | 5 | + | // handshake binds an immutable daemon identity, incarnation, accepted policy, |
| 6 | - | // the terminal publication that fences every affected stream. Like the | 6 | + | // and negotiated ceilings. The stream engine enforces admission, per-stream |
| 7 | - | // brokerwire codec (P3.1) and the broker pool core (P2.2), it is not yet | 7 | + | // identity, bounded queues, and terminal publication. A fair scheduler drains |
| 8 | - | // activated by production composition. | 8 | + | // independently cancellable streams through one reader and one writer; a |
| 9 | - | // | 9 | + | // stream-local refusal does not terminate its siblings, while physical failure |
| 10 | - | // The stateless wire adaptation is additively complete: the private | 10 | + | // settles every stream before the connection reports completion. |
| 11 | - | // directional codec over the daemonmux Protobuf envelopes (codec.go), its | 11 | + | // |
| 12 | - | // bounded ceilings (limits.go), its adapter-local message values | 12 | + | // Broker connectors and daemon listeners adapt injected raw framed transports |
| 13 | - | // (messages.go), the lossless conversions (convert.go), and the physical | 13 | + | // into logical typed connections. Accepted streams share one absolute session |
| 14 | - | // preamble that negotiates the per-connection ceilings, the authenticated | 14 | + | // handshake deadline from admission through the daemon handshake. The aggregate |
| 15 | - | // daemon identity, and the accepted policy once (preamble.go). The negotiated | 15 | + | // listener isolates physical child failures so other transports keep serving. |
| 16 | - | // effective minima are exported as MuxCeilings and are the seam the engine and | 16 | + | // Unix IPC, QUIC, and SSH stdio carriage and authentication live in their own |
| 17 | - | // scheduler constructors consume (NewStreamEngineWithCeilings, | 17 | + | // adapters; this package neither opens sockets nor owns session state. |
| 18 | - | // NewSchedulerWithCeilings); the default constructors delegate with the | |||
| 19 | - | // package policy. Encode and decode operate on one complete serialized | |||
| 20 | - | // envelope at a time over strict wire.ScanEnvelope. The in-memory stream | |||
| 21 | - | // table, admission, bounded inbound queues, and terminal publication live in | |||
| 22 | - | // engine_state.go. No socket, framing engine, or composition is introduced | |||
| 23 | - | // here. | |||
| 24 | - | // | |||
| 25 | - | // The daemon-side physical binding (binding.go) and the stateful physical | |||
| 26 | - | // preamble handshake (handshake.go) are the connection's authority layer. A | |||
| 27 | - | // ServerBinding is a validated, immutable (identity, incarnation) value over a | |||
| 28 | - | // non-empty closed set of distinct provisioned policy admissions, each naming | |||
| 29 | - | // the exact policy for one carriage shape and its locality (ServerPolicyAdmission). | |||
| 30 | - | // The broker-side handshake verifies the accepted response against the | |||
| 31 | - | // independently resolved endpoint identity and policy, the nonzero | |||
| 32 | - | // incarnation, and the ceilings it offered; the daemon-side handshake enforces | |||
| 33 | - | // the immutable binding instead of echoing the requested policy, resolves the | |||
| 34 | - | // accepted member (policy plus origin), negotiates | |||
| 35 | - | // the element-wise minima, and refuses with the precise shared rejection code. | |||
| 36 | - | // One caller-supplied context or deadline bounds the single request/response | |||
| 37 | - | // exchange, and every failure closes the carrier; a success leaves it open for | |||
| 38 | - | // the pump its owner starts afterwards. Neither file starts a pump, admits a | |||
| 39 | - | // stream, or introduces a socket, framing engine, or production composition. | |||
| 40 | - | // | |||
| 41 | - | // The private terminal-state primitive (terminal.go) is a deliberate engine | |||
| 42 | - | // foundation, not a stateless-codec concern: it introduces the publish-once | |||
| 43 | - | // terminal outcome that backs Done, Err, and FailureKind on a physical | |||
| 44 | - | // connection and on every stream, because that contract is the engine's | |||
| 45 | - | // foundation and defining it up front keeps the multiplexer carriage layered | |||
| 46 | - | // on top without changing it. It carries no framing, streams, queues, or | |||
| 47 | - | // socket. | |||
| 48 | - | // | |||
| 49 | - | // The outbound fair scheduler (scheduler.go) is the engine's outbound half: it | |||
| 50 | - | // owns one bounded, independently cancellable FIFO queue per admitted stream | |||
| 51 | - | // and orders already-encoded envelopes with byte-deficit round robin, a small | |||
| 52 | - | // bounded control priority, and immediate per-stream discard on Reset. It | |||
| 53 | - | // performs no I/O and owns no goroutine; the physical writer that drains it is | |||
| 54 | - | // pump.go. No socket, framing engine, listener, or composition is introduced | |||
| 55 | - | // here. | |||
| 56 | - | // | |||
| 57 | - | // The physical pump (pump.go) is the connection's carriage half: it composes | |||
| 58 | - | // the stateless directional codec, the stream engine, the fair scheduler, and | |||
| 59 | - | // the publish-once terminal state over the private FramedCarrier abstraction | |||
| 60 | - | // with exactly one reader and one writer goroutine. The reader strict-decodes | |||
| 61 | - | // each inbound direction and applies the engine; the writer drains the | |||
| 62 | - | // scheduler's fairly ordered immutable envelopes; a coalescing wake channel | |||
| 63 | - | // keeps the writer from polling or sleeping. A malformed outer envelope or a | |||
| 64 | - | // carrier Receive/Send error publishes the physical terminal outcome before | |||
| 65 | - | // every stream is terminalized, a stream-local semantic, reference, or queue | |||
| 66 | - | // refusal schedules exactly one Reset without touching siblings, and | |||
| 67 | - | // cancellation is an orderly close. An inbound Open that duplicates or replays | |||
| 68 | - | // an identity the engine already owns is ignored, so it never disturbs the | |||
| 69 | - | // live or retired stream it names; a fresh Open the engine refuses for | |||
| 70 | - | // capacity, a closed connection, or an invalid authority is answered with | |||
| 71 | - | // exactly one typed Mux Refused carrying its admission code and records no | |||
| 72 | - | // stream. An outbound queue overflow is settled the same way: the overflowing | |||
| 73 | - | // stream's engine record is reset and its one Reset is scheduled, and an | |||
| 74 | - | // inbound Close or Reset retires the matching scheduler record and discards | |||
| 75 | - | // its queued outbound frames. An orderly inbound Close preserves the inbound | |||
| 76 | - | // data that was already accepted: the stream moves to closing, accepts no new | |||
| 77 | - | // data, and stays readable until Take drains the last queued chunk, which is | |||
| 78 | - | // when it terminalizes and releases its slot; a Reset always discards the | |||
| 79 | - | // preserved queue at once. Flush is the explicit write barrier for callers that | |||
| 80 | - | // must publish a final frame before closing; Close itself cancels the writer | |||
| 81 | - | // and does not drain. Close unblocks the carrier through the adapter | |||
| 82 | - | // prompt-close contract and joins both goroutines. The carrier stays an | |||
| 83 | - | // abstract, testable seam: no socket, listener, streamframe, sessionwire, or | |||
| 84 | - | // ports physical implementation is introduced here. | |||
| 85 | - | // | |||
| 86 | - | // The raw-carrier bridge (carrier.go) is the connection's framing boundary: it | |||
| 87 | - | // adapts an existing raw framed transport - IPC, QUIC, or SSH stdio, each a | |||
| 88 | - | // wire.BoundedTransport - to the private FramedCarrier the pump and the | |||
| 89 | - | // preamble handshake drive. Send is synchronous; Receive is bounded to | |||
| 90 | - | // wire.PreambleLimit until the explicit, one-way Negotiate transition records | |||
| 91 | - | // the negotiated daemonmux envelope ceiling, so no receive allocates a body a | |||
| 92 | - | // peer did not bound. Close is idempotent and concurrent-safe, interrupts a | |||
| 93 | - | // blocked read or write, and joins every worker. It reuses the shared | |||
| 94 | - | // streamframe framing and introduces no socket, listener, sessionwire, or frame | |||
| 95 | - | // format of its own. | |||
| 96 | - | // | |||
| 97 | - | // The typed server-side listener (listener.go) is the daemon half of one | |||
| 98 | - | // physical connection: the pump's reader admits each incoming MuxOpen and | |||
| 99 | - | // notifies the listener through the pump's narrow admission-observer seam, the | |||
| 100 | - | // listener queues admitted streams in a bounded FIFO accept queue (at most | |||
| 101 | - | // MaxAcceptQueue, 128), and Accept hands each one back as an independent typed | |||
| 102 | - | // ports.ServerConnection built with sessionwire over that mux stream. Every | |||
| 103 | - | // stream carries one absolute local handshake deadline fixed at Open admission | |||
| 104 | - | // (protocol.HandshakeTimeout) that queue delay and the session handshake share; | |||
| 105 | - | // the deadline and the handshake completion signal are exposed to the daemon | |||
| 106 | - | // through the narrow optional HandshakePlumbing interface, so the daemon adopts | |||
| 107 | - | // this one deadline instead of starting a second one. Every admitted connection | |||
| 108 | - | // is stamped with the provisioned admission its listener accepted - the exact | |||
| 109 | - | // accepted policy and carriage origin plus the peer's declared purpose, closed | |||
| 110 | - | // admission variant, name, exact target, and bounded environment - and exposes | |||
| 111 | - | // it through the optional ports.SessionAdmissionProvider so a daemon use case | |||
| 112 | - | // consumes the accepting side's authority rather than the peer's Open. An Open | |||
| 113 | - | // whose declared locality contradicts the accepted origin (a liar Local) or that | |||
| 114 | - | // fails the closed admission contract is refused on its own stream. A stream that reaches its | |||
| 115 | - | // deadline, is refused because the accept queue is full, or is reset by the | |||
| 116 | - | // peer is settled on its own: exactly one mux Reset, its admission slot | |||
| 117 | - | // released, and no effect on a sibling or on the physical connection. An | |||
| 118 | - | // admission whose absolute deadline elapsed is settled by Accept itself, even | |||
| 119 | - | // before the watchdog observes it, and a connection whose inner session | |||
| 120 | - | // carriage closes on its own during the handshake (a sessionwire preamble | |||
| 121 | - | // failure) is settled by its terminal watcher with exactly one stream-local | |||
| 122 | - | // Reset, so no consumer Close is needed. Accept | |||
| 123 | - | // therefore never fails for a stream-local failure; it fails only when the | |||
| 124 | - | // listener was closed or when the one physical connection reached its terminal | |||
| 125 | - | // outcome, which is exactly when the shared daemon accept loop must stop. Close | |||
| 126 | - | // unblocks Accept, drains every admitted-but-unaccepted stream through its one | |||
| 127 | - | // stream-local Reset (releasing each slot and unblocking the broker's pending | |||
| 128 | - | // Open), and joins the deadline watchdog without closing the pooled physical | |||
| 129 | - | // pump. The listener is constructed before its pump starts: it registers the | |||
| 130 | - | // pump's single admission observer, which the pump refuses after Start. No | |||
| 131 | - | // socket, framing engine, or composition is introduced here. | |||
| 132 | - | // | |||
| 133 | - | // The aggregate listener (aggregate.go) is the daemon's global | |||
| 134 | - | // ports.ServerListener over several physical listeners: it owns one forwarding | |||
| 135 | - | // goroutine per registered child, delivers each child's independently accepted | |||
| 136 | - | // typed connection through one bounded FIFO, and isolates a child's terminal | |||
| 137 | - | // Accept failure - a lost or closed physical carriage - instead of surfacing it | |||
| 138 | - | // as the aggregate's own error. So the loss of one physical daemonmux transport | |||
| 139 | - | // never stops the daemon's shared accept loop while another or a newly | |||
| 140 | - | // registered child can still serve. Register and Remove take and release | |||
| 141 | - | // ownership of a child; Close unblocks Accept, closes every owned child, joins | |||
| 142 | - | // every forwarder, and closes every accepted-but-unaccepted connection. The | |||
| 143 | - | // aggregate consumes the typed ports.ServerListener/ports.ServerConnection | |||
| 144 | - | // contracts only, so it composes with the daemonmux Listener, the sessionwire | |||
| 145 | - | // listener, or any later physical listener. No socket, framing engine, or | |||
| 146 | - | // production composition is introduced here. | |||
| 147 | - | // | |||
| 148 | - | // The broker endpoint connector (connector.go) is the broker half of one | |||
| 149 | - | // pooled physical connection: EndpointConnector takes an injected narrow | |||
| 150 | - | // authenticated raw-carrier dial function, runs the physical preamble over the | |||
| 151 | - | // FramedCarrierBridge with the resolved endpoint's identity and policy as the | |||
| 152 | - | // authoritative values, negotiates the effective ceilings, and hands the live | |||
| 153 | - | // pump and LogicalConnector to a PhysicalConnection. One caller-supplied setup | |||
| 154 | - | // context or deadline bounds dial and handshake together; a successful | |||
| 155 | - | // connection is deliberately detached from it, so cancelling or expiring the | |||
| 156 | - | // setup context never stops a pooled physical connection, which Close alone | |||
| 157 | - | // owns. PhysicalConnection reports the immutable accepted identity, | |||
| 158 | - | // incarnation, and policy, delegates Done, Err, and FailureKind to the pump's | |||
| 159 | - | // publish-once terminal authority, exact-policy-checks every OpenStream before | |||
| 160 | - | // delegating to the LogicalConnector, and tears the pump and carrier down | |||
| 161 | - | // exactly once. | |||
| 162 | - | // | |||
| 163 | - | // The server supervisor (supervisor.go) is the daemon's owner of accepted raw | |||
| 164 | - | // physical carriage: Adopt bounds concurrent handshakes and admissions, | |||
| 165 | - | // completes the physical preamble against the immutable ServerBinding, | |||
| 166 | - | // restricts the pump's engine to the accepted physical policy so every inbound | |||
| 167 | - | // Open is checked before fresh stream admission, builds the typed Listener | |||
| 168 | - | // before the pump starts, and registers one owned child - which closes | |||
| 169 | - | // listener, pump, and carrier together - with the AggregateListener. One | |||
| 170 | - | // reaper per child closes and deregisters it on its own terminal outcome, | |||
| 171 | - | // isolating a lost or failed physical child from every sibling and from the | |||
| 172 | - | // aggregate, and Close tears every owned child down and joins the reapers | |||
| 173 | - | // without closing the caller-owned aggregate. The carriage stays an injected, | |||
| 174 | - | // abstract seam: daemonmux never dials, listens, authenticates, or inspects a | |||
| 175 | - | // socket, and no identity persistence or production activation is introduced | |||
| 176 | - | // here. | |||
| 177 | - | // | |||
| 178 | - | // The private Unix carriage (P3.2d) lives in internal/adapters/ipc, not here: | |||
| 179 | - | // ListenMux and DialMuxContext bind and connect a caller-supplied isolated | |||
| 180 | - | // AF_UNIX path (never the live daemon.sock) and return a raw bounded transport | |||
| 181 | - | // the EndpointConnector and ServerSupervisor consume unmodified. Listener setup | |||
| 182 | - | // creates or validates an owner-only parent and socket, recovers race-safely | |||
| 183 | - | // from a stale socket, refuses a foreign non-socket path, and both accept and | |||
| 184 | - | // dial verify same-user kernel peer credentials (SO_PEERCRED on Linux), failing | |||
| 185 | - | // closed on a platform or build without the check. Close unblocks Accept and | |||
| 186 | - | // I/O and unlinks only the socket inode the listener created. daemonmux gains | |||
| 187 | - | // no socket, dial/listen, or peer-credential code from this slice. | |||
| 188 | - | // | |||
| 189 | - | // The private QUIC carriage (P3.2e) lives in internal/adapters/quic, not here: | |||
| 190 | - | // quic.DialMuxContext and quic.Server.AcceptMux reuse the existing | |||
| 191 | - | // authenticated bootstrap contracts unchanged - the ephemeral certificate and | |||
| 192 | - | // its exact SHA-256 pin, the single-use 32-byte token, and the single-use | |||
| 193 | - | // nonce - and hand the connection's one bidirectional stream to the same | |||
| 194 | - | // EndpointConnector and ServerSupervisor as a raw bounded transport | |||
| 195 | - | // (wire.BoundedTransport). One QUIC connection is therefore one physical | |||
| 196 | - | // daemonmux connection and exactly one native QUIC stream: logical attachments | |||
| 197 | - | // are multiplexed inside that stream and are never mapped to native QUIC | |||
| 198 | - | // streams, the one-stream guard stays in force for the whole connection | |||
| 199 | - | // lifetime, and one freshly minted bootstrap server admits exactly one | |||
| 200 | - | // authenticated carriage. The caller's setup context bounds the credential | |||
| 201 | - | // wait, the pinned dial, the bounded auth record, and the physical preamble | |||
| 202 | - | // the connector runs afterwards; a refused pin, token, or nonce closes the | |||
| 203 | - | // carriage and hands nothing out, and a successful carriage detaches from the | |||
| 204 | - | // setup context exactly as the Unix and in-memory carriages do. daemonmux | |||
| 205 | - | // gains no socket, dial, TLS, or credential code from this slice. | |||
| 206 | - | // | |||
| 207 | - | // The private SSH stdio carriage lives in internal/adapters/sshstdio, not here: | |||
| 208 | - | // sshstdio.DialMuxContext starts one caller-supplied explicit command over a | |||
| 209 | - | // local ssh child process whose stdin/stdout are the raw bounded carriage, and | |||
| 210 | - | // sshstdio.NewStdioTransport is its helper half over the remote process' own | |||
| 211 | - | // stdio. The command is supplied by the caller, never the `vev _stdio` session | |||
| 212 | - | // command, so a mux carriage cannot become a second navigation path to a | |||
| 213 | - | // session; host-key and authentication policy stay owned by the target's | |||
| 214 | - | // effective OpenSSH configuration, and the carriage requests no remote PTY | |||
| 215 | - | // (`-T`). One child process is one physical daemonmux connection, exactly like | |||
| 216 | - | // the Unix and QUIC carriages: every logical attachment is multiplexed inside | |||
| 217 | - | // its stdio stream and is never mapped to another process. The caller's setup | |||
| 218 | - | // context bounds subprocess start and the physical preamble the connector runs | |||
| 219 | - | // afterwards together; a successful carriage detaches from it, and Close | |||
| 220 | - | // terminates and joins the subprocess. The child's stderr is captured bounded | |||
| 221 | - | // and sanitized, and a non-clean exit surfaces a typed sanitized error, never | |||
| 222 | - | // raw remote stderr. daemonmux gains no process, pipe, or framing code from | |||
| 223 | - | // this slice. | |||
| 224 | package daemonmux | 18 | package daemonmux | ||
| 225 | 19 | ||||
| 226 | import "path/filepath" | 20 | import "path/filepath" | ||
M internal/adapters/daemonmux/engine_state.go +1 -1
| @@ -1,4 +1,4 @@ | |||
| 1 | - | // In-memory stream state and admission (P3.2). | |
| 1 | + | // In-memory stream state and admission. | |
| 2 | 2 | // | |
| 3 | 3 | // StreamEngine owns the admission and lifecycle of the logical streams | |
| 4 | 4 | // multiplexed over one physical daemon connection. It performs no I/O and | |
| @@ -1,4 +1,4 @@ | |||||
| 1 | - | // In-memory stream state and admission (P3.2). | 1 | + | // In-memory stream state and admission. |
| 2 | // | 2 | // | ||
| 3 | // StreamEngine owns the admission and lifecycle of the logical streams | 3 | // StreamEngine owns the admission and lifecycle of the logical streams | ||
| 4 | // multiplexed over one physical daemon connection. It performs no I/O and | 4 | // multiplexed over one physical daemon connection. It performs no I/O and | ||
M internal/adapters/daemonmux/handshake.go +1 -1
| @@ -1,6 +1,6 @@ | |||
| 1 | 1 | package daemonmux | |
| 2 | 2 | ||
| 3 | - | // Physical preamble handshake (P3.2a). | |
| 3 | + | // Physical preamble handshake. | |
| 4 | 4 | // | |
| 5 | 5 | // The daemonmux connection begins with exactly one physical preamble exchange | |
| 6 | 6 | // over the private FramedCarrier, before any application envelope. The client | |
| @@ -1,6 +1,6 @@ | |||||
| 1 | package daemonmux | 1 | package daemonmux | ||
| 2 | 2 | ||||
| 3 | - | // Physical preamble handshake (P3.2a). | 3 | + | // Physical preamble handshake. |
| 4 | // | 4 | // | ||
| 5 | // The daemonmux connection begins with exactly one physical preamble exchange | 5 | // The daemonmux connection begins with exactly one physical preamble exchange | ||
| 6 | // over the private FramedCarrier, before any application envelope. The client | 6 | // over the private FramedCarrier, before any application envelope. The client | ||
M internal/adapters/daemonmux/limits.go +1 -1
| @@ -1,6 +1,6 @@ | |||
| 1 | 1 | package daemonmux | |
| 2 | 2 | ||
| 3 | - | // Stateless bound refusals (P3.2). | |
| 3 | + | // Stateless bound refusals. | |
| 4 | 4 | // | |
| 5 | 5 | // One physical daemon connection negotiates one immutable set of ceilings | |
| 6 | 6 | // exactly once, in the daemonmux physical preamble: a receive envelope | |
| @@ -1,6 +1,6 @@ | |||||
| 1 | package daemonmux | 1 | package daemonmux | ||
| 2 | 2 | ||||
| 3 | - | // Stateless bound refusals (P3.2). | 3 | + | // Stateless bound refusals. |
| 4 | // | 4 | // | ||
| 5 | // One physical daemon connection negotiates one immutable set of ceilings | 5 | // One physical daemon connection negotiates one immutable set of ceilings | ||
| 6 | // exactly once, in the daemonmux physical preamble: a receive envelope | 6 | // exactly once, in the daemonmux physical preamble: a receive envelope | ||
M internal/adapters/daemonmux/listener.go +1 -1
| @@ -1,4 +1,4 @@ | |||
| 1 | - | // Typed server-side listener over one physical Pump (P3.2). | |
| 1 | + | // Typed server-side listener over one physical Pump. | |
| 2 | 2 | // | |
| 3 | 3 | // Listener is the daemon half of one physical daemonmux connection. The pump's | |
| 4 | 4 | // reader admits each incoming MuxOpen; the listener turns every admitted stream | |
| @@ -1,4 +1,4 @@ | |||||
| 1 | - | // Typed server-side listener over one physical Pump (P3.2). | 1 | + | // Typed server-side listener over one physical Pump. |
| 2 | // | 2 | // | ||
| 3 | // Listener is the daemon half of one physical daemonmux connection. The pump's | 3 | // Listener is the daemon half of one physical daemonmux connection. The pump's | ||
| 4 | // reader admits each incoming MuxOpen; the listener turns every admitted stream | 4 | // reader admits each incoming MuxOpen; the listener turns every admitted stream | ||
M internal/adapters/daemonmux/logical_conn.go +1 -1
| @@ -1,4 +1,4 @@ | |||
| 1 | - | // Typed logical connections over one physical Pump (P3.2). | |
| 1 | + | // Typed logical connections over one physical Pump. | |
| 2 | 2 | // | |
| 3 | 3 | // A LogicalConnection is one independently cancellable typed session stream | |
| 4 | 4 | // multiplexed over one physical daemonmux Pump. It implements | |
| @@ -1,4 +1,4 @@ | |||||
| 1 | - | // Typed logical connections over one physical Pump (P3.2). | 1 | + | // Typed logical connections over one physical Pump. |
| 2 | // | 2 | // | ||
| 3 | // A LogicalConnection is one independently cancellable typed session stream | 3 | // A LogicalConnection is one independently cancellable typed session stream | ||
| 4 | // multiplexed over one physical daemonmux Pump. It implements | 4 | // multiplexed over one physical daemonmux Pump. It implements | ||
M internal/adapters/daemonmux/preamble.go +4 -4
| @@ -1,6 +1,6 @@ | |||
| 1 | 1 | package daemonmux | |
| 2 | 2 | ||
| 3 | - | // Daemonmux physical preamble (P3.2). | |
| 3 | + | // Daemonmux physical preamble. | |
| 4 | 4 | // | |
| 5 | 5 | // The first daemonmux client frame on a physical connection is always | |
| 6 | 6 | // MuxPreambleRequest; the first daemon frame is always MuxPreambleResponse. | |
| @@ -80,7 +80,7 @@ const ( | |||
| 80 | 80 | RejectionOutOfOrder uint32 = 6 | |
| 81 | 81 | // RejectionLimitRefused reports an unnegotiable advertisement. It also | |
| 82 | 82 | // covers nonzero capability bits and a policy the daemon does not | |
| 83 | - | // accept: P3.2 negotiates neither capabilities nor a merged policy | |
| 83 | + | // accept: the protocol negotiates neither capabilities nor a merged policy | |
| 84 | 84 | // server, so either is an unnegotiable advertisement. | |
| 85 | 85 | RejectionLimitRefused uint32 = 7 | |
| 86 | 86 | ) | |
| @@ -350,7 +350,7 @@ func DecodePreambleResponseBytes(payload []byte) (MuxPreambleResponse, error) { | |||
| 350 | 350 | // RejectionCodeFor maps a preamble validation failure to its precise refusal | |
| 351 | 351 | // code. Limit, magic, epoch, version, role, and policy failures each carry | |
| 352 | 352 | // their own code; nonzero capability bits are refused as | |
| 353 | - | // RejectionLimitRefused because P3.2 negotiates no capabilities; unknown scan | |
| 353 | + | // RejectionLimitRefused because the protocol negotiates no capabilities; unknown scan | |
| 354 | 354 | // failures are limit refusals. A duplicate inside one frame | |
| 355 | 355 | // (wire.ErrScanDuplicate) maps to RejectionDuplicate with the in-frame meaning | |
| 356 | 356 | // described above, never the dispatcher's cross-frame duplicate. Code 6 is | |
| @@ -373,7 +373,7 @@ func RejectionCodeFor(request *wire.MuxPreambleRequest, err error) uint32 { | |||
| 373 | 373 | return RejectionWrongRole | |
| 374 | 374 | } | |
| 375 | 375 | if request.GetCapabilityBits() != 0 { | |
| 376 | - | // No capability is negotiable in P3.2, so any bit is a refused | |
| 376 | + | // No capability is negotiable here, so any bit is a refused | |
| 377 | 377 | // limit advertisement (code 7), documented explicitly. | |
| 378 | 378 | return RejectionLimitRefused | |
| 379 | 379 | } | |
| @@ -1,6 +1,6 @@ | |||||
| 1 | package daemonmux | 1 | package daemonmux | ||
| 2 | 2 | ||||
| 3 | - | // Daemonmux physical preamble (P3.2). | 3 | + | // Daemonmux physical preamble. |
| 4 | // | 4 | // | ||
| 5 | // The first daemonmux client frame on a physical connection is always | 5 | // The first daemonmux client frame on a physical connection is always | ||
| 6 | // MuxPreambleRequest; the first daemon frame is always MuxPreambleResponse. | 6 | // MuxPreambleRequest; the first daemon frame is always MuxPreambleResponse. | ||
| @@ -80,7 +80,7 @@ const ( | |||||
| 80 | RejectionOutOfOrder uint32 = 6 | 80 | RejectionOutOfOrder uint32 = 6 | ||
| 81 | // RejectionLimitRefused reports an unnegotiable advertisement. It also | 81 | // RejectionLimitRefused reports an unnegotiable advertisement. It also | ||
| 82 | // covers nonzero capability bits and a policy the daemon does not | 82 | // covers nonzero capability bits and a policy the daemon does not | ||
| 83 | - | // accept: P3.2 negotiates neither capabilities nor a merged policy | 83 | + | // accept: the protocol negotiates neither capabilities nor a merged policy |
| 84 | // server, so either is an unnegotiable advertisement. | 84 | // server, so either is an unnegotiable advertisement. | ||
| 85 | RejectionLimitRefused uint32 = 7 | 85 | RejectionLimitRefused uint32 = 7 | ||
| 86 | ) | 86 | ) | ||
| @@ -350,7 +350,7 @@ func DecodePreambleResponseBytes(payload []byte) (MuxPreambleResponse, error) { | |||||
| 350 | // RejectionCodeFor maps a preamble validation failure to its precise refusal | 350 | // RejectionCodeFor maps a preamble validation failure to its precise refusal | ||
| 351 | // code. Limit, magic, epoch, version, role, and policy failures each carry | 351 | // code. Limit, magic, epoch, version, role, and policy failures each carry | ||
| 352 | // their own code; nonzero capability bits are refused as | 352 | // their own code; nonzero capability bits are refused as | ||
| 353 | - | // RejectionLimitRefused because P3.2 negotiates no capabilities; unknown scan | 353 | + | // RejectionLimitRefused because the protocol negotiates no capabilities; unknown scan |
| 354 | // failures are limit refusals. A duplicate inside one frame | 354 | // failures are limit refusals. A duplicate inside one frame | ||
| 355 | // (wire.ErrScanDuplicate) maps to RejectionDuplicate with the in-frame meaning | 355 | // (wire.ErrScanDuplicate) maps to RejectionDuplicate with the in-frame meaning | ||
| 356 | // described above, never the dispatcher's cross-frame duplicate. Code 6 is | 356 | // described above, never the dispatcher's cross-frame duplicate. Code 6 is | ||
| @@ -373,7 +373,7 @@ func RejectionCodeFor(request *wire.MuxPreambleRequest, err error) uint32 { | |||||
| 373 | return RejectionWrongRole | 373 | return RejectionWrongRole | ||
| 374 | } | 374 | } | ||
| 375 | if request.GetCapabilityBits() != 0 { | 375 | if request.GetCapabilityBits() != 0 { | ||
| 376 | - | // No capability is negotiable in P3.2, so any bit is a refused | 376 | + | // No capability is negotiable here, so any bit is a refused |
| 377 | // limit advertisement (code 7), documented explicitly. | 377 | // limit advertisement (code 7), documented explicitly. | ||
| 378 | return RejectionLimitRefused | 378 | return RejectionLimitRefused | ||
| 379 | } | 379 | } | ||
M internal/adapters/daemonmux/pump.go +1 -1
| @@ -1,4 +1,4 @@ | |||
| 1 | - | // Physical pump over an abstract framed carrier (P3.2). | |
| 1 | + | // Physical pump over an abstract framed carrier. | |
| 2 | 2 | // | |
| 3 | 3 | // Pump is the in-memory physical half of one daemonmux connection. It | |
| 4 | 4 | // composes the stateless directional codec (codec.go), the StreamEngine | |
| @@ -1,4 +1,4 @@ | |||||
| 1 | - | // Physical pump over an abstract framed carrier (P3.2). | 1 | + | // Physical pump over an abstract framed carrier. |
| 2 | // | 2 | // | ||
| 3 | // Pump is the in-memory physical half of one daemonmux connection. It | 3 | // Pump is the in-memory physical half of one daemonmux connection. It | ||
| 4 | // composes the stateless directional codec (codec.go), the StreamEngine | 4 | // composes the stateless directional codec (codec.go), the StreamEngine | ||
M internal/adapters/daemonmux/scheduler.go +1 -1
| @@ -1,4 +1,4 @@ | |||
| 1 | - | // Outbound fair scheduling (P3.2). | |
| 1 | + | // Outbound fair scheduling. | |
| 2 | 2 | // | |
| 3 | 3 | // Scheduler is the outbound companion of the StreamEngine on one physical | |
| 4 | 4 | // daemonmux connection. It owns one bounded, independently cancellable FIFO | |
| @@ -1,4 +1,4 @@ | |||||
| 1 | - | // Outbound fair scheduling (P3.2). | 1 | + | // Outbound fair scheduling. |
| 2 | // | 2 | // | ||
| 3 | // Scheduler is the outbound companion of the StreamEngine on one physical | 3 | // Scheduler is the outbound companion of the StreamEngine on one physical | ||
| 4 | // daemonmux connection. It owns one bounded, independently cancellable FIFO | 4 | // daemonmux connection. It owns one bounded, independently cancellable FIFO | ||
M internal/adapters/daemonmux/supervisor.go +1 -1
| @@ -1,4 +1,4 @@ | |||
| 1 | - | // Server supervisor over accepted raw physical carriers (P3.2c). | |
| 1 | + | // Server supervisor over accepted raw physical carriers. | |
| 2 | 2 | // | |
| 3 | 3 | // ServerSupervisor is the daemon-side owner of accepted daemonmux physical | |
| 4 | 4 | // connections. A daemon accept loop hands it one authenticated raw framed | |
| @@ -1,4 +1,4 @@ | |||||
| 1 | - | // Server supervisor over accepted raw physical carriers (P3.2c). | 1 | + | // Server supervisor over accepted raw physical carriers. |
| 2 | // | 2 | // | ||
| 3 | // ServerSupervisor is the daemon-side owner of accepted daemonmux physical | 3 | // ServerSupervisor is the daemon-side owner of accepted daemonmux physical | ||
| 4 | // connections. A daemon accept loop hands it one authenticated raw framed | 4 | // connections. A daemon accept loop hands it one authenticated raw framed | ||
M internal/adapters/ipc/mux.go +1 -1
| @@ -1,4 +1,4 @@ | |||
| 1 | - | // Private daemonmux Unix carriage (P3.2d). | |
| 1 | + | // Private daemonmux Unix carriage. | |
| 2 | 2 | // | |
| 3 | 3 | // This file exposes the explicit, mux-specific raw Unix carriage that the | |
| 4 | 4 | // daemonmux multiplexer (internal/adapters/daemonmux) runs over. It is | |
| @@ -1,4 +1,4 @@ | |||||
| 1 | - | // Private daemonmux Unix carriage (P3.2d). | 1 | + | // Private daemonmux Unix carriage. |
| 2 | // | 2 | // | ||
| 3 | // This file exposes the explicit, mux-specific raw Unix carriage that the | 3 | // This file exposes the explicit, mux-specific raw Unix carriage that the | ||
| 4 | // daemonmux multiplexer (internal/adapters/daemonmux) runs over. It is | 4 | // daemonmux multiplexer (internal/adapters/daemonmux) runs over. It is | ||
M internal/adapters/quic/bootstrap.go +1 -1
| @@ -20,7 +20,7 @@ import ( | |||
| 20 | 20 | "github.com/bnema/vev/internal/protocol/wire" | |
| 21 | 21 | ) | |
| 22 | 22 | ||
| 23 | - | // Bootstrap normative bounds (P6.2): ephemeral listener/certificate, | |
| 23 | + | // Bootstrap normative bounds: ephemeral listener/certificate, | |
| 24 | 24 | // 32-byte token, nonce, ≤4 KiB readiness, ≤15-second expiry, exact | |
| 25 | 25 | // SHA-256 pin, one bounded auth record, atomic one-time consumption, | |
| 26 | 26 | // ≤4 unauthenticated peers, 3-second auth deadline, exactly one | |
| @@ -20,7 +20,7 @@ import ( | |||||
| 20 | "github.com/bnema/vev/internal/protocol/wire" | 20 | "github.com/bnema/vev/internal/protocol/wire" | ||
| 21 | ) | 21 | ) | ||
| 22 | 22 | ||||
| 23 | - | // Bootstrap normative bounds (P6.2): ephemeral listener/certificate, | 23 | + | // Bootstrap normative bounds: ephemeral listener/certificate, |
| 24 | // 32-byte token, nonce, ≤4 KiB readiness, ≤15-second expiry, exact | 24 | // 32-byte token, nonce, ≤4 KiB readiness, ≤15-second expiry, exact | ||
| 25 | // SHA-256 pin, one bounded auth record, atomic one-time consumption, | 25 | // SHA-256 pin, one bounded auth record, atomic one-time consumption, | ||
| 26 | // ≤4 unauthenticated peers, 3-second auth deadline, exactly one | 26 | // ≤4 unauthenticated peers, 3-second auth deadline, exactly one | ||
M internal/adapters/quic/mux.go +1 -1
| @@ -1,4 +1,4 @@ | |||
| 1 | - | // Private daemonmux QUIC carriage (P3.2e). | |
| 1 | + | // Private daemonmux QUIC carriage. | |
| 2 | 2 | // | |
| 3 | 3 | // This file exposes the explicit, mux-specific raw QUIC carriage the daemonmux | |
| 4 | 4 | // multiplexer (internal/adapters/daemonmux) runs over. It introduces no | |
| @@ -1,4 +1,4 @@ | |||||
| 1 | - | // Private daemonmux QUIC carriage (P3.2e). | 1 | + | // Private daemonmux QUIC carriage. |
| 2 | // | 2 | // | ||
| 3 | // This file exposes the explicit, mux-specific raw QUIC carriage the daemonmux | 3 | // This file exposes the explicit, mux-specific raw QUIC carriage the daemonmux | ||
| 4 | // multiplexer (internal/adapters/daemonmux) runs over. It introduces no | 4 | // multiplexer (internal/adapters/daemonmux) runs over. It introduces no | ||
M internal/adapters/quic/quic.go +1 -1
| @@ -141,7 +141,7 @@ func clientQUICConfig(config Config) *quicgo.Config { | |||
| 141 | 141 | ||
| 142 | 142 | // serverTLSConfig presents cert and requires TLS 1.3 with the epoch ALPN. | |
| 143 | 143 | // Client certificates are not used: authentication is the SHA-256 pin | |
| 144 | - | // checked by the dialer plus the bootstrap token consumed by P6.2. | |
| 144 | + | // checked by the dialer plus the bootstrap token consumed during authentication. | |
| 145 | 145 | func serverTLSConfig(cert tls.Certificate) *tls.Config { | |
| 146 | 146 | return &tls.Config{ | |
| 147 | 147 | Certificates: []tls.Certificate{cert}, | |
| @@ -141,7 +141,7 @@ func clientQUICConfig(config Config) *quicgo.Config { | |||||
| 141 | 141 | ||||
| 142 | // serverTLSConfig presents cert and requires TLS 1.3 with the epoch ALPN. | 142 | // serverTLSConfig presents cert and requires TLS 1.3 with the epoch ALPN. | ||
| 143 | // Client certificates are not used: authentication is the SHA-256 pin | 143 | // Client certificates are not used: authentication is the SHA-256 pin | ||
| 144 | - | // checked by the dialer plus the bootstrap token consumed by P6.2. | 144 | + | // checked by the dialer plus the bootstrap token consumed during authentication. |
| 145 | func serverTLSConfig(cert tls.Certificate) *tls.Config { | 145 | func serverTLSConfig(cert tls.Certificate) *tls.Config { | ||
| 146 | return &tls.Config{ | 146 | return &tls.Config{ | ||
| 147 | Certificates: []tls.Certificate{cert}, | 147 | Certificates: []tls.Certificate{cert}, | ||
M internal/adapters/sessionwire/proto_convert_session.go +1 -1
| @@ -15,7 +15,7 @@ import ( | |||
| 15 | 15 | "github.com/bnema/vev/internal/protocol/wire" | |
| 16 | 16 | ) | |
| 17 | 17 | ||
| 18 | - | // outputCompressionThreshold mirrors the legacy codec: small snapshots stay | |
| 18 | + | // outputCompressionThreshold preserves the small-snapshot compression threshold: small snapshots stay | |
| 19 | 19 | // on the canonical raw path. | |
| 20 | 20 | const protoOutputCompressionThreshold = 1024 | |
| 21 | 21 | ||
| @@ -15,7 +15,7 @@ import ( | |||||
| 15 | "github.com/bnema/vev/internal/protocol/wire" | 15 | "github.com/bnema/vev/internal/protocol/wire" | ||
| 16 | ) | 16 | ) | ||
| 17 | 17 | ||||
| 18 | - | // outputCompressionThreshold mirrors the legacy codec: small snapshots stay | 18 | + | // outputCompressionThreshold preserves the small-snapshot compression threshold: small snapshots stay |
| 19 | // on the canonical raw path. | 19 | // on the canonical raw path. | ||
| 20 | const protoOutputCompressionThreshold = 1024 | 20 | const protoOutputCompressionThreshold = 1024 | ||
| 21 | 21 | ||||
M internal/adapters/sessionwire/proto_convert_shared.go +1 -1
| @@ -1,4 +1,4 @@ | |||
| 1 | - | // Protobuf semantic converters (P2.2, wired at the P3.3 cutover). | |
| 1 | + | // Protobuf semantic converters. | |
| 2 | 2 | // | |
| 3 | 3 | // This file owns every semantic protocol value <-> generated wire envelope | |
| 4 | 4 | // conversion used by client.go/server.go dispatch. The actual field-by-field | |
| @@ -1,4 +1,4 @@ | |||||
| 1 | - | // Protobuf semantic converters (P2.2, wired at the P3.3 cutover). | 1 | + | // Protobuf semantic converters. |
| 2 | // | 2 | // | ||
| 3 | // This file owns every semantic protocol value <-> generated wire envelope | 3 | // This file owns every semantic protocol value <-> generated wire envelope | ||
| 4 | // conversion used by client.go/server.go dispatch. The actual field-by-field | 4 | // conversion used by client.go/server.go dispatch. The actual field-by-field | ||
M internal/adapters/sessionwire/proto_envelope.go +1 -1
| @@ -1,6 +1,6 @@ | |||
| 1 | 1 | package sessionwire | |
| 2 | 2 | ||
| 3 | - | // Directional envelope adaptation (P2.2/P3.1, wired at the P3.3 cutover). | |
| 3 | + | // Directional envelope adaptation. | |
| 4 | 4 | // | |
| 5 | 5 | // encodeProtoClient/encodeProtoServer wrap one semantic message in its | |
| 6 | 6 | // directional envelope; decodeProtoClient/decodeProtoServer unwrap and | |
| @@ -1,6 +1,6 @@ | |||||
| 1 | package sessionwire | 1 | package sessionwire | ||
| 2 | 2 | ||||
| 3 | - | // Directional envelope adaptation (P2.2/P3.1, wired at the P3.3 cutover). | 3 | + | // Directional envelope adaptation. |
| 4 | // | 4 | // | ||
| 5 | // encodeProtoClient/encodeProtoServer wrap one semantic message in its | 5 | // encodeProtoClient/encodeProtoServer wrap one semantic message in its | ||
| 6 | // directional envelope; decodeProtoClient/decodeProtoServer unwrap and | 6 | // directional envelope; decodeProtoClient/decodeProtoServer unwrap and | ||
M internal/adapters/sessionwire/server.go +2 -3
| @@ -88,7 +88,7 @@ func NewServerConnectionWithDeadline(raw wire.Transport, deadline time.Time) por | |||
| 88 | 88 | // bounded environment). The admission is stored as a deep copy and exposed only | |
| 89 | 89 | // through SessionAdmission, which returns a fresh copy so a consumer can never | |
| 90 | 90 | // mutate admitted authority. An entirely zero admission is reported as ok=false, | |
| 91 | - | // exactly as the legacy constructors do, so a caller cannot accidentally | |
| 91 | + | // as absent, so a caller cannot accidentally | |
| 92 | 92 | // publish an unvalidated admission. | |
| 93 | 93 | func NewServerConnectionWithAdmission(raw wire.Transport, deadline time.Time, admission ports.SessionAdmission) ports.ServerConnection { | |
| 94 | 94 | return newServerConnection(raw, deadline, admission, !admissionAbsent(admission)) | |
| @@ -96,8 +96,7 @@ func NewServerConnectionWithAdmission(raw wire.Transport, deadline time.Time, ad | |||
| 96 | 96 | ||
| 97 | 97 | // admissionAbsent reports whether an admission is entirely unset. It is the | |
| 98 | 98 | // presence test for NewServerConnectionWithAdmission: an admission that names no | |
| 99 | - | // origin, policy, purpose, or payload is indistinguishable from the legacy | |
| 100 | - | // constructors' absent metadata and is reported as absent rather than trusted. | |
| 99 | + | // origin, policy, purpose, or payload is indistinguishable from absent metadata and is reported as absent rather than trusted. | |
| 101 | 100 | func admissionAbsent(admission ports.SessionAdmission) bool { | |
| 102 | 101 | return admission.Origin == 0 && admission.Policy == (ports.BrokerPolicy{}) && | |
| 103 | 102 | admission.Purpose == 0 && admission.Admission == 0 && admission.Name == "" && | |
| @@ -88,7 +88,7 @@ func NewServerConnectionWithDeadline(raw wire.Transport, deadline time.Time) por | |||||
| 88 | // bounded environment). The admission is stored as a deep copy and exposed only | 88 | // bounded environment). The admission is stored as a deep copy and exposed only | ||
| 89 | // through SessionAdmission, which returns a fresh copy so a consumer can never | 89 | // through SessionAdmission, which returns a fresh copy so a consumer can never | ||
| 90 | // mutate admitted authority. An entirely zero admission is reported as ok=false, | 90 | // mutate admitted authority. An entirely zero admission is reported as ok=false, | ||
| 91 | - | // exactly as the legacy constructors do, so a caller cannot accidentally | 91 | + | // as absent, so a caller cannot accidentally |
| 92 | // publish an unvalidated admission. | 92 | // publish an unvalidated admission. | ||
| 93 | func NewServerConnectionWithAdmission(raw wire.Transport, deadline time.Time, admission ports.SessionAdmission) ports.ServerConnection { | 93 | func NewServerConnectionWithAdmission(raw wire.Transport, deadline time.Time, admission ports.SessionAdmission) ports.ServerConnection { | ||
| 94 | return newServerConnection(raw, deadline, admission, !admissionAbsent(admission)) | 94 | return newServerConnection(raw, deadline, admission, !admissionAbsent(admission)) | ||
| @@ -96,8 +96,7 @@ func NewServerConnectionWithAdmission(raw wire.Transport, deadline time.Time, ad | |||||
| 96 | 96 | ||||
| 97 | // admissionAbsent reports whether an admission is entirely unset. It is the | 97 | // admissionAbsent reports whether an admission is entirely unset. It is the | ||
| 98 | // presence test for NewServerConnectionWithAdmission: an admission that names no | 98 | // presence test for NewServerConnectionWithAdmission: an admission that names no | ||
| 99 | - | // origin, policy, purpose, or payload is indistinguishable from the legacy | 99 | + | // origin, policy, purpose, or payload is indistinguishable from absent metadata and is reported as absent rather than trusted. |
| 100 | - | // constructors' absent metadata and is reported as absent rather than trusted. | |||
| 101 | func admissionAbsent(admission ports.SessionAdmission) bool { | 100 | func admissionAbsent(admission ports.SessionAdmission) bool { | ||
| 102 | return admission.Origin == 0 && admission.Policy == (ports.BrokerPolicy{}) && | 101 | return admission.Origin == 0 && admission.Policy == (ports.BrokerPolicy{}) && | ||
| 103 | admission.Purpose == 0 && admission.Admission == 0 && admission.Name == "" && | 102 | admission.Purpose == 0 && admission.Admission == 0 && admission.Name == "" && | ||
M internal/adapters/sshstdio/mux.go +1 -1
| @@ -1,4 +1,4 @@ | |||
| 1 | - | // SSH stdio daemonmux carriage (P3.2e parity). | |
| 1 | + | // SSH stdio daemonmux carriage. | |
| 2 | 2 | // | |
| 3 | 3 | // This file exposes the mux-specific SSH stdio carriage the daemonmux | |
| 4 | 4 | // multiplexer (internal/adapters/daemonmux) runs over. It is deliberately | |
| @@ -1,4 +1,4 @@ | |||||
| 1 | - | // SSH stdio daemonmux carriage (P3.2e parity). | 1 | + | // SSH stdio daemonmux carriage. |
| 2 | // | 2 | // | ||
| 3 | // This file exposes the mux-specific SSH stdio carriage the daemonmux | 3 | // This file exposes the mux-specific SSH stdio carriage the daemonmux | ||
| 4 | // multiplexer (internal/adapters/daemonmux) runs over. It is deliberately | 4 | // multiplexer (internal/adapters/daemonmux) runs over. It is deliberately | ||
M internal/app/broker_client.go +1 -1
| @@ -20,7 +20,7 @@ import ( | |||
| 20 | 20 | "github.com/bnema/vev/internal/usecase/client" | |
| 21 | 21 | ) | |
| 22 | 22 | ||
| 23 | - | // Common broker client composition (Plan 001 P7.4a). | |
| 23 | + | // Common broker client composition. | |
| 24 | 24 | // | |
| 25 | 25 | // runBrokerClient is the single terminal composition every frontend promotes: | |
| 26 | 26 | // the sandbox terminal harness, the sandbox UI-driver harness, and the ordinary | |
| @@ -20,7 +20,7 @@ import ( | |||||
| 20 | "github.com/bnema/vev/internal/usecase/client" | 20 | "github.com/bnema/vev/internal/usecase/client" | ||
| 21 | ) | 21 | ) | ||
| 22 | 22 | ||||
| 23 | - | // Common broker client composition (Plan 001 P7.4a). | 23 | + | // Common broker client composition. |
| 24 | // | 24 | // | ||
| 25 | // runBrokerClient is the single terminal composition every frontend promotes: | 25 | // runBrokerClient is the single terminal composition every frontend promotes: | ||
| 26 | // the sandbox terminal harness, the sandbox UI-driver harness, and the ordinary | 26 | // the sandbox terminal harness, the sandbox UI-driver harness, and the ordinary | ||
M internal/app/broker_daemon_start.go +1 -1
| @@ -14,7 +14,7 @@ import ( | |||
| 14 | 14 | "github.com/bnema/vev/internal/ports" | |
| 15 | 15 | ) | |
| 16 | 16 | ||
| 17 | - | // Broker-owned daemon start (Plan 001 P7, UI-driver slice 1). | |
| 17 | + | // Broker-owned daemon start. | |
| 18 | 18 | // | |
| 19 | 19 | // The broker is the only component that decides whether a target daemon may be | |
| 20 | 20 | // started. Its resolved dial target already carries the closed start | |
| @@ -14,7 +14,7 @@ import ( | |||||
| 14 | "github.com/bnema/vev/internal/ports" | 14 | "github.com/bnema/vev/internal/ports" | ||
| 15 | ) | 15 | ) | ||
| 16 | 16 | ||||
| 17 | - | // Broker-owned daemon start (Plan 001 P7, UI-driver slice 1). | 17 | + | // Broker-owned daemon start. |
| 18 | // | 18 | // | ||
| 19 | // The broker is the only component that decides whether a target daemon may be | 19 | // The broker is the only component that decides whether a target daemon may be | ||
| 20 | // started. Its resolved dial target already carries the closed start | 20 | // started. Its resolved dial target already carries the closed start | ||
M internal/app/broker_offline.go +4 -4
| @@ -30,11 +30,11 @@ import ( | |||
| 30 | 30 | "github.com/bnema/vev/pkg/safedir" | |
| 31 | 31 | ) | |
| 32 | 32 | ||
| 33 | - | // Offline broker foreground composition (Plan 001 P3.4 slice C). | |
| 33 | + | // Offline broker foreground composition. | |
| 34 | 34 | // | |
| 35 | 35 | // `_broker-serve` is a hidden, isolated sandbox command. It takes one strict | |
| 36 | 36 | // offline root, derives only sandbox runtime, state, and log paths from it, and | |
| 37 | - | // composes the P3.4 broker core and P3.3 local IPC listener over the immutable | |
| 37 | + | // composes the broker core and local IPC listener over the immutable | |
| 38 | 38 | // config marker. It never reads or writes production runtime, state, or config | |
| 39 | 39 | // and never changes an ordinary command, path, or factory. | |
| 40 | 40 | // | |
| @@ -337,8 +337,8 @@ func runBrokerServe(ctx context.Context, options brokerServeOptions, deps broker | |||
| 337 | 337 | ||
| 338 | 338 | if options.production { | |
| 339 | 339 | // The durable route schema intentionally delegates SSH trust to OpenSSH. | |
| 340 | - | // Refuse nonrepresentable legacy overrides rather than silently dropping | |
| 341 | - | // security inputs during the one-time production import. | |
| 340 | + | // Refuse route overrides that OpenSSH configuration must represent instead of dropping | |
| 341 | + | // security inputs during production import. | |
| 342 | 342 | for _, endpoint := range config.Endpoints() { | |
| 343 | 343 | registration, _ := config.Registration(endpoint) | |
| 344 | 344 | if registration.Route.KnownHostsFile() != "" || registration.Route.ConnectTimeout() != 0 { | |
| @@ -30,11 +30,11 @@ import ( | |||||
| 30 | "github.com/bnema/vev/pkg/safedir" | 30 | "github.com/bnema/vev/pkg/safedir" | ||
| 31 | ) | 31 | ) | ||
| 32 | 32 | ||||
| 33 | - | // Offline broker foreground composition (Plan 001 P3.4 slice C). | 33 | + | // Offline broker foreground composition. |
| 34 | // | 34 | // | ||
| 35 | // `_broker-serve` is a hidden, isolated sandbox command. It takes one strict | 35 | // `_broker-serve` is a hidden, isolated sandbox command. It takes one strict | ||
| 36 | // offline root, derives only sandbox runtime, state, and log paths from it, and | 36 | // offline root, derives only sandbox runtime, state, and log paths from it, and | ||
| 37 | - | // composes the P3.4 broker core and P3.3 local IPC listener over the immutable | 37 | + | // composes the broker core and local IPC listener over the immutable |
| 38 | // config marker. It never reads or writes production runtime, state, or config | 38 | // config marker. It never reads or writes production runtime, state, or config | ||
| 39 | // and never changes an ordinary command, path, or factory. | 39 | // and never changes an ordinary command, path, or factory. | ||
| 40 | // | 40 | // | ||
| @@ -337,8 +337,8 @@ func runBrokerServe(ctx context.Context, options brokerServeOptions, deps broker | |||||
| 337 | 337 | ||||
| 338 | if options.production { | 338 | if options.production { | ||
| 339 | // The durable route schema intentionally delegates SSH trust to OpenSSH. | 339 | // The durable route schema intentionally delegates SSH trust to OpenSSH. | ||
| 340 | - | // Refuse nonrepresentable legacy overrides rather than silently dropping | 340 | + | // Refuse route overrides that OpenSSH configuration must represent instead of dropping |
| 341 | - | // security inputs during the one-time production import. | 341 | + | // security inputs during production import. |
| 342 | for _, endpoint := range config.Endpoints() { | 342 | for _, endpoint := range config.Endpoints() { | ||
| 343 | registration, _ := config.Registration(endpoint) | 343 | registration, _ := config.Registration(endpoint) | ||
| 344 | if registration.Route.KnownHostsFile() != "" || registration.Route.ConnectTimeout() != 0 { | 344 | if registration.Route.KnownHostsFile() != "" || registration.Route.ConnectTimeout() != 0 { | ||
M internal/app/broker_offline_client.go +1 -1
| @@ -17,7 +17,7 @@ import ( | |||
| 17 | 17 | "github.com/bnema/vev/internal/usecase/client" | |
| 18 | 18 | ) | |
| 19 | 19 | ||
| 20 | - | // brokerClientCommand is the hidden P5.4b client entry point. It is deliberately | |
| 20 | + | // brokerClientCommand is the hidden client entry point. It is deliberately | |
| 21 | 21 | // separate from every ordinary attach, UI-driver, and web command: only an | |
| 22 | 22 | // explicitly supplied offline root can select the broker sandbox. | |
| 23 | 23 | const brokerClientCommand = "_broker-client" | |
| @@ -17,7 +17,7 @@ import ( | |||||
| 17 | "github.com/bnema/vev/internal/usecase/client" | 17 | "github.com/bnema/vev/internal/usecase/client" | ||
| 18 | ) | 18 | ) | ||
| 19 | 19 | ||||
| 20 | - | // brokerClientCommand is the hidden P5.4b client entry point. It is deliberately | 20 | + | // brokerClientCommand is the hidden client entry point. It is deliberately |
| 21 | // separate from every ordinary attach, UI-driver, and web command: only an | 21 | // separate from every ordinary attach, UI-driver, and web command: only an | ||
| 22 | // explicitly supplied offline root can select the broker sandbox. | 22 | // explicitly supplied offline root can select the broker sandbox. | ||
| 23 | const brokerClientCommand = "_broker-client" | 23 | const brokerClientCommand = "_broker-client" | ||
M internal/app/broker_offline_local.go +1 -1
| @@ -12,7 +12,7 @@ import ( | |||
| 12 | 12 | "github.com/bnema/vev/internal/usecase/broker" | |
| 13 | 13 | ) | |
| 14 | 14 | ||
| 15 | - | // Broker-owned local observation composition (Plan 001 P5.3a, P7.4b). | |
| 15 | + | // Broker-owned local observation composition. | |
| 16 | 16 | // | |
| 17 | 17 | // The offline broker observes its own machine daemon through the same daemonmux | |
| 18 | 18 | // carriage a local logical stream is dialed over. The probe completes the | |
| @@ -12,7 +12,7 @@ import ( | |||||
| 12 | "github.com/bnema/vev/internal/usecase/broker" | 12 | "github.com/bnema/vev/internal/usecase/broker" | ||
| 13 | ) | 13 | ) | ||
| 14 | 14 | ||||
| 15 | - | // Broker-owned local observation composition (Plan 001 P5.3a, P7.4b). | 15 | + | // Broker-owned local observation composition. |
| 16 | // | 16 | // | ||
| 17 | // The offline broker observes its own machine daemon through the same daemonmux | 17 | // The offline broker observes its own machine daemon through the same daemonmux | ||
| 18 | // carriage a local logical stream is dialed over. The probe completes the | 18 | // carriage a local logical stream is dialed over. The probe completes the | ||
M internal/app/broker_offline_mux.go +1 -1
| @@ -23,7 +23,7 @@ import ( | |||
| 23 | 23 | "github.com/bnema/vev/internal/protocol/wire" | |
| 24 | 24 | ) | |
| 25 | 25 | ||
| 26 | - | // Broker mux remote helper composition (Plan 001 P3.4 slice E). | |
| 26 | + | // Broker mux remote helper composition. | |
| 27 | 27 | // | |
| 28 | 28 | // The offline broker reaches a remote daemon's private daemonmux carriage | |
| 29 | 29 | // through one of three explicitly provisioned routes: a local Unix mux socket, | |
| @@ -23,7 +23,7 @@ import ( | |||||
| 23 | "github.com/bnema/vev/internal/protocol/wire" | 23 | "github.com/bnema/vev/internal/protocol/wire" | ||
| 24 | ) | 24 | ) | ||
| 25 | 25 | ||||
| 26 | - | // Broker mux remote helper composition (Plan 001 P3.4 slice E). | 26 | + | // Broker mux remote helper composition. |
| 27 | // | 27 | // | ||
| 28 | // The offline broker reaches a remote daemon's private daemonmux carriage | 28 | // The offline broker reaches a remote daemon's private daemonmux carriage | ||
| 29 | // through one of three explicitly provisioned routes: a local Unix mux socket, | 29 | // through one of three explicitly provisioned routes: a local Unix mux socket, | ||
M internal/app/broker_offline_status.go +1 -1
| @@ -25,7 +25,7 @@ import ( | |||
| 25 | 25 | "github.com/bnema/vev/pkg/safedir" | |
| 26 | 26 | ) | |
| 27 | 27 | ||
| 28 | - | // Detached connect-or-spawn and status (Plan 001 P3.4 slice D). | |
| 28 | + | // Detached connect-or-spawn and status. | |
| 29 | 29 | // | |
| 30 | 30 | // `_broker-launcher` is the intermediate half of a double fork: it starts one | |
| 31 | 31 | // hidden `_broker-serve` in a new session and exits immediately, exactly like | |
| @@ -25,7 +25,7 @@ import ( | |||||
| 25 | "github.com/bnema/vev/pkg/safedir" | 25 | "github.com/bnema/vev/pkg/safedir" | ||
| 26 | ) | 26 | ) | ||
| 27 | 27 | ||||
| 28 | - | // Detached connect-or-spawn and status (Plan 001 P3.4 slice D). | 28 | + | // Detached connect-or-spawn and status. |
| 29 | // | 29 | // | ||
| 30 | // `_broker-launcher` is the intermediate half of a double fork: it starts one | 30 | // `_broker-launcher` is the intermediate half of a double fork: it starts one | ||
| 31 | // hidden `_broker-serve` in a new session and exits immediately, exactly like | 31 | // hidden `_broker-serve` in a new session and exits immediately, exactly like | ||
M internal/app/broker_remote_probe.go +1 -1
| @@ -15,7 +15,7 @@ import ( | |||
| 15 | 15 | "github.com/bnema/vev/internal/protocol/catalogue" | |
| 16 | 16 | ) | |
| 17 | 17 | ||
| 18 | - | // Remote daemon observation composition (Plan 001 P7.4b). | |
| 18 | + | // Remote daemon observation composition. | |
| 19 | 19 | // | |
| 20 | 20 | // brokerRemoteProbe observes one configured daemon over the broker-owned | |
| 21 | 21 | // multiplexed carriage. It opens an observation stream, never an attachment, | |
| @@ -15,7 +15,7 @@ import ( | |||||
| 15 | "github.com/bnema/vev/internal/protocol/catalogue" | 15 | "github.com/bnema/vev/internal/protocol/catalogue" | ||
| 16 | ) | 16 | ) | ||
| 17 | 17 | ||||
| 18 | - | // Remote daemon observation composition (Plan 001 P7.4b). | 18 | + | // Remote daemon observation composition. |
| 19 | // | 19 | // | ||
| 20 | // brokerRemoteProbe observes one configured daemon over the broker-owned | 20 | // brokerRemoteProbe observes one configured daemon over the broker-owned | ||
| 21 | // multiplexed carriage. It opens an observation stream, never an attachment, | 21 | // multiplexed carriage. It opens an observation stream, never an attachment, | ||
M internal/app/connectivity_matrix.go +3 -3
| @@ -1,9 +1,9 @@ | |||
| 1 | 1 | package app | |
| 2 | 2 | ||
| 3 | - | // Connectivity migration matrix (Plan 001 P1.2). | |
| 3 | + | // Connectivity migration matrix. | |
| 4 | 4 | // | |
| 5 | - | // Every CLI entry point has exactly one owner. After the P7 cutover, all | |
| 6 | - | // ordinary user-facing operations reach daemons through the per-user | |
| 5 | + | // Every CLI entry point has exactly one owner. Ordinary user-facing | |
| 6 | + | // operations reach daemons through the per-user | |
| 7 | 7 | // connection broker; narrowly scoped daemon-facing transport helpers stay | |
| 8 | 8 | // infrastructure and never become alternate client façades. | |
| 9 | 9 | // | |
| @@ -1,9 +1,9 @@ | |||||
| 1 | package app | 1 | package app | ||
| 2 | 2 | ||||
| 3 | - | // Connectivity migration matrix (Plan 001 P1.2). | 3 | + | // Connectivity migration matrix. |
| 4 | // | 4 | // | ||
| 5 | - | // Every CLI entry point has exactly one owner. After the P7 cutover, all | 5 | + | // Every CLI entry point has exactly one owner. Ordinary user-facing |
| 6 | - | // ordinary user-facing operations reach daemons through the per-user | 6 | + | // operations reach daemons through the per-user |
| 7 | // connection broker; narrowly scoped daemon-facing transport helpers stay | 7 | // connection broker; narrowly scoped daemon-facing transport helpers stay | ||
| 8 | // infrastructure and never become alternate client façades. | 8 | // infrastructure and never become alternate client façades. | ||
| 9 | // | 9 | // | ||
M internal/ports/broker.go +4 -5
| @@ -13,7 +13,7 @@ import ( | |||
| 13 | 13 | "github.com/bnema/vev/internal/protocol/catalogue" | |
| 14 | 14 | ) | |
| 15 | 15 | ||
| 16 | - | // Broker semantic contracts (Plan 001 P1.3). | |
| 16 | + | // Broker semantic contracts. | |
| 17 | 17 | // | |
| 18 | 18 | // The broker is the machine-wide owner of connectivity: configured hosts, | |
| 19 | 19 | // daemon reachability and catalogue snapshots, pooled physical transports, | |
| @@ -234,7 +234,7 @@ func (t BrokerHostTombstone) Fences(candidate domain.RemoteRegistration) bool { | |||
| 234 | 234 | } | |
| 235 | 235 | ||
| 236 | 236 | // BrokerSnapshot is an immutable, fully defensive broker publication. | |
| 237 | - | // Daemons carries the broker-native daemon observations (Plan 001 P5.2a): | |
| 237 | + | // Daemons carries the broker-native daemon observations: | |
| 238 | 238 | // the local daemon entry first when present, then remote hosts in | |
| 239 | 239 | // registration order. Removed carries the bounded tombstone set that fences | |
| 240 | 240 | // stale authority. Nested slices are never mutated after publication. | |
| @@ -336,8 +336,7 @@ func (s BrokerSnapshot) Supersedes(other BrokerSnapshot) bool { | |||
| 336 | 336 | return s.Revision > other.Revision | |
| 337 | 337 | } | |
| 338 | 338 | ||
| 339 | - | // BrokerStreamAdmission is the closed attachment-admission taxonomy | |
| 340 | - | // (Plan 001 P5.3a, contract-only until the admission slice wires it): | |
| 339 | + | // BrokerStreamAdmission is the closed attachment-admission taxonomy: | |
| 341 | 340 | // an attachment stream names exactly how the daemon must admit it. | |
| 342 | 341 | // Control and observation streams carry no admission. | |
| 343 | 342 | type BrokerStreamAdmission uint8 | |
| @@ -862,7 +861,7 @@ type BrokerService interface { | |||
| 862 | 861 | // stays daemon-owned and is never moved here. Load is called once while the | |
| 863 | 862 | // broker is constructed; Store runs on the broker's serialized writer | |
| 864 | 863 | // goroutine. Store must return promptly and must never block indefinitely: | |
| 865 | - | // this seam deliberately carries no cancellation context in P2.1, and broker | |
| 864 | + | // this seam deliberately carries no cancellation context, and broker | |
| 866 | 865 | // shutdown waits for the in-flight write to finish, so a Store that blocks | |
| 867 | 866 | // without bound blocks shutdown. Implementations must bound their own write | |
| 868 | 867 | // time and return an error rather than wait forever. | |
| @@ -13,7 +13,7 @@ import ( | |||||
| 13 | "github.com/bnema/vev/internal/protocol/catalogue" | 13 | "github.com/bnema/vev/internal/protocol/catalogue" | ||
| 14 | ) | 14 | ) | ||
| 15 | 15 | ||||
| 16 | - | // Broker semantic contracts (Plan 001 P1.3). | 16 | + | // Broker semantic contracts. |
| 17 | // | 17 | // | ||
| 18 | // The broker is the machine-wide owner of connectivity: configured hosts, | 18 | // The broker is the machine-wide owner of connectivity: configured hosts, | ||
| 19 | // daemon reachability and catalogue snapshots, pooled physical transports, | 19 | // daemon reachability and catalogue snapshots, pooled physical transports, | ||
| @@ -234,7 +234,7 @@ func (t BrokerHostTombstone) Fences(candidate domain.RemoteRegistration) bool { | |||||
| 234 | } | 234 | } | ||
| 235 | 235 | ||||
| 236 | // BrokerSnapshot is an immutable, fully defensive broker publication. | 236 | // BrokerSnapshot is an immutable, fully defensive broker publication. | ||
| 237 | - | // Daemons carries the broker-native daemon observations (Plan 001 P5.2a): | 237 | + | // Daemons carries the broker-native daemon observations: |
| 238 | // the local daemon entry first when present, then remote hosts in | 238 | // the local daemon entry first when present, then remote hosts in | ||
| 239 | // registration order. Removed carries the bounded tombstone set that fences | 239 | // registration order. Removed carries the bounded tombstone set that fences | ||
| 240 | // stale authority. Nested slices are never mutated after publication. | 240 | // stale authority. Nested slices are never mutated after publication. | ||
| @@ -336,8 +336,7 @@ func (s BrokerSnapshot) Supersedes(other BrokerSnapshot) bool { | |||||
| 336 | return s.Revision > other.Revision | 336 | return s.Revision > other.Revision | ||
| 337 | } | 337 | } | ||
| 338 | 338 | ||||
| 339 | - | // BrokerStreamAdmission is the closed attachment-admission taxonomy | 339 | + | // BrokerStreamAdmission is the closed attachment-admission taxonomy: |
| 340 | - | // (Plan 001 P5.3a, contract-only until the admission slice wires it): | |||
| 341 | // an attachment stream names exactly how the daemon must admit it. | 340 | // an attachment stream names exactly how the daemon must admit it. | ||
| 342 | // Control and observation streams carry no admission. | 341 | // Control and observation streams carry no admission. | ||
| 343 | type BrokerStreamAdmission uint8 | 342 | type BrokerStreamAdmission uint8 | ||
| @@ -862,7 +861,7 @@ type BrokerService interface { | |||||
| 862 | // stays daemon-owned and is never moved here. Load is called once while the | 861 | // stays daemon-owned and is never moved here. Load is called once while the | ||
| 863 | // broker is constructed; Store runs on the broker's serialized writer | 862 | // broker is constructed; Store runs on the broker's serialized writer | ||
| 864 | // goroutine. Store must return promptly and must never block indefinitely: | 863 | // goroutine. Store must return promptly and must never block indefinitely: | ||
| 865 | - | // this seam deliberately carries no cancellation context in P2.1, and broker | 864 | + | // this seam deliberately carries no cancellation context, and broker |
| 866 | // shutdown waits for the in-flight write to finish, so a Store that blocks | 865 | // shutdown waits for the in-flight write to finish, so a Store that blocks | ||
| 867 | // without bound blocks shutdown. Implementations must bound their own write | 866 | // without bound blocks shutdown. Implementations must bound their own write | ||
| 868 | // time and return an error rather than wait forever. | 867 | // time and return an error rather than wait forever. | ||
M internal/ports/broker_observation.go +1 -1
| @@ -9,7 +9,7 @@ import ( | |||
| 9 | 9 | "github.com/bnema/vev/internal/protocol/catalogue" | |
| 10 | 10 | ) | |
| 11 | 11 | ||
| 12 | - | // Broker-native daemon observation (Plan 001 P5.2a). | |
| 12 | + | // Broker-native daemon observation. | |
| 13 | 13 | // | |
| 14 | 14 | // BrokerDaemonObservation is the broker's own projection of one daemon, local | |
| 15 | 15 | // or remote, and the only one: no daemon monitors another. It keeps | |
| @@ -9,7 +9,7 @@ import ( | |||||
| 9 | "github.com/bnema/vev/internal/protocol/catalogue" | 9 | "github.com/bnema/vev/internal/protocol/catalogue" | ||
| 10 | ) | 10 | ) | ||
| 11 | 11 | ||||
| 12 | - | // Broker-native daemon observation (Plan 001 P5.2a). | 12 | + | // Broker-native daemon observation. |
| 13 | // | 13 | // | ||
| 14 | // BrokerDaemonObservation is the broker's own projection of one daemon, local | 14 | // BrokerDaemonObservation is the broker's own projection of one daemon, local | ||
| 15 | // or remote, and the only one: no daemon monitors another. It keeps | 15 | // or remote, and the only one: no daemon monitors another. It keeps | ||
M internal/ports/session_admission.go +1 -1
| @@ -54,7 +54,7 @@ func (o SessionConnectionOrigin) Validate() error { | |||
| 54 | 54 | } | |
| 55 | 55 | ||
| 56 | 56 | // SessionAdmission is the closed admission metadata of one admitted session | |
| 57 | - | // connection (Plan 001 P5.3a): the provisioned carriage shape that accepted it, | |
| 57 | + | // connection: the provisioned carriage shape that accepted it, | |
| 58 | 58 | // the exact accepted policy, the declared stream purpose, and - for attachment | |
| 59 | 59 | // purposes only - the closed admission variant, its validated creation name, | |
| 60 | 60 | // its exact session target, and its bounded per-request environment. | |
| @@ -54,7 +54,7 @@ func (o SessionConnectionOrigin) Validate() error { | |||||
| 54 | } | 54 | } | ||
| 55 | 55 | ||||
| 56 | // SessionAdmission is the closed admission metadata of one admitted session | 56 | // SessionAdmission is the closed admission metadata of one admitted session | ||
| 57 | - | // connection (Plan 001 P5.3a): the provisioned carriage shape that accepted it, | 57 | + | // connection: the provisioned carriage shape that accepted it, |
| 58 | // the exact accepted policy, the declared stream purpose, and - for attachment | 58 | // the exact accepted policy, the declared stream purpose, and - for attachment | ||
| 59 | // purposes only - the closed admission variant, its validated creation name, | 59 | // purposes only - the closed admission variant, its validated creation name, | ||
| 60 | // its exact session target, and its bounded per-request environment. | 60 | // its exact session target, and its bounded per-request environment. | ||
M internal/usecase/broker/doc.go +4 -6
| @@ -1,7 +1,5 @@ | |||
| 1 | - | // Package broker implements vev's per-user connection broker. | |
| 2 | - | // | |
| 3 | - | // The broker is the machine-wide owner of connectivity: configured hosts, | |
| 4 | - | // daemon reachability and catalogue snapshots, pooled physical transports, | |
| 5 | - | // and multiplexed logical streams. It never owns picker UI, sessions, | |
| 6 | - | // PTYs, terminal geometry, or attachment semantics. See ADR 001. | |
| 1 | + | // Package broker owns per-user connectivity: configured hosts, daemon | |
| 2 | + | // reachability and catalogue snapshots, pooled physical transports, and | |
| 3 | + | // multiplexed logical streams. It does not own picker UI, sessions, PTYs, | |
| 4 | + | // terminal geometry, or attachment semantics. | |
| 7 | 5 | package broker | |
| @@ -1,7 +1,5 @@ | |||||
| 1 | - | // Package broker implements vev's per-user connection broker. | 1 | + | // Package broker owns per-user connectivity: configured hosts, daemon |
| 2 | - | // | 2 | + | // reachability and catalogue snapshots, pooled physical transports, and |
| 3 | - | // The broker is the machine-wide owner of connectivity: configured hosts, | 3 | + | // multiplexed logical streams. It does not own picker UI, sessions, PTYs, |
| 4 | - | // daemon reachability and catalogue snapshots, pooled physical transports, | 4 | + | // terminal geometry, or attachment semantics. |
| 5 | - | // and multiplexed logical streams. It never owns picker UI, sessions, | |||
| 6 | - | // PTYs, terminal geometry, or attachment semantics. See ADR 001. | |||
| 7 | package broker | 5 | package broker | ||
M internal/usecase/broker/lifecycle.go +1 -1
| @@ -10,7 +10,7 @@ import ( | |||
| 10 | 10 | "github.com/bnema/vev/internal/ports" | |
| 11 | 11 | ) | |
| 12 | 12 | ||
| 13 | - | // Lifecycle supervisor (Plan 001 P2.4, not activated). | |
| 13 | + | // Lifecycle supervisor. | |
| 14 | 14 | // | |
| 15 | 15 | // The supervisor is the single owner of the broker's idle lifetime. Exactly two | |
| 16 | 16 | // kinds of work can pin the broker open: | |
| @@ -10,7 +10,7 @@ import ( | |||||
| 10 | "github.com/bnema/vev/internal/ports" | 10 | "github.com/bnema/vev/internal/ports" | ||
| 11 | ) | 11 | ) | ||
| 12 | 12 | ||||
| 13 | - | // Lifecycle supervisor (Plan 001 P2.4, not activated). | 13 | + | // Lifecycle supervisor. |
| 14 | // | 14 | // | ||
| 15 | // The supervisor is the single owner of the broker's idle lifetime. Exactly two | 15 | // The supervisor is the single owner of the broker's idle lifetime. Exactly two | ||
| 16 | // kinds of work can pin the broker open: | 16 | // kinds of work can pin the broker open: | ||
M internal/usecase/broker/pool.go +1 -1
| @@ -80,7 +80,7 @@ type poolEntry struct { | |||
| 80 | 80 | idleOrder uint64 | |
| 81 | 81 | } | |
| 82 | 82 | ||
| 83 | - | // Pool is transport independent and is not production-composed in P2.2. | |
| 83 | + | // Pool is transport independent; the broker service composes it. | |
| 84 | 84 | // mu protects bookkeeping only; no port I/O or Close runs under it. | |
| 85 | 85 | type Pool struct { | |
| 86 | 86 | mu sync.Mutex | |
| @@ -80,7 +80,7 @@ type poolEntry struct { | |||||
| 80 | idleOrder uint64 | 80 | idleOrder uint64 | ||
| 81 | } | 81 | } | ||
| 82 | 82 | ||||
| 83 | - | // Pool is transport independent and is not production-composed in P2.2. | 83 | + | // Pool is transport independent; the broker service composes it. |
| 84 | // mu protects bookkeeping only; no port I/O or Close runs under it. | 84 | // mu protects bookkeeping only; no port I/O or Close runs under it. | ||
| 85 | type Pool struct { | 85 | type Pool struct { | ||
| 86 | mu sync.Mutex | 86 | mu sync.Mutex | ||
M internal/usecase/broker/registry.go +1 -1
| @@ -1335,7 +1335,7 @@ func (r *Registry) publishLocked(persist bool) { | |||
| 1335 | 1335 | return | |
| 1336 | 1336 | } | |
| 1337 | 1337 | // Remote daemons are published in registration order. The broker's own | |
| 1338 | - | // machine daemon, when a producer is configured (Plan 001 P5.3a), is the | |
| 1338 | + | // machine daemon, when a producer is configured, is the | |
| 1339 | 1339 | // prepended entry at index zero; without a producer the registry produces no | |
| 1340 | 1340 | // local observation and never invents one. | |
| 1341 | 1341 | daemons := make([]ports.BrokerDaemonObservation, 0, len(r.hosts)+1) | |
| @@ -1335,7 +1335,7 @@ func (r *Registry) publishLocked(persist bool) { | |||||
| 1335 | return | 1335 | return | ||
| 1336 | } | 1336 | } | ||
| 1337 | // Remote daemons are published in registration order. The broker's own | 1337 | // Remote daemons are published in registration order. The broker's own | ||
| 1338 | - | // machine daemon, when a producer is configured (Plan 001 P5.3a), is the | 1338 | + | // machine daemon, when a producer is configured, is the |
| 1339 | // prepended entry at index zero; without a producer the registry produces no | 1339 | // prepended entry at index zero; without a producer the registry produces no | ||
| 1340 | // local observation and never invents one. | 1340 | // local observation and never invents one. | ||
| 1341 | daemons := make([]ports.BrokerDaemonObservation, 0, len(r.hosts)+1) | 1341 | daemons := make([]ports.BrokerDaemonObservation, 0, len(r.hosts)+1) | ||
M internal/usecase/broker/registry_local.go +1 -1
| @@ -12,7 +12,7 @@ import ( | |||
| 12 | 12 | "github.com/bnema/vev/internal/protocol/catalogue" | |
| 13 | 13 | ) | |
| 14 | 14 | ||
| 15 | - | // Broker-owned local observation (Plan 001 P5.3a, P7.4b). | |
| 15 | + | // Broker-owned local observation. | |
| 16 | 16 | // | |
| 17 | 17 | // The broker's own machine daemon is not a configured host: it has no | |
| 18 | 18 | // endpoint, no registration, and no durable membership. It is observed through | |
| @@ -12,7 +12,7 @@ import ( | |||||
| 12 | "github.com/bnema/vev/internal/protocol/catalogue" | 12 | "github.com/bnema/vev/internal/protocol/catalogue" | ||
| 13 | ) | 13 | ) | ||
| 14 | 14 | ||||
| 15 | - | // Broker-owned local observation (Plan 001 P5.3a, P7.4b). | 15 | + | // Broker-owned local observation. |
| 16 | // | 16 | // | ||
| 17 | // The broker's own machine daemon is not a configured host: it has no | 17 | // The broker's own machine daemon is not a configured host: it has no | ||
| 18 | // endpoint, no registration, and no durable membership. It is observed through | 18 | // endpoint, no registration, and no durable membership. It is observed through | ||
M internal/usecase/broker/service.go +1 -1
| @@ -9,7 +9,7 @@ import ( | |||
| 9 | 9 | "github.com/bnema/vev/internal/ports" | |
| 10 | 10 | ) | |
| 11 | 11 | ||
| 12 | - | // Offline broker composition (Plan 001 P3.4 slice B). | |
| 12 | + | // Offline broker composition. | |
| 13 | 13 | // | |
| 14 | 14 | // Authority admits one accepted client connection to the broker core and | |
| 15 | 15 | // returns the connection-scoped ports.BrokerService for exactly that | |
| @@ -9,7 +9,7 @@ import ( | |||||
| 9 | "github.com/bnema/vev/internal/ports" | 9 | "github.com/bnema/vev/internal/ports" | ||
| 10 | ) | 10 | ) | ||
| 11 | 11 | ||||
| 12 | - | // Offline broker composition (Plan 001 P3.4 slice B). | 12 | + | // Offline broker composition. |
| 13 | // | 13 | // | ||
| 14 | // Authority admits one accepted client connection to the broker core and | 14 | // Authority admits one accepted client connection to the broker core and | ||
| 15 | // returns the connection-scoped ports.BrokerService for exactly that | 15 | // returns the connection-scoped ports.BrokerService for exactly that | ||
M internal/usecase/client/attachment_routes.go +2 -2
| @@ -2,8 +2,8 @@ package client | |||
| 2 | 2 | ||
| 3 | 3 | import "github.com/bnema/vev/internal/protocol" | |
| 4 | 4 | ||
| 5 | - | // Route publication and daemon navigation seams of the attached foreground | |
| 6 | - | // (Plan 003 C4/C5). The worker owns the stream, so the supervisor reaches the | |
| 5 | + | // Route publication and daemon navigation seams of the attached foreground. | |
| 6 | + | // The worker owns the stream, so the supervisor reaches the | |
| 7 | 7 | // daemon only through these bounded channels: the newest route snapshot | |
| 8 | 8 | // replaces an unsent one, and navigation failures are dropped rather than | |
| 9 | 9 | // blocking when the worker is gone. In the other direction the worker hands | |
| @@ -2,8 +2,8 @@ package client | |||||
| 2 | 2 | ||||
| 3 | import "github.com/bnema/vev/internal/protocol" | 3 | import "github.com/bnema/vev/internal/protocol" | ||
| 4 | 4 | ||||
| 5 | - | // Route publication and daemon navigation seams of the attached foreground | 5 | + | // Route publication and daemon navigation seams of the attached foreground. |
| 6 | - | // (Plan 003 C4/C5). The worker owns the stream, so the supervisor reaches the | 6 | + | // The worker owns the stream, so the supervisor reaches the |
| 7 | // daemon only through these bounded channels: the newest route snapshot | 7 | // daemon only through these bounded channels: the newest route snapshot | ||
| 8 | // replaces an unsent one, and navigation failures are dropped rather than | 8 | // replaces an unsent one, and navigation failures are dropped rather than | ||
| 9 | // blocking when the worker is gone. In the other direction the worker hands | 9 | // blocking when the worker is gone. In the other direction the worker hands | ||
M internal/usecase/client/attachment_session.go +1 -1
| @@ -12,7 +12,7 @@ import ( | |||
| 12 | 12 | "github.com/bnema/vev/internal/protocol" | |
| 13 | 13 | ) | |
| 14 | 14 | ||
| 15 | - | // Real attachment worker (Plan 001 P5.3b, offline and unactivated). | |
| 15 | + | // Real attachment worker. | |
| 16 | 16 | // | |
| 17 | 17 | // sessionAttachmentWorker drives the existing typed session protocol on the | |
| 18 | 18 | // broker logical stream the supervisor opened for one resolved request. It | |
| @@ -12,7 +12,7 @@ import ( | |||||
| 12 | "github.com/bnema/vev/internal/protocol" | 12 | "github.com/bnema/vev/internal/protocol" | ||
| 13 | ) | 13 | ) | ||
| 14 | 14 | ||||
| 15 | - | // Real attachment worker (Plan 001 P5.3b, offline and unactivated). | 15 | + | // Real attachment worker. |
| 16 | // | 16 | // | ||
| 17 | // sessionAttachmentWorker drives the existing typed session protocol on the | 17 | // sessionAttachmentWorker drives the existing typed session protocol on the | ||
| 18 | // broker logical stream the supervisor opened for one resolved request. It | 18 | // broker logical stream the supervisor opened for one resolved request. It | ||
M internal/usecase/client/attachment_worker.go +4 -4
| @@ -14,7 +14,7 @@ import ( | |||
| 14 | 14 | "github.com/bnema/vev/internal/protocol" | |
| 15 | 15 | ) | |
| 16 | 16 | ||
| 17 | - | // Attachment worker mechanisms (Plan 001 P5.1b, offline and unactivated). | |
| 17 | + | // Attachment worker mechanisms. | |
| 18 | 18 | // | |
| 19 | 19 | // This file defines the attachment mechanisms owned by the autonomous | |
| 20 | 20 | // supervisor. It reuses the terminal input pump (terminalInputPump) and | |
| @@ -390,7 +390,7 @@ type attachmentHost struct { | |||
| 390 | 390 | internalActions chan AttachmentLifecycleAction | |
| 391 | 391 | // routeDemand wakes the supervisor to publish routes when the committed | |
| 392 | 392 | // session changes; navigations carries the daemon's navigation requests | |
| 393 | - | // (Plan 003 C4/C5). Only the supervisor consumes them. | |
| 393 | + | // Only the supervisor consumes these route and navigation channels. | |
| 394 | 394 | routeDemand chan struct{} | |
| 395 | 395 | navigations chan protocol.ServerMessage | |
| 396 | 396 | // overlayActions carries driver actions the client picker overlay | |
| @@ -1129,7 +1129,7 @@ type attachmentForeground struct { | |||
| 1129 | 1129 | // tabSelect carries one pending in-place tab switch to the worker. | |
| 1130 | 1130 | tabSelect chan domain.TabStableID | |
| 1131 | 1131 | // routes carries the newest client route snapshot to the worker; replies | |
| 1132 | - | // carries the supervisor's navigation failures (Plan 003 C4/C5). | |
| 1132 | + | // carries the supervisor's navigation failures. | |
| 1133 | 1133 | routes chan protocol.RecentRouteSnapshot | |
| 1134 | 1134 | replies chan protocol.ClientMessage | |
| 1135 | 1135 | } | |
| @@ -1221,7 +1221,7 @@ func (f *attachmentForeground) finish() { | |||
| 1221 | 1221 | f.finishedOnce.Do(func() { | |
| 1222 | 1222 | // Autonomous supervisor foregrounds have a host-lifetime geometry | |
| 1223 | 1223 | // collector. At that owner-class boundary, no attachment byte may reach | |
| 1224 | - | // the picker. Isolated legacy worker replacement remains lossless. | |
| 1224 | + | // the picker. Attachment-to-attachment replacement instead delivers pending input. | |
| 1225 | 1225 | if f.input != nil && f.host != nil && f.host.ownerBoundary { | |
| 1226 | 1226 | f.input.dropOwned(f.consumer) | |
| 1227 | 1227 | } | |
| @@ -14,7 +14,7 @@ import ( | |||||
| 14 | "github.com/bnema/vev/internal/protocol" | 14 | "github.com/bnema/vev/internal/protocol" | ||
| 15 | ) | 15 | ) | ||
| 16 | 16 | ||||
| 17 | - | // Attachment worker mechanisms (Plan 001 P5.1b, offline and unactivated). | 17 | + | // Attachment worker mechanisms. |
| 18 | // | 18 | // | ||
| 19 | // This file defines the attachment mechanisms owned by the autonomous | 19 | // This file defines the attachment mechanisms owned by the autonomous | ||
| 20 | // supervisor. It reuses the terminal input pump (terminalInputPump) and | 20 | // supervisor. It reuses the terminal input pump (terminalInputPump) and | ||
| @@ -390,7 +390,7 @@ type attachmentHost struct { | |||||
| 390 | internalActions chan AttachmentLifecycleAction | 390 | internalActions chan AttachmentLifecycleAction | ||
| 391 | // routeDemand wakes the supervisor to publish routes when the committed | 391 | // routeDemand wakes the supervisor to publish routes when the committed | ||
| 392 | // session changes; navigations carries the daemon's navigation requests | 392 | // session changes; navigations carries the daemon's navigation requests | ||
| 393 | - | // (Plan 003 C4/C5). Only the supervisor consumes them. | 393 | + | // Only the supervisor consumes these route and navigation channels. |
| 394 | routeDemand chan struct{} | 394 | routeDemand chan struct{} | ||
| 395 | navigations chan protocol.ServerMessage | 395 | navigations chan protocol.ServerMessage | ||
| 396 | // overlayActions carries driver actions the client picker overlay | 396 | // overlayActions carries driver actions the client picker overlay | ||
| @@ -1129,7 +1129,7 @@ type attachmentForeground struct { | |||||
| 1129 | // tabSelect carries one pending in-place tab switch to the worker. | 1129 | // tabSelect carries one pending in-place tab switch to the worker. | ||
| 1130 | tabSelect chan domain.TabStableID | 1130 | tabSelect chan domain.TabStableID | ||
| 1131 | // routes carries the newest client route snapshot to the worker; replies | 1131 | // routes carries the newest client route snapshot to the worker; replies | ||
| 1132 | - | // carries the supervisor's navigation failures (Plan 003 C4/C5). | 1132 | + | // carries the supervisor's navigation failures. |
| 1133 | routes chan protocol.RecentRouteSnapshot | 1133 | routes chan protocol.RecentRouteSnapshot | ||
| 1134 | replies chan protocol.ClientMessage | 1134 | replies chan protocol.ClientMessage | ||
| 1135 | } | 1135 | } | ||
| @@ -1221,7 +1221,7 @@ func (f *attachmentForeground) finish() { | |||||
| 1221 | f.finishedOnce.Do(func() { | 1221 | f.finishedOnce.Do(func() { | ||
| 1222 | // Autonomous supervisor foregrounds have a host-lifetime geometry | 1222 | // Autonomous supervisor foregrounds have a host-lifetime geometry | ||
| 1223 | // collector. At that owner-class boundary, no attachment byte may reach | 1223 | // collector. At that owner-class boundary, no attachment byte may reach | ||
| 1224 | - | // the picker. Isolated legacy worker replacement remains lossless. | 1224 | + | // the picker. Attachment-to-attachment replacement instead delivers pending input. |
| 1225 | if f.input != nil && f.host != nil && f.host.ownerBoundary { | 1225 | if f.input != nil && f.host != nil && f.host.ownerBoundary { | ||
| 1226 | f.input.dropOwned(f.consumer) | 1226 | f.input.dropOwned(f.consumer) | ||
| 1227 | } | 1227 | } | ||
M internal/usecase/client/broker_operations.go +1 -2
| @@ -12,8 +12,7 @@ import ( | |||
| 12 | 12 | "github.com/bnema/vev/internal/protocol" | |
| 13 | 13 | ) | |
| 14 | 14 | ||
| 15 | - | // Client control operations over independent broker streams (Plan 001 P7, | |
| 16 | - | // worker 3). | |
| 15 | + | // Client control operations over independent broker streams. | |
| 17 | 16 | // | |
| 18 | 17 | // List, Command, Kill, KillAll, and StopDaemon are client use-case operations | |
| 19 | 18 | // that borrow a BrokerService and open one typed, independently cancellable | |
| @@ -12,8 +12,7 @@ import ( | |||||
| 12 | "github.com/bnema/vev/internal/protocol" | 12 | "github.com/bnema/vev/internal/protocol" | ||
| 13 | ) | 13 | ) | ||
| 14 | 14 | ||||
| 15 | - | // Client control operations over independent broker streams (Plan 001 P7, | 15 | + | // Client control operations over independent broker streams. |
| 16 | - | // worker 3). | |||
| 17 | // | 16 | // | ||
| 18 | // List, Command, Kill, KillAll, and StopDaemon are client use-case operations | 17 | // List, Command, Kill, KillAll, and StopDaemon are client use-case operations | ||
| 19 | // that borrow a BrokerService and open one typed, independently cancellable | 18 | // that borrow a BrokerService and open one typed, independently cancellable | ||
M internal/usecase/client/initial_navigation.go +1 -1
| @@ -9,7 +9,7 @@ import ( | |||
| 9 | 9 | "github.com/bnema/vev/internal/protocol" | |
| 10 | 10 | ) | |
| 11 | 11 | ||
| 12 | - | // Closed, one-shot initial navigation (Plan 001 P7 client cutover). | |
| 12 | + | // Closed, one-shot initial navigation. | |
| 13 | 13 | // | |
| 14 | 14 | // InitialNavigation is the comparable, closed description of the single broker | |
| 15 | 15 | // navigation a client performs after its first committed catalogue publication. | |
| @@ -9,7 +9,7 @@ import ( | |||||
| 9 | "github.com/bnema/vev/internal/protocol" | 9 | "github.com/bnema/vev/internal/protocol" | ||
| 10 | ) | 10 | ) | ||
| 11 | 11 | ||||
| 12 | - | // Closed, one-shot initial navigation (Plan 001 P7 client cutover). | 12 | + | // Closed, one-shot initial navigation. |
| 13 | // | 13 | // | ||
| 14 | // InitialNavigation is the comparable, closed description of the single broker | 14 | // InitialNavigation is the comparable, closed description of the single broker | ||
| 15 | // navigation a client performs after its first committed catalogue publication. | 15 | // navigation a client performs after its first committed catalogue publication. | ||
M internal/usecase/client/move_picker_overlay.go +1 -1
| @@ -10,7 +10,7 @@ import ( | |||
| 10 | 10 | "github.com/bnema/vev/internal/protocol" | |
| 11 | 11 | ) | |
| 12 | 12 | ||
| 13 | - | // Move-destination picker over a live attachment (Plan 003 A2). | |
| 13 | + | // Move-destination picker over a live attachment. | |
| 14 | 14 | // | |
| 15 | 15 | // The serving daemon still owns move semantics: it captures the source when | |
| 16 | 16 | // MFP/MAT runs, publishes the destination rows in a PickerSnapshot, resolves | |
| @@ -10,7 +10,7 @@ import ( | |||||
| 10 | "github.com/bnema/vev/internal/protocol" | 10 | "github.com/bnema/vev/internal/protocol" | ||
| 11 | ) | 11 | ) | ||
| 12 | 12 | ||||
| 13 | - | // Move-destination picker over a live attachment (Plan 003 A2). | 13 | + | // Move-destination picker over a live attachment. |
| 14 | // | 14 | // | ||
| 15 | // The serving daemon still owns move semantics: it captures the source when | 15 | // The serving daemon still owns move semantics: it captures the source when | ||
| 16 | // MFP/MAT runs, publishes the destination rows in a PickerSnapshot, resolves | 16 | // MFP/MAT runs, publishes the destination rows in a PickerSnapshot, resolves | ||
M internal/usecase/client/picker_catalogue.go +3 -3
| @@ -15,12 +15,12 @@ import ( | |||
| 15 | 15 | "github.com/bnema/vev/internal/protocol/catalogue" | |
| 16 | 16 | ) | |
| 17 | 17 | ||
| 18 | - | // Client-owned picker catalogue (Plan 001 P5.2b, offline and unactivated). | |
| 18 | + | // Client-owned picker catalogue. | |
| 19 | 19 | // | |
| 20 | 20 | // The autonomous supervisor owns the broker connection and the single terminal | |
| 21 | 21 | // input lifetime; this file owns the catalogue the picker presents, projected | |
| 22 | 22 | // from the broker's own observations rather than from a serving-daemon | |
| 23 | - | // catalogue. It is the P5.2b replacement source for the daemon-served | |
| 23 | + | // catalogue. It projects broker observations instead of the daemon-served | |
| 24 | 24 | // protocol.PickerSnapshot: rows are derived from ports.BrokerSnapshot, the | |
| 25 | 25 | // opaque keys stay client-local, and a selection resolves to an exact | |
| 26 | 26 | // ports.BrokerOpenStreamRequest instead of a daemon-side key handoff. | |
| @@ -572,7 +572,7 @@ func resolvePickerRequest(epoch ports.BrokerEpoch, authority pickerResolveAuthor | |||
| 572 | 572 | } | |
| 573 | 573 | ||
| 574 | 574 | // resolvePickerTarget is resolvePickerRequest plus the exact tab a tab row | |
| 575 | - | // names. refuseFailing is the picker's instant refusal (Plan 003 B4): a | |
| 575 | + | // names. refuseFailing is the picker's instant refusal: a | |
| 576 | 576 | // remote host the broker observed failing (unreachable, authentication, or an | |
| 577 | 577 | // invalid response) refuses with a notice instead of a slow attempt that | |
| 578 | 578 | // would fail the same way. An explicit CLI target keeps the attempt. | |
| @@ -15,12 +15,12 @@ import ( | |||||
| 15 | "github.com/bnema/vev/internal/protocol/catalogue" | 15 | "github.com/bnema/vev/internal/protocol/catalogue" | ||
| 16 | ) | 16 | ) | ||
| 17 | 17 | ||||
| 18 | - | // Client-owned picker catalogue (Plan 001 P5.2b, offline and unactivated). | 18 | + | // Client-owned picker catalogue. |
| 19 | // | 19 | // | ||
| 20 | // The autonomous supervisor owns the broker connection and the single terminal | 20 | // The autonomous supervisor owns the broker connection and the single terminal | ||
| 21 | // input lifetime; this file owns the catalogue the picker presents, projected | 21 | // input lifetime; this file owns the catalogue the picker presents, projected | ||
| 22 | // from the broker's own observations rather than from a serving-daemon | 22 | // from the broker's own observations rather than from a serving-daemon | ||
| 23 | - | // catalogue. It is the P5.2b replacement source for the daemon-served | 23 | + | // catalogue. It projects broker observations instead of the daemon-served |
| 24 | // protocol.PickerSnapshot: rows are derived from ports.BrokerSnapshot, the | 24 | // protocol.PickerSnapshot: rows are derived from ports.BrokerSnapshot, the | ||
| 25 | // opaque keys stay client-local, and a selection resolves to an exact | 25 | // opaque keys stay client-local, and a selection resolves to an exact | ||
| 26 | // ports.BrokerOpenStreamRequest instead of a daemon-side key handoff. | 26 | // ports.BrokerOpenStreamRequest instead of a daemon-side key handoff. | ||
| @@ -572,7 +572,7 @@ func resolvePickerRequest(epoch ports.BrokerEpoch, authority pickerResolveAuthor | |||||
| 572 | } | 572 | } | ||
| 573 | 573 | ||||
| 574 | // resolvePickerTarget is resolvePickerRequest plus the exact tab a tab row | 574 | // resolvePickerTarget is resolvePickerRequest plus the exact tab a tab row | ||
| 575 | - | // names. refuseFailing is the picker's instant refusal (Plan 003 B4): a | 575 | + | // names. refuseFailing is the picker's instant refusal: a |
| 576 | // remote host the broker observed failing (unreachable, authentication, or an | 576 | // remote host the broker observed failing (unreachable, authentication, or an | ||
| 577 | // invalid response) refuses with a notice instead of a slow attempt that | 577 | // invalid response) refuses with a notice instead of a slow attempt that | ||
| 578 | // would fail the same way. An explicit CLI target keeps the attempt. | 578 | // would fail the same way. An explicit CLI target keeps the attempt. | ||
M internal/usecase/client/picker_catalogue_projection.go +1 -1
| @@ -11,7 +11,7 @@ import ( | |||
| 11 | 11 | "github.com/bnema/vev/internal/protocol/catalogue" | |
| 12 | 12 | ) | |
| 13 | 13 | ||
| 14 | - | // Picker projections (Plan 003 B2/B3/C1), ported from the daemon-built picker | |
| 14 | + | // Picker projections, ported from the daemon-built picker | |
| 15 | 15 | // on main (picker.go, picker_lines.go). | |
| 16 | 16 | // | |
| 17 | 17 | // The catalogue publishes two projections of the same rows, keys, and | |
| @@ -11,7 +11,7 @@ import ( | |||||
| 11 | "github.com/bnema/vev/internal/protocol/catalogue" | 11 | "github.com/bnema/vev/internal/protocol/catalogue" | ||
| 12 | ) | 12 | ) | ||
| 13 | 13 | ||||
| 14 | - | // Picker projections (Plan 003 B2/B3/C1), ported from the daemon-built picker | 14 | + | // Picker projections, ported from the daemon-built picker |
| 15 | // on main (picker.go, picker_lines.go). | 15 | // on main (picker.go, picker_lines.go). | ||
| 16 | // | 16 | // | ||
| 17 | // The catalogue publishes two projections of the same rows, keys, and | 17 | // The catalogue publishes two projections of the same rows, keys, and | ||
M internal/usecase/client/picker_controller.go +4 -4
| @@ -14,7 +14,7 @@ import ( | |||
| 14 | 14 | "github.com/bnema/vev/internal/usecase/ui" | |
| 15 | 15 | ) | |
| 16 | 16 | ||
| 17 | - | // Client-owned picker controller (Plan 001 P5.2b, offline and unactivated). | |
| 17 | + | // Client-owned picker controller. | |
| 18 | 18 | // | |
| 19 | 19 | // This file is the narrow seam between the autonomous supervisor and the | |
| 20 | 20 | // client-owned catalogue. The supervisor owns raw mode, the single terminal | |
| @@ -41,7 +41,7 @@ import ( | |||
| 41 | 41 | // supervisor applies each broker publication and hands it every terminal read | |
| 42 | 42 | // from its single input lifetime; the picker decides ownership. | |
| 43 | 43 | // | |
| 44 | - | // The commit seam (Plan 001 P5.3b) is what lets the supervisor turn a user | |
| 44 | + | // The commit seam is what lets the supervisor turn a user | |
| 45 | 45 | // commit into one exact broker stream without ever reading the presentation | |
| 46 | 46 | // model itself: the picker records the decision and the key it committed | |
| 47 | 47 | // atomically, the supervisor wakes on OpsReady, and ResolveKey revalidates | |
| @@ -116,7 +116,7 @@ type pickerController struct { | |||
| 116 | 116 | } | |
| 117 | 117 | ||
| 118 | 118 | // newPickerController builds a picker over an empty catalogue. The picker owns | |
| 119 | - | // input from the start: P5.2b presents it for the whole picker presentation and | |
| 119 | + | // input from the start: the controller presents it for the whole picker presentation and | |
| 120 | 120 | // has no session pipeline to defer to. | |
| 121 | 121 | func newPickerController(clock ports.Clock, freshness time.Duration, trueColor bool) *pickerController { | |
| 122 | 122 | if supervisorNil(clock) { | |
| @@ -143,7 +143,7 @@ func (p *pickerController) Catalogue() *pickerCatalogue { | |||
| 143 | 143 | } | |
| 144 | 144 | ||
| 145 | 145 | // SetOwnsInput toggles input ownership. It is the future attach slice's release | |
| 146 | - | // boundary; P5.2b keeps it owned for the whole run. | |
| 146 | + | // boundary; the controller keeps it owned for the whole run. | |
| 147 | 147 | func (p *pickerController) SetOwnsInput(owns bool) { | |
| 148 | 148 | if p == nil { | |
| 149 | 149 | return | |
| @@ -14,7 +14,7 @@ import ( | |||||
| 14 | "github.com/bnema/vev/internal/usecase/ui" | 14 | "github.com/bnema/vev/internal/usecase/ui" | ||
| 15 | ) | 15 | ) | ||
| 16 | 16 | ||||
| 17 | - | // Client-owned picker controller (Plan 001 P5.2b, offline and unactivated). | 17 | + | // Client-owned picker controller. |
| 18 | // | 18 | // | ||
| 19 | // This file is the narrow seam between the autonomous supervisor and the | 19 | // This file is the narrow seam between the autonomous supervisor and the | ||
| 20 | // client-owned catalogue. The supervisor owns raw mode, the single terminal | 20 | // client-owned catalogue. The supervisor owns raw mode, the single terminal | ||
| @@ -41,7 +41,7 @@ import ( | |||||
| 41 | // supervisor applies each broker publication and hands it every terminal read | 41 | // supervisor applies each broker publication and hands it every terminal read | ||
| 42 | // from its single input lifetime; the picker decides ownership. | 42 | // from its single input lifetime; the picker decides ownership. | ||
| 43 | // | 43 | // | ||
| 44 | - | // The commit seam (Plan 001 P5.3b) is what lets the supervisor turn a user | 44 | + | // The commit seam is what lets the supervisor turn a user |
| 45 | // commit into one exact broker stream without ever reading the presentation | 45 | // commit into one exact broker stream without ever reading the presentation | ||
| 46 | // model itself: the picker records the decision and the key it committed | 46 | // model itself: the picker records the decision and the key it committed | ||
| 47 | // atomically, the supervisor wakes on OpsReady, and ResolveKey revalidates | 47 | // atomically, the supervisor wakes on OpsReady, and ResolveKey revalidates | ||
| @@ -116,7 +116,7 @@ type pickerController struct { | |||||
| 116 | } | 116 | } | ||
| 117 | 117 | ||||
| 118 | // newPickerController builds a picker over an empty catalogue. The picker owns | 118 | // newPickerController builds a picker over an empty catalogue. The picker owns | ||
| 119 | - | // input from the start: P5.2b presents it for the whole picker presentation and | 119 | + | // input from the start: the controller presents it for the whole picker presentation and |
| 120 | // has no session pipeline to defer to. | 120 | // has no session pipeline to defer to. | ||
| 121 | func newPickerController(clock ports.Clock, freshness time.Duration, trueColor bool) *pickerController { | 121 | func newPickerController(clock ports.Clock, freshness time.Duration, trueColor bool) *pickerController { | ||
| 122 | if supervisorNil(clock) { | 122 | if supervisorNil(clock) { | ||
| @@ -143,7 +143,7 @@ func (p *pickerController) Catalogue() *pickerCatalogue { | |||||
| 143 | } | 143 | } | ||
| 144 | 144 | ||||
| 145 | // SetOwnsInput toggles input ownership. It is the future attach slice's release | 145 | // SetOwnsInput toggles input ownership. It is the future attach slice's release | ||
| 146 | - | // boundary; P5.2b keeps it owned for the whole run. | 146 | + | // boundary; the controller keeps it owned for the whole run. |
| 147 | func (p *pickerController) SetOwnsInput(owns bool) { | 147 | func (p *pickerController) SetOwnsInput(owns bool) { | ||
| 148 | if p == nil { | 148 | if p == nil { | ||
| 149 | return | 149 | return | ||
M internal/usecase/client/route_ledger.go +1 -1
| @@ -10,7 +10,7 @@ import ( | |||
| 10 | 10 | "github.com/bnema/vev/internal/protocol/catalogue" | |
| 11 | 11 | ) | |
| 12 | 12 | ||
| 13 | - | // Client-owned route ledger (Plan 003 C4/E3). | |
| 13 | + | // Client-owned route ledger. | |
| 14 | 14 | // | |
| 15 | 15 | // The serving daemon renders the status-bar MRU, the other-session bells, the | |
| 16 | 16 | // jump-recent hints, and the palette's remote, recent-route, and | |
| @@ -10,7 +10,7 @@ import ( | |||||
| 10 | "github.com/bnema/vev/internal/protocol/catalogue" | 10 | "github.com/bnema/vev/internal/protocol/catalogue" | ||
| 11 | ) | 11 | ) | ||
| 12 | 12 | ||||
| 13 | - | // Client-owned route ledger (Plan 003 C4/E3). | 13 | + | // Client-owned route ledger. |
| 14 | // | 14 | // | ||
| 15 | // The serving daemon renders the status-bar MRU, the other-session bells, the | 15 | // The serving daemon renders the status-bar MRU, the other-session bells, the | ||
| 16 | // jump-recent hints, and the palette's remote, recent-route, and | 16 | // jump-recent hints, and the palette's remote, recent-route, and | ||
M internal/usecase/client/supervisor.go +16 -19
| @@ -15,16 +15,14 @@ import ( | |||
| 15 | 15 | "github.com/bnema/vev/internal/ports" | |
| 16 | 16 | ) | |
| 17 | 17 | ||
| 18 | - | // Autonomous client supervisor (Plan 001 P5.1a, offline and unactivated). | |
| 18 | + | // Autonomous client supervisor. | |
| 19 | 19 | // | |
| 20 | - | // The supervisor is the attachment-free, terminal-owning owner of one | |
| 20 | + | // The supervisor is the terminal-owning owner of one | |
| 21 | 21 | // autonomous client process. It enters raw mode once, before it ever reaches | |
| 22 | 22 | // for the broker, and owns a single terminal input lifetime for the whole run. | |
| 23 | 23 | // While the broker connection is down it renders the picker and keeps | |
| 24 | - | // reconnecting; it never attaches a session and never interprets terminal | |
| 25 | - | // input. Only the picker presentation and the broker-connectivity lifecycle are | |
| 26 | - | // exercised by this slice: PresentConnecting and PresentAttached are defined so | |
| 27 | - | // the attach slices can drive them later, but nothing here enters them. | |
| 24 | + | // reconnecting. One terminal input pump serves both picker and attachment; | |
| 25 | + | // the supervisor coordinates their lifetimes without decoding session output. | |
| 28 | 26 | // | |
| 29 | 27 | // Connectivity is one attempt at a time. An attempt connects, subscribes, and | |
| 30 | 28 | // waits for the first committed publication before it is Ready; readiness | |
| @@ -61,18 +59,17 @@ const ( | |||
| 61 | 59 | type Presentation uint8 | |
| 62 | 60 | ||
| 63 | 61 | const ( | |
| 64 | - | // PresentPicker shows the session picker. P5.1a exercises only this state. | |
| 62 | + | // PresentPicker shows the session picker. | |
| 65 | 63 | PresentPicker Presentation = iota + 1 | |
| 66 | - | // PresentConnecting shows the attach transition. Reserved for the attach | |
| 67 | - | // slice; the P5.1a driver never enters it. | |
| 64 | + | // PresentConnecting shows the attach transition while connecting. | |
| 68 | 65 | PresentConnecting | |
| 69 | - | // PresentAttached shows a live attachment. Reserved for the attach slice. | |
| 66 | + | // PresentAttached shows a live attachment. | |
| 70 | 67 | PresentAttached | |
| 71 | 68 | // PresentTerminating is the terminal state: raw mode is being restored and | |
| 72 | 69 | // the process is leaving. | |
| 73 | 70 | PresentTerminating | |
| 74 | - | // PresentAttachedPicker composes the client picker over a live attachment | |
| 75 | - | // (ADR 001 Amendment 1). The logical attachment stays attached: its output | |
| 71 | + | // PresentAttachedPicker composes the client picker over a live attachment. | |
| 72 | + | // The logical attachment stays attached: its output | |
| 76 | 73 | // is applied and acknowledged but not written while the picker owns the | |
| 77 | 74 | // terminal and its input. Cancel returns to the same attachment without | |
| 78 | 75 | // reconnecting. | |
| @@ -170,8 +167,8 @@ const ( | |||
| 170 | 167 | // stream: the picker released input and the supervisor is presenting the | |
| 171 | 168 | // connecting state until the initial publication is committed. | |
| 172 | 169 | supervisorAttachBegin | |
| 173 | - | // supervisorAttached marks a committed initial publication (Plan 001 | |
| 174 | - | // P5.3b): the worker proved the full output frame was written, flushed, | |
| 170 | + | // supervisorAttached marks a committed initial publication: the worker | |
| 171 | + | // proved the full output frame was written, flushed, | |
| 175 | 172 | // and UI-committed. Welcome alone never produces it. | |
| 176 | 173 | supervisorAttached | |
| 177 | 174 | // supervisorAttachEnded returns a settled attachment to the picker without | |
| @@ -329,11 +326,11 @@ type SupervisorConfig struct { | |||
| 329 | 326 | // is bound only after it owns the pump claim; no UI preserves the prior | |
| 330 | 327 | // publication-only behavior with no admitted automation. | |
| 331 | 328 | UI *UI | |
| 332 | - | // Picker is the client-owned picker (Plan 001 P5.2b). When set, the | |
| 329 | + | // Picker is the client-owned picker. When set, the | |
| 333 | 330 | // supervisor folds every broker publication into it and hands it every | |
| 334 | 331 | // terminal read from the same single input lifetime used for EOF detection, | |
| 335 | 332 | // so the picker never starts a second reader. When nil the supervisor drops | |
| 336 | - | // terminal input exactly as P5.1a does. Optional. | |
| 333 | + | // terminal input through the same pump. Optional. | |
| 337 | 334 | Picker pickerHost | |
| 338 | 335 | // AttachmentEnvironment is composition-owned process context copied into | |
| 339 | 336 | // each attachment Hello. The use case deliberately does not inspect the | |
| @@ -397,7 +394,7 @@ type Supervisor struct { | |||
| 397 | 394 | state State | |
| 398 | 395 | ||
| 399 | 396 | // attachments is the single foreground host every committed attachment | |
| 400 | - | // runs through (Plan 001 P5.3b). The supervisor owns it for the whole run | |
| 397 | + | // runs through. The supervisor owns it for the whole run | |
| 401 | 398 | // and retains close authority over each stream it admits. | |
| 402 | 399 | attachments *attachmentHost | |
| 403 | 400 | // nextAttachment identifies one attachment run within the connection | |
| @@ -1245,9 +1242,9 @@ func (s *Supervisor) renderResizeInvalidation() { | |||
| 1245 | 1242 | // started once and never replaced: a bare io.Reader cannot be interrupted, so | |
| 1246 | 1243 | // the goroutine may outlive Run when stdin never reaches EOF, exactly like the | |
| 1247 | 1244 | // attach client's input pump. It never closes caller-owned input. When a picker | |
| 1248 | - | // consumer is supplied (Plan 001 P5.2b) each read is handed to it from this one | |
| 1245 | + | // consumer is supplied each read is handed to it from this one | |
| 1249 | 1246 | // reader, so the picker never starts a second reader; without a consumer the | |
| 1250 | - | // bytes are discarded exactly as P5.1a does. | |
| 1247 | + | // bytes are discarded when no consumer is supplied. | |
| 1251 | 1248 | type terminalInputLifetime struct { | |
| 1252 | 1249 | eof chan error | |
| 1253 | 1250 | once sync.Once | |
| @@ -15,16 +15,14 @@ import ( | |||||
| 15 | "github.com/bnema/vev/internal/ports" | 15 | "github.com/bnema/vev/internal/ports" | ||
| 16 | ) | 16 | ) | ||
| 17 | 17 | ||||
| 18 | - | // Autonomous client supervisor (Plan 001 P5.1a, offline and unactivated). | 18 | + | // Autonomous client supervisor. |
| 19 | // | 19 | // | ||
| 20 | - | // The supervisor is the attachment-free, terminal-owning owner of one | 20 | + | // The supervisor is the terminal-owning owner of one |
| 21 | // autonomous client process. It enters raw mode once, before it ever reaches | 21 | // autonomous client process. It enters raw mode once, before it ever reaches | ||
| 22 | // for the broker, and owns a single terminal input lifetime for the whole run. | 22 | // for the broker, and owns a single terminal input lifetime for the whole run. | ||
| 23 | // While the broker connection is down it renders the picker and keeps | 23 | // While the broker connection is down it renders the picker and keeps | ||
| 24 | - | // reconnecting; it never attaches a session and never interprets terminal | 24 | + | // reconnecting. One terminal input pump serves both picker and attachment; |
| 25 | - | // input. Only the picker presentation and the broker-connectivity lifecycle are | 25 | + | // the supervisor coordinates their lifetimes without decoding session output. |
| 26 | - | // exercised by this slice: PresentConnecting and PresentAttached are defined so | |||
| 27 | - | // the attach slices can drive them later, but nothing here enters them. | |||
| 28 | // | 26 | // | ||
| 29 | // Connectivity is one attempt at a time. An attempt connects, subscribes, and | 27 | // Connectivity is one attempt at a time. An attempt connects, subscribes, and | ||
| 30 | // waits for the first committed publication before it is Ready; readiness | 28 | // waits for the first committed publication before it is Ready; readiness | ||
| @@ -61,18 +59,17 @@ const ( | |||||
| 61 | type Presentation uint8 | 59 | type Presentation uint8 | ||
| 62 | 60 | ||||
| 63 | const ( | 61 | const ( | ||
| 64 | - | // PresentPicker shows the session picker. P5.1a exercises only this state. | 62 | + | // PresentPicker shows the session picker. |
| 65 | PresentPicker Presentation = iota + 1 | 63 | PresentPicker Presentation = iota + 1 | ||
| 66 | - | // PresentConnecting shows the attach transition. Reserved for the attach | 64 | + | // PresentConnecting shows the attach transition while connecting. |
| 67 | - | // slice; the P5.1a driver never enters it. | |||
| 68 | PresentConnecting | 65 | PresentConnecting | ||
| 69 | - | // PresentAttached shows a live attachment. Reserved for the attach slice. | 66 | + | // PresentAttached shows a live attachment. |
| 70 | PresentAttached | 67 | PresentAttached | ||
| 71 | // PresentTerminating is the terminal state: raw mode is being restored and | 68 | // PresentTerminating is the terminal state: raw mode is being restored and | ||
| 72 | // the process is leaving. | 69 | // the process is leaving. | ||
| 73 | PresentTerminating | 70 | PresentTerminating | ||
| 74 | - | // PresentAttachedPicker composes the client picker over a live attachment | 71 | + | // PresentAttachedPicker composes the client picker over a live attachment. |
| 75 | - | // (ADR 001 Amendment 1). The logical attachment stays attached: its output | 72 | + | // The logical attachment stays attached: its output |
| 76 | // is applied and acknowledged but not written while the picker owns the | 73 | // is applied and acknowledged but not written while the picker owns the | ||
| 77 | // terminal and its input. Cancel returns to the same attachment without | 74 | // terminal and its input. Cancel returns to the same attachment without | ||
| 78 | // reconnecting. | 75 | // reconnecting. | ||
| @@ -170,8 +167,8 @@ const ( | |||||
| 170 | // stream: the picker released input and the supervisor is presenting the | 167 | // stream: the picker released input and the supervisor is presenting the | ||
| 171 | // connecting state until the initial publication is committed. | 168 | // connecting state until the initial publication is committed. | ||
| 172 | supervisorAttachBegin | 169 | supervisorAttachBegin | ||
| 173 | - | // supervisorAttached marks a committed initial publication (Plan 001 | 170 | + | // supervisorAttached marks a committed initial publication: the worker |
| 174 | - | // P5.3b): the worker proved the full output frame was written, flushed, | 171 | + | // proved the full output frame was written, flushed, |
| 175 | // and UI-committed. Welcome alone never produces it. | 172 | // and UI-committed. Welcome alone never produces it. | ||
| 176 | supervisorAttached | 173 | supervisorAttached | ||
| 177 | // supervisorAttachEnded returns a settled attachment to the picker without | 174 | // supervisorAttachEnded returns a settled attachment to the picker without | ||
| @@ -329,11 +326,11 @@ type SupervisorConfig struct { | |||||
| 329 | // is bound only after it owns the pump claim; no UI preserves the prior | 326 | // is bound only after it owns the pump claim; no UI preserves the prior | ||
| 330 | // publication-only behavior with no admitted automation. | 327 | // publication-only behavior with no admitted automation. | ||
| 331 | UI *UI | 328 | UI *UI | ||
| 332 | - | // Picker is the client-owned picker (Plan 001 P5.2b). When set, the | 329 | + | // Picker is the client-owned picker. When set, the |
| 333 | // supervisor folds every broker publication into it and hands it every | 330 | // supervisor folds every broker publication into it and hands it every | ||
| 334 | // terminal read from the same single input lifetime used for EOF detection, | 331 | // terminal read from the same single input lifetime used for EOF detection, | ||
| 335 | // so the picker never starts a second reader. When nil the supervisor drops | 332 | // so the picker never starts a second reader. When nil the supervisor drops | ||
| 336 | - | // terminal input exactly as P5.1a does. Optional. | 333 | + | // terminal input through the same pump. Optional. |
| 337 | Picker pickerHost | 334 | Picker pickerHost | ||
| 338 | // AttachmentEnvironment is composition-owned process context copied into | 335 | // AttachmentEnvironment is composition-owned process context copied into | ||
| 339 | // each attachment Hello. The use case deliberately does not inspect the | 336 | // each attachment Hello. The use case deliberately does not inspect the | ||
| @@ -397,7 +394,7 @@ type Supervisor struct { | |||||
| 397 | state State | 394 | state State | ||
| 398 | 395 | ||||
| 399 | // attachments is the single foreground host every committed attachment | 396 | // attachments is the single foreground host every committed attachment | ||
| 400 | - | // runs through (Plan 001 P5.3b). The supervisor owns it for the whole run | 397 | + | // runs through. The supervisor owns it for the whole run |
| 401 | // and retains close authority over each stream it admits. | 398 | // and retains close authority over each stream it admits. | ||
| 402 | attachments *attachmentHost | 399 | attachments *attachmentHost | ||
| 403 | // nextAttachment identifies one attachment run within the connection | 400 | // nextAttachment identifies one attachment run within the connection | ||
| @@ -1245,9 +1242,9 @@ func (s *Supervisor) renderResizeInvalidation() { | |||||
| 1245 | // started once and never replaced: a bare io.Reader cannot be interrupted, so | 1242 | // started once and never replaced: a bare io.Reader cannot be interrupted, so | ||
| 1246 | // the goroutine may outlive Run when stdin never reaches EOF, exactly like the | 1243 | // the goroutine may outlive Run when stdin never reaches EOF, exactly like the | ||
| 1247 | // attach client's input pump. It never closes caller-owned input. When a picker | 1244 | // attach client's input pump. It never closes caller-owned input. When a picker | ||
| 1248 | - | // consumer is supplied (Plan 001 P5.2b) each read is handed to it from this one | 1245 | + | // consumer is supplied each read is handed to it from this one |
| 1249 | // reader, so the picker never starts a second reader; without a consumer the | 1246 | // reader, so the picker never starts a second reader; without a consumer the | ||
| 1250 | - | // bytes are discarded exactly as P5.1a does. | 1247 | + | // bytes are discarded when no consumer is supplied. |
| 1251 | type terminalInputLifetime struct { | 1248 | type terminalInputLifetime struct { | ||
| 1252 | eof chan error | 1249 | eof chan error | ||
| 1253 | once sync.Once | 1250 | once sync.Once | ||
M internal/usecase/client/supervisor_attach.go +1 -1
| @@ -12,7 +12,7 @@ import ( | |||
| 12 | 12 | "github.com/bnema/vev/internal/protocol" | |
| 13 | 13 | ) | |
| 14 | 14 | ||
| 15 | - | // Committed attachment orchestration (Plan 001 P5.3b, offline and unactivated). | |
| 15 | + | // Committed attachment orchestration. | |
| 16 | 16 | // | |
| 17 | 17 | // After the picker resolves a committed selection to one exact | |
| 18 | 18 | // ports.BrokerOpenStreamRequest, the supervisor opens that logical stream on | |
| @@ -12,7 +12,7 @@ import ( | |||||
| 12 | "github.com/bnema/vev/internal/protocol" | 12 | "github.com/bnema/vev/internal/protocol" | ||
| 13 | ) | 13 | ) | ||
| 14 | 14 | ||||
| 15 | - | // Committed attachment orchestration (Plan 001 P5.3b, offline and unactivated). | 15 | + | // Committed attachment orchestration. |
| 16 | // | 16 | // | ||
| 17 | // After the picker resolves a committed selection to one exact | 17 | // After the picker resolves a committed selection to one exact | ||
| 18 | // ports.BrokerOpenStreamRequest, the supervisor opens that logical stream on | 18 | // ports.BrokerOpenStreamRequest, the supervisor opens that logical stream on | ||
M internal/usecase/client/supervisor_overlay.go +2 -2
| @@ -6,9 +6,9 @@ import ( | |||
| 6 | 6 | "github.com/bnema/vev/internal/protocol" | |
| 7 | 7 | ) | |
| 8 | 8 | ||
| 9 | - | // Picker overlay over a live attachment (ADR 001 Amendment 1, Plan 003 A1). | |
| 9 | + | // Picker overlay over a live attachment. | |
| 10 | 10 | // | |
| 11 | - | // The daemon's session-picker command no longer ends the attachment: it sends | |
| 11 | + | // The daemon's session-picker command keeps the attachment live: it sends | |
| 12 | 12 | // a navigation PickerOffer and the attached worker asks the supervisor for the | |
| 13 | 13 | // client picker. The supervisor then composes the same client-owned picker it | |
| 14 | 14 | // presents with no attachment over the live one: | |
| @@ -6,9 +6,9 @@ import ( | |||||
| 6 | "github.com/bnema/vev/internal/protocol" | 6 | "github.com/bnema/vev/internal/protocol" | ||
| 7 | ) | 7 | ) | ||
| 8 | 8 | ||||
| 9 | - | // Picker overlay over a live attachment (ADR 001 Amendment 1, Plan 003 A1). | 9 | + | // Picker overlay over a live attachment. |
| 10 | // | 10 | // | ||
| 11 | - | // The daemon's session-picker command no longer ends the attachment: it sends | 11 | + | // The daemon's session-picker command keeps the attachment live: it sends |
| 12 | // a navigation PickerOffer and the attached worker asks the supervisor for the | 12 | // a navigation PickerOffer and the attached worker asks the supervisor for the | ||
| 13 | // client picker. The supervisor then composes the same client-owned picker it | 13 | // client picker. The supervisor then composes the same client-owned picker it | ||
| 14 | // presents with no attachment over the live one: | 14 | // presents with no attachment over the live one: | ||
M internal/usecase/client/supervisor_picker_kill.go +1 -1
| @@ -9,7 +9,7 @@ import ( | |||
| 9 | 9 | "github.com/bnema/vev/internal/protocol" | |
| 10 | 10 | ) | |
| 11 | 11 | ||
| 12 | - | // Picker kill (Plan 003 B1). | |
| 12 | + | // Picker kill. | |
| 13 | 13 | // | |
| 14 | 14 | // `x` on a local session row kills it through the broker operations seam: one | |
| 15 | 15 | // independent, bounded control stream to the owning daemon, never the | |
| @@ -9,7 +9,7 @@ import ( | |||||
| 9 | "github.com/bnema/vev/internal/protocol" | 9 | "github.com/bnema/vev/internal/protocol" | ||
| 10 | ) | 10 | ) | ||
| 11 | 11 | ||||
| 12 | - | // Picker kill (Plan 003 B1). | 12 | + | // Picker kill. |
| 13 | // | 13 | // | ||
| 14 | // `x` on a local session row kills it through the broker operations seam: one | 14 | // `x` on a local session row kills it through the broker operations seam: one | ||
| 15 | // independent, bounded control stream to the owning daemon, never the | 15 | // independent, bounded control stream to the owning daemon, never the | ||
M internal/usecase/client/supervisor_routes.go +1 -1
| @@ -7,7 +7,7 @@ import ( | |||
| 7 | 7 | "github.com/bnema/vev/internal/protocol" | |
| 8 | 8 | ) | |
| 9 | 9 | ||
| 10 | - | // Routes and daemon navigation while attached (Plan 003 C4, C5, E3). | |
| 10 | + | // Routes and daemon navigation while attached. | |
| 11 | 11 | // | |
| 12 | 12 | // The supervisor publishes the client route ledger to the serving daemon after | |
| 13 | 13 | // the committed initial publication, whenever the attached session changes, | |
| @@ -7,7 +7,7 @@ import ( | |||||
| 7 | "github.com/bnema/vev/internal/protocol" | 7 | "github.com/bnema/vev/internal/protocol" | ||
| 8 | ) | 8 | ) | ||
| 9 | 9 | ||||
| 10 | - | // Routes and daemon navigation while attached (Plan 003 C4, C5, E3). | 10 | + | // Routes and daemon navigation while attached. |
| 11 | // | 11 | // | ||
| 12 | // The supervisor publishes the client route ledger to the serving daemon after | 12 | // The supervisor publishes the client route ledger to the serving daemon after | ||
| 13 | // the committed initial publication, whenever the attached session changes, | 13 | // the committed initial publication, whenever the attached session changes, | ||
M internal/usecase/client/terminal_input_pump.go +1 -1
| @@ -244,7 +244,7 @@ func (p *terminalInputPump) preserveResidual(consumer uint64, data []byte) { | |||
| 244 | 244 | // boundary. Picker-queued bytes are dropped before attachment claim, and | |
| 245 | 245 | // attachment-queued bytes are dropped before picker claim. No delivery, | |
| 246 | 246 | // pending read, or preserved residual may cross between those owner classes. | |
| 247 | - | // revoke remains lossless for legacy attachment-to-attachment replacement. | |
| 247 | + | // revoke remains lossless for attachment-to-attachment replacement. | |
| 248 | 248 | func (p *terminalInputPump) dropOwned(consumer uint64) { | |
| 249 | 249 | p.mu.Lock() | |
| 250 | 250 | if p.consumer != consumer { | |
| @@ -244,7 +244,7 @@ func (p *terminalInputPump) preserveResidual(consumer uint64, data []byte) { | |||||
| 244 | // boundary. Picker-queued bytes are dropped before attachment claim, and | 244 | // boundary. Picker-queued bytes are dropped before attachment claim, and | ||
| 245 | // attachment-queued bytes are dropped before picker claim. No delivery, | 245 | // attachment-queued bytes are dropped before picker claim. No delivery, | ||
| 246 | // pending read, or preserved residual may cross between those owner classes. | 246 | // pending read, or preserved residual may cross between those owner classes. | ||
| 247 | - | // revoke remains lossless for legacy attachment-to-attachment replacement. | 247 | + | // revoke remains lossless for attachment-to-attachment replacement. |
| 248 | func (p *terminalInputPump) dropOwned(consumer uint64) { | 248 | func (p *terminalInputPump) dropOwned(consumer uint64) { | ||
| 249 | p.mu.Lock() | 249 | p.mu.Lock() | ||
| 250 | if p.consumer != consumer { | 250 | if p.consumer != consumer { | ||
M internal/usecase/daemon/attention.go +1 -1
| @@ -50,7 +50,7 @@ func (d *Daemon) noteAttention(sess *session, tb *tab) { | |||
| 50 | 50 | // jumpAttention switches to the oldest pending attention target: a tab of the | |
| 51 | 51 | // attached session first, then another session of this daemon, then the | |
| 52 | 52 | // oldest bell among the client's routes on any other daemon, which the client | |
| 53 | - | // navigates to (Plan 003 C5). Returning nil never implies a switch happened — | |
| 53 | + | // navigates to. Returning nil never implies a switch happened — | |
| 54 | 54 | // it also covers "no target exists", which is routine and not an error. Only | |
| 55 | 55 | // a failure to reach a target that does exist is a genuine error. | |
| 56 | 56 | func (d *Daemon) jumpAttention(sess *session, ac *attachedClient) error { | |
| @@ -50,7 +50,7 @@ func (d *Daemon) noteAttention(sess *session, tb *tab) { | |||||
| 50 | // jumpAttention switches to the oldest pending attention target: a tab of the | 50 | // jumpAttention switches to the oldest pending attention target: a tab of the | ||
| 51 | // attached session first, then another session of this daemon, then the | 51 | // attached session first, then another session of this daemon, then the | ||
| 52 | // oldest bell among the client's routes on any other daemon, which the client | 52 | // oldest bell among the client's routes on any other daemon, which the client | ||
| 53 | - | // navigates to (Plan 003 C5). Returning nil never implies a switch happened — | 53 | + | // navigates to. Returning nil never implies a switch happened — |
| 54 | // it also covers "no target exists", which is routine and not an error. Only | 54 | // it also covers "no target exists", which is routine and not an error. Only | ||
| 55 | // a failure to reach a target that does exist is a genuine error. | 55 | // a failure to reach a target that does exist is a genuine error. | ||
| 56 | func (d *Daemon) jumpAttention(sess *session, ac *attachedClient) error { | 56 | func (d *Daemon) jumpAttention(sess *session, ac *attachedClient) error { | ||
M internal/usecase/daemon/control.go +1 -1
| @@ -731,7 +731,7 @@ func (e controlExec) RemoteCatalog(asJSON bool) (string, error) { | |||
| 731 | 731 | if !asJSON { | |
| 732 | 732 | return "", command.ErrInvalidArguments | |
| 733 | 733 | } | |
| 734 | - | // The catalogue export is a local-only projection (Plan 001 P4.3): it | |
| 734 | + | // The catalogue export is a local-only projection: it | |
| 735 | 735 | // reads the remote-free capture and never the remote directory, so a | |
| 736 | 736 | // serving daemon's own catalogue is independent of remote monitoring. | |
| 737 | 737 | inv := e.d.captureLocalSessionInventory(viewOptions{tabDetails: true, focusedTitles: true}, true) | |
| @@ -731,7 +731,7 @@ func (e controlExec) RemoteCatalog(asJSON bool) (string, error) { | |||||
| 731 | if !asJSON { | 731 | if !asJSON { | ||
| 732 | return "", command.ErrInvalidArguments | 732 | return "", command.ErrInvalidArguments | ||
| 733 | } | 733 | } | ||
| 734 | - | // The catalogue export is a local-only projection (Plan 001 P4.3): it | 734 | + | // The catalogue export is a local-only projection: it |
| 735 | // reads the remote-free capture and never the remote directory, so a | 735 | // reads the remote-free capture and never the remote directory, so a | ||
| 736 | // serving daemon's own catalogue is independent of remote monitoring. | 736 | // serving daemon's own catalogue is independent of remote monitoring. | ||
| 737 | inv := e.d.captureLocalSessionInventory(viewOptions{tabDetails: true, focusedTitles: true}, true) | 737 | inv := e.d.captureLocalSessionInventory(viewOptions{tabDetails: true, focusedTitles: true}, true) | ||
M internal/usecase/daemon/daemon.go +2 -3
| @@ -1650,7 +1650,7 @@ func (d *Daemon) routeWithContext(ctx context.Context, h protocol.Hello, tr port | |||
| 1650 | 1650 | // The accepting side's provisioned admission, when present, is the authority | |
| 1651 | 1651 | // this Hello is validated against before any restore, creation, resume | |
| 1652 | 1652 | // claim, ownership change, or environment mutation. A connection without | |
| 1653 | - | // that seam keeps its legacy validation unchanged and gains no admission | |
| 1653 | + | // that seam receives the standard Hello validation and gains no admission | |
| 1654 | 1654 | // exception, so a forged Hello can never widen what it is allowed to do. | |
| 1655 | 1655 | admission, admitted := sessionHelloAdmission(tr) | |
| 1656 | 1656 | if admitted { | |
| @@ -1728,8 +1728,7 @@ func (d *Daemon) routeWithContext(ctx context.Context, h protocol.Hello, tr port | |||
| 1728 | 1728 | return nil, nil, err | |
| 1729 | 1729 | } | |
| 1730 | 1730 | } | |
| 1731 | - | // A daemon-owned ephemeral Hello without an exact remote target is a legacy | |
| 1732 | - | // shape the daemon refuses. An authenticated remote admission that names the | |
| 1731 | + | // A daemon-owned ephemeral Hello without an exact remote target is refused by the daemon. An authenticated remote admission that names the | |
| 1733 | 1732 | // creation is the one exception, and it is granted only under a validated | |
| 1734 | 1733 | // remote admission; a connection without one never gains it. | |
| 1735 | 1734 | if !admitted && h.EnvironmentPolicy == protocol.EnvironmentPolicyDaemonOwned && h.SessionTarget == nil && | |
| @@ -1650,7 +1650,7 @@ func (d *Daemon) routeWithContext(ctx context.Context, h protocol.Hello, tr port | |||||
| 1650 | // The accepting side's provisioned admission, when present, is the authority | 1650 | // The accepting side's provisioned admission, when present, is the authority | ||
| 1651 | // this Hello is validated against before any restore, creation, resume | 1651 | // this Hello is validated against before any restore, creation, resume | ||
| 1652 | // claim, ownership change, or environment mutation. A connection without | 1652 | // claim, ownership change, or environment mutation. A connection without | ||
| 1653 | - | // that seam keeps its legacy validation unchanged and gains no admission | 1653 | + | // that seam receives the standard Hello validation and gains no admission |
| 1654 | // exception, so a forged Hello can never widen what it is allowed to do. | 1654 | // exception, so a forged Hello can never widen what it is allowed to do. | ||
| 1655 | admission, admitted := sessionHelloAdmission(tr) | 1655 | admission, admitted := sessionHelloAdmission(tr) | ||
| 1656 | if admitted { | 1656 | if admitted { | ||
| @@ -1728,8 +1728,7 @@ func (d *Daemon) routeWithContext(ctx context.Context, h protocol.Hello, tr port | |||||
| 1728 | return nil, nil, err | 1728 | return nil, nil, err | ||
| 1729 | } | 1729 | } | ||
| 1730 | } | 1730 | } | ||
| 1731 | - | // A daemon-owned ephemeral Hello without an exact remote target is a legacy | 1731 | + | // A daemon-owned ephemeral Hello without an exact remote target is refused by the daemon. An authenticated remote admission that names the |
| 1732 | - | // shape the daemon refuses. An authenticated remote admission that names the | |||
| 1733 | // creation is the one exception, and it is granted only under a validated | 1732 | // creation is the one exception, and it is granted only under a validated | ||
| 1734 | // remote admission; a connection without one never gains it. | 1733 | // remote admission; a connection without one never gains it. | ||
| 1735 | if !admitted && h.EnvironmentPolicy == protocol.EnvironmentPolicyDaemonOwned && h.SessionTarget == nil && | 1734 | if !admitted && h.EnvironmentPolicy == protocol.EnvironmentPolicyDaemonOwned && h.SessionTarget == nil && | ||
M internal/usecase/daemon/navigation_inventory.go +2 -2
| @@ -47,7 +47,7 @@ func (d *Daemon) snapshotNavigationInventory(requestID uint64) protocol.Navigati | |||
| 47 | 47 | } | |
| 48 | 48 | ||
| 49 | 49 | // localNavigationInventorySnapshot is the prepared local-only navigation | |
| 50 | - | // projection (Plan 001 P4.3): exactly one local source group, built from the | |
| 50 | + | // projection: exactly one local source group, built from the | |
| 51 | 51 | // daemon's own capture. | |
| 52 | 52 | func (d *Daemon) localNavigationInventorySnapshot(requestID uint64) protocol.NavigationInventoryResponse { | |
| 53 | 53 | inv := d.captureLocalSessionInventory(viewOptions{}, false) | |
| @@ -166,7 +166,7 @@ func (d *Daemon) resolveNavigationInventory(request protocol.NavigationInventory | |||
| 166 | 166 | } | |
| 167 | 167 | ||
| 168 | 168 | // localNavigationResolve is the prepared local-only navigation resolver | |
| 169 | - | // (Plan 001 P4.3). It rejects a structured foreign source key or registration | |
| 169 | + | // It rejects a structured foreign source key or registration | |
| 170 | 170 | // before any lookup, so a local resolve can never be satisfied by a remote | |
| 171 | 171 | // endpoint or a foreign registration even when a local session shares the | |
| 172 | 172 | // row's name. Matching is by the opaque lifecycle-qualified key only: a stale | |
| @@ -47,7 +47,7 @@ func (d *Daemon) snapshotNavigationInventory(requestID uint64) protocol.Navigati | |||||
| 47 | } | 47 | } | ||
| 48 | 48 | ||||
| 49 | // localNavigationInventorySnapshot is the prepared local-only navigation | 49 | // localNavigationInventorySnapshot is the prepared local-only navigation | ||
| 50 | - | // projection (Plan 001 P4.3): exactly one local source group, built from the | 50 | + | // projection: exactly one local source group, built from the |
| 51 | // daemon's own capture. | 51 | // daemon's own capture. | ||
| 52 | func (d *Daemon) localNavigationInventorySnapshot(requestID uint64) protocol.NavigationInventoryResponse { | 52 | func (d *Daemon) localNavigationInventorySnapshot(requestID uint64) protocol.NavigationInventoryResponse { | ||
| 53 | inv := d.captureLocalSessionInventory(viewOptions{}, false) | 53 | inv := d.captureLocalSessionInventory(viewOptions{}, false) | ||
| @@ -166,7 +166,7 @@ func (d *Daemon) resolveNavigationInventory(request protocol.NavigationInventory | |||||
| 166 | } | 166 | } | ||
| 167 | 167 | ||||
| 168 | // localNavigationResolve is the prepared local-only navigation resolver | 168 | // localNavigationResolve is the prepared local-only navigation resolver | ||
| 169 | - | // (Plan 001 P4.3). It rejects a structured foreign source key or registration | 169 | + | // It rejects a structured foreign source key or registration |
| 170 | // before any lookup, so a local resolve can never be satisfied by a remote | 170 | // before any lookup, so a local resolve can never be satisfied by a remote | ||
| 171 | // endpoint or a foreign registration even when a local session shares the | 171 | // endpoint or a foreign registration even when a local session shares the | ||
| 172 | // row's name. Matching is by the opaque lifecycle-qualified key only: a stale | 172 | // row's name. Matching is by the opaque lifecycle-qualified key only: a stale | ||
M internal/usecase/daemon/palette.go +2 -2
| @@ -113,7 +113,7 @@ func routeEntryForRef(snapshot protocol.RecentRouteSnapshot, ref protocol.RouteR | |||
| 113 | 113 | ||
| 114 | 114 | // createSessionDestinationResults lists where CNS may create a session: the | |
| 115 | 115 | // serving daemon itself, and every other daemon the client published as a | |
| 116 | - | // route host (Plan 003 E3). Only the serving daemon creates in place; every | |
| 116 | + | // route host. Only the serving daemon creates in place; every | |
| 117 | 117 | // other destination is created by the client through its broker. | |
| 118 | 118 | func createSessionDestinationResults(snapshot protocol.RecentRouteSnapshot, currentLifecycle domain.SessionLifecycleID) []palette.Result { | |
| 119 | 119 | results := make([]palette.Result, 0, len(snapshot.Hosts)+1) | |
| @@ -175,7 +175,7 @@ func paletteRouteRepresentsDaemonSession(entry protocol.RecentRouteEntry, daemon | |||
| 175 | 175 | // paletteResults projects the daemon's own inventory plus the client's route | |
| 176 | 176 | // snapshot for the palette. It keeps quick-switch exclusions, compact labels, | |
| 177 | 177 | // commands, and history behavior; other daemons' sessions and hosts come only | |
| 178 | - | // from the client routes (Plan 003 E3), and committing one navigates through | |
| 178 | + | // from the client routes, and committing one navigates through | |
| 179 | 179 | // the client. | |
| 180 | 180 | func (d *Daemon) paletteResults(current *session, commands []command.Command, routeSnapshot protocol.RecentRouteSnapshot) []palette.Result { | |
| 181 | 181 | inv := d.captureSessionInventory(viewOptions{}, false) | |
| @@ -113,7 +113,7 @@ func routeEntryForRef(snapshot protocol.RecentRouteSnapshot, ref protocol.RouteR | |||||
| 113 | 113 | ||||
| 114 | // createSessionDestinationResults lists where CNS may create a session: the | 114 | // createSessionDestinationResults lists where CNS may create a session: the | ||
| 115 | // serving daemon itself, and every other daemon the client published as a | 115 | // serving daemon itself, and every other daemon the client published as a | ||
| 116 | - | // route host (Plan 003 E3). Only the serving daemon creates in place; every | 116 | + | // route host. Only the serving daemon creates in place; every |
| 117 | // other destination is created by the client through its broker. | 117 | // other destination is created by the client through its broker. | ||
| 118 | func createSessionDestinationResults(snapshot protocol.RecentRouteSnapshot, currentLifecycle domain.SessionLifecycleID) []palette.Result { | 118 | func createSessionDestinationResults(snapshot protocol.RecentRouteSnapshot, currentLifecycle domain.SessionLifecycleID) []palette.Result { | ||
| 119 | results := make([]palette.Result, 0, len(snapshot.Hosts)+1) | 119 | results := make([]palette.Result, 0, len(snapshot.Hosts)+1) | ||
| @@ -175,7 +175,7 @@ func paletteRouteRepresentsDaemonSession(entry protocol.RecentRouteEntry, daemon | |||||
| 175 | // paletteResults projects the daemon's own inventory plus the client's route | 175 | // paletteResults projects the daemon's own inventory plus the client's route | ||
| 176 | // snapshot for the palette. It keeps quick-switch exclusions, compact labels, | 176 | // snapshot for the palette. It keeps quick-switch exclusions, compact labels, | ||
| 177 | // commands, and history behavior; other daemons' sessions and hosts come only | 177 | // commands, and history behavior; other daemons' sessions and hosts come only | ||
| 178 | - | // from the client routes (Plan 003 E3), and committing one navigates through | 178 | + | // from the client routes, and committing one navigates through |
| 179 | // the client. | 179 | // the client. | ||
| 180 | func (d *Daemon) paletteResults(current *session, commands []command.Command, routeSnapshot protocol.RecentRouteSnapshot) []palette.Result { | 180 | func (d *Daemon) paletteResults(current *session, commands []command.Command, routeSnapshot protocol.RecentRouteSnapshot) []palette.Result { | ||
| 181 | inv := d.captureSessionInventory(viewOptions{}, false) | 181 | inv := d.captureSessionInventory(viewOptions{}, false) | ||
M internal/usecase/daemon/picker.go +4 -4
| @@ -53,9 +53,9 @@ type pickerForeignViews struct { | |||
| 53 | 53 | blockLocalStopped bool | |
| 54 | 54 | } | |
| 55 | 55 | ||
| 56 | - | // localPickerViews is the prepared local-only picker projection (Plan 001 | |
| 57 | - | // P4.3). It captures live and stopped local rows, orders them exactly like the | |
| 58 | - | // hybrid projection did when no foreign source was present. | |
| 56 | + | // localPickerViews is the prepared local-only picker projection. It captures | |
| 57 | + | // live and stopped local rows, ordering them as the hybrid projection does | |
| 58 | + | // when no foreign source is present. | |
| 59 | 59 | func (d *Daemon) localPickerViews(cur *session, ac *attachedClient) pickerLocalViews { | |
| 60 | 60 | if cur != nil && ac != nil { | |
| 61 | 61 | cur.repairAttachmentView(ac) | |
| @@ -316,7 +316,7 @@ func (d *Daemon) switchToTargetForAttachment(effect *attachmentEffect, target pi | |||
| 316 | 316 | return nil | |
| 317 | 317 | } | |
| 318 | 318 | if target.RemoteTarget != nil || target.RemoteKey != nil { | |
| 319 | - | // Other daemons are client routes (Plan 003 E3): the daemon never | |
| 319 | + | // Other daemons are client routes: the daemon never | |
| 320 | 320 | // hands out a remote destination. | |
| 321 | 321 | return errAttachmentTransition | |
| 322 | 322 | } | |
| @@ -53,9 +53,9 @@ type pickerForeignViews struct { | |||||
| 53 | blockLocalStopped bool | 53 | blockLocalStopped bool | ||
| 54 | } | 54 | } | ||
| 55 | 55 | ||||
| 56 | - | // localPickerViews is the prepared local-only picker projection (Plan 001 | 56 | + | // localPickerViews is the prepared local-only picker projection. It captures |
| 57 | - | // P4.3). It captures live and stopped local rows, orders them exactly like the | 57 | + | // live and stopped local rows, ordering them as the hybrid projection does |
| 58 | - | // hybrid projection did when no foreign source was present. | 58 | + | // when no foreign source is present. |
| 59 | func (d *Daemon) localPickerViews(cur *session, ac *attachedClient) pickerLocalViews { | 59 | func (d *Daemon) localPickerViews(cur *session, ac *attachedClient) pickerLocalViews { | ||
| 60 | if cur != nil && ac != nil { | 60 | if cur != nil && ac != nil { | ||
| 61 | cur.repairAttachmentView(ac) | 61 | cur.repairAttachmentView(ac) | ||
| @@ -316,7 +316,7 @@ func (d *Daemon) switchToTargetForAttachment(effect *attachmentEffect, target pi | |||||
| 316 | return nil | 316 | return nil | ||
| 317 | } | 317 | } | ||
| 318 | if target.RemoteTarget != nil || target.RemoteKey != nil { | 318 | if target.RemoteTarget != nil || target.RemoteKey != nil { | ||
| 319 | - | // Other daemons are client routes (Plan 003 E3): the daemon never | 319 | + | // Other daemons are client routes: the daemon never |
| 320 | // hands out a remote destination. | 320 | // hands out a remote destination. | ||
| 321 | return errAttachmentTransition | 321 | return errAttachmentTransition | ||
| 322 | } | 322 | } | ||
M internal/usecase/daemon/session_admission.go +2 -2
| @@ -18,8 +18,8 @@ const admissionCwdMaxBytes = 65535 | |||
| 18 | 18 | // sessionHelloAdmission reads the provisioned admission metadata the accepting | |
| 19 | 19 | // side stamped onto an admitted connection, through the optional structural | |
| 20 | 20 | // provider seam. A connection built without that seam - a direct package | |
| 21 | - | // caller, a legacy sessionwire constructor, or a raw test transport - reports | |
| 22 | - | // present=false, and the daemon then follows its legacy validation unchanged. | |
| 21 | + | // caller, a sessionwire constructor without admission, or a raw test transport - reports | |
| 22 | + | // present=false, and the daemon applies the standard Hello validation. | |
| 23 | 23 | // The provider hands back a defensive copy, so the admission the daemon | |
| 24 | 24 | // validates can never be mutated through the connection. | |
| 25 | 25 | func sessionHelloAdmission(tr ports.ServerConnection) (ports.SessionAdmission, bool) { | |
| @@ -18,8 +18,8 @@ const admissionCwdMaxBytes = 65535 | |||||
| 18 | // sessionHelloAdmission reads the provisioned admission metadata the accepting | 18 | // sessionHelloAdmission reads the provisioned admission metadata the accepting | ||
| 19 | // side stamped onto an admitted connection, through the optional structural | 19 | // side stamped onto an admitted connection, through the optional structural | ||
| 20 | // provider seam. A connection built without that seam - a direct package | 20 | // provider seam. A connection built without that seam - a direct package | ||
| 21 | - | // caller, a legacy sessionwire constructor, or a raw test transport - reports | 21 | + | // caller, a sessionwire constructor without admission, or a raw test transport - reports |
| 22 | - | // present=false, and the daemon then follows its legacy validation unchanged. | 22 | + | // present=false, and the daemon applies the standard Hello validation. |
| 23 | // The provider hands back a defensive copy, so the admission the daemon | 23 | // The provider hands back a defensive copy, so the admission the daemon | ||
| 24 | // validates can never be mutated through the connection. | 24 | // validates can never be mutated through the connection. | ||
| 25 | func sessionHelloAdmission(tr ports.ServerConnection) (ports.SessionAdmission, bool) { | 25 | func sessionHelloAdmission(tr ports.ServerConnection) (ports.SessionAdmission, bool) { | ||
M internal/usecase/daemon/session_inventory.go +1 -1
| @@ -30,7 +30,7 @@ type localSessionInventory struct { | |||
| 30 | 30 | // sessionInventory is the daemon-owned common capture consumed by the | |
| 31 | 31 | // palette, picker, and catalog export projections. The daemon observes only | |
| 32 | 32 | // its own sessions: other daemons reach the palette through the client's | |
| 33 | - | // route snapshot (Plan 003 E3). | |
| 33 | + | // route snapshot. | |
| 34 | 34 | type sessionInventory struct { | |
| 35 | 35 | localSessionInventory | |
| 36 | 36 | } | |
| @@ -30,7 +30,7 @@ type localSessionInventory struct { | |||||
| 30 | // sessionInventory is the daemon-owned common capture consumed by the | 30 | // sessionInventory is the daemon-owned common capture consumed by the | ||
| 31 | // palette, picker, and catalog export projections. The daemon observes only | 31 | // palette, picker, and catalog export projections. The daemon observes only | ||
| 32 | // its own sessions: other daemons reach the palette through the client's | 32 | // its own sessions: other daemons reach the palette through the client's | ||
| 33 | - | // route snapshot (Plan 003 E3). | 33 | + | // route snapshot. |
| 34 | type sessionInventory struct { | 34 | type sessionInventory struct { | ||
| 35 | localSessionInventory | 35 | localSessionInventory | ||
| 36 | } | 36 | } | ||