check / check (push) Waiting to run
The canonical REPO_POLICIES.md now says that guidance for coding agents lives in one AGENTS.md at the repository root, never committed under a file or directory named after one agent tool and never split into separate memory files. This retires the in-repo memory rule that older vendored copies still carry. AGENTS.md is added to the list of files allowed in the root, which would otherwise contradict the new rule. Both checklists carry the matching item. Model: opus-5-5
9.5 KiB
9.5 KiB
title, last_modified
| title | last_modified |
|---|---|
| New Repo Checklist | 2026-10-04 |
Use this checklist when creating a new repository from scratch. Follow the steps
in order. Full policies are at
https://git.eeqj.de/sneak/prompts/raw/branch/main/prompts/REPO_POLICIES.md.
Template files can be fetched from:
https://git.eeqj.de/sneak/prompts/raw/branch/main/<path>
1. Initialize
git init- Ask the user for the license (MIT, GPL, or WTFPL)
2. First Commit (README only)
- Create
README.mdwith all required sections:- Description: name, purpose, category, license, author
- Getting Started: copy-pasteable code block
- Rationale: why does this exist?
- Design: how is it structured?
- TODO: initial task list
- License: matches chosen license
- Author: @sneak
git add README.md && git commit
3. Scaffolding (feature branch)
git checkout -b initial-scaffolding
Fetch Template Files
.gitignore— fetch fromhttps://git.eeqj.de/sneak/prompts/raw/branch/main/.gitignore, extend for language-specific artifacts. Extensions are written to.gitignore's own semantics, where an unanchored pattern already matches at every depth: never add a**/prefix here, which is a.dockerignoreform. The canonical file already carries.claude/so agent worktrees cannot be committed by accident..editorconfig— fetch fromhttps://git.eeqj.de/sneak/prompts/raw/branch/main/.editorconfigMakefile— fetch fromhttps://git.eeqj.de/sneak/prompts/raw/branch/main/Makefile, adapt targets for the project's language and tools- For JS/docs repos:
.prettierrcand.prettierignore— fetch fromhttps://git.eeqj.de/sneak/prompts/raw/branch/main/.prettierrcandhttps://git.eeqj.de/sneak/prompts/raw/branch/main/.prettierignore
Create Project Files
LICENSEfile matching the chosen licenseREPO_POLICIES.md— fetch fromhttps://git.eeqj.de/sneak/prompts/raw/branch/main/prompts/REPO_POLICIES.md- Guidance for coding agents, if the repo has any, is one
AGENTS.mdat the root — never a file or directory named after one agent tool, such asCLAUDE.mdor.claude/, and never separate memory files Dockerfileand.dockerignore— fetch.dockerignorefromhttps://git.eeqj.de/sneak/prompts/raw/branch/main/.dockerignore- Extend
.dockerignorewith the repo's own host-built artifacts, giving every depth-independent pattern a**/prefix — but write a repo-root binary anchored,/myappand never**/myapp, which would also matchcmd/myapp/and delete the package directory. Do not transplant.gitignore's patterns:.dockerignoreanchors an unprefixed pattern at the context root, so the copied form leavesconfig/.envin the build context while reading as solved. The canonical file's.claudeentry is anchored for the same reason as a repo-root binary; leave it that way, but note that it only covers agents running at the repo root — if this repo will run them in subdirectories,services/api/.claude/needs its own anchored entry. - If the image embeds a version in a binary:
.dockerignorelets.gitinto the build context. It keeps out.git/configand each submodule'sconfigunder.git/modules/at any depth (.git/modules/**/config), whichgit describedoes not need and which can hold a credential: a password in a remote URL, or the token the CI checkout step stores there. The stage that compiles hasgit(the Debian Go image has it; an alpine one needsapk add --no-cache git) and takes the version from theVERSIONbuild argument when one is given, otherwise fromgit describe --tags --always. That gives the tag on a tagged commit; on a later commit, the tag, the number of commits since it and the short commit (v1.2.3-4-gabc1234); and the short commit when no tag is reachable. The stage that compiles also marks its working directory safe for git (git config --system --add safe.directory /src): a context sent as a tar stream keeps the sender's file owners, and git refuses a checkout owned by another user, so the version would come out empty.ARG VERSIONhas no default, and the build fails if the context carries.gitand the version still comes out empty,devorunknown. A plaindocker build .with no build arguments must succeed; a Dockerfile that refuses an empty build argument drops that refusal and keeps the argument. - The Dockerfile carries a
lintphase and atestphase, each invoking its tool directly rather than throughmakeorscript/, and the final stage carries aCOPY --from=of a harmless file from each so the image cannot be built unless both passed. Keep the final stage last: a stage nothing depends on is built only when--targetnames it. - Server: the final stage builds and runs the application
- Non-server: the final stage brings up the dev environment
- Image pinned by sha256 hash with version/date comment
- Extend
- Gitea Actions workflow at
.gitea/workflows/check.ymlthat runsscript/cibuildon push — referencehttps://git.eeqj.de/sneak/prompts/raw/branch/main/.gitea/workflows/check.yml - Language-specific:
- Go:
go mod init sneak.berlin/go/<name>,.golangci.yml(fetch fromhttps://git.eeqj.de/sneak/prompts/raw/branch/main/.golangci.ymland, in the same commit, set the lint phase digest to the one named in the.golangci.ymlparagraph ofREPO_POLICIES.md) - JS:
yarn init,yarn add --dev prettier - Python:
pyproject.toml
- Go:
Configure script/ Entrypoints and Makefile
Implementations live in script/ (scripts-to-rule-them-all); Makefile targets
are thin shims calling them. Model scripts:
https://git.eeqj.de/sneak/prompts/raw/branch/main/script/<name>
- scripts are POSIX sh (
#!/bin/sh,set -eu, no bashisms) so they run on alpine images without bash script/bootstrap/make bootstrap— installs all dependencies, idempotently, assuming nothing (pkg manager detection nix/apt/brew/apk; node used if present, else pinned version via nvm from a hash-verified archive; pinned yarn via corepack); Dockerfile runs it instead of inline installsscript/setup/make setup— readies a fresh clone: runsbootstrap, theninstall-precommit, plus repo-specific initscript/test/make test—docker build --no-cache --target test ., tagged; the phase runs real tests, not a no-op (90-second timeout, 60-second hard cap on wall time)script/lint/make lint—docker build --no-cache --target lint ., tagged. No lint verdict may come from a host invocation of the linter.script/fmt/make fmt— formats code (writes; native, never in a container)script/fmt-check/make fmt-check— checks formatting (read-only; native)script/check/make check— runstest,lint,fmt-check; must not modify filesscript/projectname— outputs the project name (used byscript/dockerfor the image tag)script/docker/make docker— builds Docker image, tagged viascript/projectname(byte-identical across repos);--no-cache, plus the version as a build argscript/cibuild— cd to repo root, runscript/bootstrap, runscript/check, thendocker build --no-cache --build-arg VERSION="$version" .(what CI runs). The bootstrap is required: CI checks out and runs this alone, andscript/fmt-checkruns the formatter on the host.script/fmtandscript/fmt-checksource nvm for the pinned node version before invokingyarn, asscript/bootstrap's own install step does.script/bootstrapleaves the node and yarn it installs off thePATHof the shell that called it, so a bareyarnexits 127 on a runner carrying nothing but docker and git.- Every
docker buildinscript/is tagged, so no invocation leaves a dangling image behind script/precommit— called by the pre-commit hook; runsscript/checkscript/install-precommit— installs the pre-commit hook that runsscript/precommitmake hooks— shims toscript/install-precommit- README Entrypoints section documents the scripts and links the standard
4. Verify
make checkpassesmake dockersucceedsscript/cibuildsucceeds in a fresh clone on a host carrying nothing but docker and git, with no node or yarn onPATH, which is what CI has, and demonstrably executed the checks — a sub-second build, orCACHEDon a gate layer, means nothing ran- Plant a lint violation and confirm both
make lintand a plaindocker build .fail on it; revert. A plain build that passes proves the final stage is missing itsCOPY --from=edge to the gate phases. - No secrets in repo, and none in the build context: enumerate a probe image
rather than reading
.dockerignore - No mutable image/package references
- No unnecessary files in repo root
- All dates written as YYYY-MM-DD
5. Merge and Set Up
- Commit, merge to
main make hooksto install pre-commit hook- Add remote and push
- Verify
mainpassesmake check