Skip to content

feat: Rust coordinator — coordinator-rs workspace (plan Milestones 1–4, pilot scope)#532

Draft
Gajesh2007 wants to merge 10 commits into
masterfrom
feat/rust-coordinator
Draft

feat: Rust coordinator — coordinator-rs workspace (plan Milestones 1–4, pilot scope)#532
Gajesh2007 wants to merge 10 commits into
masterfrom
feat/rust-coordinator

Conversation

@Gajesh2007

@Gajesh2007 Gajesh2007 commented Jul 10, 2026

Copy link
Copy Markdown
Member

Summary

Implements the Rust coordinator per docs/architecture/rust-coordinator-plan.md (added in this PR, including the latency amendments: speculative prefill, prepare-stage hedging, binary hot-path frames, calibrated TTFT, single-CTE money transactions). Greenfield: everything lives under coordinator-rs/; no existing coordinator/provider/UI code is touched.

  • crates/protocol — JSON v1 wire types pinned by 43 golden vectors generated from the real Go coordinator/protocol package (omitempty semantics locked for the Swift strict decoder); protocol-v2 frames (prepare/prepared/start/started/abort/cancel/signed terminal/ACK/model lifecycle) with job/attempt/lease + session/coordinator epoch + nonce + digest fencing; binary encrypted-payload frame codec (zero-copy decode); NaCl Box byte-verified against Go (incl. precomputed shared keys), sealed-sender envelope, P-256 attestation + canonical-status verification, v2 terminal digest canonicalization.
  • crates/core — pure domain: request-lifecycle reducer (funding CAS, one prepare hedge + one sequential alternate pre-start only, full §13 cancellation ladder, sent_unknown hold), fleet admission/scoring with clamped windowed-median TTFT calibration, health machine, permit book, hedge budget, revision-fenced model presence, settlement provenance + conserving splits + checkpoint-capped billing. Nine proptest suites cover every §9 invariant.
  • migrations/ — additive rust_coord schema (8 migrations): jobs with version CAS + frozen terms + an at-most-one-started-attempt partial unique index, terminal receipts with conflict flags, financial_operations idempotency keys, insert-only fee_allocations, external inbox/intents, outbox, coordinator ownership epoch. Plus a test-only legacy baseline traced from store/postgres.go and a money-flow SQL smoke.
  • crates/server — Axum chat completions (SSE + sealed transport), models, encryption-key; RequestTask driving the core reducer (v2 two-phase prepare/fund/start + hedging, v1 compatibility mapping that works against today's Swift providers); single-task FleetActor (reliable lane > coalesced heartbeats, epoch supersede); two-lane session writer with on-wire acks and a reserved terminal-class event slot; blocking-pool trust verifier (SE signatures incl. v2 terminals — forged terminals security-fence the provider); single-CTE reserve, advisory-lock-serialized spend caps, settle with fee rows + legacy projections, release, review parking; recovery sweepers (incl. expired running jobs → review_pending); ownership guard with black-hole-detecting keeper; phased-shutdown supervisor; bootstrap shared by the binary and tests.

Verification: 263 tests green (unit + property + Postgres-backed integration + a 4-scenario full-stack e2e with real ephemeral Postgres and fake providers doing real crypto over real WebSockets, asserting actual DB money rows and zero leaked permits); clippy zero warnings; release build clean; binary smoke (migrate → serve → readyz → SIGTERM drain → ownership release). Dual review (Bugbot + independent design review) found 8 issues — all fixed with fails-without-fix regressions in the final commit.

Behavior: before / after

flowchart LR
  subgraph Before["Before (Go coordinator, unchanged by this PR)"]
    A1[Consumer request] --> B1[Preflight scan + separate committing reserve]
    B1 --> C1[Dispatch ladder: up to 64 attempts,<br/>120s queue, start-stage speculation]
    C1 --> D1[inference_accepted before real capacity]
    D1 --> E1[Settlement fan-out goroutines<br/>process-local holds]
  end
  subgraph After["After (coordinator-rs, isolated pilot path)"]
    A2[Consumer request] --> B2[Durable single-CTE reserve<br/>idempotent op keys]
    B2 --> C2[One FleetActor::admit<br/>permit + frozen quote]
    C2 --> D2[v2: prepare -> prepared lease -> fund/freeze -> start<br/>one hedge + one alternate pre-start only]
    D2 --> E2[Signed terminal -> one settlement txn<br/>fee rows + legacy projections -> ACK after commit]
    C2 -.no capacity.-> F2[Fast 429 + Retry-After<br/>no internal queue]
  end
Loading

Code: before / after

flowchart LR
  subgraph Before["Before"]
    G1[coordinator/ Go control plane<br/>PendingRequest: 4 channels + 3 locks<br/>Registry god object, 157-method Store]
  end
  subgraph After["After (new, coexisting)"]
    H2[crates/protocol<br/>wire + crypto, pure]
    H3[crates/core<br/>reducers + admission + money math, pure]
    H4[crates/server<br/>Axum / RequestTask / FleetActor /<br/>ProviderSession / SQLx ledger / recovery]
    H5[migrations/ additive rust_coord schema]
    H2 --> H4
    H3 --> H4
    H5 --> H4
  end
  G1 ---|untouched; Go remains prod| G1
Loading

Scope and non-goals

Plan Milestones 1–4 code scope (isolated-pilot surface, §23.2). Deliberately excluded, per the plan's sequencing: Go Milestone-0 safety fixes (separate fast-fix work), the dual-stack Swift provider that speaks protocol v2 on the provider side, Stripe/Privy/MDM/enrollment/self-route surfaces, and any production cutover machinery. Known gaps are listed in the final commit message (unacked pre-start rejection terminals, fixed hedge timeout pending per-model percentiles, provider auth via account API keys pending a device-token surface, v1 bills the frozen prompt estimate).

Test plan

  • cargo test --workspace — 263 green (incl. Postgres-backed ledger/recovery/e2e suites)
  • cargo clippy --workspace --all-targets — zero warnings
  • Golden-vector compatibility vs Go protocol package (coordinator-rs/fixtures/)
  • Money-flow SQL smoke vs baseline + migrations
  • Binary smoke: migrate → serve → readyz → graceful SIGTERM
  • CI on this PR (no Rust lane exists yet — follow-up: add a coordinator-rs job to ci.yml)
  • Isolated pilot per plan §23 (separate env, dedicated providers) — future milestone

Made with Cursor


View with Codesmith Autofix with Codesmith
Need help on this PR? Tag /codesmith with what you need. Autofix is disabled.

Gajesh2007 and others added 7 commits July 9, 2026 20:17
Three-crate workspace (protocol/core/server) per plan §19.1, pinned
toolchain, workspace-level dependency pins. Carries the latency-amended
rust-coordinator-plan.md as the implementation reference.

Co-authored-by: Cursor <cursoragent@cursor.com>
…Milestone 1)

- protocol: JSON v1 wire types pinned by 43 Go-generated golden vectors,
  protocol-v2 tagged frames (prepare/start/terminal/ACK + epochs), binary
  encrypted-payload codec, Go-compatible NaCl Box / sealed sender / P-256.
- core: pure request-lifecycle reducer (hedge + cancellation ladder),
  fleet admission/scoring/calibration/health/permits, settlement math;
  proptest suites for every Milestone 1 exit-gate invariant.
- migrations: additive rust_coord schema (8 migrations) + test-only legacy
  baseline + money-flow smoke, validated on ephemeral Postgres 16.

Co-authored-by: Cursor <cursoragent@cursor.com>
contracts.rs defines every seam for parallel Phase-2 development: fleet
mailbox (reliable + coalesced heartbeat lanes), two-lane session writer
handles with on-wire acknowledgement, per-attempt event sinks, the
byte-accounted bounded chunk pipe (grace-window semantics, plan 13.6),
ledger facade trait, auth seam, and shared AppState.

Co-authored-by: Cursor <cursoragent@cursor.com>
…HTTP, request task (Milestones 3-4 code)

Three parallel components against the frozen contracts:
- spine+ledger: typed config, pooled SQLx with schema gate, advisory-lock
  ownership epoch, single-CTE reserve, resize/freeze, settle (fee rows +
  legacy projections), release, recovery sweepers, fee projection worker,
  supervisor with phased shutdown; 19 Postgres-backed integration tests.
- fleet+sessions: single-task FleetActor (reliable lane > coalesced
  heartbeats, epoch supersede, revision-fenced presence, calibration),
  two-lane provider session writer with on-wire acks, v1+v2 demux,
  blocking-pool trust verifier; 16 integration tests w/ fake providers.
- http+request_task: chat completions (SSE + sealed transport), models,
  encryption-key; RequestTask driving the core reducer (v2 prepare/fund/
  start + hedge, v1 compat mapping, cancellation ladder, checkpoint-capped
  settlement); 13 integration tests.

Co-authored-by: Cursor <cursoragent@cursor.com>
… DB, real WS provider)

- AdmitGrant now carries the fleet-minted permit_id and the provider
  public key (grant-frozen, reconnect-race-free); duplicate derivations
  and the ProviderKeyDirectory seam deleted.
- PriceCard moved to exact per-MTok integer rates; reservation and
  settlement share RoundingVersion::CeilV1 (never under-reserve).
- Provider payout rate moved to RequestPolicy (env-overridable ppm).
- v2 pre-start rejection terminals feed PrepareRejected{class} + fleet
  observations (capacity invalidation + health now actually wired).
- Single global hedge budget; fleet-side accounting deleted.
- bootstrap.rs shared by main and tests; one consolidated /readyz;
  graceful-shutdown deadlock on upgraded WebSockets fixed.
- Cross-component bugs fixed: v1 chunk format undecryptable end-to-end,
  v1 funding leg skipping the durable freeze, beneficiary resolution,
  placeholder fencing identifiers in resize/settle.
- e2e_full_stack.rs: 4 scenarios (v1 streaming, v2 two-phase + checkpoint
  cap review, funds/capacity/alternate, cancel partial-settle) asserting
  actual rust_coord + legacy DB rows, permit leaks, ledger consistency.

Workspace: 249 tests green, clippy zero warnings.
Co-authored-by: Cursor <cursoragent@cursor.com>
…sions

Core reducer (Bugbot):
- Post-cancel ContentAccepted no longer commits the request or advances
  the billing checkpoint; partial settle stays capped at the pre-cancel
  checkpoint (plan 13.4-13.6). Property harness pins the invariant.
- A definitive write-failure claim after sent_unknown now HOLDS the
  attempt (no abort/release/alternate) until provider evidence, lease
  expiry, or session loss (plan 13.2).

Server (independent design review, 6 P1s):
- Spend-cap write-skew: capped reserves take pg_advisory_xact_lock on
  the account first; 8-way concurrency regression test.
- New running-job sweeper: expired running jobs without a terminal
  receipt park in review_pending (reservation retained, plan 18.1).
- v2 terminal SE signatures verified at session intake (forged =>
  security fence) + settle defense-in-depth via signature_verified
  (unverified v2 => review_pending; v1 documented transport trust).
- Event-lane overflow: reserved per-attempt slot guarantees terminal-
  class delivery (plan 9.4.5).
- Ownership keeper: 5s ping timeout detects black-holed lock
  connections; health loss is permanent by design (plan 20).
- Request tasks tracked by the supervisor's requests phase; plus a
  PermitLedger Drop backstop so dropped driver futures release permits.

Workspace: 263 tests green, clippy zero warnings.
Co-authored-by: Cursor <cursoragent@cursor.com>
@vercel

vercel Bot commented Jul 10, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
d-inference Ready Ready Preview Jul 10, 2026 10:02pm
d-inference-console-ui-dev Ready Ready Preview Jul 10, 2026 10:02pm
d-inference-landing Ready Ready Preview Jul 10, 2026 10:02pm

Request Review

@github-actions

github-actions Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

This PR introduces a substantial new Rust coordinator codebase (coordinator-rs/) that is entirely outside the current threat model's affected_files coverage and introduces new or parallel trust-boundary surface that must be modelled before any production deployment.


Trust Boundaries Touched

None of the changed files match any existing affected_files pattern. However, based on file paths and module names, the following existing trust boundaries are structurally replicated or extended by this new codebase:

Existing TB New surface in coordinator-rs/
TB-001 (consumer → coordinator) Request machine (request/machine/), admission, effects, errors
TB-002 (coordinator → provider WebSocket) Fleet admission gates (fleet/admission/), scoring, permits, health
TB-006 (admin → coordinator) Admission decisions, calibration, model presence
TB-008 (coordinator → payments) money.rs, request effects

New Attack Surface Not Covered by Existing Threats

1. Parallel coordinator implementation — trust model undefined

