DigitableCourses

A probe of the layers

Statuses

Verdict

No probe has run: the cards were printed by the server, the layers are probed by a script in the browser.

Layers

  1. The portal API answers

    not probed

    Probe
    GET /api/health — code 200, the body parses as JSON, and the status field equals ok.
    Catches
    The service is not running, has crashed, or has stopped receiving requests under /api/. Also the moment of the hourly outage: when the analytics job ate the memory and took the server down, a probe in that window would have got no answer.
    Does not catch
    An outage that happened five minutes ago: the probe is instantaneous and keeps no history. The state of the database, the mail queue and the disk are not checked by health, so “the API answers” does not mean “an order will be created”.
  2. There is a road to the bank

    not probed

    Probe
    The acquiringTrusted field from /api/health equals true, and acquiringCheckedAt is no older than 15 minutes (the service checks the road every five). A missing field means “unknown”, not “live”: the service deliberately omits it while there is nothing to check.
    Catches
    The failure of 4 August: the details were filled in, the mode was live, and yet Init never reached the bank — it broke on the certificate chain. And the death of the probe itself: if the server-side check stopped repeating, the timestamp freezes and the verdict becomes “unknown” rather than “live”.
    Does not catch
    The bank accepts Init but the payment goes no further; a failure of fiscal receipts; the wrong terminal, tariff or amount. This is one TLS handshake, not a test payment.
  3. Payments are in live mode

    not probed

    Probe
    In /api/health the mode field equals live and paymentsConfigured equals true; receiptMode is printed next to them.
    Catches
    Production left in test mode: the buttons work, orders get “paid”, and no money arrives. And the reverse — the credentials were wiped while the payment pages still offer to pay.
    Does not catch
    Exactly what this signal failed to catch on 4 August: filled in does not mean working. This pair counts as live only together with the card above; on its own, a green flag here does not mean sales.
  4. The site and the API mean the same document revisions

    not probed

    Probe
    GET /api/checkout/configofferVersion equals 2026-08-06, privacyVersion equals 2026-08-01. Both dates are baked into this site at build time, so what is compared is not the API against itself, but the API against what the reader saw in the form.
    Catches
    A divergence of revisions: the reader accepts one version of the offer while the seller records consent to another. The deployment gate checks this once, at deploy time — and never again; after a manual edit of the service settings nobody checks it at all.
    Does not catch
    An edit to the text of the offer or the policy without changing the revision number: the numbers match and the documents diverge. That is caught by the integrity manifest, not by this probe.
  5. The visit counter is counting

    not probed

    Probe
    GET /api/analytics/content-stats.jsonsource.type equals page-beacon, totals.views and totals.pages are above zero, and the last view is no older than a day. The privacy promises are checked at the same time: cookies, externalTrackers and rawIpAddressesStored are all false.
    Catches
    Zeroes on a live log — the failure in which the statistics file showed zero across 27 thousand requests, because every deployment overwrote the numbers with a placeholder. A silent beacon: the numbers are there, but the last view is yesterday's. A fall back to the file source. And a privacy regression — if the counter starts storing raw addresses, that goes red instead of unnoticed.
    Does not catch
    The undercount built into the counter: readers without JavaScript are invisible to it and cannot be otherwise. And a shrinking number: a day is a coarse measure, and an outage of a few hours inside it is indistinguishable. The number itself is printed next to the card — two probes in a row show whether it is moving.
  6. The integrity manifest and its signatures are served

    not probed

    Probe
    HEAD /integrity.json — code 200; GET /integrity.json.minisig and /en/integrity.json.minisig — code 200, and the signature starts with untrusted comment:. The manifest is only asked whether it exists: it weighs hundreds of kilobytes, and pulling it into the browser for the sake of a tick is a price paid for nothing.
    Catches
    A deployment that lost its signature or its manifest — including the English edition, which is signed separately. Without the manifest the instructions on the integrity verification page stop working, and right now nobody finds out.
    Does not catch
    The validity of the signature itself: minisign is Ed25519 over blake2b, and browser WebCrypto has neither, so what is checked is presence and shape, not cryptography. The real check is one command in a terminal: minisign -Vm integrity.json -P <key>. Whether the manifest matches the actual page files is not counted by this probe either.
  7. The narration reached the server

    not probed

    Probe
    GET /audio/post/3d-pipeline/00-overview/manifest.js — code 200 and a window.DIGITABLE_READER_AUDIO declaration; then a HEAD on the first recording at the address from that same manifest. The material is chosen by the build from data/audio/index.json — the same list that decides whether the “Listen” button is printed.
    Catches
    Narration missing from the server: the recordings are delivered around the build and never go through git, so neither the build nor the deployment sees them. A manifest with no recordings behind it gets its own verdict: that is what an unfinished delivery looks like.
    Does not catch
    The contents of a recording: the right file but the wrong voice or the wrong text. Coverage beyond the single material being probed. Slices drifting out of sync with the article text after an edit — that is caught by rebuilding the segments, not by a probe.
  8. The “Listen” button is printed in the markup

    not probed

    Probe
    GET of the first 128 KB of the page /post/3d-pipeline/00-overview/ — the markup contains data-reader-audio-trigger. What is checked is the HTML the server sends, not what a script drew afterwards: the button has to arrive as markup.
    Catches
    Exactly the failure in which the button was printed on no production page at all: the presence of audio was checked against a file on the builder's disk, and the build machine has no recordings directory whatsoever. The recordings were being served, the button was missing, and it was noticed by accident.
    Does not catch
    The button is there but pressing it plays nothing — that is the neighbouring card, about delivery of the recordings. The button on a partly narrated material: completeness is decided by the build from the index, and the probe only looks at the result.
  9. The search index is in place

    not probed

    Probe
    HEAD /search-index.json — code 200 and a size of at least 225 KB — 200 bytes for each of 1156 materials and videos. The floor is deliberately low: measurement gives 1336 bytes per entry, and there are more entries in the index than there are materials (the catalogue of language cases goes in there too). The body is not requested: the status page does not pull the search index, neither on load nor on probe.
    Catches
    The index is gone or shipped as a placeholder: search does not break visibly at that point — it silently finds nothing. The floor is computed from the number of materials, so it grows with the portal on its own.
    Does not catch
    The freshness of the index: size does not tell today's index from last year's. The quality of the results and the behaviour of the search dialog itself — that is the browser suite of scenarios, not a probe.
  10. The diagram library is delivered

    not probed

    Probe
    HEAD /js/mermaid.min.js — code 200. The body is not requested: the library weighs about three megabytes.
    Catches
    The library never reached the server, or went out under a different address. The reader then gets an empty block or an error message instead of every diagram — across the whole portal at once.
    Does not catch
    Diagrams with broken syntax. Only mermaid itself parses them, and this probe does not see such diagrams at all — it stays green through them. They are caught by another check, before deployment: every diagram of the built pages is handed to that same mermaid, and the first one that fails to parse fails the build run. There is deliberately no number here: nobody recounts it, and a number written down goes stale in silence.

Reference, not a check

Below are the identifying marks of the build and the service. They are never red: the site and the service are deployed separately, and a divergence between them is ordinary rather than a failure. They are worth looking at when a probe has gone red and you need to work out whether it is the thing you have just deployed.

Site built
2026-08-08 21:04 UTC
Materials and videos
1156
API release
Service clock