Tutors release harness — upgrade pass

2026-10-15T17:55:33.724Z · clock 2026-09-16T09:05:00.000Z · 1 run(s) per side · harness 1.37.3

ab
readerquay.io/tutors-sdk/tutors-reader:17.0.0quay.io/tutors-sdk/tutors-reader:sha-d3d7227
cataloguequay.io/tutors-sdk/tutors-catalogue:17.0.0quay.io/tutors-sdk/tutors-catalogue:sha-d3d7227
livequay.io/tutors-sdk/tutors-live:17.0.0quay.io/tutors-sdk/tutors-live:sha-d3d7227
timequay.io/tutors-sdk/tutors-time:17.0.0quay.io/tutors-sdk/tutors-time:sha-d3d7227
provenancea — pulled+verifiedb — pulled+verified
readerdigest sha256:15e3aa22476d608db97e05917b1990ade0a7871e7ec6e113da5fec741b427233
revision 432d46864626
version 17.0.0-rc.1
digest sha256:bc7ca09526ac59b2f936dd27a68ad7a9527cb8dc3be17ca41f8ec8c79c4c7abd
revision d3d72277634a
version sha-d3d7227
cataloguedigest sha256:e9f2764654cb074d7dd4412ca163bf4c2666870444d5520361d5425bda4cec0b
revision 432d46864626
version 17.0.0-rc.1
digest sha256:fbae335184067b5763c61c60b419c8a7293903f7a8eff6f85c0acf93b279bcf5
revision d3d72277634a
version sha-d3d7227
livedigest sha256:52740e55cfa7e7db3b2944137caada4e876990b937f1034c0c5e79796054f8a0
revision 432d46864626
version 17.0.0-rc.1
digest sha256:95666ae77a2816d74629566810ebcbeae8a3d7647140e449083fd8fac78a52bb
revision d3d72277634a
version sha-d3d7227
timedigest sha256:d0a9f4a2f4624038ecea3629d1a536567756d458410bee43b45e060d738d195d
revision 432d46864626
version 17.0.0-rc.1
digest sha256:accb1ea9807d95df261cbd5244ecfd98a419903011d00d84f49eaccccd026236
revision d3d72277634a
version sha-d3d7227

Image artefacts

Collected from the images, not the running apps. A cell that says NOT COLLECTED was not compared.

