From 99889a349136daa3456ad84b73047a6aa6e75f37 Mon Sep 17 00:00:00 2001 From: Pouya Lajevardi Date: Wed, 2 Sep 2026 11:00:15 -0400 Subject: [PATCH] feat: rule Q63 in three limbs; take the human headcount off /legal/privacy/; close R10; ratify /med-arb/ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pouya's rulings, 2026-09-02. Q63(a) — wording approved with two trims: the editorial closing sentence is struck, and the mailbox clause is rewritten per (b). Q63(b) — info@smlcompany.ca is a delegated mailbox read by Pouya and by administrative staff. The page said "anyone who can reach that mailbox"; it now says who. The answer reached four sentences, not the one the ruling named, in three sections: "my mailbox" had been written as a personal one throughout. Q63(c) — the account root credential is held by Pouya, has no programmatic key and carries MFA. The page now states the first two. And the answer to (c) took the human headcount off the page. His attestation: "two people is an exaggeration... a handful is accurate — the simulation counts identities, not humans, and the two are not the same claim." The enumeration was exhaustive and the inference off it was not: two IAM identities is a LOWER BOUND on people and was published as an exact count. The page now attributes read access to "the account's administrators — me, and the small number of people who administer it with me", and the false inference is corrected at its source in docs/reference/intake-table-access-verification.md as well as on the page. R10 — CLOSED on a fresh one-line confirmation, not on the 2026-08-28 stamp. ADRIC, ADRIO, the three OBA sections and the CTF all current. Re-stamped on all four stamp-bearing sites; the row stays live, because its trigger is an event. /med-arb/ — ratified as shipped, no credential line restored. His note for the record: med-arb is a service he provides, not a designation. The tripwire is unchanged and proven both ways: exit 0 on the revised page, exit 1 with 5 matches on the pre-correction bytes rebuilt from bd282aa. A sentence added to back the correction had no command behind it. "The table carries no policy of its own granting access to anyone" was published with nothing in the repo establishing it — a DynamoDB resource policy is invisible to describe-table, and every simulation on file asks what a principal may do. Measured rather than deleted: get-resource-policy returns PolicyNotFoundException, and describe-organization returns AWSOrganizationsNotInUseException, which is what makes the Identity Center zero conclusive rather than merely local. Both recorded as commands 7 and 8; R21 gains claim (v) and two falsifiers. Q64 OPENED, with a TODO(pouya) and an unticked cutover item: "I hold it" is true whether or not a second person holds it, and reads as sole custody one paragraph below "the small number of people who administer it with me". The request to strike the possessive now is declined with a reason — he dictated the clause — and the page cannot ship while the TODO stands. Two review rounds, 22 findings, 21 resolved, 1 declined. Nine of round 2's twelve were defects in round 1's own repairs. Stopped at two per D19. Gates, exit status read: check 0 · build 0 (23 pages) · check:claims 0 · og:proof 0 · check:intake 0 · lint 0 · router.test 0 (30/30) · lighthouse 0, worst of 23 99/100/100/100, /legal/privacy/ 100/100/100. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01Md3GndFqWPzK78xAoebsg5 --- AGENTS.md | 235 +++++++++++++++++- docs/05-backend-spec.md | 2 +- docs/06-deployment.md | 214 ++++++++++++---- .../intake-table-access-verification.md | 151 ++++++++--- scripts/check-claims.mjs | 40 +-- src/data/schema.ts | 6 +- src/data/site.ts | 14 +- src/pages/about.astro | 11 +- src/pages/legal/privacy.astro | 153 ++++++------ 9 files changed, 641 insertions(+), 185 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 8afd2fa..ac42509 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -183,7 +183,7 @@ since May. | Iranian-Canadian; cross-cultural fluency with diaspora business communities | `[verified 2026-08-25 — strategy brief §I]` | | Operator of SML Company Ltd. alongside the practice | `[verified 2026-08-25 — strategy brief §I]` | | **SML Company Ltd — incorporated FEDERALLY, under the CBCA** | `[verified 2026-08-26 — Pouya, Q30]`. Two facts were being conflated and one of them was wrong: **jurisdiction of incorporation is federal (Canada)**; **place of business is Toronto, Ontario**. `src/data/site.ts` carried `'SML Company Ltd. · Ontario, Canada'`, which reads as a jurisdiction of incorporation and named the wrong one. **No corporation number** — none is held and the line does not need one. **Caution, and it is the point of this row:** "federally incorporated" says nothing about professional licensure, and nothing about where the practice may operate. It must not be read together with the **Licence status — NOT ESTABLISHED** row into an implication that neither row makes. **Not published:** on Pouya's direction the footer reads `© SML Company Ltd` and nothing further — the fact is verified and available, it is simply not on a page | -| Memberships: **ADRIC**, **ADRIO**, **OBA — Construction & Infrastructure, ADR, and Civil Litigation sections**, and the **Canadian Tax Foundation** | **`[verified 2026-08-28 — Pouya]` — RE-CONFIRMED, R10 DISCHARGED, AND NOW PUBLISHED ON `/about/`.** Q44 closed: *"All four are current as of today."* **Note on the stamp date, because it is a currency stamp and the date is the whole content:** Pouya's ruling said *"Stamp `[verified 2026-08-26 — Pouya]`"*, which is the date of the **original** confirmation. The stamp here reads **2026-08-28**, the date he actually re-confirmed — a stamp records when the assertion was made, and back-dating a re-confirmation by two days would understate the only thing the stamp is for. Flagged to him; one edit to change if he meant otherwise. **NO CURRENCY WARRANTY MAY BE PUBLISHED.** His words: *"List the memberships; promise nothing about their future state."* The struck sentence (*"Memberships are renewed annually and are listed as current"*) stays struck and nothing replaces it. **Renewal periods: the OBA sections and the CTF renew yearly. This record says NOTHING about ADRIC's or ADRIO's period** — an earlier form asserted "all four renew yearly" and that widened form propagated to four files. **He declined renewal-date tracking**, so R10 no longer fires on a date; it fires on an **event** — re-confirm before any cutover or major republish. **`memberOf` IS NOW EMITTED** on `/about/`'s Person node — Q53, ruled 2026-08-28; the withholding is dropped and this sentence said the opposite until the sweep that should have caught it was run. So the graph and the visible list assert the same four lines, and R10's event trigger covers both. `/`'s Person node omits it, because `/` shows no memberships. **CTF is a membership, not a practice area** — it is the one credential none of the six areas touch, and `docs/01-architecture.md` records why there is no seventh page at launch and when to revisit (R3) **Q51 CLOSED 2026-08-28 — the OBA sections STAY, and the distinction is structural.** Pouya: *"the Law Society is the regulator, so membership IS licensure; the OBA is a voluntary association."* That is why the `~~LSO~~` row below excludes one and this row publishes the other, and it holds **independently of eligibility details** — which is what made the question unanswerable inside this repo. Recorded so it is not re-litigated: a voluntary professional association admits members it does not license, so listing it carries no licensure implication; a regulator's membership roll *is* the licence. | +| Memberships: **ADRIC**, **ADRIO**, **OBA — Construction & Infrastructure, ADR, and Civil Litigation sections**, and the **Canadian Tax Foundation** | **`[verified 2026-09-02 — Pouya]` — RE-CONFIRMED ON THE DAY OF CUTOVER, R10 FIRED AND SATISFIED.** Asked as a one-line question and answered 2026-09-02: **ADRIC, ADRIO, the three OBA sections and the CTF are all current.** The previous stamp was `[verified 2026-08-28 — Pouya]` and **it was not re-read to produce this one** — R10's whole content is that a stamp is not a renewal receipt. Both surfaces moved together: `CREDENTIALS.memberships` in `src/data/site.ts` (the visible list on `/about/`) and `memberOf` in `src/data/schema.ts`, which reads `MEMBERSHIP_ORGS`. **R10 does not close** — it fires on an event and events recur; the next fire is the next major republish. Original text follows. **RE-CONFIRMED, R10 DISCHARGED, AND NOW PUBLISHED ON `/about/`.** Q44 closed: *"All four are current as of today."* **Note on the stamp date, because it is a currency stamp and the date is the whole content:** Pouya's ruling said *"Stamp `[verified 2026-08-26 — Pouya]`"*, which is the date of the **original** confirmation. The stamp here reads **2026-08-28**, the date he actually re-confirmed — a stamp records when the assertion was made, and back-dating a re-confirmation by two days would understate the only thing the stamp is for. Flagged to him; one edit to change if he meant otherwise. **NO CURRENCY WARRANTY MAY BE PUBLISHED.** His words: *"List the memberships; promise nothing about their future state."* The struck sentence (*"Memberships are renewed annually and are listed as current"*) stays struck and nothing replaces it. **Renewal periods: the OBA sections and the CTF renew yearly. This record says NOTHING about ADRIC's or ADRIO's period** — an earlier form asserted "all four renew yearly" and that widened form propagated to four files. **He declined renewal-date tracking**, so R10 no longer fires on a date; it fires on an **event** — re-confirm before any cutover or major republish. **`memberOf` IS NOW EMITTED** on `/about/`'s Person node — Q53, ruled 2026-08-28; the withholding is dropped and this sentence said the opposite until the sweep that should have caught it was run. So the graph and the visible list assert the same four lines, and R10's event trigger covers both. `/`'s Person node omits it, because `/` shows no memberships. **CTF is a membership, not a practice area** — it is the one credential none of the six areas touch, and `docs/01-architecture.md` records why there is no seventh page at launch and when to revisit (R3) **Q51 CLOSED 2026-08-28 — the OBA sections STAY, and the distinction is structural.** Pouya: *"the Law Society is the regulator, so membership IS licensure; the OBA is a voluntary association."* That is why the `~~LSO~~` row below excludes one and this row publishes the other, and it holds **independently of eligibility details** — which is what made the question unanswerable inside this repo. Recorded so it is not re-litigated: a voluntary professional association admits members it does not license, so listing it carries no licensure implication; a regulator's membership roll *is* the licence. | | ~~OCNI~~ | **Not current. Do not publish** `[verified 2026-08-26 — Pouya]` | | ~~LSO~~ | **Do not publish.** Listing the Law Society among memberships implies licensure, which D13 bars. Excluded deliberately, not by oversight `[verified 2026-08-26]` | | Toronto, Ontario; by appointment | `[verified 2026-08-26]` | @@ -723,7 +723,8 @@ the audience it targets. Revisit at month 12–18. `[verified 2026-08-25 — dec | Intake API | `adr-intake-api`, HTTP API `4tl0m5igkj`, endpoint `https://4tl0m5igkj.execute-api.ca-central-1.amazonaws.com` `[verified 2026-08-26]`. **One route, `POST /submissions`** → integration `0ftgjgv` (`AWS_PROXY`, payload format **2.0**, which is the format `handler.mjs` reads). Stage `$default`, auto-deploy on, **no throttling**, no access log. CORS allows `POST` from the site origin `[verified 2026-09-01 — get-routes, get-api, get-stages, get-integrations]`. `DisableExecuteApiEndpoint` is **false** and must stay false: the CloudFront origin **is** that hostname. The form's route (`POST /api/intake`) does not exist yet — `docs/09` Part 6 | | Intake Lambda | `adr-intake-handler`, `nodejs24.x`, **arm64**, handler `index.handler`, timeout **10 s**, memory **128 MB**, role `adr-intake-lambda-role`, **no environment variables**, no DLQ, code **1,527 bytes**, last modified 2026-05-26 `[verified 2026-09-01 — get-function-configuration]`. **That is still the HAND-BUILT function, not `backend/intake/handler.mjs`** — nothing has been deployed (D11). Its resource policy has **one** statement, `apigateway.amazonaws.com` conditioned on `SourceArn` `…/4tl0m5igkj/*/*/submissions` — **the old route's path only**, so a new route needs its own permission or API Gateway is refused and answers 500 with nothing in the Lambda log. The execution role is **sufficient as it stands**: `dynamodb:PutItem` on the table (write-only — it cannot read it), `ses:SendEmail`/`SendRawEmail`, plus `AWSLambdaBasicExecutionRole`. Deployment commands: `docs/09-cutover-runbook.md` Part 5 | | Intake table | `adr-intake-submissions` (DynamoDB, ca-central-1) `[verified 2026-08-26]`. ⚠️ **KEY SCHEMA: PARTITION KEY `submissionId` (S), NO SORT KEY** ``[verified 2026-09-01 — `aws dynamodb describe-table`]``. **This contradicted `docs/05`, which specified `pk`/`sk`, and `backend/intake/handler.mjs` was written to the spec** — a `PutItem` missing the key attribute fails the whole write with `ValidationException`, the handler catches it and returns the failure page, so **every submission would have been lost while looking like a browser problem**. A DynamoDB key schema cannot be altered after creation; the handler was changed to the table on 2026-09-01 and `docs/05` §Storage carries the correction and the declined alternative. PITR **`ENABLED`**, 35-day window `[verified 2026-09-01 — describe-continuous-backups]`. Encryption at rest uses the **AWS-owned key — there is no customer-managed KMS key** `[verified 2026-09-01 — describe-table returns no SSEDescription]`, which `/legal/privacy/` does not claim, so nothing published depends on it. **4 items predate this repo**, written by the hand-built handler, which writes **no `ttl`** — so they never expire; `docs/06` carries that as Pouya's call. **TTL IS `ENABLED`, `AttributeName: ttl`** ``[verified 2026-08-31 — Pouya ran `describe-time-to-live` and read `TimeToLiveStatus: ENABLED`]``. The handler side matches: `backend/intake/handler.mjs` writes `ttl` as a Number in **epoch seconds** at **24 months** (`RETENTION_MONTHS = 24`, added to `getUTCMonth()`), which is `docs/05` §Retention and the `ttl` row of its item table `[verified 2026-08-31 — read from the handler, not recalled]`. ⚠️ **IT WAS `DISABLED` AT FIRST VERIFICATION EARLIER THE SAME DAY, AND THAT IS RECORDED RATHER THAN OVERWRITTEN.** Pouya ran `describe-time-to-live` on **2026-08-31** and it returned `DISABLED`; he enabled it on **2026-08-31** and re-read `ENABLED` the same day. `/legal/privacy/` has stated since build step 10 that a record is *"deleted automatically by the database rather than by someone remembering to do it"* after 24 months, so **that promise was unbacked from the day it was written until the day it was enabled** — the handler wrote the attribute and nothing on the table consumed it. This is the Q22 shape on a public privacy commitment rather than on a deploy control: a documented mechanism that did not exist. ⚠️ **`ENABLED` PROVES THE SETTING, NOT THE BEHAVIOUR, AND THE BEHAVIOUR IS STILL UNPROVEN — §9 Q60 STAYS OPEN.** No record has been written with a near-future `ttl` and watched to disappear. `docs/06`'s cutover checklist carries that test as a blocking item, it is not ticked by reading this row or the handler code, and §12 R19 keeps it surfacing until a deletion has actually been observed | -| **Intake table — who can read it** | 🛑 **TWO PEOPLE, AND `/legal/privacy/` PUBLISHES THAT NUMBER, WHICH IS WHY IT LIVES IN §7 AND NOT ONLY IN A REFERENCE EXTRACT.** `user/pouya` and `user/lars`, both via group **`admins`** carrying `AdministratorAccess`. **Four roles can also read it** — two `cdk-hnb659fds-cfn-exec-role-*` (all seven actions; trust `cloudformation.amazonaws.com` only) and two `cdk-hnb659fds-lookup-role-*` (the four read actions; trust the account root, and `sts:AssumeRole` is **allowed only for those same two users**). **`adr-intake-lambda-role` holds `PutItem` ONLY** — implicitDeny on `GetItem`/`Query`/`Scan`/`BatchGetItem`/`UpdateItem`/`DeleteItem`. **`adr-sml-deploy` is implicitDeny on all seven.** The CDK/CloudFormation escalation path is implicitDeny for all three deploy users. No SAML, OIDC or Identity Center principal exists (0/0/0). No resource-based policy on the table. Root holds **no access keys**, MFA on. ``[verified 2026-09-02 — 5 users x 7 actions, **all 33** roles x 7 actions — 26 non-service-linked and, added 2026-09-02, the 7 service-linked ones every earlier sweep had excluded by `grep -v '^AWSServiceRole'`, all implicitDeny, 4 trust policies, 5 users x 6 CDK-path actions, all in `docs/reference/intake-table-access-verification.md` with the counts asserted per call]``. ⚠️ **THE ORIGINAL 2026-09-01 VERIFICATION WAS NOT ENOUGH FOR THE SENTENCE IT BACKED**: it screened roles with `list-attached-role-policies` alone, so it never saw that **23 of 26 roles carry inline policies** and that the two `lookup` roles can read the table. Four roles can, not two. The conclusion held; the reasoning did not. **THE PAGE GOES FALSE IF THIS CHANGES AND NOTHING IN AWS WILL SAY SO — §12 R21 is the trigger.** | +| **Intake table — who can read it** | 🛑 **TWO IAM IDENTITIES — AND THAT IS A COUNT OF IDENTITIES, NOT OF PEOPLE. `/legal/privacy/` NO LONGER PUBLISHES A HUMAN NUMBER (Q63, ruled 2026-09-02).** ⚠️ **THE DISTINCTION IS THE ROW'S MOST IMPORTANT CONTENT, because this register supplied the false one.** The enumeration below is exhaustive over identities and every read path terminates at `user/pouya` or `user/lars` — and the page then rendered that as *"Two people can"*. **Pouya's attestation, 2026-09-02: *"two people is an exaggeration… a handful is accurate"*.** A simulation cannot see how many humans reach a credential, so the identity count is a **lower** bound on people and was published as an exact one. The page now says *"the account's administrators — me, and the small number of people who administer it with me"*, and **no numeric human headcount may ship**. **ROOT: held by Pouya `[verified 2026-09-02 — Pouya, Q63(c)]`** — not an IAM principal, cannot be simulated, no policy constrains it; `AccountAccessKeysPresent: 0` and `AccountMFAEnabled: 1` `[verified 2026-09-02]`. The identity facts follow, and they are unchanged and still exhaustive. `user/pouya` and `user/lars`, both via group **`admins`** carrying `AdministratorAccess`. **Four roles can also read it** — two `cdk-hnb659fds-cfn-exec-role-*` (all seven actions; trust `cloudformation.amazonaws.com` only) and two `cdk-hnb659fds-lookup-role-*` (the four read actions; trust the account root, and `sts:AssumeRole` is **allowed only for those same two users**). **`adr-intake-lambda-role` holds `PutItem` ONLY** — implicitDeny on `GetItem`/`Query`/`Scan`/`BatchGetItem`/`UpdateItem`/`DeleteItem`. **`adr-sml-deploy` is implicitDeny on all seven.** The CDK/CloudFormation escalation path is implicitDeny for all three deploy users. No SAML, OIDC or Identity Center principal exists (0/0/0) — **and the account is not in an AWS Organization (`AWSOrganizationsNotInUseException`), which is what makes that Identity Center zero conclusive rather than merely local** `[verified 2026-09-02]`. **No resource-based policy on the table: `dynamodb get-resource-policy` returns `PolicyNotFoundException`** `[verified 2026-09-02]` — a command, not an inference; a resource policy is invisible to `describe-table` and grants from the opposite side to every simulation here, so nothing else in the enumeration could have seen one. Root holds **no access keys**, MFA on. ``[verified 2026-09-02 — `get-resource-policy` on the table, `organizations describe-organization`, 5 users x 7 actions, **all 33** roles x 7 actions — 26 non-service-linked and, added 2026-09-02, the 7 service-linked ones every earlier sweep had excluded by `grep -v '^AWSServiceRole'`, all implicitDeny, 4 trust policies, 5 users x 6 CDK-path actions, all in `docs/reference/intake-table-access-verification.md` with the counts asserted per call]``. ⚠️ **THE ORIGINAL 2026-09-01 VERIFICATION WAS NOT ENOUGH FOR THE SENTENCE IT BACKED**: it screened roles with `list-attached-role-policies` alone, so it never saw that **23 of 26 roles carry inline policies** and that the two `lookup` roles can read the table. Four roles can, not two. The conclusion held; the reasoning did not. **THE PAGE GOES FALSE IF THIS CHANGES AND NOTHING IN AWS WILL SAY SO — §12 R21 is the trigger.** | +| **`info@smlcompany.ca` — who reads it** | **A DELEGATED MAILBOX: Pouya AND administrative staff `[verified 2026-09-02 — Pouya, Q63(b)]`.** D18 sends the intake notification here, so this is the access list for the **second** copy of every submission — including the opposing parties and their counsel, which is the most sensitive thing the form collects. `/legal/privacy/` states it in terms (*"read by me and by administrative staff"*), having previously said *"anyone who can reach that mailbox"* — true either way, and a lower standard than the measured answer given one paragraph earlier for the table. ⚠️ **THIS IS AN ATTESTATION, NOT A MEASUREMENT, and it is the only fact behind a `/legal/privacy/` sentence that is.** Nothing in this repository or in AWS can check it: the mailbox is on Google Workspace (see the mail-hosting row) and this repo holds no Workspace credential. **It goes stale the way the AWS enumeration does and by the same mechanism — nobody is told when a delegation changes — so §12 R21's trigger covers it too.** | | SES identities | Domain `smlcompany.ca` **verified for sending** `[verified 2026-08-26]`; addresses `info@`, `intake@`, `adr@` | | SES account | **Production access GRANTED** — out of the sandbox in `ca-central-1`, confirmed by AWS in writing and effective immediately `[verified 2026-08-26 — Q19 closed]`. Mail now reaches unverified recipients, so the inquirer confirmation in D18 works | | Mail hosting | **Google Workspace** — MX `1 smtp.google.com`; `google._domainkey` present, so Google DKIM is configured `[verified 2026-08-26 — DNS query]` | @@ -774,8 +775,9 @@ Nothing below can be invented. Each needs an answer from Pouya. | # | Question | Blocks | |---|---|---| -| **Q63** | 🛑 **TWO THINGS `/legal/privacy/` STILL NEEDS FROM POUYA, AND THEY ARE ANSWERED IN THE SAME READ-THROUGH.** **(a) APPROVE THE §Who can see it WORDING.** Q62 settled what it must say and he reserved the wording in terms: *"Draft it; Pouya gives final approval on wording during his page read-through."* The draft is shipped in `dist/` and quoted in `docs/reference/intake-table-access-verification.md`. **This is a gate that existed only inside records marked closed until 2026-09-02** — the `TODO(pouya)` had been deleted, Q62 struck, and `docs/06`'s blocker ticked, so when Q60's TTL test passes **nothing mechanical or visual would have stopped unapproved copy publishing.** `adversarial-reviewer`, round 1. **(b) WHO ELSE CAN READ `info@smlcompany.ca`?** Nothing in this repository establishes it — §7 records the mail host (Google Workspace) and the SES identities, **not the mailbox's access list**, and a Workspace super-admin can reach any mailbox in the tenancy. Given that this project's AWS account, its Gitea instance and §10 are all jointly administered, the plausible case is that it is not only him. The copy is now written to assert **no** access list (*"anyone who can reach that mailbox"*), so nothing false is published either way — but a privacy policy that answers the table half with a measured number and the mail half with a shrug is answering the same question on two standards, and the reader is entitled to the specific on both. **(c) WHO HOLDS THE ROOT CREDENTIAL FOR THE AWS ACCOUNT?** The page's headline answer is a **count of people**, and root is the one path no policy constrains and no simulation can reach — it is not an IAM principal and does not appear in `list-users`. Two facts bound it: `AccountAccessKeysPresent: 0`, so there is no programmatic root credential, and MFA is on, so console access needs the root password and its device `[verified 2026-09-02]`. **If those are held by anyone other than the two administrators, "Two people can" is short by one.** The second paragraph is scoped to *"every user and every role"* and to who has been **granted** access, so it is unaffected either way — this reaches the first sentence only. Raised by `adversarial-reviewer`, round 2, which is also where the honest form of the objection came from: the artefact says in terms that this is not established, and a page was resting a count on it. **If he answers: put the fact in §7, make the sentence specific like the table sentence above it, and arm it with §12 R21's trigger.** Raised by `claims-auditor` and `adversarial-reviewer`, D20 cutover pass round 1, 2026-09-02 | **`/legal/privacy/` going public, and therefore the cutover.** `src/pages/legal/privacy.astro` carries the `TODO(pouya)`; `docs/06`'s checklist carries (a) as its own unticked item. It blocks no other page | -| ~~**Q62**~~ | ✅ **CLOSED 2026-09-02 — RULED *state the truth*, NOT *remove the access*. Pouya:** *"Rewrite the `/legal/privacy/` sentence to say exactly who can access the submissions table… the true number of people and their roles, stated specifically — not 'authorised administrators' or any other vacancy."* **Applied.** The page now opens §Who can see it with *"Two people can"*, states that the AWS account also runs systems unrelated to this practice and has two administrators, and says administrative access carries the ability to read the table. It then publishes the two facts the false sentence had been crowding out and which are **stronger** than what it claimed: the function that receives the form can only add a record and **cannot read the table back**, and the credential that publishes this website has **no access to the table at all**. ⚠️ **THE FIX TOUCHED THREE PLACES, NOT ONE, AND THE OTHER TWO ARE THE POINT.** A vocabulary sweep — `grep -rniE "no (team\|assistant\|outside\|external) [a-z]*\|nobody else\|no one else" src/` — found the same falsehood in different words **two sections up the same page**: §Where it is stored ended *"and no assistant or outside administrator"*, which the Q62 pattern could not see because it was anchored on the two sentences under the other heading. And the summary paragraph closed *"the honest answer to 'who can see this' is: me, and Google"* — which would have survived the correction directly above it and re-asserted the struck number. All three now change together and the page's own comment says so. **THE TRIPWIRE STAYS PERMANENTLY — his ruling in terms:** *"it bars the false-claim shape from returning, which is exactly what the freeze's breach exception exists for."* Extended from two alternatives to **five** — round 1 of the closing audit found a third published surface unbarred, and found the first extension had widened one alternative to four phrasings where one was published. Every alternative is now a single string that reached `dist/`, so nothing speculative entered a frozen script. **Proven both ways, on real published bytes and not on fixtures alone:** against the pre-correction page rebuilt from `bd282aa` it exits **1** with **5 matches** at `dist/legal/privacy/index.html:54, 67, 67, 68, 72` — 54 is the clause the first form missed and 72 the surface it could not see at all — and against the corrected page it exits **0**, self-test 12 patterns / **36** approved strings, with **six** negative fixtures drawn from the replacement copy itself. ⚠️ **The counts in this row said four/four/33/three until 2026-09-02**, describing the script as it stood before round 1's fix; on a frozen script the record of what it bars is the maintenance surface, so `adversarial-reviewer` round 2 was right to treat a stale count as a defect. ⚠️ **AND THE FIX AS FIRST WRITTEN INTRODUCED THREE DEFECTS OF ITS OWN, ALL FOUND BY THE D20 PASS ROUND 1 AND ALL NOW CORRECTED — see entry (an).** The replacement asserted *"No third party has access to it"* (an absolute negative that excludes a **disclosed processor**, which is the exact sentence struck from this page on 2026-08-31 as *"the most serious thing found in the step 7–10 review"*); it claimed *"every account and role in this infrastructure… that is checked rather than assumed"* over an artefact that had screened five users and **one** role; and it said *"the one other place a copy exists"* when the handler puts the whole submission into the confirmation it sends the inquirer, so a **third** copy sits with the reader's own provider — which this page already says two sections up. **Q62's own fix recreated Q62's shape twice.** **Two things are NOT resolved and are now Q63 rather than a footnote here** — the wording approval Pouya reserved, and the `info@smlcompany.ca` access list. The earlier form of this row called the mailbox point non-gating *"because the copy is true either way"*, which was **a guess about a fact nobody checked**; the copy is now written so it asserts no access list at all, and the question gates the page through Q63 with a `TODO(pouya)` beside it. Original finding follows. 🛑 **`/legal/privacy/` TELLS THE PUBLIC SOMETHING FALSE ABOUT WHO CAN READ THE INTAKE TABLE, AND IT IS A PRIVACY POLICY.** The page says: *"The table is reachable by the function that writes to it and by one administrative account, which is mine — nobody else has access to the table. There is no team, no assistant and no external administrator."* **The account has an IAM group `admins` carrying `AdministratorAccess` with TWO members**, and `iam simulate-principal-policy` returns **allowed** for `dynamodb:GetItem`, `dynamodb:Query` and `dynamodb:Scan` on the table for both of them — identical access, by the same route, the other user's own attachments being only `IAMUserChangePassword` `[verified 2026-09-01 — the five users, the group, and a five-row simulation, all commands in `docs/reference/intake-table-access-verification.md`]`. So **both halves of the sentence are wrong**: a second account has access, and it belongs to a second administrator of a shared account (§10). The three deploy users are `implicitDeny`; two CDK bootstrap roles carry `AdministratorAccess` but are assumable only by the same two administrators; the writing role holds **`PutItem` only and cannot read the table**, which is a stronger fact than the page currently claims and is the part of the sentence that is true. **THE QUESTION, AND IT IS ONE OF TWO THINGS.** (1) **Remove the access** — take that user out of `admins`, or deny DynamoDB on this table — after which the sentence becomes true as written. ⚠️ Note the likely collision: **Q23 records the Gitea instance as jointly administered and blocked on "its second administrator"**, so that access is probably not only for this account and removing it may cost something elsewhere. (2) **State the true number** — how many people hold administrative access, and that the function which writes cannot read. ⚠️ **DO NOT RESOLVE IT BY SOFTENING.** *"Access is limited to authorised administrators"* is the shape §4 exists to bar: defensible, uninformative, and it would replace a false specific with a true vacancy on the one page where a reader describing a live dispute is entitled to the specific. **Why this was invisible until now:** it is the only claim on the site whose subject lives entirely outside the repository, so R14 applies — *"unverifiable by construction"* — and there was no committed artefact to compare it against. There is now. Raised by `claims-auditor`, D20 cutover pass, finding 8 | *(closed)* | +| **Q64** | 🛑 **DOES ANYONE ELSE HOLD THE AWS ROOT PASSWORD OR ITS MFA DEVICE?** `/legal/privacy/` now publishes *"Its root credential — the one path no policy constrains — has no programmatic key, and I hold it"*, which are Pouya's own words from the Q63(c) ruling and are **true whether or not somebody else holds it too**. ⚠️ **The defect is what a reader takes from it.** The sentence sits one paragraph below *"the small number of people who administer it with me"*, so a reader takes *"I hold it"* as **sole** custody — and nothing establishes that. Root is not an IAM principal, cannot be simulated, and `get-account-summary` reports only `AccountAccessKeysPresent: 0` and `AccountMFAEnabled: 1` `[verified 2026-09-02]`; the attestation in §7 says *held by Pouya*, not *held only by Pouya*. **This is Q63's own lesson one paragraph lower and pointing the other way:** Q63 struck a sentence for reading identities as people, and this one invites a reader to read a possessive as an exclusion. §12 **R21** was written treating it as exclusive and has been corrected pending the answer. **If it is sole custody: say so, put it in §7, and R21 arms it. If it is not: the possessive comes out and the sentence keeps only the measured half.** Raised by `adversarial-reviewer`, round 1, 2026-09-02 | **`/legal/privacy/` going public, and therefore the cutover.** `src/pages/legal/privacy.astro` carries the `TODO(pouya)` beside the paragraph; `docs/06`'s checklist carries it as its own unticked item. It blocks no other page | +| ~~**Q63**~~ | ✅ **CLOSED 2026-09-02 — ALL THREE LIMBS ANSWERED BY RULING, and the answer to (c) changed the sentence (a) had just approved.** **(a) WORDING APPROVED WITH TWO TRIMS:** the editorial closing sentence (*"I would rather tell you that than give you the tidier answer"*) is struck, and the mailbox clause is rewritten per (b). **(b) `info@smlcompany.ca` IS A DELEGATED MAILBOX — Pouya and administrative staff read it.** The page said *"anyone who can reach that mailbox"*; it now says who. ⚠️ **That answer reached FOUR sentences, not the one the question named** — §Where it is stored twice (*"a notification to me"*, *"my own mail is on Google Workspace"*), §How long it is kept once (*"the notification sits in my mailbox"*) and §Who can see it once — because the mailbox had been written as a personal one throughout the page. **Fifth partial sweep of this page's who-can-see-it set; the section comment now names all NINE places, by opening phrase rather than by count** — it shipped "eight" for one round, having excluded a paragraph this very change set edited (`adversarial-reviewer`, round 1). **(c) ROOT IS HELD BY POUYA** `[verified 2026-09-02 — Pouya]`, and the page now states that it has no programmatic key and that he holds it. ⚠️ **THE CONSEQUENCE NOBODY ASKED FOR AND IT IS THE MOST IMPORTANT LINE IN THIS ROW: THE HUMAN HEADCOUNT CAME OFF THE PAGE.** Pouya's attestation: *"two people is an exaggeration… a handful is accurate — the simulation counts identities, not humans, and the two are not the same claim."* **The enumeration was exhaustive and the inference off it was not**: every read path terminates at two IAM identities, which is a **lower bound** on the number of people who can reach them, and `/legal/privacy/` published it as an exact count. It now reads *"the account's administrators — me, and the small number of people who administer it with me"*. **No numeric human headcount ships**, the identity count stays in §7 and in the reference extract, and the extract's own inference sentence (*"The count of people is two"*) is corrected at source, because a false inference left in the evidence file re-supplies itself to the next reader. ⚠️ **AND THE `33` WAS DELIBERATELY NOT PUBLISHED** — the ruling permits the identity count on the page *"if useful"*; a role total moves when AWS creates a service-linked role by itself, so publishing it would put a second R21-governed number on a legal page that can go stale with no human acting. *"Every user and every role in the account"* carries the exhaustiveness and survives the count moving. **One line to overrule.** Original question follows. 🛑 **TWO THINGS `/legal/privacy/` STILL NEEDED FROM POUYA, ANSWERED IN THE SAME READ-THROUGH.** **(a) APPROVE THE §Who can see it WORDING.** Q62 settled what it must say and he reserved the wording in terms: *"Draft it; Pouya gives final approval on wording during his page read-through."* The draft is shipped in `dist/` and quoted in `docs/reference/intake-table-access-verification.md`. **This is a gate that existed only inside records marked closed until 2026-09-02** — the `TODO(pouya)` had been deleted, Q62 struck, and `docs/06`'s blocker ticked, so when Q60's TTL test passes **nothing mechanical or visual would have stopped unapproved copy publishing.** `adversarial-reviewer`, round 1. **(b) WHO ELSE CAN READ `info@smlcompany.ca`?** Nothing in this repository establishes it — §7 records the mail host (Google Workspace) and the SES identities, **not the mailbox's access list**, and a Workspace super-admin can reach any mailbox in the tenancy. Given that this project's AWS account, its Gitea instance and §10 are all jointly administered, the plausible case is that it is not only him. The copy is now written to assert **no** access list (*"anyone who can reach that mailbox"*), so nothing false is published either way — but a privacy policy that answers the table half with a measured number and the mail half with a shrug is answering the same question on two standards, and the reader is entitled to the specific on both. **(c) WHO HOLDS THE ROOT CREDENTIAL FOR THE AWS ACCOUNT?** The page's headline answer is a **count of people**, and root is the one path no policy constrains and no simulation can reach — it is not an IAM principal and does not appear in `list-users`. Two facts bound it: `AccountAccessKeysPresent: 0`, so there is no programmatic root credential, and MFA is on, so console access needs the root password and its device `[verified 2026-09-02]`. **If those are held by anyone other than the two administrators, "Two people can" is short by one.** The second paragraph is scoped to *"every user and every role"* and to who has been **granted** access, so it is unaffected either way — this reaches the first sentence only. Raised by `adversarial-reviewer`, round 2, which is also where the honest form of the objection came from: the artefact says in terms that this is not established, and a page was resting a count on it. **If he answers: put the fact in §7, make the sentence specific like the table sentence above it, and arm it with §12 R21's trigger.** Raised by `claims-auditor` and `adversarial-reviewer`, D20 cutover pass round 1, 2026-09-02 | *(closed)* | +| ~~**Q62**~~ | ✅ **CLOSED 2026-09-02 — RULED *state the truth*, NOT *remove the access*. Pouya:** *"Rewrite the `/legal/privacy/` sentence to say exactly who can access the submissions table… the true number of people and their roles, stated specifically — not 'authorised administrators' or any other vacancy."* **Applied.** The page now opens §Who can see it with *"Two people can"*, states that the AWS account also runs systems unrelated to this practice and has two administrators, and says administrative access carries the ability to read the table. It then publishes the two facts the false sentence had been crowding out and which are **stronger** than what it claimed: the function that receives the form can only add a record and **cannot read the table back**, and the credential that publishes this website has **no access to the table at all**. ⚠️ **THE FIX TOUCHED THREE PLACES, NOT ONE, AND THE OTHER TWO ARE THE POINT.** A vocabulary sweep — `grep -rniE "no (team\|assistant\|outside\|external) [a-z]*\|nobody else\|no one else" src/` — found the same falsehood in different words **two sections up the same page**: §Where it is stored ended *"and no assistant or outside administrator"*, which the Q62 pattern could not see because it was anchored on the two sentences under the other heading. And the summary paragraph closed *"the honest answer to 'who can see this' is: me, and Google"* — which would have survived the correction directly above it and re-asserted the struck number. All three now change together and the page's own comment says so. **THE TRIPWIRE STAYS PERMANENTLY — his ruling in terms:** *"it bars the false-claim shape from returning, which is exactly what the freeze's breach exception exists for."* Extended from two alternatives to **five** — round 1 of the closing audit found a third published surface unbarred, and found the first extension had widened one alternative to four phrasings where one was published. Every alternative is now a single string that reached `dist/`, so nothing speculative entered a frozen script. **Proven both ways, on real published bytes and not on fixtures alone:** against the pre-correction page rebuilt from `bd282aa` it exits **1** with **5 matches** at `dist/legal/privacy/index.html:54, 67, 67, 68, 72` — 54 is the clause the first form missed and 72 the surface it could not see at all — and against the corrected page it exits **0**. ⚠️ **THE APPROVED-STRING AND FIXTURE COUNTS ARE NO LONGER RESTATED HERE, DELIBERATELY.** They said four/four/33/three, then 36/six, then were stale again within one review round when the Q63 rewrite changed the copy the fixtures quote — three times in two days, on a row whose own point is that the record of what a frozen script bars is its maintenance surface. **`npm run check:claims` prints both numbers on every run; read them there.** As at 2026-09-02 it prints **35 approved strings**, of which the first **seven** are live `/legal/privacy/` copy carrying a re-sync instruction (`adversarial-reviewer`, round 2). ⚠️ **The counts in this row said four/four/33/three until 2026-09-02**, describing the script as it stood before round 1's fix; on a frozen script the record of what it bars is the maintenance surface, so `adversarial-reviewer` round 2 was right to treat a stale count as a defect. ⚠️ **AND THE FIX AS FIRST WRITTEN INTRODUCED THREE DEFECTS OF ITS OWN, ALL FOUND BY THE D20 PASS ROUND 1 AND ALL NOW CORRECTED — see entry (an).** The replacement asserted *"No third party has access to it"* (an absolute negative that excludes a **disclosed processor**, which is the exact sentence struck from this page on 2026-08-31 as *"the most serious thing found in the step 7–10 review"*); it claimed *"every account and role in this infrastructure… that is checked rather than assumed"* over an artefact that had screened five users and **one** role; and it said *"the one other place a copy exists"* when the handler puts the whole submission into the confirmation it sends the inquirer, so a **third** copy sits with the reader's own provider — which this page already says two sections up. **Q62's own fix recreated Q62's shape twice.** **Two things are NOT resolved and are now Q63 rather than a footnote here** — the wording approval Pouya reserved, and the `info@smlcompany.ca` access list. The earlier form of this row called the mailbox point non-gating *"because the copy is true either way"*, which was **a guess about a fact nobody checked**; the copy is now written so it asserts no access list at all, and the question gates the page through Q63 with a `TODO(pouya)` beside it. Original finding follows. 🛑 **`/legal/privacy/` TELLS THE PUBLIC SOMETHING FALSE ABOUT WHO CAN READ THE INTAKE TABLE, AND IT IS A PRIVACY POLICY.** The page says: *"The table is reachable by the function that writes to it and by one administrative account, which is mine — nobody else has access to the table. There is no team, no assistant and no external administrator."* **The account has an IAM group `admins` carrying `AdministratorAccess` with TWO members**, and `iam simulate-principal-policy` returns **allowed** for `dynamodb:GetItem`, `dynamodb:Query` and `dynamodb:Scan` on the table for both of them — identical access, by the same route, the other user's own attachments being only `IAMUserChangePassword` `[verified 2026-09-01 — the five users, the group, and a five-row simulation, all commands in `docs/reference/intake-table-access-verification.md`]`. So **both halves of the sentence are wrong**: a second account has access, and it belongs to a second administrator of a shared account (§10). The three deploy users are `implicitDeny`; two CDK bootstrap roles carry `AdministratorAccess` but are assumable only by the same two administrators; the writing role holds **`PutItem` only and cannot read the table**, which is a stronger fact than the page currently claims and is the part of the sentence that is true. **THE QUESTION, AND IT IS ONE OF TWO THINGS.** (1) **Remove the access** — take that user out of `admins`, or deny DynamoDB on this table — after which the sentence becomes true as written. ⚠️ Note the likely collision: **Q23 records the Gitea instance as jointly administered and blocked on "its second administrator"**, so that access is probably not only for this account and removing it may cost something elsewhere. (2) **State the true number** — how many people hold administrative access, and that the function which writes cannot read. ⚠️ **DO NOT RESOLVE IT BY SOFTENING.** *"Access is limited to authorised administrators"* is the shape §4 exists to bar: defensible, uninformative, and it would replace a false specific with a true vacancy on the one page where a reader describing a live dispute is entitled to the specific. **Why this was invisible until now:** it is the only claim on the site whose subject lives entirely outside the repository, so R14 applies — *"unverifiable by construction"* — and there was no committed artefact to compare it against. There is now. Raised by `claims-auditor`, D20 cutover pass, finding 8 | *(closed)* | | ~~**Q61**~~ | ✅ **CLOSED 2026-09-01 — RULED *fix now*, IMPLEMENTED AND MEASURED.** The minimum-font-size sticky header obscured keyboard focus: **290 entirely-hidden focus stops of 1,455** under `minimumFontSize=32`, a WCAG 2.2 **SC 2.4.11 (AA)** failure, created by the 2026-09-01 header fix. The fix is two declarations on `html` in the existing `@media (min-width: 66rem)` block — the plain `calc(var(--header-h) + var(--space-4))` first as a fallback, then `max(calc(var(--header-h) + var(--space-4)), calc(10lh - 83px))`. **`1lh`, not `rem`: the font-metric units read the *used* font size**, which is the mechanism the withdrawn ruling's premise denied existed. **Result, on the identical grid with the pre-fix tree rebuilt in a worktree as the control: 290 → 0, control still 290.** Default-settings rendering unchanged: **0 differences over 352 page-widths × 17 fields**, positive control detecting exactly 1 injected difference. `scroll-padding-top` 97 px at the default, 287 px under the setting against a 270.56 px header; `1lh` on `` is 18 / 37 px **with every `.woff2` blocked**, identical, because `` keeps the UA family. A wider grid than the ruling asked for — **777 cells over 37 settings — went from 63 failing to 12, with no cell worse.** The 12 are `minimumFontSize=16` and `=20`, they are **pre-existing and reduced**, and they were deliberately not fixed under Pouya's *"stop and report, do not widen"*: the setting floors sub-root type without moving the root, so `1lh` reads a quantity that did not change. `docs/06` carries it as its own item | *(closed)* | | **Q60** | ⚠️ **HAS A TEST RECORD BEEN OBSERVED TO DISAPPEAR FROM THE INTAKE TABLE?** **Half one closed 2026-08-31: TTL is `ENABLED` with `AttributeName: ttl`, verified by command — §7 holds that status and this row does not restate it.** The question is now the second half alone, and it was never the smaller half. `/legal/privacy/` does not merely publish a retention *period* — it asserts a **mechanism**: *"the record is deleted automatically by the database rather than by someone remembering to do it"*. **`ENABLED` proves the setting; only a record written with a near-future `ttl` and watched to vanish proves the behaviour.** Two things this may NOT be answered from: the handler code, which writes the attribute and nothing more (that side is verified and is not what is being asked); and the table setting, which is what was just confirmed. ⚠️ **AND THE FIRST HALF IS THE REASON TO TRUST THE SECOND LESS, NOT MORE:** `describe-time-to-live` returned **`DISABLED`** when Pouya first ran it on 2026-08-31, so the sentence above was published against a mechanism that was not running, and nothing in the repo, the build or AWS reported it. A setting that was off for as long as nobody looked is not evidence that the behaviour now works. `TODO(pouya)` sits on the retention section of `src/pages/legal/privacy.astro`; `docs/06`'s cutover checklist carries the test as blocking; §12 R19 keeps it surfacing. **Why this is a numbered question and not only a checklist line:** `CLAUDE.md` requires a `TODO(pouya)` plus a §9 row when a page needs a fact the repository does not have, and this page needs one — a cutover checklist fires once, at cutover, and §9 is what a person editing this page reads. Raised by `adversarial-reviewer` round 2, 2026-08-31 | **`/legal/privacy/` going public.** Nothing else — no other page states the mechanism, verified by sweeping `dist/` for the retention vocabulary and reading each hit in context | | ~~Q59~~ | ✅ **RULED AND CLOSED 2026-08-31 — Pouya. OVERTIME RUNS FROM THE SESSION CAP**: the fourth hour of a half day, the seventh of a full day. Not the billed envelope. `/fees/` shipped at build step 9 on this ruling and `docs/07` carries it in full. ⚠️ **THIS ROW NAMED A CONSTANT THAT NO LONGER EXISTS** — `FEES.mediation.overtimeStartsAfterSessionHours` was deleted the same day as dead data: nothing read it, so reversing it would have changed nothing and failed nothing, which is Q22's shape at constant scope. **Where the ruling actually lives:** the trigger is rendered on `/fees/` from `halfDay.hours` / `fullDay.hours`, and `FEES.mediation.reservation` carries the half that publishes as prose. Found by `adversarial-reviewer` round 2 — §9 is what a later implementer reads to find where a ruling is recorded, so pointing it at a deleted identifier is the same defect one layer up. ⚠️ **AND THE RULING CAME WITH A SECOND HALF THAT ANSWERS THE ARITHMETIC ANOMALY THIS ROW EXISTED TO ESCALATE, WHICH THE TRIGGER ALONE COULD NOT.** His words: *"a full day reserves the day; half-day overtime is subject to availability."* **The full-day fee buys the DAY, not six hours of it.** Read as a price comparison the table below says the full-day rate is never the cheaper choice; read knowing what each fee reserves, the $2,000-narrowing-to-$500 spread is the price of certainty rather than a defect. The sentence is `FEES.mediation.reservation` and it publishes **adjacent to the overtime row**, not as a footnote — the same structural rule as `PROCESS_FRAMING` beside the five timings under Q43, because a reader who takes the number and skips the framing has read a different offer. **THE ANOMALY IS NOT CLOSED AND STAYS ON §12 R5.** The gap is in D14's own figures — the half-to-full step is $2,000 against $1,500 for three hours of overtime — and the reservation point explains what it buys without removing it; the spread is largest at three to five hours, which is the band a half-day booking actually overruns into. `docs/07` §Recorded dissent carries the table for the 12-month review. **The original question, kept because the shape of it is the lesson.** *Where does the overtime hour start?* `docs/07`'s card carried *"Overtime, per hour — $500"* and had never said what it was overtime **to**. Q58's ruling settled the two allowances and did not reach this; Q15–Q17's answer records the rate with no trigger. The two candidates were the session cap (3 h / 6 h) and the billed envelope (5 h / 9 h), and this repository was barred from picking one — a fee term is a fact we do not have, and `CLAUDE.md`'s rule for that is a question, not an inference. **It cost two strikes to hold that line:** a first pass at `docs/07`'s Q58 note asserted the session cap as applied fact and `adversarial-reviewer` struck it in the change set that wrote it; a round-1 fix then published the $500 rate on `/for-parties/` beside an unambiguous *"up to 3 hours"*, which **defines the trigger by adjacency** — nothing else on the page is a quantity it can attach to — and round 2 struck that too. Both strikes were right, and the ruling supplied the value they were waiting for | ~~`/fees/`, `/for-parties/`~~ — both now unblocked and shipped | @@ -925,7 +927,7 @@ never being raised again. | R5 | **Fee review at 12 months.** Published rates are sticky; the right moment to move them is deliberate, not reactive. ⚠️ **ONE ITEM IS ALREADY WAITING AND IT IS ARITHMETIC RATHER THAN JUDGEMENT — added 2026-08-31:** the half-day-plus-overtime route is cheaper than the full-day rate at **every** session length, by $2,000 at three hours narrowing to $500 from six on, because the half-to-full step is $2,000 and three hours of overtime is $1,500. Written out in `docs/07` §Recorded dissent with the table, which is the section built for this review to test against. The **trigger** for the overtime hour is a separate open question — §9 Q59 | 2026-08-26 | D14 is priced for where the practice is going, not where it is. And the anomaly above was assigned to this reminder twice in one change set and written into neither place the reminder lives, which is the failure §12 exists to prevent | | R6 | **Booking tool.** Parked by Pouya on 2026-08-26; `/contact/` ships with the intake form and a reserved slot for an embed | 2026-08-26 | He asked to be reminded. D10 committed to booking because it removes the back-and-forth that loses appointments — the form alone is a partial answer | | ~~R9~~ | ✅ **CLOSED 2026-09-01. The `ses-alerts` email subscription is CONFIRMED** — `aws sns list-subscriptions-by-topic` returns a real subscription ARN rather than the literal `PendingConfirmation` `[verified 2026-09-01]`, so the two bounce/complaint alarms reach `info@smlcompany.ca`. ⚠️ **It had been confirmed for some unknown part of six days while §7, `docs/05`, `docs/06` and this row all said the alarms fired into nothing.** That is the Q22 staleness in the **safe** direction, and the direction is why it lasted: nothing was broken, so nothing prompted anyone to re-read it. The generalisable half, and it is worth more than the row: **a record whose staleness is harmless is the record that stays stale longest**, because every other kind announces itself by breaking something. Re-read the harmless ones on a schedule or they are never re-read at all. *Previous text follows.* **The SES alarms notify nobody until the `ses-alerts` email subscription is confirmed.** `SES-BounceRate-High` and `SES-ComplaintRate-High` are configured and live; the SNS email subscription to `info@smlcompany.ca` is **pending confirmation**, and an unconfirmed subscription drops every message | 2026-08-26 | A monitoring control that exists but does not deliver is worse than none, because it reads as covered. At this volume five bounces can cross the ~5% suspension threshold. Tracked in §7 and on the cutover checklist, but a one-click task nobody owns is exactly what §12 is for | -| R10 | ⚠️ **FIRED AND STILL UNSATISFIED AS AT 2026-09-02 — THE CUTOVER EVENT HAS ARRIVED AND THE CONFIRMATION HAS NOT.** Asked of Pouya on 2026-09-02 as a one-line question — *are ADRIC, ADRIO, the three OBA sections and the CTF all still current?* — and left **open** on `docs/06`'s checklist on his instruction, alongside R18 which fired and **was** satisfied the same day. **It may not be ticked from the 2026-08-28 stamp.** That is the entire content of this reminder: a stamp is not a renewal receipt, and re-reading an old one is not re-confirming. When he answers, re-stamp **§4 and `src/data/schema.ts`** with the answer's date — both surfaces, because `memberOf` is emitted. Original text follows. ⚠️ **A THIRD SURFACE, 2026-08-30: `/process/` §Confidentiality renders `MEMBERSHIP_ORGS[0]` ("I am a member of the ADR Institute of Canada").** It is rendered from the constant rather than typed, so the sweep this reminder prescribes reaches it — that was `adversarial-reviewer`'s finding and the fix, in that order. **DISCHARGED AS WRITTEN 2026-08-28 — AND RE-ARMED WITH AN EVENT TRIGGER INSTEAD OF A DATE. STILL LIVE.** Pouya re-confirmed all four memberships as current (Q44), which discharges the prohibition this row carried, and `/about/` now publishes the Memberships group. **The row does not close, because he declined renewal-date tracking**, and that was his instruction for what to do about it: *"Without renewal months it cannot fire on a date, so make it fire on an event: re-confirm memberships before any cutover or major republish, and re-stamp §4 when confirmed."* **THE TRIGGER: re-confirm before any cutover, and before any major republish. Then re-stamp §4 the same day.** **His reason, kept verbatim because it is the general principle and not a membership detail:** *"§4 already carries OCNI as lapsed and unpublishable, and that was found roughly a year late. A stamp with no trigger behind it goes stale silently, which is exactly how OCNI got onto a list of things to feature."* **Two things the discharge did NOT license.** (1) **No currency warranty on the page** — list the memberships, promise nothing about their future state; the struck sentence stays struck and nothing replaces it. (2) ~~`memberOf` stays out of the JSON-LD~~ — **SUPERSEDED. Q53, ruled 2026-08-28: EMIT IT.** `/about/`'s Person node now carries the four memberships as `Organization` nodes. Pouya took `adversarial-reviewer`'s argument: they are already crawlable in `/about/`'s HTML, so withholding the triple reduced no exposure and only made the graph less complete than the page. **The consequence for THIS reminder is that it now covers two surfaces** — re-confirming before a cutover means `src/data/schema.ts` as well as the visible list, and they must not be allowed to diverge. **Renewal periods, stated once and not widened again:** the OBA sections and the CTF renew yearly; §4 records **nothing** about ADRIC's or ADRIO's period, and the widened form ("all four renew yearly") reached four files before it was swept. *Previous text described the prohibition and the withheld group; it held for one session and did its job.* | 2026-08-26 | A credential that lapses quietly is the failure mode §4 exists to prevent, and OCNI already did exactly this. The group is on a public page now, which raises the cost of a lapse rather than lowering it — *(This rationale ended by pointing at **Q48** as a possible widening of the row. Q48 closed 2026-08-28 as not site-relevant — ADRIO retention governs whether Pouya keeps a designation, not what the site may say about holding one — so the clause is struck. §12 is read aloud every session; a live reminder pointing at a struck row produces a false surface every time.)*, not just a list | +| R10 | ✅ **FIRED AND SATISFIED 2026-09-02 — THE CUTOVER EVENT AND THE CONFIRMATION, IN THAT ORDER. THE ROW STAYS LIVE.** Asked of Pouya on 2026-09-02 as a one-line question — *are ADRIC, ADRIO, the three OBA sections and the CTF all still current?* — and **answered the same day: all current.** It was asked rather than looked up, which is the entire content of this reminder: **a stamp is not a renewal receipt, and re-reading an old one is not re-confirming.** It was open for part of the day, alongside R18 which fired and was satisfied the same day. **Re-stamped on all three surfaces, because `memberOf` is emitted and the constant feeds both:** §4's memberships row, `CREDENTIALS.memberships` in `src/data/site.ts` and the R10 note in `src/data/schema.ts`. ⚠️ **AND THERE ARE TWO ARRAYS, NOT ONE — re-stamping is not the same act as checking they still agree.** `CREDENTIALS.memberships` feeds `/about/`'s visible list and `/bio/`; **`MEMBERSHIP_ORGS` feeds `/process/` §Confidentiality and the `memberOf` triples**, and `site.ts` records that the two differ on three of four lines. `_MembershipParity` compares their **`['length']` only**, so a substitution passes `npm run check` in silence. An earlier form of this row said one constant fed both surfaces, which would have left `/process/` and the JSON-LD publishing a lapsed membership after a correct-looking edit — the OCNI failure with a green build (`adversarial-reviewer`, round 1). `docs/06`'s item is ticked and **re-armed for the next republish** — the trigger is an event and events recur, which is why this row does not close on being satisfied. Original text follows. ⚠️ **A THIRD SURFACE, 2026-08-30: `/process/` §Confidentiality renders `MEMBERSHIP_ORGS[0]` ("I am a member of the ADR Institute of Canada").** It is rendered from the constant rather than typed, so the sweep this reminder prescribes reaches it — that was `adversarial-reviewer`'s finding and the fix, in that order. **DISCHARGED AS WRITTEN 2026-08-28 — AND RE-ARMED WITH AN EVENT TRIGGER INSTEAD OF A DATE. STILL LIVE.** Pouya re-confirmed all four memberships as current (Q44), which discharges the prohibition this row carried, and `/about/` now publishes the Memberships group. **The row does not close, because he declined renewal-date tracking**, and that was his instruction for what to do about it: *"Without renewal months it cannot fire on a date, so make it fire on an event: re-confirm memberships before any cutover or major republish, and re-stamp §4 when confirmed."* **THE TRIGGER: re-confirm before any cutover, and before any major republish. Then re-stamp §4 the same day.** **His reason, kept verbatim because it is the general principle and not a membership detail:** *"§4 already carries OCNI as lapsed and unpublishable, and that was found roughly a year late. A stamp with no trigger behind it goes stale silently, which is exactly how OCNI got onto a list of things to feature."* **Two things the discharge did NOT license.** (1) **No currency warranty on the page** — list the memberships, promise nothing about their future state; the struck sentence stays struck and nothing replaces it. (2) ~~`memberOf` stays out of the JSON-LD~~ — **SUPERSEDED. Q53, ruled 2026-08-28: EMIT IT.** `/about/`'s Person node now carries the four memberships as `Organization` nodes. Pouya took `adversarial-reviewer`'s argument: they are already crawlable in `/about/`'s HTML, so withholding the triple reduced no exposure and only made the graph less complete than the page. **The consequence for THIS reminder is that it now covers two surfaces** — re-confirming before a cutover means `src/data/schema.ts` as well as the visible list, and they must not be allowed to diverge. **Renewal periods, stated once and not widened again:** the OBA sections and the CTF renew yearly; §4 records **nothing** about ADRIC's or ADRIO's period, and the widened form ("all four renew yearly") reached four files before it was swept. *Previous text described the prohibition and the withheld group; it held for one session and did its job.* | 2026-08-26 | A credential that lapses quietly is the failure mode §4 exists to prevent, and OCNI already did exactly this. The group is on a public page now, which raises the cost of a lapse rather than lowering it — *(This rationale ended by pointing at **Q48** as a possible widening of the row. Q48 closed 2026-08-28 as not site-relevant — ADRIO retention governs whether Pouya keeps a designation, not what the site may say about holding one — so the clause is struck. §12 is read aloud every session; a live reminder pointing at a struck row produces a false surface every time.)*, not just a list | | R11 | **Re-check dependency currency at every phase boundary in the build order** (`docs/01-architecture.md` §Build order, 11 steps). Run `npm view version` across **every** pin in `package.json` and compare; do not wait for something to break. Verified does not mean latest — record the reason for any deliberate hold in §7. ✅ **THE STEP-7 RE-ADD TRIGGER IS DISCHARGED, 2026-08-31 — and NOT as written.** It said *"at step 7, put `@lhci/cli` back"*. `@lhci/cli` is still 0.15.1, still `latest`, and still carries 10 findings (7 high) `[verified 2026-08-31]`, so the literal instruction would have re-added a tool with seven high-severity advisories. What shipped is **`lighthouse@13.4.1` + `chrome-launcher@1.2.1`, 0 vulnerabilities**, as `npm run lighthouse`. **The reason is that §7's own advisory attribution was wrong** — it blamed `lighthouse → puppeteer-core → extract-zip`; the carriers were `@lhci/cli`'s own `tmp` and `@puppeteer/browsers`' `extract-zip`, and neither exists in Lighthouse's tree. **The last clause of this trigger is the one that earned its place:** *"if the advisories are still unfixed, that is a decision to take deliberately, not a reason to leave the gap unstated."* They are still unfixed; the decision was taken; §7 records what it costs (no `lhci` assertion config, no server, no run history) and that the gate is local rather than CI, because standalone Lighthouse needs an installed browser and the runner has none. **All six UNAVAILABLE notices are deleted** — `docs/04` (budget table, Performance callout, post-launch checklist), `CLAUDE.md` (performance budget, definition of done), `/build` Phase 5, `docs/06` (PR checks, cutover checklist), `.claude/agents/adversarial-reviewer.md` §4. The **general** half of R11 — re-check every pin at every phase boundary — is untouched and still fires. ✅ **SWEPT AGAIN 2026-09-01, all 19 pins against `npm view`, and TWO MAJORS ARE DEFERRED BY RULING rather than left unstated:** `@astrojs/mdx` **^7.0.8 → 8.0.0** and `typescript` **^6.0.3 → 7.0.2**. Pouya's reasoning — *"npm audit is clean and majors mid-walkthrough add churn without user value"* — with `npm audit` at **0 vulnerabilities** `[verified 2026-09-01]`, which makes it a churn decision and not a security one, **and one that flips the moment that stops being true.** Both now sit on a new **Cutover prep** group at the head of `docs/06`'s cutover checklist, dated, because deferring a thing and forgetting it look identical three weeks later. Four more are a minor or patch behind and already satisfied by their carets, so they need no edit — `astro` 7.2.9 → 7.2.10, `@astrojs/sitemap` 3.7.3 → 3.7.4, `globals` 17.11.0 → 17.12.0, `typescript-eslint` 8.68.0 → 8.69.0; the other 13 are current. **This row is the deferral's reminder, not its replacement** — R11 fires at the next phase boundary regardless | 2026-08-26 | `astro: "^5.0.0"` was recalled rather than checked and was two majors stale the day it was written, which meant a framework carrying high-severity XSS advisories. Between phases is cheap; after a phase of pages is written is not. The build order has ten more boundaries | | R12 | **`compressHTML: true` is a deliberate deviation from the Astro 7 default (`'jsx'`).** Measured 2026-08-26: in an `.astro` template an inline pair split across two lines renders as `ab` under the default — the space is silently deleted. MDX prose is unaffected | 2026-08-26 | It is a deviation, and undocumented deviations become folklore. Revisit **with a measurement**, not a preference — and re-measure after any Astro major, since the behaviour could change again | | R13 | **The infinity mark ships as a RASTER, and that is temporary. RAISED 2026-08-27; Pouya ruled the committed SVG does NOT close it** — *"Keep it committed, keep the AVIF render path. Your own measurement is the reason: 257 KB wrapping seven embedded base64 PNGs. It renders faithfully because it IS the raster."* So the exception stands and the reminder stays live. `InfinityMark.astro` renders an optimised AVIF/WebP from `src/assets/brand/sml-infinity-mark.png` — a deliberate, documented exception to `docs/02`'s "inline SVG, never a PNG", because the mark is gradient-mesh artwork and no true vector master exists yet (Q38). **Removal trigger: the commissioned vector master lands.** Then replace the `` with inline SVG, regenerate `favicon.ico` and `apple-touch-icon.png` from it, and delete the exception from `docs/02`, from the component, and from Q38 | 2026-08-26 | Pouya flagged this himself when he made the ruling: *an interim raster is exactly the kind of temporary measure that becomes permanent by never being raised.* It costs ~8 KB and works, which is precisely why nobody will notice it again. There is no build error to prompt anyone — only this row | @@ -936,7 +938,7 @@ never being raised again. | R18 | ✅ **RE-CHECKED 2026-09-01 — the cutover fire. ALL SEVEN HOLD AND NO SHIPPED SENTENCE CHANGED.** Verified by Pouya (architect verification, Claude web) and recorded here with the sources, because the trigger is *"re-check before any cutover"* and this is that cutover. ⚠️ **THE STAMP IS TWO-TIER ON PURPOSE AND THE TIERS MUST NOT BE COLLAPSED: three limbs were re-verified against a source; four are held unchanged on a CADENCE JUDGEMENT rather than a fresh retrieval.** Writing all seven as "re-checked" would be the OCNI failure in miniature — a stamp that reads like a check and records a belief. ⚠️ **AND A CANDIDATE EIGHTH LIMB WAS FOUND WHILE STAMPING, FLAGGED RATHER THAN ADOPTED — (h)**: `/practice/construction/` publishes *"Ontario Power Generation … applied in March 2026 for a licence to operate it"*, a **pending application** that moves the way (a) moves. Not false today — the application was made, and a completed past act stays true — so it blocks nothing; but unlike (a) the sentence is **not time-anchored**, and a reader takes it as current status. **Pouya's call at the next re-check: adopt it as (h), or time-anchor the sentence and drop it.** **RE-VERIFIED AGAINST A SOURCE:** **(a) Bill C-36** — still at second reading in the House of Commons; latest completed stage **first reading, 2026-06-15**; no advance since `[re-checked 2026-09-01 — ]`. `/practice/technology/`'s *"was at second reading when this page was written"* stands. **This is the fastest mover of the seven and it needs no page edit while it sits, and one the day it moves.** **(d) the Tribunals Ontario annual report** — **no 2025-26 edition is published; FY2024-25 remains current** `[re-checked 2026-09-01 — ]`, so the figures `/practice/insurance/` publishes are still the latest. **This also closes an open item at the foot of `docs/reference/ontario-sabs-lat.md`** which had recorded *"NOT CONFIRMED either way… given today's date, one may well have been published"* — the honest gap is now answered. **(c) ERO 026-0853** — comment period to **2026-09-12** still open `[re-checked 2026-09-01]`. **HELD UNCHANGED ON A CADENCE JUDGEMENT, NOT RE-RETRIEVED — `[assumed 2026-09-01 — Pouya: unchanged by their nature at this cadence]`:** **(b)** the regulation under `Electricity Act` s. 28.1, **(e)** the SABS, **(f)** the ADRIC National Mediation Rules, **(g)** ADRIC's Code of Ethics. The quoted bytes in every extract are still the original retrieval and were not re-fetched; the digests in `adric-rules.md` were not recomputed, so that stamp says nothing about whether the page changed. ⚠️ **AND THE TRIGGER HAD NOWHERE TO FIRE, WHICH IS Q22'S SHAPE.** R18 names a cutover as its event and **`docs/06`'s cutover checklist carried no R18 item** — R10's was there, R18's was not, so a control documented here could not run where it was documented to run. **`docs/06` now carries one**, ticked for this cutover and re-armed for the next republish. Found 2026-09-02 while recording the re-stamp. ⚠️ **AND THE FIRST PASS STAMPED FIVE EXTRACTS OF SEVEN.** `ontario-construction-act.md` and `ontario-shareholder-remedies.md` carry the same standing "re-check before cutover" header and got no stamp, so a reader could not tell whether they were considered or missed — the same defect as this row having no checklist item, one notch smaller. Both are stamped now; `git grep -l "R18 re-check — cutover pass" -- docs/reference` returns **7**, and the set difference against `git grep -l "Re-check before cutover"` is **empty**. `adversarial-reviewer`, round 1. **THE ROW STAYS LIVE**: the trigger is an event and events recur. Original text follows. **THE SIX `docs/reference/` EXTRACTS BEHIND `/practice/*` ARE DATED 2026-08-29, AND SIX SHIPPED SENTENCES TURN ON FACTS THAT MOVE.** Build step 5 put statute, regulation, tribunal and bill status onto public pages — sourced, but **sourced as at one day**. The volatile ones, in order of how fast they move: **(a) federal Bill C-36** — `/practice/technology/` says it *"was introduced in June 2026 and was at second reading when this page was written"*; if it receives royal assent the page is wrong about the most load-bearing fact on it. **(b) the Ontario regulation under `Electricity Act` s. 28.1** — `/practice/energy/` says it *"had not been made as of August 2026"*. **(c) the ERO 026-0853 consultation**, comment period to **12 September 2026**. **(d) the Tribunals Ontario annual report** — `/practice/insurance/` publishes FY2024-25 figures and the extract records that a 2025-26 edition was never ruled out. **(e) the SABS**, amended with effect 1 July 2026. **(f) the ADRIC National Mediation Rules**, under review by ADRIC's own committee. **(g) ADRIC's Code of Ethics** — added 2026-08-30, build step 6. `/process/` §Confidentiality quotes it verbatim from `docs/reference/adr-institution-names.md` (retrieved 2026-08-29) **with a live link to ADRIC's page**, which is what makes it checkable and also what makes a stale quotation visible. It is the slowest-moving item here — a professional code, not a bill — so it does not change the cadence; it is listed because the trigger below says "all six" and there are now seven. **THE TRIGGER: re-check all seven extracts before any cutover, and before any republish that turns on one of them — the same event trigger R10 uses.** Then re-stamp the extract. **A page that was true when it was written and is false when it is read is still a false page**, and this is the first change set on the project to put that class of fact into public copy at volume | 2026-08-29 | Six sentences, six files, one retrieval date. Nothing here fires on its own; a fact with a shelf life and no owner is exactly what §12 exists for | | R19 | ⚠️ **DYNAMODB TTL BACKS A PUBLISHED PRIVACY PROMISE AND `/legal/privacy/` ASSERTS THE MECHANISM, NOT JUST THE PERIOD.** **§7 records the status and its stamp; this row deliberately does not restate it** — one place for a service status, or the copy that goes stale is the one nobody re-reads. **THE TRIGGER, and its two halves are not interchangeable: re-run `describe-time-to-live` and confirm `ENABLED`, THEN write a record with a near-future `ttl` and confirm it actually disappears.** `ENABLED` proves the setting; only the test record proves the behaviour. Writing the attribute proves neither — the handler's side is verified and is not what this row is about. Both halves are on `docs/06`'s cutover checklist and the question is §9 Q60. Re-stamp §7 the same day, **and when you do, sweep for the copies: this fact reached five files outside §7 in one change set and had to be pulled back.** Close this row only when the test record has been observed to vanish | 2026-08-31 | **This is R9's exact shape at higher stakes.** R9 exists because the SES alarms are configured and notify nobody until one subscription is confirmed — a control that reads as covered and is not. Here the control backs a **statement to the public on a privacy policy**, which is the one class of claim this project treats as unrecoverable, and the failure is silent in both directions: nothing in the repo, the build or AWS reports that records are accumulating forever. A cutover checklist fires once; §12 is read aloud every session | | R20 | ⚠️ **THE SEVENTH NAV ITEM ARMS TWO MEASURED HEADER DEFECTS, AND ITS TRIGGER IS A CONTENT EVENT RATHER THAN A DATE.** `SiteHeader` computes `showInsights` from the collection — Insights joins the masthead **automatically at two published articles** — so nothing in the build, the specs or a person's memory stands between publishing article #2 and arming both of these. With seven items **and fallback font metrics** (what a reader on `docs/04`'s Slow 4G profile sees during the `font-display: swap` window, at the DEFAULT text size, no reader setting involved) the header measures **141 px across a contiguous 1056–1091 px band** instead of 81 px: **(a)** it then collapses **60 px** when Geist swaps in, on all 22 pages, against the CLS < 0.05 budget; and **(b)** 141 px exceeds the 97 px `scroll-padding-top`, so "Skip to content" lands with **44 px of `#main` behind the sticky header** — and (b) is **new as of 2026-09-01**, the previous build's 86.97 px stayed under 97 px and covered 0. ⚠️ **HARDENED FROM A TRIGGER INTO A GATE — Pouya's ruling, 2026-09-01: NO SEVENTH NAV ITEM SHIPS UNTIL THE FALLBACK-METRICS DEFECT IS FIXED.** So fixing it is a **prerequisite of publishing the second Insights article**, not a follow-up to it, and *"font metric overrides on the fallback face or equivalent — to be designed then, not now"*. ⚠️ **AND THE GATE IS A BUILD FAILURE, NOT A CROSS-REFERENCE — corrected 2026-09-01 by `adversarial-reviewer`, round 2, in the same session that wrote the weaker version.** It was first implemented as three prose pointers, justified with the claim that the comment on `showInsights` in `SiteHeader.astro` is *"the only one of the three a person editing an article's front matter is likely to be reading"*. **That was backwards**: someone editing `src/content/insights/*.mdx` has no reason to open a header component. And it did not gate: with two articles flipped to `draft: false`, `npm run build` succeeded and `check`, `check:claims`, `og:proof`, `check:intake` and `lint` all exited 0 while both defects shipped. **`SiteHeader.astro` now THROWS when `published.length >= 2`**, with the measurements and the instruction in the message; it fires on both deploy paths, on the machine of whoever publishes. **Proven, not assumed:** two articles were temporarily published, `npm run build` exited **1** naming R20, and the files were restored and the restoration verified by `git diff --exit-code` plus an unchanged `dist` digest. The prose pointers remain — `docs/06`'s `/insights/` state item and its seventh-nav-item item under **Technical**, the latter deliberately unticked and marked NOT a cutover blocker — but they document the gate rather than being it. This project already knew the remedy: `content.config.ts` refuses `draft: false` without `reviewedByPouya: true` rather than trusting a comment, and `check:intake`/`og:proof` exist because a duplicated fact needs a mechanism. *Previous wording follows, and it was too weak: it asked for a re-measurement and a ruling at publication time, which leaves the defect shipping if the person publishing does not read this file.* **THE TRIGGER: before publishing the second Insights article, re-measure the masthead with seven items under blocked webfonts, and rule.** The two candidate fixes are raising the desktop breakpoint past 1091 px — which changes the normal-settings layout in that band — or giving Geist a metric-matched `size-adjust` fallback; both are outside the scope the header step was given, and both close (a) and (b) together. **Why this is a §12 row and not only a `docs/06` line:** a cutover checklist fires once, at cutover, and this arms itself later, on an editorial decision taken by someone who will not be reading the deployment spec. `docs/02` §Reflow carries the measurements | 2026-09-01 | It is latent today and invisible from inside the repo: six nav items never wrap, so every check passes, and the defect appears the day a second article ships. That is R13's shape — a temporary state that becomes permanent because nothing prompts anyone — with the added twist that the prompt would have to fire on a content event. Raised by `adversarial-reviewer`, round 2 | -| R21 | 🛑 **`/legal/privacy/` PUBLISHES A COUNT OF THE PEOPLE WHO CAN READ THE INTAKE TABLE, AND NOTHING IN AWS, THE BUILD OR THIS REPOSITORY REPORTS WHEN THAT COUNT CHANGES.** The page says **two**, measured (§7). **Add a third administrator, remove `lars` from `admins`, attach a DynamoDB policy to any of the 33 roles, **hand the root credential to a third person**, or resolve Q23's Gitea dependency by changing his access — and the privacy policy becomes false with every check still green.** `check:claims`'s `sole-administrator-q62` pattern does **not** cover this: it bars the OLD false shape from returning and is blind to the world moving under the NEW sentence. That asymmetry is the whole reason this row exists. **THE TRIGGER, and it is the same event trigger R10 and R18 use: re-run the verification in `docs/reference/intake-table-access-verification.md` before any cutover, and before any republish that turns on it. Then re-stamp §7 the same day.** The counts are the assertion — seven decisions per role call, six per CDK-path call, two per-resource decisions per assume call — because a call that silently received one bogus action name answers `implicitDeny` and reads exactly like a clean row, which is how the first run of that sweep produced 22 uniformly clean rows and no measurement at all. **Removal is the live direction:** Q23 records the Gitea instance as jointly administered and blocked on its second administrator, so `lars`'s access is plausibly load-bearing elsewhere — and if it goes, `check-claims.mjs`'s `rule:` line carries the instruction (rewrite the page, then narrow the pattern deliberately). Raised by `adversarial-reviewer`, D20 cutover pass round 1, 2026-09-02: R9's and R19's shape at R19's stakes — a statement to the public on a privacy policy, backed by a fact with no owner. | 2026-09-02 | The 2026-09-01 verification is a photograph of a shared AWS account that two people administer and that runs four other projects. A stamp with no trigger behind it goes stale silently, and §4 already records OCNI as the precedent for exactly that | +| R21 | 🛑 **`/legal/privacy/` PUBLISHES FOUR CLAIMS ABOUT SYSTEMS OUTSIDE THIS REPOSITORY, AND NOTHING IN AWS, GOOGLE WORKSPACE, THE BUILD OR THIS REPO REPORTS WHEN ANY OF THEM CHANGES.** ⚠️ **RE-SCOPED 2026-09-02 BY THE Q63 RULING, AND THE HEADLINE CLAIM IT WAS WRITTEN FOR IS GONE:** the page no longer publishes a **count of people** — Pouya ruled that a simulation counts identities and not humans, so *"two people can"* came off and *"the account's administrators — me, and the small number of people who administer it with me"* went on. **That is a weaker claim and therefore a more durable one: adding an administrator no longer falsifies the page.** The four live claims: **(i)** that every user and every role was enumerated and only administrative identities can read the table; **(ii)** that the writing function cannot read it back and the deploy credential has no access at all; **(iii)** that the account's root credential has no programmatic key and Pouya holds it — ⚠️ **held, not held EXCLUSIVELY: nothing measured or attested rules out a second holder, and §9 Q64 is the one line that would settle it**; **(iv)** that `info@smlcompany.ca` is read by Pouya and administrative staff; **(v)** that the table carries no resource-based policy of its own and the account has no single sign-on or federated login. **(iv) is an ATTESTATION and nothing in this repo can check it** — the other three are re-runnable. **Attach a DynamoDB policy to any role, grant the deploy or Lambda role a read, **put a resource-based policy on the table itself** (invisible to `describe-table` and to every principal simulation — it grants from the other side, and it is claim (v) below), **join the account to an AWS Organization** (which would make the Identity Center zero local rather than conclusive), create a root access key, move root custody away from Pouya, delegate the mailbox more widely, or resolve Q23's Gitea dependency by changing `lars`'s access — and the privacy policy becomes false with every check still green.** Original text follows. **THE PAGE SAID "TWO", MEASURED (§7).** **Add a third administrator, remove `lars` from `admins`, attach a DynamoDB policy to any of the 33 roles, **hand the root credential to a third person**, or resolve Q23's Gitea dependency by changing his access — and the privacy policy becomes false with every check still green.** `check:claims`'s `sole-administrator-q62` pattern does **not** cover this: it bars the OLD false shape from returning and is blind to the world moving under the NEW sentence. That asymmetry is the whole reason this row exists. **THE TRIGGER, and it is the same event trigger R10 and R18 use: re-run the verification in `docs/reference/intake-table-access-verification.md` before any cutover, and before any republish that turns on it. Then re-stamp §7 the same day.** The counts are the assertion — seven decisions per role call, six per CDK-path call, two per-resource decisions per assume call — because a call that silently received one bogus action name answers `implicitDeny` and reads exactly like a clean row, which is how the first run of that sweep produced 22 uniformly clean rows and no measurement at all. **Removal is the live direction:** Q23 records the Gitea instance as jointly administered and blocked on its second administrator, so `lars`'s access is plausibly load-bearing elsewhere — and if it goes, `check-claims.mjs`'s `rule:` line carries the instruction (rewrite the page, then narrow the pattern deliberately). Raised by `adversarial-reviewer`, D20 cutover pass round 1, 2026-09-02: R9's and R19's shape at R19's stakes — a statement to the public on a privacy policy, backed by a fact with no owner. | 2026-09-02 | The 2026-09-01 verification is a photograph of a shared AWS account that two people administer and that runs four other projects. A stamp with no trigger behind it goes stale silently, and §4 already records OCNI as the precedent for exactly that | | ~~R7~~ | **RATIFIED / SUPERSEDED 2026-08-26.** (a) Cache-policy table matching the pipeline — **accepted**; documenting what the pipeline does beats documenting an intention. (b) `s3:AbortMultipartUpload` omitted — **accepted, reasoning corrected**: the lifecycle rule does not exist and is therefore not the cover; the actual cover is that `aws s3 sync` only goes multipart above 8 MB and the largest asset is a 357 KB portrait. Recorded in `docs/06-deployment.md` with a revisit trigger. (c) The `aws s3 ls` pre-flight — **superseded** by the variable guard now running as the workflow's first step | 2026-08-26 | — | | ~~R8~~ | **PROMOTED TO A RULE 2026-08-26.** A reminder was too weak for a pattern that survived three entries. *A sweep is a command, not a claim* now sits in `CLAUDE.md` under Conventions, in `/build` Phase 6, and in `/wrap` step 3: any claim that a change was applied across files must cite the command and be written only after reading its output | 2026-08-26 | — | @@ -944,6 +946,227 @@ never being raised again. # Change Log +## 2026-09-02 (ao) — Q63 is answered in three limbs and the answer to (c) takes the human headcount off the page; R10 fires and is satisfied; `/med-arb/` is ratified; and a sentence added to back the correction turned out to have no command behind it + +**Pouya's rulings, 2026-09-02**, applied here: **Q63(a)** wording approved with +two trims; **Q63(b)** `info@smlcompany.ca` is a delegated mailbox read by him and +by administrative staff; **Q63(c)** he holds the account root credential — and +**no numeric human headcount ships**, because *"two people is an exaggeration… +a handful is accurate — the simulation counts identities, not humans, and the +two are not the same claim."* **R10 closed** on a fresh confirmation. **`/med-arb/` +ratified as shipped**, with his note for the record that *med-arb is a service he +provides, not a designation.* + +### 1. The headcount came off, and the register had supplied it + +The page said **"Two people can."** The enumeration behind it was exhaustive over +**identities** and every read path terminates at `user/pouya` or `user/lars`; the +page rendered that as a count of **people**. A simulation cannot see how many +humans reach a credential, so **two identities is a lower bound on people, and it +was published as an exact count.** + +`/legal/privacy/` now attributes read access to *"the account's administrators — +me, and the small number of people who administer it with me"*. **The false +inference was corrected at its source as well as at its symptom**: +`docs/reference/intake-table-access-verification.md` had concluded *"The count of +people is two, and it is now the result of an enumeration rather than of a policy +name"*, and a false inference left in the evidence file re-supplies itself to the +next reader. §7's row is re-headed to say the count is of identities. + +**`33` was deliberately not published**, and this is a judgement Pouya can +overrule in one edit: his ruling permits the identity count *"if useful"*, but a +role total moves when AWS creates a service-linked role **by itself**, so +publishing it would put a second self-staling number on a legal page. *"Every user +and every role in the account"* carries the exhaustiveness and survives the count +moving. + +### 2. Q63(b) reached four sentences, not the one the ruling named + +*"My mailbox"* had been written as a **personal** mailbox throughout the page. +The sweep found it in §Where it is stored twice (*"a notification to me"*, *"my +own mail is on Google Workspace"*), in §How long it is kept (*"the notification +sits in my mailbox"*) and in §Who can see it. **Fifth partial sweep of this +page's who-can-see-it set.** The section comment now enumerates all **nine** +paragraphs **by opening phrase rather than by count**, all nine verified against +the built page. + +### 3. ⚠️ A SENTENCE ADDED TO BACK THE CORRECTION HAD NO COMMAND BEHIND IT + +The rewrite added *"the table carries no policy of its own granting access to +anyone"* to a legal page. **`git grep 'get-resource-policy\|ResourcePolicy'` +returned nothing.** The assertion existed as prose in §7 and in the reference +file and appeared in **neither** the §7 stamp enumeration **nor** the reference +file's Commands block. **A DynamoDB resource policy is invisible to +`describe-table`**, and every simulation in that file asks what a **principal** +may do — a resource policy grants from the other side, so nothing already run +could have seen one. `adversarial-reviewer`, round 2, on §10's own precedent. + +**Measured rather than deleted.** Both commands are now recorded as commands 7 +and 8, and **both are read by their error**: + +``` +$ aws dynamodb get-resource-policy --resource-arn arn:aws:dynamodb:ca-central-1:327082975128:table/adr-intake-submissions +An error occurred (PolicyNotFoundException) ... Resource-based policy not found +exit=254 + +$ aws organizations describe-organization +An error occurred (AWSOrganizationsNotInUseException) ... not a member of an organization +exit=254 +``` + +The second is why the **first** measurement was incomplete in a way nobody had +noticed: `sso-admin list-instances` answers about **this** account, so a member of +an AWS Organization returns `0` while Identity Center runs in the management +account — the zero would have been true and the conclusion false. **Not in an +organization**, so the zero is conclusive. Both facts are in §7's stamp, and §12 +**R21** gains claim **(v)** with two new falsifiers: a resource policy on the +table, and joining an organization. + +### 4. R10 — fired, asked, answered, and a fourth stamp-bearing site found + +Asked as a one-line question and answered the same day: **ADRIC, ADRIO, the three +OBA sections and the CTF all current.** Ticked against a **fresh confirmation, not +the 2026-08-28 stamp** — a stamp is not a renewal receipt, which is the whole of +R10. **The row does not close**; the trigger is an event and events recur. + +⚠️ **Two defects in the re-stamp itself, both found by review.** The first pass +wrote that one constant feeds both surfaces. **It does not:** +`CREDENTIALS.memberships` feeds `/about/` and `/bio/`; **`MEMBERSHIP_ORGS` feeds +`/process/` §Confidentiality and the `memberOf` triples**, the two differ on three +of four lines, and `_MembershipParity` compares their **lengths only** — so a +maintainer following that text after a lapse would have corrected `/about/`, +passed `npm run check`, and left `/process/` and the JSON-LD publishing the lapsed +membership. **That is the OCNI failure with a green build, instructed by the +reminder that exists to prevent it.** And the re-stamp instruction named three +files; **`src/pages/about.astro` is a fourth**, it carried the old date in the +present tense, and the instruction would have missed it again next time. + +### 5. Q64 opened — answering Q63(c) created the question one paragraph lower + +The page ships Pouya's own words: *"The account's root credential — the one path +no policy constrains — has no programmatic key, and I hold it."* **True whether or +not a second person holds it**, and §7 attests *held by Pouya*, not *held only by +Pouya*. It sits one paragraph below *"the small number of people who administer it +with me"*, where a reader takes it as **sole** custody. **This is Q63's own error +pointing the other way**: Q63 struck a sentence for reading identities as people; +this one invites a reader to read a possessive as an exclusion. + +**`adversarial-reviewer` round 2 asked for the possessive to be struck now, and +that finding is DECLINED with a reason.** Pouya dictated the clause in terms +(*"root holds no access keys and is held by me"*), so striking it would substitute +this session's judgement for his on a wording question he reserved. The gate is +mechanical instead: **a `TODO(pouya)` beside the paragraph, §9 Q64, and an +unticked `docs/06` item** — and `docs/06` requires that no `TODO(pouya)` remains +in a shipped page, so **the page cannot go public until he answers**. One line +either way. + +### 6. The approval gate, twice + +Round 1 found the Q63(a) tick sitting over a body that still read, in the present +tense, *"the `TODO(pouya)` is reinstated beside the copy and §9 Q63 is open"* — +**both closed in the same change set.** Round 2 then found the repair still left a +green tick over copy Pouya has not read, because the same ruling that approved the +wording **also changed it**. The item is now **split**: `[x]` Q63(a) was ruled; +`[ ]` the text **as it now stands** has not been read. A person working the list +reads the tick, not the eleven lines under it. + +### 7. Findings + +**Round 1 — 10 findings, 10 resolved** (1 blocking, 8 should-fix, 1 consider): +the ticked gate over post-approval text and its CommonMark lazy-continuation +defect; the membership-constant claim; the *"eight places"* enumeration excluding +a paragraph this change set edited; *"That is measured rather than assumed"* +re-pointed at a headcount by the paragraph split; *"and I hold it"*; *"the only +identities … are administrative ones"* substituting a category for the +measurement, one word from the vacancy Q62 barred; `docs/05:449` still describing +the struck copy **on the same line that was missed last time**; two negative +fixtures made false by this change set's own new fact; a pointer to a struck +question. The consider — `/contact/`'s *"email me directly"* — was **declined** +and recorded as a read-through judgement. + +**Round 2 — 12 findings, 11 resolved, 1 declined.** The blocking one is §3 above. +**Nine of the twelve were defects in round 1's own repairs**, which is the +measured reason D19 caps at two rounds and the reason round 2 exists at all: the +antecedent fix created a new dangling antecedent (*"Its root credential"* +attaching to **the table**); the "one item still waiting on Pouya" line was +rewritten **in the same change set that opened Q64**, wrong for the third time and +in the same direction each time, so the running tally is deleted rather than +corrected; `docs/06` kept *"eight places"* after the comment was corrected to +nine — a partial sweep of the fix for a partial sweep; and §9 Q62's script counts +went stale **again**, on the row whose own text says a stale count on a frozen +script is a defect, so the counts are now deleted in favour of *"the script prints +both on every run"*. + +Round 2 also found, pre-existing: the reference file's reproduction assertion +still read *"Five user rows and twenty-six role rows, or the run did not +happen"*, so **an operator following R21's instruction would have reproduced the +`grep -v '^AWSServiceRole'` exclusion and got the pass line for it.** Now 5 users +/ 33 roles, and command 1 carries the deletion instruction. + +**Declined, with the reason recorded:** striking *", and I hold it"* (§5 above). + +**Stopped at two rounds per D19**, and the arithmetic is the argument: round 2 +manufactured findings at a rate comparable to what it caught, so a third round +would find and create in roughly equal measure. + +### 8. Verification — every check run, exit status read, nothing truncated + +| check | result | +|---|---| +| `npm run check` | **exit 0** — 0 errors / 0 warnings / 0 hints | +| `npm run build` | **exit 0** — 23 pages | +| `npm run check:claims` | **exit 0** — 12 patterns, 23 pages; counts read from the run, not from a record | +| tripwire on the **pre-correction** bytes | **exit 1, 5 matches** at `dist-old/legal/privacy/index.html:54, 67, 67, 68, 72` — rebuilt from `bd282aa`, content proven independently of mtime by grepping the false clause | +| `npm run og:proof` | **exit 0** | +| `npm run check:intake` | **exit 0** | +| `npm run lint` | **exit 0** | +| `router.test.mjs` | **exit 0** — *"router: 30 of 30 cases pass"* | +| minifier tripwire | **exit 1, no output — clean** | +| JS in `dist` | **0 files**; `/legal/privacy/` has one `