coordinator-rs/ appears to be a Rust rewrite (or parallel implementation) of the Go coordinator. The threat model assumes a single trusted coordinator running on EigenCloud AMD SEV-SNP. If coordinator-rs runs alongside or as a replacement, every trust assumption in the model (TB-001 through TB-009) needs to be re-evaluated for the new implementation. Critical questions that must be answered before this reaches production:

  • Does coordinator-rs enforce the same attestation chain (TB-009)? The fleet admission gates (gates.rs) and decision.rs appear to encode provider routing policy, but there is no evidence of SE-signature verification, MDM/MDA verification, or challenge-response logic in the diffed files.
  • Does admit.rs in the request machine enforce the same 11-flag private-text routing gate as coordinator/registry/registry.go:169–197? The Go gate is the single chokepoint for consumer prompt privacy (A-001). A Rust reimplementation that misses any flag is a regression against T-009 / SEC-017.
  • Does scoring.rs / permits.rs replicate the binary-hash policy and weight-hash enforcement? If scoring admits providers without checking CodeAttested (T-034) or without the weight-hash gate (SEC-007 / T-027), the Rust path is fail-open by default.

2. money.rs — payment logic without visible idempotency controls

coordinator-rs/crates/core/src/money.rs introduces monetary types alongside request/effects.rs. The Go coordinator has a known non-atomic Stripe idempotency bug (SEC-012 / T-030). If this Rust implementation touches balance mutation, the same race condition must be explicitly addressed with a DB-level unique constraint. No such constraint is visible in the diffed files.

3. provider_error.rs and request/errors.rs — error granularity leak

The Go coordinator's device auth flow leaks code lifecycle via distinct 404 vs 410 responses (TB-001 current limitations). If provider_error.rs / errors.rs propagates similarly granular error variants to unauthenticated or consumer-facing surfaces, the same enumeration risk applies.

4. hedge.rs — speculative / hedged dispatch

fleet/hedge.rs suggests hedged request dispatch (sending to multiple providers speculatively). This has direct implications for A-001 (consumer prompts): a hedged request may fan out an encrypted prompt to more than one provider simultaneously. The threat model does not currently address fan-out routing; if the second provider receives the same consumer X25519-encrypted payload, and that provider is at a lower trust level than the primary, privacy guarantees are weakened.

5. No threat model entries for coordinator-rs/

All existing threats reference Go coordinator files under coordinator/. None reference coordinator-rs/. This means:

  • Automated threat-model coverage checks (like the one that triggered this review) will never flag regressions in the Rust codebase.
  • The affected_files patterns in the threat model YAML must be extended to cover coordinator-rs/crates/core/src/fleet/admission/, request/machine/, money.rs, and equivalents before this component is used in production.

Recommendations

  1. Before merging to a production-routable path: confirm whether coordinator-rs is purely internal library code, a shadow/canary deployment, or a replacement. If it can route real consumer requests or admit real providers, a threat model amendment PR is required first.
  2. Audit fleet/admission/gates.rs and request/machine/admit.rs against the Go registry's private-text routing gate (11 flags, registry.go:169–197) and the CodeAttested gate (T-034). Any missing flag is a privacy regression.
  3. Audit money.rs + request/effects.rs for idempotency controls on balance mutation (T-030 / SEC-012).
  4. Audit fleet/hedge.rs for fan-out trust-level enforcement — hedged requests must only go to providers meeting the same trust gate as the primary.
  5. Extend threat model affected_files to cover coordinator-rs/ paths so future PRs touching this codebase receive automated coverage.

🔐 Threat model: docs/threat-model.yaml · Updates on each push to this PR

Gajesh2007 and others added 2 commits July 10, 2026 12:38
… + Anchor-derived style guide

Networking (net_*.rs tests, socket-level):
- serve.rs: accept loop replacing bare axum::serve — TCP_NODELAY on every
  accepted socket (Nagle would eat the 2ms relay budget on Linux), armed
  header_read_timeout (hyper's default was silently disabled: no timer),
  HTTP/1.1 + h2c posture documented for the Caddy upstream.
- /health alias added — prod Caddyfile health_uri probes /health; only
  /healthz existed (every request would have been shed behind real Caddy).
- WS: max_frame_size raised to 32 MiB (tungstenite default 16 MiB rejected
  large single-frame sealed payloads); close handshake now write-bounded.
- Concurrency shed before body buffering (auth + permits from headers,
  429 in 0.7ms with body incomplete); 30s body-read timeout (408 vs 413).
- SSE: X-Accel-Buffering: no + no-store; per-chunk flush verified by a
  raw-TCP latency test (mean gap 14ms at 10ms cadence, no batching);
  backpressure verified bounded end-to-end (cancel at 1.17 MiB).
- reqwest demoted to dev-deps (no production HTTP client exists).

docs/STYLE.md: code-organization rules distilled from otter-sec/anchor
(soft 300 / hard 500 line cap, thin mod.rs, private siblings, types/
error/common placement, pub(crate) discipline) for the modularization pass.

Workspace: 271 tests green, clippy zero warnings.
Co-authored-by: Cursor <cursoragent@cursor.com>
…move-only)

