connector-contract-v3: delete the v2 golden test and fixtures

Ruling connector-v3-only: no v2 peer is kept. The test's header already named
this cut as its deletion line.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Meta Vens 2026-10-28 11:04:44 +01:00
commit 685f449ddb
24 changed files with 0 additions and 517 deletions

View file

@ -1,2 +0,0 @@
*.mp binary
*.bin binary

View file

@ -1,21 +0,0 @@
# Golden v2 wire fixtures
Bytes of the v2 connector wire, produced once by CodexConnector at commit
`fd7cec4176f4e3f9a5aaa75e77ba10ce5e1522f8`. Ghostlight pins CodexConnector
`68fe94b`, not that commit; `src/lib.rs`, the whole v2 wire, is identical in
both, so these bytes are Ghostlight's wire. They are pinned by `tests/wire_golden_v2.rs`, so the kit cannot drift from
them. No CodexConnector code or dependency is part of this repository.
Generator: `generator.rs` (not compiled here). Command, run in a clone of
CodexConnector at that commit:
cp <ModelConnector>/crates/model-connector/tests/fixtures/wire_v2/generator.rs examples/gen_wire_v2.rs
cargo run --locked -q --example gen_wire_v2
It prints `FIXTURE <name> <hex>` lines; each file is the hex decoded. It was
run on Yggdrasil through the verify container with codex-connector at that
commit as a dev-dependency of the kit at d1d28f0 (same source). The `.mp`
files are rmp-serde output; `envelope_*` files carry random nonces and
AES-256-GCM ciphertext sealed under the connection key
`parity-distinct-test-key`. Regenerating changes the envelopes' bytes; the
plaintext fixtures must regenerate byte-identically.

View file

