Dotfile compliance: add root .editorconfig, harden .gitignore, exclude .git from .dockerignore #15

Open
opened 2026-08-09 03:37:13 +02:00 by clawbot · 2 comments
Collaborator

Problem

Three root-level dotfiles diverge from the org models. Verified on main at fbfe1df by diffing against the prompts repo.

1. No root .editorconfig

REPO_POLICIES.md requires: "All repos should have an .editorconfig enforcing the project's indentation settings", and lists .editorconfig in the minimum file set. The repo has backend/.editorconfig but nothing at the root, so the frontend (src/, index.html, vite.config.js, nginx.conf, script/) is unconstrained.

backend/.editorconfig is already byte-identical to the org model, so the fix is to lift it to the root.

2. .gitignore is missing the secrets and OS/editor sections

Current .gitignore is 4 lines. Diff against the org model shows these entries missing:

# OS
.DS_Store          (present)
Thumbs.db          MISSING

# Editors
*.swp *.swo *~ *.bak .idea/ .vscode/ *.sublime-*    ALL MISSING

# Environment / secrets
.env
.env.*
*.pem
*.key              ALL MISSING

The secrets entries are the serious part. REPO_POLICIES.md: "Never commit secrets. .env files, credentials, API keys, and private keys must be in .gitignore. No exceptions." The backend loads .env via godotenv, so an untracked-but-unignored .env here is a live footgun.

3. .dockerignore does not exclude .git

The org model .dockerignore starts with .git; this repo's does not. Every docker build therefore ships the full git history into the build context.

Note the interaction: Dockerfile.backend currently does COPY .git /repo/.git so that backend/Makefile's git describe works. Adding .git to .dockerignore will break that build. Resolving that coupling is out of scope here — it is handled by the Dockerfile issue. For this commit, either sequence this issue after the Dockerfile rework, or add .git to .dockerignore only once the backend build no longer needs it. Do not silently leave .git in the context and tick the box.

