Prettier scope depends on .gitignore to stay out of dot-directories; make the exclusion explicit #33

Open
opened 2026-08-09 18:30:53 +02:00 by clawbot · 1 comment
Collaborator

Problem

Since #12, script/fmt and script/fmt-check use '**/*.md' and
'**/*.css'. That glob descends into dot-directories — verified during
review of PR #32 by planting .probe-nested/deep/bad.md, which prettier
flagged.

.claude/ is out of scope today only as a side effect: prettier 3 reads
.gitignore in addition to .prettierignore, and .claude/ is in
.gitignore (added by #8). Nothing in .prettierignore excludes it.

So the protection is real but indirect. If .claude/ is ever removed from
.gitignore — or if a future prettier release changes that default, or a
--no-ignore-path-style flag is added — make fmt would begin rewriting
markdown inside sibling agent worktrees
under .claude/worktrees/. That is
writing to other checkouts of this repo from a formatting command, which is
both surprising and hard to attribute when it happens.

The same indirection is what currently keeps public/ out of scope inside the
image.

Fix

Add .claude/ to .prettierignore explicitly, so the exclusion does not
depend on .gitignore contents or on prettier's default ignore-file
behaviour. One line plus a comment recording why.

While in there, consider whether any other dot-directory should be named
explicitly rather than inherited.

Definition of done

  1. .prettierignore excludes .claude/ directly, with a comment stating that
    it must not depend on .gitignore.
  2. Verified by planting a markdown file at .claude/probe/x.md and confirming
    make fmt leaves it untouched with .claude/ temporarily removed from
    .gitignore
    — that is the condition being defended against. Restore
    .gitignore afterwards and delete the probe file.
  3. make fmt is a no-op on a clean tree; make check passes.
  4. TODO.md updated.

Also in scope — the duplicated prettier settings

.prettierrc sets tabWidth: 4 and proseWrap: always, and both scripts also
pass --tab-width 4 --prose-wrap always. This duplication is deliberate and
is being kept
: CLI flags take precedence, so the scripts format identically
in a tree where the dotfile is missing or has drifted, which is what a gate
should do.

The hazard is that editing .prettierrc alone silently changes what editors do
while make fmt-check ignores the change, with no error — the gate and the
editors disagree and nothing says so.

Add a one-line comment to each of script/fmt and script/fmt-check stating
that the flags intentionally mirror .prettierrc and that both must be changed
together. Do not remove the flags; dropping them would make the scripts
silently misformat in any tree missing the dotfile.

Out of scope

  • Changing which paths are formatted (#12 settled that; content/ is excluded
    by measurement, Go templates because prettier cannot parse them).
  • Any prettier version or configuration change beyond the comments above.
## Problem Since #12, `script/fmt` and `script/fmt-check` use `'**/*.md'` and `'**/*.css'`. That glob **descends into dot-directories** — verified during review of PR #32 by planting `.probe-nested/deep/bad.md`, which prettier flagged. `.claude/` is out of scope today only as a side effect: prettier 3 reads `.gitignore` in addition to `.prettierignore`, and `.claude/` is in `.gitignore` (added by #8). Nothing in `.prettierignore` excludes it. So the protection is real but indirect. If `.claude/` is ever removed from `.gitignore` — or if a future prettier release changes that default, or a `--no-ignore-path`-style flag is added — `make fmt` would begin **rewriting markdown inside sibling agent worktrees** under `.claude/worktrees/`. That is writing to other checkouts of this repo from a formatting command, which is both surprising and hard to attribute when it happens. The same indirection is what currently keeps `public/` out of scope inside the image. ## Fix Add `.claude/` to `.prettierignore` explicitly, so the exclusion does not depend on `.gitignore` contents or on prettier's default ignore-file behaviour. One line plus a comment recording why. While in there, consider whether any other dot-directory should be named explicitly rather than inherited. ## Definition of done 1. `.prettierignore` excludes `.claude/` directly, with a comment stating that it must not depend on `.gitignore`. 2. Verified by planting a markdown file at `.claude/probe/x.md` and confirming `make fmt` leaves it untouched **with `.claude/` temporarily removed from `.gitignore`** — that is the condition being defended against. Restore `.gitignore` afterwards and delete the probe file. 3. `make fmt` is a no-op on a clean tree; `make check` passes. 4. `TODO.md` updated. ## Also in scope — the duplicated prettier settings `.prettierrc` sets `tabWidth: 4` and `proseWrap: always`, and both scripts also pass `--tab-width 4 --prose-wrap always`. This duplication is **deliberate and is being kept**: CLI flags take precedence, so the scripts format identically in a tree where the dotfile is missing or has drifted, which is what a gate should do. The hazard is that editing `.prettierrc` alone silently changes what editors do while `make fmt-check` ignores the change, with no error — the gate and the editors disagree and nothing says so. Add a one-line comment to each of `script/fmt` and `script/fmt-check` stating that the flags intentionally mirror `.prettierrc` and that both must be changed together. Do **not** remove the flags; dropping them would make the scripts silently misformat in any tree missing the dotfile. ## Out of scope - Changing which paths are formatted (#12 settled that; `content/` is excluded by measurement, Go templates because prettier cannot parse them). - Any prettier version or configuration change beyond the comments above.
Author
Collaborator

One interaction to settle before this is implemented, because this issue's fix adds a vendor tooling directory name to .prettierignore while #43 is about removing that name from this repo's prose.

They do not conflict. The distinction ruled there applies here: an ignore-file path is load-bearing — it must match a real directory on disk or it does nothing — so it is functional configuration, not documentation, and it stays. Prose about it is what gets scrubbed.

So: add the path entry as this issue describes. Write the accompanying comment in terms of what is being excluded and why (agent working directories, i.e. entire sibling checkouts of this repo) rather than naming the product, and the two issues stay consistent.

Everything else in the definition of done stands. Note the negative control in item 2 is the whole point of the change and is not optional: the exclusion must be shown to hold with the .gitignore entry temporarily removed, since inheriting it from .gitignore is exactly the dependency being eliminated.

One interaction to settle before this is implemented, because this issue's fix adds a vendor tooling directory name to `.prettierignore` while https://git.eeqj.de/sneak/lora.vegas/issues/43 is about removing that name from this repo's prose. They do not conflict. The distinction ruled there applies here: an ignore-file **path** is load-bearing — it must match a real directory on disk or it does nothing — so it is functional configuration, not documentation, and it stays. Prose *about* it is what gets scrubbed. So: add the path entry as this issue describes. Write the accompanying comment in terms of what is being excluded and why (agent working directories, i.e. entire sibling checkouts of this repo) rather than naming the product, and the two issues stay consistent. Everything else in the definition of done stands. Note the negative control in item 2 is the whole point of the change and is not optional: the exclusion must be shown to hold with the `.gitignore` entry temporarily removed, since inheriting it from `.gitignore` is exactly the dependency being eliminated.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: sneak/lora.vegas#33