Commit Graph
4 Commits
Author SHA1 Message Date
Pouya LajevardiandClaude Opus 5 2b6176e4d7 feat: SES production access and monitoring; §7 as single source of operational truth
Q19 is closed — SES production access granted in ca-central-1, confirmed in
writing. Nothing now blocks /contact/.

The structural change is the important one. Specs in docs/ carried their own
copies of resource IDs, regions, DNS records and service state. AGENTS.md §7
is now the single source of truth for operational facts and docs/ cite it
rather than restating it, with the rule recorded in CLAUDE.md under
Conventions.

The reason is the previous commit's DKIM inversion, generalised: the same
fact lived in §7 and docs/05, a correction reached one of them, and the stale
copy told an operator to delete the records that authenticate outbound mail.
A duplicated fact is one that will eventually be wrong in one place, and the
copy that goes stale is the one nobody re-reads. Verified by grep over
docs/*.md — no operational identifier remains.

Also in this change:

- §7 records the SES monitoring: SNS topic ses-alerts, alarms
  SES-BounceRate-High (>= 0.03) and SES-ComplaintRate-High (>= 0.001), and
  the deliberate choice of email feedback forwarding over an SNS feedback
  topic at this volume. The ses-alerts email subscription is stamped PENDING
  CONFIRMATION — the alarms currently notify nobody, now tracked as R9 and on
  the cutover checklist.
- docs/05 records why those alarms are a real control: SES suspends above
  roughly a 5% bounce rate, and under 100 messages a month five bounces
  crosses it.
- Q29: the deploy guard now covers AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY
  (emptiness only, never echoed) and INTAKE_ENDPOINT, promoted to job-level
  env. An empty intake endpoint ships a live form posting to nothing, which
  is worse than a failed build. Executed under sh -e across four input
  states; fails closed, leaks nothing.
- docs/06: account ID removed from the backup-bucket callout, pointing at §10
  instead, as README already does.
- astro.config.mjs: prefetch removed entirely. Any setting ships Astro's
  prefetch script to every page against the zero-JS convention. Recorded as a
  decision; revisit against real Lighthouse numbers.

AGENTS.md entry (r) records the full reasoning.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012XquaEq4BgWMCwUqLEyNkF
2026-08-26 11:47:17 -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 e6abdf42e8 feat: execution protocol, review agents, DNS and SES findings
Build and deploy / build-and-deploy (push) Failing after 6s
2026-08-26 09:51:24 -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