Skip to content

v3.10.1 — nothing a reader sees is a marker

Choose a tag to compare

@productdevbook productdevbook released this 20 Aug 07:43
· 25 commits to main since this release

Fixes a regression in v3.10.0 that corrupts notices. Anyone on 3.10.0 should take this.

A code span inside a link was published as the renderer's own marker

  • v3.10.0 held code spans and links out of the rules that follow them, and a replacement string is not rescanned — so a span held before a link was carried into that link's text and left there as &0&.
  • [/api/status.json](https://example.com/docs) came out as <a href="…">&0&</a> on the page, in notices.json and in the feed. The RSS title still read correctly, which made it look like corruption rather than a rule.
  • 6,210 of 30,000 realistic notice bodies differ this way from v3.9.0.
  • The tests added in v3.10.0 missed it by one case: "a link inside a code span" and "emphasis inside a link's text" were both written; a code span inside a link's text was not.

An empty ?lang= answered English on the last surface that still had the bug

  • v3.2.0 fixed this for the page and the feed. notices.json asked has("lang") — true for ?lang= with nothing after it — and fed "" to langOf, which answers English. A deployment configured for Turkish answered English notices.
  • The ratchet written for exactly this defect exempted ?? undefined, which is the shape this one had.

The sweep could take the whole database's retention with it

  • The monitor ids go into the reconciliation statement rather than into parameters, and batch() is a transaction. At 15,000 monitors D1 answers SQLITE_NOMEM, and the failure discards the retention deletes with it — measured, checks from 1970 surviving a sweep — so pruning stops permanently.
  • Five hundred ids to a statement. 20,000 monitors: 10 ms, every kind correct, retention applied.

The rule this repository would be most damaged by breaking now has a check

  • "No real hostnames, tokens, database ids, chat ids or webhook addresses anywhere" was enforced by attention alone. Sixteen distinct hosts appear in the tree, all placeholders or the project's own links; anything else fails, verified with a real-shaped hostname and a real-shaped database id.
  • An agent walked around eleven existing rules with their defects present and bun run check at zero. Closed: the schema-order rule was case-sensitive (create index in lower case put the defect back byte for byte), the release gate asked only that two strings appeared somewhere in the workflow, src/worker.ts was in no rule's file list at all, the memo inventory could not cross ??=, recentEvents(db, EVENT_ROWS * 3) passed, the endpoint table was checked one way only, and the CORS rule knew new Response but not Response.json.

latest cannot move backwards

  • Any tag published latest, {{major}} and {{major}}.{{minor}} in any order, so a v3.9.1 cut after v3.10.0 would move latest and 3 back a release under everybody who pulls them — which is what the upgrade notes tell a self-hoster to do.
  • The smoke test also now reads x-nabiz from the running container and compares it with the tag; it checked only that the container answered.

Corrected

  • "It applies schema.sql on start and then adds any missing column" was backwards, and had been since the commit that swapped the order.
  • "One statement failing takes the rest of the file with it" is true of bun:sqlite and not of wrangler d1 execute --file, which is all-or-nothing.
  • The probe's comment said both that the round's deadline gives "timed out" and that saying so is untrue. timeout means nothing answered in the time there was; a timeout longer than three quarters of the interval can never be reached, and docs/monitors.md says so where an operator sets it.

Upgrading

  • A pull. No schema change.