Filed by the top-level sdlc manager. sneak's standing order (2026-09-29): all fleet work on sandcastle stays under 10 GiB of RAM combined and each worker under 2-3 GiB at once, by not doing RAM-intensive things.
webhooker's make test (go test -v -race -timeout 90s ./...) breaks that on its own: the handlers test binary reached 6.7 GiB resident at about 09:00 UTC and 4.8 GiB at 09:12 UTC, both during reviews on sandcastle, and the database test binary 2.7 GiB. Every worker and reviewer that runs the gate goes over the cap.
Definition of done:
The peak resident memory of the whole make test run is under 2 GiB, measured (for example with /usr/bin/time -v) and recorded here before and after.
The cause is found and fixed in the tests or the code, not hidden: -race stays, no test is deleted or skipped, and coverage does not drop. If a test must hold large data, it streams it or uses a smaller size that still exercises the same path.
If the memory comes from the product code rather than the tests (a leak, unbounded buffers), that is fixed and says so.
Model: opus-5-5
Filed by the top-level sdlc manager. sneak's standing order (2026-09-29): all fleet work on sandcastle stays under 10 GiB of RAM combined and each worker under 2-3 GiB at once, by not doing RAM-intensive things.
webhooker's `make test` (`go test -v -race -timeout 90s ./...`) breaks that on its own: the `handlers` test binary reached 6.7 GiB resident at about 09:00 UTC and 4.8 GiB at 09:12 UTC, both during reviews on sandcastle, and the `database` test binary 2.7 GiB. Every worker and reviewer that runs the gate goes over the cap.
Definition of done:
- The peak resident memory of the whole `make test` run is under 2 GiB, measured (for example with `/usr/bin/time -v`) and recorded here before and after.
- The cause is found and fixed in the tests or the code, not hidden: `-race` stays, no test is deleted or skipped, and coverage does not drop. If a test must hold large data, it streams it or uses a smaller size that still exercises the same path.
- If the memory comes from the product code rather than the tests (a leak, unbounded buffers), that is fixed and says so.
Model: opus-5-5
clawbot
self-assigned this 2026-09-29 11:11:27 +02:00
Plan. The before figures are the ones on this issue: handlers 6.7 GiB and 4.8 GiB, database 2.7 GiB. Do not run the whole suite to re-measure them; that alone breaks the cap.
Likely causes, to confirm by measuring one package or one test at a time (for example /usr/bin/time -v, or go test -run <Test> -memprofile on a single package):
Hashing:internal/database/password.go hashes with Argon2id at argon2Memory = 64 MB per hash. Every test that creates or checks a password pays that, several times over under -race, and 32 test files in internal/handlers and internal/database call t.Parallel().
Packages at once:script/test runs go test ./..., which runs several package test binaries at the same time, so the peak is their sum.
Fix what the measurements show, plainly:
Test-only hashing cost: for example, a lower-cost setting that only tests use, injected through the existing constructor or config, while the product default stays 64 MB. One test must keep exercising the real parameters, so production hashing stays covered. Admin login security is settled, so the product's hashing does not change.
Parallelism: bound t.Parallel() or the package parallelism only if that is what the numbers point to. make test must stay inside the repo's 60 s cap (REPO_POLICIES.md); say its duration before and after in one line on the PR.
Product code: if the memory comes from the product rather than the tests, fix it there and say so.
Unchanged: -race, every test, and coverage.
After the fix, measure the whole make test peak once, through the webhooker gate lock. Record the before and after figures on this issue in one short comment; that is the one place the issue asks for numbers. If the after figure is still over 2 GiB, stop and say so here.
Model: opus-5-5
Plan. The before figures are the ones on this issue: `handlers` 6.7 GiB and 4.8 GiB, `database` 2.7 GiB. Do not run the whole suite to re-measure them; that alone breaks the cap.
Likely causes, to confirm by measuring one package or one test at a time (for example `/usr/bin/time -v`, or `go test -run <Test> -memprofile` on a single package):
- **Hashing:** `internal/database/password.go` hashes with Argon2id at `argon2Memory = 64 MB` per hash. Every test that creates or checks a password pays that, several times over under `-race`, and 32 test files in `internal/handlers` and `internal/database` call `t.Parallel()`.
- **Packages at once:** `script/test` runs `go test ./...`, which runs several package test binaries at the same time, so the peak is their sum.
Fix what the measurements show, plainly:
- **Test-only hashing cost:** for example, a lower-cost setting that only tests use, injected through the existing constructor or config, while the product default stays `64 MB`. One test must keep exercising the real parameters, so production hashing stays covered. Admin login security is settled, so the product's hashing does not change.
- **Parallelism:** bound `t.Parallel()` or the package parallelism only if that is what the numbers point to. `make test` must stay inside the repo's 60 s cap (`REPO_POLICIES.md`); say its duration before and after in one line on the PR.
- **Product code:** if the memory comes from the product rather than the tests, fix it there and say so.
Unchanged: `-race`, every test, and coverage.
After the fix, measure the whole `make test` peak once, through the webhooker gate lock. Record the before and after figures on this issue in one short comment; that is the one place the issue asks for numbers. If the after figure is still over 2 GiB, stop and say so here.
Model: opus-5-5
Before, not re-measured (running the old suite whole would itself break the cap). Peak: the figures in this issue's description, per test binary: internal/handlers 6.7 GiB and 4.8 GiB, internal/database 2.7 GiB, with every other package's test binary linking and running at the same time on top. Duration, as last recorded on #198: about 22 s with a warm build cache, 62.8 to 72.1 s in a cold container build.
Model: opus-5-5
Before, not re-measured (running the old suite whole would itself break the cap). Peak: the figures in this issue's description, per test binary: `internal/handlers` 6.7 GiB and 4.8 GiB, `internal/database` 2.7 GiB, with every other package's test binary linking and running at the same time on top. Duration, as last recorded on https://git.eeqj.de/sneak/webhooker/issues/198: about 22 s with a warm build cache, 62.8 to 72.1 s in a cold container build.
Model: opus-5-5
After, on 0a112fa (#404), one run through the gate lock with a warm build cache, summing every process in the run: peak 1439 MiB, make test 16.6 s. The largest single process was the internal/handlers test binary at 665 MiB. With a cold build cache (measured before the final rebase): peak 1253 MiB, 124 s at a host load average near 110.
Model: opus-5-5
After, on `0a112fa` (https://git.eeqj.de/sneak/webhooker/pulls/404), one run through the gate lock with a warm build cache, summing every process in the run: peak 1439 MiB, `make test` 16.6 s. The largest single process was the `internal/handlers` test binary at 665 MiB. With a cold build cache (measured before the final rebase): peak 1253 MiB, 124 s at a host load average near 110.
Model: opus-5-5
Built in #404. The memory came from the tests, not the product: every test that starts a database hashes the admin password with Argon2id at 64 MB, and dozens of those tests ran at once under -race. The test packages that hash now lower that cost to 1 MB before any test runs, one test still hashes and verifies at the shipped parameters, and script/test runs at most four packages and eight parallel tests at once. The product's hashing parameters are unchanged.
Judgement call: nothing makes a new test package that starts a database lower the cost; one that does not pays the full 64 MB per start.
Judgement call: limiting packages to four also limits compilation, so a cold build cache compiles more slowly.
Model: opus-5-5
Built in https://git.eeqj.de/sneak/webhooker/pulls/404. The memory came from the tests, not the product: every test that starts a database hashes the admin password with Argon2id at 64 MB, and dozens of those tests ran at once under `-race`. The test packages that hash now lower that cost to 1 MB before any test runs, one test still hashes and verifies at the shipped parameters, and `script/test` runs at most four packages and eight parallel tests at once. The product's hashing parameters are unchanged.
- Judgement call: nothing makes a new test package that starts a database lower the cost; one that does not pays the full 64 MB per start.
- Judgement call: limiting packages to four also limits compilation, so a cold build cache compiles more slowly.
Model: opus-5-5
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.
Filed by the top-level sdlc manager. sneak's standing order (2026-09-29): all fleet work on sandcastle stays under 10 GiB of RAM combined and each worker under 2-3 GiB at once, by not doing RAM-intensive things.
webhooker's
make test(go test -v -race -timeout 90s ./...) breaks that on its own: thehandlerstest binary reached 6.7 GiB resident at about 09:00 UTC and 4.8 GiB at 09:12 UTC, both during reviews on sandcastle, and thedatabasetest binary 2.7 GiB. Every worker and reviewer that runs the gate goes over the cap.Definition of done:
make testrun is under 2 GiB, measured (for example with/usr/bin/time -v) and recorded here before and after.-racestays, no test is deleted or skipped, and coverage does not drop. If a test must hold large data, it streams it or uses a smaller size that still exercises the same path.Model: opus-5-5
Plan. The before figures are the ones on this issue:
handlers6.7 GiB and 4.8 GiB,database2.7 GiB. Do not run the whole suite to re-measure them; that alone breaks the cap.Likely causes, to confirm by measuring one package or one test at a time (for example
/usr/bin/time -v, orgo test -run <Test> -memprofileon a single package):internal/database/password.gohashes with Argon2id atargon2Memory = 64 MBper hash. Every test that creates or checks a password pays that, several times over under-race, and 32 test files ininternal/handlersandinternal/databasecallt.Parallel().script/testrunsgo test ./..., which runs several package test binaries at the same time, so the peak is their sum.Fix what the measurements show, plainly:
64 MB. One test must keep exercising the real parameters, so production hashing stays covered. Admin login security is settled, so the product's hashing does not change.t.Parallel()or the package parallelism only if that is what the numbers point to.make testmust stay inside the repo's 60 s cap (REPO_POLICIES.md); say its duration before and after in one line on the PR.Unchanged:
-race, every test, and coverage.After the fix, measure the whole
make testpeak once, through the webhooker gate lock. Record the before and after figures on this issue in one short comment; that is the one place the issue asks for numbers. If the after figure is still over 2 GiB, stop and say so here.Model: opus-5-5
Before, not re-measured (running the old suite whole would itself break the cap). Peak: the figures in this issue's description, per test binary:
internal/handlers6.7 GiB and 4.8 GiB,internal/database2.7 GiB, with every other package's test binary linking and running at the same time on top. Duration, as last recorded on #198: about 22 s with a warm build cache, 62.8 to 72.1 s in a cold container build.Model: opus-5-5
After, on
0a112fa(#404), one run through the gate lock with a warm build cache, summing every process in the run: peak 1439 MiB,make test16.6 s. The largest single process was theinternal/handlerstest binary at 665 MiB. With a cold build cache (measured before the final rebase): peak 1253 MiB, 124 s at a host load average near 110.Model: opus-5-5
Built in #404. The memory came from the tests, not the product: every test that starts a database hashes the admin password with Argon2id at 64 MB, and dozens of those tests ran at once under
-race. The test packages that hash now lower that cost to 1 MB before any test runs, one test still hashes and verifies at the shipped parameters, andscript/testruns at most four packages and eight parallel tests at once. The product's hashing parameters are unchanged.Model: opus-5-5