feat: cut /legal/privacy/ §Who can see it to four plain statements; name SML Company Ltd on the consent; close Q64 moot

Two rulings from Pouya, 2026-09-02.

(1) The section stays generic — "it over-explains technical mechanics that
belong in the evidence file, not in front of an inquirer." Deleted: the
measurement paragraph, the root-credential sentence, the SSO/federated-login
enumeration, the resource-policy clause, the "company that runs a database"
aside, the deploy-credential sentence and the three-copies summary. All of it
stays true and stays measured in AGENTS.md §7 and the evidence file, which now
maps each shipped sentence to what it rests on.

(2) The consent string names the corporation: "I consent to SML Company Ltd
storing and using the information in this form…". docs/05 §Consent text moves
with it, proven byte-identical. Two new §4 rows carry the attestations the copy
rests on.

(3) The §Who can see it approval closes via the page read-through, which is now
blocker 2 in docs/06's callout rather than a checklist line.

Q64 closes MOOT — the paragraph it was about was deleted, so it gates nothing.
The underlying gap is unchanged: §7 records root as held by Pouya, not held only
by Pouya, and nothing about root custody may be published without asking again.

Two sentences were added back under review: the shared-account disclosure, to
§Where it is stored (a storage disclosure, never named in the ruling — without
it no page said the intake sits in a shared account), and one naming SML Company
Ltd in the policy, because a consent naming a company the linked policy never
mentions is an accountability gap.

adversarial-reviewer, two rounds, 14 findings, all resolved, none declined;
nine of round 2's ten were defects in round 1's own repairs. claims-auditor
correctly deferred to cutover per D20.

