Commit Graph
6 Commits
Author SHA1 Message Date
Pouya LajevardiandClaude Opus 5 77a7b410b2 feat: apply six rulings; close Q22/Q44/Q45/Q46(b)/Q47; revert Q47's two graph fields
Pouya's rulings: Q44 (memberships current — ship the group), Q45 (PDF bio
deferred to step 9), Q46(a) (three offerings pass all gates), Q46(b) (§11
ratified as the source for definitional expansions, conditional on committing
the source), Q47 (set jobTitle and worksFor), the legal-advice formulation
ratified without change, and Q22 closed on his own execution evidence.

Q46(b): docs/reference/adrio-designations.md commits all five ADRIO expansions
with reproducible sha256 (four fetches each; both review agents independently
reproduced every digest). It immediately caught the error Pouya raised in the
same message — §11 had said "Chartered Mediator-Arbitrator" since the file was
created, ADRIO's term is "Chartered Med-Arbitrator", and the wrong form was in
dist/about/index.html. Four prior review passes read that string and checked
only whether it was sourced, not whether it was right.

Q47 REVERTED after both review agents struck it independently. jobTitle shipped
for one pass as "Mediator and Commercial Arbitrator" — the string claims-auditor
had removed from this same node's description the previous day, since §4 has no
row for a completed arbitration. The implementation flagged the wrong defect: it
argued about scoping and missed that the whole string was already struck. worksFor
was reverted because ProfessionalService.provider is this Person, so
provider -> Person -> worksFor asserts a same-entity claim transitively. Now
jobTitle: 'Mediator', no worksFor. Q49 asks for the two §4 rows.

Q44: memberships render with NO currency warranty (his condition), and R10 is
re-armed with an event trigger rather than a date since he declined renewal-date
tracking. Q22: §7 goes to PROVISIONED; R17 carries the first rotation date,
2026-11-26. New CLAUDE.md convention, his: never suppress stderr in a
verification script — suppression turns "it failed" into "it found nothing".

Two review rounds resolved 48 findings; the majority of the second round were
defects in the first round's fixes, including a re-widening of §4's renewal
period inside the comment that corrects that widening, a cited guard in
schema.ts that does not exist, and a struck §9 row describing a reverted state.
Three findings were one lift from a public page: docs/03's /for-parties/
directive breached D13 twice, docs/01 told an implementer an unpublishable strip
could ship, and docs/07 priced three ungated offerings with no gate note.

Also commits docs/reference/adrio-extract/ — the extraction script and its five
outputs, since the digests covered raw HTML and said nothing about the text the
term counts were run against. The equivalent gap for Q22's IAM verification is
NOT closed and is Q52.

Verified: astro check 0/0/0, eslint + prettier clean, build 2 pages, 0 .js
emitted, minifier guard silent, animation-timeline intact, no currency-warranty
phrasing in dist, JSON-LD correct on both pages.
NOT run: Lighthouse (tool unavailable until step 7, R11); HTML validator.

Opens Q48-Q53. Live reminders: R1, R10, R11, R13, R14, R15, R16, R17.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0148NztQskLKKApP5SzAA78e
2026-08-28 13:50:58 -04:00
Pouya LajevardiandClaude Opus 5 c576b9a85f feat: build step 3 — /about/, minus its memberships; close Q40–Q43
Build and deploy / build-and-deploy (push) Failing after 6s
Applies Pouya's rulings on Q42, Q41(a)(b)(c), Q43 and Q40, then builds
`/about/` — six of docs/01's seven items.

`/about/` ships WITHOUT a memberships group. R10 is a prohibition on
shipping a page that lists memberships before they are re-confirmed; the
re-confirmation is a fact only Pouya holds and was not obtained. The
first version published all four and disclosed the gap in five places
instead; both review agents rejected that. Q44 carries the question.

Rulings:
- Q42 — ENE, dispute-system design and pre-dispute technical advisory
  rowed; settlement counsel struck as a partisan role. The strike
  exposed a hole in the offering test, which now states the prior
  question it was missing.
- Q41(a) — Q37 reaches prose, and prose is held to a higher bar. The
  sentence is now one constant, ASYMMETRY_LINE, because two hand-typed
  copies had already diverged inside one session.
- Q41(b) — not restored; the implication turned out to be in three
  places, two of which survived the sweep that closed it.
