Five items of Pouya's production run, 2026-09-01.
Q61 — scroll-padding-top becomes a max() ramp on `10lh - 83px`, with the
plain calc() first as the fallback for engines without `lh`. Hidden focus
stops under minimumFontSize=32: 290 of 1,455 -> 0, control build still
290. Default settings byte-identical (0 differences over 352 page-widths x
17 fields). The 12 residual cells at minimumFontSize=16/20 are pre-existing
and unchanged-or-better; reported, not widened, per instruction.
Intake backend + CloudFront — docs/09-cutover-runbook.md is the
copy-paste sequence for admin execution: every command followed by its
verification and expected output, rollback per part, and Part 10 is Q60's
TTL test. infra/cloudfront/router.js is the trailing-slash function
(30-case suite; 8 fail against the pre-review version, incl. a
protocol-relative open redirect). infra/cloudfront/configure.mjs is
dry-run-by-default and idempotent. scripts/intake-env.mjs emits the six
Lambda env vars from src/data/site.ts.
Four launch blockers found by reading the running system:
- handler.mjs wrote pk/sk; the live table's key is submissionId with no
sort key, so every submission would have failed validation silently
- the Lambda invoke permission is scoped to the old route path
- 22 of 23 pages 403 without the router function
- there was no 404 page; src/pages/404.astro adds it
Claims audit (D20 cutover pass) — five gloss over-reaches corrected on
/practice/energy/, /practice/insurance/ (x2), /practice/technology/ and
/med-arb/. Three findings left open for Pouya: Q62, the /med-arb/ gloss,
and Q60.
Q62 — one frozen-tripwire pattern added under the freeze's own breach
exception, with a probe and four negative fixtures. check:claims exits 1
until the false /legal/privacy/ sentence is corrected, so both deploy
paths are blocked by a mechanism rather than by memory.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Md3GndFqWPzK78xAoebsg5
7.1 KiB
Who can read adr-intake-submissions — verification extract
Why this file exists. /legal/privacy/ makes a statement to the public about
who can see the contents of the intake table. AGENTS.md §4 admits no factual
claim that cannot be traced, and CLAUDE.md's R14 rule is that anything a spec
claims about must be reachable from the repository — "if the artefact lives only
in a console, no reviewer can compare the claim against it and the claim is
unverifiable by construction." Until this file existed, that sentence was the
one claim on the site whose subject was entirely outside the repo.
Raised by claims-auditor in the D20 cutover audit, 2026-09-01, finding 8.
Provenance. Every figure below was read from AWS on 2026-09-01 with the
commands listed at the end, run read-only as arn:aws:iam::327082975128:user/pouya.
No command in this file creates or changes anything. Re-run them rather than
trusting this file; it is dated for that reason.
The claim being checked
src/pages/legal/privacy.astro, §Who can see it:
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 finding: it is false
The account has an IAM group admins carrying the AWS managed policy
AdministratorAccess, and it has two members: pouya and lars.
iam simulate-principal-policy for dynamodb:GetItem, dynamodb:Query and
dynamodb:Scan against
arn:aws:dynamodb:ca-central-1:327082975128:table/adr-intake-submissions, across
all five IAM users in the account:
| principal | GetItem | Query | Scan |
|---|---|---|---|
user/pouya |
allowed | allowed | allowed |
user/lars |
allowed | allowed | allowed |
user/adr-sml-deploy |
implicitDeny | implicitDeny | implicitDeny |
user/gitea-deploy-meshkinilaw |
implicitDeny | implicitDeny | implicitDeny |
user/meshkini-backend-deploy |
implicitDeny | implicitDeny | implicitDeny |
lars holds exactly the access pouya holds, by the same route: membership of
admins. The user's own attachments are only IAMUserChangePassword, so the
group is the whole of it.
So the published sentence is wrong on both of its halves — a second account has access, and it belongs to a second administrator of a shared account.
The rest of the surface, recorded so the check is complete rather than partial
- 5 IAM users:
adr-sml-deploy,gitea-deploy-meshkinilaw,lars,meshkini-backend-deploy,pouya. The three deploy users are allimplicitDenyabove.adr-sml-deploy's scope is S3 + CloudFront and touches no table (docs/reference/deploy-credential-verification.md). - 1 IAM group:
admins—AdministratorAccessandBilling, two members. - 33 IAM roles, 26 of them not service-linked. Two carry
AdministratorAccess:cdk-hnb659fds-cfn-exec-role-327082975128-ca-central-1and…-us-east-1. These are AWS CDK bootstrap CloudFormation execution roles, assumable by CloudFormation for stack deployment. They are a real path to the table for anyone who can deploy a CDK stack in this account — which is the two administrators above — rather than a third party. adr-intake-lambda-roleis the writing principal:dynamodb:PutItemon this table,ses:SendEmail/SendRawEmail, plusAWSLambdaBasicExecutionRole.PutItemonly — it cannot read the table, which is worth stating because it is a stronger fact than the page currently claims and it is the part of the sentence that is true.- No resource-based policy on the table. DynamoDB supports one; this table has none, so access is governed entirely by identity policies.
- The account is not single-project (
AGENTS.md§10).larsand the twomeshkini*/gitea*users are evidence of that on the IAM surface, not just in the S3 bucket listing §10 describes.
What has to happen before /legal/privacy/ goes public
Tracked as AGENTS.md §9 Q62. It is one of two things and both are Pouya's:
- Remove the access — take
larsout ofadmins, or replace that membership with a policy that denies DynamoDB on this table — and then this sentence becomes true. Note the likely collision:AGENTS.mdQ23 records the Gitea instance as jointly administered and blocked on "its second administrator", so this account is probably not the only thing that access is for. - Correct the sentence to what is true. It is a privacy policy, so the honest version is short and specific — the number of people with administrative access, and that the function that 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 is entitled to the specific.
Commands
Run as user/pouya, ca-central-1, all read-only. Exit status read on each; no
stderr suppressed anywhere.
aws iam list-users --query 'Users[].UserName'
aws iam list-groups --query 'Groups[].GroupName'
aws iam get-group --group-name admins --query 'Users[].UserName'
aws iam list-attached-group-policies --group-name admins --query 'AttachedPolicies[].PolicyName'
aws iam list-group-policies --group-name admins --query 'PolicyNames'
aws iam list-groups-for-user --user-name lars --query 'Groups[].GroupName'
aws iam list-attached-user-policies --user-name lars --query 'AttachedPolicies[].PolicyName'
aws iam list-user-policies --user-name lars --query 'PolicyNames'
TARN="arn:aws:dynamodb:ca-central-1:327082975128:table/adr-intake-submissions"
for U in pouya lars adr-sml-deploy gitea-deploy-meshkinilaw meshkini-backend-deploy; do
aws iam simulate-principal-policy \
--policy-source-arn "arn:aws:iam::327082975128:user/${U}" \
--action-names dynamodb:GetItem dynamodb:Query dynamodb:Scan \
--resource-arns "$TARN" \
--query 'EvaluationResults[].{A:EvalActionName,D:EvalDecision}' --output text
done
# Roles: 33 total, 26 non-service-linked; screened for broad policies.
for R in $(aws iam list-roles --query 'Roles[].RoleName' --output text \
| tr '\t' '\n' | grep -v '^AWSServiceRole'); do
aws iam list-attached-role-policies --role-name "$R" \
--query 'AttachedPolicies[].PolicyName' --output text
done
aws iam get-role-policy --role-name adr-intake-lambda-role \
--policy-name adr-intake-lambda-inline --query PolicyDocument
aws iam list-attached-role-policies --role-name adr-intake-lambda-role
⚠️ simulate-principal-policy was the tool that produced a false negative on
this project once already — AGENTS.md Q22, where eight checks returned empty
because 2>/dev/null was hiding an InvalidInput error caused by a zsh
parameter-expansion bug ($ACCT:user/ parses :u as a history modifier). The
loop above brace-quotes ${U} for that reason, prints one line per principal so
a silently-skipped iteration is visible as a missing row, and suppresses nothing.
Five rows, or the run did not happen.