| 1 | # đŸ¤– AGENTS.md: todo-go |
| 2 | |
| 3 | The CARLOS bakeoff's TodoMVC, in Go. Live at |
| 4 | `https://todo-go.bfj.oncarlos.com` (Carloku app `todo-go`, account `bfj`). |
| 5 | |
| 6 | ## The one rule |
| 7 | |
| 8 | **Every page works as plain HTML forms first.** The server renders the |
| 9 | whole app, and every change is a form POST answered with a 303. The |
| 10 | JavaScript in `web/static/app.js` only sends those same POSTs in the |
| 11 | background and swaps in the HTML the server sends back. If a feature |
| 12 | can't be done with JavaScript off, it is done differently, not skipped. |
| 13 | |
| 14 | `BRIEF.md` and `CONTRACT.md` at the repo root are binding; this file |
| 15 | adds what is specific to the Go build. |
| 16 | |
| 17 | ## Tenancy declaration |
| 18 | |
| 19 | | Question | Answer | |
| 20 | |---|---| |
| 21 | | What is one instance? | The whole app. One process, one SQLite file, one unix socket | |
| 22 | | How do people reach it? | Anonymously. A visitor's first request sets a random cookie (256 bits), and that cookie is their list. No sign-in, no accounts | |
| 23 | | Where is each list kept? | In the one SQLite file, each row keyed by the SHA-256 of the visitor's cookie. The app never stores the cookie itself, so a copy of the database can't be used to open anyone's list | |
| 24 | | Trust class | **C**, chosen 2026-10-23: todo titles are stored as plain text, readable by the server and by anyone holding the database or its replicas. A todo list for a public demo doesn't justify server-blind encryption | |
| 25 | | Benefits claimed | Hibernation (the instance sleeps when idle and starts in milliseconds), replication of the one file by the platform | |
| 26 | | Costs accepted | A list lives as long as its cookie: clear cookies and the list is gone, and there is no way to move a list between browsers. Every list shares one file, so there is no per-visitor export or erasure beyond "delete by cookie hash" | |
| 27 | |
| 28 | ## Rules |
| 29 | |
| 30 | - One static binary, `CGO_ENABLED=0`. SQLite through `modernc.org/sqlite`. |
| 31 | - Migrations in `internal/todo/store.go` only ever add. Never edit or |
| 32 | remove a shipped migration; append a new one. |
| 33 | - Every query that touches a todo names the caller's list. An id that |
| 34 | isn't in the caller's list is a 404. |
| 35 | - Titles are rendered by `html/template`, never as raw HTML. |
| 36 | - JavaScript is one small ES module with no build step. Keep it under |
| 37 | 300 lines. |
| 38 | - Servers bind `127.0.0.1` only. Don't change `GOCACHE`; `make |
| 39 | build-arm64 COLD=1` passes `-a` instead. |
| 40 | |