appartefactab
readermanifest10 layers, 309.2 MB, USER 1001, ports 3000/tcp (docker image inspect)10 layers, 308.9 MB, USER 1001, ports 3000/tcp (docker image inspect)
readersbom134 distinct package(s) (cosign attestation (signature verified))134 distinct package(s) (cosign attestation (signature verified))
readervulnsNOT COLLECTED: grype is not installed (https://github.com/anchore/grype#installation, or set HARNESS_VULN_CMD to another scanner, e.g. trivy)NOT COLLECTED: grype is not installed (https://github.com/anchore/grype#installation, or set HARNESS_VULN_CMD to another scanner, e.g. trivy)
cataloguemanifest10 layers, 274.2 MB, USER 1001, ports 3000/tcp (docker image inspect)10 layers, 274.2 MB, USER 1001, ports 3000/tcp (docker image inspect)
cataloguesbom134 distinct package(s) (cosign attestation (signature verified))134 distinct package(s) (cosign attestation (signature verified))
cataloguevulnsNOT COLLECTED: grype is not installed (https://github.com/anchore/grype#installation, or set HARNESS_VULN_CMD to another scanner, e.g. trivy)NOT COLLECTED: grype is not installed (https://github.com/anchore/grype#installation, or set HARNESS_VULN_CMD to another scanner, e.g. trivy)
livemanifest10 layers, 274.5 MB, USER 1001, ports 3000/tcp (docker image inspect)10 layers, 274.5 MB, USER 1001, ports 3000/tcp (docker image inspect)
livesbom134 distinct package(s) (cosign attestation (signature verified))134 distinct package(s) (cosign attestation (signature verified))
livevulnsNOT COLLECTED: grype is not installed (https://github.com/anchore/grype#installation, or set HARNESS_VULN_CMD to another scanner, e.g. trivy)NOT COLLECTED: grype is not installed (https://github.com/anchore/grype#installation, or set HARNESS_VULN_CMD to another scanner, e.g. trivy)
timemanifest10 layers, 285.2 MB, USER 1001, ports 3000/tcp (docker image inspect)10 layers, 285.2 MB, USER 1001, ports 3000/tcp (docker image inspect)
timesbom143 distinct package(s) (cosign attestation (signature verified))143 distinct package(s) (cosign attestation (signature verified))
timevulnsNOT COLLECTED: grype is not installed (https://github.com/anchore/grype#installation, or set HARNESS_VULN_CMD to another scanner, e.g. trivy)NOT COLLECTED: grype is not installed (https://github.com/anchore/grype#installation, or set HARNESS_VULN_CMD to another scanner, e.g. trivy)

Upgrade rehearsal (compose)

upstreamrequestsfailed5xxp95
a300004.3 ms
b600003.5 ms
all90000switched at 17.4 s

Differences (29; 0 unclaimed)

artefactscopewhat changedclaimed by
vulnsreader/not-collectedNOT COLLECTED: vulns of reader on both sides: grype is not installed (https://github.com/anchore/grype#installation, or set HARNESS_VULN_CMD to another scanner, e.g. trivy)
detail
a: grype is not installed (https://github.com/anchore/grype#installation, or set HARNESS_VULN_CMD to another scanner, e.g. trivy)
b: grype is not installed (https://github.com/anchore/grype#installation, or set HARNESS_VULN_CMD to another scanner, e.g. trivy)
informational
vulnscatalogue/not-collectedNOT COLLECTED: vulns of catalogue on both sides: grype is not installed (https://github.com/anchore/grype#installation, or set HARNESS_VULN_CMD to another scanner, e.g. trivy)
detail
a: grype is not installed (https://github.com/anchore/grype#installation, or set HARNESS_VULN_CMD to another scanner, e.g. trivy)
b: grype is not installed (https://github.com/anchore/grype#installation, or set HARNESS_VULN_CMD to another scanner, e.g. trivy)
informational
vulnslive/not-collectedNOT COLLECTED: vulns of live on both sides: grype is not installed (https://github.com/anchore/grype#installation, or set HARNESS_VULN_CMD to another scanner, e.g. trivy)
detail
a: grype is not installed (https://github.com/anchore/grype#installation, or set HARNESS_VULN_CMD to another scanner, e.g. trivy)
b: grype is not installed (https://github.com/anchore/grype#installation, or set HARNESS_VULN_CMD to another scanner, e.g. trivy)
informational
vulnstime/not-collectedNOT COLLECTED: vulns of time on both sides: grype is not installed (https://github.com/anchore/grype#installation, or set HARNESS_VULN_CMD to another scanner, e.g. trivy)
detail
a: grype is not installed (https://github.com/anchore/grype#installation, or set HARNESS_VULN_CMD to another scanner, e.g. trivy)
b: grype is not installed (https://github.com/anchore/grype#installation, or set HARNESS_VULN_CMD to another scanner, e.g. trivy)
informational
runtimeruntime/summarycontainer posture collected for catalogue, live, reader, reader-auth, time on both sides (compose)
detail
catalogue: a — uid 1001:0, caps none, root fs ro, /tmp rw, no-new-privileges, seccomp filter
           b — uid 1001:0, caps none, root fs ro, /tmp rw, no-new-privileges, seccomp filter
live: a — uid 1001:0, caps none, root fs ro, /tmp rw, no-new-privileges, seccomp filter
      b — uid 1001:0, caps none, root fs ro, /tmp rw, no-new-privileges, seccomp filter
reader: a — uid 1001:0, caps none, root fs ro, /tmp rw, no-new-privileges, seccomp filter
        b — uid 1001:0, caps none, root fs ro, /tmp rw, no-new-privileges, seccomp filter
reader-auth: a — uid 1001:0, caps none, root fs ro, /tmp rw, no-new-privileges, seccomp filter
             b — uid 1001:0, caps none, root fs ro, /tmp rw, no-new-privileges, seccomp filter
time: a — uid 1001:0, caps none, root fs ro, /tmp rw, no-new-privileges, seccomp filter
      b — uid 1001:0, caps none, root fs ro, /tmp rw, no-new-privileges, seccomp filter
informational
startupstartup/not-collectedNOT COLLECTED: startup time on side a: switched off with --startup-restarts 0informational
startupstartup/not-collectedNOT COLLECTED: startup time on side b: switched off with --startup-restarts 0informational
image-hardeningreader/healthcheckreader: declares no HEALTHCHECK (production too)informing (reported, never gates)
image-hardeningcatalogue/healthcheckcatalogue: declares no HEALTHCHECK (production too)informing (reported, never gates)
image-hardeninglive/healthchecklive: declares no HEALTHCHECK (production too)informing (reported, never gates)
image-hardeningtime/healthchecktime: declares no HEALTHCHECK (production too)informing (reported, never gates)
build-provenancereader/slsareader: carries no SLSA provenance verified under the publishing identity on bc7ca09526ac (production too)informing (reported, never gates)
build-provenancecatalogue/slsacatalogue: carries no SLSA provenance verified under the publishing identity on fbae33518406 (production too)informing (reported, never gates)
build-provenancelive/slsalive: carries no SLSA provenance verified under the publishing identity on 95666ae77a28 (production too)informing (reported, never gates)
build-provenancetime/slsatime: carries no SLSA provenance verified under the publishing identity on accb1ea9807d (production too)informing (reported, never gates)
vuln-ceilingreader/not-evaluatedreader: vuln-ceiling could not be evaluated on b: no vulnerability scan: grype is not installed (https://github.com/anchore/grype#installation, or set HARNESS_VULN_CMD to another scanner, e.g. trivy)informational
vuln-ceilingcatalogue/not-evaluatedcatalogue: vuln-ceiling could not be evaluated on b: no vulnerability scan: grype is not installed (https://github.com/anchore/grype#installation, or set HARNESS_VULN_CMD to another scanner, e.g. trivy)informational
vuln-ceilinglive/not-evaluatedlive: vuln-ceiling could not be evaluated on b: no vulnerability scan: grype is not installed (https://github.com/anchore/grype#installation, or set HARNESS_VULN_CMD to another scanner, e.g. trivy)informational
vuln-ceilingtime/not-evaluatedtime: vuln-ceiling could not be evaluated on b: no vulnerability scan: grype is not installed (https://github.com/anchore/grype#installation, or set HARNESS_VULN_CMD to another scanner, e.g. trivy)informational
asset-graphreaderreader: the asset graph changed: 111 → 111 immutable requests (JS 92 → 92, CSS 19 → 19), 1.1 MB → 1.1 MB; 0 network and 0 headers difference(s) are this churninforming (reported, never gates)
sloreader-availability/not-evaluatedreader-availability: not evaluated on b: 4 request(s) from its /metrics across the journeys, fewer than 20informational
sloreader-latency/not-evaluatedreader-latency: not evaluated on b: 4 request(s) from its /metrics across the journeys, fewer than 20informational
slocatalogue-availability/not-evaluatedcatalogue-availability: not evaluated on b: its /metrics across the journeys carries no availability SLI for catalogueinformational
slocatalogue-latency/not-evaluatedcatalogue-latency: not evaluated on b: its /metrics across the journeys carries no latency SLI for catalogueinformational
slolive-availability/not-evaluatedlive-availability: not evaluated on b: its /metrics across the journeys carries no availability SLI for liveinformational
slolive-latency/not-evaluatedlive-latency: not evaluated on b: its /metrics across the journeys carries no latency SLI for liveinformational
slotime-availability/not-evaluatedtime-availability: not evaluated on b: its /metrics across the journeys carries no availability SLI for timeinformational
slotime-latency/not-evaluatedtime-latency: not evaluated on b: its /metrics across the journeys carries no latency SLI for timeinformational
upgraderollout900 requests through the rollout, none failed; switched at 17.4sinformational

Policy: what b must be informing

Checks on the candidate alone, whatever production is: image hardening (root user, no healthcheck, a secret in the environment or the layer history), build provenance (SLSA provenance from image-build.yml) and the vulnerability ceiling (a critical or high advisory with a fix available). Informing: reported, never gates; a claim can still cover a finding. Hover a cell for what was checked.

appimage-hardeningbuild-provenancevuln-ceiling
reader1 finding (1 on production too)1 finding (1 on production too)not evaluated
catalogue1 finding (1 on production too)1 finding (1 on production too)not evaluated
live1 finding (1 on production too)1 finding (1 on production too)not evaluated
time1 finding (1 on production too)1 finding (1 on production too)not evaluated

Informing (9; 9 unclaimed) reported, never gates

19 of 27 engines are blocking; informing (reported, never gates): image-hardening (no date set to block), build-provenance (no date set to block), vuln-ceiling (no date set to block), timing-tolerance (no date set to block), asset-graph (no date set to block), replay (no date set to block), slo (no date set to block), realtime (no date set to block). An informing engine's findings are listed here and never change the verdict, the Gate or the exit code; a claim can still cover one.

enginescopewhat it foundlevelclaimed by
image-hardeningreader/healthcheckreader: declares no HEALTHCHECK (production too)no date setunclaimed
image-hardeningcatalogue/healthcheckcatalogue: declares no HEALTHCHECK (production too)no date setunclaimed
image-hardeninglive/healthchecklive: declares no HEALTHCHECK (production too)no date setunclaimed
image-hardeningtime/healthchecktime: declares no HEALTHCHECK (production too)no date setunclaimed
build-provenancereader/slsareader: carries no SLSA provenance verified under the publishing identity on bc7ca09526ac (production too)no date setunclaimed
build-provenancecatalogue/slsacatalogue: carries no SLSA provenance verified under the publishing identity on fbae33518406 (production too)no date setunclaimed
build-provenancelive/slsalive: carries no SLSA provenance verified under the publishing identity on 95666ae77a28 (production too)no date setunclaimed
build-provenancetime/slsatime: carries no SLSA provenance verified under the publishing identity on accb1ea9807d (production too)no date setunclaimed
asset-graphreaderreader: the asset graph changed: 111 → 111 immutable requests (JS 92 → 92, CSS 19 → 19), 1.1 MB → 1.1 MB; 0 network and 0 headers difference(s) are this churnno date setunclaimed

Masks

Fired: response-date×4, request-id×4, etag×4, metrics-process×602, metrics-timing-histograms×4, third-party-requests×62, hashed-assets×222, footer-tutors-version×28, transport-length×4, transport-connection×4, transport-keepalive×4.
Silent this run: persistence-stub-requests, realtime-rest-fallback-warning, oauth-callback-state, media-range-status, chromium-compute-pressure-policy, transport-encoding, transport-transfer — a mask that never fires is a mask to delete.