diff --git a/docs/project-state.md b/docs/project-state.md index 65878c1..e12be2a 100644 --- a/docs/project-state.md +++ b/docs/project-state.md @@ -89,6 +89,57 @@ Living list of what's done and what's next for blog.hoelee.com. Work through the > This plan comes from a full research pass (Sept 2026) comparing blog.hoelee.com against reference developer blogs (Simon Willison, Josh Comeau, Dan Abramov/overreacted, Julia Evans) + industry surveys. Priority is fixed: **identity & content → discovery → polish.** Don't reorder unless the user says so. > > **⚠ Re-checked against the live site 2026-09-29 (§4).** Parts of Phase A/C/D are stale — **C1, D1 and B2b are DONE.** The measured bottleneck is no longer content; it is **distribution / visibility**. Per user decision on 2026-09-29, **Phase E is inserted at the TOP of the queue — start there**, then work the still-open A/C items. +> +> **▶ NEXT TASK (user decision 2026-10-18): Step B6b — the 72-post artwork rollout.** It sits below in **Phase F** and outranks Phase E; it needs a GPU window, so a fresh session starts by reading Phase F, not Phase E. + +### Phase F — Artwork rollout: v2 "one art, four targets" (NEXT; user decision 2026-10-18) + +**Step B6b — Replace all 72 posts' artwork with the consultant-approved v2 set.** 🔵 Ready to run; blocked on a GPU window + three answers + +Everything below is measured, not planned. A fresh session needs no other context to continue. + +| Piece | State | +|---|---| +| The renderer | `scripts/og-gen/render_from_art.mjs` (committed `a41448b`) — one zero-text base frame → banner 1600×900 (`banners/.webp` + `.jpg` fallback), social card 1200×630 (`og/.jpg` EN, `og/zh-.jpg` ZH), thumbs `og/thumb/-{800,400}.webp` | +| The layout | `scripts/og-gen/template-v2.2.html` — frosted 736×536 bento card, blueprint grid, full-width evidence bar, self-fitting headline that reports `FIT px` through ``; a card that never settles fails the run | +| Per-post inputs | `scripts/og-gen/art-meta.json` — `art` (default `<art-dir>/<slug>.png`), `evidence` (**required, hand-written**), optional `ogTitle_en/zh`, optional `tags` | +| Prompts | `scripts/og-gen/prompts_catalog.json` — **72** entries (one visual metaphor + prompt per post) | +| Base art on disk | **2 of 72** — `C:/AI/ideogram4/out/sample_prod_169_00001_.png`, `sample_oom_169_00001_.png` (the consultant samples). **70 still to generate, and this is the GPU half of the job** | +| Evidence lines written | **2 of 72** (`running-production-infrastructure-solo`, `docker-reported-exit-0-the-oom-killer-disagreed`) | +| Live site | still the **v1** set: 72 `public/banners/*.png` + 72 `public/og/*.png` from the terminal-panel generators (2026-10-06…10-16). Nothing a visitor sees has changed yet | +| Reference delivery | `C:/Users/hoelee/Desktop/blog-og-image-redesign-brief/delivery-for-consultant-round4/` (+ `00-第四轮-实施反馈与3个待定细节.md` for the three open questions) | + +**What the GPU run has to produce.** 70 zero-text 16:9 frames (1360×768 or 1920×1080), one per post, from that post's entry in `prompts_catalog.json` — Ideogram 4 pipeline (`C:/AI/ideogram4/`) or ComfyUI on the Win11 VM's RTX 3060. Hard rules from the consultant: **no text, letters, numbers, HUD or watermark anywhere in the art** (put them in `art-meta.json` under `art` and drop them into `C:/AI/ideogram4/out/<slug>.png`, which is the renderer's default path). + +**Three decisions still open** (asked of the consultant in round 4 §二; the owner may simply pick the defaults): +1. English headline rag → **default: (C) shorten the card headline only**, via `ogTitle_en` in `art-meta.json` (article title untouched). +2. CJK headline length cap → **default: ≤30 characters incl. punctuation** (EN ≤65). +3. List thumbnail crop → **default: keep 100% right-focus**; switch to 85% only if the 3-line bento cards read cramped at ~398 px. + +**Format decision — measured, take it unless the owner objects.** A composited card renders **558 KB as PNG** vs a 42 KB average today; ×144 that is ~84 MB of repo and a heavy share payload. Same card: 256-colour PNG 240 KB, **mozjpeg q85 84 KB**, q78 70 KB. `--format jpg` is the renderer default. ⚠ Shipping `.jpg` means: +- `ogImage:` changed on **144** frontmatter files (`/og/<slug>.jpg`, ZH `/og/zh-<slug>.jpg`), and +- **`src/components/PostList.astro` line ~42 must change** from `.replace(/\.png$/, …)` to `/\.(png|jpe?g)$/`, or every listing thumb derives `…-800.webp` from `slug.jpg` and 404s. + +**Order of work** +1. Generate the 70 base frames (GPU), named `<slug>.png` under `C:/AI/ideogram4/out/`. +2. Write 70 `evidence` strings into `art-meta.json` — **draft them from the posts, then have the owner approve**; never invent a number. The renderer aborts and lists every slug that lacks one. +3. Dry-run the whole set to a scratch dir: + `node scripts/og-gen/render_from_art.mjs --all --limit 4 --out "$TMPDIR/og-check"` — expect `FIT` on all four cards. +4. Render into `public/` (`--all`), then `uv run --with pillow python scripts/optimize-images.py` for the v1-derived WebPs **only if any v1 file survives**; the renderer already emits its own thumbs. +5. Do the `.jpg` migration (frontmatter ×144 + `PostList.astro`) in the **same commit** as the images, or the site points at missing files. +6. `npm run build`, then `npm run preview`-equivalent check + the four URL assertions, commit, push `origin` **and** `github`. + +**How to prove it worked (do not eyeball it — vision reads were unavailable on 2026-10-18)** +- Reproducibility: re-render the two sample slugs and their banner + 800 px thumb must be **byte-identical** to the accepted delivery (sha256 `16e6a7b0`, `f3b29f38`, `c4e28291`, `8095ec6c`). +- Card layout: probe `.og/gen/<slug>-{en,zh}.html` in an iframe (serve the repo root over http — `file://` iframes are opaque origins) and assert `title` line count ≤3, `documentElement.scrollHeight − 630 == 0`, evidence bar `scrollWidth − clientWidth == 0`. +- Tags/banner: `python <skill>/scripts/measure_og_banner.py <slug> <repo>` → `rows==1`, `overflow==0`, banner `delta<=3` — it only covers the tag row and terminal panel, not the headline. +- After deploy: every `/og/<slug>.jpg`, `/og/zh-<slug>.jpg`, `/banners/<slug>.{webp,jpg}`, `-800.webp` returns 200 **with cache-busting** (Cloudflare caches a negative 404 for 16 days). + +**Known gaps in the plan** +- The **OCR pseudo-text gate** promised to the consultant (auto-regenerate a frame that contains readable characters) is **not implemented** — it has to be written or the promise withdrawn. +- `art-meta.json` is committed with only the two sample entries; the 70 others are the work. +- Extra thumbs: the renderer emits 400 px and 800 px; nothing else consumes them. + ### Phase E — Distribution & visibility (added 2026-09-29 from the live re-audit — DO THESE FIRST) @@ -900,6 +951,12 @@ not needed), cross-checked against the local repo at `D:/dev/hoelee-blog`. --- ## 4b. Live re-check — 2026-10-17 (after batches B1–B4) + +**Appended 2026-10-18 (measured after the B6 front-end deploy and the commit-churn publish):** +- `/` and `/zh/` serve the bento featured grid (`featured-bento-grid`, 4 cards, OG thumbs `naturalWidth 800`); the light theme's pill contrast is fixed (1.96 → 6.10); `last-modified` moved within 67 s of the push, so the CF purge still works. +- The commit-churn post is live in both languages (`pubDate 2026-10-18`), sitemap now **250 URLs**, both new URLs carry `lastmod 2026-10-18` + 2 hreflang alternates, RSS contains it, `/posts/` order monotonic with it on top. +- Cron facts at this moment: `devto daily crosspost` published 2 of a 70-deep queue, `linkedin-daily-post` has published **5** (silent unless it publishes — read `cron/output/35f8985f609a/*.md`, not `last_status`). + ... - **B6 Visual Redesign Milestone reached (2026-10-18)**: - Ideogram 4 pipeline running locally (`1360x768`, ar 16:9).