2 Commits
Author SHA1 Message Date
clawbot 3066aae835 Allow go test on one package while iterating (closes #51)
check / check (push) Waiting to run
Follows sneak's ruling at
#51 (comment). An agent
whose work is confined to one package may run `go test` directly on that
package's suite, or on individual tests in it, while iterating. `go build`,
`go vet` and the linter still go through make targets. The full `make check`
is still required before every push. The `Makefile` gains nothing.

The rule on Docker now says the lint and test gates run there, because a run
while iterating is not a gate.

Model: opus-5-5
2026-11-04 19:32:37 +01:00
clawbot 86c7617f86 Install node, yarn and python from the distribution (closes #146)
check / check (push) Canceled after 0s
Follows sneak's ruling at
#146 (comment). Runtimes
and the installer tools bundled with python come from the distribution,
with no version and no hash. Third-party packages stay pinned by hash.

script/bootstrap drops nvm and corepack. It installs node, yarn and the
node packages only when yarn.lock is in the tree, and stops there when
yarn's major version is not 1. This repository's Dockerfile starts from
Alpine 3.24. The Python example starts from debian:trixie-slim, keeps
pipenv at $HOME/.pipenv on a host and in an image, and sets
PIP_ONLY_BINARY=:all:, so pip downloads no build tools without a hash
check.

Model: opus-5-5
2026-11-04 09:55:26 +01:00
4 changed files with 40 additions and 21 deletions
+7
View File
@@ -21,6 +21,13 @@ fmt-check, and commit.
# Completed Steps # Completed Steps
- 2026-11-04: An agent whose work is confined to one package may run `go test`
directly on that package's suite, or on individual tests in it, while
iterating (https://git.eeqj.de/sneak/prompts/issues/51), on sneak's ruling at
https://git.eeqj.de/sneak/prompts/issues/51#issuecomment-167600. The full
`make check` is still required before every push, and the `Makefile` gains
nothing. The rule on Docker now names the lint and test gates, because a run
while iterating is not one.
- 2026-11-04: node, yarn, npm, python, pip and venv now come from the - 2026-11-04: node, yarn, npm, python, pip and venv now come from the
distribution with no version and no hash distribution with no version and no hash
(https://git.eeqj.de/sneak/prompts/issues/146), on sneak's ruling at (https://git.eeqj.de/sneak/prompts/issues/146), on sneak's ruling at
+5 -3
View File
@@ -167,7 +167,9 @@ with your task.
- [ ] JS: `package.json`, `yarn.lock`, `.prettierrc`, `.prettierignore` - [ ] JS: `package.json`, `yarn.lock`, `.prettierrc`, `.prettierignore`
(fetch from (fetch from
`https://git.eeqj.de/sneak/prompts/raw/branch/main/.prettierrc` and `https://git.eeqj.de/sneak/prompts/raw/branch/main/.prettierrc` and
`https://git.eeqj.de/sneak/prompts/raw/branch/main/.prettierignore`) `https://git.eeqj.de/sneak/prompts/raw/branch/main/.prettierignore`).
Make the first `yarn.lock` with yarn 1, from a distribution that
packages it, such as Alpine (`apk add nodejs yarn`).
- [ ] Python: `pyproject.toml` - [ ] Python: `pyproject.toml`
- [ ] Docs/writing: `.prettierrc`, `.prettierignore` (same URLs as above) - [ ] Docs/writing: `.prettierrc`, `.prettierignore` (same URLs as above)
@@ -211,8 +213,8 @@ with your task.
image whose distribution packages yarn 1, such as Alpine. image whose distribution packages yarn 1, such as Alpine.
- [ ] `script/bootstrap`, `script/fmt` and `script/fmt-check` run yarn by - [ ] `script/bootstrap`, `script/fmt` and `script/fmt-check` run yarn by
whichever name is present: `yarn`, or `yarnpkg` on Debian and Ubuntu. With whichever name is present: `yarn`, or `yarnpkg` on Debian and Ubuntu. With
neither name on `PATH`, they print one line saying to run neither name on `PATH`, `script/fmt` and `script/fmt-check` print one line
`script/bootstrap`, and exit 1. saying to run `script/bootstrap`, and exit 1.
- [ ] `script/bootstrap` installs no linter of its own — delete the block, its - [ ] `script/bootstrap` installs no linter of its own — delete the block, its
version variables and its call site. A JS repo's `yarn install` stays; it version variables and its call site. A JS repo's `yarn install` stays; it
brings a linter along with every other dependency, and no verdict is taken brings a linter along with every other dependency, and no verdict is taken
+5 -3
View File
@@ -179,7 +179,9 @@ Template files can be fetched from:
`https://git.eeqj.de/sneak/prompts/raw/branch/main/.golangci.yml` and, `https://git.eeqj.de/sneak/prompts/raw/branch/main/.golangci.yml` and,
in the same commit, set the lint phase digest to the one named in the in the same commit, set the lint phase digest to the one named in the
`.golangci.yml` paragraph of `REPO_POLICIES.md`) `.golangci.yml` paragraph of `REPO_POLICIES.md`)
- [ ] JS: `yarn init`, `yarn add --dev prettier` - [ ] JS: `yarn init`, `yarn add --dev prettier`. `script/bootstrap`
installs no yarn until `yarn.lock` exists, so use yarn 1 from a
distribution that packages it, such as Alpine (`apk add nodejs yarn`).
- [ ] Python: `pyproject.toml` - [ ] Python: `pyproject.toml`
## Configure script/ Entrypoints and Makefile ## Configure script/ Entrypoints and Makefile
@@ -236,8 +238,8 @@ are thin shims calling them. Model scripts:
`script/fmt-check` runs the formatter on the host. `script/fmt-check` runs the formatter on the host.
- [ ] `script/bootstrap`, `script/fmt` and `script/fmt-check` run yarn by - [ ] `script/bootstrap`, `script/fmt` and `script/fmt-check` run yarn by
whichever name is present: `yarn`, or `yarnpkg` on Debian and Ubuntu. With whichever name is present: `yarn`, or `yarnpkg` on Debian and Ubuntu. With
neither name on `PATH`, they print one line saying to run neither name on `PATH`, `script/fmt` and `script/fmt-check` print one line
`script/bootstrap`, and exit 1. saying to run `script/bootstrap`, and exit 1.
- [ ] No `docker build` in `script/` leaves a dangling image behind: - [ ] No `docker build` in `script/` leaves a dangling image behind:
`script/lint` and `script/test` write no image, and `script/docker` and `script/lint` and `script/test` write no image, and `script/docker` and
`script/cibuild` tag theirs `script/cibuild` tag theirs
+23 -15
View File
@@ -123,26 +123,28 @@ style conventions are in separate documents:
`script/bootstrap` installs node, yarn and the node packages only when `script/bootstrap` installs node, yarn and the node packages only when
`yarn.lock` is in the tree. With no `yarn.lock`, it installs no node and no `yarn.lock` is in the tree. With no `yarn.lock`, it installs no node and no
yarn, and it does not check yarn's version. yarn, and it does not check yarn's version. Make a repository's first
`yarn.lock` with yarn 1, from a distribution that packages it, such as
Alpine (`apk add nodejs yarn`).
Debian and Ubuntu name the yarn command `yarnpkg`. `script/bootstrap`, Debian and Ubuntu name the yarn command `yarnpkg`. `script/bootstrap`,
`script/fmt` and `script/fmt-check` each carry the same small function that `script/fmt` and `script/fmt-check` each carry the same small function that
runs whichever name is present. With neither name on `PATH`, the function runs whichever name is present. With neither name on `PATH`, `script/fmt`
prints one line saying to run `script/bootstrap`, and exits 1. and `script/fmt-check` print one line saying to run `script/bootstrap`, and
exit 1.
With `yarn.lock` in the tree, `script/bootstrap` stops with a one-line With `yarn.lock` in the tree, `script/bootstrap` stops with a one-line
message when yarn's major version is not 1, before it installs any node message when yarn's major version is not 1, before it installs any node
packages. Debian 13 and Ubuntu 26.04 package yarn 4. With packages. Debian 13 and Ubuntu 26.04 package yarn 4. With
`--frozen-lockfile`, yarn 4 refuses a yarn 1 `yarn.lock`. Without that flag, `--frozen-lockfile`, yarn 4 refuses a yarn 1 `yarn.lock`. Without that flag,
it rewrites the file in its own format, with its own hashes in place of it rewrites the file in its own format, with yarn 4 hashes in place of the
these. A host whose distribution packages yarn 4 moves to one that packages yarn 1 ones. A host whose distribution packages yarn 4 moves to one that
yarn 1, such as Alpine or Ubuntu 24.04. packages yarn 1, such as Alpine or Ubuntu 24.04.
A `Dockerfile` stage copies `yarn.lock` before it runs `script/bootstrap` A `Dockerfile` stage copies `yarn.lock` before it runs `script/bootstrap`
only if that stage needs yarn. A stage that needs yarn starts from an image only if that stage needs yarn. A stage that needs yarn starts from an image
whose distribution packages yarn 1, such as Alpine. The Python and Go stages whose distribution packages yarn 1, such as Alpine. The Python and Go stages
below need no yarn, so they copy no `yarn.lock` before that step and never below need no yarn and copy no `yarn.lock`, so they never reach the stop.
reach the stop.
`script/cibuild` runs the CI build, and the Gitea workflow calls it. The `script/cibuild` runs the CI build, and the Gitea workflow calls it. The
script changes to the repo root, runs `script/bootstrap`, runs script changes to the repo root, runs `script/bootstrap`, runs
@@ -174,6 +176,12 @@ style conventions are in separate documents:
instead of invoking the underlying tools directly. The Makefile is the single instead of invoking the underlying tools directly. The Makefile is the single
source of truth for how these operations are run. source of truth for how these operations are run.
An agent whose work is confined to one package may run `go test` directly on
that package's suite, or on individual tests in it, while iterating. This is
the only exception to this rule. `go build`, `go vet` and the linter still
go through make targets. A run while iterating is not a gate, so the full
`make check` is still required before every push.
- The Makefile is authoritative documentation for how the repo is used. Beyond - The Makefile is authoritative documentation for how the repo is used. Beyond
the required targets above, it should have targets for every common operation: the required targets above, it should have targets for every common operation:
- running a local development server (`make run`, `make dev`) - running a local development server (`make run`, `make dev`)
@@ -205,9 +213,9 @@ style conventions are in separate documents:
and the dependency manifests it needs (`package.json` + `yarn.lock`, and the dependency manifests it needs (`package.json` + `yarn.lock`,
`go.mod` + `go.sum`, etc.) before running it. `go.mod` + `go.sum`, etc.) before running it.
- **Linting and testing run in Docker, as phases of the `Dockerfile`.** There is - **The lint and test gates run in Docker, as phases of the `Dockerfile`.**
no separate lint file. `script/lint` and `script/test` each build one phase There is no separate lint file. `script/lint` and `script/test` each build one
and nothing else: phase and nothing else:
```sh ```sh
docker build --build-arg CACHEBUST="$(date +%s)-$$" \ docker build --build-arg CACHEBUST="$(date +%s)-$$" \
@@ -569,10 +577,10 @@ style conventions are in separate documents:
"$HOME/.pipenv/bin/pipenv" install --dev --deploy "$HOME/.pipenv/bin/pipenv" install --dev --deploy
``` ```
Make `script/requirements.txt` once with Make `script/requirements.txt` once, with
`echo pipenv | pip-compile --generate-hashes --allow-unsafe -o script/requirements.txt -`, `echo pipenv | pip-compile --generate-hashes --allow-unsafe -o script/requirements.txt -`.
from Alpine's `py3-pip-tools` package, because Debian and Ubuntu do not `pip-compile` comes from Alpine's `py3-pip-tools` package; Debian and Ubuntu
package it. Make the first `Pipfile.lock` with do not package `pip-tools`. Make the first `Pipfile.lock` with
`$HOME/.pipenv/bin/pipenv lock`, after the `pip install` line has installed `$HOME/.pipenv/bin/pipenv lock`, after the `pip install` line has installed
pipenv. pipenv.