@ -1,6 +0,0 @@
栙$gamecult.codex.transport_envelope.v2璸arity-caller﹔equest-1狪nvocation溙<6E>塘h虄虒抬x泰Y探<1B>環谭听题虠虆3陶 糖烃虘誊h抬台涕[酞藤!A屉虊甜铁疼;屉铁| 酞躺`!铁铁虤抬虗
虂k剔'vCZ锑號虒虉 8J抬汤d蹋虠N炭F炭zm6<6D><36>
眺添甜\\NMq號套虠 贴1替苔摊惕 4*{趟胎瘫
讨苔e糖台虖
贪虇i贪G*S虂坛碳桃胎坍誊!N汤萄虪虃太虣7虂糖贪天虄汤态c苔趟 桃滩1k提~h踢3$腾虪K踢贪贴誊4{逃踢碳泰U.)烫汰踏r虪听天唐^bbI虉y^坛踢烫虂躺:虪虤-体YXo逃桃[Qy虡太
X逃I:3探淘贪D&V'-舔uf虒X1跳桃.虧|4c蹄虌E体A踢替虩掏Q梯L虃-提w贪u檀3坦>田$Qz汤k m'+绦挞G 檀s坍00 f)谭C摊虣*虇虙疼y~贴Hz跳体听"糖挞*%挑o躺摊藤x處}虌滔梯Y倘C填檀炭u厅谈x/g屉恬虡X-藤搪坍虇N天RI):H恬躺虙汤虊虠f疼虪'\s台 虧s虊棠GVa逃潭滩C\\`=p 虨w處H讨4唐特>lfL蹋烃啼讨v炭剔J屉

View file

@ -1,7 +0,0 @@
–Ù$gamecult.codex.transport_envelope.v2­parity-caller©request-1¦ResultœÌ…Ì¢ÌÇ"̇Ì<E280A1>GÌ©ÜCÌôÌË Ì<>ÌéHÌßÌ—ÌÿÌÐÌ´ÌÝÌá\Ìö]2/ÌÎe"̘
Ì¿ÌáÌìÌü{GÌÚṴ̧^b3Ìûj̢̗̟ÌÃÌ’sÌ•*Ì» ÌøÌä= ̸̄<ÌÁ{ÌýÌã.ÌØ8~̫̓CÌâ
̱̘ÌË
[Ì‚ÌÉoÌ–(47ÌÌBML̲Ìó̢̳Ì<C2A2>hp,ÌîÌ®wÌê6DHÌðbÌÏÌÌb̹@a̧ÌÑ̵̎Ì´Ì<>kÌäÌ’ÌáÌóÌ€ÌÑN+ÌüMÌÀjG %Ìß/Ìô
ÌÁÌò̸%Ì»Ì<C2BB>@sT`ÌâÌ’}P̈ÌÒ ÌëÌÊÌÞ Ì«Ìâ:ÌÚ̟̖̔Ìû^Ìô>ÌûX.x
r]F8Ì<38>ÌÛÌ‹Ì÷Ì<C3B7>5ÌÚGÌÆÌºÌÃÌ®C@(ÌóÌÓ̾{̾ÌÙMÌÓ~)Ìà 7ÌÐÌòI+'v ÌøUnP̈$U(NÌêÌçÌüsÌ¢T^[ÌÊYÌæÌ<C3A6>zÌâ.wÌÆeÌ™C̦̿̄"U^trÌöÌ<C3B6>ÌÙ̦Ìï̯̬ÌçÌÜÌž+ÌÑ/b̯̭̼Ìî*$Ì× ÌŠÌ²̘ÌÕ\K5̧f
Ìò̃b}̦̬o.Ẁ̧&Ìå̶̑[

View file

@ -1,171 +0,0 @@
//! Generator of the golden v2 wire fixtures beside it. It is not compiled by this
//! workspace: it was run once, as an example of CodexConnector at commit
//! fd7cec4176f4e3f9a5aaa75e77ba10ce5e1522f8 (see README.md here for the command).
//! It prints one `FIXTURE <name> <hex>` line per file.
use codex_connector as v2;
use serde::Serialize;
const KEY: &str = "parity-distinct-test-key";
const CALLER: &str = "parity-caller";
fn bytes<T: Serialize>(value: &T) -> Vec<u8> {
rmp_serde::to_vec(value).unwrap()
}
fn emit(name: &str, data: &[u8]) {
let hex: String = data.iter().map(|byte| format!("{byte:02x}")).collect();
println!("FIXTURE {name} {hex}");
}
fn request(choice: v2::CodexToolChoice) -> v2::CodexProviderRequest {
let mut request =
v2::CodexProviderRequest::new("request-1", "conversation-1", "gpt-5.4", "Be exact.");
request.input = vec![
v2::CodexInputItem::UserText {
text: "state".to_string(),
},
v2::CodexInputItem::AssistantText {
text: "reply".to_string(),
},
v2::CodexInputItem::ToolCall {
call_id: "call-1".to_string(),
name: "read_source".to_string(),
arguments: "{}".to_string(),
},
v2::CodexInputItem::ToolResult {
call_id: "call-1".to_string(),
output: "ok".to_string(),
},
];
request.tools = vec![v2::CodexToolDefinition {
name: "read_source".to_string(),
description: "Read one admitted source.".to_string(),
parameters_json: r#"{"type":"object"}"#.to_string(),
}];
request.tool_choice = choice;
request.reasoning_effort = Some("high".to_string());
request.parallel_tool_calls = true;
request.max_output_tokens = Some(512);
request.prompt_cache_key = Some("cache-1".to_string());
request
}
fn invocation(choice: v2::CodexToolChoice) -> v2::CodexTransportInvocation {
v2::CodexTransportInvocation::new(CALLER, 2_000, [7; 32], request(choice)).unwrap()
}
fn receipt(
invocation: &v2::CodexTransportInvocation,
outcome: v2::CodexTransportOutcome,
) -> v2::CodexTransportReceipt {
v2::CodexTransportReceipt {
schema_id: v2::RECEIPT_SCHEMA_ID.to_string(),
request_id: invocation.request_id().to_string(),
caller_runtime_id: invocation.caller_runtime_id.clone(),
native_request_sha256: invocation.native_request_sha256,
provider_request_sha256: invocation.provider_request_sha256,
model: invocation.request.model.clone(),
transport: "parity-sse".to_string(),
outcome,
}
}
fn main() {
let key = v2::CodexTransportKey::from_connection_secret(KEY).unwrap();
let auto = invocation(v2::CodexToolChoice::Auto);
let required = invocation(v2::CodexToolChoice::Required);
emit("invocation_auto.mp", &bytes(&auto));
emit("invocation_required.mp", &bytes(&required));
emit(
"canonical_invocation.bin",
&v2::canonical_invocation_bytes(&required).unwrap(),
);
emit(
"canonical_provider_request.bin",
&v2::canonical_provider_request_bytes(&required.request).unwrap(),
);
emit(
"provider_request_sha256.bin",
&v2::provider_request_sha256(&required.request).unwrap(),
);
emit(
"envelope_invocation.mp",
&bytes(&v2::encrypt_invocation(&required, &key).unwrap()),
);
let completed = v2::CodexTransportResult::transported(
&required,
vec![
v2::CodexTransportEvent {
sequence: 0,
payload: v2::CodexTransportEventPayload::TextDelta {
text: "hello".to_string(),
},
},
v2::CodexTransportEvent {
sequence: 1,
payload: v2::CodexTransportEventPayload::ToolCall {
call_id: "call-2".to_string(),
name: "read_source".to_string(),
arguments: "{}".to_string(),
},
},
],
receipt(
&required,
v2::CodexTransportOutcome::Completed {
provider_response_id: Some("response-1".to_string()),
input_tokens: Some(10),
output_tokens: Some(3),
reasoning_output_tokens: Some(1),
cached_input_tokens: Some(4),
},
),
);
emit("result_transported.mp", &bytes(&completed));
emit(
"envelope_result_transported.mp",
&bytes(&v2::encrypt_result(&completed, &key).unwrap()),
);
let failed = v2::CodexTransportResult::transported(
&required,
Vec::new(),
receipt(
&required,
v2::CodexTransportOutcome::Failed {
failure_kind: "result_size".to_string(),
message: "provider result exceeded its byte bound".to_string(),
},
),
);
emit("result_failed.mp", &bytes(&failed));
emit(
"envelope_result_failed.mp",
&bytes(&v2::encrypt_result(&failed, &key).unwrap()),
);
use v2::CodexRefusal as R;
let refusals = [
("expired", R::Expired),
("identity_substitution", R::IdentitySubstitution),
("provider_digest_substitution", R::ProviderDigestSubstitution),
("policy", R::Policy),
("capacity", R::Capacity),
("in_flight", R::InFlight),
("indeterminate", R::Indeterminate),
("replay_conflict", R::ReplayConflict),
("malformed", R::Malformed),
];
for (name, refusal) in refusals {
let refused = v2::CodexTransportResult::refused(&required, refusal);
emit(&format!("result_refused_{name}.mp"), &bytes(&refused));
if name == "replay_conflict" {
emit(
"envelope_result_refused_replay_conflict.mp",
&bytes(&v2::encrypt_result(&refused, &key).unwrap()),
);
}
}
}

View file

@ -1 +0,0 @@
”Ù"gamecult.codex.transport_result.v2©request-1­parity-caller<65>§Refused¨Capacity

View file

@ -1 +0,0 @@
”Ù"gamecult.codex.transport_result.v2©request-1­parity-caller<65>§Refused§Expired

View file

@ -1 +0,0 @@
”Ù"gamecult.codex.transport_result.v2©request-1­parity-caller<65>§Refused´IdentitySubstitution

View file

@ -1 +0,0 @@
”Ù"gamecult.codex.transport_result.v2©request-1­parity-caller<65>§Refused¨InFlight

View file

@ -1 +0,0 @@
”Ù"gamecult.codex.transport_result.v2©request-1­parity-caller<65>§Refused­Indeterminate

View file

@ -1 +0,0 @@
”Ù"gamecult.codex.transport_result.v2©request-1­parity-caller<65>§Refused©Malformed

View file

@ -1 +0,0 @@
”Ù"gamecult.codex.transport_result.v2©request-1­parity-caller<65>§Refused¦Policy

View file

@ -1 +0,0 @@
”Ù"gamecult.codex.transport_result.v2©request-1­parity-caller<65>§RefusedºProviderDigestSubstitution

View file

@ -1 +0,0 @@
”Ù"gamecult.codex.transport_result.v2©request-1­parity-caller<65>§Refused®ReplayConflict

View file

@ -1,301 +0,0 @@
//! The kit speaks the v2 wire of CodexConnector fd7cec4, the library Ghostlight pins.
//! The golden bytes in `fixtures/wire_v2` were produced by that library (see its README);
//! nothing of it is linked here. Deleted with the fixtures by cut connector-contract-v3,
//! which changes the wire.
use model_connector as kit;
use serde::Serialize;
use serde::de::DeserializeOwned;
const KEY: &str = "parity-distinct-test-key";
const CALLER: &str = "parity-caller";
macro_rules! golden {
($name:literal) => {
include_bytes!(concat!("fixtures/wire_v2/", $name)) as &[u8]
};
}
fn bytes<T: Serialize>(value: &T) -> Vec<u8> {
rmp_serde::to_vec(value).unwrap()
}
/// The value serializes to the golden bytes and the golden bytes decode back to it.
fn assert_wire<T: Serialize + DeserializeOwned + PartialEq + std::fmt::Debug>(
name: &str,
value: &T,
golden: &[u8],
) {
assert_eq!(bytes(value), golden, "{name}: serialized bytes");
let decoded: T = rmp_serde::from_slice(golden).unwrap();
assert_eq!(&decoded, value, "{name}: decoded value");
}
fn request(choice: kit::ToolChoice) -> kit::ProviderRequest {
let mut request =
kit::ProviderRequest::new("request-1", "conversation-1", "gpt-5.4", "Be exact.");
request.input = vec![
kit::InputItem::UserText {
text: "state".to_string(),
},
kit::InputItem::AssistantText {
text: "reply".to_string(),
},
kit::InputItem::ToolCall {
call_id: "call-1".to_string(),
name: "read_source".to_string(),
arguments: "{}".to_string(),
},
kit::InputItem::ToolResult {
call_id: "call-1".to_string(),
output: "ok".to_string(),
},
];
request.tools = vec![kit::ToolDefinition {
name: "read_source".to_string(),
description: "Read one admitted source.".to_string(),
parameters_json: r#"{"type":"object"}"#.to_string(),
}];
request.tool_choice = choice;
request.reasoning_effort = Some("high".to_string());
request.parallel_tool_calls = true;
request.max_output_tokens = Some(512);
request.prompt_cache_key = Some("cache-1".to_string());
request
}
fn invocation(choice: kit::ToolChoice) -> kit::TransportInvocation {
kit::TransportInvocation::new(CALLER, 2_000, [7; 32], request(choice)).unwrap()
}
fn receipt(
invocation: &kit::TransportInvocation,
outcome: kit::TransportOutcome,
) -> kit::TransportReceipt {
kit::TransportReceipt {
schema_id: kit::RECEIPT_SCHEMA_ID.to_string(),
request_id: invocation.request_id().to_string(),
caller_runtime_id: invocation.caller_runtime_id.clone(),
native_request_sha256: invocation.native_request_sha256,
provider_request_sha256: invocation.provider_request_sha256,
model: invocation.request.model.clone(),
transport: "parity-sse".to_string(),
outcome,
}
}
fn completed(invocation: &kit::TransportInvocation) -> kit::TransportResult {
kit::TransportResult::transported(
invocation,
vec![
kit::TransportEvent {
sequence: 0,
payload: kit::TransportEventPayload::TextDelta {
text: "hello".to_string(),
},
},
kit::TransportEvent {
sequence: 1,
payload: kit::TransportEventPayload::ToolCall {
call_id: "call-2".to_string(),
name: "read_source".to_string(),
arguments: "{}".to_string(),
},
},
],
receipt(
invocation,
kit::TransportOutcome::Completed {
provider_response_id: Some("response-1".to_string()),
input_tokens: Some(10),
output_tokens: Some(3),
reasoning_output_tokens: Some(1),
cached_input_tokens: Some(4),
},
),
)
}
fn failed(invocation: &kit::TransportInvocation) -> kit::TransportResult {
kit::TransportResult::transported(
invocation,
Vec::new(),
receipt(
invocation,
kit::TransportOutcome::Failed {
failure_kind: "result_size".to_string(),
message: "provider result exceeded its byte bound".to_string(),
},
),
)
}
fn key() -> kit::TransportKey {
kit::TransportKey::from_connection_secret(KEY).unwrap()
}
fn refusals() -> [(&'static str, kit::Refusal, &'static [u8]); 9] {
use kit::Refusal as R;
[
("expired", R::Expired, golden!("result_refused_expired.mp")),
(
"identity_substitution",
R::IdentitySubstitution,
golden!("result_refused_identity_substitution.mp"),
),
(
"provider_digest_substitution",
R::ProviderDigestSubstitution,
golden!("result_refused_provider_digest_substitution.mp"),
),
("policy", R::Policy, golden!("result_refused_policy.mp")),
(
"capacity",
R::Capacity,
golden!("result_refused_capacity.mp"),
),
(
"in_flight",
R::InFlight,
golden!("result_refused_in_flight.mp"),
),
(
"indeterminate",
R::Indeterminate,
golden!("result_refused_indeterminate.mp"),
),
(
"replay_conflict",
R::ReplayConflict,
golden!("result_refused_replay_conflict.mp"),
),
(
"malformed",
R::Malformed,
golden!("result_refused_malformed.mp"),
),
]
}
#[test]
fn schema_ids_are_the_v2_ids() {
assert_eq!(
kit::PROVIDER_REQUEST_SCHEMA_ID,
"gamecult.codex.provider_request.v2"
);
assert_eq!(
kit::INVOCATION_SCHEMA_ID,
"gamecult.codex.transport_invocation.v2"
);
assert_eq!(kit::RESULT_SCHEMA_ID, "gamecult.codex.transport_result.v2");
assert_eq!(
kit::RECEIPT_SCHEMA_ID,
"gamecult.codex.transport_receipt.v2"
);
assert_eq!(
kit::ENVELOPE_SCHEMA_ID,
"gamecult.codex.transport_envelope.v2"
);
}
#[test]
fn invocations_carry_the_v2_bytes_for_each_tool_choice() {
assert_wire(
"auto",
&invocation(kit::ToolChoice::Auto),
golden!("invocation_auto.mp"),
);
assert_wire(
"required",
&invocation(kit::ToolChoice::Required),
golden!("invocation_required.mp"),
);
}
#[test]
fn results_carry_the_v2_bytes_for_success_and_failure() {
let invocation = invocation(kit::ToolChoice::Required);
assert_wire(
"transported",
&completed(&invocation),
golden!("result_transported.mp"),
);
assert_wire("failed", &failed(&invocation), golden!("result_failed.mp"));
}
#[test]
fn every_refusal_carries_its_v2_bytes() {
let invocation = invocation(kit::ToolChoice::Required);
for (name, refusal, golden) in refusals() {
assert_wire(
name,
&kit::TransportResult::refused(&invocation, refusal),
golden,
);
}
}
#[test]
fn canonical_bytes_and_provider_digest_are_the_v2_bytes() {
let invocation = invocation(kit::ToolChoice::Required);
assert_eq!(
kit::canonical_invocation_bytes(&invocation).unwrap(),
golden!("canonical_invocation.bin")
);
assert_eq!(
kit::canonical_provider_request_bytes(&invocation.request).unwrap(),
golden!("canonical_provider_request.bin")
);
assert_eq!(
kit::provider_request_sha256(&invocation.request)
.unwrap()
.as_slice(),
golden!("provider_request_sha256.bin")
);
}
#[test]
fn v2_sealed_envelopes_decrypt_and_validate_under_the_kit() {
let invocation = invocation(kit::ToolChoice::Required);
let envelope: kit::TransportEnvelope =
rmp_serde::from_slice(golden!("envelope_invocation.mp")).unwrap();
let received = kit::decrypt_invocation(&envelope, &key()).unwrap();
assert_eq!(bytes(&received), bytes(&invocation));
let results = [
(
golden!("envelope_result_transported.mp"),
completed(&invocation),
),
(golden!("envelope_result_failed.mp"), failed(&invocation)),
(
golden!("envelope_result_refused_replay_conflict.mp"),
kit::TransportResult::refused(&invocation, kit::Refusal::ReplayConflict),
),
];
for (sealed, expected) in results {
let envelope: kit::TransportEnvelope = rmp_serde::from_slice(sealed).unwrap();
let received = kit::decrypt_result(&envelope, &key(), &invocation).unwrap();
assert_eq!(bytes(&received), bytes(&expected));
}
}
#[test]
fn kit_sealed_envelopes_have_the_v2_shape() {
let invocation = invocation(kit::ToolChoice::Required);
let golden: kit::TransportEnvelope =
rmp_serde::from_slice(golden!("envelope_invocation.mp")).unwrap();
let sealed = kit::encrypt_invocation(&invocation, &key()).unwrap();
assert_eq!(sealed.schema_id, golden.schema_id);
assert_eq!(sealed.caller_runtime_id, golden.caller_runtime_id);
assert_eq!(sealed.request_id, golden.request_id);
assert_eq!(sealed.message_kind, golden.message_kind);
assert_eq!(sealed.ciphertext.len(), golden.ciphertext.len());
assert_ne!(sealed.nonce, golden.nonce, "nonces are fresh per seal");
let golden: kit::TransportEnvelope =
rmp_serde::from_slice(golden!("envelope_result_transported.mp")).unwrap();
let sealed = kit::encrypt_result(&completed(&invocation), &key()).unwrap();
assert_eq!(sealed.message_kind, golden.message_kind);
assert_eq!(sealed.ciphertext.len(), golden.ciphertext.len());
}