Definition of done

  • A root .editorconfig exists and is byte-identical to backend/.editorconfig (which already matches the org model).
  • backend/.editorconfig is deleted — a single root .editorconfig with root = true covers the whole tree, and a duplicate in a subdirectory is redundant.
  • .gitignore contains, at minimum, the OS, editor, node, and environment/secrets sections from the org model, including .env, .env.*, *.pem, and *.key.
  • .dockerignore excludes .gitor, if the backend build still requires .git, this bullet is explicitly deferred with a comment on this issue explaining why, and the issue stays open until it can be satisfied.
  • No file that is currently tracked becomes ignored as a side effect. Verify with git status --short being clean after the change and git ls-files unchanged except for the intended .editorconfig moves.
  • make check passes at the repo root and in backend/.
  • TODO.md updated in the same commit.
  • Commit title ends with (closes #N).

Implementation requirements

  • Copy the org models verbatim rather than hand-authoring; source them from the local prompts clone or https://git.eeqj.de/sneak/prompts/raw/branch/main/<file>.
  • make targets and script/ entrypoints only.
  • Markdown touched by this change must be formatted with make fmt before committing.
  • No attribution trailers in the commit message.
## Problem Three root-level dotfiles diverge from the org models. Verified on `main` at `fbfe1df` by diffing against the `prompts` repo. ### 1. No root `.editorconfig` `REPO_POLICIES.md` requires: "All repos should have an `.editorconfig` enforcing the project's indentation settings", and lists `.editorconfig` in the minimum file set. The repo has `backend/.editorconfig` but **nothing at the root**, so the frontend (`src/`, `index.html`, `vite.config.js`, `nginx.conf`, `script/`) is unconstrained. `backend/.editorconfig` is already byte-identical to the org model, so the fix is to lift it to the root. ### 2. `.gitignore` is missing the secrets and OS/editor sections Current `.gitignore` is 4 lines. Diff against the org model shows these entries missing: ``` # OS .DS_Store (present) Thumbs.db MISSING # Editors *.swp *.swo *~ *.bak .idea/ .vscode/ *.sublime-* ALL MISSING # Environment / secrets .env .env.* *.pem *.key ALL MISSING ``` The secrets entries are the serious part. `REPO_POLICIES.md`: "Never commit secrets. `.env` files, credentials, API keys, and private keys must be in `.gitignore`. No exceptions." The backend loads `.env` via `godotenv`, so an untracked-but-unignored `.env` here is a live footgun. ### 3. `.dockerignore` does not exclude `.git` The org model `.dockerignore` starts with `.git`; this repo's does not. Every `docker build` therefore ships the full git history into the build context. Note the interaction: `Dockerfile.backend` currently does `COPY .git /repo/.git` so that `backend/Makefile`'s `git describe` works. Adding `.git` to `.dockerignore` will break that build. **Resolving that coupling is out of scope here** — it is handled by the Dockerfile issue. For this commit, either sequence this issue after the Dockerfile rework, or add `.git` to `.dockerignore` only once the backend build no longer needs it. Do not silently leave `.git` in the context and tick the box. ## Definition of done - [ ] A root `.editorconfig` exists and is byte-identical to `backend/.editorconfig` (which already matches the org model). - [ ] `backend/.editorconfig` is deleted — a single root `.editorconfig` with `root = true` covers the whole tree, and a duplicate in a subdirectory is redundant. - [ ] `.gitignore` contains, at minimum, the OS, editor, node, and environment/secrets sections from the org model, including `.env`, `.env.*`, `*.pem`, and `*.key`. - [ ] `.dockerignore` excludes `.git` — **or**, if the backend build still requires `.git`, this bullet is explicitly deferred with a comment on this issue explaining why, and the issue stays open until it can be satisfied. - [ ] No file that is currently tracked becomes ignored as a side effect. Verify with `git status --short` being clean after the change and `git ls-files` unchanged except for the intended `.editorconfig` moves. - [ ] `make check` passes at the repo root and in `backend/`. - [ ] `TODO.md` updated in the same commit. - [ ] Commit title ends with ` (closes #N)`. ## Implementation requirements - Copy the org models verbatim rather than hand-authoring; source them from the local `prompts` clone or `https://git.eeqj.de/sneak/prompts/raw/branch/main/<file>`. - `make` targets and `script/` entrypoints only. - Markdown touched by this change must be formatted with `make fmt` before committing. - No attribution trailers in the commit message.
clawbot added this to the 1.0.0 milestone 2026-08-09 03:37:13 +02:00
Author
Collaborator

Implementation plan

Branching from main at fbfe1df onto chore/dotfile-compliance, working in a
throwaway git worktree.

1. Root .editorconfig (will do)

git mv backend/.editorconfig .editorconfig. I diffed
backend/.editorconfig against /home/user/dev/prompts/.editorconfig — they
are byte-identical, so this is a pure move with no content change. root = true
at the repo root then covers src/, index.html, vite.config.js,
nginx.conf, script/, and backend/ in one file.

2. .gitignore (will do)

Start from the org model verbatim (copied from the local prompts clone, not
hand-authored), then re-append the two repo-specific entries the current file
carries that the model does not: dist/ (Vite output) and *.log. Result:

  • # OS.DS_Store, Thumbs.db
  • # Editors*.swp, *.swo, *~, *.bak, .idea/, .vscode/,
    *.sublime-*
  • # Nodenode_modules/
  • # Environment / secrets.env, .env.*, *.pem, *.key
  • # Build outputdist/
  • # Logs*.log

backend/.gitignore is left alone: its entries are backend-specific paths
(/netwatch-server, *.out, *.test, data/) and are out of scope here.

3. .dockerignore .git exclusion — DEFERRING, explicitly

I am not adding .git to .dockerignore in this PR, and I am saying so rather
than ticking the box. Both images read git metadata at build time on main at
fbfe1df:

  • Dockerfile.backend line 12 is literally COPY .git /repo/.git, because
    backend/Makefile shells out to git describe for the version stamp. A
    .dockerignore entry would make that COPY fail outright — the build errors,
    it does not merely degrade.
  • Dockerfile does COPY . . and then RUN make check, whose test step is the
    production yarn build. vite.config.js lines 5-6 call
    git rev-parse --short HEAD and git rev-parse HEAD at config-eval time, so
    Vite would throw before a single module is transformed.

So the bullet cannot be satisfied here without breaking docker build . and
docker build -f Dockerfile.backend ., and un-coupling the builds from .git
(build-arg version injection instead of in-container git) is owned by the
Dockerfile issue, not this one. Per the definition of done's own escape hatch,
this issue should stay open after the PR merges, carrying only that one
remaining bullet.

Verification

  • Snapshot git ls-files before and after; the only permitted delta is
    backend/.editorconfig -> .editorconfig. This is the specific way to get
    this change wrong, so it gets an explicit before/after diff rather than a
    glance.
  • git status --short clean after the change, confirming no tracked file was
    swallowed by a new pattern (there are no tracked .env/*.pem/*.key/
    .vscode//.idea/ paths today — checked).
  • make check at the repo root and make check in backend/.
  • make fmt over the TODO.md edit before committing.

TODO.md gets one additive line at the top of Completed Steps in the same
commit. I am deliberately not rewriting its Status/Next Step sections: PR #31 is
open and merge-ready and already rewrites exactly those, so touching them would
manufacture a conflict for no benefit.

## Implementation plan Branching from `main` at `fbfe1df` onto `chore/dotfile-compliance`, working in a throwaway git worktree. ### 1. Root `.editorconfig` (will do) `git mv backend/.editorconfig .editorconfig`. I diffed `backend/.editorconfig` against `/home/user/dev/prompts/.editorconfig` — they are byte-identical, so this is a pure move with no content change. `root = true` at the repo root then covers `src/`, `index.html`, `vite.config.js`, `nginx.conf`, `script/`, and `backend/` in one file. ### 2. `.gitignore` (will do) Start from the org model verbatim (copied from the local `prompts` clone, not hand-authored), then re-append the two repo-specific entries the current file carries that the model does not: `dist/` (Vite output) and `*.log`. Result: - `# OS` — `.DS_Store`, `Thumbs.db` - `# Editors` — `*.swp`, `*.swo`, `*~`, `*.bak`, `.idea/`, `.vscode/`, `*.sublime-*` - `# Node` — `node_modules/` - `# Environment / secrets` — `.env`, `.env.*`, `*.pem`, `*.key` - `# Build output` — `dist/` - `# Logs` — `*.log` `backend/.gitignore` is left alone: its entries are backend-specific paths (`/netwatch-server`, `*.out`, `*.test`, `data/`) and are out of scope here. ### 3. `.dockerignore` `.git` exclusion — DEFERRING, explicitly I am not adding `.git` to `.dockerignore` in this PR, and I am saying so rather than ticking the box. Both images read git metadata at build time on `main` at `fbfe1df`: - `Dockerfile.backend` line 12 is literally `COPY .git /repo/.git`, because `backend/Makefile` shells out to `git describe` for the version stamp. A `.dockerignore` entry would make that `COPY` fail outright — the build errors, it does not merely degrade. - `Dockerfile` does `COPY . .` and then `RUN make check`, whose test step is the production `yarn build`. `vite.config.js` lines 5-6 call `git rev-parse --short HEAD` and `git rev-parse HEAD` at config-eval time, so Vite would throw before a single module is transformed. So the bullet cannot be satisfied here without breaking `docker build .` and `docker build -f Dockerfile.backend .`, and un-coupling the builds from `.git` (build-arg version injection instead of in-container `git`) is owned by the Dockerfile issue, not this one. Per the definition of done's own escape hatch, this issue should stay open after the PR merges, carrying only that one remaining bullet. ### Verification - Snapshot `git ls-files` before and after; the only permitted delta is `backend/.editorconfig` -> `.editorconfig`. This is the specific way to get this change wrong, so it gets an explicit before/after diff rather than a glance. - `git status --short` clean after the change, confirming no tracked file was swallowed by a new pattern (there are no tracked `.env`/`*.pem`/`*.key`/ `.vscode/`/`.idea/` paths today — checked). - `make check` at the repo root and `make check` in `backend/`. - `make fmt` over the `TODO.md` edit before committing. `TODO.md` gets one additive line at the top of Completed Steps in the same commit. I am deliberately not rewriting its Status/Next Step sections: PR #31 is open and merge-ready and already rewrites exactly those, so touching them would manufacture a conflict for no benefit.
Author
Collaborator

Deferral notice for the .dockerignore bullet

PR #35 (chore/dotfile-compliance, 4a7bdf8) implements bullets 1 and 2. Bullet
3 — .dockerignore excluding .git — is explicitly deferred, per the escape
hatch in this issue's own definition of done. Stating it plainly rather than
quietly ticking or quietly skipping it:

.dockerignore is unmodified by that PR. Adding .git today breaks both image
builds on main at fbfe1df, and breaks them hard — build failure, not silent
degradation:

  • Dockerfile.backend:12 is literally COPY .git /repo/.git, feeding
    git describe --always --dirty in backend/Makefile. Ignoring .git leaves
    that COPY with no source and the build errors.
  • Dockerfile does COPY . . then RUN make check, whose test step is the
    production vite build. vite.config.js lines 5-6 call
    git rev-parse --short HEAD and git rev-parse HEAD at config-eval time, so
    Vite throws before transforming a single module. Note the frontend never
    COPYs .git deliberately — it inherits it from COPY . ., which is exactly
    why the ignore entry bites there too.

Un-coupling the builds from in-container git metadata is #17's job for the
backend half; the frontend vite.config.js half was not covered by any existing
issue.

One deviation from the DoD, flagged

The DoD says this issue stays open until that bullet is satisfied, but the
commit title is required to end with (closes #15), so merging #35 will
auto-close this. To keep the residual work from evaporating I have filed #36,
which carries the .dockerignore bullet plus the vite.config.js decoupling and
is sequenced after #17. If you would rather keep #15 open as the tracking issue
instead, reopen it and close #36 as a duplicate — the work is identical either
way, this is just about which number carries it.

Other DoD bullets

  • Root .editorconfig exists, cmp-verified byte-identical to the org model.
  • backend/.editorconfig deleted (it was the source of the git mv).
  • .gitignore has the OS, Editors, Node, and Environment/secrets sections
    verbatim from the model, plus this repo's dist/ and *.log.
  • No tracked file became ignored: git ls-files differs only by the
    .editorconfig relocation, git check-ignore over the whole tracked set
    matches nothing, git status --short clean.
  • Root make check and cd backend && make check both pass.
  • TODO.md updated in the same commit; make fmt run beforehand.
## Deferral notice for the `.dockerignore` bullet PR #35 (`chore/dotfile-compliance`, `4a7bdf8`) implements bullets 1 and 2. Bullet 3 — `.dockerignore` excluding `.git` — is **explicitly deferred**, per the escape hatch in this issue's own definition of done. Stating it plainly rather than quietly ticking or quietly skipping it: `.dockerignore` is unmodified by that PR. Adding `.git` today breaks both image builds on `main` at `fbfe1df`, and breaks them hard — build failure, not silent degradation: - `Dockerfile.backend:12` is literally `COPY .git /repo/.git`, feeding `git describe --always --dirty` in `backend/Makefile`. Ignoring `.git` leaves that `COPY` with no source and the build errors. - `Dockerfile` does `COPY . .` then `RUN make check`, whose test step is the production `vite build`. `vite.config.js` lines 5-6 call `git rev-parse --short HEAD` and `git rev-parse HEAD` at config-eval time, so Vite throws before transforming a single module. Note the frontend never `COPY`s `.git` deliberately — it inherits it from `COPY . .`, which is exactly why the ignore entry bites there too. Un-coupling the builds from in-container git metadata is #17's job for the backend half; the frontend `vite.config.js` half was not covered by any existing issue. ### One deviation from the DoD, flagged The DoD says this issue stays open until that bullet is satisfied, but the commit title is required to end with ` (closes #15)`, so merging #35 will auto-close this. To keep the residual work from evaporating I have filed **#36**, which carries the `.dockerignore` bullet plus the `vite.config.js` decoupling and is sequenced after #17. If you would rather keep #15 open as the tracking issue instead, reopen it and close #36 as a duplicate — the work is identical either way, this is just about which number carries it. ### Other DoD bullets - Root `.editorconfig` exists, `cmp`-verified byte-identical to the org model. - `backend/.editorconfig` deleted (it was the source of the `git mv`). - `.gitignore` has the OS, Editors, Node, and Environment/secrets sections verbatim from the model, plus this repo's `dist/` and `*.log`. - No tracked file became ignored: `git ls-files` differs only by the `.editorconfig` relocation, `git check-ignore` over the whole tracked set matches nothing, `git status --short` clean. - Root `make check` and `cd backend && make check` both pass. - `TODO.md` updated in the same commit; `make fmt` run beforehand.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: sneak/netwatch#15