Commit Graph
183 Commits
Author SHA1 Message Date
hoelee 7c05a895ec post(batch-08): publish 5 incident & infrastructure posts after Argon review (EN+ZH)
Deploy / build (push) Successful in 1m35s
2026-11-01 14:53:49 +08:00
hoelee c9d00147df post(504): link the public artifact repo and v1.3 report; note cross-session drift
Deploy / build (push) Successful in 39s
2026-10-30 06:09:48 +08:00
hoelee 5b9034e34d post(case-studies): link the published whitepaper from both locales
Deploy / build (push) Successful in 1m25s
doc.hoelee.com/whitepaper-504-read-amplification-swr.html now exists, so the
closing line stops being a promise and becomes a link.
2026-10-30 02:59:15 +08:00
hoelee 2b9aca335e post(case-studies): the 504 that never happens on the dev machine (EN+ZH)
Deploy / build (push) Successful in 3m39s
Condensed, publishable version of the 504 read-amplification whitepaper --
the 10-minute narrative rather than the full report:

- read amplification: four reads per source file, 960 whole-file reads per
  page load for a list of titles and three status words
- the false negative: collapsing four reads to one buys only 1.5-1.9x on
  local NVMe, which is why the defect ships; the same code is 40x worse once
  each read carries a round trip
- timeout budget inversion: 30s Traefik / 60s Nginx / 120s Gunicorn produces
  orphaned responses, evidenced by the same X-Request-ID logged as abandoned
  upstream and completed downstream
- the fix is architectural: SWR + single flight + mtime/size signature diff,
  request path 433.5 ms -> 0.3 us, refresh after one change reads one file
- the bug the cache almost introduced: comparing source hash to translation
  hash can never match, so every note classified as outdated and the
  three-state display silently collapsed to two
- four stated limits: one laptop, +/-20% jitter, projection not measurement
  (stat() not billed, so network-volume incremental is ~2.4s not 37ms), and a
  synthetic corpus

Both language versions stay draft until artwork and a publish date are set;
the jumpLinks anchors and the <details> line count were verified against the
real render, not by eye.
2026-10-30 01:49:24 +08:00
hoelee 403d4c0d9f fix(posts): consultant final review — release ready (v1.2)
Deploy / build (push) Successful in 29s
02 comfyui (EN+ZH)
- unify the asset numbers end to end: 108 cover pairs = 216 banner+OG
  assets. The intro, the frontmatter metric, the description and the
  `ws.close()` comment all still carried the old "89", which contradicted
  the 216/25.9-min figure in the result section (consultant finding).
- state the timing scope explicitly: end-to-end per slug, diffusion plus
  the Pillow clearance audit and the two-size WebP encode.
- disclose the limit of the mtime evidence: mtime keeps only the last
  write, so gate-rejected re-queues from an earlier pass do not lengthen
  the measured window.

01 payments (EN+ZH)
- the idempotency comment now names the 72h bank reconciliation window,
  which is the boundary that makes EXPIRED a legitimate fulfilment entry
  point (line count unchanged at 27).
2026-10-29 14:29:03 +08:00
hoelee bfcf61c7ea fix(posts): consultant round-2 convergence (v1.2)
Deploy / build (push) Successful in 36s
01 payments (EN+ZH)
- idempotency gate is now a whitelist: only PENDING and a late-settled
  EXPIRED may enter fulfilment. Checking only for FULFILLED left the whole
  PROCESSING window open to a second queue push (consultant finding).
- k-of-n -> two-tier: both chassis anchors (SMBIOS board UUID + CPU
  architectural signature) matching is sufficient; if one anchor changed,
  every auxiliary digest must match. Aux dimension moved off the volatile
  OS GUID onto permanent NIC MAC.
- FSM diagram: RETRY_QUEUE branches from PROCESSING, not FULFILLED

02 comfyui covers (EN+ZH)
- subscribe the WebSocket BEFORE queue_prompt, settimeout(120),
  try/finally ws.close(), /history fallback on timeout: fixes the
  lost-terminal-frame hang and the per-image socket leak
- document Pillow half-wave rectified Laplacian (offset=0 clamps negative
  responses to 0) and why a signed float kernel would not work here
- replace the unverifiable "89 covers in 48 minutes" with the filesystem
  evidence: 216 assets (108 banner+OG pairs) inside a 25.9-min window
- ZH: drop the colloquial imperative; add self-bootstrapping note

03 traefik yaegi (ZH)
- the .traefik.yml contract paragraph and scoreThreshold 120 had only
  landed in the EN file; both now applied to ZH
- <summary> line counts corrected 29 -> 30 in both languages (verified
  programmatically for all eight code blocks)

layout
- standing provenance note in the site footer (sanitised client
  identifiers / production thresholds), per consultant Q7 ruling
2026-10-29 14:18:52 +08:00
hoelee a7077a3a1d fix(posts): apply consultant round-1 audit to 01 and 03
Deploy / build (push) Successful in 32s
01 architecting-sea-payment-and-offline-licensing-pipelines (EN+ZH)
- rewrite toyyibPay callback: hash = MD5(secretKey+status+order_id+refno+"ok")
  with hash_equals, transBegin + lockForUpdateByBillCode (no TOCTOU),
  integer-cents money comparison, fulfilment queued after commit so a
  gateway outage cannot roll back a paid order
- abstract hardware fingerprint to multi-dimensional immutable registers;
  add k-of-n (4 choose 3) threshold matching section
- drop unmeasured metrics (99.8% / 1.8s / 70%); fix duplicated 离线离线 typo

03 traefik-yaegi-plugin-package-name-trap (EN+ZH)
- title: drop second-person "Your"
- fix YAIEGI -> YAEGI code comment typo
- add Go-spec root cause (hyphen is subtraction, go.mod decoupling vs Yaegi)
- add .traefik.yml manifest contract paragraph
- sanitize YAML thresholds as illustrative; add "where Yaegi stops being
  the right tool" boundary section
- de-second-person the closing paragraph

Consultant review pack v1.1 shipped separately (docx 05 = response ledger).
2026-10-29 13:59:02 +08:00
hoelee c0ea7ea066 docs(review): hygiene cleanup and review preparation for 3 pending posts
Deploy / build (push) Successful in 33s
2026-10-29 13:31:32 +08:00
hoelee cf2b77d0dd post(batch-07): apply consultant micro-fixes to A/B/C (EN+ZH)
Deploy / build (push) Successful in 20s
A: drop the arrow artefact in the log block, name the upstream SSO gate as the
   party that writes 499, add I/O headroom to the latency lesson, make the 53-line
   snippet self-contained, correct summary line counts (53/18 not 52/22).
B: remove second person from the closing paragraph, <details class=tech-deep-dive>
   + summary with deliverable and 28 lines, ZH jumpLinks -> explicit English anchors.
C: three->four failure modes, remove 4 second-person spots, details class + 61/63
   lines, ZH anchors, and an explicit <a id> on the EN H2 whose backticked heading
   slugified to 'the-naive--map-0-...' (double hyphen).
2026-10-28 09:50:50 +08:00
hoelee f5f8e74a92 post: first-person voice pass on the 499 post (EN+ZH, no second person in body)
Deploy / build (push) Successful in 25s
2026-10-28 09:09:48 +08:00
hoelee ec2b89130b post: when a proxy timeout returns HTML instead of JSON (EN+ZH)
Deploy / build (push) Successful in 24s
499 post-mortem: an O(n) library audit inside a polled GET on a one-core
cgroup, three reverse-proxy hops, and the status no monitor watches.

- measured: 13.6 s idle / 17.7-98.5-35.8 s probes / 76-2507 s under load
- evidence triad: 7x 499 @ portal, zero app-log entries, in-container repro
- fix: 300 s TTL cache + single-flight refresh + refreshing/cached_at flags,
  text-first client reader, ?refresh=1
- result: cached path 200 in 0.24-0.36 s (median 0.26 s)
- art: ideogram4 base frame + 4 derived targets, art-meta evidence line
- LinkedIn companion: docs/linkedin/batch-07-linkedin-posts.md
2026-10-28 09:00:11 +08:00
hoelee 8a581dc68b feat(posts): publish batch-06 posts 01 & 02, render full visual asset suites for all 5 posts 2026-10-27 22:30:31 +08:00
hoelee c49c4ff725 feat(posts): adopt consultant rulings on decoupled slug, decoding contracts, and pillow laplacian filter 2026-10-27 21:48:24 +08:00
hoelee 0e31199510 fix(posts): apply consultant review corrections to batch-06 and update review pack v2.0 2026-10-27 20:53:31 +08:00
hoelee b2fdccf284 feat(posts): draft batch-06 (5 bilingual posts) and package consultant review pack 2026-10-27 20:34:54 +08:00
hoelee 69ce61a932 docs(review): apply batch-01 consultant fixes and update review status
Deploy / build (push) Successful in 23s
2026-10-27 06:15:27 +08:00
hoelee cd6511a0b3 docs(review): apply batch-04 consultant fixes and approve 5 tutorial/web3 posts
Deploy / build (push) Successful in 22s
- performUpkeep: external callable, re-check is mandatory security (not stale-data hygiene)
- BasicNft.tokenURI: ownerOf -> _ownerOf, dead custom error explained
- storage (SSTORE) vs EIP-170 runtime bytecode separated, derived ~1.3M gas for the two SVGs
- subs-15 retimed from a fresh faster-whisper word alignment (10.84s first line, was 28.22s) + SRT regenerated
- RDAP needs curl -L (bootstrap 302), ASN/Spamhaus blocklist check added
- learning-project framing -> Sepolia reference implementation / testnet validation build
- dynamicCta on the two posts that ended with no conversion block
- cross-links between the two NFT posts; tracker 91/91 approved
2026-10-27 06:13:00 +08:00
hoelee 19de315201 review: apply consultant batch-05 (devops re-review) fixes to 11 posts
- 11/telegram: rebuild the b"\r\n".join() explanation around the two real
  failure modes (line-splitting binary + doubled CRLF before Content-Disposition);
  fix the CR-eaten escapes that broke the inline code and the parts[] sample;
  close the Round 3 PID 1 vs docker exec gap; drop the leftover EN/ZH family
  framing; add the host anchor
- 04/09: the zero-block CRC32C belongs on the found side, not wanted; note the
  little-endian print order (0x98f94189 -> 0x8941f998); close the 09-22 scrub
  window and link the TRIM sequel from 09's result
- 06: losetup -p is --pass-fd, not a priority; explain the -2 in /proc/swaps
- 03: UDMA_CRC only counts ICRC frame faults; add the destructive-write warning
  to the raw fio recipe
- 02: CONFIG_CFS_BANDWIDTH, not 'no CFS scheduler'; SME wording in the ZH CTA
- 01: three reclaims (115.8 + 5.0 GiB), 344 GiB/8d = 1.8 GiB/h not 1.5
- 05/07/10: blueprint fields; 10 filters blank snapshot lines + names the
  empty-snapshot overwrite case; 07 comments that a container name survives
  recreation
2026-10-27 06:09:53 +08:00
hoelee a7d1cbaf3a docs(review): record approval and feedback resolution for batch-03
Deploy / build (push) Successful in 29s
2026-10-27 06:09:20 +08:00
hoelee a7e683100b review: apply external consultant editorial fixes and update audit tracker to 74/91 approved
Deploy / build (push) Successful in 28s
2026-10-27 05:29:08 +08:00
hoelee 4e64bfc9ae fix(listing): make the mobile archive reachable and clear the AA misses
Deploy / build (push) Successful in 33s
Review pass on the 041471d delivery, measured rather than eyeballed.

/posts/ on a phone put its first archive row 2.36 screens down (featured block
1235 px + 435 px of controls = row at 1996 px at 390x844), so a reader who came
to browse had to scroll past three stacked 16:9 cards. Below 700 px the cards are
now horizontal — thumb 38 %, excerpt dropped, title clamped to three lines — and
the block header carries `All 91 posts ↓` into #archive-list (with scroll-margin
for the sticky header), which doubles as the bypass-block affordance. Block
1235 → 523 px, card 392 → 153 px, first row 1996 → 1309 px.

Two new small-text colours measured under WCAG AA (.feat-min 3.04:1,
.archive-status 3.67:1 at ~12 px) move to --muted → 5.78:1 and 6.99:1. The
featured heading went with them; pre-existing --faint dates (3.67:1) were left
alone rather than restyling 91 rows.

/categories/ still showed the old Gemini case-studies.webp while the category
page had the new topology banner — one category, two art languages. The tile now
uses case-studies-banner-1200.webp (14 KB) letterboxed on #0b1613: a 16:9 centre
crop sliced the outer host panels in half, the letterbox was measured seamless.

`6min read` was emitted without its space (template-literal fix → `6 min read`,
`6 分钟`, verified in dist/). Both /posts/ ledes stopped claiming the page is
purely newest-first.

probe-layout: 72/72 viewport checks, collapse still 425→0→425 (1280) and
523→0→523 (390) in EN and ZH.
2026-10-27 05:27:06 +08:00
hoelee 09596fe7a5 edit(content): review batch-2 editorial pass across 24 posts (EN + ZH)
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.
2026-10-27 04:07:00 +08:00
hoelee 041471d25e feat(listing): portfolio-first archive, case-study hero, row action links
/posts/ and /zh/posts/ become hybrid: three fixed-slug flagship cards above the
complete year/month archive, with the flagship block collapsing (inert, h=0) as
soon as the reader filters. /categories/case-studies/ becomes a portfolio: compact
two-column hero with a 21:9 deterministic topology banner, flagship ordering from
lib/portfolio.ts instead of pubDate, and one measured pill per card.

Also fixes what the screenshot review turned up: ZH archive rows and category chips
were printing raw English slugs, the two chip strips were unlabelled and read as one
list with a duplicated 'devops', card meta rows broke rhythm past four tags, the nav
had no current-section indicator, and mobile title links were under the 44px tap
minimum. scripts/probe-layout.mjs is the repeatable gate: 72/72 page x viewport
checks and the collapse test.
2026-10-27 04:06:54 +08:00
hoelee 68771101ea edit(content): review batch-1 editorial pass across 24 posts (EN + ZH)
- 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
2026-10-27 03:29:03 +08:00
hoelee c5e473aaad feat(blueprints): launch 3 system blueprints, 12 topology layers & in-article mounting
Deploy / build (push) Successful in 24s
2026-10-27 01:33:56 +08:00
hoelee 419c962e2f feat(architecture): implement consultant review r4 (stream separation, nav upgrade, internal cta, schema & anchor fixes)
Deploy / build (push) Successful in 25s
2026-10-27 01:19:38 +08:00
hoelee 4a3c329fc6 feat(about): upgrade about page into dual-track work-with-me conversion hub 2026-10-27 00:44:44 +08:00
hoelee 355fecd348 feat(content): implement consultant review recommendations (executive summary, dynamic cta, homelab cleanup)
Deploy / build (push) Successful in 25s
2026-10-27 00:31:50 +08:00
hoelee 5ecf25d37c feat(hero): use the workstation-to-server-racks render as the hero banner
Deploy / build (push) Successful in 22s
Replaces the generated isometric diagram with the supplied 2752x1536
render (engineer at a multi-monitor desk, container streams flowing into
server racks). Re-exported at 1024/1280/2048 widths; alt text and the
lightbox caption now describe what the image actually shows.
2026-10-26 11:24:24 +08:00
hoelee 2747950eac feat(hero): replace banner with full-frame architecture illustration
Deploy / build (push) Successful in 22s
The previous hero-banner was composed as a wide banner with an empty left
40% reserved for overlay text. In the 50/50 hero column it rendered as a
shrunken half-width picture with dead space on both sides.

New illustration fills the whole 16:9 frame edge to edge (code/CI/CD left,
container + host cluster centre, observability right) so the right hero
column reads as a system diagram at its native 518px width, with the
2048w lightbox for detail reading.

