Skip to content

IPC v1: align response decoding with forward-compatibility rules #420

Closed

Description

@mamoreau-devolutions

Context

While validating an independent secretspec.provider/1 implementation against feat/ipc-v1 at ce29ab8 / #362, I found that the normative response-evolution rule is not consistently implemented.

Problem

docs/src/content/docs/reference/ipc-wire.md says:

  • enumerations are closed for senders and open for receivers;
  • requests are strict and results are tolerant;
  • receivers ignore unknown members in response and result objects;
  • unknown error codes/kinds must remain reportable as unnamed failures.

However, the reference Rust decoder rejects several additive response shapes:

  • secretspec-ipc/src/jsonrpc.rs: SuccessResponse and ErrorResponse use #[serde(deny_unknown_fields)];
  • secretspec-ipc/src/error.rs: RpcError, ErrorData, and InteractionReference use deny_unknown_fields;
  • secretspec-ipc/src/protocol.rs: multiple initialized-application, metadata, and result types use deny_unknown_fields.

The canonical schemas also close result/error objects and enumerate known error codes/kinds (schema/ipc/v1/common.schema.json, provider.schema.json, and resolver.schema.json). That is useful for validating what a v1 sender may emit, but it does not express what a forward-compatible v1 receiver must accept.

As written, adding descriptive output to a later compatible revision can terminate sessions with older Rust clients even though the protocol says it must not.

Suggested resolution

  1. Keep request/notification parameter decoding strict.
  2. Make response envelopes, result objects, and error data tolerant of unknown members on receive.
  3. Continue enforcing known-code/known-kind pairing; decode an unknown code/kind as an explicit non-success, honoring retryable without blind retry.
  4. Clarify that the JSON schemas define canonical sender output, if that is the intent, and separately test receiver compatibility.
  5. Audit tagged result enums so an additive field does not reject an otherwise known variant.

Deterministic coverage

Add cases for:

  • unknown top-level member on a success and error response;
  • unknown nested member in a known result variant;
  • unknown additive error.data member;
  • unknown code plus unknown kind being surfaced as an unnamed failure;
  • known code paired with the wrong kind still being rejected;
  • the same unknown members on requests still being rejected.

The IPC freeze gate in docs/src/content/docs/development/ipc-implementation.md says a known discrepancy between implementation and reference documentation blocks the v1 release.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions