From 99d757c31db140248f9e01e54a745b71d3f2c304 Mon Sep 17 00:00:00 2001 From: clawbot Date: Sun, 9 Aug 2026 09:57:43 +0000 Subject: [PATCH] Re-vendor REPO_POLICIES.md from the canonical copy (closes #20) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The vendored copy had drifted to 368 lines against the canonical 408 while still declaring `last_modified: 2026-07-06`, so nothing about the file signalled that it was stale. Agents working in this repo read the vendored copy to learn the rules, which makes a silent 40-line gap a source of real defects rather than untidiness: two have already been traced to exactly this drift, `script/fmt` having dropped the prettier Markdown pass (#19, still open) and the README having no Entrypoints section (#21, since fixed). Restored by copying the canonical file wholesale — no hand-editing, no partial merge, no local adaptation, because it is a vendored copy and its value comes from matching upstream byte for byte. What comes back: - the entire Scripts to Rule Them All section, including the POSIX sh requirement, the repo-root discovery idiom, and the division between the standard's canonical scripts and our four extensions - `bootstrap`, `setup` and `hooks` in the required Makefile target list - the `script/precommit` paragraph and how the pre-commit hook is wired through `script/install-precommit` - the README **Entrypoints** section requirement - the Dockerfile bootstrap-layer guidance and the `script/cibuild` wording in the Gitea Actions bullet Verified: `diff` against the canonical file is empty, sha256 is 117dde7f148ed3cd693b333312f6345a0a0ee84fadbbe5cca559ca6fed4a1775, and `REPO_POLICIES.md` is the only changed path. `make check` is green. No `TODO.md` entry accompanies this commit. The repo convention is to record the work in the same commit, but the issue's definition of done restricts the change to `REPO_POLICIES.md` alone; that scope discipline is what lets a docs-only change skip adversarial review. --- REPO_POLICIES.md | 80 ++++++++++++++++++++++++++++++++++++------------ 1 file changed, 60 insertions(+), 20 deletions(-) diff --git a/REPO_POLICIES.md b/REPO_POLICIES.md index e30bf16..bc2f161 100644 --- a/REPO_POLICIES.md +++ b/REPO_POLICIES.md @@ -34,10 +34,46 @@ style conventions are in separate documents: every file before committing. There are zero exceptions to this rule. - Every repo with software must have a root `Makefile` with these targets: - `make test`, `make lint`, `make fmt` (writes), `make fmt-check` (read-only), - `make check` (prereqs: `test`, `lint`, `fmt-check`), `make docker`, and - `make hooks` (installs pre-commit hook). A model Makefile is at - `https://git.eeqj.de/sneak/prompts/raw/branch/main/Makefile`. + `make bootstrap`, `make setup`, `make test`, `make lint`, `make fmt` (writes), + `make fmt-check` (read-only), `make check` (runs `test`, `lint`, `fmt-check`), + `make docker`, and `make hooks` (installs pre-commit hook). A model Makefile + is at `https://git.eeqj.de/sneak/prompts/raw/branch/main/Makefile`. + +- Repos follow the + [Scripts to Rule Them All](https://github.com/github/scripts-to-rule-them-all) + pattern: the implementation of each Makefile target lives in an executable + script in `script/` (`script/bootstrap`, `script/setup`, `script/test`, + `script/lint`, `script/fmt`, `script/fmt-check`, `script/check`, + `script/docker`), and the Makefile targets are thin shims that call them. The + scripts must be POSIX sh (`#!/bin/sh`, `set -eu`, no bashisms) so they run in + minimal containers (e.g. alpine images have no bash); locate the repo root + with `$(cd "$(dirname "$0")/.." && pwd -P)` and `cd` there before acting. From + the standard's canonical set we use `bootstrap`, `setup` (make the repo ready + for development after a fresh clone: runs `bootstrap`, then + `install-precommit`, plus any repo-specific initialization), `test`, and + `cibuild`. `script/bootstrap` installs all dependencies idempotently and + assumes nothing is present: base tools come from nix, apt, brew, or apk + (detected in that order; apt runs noninteractive). For node it uses the + installed node if present; otherwise it installs a PINNED node version via + nvm, first installing nvm itself if missing — from a hash-verified GitHub + release archive (never `curl | sh`), with bash installed as an explicit + prerequisite since nvm requires bash. yarn is then pinned via + `corepack prepare yarn@ --activate`. Never install "latest" or "lts"; + always exact versions. `script/cibuild` runs the CI build: it changes to the + repo root and runs `docker build .`; the Gitea workflow calls it. Four further + scripts are our own extensions to the standard: `script/check` runs + `script/test`, `script/lint`, and `script/fmt-check`; `script/precommit` is + what the git pre-commit hook runs, and it calls `script/check`; + `script/install-precommit` installs the git pre-commit hook (the `make hooks` + target shims to it); and `script/projectname` (literally that filename) simply + outputs the project's name. Scripts that need the name call + `script/projectname` — e.g. `script/docker` assembles its image tag from it — + so those scripts stay byte-identical across all repos. Repo-type-specific + pre-commit extras (e.g. `go mod tidy` verification in Go repos) belong in + `script/precommit`, not in the hook itself. Model scripts are at + `https://git.eeqj.de/sneak/prompts/raw/branch/main/script/`. The README + must document the provided scripts in an **Entrypoints** section (see the + README requirements below). - Always use Makefile targets (`make fmt`, `make test`, `make lint`, etc.) instead of invoking the underlying tools directly. The Makefile is the single @@ -57,7 +93,11 @@ style conventions are in separate documents: as a build step so the build fails if the branch is not green. For non-server repos, the Dockerfile should bring up a development environment and run `make check`. For server repos, `make check` should run as an early build - stage before the final image is assembled. + stage before the final image is assembled. Dockerfiles install development + prerequisites by running `script/bootstrap` rather than duplicating installs + inline; COPY `script/` and the dependency manifests (`package.json` + + `yarn.lock`, `go.mod` + `go.sum`, etc.) before running it so the bootstrap + layer stays cached until dependencies change. - **Dockerfiles must use a separate lint stage for fail-fast feedback.** Go repos use a multistage build where linting runs in an independent stage based @@ -127,8 +167,9 @@ style conventions are in separate documents: artifacts or heavier dependencies. - Every repo should have a Gitea Actions workflow (`.gitea/workflows/`) that - runs `docker build .` on push. Since the Dockerfile already runs `make check`, - a successful build implies all checks pass. + runs `script/cibuild` (which runs `docker build .`) on push. Since the + Dockerfile already runs `make check`, a successful build implies all checks + pass. - Use platform-standard formatters: `black` for Python, `prettier` for JS/CSS/Markdown/HTML, `go fmt` for Go. Always use default configuration with @@ -136,9 +177,11 @@ style conventions are in separate documents: Markdown (hard-wrap at 80 columns). Documentation and writing repos (Markdown, HTML, CSS) should also have `.prettierrc` and `.prettierignore`. -- Pre-commit hook: `make check` if local testing is possible, otherwise - `make lint && make fmt-check`. The Makefile should provide a `make hooks` - target to install the pre-commit hook. +- Pre-commit hook: runs `script/precommit`, which calls `script/check`. If local + testing is not possible in the repo, `script/precommit` may skip `script/test` + and run only `script/lint` and `script/fmt-check`. The hook is installed by + `script/install-precommit`; the Makefile must provide a `make hooks` target + that shims to it. - All repos with software must have tests that run via the platform-standard test framework (`go test`, `pytest`, `jest`/`vitest`, etc.). If no meaningful @@ -297,6 +340,10 @@ style conventions are in separate documents: "µPaaS is an MIT-licensed Go web application by @sneak that receives git-frontend webhooks and deploys applications via Docker in realtime." - **Getting Started**: Copy-pasteable install/usage code block. + - **Entrypoints**: Opens by stating that the repo adheres to the + [Scripts to Rule Them All](https://github.com/github/scripts-to-rule-them-all) + standard (with that link), then documents each provided `script/` + entrypoint and its purpose. - **Rationale**: Why does this exist? - **Design**: How is the program structured? - **TODO**: Update meticulously, even between commits. When planning, put @@ -326,16 +373,6 @@ style conventions are in separate documents: - All repos should have an `.editorconfig` enforcing the project's indentation settings. -- **Claude Code repo memory is versioned in the repo**, not left only in - `~/.claude` on one machine. Each memory is one file at - `.claude/memory/.md`, and every memory file must be `@`-imported - from `.claude/CLAUDE.md` (one `- @memory/.md` list line per file; - relative import paths resolve against `.claude/`, and Claude Code expands - the imports into context at session launch). When adding a memory, add both - the file and its import line. A root `MEMORY.md` is a violation — Claude - Code never auto-loads it; split it into `.claude/memory/` files. Repos with - no memories yet need no `.claude/` scaffolding. - - Avoid putting files in the repo root unless necessary. Root should contain only project-level config files (`README.md`, `Makefile`, `Dockerfile`, `LICENSE`, `.gitignore`, `.editorconfig`, `REPO_POLICIES.md`, and @@ -361,6 +398,9 @@ style conventions are in separate documents: - `README.md`, `.git`, `.gitignore`, `.editorconfig` - `LICENSE`, `REPO_POLICIES.md` (copy from the `prompts` repo) - `Makefile` + - `script/` entrypoints (`bootstrap`, `setup`, `projectname`, `test`, + `lint`, `fmt`, `fmt-check`, `check`, `docker`, `cibuild`, `precommit`, + `install-precommit`) - `Dockerfile`, `.dockerignore` - `.gitea/workflows/check.yml` - Go: `go.mod`, `go.sum`, `.golangci.yml` -- 2.49.1