carlos / todomvc-bakeoff Public
docs(go): AGENTS.md with the one rule and tenancy declaration
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 file changed,
+36
−0
apps/go/AGENTS.md+36 −0
diff --git a/apps/go/AGENTS.md b/apps/go/AGENTS.md| new file mode 100644 |
| index 0000000..4a525fb |
| --- /dev/null |
| +++ b/apps/go/AGENTS.md |
| @@ -0,0 +1,36 @@ |
| +# 🤖 AGENTS.md: todo-go |
| + |
| +TodoMVC for the CARLOS bakeoff, in Go. `BRIEF.md` and `CONTRACT.md` at |
| +the repo root are binding; this file says how this app keeps them. |
| + |
| +## The one rule |
| + |
| +**The page works with JavaScript off.** Every action is a plain form |
| +POST answered with a 303, and every view is a server-rendered page. The |
| +JavaScript in `static/app.js` only replays those same forms with |
| +`fetch` and swaps in the HTML the server renders, so there is exactly |
| +one renderer and one source of truth: the server and its SQLite file. |
| +If a feature can't be done that way, it doesn't go in. |
| + |
| +## Tenancy declaration (written 2026-10-23, before code) |
| + |
| +| Question | Answer | |
| +|---|---| |
| +| What is one instance? | The whole app. One instance on `todo-go.bfj.oncarlos.com`, one SQLite file | |
| +| Who are the users? | Anonymous visitors. No sign-in, no accounts | |
| +| How is each visitor's data kept apart? | Each visitor gets a list through an anonymous cookie (`HttpOnly; SameSite=Lax; Path=/`, `Secure` over https) holding 256 random bits plus a MAC. The database stores only a SHA-256 of the cookie, and every query that touches a todo is filtered by that hash. A todo id outside the caller's list answers 404 | |
| +| Trust class | **C**. Todo titles are stored as plain text and the server can read them. Chosen on purpose: a public demo list with no accounts has no key to encrypt to, and this is written down here and in the README | |
| +| Residue | Titles, completion flags, creation times, and the cookie hashes. No IPs, no user agents | |
| +| Benefits earned | Platform replication and hibernation of the one file; per-visitor isolation enforced in every query | |
| +| Costs accepted | One shared instance: a crash takes every visitor down together. Lists are as private as the cookie; clearing cookies loses the list | |
| + |
| +## Rules for working here |
| + |
| +- Stdlib first. The only third-party dependency is the SQLite driver |
| + (`modernc.org/sqlite`, pure Go, so `CGO_ENABLED=0` works). Adding |
| + another is a decision recorded in `README.md` and `DEPS`. |
| +- Migrations only add. Never drop or rewrite data. |
| +- `static/base.css` and `static/index.css` are byte-for-byte copies of |
| + `shared/`; a test checks it. |
| +- Bind `127.0.0.1` only when running locally. Never change `GOCACHE`. |
| +- Commits end with a `Co-Authored-By:` trailer naming the model. |