Release History¶
Auto-generated from CHANGELOG.md.
Changelog¶
0.6.0 (2026-09-10)¶
Features¶
0.5.0 (2026-09-08)¶
Features¶
Bug Fixes¶
- deps: update module github.com/jackc/pgx/v5 to v5.11.0 (#199) (6637e6d)
- ui: keep the match list's row lines in one piece (#198) (2037c58)
Refactoring¶
0.4.0 (2026-09-06)¶
Features¶
- preview environments — per-PR artefacts, a demo field, and the cleanup that pays for them (#190) (c47a6de)
Bug Fixes¶
Refactoring¶
0.3.0 (2026-09-05)¶
Features¶
- ci: gate pull requests on govulncheck against the source (#181) (513a08d)
- ci: run govulncheck from Ci, and gate on the Trivy scan (#183) (d67795e)
0.2.1 (2026-09-04)¶
Bug Fixes¶
- ci: name snapshots by commit so they cannot claim a release tag (#177) (4e851fb), closes #172
- ci: tag the pushed artefact instead of rendering it twice (#179) (7cca1ef), closes #172
0.2.0 (2026-09-04)¶
Features¶
0.1.0 (2026-09-04)¶
Features¶
- ap1: Gerüst — Go-Modul, templ/HTMX, Postgres, Docker, Task, Dagger (c471031)
- auth: a way back into your own player (e2ace29)
- auth: forget a session, not only its cookie (2d65ce7)
- auth: recognise returning players by a signed cookie (c60ff71)
- auth: sign out on this device (e243aae)
- auth: slow down guessing at a credential (dfe2f04), closes #70
- auth: who may act for somebody else (51cac90)
- best-of-three by default, the service rule in the hint, and the mascot at the top (fb5194c)
- build: say which commit is running, and how old it is (81f19d6)
- build: say which commit is running, and how old it is (3f310d0)
- compose: a stack for an evening at the table (d2a33d6)
- config: grant the first admin from the environment (9ec5d28), closes #73
- config: SP_KIOSK_TOKEN (4186bc9)
- credential: generate recovery codes and hash them with argon2id (b58a92b)
- db: a row per unlocked kiosk machine (afe6a9d), closes #77
- db: mark who may act for somebody else (e4c0cd3), closes #73
- db: record how a result was entered (ce8e818), closes #71
- db: store player credentials in their own table (119937c)
- deploy: environment profiles from outside the repo, and a worked patch example (faa3889)
- deploy: make External Secrets optional, not a requirement (58e8a7b)
- deploy: publish the manifests as a kustomize OCI artefact (4de363b), closes #80
- deploy: render the database, and bring an environment up in one command (0313728)
- deploy: render the database, and bring an environment up in one command (dc5e304)
- deploy: render the Kubernetes manifests from KCL (29a83a3)
- deploy: render the Kubernetes manifests from KCL (32132c1)
- deploy: take an environment profile from outside the repo (9e7ec20)
- dod: exclude tournament matches by tournament_id (a1df198)
- kiosk: give a grant an operator (6231244), closes #90
- kiosk: give each machine its own grant (0c26ef5), closes #77
- kiosk: issue a recovery code for somebody standing at the table (ee74b9c)
- kiosk: list the tournaments a result can still go into (369410c)
- kiosk: list the tournaments a result can still go into (77739d4), closes #124
- kiosk: make kiosk access revocable and traceable (cb837e1)
- kiosk: offer a way back from the result that was just entered (4ae04c5)
- kiosk: put the code in a form, and brake guessing at it (278dc40)
- kiosk: put the code in a form, and brake guessing at it (2efe180)
- match: accept a match played over a single set (089be4c), closes #114
- match: allow a match played over a single set (d790cc2)
- matches: filter the list by player, starting with your own (0fc4bb2)
- matches: filter the list by player, starting with your own (7f1ac1b)
- matches: read the list from the side of whoever it is about (546a8a4)
- match: let a caller ask whether a mode exists (076dd26)
- match: make best-of-three the default, and name the mode in one place (6377795)
- match: offer the one-set mode in the picker (87ef7b2), closes #114
- match: validate proposed match results (4a63a5a)
- ops: read the Definition of Done out of the database (ca5a0b7)
- ops: read the Definition of Done out of the database (ba13015)
- qr: render QR codes as SVG geometry (3ca83b4)
- repository: count what waits on a player (341d81b)
- repository: read everybody's matches, and what each one was worth (ee1b838)
- repository: replace the result of a contested match (334a548)
- rules: say what the diagonal serve costs and who begins (a325552)
- rules: say what the diagonal serve costs and who begins (dd99ac8)
- run a tournament on one laptop, and let a rejected form say why (03e72d4)
- scoring: correct a contested result back into pending (d92c31b)
- scoring: put both ratings back when a result is taken back (98fa4a5)
- scoring: record a result that needs no confirmation (e3179c2)
- scoring: settle a confirmed match (90c9e88)
- server: a kiosk for one machine at the table (d584598)
- server: a kiosk for one machine at the table (7ea7896)
- server: confirm or dispute a reported result (146235d)
- server: correct a contested result instead of a dead end (282bf14)
- server: offer a correction instead of a dead end (1277e20)
- server: put a printable QR sheet next to the table (d318ad8)
- server: QR entry at the table (9771bd5)
- server: record match results (a845dde)
- server: show the ranking and a player profile (fdb484a)
- signin: open the start page on the name picker (266b4dd)
- signin: open the start page on the name picker (552c444)
- skills: add branch-naming (fba6abf)
- standings: count records in SQL and rank them in Go (f39924e)
- stats: a Statistik tab — head-to-head and the office totals (5677d9c)
- stats: make the head-to-head matrix say what it counts (a0d304c)
- stats: who beat whom, and how much has actually been played (5400547), closes #121
- task: pick the address instead of typing it (55132e6)
- task: pick the address instead of typing it, and write the kiosk down (bc7eea1)
- tournament: a point for losing in the deciding set (97fcf07)
- tournament: a point for losing in the deciding set (bb1ae83)
- tournament: a quick tournament — draw, table, and entry at the table (57123f9)
- tournament: ask for the mode at the draw (fcb5a0f)
- tournament: ask for the mode at the draw and enter under it (fca7256)
- tournament: confirm a result without leaving the tournament (1dfea08)
- tournament: create a quick tournament, and run it from the table (36919a4), closes #41
- tournament: draw return legs and name the final (65c0f8c)
- tournament: end one at any time, and clear away the ones nobody played (cd0659a)
- tournament: end one at any time, and clear away the ones nobody played (c3daf91)
- tournament: let an evening be played without a rating (a15531a)
- tournament: let an evening be played without a rating (8a99bd8)
- tournament: let players enter their own results (e7e5089)
- tournament: let players enter their own results (3b41055)
- tournament: name the two ends of the table, and give the first serve (5a1bcfa)
- tournament: name the two ends of the table, and give the first serve (b3d1adf)
- tournament: offer return legs and a final when starting one (0cbfcfb)
- tournament: offer to play the same field again (6f3b76f)
- tournament: offer to play the same field again (aab53d2)
- tournament: return legs and a final (9df2443)
- tournament: say the field is fixed, and offer a table in points (bbd4930)
- tournament: say the field is fixed, and offer a table in points (cb14779)
- tournament: store a tournament and the matches booked to it (44dc947), closes #41
- tournament: store the mode on the tournament (a8485d6)
- tournament: store which slot of the draw a match fills (7942c1f)
- tournament: the round robin draw and the table, as pure logic (1573c3b), closes #41
- ttr: add the rating package (6e99836)
- web: a button that catches the page up (a41d73c)
- web: a button that catches the page up (b5c05b6)
- web: a list of every match, with every set (a99a58e)
- web: a list of every match, with every set (b640b7d)
- web: a page saying who may act for somebody else (9fd654e)
- web: a Statistik tab, with the two figures that hold up today (93337ff), closes #121
- web: dark interface with mono labels and rank chips (8cd9c80)
- web: dark interface with mono labels and rank chips (3913afb)
- web: give every player their own blade colour (1366949)
- web: give every player their own blade colour (27aebcf)
- web: give the app its own mark (672d696)
- web: give the app its own mark, and stop a long name from taking the page sideways (5f7d8cd)
- web: give the pages that belong to nobody a colour of their own (5e98baf)
- web: give the pages that belong to nobody a colour of their own (62c5ae0)
- web: give the ranking a page, and the fields a border you can see (5dea70d)
- web: give the ranking a page, and the fields a border you can see (75ff30c)
- web: greet the player by name, and keep the mascot on the right (786bd01)
- web: greet the player by name, and keep the mascot on the right (c129440)
- web: issue a recovery code at join and show it once (b4bee90), closes #70
- web: link the two printed sheets to each other (8a6ffcb)
- web: move the navigation above the content, and the status onto a page (d900718)
- web: move the navigation above the content, and the status onto a page (ee8554d)
- web: print the house rules on a sheet of their own (f5f0549)
- web: print the house rules on a sheet of their own (618b242)
- web: put the session in the top bar, and switch to violet (0222134)
- web: put the session in the top bar, and switch to violet (e4c3370)
- web: read results from the side of whoever is reading them (718ee49)
- web: say how a tie is decided, and make the form usable with a thumb (e611e75)
- web: say how a tie is decided, and make the tournament form usable with a thumb (6613ff5)
- web: say whose points go in which box, and lead the kiosk with the frequent thing (485c5f2)
- web: say whose points go in which box, and lead with the frequent thing (1661e4a)
- web: set a PIN, and issue yourself a new recovery code (e79d012), closes #70
- web: set the mascot beside the heading instead of above it (22726a9)
- web: set the tools apart at the end of the navigation (162b89c)
- web: set the tools apart at the end of the navigation (9d694cf)
- web: show only the sets a mode can have (b0ae9ff)
- web: sign in with a name and a secret (4b1c5c0), closes #70
- web: sign out on this device (cb5daf5)
- web: start every score box at zero (9b8f9c1)
- web: state the probes instead of linking to them (0c27ca2)
- web: state who serves, and greet from the top of the page (077566e)
- web: take a kiosk machine back (d28a5b9), closes #77
- web: the mascot as a vector, inlined so the blade can be recoloured (bea3768)
- web: the mascot as a vector, inlined so the blade can be recoloured (40a5f29)
Bug Fixes¶
- ci: give the measurement check a psql, and make an empty database fail (d18c36b)
- config: stop requiring a session key to run migrations (0b9bb5f)
- dagger: align the Go builder image and drop a dead constant (f251d7a)
- deploy: gateway namespace, optional ESO, and the manual path written down (06ff5e0)
- deploy: pin the image to the tag the artefact carries (6998b75)
- deploy: refuse an HTTPRoute with no gateway namespace (7da1724)
- deploy: render the shape the kustomize chain expects (82cf5b0)
- deploy: write profiles in the format the publish chain reads (6da0b2b)
- deploy: write profiles in the format the publish chain reads (41c56e7)
- deps: update github.com/pressly/goose/v3 to v3.28.0 (69e2508)
- deps: update golang.org/x/crypto to v0.56.0 (ddf5f75)
- deps: update goose to v3.28.0 and x/crypto to v0.56.0 (badd592)
- kcl: write the redirect route's default matches (#168) (bf2a87e)
- kiosk: call the section what it is (79566bc)
- kiosk: let a result that counts at once be taken back (585e287)
- kiosk: name who is typing, and refuse to write until it is named (38cf822)
- kiosk: refuse a match the browser is signed in as a player of (ba4b67b)
- kiosk: refuse a match the browser is signed in as a player of (ac81139), closes #90
- kiosk: refuse to write until the machine says who is typing (285af41), closes #90
- make a failed
task upexplain itself, and two bugs found on the way (8af6f87) - matches: a tagged switch on the picker value (854e5d0)
- ops: office:setup dies on a Mac, and offers the wrong address when it does not (1dfbf1e)
- ops: stop offering addresses no phone can reach (a6d1a60)
- ops: stop the address list dying on the last interface (2c453b4)
- server: keep New's comment attached to New (0c0c48f)
- server: log a stack trace with a recovered panic (105a5d6)
- server: stop serving the script and stylesheet from an hour-old cache (a03ce52)
- signin: give the PIN the number pad ADR-0007 promised (9338f70)
- signin: give the PIN the number pad ADR-0007 promised (168b960), closes #117
- signin: keep the secret label off the name picker's line (140d469)
- standings: rank nobody before anybody has played (862835f)
- start every score box at zero, and stop serving the script from an hour-old cache (be5230e)
- stats: stop counting single-set wins as whitewashes (d111297)
- task: say why a service did not come up (b538df0)
- templates: generate the way the repo does, not from the root (b563f85)
- templates: give Behind its own doc comment (8539072)
- templates: keep MatchListView's comment attached to it (58b1c3d)
- test: give the integration tests a database of their own (16c7516), closes #163
- test: give the integration tests their own database, and refuse any other (ceb0256)
- test: refuse to empty a database that is not named for tests (faf301c), closes #163
- test: run the database suites one package at a time (77d6b39)
- tournament: break a three-way tie by the sub-table, not pairwise (085c275)
- tournament: enter a result the way the rest of the app does (c495298)
- tournament: enter a result the way the rest of the app does (ea93eac)
- tournament: keep the rating answer when a draw is edited (127d44f)
- tournament: link to result entry instead of describing its address (13e8b0f)
- tournament: link to result entry instead of describing its address (7eea3d4)
- tournament: remove the pairwise helpers the sub-table replaced (0dde449)
- web: deliver result entry with the join, not on the next reload (bba8a1a)
- web: deliver result entry with the join, not on the next reload (5f52b17), closes #75
- web: give the tappable names a class of their own (3548b97)
- web: keep a long name from taking the page sideways (a1dc69f)
- web: keep a refresh next to the list that must not go stale (82cab61)
- web: keep the tables inside their scroll box on a phone (e812e6c)
- web: let a rejected form say why (02b0e0b)
- web: make the accent pass AA, and give first place the logo colour (3dffc1e)
- web: rank nobody before anybody has played, and make the accent pass AA (a9ea99d)
- web: say what /info answers instead of naming the probes (752abee)
- web: show a match's state beside the score, not inside the TTR column (ab832fd), closes #76
- web: stop the kiosk offering a player against themselves, and add a slider (46dc634)
- web: stop the kiosk offering a player against themselves, and add a slider under every score (b04466f)
- web: stop the statistics page scrolling sideways on a phone (d817ab5)
Refactoring¶
- deploy: publish a base no cluster is named in (3382ad1)
- deploy: publish a base no cluster is named in (2439635)
- switch code, comments and tooling to English (a4ee52f)
- switch code, comments and tooling to English (1a11b9e)
- tournament: fill the view only after the load succeeded (fec666f)
- web: drop the name from the join confirmation (163fac8)
- web: drop the name from the join confirmation (e082c83)