Literate AI

Repository documentation

Native gRPC oracle declarations

The opt-in literate-ai/ipc-surface-conformance-acceptance@2 document loads native gRPC expectations for a persistent-service Component. Loading validates the declared protobuf closure and cases. Default native lifecycle dispatch is implemented; installed integration and live generated-surface qualification remain pending under IPC-SURFACE-001. Native @2 gRPC declarations select the default native adapter. Missing optional dependencies refuse before socket allocation or service launch. Legacy @1 non-REST documents still require an explicit protocol adapter. Loading a document is not acceptance.

Keep the verifier document under verification/acceptance/<component>.json (or its named-entrypoint oracle path). Do not reference it from generator-visible Component specifications. Existing @1 documents retain their shape and identities; REST authors do not need to migrate.

Version 2 keeps the common specification_set_identity, surface_version, compatibility and process fields, and requires protocol: "grpc". declared_schema_identity is the SHA-256 identity of the exact binary protobuf FileDescriptorSet. Every dependency must be included; global protobuf registrations cannot supply omitted files. Declaration order may differ from dependency order. This raw-byte identity is not a claim of cross-runtime canonical serialization.

description_probe has exactly two required fields:

Field Value
descriptor_set_hex Complete descriptor bytes in lowercase hexadecimal, without whitespace
timeout_milliseconds Integer from 1 through 120000 for reflection observation

request_cases contains 1 through 64 objects. Every field below is required; unknown fields refuse loading.

Field Value
method Exact /fully.qualified.Service/Method
input_type, output_type Protobuf full names matching the descriptor method
cardinality unary-unary, unary-stream, stream-unary, or stream-stream
requests, responses Ordered arrays of lowercase hexadecimal message bytes
status Canonical gRPC status name such as OK or INVALID_ARGUMENT
status_message Expected text, including an empty string when appropriate
timeout_milliseconds Integer from 1 through 120000
error_details Array of objects with exactly type_name and hexadecimal message

Unary requests contain exactly one message. Successful unary responses contain exactly one message; failed unary calls declare none. Streams may be empty, and a failed response stream may contain messages preceding the failure. Successful calls cannot declare error details. All messages and details must decode against the pinned descriptor closure, satisfy required fields and contain no undeclared fields.

The entire JSON document remains limited to 1 MiB, including hexadecimal expansion. Internal per-message and descriptor bounds do not raise that public document limit. Each message sequence has at most 1024 entries and each case at most 32 error details. Loading native declarations requires the optional grpc-acceptance protobuf runtime; REST loading does not require protobuf. Native execution must also enforce process and per-call deadlines and prove served reflection matches the declared closure.

Descriptor comparison boundary

The internal comparator accepts a complete immutable tuple of reflected FileDescriptorProto byte strings, limited to 128 files and 4 MiB in total. It matches the exact declared filename set and rejects missing, extra or repeated filenames, including identical duplicates. Each parsed file is encoded deterministically by the same protobuf runtime on both sides, then compared; the outer filename collection is sorted, and explicit JSON names equal to the bound runtime's implicit default are omitted from comparison. This handles protoc populating a default json_name which Python reflection omits. Custom JSON names, repeated declarations, dependencies, options and source information remain significant. Normalization identity schema literate-ai/grpc-descriptor-normalization@2 records this policy; raw declared and observed byte identities remain unchanged. The rule follows protobuf JSON field-name semantics. Unknown wrapper fields in the original FileDescriptorSet refuse loading because file-level reflection cannot account for them.

Successful comparison records the declared raw identity, the ordered raw-observation identity, a normalized identity scoped to the protobuf version and implementation, and sorted filenames. The comparison does not modify the declared raw identity or claim that protobuf serialization is canonical across runtimes. This follows the protobuf serialization limitation. The transport must collect the complete descriptor closure from the gRPC reflection response under its deadline.

Observation time budget

The lifecycle passes the process time remaining after readiness to IpcSurfaceProbe.observe_with_timeout. Native transports must use the smaller of that remaining budget and each declared reflection/call timeout, reducing the remaining budget between operations. They must not restart the full process timeout after readiness or for each RPC. The lifecycle rechecks process health and elapsed time after observation and shuts down the service on refusal.

Existing adapters implementing only observe remain supported through a fallback. That compatibility path cannot preempt a blocking adapter; the post-observation check prevents a late result from being accepted. Native transport must implement the budget-aware operation before its execution path is qualified.

Native transport

GrpcIpcSurfaceProbe supplies loopback-only native observation through the Python adapter API and default @2 lifecycle dispatch. Its channels disable HTTP proxy routing and accept only the lifecycle's http://127.0.0.1:<port> address form. Readiness uses native channel readiness. Observation collects reflection descriptors and drives unary/unary, unary/stream, stream/unary and stream/stream calls with the remaining lifecycle budget. Installed default-dispatch qualification remains pending.

The optional grpc-acceptance dependency set pins gRPC, reflection and status helpers at 1.84.0 alongside protobuf 7.36.2. Dependencies remain optional for REST. The adapter validates response and error-detail protobuf types and compares ordered response bytes, canonical status names, status text and typed error-detail bytes to the oracle. These message expectations are wire-exact. Rich status metadata must agree with the terminal gRPC status. Invalid messages and bounded-stream violations refuse observation; mismatching valid responses produce a rejected conformance observation. Calls and channels are cancelled or closed on exit.

Reflection may repeat a dependency across different request replies; identical repeats are collected once, while conflicts and duplicates within one reply refuse. Missing replies, wrong request correspondence, extra files and incomplete closures refuse. The total reflected payload is bounded to 4 MiB. Observed RPC payloads across all cases are bounded to 8 MiB, with existing per-message, sequence and detail limits; channel receive/send limits and a 64 KiB metadata bound apply as well. Raw reflected payloads are retained in served_description_bytes; raw response, status and detail observations are retained in the versioned protocol_detail JSON. The evidence also binds normalized reflection and per-case observation identities.

Real local fixture tests cover these paths. Default-dispatch tests launch and stop an actual child service on acceptance, response refusal and deadline failure. Its acceptance record retains raw reflection bytes and RPC details, whose per-case identities can be independently recomputed. Installed default-dispatch qualification and a live generated gRPC surface remain required for the complete release claim.

Read the Markdown sourceConference homePublished 1.3.0 · Patch 1.3.1 in progress · Development 1.4