Skip to content

R8 post-merge battery fixes: rollout order, pre-R8 producer marker, anchor check - #56

Merged
hhuuggoo merged 6 commits into
release-2026.08.01from
hugo/r8-postmerge-battery-fixes
Oct 4, 2026
Merged

hhuuggoo merged 6 commits into
release-2026.08.01from
hugo/r8-postmerge-battery-fixes

Conversation

@hhuuggoo

@hhuuggoo hhuuggoo commented Oct 4, 2026

Copy link
Copy Markdown
Contributor

Post-merge battery fixes for phoebe #55 (R8 hard cut of the five legacy quota headers), run wf_9d5ad211-fb2 (Tier 2, 1 round, gate green: build, vet, gofmt, golangci-lint, go test -race, integration and admission-integration suites).

  • docs/shared-tier-admission.md: the R8 rollout section said the components "can roll in any order". That is wrong in one case: if the saturn-k8s chart that drops the legacy names from trustedHeaders (and therefore from the Traefik strip middleware) rolls before every phoebe replica runs the R8 image, and admission is enabled, a pre-R8 replica accepts a client-forged legacy envelope on a request with no X-Saturn-Owner-Id. The doc now states the order: every phoebe replica on the R8 image first (or admission kept off for the whole cutover), then the chart.
  • A 503 caused by a request that carries only legacy headers logs a distinct pre-R8-producer marker, so a stale producer is visible during the cutover.
  • Startup flags a configured PHOEBE_TRUSTED_HEADERS that omits the owner or org anchor.
  • Tests: legacy headers are ignored when the owner anchor is present; an unmapped org stays on the default lane.

Contracts

  • Deploy order for R8 (documented, not enforced): phoebe R8 image on every replica BEFORE the saturn-k8s chart from #1073, or admission.enabled: false throughout. Admission is off by default (R12), so the current state is not exposed.
  • Open security question for Hugo (not changed here): after #1073 the five legacy header names are no longer stripped at the edge, so client-supplied copies reach the vLLM/Dynamo upstream unchanged. Nothing reads them today. Options and a recommendation are in the serving-mode claim (Q-R8STRIP); no code in this PR changes what is stripped.
  • No other contract change: no header is added to or removed from the trusted set, the strip list, or the parser.

https://claude.ai/code/session_01JR59LERE7vBqUT9cga5Kvq

hhuuggoo and others added 6 commits October 4, 2026 00:28
The 'roll in any order' justification claimed the scoped envelope was
stamped on every admission route, contradicting the per-resource-route
drain requirement. State the real reason (admission stays disabled for the
cutover), narrow the stamping claim to gateway routes, and document the
image-before-chart ordering constraint plus the unstripped pass-through of
legacy headers after the cutover.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…-only 503

parseTrustedRateLimits builds the org/owner name and value arrays once and
derives the anchorless-scoped check from them (no duplicated 8-field list).
The no-policy branch returns errNoTrustedRateLimitPolicy; the proxy call site
adds a log-only WARN (legacy_envelope_present=true) when the raw request
still carries the removed legacy quota headers. Response status and body are
unchanged and the legacy names never feed a trust or limit decision.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…tays on default lane

Rename TestLegacyOnlyQuotaHeadersFailClosed to TestLegacyQuotaHeadersAreIgnored
and add the anchored cases that would fail if legacy headers were read (zero
caps, malformed values). Add TestLegacyOnlyQuotaHeadersLogPreR8ProducerMarker
and TestUnmappedOrgStaysOnDefaultLaneDynamoHints.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
After R8, X-Saturn-Owner-Id is the only anchor for the quota policy, and
admission also requires X-Saturn-Org-Id. A configured PHOEBE_TRUSTED_HEADERS
that omits either now logs an ERROR at startup naming the header and the 503
consequence. The list is still installed as written and phoebe does not exit.

Tests: TestLoadTrustedHeadersErrorsWhenOwnerOrOrgAnchorMissing,
TestLoadTrustedHeadersNoErrorForPinnedList. The fallback no-regression test's
doc comment now records that R8 removed five headers the pre-gate parser read.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Pre-R8 phoebe replicas still parse the legacy envelope, so the edge must keep
blanking the five legacy names (strip-only, not trusted) until every replica
runs the R8 image.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…r-56

# Conflicts:
#	internal/identity/trusted_headers_test.go
@hhuuggoo
hhuuggoo merged commit bfb9ebf into release-2026.08.01 Oct 4, 2026
4 of 8 checks passed
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