You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite. Learn more
This PR bumps the envoy-protocol from v4 to v5, adding SqlitePreloadHints wire messages that allow actors to persist SQLite page preload hints back to the engine. It is a stacked draft PR targeting mock-agentic-loop/sqlite-vfs-runtime-helpers, scoped to protocol definitions only.
Protocol Design
The new types are well-structured:
SqlitePreloadHints supports both sparse pgnos and ranges — good, as it handles both random-access hot pages and sequential read patterns efficiently.
SqlitePersistPreloadHintsResponse properly adds SqliteFenceMismatch as a distinct error variant (separate from SqliteErrorResponse), matching the generation-fencing semantics in SqlitePersistPreloadHintsRequest.
Backward compat conversions are correct: v4→v5 is a no-op (convert_same_bytes) for all unchanged types, and v5→v4 returns a ProtocolCompatibilityError if the new request/response variant is encountered. The ProtocolCompatibilityFeature::SqlitePreloadHints entry correctly uses the plural "require" verb form (consistent with existing entries).
The engine CLAUDE.md (engine/CLAUDE.md, rule 6a) explicitly prohibits this pattern:
"Never rely on byte-identical wire layout across versions. Every cross-version converter must reconstruct the target type field-by-field, even when versions appear identical today. No serde_bare::to_vec + from_slice shortcuts."
The PR adds new uses of convert_same_bytes / convert_same_bytes_ref for ToEnvoyConn, ToGateway, ToOutbound, and ActorCommandKeyData v4↔v5 conversions. These types are byte-identical across v4 and v5, but the rule is categorical: every converter must be field-by-field.
Affected sites:
versioned.rs — ToEnvoyConn::deserialize_version case 4, ToEnvoyConn::serialize_version case 4
Same for ToGateway, ToOutbound, ActorCommandKeyData
Each should reconstruct field-by-field (or at minimum document explicitly why byte-identity is stable here, if there's an exception path that isn't clear from the CLAUDE.md).
Missing exhaustive match arm in pegboard-envoy
engine/packages/pegboard-envoy/src/ws_to_tunnel_task.rs exhaustively matches on protocol::ToRivet. With v5 exporting ToRivetSqlitePersistPreloadHintsRequest, the existing match will fail to compile until a handler arm is added. A stub that returns SqlitePersistPreloadHintsResponse::SqliteErrorResponse("not yet wired") (consistent with the existing exec/execute stubs at lines 403–435) would unblock compilation while the real handler lands.
SqliteFenceMismatch carries no actionable metadata
type SqliteFenceMismatch struct {
reason: str
}
The engine knows both the expected and actual generation at the point it returns a fence mismatch. Including expectedGeneration: SqliteGeneration and actualGeneration: SqliteGeneration would let callers log a useful diagnostic instead of parsing a freeform string. Compare how SQLite VFS correctness issues are surfaced elsewhere — a structured mismatch is easier to act on.
Minor
PR description is empty — the checklist template is not filled in. Even for a draft, a one-line summary of what the PR does and what's being deferred to follow-up PRs would help reviewers.
No serialization round-trip test for the new types — the existing versioned.rs tests cover ToEnvoyCommands and ActorCommandKeyData. A test that round-trips ToRivetSqlitePersistPreloadHintsRequest across version boundaries (v4→v5 incompatibility path, v5→v5 identity) would catch any codegen issues early.
PROTOCOL_VERSION version test duplication — versioned.rs test and stateless_sqlite_v3.rs both assert PROTOCOL_VERSION == 5. That's fine, just noting it is intentional.
What's Good
Clean protocol layering: the new request/response pair follows the exact same requestId: u32 + data: T envelope as all other SQLite messages.
SqlitePreloadHintRange { startPgno, pageCount } is a compact, cache-friendly representation for sequential page access hints.
Version converter chain is mechanically correct — v1→v5 deserialization and v5→v1 serialization paths are all wired correctly with appropriate incompatibility gates.
TypeScript and Rust codegen are properly aligned (union tag positions match, VERSION = 5 updated).
Summary: The protocol schema and versioning are structurally sound. The two blocking items before merging are the convert_same_bytes policy violation and the missing exhaustive match arm in pegboard-envoy. The SqliteFenceMismatch metadata gap is worth fixing before this ships to production for debuggability.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Please include a summary of the changes and the related issue. Please also include relevant motivation and context.
Type of change
How Has This Been Tested?
Please describe the tests that you ran to verify your changes.
Checklist: