A record completed under a wide frame and replayed by a serve at a narrower one must
come back as the typed stand-in; passing begin any other frame (usize::MAX) delivers the
wide record the narrow write cannot carry.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Naming a request by the SHA-256 of its id is a wire meaning v2 does not have: no v2
client could read that reply. begin now seals Refused(Malformed) with the request's own
id and drops the connection (FrameBound) only when that sealed refusal cannot fit the
frame. ConnectorClient refuses an id past MAX_IDENTITY_BYTES before connecting, with
the typed RequestIdTooLong error.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- begin(): an id past MAX_IDENTITY_BYTES gets Refusal::Malformed naming the request by its SHA-256, so the reply fits the smallest frame; no dropped connection
- frame_bytes_for_payload, payload_bytes_for_frame and MAX_IDENTITY_BYTES are public; ServeError::FrameBound states the frame needed
- complete(): FrameBound releases the caller's slot
- begin() takes the frame: a recorded result that no longer fits is replaced by the stand-in failure
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
complete() measures the serialized sealed envelope against the frame and
records the typed result_size failure (fixed transport, itself guaranteed to
fit) when it does not fit, so no Completed record is undeliverable. serve's
validation derives the caller payload bound from the real worst-case encoding
of the int-array ciphertext instead of plaintext length. Identities are capped
at 256 bytes so the stand-in's size is bounded. The wire encoding is unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
wire_parity_v2 linked CodexConnector (PolyForm Noncommercial) into the kit's
test build. The v2 bytes it compared against are now committed, generated once
from fd7cec4 (generator and command beside them): invocations for both
tool-choice values, a completed, a failed and a refused result for every
refusal, canonical bytes, the provider digest and v2-sealed envelopes the kit
must decrypt. envelope.rs tests pin the outer-identity match on each field,
envelope validation, and the inclusive, never-empty frame bounds.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
serve now refuses, before opening anything, a frame under 8192 bytes, fewer
connections than max(sum of caller slots, 8), and a caller payload bound outside
4096..=frame-4096 (the base daemon's validate, unchanged). A provider result
larger than frame-4096 becomes a typed result_size failure before it is recorded,
so a retry replays deliverable bytes. A payload over a caller's bound is refused
Policy on the wire instead of dropping the connection. The orphan capacity
helpers are deleted; the accept loop takes its connection source so a test can
present a non-loopback peer.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Entry points, verify commands, and the AGPL-3.0-only relicense record: lifted
from CodexConnector fd7cec4, formerly PolyForm Noncommercial.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A kit-encrypted invocation and result decrypt and validate under codex-connector
fd7cec4 and the reverse; canonical invocation bytes, canonical provider request
bytes, the provider digest and the five schema ids are equal. The dev-dependency
and this test are deleted by connector-contract-v3, which changes the wire.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
service.rs is CodexConnector lib.rs 954-1313 verbatim under the rename rule.
serve.rs is the accept loop of daemon.rs over ProviderBackend (ready, execute),
ServeLimits, CallerConfig and load_admissions; no config document, no provider,
no Idunn route observation. serve refuses a non-loopback listener and drops
non-loopback peers. ready() is consulted once, before replay state is opened and
before the first accept, as base consulted readiness at startup; execute is
called on the request path without consulting it (base only checked readiness
for health). New tests: end-to-end replay with a counting backend, readiness
timing, limits, peer and listener refusal, connection permits, and behavioural
kills for survivors in service policy, payload bound, refusal mapping, restart
record validation and completion mismatch.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Workspace with the model-connector crate. contract.rs, envelope.rs and client.rs
are CodexConnector lib.rs moved verbatim under the rename rule (strip the leading
Codex from identifiers); schema id strings are unchanged, so the v2 wire is
unchanged. canonical_responses_body stays behind: it is OpenAI Responses lowering.
The moved tests keep their bodies; shared fixtures live in fixtures.rs.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>