| 1 | # đŸ¤– AGENTS.md: todo-haskell |
| 2 | |
| 3 | The one rule: **every visitor's list is theirs alone.** Every query that |
| 4 | reads or changes a todo is scoped to the list named by the caller's own |
| 5 | cookie, and a request naming anything outside that list changes nothing |
| 6 | and answers 404. |
| 7 | |
| 8 | ## Tenancy |
| 9 | |
| 10 | - **One instance for the whole app.** `todo-haskell` runs as a single |
| 11 | Carloku instance on `todo-haskell.bfj.oncarlos.com`, with one SQLite |
| 12 | file. |
| 13 | - **Each visitor's list is kept separately by an anonymous cookie.** The |
| 14 | first visit mints a random 256-bit value, stores it as a row in |
| 15 | `lists`, and sets it as the `todo_list` cookie (`HttpOnly; |
| 16 | SameSite=Lax; Path=/`, plus `Secure` over https). A value the app |
| 17 | doesn't hold gets a fresh empty list, never an error. |
| 18 | - **No sign-in.** Losing the cookie loses the list; that's accepted. |
| 19 | - **Trust class C.** The todo text is stored in SQLite as plain text. The |
| 20 | operator can read it. That's a deliberate choice for a demo app, not an |
| 21 | oversight, and nobody should store anything secret in it. |
| 22 | |
| 23 | ## Rules for changing this app |
| 24 | |
| 25 | - Work only in `apps/haskell/`. The bakeoff's `BRIEF.md` and |
| 26 | `CONTRACT.md` are binding. |
| 27 | - Migrations only ever add. Never drop or rewrite a table or a column. |
| 28 | - Servers bind `127.0.0.1` or a unix socket, nothing else. |
| 29 | - Cabal's store lives under `.cache/`, set by the `Makefile`. Don't |
| 30 | point it anywhere shared. |
| 31 | - Commits end with a `Co-Authored-By:` trailer naming the model. |
| 32 | |