Commit Graph
3 Commits
Author SHA1 Message Date
Pouya LajevardiandClaude Opus 5 4735989f0b feat: cut /legal/privacy/ §Who can see it to four plain statements; name SML Company Ltd on the consent; close Q64 moot
Two rulings from Pouya, 2026-09-02.

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

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

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

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

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

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

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

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Md3GndFqWPzK78xAoebsg5
2026-09-02 12:03:47 -04:00
Pouya LajevardiandClaude Opus 5 9f2d2eeb04 fix: resolve adversarial review round 2 — 9 findings, 8 of them in round 1's fixes
Build and deploy / build-and-deploy (push) Failing after 4s
D19 caps the loop at two rounds, and this is what the second round is for.

BLOCKING. Round 1 made NO_RETAINER_NOTICE a requireEnv and added it to no
document, while the fix's own comment claimed docs/06 named it. The deployment
list said five variables for a handler that needs six, so an operator following
the cutover checklist would have deployed a function that throws at cold start
on every invocation — 5xx from API Gateway, every inquiry lost from the moment
/api/* was wired, loud in CloudWatch and silent to Pouya. docs/05 and docs/06
now name all six, and the comment that asserted the documentation existed is
corrected rather than deleted.

The intake route check added in round 1 could not fail: curl -w already prints
000 on a failed transfer, so `|| echo 000` double-appended and the failure arm
was unreachable, and the pass arm accepted anything that was not literally 404 —
including the 403 CloudFront returns when the /api/* behaviour is missing, which
is the one distinction the check exists to draw. It now sends the correct Origin
and asserts a positive: 303 to /contact/could-not-send/, which the handler
returns before any DynamoDB write or email. Probed on refused/501/403/303; the
old version passed the first three. Fixed in both deploy paths.

Removing priceRange left three statements saying it was present or pending, one
of them the stated reason /fees/ emits no Offer node. Deleting
overtimeStartsAfterSessionHours left AGENTS.md §9 naming it and left Q59
recorded as open. The Google-as-processor fix was applied to the privacy
policy's "Where it is stored" and not to "Who can see it", which still read
"Nobody else has access".

And the variable removal was justified with a path-scoped git grep — which also
cannot see untracked files. The unscoped sweep found docs/06's variable table,
the OIDC example, and .env.example still carrying them; .env.example also
restates the execute-api hostname, falsifying a live claim in intake.ts that has
been corrected. That file is not edited here: this environment denies read
access to it, and nothing may edit a file it cannot read. It is in the batched
list.

Also: og:image:alt was the page title rather than the card's headline on 20
pages; og-card.ts documented the wrong path and invocation for the contact
sheet; deploy-local.sh still said Q22's deploy credential "does NOT yet exist";
and the round-1 fix comments were trimmed per D19, though the ratio held at 0.44.

Round 2 also confirmed the round-1 fixes by measurement: all 56 .btn instances
across 22 pages, the consent checkbox's computed accessible name, the radio
labels hit-tested at 44px, and og:proof exercised against synthetic article
pages in a sandbox.

Verified: check/build/check:claims/og:proof/check:intake/lint/bio:pdf all exit 0
on a clean build; 22 pages; Lighthouse 99-100 / 100 / 100 / 100, CLS 0.000.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Md3GndFqWPzK78xAoebsg5
2026-08-31 11:21:07 -04:00
Pouya LajevardiandClaude Opus 5 210bc25a26 feat: build steps 7a-10 — the site is complete and reviewable at 22 pages
Steps 7a through 10 as one authorised run. Nothing deployed (D11).

7a  Lighthouse returns as `lighthouse@13.4.1` + `chrome-launcher`, NOT
    `@lhci/cli`. AGENTS.md §7's advisory attribution was wrong: the carriers
    were @lhci/cli's own `tmp` and @puppeteer/browsers' `extract-zip`, not
    Lighthouse, which audits clean. A deliberate deviation from R11's literal
    trigger, recorded with what it costs. Local gate; CI has no Chrome.

7b  OG card generator (satori + sharp) discharges R15 — 20 typed cards plus
    per-article cards; the portrait stays on / and /about/ by Q40. Insights
    plumbing: ArticleCard, Prose, the index, the article route, articleGraph,
    and /'s section 7. Card copy is constrained structurally because text in a
    JPEG cannot be grepped by check:claims: every headline IS its page's <h1>,
    enforced by `npm run og:proof`.

7c  Five drafted launch articles, draft: true / reviewedByPouya: false. An
    independent compliance audit returned 76 findings and 57 unsourced
    assertions; all blocking and should-fix applied.

8   /contact/, the intake form, and backend/intake/ (undeployed). Plain HTML
    POST to a same-origin /api/intake with a 303 redirect, so the form works
    with zero JavaScript. docs/05 records three deliberate deviations.

9   /fees/ on Q59's ruling — overtime runs from the session cap, and the
    reservation point ships adjacent to the rate. One-page PDF bio discharges
    R16; /bio/ is its source, so the circulated artefact stays inside the
    review apparatus.

10  /legal/privacy/ and /legal/terms/, written to the backend as built. Three
    of the policy's statements are derived and cannot drift.

Also: /about/'s inverse credentials band (approved at step 6); Q59 closed;
R15 and R16 discharged; and a fix to shipped copy — /practice/energy/ asserted
the absence of a regulation the source extract says must not be asserted.

Review: adversarial-reviewer, two rounds (D20/D19). Round 1 returned 16
findings including two blocking — an invisible ghost button on /fees/ at
1.00:1 that Lighthouse scored 100, and a privacy policy that named one data
processor when there are two. All 16 acted on.

Lighthouse, 22 pages, mobile: performance 99-100, accessibility 100,
best practices 100, SEO 100 on every indexable page, CLS 0.000.

AGENTS.md entry (ah) has the detail, including four of my own verification
commands that were wrong and what each of them nearly caused.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Md3GndFqWPzK78xAoebsg5
2026-08-31 10:56:54 -04:00