- Q41(c) — verified against the LAT's own Rules and extracted into
  docs/reference/lat-case-conference.md. Rule 2.4 makes "Pre-Hearing
  Conference" the Tribunal's own term for a case conference; the Rules
  contain zero occurrences of `mediat` in 66,593 characters.
- Q43 — the timings are service commitments; PROCESS_FRAMING renders
  adjacent to them, not in a lede above.
- Q40 — bundled to step 7 as R15, blocking cutover.

Four review passes, 43 findings, nine of them defects in their own
predecessors' fixes. The worst was mine: the false universal Q39 struck
reached a public page. Also fixed a portrait ladder that upscaled 1.93x
at 1024/DPR2 on BOTH pages — the shipped home page included — because
its 960 ceiling was derived from the layout range where the image is
narrowest.

Verified: check/lint/build/audit clean; 0 upscaling across 11 device
profiles; 0 overflow and 0 over-wide elements at 13 widths; 0 contrast
failures across 127 and 88 painted pairs; 0 print failures against white
paper; reveal 0 hidden under reduced-motion and print; zero JavaScript.
Lighthouse NOT RUN — tool unavailable until step 7 (R11). HTML validator
NOT RUN.

Opens Q44 (memberships), Q45 (PDF bio), Q46 (offering-test gating; the
glossary standard), Q47 (jobTitle without worksFor). Adds R15.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0148NztQskLKKApP5SzAA78e
2026-08-28 12:10:41 -04:00
Pouya LajevardiandClaude Opus 5 8134709548 feat: build step 1 — scaffold, layout, header, footer, SEO; zero JavaScript
Build order step 1 (docs/01): scaffold, tokens, base layout, header,
footer, SEO component, plus a temporary /type-scale/ proof sheet that
step 2 deletes.

