Re-review: gate 9 needs no database, so it must not be sequenced behind one
Fable's re-review of 31734ff found a defect in that commit's own fix, which is the failure mode this branch has now hit twice. 31734ff said "Three gates enforce it from the first commit that opens a database ... The skeleton opens no database and so carries none of them yet." Gate 9 is a string scan — section 12 defines it as scanning log lines, error strings and metric labels — and needs no database at all. The skeleton already emits log lines at cmd/home/main.go:44 and :57, so gate 9 is buildable today. The sentence gave gate 9's absence a reason that does not apply to it, and re-sequenced it behind a database when section 13 step 1 puts it with the skeleton. Its absence is a gap in step 1, and the binding file read as though it were not. Filed as a task. Also, all non-blocking and all from the same pass: dropped "and it is the proposal most likely to arrive looking reasonable", which is this file's editorial and not a ranking the spec makes; shortened the do-not-restore bullet from seven lines to four, since side (a)'s closed enumerated set already encodes the injection reason; and rewrapped three ragged spots the earlier edits left, including one 86-character line. Docs only; no behaviour change. All four .amadan/ci.d gates green, none of which reads this file. 🤖 Generated with Claude Opus 5, at the direction of Paul Campbell.
Reviewed-By: Fable 5.1 (two passes; REQUEST CHANGES on b19f0fa and 31734ff) Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BPUHaNUtTvE7f1VpFWZUHY
1 file changed,
+16
−22
AGENTS.md+16 −22
diff --git a/AGENTS.md b/AGENTS.md| index 2ecd506..8325786 100644 |
| --- a/AGENTS.md |
| +++ b/AGENTS.md |
| @@ -30,14 +30,13 @@ address"** — a magic link's address is at rest between send and click, |
| sealed (§3.2), not absent — and **"some unidentified person"**: a team-set |
| fingerprint plus one outside fact names the row (§3.3). |
| -Three gates enforce it from the first commit that opens a database (§12, |
| -and §13 step 1 lists all three): a **plaintext grep** over the raw SQLite |
| -file and WAL **plus this app's store objects**, against a seeded corpus of |
| -known addresses; a **no-address-at-rest** test asserting the schema has no |
| -address column and that a full sign-in plus directory upsert **plus rekey** |
| -leaves no readable address anywhere, **WAL included**; and |
| -**no-content-in-logs** (gate 9). The skeleton opens no database and so |
| -carries none of them yet. |
| +Three gates enforce it (§12; §13 step 1 lists all three): a **plaintext |
| +grep** over the raw SQLite file and WAL **plus this app's store objects**, |
| +against a seeded corpus of known addresses; a **no-address-at-rest** test |
| +asserting the schema has no address column and that a full sign-in plus |
| +directory upsert **plus rekey** leaves no readable address anywhere, **WAL |
| +included**; and **no-content-in-logs** (gate 9). Gates 1 and 2 need a |
| +database and the skeleton has none; gate 9 does not, and is not there yet. |
| --- |
| @@ -115,30 +114,24 @@ quietly ignored). |
| home already holds it for its own purposes, so carrying it adds nothing to |
| what the home knows. Theme passes both. A role fails (a). **"Which |
| documents you can see" passes (a) and fails (b)** — it hands the home a |
| - document-level graph it has no business holding, and it is the proposal |
| - most likely to arrive looking reasonable. |
| -- **Do not restore the earlier one-sided wording** ("the instance would |
| - behave identically given a hostile value"). §5.4 records why: it is false |
| - even for theme, since a hostile value gives an ugly page and an ugly page |
| - *is* different behaviour — a test its own example fails is a gap someone |
| - smuggles through — and it assumed the validation that makes it safe, since |
| - a free-string theme interpolated into CSS is an injection, not an ugly |
| - page. |
| + document-level graph it has no business holding. |
| +- **Do not restore "the instance would behave identically given a hostile |
| + value."** §5.4 retracts it: a hostile theme gives an ugly page, which *is* |
| + different behaviour, so the test's own example fails it — and without (a)'s |
| + closed set, a free-string theme in CSS is an injection, not an ugly page. |
| - Assertion expiry is **120 seconds, not "seconds"** — sized to worst-case |
| cold wake plus clock skew, because the exchange request *is* what wakes a |
| hibernating instance and a tighter window makes the first sign-in to any |
| cold instance fail and loop. Widening it costs nothing **against the |
| threat model**, because **single-use `jti` is what stops replay**, not |
| - brevity. The long-lived thing is the session |
| - the instance mints. |
| + brevity. The long-lived thing is the session the instance mints. |
| - Every assertion names the **app and instance host** it is for. Without |
| audience binding, team A's assertion replays against team B, and a |
| deployment has thousands of siblings to replay against. |
| - **Signed identity claims are trusted for identity; every other claim must |
| be cosmetically failable.** The subject flagrantly fails (a) — a hostile |
| subject is account takeover — so the test must exempt identity by |
| - construction or it proves too much and gets |
| - argued around. |
| + construction or it proves too much and gets argued around. |
| - **Any "prune when all consumers have caught up" is unbounded in a |
| hibernating fleet.** A dormant instance runs no timers to advance its |
| cursor. Retention is a fixed horizon or a per-consumer TTL, never a |
| @@ -164,7 +157,8 @@ quietly ignored). |
| whole suite directory. |
| - Migrations are additive-only. |
| - **No address, team name, or queue payload in any log line, error string, |
| - job status message or metric label.** Platform-held logs are storage we cannot grep. |
| + job status message or metric label.** Platform-held logs are storage we |
| + cannot grep. |
| **Frontend** |
| - Write `class="rst-*"`. The bare-attribute grammar is ruled but not |