Registry content measurement
The registry-web data plane serves GET /doctor/registry-web/checks. Use an Authority-issued access token with ops.health; a repository-grant token from registry-token does not grant access to this operational endpoint. Anonymous requests return 401, and an authenticated token without that scope returns 403.
Configure Authority:ResourceServer:Authority and its Audiences list. The Compose/release templates supply the local Authority issuer and stellaops audience; REGISTRY_DOCTOR_AUTHORITY_URL changes the issuer URL. Metadata uses HTTPS and the host’s configured trust roots. Missing issuer/audience configuration refuses startup. The data plane’s pull/push bearer contract remains independent: requests outside the Doctor path do not invoke Authority token validation or metadata retrieval.
When discovery advertises a JWKS hostname that is not directly reachable from the service, Authority:ResourceServer:JwksAddress can select the authoritative keys through a reachable TLS ingress. The local profile uses https://stella-ops.local/.well-known/openid-configuration and https://stella-ops.local/jwks, with HTTPS verification required and the existing CA bundle mounted. It keeps the configured Authority issuer unchanged. Do not disable server transport security or certificate validation to make discovery work.
The shared standard checks use an explicit context for Registry’s own database. The additional owned-state ID is bucket:<Registry:Storage:Bucket>; with the shipped bucket it is bucket:registry-content, and the check ID is doctor.standard.state.size-budget.bucket-registry-content.
Measurement uses Registry’s existing S3 client against the configured self-hosted object store. It sums object lengths across every ListObjectsV2 page in the whole owned bucket, including resumable-upload staging and objects outside the normal registry/ content prefix. It does not infer size from metadata rows or assume the content prefix accounts for every stored byte.
A missing object size, missing completeness marker, missing/repeated continuation token, failed page, overflow or page limit produces Warning with no byte total. A complete empty listing reports zero. Cancellation propagates. This is an observation during concurrent writes, not an atomic quota or physical disk-block count. The optional budget is Doctor:State:bucket:registry-content:BudgetBytes in a configuration file/provider; no default budget or new write refusal is enabled.
Source 35df3befb9 and the live receipt verify direct JWT authorization, the independent bucket total and unchanged distribution challenge. The operator CLI lacks the token-issuance scope for a live positive pull; the full Registry suite verifies the pull/push contract. Re-verify with tools/scripts/test-targeted-xunit.ps1 -Project src/Registry/__Tests/StellaOps.Registry.WebService.Tests/StellaOps.Registry.WebService.Tests.csproj -Class *RegistryContentOwnedStateMeasurerTests* -BuildProjectReferences and the RegistryDoctorAuthenticationTests, RegistryReadPlaneTests and RegistryPushPlaneTests classes. Live acceptance must verify source/image identity, 401/403/200 controls, an independent listing of the same bucket, and the existing distribution challenge. For a caller already entitled to obtain a repository-grant token, also verify an existing distribution read. This endpoint does not automatically enroll Registry in the Platform Doctor aggregate.
