diff --git a/README.md b/README.md index 0a6b280..af48c49 100644 --- a/README.md +++ b/README.md @@ -624,6 +624,11 @@ capability, or creating/registering a missing resource. ## CI, Security, And Releases +The automation-facing compatibility policy is documented in +[`docs/compatibility.md`](docs/compatibility.md). It defines the intended +stability rules for CLI commands, `--json` output, the local control JSONL +protocol, Iroh peer wire protocols, SQLite metadata, and signed operation logs. + GitHub Actions workflows live under `.github/workflows/`: - `ci.yml` runs formatting, clippy, docs, `cargo check`, and workspace tests on diff --git a/crates/geth-control/src/lib.rs b/crates/geth-control/src/lib.rs index 60acdf4..4eeb661 100644 --- a/crates/geth-control/src/lib.rs +++ b/crates/geth-control/src/lib.rs @@ -3204,4 +3204,23 @@ mod tests { response ); } + + #[test] + fn malformed_and_unknown_protocol_inputs_fail() { + for input in [ + "{", + "{}", + r#"{"type":"unknown"}"#, + r#"{"type":"status","extra":}"#, + ] { + assert!(decode_request(input).is_err()); + assert!(decode_response(input).is_err()); + assert!(decode_peer_request(input).is_err()); + assert!(decode_peer_response(input).is_err()); + assert!(decode_pipe_wire_request(input).is_err()); + assert!(decode_pipe_wire_response(input).is_err()); + assert!(decode_overlay_wire_request(input).is_err()); + assert!(decode_overlay_wire_response(input).is_err()); + } + } } diff --git a/docs/compatibility.md b/docs/compatibility.md new file mode 100644 index 0000000..cfaafe0 --- /dev/null +++ b/docs/compatibility.md @@ -0,0 +1,105 @@ +# Compatibility Policy + +`geth` has not shipped a stable release yet. Until the first deployment tag, +contracts may still change, but changes must be deliberate, documented in this +file, and reflected in `docs/production-readiness-roadmap.md`. + +After the first deployment tag, compatibility is defined by the surfaces below. + +## CLI Commands + +Commands documented in `README.md` are the automation-facing CLI surface. +Existing command names, positional argument meanings, flag names, and default +behavior should remain compatible within a major release. + +Backward-compatible CLI changes include: + +- Adding optional flags with defaults that preserve previous behavior. +- Adding new subcommands. +- Adding fields to human-readable output when `--json` is not requested. +- Improving error messages while preserving the error kind and recovery path. + +Breaking CLI changes include: + +- Renaming or removing a documented command or flag. +- Changing the meaning of an existing argument or default. +- Changing exit success for the same observable result. +- Requiring a daemon, network path, privileged service, or host mutation where a + documented local command did not previously require one. + +Prototype commands must be called out in `README.md` or feature docs with an +explicit migration expectation before scripts depend on them. + +## JSON Output + +`--json` output is the preferred script contract. For stable commands, the +top-level response variant name and existing field names keep their meaning +within a major release. + +Backward-compatible JSON changes include: + +- Adding nullable or optional fields. +- Adding enum variants for new commands or new explicit states. +- Adding elements to arrays where ordering was not documented as stable. + +Breaking JSON changes include: + +- Removing or renaming fields. +- Changing field type, unit, or identifier format. +- Reusing a field for a different semantic meaning. +- Changing a documented stable ordering. + +Automation should ignore unknown fields. Tests that assert JSON fixtures should +cover the subset intended as stable rather than every incidental field. + +## Local Control JSONL + +The local daemon control socket uses newline-delimited JSON request and response +messages from `geth-control`. This protocol is local-only and not a remote trust +boundary, but local automation may still rely on it. + +Stable local-control variants follow the same compatibility rules as `--json` +output. Unknown variants, malformed JSON, and messages without a trailing +newline must fail without daemon state mutation. Local control must not become a +remote transport. + +## Peer Wire Protocols + +Node-to-node geth communication is Iroh-only. Peer protocols are grouped by +explicit ALPNs: + +- `/geth/control/1` for authenticated peer-control requests. +- `/geth/pipe/1` for authorized pipe byte streams. +- `/geth/overlay/1` for authorized overlay packets. + +Within a major release, existing peer request and response variants should keep +their field names, field meanings, nonce behavior, peer-card validation, and +endpoint-binding validation. New variants must use explicit capabilities and +resource IDs. Discovery data remains untrusted and never grants capabilities. + +Breaking peer-wire changes require a version bump, migration note, and tests +showing old messages fail closed rather than being interpreted as a different +operation. + +## SQLite Metadata + +The metadata database is product state. Schema changes must be represented as +ordered migrations before deployment. Fresh opens and repeated opens must be +idempotent, and multi-table writes that represent one logical operation should +commit atomically. + +Stable table columns may be added through migrations. Removing or repurposing a +column requires a migration note and a recovery path. SQLite state is an +implementation detail for scripts unless a table is explicitly documented as +stable. + +## Signed Operations + +Signed keychain, auth, SSH certificate, and SSH revocation payloads are durable +compatibility surfaces. Signed payloads must use deterministic canonical +encoding with explicit namespaces and versions. A verifier must never treat +arbitrary JSON serialization as signed canonical data. + +Changing a signed payload shape, namespace, or verification rule requires a new +versioned namespace or a documented migration that preserves validation of +existing signed history. diff --git a/docs/production-readiness-roadmap.md b/docs/production-readiness-roadmap.md index 8e49f48..452f27f 100644 --- a/docs/production-readiness-roadmap.md +++ b/docs/production-readiness-roadmap.md @@ -86,13 +86,13 @@ behavior. Goal: make command, JSON, and protocol contracts explicit enough for scripts and downstream projects. -- `[ ]` Define compatibility policy. +- `[x]` Define compatibility policy. Acceptance criteria: - - `[ ]` CLI command compatibility is documented. - - `[ ]` `--json` output compatibility is documented. - - `[ ]` Local control JSONL compatibility is documented. - - `[ ]` Peer wire protocol compatibility is documented. - - `[ ]` SQLite and signed-operation compatibility are documented. + - `[x]` CLI command compatibility is documented. + - `[x]` `--json` output compatibility is documented. + - `[x]` Local control JSONL compatibility is documented. + - `[x]` Peer wire protocol compatibility is documented. + - `[x]` SQLite and signed-operation compatibility are documented. - `[ ]` Add golden JSON tests. Acceptance criteria: @@ -101,13 +101,13 @@ and downstream projects. failures. - `[ ]` Fixture updates require intentional review. -- `[ ]` Expand protocol roundtrip tests. +- `[~]` Expand protocol roundtrip tests. Acceptance criteria: - `[ ]` Every `ControlRequest` and `ControlResponse` variant roundtrips. - `[ ]` Every `PeerControlRequest` and `PeerControlResponse` variant roundtrips. - `[ ]` Pipe and overlay wire protocol variants roundtrip. - - `[ ]` Unknown or malformed protocol inputs fail safely. + - `[x]` Unknown or malformed protocol inputs fail safely. - `[ ]` Classify command stability. Acceptance criteria: