Repository navigation
routine 2026-10-13: #heading lands on it, README images keep their size, stalls that say why, marked 18.1.1 - #24
Merged
Merged
Conversation
marked 18.1.1 changes rendered output (blockquote lazy lines, html blocks interrupting paragraphs, backslashes in code spans, tab stops), so it was held a night. All 8 READMEs and all 98 posts (94 from the live content volume, 4 fixtures) render byte-identical through renderMarkdown on 18.1.0 and 18.1.1; five of eight probes taken from the release notes do differ between the two, so the diff could see a change had there been one. package.json, package-lock.json, ROADMAP.md Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
vitest is dev-only and nothing it touches reaches the build: typecheck clean, 276/276 tests, build green, every route's status code identical to the previous build's. Vue 3.5.44 shipped this morning with SSR, hydration and scheduler changes, so it goes on the roadmap with a diff plan instead. package.json, package-lock.json, ROADMAP.md Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Two scrolls raced on a fresh load with a fragment. HTML's scroll to the fragment uses behavior auto, so the stylesheet's scroll-behavior: smooth made Chromium's own fragment scroll an animation from the top, while vue-router jumped to the same heading as the app started; when the animation's first step (always 4 or 18 px here) landed after the jump it was added on top. restore-jump.client.ts now holds scroll-behavior: auto for a fresh load with a hash too, as it did for reloads and Back/Forward. Nanna at 390 px, #api-key-invalid, uninstrumented: 4/20 cold loads off at full speed and 19/20 at 6x CPU before; 0/20 and 0/20 after. check:navigation could not see a +4 miss (text still 12 px clear of the masthead), so it now also wants the heading's box on scroll-padding-top's line within 2 px, and takes the cold load at 6x CPU in Chromium via a new page.throttle() in scripts/lib/browser.mjs (a no-op in Firefox). Main's build fails it on 9 cold loads across 5 pages; this build passes 160/160 in Chromium and Firefox. app/plugins/restore-jump.client.ts, scripts/check-navigation.mjs, scripts/lib/browser.mjs, ROADMAP.md Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The CDP and BiDi clients sent requests with no timeout, so a page whose renderer stopped answering held a check until CI's 15-minute step limit with nothing to say what it waited for (check:navigation on Nanna at 390 px, 2026-10-12). Every request now rejects after REQUEST_TIMEOUT_MS (180 s) with its method and the expression or URL it carried. Proved with an evaluate of a promise that never settles: rejected at 180 s in Chromium (Runtime.evaluate) and Firefox (script.evaluate), and the page answered the next call in milliseconds. check:navigation and a11y:browser in both engines ran green under it, with no false fires. scripts/lib/cdp.mjs, scripts/lib/bidi.mjs, ROADMAP.md Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A missed size probe is not cached, so the README is served with that image at 0x0 until the next refresh, and cold starts (every deploy) are where misses land. img.shields.io answered in 3.0 s to 1 request in 9 from this host, past the 2 s budget; a local server tonight served splimes with four badges unsized. statedSizes() reads the sizes a rendered README states, and sizeReadmeImages() now takes the snapshot's copy of the same README's sizes as a fallback for any image the live probe misses. A live answer still wins. Cold-started behind a CONNECT proxy refusing img.shields.io: main's build served 18 README images unsized across 5 about pages, this one 0. 279 tests, typecheck clean, build green, routes unchanged, check clean. shared/markdown/image-size.ts, server/utils/readmeImages.ts, server/utils/github.ts, test/image-size.test.ts, ROADMAP.md Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
npm run sync wrote a README image unsized into the snapshot whenever its size probe missed, which takes away the very fallback the server now uses for its own misses. withImageSizes() keeps the previous snapshot's size for such an image (statedSizes) and logs how many it kept. Behind a CONNECT proxy refusing img.shields.io: main's script wrote 22 unsized images into data/projects.generated.json; this one wrote 0, keeping 22 sizes across six READMEs. (Snapshot restored afterwards; the refresh for this run is a separate commit.) scripts/fetch-projects.mjs, ROADMAP.md Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
/healthz and the status page carry readmeImages: per image per render, measured by a probe (or the day's cached answer), kept at the snapshot's size because the probe missed, or unsized. The fallback landed earlier tonight hides misses from the page; this says whether production has any. With img.shields.io refused from cold: 6 measured, 22 kept, 0 unsized; without: 28 measured. Typecheck clean, 279 tests, build green, routes unchanged; status page checked at 390 and 1280 px. shared/types/health.ts, server/utils/health.ts, server/utils/readmeImages.ts, app/pages/status.vue, README.md, ROADMAP.md Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A 1.4 KB page that reproduces, outside the site, the race fixed in restore-jump.client.ts: scroll-behavior: smooth, a #target 16,000 px down, and one instant scrollTo to the same place shortly after load. Chromium 152.0.7977.82 at 390 px, 30 cold loads per case: a jump 10 ms after load lands 4 or 13 px past on 30/30, 20 ms after lands 13 or 24 px past on 30/30; with scroll-behavior: auto, on target 60/60; with no jump, on target 30/30. Reporting it upstream is the owner's call. docs/repro/smooth-fragment-overshoot.html, ROADMAP.md Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…the fix Headless Firefox draws no backdrop-filter at all, plain blur included, so the routine cannot settle what a real Firefox shows. But Mozilla bug 1961378 (open) says backdrop-filter is ignored entirely when an SVG url() filter falls back to a blob image, and its duplicate 1972363 names feImage and feDisplacementMap, which the masthead's two filters use. Firefox passes the @supports that hands it that chain. The item now carries the one-condition fix (not (-moz-appearance: none)) to ship once someone has looked in a real Firefox, before and after. ROADMAP.md Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The stall last seen 2026-10-12 recurred tonight in 1 of 3 Chromium check:navigation runs: arrive()'s evaluate on Nanna at 1280 px went 180 s unanswered (the new request timeout caught it; before, CI's 15-minute step did). Both stalls were on Nanna, on the last page of a width's pass. A page that throws or stalls is now a failure of that page, not the end of the run: it reports the last four calls made of it and, in Chromium, the busiest renderer's CPU time over one second (busy(), from SystemInfo.getProcessInfo), then the run continues in a fresh tab. On a stand-in page that spins after load: "stalled after goto → goto → evaluate; renderer busy (0.99 CPU s in 1 s)", and the next page checked. The real check: 160/160 in Chromium and in Firefox. scripts/check-navigation.mjs, scripts/lib/browser.mjs, ROADMAP.md Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Skidbladnir v1.4.4 (released 2026-10-13) and its README, crate download counts, push times. Every README image in it carries its size. data/projects.generated.json Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Caught one more check:navigation stall tonight with the new report: on Skidbladnir at 1280 px, the first page of the pass in a fresh tab, on arrive(blog) right after clicking the blog tab, renderer idle (0.00 CPU s in 1 s). That rules out the longest README and an old tab, and says the page was waiting, not computing. The report now also tries a plain evaluate (visibilityState, readyState, path) with 5 s to answer: on a stand-in that spins, no answer; on an idle one, "visible, complete, /projects/y/about". The next real stall will say whether only the stuck promise's timers were held or the page was blocked. scripts/check-navigation.mjs, ROADMAP.md Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
15 complete Chromium check:navigation runs on this branch without the splimes reload drift; the stall recurred once in the seven hunt runs. ROADMAP.md Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Nightly routine, 2026-10-13 (21:10 CDT → past 01:10). Eleven increments plus the snapshot. In order:
1. marked 18.1.1, on a byte diff —
f3c2003Roadmap: the held marked 18.1.1 item. Ticked.
Files:
package.json,package-lock.json,ROADMAP.md.marked 18.1.1 changes rendered output: blockquote lazy lines, HTML blocks interrupting paragraphs, backslashes in code spans, and tab stops. So it went in only on a byte diff.
renderMarkdownon 18.1.0 and on 18.1.1. The output is byte-identical.Results: typecheck clean; 276/276 tests; build green;
audit:runtimeclean. Every route answered as below;check22 pages / 79 URLs clean. Screenshots: home, Skidbladnir and Nisaba at 1280 and 390, looked at.2. vitest 5.0.4; Vue 3.5.44 held —
8449f84Roadmap: new
[ ]for Vue 3.5.44.Files:
package.json,package-lock.json,ROADMAP.md.3. A cold load of
#headinglands on it —1ec2ac7Roadmap: the cold-load miss from #23. Ticked.
Files:
app/plugins/restore-jump.client.ts,scripts/check-navigation.mjs,scripts/lib/browser.mjs,ROADMAP.md.Cause: two scrolls raced.
auto, so the site'sscroll-behavior: smoothmade Chromium's own fragment scroll an animation from the top.Fix:
restore-jump.client.tsnow holdsscroll-behavior: autoon a fresh load that carries a fragment, as it already did for reloads and Back/Forward.Nanna at 390 px,
#api-key-invalid, no instrumentation:The check now sees it. Before, it couldn't: a +4 miss leaves the text 12 px clear, inside the 0–200 band.
scroll-padding-top's line, within 2 px.page.throttle().A first try compared the heading's text line and failed every heading that has space above its text inside the box; that was fixed to the box before landing.
Results:
check22 pages / 79 URLs clean;a11y23 pages clean.a11y:browseranda11y:firefox: 23 pages × 3 widths, clean.chromium --screenshotof the#fragmentURL came out blank (2.7 KB), so it is not used as evidence.4. A request that never answers fails in 180 s —
4ea706cRoadmap: new sub-item under the cold-load item.
Files:
scripts/lib/cdp.mjs,scripts/lib/bidi.mjs,ROADMAP.md.The CDP and BiDi clients had no request timeout, so a hung page held CI's step for 15 minutes. Every request now rejects after 180 s, naming its method and its expression or URL.
5. README images keep the snapshot's size when a probe misses —
0eddd79Roadmap: new
[x].Files:
shared/markdown/image-size.ts,server/utils/readmeImages.ts,server/utils/github.ts,test/image-size.test.ts,ROADMAP.md.Problem: a missed size probe isn't cached, so the README goes out with that image at 0 × 0 until the next refresh. Cold starts, i.e. every deploy, are where misses land.
Fix:
statedSizes()reads the snapshot's sizes for the same README andsizeReadmeImagesfalls back to them. A live answer still wins.Proof: cold start behind a CONNECT proxy that refuses img.shields.io.
Results: 279 tests (3 new); typecheck clean; build green; routes unchanged;
checkclean.The badges were a suspect for a 31 px reload drift seen once (open item), but they move the page 2.3 px, so they don't explain it.
6. …and
npm run syncdoesn't write a miss into the snapshot —17b45bbFiles:
scripts/fetch-projects.mjs,ROADMAP.md.A miss during sync wrote the image unsized into the snapshot, which would take away the fallback from increment 5. Sync now keeps the previous snapshot's size and logs it.
Proof: behind the same proxy, main's script wrote 22 unsized images; this one wrote 0, keeping 22 sizes across 6 READMEs. The snapshot was restored afterwards.
7.
/healthzcounts how README images were sized —2780a4dFiles:
shared/types/health.ts,server/utils/health.ts,server/utils/readmeImages.ts,app/pages/status.vue,README.md,ROADMAP.md.readmeImages: { measured, kept, unsized }now appears on/healthzand as a status-page row. The fallback hides misses from the page; this shows whether production has any.Results: typecheck, tests and build green; routes unchanged; status page looked at, 390 and 1280.
8. A minimal Chromium repro of the fragment race —
bda7343Files:
docs/repro/smooth-fragment-overshoot.html(1.4 KB),ROADMAP.md.Chromium 152 at 390 px, 30 cold loads each:
scroll-behavior: autoCSSOM View says a new scroll aborts an ongoing smooth one; this is not that. Reporting it is an owner
[ ].9. The Firefox masthead: likely broken, with the fix written down —
b02913aRoadmap: the "look in a real Firefox" item, sharpened. Still
[ ].What I could and couldn't check: headless Firefox draws no
backdrop-filterat all: not the site's chain, not a plainblur(2.5px), notblur(8px), with anygfx.webrender.*pref. So the routine can't see it.Why it's likely broken:
backdrop-filteris dropped entirely when an SVGurl()filter falls back to a blob image.feImageandfeDisplacementMap, which the masthead filters use (4feDisplacementMap, 2feImage).The fix, not shipped because nobody has looked:
and (not (-moz-appearance: none))on the@supports. That query is true in Firefox 155 and false in Chromium 152.Needs a person with a real Firefox: look before and after. Alternatively, a headless compositor (
cageorsway, a pacman install) would let the routine look for itself.10–11. The check:navigation stall, caught and narrowed —
a3c43bb,fb656bbFiles:
scripts/check-navigation.mjs,scripts/lib/browser.mjs,ROADMAP.md.Caught twice tonight (#23's stall), thanks to increment 4:
arrive's evaluate went 180 s unanswered.My first theory (Nanna's length, an old tab) is wrong: the second stall was a different page in a fresh tab, so neither fits.
What a stalled page does now:
Shown on a stand-in site:
The real check passes 160/160 in both engines with this in place. Still open: the next stall's answer to the plain-evaluate question.
Snapshot —
a1200eanpm run sync: Skidbladnir v1.4.4 (released 2026-10-13), downloads and push times. Every README image is sized.Verification of the shipping tree
The final tree, snapshot included, built and served, all green:
check: 22 pages / 79 URLsa11y: 23 pagesa11y:browseranda11y:firefox: 23 pages × 1280 / 390 / 320check:navigation: 160/160 in Chromium and in Firefox/healthz:ok, live, readmeImages 116 measured / 0 kept / 0 unsizedServer routes (built server, real codes):
/healthz,/,/projects, every/projects/<slug>/aboutand/blog,/api/projects,/api/projects/onyums,/sitemap.xml,/news,/robots.txt,/releases.xml./projects/<slug>, to/about./projects/no-such-project,/no-such-page,/api/projects/nope, and the admin routes./onion-frame, as expected locally without a gateway.These are unchanged from increment 1 through the final build.
Bugs found, not fixed
pagehidesaved, so the page moved between reading and unload. Not the badges (2.3 px). Not seen in 15 complete Chromium runs on this branch.[ ]with next steps.ERR_CONNECTION_CLOSEDon Skidbladnir at 390 px, with a client navigation to#editionslanding the box 27 px under the aim (43 vs 16). The console error fails the check on its own, so the run was red either way. My guess is an external README image failing during the scroll and changing size above the heading; the error carries no URL, so that isn't shown. A[ ]for next run: log the failed URL, and find out what a broken README image does to the layout.Research
autoand runs the ancestor-revealing algorithm, which explains both the animation and the auto-opened<details>. https://html.spec.whatwg.org/multipage/browsing-the-web.html#scroll-to-the-fragment-identifierbackdrop-filteris ignored when an SVGurl()filter falls back to a blob image; dup 1972363 namesfeImage/feDisplacementMap. https://bugzilla.mozilla.org/show_bug.cgi?id=1961378 · https://bugzilla.mozilla.org/show_bug.cgi?id=1972363Done vs open
Done: increments 1–11; snapshot refreshed.
Onion probe: 4 scheduled runs in ~31 h, one first-try connect timeout, three first-try reaches in 11–13 s. Logged in the roadmap; too few to weigh C Tor.
Glance:
glance.basicautomation.ionow resolves publicly through Cloudflare and answers 401, so it is behind auth. The roadmap item was already ticked.New
[ ]:Still owner-gated or upstream: unchanged from #23, plus the Firefox look.
STOP REASON: 4 h cutoff (21:10 → past 01:10 CDT). For the last hour the frontier was thin: what remained was owner-gated, upstream-blocked, held for soak, or waiting on a stall to recur.
Recommended next step
@supportschange.Shipped
7606f2c, with main's tree identical to the verified branch.nightly-2026-10-13.basicautomation-site:previous.:local(b82154695c85), built from merged main, reportedhealthyin about 6 s./200,<title>"basic automation — software for the productive";/projects/skidbladnir/about200;/projects200;/status200./healthz200:ok, datalive, onionlaunched,readmeImages28 measured / 0 kept / 0 unsized.https://basicautomation.io/projects/nanna/about#api-key-invalidat 390 px, all with the heading exactly 16 px under the masthead.🤖 Generated with Claude Code