Skip to content

test(runtime-e2e): add x-client-id/ parity with the other 4 SDKs#41

Merged
saurabhjain1592 merged 1 commit into
mainfrom
feat/runtime-e2e-x-client-id-parity
May 19, 2026
Merged

test(runtime-e2e): add x-client-id/ parity with the other 4 SDKs#41
saurabhjain1592 merged 1 commit into
mainfrom
feat/runtime-e2e-x-client-id-parity

Conversation

@saurabhjain1592

Copy link
Copy Markdown
Member

Summary

Closes the post-merge coherence gap caught by master-tracker review of workstream B of Epic #2230: the Rust SDK was missing the runtime-e2e/x-client-id/ runner shipped by the other 4 SDKs (Go #168, Python #195, TS #227, Java #177).

This PR adds the runner. No SDK code changesrc/client.rs is unchanged from v0.3.0. Pure test infrastructure.

Bumps to v0.3.1 (patch).

Files

  • runtime-e2e/x-client-id/README.md — what the test verifies + how to run + parity context
  • runtime-e2e/x-client-id/test.sh — bash entry point: boots community docker-compose stack, runs the helper, asserts. Same shape as runtime-e2e/anthropic_interceptor/test.sh.
  • runtime-e2e/x-client-id/helper/ — small Rust cargo project (binary, publish = false) implementing an in-process forwarding-proxy: binds tokio TcpListener on 127.0.0.1:0, captures the SDK's outbound headers off the wire, forwards the request to AXONFLOW_AGENT_URL via reqwest, asserts the 4 v9 invariants.
  • CHANGELOG.md — v0.3.1 entry
  • Cargo.tomlversion = "0.3.1"

R1 — mechanical

  • cargo build --release clean
  • cargo clippy --all-targets -- -D warnings clean (SDK)
  • cargo clippy --all-targets -- -D warnings --manifest-path runtime-e2e/x-client-id/helper/Cargo.toml clean
  • cargo fmt --check clean (SDK + helper)
  • cargo test --quiet23 passed, 0 failed (existing v0.3.0 wiremock unit tests still pass — additive change)

R2 — functional (real-wire helper run)

Disclosure: Docker Desktop on the session host returned HTTP 500 from its API socket regardless of API version, so test.sh's full docker-compose path could not run end-to-end in this session. CI will exercise that path. To prove the helper logic itself is correct end-to-end, I ran the helper against a Python stand-in HTTP upstream on 127.0.0.1:18081 with full request-capture.

Helper stdout (PASS):

PASS: 4/4 header assertions
  X-Client-ID:       demo-client
  X-Axonflow-Client: sdk-rust/0.3.1
  Authorization:     Basic <redacted base64>
  X-Tenant-ID:       <absent (✓)>

Wire-level headers as received by the upstream (these are the exact bytes the agent would see):

content-type:      application/json
accept:            */*
user-agent:        axonflow-sdk-rust/0.3.1
x-axonflow-client: sdk-rust/0.3.1
authorization:     Basic ZGVtby1jbGllbnQ6ZGVtby1zZWNyZXQ=
x-client-id:       demo-client
host:              127.0.0.1:18081
content-length:    102

Decoding Basic ZGVtby1jbGllbnQ6ZGVtby1zZWNyZXQ=demo-client:demo-secret ✓ matches AXONFLOW_TENANT_ID:AXONFLOW_TENANT_SECRET.
x-tenant-id is absent ✓ — agent's apiAuthMiddleware still accepts it as an alias for back-compat through v9, but SDK-side we standardize on x-client-id.

R3 — hostile self-review (per feedback_mutation_test_to_prove_assertion_not_tautological.md)

Mutation test:

Step Action Result
1 Backed up src/client.rs/tmp/client_rs_baseline OK
2 Replaced headers.insert(\"X-Client-ID\", val); with // MUTATION-TEST: removed X-Client-ID OK
3 Reran helper (SDK rebuilt from mutated source) FAIL — exit code 1, stderr: FAIL: X-Client-ID: want \"demo-client\", got None
4 Restored src/client.rs from baseline OK
5 Reran helper PASS — exit code 0, all 4 assertions passed

✅ Mutation confirmed: the runtime-e2e assertion fails iff the SDK does not emit X-Client-ID. Assertion is not tautological.

Hostile review pass also checked:

  • clippy::doc_overindented_list_items on a multi-line doc-comment list in the helper — fixed in source before commit
  • No SDK behaviour changegit diff origin/main -- src/ is empty
  • Cross-SDK parity confirmed: Go has main.go, Python has test.py, TS has test.mjs, Java has SdkXClientIdTest.java, Rust now has test.sh + helper/ (matching Rust's existing anthropic_interceptor style)
  • Cargo.lock of helper not committed (helper-local .gitignore) — same justification as the comment in that file

Full R3 doc kept at /tmp/v9-rust-e2e-20260519T221516Z/r3.md (not committed per feedback_evidence_bundles_never_in_git.md).

Coordination

  • Independent of Phase 5 / Workstream C / Workstream D.
  • Per feedback_sub_sessions_admin_merge_when_ci_green_r3_done.md, admin-merging on green CI + R3 done; no master-tracker gating.

Mirrors the runtime-e2e/x-client-id/ runners shipped in workstream B of
Epic getaxonflow/axonflow-enterprise#2230 across Go/Python/TS/Java —
the Rust SDK was the one outlier, verifying v9 X-Client-ID via
wiremock-only unit tests with no live-agent companion.

runtime-e2e/x-client-id/test.sh boots the community docker-compose
stack (same shape as runtime-e2e/anthropic_interceptor/test.sh), then
builds + runs runtime-e2e/x-client-id/helper/, a small tokio-based
forwarding proxy that points the SDK at a 127.0.0.1 listener, captures
the SDK's outbound headers off the wire, forwards the request to the
real agent via reqwest, and asserts: X-Client-ID == AXONFLOW_TENANT_ID,
X-Axonflow-Client starts with sdk-rust/, Authorization starts with
'Basic ', and X-Tenant-ID is absent.

This is the wire-level companion to tests/x_client_id_header_test.rs
(which uses wiremock) — both must pass for the v9 identity contract
to be held.

Bumps to v0.3.1 (patch — test infrastructure only, no SDK code
change).

Signed-off-by: Saurabh Jain <saurabh.jain@getaxonflow.com>
@saurabhjain1592 saurabhjain1592 merged commit 38fac3b into main May 19, 2026
9 checks passed
@saurabhjain1592 saurabhjain1592 deleted the feat/runtime-e2e-x-client-id-parity branch May 19, 2026 22:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant