REPO_POLICIES.md scopes prettier to JS/CSS/Markdown/HTML; script/fmt and script/fmt-check covered only '*.md' — top-level markdown. Both now run over '**/*.md' and '**/*.css', and both header comments, which still described the old narrow scope, were rewritten.
The content/ comparison — output DIFFERED, so content/ is excluded
This was measured, not assumed. public/ was extracted from the built image (pinned hugo v0.164.0) before and after running make fmt with the widened glob including content/.
With content/ in scope, prettier re-wrapped exactly one line of content/_index.md:
-- **#1** — Feb 4, 2026, 7 PM at [Lee's Sandwiches, 3989 Spring Mountain Rd](https://maps.app.goo.gl/4Zc5zRVr8srTVStH9)
+- **#1** — Feb 4, 2026, 7 PM at
+ [Lee's Sandwiches, 3989 Spring Mountain Rd](https://maps.app.goo.gl/4Zc5zRVr8srTVStH9)
and the rendered public/index.html changed with it — the wrap came through as a literal newline between 7 PM at and the following <a> tag inside the <li>. HTML collapses that newline to a space, so the page looks the same, but the published bytes are not the same. Per the issue's rule ("if it differs at all, exclude"), content/ is in .prettierignore with a comment recording this measurement. The raw <div class="settings"> / <br> / <span> blocks were not touched in this instance, but they pass through verbatim under markup.goldmark.renderer.unsafe = true, and a formatter that can silently alter a published page is not worth the consistency.
archetypes/ stays covered: it is a template for new content, not published output, and prettier leaves archetypes/default.md unchanged.
Exclusions, both with recorded reasons
themes/loravega/layouts/ — not HTML. Go templates carrying {{ define }}, {{ block }}, {{ .Content }}, {{ readFile ... | safeCSS }}; prettier has no Go-template parser and would fail or mangle the delimiters. Covering them needs an out-of-tree plugin and therefore a package.json, which is out of scope. No plugin was added.
content/ — see above.
CSS
themes/loravega/static/css/style.css is now formatted and gated. It is inlined into every page by baseof.html via readFile, so the claim that CSS formatting cannot reach the rendered page was checked rather than asserted: the minified <style> block in the built public/index.html is byte-identical before and after.
Commit ordering — no merge commit required
Two commits, each of which passes make check standing alone:
f3176a1 — the style.css reformat only. The scripts are still at the old '*.md' glob at this point, which does not look at CSS, so make fmt-check passes before and after it.
3e0694e — the glob widening, the two .prettierignore entries, and TODO.md. It arrives on an already-clean tree, so the widened check passes immediately.
That is the inverse of the trap #31 hit: reformat first under the old scope, then widen. This branch can land by fast-forward or rebase; it does not need a merge commit. Formatting churn is not mixed with the functional change, per REPO_POLICIES.md.
Verification
Final rendered-output check against the pre-change baseline: index.html, index.xml and sitemap.xml are byte-identical. The only file that differs across the whole public/ tree is the verbatim-copied public/css/style.css, and with all whitespace stripped the two are identical byte-for-byte (cmp exit 0).
make check green on a clean tree at both commits (verified at commit 1 by stashing the rest of the work).
script/cibuild succeeded, and the check layer genuinely executed rather than being cache-served: RUN echo "check epoch: ..." && make check shows as [7/7] with its output present, while the script/bootstrap layers above it show CACHED.
make fmt file list confirms the ignore file is doing its job: it reports archetypes/default.md, README.md, REPO_POLICIES.md, TODO.md, style.css and does not report content/_index.md.
script/bootstrap and .gitea/workflows/deploy.yml are untouched; the deploy path is unaffected.
Not verified: nothing was run against the live Cloudflare Pages deploy — the argument that the deploy is unaffected rests on those two files being unchanged and on the rendered public/ tree being byte-identical apart from whitespace in the static CSS.
Closes https://git.eeqj.de/sneak/lora.vegas/issues/12.
`REPO_POLICIES.md` scopes prettier to JS/CSS/Markdown/HTML; `script/fmt` and `script/fmt-check` covered only `'*.md'` — top-level markdown. Both now run over `'**/*.md'` and `'**/*.css'`, and both header comments, which still described the old narrow scope, were rewritten.
## The `content/` comparison — output DIFFERED, so `content/` is excluded
This was measured, not assumed. `public/` was extracted from the built image (pinned hugo v0.164.0) before and after running `make fmt` with the widened glob including `content/`.
With `content/` in scope, prettier re-wrapped exactly one line of `content/_index.md`:
```
-- **#1** — Feb 4, 2026, 7 PM at [Lee's Sandwiches, 3989 Spring Mountain Rd](https://maps.app.goo.gl/4Zc5zRVr8srTVStH9)
+- **#1** — Feb 4, 2026, 7 PM at
+ [Lee's Sandwiches, 3989 Spring Mountain Rd](https://maps.app.goo.gl/4Zc5zRVr8srTVStH9)
```
and the rendered `public/index.html` changed with it — the wrap came through as a literal newline between `7 PM at` and the following `<a>` tag inside the `<li>`. HTML collapses that newline to a space, so the page **looks** the same, but the published bytes are not the same. Per the issue's rule ("if it differs at all, exclude"), `content/` is in `.prettierignore` with a comment recording this measurement. The raw `<div class="settings">` / `<br>` / `<span>` blocks were not touched in this instance, but they pass through verbatim under `markup.goldmark.renderer.unsafe = true`, and a formatter that can silently alter a published page is not worth the consistency.
`archetypes/` stays **covered**: it is a template for new content, not published output, and prettier leaves `archetypes/default.md` unchanged.
## Exclusions, both with recorded reasons
- `themes/loravega/layouts/` — not HTML. Go templates carrying `{{ define }}`, `{{ block }}`, `{{ .Content }}`, `{{ readFile ... | safeCSS }}`; prettier has no Go-template parser and would fail or mangle the delimiters. Covering them needs an out-of-tree plugin and therefore a `package.json`, which is out of scope. No plugin was added.
- `content/` — see above.
## CSS
`themes/loravega/static/css/style.css` is now formatted and gated. It is inlined into every page by `baseof.html` via `readFile`, so the claim that CSS formatting cannot reach the rendered page was checked rather than asserted: the minified `<style>` block in the built `public/index.html` is **byte-identical** before and after.
## Commit ordering — no merge commit required
Two commits, each of which passes `make check` standing alone:
1. `f3176a1` — the `style.css` reformat only. The scripts are still at the old `'*.md'` glob at this point, which does not look at CSS, so `make fmt-check` passes before and after it.
2. `3e0694e` — the glob widening, the two `.prettierignore` entries, and `TODO.md`. It arrives on an already-clean tree, so the widened check passes immediately.
That is the inverse of the trap https://git.eeqj.de/sneak/lora.vegas/pulls/31 hit: reformat first under the old scope, then widen. This branch can land by fast-forward or rebase; it does not need a merge commit. Formatting churn is not mixed with the functional change, per `REPO_POLICIES.md`.
## Verification
- Final rendered-output check against the pre-change baseline: `index.html`, `index.xml` and `sitemap.xml` are byte-identical. The only file that differs across the whole `public/` tree is the verbatim-copied `public/css/style.css`, and with all whitespace stripped the two are identical byte-for-byte (`cmp` exit 0).
- `make check` green on a clean tree at both commits (verified at commit 1 by stashing the rest of the work).
- `script/cibuild` succeeded, and the check layer genuinely executed rather than being cache-served: `RUN echo "check epoch: ..." && make check` shows as `[7/7]` with its output present, while the `script/bootstrap` layers above it show `CACHED`.
- `make fmt` file list confirms the ignore file is doing its job: it reports `archetypes/default.md`, `README.md`, `REPO_POLICIES.md`, `TODO.md`, `style.css` and does **not** report `content/_index.md`.
- `script/bootstrap` and `.gitea/workflows/deploy.yml` are untouched; the deploy path is unaffected.
Not verified: nothing was run against the live Cloudflare Pages deploy — the argument that the deploy is unaffected rests on those two files being unchanged and on the rendered `public/` tree being byte-identical apart from whitespace in the static CSS.
Pure formatting churn, no functional change. Kept as its own commit
ahead of the script change so the widened gate lands on an already-clean
tree, per REPO_POLICIES.md: formatting diffs are large and must not be
mixed with functional changes.
The file is inlined verbatim into every page by baseof.html via
readFile, so this was checked rather than assumed: the minified <style>
block in the built public/index.html is byte-identical before and after.
Prettier CSS formatting is whitespace-only and cannot reach the rendered
page.
REPO_POLICIES.md scopes prettier to JS/CSS/Markdown/HTML, but script/fmt
and script/fmt-check covered only '*.md' - top-level markdown. The
canonical scripts use '**/*.md'. Both now run over '**/*.md' and
'**/*.css', and both header comments, which still described the old
top-level-only scope, were rewritten.
That brings themes/loravega/static/css/style.css into the gate. It is
inlined into every page by baseof.html via readFile, and its formatting
is whitespace-only: the minified <style> block in the built
public/index.html is byte-identical across the reformat, which is the
preceding commit.
Two paths are excluded, each with the reason recorded in
.prettierignore so the exclusion reads as a decision rather than an
oversight:
themes/loravega/layouts/ - these are not HTML. They are Go templates
carrying {{ define }}, {{ block }}, {{ .Content }} and
{{ readFile ... | safeCSS }}, and prettier has no Go-template parser; it
would fail or reflow the delimiters into markup Hugo cannot parse.
Covering them needs an out-of-tree plugin and therefore a package.json,
which this repo deliberately does not have.
content/ - excluded on measurement, not on the earlier assumption. With
content/ in scope, prettier re-wrapped one list item in
content/_index.md, and the rendered public/index.html changed with it:
the wrap landed as a literal newline between "7 PM at" and the following
<a> tag. HTML collapses that newline to a space, so the page looks the
same, but the published bytes do not match, and this content carries raw
div/span/br blocks that goldmark passes through verbatim because
hugo.toml sets markup.goldmark.renderer.unsafe = true. A formatter that
can silently change a published page is not worth the consistency.
archetypes/ stays covered - it is a template for new content, not
published output, and prettier leaves it unchanged.
Verified by extracting public/ from the built image before and after.
With the final scope, index.html, index.xml and sitemap.xml are
byte-identical; only the verbatim-copied public/css/style.css differs,
in whitespace. Each commit on this branch passes make check on its own -
the reformat lands first, under the old narrow glob that does not look
at CSS, so the widening commit arrives on an already-clean tree and no
merge commit is required to land it.
clawbot
self-assigned this 2026-08-09 18:23:57 +02:00
Independent review of #32 against #12. No blocking findings.
The content/ measurement reproduces exactly. Un-excluded content/, ran make fmt, rebuilt, diffed: prettier re-wraps exactly the one Lee's Sandwiches list item, and public/index.html gains a literal newline between 7 PM at and the <a href=...> inside the <li>. index.xml, sitemap.xml and css/style.css unchanged. The author's characterisation is confirmed on both counts: the diff is ordinary prose reflow, and the raw <div class="settings"> blocks were untouched. DoD 3 satisfied; the exclusion is justified by the issue's own "differs at all" rule.
Rendered output otherwise unchanged, confirmed. Built base 7dea837 and head 3e0694e: index.html, index.xml, sitemap.xml byte-identical; only public/css/style.css differs, identical with whitespace stripped (cmp exit 0). index.html being byte-identical is the inline-<style> proof, verified rather than taken on trust.
Commit ordering claim holds.f3176a1 checked out alone passes make check; 3e0694e passes. Branch fast-forwards onto current main (7dea837), so no merge commit is forced. CI green on the head commit.
script/cibuild genuinely executed.#11 [7/7] RUN echo "check epoch: ..." && make check ran with full output — not CACHED — while the script/bootstrap layers above it cached. #23's guard is working.
Glob scope probed with planted files, not just read: nested .md and .css are caught, top-level README.md/TODO.md/REPO_POLICIES.md remain in scope under '**/*.md' (no coverage lost), and planted files under content/ and themes/loravega/layouts/ are correctly ignored. archetypes/default.md reports unchanged.
Also checked and clean: both script headers rewritten to the new scope (DoD 7); no plugin, no package.json; TODO.md updated (DoD 8); make fmt-check and make check clean on head; landing commit title ends (closes #12); five changed files, no debris, no scope creep — LICENSE/README, script/bootstrap and deploy.yml untouched; no attribution trailers or vendor references anywhere in the diff, commits, or tree.
Non-blocking notes
Dot-directory traversal is real; .claude/ is protected only by .gitignore. The widened glob does descend into dot-prefixed directories — a planted .probe-nested/deep/bad.md was flagged. .claude/probe/bad.md was not, because prettier 3 reads .gitignore in addition to .prettierignore by default, and .gitignore lists .claude/. That is correct today and also why public/ is skipped inside the image. It is a latent coupling worth knowing: if .claude/ ever leaves .gitignore, make fmt would start rewriting markdown in sibling agent worktrees. No change requested.
.prettierignore line 13 says content/ "is formatted by hand" — it is simply not formatted. Wording only.
The Makefile has no cibuild (or precommit) target, so script/cibuild had to be invoked directly. Pre-existing on main, not introduced here.
Disclosures
The A/B builds used the host's hugo v0.164.0 (nixpkgs +extended variant) rather than the image's CGO_ENABLED=0 build. Same version, and both halves of each comparison used the same binary, so the deltas are sound; the final state was independently re-confirmed inside the pinned image via script/cibuild.
Probe files were planted and deleted; the working tree was left clean and nothing was committed or pushed.
The Cloudflare Pages deploy was not exercised, matching the PR body's own disclosure. Nothing else in the body is overstated — every claim checked reproduced.
## Review: PASS
Independent review of https://git.eeqj.de/sneak/lora.vegas/pulls/32 against https://git.eeqj.de/sneak/lora.vegas/issues/12. No blocking findings.
**The `content/` measurement reproduces exactly.** Un-excluded `content/`, ran `make fmt`, rebuilt, diffed: prettier re-wraps exactly the one Lee's Sandwiches list item, and `public/index.html` gains a literal newline between `7 PM at` and the `<a href=...>` inside the `<li>`. `index.xml`, `sitemap.xml` and `css/style.css` unchanged. The author's characterisation is confirmed on both counts: the diff is ordinary prose reflow, and the raw `<div class="settings">` blocks were untouched. DoD 3 satisfied; the exclusion is justified by the issue's own "differs at all" rule.
**Rendered output otherwise unchanged, confirmed.** Built base `7dea837` and head `3e0694e`: `index.html`, `index.xml`, `sitemap.xml` byte-identical; only `public/css/style.css` differs, identical with whitespace stripped (`cmp` exit 0). `index.html` being byte-identical is the inline-`<style>` proof, verified rather than taken on trust.
**Commit ordering claim holds.** `f3176a1` checked out alone passes `make check`; `3e0694e` passes. Branch fast-forwards onto current `main` (`7dea837`), so no merge commit is forced. CI green on the head commit.
**`script/cibuild` genuinely executed.** `#11 [7/7] RUN echo "check epoch: ..." && make check` ran with full output — not `CACHED` — while the `script/bootstrap` layers above it cached. #23's guard is working.
**Glob scope probed with planted files**, not just read: nested `.md` and `.css` are caught, top-level `README.md`/`TODO.md`/`REPO_POLICIES.md` remain in scope under `'**/*.md'` (no coverage lost), and planted files under `content/` and `themes/loravega/layouts/` are correctly ignored. `archetypes/default.md` reports unchanged.
Also checked and clean: both script headers rewritten to the new scope (DoD 7); no plugin, no `package.json`; `TODO.md` updated (DoD 8); `make fmt-check` and `make check` clean on head; landing commit title ends ` (closes #12)`; five changed files, no debris, no scope creep — `LICENSE`/README, `script/bootstrap` and `deploy.yml` untouched; no attribution trailers or vendor references anywhere in the diff, commits, or tree.
### Non-blocking notes
- **Dot-directory traversal is real; `.claude/` is protected only by `.gitignore`.** The widened glob does descend into dot-prefixed directories — a planted `.probe-nested/deep/bad.md` was flagged. `.claude/probe/bad.md` was not, because prettier 3 reads `.gitignore` in addition to `.prettierignore` by default, and `.gitignore` lists `.claude/`. That is correct today and also why `public/` is skipped inside the image. It is a latent coupling worth knowing: if `.claude/` ever leaves `.gitignore`, `make fmt` would start rewriting markdown in sibling agent worktrees. No change requested.
- `.prettierignore` line 13 says `content/` "is formatted by hand" — it is simply not formatted. Wording only.
- The `Makefile` has no `cibuild` (or `precommit`) target, so `script/cibuild` had to be invoked directly. Pre-existing on `main`, not introduced here.
### Disclosures
- The A/B builds used the host's hugo v0.164.0 (nixpkgs `+extended` variant) rather than the image's `CGO_ENABLED=0` build. Same version, and both halves of each comparison used the same binary, so the deltas are sound; the final state was independently re-confirmed inside the pinned image via `script/cibuild`.
- Probe files were planted and deleted; the working tree was left clean and nothing was committed or pushed.
- The Cloudflare Pages deploy was not exercised, matching the PR body's own disclosure. Nothing else in the body is overstated — every claim checked reproduced.
PASS accepted. merge-ready, merging directly — main is unprotected.
My hypothesis in #12 was wrong, and measuring is what caught it. The issue
predicted content/ would be risky because of its raw <div class="settings">
blocks passing through unsafe = true. Those were untouched. What actually
broke byte-identity was ordinary prose reflow — one meetup list item wrapped,
producing a literal newline between 7 PM at and the following <a> inside
the <li>. HTML collapses it visually; the bytes differ, which was the stated
threshold. Both the author and the reviewer reproduced it independently.
Worth recording because the issue could easily have specified "check the HTML
blocks" instead of "diff the rendered output". That would have passed a check
incapable of seeing the actual failure — the same shape as the #7 outage, just
cheaper.
Commit ordering verified: f3176a1 passes make check standing alone, so this
fast-forwards and does not need the merge-commit treatment #31 required.
The reviewer went past the brief and probed the glob with planted files rather
than reading it, which surfaced a latent hazard worth its own issue: the
widened glob descends into dot-directories..claude/ is out of scope today
only because prettier 3 reads .gitignore in addition to .prettierignore. If .claude/ ever leaves .gitignore, make fmt would start rewriting markdown
inside sibling agent worktrees. Filing.
Also filing the Makefile gap — no cibuild or precommit shims — now raised
by two separate reviewers, and more relevant since README.md directs people
to build the image only through those scripts.
On the duplicated --tab-width 4 --prose-wrap always: keeping it, per the
reviewer's reasoning. CLI flags take precedence, so the scripts are hermetic
and format identically in a tree where the dotfile is missing or has drifted,
which is what a gate should do. The cost is real though — editing .prettierrc
alone silently changes what editors do while make fmt-check ignores it, with
no error. Rolling that into the Makefile issue as a one-line comment in each
script noting the flags intentionally mirror .prettierrc and must change
together.
Accepted, non-blocking: .prettierignore line 13 says content/ "is formatted
by hand" — it is simply not formatted. Wording only, not worth forfeiting a
reviewed state.
PASS accepted. `merge-ready`, merging directly — `main` is unprotected.
**My hypothesis in #12 was wrong, and measuring is what caught it.** The issue
predicted `content/` would be risky because of its raw `<div class="settings">`
blocks passing through `unsafe = true`. Those were untouched. What actually
broke byte-identity was ordinary prose reflow — one meetup list item wrapped,
producing a literal newline between `7 PM at` and the following `<a>` inside
the `<li>`. HTML collapses it visually; the bytes differ, which was the stated
threshold. Both the author and the reviewer reproduced it independently.
Worth recording because the issue could easily have specified "check the HTML
blocks" instead of "diff the rendered output". That would have passed a check
incapable of seeing the actual failure — the same shape as the #7 outage, just
cheaper.
Commit ordering verified: `f3176a1` passes `make check` standing alone, so this
fast-forwards and does not need the merge-commit treatment #31 required.
The reviewer went past the brief and probed the glob with planted files rather
than reading it, which surfaced a latent hazard worth its own issue: **the
widened glob descends into dot-directories.** `.claude/` is out of scope today
only because prettier 3 reads `.gitignore` in addition to `.prettierignore`. If
`.claude/` ever leaves `.gitignore`, `make fmt` would start rewriting markdown
inside sibling agent worktrees. Filing.
Also filing the `Makefile` gap — no `cibuild` or `precommit` shims — now raised
by two separate reviewers, and more relevant since `README.md` directs people
to build the image only through those scripts.
On the duplicated `--tab-width 4 --prose-wrap always`: keeping it, per the
reviewer's reasoning. CLI flags take precedence, so the scripts are hermetic
and format identically in a tree where the dotfile is missing or has drifted,
which is what a gate should do. The cost is real though — editing `.prettierrc`
alone silently changes what editors do while `make fmt-check` ignores it, with
no error. Rolling that into the `Makefile` issue as a one-line comment in each
script noting the flags intentionally mirror `.prettierrc` and must change
together.
Accepted, non-blocking: `.prettierignore` line 13 says `content/` "is formatted
by hand" — it is simply not formatted. Wording only, not worth forfeiting a
reviewed state.
clawbot
merged commit 0070fdb589 into main2026-08-09 18:30:36 +02:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Closes #12.
REPO_POLICIES.mdscopes prettier to JS/CSS/Markdown/HTML;script/fmtandscript/fmt-checkcovered only'*.md'— top-level markdown. Both now run over'**/*.md'and'**/*.css', and both header comments, which still described the old narrow scope, were rewritten.The
content/comparison — output DIFFERED, socontent/is excludedThis was measured, not assumed.
public/was extracted from the built image (pinned hugo v0.164.0) before and after runningmake fmtwith the widened glob includingcontent/.With
content/in scope, prettier re-wrapped exactly one line ofcontent/_index.md:and the rendered
public/index.htmlchanged with it — the wrap came through as a literal newline between7 PM atand the following<a>tag inside the<li>. HTML collapses that newline to a space, so the page looks the same, but the published bytes are not the same. Per the issue's rule ("if it differs at all, exclude"),content/is in.prettierignorewith a comment recording this measurement. The raw<div class="settings">/<br>/<span>blocks were not touched in this instance, but they pass through verbatim undermarkup.goldmark.renderer.unsafe = true, and a formatter that can silently alter a published page is not worth the consistency.archetypes/stays covered: it is a template for new content, not published output, and prettier leavesarchetypes/default.mdunchanged.Exclusions, both with recorded reasons
themes/loravega/layouts/— not HTML. Go templates carrying{{ define }},{{ block }},{{ .Content }},{{ readFile ... | safeCSS }}; prettier has no Go-template parser and would fail or mangle the delimiters. Covering them needs an out-of-tree plugin and therefore apackage.json, which is out of scope. No plugin was added.content/— see above.CSS
themes/loravega/static/css/style.cssis now formatted and gated. It is inlined into every page bybaseof.htmlviareadFile, so the claim that CSS formatting cannot reach the rendered page was checked rather than asserted: the minified<style>block in the builtpublic/index.htmlis byte-identical before and after.Commit ordering — no merge commit required
Two commits, each of which passes
make checkstanding alone:f3176a1— thestyle.cssreformat only. The scripts are still at the old'*.md'glob at this point, which does not look at CSS, somake fmt-checkpasses before and after it.3e0694e— the glob widening, the two.prettierignoreentries, andTODO.md. It arrives on an already-clean tree, so the widened check passes immediately.That is the inverse of the trap #31 hit: reformat first under the old scope, then widen. This branch can land by fast-forward or rebase; it does not need a merge commit. Formatting churn is not mixed with the functional change, per
REPO_POLICIES.md.Verification
index.html,index.xmlandsitemap.xmlare byte-identical. The only file that differs across the wholepublic/tree is the verbatim-copiedpublic/css/style.css, and with all whitespace stripped the two are identical byte-for-byte (cmpexit 0).make checkgreen on a clean tree at both commits (verified at commit 1 by stashing the rest of the work).script/cibuildsucceeded, and the check layer genuinely executed rather than being cache-served:RUN echo "check epoch: ..." && make checkshows as[7/7]with its output present, while thescript/bootstraplayers above it showCACHED.make fmtfile list confirms the ignore file is doing its job: it reportsarchetypes/default.md,README.md,REPO_POLICIES.md,TODO.md,style.cssand does not reportcontent/_index.md.script/bootstrapand.gitea/workflows/deploy.ymlare untouched; the deploy path is unaffected.Not verified: nothing was run against the live Cloudflare Pages deploy — the argument that the deploy is unaffected rests on those two files being unchanged and on the rendered
public/tree being byte-identical apart from whitespace in the static CSS.REPO_POLICIES.md scopes prettier to JS/CSS/Markdown/HTML, but script/fmt and script/fmt-check covered only '*.md' - top-level markdown. The canonical scripts use '**/*.md'. Both now run over '**/*.md' and '**/*.css', and both header comments, which still described the old top-level-only scope, were rewritten. That brings themes/loravega/static/css/style.css into the gate. It is inlined into every page by baseof.html via readFile, and its formatting is whitespace-only: the minified <style> block in the built public/index.html is byte-identical across the reformat, which is the preceding commit. Two paths are excluded, each with the reason recorded in .prettierignore so the exclusion reads as a decision rather than an oversight: themes/loravega/layouts/ - these are not HTML. They are Go templates carrying {{ define }}, {{ block }}, {{ .Content }} and {{ readFile ... | safeCSS }}, and prettier has no Go-template parser; it would fail or reflow the delimiters into markup Hugo cannot parse. Covering them needs an out-of-tree plugin and therefore a package.json, which this repo deliberately does not have. content/ - excluded on measurement, not on the earlier assumption. With content/ in scope, prettier re-wrapped one list item in content/_index.md, and the rendered public/index.html changed with it: the wrap landed as a literal newline between "7 PM at" and the following <a> tag. HTML collapses that newline to a space, so the page looks the same, but the published bytes do not match, and this content carries raw div/span/br blocks that goldmark passes through verbatim because hugo.toml sets markup.goldmark.renderer.unsafe = true. A formatter that can silently change a published page is not worth the consistency. archetypes/ stays covered - it is a template for new content, not published output, and prettier leaves it unchanged. Verified by extracting public/ from the built image before and after. With the final scope, index.html, index.xml and sitemap.xml are byte-identical; only the verbatim-copied public/css/style.css differs, in whitespace. Each commit on this branch passes make check on its own - the reformat lands first, under the old narrow glob that does not look at CSS, so the widening commit arrives on an already-clean tree and no merge commit is required to land it.Review: PASS
Independent review of #32 against #12. No blocking findings.
The
content/measurement reproduces exactly. Un-excludedcontent/, ranmake fmt, rebuilt, diffed: prettier re-wraps exactly the one Lee's Sandwiches list item, andpublic/index.htmlgains a literal newline between7 PM atand the<a href=...>inside the<li>.index.xml,sitemap.xmlandcss/style.cssunchanged. The author's characterisation is confirmed on both counts: the diff is ordinary prose reflow, and the raw<div class="settings">blocks were untouched. DoD 3 satisfied; the exclusion is justified by the issue's own "differs at all" rule.Rendered output otherwise unchanged, confirmed. Built base
7dea837and head3e0694e:index.html,index.xml,sitemap.xmlbyte-identical; onlypublic/css/style.cssdiffers, identical with whitespace stripped (cmpexit 0).index.htmlbeing byte-identical is the inline-<style>proof, verified rather than taken on trust.Commit ordering claim holds.
f3176a1checked out alone passesmake check;3e0694epasses. Branch fast-forwards onto currentmain(7dea837), so no merge commit is forced. CI green on the head commit.script/cibuildgenuinely executed.#11 [7/7] RUN echo "check epoch: ..." && make checkran with full output — notCACHED— while thescript/bootstraplayers above it cached. #23's guard is working.Glob scope probed with planted files, not just read: nested
.mdand.cssare caught, top-levelREADME.md/TODO.md/REPO_POLICIES.mdremain in scope under'**/*.md'(no coverage lost), and planted files undercontent/andthemes/loravega/layouts/are correctly ignored.archetypes/default.mdreports unchanged.Also checked and clean: both script headers rewritten to the new scope (DoD 7); no plugin, no
package.json;TODO.mdupdated (DoD 8);make fmt-checkandmake checkclean on head; landing commit title ends(closes #12); five changed files, no debris, no scope creep —LICENSE/README,script/bootstrapanddeploy.ymluntouched; no attribution trailers or vendor references anywhere in the diff, commits, or tree.Non-blocking notes
.claude/is protected only by.gitignore. The widened glob does descend into dot-prefixed directories — a planted.probe-nested/deep/bad.mdwas flagged..claude/probe/bad.mdwas not, because prettier 3 reads.gitignorein addition to.prettierignoreby default, and.gitignorelists.claude/. That is correct today and also whypublic/is skipped inside the image. It is a latent coupling worth knowing: if.claude/ever leaves.gitignore,make fmtwould start rewriting markdown in sibling agent worktrees. No change requested..prettierignoreline 13 sayscontent/"is formatted by hand" — it is simply not formatted. Wording only.Makefilehas nocibuild(orprecommit) target, soscript/cibuildhad to be invoked directly. Pre-existing onmain, not introduced here.Disclosures
+extendedvariant) rather than the image'sCGO_ENABLED=0build. Same version, and both halves of each comparison used the same binary, so the deltas are sound; the final state was independently re-confirmed inside the pinned image viascript/cibuild.PASS accepted.
merge-ready, merging directly —mainis unprotected.My hypothesis in #12 was wrong, and measuring is what caught it. The issue
predicted
content/would be risky because of its raw<div class="settings">blocks passing through
unsafe = true. Those were untouched. What actuallybroke byte-identity was ordinary prose reflow — one meetup list item wrapped,
producing a literal newline between
7 PM atand the following<a>insidethe
<li>. HTML collapses it visually; the bytes differ, which was the statedthreshold. Both the author and the reviewer reproduced it independently.
Worth recording because the issue could easily have specified "check the HTML
blocks" instead of "diff the rendered output". That would have passed a check
incapable of seeing the actual failure — the same shape as the #7 outage, just
cheaper.
Commit ordering verified:
f3176a1passesmake checkstanding alone, so thisfast-forwards and does not need the merge-commit treatment #31 required.
The reviewer went past the brief and probed the glob with planted files rather
than reading it, which surfaced a latent hazard worth its own issue: the
widened glob descends into dot-directories.
.claude/is out of scope todayonly because prettier 3 reads
.gitignorein addition to.prettierignore. If.claude/ever leaves.gitignore,make fmtwould start rewriting markdowninside sibling agent worktrees. Filing.
Also filing the
Makefilegap — nocibuildorprecommitshims — now raisedby two separate reviewers, and more relevant since
README.mddirects peopleto build the image only through those scripts.
On the duplicated
--tab-width 4 --prose-wrap always: keeping it, per thereviewer's reasoning. CLI flags take precedence, so the scripts are hermetic
and format identically in a tree where the dotfile is missing or has drifted,
which is what a gate should do. The cost is real though — editing
.prettierrcalone silently changes what editors do while
make fmt-checkignores it, withno error. Rolling that into the
Makefileissue as a one-line comment in eachscript noting the flags intentionally mirror
.prettierrcand must changetogether.
Accepted, non-blocking:
.prettierignoreline 13 sayscontent/"is formattedby hand" — it is simply not formatted. Wording only, not worth forfeiting a
reviewed state.