Add the canonical policy dotfiles: REPO_POLICIES.md, .editorconfig, .prettierrc, .prettierignore, and extend .gitignore #8
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Problem
REPO_POLICIES.mdlists the files every repo must contain at minimum. Thisrepo is missing four of them, and its
.gitignoreis missing the mandatedcontent. All five are verbatim drops of canonical files from the
promptsrepo, so this is one cohesive commit.
Missing:
REPO_POLICIES.mdRequired in the minimum file list. Fetch from
https://git.eeqj.de/sneak/prompts/raw/branch/main/prompts/REPO_POLICIES.md.It must retain its YAML front matter (
title:andlast_modified: YYYY-MM-DD) so it can be kept in sync as policies evolve.Missing:
.editorconfig"All repos should have an
.editorconfigenforcing the project's indentationsettings." Canonical contents:
Missing:
.prettierrcand.prettierignore"Documentation and writing repos (Markdown, HTML, CSS) should also have
.prettierrcand.prettierignore." A Hugo site is exactly that. Canonicalcontents:
.prettierrc:.prettierignore:Note that
script/fmtandscript/fmt-checkalready pass--tab-width 4 --prose-wrap alwayson the command line. Keep those flags — the canonicalscripts duplicate them deliberately so the scripts work standalone when copied
as a template. Adding
.prettierrcmust not change whatmake fmtdoes.Incomplete:
.gitignoreCurrent contents are Hugo outputs only (
/public/,/resources/,.hugo_build.lock). Policy: ".gitignoreshould be comprehensive from thestart: OS files (
.DS_Store), editor files (.swp,*~), language buildartifacts, and
node_modules/", and separately "Never commit secrets..envfiles, credentials, API keys, and private keys must be in
.gitignore. Noexceptions."
Append the canonical block, keeping the existing Hugo lines:
Definition of done
REPO_POLICIES.mdexists at the repo root, is byte-identical to theupstream canonical copy, and
head -5 REPO_POLICIES.mdcontainslast_modified:..editorconfig,.prettierrc,.prettierignoreexist at the repo rootwith exactly the contents quoted above.
.gitignoreretains its three existing Hugo lines and gains the canonicalblock above; it contains the literal patterns
.env,*.key, and*.pem.make fmtproduces no diff after the change (adding.prettierrcmust be ano-op against the flags already passed by
script/fmt). If it does producea diff, commit the reformat as its own separate commit — formatting churn
must not be mixed with functional changes.
make checkpasses andscript/cibuildsucceeds.TODO.mdis updated in the same commit as the work, per the Workflow block.Explicitly out of scope — no Hugo equivalent, do not add
Each of the following is either language-specific or not required by any org
standard. Do not create them:
go.mod,go.sum,.golangci.yml— Go module and Go linter files; there isno Go code here.
package.json,yarn.lock— only required for JS repos.script/fmtgetsprettier via
npx --yes prettier@<pinned>, so there is no dependencymanifest to maintain. Adding one would pull in the whole node/nvm/corepack
pinning apparatus for a single formatter.
pyproject.toml— wrong language.CONTRIBUTING.md,SECURITY.md,.gitattributes,CHANGELOG.md,AGENTS.md, rootCLAUDE.md, renovate/dependabot config, issue/PRtemplates,
CODEOWNERS— none of these appear in any org standard. Theywere checked for explicitly and are not mandated.
.claude/scaffolding — the memory policy states "Repos with no memories yetneed no
.claude/scaffolding." This repo has none.Ref:
REPO_POLICIES.mdminimum file list;EXISTING_REPO_CHECKLIST.md.Additional scope for this issue, found while testing the
script/cibuildcachebehaviour for #23.
git status --porcelainin a clean checkout reports:.claude/is agent tooling scaffolding (it holdsworktrees/among otherthings). It is in neither
.gitignorenor.dockerignore, which has twoconsequences:
git addpicksit up.
REPO_POLICIES.mdforbidsgit add -A/git add .precisely tolimit this class of mistake, but the ignore file is the belt to that
braces.
DockerfiledoesCOPY . .and.dockerignorecurrently lists only.git,public,resources, and.hugo_build.lock. So.claude/— includingworktrees/, which can holdentire additional checkouts of this repo — gets copied into the image. That
inflates the context and the image, slows every build, and in the worst case
copies unrelated in-flight work into a build artifact.
Add
.claude/to both files as part of this issue:.gitignore— alongside the canonical block already specified above..dockerignore— which should also gain the editor/OS patterns for the samereason; there is no value in shipping
.DS_Storeor.idea/into the buildcontext either.
Updated definition-of-done items for this issue:
.gitignorecontains.claude/, andgit status --porcelainis empty in aclean checkout with agent tooling present.
.dockerignorecontains.claude/and the OS/editor patterns. Verify bybuilding and confirming the context size drops (or at minimum that
.claude/is absent from the image —docker run --rm <image> ls -a /srcshould not list it).
Note the ordering interaction with #23: until #23 lands, a
script/cibuildrunmay be served entirely from cache, so a build used to verify item 8 must be run
with the cache defeated or it will prove nothing.
Blocked on #23 — do not land the
.dockerignoreportion of this issuefirst.
Adding
.claude/to.dockerignoreremoves a live source of build-contextchurn.
.claude/worktrees/is created and destroyed constantly by tooling, andthat churn intermittently invalidates
COPY . ., forcing theRUN make checklayer to actually execute. Excluding it makes Docker's cache stickier and more
consistent — correct in itself, but it removes an accidental safety net while
#23's unearned-green hole is still open. The gate would get quietly weaker,
with nothing in the build output to signal the change.
Required sequencing:
make checkcannot be served from cache)..dockerignorechange.the cache behaviour that #23 was validated against.
The rest of this issue —
REPO_POLICIES.md,.editorconfig,.prettierrc,.prettierignore, and the.gitignoreadditions including.claude/— has nosuch dependency and can proceed at any time. If it is convenient to start
this issue before #23 is done, split it: land everything except the
.dockerignoreedit, and leave that for a follow-up commit after #23. Adding.claude/to.gitignoreis unaffected; only the Docker build context mattershere.
For the record, the fleet-wide version of this warning describes repos with
no
.dockerignoreat all being accidentally protected because.gitchurnsin the context. That is not this repo — lora.vegas already excludes
.git,which is why the cache hole reproduces here cleanly. The dependency above is
real but arrives via
.claude/, not.git.Correction to the
.dockerignorework — pattern semantics. This is asecurity point, not a tidiness one.
.dockerignoredoes not use.gitignoresemantics. It matches with Go'sfilepath.Matchrules, extended with**. Two consequences that break thenaive approach:
*does not cross/. So*.keymatchesserver.keyat the contextroot and does not match
certs/server.key.node_modules/excludes only a top-level
node_modules, not a nested one.Another repo on the roster proved this empirically by planting files at depth
and watching
config/.env,certs/server.key, and nestednode_modulesallreach the build context despite patterns that appeared to cover them.
For this repo that matters directly, because the
DockerfiledoesCOPY . .and the whole point of the secrets patterns is that a stray key or
.envmustnever be baked into an image. A
.dockerignorethat silently protects only theroot is worse than an obviously incomplete one, because it reads as complete.
Requirement: every depth-independent pattern in
.dockerignoregets a**/prefix. So**/.env,**/*.key,**/*.pem,**/node_modules,**/.DS_Store,**/.claude, and so on. Patterns that genuinely areroot-anchored —
public,resources— stay unprefixed, deliberately, sincethose are specifically the Hugo output directories at the repo root.
Note this applies only to
.dockerignore..gitignorehas differentsemantics where an unanchored pattern already matches at any depth, so the
canonical
.gitignoreblock quoted in the issue body is correct as written andmust not be given
**/prefixes.Added definition-of-done item:
.dockerignorepatterns by planting throwaway files at least twodirectories deep — e.g.
a/b/.env,a/b/server.key,a/b/node_modules/x— then confirming they are absent from the built image (
docker run --rm <image> find /src -name '.env' -o -name '*.key'returns nothing). Deletethe throwaway files afterwards. Testing only at the repo root does not
exercise the bug and will produce a false pass.
Tracked upstream as
prompts#29.Combined with the earlier ordering note, the
.dockerignoreportion of thisissue now has two constraints: it lands after #23, and it must use
**/prefixes verified at depth. The rest of this issue is unaffected and can
proceed independently.
Implementation plan
Branching from current
main(ccdedc3), which already contains #23 /PR #30, so the ordering
constraint from the second comment is satisfied and the
.dockerignorechangecan land in this same commit rather than a follow-up.
One commit,
... (closes #8):REPO_POLICIES.md—curlthe raw canonical frompromptsverbatim (bytecopy, not a reflow), front matter intact. Note it lands inside
script/fmt-check's*.mdglob, so it must already satisfy--tab-width 4 --prose-wrap always; if it does not, item 4 of the DoD and"byte-identical" collide and I will report that rather than reformat it
silently.
.editorconfig,.prettierrc,.prettierignore— exactly the contentsquoted in the body.
.gitignore— keep the three Hugo lines, append the canonical blockverbatim, plus a
.claude/entry. No**/prefixes here — unanchored.gitignorepatterns already match at any depth..dockerignore— every depth-independent pattern gets**/(
**/.env,**/.env.*,**/*.key,**/*.pem,**/node_modules,**/.DS_Store,**/.claude, editor patterns, ...).publicandresourcesstay unprefixed: they are the root Hugo output dirs byintention.
.gitand.hugo_build.lockkeep their current form.Not touched, per the out-of-scope list:
LICENSE(that is#10, still awaiting an owner
decision — the README License section stays as-is),
go.mod,package.json,yarn.lock,CONTRIBUTING.md,SECURITY.md,.gitattributes,CHANGELOG.md,AGENTS.md, root agent-memory file, renovate/dependabot,.claude/scaffolding.Verification
.dockerignoreproof (DoD 9): planta/b/.env,a/b/server.key,a/b/node_modules/xand a.claude/marker, build, thendocker run --rm <image> find /src -name '.env' -o -name '*.key'and expectempty. Root-only testing does not exercise the bug. Throwaways deleted
after, and I will also confirm the pre-change
.dockerignorefails thissame probe, so the test is shown to have teeth.
consecutive
script/cibuildruns on an unchanged tree, both pasted, bothshowing the two Hugo builds plus the prettier line, with
RUN script/bootstrapstill
CACHEDin the second.make fmtdiff-free,make checkgreen,make dockerstill builds.docker builder prunein any form — shared host. Cache defeat is scopedto
--no-cache-filter/ a throwaway tag.TODO.mdupdated in the same commit.script/bootstrapanddeploy.ymlareuntouched, so the live deploy path is unaffected and no temporary branch
trigger is needed.
I will also reconcile a wording conflict this introduces:
REPO_POLICIES.mdsays
make check"must not modify any files in the repo", whilescript/check's header says "must not modify any tracked files". Both willbe present in the tree; I will call out which is authoritative in the PR rather
than leave them contradicting.
Done in PR #31 (branch
policy-dotfiles), two commits offccdedc3.What was built:
REPO_POLICIES.md(byte-identical canonical copy, frontmatter intact),
.editorconfig,.prettierrc,.prettierignore(canonicalcontents),
.gitignoreextended with the canonical block plus.claude/, and.dockerignorerewritten with**/-prefixed depth-independent patterns.LICENSEand the README License section untouched, per the out-of-scope listand #10.
script/bootstrapand
deploy.ymluntouched, so the live deploy path is unaffected.DoD 9 (depth-planted
.dockerignore): passes, with a counterfactual so thetest is shown to have teeth. Planted
a/b/.env,a/b/server.key,a/b/deep.pem,a/b/node_modules/x,config/.env,certs/server.key,.claude/worktrees/marker.txt. With the canonical patterns left unprefixed,all six depth-planted paths reach
/srcin the image:With the shipped
**/form,docker run --rm lora.vegas find /src -name '.env' -o -name '*.key' -o -name '*.pem' -o -name 'node_modules' -o -name '.claude'returns nothing, and
ls -a /srcdoes not list.claude. The emptiedadirectory shell still appears —
.dockerignoreexcludes matching files, and adirectory left empty is still created in the context — but nothing inside it
survived. Throwaways and probe images deleted; no
docker builder prunewasrun at any point.
Comment 3's step 3 (#23
re-verification): passes against the new, smaller context. Two consecutive
script/cibuildruns on an unchanged tree; run 2 hasCOPY . .CACHEDandRUN script/bootstrapCACHED, yet the check layer still executes — two Hugobuilds and
All matched files use Prettier code style!in both runs. Fulloutput is pasted in the PR. A bare
docker build .still fails on theCHECK_EPOCHguard.Two DoD conflicts surfaced, neither resolved silently:
REPO_POLICIES.mdis not clean under this repo's prettiersettings — prettier@3.4.2 inserts a blank line before a nested list that
follows a paragraph, in five places — so DoD 1 (byte-identical) and DoD 4
(
make fmtdiff-free) cannot both hold. Resolved as DoD 4 anticipates:commit 1 adds the byte-identical copy, commit 2 is the five-blank-line
reformat on its own. Syncing that back upstream is now a Future Step.
REPO_POLICIES.mdsaysmake check"must not modify any files in therepo";
script/check's header says "must not modify any tracked files".make checkwritespublic/and.hugo_build.lock, both gitignored, sogit status --porcelainis empty but files are created.script/check'swording is the accurate one; the policy sentence is unsatisfiable for any
repo whose check builds artifacts. Called out in the PR for a decision
rather than patched locally, since the canonical copy should not diverge.
make fmtis a no-op atHEAD,make checkis green and leaves the treeclean,
make dockerbuilds.TODO.mdupdated in the functional commit.Two defects in the canonical upstream files, found while implementing this.
Recording here because they affect every repo that syncs them and I have no
write access to
prompts. @sneak — these want fixing at source.1.
prompts/prompts/REPO_POLICIES.mdis not prettier-clean. prettier@3.4.2with the shared settings (tab width 4,
proseWrap: always) wants a blank linebefore a nested list following a paragraph, in five places. So any repo that
both commits the canonical file byte-identical and runs prettier over its
own markdown in
make checkhas two requirements that cannot both hold. PR #31handles it by splitting into a byte-identical commit plus a reformat commit,
but every future sync into any repo re-introduces the conflict. Fix: reformat
the file upstream with the shared settings; downstream copies then become
straight byte syncs.
2.
REPO_POLICIES.mdand the canonicalscript/checkcontradict eachother. The policy says
make check"must not modify any files in the repo";script/check's header says "must not modify any tracked files". Thepolicy version is unsatisfiable for any repo whose check builds artifacts —
this one writes
public/and.hugo_build.lock, both gitignored. It alsocannot be used as a literal compliance probe, since it would fail every repo
that builds anything. Fix: change the policy line to "tracked files", matching
script/check.PR #31 treats
script/checkas authoritative locally and deliberately doesnot patch the committed canonical copy — diverging it downstream would
defeat the purpose of committing it. That is the right call, but it leaves this
repo carrying a canonical file that contradicts a canonical script until
upstream is fixed.
Neither blocks PR #31.