THE FONTS WERE NEVER ON DISK. global.css declared six @font-face rules
pointing at /fonts/*.woff2 and public/fonts/ did not exist, so every
face had been silently falling back to Georgia and the system sans.
Six cuts committed, 123,804 bytes, SIL OFL 1.1, provenance in
docs/reference/fonts-provenance.md. ?v=1 on every URL because the
deploy script serves them immutable for a year.

ZERO JAVASCRIPT. The reveal was an inline IntersectionObserver in
<head>; docs/05 specifies script-src 'self' with no unsafe-inline, so
the only script on the site was the one thing the site's own CSP would
refuse to execute. Replaced with animation-timeline: view() behind
@supports. 0 script tags and 0 .js files in dist.

The infinity mark is lifted verbatim from the deployed site's own
smlMark loading thumbnail, not redrawn (Q32 asks whether a canonical
vector exists). The proof sheet computes its contrast table from
tokens.css rather than restating docs/02 — all eleven ratios reproduce
the measured table exactly.

Register: Canadian Tax Foundation added (§4, R10 widened); Q30 closed
— SML Company Ltd is federally incorporated under the CBCA, and the
footer publishes neither that nor the place of business; Q31 closed —
Plausible, on EU-only data residency (D15 amended). ROLE constants
added for "Director of Firm Operations" and "active litigation
exposure" so step 3 does not hand-type them.

Lighthouse unavailability now stated in six places rather than left as
a control that had silently stopped existing (§7, R11).

Both review agents ran twice. The second pass found four defects in
the first pass's fixes, including the minifier bug written back into
its own fix and a colour-alone repair that used the banned gold-on-
cream pairing at 2.10:1. Measured in headless Chrome at thirteen
widths with a seventh nav item injected: 0 overflow, 0 tap targets
under 44x44, 0 focus-order inversions, state indicators at 12.29:1,
755 words of body text with no JavaScript.

Opened: Q32-Q37. Closed: Q30, Q31.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012XquaEq4BgWMCwUqLEyNkF
2026-08-26 15:57:02 -04:00
Pouya LajevardiandClaude Opus 5 7514a49803 feat: upgrade to Astro 7; harden the content schema; wire a11y linting
Amends D1 to pin the major explicitly (v7.x) rather than inherit it. The
^5.0.0 pin was recalled rather than checked and was two majors stale the day
it was written, which meant shipping a framework carrying high-severity XSS
advisories. CLAUDE.md now requires every version pin to be verified against
the registry, and R11 requires re-checking at each build-order boundary.

npm audit now reports 0 vulnerabilities, down from 16. Every Astro advisory
is cleared; the residual 10 all traced to @lhci/cli, which is removed — it
was the sole source of 7 high-severity findings, 0.15.1 is latest so there
was no clean upgrade, and it cannot run without pages or a lighthouserc.
Re-added at build step 7 with a freshly verified pin.

Content collections migrated to the Content Layer API: src/content.config.ts,
loader: glob(), z from astro/zod.

Two review passes found seven defects in the fix itself, all now closed:

- z.coerce.date() read an unquoted 20260801 as epoch milliseconds and
  yielded 1970-01-01 silently; the first replacement then accepted
  2026-13-45 as an Invalid Date and rolled 2026-02-30 over to 2026-03-02.
  Dates are now anchored, date-only, parsed as UTC and round-tripped.
- The title bound applied the SEO spec's 50-60 to the headline rather than
  the rendered <title>, which guaranteed 68-78 on every article and rejected
  all five planned launch headlines. Articles are now the documented
  exception: the headline is the <title>, no suffix.
- An article could ship an image with no alt text, or whitespace-only alt.
- Two schema comments asserted controls nothing enforced; both are now real
  refinements, each tested with a failing and a passing case.
- PRACTICE_SLUGS and PRACTICE_AREAS could drift silently; a compile-time
  check now catches both directions.
- eslint.config.js imported globals and @eslint/js undeclared, resolving by
  hoisting accident.
- scripts/deploy-local.sh claimed parity with CI while skipping npm run
  check and two credential guards — on the only path this site can ship
  today.

Accessibility linting is on (36 jsx-a11y rules) before step 1 writes the
layout. An earlier claim in §7 that none was possible was wrong twice, and
is corrected in AGENTS.md entry (t) along with the reasoning.

Opens Q30 and Q31 for two unregistered claims in src/data/site.ts.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012XquaEq4BgWMCwUqLEyNkF
2026-08-26 14:10:09 -04:00
Pouya LajevardiandClaude Opus 5 6bf1167624 fix: sweep D3 amendment through the specs; correct inverted DKIM table
The re-audit of the deploy-guard change surfaced defects well outside the
diff, including one that would have broken production mail.

docs/05-backend-spec.md had the two SES DKIM sets exactly inverted, labelling
the three records that resolve as "orphans" and the three NXDOMAIN records as
"Live. Never delete". Entry (j) corrected this in AGENTS.md §7 and the
correction never reached docs/05. Since SES has no custom MAIL FROM, DKIM is
the only thing satisfying DMARC, so acting on that table would have silently
broken intake mail authentication.

Also in this change:

- .gitea/workflows/deploy.yml gains a guard as steps[0] that fails the run,
  naming the variable, if AWS_REGION, S3_BUCKET or CLOUDFRONT_DISTRIBUTION_ID
  is empty — how a Gitea too old for the vars context manifests. Verified
  fail-closed under bash -e, sh -e and bash -euo pipefail.
- AGENTS.md Current Truth: SPF and DMARC recorded as present (Q20), the
  matching §10 High risk row retired, three duplicate Q rows removed.
- docs/reference/AWS-Hosting-Guide.md tracked and given a do-not-execute
  banner; it was an executable procedure for the architecture D1/D3 replace.
- Copy decks: "a working litigator" and "an active litigation practice"
  replaced with the register's own wording; LegalService JSON-LD replaced with
  ProfessionalService; tribunal-secretary offers removed per D14; nine stale
  question blockers swept.
- astro.config.mjs: prefetchAll disabled — it injected JS into every page
  against the zero-JS convention with no decision recorded.
- src/data/site.ts: unregistered response-time commitment nulled (Q27);
  OBA section names downgraded to [assumed] (Q28).
- s3:AbortMultipartUpload reasoning corrected to measure ./dist, not the repo.

Opens Q27, Q28, Q29. AGENTS.md entry (q) records the full resolution,
including the findings declined and why.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012XquaEq4BgWMCwUqLEyNkF
2026-08-26 11:28:42 -04:00
Pouya Lajevardi 19f7226661 chore: project scaffold, specs, and working record
Build and deploy / build-and-deploy (push) Failing after 5s
2026-08-26 08:51:16 -04:00