Skip to content

Telemetry & observability pipeline with Datadog integration#43

Merged
Gajesh2007 merged 16 commits into
masterfrom
cursor/production-system-telemetry-b491
Apr 22, 2026
Merged

Telemetry & observability pipeline with Datadog integration#43
Gajesh2007 merged 16 commits into
masterfrom
cursor/production-system-telemetry-b491

Conversation

@Gajesh2007

@Gajesh2007 Gajesh2007 commented Apr 16, 2026

Copy link
Copy Markdown
Member

Summary

Production observability pipeline for all components (coordinator, provider, macOS app, console UI) with Datadog as the primary backend.

  • Coordinator APM: dd-trace-go middleware for automatic HTTP request tracing, latency percentiles, and error tracking
  • DogStatsD metrics: inference dispatches, provider registrations, WS disconnects, attestation failures, queue depth, HTTP latency — all with dimensional tags
  • Provider → Coordinator → Datadog relay: 800+ provider Macs can't run the DD agent, so they batch events to the coordinator's /v1/telemetry/events endpoint, which forwards to Datadog Logs API (5s flush / 100-event batches)
  • Fatal alerting: severity=fatal events trigger Datadog Events so monitors can page
  • Log-trace correlation: custom slog handler injects dd.trace_id and dd.span_id into every coordinator log entry
  • Console UI RUM: Datadog Real User Monitoring with session replay (20%), user identity tracking, and Core Web Vitals
  • Privacy: field allowlisting enforced server-side before forwarding — prompts/responses never reach telemetry

Architecture

Provider (Rust) ──┐
macOS App (Swift) ─┤──► POST /v1/telemetry/events ──► Coordinator ──┬─► Datadog Logs API
Console UI (TS) ──┘    (rate-limited, allowlisted)                   ├─► Datadog Events API (fatal)
                                                                     └─► DogStatsD (metrics)
Coordinator (Go) ──► dd-trace-go ──► Datadog APM (traces)
Console UI ──► @datadog/browser-rum ──► Datadog RUM

What was stripped from the original telemetry PR

  • Postgres telemetry storage (queries, retention loop) — Datadog handles storage + retention
  • Admin telemetry dashboard at /stats/telemetry — use Datadog Log Explorer + Dashboards
  • Admin telemetry API proxy routes

Env vars required

Coordinator:

  • DD_API_KEY — Datadog API key
  • DD_SITE — Datadog region (e.g. datadoghq.com)
  • DD_ENVproduction or development
  • DD_DOGSTATSD_URL — DogStatsD address (default localhost:8125)

Console UI (Vercel):

  • NEXT_PUBLIC_DD_APPLICATION_ID — Datadog RUM application ID
  • NEXT_PUBLIC_DD_CLIENT_TOKEN — Datadog RUM client token
  • NEXT_PUBLIC_DD_SITE — Datadog region

Suggested Datadog monitors

  • Fatal events: logs("service:d-inference-coordinator source:provider severity:fatal").count() > 0
  • P95 latency: p95:trace.http.request{service:d-inference-coordinator} > 10s
  • Provider disconnect storm: sum:d_inference.ws.disconnects{*}.as_count() > 50 in 15min
  • Queue saturation: avg:d_inference.request_queue.depth{*} > 20

Test plan

  • go test ./... — all coordinator packages pass
  • cargo test — 281/281 provider tests pass (1 pre-existing flaky under parallel execution)
  • npm run build — console UI builds clean
  • npm test — 77/78 pass (1 pre-existing unrelated failure in api.test.ts)
  • Deploy to dev environment with DD_API_KEY set and verify traces appear in Datadog APM
  • Verify provider telemetry events appear in Datadog Log Explorer
  • Verify RUM sessions appear in Datadog UX Monitoring

🤖 Generated with Claude Code

@vercel

vercel Bot commented Apr 16, 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 Apr 17, 2026 0:49am
d-inference-landing Ready Ready Preview Apr 17, 2026 0:49am

Request Review

Comment thread console-ui/src/lib/telemetry.ts Fixed
Comment thread coordinator/internal/store/telemetry_postgres.go Fixed
cursoragent and others added 12 commits April 22, 2026 01:55
Introduces the telemetry wire protocol used across all EigenInference
components. Defines a single TelemetryEvent JSON shape with source,
severity, kind, machine_id, request_id, session_id, message, fields,
and stack.

- coordinator/internal/protocol/telemetry.go — canonical Go definition
- provider/src/telemetry/{mod,event,client,queue,layer,panic_hook,stderr_scraper}.rs — Rust mirror + machinery stubs
- console-ui/src/lib/telemetry-types.ts — TS mirror for the browser
- provider: fixed Cargo.toml so non-macOS deps (axum, anyhow, base64, chrono, etc.) compile everywhere, not just macOS
- provider: added once_cell + backtrace deps
- provider: fixed inprocess_engine type-inference issue when building without the python feature

Unit tests cover JSON round-trip, optional-field omission, and the
disk-backed overflow queue. Phase 1 (coordinator ingestion) next.

Co-authored-by: Gajesh Naik <Gajesh2007@users.noreply.github.com>
Adds the full ingestion pipeline on the coordinator side.

Storage
  - Postgres: new telemetry_events table with indexes on ts, source+severity,
    kind, machine_id, and request_id. Inserts use pgx CopyFrom.
  - Memory: bounded 10_000-event ring buffer with the same read API.
  - Common: TelemetryEventRecord + TelemetryFilter + TelemetryKindCount types
    in the store package.

API
  - POST /v1/telemetry/events — batch ingestion from providers, the macOS app,
    and the web console. Max 64KB body, max 100 events/batch, per-source
    token-bucket rate limiting (200 burst + 100/min authenticated,
    30 burst + 10/min anonymous). Fields outside the server allowlist are
    silently dropped so free-form user data can never leak into telemetry.
    Unknown source/severity/kind values are coerced to safe defaults
    (forward-compat with newer clients). Providers are automatically
    identified by their device-linked auth token; machine_id is derived
    deterministically from a SHA-256 digest.
  - GET  /v1/admin/telemetry — admin-only list with full filtering.
  - GET  /v1/admin/telemetry/summary — admin-only rollup by kind.
  - GET  /v1/admin/metrics — admin-only metrics snapshot (JSON or Prometheus
    text format).

Metrics
  - New Metrics registry (counters, histograms, computed gauges) with a
    stable key scheme, default latency buckets, and Prometheus text encoder.
  - Default gauge providers_online registered at boot.
  - Ingestion handler bumps telemetry_events_total{source,severity,kind}.

