docs(spec): S13 probe-timeout scope and blob cap reconciliation
Two amendments to docs/specs/S13-virtual-remote-foundation.md, covering fixes
2 and 4 of #269. Fixes 1 and 3 are code changes in internal/remote and stay
with #269.
Fix 2 — resolution.probe_timeout bounds the HEAD leg alone
S13 defined Probe as the HEAD and bounded it with resolution.probe_timeout,
with no carve-out for a slice whose Probe has to acquire credentials first. Read
literally, that wraps handshake and HEAD in one 5s window and fails every
cold-credential container Probe against an upstream that answers the HEAD
promptly.
The spec now says the timeout binds the HEAD alone, and that a slice charges
credential acquisition to a budget it defines and names, the two running in
sequence on independent deadlines. This confirms a reading rather than changing
intent: docs/specs/S16-container-remote.md reaches the same conclusion in its
Follow-ups and assigns it to S32, and the budget already exists —
token_exchange_timeout is 10s on main, which the configuration reference
describes as separate from the timeouts that bound the upstream artifact call.
Two supporting edits:
- The health probe raises no version of this question: it sends a bare
HEADwith no credentials, because its status taxonomy counts401and403as reachable. Stated where a reader comparing the two identically named knobs will look for it. - The on-demand-probe criterion said a bare
probe_timeoutwhile two configuration blocks declare a field by that name. It now nameshealth_check.probe_timeout.
A new acceptance criterion covers the half that is testable against the S13
service layer — that resolution.probe_timeout bounds the HEAD. The handshake
half needs a slice that runs one, so it belongs to S32.
Fix 4 — the body_size_cap_blob gap against ADR-004, recorded not resolved
## Resolutions records what the evidence settles; ## Follow-ups records what
it does not.
Settled: 5 GB and 50 GB are not two answers to one question. ADR-004's 50 GB
bounds a blob uploaded to a hosted container repository; body_size_cap_blob
bounds a response body read from an upstream. They still leave a reachability
gap — a container layer between the two is accepted on the hosted path and
refused on the remote one, so an image this registry can host is an image it
cannot proxy. The per-request max_body_bytes override cannot close it, because
it clamps to body_size_cap_blob as the enforced ceiling (client.go
bodyCap); a container slice cannot raise itself above 5 GB. That makes the
single global knob the defect rather than the value it carries.
Open, and left to #269: whether to raise the global default or split the cap per
format the way the hosted configuration already is (container.blob_max_size
50 GB, maven.max_artifact_size 5 GB, npm.max_tarball_size 5 GB). The two
differ in denial-of-service posture rather than in wording, and ADR-004 stating
limits per format is evidence against one global number but not a decision to
change one.
This also adds ADR-004 to the References section, which lists every other ADR the spec cites.
Not changed here
S16's three Follow-up bullets pointing at #269. One reads stale once this lands, but #269 stays open for fixes 1 and 3 and for fix 4's number, and two open container-remote MRs are changing that file. Trim them when #269 closes.
Related to #269