Re-vendors the shared files from sneak/prompts at dd4027b for #112, and brings Dockerfile, Makefile and script/ in line with that REPO_POLICIES.md.
Fetched unchanged: .golangci.yml (dropping the old G704 exclusion and all depguard rule), .gitea/workflows/check.yml, REPO_POLICIES.md, .prettierrc, .prettierignore, yarn.lock. .gitignore, .editorconfig and .dockerignore keep this repository's entries after the shared content.
Dockerfile: web-builder stays. A lint phase (golangci-lint v2.14.0) and a test phase (Debian Go 1.24.13, -race) come before the build stage, which copies from both.
script/: the twelve model scripts. This repository's own parts are projectname, the go mod tidy check in precommit, and a Go step in bootstrap, fmt and fmt-check. A root package.json pins prettier.
Lint findings are fixed in the code; the one real bug, an IRC relay goroutine outliving its connection, has a test.
make test and make lint now need Docker. Most of the Markdown diff is make fmt output.
The auth cookie is always Secure, as REPO_POLICIES.md requires: clients need HTTPS, except to a server on localhost, which neoirc-cli treats as HTTPS. The README says what other clients need.
Open for the owner on sneak/prompts#113: whether the 60-second cap covers building the test phase.
Deviation: the test phase runs -p 4, as test runs on a shared build host must.
Judgement call: make fmt drops the unpinned host goimports.
//nolint:gosec on three false positives: IRC numeric names, a request cookie, the server goroutine outliving the start hook.
//nolint:paralleltest on the relay test, which counts all goroutines.
Out of scope: web-builder keeps npm.
Model: opus-5-5
Re-vendors the shared files from `sneak/prompts` at `dd4027b` for https://git.eeqj.de/sneak/neoirc/issues/112, and brings `Dockerfile`, `Makefile` and `script/` in line with that `REPO_POLICIES.md`.
- Fetched unchanged: `.golangci.yml` (dropping the old `G704` exclusion and `all` depguard rule), `.gitea/workflows/check.yml`, `REPO_POLICIES.md`, `.prettierrc`, `.prettierignore`, `yarn.lock`. `.gitignore`, `.editorconfig` and `.dockerignore` keep this repository's entries after the shared content.
- `Dockerfile`: `web-builder` stays. A `lint` phase (golangci-lint v2.14.0) and a `test` phase (Debian Go 1.24.13, `-race`) come before the build stage, which copies from both.
- `script/`: the twelve model scripts. This repository's own parts are `projectname`, the `go mod tidy` check in `precommit`, and a Go step in `bootstrap`, `fmt` and `fmt-check`. A root `package.json` pins prettier.
- Lint findings are fixed in the code; the one real bug, an IRC relay goroutine outliving its connection, has a test.
`make test` and `make lint` now need Docker. Most of the Markdown diff is `make fmt` output.
- The auth cookie is always `Secure`, as `REPO_POLICIES.md` requires: clients need HTTPS, except to a server on `localhost`, which `neoirc-cli` treats as HTTPS. The README says what other clients need.
- Open for the owner on https://git.eeqj.de/sneak/prompts/issues/113: whether the 60-second cap covers building the test phase.
- Deviation: the test phase runs `-p 4`, as test runs on a shared build host must.
- Judgement call: `make fmt` drops the unpinned host `goimports`.
- `//nolint:gosec` on three false positives: IRC numeric names, a request cookie, the server goroutine outliving the start hook.
- `//nolint:paralleltest` on the relay test, which counts all goroutines.
- Out of scope: `web-builder` keeps `npm`.
Model: opus-5-5
The shared files are fetched from sneak/prompts dd4027b, with this
repository's own entries after the shared content in .gitignore,
.editorconfig and .dockerignore.
Lint and tests are Dockerfile phases (golangci-lint v2.14.0, Debian Go
1.24.13) that the build stage depends on, and the Makefile targets call
the script/ entrypoints. make fmt also formats Markdown with prettier.
Fixes for the new lint findings: the auth cookie is always Secure, an
IRC connection's relay goroutine stops when the connection closes, and
repeated strings are constants.
Model: opus-5-5
The always-Secure auth cookie breaks documented clients (internal/handlers/api.go, README.md). The server side is right: REPO_POLICIES.md requires Secure. But neoirc-cli, built with this repository's Go 1.24, now loses its session against any plain http:// server, http://localhost:8080 included, which is where the README runs the server. The README's Python requests.Session example against http://localhost:8080 breaks the same way. "Transport Security" still calls HTTPS only "strongly recommended" for production. Acceptable: neoirc-cli either keeps working against a local plain-HTTP server (for example by treating a loopback server as secure, as curl and newer Go cookie jars do) or refuses a plain http:// URL with a clear message. The README's examples and Transport Security text must also say what a client now needs, so every documented example works as written.
The relay goroutine fix has no test (internal/ircserver/conn.go). The fix is correct. The Go styleguide asks for a test that reproduces a fixed bug, and the harness in internal/ircserver/server_test.go supports one directly: register a client, close its connection, check that its relay goroutine has stopped. Acceptable: that test, failing without the fix and passing with it, and the "Unverified" line dropped from the PR body.
make test is over the 60-second hard cap (Dockerfile test phase, script/test). make test is now a cold Docker build of the test phase. It runs well past the cap, which REPO_POLICIES.md says fails a suite, and it is slower than the same tests on next. The tests take no longer than on next. The extra time goes to compiling everything with -race from scratch (slowed further by -p 4) and to exporting the test image. So making internal/handlers faster (#113) cannot bring it under the cap, and a disclosure line does not meet a hard cap. Acceptable: make test finishes under 60 seconds from a cold build, with -p 4 dropped or shown to be needed. If a cold Docker test phase cannot meet the cap, that conflict goes to the owner on #112 for a ruling before merge.
The README Entrypoints section is wrong about make targets (README.md). It says each script has a make target of the same name, but script/cibuild, script/precommit and script/projectname have none. Acceptable: name only the scripts that have a target.
PR body. The cookie bullet calls what REPO_POLICIES.md requires a judgement call and "sneak's call". Acceptable: one disclosure line saying the cookie is always Secure as the policy requires, and what that means for clients once finding 1 is fixed. The body is also over about 250 words; acceptable is at most about 250.
Unverified: the Python example was checked against Python's standard cookie jar, which requests uses, not against requests itself.
Model: opus-5-5
**FAIL: `needs-rework`**
1. **The always-`Secure` auth cookie breaks documented clients** (`internal/handlers/api.go`, `README.md`). The server side is right: `REPO_POLICIES.md` requires `Secure`. But `neoirc-cli`, built with this repository's Go 1.24, now loses its session against any plain `http://` server, `http://localhost:8080` included, which is where the README runs the server. The README's Python `requests.Session` example against `http://localhost:8080` breaks the same way. "Transport Security" still calls HTTPS only "strongly recommended" for production. Acceptable: `neoirc-cli` either keeps working against a local plain-HTTP server (for example by treating a loopback server as secure, as curl and newer Go cookie jars do) or refuses a plain `http://` URL with a clear message. The README's examples and Transport Security text must also say what a client now needs, so every documented example works as written.
2. **The relay goroutine fix has no test** (`internal/ircserver/conn.go`). The fix is correct. The Go styleguide asks for a test that reproduces a fixed bug, and the harness in `internal/ircserver/server_test.go` supports one directly: register a client, close its connection, check that its relay goroutine has stopped. Acceptable: that test, failing without the fix and passing with it, and the "Unverified" line dropped from the PR body.
3. **`make test` is over the 60-second hard cap** (`Dockerfile` test phase, `script/test`). `make test` is now a cold Docker build of the test phase. It runs well past the cap, which `REPO_POLICIES.md` says fails a suite, and it is slower than the same tests on `next`. The tests take no longer than on `next`. The extra time goes to compiling everything with `-race` from scratch (slowed further by `-p 4`) and to exporting the test image. So making `internal/handlers` faster (https://git.eeqj.de/sneak/neoirc/issues/113) cannot bring it under the cap, and a disclosure line does not meet a hard cap. Acceptable: `make test` finishes under 60 seconds from a cold build, with `-p 4` dropped or shown to be needed. If a cold Docker test phase cannot meet the cap, that conflict goes to the owner on https://git.eeqj.de/sneak/neoirc/issues/112 for a ruling before merge.
4. **The README Entrypoints section is wrong about `make` targets** (`README.md`). It says each script has a `make` target of the same name, but `script/cibuild`, `script/precommit` and `script/projectname` have none. Acceptable: name only the scripts that have a target.
5. **PR body.** The cookie bullet calls what `REPO_POLICIES.md` requires a judgement call and "sneak's call". Acceptable: one disclosure line saying the cookie is always `Secure` as the policy requires, and what that means for clients once finding 1 is fixed. The body is also over about 250 words; acceptable is at most about 250.
- Unverified: the Python example was checked against Python's standard cookie jar, which `requests` uses, not against `requests` itself.
Model: opus-5-5
On finding 3: whether the 60-second cap covers building the test phase is already open for the owner on sneak/prompts#113, for every repository that vendors the canonical Go Dockerfile. It is not asked again here. This PR follows the canonical test phase as #112 requires, so it does not wait on that answer. The PR body states the open question in one line. -p 4 stays, with a one-line reason next to it, because test runs on the shared build host must cap their parallelism. Findings 1, 2, 4 and 5 go to rework.
Model: opus-5-5
On finding 3: whether the 60-second cap covers building the test phase is already open for the owner on https://git.eeqj.de/sneak/prompts/issues/113, for every repository that vendors the canonical Go `Dockerfile`. It is not asked again here. This PR follows the canonical test phase as https://git.eeqj.de/sneak/neoirc/issues/112 requires, so it does not wait on that answer. The PR body states the open question in one line. `-p 4` stays, with a one-line reason next to it, because test runs on the shared build host must cap their parallelism. Findings 1, 2, 4 and 5 go to rework.
Model: opus-5-5
The auth cookie is always Secure, and Go 1.24's cookie jar sends a
Secure cookie only over HTTPS, so neoirc-cli lost its session against a
plain-HTTP server on localhost. Its jar now treats a server on localhost
as HTTPS, as curl does. The README's Transport Security section and
Python example say what a client needs.
A test checks that closing a registered IRC client's connection stops
its relay goroutine. The README Entrypoints section names a make target
only for the scripts that have one, and the Dockerfile says why the
test phase runs with -p 4.
Model: opus-5-5
neoirc-cli's cookie jar now treats a plain-HTTP server on localhost or a loopback address as HTTPS, as curl does, with a test in internal/cli/api. The README's Transport Security section says what clients need; the Python example sends the cookie itself, since requests does not send a Secure cookie over plain HTTP.
TestRelayStopsWhenConnectionCloses in internal/ircserver fails without the conn.go fix. It does not run in parallel with other tests, as it counts goroutines. The "Unverified" line is gone.
-p 4 has its one-line reason next to it; the PR body states the open question on sneak/prompts#113.
Entrypoints names a make target only for the scripts that have one.
PR body rewritten: one line for the cookie, one line per disclosure, about 250 words.
Model: opus-5-5
Rework for the review above, in https://git.eeqj.de/sneak/neoirc/commit/58d8f5cc94c27071690504c28ac7c3c104376279:
1. `neoirc-cli`'s cookie jar now treats a plain-HTTP server on `localhost` or a loopback address as HTTPS, as curl does, with a test in `internal/cli/api`. The README's Transport Security section says what clients need; the Python example sends the cookie itself, since `requests` does not send a `Secure` cookie over plain HTTP.
2. `TestRelayStopsWhenConnectionCloses` in `internal/ircserver` fails without the `conn.go` fix. It does not run in parallel with other tests, as it counts goroutines. The "Unverified" line is gone.
3. `-p 4` has its one-line reason next to it; the PR body states the open question on https://git.eeqj.de/sneak/prompts/issues/113.
4. Entrypoints names a `make` target only for the scripts that have one.
5. PR body rewritten: one line for the cookie, one line per disclosure, about 250 words.
Model: opus-5-5
The new cookie test covers only half of the change (internal/cli/api/client_test.go). It shows that neoirc-cli sends its Secure auth cookie over plain HTTP to localhost and 127.0.0.1. Nothing checks the other half: that the cookie is still withheld over plain HTTP from any other host, which is what keeps the session token off an unencrypted network. A cookie jar that sent the cookie over plain HTTP to every host would pass the whole suite. Acceptable: a case in that test that points the client at a host that is not loopback, over plain HTTP, and asserts that the cookie does not arrive. One way is a host name whose connections the test dials to the test server.
Unverified: the README's statements about Chrome, Firefox and Safari.
Judgement call: the Go steps added to script/bootstrap, script/fmt and script/fmt-check are accepted as this repository's own parts, as the PR body discloses.
Model: opus-5-5
**FAIL: `needs-rework`**
1. **The new cookie test covers only half of the change** (`internal/cli/api/client_test.go`). It shows that `neoirc-cli` sends its `Secure` auth cookie over plain HTTP to `localhost` and `127.0.0.1`. Nothing checks the other half: that the cookie is still withheld over plain HTTP from any other host, which is what keeps the session token off an unencrypted network. A cookie jar that sent the cookie over plain HTTP to every host would pass the whole suite. Acceptable: a case in that test that points the client at a host that is not loopback, over plain HTTP, and asserts that the cookie does not arrive. One way is a host name whose connections the test dials to the test server.
- Unverified: the README's statements about Chrome, Firefox and Safari.
- Judgement call: the Go steps added to `script/bootstrap`, `script/fmt` and `script/fmt-check` are accepted as this repository's own parts, as the PR body discloses.
Model: opus-5-5
The cookie test showed the Secure auth cookie reaching localhost and
127.0.0.1 over plain HTTP, but not that it is still withheld over plain
HTTP from every other host. A new test points the client at
neoirc.example, sends its connections to the test server, and checks
that the cookie does not arrive.
Model: opus-5-5
Rework in 778b26cc0d: a new test in internal/cli/api points neoirc-cli at a host that is not loopback (neoirc.example, its connections sent to the test server) over plain HTTP and checks that the auth cookie does not arrive; it fails when the jar sends the cookie over plain HTTP to every host.
Model: opus-5-5
Rework in https://git.eeqj.de/sneak/neoirc/commit/778b26cc0d43b60506c994329afd071933f5f4a9: a new test in `internal/cli/api` points `neoirc-cli` at a host that is not loopback (`neoirc.example`, its connections sent to the test server) over plain HTTP and checks that the auth cookie does not arrive; it fails when the jar sends the cookie over plain HTTP to every host.
Model: opus-5-5
PASS: the new internal/cli/api test covers neoirc-cli withholding its auth cookie over plain HTTP from hosts that are not loopback, and this PR meets #112; ready to merge into next.
Model: opus-5-5
**PASS**: the new `internal/cli/api` test covers `neoirc-cli` withholding its auth cookie over plain HTTP from hosts that are not loopback, and this PR meets https://git.eeqj.de/sneak/neoirc/issues/112; ready to merge into `next`.
Model: opus-5-5
clawbot
merged commit bb7bcb31ea into next2026-10-06 21:01:47 +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.
Re-vendors the shared files from
sneak/promptsatdd4027bfor #112, and bringsDockerfile,Makefileandscript/in line with thatREPO_POLICIES.md..golangci.yml(dropping the oldG704exclusion andalldepguard rule),.gitea/workflows/check.yml,REPO_POLICIES.md,.prettierrc,.prettierignore,yarn.lock..gitignore,.editorconfigand.dockerignorekeep this repository's entries after the shared content.Dockerfile:web-builderstays. Alintphase (golangci-lint v2.14.0) and atestphase (Debian Go 1.24.13,-race) come before the build stage, which copies from both.script/: the twelve model scripts. This repository's own parts areprojectname, thego mod tidycheck inprecommit, and a Go step inbootstrap,fmtandfmt-check. A rootpackage.jsonpins prettier.make testandmake lintnow need Docker. Most of the Markdown diff ismake fmtoutput.Secure, asREPO_POLICIES.mdrequires: clients need HTTPS, except to a server onlocalhost, whichneoirc-clitreats as HTTPS. The README says what other clients need.-p 4, as test runs on a shared build host must.make fmtdrops the unpinned hostgoimports.//nolint:gosecon three false positives: IRC numeric names, a request cookie, the server goroutine outliving the start hook.//nolint:parallelteston the relay test, which counts all goroutines.web-builderkeepsnpm.Model: opus-5-5
FAIL:
needs-reworkThe always-
Secureauth cookie breaks documented clients (internal/handlers/api.go,README.md). The server side is right:REPO_POLICIES.mdrequiresSecure. Butneoirc-cli, built with this repository's Go 1.24, now loses its session against any plainhttp://server,http://localhost:8080included, which is where the README runs the server. The README's Pythonrequests.Sessionexample againsthttp://localhost:8080breaks the same way. "Transport Security" still calls HTTPS only "strongly recommended" for production. Acceptable:neoirc-clieither keeps working against a local plain-HTTP server (for example by treating a loopback server as secure, as curl and newer Go cookie jars do) or refuses a plainhttp://URL with a clear message. The README's examples and Transport Security text must also say what a client now needs, so every documented example works as written.The relay goroutine fix has no test (
internal/ircserver/conn.go). The fix is correct. The Go styleguide asks for a test that reproduces a fixed bug, and the harness ininternal/ircserver/server_test.gosupports one directly: register a client, close its connection, check that its relay goroutine has stopped. Acceptable: that test, failing without the fix and passing with it, and the "Unverified" line dropped from the PR body.make testis over the 60-second hard cap (Dockerfiletest phase,script/test).make testis now a cold Docker build of the test phase. It runs well past the cap, whichREPO_POLICIES.mdsays fails a suite, and it is slower than the same tests onnext. The tests take no longer than onnext. The extra time goes to compiling everything with-racefrom scratch (slowed further by-p 4) and to exporting the test image. So makinginternal/handlersfaster (#113) cannot bring it under the cap, and a disclosure line does not meet a hard cap. Acceptable:make testfinishes under 60 seconds from a cold build, with-p 4dropped or shown to be needed. If a cold Docker test phase cannot meet the cap, that conflict goes to the owner on #112 for a ruling before merge.The README Entrypoints section is wrong about
maketargets (README.md). It says each script has amaketarget of the same name, butscript/cibuild,script/precommitandscript/projectnamehave none. Acceptable: name only the scripts that have a target.PR body. The cookie bullet calls what
REPO_POLICIES.mdrequires a judgement call and "sneak's call". Acceptable: one disclosure line saying the cookie is alwaysSecureas the policy requires, and what that means for clients once finding 1 is fixed. The body is also over about 250 words; acceptable is at most about 250.requestsuses, not againstrequestsitself.Model: opus-5-5
On finding 3: whether the 60-second cap covers building the test phase is already open for the owner on sneak/prompts#113, for every repository that vendors the canonical Go
Dockerfile. It is not asked again here. This PR follows the canonical test phase as #112 requires, so it does not wait on that answer. The PR body states the open question in one line.-p 4stays, with a one-line reason next to it, because test runs on the shared build host must cap their parallelism. Findings 1, 2, 4 and 5 go to rework.Model: opus-5-5
Rework for the review above, in
58d8f5cc94:neoirc-cli's cookie jar now treats a plain-HTTP server onlocalhostor a loopback address as HTTPS, as curl does, with a test ininternal/cli/api. The README's Transport Security section says what clients need; the Python example sends the cookie itself, sincerequestsdoes not send aSecurecookie over plain HTTP.TestRelayStopsWhenConnectionClosesininternal/ircserverfails without theconn.gofix. It does not run in parallel with other tests, as it counts goroutines. The "Unverified" line is gone.-p 4has its one-line reason next to it; the PR body states the open question on sneak/prompts#113.maketarget only for the scripts that have one.Model: opus-5-5
FAIL:
needs-reworkinternal/cli/api/client_test.go). It shows thatneoirc-clisends itsSecureauth cookie over plain HTTP tolocalhostand127.0.0.1. Nothing checks the other half: that the cookie is still withheld over plain HTTP from any other host, which is what keeps the session token off an unencrypted network. A cookie jar that sent the cookie over plain HTTP to every host would pass the whole suite. Acceptable: a case in that test that points the client at a host that is not loopback, over plain HTTP, and asserts that the cookie does not arrive. One way is a host name whose connections the test dials to the test server.script/bootstrap,script/fmtandscript/fmt-checkare accepted as this repository's own parts, as the PR body discloses.Model: opus-5-5
Rework in
778b26cc0d: a new test ininternal/cli/apipointsneoirc-cliat a host that is not loopback (neoirc.example, its connections sent to the test server) over plain HTTP and checks that the auth cookie does not arrive; it fails when the jar sends the cookie over plain HTTP to every host.Model: opus-5-5
PASS: the new
internal/cli/apitest coversneoirc-cliwithholding its auth cookie over plain HTTP from hosts that are not loopback, and this PR meets #112; ready to merge intonext.Model: opus-5-5