feat(docs): prod-faithful dev loop, mermaid cache, favicon, doc fixes - #277
Conversation
…tion The favicon.svg has carried a prefers-color-scheme swap since the brand kit landed, but no browser ever showed it: #193 dropped the sizes="any" SVG icon link, so Chromium selected the static .ico, and Chromium only rasterizes an SVG favicon once regardless (crbug.com/1208277). - restore the explicit sizes="any" SVG icon link next to the numeric-sized .ico (the pair Chromium + Firefox both need) - generate statically-colored favicon-{light,dark}.svg in the brand kit - live-swap them from Head.astro on prefers-color-scheme changes, GitHub-style: replace the link node each time (in-place href mutation is only honored transiently) and remove the .ico from the live candidate list — Chromium's scorer otherwise commits the exact-size .ico over a sizes="any" SVG, verified via the profile Favicons DB - keep the self-styling favicon.svg + .ico SSR markup for no-JS consumers; Safari ≤18 falls back to the root /favicon.ico auto-probe Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- CHANGELOG: Unreleased Fixed entry for the theme-adaptive favicon, superseding the favicon wiring described in the branding-pipeline entry - generate.sh: lockup-*.svg are outlined to paths in place — the comment claimed they still hold <text> - Makefile: branding-docs help text pointed at the wrong mark.svg path Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
# Conflicts: # CHANGELOG.md
|
Need the big picture first? Review this PR in Change Stack to see what changed before going file by file. Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughThis PR adds theme-adaptive favicon support (static light/dark SVGs + runtime swap), implements a production-faithful rebuild-on-save docs dev loop (new Node script + Wrangler serving), and updates config, tooling, docs, and changelog entries to reflect these changes. ChangesTheme-Adaptive Favicon and Production-Faithful Docs Dev Loop
🎯 3 (Moderate) | ⏱️ ~25 minutes Note 🎁 Summarized by CodeRabbit FreeYour organization is on the Free plan. CodeRabbit will generate a high-level summary and a walkthrough for each pull request. For a comprehensive line-by-line review, please upgrade your subscription to CodeRabbit Pro by visiting https://app.coderabbit.ai/login. Comment |
|
📚 Docs preview is live: https://0a4f7e85-wavehouse-docs.wave-rf.workers.dev Updated for commit 12a734c |
make dev-docs no longer runs `astro dev`, whose dev server skips everything the Cloudflare Worker adds in production (cloudflare-md-router .md twins, pagefind search, starlight-llm-tools outputs) — the de-facto workflow had become a manual build-docs + preview-docs cycle, restarted by hand per change. docs/scripts/dev.mjs (new) now drives the loop: a debounced full `astro build` per save into a .dev-dist/ staging dir, synced in place into dist/ only on success (plain node fs — no rsync or any other external tool), served through `wrangler dev --live-reload` on :4321 (DOCS_PORT overrides) so the browser refreshes itself per green build and a failed build keeps serving the last good site (red banner + terminal bell). Watch set: src/, public/, astro.config.mjs, tsconfig.json, package.json, .env*; wrangler watches worker/index.ts and wrangler.jsonc itself. starlight-links-validator is skipped under WAVEHOUSE_DOCS_WATCH=1 so mid-edit dangling links don't block previewing every save — DOCS_WATCH_STRICT=1 keeps it on; CI and make build-docs enforce links unchanged. The raw HMR server remains as `pnpm run start`, and the VS Code launch config gains an entry for each. Mermaid SSR re-rendered all 17 diagrams through headless Chromium on every build, diagrams changed or not. astro.config.mjs now uses astro-themed-mermaid v0.2.0's `rehypeMermaid` export — rehype-mermaid behind a content-addressed per-diagram disk cache (keyed on diagram source + render options + package versions, entries re-id'd to content-derived ids). Measured: no-diagram-change rebuilds 6-7s → ~3.7s, single-diagram edits re-render only their page, output byte-identical modulo SVG ids; save → refreshed browser is ~4s end to end. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The contributor docs (development.md §CI & review automation, CONTRIBUTING.md) still described the pre-consolidation pipeline: pr-title.yml and a `Validate` check, `Check`/`Build` required contexts, project-orchestrator.yml card movement, and label.yml — all replaced by housekeeping.yml / the single `CI` job / native Projects v2 board workflows (May 2026 consolidation, #115). Rewritten against the live config: required checks are CI, PR housekeeping (Conventional Commits title + 72-char cap, labeler step, reviewer assignment on open/ready), and Admin approval; the inverted "Lint/Test not required (#57)" note is dropped. Also fixes a Chromium misattribution carried in prose and two Makefile comments — starlight-links-validator needs no browser; only rehype-mermaid does — and adds docs/.dev-dist/ to make clean's help text and the development.md targets table. Found by the docs-reviewer pre-push gate (5 MUST / 1 SHOULD / 1 MAY, all addressed). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Round-2 reviewer findings: "nothing else uses a browser" overclaimed — the manual scripts/screenshot.mjs QA helper launches the same Playwright Chromium (scoped the claim to the docs *build* in development.md and the install-playwright-docs Makefile comment), and development.md still quoted AGENTS.md §"Review Response (MANDATORY)", renamed to §"Review Response" in #129. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Both round-3 reviewers flagged the same single remainder: the bare `scripts/screenshot.mjs` form added in 06d0a4b reads as repo-root `scripts/` (which has no such file) in the root Makefile comment, development.md's repo-root path convention, and the CHANGELOG entry. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Two reviewer-flagged follow-ups from the docs-accuracy sweep: admin-approval.yml's header claimed the ruleset's required_approving_review_count is 0 — the live ruleset says 1 (any collaborator); the status check is what makes one of those approvals specifically an admin's. And AGENTS.md's `make clean` one-liner omitted the docs build outputs (docs/dist/ predating this branch, docs/.dev-dist/ added by it) that the Makefile help text lists. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Post-wizard hardening of the PostHog integration:
- route analytics through the managed reverse proxy t.wave-rf.com and set
ui_host so toolbar/app links still point at us.posthog.com
- commit public token/host fallbacks in posthog.astro: CI builds docs with
no PUBLIC_POSTHOG_* env and docs/.env is gitignored, so the wizard's
.env-only wiring shipped a dead snippet in production
- extract the index.mdx inline tracking script into
HomepageCtaTracking.astro — MDX parses `{` as JSX expressions, so a raw
<script is:inline> body fails `astro build` (acorn parse error)
- move the wizard's agent skill to repo-root .claude/skills/ (the only
location discovered when sessions launch from the repo root) and fix the
six markdownlint errors in its reference files
Verified: prod-faithful build without .env renders the relay host on every
page; headless-browser run confirms hero/footer/homepage click listeners
fire posthog.capture with the documented payloads and the ClientRouter
soft-nav $pageview (pushState) captures; relay accepts ingest POSTs (200).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- CHANGELOG: add the [Unreleased] entry for the analytics rework - api.md: drop the stray 400 unknown-table row (handler returns 404) - claude-code.md: inventory the vendored integration-astro-view-transitions skill in both .claude/ tables - docs-prose.sh (+ AGENTS.md / docs-review.md lockstep lists): denylist the frozen wizard report as an internal artifact; correct its drifted file attributions (index.mdx → HomepageCtaTracking.astro) - deployment.md: make clean comment now lists docs/.dev-dist/ - rename posthog.astro → PostHog.astro to match component naming Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Two path-scoped configs — `.github/.markdownlint.json` and `.claude/.markdownlint.json` — held nothing but `"WH001": false`, silently switching the no-hard-wrapped-prose rule off for CI docs and agent prompts ever since #489 introduced it. `CONTRIBUTING.md:97` tells contributors `make lint` enforces WH001 **everywhere**, while `AGENTS.md:342` and the `.markdownlint-cli2.jsonc` header wrote up the carve-out — three descriptions of one rule, disagreeing. That cost a round trip on #520: a reviewer correctly flagged a hard-wrapped bullet in `.github/workflows/README.md`, an agent pointed at `"WH001": false` for that path and pushed back, and the reviewer recorded a persistent *learning* never to flag WH001 there — the wrong invariant, learned off the wrong side of the contradiction. ## What changed - **Both configs deleted.** Each held only `extends` + the override, so the root `.markdownlint.json` (`"WH001": true`) governs again. The `ignores` array is untouched — there is now **no path-scoped carve-out of any kind**. - **51 hard-wrapped paragraphs reflowed** by `make fix`: 41 in `.github/workflows/README.md` (378 → 171 lines), 10 in `.claude/skills/pm-triage/references/routine.md`. Mechanical joins; no wording changed. - **The vendored PostHog skill is deleted** — `.claude/skills/integration-astro-view-transitions/`, 9 files / ~1,456 lines including an 809-line `EXAMPLE.md` copied wholesale from `PostHog/context-mill`. Its integration job finished in #277, nothing in the repo calls it, and the live docs-site setup is documented in `docs/src/components/PostHog.astro` and the CHANGELOG. Unowned third-party prose drifts silently on every upstream bump and nobody here reviews it — and it was the single file that would have needed a special-case exclusion, so removing it is what lets the rule apply with **no exception at all** rather than one documented one. - **Docs reconciled** so all four descriptions agree. `AGENTS.md:342` and the config header rewritten; `AGENTS.md:326` and `CONTRIBUTING.md:97` already said "everywhere" and are now true. `AGENTS.md:342` also tells future readers *not* to reintroduce a subtree override, pointing at an in-file `markdownlint-disable` as the visible escape hatch — verified to actually work, block form only. - **Two dead denylist entries swept.** `docs/posthog-setup-report.md` (the wizard's other artifact, deleted in #502) and `PERF-CLAIMS-REVIEW.md` — which was never tracked at all, so it guarded a file that has never existed. The list's other general cases are patterns (`*.draft.md`, `*.old.md`) that already cover a one-off review document. Removed from all four lockstep locations; `scripts/docs-prose.sh all` still resolves the same 27-file prose set. ## What review turned up None of this was in #521's scope. All of it is the same defect class — documentation asserting a state of the world that had moved on — which is what made a whole-file read worth doing. - **WH001 has a blind spot.** `no-hard-wrapped-prose.mjs:139` classifies any line indented four or more spaces as an indented code block, so a **nested** list item is never joined. Three hard-wrapped bullets sat in `.github/workflows/README.md` — in the very file this PR reflowed — invisible to the autofix. Unwrapped by hand; they were the last hard-wrapped prose paragraphs in the repo. - **That made a documented rule false.** `AGENTS.md:326` and `development.md:432` both promised "a list item is joined as a unit". Not for nested items — a contributor would expect `make fix` to unwrap one and it silently doesn't. Both now state the four-space caveat. - **`scripts/docs-prose.sh`'s header undercounted its own lockstep set**, naming two sibling copies of the denylist when there are three. The missed one is `.claude/agents/docs-reviewer.md` — the gating subagent's own system prompt — which `git log -S` shows had been out of sync for the entire life of the `posthog-setup-report.md` exclusion, and agreed only by accident of this branch removing it. - **The job graph contradicted itself.** `docs-deploy` was drawn without its `needs` edges from `unit`, `integration`, and `e2e`, and `ci`/`docs-preview` were missing `changes` — while the legend three lines below states "Solid arrows are `needs` edges" and `changes --> deploy` *was* drawn. Five edges added; the diagram now matches `ci.yml` edge-for-edge in both directions. - **`claude-code.md` deferred to work that had already shipped.** It told readers that "when #121 lands a SigNoz dev stack with `make dev-obs`" Grafana MCP would become useful. #121 closed as *completed* in May, `dev-obs` exists nowhere in the tree (the real targets are `obs-aspire` / `obs-grafana` / `obs-front`), and `deployment.md` states outright that no heavy multi-node cluster like SigNoz is maintained for local development. Now points at `make obs-grafana`. Filed rather than fixed here: **#523**, where `deployment.md` claims all three local observability stacks publish OTLP `4318`, but only `obs-front` does. ## Test plan - `make ci` green end to end on the final tree, marker matches HEAD. - `markdownlint-cli2` reports 0 issues over all 42 tracked `.md`, and `pnpm lint:md` 0 over all 48 tracked `.md` + `.mdx` — "every tracked Markdown file" is literally, not approximately, true. `make fix` is a fixpoint. - **Reflow safety proven, not eyeballed.** Reviewers reconstructed the pre-image files, re-ran the repo's own `markdownlint-cli2 --fix`, and diffed: the branch files are **byte-identical to the autofix output**, ruling out a hand-edit in the reflow. Independently, word-level diffs against `main` show `routine.md` is word-for-word identical and `.github/workflows/README.md`'s only content changes are the five graph edges and the past-tensed badges sentence. - **"Last hard-wrapped prose in the repo" was checked against WH001's own blind spot** rather than its 0-issue result: a scan of all 48 tracked files for nested list items with 4-space continuations found four hits, all YAML frontmatter. No prose. - Every drawn graph edge verified against `ci.yml`'s `needs`, both directions — nine into `ci`, seven into `docs-deploy`, two into `docs-preview`, none spurious. - `shellcheck` + `bash -n` clean on `docs-prose.sh`; the new `/deployment#local-observability-stack` anchor is validated by `starlight-links-validator` during `make ci`'s docs build. Closes #521 --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Summary
Four change sets, one theme: the docs workflow now behaves like production, fast.
1. Production-faithful
make dev-docs(docs/scripts/dev.mjs, new):astro devskips everything the Cloudflare Worker adds in production —cloudflare-md-routercontent negotiation (.mdtwins), the pagefind search index,starlight-llm-toolsoutputs — so the de-facto workflow had become manually cyclingmake build-docs && make preview-docs. The dev loop now rebuilds on save (debounced; mid-build saves coalesce) into a.dev-dist/staging dir, syncs intodist/only on green builds (plain node fs — no rsync or other external tools), and serves throughwrangler dev --live-reloadon :4321 (DOCS_PORToverrides): the browser refreshes itself per build, and a failed build keeps serving the last good site (red banner + terminal bell).starlight-links-validatoris skipped in watch builds so mid-edit dangling links don't block previewing (DOCS_WATCH_STRICT=1keeps it on; CI andmake build-docsenforce links unchanged). The raw HMR server stays available aspnpm run start.2. Per-diagram Mermaid render cache: every build re-rendered all 17 diagrams through headless Chromium, diagrams changed or not.
docs/astro.config.mjsnow usesastro-themed-mermaidv0.2.0'srehypeMermaidexport (released as part of this work) —rehype-mermaidbehind a content-addressed per-diagram disk cache. Warm rebuilds drop 6–7s → ~3.7s, a single-diagram edit re-renders only its page, and output is byte-identical modulo SVG ids. Save → refreshed browser is ~4s end to end.3. Theme-adaptive favicon that actually displays (commit 19e7a10): four stacked causes peeled — #193 dropped the
sizes="any"SVG link (Chromium then picks the.ico); Chromium rasterizes an SVG favicon once and never re-renders on theme flip (crbug.com/1208277); in-placehrefmutation is honored only transiently; and Chromium's scorer commits an exact-size.icoover asizes="any"SVG (verified against the profileFaviconsSQLite, contradicting the standard blog advice). Fixed via the restored icon-link pair, statically-coloredfavicon-{light,dark}.svgbrand-kit variants, and aHead.astrolive-swap script (fresh link node per repaint,.icoremoved from live candidates). No-JS and Safari ≤18 keep working fallbacks.4. CI/review-automation docs refresh (commit 0b54c50):
development.md§CI & review automation andCONTRIBUTING.mdstill describedpr-title.yml/Validate,Check/Buildchecks,project-orchestrator.yml, andlabel.yml— all replaced byhousekeeping.yml/ the singleCIjob / native Projects v2 board workflows (May consolidation, #115). Rewritten against the live config, the 72-char title cap documented, and a Chromium misattribution corrected (starlight-links-validatorneeds no browser; onlyrehype-mermaiddoes).Test plan
Accept: text/markdowntwin negotiation,/llms.txt, pagefind, failed builds keep serving the previous dist, file↔directory type-flip recovery in the sync,DOCS_WATCH_STRICT=1fails loudly on a planted broken link, SIGINT/SIGTERM/pkillteardown leaves no orphansastro:build:donetheme patch counts unchanged; v0.2.0 ships 12 unit tests covering hit/miss/harvest/re-id/corruption pathsFaviconsDB ground truth, Playwright DOM swap checks both directions + across view transitions, manual Brave/Firefox/Safarigh api),housekeeping.yml,ci.yml, andadmin-approval.ymlby the pre-push review gatemake cigreen for every pushed tree (tree-keyed markers); both pre-push reviewers (code + docs) at ship_it for HEADRelated issues
🤖 Generated with Claude Code