Applied docs/STYLE.md (conventions distilled from otter-sec/anchor:
thin mod.rs = docs + re-exports, private siblings, types/error/common
placement, soft 300 / hard 500 line cap, one-sentence //! everywhere):

- request_task/driver.rs (1608) -> driver/ (11 files: dispatch, events,
  effects, chunks, timers, settlement, cancel, hedge, pumps, permits)
- contracts.rs (860) -> contracts/ (policy, session, chunks, fleet,
  ledger, state; flat re-exports keep every path stable)
- ledger/settle.rs (844) -> settle/ (transaction, receipt, money, review)
- http/chat.rs (663) -> chat/ (handler, request, stream, aggregate)
- trust.rs (548) -> trust/ (verifier, registration, challenge, types)
- json_v2/frames.rs (521) -> frames/ (7 files); settlement.rs (441) ->
  settlement/ (5); fleet/admission.rs (422) -> admission/ (4)
- sweep splits: fleet/admit, provider_session (v2_chunks, delivery,
  deps, lifecycle), http (config, middleware, provider_ws, state)
- tests: http_harness -> http_support/ module (no longer a standalone
  binary); http_chat and e2e_full_stack split one-feature-per-file
  with shared e2e_support/; 122 tests exact-name parity
- pub(crate)/pub(super) tightening where no external consumer exists

Move-only: zero behavior change, all external paths preserved via
re-export shims. Largest src file now 393 lines (was 1608); nothing
over the 500 hard cap. Workspace: 271 tests green, clippy zero
warnings, fmt clean.

Co-authored-by: Cursor <cursoragent@cursor.com>
@Gajesh2007

Copy link
Copy Markdown
Member Author

Two follow-up commits pushed:

Networking audit (a27d8064) — verified the HTTP/SSE/WebSocket stack at the socket level against the production Caddy topology; five real fixes: TCP_NODELAY + armed header-read timeout via a dedicated accept loop (bare axum::serve sets neither — Nagle alone would have blown the 2ms relay budget on the Linux host), a /health alias (prod Caddyfile probes /health; only /healthz existed — behind real Caddy every request would have been shed), WS max_frame_size 16→32 MiB + bounded close handshake, concurrency shed before body buffering, and X-Accel-Buffering/no-store on SSE. Raw-TCP latency test shows per-chunk delivery with no batching (mean gap 14ms at a 10ms send cadence); backpressure verified bounded end-to-end (provider cancel at 1.17 MiB with a stalled reader).

Modularization (8dd46787) — move-only restructure per coordinator-rs/docs/STYLE.md, distilled from the otter-sec/anchor workspace conventions (thin mod.rs, one concern per file, private siblings, types/error placement). Largest source file went from 1608 lines to 393; nothing above the 500 hard cap; all external paths preserved via re-export shims; 122 integration tests exact-name parity.

Workspace after both: 271 tests green, clippy zero warnings, fmt clean.

…TESTING.md

Move-only restructure of all three crates' integration tests from 27
separate test binaries into one tests/it/ binary per crate with a
module tree (e2e/, http/, ledger/, session/, net/ for server;
request/, fleet/, settlement/ for core; crypto/ for protocol):

- all #[path] support-module stitching deleted; harnesses are plain
  crate::support::* modules compiled once
- exact leaf test-name parity (server 71, core 53, protocol 19;
  sorted-name diffs empty); zero assertion/tunable changes
- parallelism audit for the merged binaries: per-test isolated
  Postgres clusters verified, no fixed ports, the four wall-clock-
  sensitive tests serialize behind support::timing_lock()
- proptest seed files relocated to the SourceParallel mirror tree
  (tests/proptest-regressions/<module>/<file>.txt) and proven read
  via corrupt-line probes
- dead-code allows removed from support modules (merged binary makes
  helpers live); 3 genuinely dead items deleted
- docs/TESTING.md: workspace test map, slice commands, external deps,
  golden-vector regeneration, plan-section traceability table
- STYLE.md rule 10 codifies the tests/it pattern

Server suite wall clock 20.6s -> ~12s; linked test executables 20 -> 3.
Workspace: 271 tests green, clippy zero warnings.

Co-authored-by: Cursor <cursoragent@cursor.com>
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