Tracker at 20 approved / 71 pending. Same pass as batch 1: first person throughout,
no LAN IPs in prose, ZH twins normalised to simplified Chinese, dynamicCta where the
post ends on a concrete next step.
- voice: first-person throughout (we/our -> I/my), matching the post guideline
- privacy: internal LAN IPs replaced with placeholder hostnames
(n8n.internal, gpu-node.internal); one compose volume path generalised
- ZH twins: Traditional -> Simplified characters (site serves zh-Hans),
whole-file renormalisation where the twin was still Traditional
- dynamicCta: true on 12 posts so the contextual dual-track CTA renders
- long configs wrapped in <details class="tech-deep-dive"> with a summary
naming the artefact and line count
- self-hosted-tts: token refresh now writes .tmp + atomic mv, with a note on
the 401 race the old truncating redirect created
Adds EN + ZH post php2shell-patching-every-php-runtime-i-manage: measured
PHP versions across the fleet, the order the fixes shipped in, the 8.5
package trap, the OLS vhost handler switch, and the silent bot-block bug
the sweep uncovered. Ships og cards (EN/ZH), banner + webp, 2 thumbs.
The benchmark table derives its figures from 218.3 s ((352-218.3)/352 = 37.98%),
while the TL;DR said 38.1% (that one came from rounding 218 exactly). Same page
carried both numbers; now the TL;DR matches the table. 1.61x throughput is
unchanged (352/218.3 = 1.6125).
Reviewer's five "highest priority" items, each checked against the source before acting:
* 38% speedup -> 38.1% less render time (352s -> 218s, 1.61x throughput); says it was
a single run each, same clip, same machine, same encoder settings.
* "microsecond-accurate" -> frame-accurate: at 30 fps one frame is 33.3 ms, and the text
now states that word-level timestamps are not microsecond-accurate.
* "Three minutes later" -> "a few minutes later", plus the one measured number (218 s
render for the 4-minute track) so the claim is checkable.
* Zero Jitter / Zero Light Flashing -> "no visible jitter" / "no dark flash at the cut",
scoped to the clip that was measured.
* ti.mode 0o666 -> 0o644. Hygiene, not the syntax error he reported: source and live HTML
both read 0o666 (the live page splits it across two highlight spans and his text
extraction inserted a space), and 0o666 is legal Python.
* "0 MB RAM spike in Chrome" now scopes itself to the Chrome container and says the
Python client still buffers the whole tar. New "What this pattern does not solve"
block: client buffering, target directory must already exist, tar member names become
container paths, Portainer key / CDP 9222 are root-equivalent.
All three posts get a TL;DR and inline cross-links (the trio had zero internal links
before); the ZH links use the real /posts/zh/<slug>/ path.
Not done, because it needs the owner's data rather than invention: end-to-end timing
table, benchmark conditions, whether 1.89 s was a single run, before/after jitter clips,
the "what still needs a human" list. Task list:
docs/consultant-review-2026-10-22-3-video-posts.md.
Artwork for the three slugs regenerated (1600x900 banner, 1200x630 share cards EN+ZH,
400/800 list thumbs); the ZH pipeline card already carries the corrected description.
The YuE2 and subtitles posts shipped text-only: render_from_art.mjs only READS
ogImage/banner, and after the 2026-10-19 bulk migration no script had to write
them, so both pages advertised /og-default.jpg and rendered no hero banner.
- new metaphors (in build_captions.py, frozen here via sync_prompts_catalog.py),
captions, art-meta evidence, banner plan and the five derived files per slug
- frontmatter: ogImage + banner in EN and ZH for both posts
- scripts/check-assets.mjs is now step 1 of npm run build, so CI fails when a
published post lacks a language-correct og card, banner, banner .webp or
400/800 list thumb. It reported 16 problems on the unfixed tree, all here.
The ::before used CSS escapes written through a Python string, which ate them
(octal escape) and shipped control bytes — the button read as mojibake.
- use a literal UTF-8 arrow instead of \2193\0020
- figcaption is now flex, so a long title wraps under the button rather than
being crowded by a float; verified at 360px and 680px
- round the shown duration down so it matches the player's clock (197 s = 3:17)
Tutorial on turning untimed AI-generated audio into LRC + SRT: align ASR word
timestamps against the KNOWN lyrics (SequenceMatcher) instead of trusting a
transcript, then a governor that rejects impossible anchors, refills runs by
unit-proportional duration, and enforces a 1.2 s minimum line gap.
Ships 18 English songs (342 subtitle lines, mean anchor coverage 0.96, 9/18
fully anchored) with synced lyrics plus downloadable .srt per track. Documents
both player bugs and the headless-Chrome numeric probe that finally caught them.
offsetTop is measured from the nearest positioned ancestor, so inside an
unpositioned .yue2-box it returned the line's distance from the page top
(thousands of px). scrollTop clamped that to maxScroll, so the box jumped to the
bottom the moment singing started and the text was unreadable.
Now: box.scrollTop += (pr.top - br.top) - (clientHeight - lineHeight)/2, plus
position:relative on the box. Verified in headless Chrome with a numeric probe:
the active line sits ~124px into a 274px box at t=48/100, nothing is highlighted
and scrollTop=0 at t=0, and the box settles at maxScroll only for the final lines.
findIndex(t > now) - 1 returned -1 before the first line started, which the
`if (i < 0) i = lines.length - 1` guard turned into the LAST line — so playback
began scrolled to the bottom. Use a last-passed-index scan instead (-1 = before
the first line), centre the active line inside the box (so upcoming lyrics are
visible), and scroll the box itself rather than scrollIntoView(), which dragged
the whole page. Also bumps the box to 250px. Fixes yue2 post + both Suno posts.
Twelve Mandarin songs came back exactly 240.000 s with the outros cut.
Documents the ffprobe tell, the BPM myth, the seed-cache trap, the
2.0-2.8 hanzi/s spread, the 300 s VRAM ceiling, and the archive-the-clipped
policy. Ships 11 finished tracks with ASR-derived synced lyrics (EN + ZH).
The card renderer already normalises straight quotes to “ ”, but the post H1 and the HTML
<title> were still printing an escaped straight quote (). The two ZH posts that use
quoted phrases now carry the curly characters in the frontmatter itself, so the article page
matches the card.
Every post now carries one unique local-ComfyUI/Ideogram 4 base frame, composited
into EN + ZH share cards, a banner and list thumbs.
- the shipped prompts_catalog held only 21 distinct metaphors for 72 posts (16
shared one visual), so all 72 were rewritten as unique object+state metaphors
and 10 frames re-rolled after OCR found pseudo-text rendered at legible size
- render_from_art.mjs emits JPEG by default (558 KB PNG -> 84 KB mozjpeg q85);
the ZH 1200x630 card did not exist before this batch
- 288 frontmatter fields migrated; the 144 v1 PNGs are gone
- PostList's thumb helper keys off the base slug (a ZH card is zh-<slug>.jpg while
the thumb is <slug>-800.webp, which 404'd the whole ZH listing)
- [...slug].astro's <picture> regex accepts .jpg
- the repo now carries the art inputs (metaphors.json, captions/<slug>.json,
refreshed prompts_catalog.json) so a frame is reproducible from git alone
The commit-churn post the owner read and approved today, published in the
first-person voice he asked for.
- Voice rewrite before publishing: the draft opened on "when managers or
recruiters ask how productive an engineer is" and addressed the reader in the
second person throughout (you/your 12 -> 2, both in the CTA; ZH 你 5 -> 2).
It now reads as a log entry: "Last week I did something I almost never bother
to do: I counted my own commits." Headings moved from essay titles to actions.
Numbers, the 5-repo table and every claim are unchanged.
- Title changed at the owner's request:
"Why 500,000 Lines of Commit Churn Only Left 230,000 Lines in Production"
-> "I Committed 518,000 Lines in 30 Days. Production Kept 235,000."
(ZH: 30 天提交 51.8 万行,生产环境只留下 23.5 万行), pubDate 2026-10-18.
- Fixed two real defects found while making the card: the draft claimed "four
automated gates" and listed three; and og-gen split titles at the word-count
midpoint, breaking at "…Lines in / 30 Days" — the splitter now prefers a
sentence boundary near the middle and falls back to the midpoint.
- og PNG regenerated for the new title, thumbs and banner WebP re-derived.
Measured: card 2 title lines, overflowY 0, measure_og_banner PASS (tags 1 row,
banner delta 2), build clean, /posts/ monotonic with this post on top.
Also queued the post at the head of the dev.to drip (queue 69 -> 70).
- my-backup-was-using-someone-elses-api-quota (notes, 2026-10-15, pinned by its own evidence)
- space-reclamation-wasnt-stuck-it-was-waiting (devops, 2026-10-14, pinned by its own samples)
- adding-a-domain-to-someone-elses-mail-server (notes, 2025-05-06, backdated: no date/version pins)
- embedding-fonts-so-a-pdf-looks-the-same-everywhere (engineering, 2025-01-22, backdated: no date/version pins)
All four updatedDate 2026-10-16 so every lastmod stays honest; the two backdated posts carry no prose links
(a backdated post may only link backwards). og measured rows=1/overflow=0, banners 8 rows/delta=2/overflow=0.
Backdated into the 2025-02 gap: pubDate 2025-02-20, updatedDate 2026-10-16 (lastmod honest).
No calendar dates or checkable version pins in the prose — the condition for backdating — and
no internal links, since every post it would cite is dated later and a backdated post may only
link backwards (see project-state B2n). Generators: additive entries only (5 + 17 lines, 0 deletions).
- calibrating-intel-quick-sync-hevc-quality (tutorials): pubDate 2026-10-14, updatedDate 2026-10-16
(its real work date; sitemap lastmod stays honest). ffmpeg 9.0.2 pins it to 2026-09-18 at the earliest,
so it cannot be backdated — see project-state B2l.
- docker-reported-exit-0-the-oom-killer-disagreed (devops): pubDate 2026-10-16, date-pinned by its own
dmesg table, ships on the real date.
- og measured rows=1/overflow=0, banners delta=2/overflow=0 on both; build 159 pages, no warnings.
- git rm src/content/posts/the-dialog-opened-in-7-seconds-my-script-waited-5.md + the zh twin
- drop its TERMINALS/BANNERS entries from both generators (pure deletions: 0 added, 17 + 5 removed,
node --check OK, 0 remaining references to the slug, the other three slugs intact)
- build still 153 pages; no route, no listing row, no sitemap entry
Written 2026-10-16 from the linkedin-daily-post session, then dropped by the user.
Kept as draft:true rather than deleted so the text is version-controlled and a
flip of one flag can publish it later. draft:true excludes it from the build
(153 pages vs 155), the listings and the sitemap — verified. Its OG/banner PNGs
were deleted (drafts in this repo ship without images); BANNERS/TERMINALS entries
for the slug are already committed, so regeneration is one command.
- draft: true -> false in both files, pubDate 2026-09-20 kept, updatedDate 2026-10-16 (lastmod honest)
- fix the CTA's displayed phone number (011-797 2969 -> +60 12-797 2969)
- generate public/og + public/banners for the slug (og rows=1 overflow=0; banner delta=2 overflow=0)
- generators carry the TERMINALS/BANNERS entries for this post; three more entries for
posts written the same session (held for review, not committed here) are inert