Retention
  - New internal/telemetry package. RunRetentionLoop prunes events older than
    EIGENINFERENCE_TELEMETRY_MAX_AGE (default 14d) every
    EIGENINFERENCE_TELEMETRY_PRUNE_INTERVAL (default 1h). Wired into main.go.

Tests
  - Memory store: insert/list/filter/ring-buffer-overflow/prune/count-by-kind.
  - HTTP handlers: anon ingest, malformed JSON, oversized batch, oversized
    body, empty-message rejection, rate limit, enum coercion, admin auth,
    admin list+summary, allowlist sanity, long-message truncation.

Full go test ./... passes across all packages.

Co-authored-by: Gajesh Naik <Gajesh2007@users.noreply.github.com>
Adds panic recovery, in-process metrics wired everywhere, and a
coordinator-side telemetry emitter that writes directly to the store.

Emitter (internal/telemetry/emitter.go)
  - NewEmitter(logger, store, metrics, version) — single coordinator-wide
    emitter. Persists one row per event, mirrors to slog at the appropriate
    level, bumps telemetry_events_total via the minimal MetricsSink adapter.
  - Event type exposes severity / kind / message / fields / request_id / stack.
  - Per-process SessionID so admin UI can group events from one boot.

Server wiring
  - Server holds *telemetry.Emitter + *Metrics. SetEmitter from main.go.
  - New helpers emit / emitRequest / emitPanic for call-site ergonomics.
  - Metrics() getter so main.go can pass the registry into the emitter.

Recover middleware
  - New recoverMiddleware wrapped outside loggingMiddleware; catches panics
    in any handler, captures debug.Stack, emits a fatal panic event, and
    returns 500. Propagates http.ErrAbortHandler unchanged.

Metrics rollout
  - HTTP requests: http_requests_total{method,path,status} +
    http_request_duration_ms histogram.
  - Inference path: inference_dispatches_total{result=success|retry|timeout|failure}.
  - Attestation: attestation_failures_total{reason}.
  - Provider lifecycle: provider_registrations_total{trust_level},
    ws_disconnects_total{reason}.
  - Default gauges: providers_online, pending_image_uploads.

Telemetry event sites in consumer.go / provider.go
  - inference retry / first-chunk timeout / dispatch-exhausted failure.
  - provider registration (with trust level + chip).
  - attestation challenge failure (promoted to error when threshold reached).
  - WebSocket read errors.

Prometheus renderer
  - Labels are serialized correctly ("k"="v"), le= suffix is merged into
    histogram bucket labels instead of concatenated to the metric name.

Tests
  - metrics_test.go covers counter add, stable-label keying regardless of
    order, histogram bucket cumulative counts + sum, gauge recompute, and
    Prom text format.
  - recover_middleware_test.go panics a handler and asserts a stored
    telemetry event with non-empty stack.

Full go test ./... is green.

Co-authored-by: Gajesh Naik <Gajesh2007@users.noreply.github.com>
…connect events

Wires the Rust provider into the telemetry pipeline.

Boot (cmd_serve)
  - Initializes the telemetry client with the coordinator URL, device-linked
    auth token, machine_id (SE public key), and version.
  - Installs the panic hook BEFORE the subprocess spawns so any crash during
    model load / backend bringup is captured with a full backtrace.
  - Emits a provider_start event with hardware context (chip, memory).

Backend monitor (backend/mod.rs)
  - Health-check failures now emit a backend_crash event with the backend
    name and the error (if any). Restart failures emit a second event
    so operators see both the trigger and the recovery outcome.

Coordinator client (coordinator.rs)
  - Reconnect storms are reported at exponential intervals (attempts 3, 10,
    then every 30) so transient Wi-Fi hiccups don't spam the admin console.
  - Events include the reconnect count + last error + ws_state.

Tests
  - tests/telemetry_symmetry.rs — self-contained Rust fixture asserting the
    wire JSON shape (enum casing, optional omission) matches Go.
  - tests/telemetry_integration.rs — real reqwest POST against a local axum
    stub, confirming the batch shape the client sends is valid.
  - coordinator/internal/protocol/telemetry_symmetry_test.go — Go canonical
    encoding check.

Also: full cargo test (246 unit + 3 integration) still passes.

Co-authored-by: Gajesh Naik <Gajesh2007@users.noreply.github.com>
Adds a Swift-side telemetry reporter that ships app-level failures to the
coordinator ingest endpoint using the same wire protocol as the provider.

TelemetryReporter
  - Singleton reporter with a bounded 500-event in-memory buffer.
  - Debounced batch flush (3s idle, max 100 events per batch).
  - Server-side allowlist mirrored client-side so we never accidentally
    ship prompts or free-form user content.
  - Stable per-install machine ID (UUID stored in UserDefaults).
  - Per-launch session ID so admin UI can group events from a run.
  - Retries on transport error without unbounded growth.

App wiring
  - EigenInferenceApp/AppDelegate installs NSSetUncaughtExceptionHandler
    that ships a fatal panic event with the full call stack.
  - configureTelemetry() resolves the coordinator URL from ConfigManager,
    converting wss:// -> https:// so the ingest endpoint reaches the same
    host as the WebSocket.

ProviderManager
  - Subprocess crashes now emit a structured backend_crash event with
    exit_code / signal / attempt / model / truncated last-stderr.
  - Startup failures emit a backend_crash event too so operators don't
    miss spawn-time problems.
  - Restart-limit-exceeded upgrades to severity=fatal with reason
    'restart_limit_exceeded'.

Tests
  - TelemetryReporterTests covers enum raw values (wire contract with Go),
    wss/ws -> https/http URL mapping, machine_id stability, and session_id
    presence. Runs in macOS CI where swift is available.

Co-authored-by: Gajesh Naik <Gajesh2007@users.noreply.github.com>
Hooks the Next.js console into the telemetry pipeline.

Client (src/lib/telemetry.ts)
  - Debounced batch sender (100 events max per flush, 2s debounce).
  - Client-side allowlist mirror so we don't even send prompts / nested
    objects that the coordinator would drop.
  - Per-session UUID + proper id/timestamp stamping.
  - Uses navigator.sendBeacon on page unload when available; falls back
    to fetch with keepalive.
  - On transport failure, the batch is re-queued oldest-first with a
    hard cap so live errors are never starved.
  - Exports _resetForTest + _bufferSize for vitest.

