geth/docs/compatibility.md

105 lines
4.2 KiB
Markdown

# 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.