feat: rule Q62 by stating the truth; strike the /med-arb/ gloss; re-stamp R18
Pouya's four rulings of 2026-09-01, applied 2026-09-02.
Q62 — RULED "state the truth", not "remove the access". /legal/privacy/
now says two people can read the intake table, names their role, and adds
the two stronger facts the false sentence had crowded out: the handler
role holds PutItem only, and adr-sml-deploy is implicitDeny on all seven
read and write actions. Wording is subject to Pouya's read-through —
Q63(a), with a TODO(pouya) beside the copy.
The ruling named one sentence; a vocabulary sweep found the falsehood in
three places, and the audit then found two more. Five paragraphs now
answer "who can see it" and change together.
The tripwire stays permanently, per ruling, and grew from two
alternatives to five. Every alternative is one string that reached dist/.
Proven both ways against the pre-correction page rebuilt from bd282aa:
exit 1 with 5 matches at dist/legal/privacy/index.html:54,67,67,68,72;
exit 0 on the corrected page, self-test 12 patterns / 36 approved
strings.
/med-arb/ — the gloss is struck with no replacement, per ruling. The
strike left "the section above" pointing at the ADRIC rule set and "the
agreement" with no antecedent; both fixed. The bare designations line
sitting under ADRIC's quoted competence requirement is also struck, which
goes beyond the ruling and is flagged for Pouya.
R18 — re-stamped, two-tier: (a)(c)(d) re-verified against a source,
(b)(e)(f)(g) held on a cadence judgement. All seven hold, no shipped
sentence changed. R18's trigger had NO cutover checklist item and had
stamped five extracts of seven; both fixed. Candidate limb (h) flagged.
R10 — fired and unsatisfied; left open on instruction.
The evidence behind the new privacy sentence was weaker than the
sentence. Re-measured: 33 of 33 roles simulated (23 of 26 carried inline
policies nobody had read; the two CDK lookup roles can read the table),
four trust policies, the CloudFormation escalation path for all five
users, 0 federated providers, root recorded. Every read path terminates
at the same two people.
Two review rounds, 36 findings. 35 fixed, 1 declined. Five of round 2's
were defects in round 1's own fixes; stopped at two per D19.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Md3GndFqWPzK78xAoebsg5
This commit is contained in:
co-authored by
Claude Opus 5
parent
bd282aa47d
commit
6aaf089b05
@@ -81,7 +81,7 @@ const RETENTION_MONTHS = 24;
|
||||
|
||||
/** Bump this on ANY substantive edit. A privacy policy with a stale date is a
|
||||
* policy a reader cannot tell they are reading an old version of. */
|
||||
const LAST_UPDATED = '31 August 2026';
|
||||
const LAST_UPDATED = '2 September 2026';
|
||||
|
||||
/* Rendered from the form's own field list, so the two cannot drift. `consent`
|
||||
and the honeypot are absent from `INTAKE_FIELDS` deliberately and are
|
||||
@@ -122,10 +122,30 @@ const COLLECTED = INTAKE_FIELDS.map((field) => field.label);
|
||||
<ul>
|
||||
{COLLECTED.map((label) => <li>{label}</li>)}
|
||||
</ul>
|
||||
{
|
||||
/* ⚠️ DO NOT WRITE "your IP address" HERE, AND DO NOT CONCLUDE ANYTHING
|
||||
ABOUT WHETHER THE ADDRESS IDENTIFIES ANYONE. The handler stores
|
||||
`requestContext.http.sourceIp` — behind the `/api/*` behaviour that
|
||||
is a CloudFront edge, so the expected value is Amazon's. **Expected,
|
||||
not measured:** `docs/09` Part 7.2 measures it at cutover and
|
||||
enumerates three outcomes, one of which is that the reader's own
|
||||
address does land. This copy therefore states only why the field is
|
||||
kept, which is true in all three. A previous form hedged "usually
|
||||
not yours" and then asserted "not precise enough to identify you" —
|
||||
false in exactly the branch the hedge admitted. `claims-auditor`,
|
||||
then `adversarial-reviewer` round 2. */
|
||||
}
|
||||
<p>
|
||||
Submitting the form also records the date and time, your IP address
|
||||
and your browser's user-agent string. Those three are kept for
|
||||
investigating abuse of the form and are not used for anything else.
|
||||
Submitting the form also records the date and time and your browser's
|
||||
user-agent string. Those two are kept for investigating abuse of the
|
||||
form and are not used for anything else.
|
||||
</p>
|
||||
<p>
|
||||
It also records the network address the request arrived from. This
|
||||
site sits behind a content delivery network, so that address is
|
||||
normally the network's own rather than your connection's — which is
|
||||
why it is kept simply because it arrives with the request, and not as
|
||||
a way of identifying anyone.
|
||||
</p>
|
||||
<p>
|
||||
Nothing else on this site collects personal information. There is no
|
||||
@@ -204,9 +224,10 @@ const COLLECTED = INTAKE_FIELDS.map((field) => field.label);
|
||||
what they keep.
|
||||
</p>
|
||||
<p>
|
||||
No one else receives it. There is no CRM, no mailing list, no
|
||||
analytics on the submission, and no assistant or outside
|
||||
administrator.
|
||||
No one else is sent it. There is no CRM, no mailing list and no
|
||||
analytics on the submission. Who can read what is stored is a
|
||||
different question from who it is sent to, and it is answered under
|
||||
"Who can see it" below.
|
||||
</p>
|
||||
|
||||
<h2>How long it is kept</h2>
|
||||
@@ -236,43 +257,76 @@ const COLLECTED = INTAKE_FIELDS.map((field) => field.label);
|
||||
|
||||
<h2>Who can see it</h2>
|
||||
{
|
||||
/* ⚠️ THIS SAID "Nobody else has access" AND THE SECTION TWO ABOVE HAD
|
||||
JUST NAMED GOOGLE. The Google correction was applied to §Where it is
|
||||
stored and not swept into the section actually headed with the
|
||||
question a reader asks — so the page answered "who can see the names
|
||||
of the opposing parties I gave you?" with *nobody else* under that
|
||||
heading and *Google* under a different one. Fixing one section and
|
||||
not the section that answers the same question is the sweep failure
|
||||
`CLAUDE.md` describes. Found by `adversarial-reviewer` round 2. */
|
||||
/* ⚠️ FIVE PARAGRAPHS ANSWER "WHO CAN SEE IT" AND THEY CHANGE
|
||||
TOGETHER: this section's four — the count, the measured enumeration,
|
||||
the two narrow credentials, the three copies — and §Where it is
|
||||
stored's last one. Every defect here has been a partial sweep of that
|
||||
set, and there have been four.
|
||||
**The enumeration paragraph is the one that goes stale on its own**,
|
||||
because it is a claim about the present state of an AWS account: §12
|
||||
**R21** is its trigger, and
|
||||
`docs/reference/intake-table-access-verification.md` holds the
|
||||
commands. `check-claims.mjs`'s `sole-administrator-q62` pattern is a
|
||||
permanent bar on the old shape returning (Pouya, ruled 2026-09-01). */
|
||||
}
|
||||
{
|
||||
/* TODO(pouya): the sentence below is FALSE as at 2026-09-01 and this
|
||||
page must not go public until you rule — §9 Q62. The AWS account has
|
||||
an `admins` IAM group carrying `AdministratorAccess` with TWO
|
||||
members, you and one other person, and
|
||||
`simulate-principal-policy` returns **allowed** for
|
||||
`dynamodb:GetItem`/`Query`/`Scan` on this table for both.
|
||||
Evidence and commands:
|
||||
`docs/reference/intake-table-access-verification.md`.
|
||||
THE QUESTION: do you remove that access — which may be the same
|
||||
co-administrator Q23's Gitea instance depends on, so it is not free
|
||||
— or does this paragraph state the true number? Nothing here may be
|
||||
softened into "authorised administrators": on this page a reader is
|
||||
entitled to the specific, and a true vacancy is worse than a false
|
||||
specific only in that it cannot be caught.
|
||||
Raised by `claims-auditor`, D20 cutover audit, finding 8. */
|
||||
/* TODO(pouya): TWO THINGS, BOTH FOR YOUR READ-THROUGH — §9 Q63.
|
||||
(1) APPROVE THE WORDING BELOW. Your ruling settled what it must say;
|
||||
you reserved the wording. Nothing else gates it.
|
||||
(2) WHO ELSE CAN READ `info@smlcompany.ca`? The paragraph below says
|
||||
"anyone who can reach that mailbox", which is true whatever the
|
||||
answer — but §7 records the mail host and the SES identities and NOT
|
||||
the mailbox's access list, so this repository cannot state the
|
||||
number a reader of a privacy policy is entitled to. If the Workspace
|
||||
is administered by anyone else, or the address is a shared alias,
|
||||
say so and this becomes specific like the table sentence above it.
|
||||
Raised by `claims-auditor` and `adversarial-reviewer`, D20 cutover
|
||||
pass, 2026-09-02. */
|
||||
}
|
||||
<p>
|
||||
I can. 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.
|
||||
Two people can. The table sits in an Amazon Web Services account that
|
||||
also runs systems unrelated to this practice, and that account has two
|
||||
administrators — me, and one other person who administers it with me.
|
||||
Administrative access to the account carries the ability to read the
|
||||
table, so both of us can read what you send. I would rather tell you
|
||||
that than give you the tidier answer.
|
||||
</p>
|
||||
<p>
|
||||
The one other place a copy exists is the notification email, which
|
||||
sits in the Google Workspace mailbox named above. So the honest answer
|
||||
to "who can see this" is: me, and Google as the company that runs my
|
||||
mail.
|
||||
No one outside those two people has been granted access to the table,
|
||||
and that is measured rather than assumed: every user and every role in
|
||||
the account was simulated against this table, and the only ones that
|
||||
come back able to read it lead to those same two people. Amazon Web
|
||||
Services operates the table, as <em>Where it is stored</em> above says —
|
||||
a company that runs a database is not someone who has been given access
|
||||
to it, and both of those are true at once.
|
||||
</p>
|
||||
<p>
|
||||
Two things in the system are narrower than I am, and they are worth
|
||||
stating because they are the part you cannot check for yourself. The
|
||||
function that receives the form
|
||||
<strong>can only add a record — it cannot read the table back.</strong
|
||||
> And the credential that publishes this website has
|
||||
<strong>no access to the table at all</strong>, for reading or for
|
||||
writing.
|
||||
</p>
|
||||
{
|
||||
/* ⚠️ THREE COPIES, NOT TWO, AND THE THIRD IS THE READER'S OWN. This
|
||||
said "the one other place a copy exists" and named only my mailbox —
|
||||
while the handler puts the whole submission into the confirmation it
|
||||
sends the inquirer, under "What you sent:" (the second
|
||||
`SendEmailCommand` in `backend/intake/handler.mjs`). So a copy sits
|
||||
with the reader's provider, which §Where it is stored already tells
|
||||
them. An absolute enumeration standing one section from the page's
|
||||
own counter-example is what Q62 was; this is the same shape and it
|
||||
was introduced by Q62's own fix. Found by `claims-auditor`. */
|
||||
}
|
||||
<p>
|
||||
There are therefore three copies of what you send. The record in the
|
||||
table, which the two people above can read. The notification in my own
|
||||
mailbox, which is on Google Workspace — so Google holds a copy of
|
||||
whatever you sent me, and so does anyone who can reach that mailbox.
|
||||
And the confirmation that went to you, which sits with whoever runs
|
||||
your email; that copy is in your hands rather than mine.
|
||||
</p>
|
||||
|
||||
<h2>Cookies and analytics</h2>
|
||||
|
||||
Reference in New Issue
Block a user