Proxy route (src/app/api/telemetry/route.ts)
  - POST /api/telemetry forwards to {NEXT_PUBLIC_COORDINATOR_URL}/v1/telemetry/events.
  - 64KB body cap matches coordinator's limit.
  - Pass-through of Authorization header for account attribution.
  - 10s upstream timeout so a wedged coordinator can't stall page unload.
  - 502 on upstream failure so the client re-queues correctly.

Global handlers (TelemetryInitializer + global-error.tsx)
  - window.error and unhandledrejection forwarders emit http_error events.
  - TelemetryInitializer emits a session_start log on first mount.
  - Next.js global-error.tsx boundary catches unrecoverable render
    errors, reports fatal + renders a friendly fallback with a reset
    button. Stack trace included.

Tests (console-ui/__tests__/telemetry.test.ts)
  - Happy-path forwarding (202 + correct URL + auth header).
  - Oversized body rejection (413).
  - Upstream failure returns 502.
  - Client-side allowlist filtering.

TS + lint clean on all new files. Pre-existing test failures on master
are untouched.

Co-authored-by: Gajesh Naik <Gajesh2007@users.noreply.github.com>
Adds a /stats/telemetry page to the console so admins can inspect the
live event stream and triage incidents without SSHing into the DB.

Page (console-ui/src/app/stats/telemetry/page.tsx)
  - Last-24h rollup tiles grouped by (source, severity, kind).
  - Filterable event list (source, severity, kind).
  - Per-event expandable details with fields JSON and stack trace.
  - Color-coded severity column.
  - Relies on coordinator-side admin enforcement: non-admin Privy users
    get a 403 and a friendly message rather than a broken page.

Proxy routes
  - GET /api/admin/telemetry -> coordinator GET /v1/admin/telemetry.
  - GET /api/admin/telemetry/summary -> coordinator rollup endpoint.
  - Pass-through of Authorization header so the coordinator is the
    single source of truth for access control.

Co-authored-by: Gajesh Naik <Gajesh2007@users.noreply.github.com>
- docs/telemetry.md: full architecture, wire protocol, endpoint table,
  privacy/allowlist contract, retention config, schema, per-component
  emission sites, and a 'how to add a new emit site' guide.
- AGENTS.md / CLAUDE.md: telemetry symmetry sync points (Go + Rust + TS)
  and the field-allowlist privacy invariant called out in 'Common Pitfalls'.

Co-authored-by: Gajesh Naik <Gajesh2007@users.noreply.github.com>
Adds a coordinator-side E2E test that drives the full ingestion pipeline
through the real HTTP server:
  - POST /v1/telemetry/events with an intentionally rogue 'prompt' field.
  - Assert admin list requires auth (403 without, 200 with).
  - Assert the stored event has the prompt field STRIPPED (privacy
    invariant).
  - Assert the admin summary endpoint returns counts.
  - Assert JSON metrics snapshot contains the ingestion counter.
  - Assert Prometheus text format is well-formed.
  - Seed a 30-day-old event, run the retention loop, confirm deletion.

Adds telemetry.RunRetentionLoopOnce for synchronous prune trigger, used
by the test above.

Full coordinator suite (go test ./...): all packages green.
Full provider suite (cargo test --no-default-features): 246 unit + 3
integration tests green.

Live binary run (in-memory store) verified:
  - 1 event ingest -> 202, allowlist strips 'prompt' field.
  - admin list returns cleaned event.
  - metrics endpoint shows http_requests_total + telemetry_events_total.
  - Prometheus format renders correctly.
  - Anon rate limiter: first 20-event flood accepted, next three flushes
    rejected with 429.
  - Malformed JSON -> 400.

Walkthrough artifact: /opt/cursor/artifacts/telemetry-live-demo.md

Co-authored-by: Gajesh Naik <Gajesh2007@users.noreply.github.com>
CI's gofmt -l check on the Coordinator Tests job flagged three files
authored in this PR. Pure whitespace/alignment diffs from gofmt -w; no
behavior change.

  internal/api/server.go
  internal/api/telemetry_handlers.go
  internal/api/telemetry_handlers_test.go

go test ./... still green.

Co-authored-by: Gajesh Naik <Gajesh2007@users.noreply.github.com>
Lint cleanup for the new telemetry handler — the orphan prettyJSON helper
was never wired up, and 'max' shadows a Go 1.21+ predeclared builtin.
Renamed to maxLen.

The remaining Coordinator Lint job failures (gochecknoglobals, sloglint,
gocognit, testpackage) match the existing codebase style and are
already failing on master, not introduced by this PR.

Co-authored-by: Gajesh Naik <Gajesh2007@users.noreply.github.com>
Replace self-hosted Postgres telemetry storage with Datadog integration:

- Add dd-trace-go APM for automatic request tracing on coordinator
- Add DogStatsD metrics: HTTP latency, inference dispatches, provider
  registrations, WS disconnects, attestation failures, queue depth
- Forward provider/app/console telemetry events to Datadog Logs API
  via batched async forwarder (5s flush / 100-event batches)