Also add a 1280w WebP so DPR2 desktops do not pull the 2048w asset on
first paint.
2026-10-26 11:11:22 +08:00
hoelee f0b98843e9 feat(home): upgrade hero with lightbox banner, infra stats grid, tech pills, and category shortcuts
Deploy / build (push) Successful in 17s
2026-10-26 10:39:59 +08:00
hoelee d5a0fc089d feat(hero): refactor home hero to 2-column desktop grid and mobile visual flow
Deploy / build (push) Successful in 24s
2026-10-26 10:16:14 +08:00
hoelee 9fd02b8320 feat(hero): add AI-generated 'From Code to Production' architecture banner to homepage
Deploy / build (push) Successful in 23s
2026-10-26 09:46:24 +08:00
hoelee 18145b5db2 feat(header): logo mark + Lee Teong Hoe in brand, two-row mobile nav
Deploy / build (push) Successful in 29s
- brand: three-colour Hoelee mark (rasterised from the brand vector,
  transparent, public/images/hoelee-mark-96.png) followed by the name
- section links grouped in .nav-links so the mobile header puts them on
  their own row instead of wrapping past the search/lang/theme controls
- measured 320/360/390/414/600/768/1280: scrollWidth == innerWidth,
  header 91.6px two rows (<600px) / 60.3px one row, mark loads at 22/26px
2026-10-26 08:26:01 +08:00
hoelee 753e87d930 fix(audio): calibrate 60-track LRC timestamps with faster-whisper & strip rogue Korean characters
Deploy / build (push) Successful in 27s
2026-10-26 07:22:25 +08:00
hoelee 6ad1288ec7 fix(styles): prevent info overflow with dedicated full-width line and enlarge desktop cover to 38%
Deploy / build (push) Successful in 24s
2026-10-26 04:22:47 +08:00
hoelee af37f7ff1b style(posts): expand cover art to 1/3 width on desktop and 100% full-width on mobile
Deploy / build (push) Successful in 27s
2026-10-26 04:09:31 +08:00
hoelee 2b495efe43 feat(posts): publish 60-song full-length YuE2 BF16 tutorial with track navigator & lazy loading
Deploy / build (push) Successful in 25s
2026-10-26 03:58:10 +08:00
hoelee 0a4fc47fce feat(categories): replace procedural SVG art with Gemini-generated WebP editorial banners
Deploy / build (push) Successful in 23s
2026-10-26 02:48:06 +08:00
hoelee fa156b0b9d feat(posts): publish 3-part agent orchestration series across historical dates with full EN+ZH assets
Deploy / build (push) Successful in 27s
2026-10-25 19:47:54 +08:00
hoelee d5ab7dec81 feat(posts): publish 4-part windows-mcp series across historical dates with full EN+ZH assets
Deploy / build (push) Successful in 22s
2026-10-25 18:45:43 +08:00
hoelee 4cfbc33a6f feat(posts): update banner, og, and article body with face-swapping pipeline
Deploy / build (push) Successful in 22s
2026-10-25 11:59:42 +08:00
hoelee 6ab9526db1 docs(posts): reflect real workflow with gemini argon 4, iterative rerolls, and filmora editing
Deploy / build (push) Successful in 19s
2026-10-25 11:47:30 +08:00
hoelee 103ccedd63 feat(posts): publish 4-minute ai music video case study (en+zh)
Deploy / build (push) Successful in 22s
2026-10-25 11:37:07 +08:00
hoelee 1b795cee9d feat(posts): PHP2Shell — every PHP runtime I manage was vulnerable
Deploy / build (push) Successful in 23s
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.
2026-10-23 02:02:50 +08:00
hoelee cf4504ed21 fix(posts): one render number per page — 38.0% everywhere (352s -> 218.3s)
Deploy / build (push) Successful in 29s
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).
2026-10-22 21:14:40 +08:00
hoelee 04a1082e94 docs(blog): complete consultant review enhancements with compositing diagrams and benchmarks
Deploy / build (push) Successful in 16s
2026-10-22 19:31:10 +08:00
hoelee f32ae90cf0 fix(posts): correct the 3 video posts after consultant review, with fresh artwork
Deploy / build (push) Successful in 39s
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.
2026-10-22 19:29:26 +08:00
hoelee 6409f751a9 feat(posts): add 2 local TTS posts (EN+ZH) on CosyVoice 2 stack and percent-encoding post-mortem
Deploy / build (push) Successful in 25s
2026-10-22 19:16:25 +08:00
hoelee 19023d2e4e feat(posts): add 3 video automation posts (EN+ZH) backdated into 2025 archive gaps with full artwork suite
Deploy / build (push) Successful in 31s
2026-10-22 18:47:41 +08:00