Repository navigation
phoebe #60 post-merge battery: contract-only gating, R10 reservation clamp, lint - #61
Merged
Merged
Conversation
…tests - Under admission.enabled=false, an envelope with no limit header no longer touches the admission store (no Admit/lease/finish); every fail-closed check (missing org, malformed/partial envelope, underivable graph) still runs first. admission.RateLimits gains exported Any(). - Generated-token reservation: /v1/embeddings reserves 1 output token; an undeclared max_tokens is clamped to the smallest positive contract generated-token limit; a single request above a contract scope's whole per-window limit is rejected as unsatisfiable (400, no Retry-After) instead of a 429 that repeats forever. - Lane scope now precedes the contract scopes, so every operator scope wins a tie (503), as documented. - admission.FromSettings is the one admitter constructor; cmd/interceptor buildAdmission and the proxy contract tests both call it, with tests in internal/admission and cmd/interceptor. - One list of scoped limit headers (identity.ScopedRateLimitHeaders and friends) shared by the parser, the envelope check and the test helpers. - config.DefaultMaxOutputTokens is the single R10 default. - Flag-off negative tests: per-header partial envelope, missing org, degenerate graph, malformed and uncached-above-total values; binding operator tiers ignored under the flag-off cases; lane tie case. Claude-Session: https://claude.ai/code/session_01JR59LERE7vBqUT9cga5Kvq Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
A leftover invalid admission.leaseTtl on an install with admission disabled and no Valkey configured was ignored before contract limits became store-gated; it must not crash-loop the interceptor now. The value is still validated (parse + 1s floor) whenever admission.valkeyAddr or emit.valkeyAddr resolves a store, or admission is enabled. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Startup logs at Info when the admission store comes from emit.valkeyAddr. A Valkey OOM reply (shared noeviction Valkey filled by a metering backlog) is logged under its own bypass label instead of generic unavailability. Docs describe the store settings that apply with admission.enabled=false and the coupling with the metering Valkey. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Covers the unmapped-organization path (falls back to lanes.default) that the existing gold-lane tie case does not exercise. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Pre-#60 replicas do not admit while admission.enabled is false, so only updated replicas count and limit requests until the rollout completes. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…alkey OOM string Claude-Session: https://claude.ai/code/session_01JR59LERE7vBqUT9cga5Kvq
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Post-merge battery fixes for phoebe #60 (contract rate limits enforced), run
wf_3837de1f-50c(Tier 2, 1 round; 27 raw, 20 confirmed). Gate: build, vet, gofmt, golangci-lint,go test -race ./...all pass atab622a6(the battery's own gate was red only on two test-file lint findings, fixed here).What changes
admission.enabled=false, a shared request engages the admission store only when the trusted envelope carries at least one limit header. A request with only the owner-id anchor (Atlas stamps it on every gateway request) no longer makes a Valkey round trip. Every fail-closed check (missing org, malformed or partial envelope, underivable graph) still runs first; a limit header without the owner-id anchor still fails closed.max_tokensis clamped to the smallest positive contract generated-token limit;/v1/embeddingsreserves 1 output token.admission.FromSettings), one list of scoped limit headers, one R10 default (config.DefaultMaxOutputTokens); flag-off negative tests; startup log when the store falls back to the metering Valkey; a separate bypass label for Valkey OOM replies; docs on the metering-Valkey coupling and on under-enforcement during a mixed rollout.Contracts
max_tokensabove the org's generated-tokens-per-minute) is rejected 400 "unsatisfiable" with no Retry-After, instead of a 429 that would repeat forever. Exhausted-but-satisfiable contracts stay 429 + Retry-After; operator capacity stays 503; both exhausted stays 503.max_tokensis clamped to the smallest positive contract generated-token limit when that is below the R10 default (4096).admission.valkeyAddr, the store is the metering Valkey (emit.valkeyAddr), shared with the metering stream (noeviction). Kept deliberately — it is the only store the chart deploys, and the 2026-10-06 R12 clarification says contract limits apply whenever configured. Admission keys use their own prefix and TTLs; a Valkey OOM reply bypasses admission (logged under its own label) rather than blocking traffic.keyPrefix,leaseTtlanddefaultMaxOutputTokensonly insideif .Values.admission.enabled, so those values are ignored in contract-only mode. Tracked by the serving-mode stream.https://claude.ai/code/session_01JR59LERE7vBqUT9cga5Kvq