- Emit Datadog Events for fatal-severity alerts (monitor-triggerable)
- Add slog handler for dd.trace_id/dd.span_id log-trace correlation
- Add Datadog RUM to console UI with session replay and user identity
- Strip Postgres telemetry queries, admin dashboard, retention loop
- Keep provider→coordinator event relay (providers can't run DD agent)
- Keep field allowlisting and rate limiting on ingestion endpoint
- Fix provider Cargo.toml duplicate macos dependency section
- Fix goroutine race in log flush WaitGroup initialization
@Gajesh2007
Gajesh2007 force-pushed the cursor/production-system-telemetry-b491 branch from 7748476 to 34c8202 Compare April 22, 2026 13:34
@Gajesh2007 Gajesh2007 changed the title Telemetry & crash-reporting pipeline (all components) Telemetry & observability pipeline with Datadog integration Apr 22, 2026
Comment thread coordinator/internal/datadog/datadog.go Fixed
- Replace Math.random() fallback with crypto.getRandomValues for
  session ID generation in telemetry client
- Cap Fields map size before allocation to prevent integer overflow
  in Datadog log forwarding
Comment thread coordinator/internal/datadog/datadog.go Fixed
Fetch DD_API_KEY and DD_SITE from GCP Secret Manager alongside
existing secrets. Sets DD_ENV=development and DD_SERVICE for the
dev coordinator on GCE.
@Gajesh2007
Gajesh2007 marked this pull request as ready for review April 22, 2026 14:00
@Gajesh2007
Gajesh2007 merged commit 76644dc into master Apr 22, 2026
9 of 15 checks passed
Gajesh2007 added a commit that referenced this pull request Jun 17, 2026
Picks up the dequant makeMask fast path (MLX #3384 avoidance on the GPT-OSS
dequant path) and the composite-CacheList guard in cacheFactoryKind.
Gajesh2007 added a commit that referenced this pull request Jun 18, 2026
- BatchScheduler: reserve VLM media requests at the fp16 KV rate, not the
  quantized rate. VLM media streams through container.generate (fp16 KV, not the
  quantized batched cache), so reserving at the ~0.52x quantized rate under-counts
  ~2x and risks unified-memory OOM under concurrent media. New fp16KVBytesPerToken;
  no-op when KV quant is off.
- kv-attn-selftest: exit(1) when any DAR gate fails (was always exit 0 -> CI would
  treat a failing correctness gate as success).
- kv-engine-demo: enforce --generation-timeout in the concurrency sweep (per-stream
  timeout race) so a stalled stream aborts instead of hanging; also dump full
  fp16-vs-quant generations for eyeball quality diffing.
- kv-quant-gate: --candidate auto honors DARKBLOOM_KV_GPTOSS_KERNEL=1 (kernel vs
  dequant), mirroring the live scheduler.
- Bump mlx-swift-lm -> quantized-cache IOGPU leak fix (#43).

Note: Codex 'kernel silently dequant for Gemma' (Scheduler.swift:947) verified as a
FALSE POSITIVE — the served gemma-4-26b checkpoint has vision_config, so it loads via
the VLM Gemma4 class which DOES use the quantized kernel (Gemma4.swift:839/893); the
update-only LLM Gemma4Text class is never instantiated for it.
Gajesh2007 added a commit that referenced this pull request Jun 20, 2026
- BatchScheduler: reserve VLM media requests at the fp16 KV rate, not the
  quantized rate. VLM media streams through container.generate (fp16 KV, not the
  quantized batched cache), so reserving at the ~0.52x quantized rate under-counts
  ~2x and risks unified-memory OOM under concurrent media. New fp16KVBytesPerToken;
  no-op when KV quant is off.
- kv-attn-selftest: exit(1) when any DAR gate fails (was always exit 0 -> CI would
  treat a failing correctness gate as success).
- kv-engine-demo: enforce --generation-timeout in the concurrency sweep (per-stream
  timeout race) so a stalled stream aborts instead of hanging; also dump full
  fp16-vs-quant generations for eyeball quality diffing.
- kv-quant-gate: --candidate auto honors DARKBLOOM_KV_GPTOSS_KERNEL=1 (kernel vs
  dequant), mirroring the live scheduler.
- Bump mlx-swift-lm -> quantized-cache IOGPU leak fix (#43).

Note: Codex 'kernel silently dequant for Gemma' (Scheduler.swift:947) verified as a
FALSE POSITIVE — the served gemma-4-26b checkpoint has vision_config, so it loads via
the VLM Gemma4 class which DOES use the quantized kernel (Gemma4.swift:839/893); the
update-only LLM Gemma4Text class is never instantiated for it.
Gajesh2007 added a commit that referenced this pull request Jun 20, 2026
…ntation

Submodule mlx-swift-lm -> 0f46814 (darkbloom/kvquant, #43): on-GPU penalty
sampler, KV-quant SDPA mx.compile + n==1 decode-mask skip, per-token decode
wins (logSumExp skip, B==1 .item(), resource-debug off-by-default).

kv-engine-demo: add submit->first-token TTFT and prefill tok/s measurement
(measurement-only).
Gajesh2007 added a commit that referenced this pull request Jun 20, 2026
mlx-swift-lm #43 squash-merged to main as a9e0ee1 and its branch was deleted,
orphaning the prior submodule pointer. Re-point to the merged main commit
(identical engine tree to the tested head, no behavior change) so the
submodule is fetchable from a clean checkout/CI.
Gajesh2007 added a commit that referenced this pull request Jun 20, 2026
mlx-swift-lm #43 squash-merged to main (a9e0ee1) and its branch was deleted,
orphaning the prior pointer. Re-point to the merged main commit so the
submodule is fetchable from a clean checkout/CI.
Gajesh2007 added a commit that referenced this pull request Jun 20, 2026
…-313) (#377)

* feat(provider): KV quant benchmark gate with V-only affine4 pass

- Add kv-quant-gate CLI and supporting Benchmark/KVQuant modules for
  PPL, logits, output, NIAH, performance, and memory suites.
- Implement custom KVQuantizedCache and VOnlyQuantizedKVCache wrappers
  with start-token delay and sliding-window preservation.
- Wire candidate cache injection into the performance runner so
  reference and candidate metrics are collected end-to-end.
- Resolve HF-cache symlinks before file-extension checks in
  LocalMLXModelReadiness so downloaded snapshots load correctly.
- Shift release thresholds to agreement metrics where the fp16 baseline
  itself can fail (output/NIAH), and add json_valid/required_substrings
  agreement rates.
- Default candidate is full-v-affine4:g64:start1024; affine4/8 full-KV
  and turbo modes are currently rejected as unsupported by the gate.

V-only affine4 passes quality gates for both Gemma 4 26B and GPT-OSS-20B.

* feat(provider): bfloat16 KV cache mode and benchmark-gated quality

- Add `bf16-kv:start1024` candidate mode with a custom BFloat16KVCache
  wrapper. This halves KV-cache precision with no model-attention changes
  and passes PPL/logits/output/NIAH gates for both Gemma 4 26B and
  GPT-OSS-20B.
- Switch `affine4/8` full-KV modes to mlx-swift-lm upstream dynamic
  quantization (GenerateParameters.kvBits) and add an incremental
  teacher-forced scorer so the PPL/logits suites can exercise the same
  quantized generation path. (Upstream QuantizedKVCache fatal-errors on
  the single-forward update path, so the old scorer could not be used.)
- Reset MLX peak memory between reference and candidate baseline runs so
  peak-memory ratios are per-run rather than cumulative.
- Use peak-memory max (instead of mean) for threshold memory ratios.
- Update KVQuantExecutionTests for the new affine4/8/bf16 behavior.

* feat(provider): add full-v-bf16 KV cache candidate

- Add `full-v-bf16:start1024` candidate mode and VOnlyBFloat16KVCache
  wrapper: keys stay fp16, values are stored as bfloat16 after the start
  token. This is intended as a middle-ground compression option that
  works with model attentions using the plain update(keys:values:) path.
- Quality gate passes for Gemma 4 26B; memory/perf impact is still being
  measured against the current total-GPU-peak metric.
- Update KVQuantExecutionTests for the new mode.

* feat(provider): protocol-safe quantized cache wrapper and policy alignment

- Add ProtocolSafeQuantizedKVCache: wraps upstream QuantizedKVCache and
  implements update(keys:values:) with a dequantizing fallback. This lets
  full-KV affine modes run through both the native quantized attention
  path and the plain update path used by single-forward scoring.
- Switch affine4/8 execution back to a custom cache factory (the protocol-safe
  wrapper) so the gate can evaluate full-KV quantization end-to-end.
- Add a minimum PPL ratio threshold (0.99) so large candidate-perplexity
  decreases are also flagged as failures.
- Update KVQuantPolicy to recommend the validated `full-v-affine4:g64:start1024`
  candidate for Gemma 4 and GPT-OSS, and adjust KVQuantPolicyTests.

* feat(kvquant): prove kernel correctness, fix scorer measurement bug, add capacity metric

First-principles instrumentation for the KV-cache capacity objective:

- kv-attn-selftest executable: deterministic numerical probes proving
  quantizedScaledDotProductAttention == dequantize+SDPA exactly (MHA/GQA/
  causal/decode, 8/4-bit), so the kernel is correct after the mask-fill fix.
  Outlier + multi-step + per-channel isolation cases included.
- Fix mask-fill bug in quantizedScaledDotProductAttention (vendored): masked
  positions used +leastNormalMagnitude (~0) instead of -inf.
- Fix a measurement bug: the single-forward PPL/logits scorer let start-delayed
  caches silently return fp16 (never engaging quantization). Candidate scoring
  now runs true incremental token-by-token through the candidate's own cache.
  KVQuantCacheProbe deterministically validates single-forward vs incremental
  divergence (one-shot diff 0.0 vs incremental 0.31) — no 26B run needed.
- Add a model-free capacity suite + per-mode stored K/V bits and
  capacityRatioVsFP16 (incl. affine scale/bias overhead). Exposes that bf16
  modes are 1.0x (no capacity gain) and affine8 is ~1.78x (overhead), making
  KV-bytes-per-token the headline metric.

Finding: Gemma 4 K8V8 collapse (top1 0.56) is genuine compounded quantization
loss across ~48 layers, NOT a kernel bug (dequant path == kernel path == 0.5595).
Per-layer cos 0.999 still compounds to large end-to-end drift.

* feat(kvquant): trustworthy generation-fidelity gate; honest quality/capacity Pareto

Raw-text teacher-forced PPL/logits was an untrustworthy gauge (reference NLL
~5.3 nats / PPL ~200 on trivial text; ppl.ratio<1). Replace the logits suite
with generation-fidelity: the reference greedily continues a coherent prompt,
the candidate is teacher-forced over that continuation, and we measure top-1 /
top-5 agreement on confident tokens through the correct generation forward
(quantization engaged incrementally). reference-self match = 1.000 validates it.

Honest Gemma 4 26B Pareto (capacity includes affine scale/bias overhead):
  V-only 4-bit  start1024 : 1.56x,  top1 1.000
  K8V8          start0    : 1.78x,  top1 0.931, top5 0.993
  K4V4          start0    : 3.56x,  top1 0.892, top5 0.941

Conclusion: earlier 'catastrophic' 0.56 numbers were gauge artifacts, not real
quantization loss. V4 is effectively lossless; K8V8 is already 0.93 with no
start delay. Next: long-context stress + start-delay/residual window + asymmetric
K8/V4 to reach quality-preserving 2x.

* feat(kvquant): establish quality-preserving ~2x via long-context gen-fidelity sweep

Long-context generation-fidelity (2048-3072 tok prompts, ~768 samples) gives a
trustworthy quality x capacity Pareto on BOTH target models:

  K8V8 g128  -> 1.94x : Gemma 0.973 top1,  GPT-OSS 0.982 top1   (robust ~2x)
  K6V6 g64   -> 2.46x : Gemma 0.977 top1,  GPT-OSS 0.932 (min 0.78, riskier)
  V4         -> 1.56x : ~0.995 (near-lossless anchor)

Path selection (both store quantized = capacity gain):
- Gemma 4: kernel path (ProtocolSafeQuantizedKVCache, quantized attention).
- GPT-OSS: kernel path FATALS ('Quantized attention does not support non-zero
  sinks'); use dequant path (KVQuantizedCache) which is sink-safe and still
  stores quantized.

Gate plumbing: long coherent prompts truncated to target context; prompt primed
in one batched forward then decoded token-by-token; KVQ_BITS/KVQ_GROUP/KVQ_DEQUANT
env knobs for Pareto sweeps. Conclusion: ~2x capacity at high fidelity is real;
K8V8 g128 is the conservative cross-model pick.

* DAR-313: make validated KV-quant configs first-class modes, remove env-var sweep hacks

- Remove KVQ_BITS/KVQ_GROUP/KVQ_DEQUANT env reads from affine4/affine8 execution.
- Add first-class modes: k8v8:g128, k8v8:g64:dequant, k6v6:g64, k6v6:g64:dequant.
- Wire all KVQuantCandidateMode switches (types, cacheSpec, execution config).
- Update effectiveBits to use the mode's actual group size for accurate capacity ratio.
- Add parse + factory-non-nil tests for the four new modes.

* chore(submodule): bump mlx-swift-lm to darkbloom/kvquant (KV-quant mask fix) [DAR-313]

* chore(kvquant): point engine submodule at merged main (#43 -> a9e0ee1)

mlx-swift-lm #43 squash-merged to main (a9e0ee1) and its branch was deleted,
orphaning the prior pointer. Re-point to the merged main commit so the
submodule is fetchable from a clean checkout/CI.
Gajesh2007 added a commit that referenced this pull request Jun 20, 2026
)

* feat(provider): KV quant benchmark gate with V-only affine4 pass

- Add kv-quant-gate CLI and supporting Benchmark/KVQuant modules for
  PPL, logits, output, NIAH, performance, and memory suites.
- Implement custom KVQuantizedCache and VOnlyQuantizedKVCache wrappers
  with start-token delay and sliding-window preservation.
- Wire candidate cache injection into the performance runner so
  reference and candidate metrics are collected end-to-end.
- Resolve HF-cache symlinks before file-extension checks in
  LocalMLXModelReadiness so downloaded snapshots load correctly.
- Shift release thresholds to agreement metrics where the fp16 baseline
  itself can fail (output/NIAH), and add json_valid/required_substrings
  agreement rates.
- Default candidate is full-v-affine4:g64:start1024; affine4/8 full-KV
  and turbo modes are currently rejected as unsupported by the gate.

V-only affine4 passes quality gates for both Gemma 4 26B and GPT-OSS-20B.

* feat(provider): bfloat16 KV cache mode and benchmark-gated quality

- Add `bf16-kv:start1024` candidate mode with a custom BFloat16KVCache
  wrapper. This halves KV-cache precision with no model-attention changes
  and passes PPL/logits/output/NIAH gates for both Gemma 4 26B and
  GPT-OSS-20B.
- Switch `affine4/8` full-KV modes to mlx-swift-lm upstream dynamic
  quantization (GenerateParameters.kvBits) and add an incremental
  teacher-forced scorer so the PPL/logits suites can exercise the same
  quantized generation path. (Upstream QuantizedKVCache fatal-errors on
  the single-forward update path, so the old scorer could not be used.)
- Reset MLX peak memory between reference and candidate baseline runs so
  peak-memory ratios are per-run rather than cumulative.
- Use peak-memory max (instead of mean) for threshold memory ratios.
- Update KVQuantExecutionTests for the new affine4/8/bf16 behavior.

* feat(provider): add full-v-bf16 KV cache candidate

- Add `full-v-bf16:start1024` candidate mode and VOnlyBFloat16KVCache
  wrapper: keys stay fp16, values are stored as bfloat16 after the start
  token. This is intended as a middle-ground compression option that
  works with model attentions using the plain update(keys:values:) path.
- Quality gate passes for Gemma 4 26B; memory/perf impact is still being
  measured against the current total-GPU-peak metric.
- Update KVQuantExecutionTests for the new mode.

* feat(provider): protocol-safe quantized cache wrapper and policy alignment

- Add ProtocolSafeQuantizedKVCache: wraps upstream QuantizedKVCache and
  implements update(keys:values:) with a dequantizing fallback. This lets
  full-KV affine modes run through both the native quantized attention
  path and the plain update path used by single-forward scoring.
- Switch affine4/8 execution back to a custom cache factory (the protocol-safe
  wrapper) so the gate can evaluate full-KV quantization end-to-end.
- Add a minimum PPL ratio threshold (0.99) so large candidate-perplexity
  decreases are also flagged as failures.
- Update KVQuantPolicy to recommend the validated `full-v-affine4:g64:start1024`
  candidate for Gemma 4 and GPT-OSS, and adjust KVQuantPolicyTests.

* feat(kvquant): prove kernel correctness, fix scorer measurement bug, add capacity metric

First-principles instrumentation for the KV-cache capacity objective:

- kv-attn-selftest executable: deterministic numerical probes proving
  quantizedScaledDotProductAttention == dequantize+SDPA exactly (MHA/GQA/
  causal/decode, 8/4-bit), so the kernel is correct after the mask-fill fix.
  Outlier + multi-step + per-channel isolation cases included.
- Fix mask-fill bug in quantizedScaledDotProductAttention (vendored): masked
  positions used +leastNormalMagnitude (~0) instead of -inf.
- Fix a measurement bug: the single-forward PPL/logits scorer let start-delayed
  caches silently return fp16 (never engaging quantization). Candidate scoring
  now runs true incremental token-by-token through the candidate's own cache.
  KVQuantCacheProbe deterministically validates single-forward vs incremental
  divergence (one-shot diff 0.0 vs incremental 0.31) — no 26B run needed.
- Add a model-free capacity suite + per-mode stored K/V bits and
  capacityRatioVsFP16 (incl. affine scale/bias overhead). Exposes that bf16
  modes are 1.0x (no capacity gain) and affine8 is ~1.78x (overhead), making
  KV-bytes-per-token the headline metric.

Finding: Gemma 4 K8V8 collapse (top1 0.56) is genuine compounded quantization
loss across ~48 layers, NOT a kernel bug (dequant path == kernel path == 0.5595).
Per-layer cos 0.999 still compounds to large end-to-end drift.

* feat(kvquant): trustworthy generation-fidelity gate; honest quality/capacity Pareto

Raw-text teacher-forced PPL/logits was an untrustworthy gauge (reference NLL
~5.3 nats / PPL ~200 on trivial text; ppl.ratio<1). Replace the logits suite
with generation-fidelity: the reference greedily continues a coherent prompt,
the candidate is teacher-forced over that continuation, and we measure top-1 /
top-5 agreement on confident tokens through the correct generation forward
(quantization engaged incrementally). reference-self match = 1.000 validates it.

Honest Gemma 4 26B Pareto (capacity includes affine scale/bias overhead):
  V-only 4-bit  start1024 : 1.56x,  top1 1.000
  K8V8          start0    : 1.78x,  top1 0.931, top5 0.993
  K4V4          start0    : 3.56x,  top1 0.892, top5 0.941

Conclusion: earlier 'catastrophic' 0.56 numbers were gauge artifacts, not real
quantization loss. V4 is effectively lossless; K8V8 is already 0.93 with no
start delay. Next: long-context stress + start-delay/residual window + asymmetric
K8/V4 to reach quality-preserving 2x.

* feat(kvquant): establish quality-preserving ~2x via long-context gen-fidelity sweep

Long-context generation-fidelity (2048-3072 tok prompts, ~768 samples) gives a
trustworthy quality x capacity Pareto on BOTH target models:

  K8V8 g128  -> 1.94x : Gemma 0.973 top1,  GPT-OSS 0.982 top1   (robust ~2x)
  K6V6 g64   -> 2.46x : Gemma 0.977 top1,  GPT-OSS 0.932 (min 0.78, riskier)
  V4         -> 1.56x : ~0.995 (near-lossless anchor)

Path selection (both store quantized = capacity gain):
- Gemma 4: kernel path (ProtocolSafeQuantizedKVCache, quantized attention).
- GPT-OSS: kernel path FATALS ('Quantized attention does not support non-zero
  sinks'); use dequant path (KVQuantizedCache) which is sink-safe and still
  stores quantized.

Gate plumbing: long coherent prompts truncated to target context; prompt primed
in one batched forward then decoded token-by-token; KVQ_BITS/KVQ_GROUP/KVQ_DEQUANT
env knobs for Pareto sweeps. Conclusion: ~2x capacity at high fidelity is real;
K8V8 g128 is the conservative cross-model pick.

* DAR-313: make validated KV-quant configs first-class modes, remove env-var sweep hacks

- Remove KVQ_BITS/KVQ_GROUP/KVQ_DEQUANT env reads from affine4/affine8 execution.
- Add first-class modes: k8v8:g128, k8v8:g64:dequant, k6v6:g64, k6v6:g64:dequant.
- Wire all KVQuantCandidateMode switches (types, cacheSpec, execution config).
- Update effectiveBits to use the mode's actual group size for accurate capacity ratio.
- Add parse + factory-non-nil tests for the four new modes.

* chore(submodule): bump mlx-swift-lm to darkbloom/kvquant (KV-quant mask fix) [DAR-313]

* feat(kvquant): batched quantized-cache numerical gate + submodule bump (DAR-314)

Adds QuantizedBatchKVCache deterministic correctness gate to kv-attn-selftest
(single-row/left-padding/GQA/growth + finalize/extend/filter, dequant-same-data
reference) and bumps mlx-swift-lm to the QuantizedBatchKVCache commit.

* feat(provider): wire K8V8 KV-quant into batching engine, off by default (DAR-317/318)

Opt-in backend.kv_quant flag (default off); Gemma-4-only via KVQuantPolicy.
Quantized full-attention BatchKVCache (g128/b8), fp16 sliding; KV byte budget
cut ~1.94x so admission grants ~2x tokens; prefix-cache/MTP disabled when on.
Flag-off verified byte-for-byte no-regression. Bumps mlx-swift-lm pointer.

* feat(provider): kv-engine-demo (e2e capacity proof) + --local flag + policy doc (DAR-318)

kv-engine-demo builds the real BatchedEngine fp16 vs K8V8 g128 on Gemma 4:
capacity kv_bytes/token 0.516x -> token budget 1.95x; word-level output parity
(sanity; rigorous quality = single-seq top1 0.973); decode tok/s ~parity.
StartCommand --local now honors backend.kv_quant; KVQuantPolicy doc reflects
k8v8:g128. Read-only telemetry accessors for the harness.

* feat(provider): GPT-OSS KV-quant on continuous batching via dequant cache (DAR-322)

resolveKVQuantScheme: Gemma -> kernel g128; GPT-OSS -> dequant g64 (head_dim
guard); flag default off. Byte budget ~1.88x for GPT-OSS. e2e (real BatchedEngine):
capacity 1.88x, rigorous top1 0.971, decode ~0.85x (stable to 512 tok). Bumps
submodule pointer; demo label derives from resolved scheme.

* feat(kv-engine-demo): long-context decode sweep + dequant microbench (DAR-323)

Adds --prompt-tokens sweep, --dequant-iters microbench, --capacity-only. Used to
show GPT-OSS dequant decode is a FLAT ~10-15% (not O(n^2)): quant/fp16 ratio
0.86-0.92 across 512..16384; engine overlaps ~85-90% of raw dequant.

* fix(kvquant): gate live K+V schemes by capacity

* fix(kvquant): address Codex review (#378) — diagnostics, tests, gate

- kv-engine-demo: label the quantized run by the actual resolved scheme
  (Gemma g128 / GPT-OSS dequant|kernel / fp16 for unsupported) and reject
  unsupported model families up front instead of reporting a bogus
  fp16-vs-fp16 'quantized' comparison.
- kv-engine-demo: race stream consumption against --generation-timeout so a
  stall before/between chunks aborts instead of hanging forever.
- KVQuantPerformanceRunner: only apply the decode-TPS regression gate to the
  performance suite; the memory suite shares the runner and must not fail on
  throughput.
- kv-attn-selftest: fold the live g128 finalize/extend/filter checks into the
  DAR-314 gate (dar314Ok) instead of a followUpOk that is re-declared later and
  discarded their failures.
- KVQuantEngineTests: mark the suite .serialized; tests mutate the process-wide
  DARKBLOOM_KV_GPTOSS_KERNEL env and raced under parallel execution.

* fix(kvquant): address Codex round-2 review (#378) + submodule leak bump

- BatchScheduler: reserve VLM media requests at the fp16 KV rate, not the
  quantized rate. VLM media streams through container.generate (fp16 KV, not the
  quantized batched cache), so reserving at the ~0.52x quantized rate under-counts
  ~2x and risks unified-memory OOM under concurrent media. New fp16KVBytesPerToken;
  no-op when KV quant is off.
- kv-attn-selftest: exit(1) when any DAR gate fails (was always exit 0 -> CI would
  treat a failing correctness gate as success).
- kv-engine-demo: enforce --generation-timeout in the concurrency sweep (per-stream
  timeout race) so a stalled stream aborts instead of hanging; also dump full
  fp16-vs-quant generations for eyeball quality diffing.
- kv-quant-gate: --candidate auto honors DARKBLOOM_KV_GPTOSS_KERNEL=1 (kernel vs
  dequant), mirroring the live scheduler.
- Bump mlx-swift-lm -> quantized-cache IOGPU leak fix (#43).

Note: Codex 'kernel silently dequant for Gemma' (Scheduler.swift:947) verified as a
FALSE POSITIVE — the served gemma-4-26b checkpoint has vision_config, so it loads via
the VLM Gemma4 class which DOES use the quantized kernel (Gemma4.swift:839/893); the
update-only LLM Gemma4Text class is never instantiated for it.

* fix(kvquant): gate enforcement + Gemma head_dim guard + selftest exit; bump engine

Provider/gate (safe-set review fixes):
- kv-quant-gate: exit non-zero when the report is failed; skipped is non-zero
  unless --allow-missing-data (wires the previously-unused flag). CI can now
  enforce the gate without parsing JSON.
- KVQuantThresholdEvaluator: fail closed on unreadable/malformed threshold JSON,
  empty rule sets, and zero matched metrics (was silently ignored) + unit tests.
- resolveKVQuantScheme: guard Gemma 4 on (global_head_dim ?? head_dim) % 128 == 0
  so a malformed/variant config disables KV quant instead of trapping the
  quantized cache precondition at decode + unit tests.
- kv-attn-selftest: fold runCase/runMultiStepCacheTest verdicts into the exit
  status (early probes could print [FAIL] but still exit 0).
- Bump libs/mlx-swift-lm to the engine commit that restricts KV-quant to plain
  KVCacheSimple and forces the cold path under quantization.

Deferred (separate pass): GPT-OSS dequant peak-memory accounting, hybrid
sliding-window fp16 reservation, VLM-reservation -> coordinator capacity, and
release.json metric emission/pruning.

* perf(provider): keep engine concurrency cap in sync with effective cap

TASK A — concurrency-cap sync (throughput at concurrency).

The continuous-batching engine's per-step concurrency is set by the
scheduler via engine.setMaxNumSeqs(...). It was told the cold-start cap
exactly ONCE at load and never heard the adaptive ramp:

  - load pinned dynamicMaxConcurrentRequests to min(4, maxConcurrentRequests)
    and pushed that single value to the engine;
  - AdaptiveBatchCapPolicy later raised dynamicMaxConcurrentRequests but
    only mirrored to the engine when the *adaptive* value changed, and the
    cold-start burst has no TPS samples yet so the ramp hadn't engaged.

Net effect: with maxConcurrentRequests=8 (memory admitting) the engine
stayed pinned at 4, so 8 concurrent requests ran as two serialized waves
of 4 — roughly halving aggregate throughput at concurrency.

Fix:
  - Add syncEngineConcurrency(): computes the effective cap IDENTICALLY to
    effectiveMaxConcurrentRequests — max(1, min(maxConcurrentRequests,
    dynamicMaxConcurrentRequests, memoryBoundMaxConcurrentRequests)) — and
    pushes it to the engine only when it changed from lastPushedMaxNumSeqs.
    It is the single setMaxNumSeqs push point. Called at load (replacing the
    raw setMaxNumSeqs) and on every finish via updateDynamicMaxConcurrentRequests
    (now re-syncs unconditionally, so a moved memory clamp is honored even
    when the adaptive cap is unchanged).
  - Cold-start seed: seed dynamicMaxConcurrentRequests to the configured
    ceiling max(1, maxConcurrentRequests) at all three sites (init,
    applyPostLoadBudgets, stopCurrentEngine) instead of min(4, ...). The
    memory clamp is authoritative in effectiveMaxConcurrentRequests /
    syncEngineConcurrency, so the engine is NEVER told more than
    memoryBoundMaxConcurrentRequests (OOM safe) or maxConcurrentRequests.
    Seeding at the ceiling (rather than min(ceiling, memoryBound)) also lets
    the effective cap track a RISING memory bound immediately instead of
    waiting for the slow adaptive ramp. (memoryBoundMaxConcurrentRequests is
    file-private to the telemetry extension and not referenceable from the
    seed sites, which is also why the seed defers the clamp to sync.)
  - Reset lastPushedMaxNumSeqs = -1 in stopCurrentEngine so a freshly-built
    engine (which starts at its own config.maxNumSeqs default) is always
    re-pushed on the next load.

Adds BatchSchedulerConcurrencyCapTests (non-live, no GPU): with
maxConcurrentRequests=8 and memory admitting, the effective cap and the
value syncEngineConcurrency pushes are both 8; with bridges that raise the
average reservation the memory clamp holds the pushed value at 4 (OOM
safety); sync is idempotent; a 1-slot config stays at 1.

TASK B — demo throughput metric.

kv-engine-demo's concurrency sweep reported aggregate decode tok/s as total
decode tokens / the GLOBAL first-token→last-token wall window, which
includes later waves' queue-wait/prefill and so under-reports steady-state
decode. runConcurrentBatch now returns two clearly-labeled numbers:
steadyStateDecodeTps (sum of per-stream decode rates, each over that
stream's own decode window) as the capacity headline, and wallClockDecodeTps
(the previous total/global-window number) for contrast. Measurement-only;
no engine/scheduler behavior change.

* perf(provider): bump engine to perf line + TTFT/prefill demo instrumentation

Submodule mlx-swift-lm -> 0f46814 (darkbloom/kvquant, #43): on-GPU penalty
sampler, KV-quant SDPA mx.compile + n==1 decode-mask skip, per-token decode
wins (logSumExp skip, B==1 .item(), resource-debug off-by-default).

kv-engine-demo: add submit->first-token TTFT and prefill tok/s measurement
(measurement-only).

* feat(kvquant): compose KV-quant + prefix cache for the dequant scheme (DAR-319 v2)

Relax the mutual-exclusion gate so GPT-OSS (.dequant) gets BOTH ~2x KV
capacity AND prefix-cache TTFT. The engine checkpoint-restore now rebuilds
QUANTIZED batched caches (mlx-swift-lm 48866bc, restoredFullAttentionCache),
so restored rows are concrete-class-compatible with quantized cold rows. The
native-kernel scheme (Gemma g128) stays excluded pending its own composition;
drafter-MTP unchanged. Submodule mlx-swift-lm -> 48866bc.

* chore(kvquant): clean ticket refs from comments + bump engine

Remove internal tracker numbers from KV-quant comments and self-test/demo
labels for readability (no logic change). Bump mlx-swift-lm to pick up the
finish-time prompt-cache extract optimization.

* feat(kvquant): document kv_quant opt-in switch + log activation at load

Fix the stale BackendSettings.kvQuant doc (KV-quant supports GPT-OSS AND
Gemma 4, not Gemma-only) and document the per-provider opt-in. Add a kv-quant
logger that, at model load, records whether kv_quant actually engaged for the
model (scheme + KV bytes/token + prefix-cache state) or fell back to fp16 —
so a beta provider can confirm the switch via 'darkbloom logs'.

* chore(kvquant): point engine submodule at merged main (#43 -> a9e0ee1)

mlx-swift-lm #43 squash-merged to main as a9e0ee1 and its branch was deleted,
orphaning the prior submodule pointer. Re-point to the merged main commit
(identical engine tree to the tested head, no behavior change) so the
submodule is fetchable from a clean checkout/CI.

* chore(kvquant): point engine submodule at merged main (#46 -> 8a9bc7c)

Picks up #46 (quantize sliding-window layers: QuantizedBatchRotatingKVCache /
DequantBatchRotatingKVCache + windowSize front-trim + sink-safe GPT-OSS kernel)
plus the rotating analog of restoredFullAttentionCache so KV-quant composes with
prefix-cache restore on sliding-window layers. Engine main 8a9bc7c == previously
tested integration (byte-identical tree).
cursor Bot pushed a commit that referenced this pull request Jul 10, 2026
Admin recover-undispatched now enqueue_critical(inference.released) so
refunds cannot silently lose their durable side effect. release_sql gates
the same outbox insert on mark+credit. Quiescence stays blocked until drain.
cursor Bot pushed a commit that referenced this pull request Jul 10, 2026
Wire prepare-fail, prepare-timeout, resize-authorize failure, and pre-start
cancel through release_job_with_outbox / enqueue_released so all refunds
emit critical outbox side effects (DECISIONS #43).
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.

3 participants