Rewrite REPO_POLICIES.md sentence by sentence (closes #136) (#147)
check / check (push) Canceled after 0s
check / check (push) Canceled after 0s
Rewrites every sentence of `prompts/REPO_POLICIES.md` against the sentence rules, for #136. No rule's meaning, `must`/`should` or order changed. Code blocks, digests, URLs and commands are byte-identical. Both checklists carry the same rewrite of the paragraph they quote. ## For sneak Kept as they are: each looks false or contradicts another rule. Line numbers are this branch's. - Lines 196-197: the final stage carries the `COPY --from=` lines; in the `Dockerfile` (345-346) the build stage does, the runtime stage none. - Lines 629-641 and 670-675: `make test` runs `go test` and `pytest` on the host; 80-81 make targets shims, 183-185 make `script/test` a Docker build. - Lines 23-37 pin by hash; 103-112 install node (nvm) and yarn (corepack) by version. Tracked at #146. - Line 131 counts four extensions; `script/lint`, `script/fmt`, `script/fmt-check`, `script/docker` (85-89) are not in the standard either. - Lines 149-151: the Makefile is the single source of truth; 80-81 (implementation in `script/`), 211 (tool invoked in a phase), 616 (test command in the `Dockerfile`). - Lines 64-68 require `make test` and `make lint`, which 183-185 make Docker builds; line 167 only says a repo should have a `Dockerfile`. - Line 759 says byte-identical; the block at 767 has `tag="$(script/projectname)"`, both scripts have `tag="$("$SCRIPT_DIR/projectname")"`. - Lines 834-839: `script/bootstrap` never tests presence, 860 excepts only node; `ensure_yarn` in the canonical `script/bootstrap` skips the install when yarn is present, without a version check. ## Disclosures - Judgement call: short name lists stay inline under about 15 words. Model: fable-5-1 Co-authored-by: sneak <sneak@sneak.berlin> Reviewed-on: #147 Co-authored-by: clawbot <35+clawbot@noreply.example.org>
This commit was merged in pull request #147.
This commit is contained in:
@@ -21,6 +21,13 @@ fmt-check, and commit.
|
|||||||
|
|
||||||
# Completed Steps
|
# Completed Steps
|
||||||
|
|
||||||
|
- 2026-11-04: Rewrote `prompts/REPO_POLICIES.md` sentence by sentence
|
||||||
|
(https://git.eeqj.de/sneak/prompts/issues/136), on sneak's yes at
|
||||||
|
https://git.eeqj.de/sneak/prompts/issues/136#issuecomment-165193. Every rule
|
||||||
|
keeps its meaning and its place, and `must` and `should` stay as they were.
|
||||||
|
Long sentences are split, comma-chained lists are now bulleted lists, and
|
||||||
|
every reason stays. Code blocks, digests, URLs, file names, commands and
|
||||||
|
quoted strings are unchanged.
|
||||||
- 2026-11-03: The canonical golangci-lint is now v2.15.0, still built with
|
- 2026-11-03: The canonical golangci-lint is now v2.15.0, still built with
|
||||||
go1.27.0, so the `go` directive rule is unchanged (issue 142). Repositories
|
go1.27.0, so the `go` directive rule is unchanged (issue 142). Repositories
|
||||||
pick this up on their next re-vendor. Each item in the canonical
|
pick this up on their next re-vendor. Each item in the canonical
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
title: Existing Repo Checklist
|
title: Existing Repo Checklist
|
||||||
last_modified: 2026-11-03
|
last_modified: 2026-11-04
|
||||||
---
|
---
|
||||||
|
|
||||||
Use this checklist when beginning work in a repo that may not yet conform to our
|
Use this checklist when beginning work in a repo that may not yet conform to our
|
||||||
@@ -56,14 +56,14 @@ with your task.
|
|||||||
- the step that runs `script/bootstrap` to install a Python `test` phase's
|
- the step that runs `script/bootstrap` to install a Python `test` phase's
|
||||||
packages from `Pipfile.lock`
|
packages from `Pipfile.lock`
|
||||||
- [ ] A stage with none of these steps declares `ARG CACHEBUST` right after
|
- [ ] A stage with none of these steps declares `ARG CACHEBUST` right after
|
||||||
`FROM`. A step that installs anything else as well, such as a
|
`FROM`. A step that also installs anything else comes after
|
||||||
`script/bootstrap` that also installs node packages, comes after it too.
|
`ARG CACHEBUST` too. A `script/bootstrap` that also installs node packages
|
||||||
The `script/` builds pass a new `CACHEBUST` value on every build, which
|
is one. The `script/` builds pass a new `CACHEBUST` value on every build,
|
||||||
reruns every `RUN` step after that line and leaves the layers above it and
|
which reruns every `RUN` step after that line and leaves the layers above
|
||||||
the cache mounts in place; `--no-cache` would build those layers again and
|
it and the cache mounts in place; `--no-cache` would build those layers
|
||||||
empty the mounts. A stage without the `ARG` line is served from cache on
|
again and empty the mounts. A stage without the `ARG` line is served from
|
||||||
an unchanged tree, so the scripts and the `ARG` lines are re-vendored in
|
cache on an unchanged tree, so the scripts and the `ARG` lines are
|
||||||
one commit.
|
re-vendored in one commit.
|
||||||
- [ ] Go: each Go stage downloads the modules (`COPY go.mod go.sum ./`,
|
- [ ] Go: each Go stage downloads the modules (`COPY go.mod go.sum ./`,
|
||||||
`RUN go mod download`) above `ARG CACHEBUST`; the steps that compile
|
`RUN go mod download`) above `ARG CACHEBUST`; the steps that compile
|
||||||
(`golangci-lint run`, `go test`, `go build`) mount Go's build cache
|
(`golangci-lint run`, `go test`, `go build`) mount Go's build cache
|
||||||
@@ -76,15 +76,19 @@ with your task.
|
|||||||
- [ ] Python: a `test` phase that installs its packages from `Pipfile.lock` does
|
- [ ] Python: a `test` phase that installs its packages from `Pipfile.lock` does
|
||||||
it above `ARG CACHEBUST`, with `COPY script/ script/`,
|
it above `ARG CACHEBUST`, with `COPY script/ script/`,
|
||||||
`COPY Pipfile Pipfile.lock ./` and `RUN script/bootstrap`. When
|
`COPY Pipfile Pipfile.lock ./` and `RUN script/bootstrap`. When
|
||||||
`script/bootstrap` runs in that step, it installs nothing beyond system
|
`script/bootstrap` runs in that step, it installs nothing beyond these:
|
||||||
packages, pipenv and its dependencies, and the packages from
|
- system packages
|
||||||
`Pipfile.lock`. It installs pipenv and its dependencies by hash, with
|
- pipenv and its dependencies
|
||||||
`pip install --require-hashes`. It installs the packages from
|
- the packages from `Pipfile.lock`
|
||||||
`Pipfile.lock` with `pipenv install --deploy`, plus `--dev` when the tests
|
|
||||||
need the development packages. It installs no Python there, because the
|
It installs pipenv and its dependencies by hash, with
|
||||||
tests use the base image's. The tests run after `ARG CACHEBUST`, and every
|
`pip install --require-hashes`. It installs the packages from `Pipfile.lock`
|
||||||
other stage installs its Python packages after it, as in the Python `test`
|
with `pipenv install --deploy`, plus `--dev` when the tests need the
|
||||||
phase example in `REPO_POLICIES.md`
|
development packages. It installs no Python there, because the tests use the
|
||||||
|
base image's. The tests run after `ARG CACHEBUST`, and every other stage
|
||||||
|
installs its Python packages after it, as in the Python `test` phase example
|
||||||
|
in `REPO_POLICIES.md`
|
||||||
|
|
||||||
- [ ] The gate phases invoke their tools directly, never through `make lint` or
|
- [ ] The gate phases invoke their tools directly, never through `make lint` or
|
||||||
`script/test` — those are themselves a `docker build` and would recurse
|
`script/test` — those are themselves a `docker build` and would recurse
|
||||||
inside a build step
|
inside a build step
|
||||||
@@ -105,37 +109,43 @@ with your task.
|
|||||||
`services/api/.claude/`: add anchored entries for those directories.
|
`services/api/.claude/`: add anchored entries for those directories.
|
||||||
- [ ] If the repo embeds a version in a binary: `.dockerignore` lets `.git` into
|
- [ ] If the repo embeds a version in a binary: `.dockerignore` lets `.git` into
|
||||||
the build context. It keeps out every git `config` at any depth
|
the build context. It keeps out every git `config` at any depth
|
||||||
(`**/.git/config`, `**/.git/modules/**/config`): the repository's own,
|
(`**/.git/config`, `**/.git/modules/**/config`):
|
||||||
each submodule's under `.git/modules/`, and that of a submodule keeping
|
- the repository's own
|
||||||
its own `.git` directory. `git describe` does not need them, and each can
|
- each submodule's under `.git/modules/`
|
||||||
hold a credential: a password in a remote URL, or the token the CI
|
- that of a submodule keeping its own `.git` directory
|
||||||
checkout step stores there. A submodule whose name has a `config` segment
|
|
||||||
(`config`, `deploy/config`, `config/lib`) loses its whole git directory to
|
`git describe` does not need them, and each can hold a credential: a
|
||||||
`**/.git/modules/**/config`, and Go's version stamping then fails the
|
password in a remote URL, or the token the CI checkout step stores there.
|
||||||
build: give it a name without that segment (`git submodule add --name`).
|
Some submodule names have a `config` segment, as in `config`,
|
||||||
The stage that compiles has `git` (the Debian Go image has it; an alpine
|
`deploy/config` or `config/lib`. Such a submodule loses its whole git
|
||||||
one needs `apk add --no-cache git`) and takes the version from the
|
directory to `**/.git/modules/**/config`, and Go's version stamping then
|
||||||
`VERSION` build argument when one is given, otherwise from
|
fails the build. Give it a name without that segment
|
||||||
`git describe --tags --always`. That gives the tag on a tagged commit; on
|
(`git submodule add --name`). The stage that compiles has `git`: the Debian
|
||||||
a later commit, the tag, the number of commits since it and the short
|
Go image has it, and an alpine one needs `apk add --no-cache git`. That
|
||||||
commit (`v1.2.3-4-gabc1234`); and the short commit when no tag is
|
stage takes the version from the `VERSION` build argument when one is given,
|
||||||
reachable. The stage that compiles also marks its working directory safe
|
otherwise from `git describe --tags --always`. That gives:
|
||||||
for git (`git config --system --add safe.directory /src`): a context sent
|
- the tag, on a tagged commit
|
||||||
as a tar stream keeps the sender's file owners, and git refuses a checkout
|
- the tag, the number of commits since it and the short commit
|
||||||
owned by another user, so the version would come out empty. `ARG VERSION`
|
(`v1.2.3-4-gabc1234`), on a later commit
|
||||||
has no default, and the build fails if the context carries `.git` and the
|
- the short commit, when no tag is reachable
|
||||||
version still comes out empty, `dev` or `unknown`. A plain
|
|
||||||
`docker build .` with no build arguments must succeed; a Dockerfile that
|
The stage that compiles also marks its working directory safe for git
|
||||||
refuses an empty build argument drops that refusal and keeps the argument.
|
(`git config --system --add safe.directory /src`). A context sent as a tar
|
||||||
A checkout whose `.git` is a file (a linked worktree, or a repository
|
stream keeps the sender's file owners, and git refuses a checkout owned by
|
||||||
checked out as a submodule) is the exception: that file points to a git
|
another user, so the version would come out empty. `ARG VERSION` has no
|
||||||
directory outside the build context, so the build cannot read the version
|
default. The build fails if the context carries `.git` and the version still
|
||||||
and a plain `docker build .` fails; pass the version with
|
comes out empty, `dev` or `unknown`. A plain `docker build .` with no build
|
||||||
`--build-arg VERSION=...`. `script/docker` and `script/cibuild` already
|
arguments must succeed; a Dockerfile that refuses an empty build argument
|
||||||
pass the version they compute on the host; it takes precedence. The
|
drops that refusal and keeps the argument. A checkout whose `.git` is a file
|
||||||
canonical `.gitea/workflows/check.yml` sets `fetch-depth: 0` on its
|
is the exception: a linked worktree, or a repository checked out as a
|
||||||
checkout step, which otherwise clones shallow and fetches no tags, so a CI
|
submodule. That file points to a git directory outside the build context, so
|
||||||
build finds the tag too.
|
the build cannot read the version and a plain `docker build .` fails. Pass
|
||||||
|
the version with `--build-arg VERSION=...`. `script/docker` and
|
||||||
|
`script/cibuild` already pass the version they compute on the host; it takes
|
||||||
|
precedence. The canonical `.gitea/workflows/check.yml` sets `fetch-depth: 0`
|
||||||
|
on its checkout step, which otherwise clones shallow and fetches no tags, so
|
||||||
|
a CI build finds the tag too.
|
||||||
|
|
||||||
- [ ] Gitea Actions workflow in `.gitea/workflows/` runs `script/cibuild` on
|
- [ ] Gitea Actions workflow in `.gitea/workflows/` runs `script/cibuild` on
|
||||||
push, checks out with `persist-credentials: false` and with
|
push, checks out with `persist-credentials: false` and with
|
||||||
`fetch-depth: 0` (which fetches the tags `git describe` needs), carries
|
`fetch-depth: 0` (which fetches the tags `git describe` needs), carries
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
title: New Repo Checklist
|
title: New Repo Checklist
|
||||||
last_modified: 2026-11-03
|
last_modified: 2026-11-04
|
||||||
---
|
---
|
||||||
|
|
||||||
Use this checklist when creating a new repository from scratch. Follow the steps
|
Use this checklist when creating a new repository from scratch. Follow the steps
|
||||||
@@ -75,34 +75,42 @@ Template files can be fetched from:
|
|||||||
anchored entry.
|
anchored entry.
|
||||||
- If the image embeds a version in a binary: `.dockerignore` lets `.git`
|
- If the image embeds a version in a binary: `.dockerignore` lets `.git`
|
||||||
into the build context. It keeps out every git `config` at any depth
|
into the build context. It keeps out every git `config` at any depth
|
||||||
(`**/.git/config`, `**/.git/modules/**/config`): the repository's own,
|
(`**/.git/config`, `**/.git/modules/**/config`):
|
||||||
each submodule's under `.git/modules/`, and that of a submodule keeping
|
- the repository's own
|
||||||
its own `.git` directory. `git describe` does not need them, and each can
|
- each submodule's under `.git/modules/`
|
||||||
hold a credential: a password in a remote URL, or the token the CI
|
- that of a submodule keeping its own `.git` directory
|
||||||
checkout step stores there. A submodule whose name has a `config` segment
|
|
||||||
(`config`, `deploy/config`, `config/lib`) loses its whole git directory to
|
`git describe` does not need them, and each can hold a credential: a
|
||||||
`**/.git/modules/**/config`, and Go's version stamping then fails the
|
password in a remote URL, or the token the CI checkout step stores
|
||||||
build: give it a name without that segment (`git submodule add --name`).
|
there. Some submodule names have a `config` segment, as in `config`,
|
||||||
The stage that compiles has `git` (the Debian Go image has it; an alpine
|
`deploy/config` or `config/lib`. Such a submodule loses its whole git
|
||||||
one needs `apk add --no-cache git`) and takes the version from the
|
directory to `**/.git/modules/**/config`, and Go's version stamping then
|
||||||
|
fails the build. Give it a name without that segment
|
||||||
|
(`git submodule add --name`). The stage that compiles has `git`: the
|
||||||
|
Debian Go image has it, and an alpine one needs
|
||||||
|
`apk add --no-cache git`. That stage takes the version from the
|
||||||
`VERSION` build argument when one is given, otherwise from
|
`VERSION` build argument when one is given, otherwise from
|
||||||
`git describe --tags --always`. That gives the tag on a tagged commit; on
|
`git describe --tags --always`. That gives:
|
||||||
a later commit, the tag, the number of commits since it and the short
|
- the tag, on a tagged commit
|
||||||
commit (`v1.2.3-4-gabc1234`); and the short commit when no tag is
|
- the tag, the number of commits since it and the short commit
|
||||||
reachable. The stage that compiles also marks its working directory safe
|
(`v1.2.3-4-gabc1234`), on a later commit
|
||||||
for git (`git config --system --add safe.directory /src`): a context sent
|
- the short commit, when no tag is reachable
|
||||||
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 VERSION`
|
The stage that compiles also marks its working directory safe for git
|
||||||
has no default, and the build fails if the context carries `.git` and the
|
(`git config --system --add safe.directory /src`). A context sent as a
|
||||||
version still comes out empty, `dev` or `unknown`. A plain
|
tar stream keeps the sender's file owners, and git refuses a checkout
|
||||||
`docker build .` with no build arguments must succeed; a Dockerfile that
|
owned by another user, so the version would come out empty.
|
||||||
refuses an empty build argument drops that refusal and keeps the argument.
|
`ARG VERSION` has no default. The build fails if the context carries
|
||||||
A checkout whose `.git` is a file (a linked worktree, or a repository
|
`.git` and the version still comes out empty, `dev` or `unknown`. A
|
||||||
checked out as a submodule) is the exception: that file points to a git
|
plain `docker build .` with no build arguments must succeed; a
|
||||||
directory outside the build context, so the build cannot read the version
|
Dockerfile that refuses an empty build argument drops that refusal and
|
||||||
and a plain `docker build .` fails; pass the version with
|
keeps the argument. A checkout whose `.git` is a file is the exception:
|
||||||
`--build-arg VERSION=...`, as `script/docker` and `script/cibuild` already
|
a linked worktree, or a repository checked out as a submodule. That file
|
||||||
do.
|
points to a git directory outside the build context, so the build cannot
|
||||||
|
read the version and a plain `docker build .` fails. Pass the version
|
||||||
|
with `--build-arg VERSION=...`, as `script/docker` and `script/cibuild`
|
||||||
|
already do.
|
||||||
|
|
||||||
- The Dockerfile carries a `lint` phase and a `test` phase, each invoking
|
- The Dockerfile carries a `lint` phase and a `test` phase, each invoking
|
||||||
its tool directly rather than through `make` or `script/`, and the final
|
its tool directly rather than through `make` or `script/`, and the final
|
||||||
stage carries a `COPY --from=` of a harmless file from each so the image
|
stage carries a `COPY --from=` of a harmless file from each so the image
|
||||||
@@ -115,14 +123,14 @@ Template files can be fetched from:
|
|||||||
- the step that runs `script/bootstrap` to install a Python `test`
|
- the step that runs `script/bootstrap` to install a Python `test`
|
||||||
phase's packages from `Pipfile.lock`
|
phase's packages from `Pipfile.lock`
|
||||||
- A stage with none of these steps declares `ARG CACHEBUST` right after
|
- A stage with none of these steps declares `ARG CACHEBUST` right after
|
||||||
`FROM`. A step that installs anything else as well, such as a
|
`FROM`. A step that also installs anything else comes after
|
||||||
`script/bootstrap` that also installs node packages, comes after it too.
|
`ARG CACHEBUST` too. A `script/bootstrap` that also installs node packages
|
||||||
The `script/` builds pass a new `CACHEBUST` value on every build, which
|
is one. The `script/` builds pass a new `CACHEBUST` value on every build,
|
||||||
reruns every `RUN` step after that line and leaves the layers above it and
|
which reruns every `RUN` step after that line and leaves the layers above
|
||||||
the cache mounts in place; `--no-cache` would build those layers again and
|
it and the cache mounts in place; `--no-cache` would build those layers
|
||||||
empty the mounts. A stage without the `ARG` line is served from cache on
|
again and empty the mounts. A stage without the `ARG` line is served from
|
||||||
an unchanged tree, so the scripts and every stage's `ARG CACHEBUST` line
|
cache on an unchanged tree, so the scripts and every stage's
|
||||||
are added in the same commit.
|
`ARG CACHEBUST` line are added in the same commit.
|
||||||
- Go: each Go stage downloads the modules (`COPY go.mod go.sum ./`,
|
- Go: each Go stage downloads the modules (`COPY go.mod go.sum ./`,
|
||||||
`RUN go mod download`) above `ARG CACHEBUST`; the steps that compile
|
`RUN go mod download`) above `ARG CACHEBUST`; the steps that compile
|
||||||
(`golangci-lint run`, `go test`, `go build`) mount Go's build cache
|
(`golangci-lint run`, `go test`, `go build`) mount Go's build cache
|
||||||
@@ -135,18 +143,23 @@ Template files can be fetched from:
|
|||||||
- Python: a `test` phase that installs its packages from `Pipfile.lock` does
|
- Python: a `test` phase that installs its packages from `Pipfile.lock` does
|
||||||
it above `ARG CACHEBUST`, with `COPY script/ script/`,
|
it above `ARG CACHEBUST`, with `COPY script/ script/`,
|
||||||
`COPY Pipfile Pipfile.lock ./` and `RUN script/bootstrap`. When
|
`COPY Pipfile Pipfile.lock ./` and `RUN script/bootstrap`. When
|
||||||
`script/bootstrap` runs in that step, it installs nothing beyond system
|
`script/bootstrap` runs in that step, it installs nothing beyond these:
|
||||||
packages, pipenv and its dependencies, and the packages from
|
- system packages
|
||||||
`Pipfile.lock`. It installs pipenv and its dependencies by hash, with
|
- pipenv and its dependencies
|
||||||
|
- the packages from `Pipfile.lock`
|
||||||
|
|
||||||
|
It installs pipenv and its dependencies by hash, with
|
||||||
`pip install --require-hashes`. It installs the packages from
|
`pip install --require-hashes`. It installs the packages from
|
||||||
`Pipfile.lock` with `pipenv install --deploy`, plus `--dev` when the tests
|
`Pipfile.lock` with `pipenv install --deploy`, plus `--dev` when the
|
||||||
need the development packages. It installs no Python there, because the
|
tests need the development packages. It installs no Python there,
|
||||||
tests use the base image's. The tests run after `ARG CACHEBUST`, and every
|
because the tests use the base image's. The tests run after
|
||||||
other stage installs its Python packages after it, as in the Python `test`
|
`ARG CACHEBUST`, and every other stage installs its Python packages
|
||||||
phase example in `REPO_POLICIES.md`
|
after it, as in the Python `test` phase example in `REPO_POLICIES.md`
|
||||||
|
|
||||||
- Server: the final stage builds and runs the application
|
- Server: the final stage builds and runs the application
|
||||||
- Non-server: the final stage brings up the dev environment
|
- Non-server: the final stage brings up the dev environment
|
||||||
- Image pinned by sha256 hash with version/date comment
|
- Image pinned by sha256 hash with version/date comment
|
||||||
|
|
||||||
- [ ] Gitea Actions workflow at `.gitea/workflows/check.yml` that runs
|
- [ ] Gitea Actions workflow at `.gitea/workflows/check.yml` that runs
|
||||||
`script/cibuild` on push, checks out with `persist-credentials: false` and
|
`script/cibuild` on push, checks out with `persist-credentials: false` and
|
||||||
with `fetch-depth: 0` (which fetches the tags `git describe` needs),
|
with `fetch-depth: 0` (which fetches the tags `git describe` needs),
|
||||||
|
|||||||
+475
-346
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user