Gates, exit status read: check 0 · build 0 (23 pages) · check:claims 0
(12 patterns, 33 approved strings) · check:intake 0 · og:proof 0 · lint 0 ·
lighthouse 0, worst of 23 99/100/100/100. Tripwire proven both ways — exit 0 on
the revised page, exit 1 with 5 matches on the bd282aa bytes. Regex untouched.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Md3GndFqWPzK78xAoebsg5
This commit is contained in:
Pouya Lajevardi
2026-09-02 12:03:47 -04:00
co-authored by Claude Opus 5
parent 99889a3491
commit 4735989f0b
7 changed files with 602 additions and 259 deletions
+12 -4
View File
@@ -146,7 +146,7 @@ might reasonably treat as privileged. The intake call is for that.
### Consent text
> I consent to Pouya Lajevardi storing and using the information in this form to
> I consent to SML Company Ltd storing and using the information in this form to
> respond to my inquiry and to run a conflicts check. I understand that
> submitting this form does not create a retainer, does not appoint a neutral,
> and does not itself establish a mediatorparty relationship.
@@ -216,8 +216,16 @@ against this row.
| `ttl` | epoch seconds — **the input to automatic deletion; see §Retention for why writing it is not the mechanism** |
**Encryption at rest** with a customer-managed KMS key. **Point-in-time recovery
on.** Table access limited to the Lambda role and one named administrative
principal.
on.** ⚠️ **THE THIRD LINE HERE WAS *"table access limited to the Lambda role and
one named administrative principal"*, AND IT WAS THE Q62 FALSEHOOD — struck
2026-09-02.** It is false on both halves: `adr-intake-lambda-role` holds
`PutItem` **only** and cannot read the table at all, and access is not one
principal. **`AGENTS.md` §7's `Intake table — who can read it` row is the answer
and this spec does not restate it** — a duplicated fact is one that goes wrong in
the copy nobody re-reads, which is what happened here: the Q62 sweep ran over
`src/` and never reached a spec, and `check:claims` carries this exact sentence
as a string that reached `dist/`. It survived the sweep this file's own
definition-of-done claims to have completed (`adversarial-reviewer`, round 2).
⚠️ **TWO OF THOSE THREE ARE THE STATE OF THE RUNNING TABLE AND ONE IS NOT.**
PITR is **on** `[verified 2026-09-01 — describe-continuous-backups,
@@ -446,7 +454,7 @@ Plausible or Fathom, cookieless, no consent banner.
- [ ] **TTL set and verified by test record.** ⚠️ **THIS ONE BACKS A PUBLISHED PROMISE.** `/legal/privacy/` states that records are deleted automatically after 24 months, and it asserts the **mechanism**, not only the period. The handler writes the `ttl` attribute — epoch seconds, 24 months, confirmed against this spec `[verified 2026-08-31]` — and **writing the attribute is not the mechanism**: TTL must also be enabled on the table, which is a table setting the code cannot see. **`AGENTS.md` §7 holds that status and its stamp; this line does not restate it** — it restated it once, went stale within the day, and had to be pulled back (§12 R19). **The test record is what closes this item, not the status:** `ENABLED` proves the setting, a record written with a near-future `ttl` and observed to vanish proves the behaviour. Tracked as §9 Q60
- [x] **PITR enabled** — `ENABLED`, 35-day window `[verified 2026-09-01 — describe-continuous-backups]`
- [ ] KMS customer-managed key. **Not on the table: encryption at rest is with the AWS-owned key** `[verified 2026-09-01 — describe-table returns no SSEDescription]`. **Not claimed on `/legal/privacy/`** — the page says "encrypted at rest", which is unconditionally true of every DynamoDB table and does not mention a customer-managed key, so nothing published depends on it. An improvement, not a blocker
- [x] ✅ **Table access matches what `/legal/privacy/` says about it — 2026-09-02.** **The access is unchanged; the page now states it.** Pouya ruled *state the truth* rather than *remove the access* (§9 Q62), so the page attributes read access to **the account's administrators of a shared account, with no human headcount** — the count came off later the same day under §9 Q63, because a simulation counts identities and the page was reading them as people — and adds the two stronger facts the false sentence had crowded out: the handler role holds `PutItem` **only**, and `adr-sml-deploy` is `implicitDeny` on all seven read **and** write actions. Evidence and commands: `docs/reference/intake-table-access-verification.md`, whose enumeration was **extended on 2026-09-02** — the original screened roles by `list-attached-role-policies` alone, missing that 23 of 26 non-service-linked roles carry inline policies and that the two CDK `lookup` roles can read the table. Four roles can, not two; every one of them is reachable only by those administrators. ⚠️ **Do not restate that as a count of PEOPLE** — this line said *"all four terminate at the same two people"* until 2026-09-02, which is the inference §9 Q63 struck. ⚠️ **THIS LINE SAID "IT DOES NOT" FOR A DAY AFTER THE PAGE WAS CORRECTED, AND IT IS A DEFINITION-OF-DONE LIST SOMEONE FOLLOWS AT CUTOVER** — the Q62 sweep was run over `src/` only, so it could not reach a spec. `adversarial-reviewer`, round 1. The sweep across `docs/` is in the Change Log entry
- [x] ✅ **Table access matches what `/legal/privacy/` says about it — 2026-09-02.** **The access is unchanged; the page now states it.** Pouya ruled *state the truth* rather than *remove the access* (§9 Q62), so the page states the truth about access rather than a false exclusivity. ⚠️ **WHAT IT STATES CHANGED TWICE MORE THAT DAY AND THIS LINE IS WRITTEN AGAINST THE SHIPPED BYTES, NOT AGAINST THE RULING.** §9 Q63 took the human headcount off (a simulation counts identities and the page was reading them as people), and a second ruling then cut §Who can see it to **four plain statements**. The page now says: *"The record in the table: me, and the small number of people who administer the account it sits in with me"*; that the receiving system *"can only add a record — it cannot read back what is stored"*; where the notification goes and who reads it; and that the confirmation sits with the reader's own provider. **§Where it is stored carries the shared-account disclosure** — *"an Amazon Web Services account that also runs systems unrelated to this practice"*. ⚠️ **`adr-sml-deploy` is `implicitDeny` on all seven read AND write actions — MEASURED, TRUE, AND NO LONGER ON THE PAGE**; it went with the mechanics cut and it is §7's claim now, not the policy's. Do not tick this item against a page that states it. Evidence and commands: `docs/reference/intake-table-access-verification.md`, whose enumeration was **extended on 2026-09-02** — the original screened roles by `list-attached-role-policies` alone, missing that 23 of 26 non-service-linked roles carry inline policies and that the two CDK `lookup` roles can read the table. Four roles can, not two; every one of them is reachable only by those administrators. ⚠️ **Do not restate that as a count of PEOPLE** — this line said *"all four terminate at the same two people"* until 2026-09-02, which is the inference §9 Q63 struck. ⚠️ **THIS LINE SAID "IT DOES NOT" FOR A DAY AFTER THE PAGE WAS CORRECTED, AND IT IS A DEFINITION-OF-DONE LIST SOMEONE FOLLOWS AT CUTOVER** — the Q62 sweep was run over `src/` only, so it could not reach a spec. `adversarial-reviewer`, round 1. The sweep across `docs/` is in the Change Log entry
- [ ] Both emails send; SPF/DKIM/DMARC aligned; inbox-tested, not spam-tested
- [ ] **CloudWatch alarms on Lambda `Errors` and API Gateway `5xx`** — replacing the DLQ item, which is struck: a DLQ on a **synchronously** invoked function never receives anything, so the alarm on its depth would have been permanently green. See §Notification. The handler writes to DynamoDB **before** sending mail, so the protection this item was pointing at is in the code rather than in a queue
- [x] **Form usable by keyboard only.** Errors are announced by the browser's own validation, which with no script is the only thing that can announce them inline — `role="alert"` needs a live region and something to write into it