scripts/tests/generated-child_test.sh substitutes Dockerfile into the throwaway child (added in 2c4158a), but nothing ever executes or parses it. The harness runs templ generate, go list, go build, go vet and golangci-lint — none of which read the Dockerfile. So the build path it references is substituted and then never checked.
Demonstrated on main (2c4158a) by breaking it on purpose:
RUN templ generate &&CGO_ENABLED=0 go build -trimpath -ldflags='-s -w' -o /out/app ./cmd/__PROJECT_NAME__
A wrong path there produces a child repo that passes task check and fails in Build & Import, which in the template is always skipped — so the template can never see it.
Why this is worth closing
This is the estate's "rename leftovers hide in the Dockerfile" footgun, and it is the one file where a stale cmd/ path survives every Go-level gate by construction. template-go-agent#1/#2 were the same shape: a defect in the entrypoint that the repo's own green CI could not reach.
Note the build job calls .gitea/build-image.sh (infra#309), so the real build is not inlined here — but the ./cmd/<name> argument in the Dockerfile still is.
Options
Cheapest, no daemon: assert that the path the Dockerfile builds exists in the substituted child — extract the go build ... ./cmd/X argument and check [ -d "$tmp/cmd/X" ]. Catches the rename-leftover class, runs in milliseconds, no container runtime needed in task check.
Fuller: actually build the image in the child inside CI. More faithful, but it puts a container build in task check, which is a real cost on every local run and needs a runtime that may not be present — and the harness's missing-tool branch is now (correctly) a hard failure, so that would have to be handled deliberately.
Option 1 is probably the right trade; option 2 arguably belongs in the child's own CI rather than the template's gate.
Done when
Changing the ./cmd/... path in Dockerfile to something that does not exist makes task check fail, demonstrated by breaking it rather than by reading the script
A correct Dockerfile still passes, and the check does not require a container runtime to be installed (or, if it does, its absence is a FAIL with a stated reason — never a skip)
The same gap is closed in mathias/template-go-agent, whose harness shares this lineage
Source
Found while gating #13 (which closed#8 and #12). Raised there as a note-only finding — it is not a regression from that PR, which improved matters by substituting the file at all. Related: template-go-agent#1, #2, infra#309.
## The gap
`scripts/tests/generated-child_test.sh` substitutes `Dockerfile` into the throwaway child (added in `2c4158a`), but nothing ever *executes* or parses it. The harness runs `templ generate`, `go list`, `go build`, `go vet` and `golangci-lint` — none of which read the Dockerfile. So the build path it references is substituted and then never checked.
Demonstrated on `main` (`2c4158a`) by breaking it on purpose:
```
$ sed -i 's|./cmd/__PROJECT_NAME__|./cmd/does_not_exist|' Dockerfile
$ bash scripts/tests/generated-child_test.sh
...
5 passed, 0 failed (exit 0)
```
`Dockerfile:8` is:
```dockerfile
RUN templ generate && CGO_ENABLED=0 go build -trimpath -ldflags='-s -w' -o /out/app ./cmd/__PROJECT_NAME__
```
A wrong path there produces a child repo that passes `task check` and fails in `Build & Import`, which in the template is always skipped — so the template can never see it.
## Why this is worth closing
This is the estate's "rename leftovers hide in the Dockerfile" footgun, and it is the one file where a stale `cmd/` path survives every Go-level gate by construction. `template-go-agent#1`/`#2` were the same shape: a defect in the entrypoint that the repo's own green CI could not reach.
Note the build job calls `.gitea/build-image.sh` (infra#309), so the real build is not inlined here — but the `./cmd/<name>` argument in the Dockerfile still is.
## Options
1. **Cheapest, no daemon:** assert that the path the Dockerfile builds exists in the substituted child — extract the `go build ... ./cmd/X` argument and check `[ -d "$tmp/cmd/X" ]`. Catches the rename-leftover class, runs in milliseconds, no container runtime needed in `task check`.
2. **Fuller:** actually build the image in the child inside CI. More faithful, but it puts a container build in `task check`, which is a real cost on every local run and needs a runtime that may not be present — and the harness's missing-tool branch is now (correctly) a hard failure, so that would have to be handled deliberately.
Option 1 is probably the right trade; option 2 arguably belongs in the child's own CI rather than the template's gate.
## Done when
- Changing the `./cmd/...` path in `Dockerfile` to something that does not exist makes `task check` fail, demonstrated by breaking it rather than by reading the script
- A correct Dockerfile still passes, and the check does not require a container runtime to be installed (or, if it does, its absence is a FAIL with a stated reason — never a skip)
- The same gap is closed in `mathias/template-go-agent`, whose harness shares this lineage
## Source
Found while gating #13 (which closed #8 and #12). Raised there as a note-only finding — it is not a regression from that PR, which improved matters by substituting the file at all. Related: `template-go-agent#1`, `#2`, infra#309.
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.
The gap
scripts/tests/generated-child_test.shsubstitutesDockerfileinto the throwaway child (added in2c4158a), but nothing ever executes or parses it. The harness runstempl generate,go list,go build,go vetandgolangci-lint— none of which read the Dockerfile. So the build path it references is substituted and then never checked.Demonstrated on
main(2c4158a) by breaking it on purpose:Dockerfile:8is:A wrong path there produces a child repo that passes
task checkand fails inBuild & Import, which in the template is always skipped — so the template can never see it.Why this is worth closing
This is the estate's "rename leftovers hide in the Dockerfile" footgun, and it is the one file where a stale
cmd/path survives every Go-level gate by construction.template-go-agent#1/#2were the same shape: a defect in the entrypoint that the repo's own green CI could not reach.Note the build job calls
.gitea/build-image.sh(infra#309), so the real build is not inlined here — but the./cmd/<name>argument in the Dockerfile still is.Options
go build ... ./cmd/Xargument and check[ -d "$tmp/cmd/X" ]. Catches the rename-leftover class, runs in milliseconds, no container runtime needed intask check.task check, which is a real cost on every local run and needs a runtime that may not be present — and the harness's missing-tool branch is now (correctly) a hard failure, so that would have to be handled deliberately.Option 1 is probably the right trade; option 2 arguably belongs in the child's own CI rather than the template's gate.
Done when
./cmd/...path inDockerfileto something that does not exist makestask checkfail, demonstrated by breaking it rather than by reading the scriptmathias/template-go-agent, whose harness shares this lineageSource
Found while gating #13 (which closed #8 and #12). Raised there as a note-only finding — it is not a regression from that PR, which improved matters by substituting the file at all. Related:
template-go-agent#1,#2, infra#309.