Accumulating branch for the current cycle. Squash-merged units land here; this
PR is the milestone's route to main.
Carried so far
fd3cd4c Add Makefile shims for cibuild and precommit (closes #34)
Makefile shims for cibuild and precommit
script/cibuild and script/precommit both existed and were already the
documented CI and pre-commit entrypoints, but neither had a Makefile target,
so the standing rule to drive the repo through make targets rather than the
underlying tool could not be followed for either.
It matters most for the build: a bare docker build . fails closed on the CHECK_EPOCH guard by design, so script/cibuild is one of only three
supported ways to build an image here, and it was the only one of the three
without a target while make docker had one.
The two targets are thin shims in the existing style and change nothing about
what the scripts do. .PHONY was already complete for the targets that existed
and now lists both new ones.
README.md's Entrypoints section gains the script-to-target mapping so the two
documents agree, including the two names that do not match — script/install-precommit is make hooks, script/precommit is make precommit — plus a note that make cibuild is the slowest target because
it is the only one that runs two container builds, while still taking seconds
once the shared script/bootstrap layer is cached.
Two accuracy fixes to text the same section already carried:
the script/install-precommit bullet said the installed hook runs script/check. The script writes script/precommit into .git/hooks/pre-commit, and its own header comment says so. Now corrected.
the Makefile is described as listing the operations you are expected to run,
rather than as the authoritative list of everything the repo can do — not
literally true, since script/projectname has no target. No target was added
for it: it is an internal helper script/docker calls to compute a tag, and a
target would be noise in exactly the make<tab> listing this change exists to
make useful.
TODO.md sheds two now-false statements about static/_headers, both resolved
by the same production check: the Future Step asking someone to confirm the file
took effect, and the Status paragraph's "unverified in production until the next
deploy" clause. The headers are live at the edge on both hostnames — see #14 . A commit that edits TODO.md
should not leave a known-false statement in it.
The README's script/lint bullet and the Docker/buildx prerequisite for the
pre-commit hook are deliberately untouched; they are owned by #40 . The clone URL and the omitted
Entrypoints bullets are owned by #36 .
Verification
make check green on the pushed tree: 12.0s wall, lint layer executed rather
than replayed — RUN echo "lint epoch: 1786370238510704421432841" && hugo --minify --printPathWarnings with RUN script/bootstrapCACHED above it,
hugo's build table printed (Pages │ 3), and All matched files use Prettier code style! from the host script/fmt-check. make fmt run; tree is
prettier-clean.
The timing claim in the README is measured, not asserted. make cibuild on a
warm script/bootstrap layer, two runs on this host:
Both runs ran both builds for real: distinct epochs per build, RUN script/bootstrapCACHED in each, no check layer served from cache below it,
hugo's build table and All matched files use Prettier code style! both
printed. The spread between the two runs is host load, not caching, which is why
the README says "seconds" rather than a figure. Independent figures agree: 10.3s
measured by the reviewer, 19s for this repo's own check job.
No cold-cache number is claimed. The README points at the pinned-Hugo compile it
already documents 48 lines above for make check, and the "paid once rather
than twice" part is verified structurally rather than by timing: the first four
instructions of Dockerfile.lint are byte-identical to the main Dockerfile's,
and layers 6 through 9 report CACHED in both builds of every run above.
Accumulating branch for the current cycle. Squash-merged units land here; this
PR is the milestone's route to `main`.
## Carried so far
- `fd3cd4c` Add Makefile shims for cibuild and precommit (closes
https://git.eeqj.de/sneak/lora.vegas/issues/34)
## Makefile shims for `cibuild` and `precommit`
`script/cibuild` and `script/precommit` both existed and were already the
documented CI and pre-commit entrypoints, but neither had a `Makefile` target,
so the standing rule to drive the repo through make targets rather than the
underlying tool could not be followed for either.
It matters most for the build: a bare `docker build .` fails closed on the
`CHECK_EPOCH` guard by design, so `script/cibuild` is one of only three
supported ways to build an image here, and it was the only one of the three
without a target while `make docker` had one.
The two targets are thin shims in the existing style and change nothing about
what the scripts do. `.PHONY` was already complete for the targets that existed
and now lists both new ones.
`README.md`'s Entrypoints section gains the script-to-target mapping so the two
documents agree, including the two names that do not match —
`script/install-precommit` is `make hooks`, `script/precommit` is
`make precommit` — plus a note that `make cibuild` is the slowest target because
it is the only one that runs two container builds, while still taking seconds
once the shared `script/bootstrap` layer is cached.
Two accuracy fixes to text the same section already carried:
- the `script/install-precommit` bullet said the installed hook runs
`script/check`. The script writes `script/precommit` into
`.git/hooks/pre-commit`, and its own header comment says so. Now corrected.
- the `Makefile` is described as listing the operations you are expected to run,
rather than as the authoritative list of everything the repo can do — not
literally true, since `script/projectname` has no target. No target was added
for it: it is an internal helper `script/docker` calls to compute a tag, and a
target would be noise in exactly the `make<tab>` listing this change exists to
make useful.
`TODO.md` sheds two now-false statements about `static/_headers`, both resolved
by the same production check: the Future Step asking someone to confirm the file
took effect, and the Status paragraph's "unverified in production until the next
deploy" clause. The headers are live at the edge on both hostnames — see
https://git.eeqj.de/sneak/lora.vegas/issues/14 . A commit that edits `TODO.md`
should not leave a known-false statement in it.
The README's `script/lint` bullet and the Docker/buildx prerequisite for the
pre-commit hook are deliberately untouched; they are owned by
https://git.eeqj.de/sneak/lora.vegas/issues/40 . The clone URL and the omitted
Entrypoints bullets are owned by
https://git.eeqj.de/sneak/lora.vegas/issues/36 .
### Verification
`make check` green on the pushed tree: 12.0s wall, lint layer executed rather
than replayed — `RUN echo "lint epoch: 1786370238510704421432841" && hugo
--minify --printPathWarnings` with `RUN script/bootstrap` `CACHED` above it,
hugo's build table printed (`Pages │ 3`), and `All matched files use Prettier
code style!` from the host `script/fmt-check`. `make fmt` run; tree is
prettier-clean.
The timing claim in the README is measured, not asserted. `make cibuild` on a
warm `script/bootstrap` layer, two runs on this host:
- 8.5s wall — lint epoch `1786369920780624631128596`, check epoch
`1786369924399735260128592`
- 17.6s wall — lint epoch `1786370037454771976238757`, check epoch
`1786370042637796958238753`
Both runs ran both builds for real: distinct epochs per build, `RUN
script/bootstrap` `CACHED` in each, no check layer served from cache below it,
hugo's build table and `All matched files use Prettier code style!` both
printed. The spread between the two runs is host load, not caching, which is why
the README says "seconds" rather than a figure. Independent figures agree: 10.3s
measured by the reviewer, 19s for this repo's own `check` job.
No cold-cache number is claimed. The README points at the pinned-Hugo compile it
already documents 48 lines above for `make check`, and the "paid once rather
than twice" part is verified structurally rather than by timing: the first four
instructions of `Dockerfile.lint` are byte-identical to the main `Dockerfile`'s,
and layers 6 through 9 report `CACHED` in both builds of every run above.
script/cibuild and script/precommit both existed and were already the
documented CI and pre-commit entrypoints, but neither had a Makefile
target, so the standing rule to drive the repo through make targets
rather than the underlying tool could not be followed for either.
It matters most for the build. A bare `docker build .` fails closed on
the CHECK_EPOCH guard by design, so script/cibuild is one of only three
supported ways to build an image here, and it was the only one of the
three without a target while `make docker` had one.
The two targets are thin shims in the same style as every other target
and change nothing about what the scripts do. .PHONY was already
complete for the targets that existed and now lists both new ones.
README.md's Entrypoints section gains the script-to-target mapping so
the two documents agree, including the two names that do not match:
script/install-precommit is `make hooks`, and script/precommit is
`make precommit`. It also warns that `make cibuild` runs two container
builds and costs minutes, so nobody types it expecting the runtime the
other make targets have.
clawbot
self-assigned this 2026-08-10 15:40:31 +02:00
Review of 341c8af — FAIL (needs-rework). Two README accuracy defects; everything else passes.
1. README.md:90-92 — "budget minutes" is false on the common path and contradicts the same file.
The new paragraph says make cibuild "runs two container builds rather than anything on the host, so budget minutes, not the seconds a make-shaped command usually implies." Two container builds is correct. "Budget minutes" is true only on a machine with no cached script/bootstrap layer — i.e. the first build ever. Measured independently on this head commit: make cibuild 10.3s wall, make precommit 4.0s, and this repo's own check / check job on 341c8af reports "Successful in 19s". The PR body's own evidence says 9.8s in the same breath as the doc claim. README.md:42-45 already states the rule correctly for make check — "On a machine that has never built the image, the first run compiles the pinned Hugo from source, which takes minutes; later runs reuse that cached layer" — so the new paragraph contradicts accurate text 48 lines above it. Acceptable: qualify cold vs warm the way the Getting Started paragraph already does, or drop the absolute and say it is the slowest target because it is two container builds plus an image export.
2. README.md:80-81 vs README.md:86 — the Entrypoints section now gives two different answers for what the pre-commit hook runs.
The pre-existing bullet reads "script/install-precommit — install the git pre-commit hook that runs script/check". script/install-precommit actually writes #!/bin/sh / set -e / script/precommit, and the script's own header comment says script/precommit. This commit adds, four lines below, "script/precommit, which is what the installed hook runs". The wrong claim and the right one now sit in one section. Neither #36 (SSH clone URL plus the omitted script/precommit and script/projectname bullets) nor #40 (the script/lint bullet) owns this line, so it is unowned. Given the commit's stated purpose is making the two documents agree, it should not leave the README disagreeing with itself. Acceptable: script/check becomes script/precommit in that bullet.
Notes, not blocking.
The new sentence "the Makefile is the authoritative list of what this repo can do" is not literally true: script/projectname exists with no make target. Adding one is out of scope here and no issue owns it.
Since #38 the installed hook reaches docker build via script/precommit to script/check to script/lint, so committing now requires a Docker daemon and the first commit on a cold machine compiles Hugo from source. script/check's own comment says this; the README does not. Pre-existing, but this PR is the one that documents the hook path.
Verified and passing..PHONY is exactly complete — 12 targets defined, 12 declared, no gap in either direction, new entries in definition order. Shims match the existing style. make cibuild reproduced independently rather than taken on trust: one invocation, 10.3s, two builds, distinct epochs 17863694948740640243979767 (lint) and 17863694970500381513979763 (check), RUN script/bootstrapCACHED in both, both check layers DONE and not CACHED, hugo's build table and All matched files use Prettier code style! both printed — the execution claim holds. make precommit green on a clean tree with the lint layer genuinely re-executing. make check and formatting clean. TODO.md's new Next Step is the top item of the startable Future Steps group, not from ## Blocked. script/cibuild, script/precommit, the README script/lint bullet and the clone URL are all untouched. Commit message carries (closes #34), no attribution trailers. CI green on 341c8af (19s; it sat queued about 7 minutes first). Mergeable, fast-forward onto main. Deploy path proven unaffected rather than assumed: .gitea/workflows/deploy.yml runs script/bootstrap then script/test, and the rendered public/ from 341c8af is byte-for-byte identical to that from 910f343.
Review of `341c8af` — **FAIL (`needs-rework`)**. Two README accuracy defects; everything else passes.
**1. `README.md:90-92` — "budget minutes" is false on the common path and contradicts the same file.**
The new paragraph says `make cibuild` "runs two container builds rather than anything on the host, so budget minutes, not the seconds a `make`-shaped command usually implies." Two container builds is correct. "Budget minutes" is true only on a machine with no cached `script/bootstrap` layer — i.e. the first build ever. Measured independently on this head commit: `make cibuild` 10.3s wall, `make precommit` 4.0s, and this repo's own `check / check` job on `341c8af` reports "Successful in 19s". The PR body's own evidence says 9.8s in the same breath as the doc claim. `README.md:42-45` already states the rule correctly for `make check` — "On a machine that has never built the image, the first run compiles the pinned Hugo from source, which takes minutes; later runs reuse that cached layer" — so the new paragraph contradicts accurate text 48 lines above it. Acceptable: qualify cold vs warm the way the Getting Started paragraph already does, or drop the absolute and say it is the slowest target because it is two container builds plus an image export.
**2. `README.md:80-81` vs `README.md:86` — the Entrypoints section now gives two different answers for what the pre-commit hook runs.**
The pre-existing bullet reads "`script/install-precommit` — install the git pre-commit hook that runs `script/check`". `script/install-precommit` actually writes `#!/bin/sh` / `set -e` / `script/precommit`, and the script's own header comment says `script/precommit`. This commit adds, four lines below, "`script/precommit`, which is what the installed hook runs". The wrong claim and the right one now sit in one section. Neither https://git.eeqj.de/sneak/lora.vegas/issues/36 (SSH clone URL plus the omitted `script/precommit` and `script/projectname` bullets) nor https://git.eeqj.de/sneak/lora.vegas/issues/40 (the `script/lint` bullet) owns this line, so it is unowned. Given the commit's stated purpose is making the two documents agree, it should not leave the README disagreeing with itself. Acceptable: `script/check` becomes `script/precommit` in that bullet.
**Notes, not blocking.**
- The new sentence "the `Makefile` is the authoritative list of what this repo can do" is not literally true: `script/projectname` exists with no make target. Adding one is out of scope here and no issue owns it.
- Since https://git.eeqj.de/sneak/lora.vegas/issues/38 the installed hook reaches `docker build` via `script/precommit` to `script/check` to `script/lint`, so committing now requires a Docker daemon and the first commit on a cold machine compiles Hugo from source. `script/check`'s own comment says this; the README does not. Pre-existing, but this PR is the one that documents the hook path.
**Verified and passing.** `.PHONY` is exactly complete — 12 targets defined, 12 declared, no gap in either direction, new entries in definition order. Shims match the existing style. `make cibuild` reproduced independently rather than taken on trust: one invocation, 10.3s, two builds, distinct epochs `17863694948740640243979767` (lint) and `17863694970500381513979763` (check), `RUN script/bootstrap` `CACHED` in both, both check layers `DONE` and not `CACHED`, hugo's build table and `All matched files use Prettier code style!` both printed — the execution claim holds. `make precommit` green on a clean tree with the lint layer genuinely re-executing. `make check` and formatting clean. `TODO.md`'s new Next Step is the top item of the startable Future Steps group, not from `## Blocked`. `script/cibuild`, `script/precommit`, the README `script/lint` bullet and the clone URL are all untouched. Commit message carries ` (closes #34)`, no attribution trailers. CI green on `341c8af` (19s; it sat queued about 7 minutes first). Mergeable, fast-forward onto `main`. Deploy path proven unaffected rather than assumed: `.gitea/workflows/deploy.yml` runs `script/bootstrap` then `script/test`, and the rendered `public/` from `341c8af` is byte-for-byte identical to that from `910f343`.
Manager note. Review FAILED; needs-rework. Rework going to a fresh implementer.
Both findings are accepted. Finding 1 is the notable one: the commit asserts make cibuild "costs minutes" in the same breath as the PR body reporting 9.8s, and 48 lines above it the README already gets this right for make check by distinguishing the cold first build from warm runs. A commit whose purpose is making two documents agree cannot ship a new sentence that contradicts the file it is in.
On the reviewer's open question about "the Makefile is the authoritative list of what this repo can do" versus script/projectname having no target: soften the sentence, do not add a make projectname target. script/projectname is an internal helper that script/docker calls to compute a tag, not an operation anyone runs, and a target for it would be noise in exactly the make<tab> listing this issue is trying to make useful.
Not folding in the pre-commit Docker/buildx prerequisite the reviewer raises as non-blocking, despite it being adjacent text: it is #40 , and two commits editing the same README paragraph would collide for no gain. It is pre-existing, not introduced here.
Manager note. Review FAILED; `needs-rework`. Rework going to a fresh implementer.
Both findings are accepted. Finding 1 is the notable one: the commit asserts `make cibuild` "costs minutes" in the same breath as the PR body reporting 9.8s, and 48 lines above it the README already gets this right for `make check` by distinguishing the cold first build from warm runs. A commit whose purpose is making two documents agree cannot ship a new sentence that contradicts the file it is in.
On the reviewer's open question about "the `Makefile` is the authoritative list of what this repo can do" versus `script/projectname` having no target: soften the sentence, do not add a `make projectname` target. `script/projectname` is an internal helper that `script/docker` calls to compute a tag, not an operation anyone runs, and a target for it would be noise in exactly the `make<tab>` listing this issue is trying to make useful.
Not folding in the pre-commit Docker/buildx prerequisite the reviewer raises as non-blocking, despite it being adjacent text: it is https://git.eeqj.de/sneak/lora.vegas/issues/40 , and two commits editing the same README paragraph would collide for no gain. It is pre-existing, not introduced here.
Reworked. 341c8af amended to 2c8f382; still one commit on next, parent
still 910f343. Force-push preconditions were re-checked immediately before
pushing — origin/next was still exactly 341c8af and this PR was still open —
and the push used --force-with-lease against that SHA.
Finding 1 — fixed. The "budget minutes" absolute is gone. The paragraph now
reads: make cibuild is the slowest target because it is the only one that runs
two container builds, the two share the script/bootstrap layer byte-for-byte
so the pinned-Hugo compile is paid once per machine rather than twice, and once
that layer is cached a full run takes seconds. No new cold number is asserted —
it points at the compile the file already documents 48 lines above for make check, which is where you said the rule was already modelled correctly.
Measured rather than reasoned. make cibuild on a warm cache, twice on this
host: 8.5s and 17.6s. Both runs executed both builds — distinct epochs per build
(1786369920780624631128596 / 1786369924399735260128592, then 1786370037454771976238757 / 1786370042637796958238753), RUN script/bootstrapCACHED in each, no check layer served from cache below it,
hugo's build table and All matched files use Prettier code style! printed in
each. The 8.5-to-17.6 spread is host load, not caching, which is why the README
says "seconds" and not a figure. That brackets your 10.3s and the 19s CI job.
The "paid once rather than twice" clause is structural, not timed: the first
four instructions of Dockerfile.lint are byte-identical to the main Dockerfile's by design, and layers 6-9 report CACHED in both builds of both
runs.
Finding 2 — fixed. The script/install-precommit bullet now says script/precommit. That is what the script writes into .git/hooks/pre-commit
(printf '#!/bin/sh\nset -e\nscript/precommit\n') and what its own header
comment claims. The section no longer gives two answers.
Non-blocking note on "the authoritative list" — softened, no target added.
Per the manager ruling: the sentence now says the Makefile lists the
operations you are expected to run. No make projectname target — it is an
internal helper script/docker calls to compute a tag, not an operation anyone
runs, and a target would be noise in exactly the make<tab> listing this issue
exists to make useful.
Non-blocking note on the pre-commit Docker/buildx prerequisite — not folded
in, deliberately. It is #40 and two
commits editing the same paragraph would collide. Pre-existing, not introduced
here. The script/lint bullet remains untouched for the same reason.
Also in this commit, on instruction:TODO.md loses the stale Future Step
asking someone to confirm static/_headers took effect in production. It was
confirmed live on both hostnames on 2026-08-10, recorded at #14 . Noted in the commit body.
The TODO.md Completed Steps entry for this work carried the same "costs
minutes" claim the README did, so it was corrected in the same pass rather than
left to contradict the fixed README.
make check green on the pushed tree: 7.3s, lint layer executed with a fresh
epoch (1786370023804277711230036) above a CACHEDRUN script/bootstrap,
hugo's build table printed, All matched files use Prettier code style! from
the host check. make fmt run; tree is prettier-clean and git status empty.
One thing left alone that a reviewer may want to rule on: TODO.md's Status
paragraph still says the _headers file is "unverified in production until the
next deploy", which the same production check disproves. Out of the three-item
scope handed to me, so raised rather than changed.
Reworked. `341c8af` amended to `2c8f382`; still one commit on `next`, parent
still `910f343`. Force-push preconditions were re-checked immediately before
pushing — `origin/next` was still exactly `341c8af` and this PR was still open —
and the push used `--force-with-lease` against that SHA.
**Finding 1 — fixed.** The "budget minutes" absolute is gone. The paragraph now
reads: `make cibuild` is the slowest target because it is the only one that runs
two container builds, the two share the `script/bootstrap` layer byte-for-byte
so the pinned-Hugo compile is paid once per machine rather than twice, and once
that layer is cached a full run takes seconds. No new cold number is asserted —
it points at the compile the file already documents 48 lines above for
`make check`, which is where you said the rule was already modelled correctly.
Measured rather than reasoned. `make cibuild` on a warm cache, twice on this
host: 8.5s and 17.6s. Both runs executed both builds — distinct epochs per build
(`1786369920780624631128596` / `1786369924399735260128592`, then
`1786370037454771976238757` / `1786370042637796958238753`), `RUN
script/bootstrap` `CACHED` in each, no check layer served from cache below it,
hugo's build table and `All matched files use Prettier code style!` printed in
each. The 8.5-to-17.6 spread is host load, not caching, which is why the README
says "seconds" and not a figure. That brackets your 10.3s and the 19s CI job.
The "paid once rather than twice" clause is structural, not timed: the first
four instructions of `Dockerfile.lint` are byte-identical to the main
`Dockerfile`'s by design, and layers 6-9 report `CACHED` in both builds of both
runs.
**Finding 2 — fixed.** The `script/install-precommit` bullet now says
`script/precommit`. That is what the script writes into `.git/hooks/pre-commit`
(`printf '#!/bin/sh\nset -e\nscript/precommit\n'`) and what its own header
comment claims. The section no longer gives two answers.
**Non-blocking note on "the authoritative list" — softened, no target added.**
Per the manager ruling: the sentence now says the `Makefile` lists the
operations you are expected to run. No `make projectname` target — it is an
internal helper `script/docker` calls to compute a tag, not an operation anyone
runs, and a target would be noise in exactly the `make<tab>` listing this issue
exists to make useful.
**Non-blocking note on the pre-commit Docker/buildx prerequisite — not folded
in, deliberately.** It is https://git.eeqj.de/sneak/lora.vegas/issues/40 and two
commits editing the same paragraph would collide. Pre-existing, not introduced
here. The `script/lint` bullet remains untouched for the same reason.
**Also in this commit, on instruction:** `TODO.md` loses the stale Future Step
asking someone to confirm `static/_headers` took effect in production. It was
confirmed live on both hostnames on 2026-08-10, recorded at
https://git.eeqj.de/sneak/lora.vegas/issues/14 . Noted in the commit body.
The `TODO.md` Completed Steps entry for this work carried the same "costs
minutes" claim the README did, so it was corrected in the same pass rather than
left to contradict the fixed README.
`make check` green on the pushed tree: 7.3s, lint layer executed with a fresh
epoch (`1786370023804277711230036`) above a `CACHED` `RUN script/bootstrap`,
hugo's build table printed, `All matched files use Prettier code style!` from
the host check. `make fmt` run; tree is prettier-clean and `git status` empty.
One thing left alone that a reviewer may want to rule on: `TODO.md`'s Status
paragraph still says the `_headers` file is "unverified in production until the
next deploy", which the same production check disproves. Out of the three-item
scope handed to me, so raised rather than changed.
Follow-up amend on the manager ruling about the TODO.md Status paragraph. 2c8f382 amended to fd3cd4c; still one commit on next, parent still 910f343.
Preconditions re-checked immediately before pushing: origin/next was still
exactly 2c8f382 and this PR was still open. Pushed with --force-with-lease
against that SHA.
The Status paragraph's _headers clause changed from "unverified in production
until the next deploy" to "confirmed live in production on both hostnames". One
clause; the rest of the paragraph is untouched. TODO.md now makes the same
claim in both places it mentions the file, and neither is false.
make check re-run after the edit and green: 12.0s wall, lint layer executed
rather than replayed — fresh epoch 1786370238510704421432841 above a CACHED RUN script/bootstrap, hugo's own build table printed (Pages │ 3), and All matched files use Prettier code style! from the host script/fmt-check. make fmt run first; the markdown reflowed and the tree is prettier-clean with git status empty.
The PR body is updated to carry fd3cd4c and the current TODO.md description.
Follow-up amend on the manager ruling about the `TODO.md` Status paragraph.
`2c8f382` amended to `fd3cd4c`; still one commit on `next`, parent still
`910f343`.
Preconditions re-checked immediately before pushing: `origin/next` was still
exactly `2c8f382` and this PR was still open. Pushed with `--force-with-lease`
against that SHA.
The Status paragraph's `_headers` clause changed from "unverified in production
until the next deploy" to "confirmed live in production on both hostnames". One
clause; the rest of the paragraph is untouched. `TODO.md` now makes the same
claim in both places it mentions the file, and neither is false.
`make check` re-run after the edit and green: 12.0s wall, lint layer executed
rather than replayed — fresh epoch `1786370238510704421432841` above a `CACHED`
`RUN script/bootstrap`, hugo's own build table printed (`Pages │ 3`), and
`All matched files use Prettier code style!` from the host `script/fmt-check`.
`make fmt` run first; the markdown reflowed and the tree is prettier-clean with
`git status` empty.
The PR body is updated to carry `fd3cd4c` and the current `TODO.md` description.
Independent re-review of fd3cd4c — PASS (merge-ready). Both prior findings are closed, the two amends disturbed nothing, and the rest of the checklist holds: .PHONY exactly complete (12 defined, 12 declared, definition order), shims match house style, README and TODO.md internally consistent and free of the stale _headers claims, scope confined to Makefile/README.md/TODO.md with no make projectname target, script/cibuild and script/precommit untouched, commit carries (closes #34) with no attribution trailers, formatting clean, fast-forwardable onto main at 910f343, and check / check green on this head commit (Successful in 16s).
Deploy path proven, not assumed: .gitea/workflows/deploy.yml runs script/bootstrap then script/test, and the rendered public/ from fd3cd4c hashes byte-for-byte identical to the one from 910f343.
Two things worth stating rather than leaving implied.
The green was probed, not just observed.make cibuild in a fresh clone ran both builds for real — distinct epochs 1786370405436619916564273 (lint) and 1786370413965578498564266 (check), RUN script/bootstrapCACHED above and no check layer cached below in either, hugo's build table and All matched files use Prettier code style! both printed. Because a passing shim proves nothing about a failing one, both new targets were also driven with a planted defect: an unformatted TODO.md makes make precommit exit 2 at Makefile:31, and a malformed hugo.toml makes make cibuild exit 2 at Makefile:28 on the lint build. Both probes were reverted; nothing was committed or pushed.
The "paid once per machine rather than twice" claim is verified structurally, not measured cold. The first four instructions of Dockerfile.lint and the main Dockerfile are byte-identical (FROM the same digest, WORKDIR /src, COPY script/ script/, RUN script/bootstrap) over the same build context and the same builder, so the two builds resolve to the same cache record by construction — the Dockerfile's filename is not part of the key. Demonstrating it from an empty cache would mean destroying build cache shared with other work on this host, so it was not done; the claim rests on the instruction chain, which is sufficient for what the README asserts.
Independent re-review of `fd3cd4c` — **PASS (`merge-ready`)**. Both prior findings are closed, the two amends disturbed nothing, and the rest of the checklist holds: `.PHONY` exactly complete (12 defined, 12 declared, definition order), shims match house style, README and `TODO.md` internally consistent and free of the stale `_headers` claims, scope confined to `Makefile`/`README.md`/`TODO.md` with no `make projectname` target, `script/cibuild` and `script/precommit` untouched, commit carries ` (closes #34)` with no attribution trailers, formatting clean, fast-forwardable onto `main` at `910f343`, and `check / check` green on this head commit (`Successful in 16s`).
Deploy path proven, not assumed: `.gitea/workflows/deploy.yml` runs `script/bootstrap` then `script/test`, and the rendered `public/` from `fd3cd4c` hashes byte-for-byte identical to the one from `910f343`.
Two things worth stating rather than leaving implied.
**The green was probed, not just observed.** `make cibuild` in a fresh clone ran both builds for real — distinct epochs `1786370405436619916564273` (lint) and `1786370413965578498564266` (check), `RUN script/bootstrap` `CACHED` above and no check layer cached below in either, hugo's build table and `All matched files use Prettier code style!` both printed. Because a passing shim proves nothing about a failing one, both new targets were also driven with a planted defect: an unformatted `TODO.md` makes `make precommit` exit 2 at `Makefile:31`, and a malformed `hugo.toml` makes `make cibuild` exit 2 at `Makefile:28` on the lint build. Both probes were reverted; nothing was committed or pushed.
**The "paid once per machine rather than twice" claim is verified structurally, not measured cold.** The first four instructions of `Dockerfile.lint` and the main `Dockerfile` are byte-identical (`FROM` the same digest, `WORKDIR /src`, `COPY script/ script/`, `RUN script/bootstrap`) over the same build context and the same builder, so the two builds resolve to the same cache record by construction — the Dockerfile's filename is not part of the key. Demonstrating it from an empty cache would mean destroying build cache shared with other work on this host, so it was not done; the claim rests on the instruction chain, which is sufficient for what the README asserts.
Built public/ is byte-identical to 910f343, so the resulting deploy publishes nothing new — same low-risk profile as the last merge.
Two of the reviewer's four disclosures are being filed rather than dropped: the untagged script/cibuild build leaving a dangling image per run, which matters more now that make cibuild makes the CI build easy to run locally, and a documentation-hygiene item in TODO.md. The make test timeout gap is already tracked at #16 and needs nothing new.
Accepting the structural — rather than cold-cache — verification of the shared script/bootstrap layer. Demonstrating it from cold would mean destroying build cache shared with other sessions, which is not a trade worth making for a README sentence; the instruction prefix, context and builder are identical, and the Dockerfile filename is not part of the cache key.
Manager note. Re-review PASSED. Merging to `main`.
Built `public/` is byte-identical to `910f343`, so the resulting deploy publishes nothing new — same low-risk profile as the last merge.
Two of the reviewer's four disclosures are being filed rather than dropped: the untagged `script/cibuild` build leaving a dangling image per run, which matters more now that `make cibuild` makes the CI build easy to run locally, and a documentation-hygiene item in `TODO.md`. The `make test` timeout gap is already tracked at https://git.eeqj.de/sneak/lora.vegas/issues/16 and needs nothing new.
Accepting the structural — rather than cold-cache — verification of the shared `script/bootstrap` layer. Demonstrating it from cold would mean destroying build cache shared with other sessions, which is not a trade worth making for a README sentence; the instruction prefix, context and builder are identical, and the Dockerfile filename is not part of the cache key.
clawbot
merged commit 38b0bcf11d into main2026-08-10 16:14:54 +02:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Accumulating branch for the current cycle. Squash-merged units land here; this
PR is the milestone's route to
main.Carried so far
fd3cd4cAdd Makefile shims for cibuild and precommit (closes#34)
Makefile shims for
cibuildandprecommitscript/cibuildandscript/precommitboth existed and were already thedocumented CI and pre-commit entrypoints, but neither had a
Makefiletarget,so the standing rule to drive the repo through make targets rather than the
underlying tool could not be followed for either.
It matters most for the build: a bare
docker build .fails closed on theCHECK_EPOCHguard by design, soscript/cibuildis one of only threesupported ways to build an image here, and it was the only one of the three
without a target while
make dockerhad one.The two targets are thin shims in the existing style and change nothing about
what the scripts do.
.PHONYwas already complete for the targets that existedand now lists both new ones.
README.md's Entrypoints section gains the script-to-target mapping so the twodocuments agree, including the two names that do not match —
script/install-precommitismake hooks,script/precommitismake precommit— plus a note thatmake cibuildis the slowest target becauseit is the only one that runs two container builds, while still taking seconds
once the shared
script/bootstraplayer is cached.Two accuracy fixes to text the same section already carried:
script/install-precommitbullet said the installed hook runsscript/check. The script writesscript/precommitinto.git/hooks/pre-commit, and its own header comment says so. Now corrected.Makefileis described as listing the operations you are expected to run,rather than as the authoritative list of everything the repo can do — not
literally true, since
script/projectnamehas no target. No target was addedfor it: it is an internal helper
script/dockercalls to compute a tag, and atarget would be noise in exactly the
make<tab>listing this change exists tomake useful.
TODO.mdsheds two now-false statements aboutstatic/_headers, both resolvedby the same production check: the Future Step asking someone to confirm the file
took effect, and the Status paragraph's "unverified in production until the next
deploy" clause. The headers are live at the edge on both hostnames — see
#14 . A commit that edits
TODO.mdshould not leave a known-false statement in it.
The README's
script/lintbullet and the Docker/buildx prerequisite for thepre-commit hook are deliberately untouched; they are owned by
#40 . The clone URL and the omitted
Entrypoints bullets are owned by
#36 .
Verification
make checkgreen on the pushed tree: 12.0s wall, lint layer executed ratherthan replayed —
RUN echo "lint epoch: 1786370238510704421432841" && hugo --minify --printPathWarningswithRUN script/bootstrapCACHEDabove it,hugo's build table printed (
Pages │ 3), andAll matched files use Prettier code style!from the hostscript/fmt-check.make fmtrun; tree isprettier-clean.
The timing claim in the README is measured, not asserted.
make cibuildon awarm
script/bootstraplayer, two runs on this host:1786369920780624631128596, check epoch17863699243997352601285921786370037454771976238757, check epoch1786370042637796958238753Both runs ran both builds for real: distinct epochs per build,
RUN script/bootstrapCACHEDin each, no check layer served from cache below it,hugo's build table and
All matched files use Prettier code style!bothprinted. The spread between the two runs is host load, not caching, which is why
the README says "seconds" rather than a figure. Independent figures agree: 10.3s
measured by the reviewer, 19s for this repo's own
checkjob.No cold-cache number is claimed. The README points at the pinned-Hugo compile it
already documents 48 lines above for
make check, and the "paid once ratherthan twice" part is verified structurally rather than by timing: the first four
instructions of
Dockerfile.lintare byte-identical to the mainDockerfile's,and layers 6 through 9 report
CACHEDin both builds of every run above.Review of
341c8af— FAIL (needs-rework). Two README accuracy defects; everything else passes.1.
README.md:90-92— "budget minutes" is false on the common path and contradicts the same file.The new paragraph says
make cibuild"runs two container builds rather than anything on the host, so budget minutes, not the seconds amake-shaped command usually implies." Two container builds is correct. "Budget minutes" is true only on a machine with no cachedscript/bootstraplayer — i.e. the first build ever. Measured independently on this head commit:make cibuild10.3s wall,make precommit4.0s, and this repo's owncheck / checkjob on341c8afreports "Successful in 19s". The PR body's own evidence says 9.8s in the same breath as the doc claim.README.md:42-45already states the rule correctly formake check— "On a machine that has never built the image, the first run compiles the pinned Hugo from source, which takes minutes; later runs reuse that cached layer" — so the new paragraph contradicts accurate text 48 lines above it. Acceptable: qualify cold vs warm the way the Getting Started paragraph already does, or drop the absolute and say it is the slowest target because it is two container builds plus an image export.2.
README.md:80-81vsREADME.md:86— the Entrypoints section now gives two different answers for what the pre-commit hook runs.The pre-existing bullet reads "
script/install-precommit— install the git pre-commit hook that runsscript/check".script/install-precommitactually writes#!/bin/sh/set -e/script/precommit, and the script's own header comment saysscript/precommit. This commit adds, four lines below, "script/precommit, which is what the installed hook runs". The wrong claim and the right one now sit in one section. Neither #36 (SSH clone URL plus the omittedscript/precommitandscript/projectnamebullets) nor #40 (thescript/lintbullet) owns this line, so it is unowned. Given the commit's stated purpose is making the two documents agree, it should not leave the README disagreeing with itself. Acceptable:script/checkbecomesscript/precommitin that bullet.Notes, not blocking.
Makefileis the authoritative list of what this repo can do" is not literally true:script/projectnameexists with no make target. Adding one is out of scope here and no issue owns it.docker buildviascript/precommittoscript/checktoscript/lint, so committing now requires a Docker daemon and the first commit on a cold machine compiles Hugo from source.script/check's own comment says this; the README does not. Pre-existing, but this PR is the one that documents the hook path.Verified and passing.
.PHONYis exactly complete — 12 targets defined, 12 declared, no gap in either direction, new entries in definition order. Shims match the existing style.make cibuildreproduced independently rather than taken on trust: one invocation, 10.3s, two builds, distinct epochs17863694948740640243979767(lint) and17863694970500381513979763(check),RUN script/bootstrapCACHEDin both, both check layersDONEand notCACHED, hugo's build table andAll matched files use Prettier code style!both printed — the execution claim holds.make precommitgreen on a clean tree with the lint layer genuinely re-executing.make checkand formatting clean.TODO.md's new Next Step is the top item of the startable Future Steps group, not from## Blocked.script/cibuild,script/precommit, the READMEscript/lintbullet and the clone URL are all untouched. Commit message carries(closes #34), no attribution trailers. CI green on341c8af(19s; it sat queued about 7 minutes first). Mergeable, fast-forward ontomain. Deploy path proven unaffected rather than assumed:.gitea/workflows/deploy.ymlrunsscript/bootstrapthenscript/test, and the renderedpublic/from341c8afis byte-for-byte identical to that from910f343.Manager note. Review FAILED;
needs-rework. Rework going to a fresh implementer.Both findings are accepted. Finding 1 is the notable one: the commit asserts
make cibuild"costs minutes" in the same breath as the PR body reporting 9.8s, and 48 lines above it the README already gets this right formake checkby distinguishing the cold first build from warm runs. A commit whose purpose is making two documents agree cannot ship a new sentence that contradicts the file it is in.On the reviewer's open question about "the
Makefileis the authoritative list of what this repo can do" versusscript/projectnamehaving no target: soften the sentence, do not add amake projectnametarget.script/projectnameis an internal helper thatscript/dockercalls to compute a tag, not an operation anyone runs, and a target for it would be noise in exactly themake<tab>listing this issue is trying to make useful.Not folding in the pre-commit Docker/buildx prerequisite the reviewer raises as non-blocking, despite it being adjacent text: it is #40 , and two commits editing the same README paragraph would collide for no gain. It is pre-existing, not introduced here.
341c8afd76to2c8f3827ffReworked.
341c8afamended to2c8f382; still one commit onnext, parentstill
910f343. Force-push preconditions were re-checked immediately beforepushing —
origin/nextwas still exactly341c8afand this PR was still open —and the push used
--force-with-leaseagainst that SHA.Finding 1 — fixed. The "budget minutes" absolute is gone. The paragraph now
reads:
make cibuildis the slowest target because it is the only one that runstwo container builds, the two share the
script/bootstraplayer byte-for-byteso the pinned-Hugo compile is paid once per machine rather than twice, and once
that layer is cached a full run takes seconds. No new cold number is asserted —
it points at the compile the file already documents 48 lines above for
make check, which is where you said the rule was already modelled correctly.Measured rather than reasoned.
make cibuildon a warm cache, twice on thishost: 8.5s and 17.6s. Both runs executed both builds — distinct epochs per build
(
1786369920780624631128596/1786369924399735260128592, then1786370037454771976238757/1786370042637796958238753),RUN script/bootstrapCACHEDin each, no check layer served from cache below it,hugo's build table and
All matched files use Prettier code style!printed ineach. The 8.5-to-17.6 spread is host load, not caching, which is why the README
says "seconds" and not a figure. That brackets your 10.3s and the 19s CI job.
The "paid once rather than twice" clause is structural, not timed: the first
four instructions of
Dockerfile.lintare byte-identical to the mainDockerfile's by design, and layers 6-9 reportCACHEDin both builds of bothruns.
Finding 2 — fixed. The
script/install-precommitbullet now saysscript/precommit. That is what the script writes into.git/hooks/pre-commit(
printf '#!/bin/sh\nset -e\nscript/precommit\n') and what its own headercomment claims. The section no longer gives two answers.
Non-blocking note on "the authoritative list" — softened, no target added.
Per the manager ruling: the sentence now says the
Makefilelists theoperations you are expected to run. No
make projectnametarget — it is aninternal helper
script/dockercalls to compute a tag, not an operation anyoneruns, and a target would be noise in exactly the
make<tab>listing this issueexists to make useful.
Non-blocking note on the pre-commit Docker/buildx prerequisite — not folded
in, deliberately. It is #40 and two
commits editing the same paragraph would collide. Pre-existing, not introduced
here. The
script/lintbullet remains untouched for the same reason.Also in this commit, on instruction:
TODO.mdloses the stale Future Stepasking someone to confirm
static/_headerstook effect in production. It wasconfirmed live on both hostnames on 2026-08-10, recorded at
#14 . Noted in the commit body.
The
TODO.mdCompleted Steps entry for this work carried the same "costsminutes" claim the README did, so it was corrected in the same pass rather than
left to contradict the fixed README.
make checkgreen on the pushed tree: 7.3s, lint layer executed with a freshepoch (
1786370023804277711230036) above aCACHEDRUN script/bootstrap,hugo's build table printed,
All matched files use Prettier code style!fromthe host check.
make fmtrun; tree is prettier-clean andgit statusempty.One thing left alone that a reviewer may want to rule on:
TODO.md's Statusparagraph still says the
_headersfile is "unverified in production until thenext deploy", which the same production check disproves. Out of the three-item
scope handed to me, so raised rather than changed.
2c8f3827fftofd3cd4c18cFollow-up amend on the manager ruling about the
TODO.mdStatus paragraph.2c8f382amended tofd3cd4c; still one commit onnext, parent still910f343.Preconditions re-checked immediately before pushing:
origin/nextwas stillexactly
2c8f382and this PR was still open. Pushed with--force-with-leaseagainst that SHA.
The Status paragraph's
_headersclause changed from "unverified in productionuntil the next deploy" to "confirmed live in production on both hostnames". One
clause; the rest of the paragraph is untouched.
TODO.mdnow makes the sameclaim in both places it mentions the file, and neither is false.
make checkre-run after the edit and green: 12.0s wall, lint layer executedrather than replayed — fresh epoch
1786370238510704421432841above aCACHEDRUN script/bootstrap, hugo's own build table printed (Pages │ 3), andAll matched files use Prettier code style!from the hostscript/fmt-check.make fmtrun first; the markdown reflowed and the tree is prettier-clean withgit statusempty.The PR body is updated to carry
fd3cd4cand the currentTODO.mddescription.Independent re-review of
fd3cd4c— PASS (merge-ready). Both prior findings are closed, the two amends disturbed nothing, and the rest of the checklist holds:.PHONYexactly complete (12 defined, 12 declared, definition order), shims match house style, README andTODO.mdinternally consistent and free of the stale_headersclaims, scope confined toMakefile/README.md/TODO.mdwith nomake projectnametarget,script/cibuildandscript/precommituntouched, commit carries(closes #34)with no attribution trailers, formatting clean, fast-forwardable ontomainat910f343, andcheck / checkgreen on this head commit (Successful in 16s).Deploy path proven, not assumed:
.gitea/workflows/deploy.ymlrunsscript/bootstrapthenscript/test, and the renderedpublic/fromfd3cd4chashes byte-for-byte identical to the one from910f343.Two things worth stating rather than leaving implied.
The green was probed, not just observed.
make cibuildin a fresh clone ran both builds for real — distinct epochs1786370405436619916564273(lint) and1786370413965578498564266(check),RUN script/bootstrapCACHEDabove and no check layer cached below in either, hugo's build table andAll matched files use Prettier code style!both printed. Because a passing shim proves nothing about a failing one, both new targets were also driven with a planted defect: an unformattedTODO.mdmakesmake precommitexit 2 atMakefile:31, and a malformedhugo.tomlmakesmake cibuildexit 2 atMakefile:28on the lint build. Both probes were reverted; nothing was committed or pushed.The "paid once per machine rather than twice" claim is verified structurally, not measured cold. The first four instructions of
Dockerfile.lintand the mainDockerfileare byte-identical (FROMthe same digest,WORKDIR /src,COPY script/ script/,RUN script/bootstrap) over the same build context and the same builder, so the two builds resolve to the same cache record by construction — the Dockerfile's filename is not part of the key. Demonstrating it from an empty cache would mean destroying build cache shared with other work on this host, so it was not done; the claim rests on the instruction chain, which is sufficient for what the README asserts.Manager note. Re-review PASSED. Merging to
main.Built
public/is byte-identical to910f343, so the resulting deploy publishes nothing new — same low-risk profile as the last merge.Two of the reviewer's four disclosures are being filed rather than dropped: the untagged
script/cibuildbuild leaving a dangling image per run, which matters more now thatmake cibuildmakes the CI build easy to run locally, and a documentation-hygiene item inTODO.md. Themake testtimeout gap is already tracked at #16 and needs nothing new.Accepting the structural — rather than cold-cache — verification of the shared
script/bootstraplayer. Demonstrating it from cold would mean destroying build cache shared with other sessions, which is not a trade worth making for a README sentence; the instruction prefix, context and builder are identical, and the Dockerfile filename is not part of the cache key.clawbot referenced this pull request2026-09-03 15:17:15 +02:00