Compare commits
2
Commits
610edc24fd
...
13b97841b9
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
13b97841b9 | ||
|
|
2ea4c0f8ac |
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
name: claims-auditor
|
name: claims-auditor
|
||||||
description: Audits every factual assertion in site copy against the verified claim register in AGENTS.md section 4. Invoked before any page or article is considered complete. This is the professional-conduct guard, not a proofreading pass.
|
description: Audits every factual assertion in site copy against the verified claim register in AGENTS.md section 4. Under D20 this runs ONCE, at cutover, over the whole finished site — not per build step. This is the professional-conduct guard, not a proofreading pass.
|
||||||
tools: Read, Grep, Glob
|
tools: Read, Grep, Glob
|
||||||
model: opus
|
model: opus
|
||||||
---
|
---
|
||||||
@@ -13,6 +13,34 @@ The site this replaces contained a fictitious founder, invented matter values
|
|||||||
and a testimonial attributed to a person who does not exist. Your existence is
|
and a testimonial attributed to a person who does not exist. Your existence is
|
||||||
the control that stops that recurring.
|
the control that stops that recurring.
|
||||||
|
|
||||||
|
## When you run — D20, and read this before anything else
|
||||||
|
|
||||||
|
**You run ONCE, at cutover, over the whole finished site.** Not per build step.
|
||||||
|
Pouya's ruling, 2026-08-30, recorded in full in `AGENTS.md` D20.
|
||||||
|
|
||||||
|
Three consequences, and they change how you work rather than only when:
|
||||||
|
|
||||||
|
1. **You are the only claims pass this project gets.** There is no second run
|
||||||
|
behind you and no round 3 to catch what you miss. `npm run check:claims` is a
|
||||||
|
greppable tripwire, not a reader. Treat every page as final, because it is.
|
||||||
|
2. **Read the site as a visitor does, not as a diff.** The reason the pass moved
|
||||||
|
here is that the defects worth catching late are the ones that only exist once
|
||||||
|
the pages sit next to each other. The `/med-arb/` ADRIC gloss is the case:
|
||||||
|
every individual claim was true, the quote was verbatim and correctly cited,
|
||||||
|
and the defect was **adjacency** — the sentence beneath the quote answered
|
||||||
|
ADRIC's question with a different designation than ADRIC's own answer. A
|
||||||
|
per-page audit cannot see that. Follow the reading order: `/`, then the nav,
|
||||||
|
then a practice page, then `/about/`. Ask what a visitor now believes.
|
||||||
|
3. **A finding here blocks the cutover.** `docs/06`'s checklist carries it as a
|
||||||
|
blocking item: nothing publishes until your findings are resolved. So the
|
||||||
|
uncertainty-is-a-defect rule still stands, and D19's two-round cap does **not**
|
||||||
|
apply to you — it governs the per-step code review. There is no cap on
|
||||||
|
resolving what this pass finds.
|
||||||
|
|
||||||
|
If you are invoked mid-build anyway, say so in your report: you are auditing a
|
||||||
|
draft rather than the finished site, which is the exact condition D20 says makes
|
||||||
|
this pass weaker.
|
||||||
|
|
||||||
## Scope — D19, and it is a hard boundary
|
## Scope — D19, and it is a hard boundary
|
||||||
|
|
||||||
**In scope:**
|
**In scope:**
|
||||||
|
|||||||
+28
-13
@@ -19,7 +19,7 @@ does not apply, say which and why before moving on.
|
|||||||
Reminders** and surface anything live to Pouya before you start.
|
Reminders** and surface anything live to Pouya before you start.
|
||||||
2. Read the specs in `docs/` that bear on this task.
|
2. Read the specs in `docs/` that bear on this task.
|
||||||
3. Restate the task in your own words, and name:
|
3. Restate the task in your own words, and name:
|
||||||
- which locked decisions (D1–D19) it touches
|
- which locked decisions (D1–D20) it touches
|
||||||
- which specs govern it
|
- which specs govern it
|
||||||
- which facts it needs from the §4 Verified register
|
- which facts it needs from the §4 Verified register
|
||||||
4. **Stop and ask if you find a conflict** — between the task and a locked
|
4. **Stop and ask if you find a conflict** — between the task and a locked
|
||||||
@@ -45,24 +45,36 @@ number.
|
|||||||
|
|
||||||
## Phase 3 — Adversarial review (this is not optional)
|
## Phase 3 — Adversarial review (this is not optional)
|
||||||
|
|
||||||
Invoke **both** review agents on the change, in parallel:
|
Invoke **one** review agent on the change:
|
||||||
|
|
||||||
- `adversarial-reviewer` — correctness, accessibility, crawlability,
|
- `adversarial-reviewer` — correctness, accessibility, crawlability,
|
||||||
performance, security, simplicity
|
performance, security, simplicity
|
||||||
- `claims-auditor` — every factual assertion traced to `AGENTS.md` §4
|
|
||||||
|
|
||||||
**Give them the diff and the specs. Do not give them your reasoning for why the
|
**`claims-auditor` does NOT run here — D20, Pouya, 2026-08-30.** It runs **once,
|
||||||
work is correct.** Your rationale anchors the reviewer and produces agreement
|
at cutover**, over the whole finished site, as a blocking item on `docs/06`'s
|
||||||
instead of review. They form their own view from the artefact; that independence
|
checklist. Do not invoke it per step, and do not reinstate it because a change
|
||||||
is the whole point of the phase.
|
set looks claim-heavy: that judgement was already made against the measured cost,
|
||||||
|
which `AGENTS.md` D20 records in full. If a claim genuinely worries you, the
|
||||||
|
answer is a `TODO(pouya)` and a §9 question — the thing that blocks — not an
|
||||||
|
unscheduled audit.
|
||||||
|
|
||||||
|
Two things carry the claims risk between now and cutover, and neither is
|
||||||
|
optional: **`npm run check:claims` in Phase 5**, and **Pouya reading the copy as
|
||||||
|
it is built**.
|
||||||
|
|
||||||
|
**Give it the diff and the specs. Do not give it your reasoning for why the work
|
||||||
|
is correct.** Your rationale anchors the reviewer and produces agreement instead
|
||||||
|
of review. It forms its own view from the artefact; that independence is the
|
||||||
|
whole point of the phase.
|
||||||
|
|
||||||
### Scope — D19
|
### Scope — D19
|
||||||
|
|
||||||
Review is bounded. **In scope:** `dist/`, `src/`, the specs that direct copy
|
Review is bounded. **In scope:** `dist/`, `src/`, the specs that direct copy
|
||||||
(`docs/01`, `03`, `04`, `07`), and `AGENTS.md` §3, §4, §7, §9, §12. **Out of
|
(`docs/01`, `03`, `04`, `07`), and `AGENTS.md` §3, §4, §7, §9, §12. **Out of
|
||||||
scope:** the Change Log, the agents' own briefs, `AGENTS.md` prose outside those
|
scope:** the Change Log, the agents' own briefs, `AGENTS.md` prose outside those
|
||||||
sections, and the historical accuracy of code comments. Both briefs carry the
|
sections, and the historical accuracy of code comments. Both agent briefs carry
|
||||||
same boundary — do not widen it in the prompt.
|
the same boundary — do not widen it in the prompt. It binds the cutover claims
|
||||||
|
pass too, which is the one place `claims-auditor` still runs.
|
||||||
|
|
||||||
### The stop signal
|
### The stop signal
|
||||||
|
|
||||||
@@ -72,8 +84,9 @@ itself, and noticing it is part of the job — not a licence to skip the phase.
|
|||||||
The shape to watch for, from the session that produced D19: a Change Log sweep
|
The shape to watch for, from the session that produced D19: a Change Log sweep
|
||||||
that could not reproduce *because writing it changed the file it counted*.
|
that could not reproduce *because writing it changed the file it counted*.
|
||||||
|
|
||||||
If the change touches no user-facing copy, `claims-auditor` may be skipped — say
|
**The claims pass is deferred, not deleted.** Say which review ran in your
|
||||||
so explicitly.
|
report. "Reviewed" without naming the agent reads as both, and under D20 it is
|
||||||
|
one.
|
||||||
|
|
||||||
## Phase 4 — Resolve
|
## Phase 4 — Resolve
|
||||||
|
|
||||||
@@ -113,8 +126,10 @@ npm run check:claims
|
|||||||
```
|
```
|
||||||
|
|
||||||
`check:claims` greps the built pages for the §4 Forbidden set — Pouya's ruling,
|
`check:claims` greps the built pages for the §4 Forbidden set — Pouya's ruling,
|
||||||
2026-08-29. **Every pattern it catches is a finding neither review agent has to
|
2026-08-29. **Under D20 it is the only per-step claims control there is**, so
|
||||||
spend a pass on**, which is D19 served directly. It self-tests its own patterns
|
never skip it and never let a build ship on a stale `dist/`. It is a tripwire,
|
||||||
|
not a program: it catches the §4 breaches that are greppable and it makes no
|
||||||
|
claim about the ones that are not. It self-tests its own patterns
|
||||||
before it sweeps and refuses to run against an empty or stale `dist/`, so a pass
|
before it sweeps and refuses to run against an empty or stale `dist/`, so a pass
|
||||||
is a pass on the bytes that would ship. **A match is not yet a finding** — read
|
is a pass on the bytes that would ship. **A match is not yet a finding** — read
|
||||||
the context it prints. If a pattern is genuinely wrong, change it deliberately
|
the context it prints. If a pattern is genuinely wrong, change it deliberately
|
||||||
|
|||||||
@@ -10,13 +10,17 @@ Scope: $ARGUMENTS
|
|||||||
If no scope is given, review the uncommitted working tree (`git status`,
|
If no scope is given, review the uncommitted working tree (`git status`,
|
||||||
`git diff`).
|
`git diff`).
|
||||||
|
|
||||||
Invoke **both** agents in parallel on that scope:
|
Invoke **`adversarial-reviewer`** on that scope.
|
||||||
|
|
||||||
- `adversarial-reviewer`
|
**`claims-auditor` is not part of this command — D20, Pouya, 2026-08-30.** The
|
||||||
- `claims-auditor` — unless nothing user-facing changed, in which case say so
|
claims pass runs **once, at cutover**, over the whole finished site; `AGENTS.md`
|
||||||
|
D20 records the reasoning and the measured cost of deferring it. Run it here only
|
||||||
|
if Pouya asks for it by name in `$ARGUMENTS` — in which case say in the report
|
||||||
|
that it was run out of band, and against a draft rather than the finished site,
|
||||||
|
because that is the condition D20 says weakens it.
|
||||||
|
|
||||||
Give them the diff and the relevant specs from `docs/`. **Do not brief them on
|
Give it the diff and the relevant specs from `docs/`. **Do not brief it on why
|
||||||
why the code is correct** — that anchors the review and turns it into agreement.
|
the code is correct** — that anchors the review and turns it into agreement.
|
||||||
|
|
||||||
Report findings grouped by severity, most severe first. For each: the defect, the
|
Report findings grouped by severity, most severe first. For each: the defect, the
|
||||||
concrete failure it produces, and the fix. Do not fix anything yet — Pouya
|
concrete failure it produces, and the fix. Do not fix anything yet — Pouya
|
||||||
|
|||||||
@@ -128,8 +128,9 @@ without an explicit instruction and a Change Log entry. `[verified 2026-08-25]`
|
|||||||
| D14 | Fee structure | **Single published rate card, all mediation matters at one rate.** Confirmed by Pouya 2026-08-26; figures in `docs/07-fees.md`. No tribunal-secretary line | Two-tier card (recommended by Claude, declined); ranges; fees on request |
|
| D14 | Fee structure | **Single published rate card, all mediation matters at one rate.** Confirmed by Pouya 2026-08-26; figures in `docs/07-fees.md`. No tribunal-secretary line | Two-tier card (recommended by Claude, declined); ranges; fees on request |
|
||||||
| D15 | Analytics | **Plausible.** Privacy-first and cookieless: no cookie banner, nothing to consent to, one line in the privacy policy. *Amended 2026-08-26 (Q31):* the original read "Plausible **or** Fathom", i.e. undecided, and a guessed `'plausible'` had already leaked into `src/data/site.ts` from it. **Decided, not defaulted** — Pouya checked rather than assumed and found his own assumption wrong: Fathom is Canadian-owned, which is the intuitive answer here, but it stores non-EU traffic on **US servers** and isolates in the EU only for EU visitors. Plausible keeps all data in the EU. For a practice whose privacy posture is part of the offer, EU-only beats US-hosted, and ownership is not the axis that matters | GA4; no analytics at all; **Fathom** — rejected on data residency, not on quality |
|
| D15 | Analytics | **Plausible.** Privacy-first and cookieless: no cookie banner, nothing to consent to, one line in the privacy policy. *Amended 2026-08-26 (Q31):* the original read "Plausible **or** Fathom", i.e. undecided, and a guessed `'plausible'` had already leaked into `src/data/site.ts` from it. **Decided, not defaulted** — Pouya checked rather than assumed and found his own assumption wrong: Fathom is Canadian-owned, which is the intuitive answer here, but it stores non-EU traffic on **US servers** and isolates in the EU only for EU visitors. Plausible keeps all data in the EU. For a practice whose privacy posture is part of the offer, EU-only beats US-hosted, and ownership is not the axis that matters | GA4; no analytics at all; **Fathom** — rejected on data residency, not on quality |
|
||||||
| D18 | Intake email | **Two emails per submission** — notification to `info@smlcompany.ca`, and a **confirmation receipt to the inquirer**. Pouya, 2026-08-26. The receipt is what requires SES production access (Q19) | Notification only; no email; no form at all |
|
| D18 | Intake email | **Two emails per submission** — notification to `info@smlcompany.ca`, and a **confirmation receipt to the inquirer**. Pouya, 2026-08-26. The receipt is what requires SES production access (Q19) | Notification only; no email; no form at all |
|
||||||
| D17 | Working method | **Pouya architects; Claude Code implements and then adversarially reviews its own work.** Six-phase loop encoded in `.claude/commands/build.md`; two independent review agents in `.claude/agents/`; extended thinking on by default. Standing agreement — not restated per prompt | Implement-and-report; single generic reviewer; review only on request |
|
| D17 | Working method | **Pouya architects; Claude Code implements and then adversarially reviews its own work.** Six-phase loop encoded in `.claude/commands/build.md`; two independent review agents in `.claude/agents/`; extended thinking on by default. Standing agreement — not restated per prompt. ***Amended 2026-08-30 — see D20:*** *the per-step review is `adversarial-reviewer` **alone**. `claims-auditor` no longer runs per step; it runs **once, at cutover, over the whole finished site**. "Two independent review agents" now describes the project, not the step* | Implement-and-report; single generic reviewer; review only on request |
|
||||||
| D19 | Bounding the review loop | **Review scope is `dist/`, `src/`, the specs that direct copy (`docs/01`, `03`, `04`, `07`), and `AGENTS.md` §3, §4, §7, §9, §12. TWO ROUNDS IS THE CAP. Findings are blocking or should-fix, with a "consider" only where acting on it changes what ships. A non-gating observation is a Change Log note, not a numbered question. Comments record decisions, not history.** Pouya's ruling, 2026-08-28, on his own measurement: 48 findings across two rounds with most of round two being defects in round one's fixes; 342 lines added to `src/` for 8 functional; four findings that were stale statements inside comments written that same session; and a Change Log sweep that could not reproduce because writing it changed the file it counted. His words: *"Every one is a real defect — but they are defects in the record about the record, and that is infinite regress. My fault for never bounding scope."* **Out of scope: the Change Log, the agents' own briefs, `AGENTS.md` prose outside those five sections, and the historical accuracy of code comments.** A false statement in a Change Log entry is corrected when noticed; it does not get a review pass, because no visitor reads it. Swept into `.claude/agents/adversarial-reviewer.md`, `.claude/agents/claims-auditor.md`, `/build` Phases 2–4, `/wrap` and `CLAUDE.md` | Unbounded scope; a third round; reporting every "consider"; a numbered question per observation |
|
| D19 | Bounding the review loop | **Review scope is `dist/`, `src/`, the specs that direct copy (`docs/01`, `03`, `04`, `07`), and `AGENTS.md` §3, §4, §7, §9, §12. TWO ROUNDS IS THE CAP. Findings are blocking or should-fix, with a "consider" only where acting on it changes what ships. A non-gating observation is a Change Log note, not a numbered question. Comments record decisions, not history.** Pouya's ruling, 2026-08-28, on his own measurement: 48 findings across two rounds with most of round two being defects in round one's fixes; 342 lines added to `src/` for 8 functional; four findings that were stale statements inside comments written that same session; and a Change Log sweep that could not reproduce because writing it changed the file it counted. His words: *"Every one is a real defect — but they are defects in the record about the record, and that is infinite regress. My fault for never bounding scope."* **Out of scope: the Change Log, the agents' own briefs, `AGENTS.md` prose outside those five sections, and the historical accuracy of code comments.** A false statement in a Change Log entry is corrected when noticed; it does not get a review pass, because no visitor reads it. Swept into `.claude/agents/adversarial-reviewer.md`, `.claude/agents/claims-auditor.md`, `/build` Phases 2–4, `/wrap` and `CLAUDE.md`. ***Amended 2026-08-30 — see D20:*** *the two-round cap governs the **per-step code review**, which is now `adversarial-reviewer` alone. It does **not** govern the single cutover claims pass — that one runs until its findings are resolved, because there is no second pass behind it. A cap on rounds is not a licence to publish an unresolved claims finding* | Unbounded scope; a third round; reporting every "consider"; a numbered question per observation |
|
||||||
|
| D20 | Where the claims pass runs | **`claims-auditor` runs ONCE, at cutover, over the whole finished site — not per build step.** Per step: **`adversarial-reviewer` alone** — correctness, accessibility, crawlability, performance, security, simplicity — two rounds max, per D19. `npm run check:claims` is **unchanged**: it runs on every build and on both deploy paths. It is the mechanical floor and it stays. **Pouya reads the copy as it is built; that is the human pass.** *Recorded in full, because "we stopped running the compliance check" must read as a calibration decision and not as erosion.* **Why.** Nothing has shipped and there is no public site, so every claims finding to date has been about a page no visitor can reach — the entire risk is deferred to cutover, and auditing nine build steps and then re-auditing the fixes is auditing a draft nobody can read. A single pass over twenty finished pages will also catch **more** than nine passes over drafts, because it sees the site as a reader does: the `/med-arb/` ADRIC gloss is the proof — no individual claim was false, the defect was **adjacency**, and adjacency defects do not exist until the pages sit next to each other. The code reviewer stays per step because **what it catches compounds** — an accessibility or crawlability defect propagates into every page built on it. A claims defect does not compound; it sits there until someone reads it. **What this costs, recorded honestly so a later reader can weigh it.** `claims-auditor` has caught, among others: the struck false universal reaching a public page in the first person; a `<title>` reading *"Sole Arbitrator"*; *"Every award I issue"* on a practice with no completed arbitration; four breaches of the Q54 gate on the day it was written; the memberships currency warranty; and a §4 Verified row authorising exactly what D16 forbids. Those are real, and several are the class of thing that reads badly on the site of a person who holds a JD. Deferring the check to cutover accepts that such a defect may live in an unpublished draft for weeks. **It must not survive cutover** — `docs/06`'s checklist carries two blocking items for it, near the top, and nothing publishes until both are clean. Pouya's ruling, 2026-08-30. Swept to `CLAUDE.md`, `/build` Phase 3, `/review`, `.claude/agents/claims-auditor.md`, `docs/06` and `docs/08` | Per-step claims audit (the status quo — its cost is recorded above, not dismissed); dropping the claims pass entirely; relying on `check:claims` alone |
|
||||||
| D16 | Naming the boutique | **Never named.** Referred to throughout as *a Toronto litigation and ADR boutique*. Pouya's decision, 2026-08-26 | Naming the firm |
|
| D16 | Naming the boutique | **Never named.** Referred to throughout as *a Toronto litigation and ADR boutique*. Pouya's decision, 2026-08-26 | Naming the firm |
|
||||||
|
|
||||||
## 4. Credential and claim register
|
## 4. Credential and claim register
|
||||||
@@ -173,7 +174,7 @@ since May.
|
|||||||
| Q.Med designation through ADRIC / ADRIO | `[verified 2026-08-25 — strategy brief §I]` |
|
| Q.Med designation through ADRIC / ADRIO | `[verified 2026-08-25 — strategy brief §I]` |
|
||||||
| Has completed multiple sole mediations | `[verified 2026-08-25 — strategy brief §I]` — count deliberately not published, see below |
|
| Has completed multiple sole mediations | `[verified 2026-08-25 — strategy brief §I]` — count deliberately not published, see below |
|
||||||
| **Practised role — "Mediator"** | `[verified 2026-08-28 — Pouya, Q49]`. **The row `Person.jobTitle` stands on, and the ruling grants exactly one.** Pouya: *"one row: 'Mediator', supported by Q.Med plus completed sole mediations."* Both supports are rows immediately above. **"Arbitrator" as a practised role is still NOT a row** — §4 Offerings verifies that appointments are *accepted* and records no completed arbitration, which is why `claims-auditor` struck *"Mediator and Commercial Arbitrator"* from the same node's `description` on 2026-08-27. The arbitration **offering** is unaffected: `description` and `serviceType` both carry it. **Q49(b) is declined by the same ruling** — one row was granted and the corporate relation *"the entity the practice operates through"* was not it, so `worksFor` stays out of the graph. The row that does exist is *"Operator of SML Company Ltd. **alongside** the practice"*, a different structural relation |
|
| **Practised role — "Mediator"** | `[verified 2026-08-28 — Pouya, Q49]`. **The row `Person.jobTitle` stands on, and the ruling grants exactly one.** Pouya: *"one row: 'Mediator', supported by Q.Med plus completed sole mediations."* Both supports are rows immediately above. **"Arbitrator" as a practised role is still NOT a row** — §4 Offerings verifies that appointments are *accepted* and records no completed arbitration, which is why `claims-auditor` struck *"Mediator and Commercial Arbitrator"* from the same node's `description` on 2026-08-27. The arbitration **offering** is unaffected: `description` and `serviceType` both carry it. **Q49(b) is declined by the same ruling** — one row was granted and the corporate relation *"the entity the practice operates through"* was not it, so `worksFor` stays out of the graph. The row that does exist is *"Operator of SML Company Ltd. **alongside** the practice"*, a different structural relation |
|
||||||
| **Q.Arb — HELD** | `[verified 2026-08-29 — Pouya]`. **Obtained July 2026 — RECORDED HERE, NOT PUBLISHED.** His instruction: public copy carries **`Q.Arb (ADRIC / ADRIO)`** beside Q.Med and **nothing more** — no date, no acquisition story. ⚠️ **EVERY STAGE FORM IS STRUCK: "commenced", "in progress", "pathway", "not yet", and the "once/when I hold it" constructions.** This row read *"credentialing pathway — commenced August 2026"* `[verified 2026-08-26 — Pouya]` from 2026-08-26 until 2026-08-29, and every one of those words is now false in the **opposite** direction from the one this register normally guards — the site would be **understating** a held credential. Both directions are misdescription. ⚠️ **THE TWO DATES CANNOT BOTH BE TRUE, AND THIS ROW DOES NOT RECONCILE THEM — OPEN AS Q55.** The Change Log of **2026-08-26 (a)** records *"Q.Arb dated. Old → new: `[assumed]`, stage unknown → **commenced August 2026** `[verified 2026-08-26]`"* — Pouya's own report, three days before this one. **A designation cannot have been obtained in July from a pathway that commenced in August.** One of the two self-reports is wrong and the register cannot say which. **NOTHING PUBLISHED TURNS ON IT:** the site says *held*, which is his ruling either way, and the date is not published — so this does not block. It is flagged because §4's whole function is that a stamped claim is checkable, and this one is contradicted on the face of the record. Found by `claims-auditor` 2026-08-30. **The Forbidden row against "held, imminent, nearly complete" is struck with it** |
|
| **Q.Arb — HELD** | **The stamp is SPLIT, deliberately, and Pouya ratified the split on 2026-08-30.** Status: `[verified 2026-08-29 — Pouya]` — he holds it. Date: **Obtained July 2026** `[Pouya's stated basis 2026-08-29]` — the register vouches only for what he stated, never for the date itself, because it holds contrary evidence (below). **THE DATE IS RECORDED HERE AND NOT PUBLISHED.** His instruction: public copy carries **`Q.Arb (ADRIC / ADRIO)`** beside Q.Med and **nothing more** — no date, no acquisition story. ⚠️ **EVERY STAGE FORM IS STRUCK: "commenced", "in progress", "pathway", "not yet", and the "once/when I hold it" constructions.** This row read *"credentialing pathway — commenced August 2026"* `[verified 2026-08-26 — Pouya]` from 2026-08-26 until 2026-08-29, and every one of those words is now false in the **opposite** direction from the one this register normally guards — the site would be **understating** a held credential. Both directions are misdescription. ⚠️ **THE TWO DATES CANNOT BOTH BE TRUE, AND THIS ROW DOES NOT RECONCILE THEM — Q55, CLOSED UNRESOLVED 2026-08-30.** The Change Log of **2026-08-26 (a)** records *"Q.Arb dated. Old → new: `[assumed]`, stage unknown → **commenced August 2026** `[verified 2026-08-26]`"* — Pouya's own report, three days before this one. **A designation cannot have been obtained in July from a pathway that commenced in August.** One of the two self-reports is wrong and the register cannot say which. **NOTHING PUBLISHED TURNS ON IT:** the site says *held*, which is his ruling either way, and the date is not published — so this does not block. It is flagged because §4's whole function is that a stamped claim is checkable, and this one is contradicted on the face of the record. Found by `claims-auditor` 2026-08-30 and **closed the same day without being resolved — Pouya's ruling, and the distinction is the point.** *"The date is not published and nothing depends on it. A register that says 'two inconsistent reports of an unpublished fact, neither relied on' is complete."* So: the 2026-08-26 (a) Change Log report of *commenced August 2026* stands **UNRECONCILED**, permanently and on purpose. **Do not reconcile it by inference, do not re-stamp it, and do not put it back to Pouya** — it was closed by the architect, not left open. What makes the closure safe is the split stamp above: nothing in this register or on the site rests on the date. **The Forbidden row against "held, imminent, nearly complete" is struck with it** |
|
||||||
| ~~C.Med-Arb stated as long-term designation goal~~ | **STRUCK 2026-08-29 — Pouya. `C.MED-ARB IS OUT ENTIRELY`, and it must not be reinstated from the strategy brief**, which made it *"the explicit long-term professional narrative"*. **This is a deliberate deviation from the brief and it is recorded as one** — see the Change Log entry of 2026-08-30 (ad). His reasoning: *"Pouya holds Q.Med and Q.Arb, which is what med-arb requires. The page says he conducts med-arb and stops."* **The designation is still real and stays in §11 as a DEFINITION** — what is struck is its status as a published goal *of his*. Superseded `[verified 2026-08-25 — strategy brief §I, §IV]` |
|
| ~~C.Med-Arb stated as long-term designation goal~~ | **STRUCK 2026-08-29 — Pouya. `C.MED-ARB IS OUT ENTIRELY`, and it must not be reinstated from the strategy brief**, which made it *"the explicit long-term professional narrative"*. **This is a deliberate deviation from the brief and it is recorded as one** — see the Change Log entry of 2026-08-30 (ad). His reasoning: *"Pouya holds Q.Med and Q.Arb, which is what med-arb requires. The page says he conducts med-arb and stops."* **The designation is still real and stays in §11 as a DEFINITION** — what is struck is its status as a published goal *of his*. Superseded `[verified 2026-08-25 — strategy brief §I, §IV]` |
|
||||||
| Kompass Arbitration Certificate Program — completed | `[verified 2026-08-25 — strategy brief §I]` |
|
| Kompass Arbitration Certificate Program — completed | `[verified 2026-08-25 — strategy brief §I]` |
|
||||||
| Stitt Feld Handy negotiation and ADR workshop sequence — completed | `[verified 2026-08-25 — strategy brief §I]` |
|
| Stitt Feld Handy negotiation and ADR workshop sequence — completed | `[verified 2026-08-25 — strategy brief §I]` |
|
||||||
@@ -398,8 +399,8 @@ never be read as one:
|
|||||||
|
|
||||||
| Offering | Status |
|
| Offering | Status |
|
||||||
|---|---|
|
|---|---|
|
||||||
| **Mediation** — sole mediator | `[verified 2026-08-26 — Pouya]`. Q.Med held; §4 also verifies multiple completed sole mediations |
|
| **Mediation** — sole mediator | `[verified 2026-08-26 — Pouya]`. Q.Med held; §4 also verifies multiple completed sole mediations. ⚠️ **UNSCOPED, AND DELIBERATELY SO — Q56, ruled by Pouya 2026-08-30. Do not add "commercial" to this row, and do not scope it on a page.** He mediates commercial, construction, insurance/SABS, shareholder and cross-cultural matters, and the practice pages say so. ⚠️ **THAT LIST IS ILLUSTRATIVE OF BREADTH, NOT A CLOSED SET, and it is not the authorised subject-matter list** — Q35's gate governs that, and the site publishes **six** areas of which every one offers mediation (`src/data/practice-pages.ts`), **technology and energy included**. Read as an enumeration it is short by two, and a later reader would strike two live pages or open a question that did not need opening. Flagged to Pouya rather than rewritten, because the words are his ruling. Raised by `adversarial-reviewer`, 2026-08-30. **Why this row and the arbitration row below do not match, so the asymmetry reads as designed rather than as an oversight:** arbitration is scoped commercial because of a **legal gate** — Q39, family arbitration in Ontario requires prescribed training. **Mediation has no such gate.** The site said *"Commercial Mediation"* on four surfaces until 2026-08-30; that was under-describing the offering, and it was corrected rather than ratified |
|
||||||
| **Arbitration — sole arbitrator** (commercial) | `[verified 2026-08-26 — Pouya, Q33/Q36]`. Offered **now**. Not gated by Q.Arb. **Commercial**, and the scope is now load-bearing rather than provisional: Q39 closed 2026-08-27 and **family arbitration is excluded by Pouya's choice** — see the row below |
|
| **Arbitration — sole arbitrator** (commercial) | `[verified 2026-08-26 — Pouya, Q33/Q36]`. Offered **now**. Not gated by Q.Arb. **Commercial**, and the scope is now load-bearing rather than provisional: Q39 closed 2026-08-27 and **family arbitration is excluded by Pouya's choice** — see the row below. ⚠️ **THE SCOPE IS A LEGAL GATE, NOT A POSITIONING CHOICE — Q56, 2026-08-30.** Family arbitration in Ontario requires prescribed training, which is why this word is load-bearing here and **must not be copied onto the mediation row above**: mediation has no equivalent gate and is unscoped on purpose |
|
||||||
| **Arbitration — party-appointed** | `[verified 2026-08-26 — Pouya, Q33/Q36]`. Offered **now** |
|
| **Arbitration — party-appointed** | `[verified 2026-08-26 — Pouya, Q33/Q36]`. Offered **now** |
|
||||||
| **Arbitration — co-arbitration** | `[verified 2026-08-26 — Pouya, Q33/Q36]`. Offered **now**. This closes Q36, which had flagged the claim as asserted in three specs and resting on no §4 row — the row is here |
|
| **Arbitration — co-arbitration** | `[verified 2026-08-26 — Pouya, Q33/Q36]`. Offered **now**. This closes Q36, which had flagged the claim as asserted in three specs and resting on no §4 row — the row is here |
|
||||||
| **Med-Arb** — mediation-arbitration | `[verified 2026-08-27 — Pouya, Q35]`. Offered **now**. Both halves are live: Q.Med is held, and arbitration appointments are accepted (rows above). Ungated by the same reasoning as arbitration. This closes the "Still unanswered" note that used to sit below this table, and it is why `/med-arb/` may stay in the footer sitemap |
|
| **Med-Arb** — mediation-arbitration | `[verified 2026-08-27 — Pouya, Q35]`. Offered **now**. Both halves are live: Q.Med is held, and arbitration appointments are accepted (rows above). Ungated by the same reasoning as arbitration. This closes the "Still unanswered" note that used to sit below this table, and it is why `/med-arb/` may stay in the footer sitemap |
|
||||||
@@ -607,10 +608,10 @@ do not re-open it against the quoted ruling above.**
|
|||||||
|
|
||||||
| Undertaking | Where it ships | Status |
|
| Undertaking | Where it ships | Status |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| **(a) Med-arb — the switch.** *"The switch is agreed in writing before the mediation phase begins, or I do not take the appointment. I will not convert a mediation into an arbitration on the day because the room has run out of road."* | `/med-arb/` §What I undertake | `[verified 2026-08-29 — Pouya, Q54]` |
|
| **(a) Med-arb — the switch.** *"The switch is agreed in writing before the mediation phase begins, or I do not take the appointment. I will not convert a mediation into an arbitration on the day because the room has run out of road."* | `/med-arb/` §What I undertake **and `/process/` §If it does not settle** (added 2026-08-30, build step 6 — it is the answer to the question that section exists to answer, and it is rendered from the constant, not retyped) | `[verified 2026-08-29 — Pouya, Q54]` |
|
||||||
| **(b) Med-arb — caucus material.** *"If a party tells me something in caucus they are not prepared for me to rely on as arbitrator, they say so at the time, and it does not enter the arbitral record."* | `/med-arb/` §What I undertake | `[verified 2026-08-29 — Pouya, Q54]` |
|
| **(b) Med-arb — caucus material.** *"If a party tells me something in caucus they are not prepared for me to rely on as arbitrator, they say so at the time, and it does not enter the arbitral record."* | `/med-arb/` §What I undertake | `[verified 2026-08-29 — Pouya, Q54]` |
|
||||||
| **(c) Med-arb — the hard one.** *"If I cannot decide a remaining issue without relying on something said to me in confidence, I say so and step out of the arbitral phase rather than decide on it."* | `/med-arb/` §What I undertake | `[verified 2026-08-29 — Pouya, Q54]`. **SHIPS AS DRAFTED, and this row carries his reasoning because it is the only one that cost anything to make.** *"It is the strongest available answer to the med-arb objection, and cheaper in practice than it sounds — the arbitral phase runs on the evidentiary record, not the caucus, so the case where a neutral genuinely cannot decide without confidential material is uncommon. `/med-arb/` was raising the hardest question about med-arb and answering it only at the level of process design."* Q54 warned that *"a neutral who would not honour it must not publish it"*; he published it. **This is the row where softening would be worst and least visible** — a version that says he "may" step out, or that he "considers" stepping out, is a different commitment wearing the same words |
|
| **(c) Med-arb — the hard one.** *"If I cannot decide a remaining issue without relying on something said to me in confidence, I say so and step out of the arbitral phase rather than decide on it."* | `/med-arb/` §What I undertake | `[verified 2026-08-29 — Pouya, Q54]`. **SHIPS AS DRAFTED, and this row carries his reasoning because it is the only one that cost anything to make.** *"It is the strongest available answer to the med-arb objection, and cheaper in practice than it sounds — the arbitral phase runs on the evidentiary record, not the caucus, so the case where a neutral genuinely cannot decide without confidential material is uncommon. `/med-arb/` was raising the hardest question about med-arb and answering it only at the level of process design."* Q54 warned that *"a neutral who would not honour it must not publish it"*; he published it. **This is the row where softening would be worst and least visible** — a version that says he "may" step out, or that he "considers" stepping out, is a different commitment wearing the same words |
|
||||||
| **(d) Mediation — caucus confidentiality.** *"What a party tells me in caucus stays in that caucus until they tell me I may use it, and I do not carry a number across the hall that I was not given to carry."* | `/mediation/` §Confidentiality | `[verified 2026-08-29 — Pouya, Q54]`. Shipped for one pass at step 4 and removed by `claims-auditor` — correctly: the gate had been applied to `/med-arb/` in the same change set and not one file over. It is here now because it is answered, not because the gate relaxed |
|
| **(d) Mediation — caucus confidentiality.** *"What a party tells me in caucus stays in that caucus until they tell me I may use it, and I do not carry a number across the hall that I was not given to carry."* | `/mediation/` §Confidentiality, **`/process/` §Confidentiality, and `/for-parties/` §Questions** — the last both visibly and inside that page's `FAQPage` node (all added 2026-08-30, build step 6). **Three surfaces.** The row recorded two for one pass; `adversarial-reviewer` found the third, and an incomplete "where it ships" on the one class Pouya flagged as failing *silently* is this column doing the opposite of its job | `[verified 2026-08-29 — Pouya, Q54]`. Shipped for one pass at step 4 and removed by `claims-auditor` — correctly: the gate had been applied to `/med-arb/` in the same change set and not one file over. It is here now because it is answered, not because the gate relaxed |
|
||||||
| **(e) Arbitration — procedure.** *"I will not run a process whose shape nobody agreed to in advance."* | `/arbitration/` §Rules | `[verified 2026-08-29 — Pouya, Q54]`. Same one-pass history as (d). **It REPLACED a third-person sentence rather than joining it** — the page already ended that paragraph *"What does not is a process whose shape nobody agreed to in advance"*, the observation form of the same proposition, and keeping both would have set the undertaking beside its own paraphrase |
|
| **(e) Arbitration — procedure.** *"I will not run a process whose shape nobody agreed to in advance."* | `/arbitration/` §Rules | `[verified 2026-08-29 — Pouya, Q54]`. Same one-pass history as (d). **It REPLACED a third-person sentence rather than joining it** — the page already ended that paragraph *"What does not is a process whose shape nobody agreed to in advance"*, the observation form of the same proposition, and keeping both would have set the undertaking beside its own paraphrase |
|
||||||
| **(f) Arbitration — the award date.** *"The date the award is due is fixed in the first procedural order rather than left open."* | `/arbitration/` §Awards | `[verified 2026-08-29 — Pouya, Q54]`. Same replacement as (e), of *"The date an award is due belongs in the first procedural order"*. **The sentence after it is unchanged and is doing different work:** *"No number is published here"* is §4 Forbidden's bar on a time-to-award statistic, which is not what this undertaking is |
|
| **(f) Arbitration — the award date.** *"The date the award is due is fixed in the first procedural order rather than left open."* | `/arbitration/` §Awards | `[verified 2026-08-29 — Pouya, Q54]`. Same replacement as (e), of *"The date an award is due belongs in the first procedural order"*. **The sentence after it is unchanged and is doing different work:** *"No number is published here"* is §4 Forbidden's bar on a time-to-award statistic, which is not what this undertaking is |
|
||||||
|
|
||||||
@@ -650,7 +651,7 @@ cannot vouch for.
|
|||||||
| Guarantees of outcome, or superlatives ("best", "leading", "top-rated") | Unverifiable as written, and they read as insecure to the audience this site is for. Marketing rules for regulated professions also treat them as suspect. *(Reason restated 2026-08-26: this row previously read "LSO marketing rules", which asserts the regulatory status the row above marks NOT ESTABLISHED. It was the last surviving instance, flagged in entries (o) and (q) and answered in Q26 as already fixed — it was not. **Restated by Claude Code; the rule itself is unchanged and the restatement needs Pouya's ratification.**)* |
|
| Guarantees of outcome, or superlatives ("best", "leading", "top-rated") | Unverifiable as written, and they read as insecure to the audience this site is for. Marketing rules for regulated professions also treat them as suspect. *(Reason restated 2026-08-26: this row previously read "LSO marketing rules", which asserts the regulatory status the row above marks NOT ESTABLISHED. It was the last surviving instance, flagged in entries (o) and (q) and answered in Q26 as already fixed — it was not. **Restated by Claude Code; the rule itself is unchanged and the restatement needs Pouya's ratification.**)* |
|
||||||
| The word **"lawyer"** used of Pouya; "called to the bar"; "licensed"; "my law practice"; "my litigation practice"; any post-nominal implying a licence | D13. The site asserts the JD and nothing further |
|
| The word **"lawyer"** used of Pouya; "called to the bar"; "licensed"; "my law practice"; "my litigation practice"; any post-nominal implying a licence | D13. The site asserts the JD and nothing further |
|
||||||
| Any phrasing that *implies* entitlement to practise law without saying so — "acts for clients", "represents parties", "my clients", "legal advice" | Same rule. Implication is the risk, not just the word. Describe the role factually instead: *Director of Firm Operations at a Toronto litigation and ADR boutique*, and the matter types worked on |
|
| Any phrasing that *implies* entitlement to practise law without saying so — "acts for clients", "represents parties", "my clients", "legal advice" | Same rule. Implication is the risk, not just the word. Describe the role factually instead: *Director of Firm Operations at a Toronto litigation and ADR boutique*, and the matter types worked on |
|
||||||
| **Q.Arb described as commenced, in progress, a pathway, or not yet held** | **It is HELD** `[verified 2026-08-29 — Pouya]`. Publish `Q.Arb (ADRIC / ADRIO)`. **The acquisition date is recorded in §4 and is NOT published** — and it is itself open (Q55). `npm run check:claims` `q-arb-as-a-stage` enforces the stage words and a date near the designation, on `dist/` |
|
| **Q.Arb described as commenced, in progress, a pathway, or not yet held** | **It is HELD** `[verified 2026-08-29 — Pouya]`. Publish `Q.Arb (ADRIC / ADRIO)`. **The acquisition date is recorded in §4 and is NOT published** — and it is itself contradicted on the record and deliberately left that way (Q55, closed unresolved 2026-08-30). `npm run check:claims` `q-arb-as-a-stage` enforces the stage words and a date near the designation, on `dist/` |
|
||||||
| ~~Q.Arb described as held, imminent, or "nearly complete"~~ | **STRUCK 2026-08-29 — Q.ARB IS HELD.** This row was correct from 2026-08-26 to 2026-08-29 and is now exactly backwards. **What replaces it is the opposite bar:** Q.Arb described as *commenced*, *in progress*, *a pathway*, or *not yet held* — see the Verified row. The publishable form is `Q.Arb (ADRIC / ADRIO)`; the acquisition date is recorded in §4 and is **not** published |
|
| ~~Q.Arb described as held, imminent, or "nearly complete"~~ | **STRUCK 2026-08-29 — Q.ARB IS HELD.** This row was correct from 2026-08-26 to 2026-08-29 and is now exactly backwards. **What replaces it is the opposite bar:** Q.Arb described as *commenced*, *in progress*, *a pathway*, or *not yet held* — see the Verified row. The publishable form is `Q.Arb (ADRIC / ADRIO)`; the acquisition date is recorded in §4 and is **not** published |
|
||||||
|
|
||||||
### The substitution principle
|
### The substitution principle
|
||||||
@@ -702,8 +703,8 @@ the audience it targets. Revisit at month 12–18. `[verified 2026-08-25 — dec
|
|||||||
| Thing | Value |
|
| Thing | Value |
|
||||||
|---|---|
|
|---|---|
|
||||||
| Framework | **Astro 7.2.9**, `output: 'static'` `[verified 2026-08-27 — npm view astro version, D1 as amended]`. `@astrojs/mdx` 7.0.8, `@astrojs/sitemap` 3.7.3, `sharp` 0.35.4 — all three at `latest`. Bumped from 7.2.7 at the step 1 → step 2 phase boundary under R11: 7.2.8 published 2026-08-26 and 7.2.9 on 2026-08-27, i.e. **two patches appeared inside 48 hours**, which is the argument for checking at boundaries rather than on failure. `engines` unchanged at `node >=22.12.0`, `npm >=9.6.5` `[verified 2026-08-27 — npm view astro@7.2.9 engines]` |
|
| Framework | **Astro 7.2.9**, `output: 'static'` `[verified 2026-08-27 — npm view astro version, D1 as amended]`. `@astrojs/mdx` 7.0.8, `@astrojs/sitemap` 3.7.3, `sharp` 0.35.4 — all three at `latest`. Bumped from 7.2.7 at the step 1 → step 2 phase boundary under R11: 7.2.8 published 2026-08-26 and 7.2.9 on 2026-08-27, i.e. **two patches appeared inside 48 hours**, which is the argument for checking at boundaries rather than on failure. `engines` unchanged at `node >=22.12.0`, `npm >=9.6.5` `[verified 2026-08-27 — npm view astro@7.2.9 engines]` |
|
||||||
| **TypeScript — HELD at 6.x, and the hold is a peer constraint rather than a preference** | Pinned `^6.0.3`; `npm view typescript version` returns **7.0.2** `[verified 2026-08-29 — R11, step 4 → 5 phase boundary]`. **One major behind, which is the exact shape D1 was amended over — so the reason is recorded rather than the hold being silent.** `@astrojs/check@0.9.10` declares `peerDependencies: { typescript: '^5.0.0 \|\| ^6.0.0' }` `[verified 2026-08-29 — npm view @astrojs/check@0.9.10 peerDependencies]`, and `npm run check` is `astro check`, which is the type gate the deploy path runs before it builds. **Removal trigger: `@astrojs/check` widens the range to include 7.** Re-check at every phase boundary under R11 — this is a hold on a dependency's schedule, not on a judgement, so it lifts without a decision |
|
| **TypeScript — HELD at 6.x, and the hold is a peer constraint rather than a preference** | Pinned `^6.0.3`; `npm view typescript version` returns **7.0.2** `[verified 2026-08-30 — R11, step 5 → 6 phase boundary; unchanged from 2026-08-29]`. **The removal trigger was re-checked rather than recalled:** `npm view @astrojs/check@0.9.10 peerDependencies` still returns `{ typescript: '^5.0.0 || ^6.0.0' }`, so the hold stands. **One major behind, which is the exact shape D1 was amended over — so the reason is recorded rather than the hold being silent.** `@astrojs/check@0.9.10` declares `peerDependencies: { typescript: '^5.0.0 \|\| ^6.0.0' }` `[verified 2026-08-29 — npm view @astrojs/check@0.9.10 peerDependencies]`, and `npm run check` is `astro check`, which is the type gate the deploy path runs before it builds. **Removal trigger: `@astrojs/check` widens the range to include 7.** Re-check at every phase boundary under R11 — this is a hold on a dependency's schedule, not on a judgement, so it lifts without a decision |
|
||||||
| Lint toolchain | ESLint **10.9.1**, `@eslint/js` 10.0.1, `globals` 17.11.0, `eslint-plugin-astro` **3.1.0**, `eslint-plugin-jsx-a11y` 6.10.2, `typescript-eslint` 8.68.0, `typescript` **6.0.3** — **every pin at the registry's `latest` except `typescript`** `[verified 2026-08-27 — npm view, all 14 pins]`. `@eslint/js` and `globals` are declared explicitly; before 2026-08-26 `eslint.config.js` imported them and they resolved only by npm hoisting accident. **Accessibility linting is on** — `flat/jsx-a11y-recommended`, 36 rules `[verified 2026-08-26 — 7 rules fired on a deliberately inaccessible .astro file]`. `eslint-plugin-jsx-a11y@6.10.2` declares a stale `eslint ^3..^9` peer range; a one-line `overrides` entry in `package.json` resolves it. ⚠️ **`eslint-plugin-astro@3.1.0` declares `node ^22.22.3 \|\| ^24.16.0 \|\| >=26.3.0`**, which excludes Pouya's Node 25.6.0 — `npm install` prints EBADENGINE there. Dev-time only, and `nvm use` (Node 22 LTS, per `.nvmrc`) clears it. **`typescript` — the hold, and it was too wide by a whole major until 2026-08-27.** `latest` is **7.0.2** and it is unusable here: `typescript-eslint@8.68.0` peers `typescript >=4.8.4 <6.1.0` and `@astrojs/check@0.9.10` peers `^5.0.0 \|\| ^6.0.0`, so taking 7 breaks **both** the linter and `astro check` `[verified 2026-08-27 — npm view <pkg> peerDependencies]`. **But this row previously read "held at 5.x", and 6.0.3 is a stable release both peers accept** — so the pin sat a full major behind for no reason the record could name, in a row whose whole job is to name the reason. Now at **6.0.3**, the newest version compatible with both peers; `npx tsc --version` reports 6.0.3 and the full gate is green `[verified 2026-08-27]`. The 6.x listing is mostly `-dev` and `-beta` tags; **6.0.2 and 6.0.3 are the only stable 6.x releases**, which is why `npm view typescript version` (7.0.2) is not the number to pin against here. Re-check at the next phase boundary: the hold ends when `typescript-eslint` widens its peer range past `<6.1.0` |
|
| Lint toolchain | ESLint **10.9.1**, `@eslint/js` 10.0.1, `globals` 17.11.0, `eslint-plugin-astro` **3.1.0**, `eslint-plugin-jsx-a11y` 6.10.2, `typescript-eslint` 8.68.0, `typescript` **6.0.3** — **every pin at the registry's `latest` except `typescript`** `[verified 2026-08-30 — npm view, all 14 pins, R11 at the step 5 → 6 boundary; thirteen current, one held]`. `@eslint/js` and `globals` are declared explicitly; before 2026-08-26 `eslint.config.js` imported them and they resolved only by npm hoisting accident. **Accessibility linting is on** — `flat/jsx-a11y-recommended`, 36 rules `[verified 2026-08-26 — 7 rules fired on a deliberately inaccessible .astro file]`. `eslint-plugin-jsx-a11y@6.10.2` declares a stale `eslint ^3..^9` peer range; a one-line `overrides` entry in `package.json` resolves it. ⚠️ **`eslint-plugin-astro@3.1.0` declares `node ^22.22.3 \|\| ^24.16.0 \|\| >=26.3.0`**, which excludes Pouya's Node 25.6.0 — `npm install` prints EBADENGINE there. Dev-time only, and `nvm use` (Node 22 LTS, per `.nvmrc`) clears it. **`typescript` — the hold, and it was too wide by a whole major until 2026-08-27.** `latest` is **7.0.2** and it is unusable here: `typescript-eslint@8.68.0` peers `typescript >=4.8.4 <6.1.0` and `@astrojs/check@0.9.10` peers `^5.0.0 \|\| ^6.0.0`, so taking 7 breaks **both** the linter and `astro check` `[verified 2026-08-27 — npm view <pkg> peerDependencies]`. **But this row previously read "held at 5.x", and 6.0.3 is a stable release both peers accept** — so the pin sat a full major behind for no reason the record could name, in a row whose whole job is to name the reason. Now at **6.0.3**, the newest version compatible with both peers; `npx tsc --version` reports 6.0.3 and the full gate is green `[verified 2026-08-27]`. The 6.x listing is mostly `-dev` and `-beta` tags; **6.0.2 and 6.0.3 are the only stable 6.x releases**, which is why `npm view typescript version` (7.0.2) is not the number to pin against here. Re-check at the next phase boundary: the hold ends when `typescript-eslint` widens its peer range past `<6.1.0` |
|
||||||
| Lighthouse CI | **Not installed, and that is now stated wherever the check is claimed.** `@lhci/cli` was the sole source of all 10 `npm audit` findings (7 high, via `lighthouse → puppeteer-core → extract-zip`), 0.15.1 is `latest` so there was no clean upgrade, and it cannot run at all — no pages, no `lighthouserc`. Removed 2026-08-26; **`npm audit` now reports 0 vulnerabilities** `[verified 2026-08-26 — npm audit]`. Removing it left a **documented control that no longer exists** — `docs/04`, `CLAUDE.md` and `/build` Phase 5 all required a run that had silently become impossible, which is Q22's defect in a different costume. Fixed 2026-08-26: the unavailability is stated in `docs/04-seo-spec.md` (budget table, the callout under Performance, and the post-launch checklist), `CLAUDE.md` (performance budget and the definition of done), `.claude/commands/build.md` Phase 5, `docs/06-deployment.md` (PR checks and the cutover checklist), and `.claude/agents/adversarial-reviewer.md` §4 — which is also told **not** to raise the absence as a finding. **Re-add at build step 7** with a pin verified that day and a check for a patched release; do not assume 0.15.1 is still the ceiling (R11) |
|
| Lighthouse CI | **Not installed, and that is now stated wherever the check is claimed.** `@lhci/cli` was the sole source of all 10 `npm audit` findings (7 high, via `lighthouse → puppeteer-core → extract-zip`), 0.15.1 is `latest` so there was no clean upgrade, and it cannot run at all — no pages, no `lighthouserc`. Removed 2026-08-26; **`npm audit` now reports 0 vulnerabilities** `[verified 2026-08-26 — npm audit]`. Removing it left a **documented control that no longer exists** — `docs/04`, `CLAUDE.md` and `/build` Phase 5 all required a run that had silently become impossible, which is Q22's defect in a different costume. Fixed 2026-08-26: the unavailability is stated in `docs/04-seo-spec.md` (budget table, the callout under Performance, and the post-launch checklist), `CLAUDE.md` (performance budget and the definition of done), `.claude/commands/build.md` Phase 5, `docs/06-deployment.md` (PR checks and the cutover checklist), and `.claude/agents/adversarial-reviewer.md` §4 — which is also told **not** to raise the absence as a finding. **Re-add at build step 7** with a pin verified that day and a check for a patched release; do not assume 0.15.1 is still the ceiling (R11) |
|
||||||
| Node | **22 LTS line**, `.nvmrc` holds `22` so it tracks the latest 22.x rather than freezing at a floor. `package.json` declares **`engines.node` = `^22.13.0 || >=24`** (verbatim — it excludes Node 23, an EOL odd line, which a flat `>=22.13.0` would have admitted) and **`engines.npm >=9.6.5`** — the intersection of every dependency's own floor: Astro 7 and `@astrojs/mdx` 7 need `>=22.12.0`, ESLint 10 needs `^20.19.0 \|\| ^22.13.0 \|\| >=24` `[verified 2026-08-26 — npm view astro@7.2.7 engines, npm view eslint@10.9.1 engines]`. **Pouya's machine reports Node v25.6.0** `[verified 2026-08-26 — node -v]`, an odd-numbered non-LTS line; it satisfies the floor, but `nvm use` keeps local and CI on the same runtime |
|
| Node | **22 LTS line**, `.nvmrc` holds `22` so it tracks the latest 22.x rather than freezing at a floor. `package.json` declares **`engines.node` = `^22.13.0 || >=24`** (verbatim — it excludes Node 23, an EOL odd line, which a flat `>=22.13.0` would have admitted) and **`engines.npm >=9.6.5`** — the intersection of every dependency's own floor: Astro 7 and `@astrojs/mdx` 7 need `>=22.12.0`, ESLint 10 needs `^20.19.0 \|\| ^22.13.0 \|\| >=24` `[verified 2026-08-26 — npm view astro@7.2.7 engines, npm view eslint@10.9.1 engines]`. **Pouya's machine reports Node v25.6.0** `[verified 2026-08-26 — node -v]`, an odd-numbered non-LTS line; it satisfies the floor, but `nvm use` keeps local and CI on the same runtime |
|
||||||
| Styling | Plain CSS with custom properties. No Tailwind, no CSS-in-JS `[verified 2026-08-25]` |
|
| Styling | Plain CSS with custom properties. No Tailwind, no CSS-in-JS `[verified 2026-08-25]` |
|
||||||
@@ -770,8 +771,10 @@ Nothing below can be invented. Each needs an answer from Pouya.
|
|||||||
|
|
||||||
| # | Question | Blocks |
|
| # | Question | Blocks |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| **Q56** | ⚠️ **IS THE MEDIATION OFFERING SCOPED COMMERCIAL, OR NOT? THE SITE SAYS BOTH.** §4 Offerings rows arbitration three times, each **scoped commercial**; the mediation row is `**Mediation** — sole mediator`, **unscoped**. Shipped output scopes it anyway: `/mediation/`'s `<title>` is *"Commercial Mediation"*, its `Service` node is `name: "Commercial mediation"`, and `/` and `/about/` both say *"I mediate commercial disputes"*. Meanwhile **`/practice/insurance/` offers mediation in matters that are not commercial on any ordinary reading** — *"Disputes between an insured person and an insurer under the Statutory Accident Benefits Schedule"*, with *"What I offer is private mediation"*. An individual claimant against their own insurer is not a commercial dispute. **Nothing here is a false claim** — scoping a page to commercial mediation asserts *less* than the unscoped §4 row grants, and narrower than the row is always safe. **The problem is that the two halves cannot both be the whole picture**: either the practice takes non-commercial mediations (and the site-wide "commercial" framing under-describes it, including on the page an appointing body reads), or it does not (and `/practice/insurance/` is offering something outside the offering). **What is needed:** either a §4 Offerings row scoping mediation, with `/practice/insurance/`'s SABS framing reconciled to it — or a decision that mediation is deliberately unscoped, in which case the site-wide "commercial" wording is a positioning choice and should be recorded as one rather than read as a limit. **Pre-existing, not created 2026-08-30** — but this change set newly wrote the claim onto `/med-arb/` and it has been removed again pending this answer. Raised by `adversarial-reviewer`, 2026-08-30 | **Nothing at present.** No page is wrong; the register is silent where the site is specific |
|
| **Q58** | **DOES `hours` IN THE MEDIATION RATE CARD MEAN THE LENGTH OF THE DAY, OR THE BILLED ENVELOPE INCLUDING PREPARATION?** `docs/07-fees.md` reads *"Half day — **up to 3.5 h, including 2 h preparation**"* and *"Full day — up to 7 h, including 3 h preparation"*. Taken at face value, 3.5 is the whole billed envelope and the **time in the room is 1.5 h** for a half day and **4 h** for a full day. **Against that reading:** 3.5 and 7 are exactly 2×, which they would not be if preparation sat inside them (1.5 vs 4 is not 2×). So either the card's wording is wrong in the one document that is the authority on money, or `FEES.mediation.*.hours` in `src/data/site.ts` does not mean what a page would naturally publish it as. **This was one sentence from shipping.** A draft of `/for-parties/` answered *"What happens on the day?"* with *"A half day is about 3.5 hours"* — the envelope presented as the day, to the reader least able to check it. The sentence was removed rather than resolved by inference; the page now says only that you book a half day or a full day. **What is needed:** one line from Pouya saying which the 3.5 and 7 are. Then `docs/07`'s two rows or `site.ts`'s field gains the correction, and the semantics go in the constant's doc comment (a warning is there now). **`/fees/` at build step 9 publishes this table and cannot be built without the answer.** Raised by `adversarial-reviewer`, 2026-08-30 | **`/fees/` (step 9), and any sentence anywhere stating how long a mediation day is.** Nothing currently shipping — no page states a duration |
|
||||||
| **Q55** | ⚠️ **WHEN WAS Q.Arb ACTUALLY OBTAINED? THE REGISTER HOLDS TWO DATES FROM THE SAME SOURCE AND THEY CANNOT BOTH BE TRUE.** (a) **2026-08-26 (a)**, Change Log, `[verified 2026-08-26]`: *"Q.Arb dated. Old → new: `[assumed]`, stage unknown → **commenced August 2026**"*. (b) **2026-08-29**, Pouya's amendment, now the §4 Verified row: *"Obtained July 2026"*. A designation cannot have been obtained in July from a pathway reported as commencing in August, and (a) was reported three days before (b). One self-report is wrong; the register cannot say which, and **inferring it would be exactly the guessed-explanation failure `CLAUDE.md` bars**. **THIS DOES NOT BLOCK, and that is the whole reason it is a question rather than a hold.** The published claim is *held* — **which is faithful to his most recent instruction, and that is a different thing from correct.** §4's premise is that `[verified — Pouya]` establishes *what he reported*, never the fact, and this is the one row where the register holds documented evidence that a self-report about this credential is wrong. The date is deliberately unpublished, so no page turns on the answer. What turns on it is whether §4 can vouch for its own highest-stakes new row. **What is needed:** one line from Pouya giving the correct date, and whether (a) was a misreport, a different milestone, or something else. Then re-stamp the §4 row and correct or annotate (a) — the Change Log is append-only, so (a) gets a pointer, never an edit. Raised by `claims-auditor`, 2026-08-30 | **Nothing.** The site states what Pouya most recently instructed; what is affected is §4's ability to vouch for its own row |
|
| **Q57** | **WHAT HAPPENS WHEN A CONFLICTS CHECK TURNS SOMETHING UP?** `/process/` §Conflicts ships saying **when** the check runs (the intake call, before anything is agreed) and **what it needs** (full legal names of the parties, the parent or affiliate actually behind the dispute, counsel on each side). It stops there, and the stop is deliberate: **any sentence naming the outcome is a SEVENTH conduct undertaking**, and §4's gate for that class is one line — *"an undertaking may be published only where Pouya has made it in terms. Not 'would obviously agree to', not 'follows from the process' — said."* *"If a conflict appears I decline the appointment"* is exactly what that gate refuses to let this repository infer, however obvious it looks. **What is needed:** one sentence from Pouya, in his words, or a decision that the page says nothing further. `TODO(pouya)` sits at `src/pages/process.astro` §Conflicts. Raised at build step 6, 2026-08-30 | **The outcome half of `/process/` §Conflicts.** The section ships and is accurate; a reader who asks the obvious next question does not find the answer on the page |
|
||||||
|
| ~~Q56~~ | **RULED 2026-08-30 — MEDIATION IS *NOT* SCOPED COMMERCIAL.** Pouya: *"Correct the four 'Commercial Mediation' surfaces to 'Mediation'; leave §4's mediation row unscoped."* **And the asymmetry with arbitration is DESIGNED, not an oversight — the reason is now recorded beside both §4 rows so nobody tidies them into a matching pair.** **Arbitration is scoped commercial because of a LEGAL GATE:** Q39 — family arbitration in Ontario requires prescribed training, and Pouya has excluded it by choice. **Mediation has no such gate**; he mediates commercial, construction, insurance/SABS, shareholder and cross-cultural matters, and the practice pages say so. So the site-wide "commercial" framing was **under-describing a wider offering**, which is why it is corrected rather than ratified as a positioning choice. `/practice/insurance/`'s SABS framing needs no reconciliation: it was never outside the offering. **The question as raised is preserved below.** ⚠️ **IS THE MEDIATION OFFERING SCOPED COMMERCIAL, OR NOT? THE SITE SAID BOTH.** §4 Offerings rows arbitration three times, each **scoped commercial**; the mediation row is `**Mediation** — sole mediator`, **unscoped**. Shipped output scopes it anyway: `/mediation/`'s `<title>` is *"Commercial Mediation"*, its `Service` node is `name: "Commercial mediation"`, and `/` and `/about/` both say *"I mediate commercial disputes"*. Meanwhile **`/practice/insurance/` offers mediation in matters that are not commercial on any ordinary reading** — *"Disputes between an insured person and an insurer under the Statutory Accident Benefits Schedule"*, with *"What I offer is private mediation"*. An individual claimant against their own insurer is not a commercial dispute. **Nothing here is a false claim** — scoping a page to commercial mediation asserts *less* than the unscoped §4 row grants, and narrower than the row is always safe. **The problem is that the two halves cannot both be the whole picture**: either the practice takes non-commercial mediations (and the site-wide "commercial" framing under-describes it, including on the page an appointing body reads), or it does not (and `/practice/insurance/` is offering something outside the offering). **What is needed:** either a §4 Offerings row scoping mediation, with `/practice/insurance/`'s SABS framing reconciled to it — or a decision that mediation is deliberately unscoped, in which case the site-wide "commercial" wording is a positioning choice and should be recorded as one rather than read as a limit. **Pre-existing, not created 2026-08-30** — but this change set newly wrote the claim onto `/med-arb/` and it has been removed again pending this answer. Raised by `adversarial-reviewer`, 2026-08-30 | **Nothing — ruled the same day it was raised.** No page was wrong; the register was silent where the site was specific, and the ruling makes the site match the register rather than the other way round |
|
||||||
|
| ~~Q55~~ | **CLOSED 2026-08-30 — NOT RESOLVED, AND THE DIFFERENCE IS THE RULING.** Pouya: *"The date is not published and nothing depends on it. Your split stamp was right: `[verified]` on the status, `[Pouya's stated basis]` on the date, the 2026-08-26 record noted as unreconciled. A register that says 'two inconsistent reports of an unpublished fact, neither relied on' is complete. Do not put it to Pouya."* **So this row is not a question any more and must not be re-raised as one.** §4's Q.Arb row now carries the split stamp explicitly and marks the 2026-08-26 (a) report **unreconciled, permanently**. **Why closing beats answering here:** the register's job is to say what it can vouch for, and it can vouch for exactly this — that he reported a July acquisition, that he had reported an August commencement three days earlier, and that no published claim rests on either. Asking again would buy a third self-report about a fact the site does not state. **The question as raised is preserved below, because the evidence is the record.** ⚠️ **WHEN WAS Q.Arb ACTUALLY OBTAINED? THE REGISTER HOLDS TWO DATES FROM THE SAME SOURCE AND THEY CANNOT BOTH BE TRUE.** (a) **2026-08-26 (a)**, Change Log, `[verified 2026-08-26]`: *"Q.Arb dated. Old → new: `[assumed]`, stage unknown → **commenced August 2026**"*. (b) **2026-08-29**, Pouya's amendment, now the §4 Verified row: *"Obtained July 2026"*. A designation cannot have been obtained in July from a pathway reported as commencing in August, and (a) was reported three days before (b). One self-report is wrong; the register cannot say which, and **inferring it would be exactly the guessed-explanation failure `CLAUDE.md` bars**. **THIS DOES NOT BLOCK, and that is the whole reason it is a question rather than a hold.** The published claim is *held* — **which is faithful to his most recent instruction, and that is a different thing from correct.** §4's premise is that `[verified — Pouya]` establishes *what he reported*, never the fact, and this is the one row where the register holds documented evidence that a self-report about this credential is wrong. The date is deliberately unpublished, so no page turns on the answer. What turns on it is whether §4 can vouch for its own highest-stakes new row. **What is needed:** one line from Pouya giving the correct date, and whether (a) was a misreport, a different milestone, or something else. Then re-stamp the §4 row and correct or annotate (a) — the Change Log is append-only, so (a) gets a pointer, never an edit. Raised by `claims-auditor`, 2026-08-30 | **Nothing — and closed on that basis rather than despite it.** The site states what Pouya most recently instructed, and no page carries the date |
|
||||||
| ~~Q1~~ | **ANSWERED 2026-08-26.** Licensure is left out entirely; the site asserts the JD only. See D13 | — |
|
| ~~Q1~~ | **ANSWERED 2026-08-26.** Licensure is left out entirely; the site asserts the JD only. See D13 | — |
|
||||||
| ~~Q2~~ | **ANSWERED 2026-08-26, AND SUPERSEDED 2026-08-29.** The answer then was *"Q.Arb commenced August 2026"*. **Q.Arb is now HELD** — see the §4 Verified row. ⚠️ Corrected in place because §9 is Current Truth; the superseded answer is preserved above rather than deleted, and **the conflict between the two dates is open as Q55** | — |
|
| ~~Q2~~ | **ANSWERED 2026-08-26, AND SUPERSEDED 2026-08-29.** The answer then was *"Q.Arb commenced August 2026"*. **Q.Arb is now HELD** — see the §4 Verified row. ⚠️ Corrected in place because §9 is Current Truth; the superseded answer is preserved above rather than deleted, and **the conflict between the two dates is open as Q55** | — |
|
||||||
| ~~Q3~~ | **ANSWERED 2026-08-26.** Email `info@smlcompany.ca`. No public phone — "By scheduled call". Location: Toronto · Ontario · By appointment | — |
|
| ~~Q3~~ | **ANSWERED 2026-08-26.** Email `info@smlcompany.ca`. No public phone — "By scheduled call". Location: Toronto · Ontario · By appointment | — |
|
||||||
@@ -914,7 +917,7 @@ never being raised again.
|
|||||||
| R5 | **Fee review at 12 months.** Published rates are sticky; the right moment to move them is deliberate, not reactive | 2026-08-26 | D14 is priced for where the practice is going, not where it is |
|
| R5 | **Fee review at 12 months.** Published rates are sticky; the right moment to move them is deliberate, not reactive | 2026-08-26 | D14 is priced for where the practice is going, not where it is |
|
||||||
| R6 | **Booking tool.** Parked by Pouya on 2026-08-26; `/contact/` ships with the intake form and a reserved slot for an embed | 2026-08-26 | He asked to be reminded. D10 committed to booking because it removes the back-and-forth that loses appointments — the form alone is a partial answer |
|
| R6 | **Booking tool.** Parked by Pouya on 2026-08-26; `/contact/` ships with the intake form and a reserved slot for an embed | 2026-08-26 | He asked to be reminded. D10 committed to booking because it removes the back-and-forth that loses appointments — the form alone is a partial answer |
|
||||||
| R9 | **The SES alarms notify nobody until the `ses-alerts` email subscription is confirmed.** `SES-BounceRate-High` and `SES-ComplaintRate-High` are configured and live; the SNS email subscription to `info@smlcompany.ca` is **pending confirmation**, and an unconfirmed subscription drops every message | 2026-08-26 | A monitoring control that exists but does not deliver is worse than none, because it reads as covered. At this volume five bounces can cross the ~5% suspension threshold. Tracked in §7 and on the cutover checklist, but a one-click task nobody owns is exactly what §12 is for |
|
| R9 | **The SES alarms notify nobody until the `ses-alerts` email subscription is confirmed.** `SES-BounceRate-High` and `SES-ComplaintRate-High` are configured and live; the SNS email subscription to `info@smlcompany.ca` is **pending confirmation**, and an unconfirmed subscription drops every message | 2026-08-26 | A monitoring control that exists but does not deliver is worse than none, because it reads as covered. At this volume five bounces can cross the ~5% suspension threshold. Tracked in §7 and on the cutover checklist, but a one-click task nobody owns is exactly what §12 is for |
|
||||||
| R10 | **DISCHARGED AS WRITTEN 2026-08-28 — AND RE-ARMED WITH AN EVENT TRIGGER INSTEAD OF A DATE. STILL LIVE.** Pouya re-confirmed all four memberships as current (Q44), which discharges the prohibition this row carried, and `/about/` now publishes the Memberships group. **The row does not close, because he declined renewal-date tracking**, and that was his instruction for what to do about it: *"Without renewal months it cannot fire on a date, so make it fire on an event: re-confirm memberships before any cutover or major republish, and re-stamp §4 when confirmed."* **THE TRIGGER: re-confirm before any cutover, and before any major republish. Then re-stamp §4 the same day.** **His reason, kept verbatim because it is the general principle and not a membership detail:** *"§4 already carries OCNI as lapsed and unpublishable, and that was found roughly a year late. A stamp with no trigger behind it goes stale silently, which is exactly how OCNI got onto a list of things to feature."* **Two things the discharge did NOT license.** (1) **No currency warranty on the page** — list the memberships, promise nothing about their future state; the struck sentence stays struck and nothing replaces it. (2) ~~`memberOf` stays out of the JSON-LD~~ — **SUPERSEDED. Q53, ruled 2026-08-28: EMIT IT.** `/about/`'s Person node now carries the four memberships as `Organization` nodes. Pouya took `adversarial-reviewer`'s argument: they are already crawlable in `/about/`'s HTML, so withholding the triple reduced no exposure and only made the graph less complete than the page. **The consequence for THIS reminder is that it now covers two surfaces** — re-confirming before a cutover means `src/data/schema.ts` as well as the visible list, and they must not be allowed to diverge. **Renewal periods, stated once and not widened again:** the OBA sections and the CTF renew yearly; §4 records **nothing** about ADRIC's or ADRIO's period, and the widened form ("all four renew yearly") reached four files before it was swept. *Previous text described the prohibition and the withheld group; it held for one session and did its job.* | 2026-08-26 | A credential that lapses quietly is the failure mode §4 exists to prevent, and OCNI already did exactly this. The group is on a public page now, which raises the cost of a lapse rather than lowering it — *(This rationale ended by pointing at **Q48** as a possible widening of the row. Q48 closed 2026-08-28 as not site-relevant — ADRIO retention governs whether Pouya keeps a designation, not what the site may say about holding one — so the clause is struck. §12 is read aloud every session; a live reminder pointing at a struck row produces a false surface every time.)*, not just a list |
|
| R10 | ⚠️ **A THIRD SURFACE, 2026-08-30: `/process/` §Confidentiality renders `MEMBERSHIP_ORGS[0]` ("I am a member of the ADR Institute of Canada").** It is rendered from the constant rather than typed, so the sweep this reminder prescribes reaches it — that was `adversarial-reviewer`'s finding and the fix, in that order. **DISCHARGED AS WRITTEN 2026-08-28 — AND RE-ARMED WITH AN EVENT TRIGGER INSTEAD OF A DATE. STILL LIVE.** Pouya re-confirmed all four memberships as current (Q44), which discharges the prohibition this row carried, and `/about/` now publishes the Memberships group. **The row does not close, because he declined renewal-date tracking**, and that was his instruction for what to do about it: *"Without renewal months it cannot fire on a date, so make it fire on an event: re-confirm memberships before any cutover or major republish, and re-stamp §4 when confirmed."* **THE TRIGGER: re-confirm before any cutover, and before any major republish. Then re-stamp §4 the same day.** **His reason, kept verbatim because it is the general principle and not a membership detail:** *"§4 already carries OCNI as lapsed and unpublishable, and that was found roughly a year late. A stamp with no trigger behind it goes stale silently, which is exactly how OCNI got onto a list of things to feature."* **Two things the discharge did NOT license.** (1) **No currency warranty on the page** — list the memberships, promise nothing about their future state; the struck sentence stays struck and nothing replaces it. (2) ~~`memberOf` stays out of the JSON-LD~~ — **SUPERSEDED. Q53, ruled 2026-08-28: EMIT IT.** `/about/`'s Person node now carries the four memberships as `Organization` nodes. Pouya took `adversarial-reviewer`'s argument: they are already crawlable in `/about/`'s HTML, so withholding the triple reduced no exposure and only made the graph less complete than the page. **The consequence for THIS reminder is that it now covers two surfaces** — re-confirming before a cutover means `src/data/schema.ts` as well as the visible list, and they must not be allowed to diverge. **Renewal periods, stated once and not widened again:** the OBA sections and the CTF renew yearly; §4 records **nothing** about ADRIC's or ADRIO's period, and the widened form ("all four renew yearly") reached four files before it was swept. *Previous text described the prohibition and the withheld group; it held for one session and did its job.* | 2026-08-26 | A credential that lapses quietly is the failure mode §4 exists to prevent, and OCNI already did exactly this. The group is on a public page now, which raises the cost of a lapse rather than lowering it — *(This rationale ended by pointing at **Q48** as a possible widening of the row. Q48 closed 2026-08-28 as not site-relevant — ADRIO retention governs whether Pouya keeps a designation, not what the site may say about holding one — so the clause is struck. §12 is read aloud every session; a live reminder pointing at a struck row produces a false surface every time.)*, not just a list |
|
||||||
| R11 | **Re-check dependency currency at every phase boundary in the build order** (`docs/01-architecture.md` §Build order, 11 steps). Run `npm view <pkg> version` across **every** pin in `package.json` and compare; do not wait for something to break. Verified does not mean latest — record the reason for any deliberate hold in §7. **Carries one specific re-add trigger: at step 7, put `@lhci/cli` back.** Check for a patched release — do not assume `0.15.1` is still the ceiling just because it was on 2026-08-26 — pin it against `npm view` that day, write a `lighthouserc` with the budgets from `docs/04-seo-spec.md`, and delete the UNAVAILABLE notices this repo now carries in six places (§7 lists them). If the advisories are still unfixed, that is a decision to take deliberately, not a reason to leave the gap unstated | 2026-08-26 | `astro: "^5.0.0"` was recalled rather than checked and was two majors stale the day it was written, which meant a framework carrying high-severity XSS advisories. Between phases is cheap; after a phase of pages is written is not. The build order has ten more boundaries |
|
| R11 | **Re-check dependency currency at every phase boundary in the build order** (`docs/01-architecture.md` §Build order, 11 steps). Run `npm view <pkg> version` across **every** pin in `package.json` and compare; do not wait for something to break. Verified does not mean latest — record the reason for any deliberate hold in §7. **Carries one specific re-add trigger: at step 7, put `@lhci/cli` back.** Check for a patched release — do not assume `0.15.1` is still the ceiling just because it was on 2026-08-26 — pin it against `npm view` that day, write a `lighthouserc` with the budgets from `docs/04-seo-spec.md`, and delete the UNAVAILABLE notices this repo now carries in six places (§7 lists them). If the advisories are still unfixed, that is a decision to take deliberately, not a reason to leave the gap unstated | 2026-08-26 | `astro: "^5.0.0"` was recalled rather than checked and was two majors stale the day it was written, which meant a framework carrying high-severity XSS advisories. Between phases is cheap; after a phase of pages is written is not. The build order has ten more boundaries |
|
||||||
| R12 | **`compressHTML: true` is a deliberate deviation from the Astro 7 default (`'jsx'`).** Measured 2026-08-26: in an `.astro` template an inline pair split across two lines renders as `<em>a</em><strong>b</strong>` under the default — the space is silently deleted. MDX prose is unaffected | 2026-08-26 | It is a deviation, and undocumented deviations become folklore. Revisit **with a measurement**, not a preference — and re-measure after any Astro major, since the behaviour could change again |
|
| R12 | **`compressHTML: true` is a deliberate deviation from the Astro 7 default (`'jsx'`).** Measured 2026-08-26: in an `.astro` template an inline pair split across two lines renders as `<em>a</em><strong>b</strong>` under the default — the space is silently deleted. MDX prose is unaffected | 2026-08-26 | It is a deviation, and undocumented deviations become folklore. Revisit **with a measurement**, not a preference — and re-measure after any Astro major, since the behaviour could change again |
|
||||||
| R13 | **The infinity mark ships as a RASTER, and that is temporary. RAISED 2026-08-27; Pouya ruled the committed SVG does NOT close it** — *"Keep it committed, keep the AVIF render path. Your own measurement is the reason: 257 KB wrapping seven embedded base64 PNGs. It renders faithfully because it IS the raster."* So the exception stands and the reminder stays live. `InfinityMark.astro` renders an optimised AVIF/WebP from `src/assets/brand/sml-infinity-mark.png` — a deliberate, documented exception to `docs/02`'s "inline SVG, never a PNG", because the mark is gradient-mesh artwork and no true vector master exists yet (Q38). **Removal trigger: the commissioned vector master lands.** Then replace the `<Picture>` with inline SVG, regenerate `favicon.ico` and `apple-touch-icon.png` from it, and delete the exception from `docs/02`, from the component, and from Q38 | 2026-08-26 | Pouya flagged this himself when he made the ruling: *an interim raster is exactly the kind of temporary measure that becomes permanent by never being raised.* It costs ~8 KB and works, which is precisely why nobody will notice it again. There is no build error to prompt anyone — only this row |
|
| R13 | **The infinity mark ships as a RASTER, and that is temporary. RAISED 2026-08-27; Pouya ruled the committed SVG does NOT close it** — *"Keep it committed, keep the AVIF render path. Your own measurement is the reason: 257 KB wrapping seven embedded base64 PNGs. It renders faithfully because it IS the raster."* So the exception stands and the reminder stays live. `InfinityMark.astro` renders an optimised AVIF/WebP from `src/assets/brand/sml-infinity-mark.png` — a deliberate, documented exception to `docs/02`'s "inline SVG, never a PNG", because the mark is gradient-mesh artwork and no true vector master exists yet (Q38). **Removal trigger: the commissioned vector master lands.** Then replace the `<Picture>` with inline SVG, regenerate `favicon.ico` and `apple-touch-icon.png` from it, and delete the exception from `docs/02`, from the component, and from Q38 | 2026-08-26 | Pouya flagged this himself when he made the ruling: *an interim raster is exactly the kind of temporary measure that becomes permanent by never being raised.* It costs ~8 KB and works, which is precisely why nobody will notice it again. There is no build error to prompt anyone — only this row |
|
||||||
@@ -922,7 +925,7 @@ never being raised again.
|
|||||||
| R15 | **Every page shares ONE Open Graph image — the portrait — and that is an interim for seventeen of the nineteen. RULED, DEFERRED, AND TRACKED HERE ON POUYA'S INSTRUCTION:** *"Record the trigger so it cannot quietly become permanent."* Q40, 2026-08-27. The portrait is the **decided** card for `/` and `/about/` — a face is the strongest social preview for a personal brand. It is the wrong card for the other seventeen, where a typed card carrying the page title does the work. **Removal trigger: build step 7**, where Insights needs per-article cards anyway — one generator (`satori` or `astro-og-canvas`, pinned against `npm view` that day per R11), one dependency, one review. Then delete the interim note from `docs/04` and the cutover line from `docs/06`. **Blocks cutover; does not block steps 3–6** | 2026-08-27 | Nobody on this project will ever see the defect. A link preview is rendered by LinkedIn, Slack and Teams for a reader who is not us, and `docs/04` requires a **unique** title and description per page — nineteen unique pages that all preview identically is the failure, and it is invisible from inside the repo. It costs nothing and works, which is exactly the R13 shape |
|
| R15 | **Every page shares ONE Open Graph image — the portrait — and that is an interim for seventeen of the nineteen. RULED, DEFERRED, AND TRACKED HERE ON POUYA'S INSTRUCTION:** *"Record the trigger so it cannot quietly become permanent."* Q40, 2026-08-27. The portrait is the **decided** card for `/` and `/about/` — a face is the strongest social preview for a personal brand. It is the wrong card for the other seventeen, where a typed card carrying the page title does the work. **Removal trigger: build step 7**, where Insights needs per-article cards anyway — one generator (`satori` or `astro-og-canvas`, pinned against `npm view` that day per R11), one dependency, one review. Then delete the interim note from `docs/04` and the cutover line from `docs/06`. **Blocks cutover; does not block steps 3–6** | 2026-08-27 | Nobody on this project will ever see the defect. A link preview is rendered by LinkedIn, Slack and Teams for a reader who is not us, and `docs/04` requires a **unique** title and description per page — nineteen unique pages that all preview identically is the failure, and it is invisible from inside the repo. It costs nothing and works, which is exactly the R13 shape |
|
||||||
| R16 | **The one-page PDF bio does not exist, and it is deferred to build step 9 — not dropped. RULED AND TRACKED HERE ON POUYA'S INSTRUCTION:** *"Record the trigger so it doesn't become another quiet interim."* Q45, 2026-08-28. His reasoning: it is a **derived artefact**, so building it before `/about/` and `/fees/` are final means building it twice — and an appointment proposal needs the fee card as much as the bio. **Removal trigger: build step 9, alongside `/fees/`.** Two decisions travel with it and are **not** settled by the deferral: (a) generated at build (a dependency and an `npm audit` surface, against R11) or authored once as a designed artefact; (b) whether it carries anything the site does not — a matter list, a fee summary, referees — **each of which is a §4 question of its own**, and the matter list would collide with §4 Forbidden directly. Then delete `docs/01` §`/about/` item 7's pending note | 2026-08-28 | **It is the one artefact class this project's review apparatus cannot reach.** A web page is re-reviewed by every audit and re-checked by every build; a PDF circulated with an appointment proposal is read once, by the reader who matters most, and never seen by a reviewer again. `/about/` currently ships with no link to it, which is correct — a dead link on the page an appointing body reads is worse than the absence — and that means **nothing on the site will ever prompt anyone about this.** Only this row will |
|
| R16 | **The one-page PDF bio does not exist, and it is deferred to build step 9 — not dropped. RULED AND TRACKED HERE ON POUYA'S INSTRUCTION:** *"Record the trigger so it doesn't become another quiet interim."* Q45, 2026-08-28. His reasoning: it is a **derived artefact**, so building it before `/about/` and `/fees/` are final means building it twice — and an appointment proposal needs the fee card as much as the bio. **Removal trigger: build step 9, alongside `/fees/`.** Two decisions travel with it and are **not** settled by the deferral: (a) generated at build (a dependency and an `npm audit` surface, against R11) or authored once as a designed artefact; (b) whether it carries anything the site does not — a matter list, a fee summary, referees — **each of which is a §4 question of its own**, and the matter list would collide with §4 Forbidden directly. Then delete `docs/01` §`/about/` item 7's pending note | 2026-08-28 | **It is the one artefact class this project's review apparatus cannot reach.** A web page is re-reviewed by every audit and re-checked by every build; a PDF circulated with an appointment proposal is read once, by the reader who matters most, and never seen by a reviewer again. `/about/` currently ships with no link to it, which is correct — a dead link on the page an appointing body reads is worse than the absence — and that means **nothing on the site will ever prompt anyone about this.** Only this row will |
|
||||||
| R17 | **THE DEPLOY KEY'S FIRST ROTATION IS DUE 2026-11-26, AND THAT DATE IS THE WHOLE ROW.** Access key for `adr-sml-deploy` created **2026-08-26**; D3 commits to **quarterly** rotation. Pouya's instruction when Q22 closed: *"Put the DATE in the R-series reminder, not the intention."* **Rotation procedure is in `docs/06-deployment.md` §Key rotation** — create the second key, update the Gitea secrets, verify a deploy, **then** delete the first; never delete before verifying, or the next push fails with no way to authenticate the fix. **Then set the next date here (2027-02-26) rather than deleting the row.** Also re-run **all nine** `simulate-principal-policy` checks after any policy edit (they are listed and reproducible in `docs/reference/deploy-credential-verification.md` §5) — the narrowness is the control (§10), and a widened policy is invisible from inside the repo. **The key is currently UNUSED — `AccessKeyLastUsed` returns `ServiceName`/`Region` = `N/A` and no `LastUsedDate`** — because deploys still run locally via `npm run deploy`; that does not pause the clock, and an unused long-lived key is exactly the one nobody remembers to rotate | 2026-08-28 | This is the reminder D3 has been waiting for a subject since 2026-08-26. §10 records the reason it matters more here than on a normal project: the secret lives on **jointly-administered** infrastructure, and the account also holds another business's client-database backups. A static key on shared infrastructure is only as safe as its age and its scope, and **nothing in the repo, the build, or AWS will prompt anyone on either.** §7 carries the inventory; this row carries the date |
|
| R17 | **THE DEPLOY KEY'S FIRST ROTATION IS DUE 2026-11-26, AND THAT DATE IS THE WHOLE ROW.** Access key for `adr-sml-deploy` created **2026-08-26**; D3 commits to **quarterly** rotation. Pouya's instruction when Q22 closed: *"Put the DATE in the R-series reminder, not the intention."* **Rotation procedure is in `docs/06-deployment.md` §Key rotation** — create the second key, update the Gitea secrets, verify a deploy, **then** delete the first; never delete before verifying, or the next push fails with no way to authenticate the fix. **Then set the next date here (2027-02-26) rather than deleting the row.** Also re-run **all nine** `simulate-principal-policy` checks after any policy edit (they are listed and reproducible in `docs/reference/deploy-credential-verification.md` §5) — the narrowness is the control (§10), and a widened policy is invisible from inside the repo. **The key is currently UNUSED — `AccessKeyLastUsed` returns `ServiceName`/`Region` = `N/A` and no `LastUsedDate`** — because deploys still run locally via `npm run deploy`; that does not pause the clock, and an unused long-lived key is exactly the one nobody remembers to rotate | 2026-08-28 | This is the reminder D3 has been waiting for a subject since 2026-08-26. §10 records the reason it matters more here than on a normal project: the secret lives on **jointly-administered** infrastructure, and the account also holds another business's client-database backups. A static key on shared infrastructure is only as safe as its age and its scope, and **nothing in the repo, the build, or AWS will prompt anyone on either.** §7 carries the inventory; this row carries the date |
|
||||||
| R18 | **THE SIX `docs/reference/` EXTRACTS BEHIND `/practice/*` ARE DATED 2026-08-29, AND SIX SHIPPED SENTENCES TURN ON FACTS THAT MOVE.** Build step 5 put statute, regulation, tribunal and bill status onto public pages — sourced, but **sourced as at one day**. The volatile ones, in order of how fast they move: **(a) federal Bill C-36** — `/practice/technology/` says it *"was introduced in June 2026 and was at second reading when this page was written"*; if it receives royal assent the page is wrong about the most load-bearing fact on it. **(b) the Ontario regulation under `Electricity Act` s. 28.1** — `/practice/energy/` says it *"had not been made as of August 2026"*. **(c) the ERO 026-0853 consultation**, comment period to **12 September 2026**. **(d) the Tribunals Ontario annual report** — `/practice/insurance/` publishes FY2024-25 figures and the extract records that a 2025-26 edition was never ruled out. **(e) the SABS**, amended with effect 1 July 2026. **(f) the ADRIC National Mediation Rules**, under review by ADRIC's own committee. **THE TRIGGER: re-check all six extracts before any cutover, and before any republish that turns on one of them — the same event trigger R10 uses.** Then re-stamp the extract. **A page that was true when it was written and is false when it is read is still a false page**, and this is the first change set on the project to put that class of fact into public copy at volume | 2026-08-29 | Six sentences, six files, one retrieval date. Nothing here fires on its own; a fact with a shelf life and no owner is exactly what §12 exists for |
|
| R18 | **THE SIX `docs/reference/` EXTRACTS BEHIND `/practice/*` ARE DATED 2026-08-29, AND SIX SHIPPED SENTENCES TURN ON FACTS THAT MOVE.** Build step 5 put statute, regulation, tribunal and bill status onto public pages — sourced, but **sourced as at one day**. The volatile ones, in order of how fast they move: **(a) federal Bill C-36** — `/practice/technology/` says it *"was introduced in June 2026 and was at second reading when this page was written"*; if it receives royal assent the page is wrong about the most load-bearing fact on it. **(b) the Ontario regulation under `Electricity Act` s. 28.1** — `/practice/energy/` says it *"had not been made as of August 2026"*. **(c) the ERO 026-0853 consultation**, comment period to **12 September 2026**. **(d) the Tribunals Ontario annual report** — `/practice/insurance/` publishes FY2024-25 figures and the extract records that a 2025-26 edition was never ruled out. **(e) the SABS**, amended with effect 1 July 2026. **(f) the ADRIC National Mediation Rules**, under review by ADRIC's own committee. **(g) ADRIC's Code of Ethics** — added 2026-08-30, build step 6. `/process/` §Confidentiality quotes it verbatim from `docs/reference/adr-institution-names.md` (retrieved 2026-08-29) **with a live link to ADRIC's page**, which is what makes it checkable and also what makes a stale quotation visible. It is the slowest-moving item here — a professional code, not a bill — so it does not change the cadence; it is listed because the trigger below says "all six" and there are now seven. **THE TRIGGER: re-check all seven extracts before any cutover, and before any republish that turns on one of them — the same event trigger R10 uses.** Then re-stamp the extract. **A page that was true when it was written and is false when it is read is still a false page**, and this is the first change set on the project to put that class of fact into public copy at volume | 2026-08-29 | Six sentences, six files, one retrieval date. Nothing here fires on its own; a fact with a shelf life and no owner is exactly what §12 exists for |
|
||||||
| ~~R7~~ | **RATIFIED / SUPERSEDED 2026-08-26.** (a) Cache-policy table matching the pipeline — **accepted**; documenting what the pipeline does beats documenting an intention. (b) `s3:AbortMultipartUpload` omitted — **accepted, reasoning corrected**: the lifecycle rule does not exist and is therefore not the cover; the actual cover is that `aws s3 sync` only goes multipart above 8 MB and the largest asset is a 357 KB portrait. Recorded in `docs/06-deployment.md` with a revisit trigger. (c) The `aws s3 ls` pre-flight — **superseded** by the variable guard now running as the workflow's first step | 2026-08-26 | — |
|
| ~~R7~~ | **RATIFIED / SUPERSEDED 2026-08-26.** (a) Cache-policy table matching the pipeline — **accepted**; documenting what the pipeline does beats documenting an intention. (b) `s3:AbortMultipartUpload` omitted — **accepted, reasoning corrected**: the lifecycle rule does not exist and is therefore not the cover; the actual cover is that `aws s3 sync` only goes multipart above 8 MB and the largest asset is a 357 KB portrait. Recorded in `docs/06-deployment.md` with a revisit trigger. (c) The `aws s3 ls` pre-flight — **superseded** by the variable guard now running as the workflow's first step | 2026-08-26 | — |
|
||||||
| ~~R8~~ | **PROMOTED TO A RULE 2026-08-26.** A reminder was too weak for a pattern that survived three entries. *A sweep is a command, not a claim* now sits in `CLAUDE.md` under Conventions, in `/build` Phase 6, and in `/wrap` step 3: any claim that a change was applied across files must cite the command and be written only after reading its output | 2026-08-26 | — |
|
| ~~R8~~ | **PROMOTED TO A RULE 2026-08-26.** A reminder was too weak for a pattern that survived three entries. *A sweep is a command, not a claim* now sits in `CLAUDE.md` under Conventions, in `/build` Phase 6, and in `/wrap` step 3: any claim that a change was applied across files must cite the command and be written only after reading its output | 2026-08-26 | — |
|
||||||
|
|
||||||
@@ -930,6 +933,506 @@ never being raised again.
|
|||||||
|
|
||||||
# Change Log
|
# Change Log
|
||||||
|
|
||||||
|
## 2026-08-30 (af) — Build step 6: `/process/` and `/for-parties/`, the first step under D20 — and the frozen `check:claims` failed the build on compliant copy, which is the freeze working
|
||||||
|
|
||||||
|
**Two pages, 14 in `dist/` (was 12), zero JavaScript, one `<h1>` each, no skipped
|
||||||
|
heading levels.** The rulings they were built under are entry (ae) below.
|
||||||
|
|
||||||
|
**Reviewed by `adversarial-reviewer` only — D20, first application.**
|
||||||
|
`claims-auditor` was **not** run; it runs once, at cutover. Saying which agent
|
||||||
|
ran is now required by `/build` Phase 3, because "reviewed" reads as both.
|
||||||
|
|
||||||
|
### `/process/` — the shape of an engagement
|
||||||
|
|
||||||
|
`PROCESS` and `PROCESS_FRAMING` rendered from `src/data/site.ts`, so `/` and
|
||||||
|
`/process/` cannot drift on the five timings. **Q43's framing sits directly under
|
||||||
|
the last step**, not in the section lede — verified in the built bytes, not
|
||||||
|
asserted: the sentence follows *"Day 30 onward · Minutes of settlement — or an
|
||||||
|
award"* with nothing between them.
|
||||||
|
|
||||||
|
Conflicts, confidentiality and the non-settlement outcome are the three things
|
||||||
|
`docs/01` requires beyond the steps. Two of the three close with a **conduct
|
||||||
|
undertaking rendered from the constant**, never retyped — (d) on confidentiality
|
||||||
|
and (a) on the switch — and §4's "Where it ships" column is updated for both.
|
||||||
|
|
||||||
|
### The third one stops early, and the stop is the point — Q57
|
||||||
|
|
||||||
|
`/process/` §Conflicts says **when** the check runs and **what it needs**. It does
|
||||||
|
not say what happens when one turns something up, because **that sentence would
|
||||||
|
be a seventh conduct undertaking** and §4's gate for that class is one line:
|
||||||
|
*"an undertaking may be published only where Pouya has made it in terms. Not
|
||||||
|
'would obviously agree to', not 'follows from the process' — said."*
|
||||||
|
|
||||||
|
*"If a conflict appears I decline the appointment"* is exactly what that gate
|
||||||
|
refuses to let this repository infer, however obvious it looks. `TODO(pouya)` in
|
||||||
|
the source, **Q57** in §9. One sentence from him closes it.
|
||||||
|
|
||||||
|
### `/for-parties/` — and it is the page `docs/03` warns about
|
||||||
|
|
||||||
|
The one page in the second person. `NEUTRAL_ROLE_LINE` gets **its own section
|
||||||
|
above the questions** rather than a slot inside them: `docs/03` requires this
|
||||||
|
page to say it explicitly, and the sentence a party most needs is not one to make
|
||||||
|
them scroll for.
|
||||||
|
|
||||||
|
Eight questions, written as questions a party actually asks, so `FAQPage` is
|
||||||
|
honest — `docs/04` allows the node here *"only where the visible page genuinely
|
||||||
|
is Q&A"*. **One array feeds both the visible page and the node**, so a question
|
||||||
|
cannot enter the structured data without appearing on the page. The caucus
|
||||||
|
undertaking renders through `<Undertaking>` visibly and is joined into the
|
||||||
|
answer text for the node, which is plain text by schema — one source, two shapes,
|
||||||
|
neither typed twice. **Fee figures are interpolated from `FEES`**, so the page a
|
||||||
|
party reads cannot drift from D14's card.
|
||||||
|
|
||||||
|
**Reading level, measured rather than claimed, and the instrument checked both
|
||||||
|
ways.** `docs/03` requires grade 9. A syllable heuristic that **undercounts**
|
||||||
|
(it merges `ia`/`io` and eats `-le`) returns Flesch–Kincaid **4.5**; one
|
||||||
|
corrected to split those vowel groups **overcounts** and returns **4.9**. Both
|
||||||
|
bracket the true value well under the requirement, and the syllable-independent
|
||||||
|
metric agrees: **9.6 words per sentence** in `<main>`, longest sentence 36 words.
|
||||||
|
Reported as a range because a single estimate here would be a claim about the
|
||||||
|
counter.
|
||||||
|
|
||||||
|
### `check:claims` failed the build on compliant copy, and the copy moved
|
||||||
|
|
||||||
|
The page shipped *"Do I need my own lawyer?"*, *"coming without a lawyer"* and
|
||||||
|
*"you are not a lawyer"* — every one of them about the **reader**. §4 bars the
|
||||||
|
word *used of Pouya*, so all three are compliant on the register's own wording.
|
||||||
|
**`licensure-of-pouya` failed the build on five matches anyway**, because a bare
|
||||||
|
`\blawyer\b` cannot tell whose.
|
||||||
|
|
||||||
|
**The copy moved, not the gate**, and there were three reasons rather than one:
|
||||||
|
|
||||||
|
1. **There is no allowlist.** `mustNotMatch` fixtures only assert in the
|
||||||
|
self-test that a pattern stays silent on approved strings; they are **not**
|
||||||
|
applied when scanning `dist/`. Adding one would not have unblocked the build
|
||||||
|
— it would have made the self-test fail instead. Worth recording, because
|
||||||
|
"add it to the approved list" is the obvious first move and it does not exist.
|
||||||
|
2. **The precedent runs this way.** When `/med-arb/` shipped *"the neutral who
|
||||||
|
heard my client in caucus"* — counsel's voice, not Pouya's — the copy changed
|
||||||
|
to *"our client"* and the pattern widened. Same shape, same call.
|
||||||
|
3. **The freeze.** Narrowing `\blawyer\b` to exclude reader-owned uses is a
|
||||||
|
refactor of the strongest pattern on the site, on the page `docs/03` names as
|
||||||
|
where the barred phrasing is most tempting. That is the coverage work the
|
||||||
|
freeze bars.
|
||||||
|
|
||||||
|
The replacements are better copy, which is the part worth noting: *"Should I get
|
||||||
|
my own legal advice?"* uses `NEUTRAL_ROLE_LINE`'s own wording, and the hero lede
|
||||||
|
went from *"you are not a lawyer"* to *"nobody has explained what one is"* —
|
||||||
|
which targets the need rather than the reader's credential. The constraint is
|
||||||
|
recorded in the page header so the next editor does not re-introduce it.
|
||||||
|
|
||||||
|
### Two dangling internal links closed, on every page
|
||||||
|
|
||||||
|
`SECONDARY_NAV` in `src/data/site.ts` has linked `/process/` and `/for-parties/`
|
||||||
|
from the footer since step 1, and neither page existed. **Every one of the 12
|
||||||
|
previously built pages therefore shipped two broken internal links.** `site.ts`
|
||||||
|
is unchanged in this change set — the pages simply arrived. All internal links
|
||||||
|
now resolve except `/contact/`, `/fees/`, `/insights/` and `/legal/*`, which are
|
||||||
|
build steps 7–10.
|
||||||
|
|
||||||
|
### Structured data
|
||||||
|
|
||||||
|
`/process/` emits **`Person` only** — a new `pageGraph()`, which
|
||||||
|
`practiceIndexGraph()` now delegates to. **No `Service` node, deliberately**: the
|
||||||
|
five timings are publishable only under Q43's framing sentence, and a `Service`
|
||||||
|
node would carry the numbers into a field where no framing travels with them.
|
||||||
|
`/for-parties/` emits `Person` + `FAQPage`; `faqNode()` is factored out and
|
||||||
|
`medArbGraph()` now calls it instead of carrying its own copy of the mapping.
|
||||||
|
|
||||||
|
### R11 at the step 5 → 6 phase boundary — same one pin, same recorded reason
|
||||||
|
|
||||||
|
`npm view` run across all fourteen pins, exit status read. **Thirteen are
|
||||||
|
current.** `typescript` is pinned `^6.0.3` against a latest of `7.0.2` — the same
|
||||||
|
deliberate hold recorded at the step 4 → 5 boundary, and the trigger was
|
||||||
|
**re-verified rather than recalled**:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ npm view @astrojs/check@0.9.10 peerDependencies
|
||||||
|
{ typescript: '^5.0.0 || ^6.0.0' }
|
||||||
|
```
|
||||||
|
|
||||||
|
`astro check` is the type gate both deploy paths run, so the hold stands.
|
||||||
|
**Removal trigger unchanged: `@astrojs/check` widens the range.** A hold on a
|
||||||
|
dependency's schedule, not on a judgement.
|
||||||
|
|
||||||
|
### The code review — 9 findings, 2 blocking, all accepted
|
||||||
|
|
||||||
|
`adversarial-reviewer` only, per D20. **`claims-auditor` was not run.**
|
||||||
|
|
||||||
|
**BLOCKING 1 — a body link shipped at 1.88:1, which is worse than the defect this
|
||||||
|
project treats as canonical.** `/process/`'s Code-of-Ethics link sits on
|
||||||
|
`.section-inverse` and inherited the global `a { color: var(--link) }` —
|
||||||
|
`--maroon-l`, a token whose own comment says *"links on cream 8.95:1"*. Nothing
|
||||||
|
overrode it for a dark ground. **Measured independently before acting**, and the
|
||||||
|
instrument was validated by reproducing three documented values exactly (8.95:1
|
||||||
|
maroon-l on cream, 11.09:1 gold-l on ink, 16.81:1 cream on ink):
|
||||||
|
|
||||||
|
```
|
||||||
|
1.88:1 --link (maroon-l #7a2a2c) on --bg-inverse (ink #1a1614)
|
||||||
|
1.10:1 :hover (maroon-d #3d1112) on the same ground
|
||||||
|
```
|
||||||
|
|
||||||
|
`CLAUDE.md` records gold-on-cream at **2.10:1** as the thing that must never
|
||||||
|
ship. This was worse, on hover by a factor of two. **`/process/` is the site's
|
||||||
|
first body link on a dark band** — `SiteFooter` colours its own, which is the
|
||||||
|
only reason the hole had never opened. Fixed in `global.css` beside the
|
||||||
|
`:focus-visible` rule that exists for exactly this reason, not in the page.
|
||||||
|
|
||||||
|
**And the `:not(.btn)` in that fix is load-bearing, not decoration.**
|
||||||
|
`.section-inverse a:not(.btn)` has specificity (0,2,1); `.btn-gold[data-astro-cid]`
|
||||||
|
has (0,2,0). Without the exclusion the new rule would have **overridden every
|
||||||
|
gold button on an inverse ground**, which is the repair introducing a second
|
||||||
|
defect — the exact shape `/build` Phase 4 exists to catch. Verified after the
|
||||||
|
fix by enumerating every non-`.btn` anchor inside any `.section-inverse` or
|
||||||
|
`.section-accent` across all 14 built pages: **one, and it is this link.**
|
||||||
|
|
||||||
|
**BLOCKING 2 — the fee shipped as "with preparation included", which `docs/07`
|
||||||
|
forbids in terms.** *"Preparation time is bundled and **must be stated on the
|
||||||
|
page** — 'including 2 hours of preparation'… **Do not quietly fold it into the
|
||||||
|
hours figure.**"* The allowance is **capped**, so the unqualified form sells an
|
||||||
|
uncapped one, to the reader least able to check it — and `/mediation/` already
|
||||||
|
ships the promise that the site does the opposite. `grep -n prepIncluded src/`
|
||||||
|
returned **only the declaration**: the constant existed for this exact sentence
|
||||||
|
and had no consumer anywhere. Now interpolated on both figures.
|
||||||
|
|
||||||
|
**And one finding I could not resolve, so it became Q58 rather than a guess.**
|
||||||
|
`docs/07`'s card reads *"Half day — up to 3.5 h, **including** 2 h
|
||||||
|
preparation"*, which makes 3.5 the **billed envelope** and the time in the room
|
||||||
|
**1.5 h**. Against that: 3.5 and 7 are exactly 2×, which they would not be if
|
||||||
|
preparation sat inside them. One of the two is wrong, and a draft of
|
||||||
|
`/for-parties/` had already answered *"What happens on the day?"* with *"A half
|
||||||
|
day is about 3.5 hours"* — the envelope presented as the day. **The sentence was
|
||||||
|
removed, not reconciled**; the page now says only that you book a half day or a
|
||||||
|
full day. `site.ts`'s `hours` field carries a warning against publishing it as a
|
||||||
|
duration. **`/fees/` at step 9 cannot be built without the answer.**
|
||||||
|
|
||||||
|
**The other six, all accepted:**
|
||||||
|
|
||||||
|
1. ***"on this it is one sentence"* was a completeness claim about a third
|
||||||
|
party's Code that the cited artefact contradicts.** The extract is a scrape
|
||||||
|
of one web page carrying three quoted lines, and **eighteen lines above** it
|
||||||
|
records a separate instrument — ADRIC's **Code of Conduct for Mediators** —
|
||||||
|
bearing on the same subject. The source cited supplied the counter-example.
|
||||||
|
Fourth instance of the named gloss pattern, after the LAT ellipsis, the IESO
|
||||||
|
"connection allocation" and the `/med-arb/` ADRIC gloss — **and the first one
|
||||||
|
caught before shipping.** Now reads *"and it says:"*.
|
||||||
|
2. **"Caucus" was undefined jargon on the one page whose spec bars jargon.** Used
|
||||||
|
twice, never defined; §11 has no entry; `/mediation/` — the *counsel*-facing
|
||||||
|
page — actually glosses it and `/for-parties/` did not. Glossed in the page
|
||||||
|
copy, **never inside `CONDUCT_UNDERTAKINGS.mediationCaucus`**. Note the
|
||||||
|
measurement's blind spot: Flesch–Kincaid put the page at grade 4–7, well
|
||||||
|
inside the grade-9 requirement, **because the formula cannot see a single
|
||||||
|
unfamiliar noun.** A reading-level score is not a jargon check.
|
||||||
|
3. **`docs/01` still instructed *"not your lawyer"*** — struck in `docs/03` on
|
||||||
|
2026-08-28 with a two-point explanation, and the sweep never reached
|
||||||
|
`docs/01`. **This change set edited `docs/01` and did not fix it.** The page
|
||||||
|
avoided the trap; the spec that directs the page did not. Replaced with a
|
||||||
|
pointer to `NEUTRAL_ROLE_LINE` and the struck forms.
|
||||||
|
4. **§4 undertaking row (d) recorded two surfaces and there are three** —
|
||||||
|
`/for-parties/` publishes it visibly and inside the `FAQPage` node. An
|
||||||
|
incomplete "where it ships" on the one class Pouya flagged as failing
|
||||||
|
*silently* is that column doing the opposite of its job.
|
||||||
|
5. **`/process/` hand-typed the ADRIC membership.** Character-identical to
|
||||||
|
`MEMBERSHIP_ORGS[0]`, and R10's re-confirm trigger sweeps the constants, not
|
||||||
|
the pages — so after a lapse this page would have kept asserting it. The OCNI
|
||||||
|
shape exactly. Now interpolated, and R10 records the third surface.
|
||||||
|
6. **`practiceIndexGraph` had become a pure alias** — one caller, zero
|
||||||
|
behaviour, 13 lines of comment over 3 lines of code, and the comment's
|
||||||
|
reasoning is about `/practice/` rather than about graph shape. My churn from
|
||||||
|
an hour earlier. Deleted; `practice.astro` imports `pageGraph` and the
|
||||||
|
reasoning now sits beside the call that makes the decision.
|
||||||
|
|
||||||
|
### One defect I introduced while fixing them, and what caught it
|
||||||
|
|
||||||
|
Removing the duration turned a template literal into a plain string — **but I
|
||||||
|
replaced the closing backtick and left the opening one**, so the frontmatter
|
||||||
|
fence broke and TypeScript read the rest of the file as one string. **`astro
|
||||||
|
check` returned exit 1 with 50 errors**, and both deploy paths run `check` before
|
||||||
|
`build`, so nothing could have shipped. Recorded because it is the case
|
||||||
|
`CLAUDE.md`'s truncation rule is about from the other side: the verdict was read
|
||||||
|
as an **exit status**, not as the tail of a pipe.
|
||||||
|
|
||||||
|
### Two limits on this pass, stated rather than omitted
|
||||||
|
|
||||||
|
- **Lighthouse: not run — tool unavailable.** `@lhci/cli` removed 2026-08-26,
|
||||||
|
returns at step 7 under R11.
|
||||||
|
- **Mobile layout at 390px: not measured.** Headless Chrome lays out at a wider
|
||||||
|
viewport and crops to the requested width; the reviewer validated that by
|
||||||
|
checking already-reviewed pages clip identically, so the clipping is the
|
||||||
|
instrument rather than the pages. Element-level widths at 390px remain
|
||||||
|
unmeasured and need a real driver — `puppeteer` is not installed, only an
|
||||||
|
empty `node_modules/@puppeteer` directory exists.
|
||||||
|
|
||||||
|
### And a sweep caveat worth keeping
|
||||||
|
|
||||||
|
**`git grep` silently misses untracked files.** Both new pages were untracked for
|
||||||
|
the whole of this build, so any `git grep` across step 6 returned a clean result
|
||||||
|
that meant nothing. Use plain `grep -rn` until the files are staged. Same family
|
||||||
|
as R8: a real command, read honestly, and the wrong command.
|
||||||
|
|
||||||
|
### And working the `docs/03` checklist against the pages found the checklist wrong
|
||||||
|
|
||||||
|
Not a review finding — this came from actually running the compliance checklist
|
||||||
|
rather than assuming it. Item 2 read *"No matter counts, settlement rates,
|
||||||
|
**dollar figures**, or time-to-award stats"*, and `/for-parties/` is **the first
|
||||||
|
page on the site to publish a fee** (`grep -roh '\$[0-9][0-9,]*' dist` returns
|
||||||
|
`$2,000` and `$4,000`, both on that page and nowhere else). Read literally, the
|
||||||
|
checklist forbade the page `docs/01` commits to and the rate card D8 commits to.
|
||||||
|
|
||||||
|
**§4's own row was never wrong** — it reads *"Aggregate value resolved; any
|
||||||
|
dollar figure attached to **past matters**"*. The checklist **dropped the
|
||||||
|
qualifier when it mirrored it**, which is `CLAUDE.md`'s duplicated-fact rule
|
||||||
|
exactly: the copy that goes stale is the one nobody re-reads. Item scoped, with
|
||||||
|
§4's wording cited rather than restated.
|
||||||
|
|
||||||
|
**Third instance of an unscoped checklist line flagging the copy the spec
|
||||||
|
requires** — the other two are the testimonials item and the capacity-phrasing
|
||||||
|
item, both corrected the same way, and `docs/03` records that the checklist *"is
|
||||||
|
what gets grepped"*.
|
||||||
|
|
||||||
|
### Verification — exit statuses read directly, never through a pipe
|
||||||
|
|
||||||
|
```
|
||||||
|
npm run check exit 0 0 errors / 0 warnings / 0 hints (34 files)
|
||||||
|
npm run lint exit 0
|
||||||
|
npm run build exit 0 14 pages
|
||||||
|
npm run check:claims exit 0 11 patterns, 26 approved strings, 14 pages
|
||||||
|
npm audit exit 0 0 vulnerabilities
|
||||||
|
```
|
||||||
|
|
||||||
|
Also run and read: the minifier trap (`grep -rE 'animation:[^;}]*(scroll\(\)|
|
||||||
|
view\(\))' dist --include='*.css'` → **exit 1, no match**); a secret scan whose
|
||||||
|
**own** exit status was read rather than a pipeline's (**exit 1, no match** —
|
||||||
|
the first attempt piped through `head` and reported `head`'s status, which is
|
||||||
|
the failure `CLAUDE.md` names); all 14 pages for one `<h1>`, no skipped heading
|
||||||
|
levels, canonical, OG/Twitter, JSON-LD parse, and title/description inside
|
||||||
|
50–60 / 140–160 (**14/14 in band, all unique**); every internal link resolved
|
||||||
|
except `/contact/`, `/fees/`, `/insights/` and `/legal/*`, which are steps 7–10;
|
||||||
|
zero `client:*` directives and zero non-JSON-LD `<script>` on either new page.
|
||||||
|
|
||||||
|
**`PROCESS_FRAMING` verified in the shipped bytes**, not asserted: it follows
|
||||||
|
*"Day 30 onward · Minutes of settlement — or an award"* with nothing between.
|
||||||
|
|
||||||
|
### And the `set -- $pair` bug recurred, in the direction that is dangerous
|
||||||
|
|
||||||
|
`CLAUDE.md` records a zsh digest-comparison loop that printed **`DIFFER` on all
|
||||||
|
five rows** because `set -- $pair` gave the loop body one argument. The same loop
|
||||||
|
shape was used here to confirm nine files matched a saved copy, and it printed
|
||||||
|
**`same` on all nine** — a uniformly *good* result from a comparison that never
|
||||||
|
ran. `shasum` was invoked as `shasum -a 256 "AGENTS.md AGENTS.md"`, errored, and
|
||||||
|
left **both** variables empty, so `[ "$a" = "$b" ]` compared `""` to `""` and
|
||||||
|
passed.
|
||||||
|
|
||||||
|
**The `DIFFER` version announces itself; this one does not.** "Uniformly bad"
|
||||||
|
gets re-checked because it is alarming. **"Uniformly good" is what you were
|
||||||
|
hoping for, and it ends the check.** Re-run in Python with an `os.path.isfile`
|
||||||
|
assertion on both sides — the step the shell loop skipped — and the nine files
|
||||||
|
are genuinely byte-identical. Add to the sweep discipline: **a comparison must
|
||||||
|
assert that both things it compares exist.**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2026-08-30 (ae) — D20 moves the claims pass to cutover; Q56 rules mediation UNSCOPED and records why the asymmetry with arbitration is designed; Q55 is closed without being resolved; and `check:claims` is frozen
|
||||||
|
|
||||||
|
**Three rulings and two conventions, all Pouya's, recorded in one entry because
|
||||||
|
they were one directive.** Build step 6 was run under them the same day and is recorded in its own entry.
|
||||||
|
|
||||||
|
### D20 — the per-step claims audit stops, and this must read as calibration
|
||||||
|
|
||||||
|
**New locked decision. `claims-auditor` runs ONCE, at cutover, over the whole
|
||||||
|
finished site.** Per step it is `adversarial-reviewer` alone, two rounds max
|
||||||
|
under D19. `npm run check:claims` is **unchanged** and still runs on every build
|
||||||
|
and both deploy paths. Pouya reads the copy as it is built; that is the human
|
||||||
|
pass.
|
||||||
|
|
||||||
|
**His reasoning, recorded in full in §3 D20 rather than summarised here**, because
|
||||||
|
"we stopped running the compliance check" is the kind of sentence a later reader
|
||||||
|
has to be able to weigh:
|
||||||
|
|
||||||
|
- **Nothing has shipped.** Every claims finding to date has been about a page no
|
||||||
|
visitor can reach — the entire risk is deferred to cutover already, and
|
||||||
|
auditing nine build steps then re-auditing the fixes is auditing a draft
|
||||||
|
nobody can read.
|
||||||
|
- **One pass over twenty finished pages catches MORE than nine over drafts**,
|
||||||
|
because it sees the site as a reader does. The `/med-arb/` ADRIC gloss is the
|
||||||
|
proof: no individual claim was false, the defect was **adjacency**, and
|
||||||
|
adjacency does not exist until the pages sit next to each other.
|
||||||
|
- **The code reviewer stays per step because what it catches compounds.** An
|
||||||
|
accessibility or crawlability defect propagates into the next page built on
|
||||||
|
it. A claims defect does not compound; it sits there until someone reads it.
|
||||||
|
|
||||||
|
**And what it costs is recorded, not glossed.** `claims-auditor` has caught the
|
||||||
|
struck false universal reaching a public page in the first person, a `<title>`
|
||||||
|
reading "Sole Arbitrator", "Every award I issue" on a practice with no completed
|
||||||
|
arbitration, four breaches of the Q54 gate on the day it was written, the
|
||||||
|
memberships currency warranty, and a §4 Verified row authorising exactly what
|
||||||
|
D16 forbids. D20 accepts that a defect of that class may now live in an
|
||||||
|
unpublished draft for weeks. **It must not survive cutover** — `docs/06` carries
|
||||||
|
two blocking items for it at the top of the checklist.
|
||||||
|
|
||||||
|
**One substitution, flagged rather than made silently.** Pouya's directive wrote
|
||||||
|
that several of those defects "read badly on a legal professional's site".
|
||||||
|
`CLAUDE.md` bars describing him as a legal professional **anywhere, that file
|
||||||
|
included**, so §3 D20 says "the site of a person who holds a JD". The
|
||||||
|
substitution is his rule applied to his own sentence; the meaning is unchanged.
|
||||||
|
|
||||||
|
### The D20 sweep, as a command
|
||||||
|
|
||||||
|
D20 was swept to the six destinations Pouya named plus §3 itself. Verified by
|
||||||
|
command, output read before this line was written:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ git grep -c 'D20' -- CLAUDE.md AGENTS.md docs/ .claude/
|
||||||
|
.claude/agents/claims-auditor.md:4
|
||||||
|
.claude/commands/build.md:5
|
||||||
|
.claude/commands/review.md:3
|
||||||
|
AGENTS.md:3
|
||||||
|
CLAUDE.md:5
|
||||||
|
docs/06-deployment.md:3
|
||||||
|
docs/08-execution-protocol.md:5
|
||||||
|
```
|
||||||
|
|
||||||
|
`D17` and `D19` are amended in place rather than superseded: D17's "two
|
||||||
|
independent review agents" now describes the project rather than the step, and
|
||||||
|
**D19's two-round cap is explicitly scoped to the per-step code review** — it
|
||||||
|
does not govern the cutover claims pass, which has no second pass behind it and
|
||||||
|
runs until its findings are resolved.
|
||||||
|
|
||||||
|
Three residual per-step references were caught by re-reading rather than by the
|
||||||
|
sweep: `/build`'s "Both briefs carry the same boundary", `/build` Phase 5's
|
||||||
|
"a finding neither review agent has to spend a pass on", and `docs/08`'s
|
||||||
|
"Verifying they are loaded" block, which the edit had orphaned inside a new
|
||||||
|
subsection. All three corrected.
|
||||||
|
|
||||||
|
### Q56 — RULED. Mediation is NOT scoped commercial
|
||||||
|
|
||||||
|
Pouya: *"Correct the four 'Commercial Mediation' surfaces to 'Mediation'; leave
|
||||||
|
§4's mediation row unscoped."*
|
||||||
|
|
||||||
|
**The reason is recorded beside BOTH §4 rows so the asymmetry reads as designed
|
||||||
|
rather than as an oversight.** Arbitration is scoped commercial because of a
|
||||||
|
**legal gate** — Q39, family arbitration in Ontario requires prescribed training.
|
||||||
|
**Mediation has no such gate.** A later editor tidying the two rows into a
|
||||||
|
matching pair would be reintroducing the defect, and both rows now say so.
|
||||||
|
|
||||||
|
**Q56 named four surfaces. The sweep changed thirteen shipped strings across five
|
||||||
|
files, and `adversarial-reviewer` then found three more it had missed.** The
|
||||||
|
count matters because the enumeration is what a later auditor treats as the
|
||||||
|
completeness list — the same shape as the `Q.Arb` sweep that missed ten lines in
|
||||||
|
`docs/03`. What was corrected:
|
||||||
|
|
||||||
|
| Where | Was |
|
||||||
|
|---|---|
|
||||||
|
| `/mediation/` `<title>` | `Commercial Mediation · …` |
|
||||||
|
| `/mediation/` `Service.name` | `Commercial mediation` |
|
||||||
|
| `/mediation/` `Service.description` | `Sole-mediator appointments in commercial disputes.` |
|
||||||
|
| `/mediation/` meta description | `Sole mediator for commercial disputes in Toronto.` |
|
||||||
|
| `/mediation/` §Subject matter lede | `Where a commercial mediation usually turns on…` |
|
||||||
|
| `/mediation/` §The role | `What I bring to a commercial file…` ← **round 2** |
|
||||||
|
| `/` meta description | `Commercial mediation and arbitration in Toronto.` |
|
||||||
|
| `/` hero lede | `I mediate commercial disputes from Toronto…` |
|
||||||
|
| `/about/` hero lede | `I mediate commercial disputes and I accept…` |
|
||||||
|
| `/practice/` meta description | `Six areas where a commercial dispute…` ← **round 2** |
|
||||||
|
| `/practice/` hero lede | `Each of these is a place where a commercial dispute…` ← **round 2** |
|
||||||
|
| `/practice/` §The processes | `…choosing between, in commercial matters.` ← **round 2, BLOCKING** |
|
||||||
|
| `src/data/schema.ts` `ProfessionalService.description` | `Commercial mediation and arbitration for…` |
|
||||||
|
|
||||||
|
**The blocking one is the finding of this change set, and my sweep could not have
|
||||||
|
found it.** `/practice/` shipped *"These describe the process the parties are
|
||||||
|
choosing between, in commercial matters"* immediately above links to
|
||||||
|
`/mediation/`, `/arbitration/` and `/med-arb/` — so "these" scopes **mediation**,
|
||||||
|
on the page that distributes traffic to it, hours after this same change set
|
||||||
|
wrote *"do not scope it on a page"* into §4. **"Commercial" and "mediation" are
|
||||||
|
never in the same element**, so no proximity grep reaches it. Counsel with a SABS
|
||||||
|
mediation reads the six area cards, reads that the processes are offered in
|
||||||
|
commercial matters, and concludes the practice does not take their matter.
|
||||||
|
|
||||||
|
`docs/03` now carries the command **and its limit**: the proximity grep finds the
|
||||||
|
adjacent form only, and for the split form there is no pattern — read every
|
||||||
|
`commercial` in `src/` and `dist/` and ask what each one is scoping.
|
||||||
|
|
||||||
|
**Left deliberately, so the judgement is visible rather than missed:**
|
||||||
|
`/practice/cross-cultural/` ships *"These run as commercial mediations and
|
||||||
|
arbitrations, from Toronto"*. Its referent is the cross-cultural **commercial**
|
||||||
|
matters the page has just defined — §4's own words for that area — so it is
|
||||||
|
context, not a scope on the offering. It is the only literal `commercial
|
||||||
|
mediation` string left in `dist/`. Raised by `adversarial-reviewer` as a
|
||||||
|
judgement call; called this way, and recorded here so Pouya can reverse it.
|
||||||
|
|
||||||
|
**And §4's mediation enumeration is annotated rather than edited.** Pouya's
|
||||||
|
ruling lists five subject matters — *"commercial, construction, insurance/SABS,
|
||||||
|
shareholder and cross-cultural"* — against **six** published areas, every one of
|
||||||
|
which offers mediation. Technology and energy are absent. Read as an
|
||||||
|
enumeration the row is short by two and a later reader would strike two live
|
||||||
|
pages. The row now says the list is **illustrative of breadth, not a closed
|
||||||
|
set**, and that Q35's gate governs the authorised subject matter. The words are
|
||||||
|
his ruling, so they were annotated, not rewritten. **Flagged to him.**
|
||||||
|
|
||||||
|
### Q55 — CLOSED WITHOUT BEING RESOLVED, and the difference is the ruling
|
||||||
|
|
||||||
|
Pouya: *"The date is not published and nothing depends on it… A register that
|
||||||
|
says 'two inconsistent reports of an unpublished fact, neither relied on' is
|
||||||
|
complete. Do not put it to Pouya."*
|
||||||
|
|
||||||
|
§4's Q.Arb row now carries the **split stamp explicitly**, which it did not
|
||||||
|
before: `[verified 2026-08-29 — Pouya]` on the **status**, `[Pouya's stated basis
|
||||||
|
2026-08-29]` on the **date**. The 2026-08-26 (a) Change Log report of *commenced
|
||||||
|
August 2026* stands **unreconciled, permanently and on purpose** — the row says
|
||||||
|
so, and says not to reconcile it by inference, re-stamp it, or put it back to
|
||||||
|
him. The publication rule is untouched: no date ships.
|
||||||
|
|
||||||
|
### `check:claims` IS FROZEN — a tripwire, not a program
|
||||||
|
|
||||||
|
Pouya's ruling, on his own measurement: round 2 of the Q.Arb amendment found
|
||||||
|
**five defects in round 1's fixes to that script, two of which made it worse than
|
||||||
|
before the pattern existed**. At that point it was generating defects at roughly
|
||||||
|
the rate it caught them. The rule, now in `CLAUDE.md`:
|
||||||
|
|
||||||
|
- a pattern is added **only after a real breach has reached `dist/`**, never
|
||||||
|
speculatively;
|
||||||
|
- each addition ships with **a probe** proving it catches the actual breach
|
||||||
|
**and a negative fixture** proving it stays silent on the nearest approved
|
||||||
|
copy;
|
||||||
|
- **no refactors, no coverage improvements, no tidying.**
|
||||||
|
|
||||||
|
The script was not touched in this change set, and step 6 tested the freeze
|
||||||
|
within hours, on `/for-parties/` at build step 6.
|
||||||
|
|
||||||
|
### Two conventions into `CLAUDE.md`
|
||||||
|
|
||||||
|
1. **Sweep the vocabulary, not only the subject.** `git grep 'Q.Arb'` is
|
||||||
|
line-anchored and could not find ten lines entirely about Q.Arb that never
|
||||||
|
name it. R8's sharpest edge: a sweep can be a real command, read honestly,
|
||||||
|
and still be the wrong command. The `/practice/` finding above is the same
|
||||||
|
rule from a third angle — there the two words are not even in the same
|
||||||
|
element, so **no** pattern reaches it and only reading does.
|
||||||
|
2. **Agent definitions load at session start.** An edit to `.claude/agents/*.md`
|
||||||
|
does not reach the session that made it. Restart before relying on one, and
|
||||||
|
**say in the report which version actually ran.** Found when `claims-auditor`
|
||||||
|
reconstructed the gloss lens from this Change Log rather than having it in
|
||||||
|
its brief.
|
||||||
|
|
||||||
|
Convention 2 is also in `docs/08` beside the "verifying the agents are loaded"
|
||||||
|
instruction, which is where someone checking that would look.
|
||||||
|
|
||||||
|
### Verification
|
||||||
|
|
||||||
|
```
|
||||||
|
npm run check exit 0 0 errors / 0 warnings / 0 hints
|
||||||
|
npm run lint exit 0
|
||||||
|
npm run build exit 0
|
||||||
|
npm run check:claims exit 0
|
||||||
|
```
|
||||||
|
|
||||||
|
The `Commercial Mediation` correction was verified on `dist/` rather than on
|
||||||
|
`src/`: `grep -ric 'commercial mediation' dist/` returns **1**, and it is
|
||||||
|
`/practice/cross-cultural/`'s deliberate leave, recorded above. The reviewer
|
||||||
|
independently enumerated **all 62 occurrences of `commercial`** across the 14
|
||||||
|
built pages with 240 characters of context and read each one — **none scopes
|
||||||
|
mediation.**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## 2026-08-30 (ad) — Q.Arb is HELD; C.Med-Arb is struck entirely; the paired-disclosure condition dissolves with the stage it required — and this deviates from the strategy brief deliberately
|
## 2026-08-30 (ad) — Q.Arb is HELD; C.Med-Arb is struck entirely; the paired-disclosure condition dissolves with the stage it required — and this deviates from the strategy brief deliberately
|
||||||
|
|
||||||
**Type:** ruling + D3-class sweep. **20 files, +1064 / −607.** `src/` alone is
|
**Type:** ruling + D3-class sweep. **20 files, +1064 / −607.** `src/` alone is
|
||||||
|
|||||||
@@ -57,8 +57,9 @@ being restated in the prompt.
|
|||||||
anything live), read the governing specs, name the decisions the task touches,
|
anything live), read the governing specs, name the decisions the task touches,
|
||||||
and **stop and ask on any conflict**. A blocked build is a correct build.
|
and **stop and ask on any conflict**. A blocked build is a correct build.
|
||||||
2. **Implement** — following the conventions below.
|
2. **Implement** — following the conventions below.
|
||||||
3. **Adversarial review** — invoke `adversarial-reviewer` and `claims-auditor` in
|
3. **Adversarial review** — invoke `adversarial-reviewer` on the diff. **D20:
|
||||||
parallel on the diff.
|
`claims-auditor` does NOT run per step.** It runs once, at cutover, over the
|
||||||
|
whole finished site.
|
||||||
4. **Resolve** — fix each finding or decline it with a stated reason. Re-review
|
4. **Resolve** — fix each finding or decline it with a stated reason. Re-review
|
||||||
material fixes.
|
material fixes.
|
||||||
5. **Verify** — run the checks. Never report a check as passing that you did not
|
5. **Verify** — run the checks. Never report a check as passing that you did not
|
||||||
@@ -67,6 +68,14 @@ being restated in the prompt.
|
|||||||
|
|
||||||
`/review` runs phase 3 alone. `/wrap` runs phase 6 at session end.
|
`/review` runs phase 3 alone. `/wrap` runs phase 6 at session end.
|
||||||
|
|
||||||
|
**Agent definitions load at session start.** An edit to `.claude/agents/*.md`
|
||||||
|
does not reach the session you made it in — the brief in force is the one that
|
||||||
|
was on disk when the session began. After committing a change to one, **restart
|
||||||
|
before relying on it, and say in the report which version actually ran.** Found
|
||||||
|
2026-08-30: the gloss lens was added to `claims-auditor` and the agent then
|
||||||
|
reconstructed it from the `AGENTS.md` Change Log rather than having it in its
|
||||||
|
brief, which is luck, not process.
|
||||||
|
|
||||||
**Think deeply before acting.** Extended thinking is on by default for this
|
**Think deeply before acting.** Extended thinking is on by default for this
|
||||||
project (`.claude/settings.json`), and `/build` and `/review` request it
|
project (`.claude/settings.json`), and `/build` and `/review` request it
|
||||||
explicitly. The planning and review phases are where it earns its cost — a defect
|
explicitly. The planning and review phases are where it earns its cost — a defect
|
||||||
@@ -90,11 +99,33 @@ an accusation, and do not argue a reviewer down — either fix it, or record the
|
|||||||
reason you declined it so a later reader can see the judgement was made rather
|
reason you declined it so a later reader can see the judgement was made rather
|
||||||
than missed.
|
than missed.
|
||||||
|
|
||||||
**Two reviewers, because they catch different things.** `adversarial-reviewer`
|
**Two reviewers, because they catch different things — but they no longer run at
|
||||||
reads the code. `claims-auditor` reads the copy against the §4 register and knows
|
the same time.** `adversarial-reviewer` reads the code. `claims-auditor` reads the
|
||||||
nothing about whether the code is elegant. A generic reviewer consistently
|
copy against the §4 register and knows nothing about whether the code is elegant.
|
||||||
under-weights the professional-conduct check, which is the highest-stakes failure
|
A generic reviewer consistently under-weights the professional-conduct check,
|
||||||
mode on this project — so it gets its own pass.
|
which is the highest-stakes failure mode on this project — so it keeps its own
|
||||||
|
pass rather than being folded into the code review.
|
||||||
|
|
||||||
|
**D20, 2026-08-30 — the claims pass moved to cutover.** Per step it is
|
||||||
|
`adversarial-reviewer` alone. `claims-auditor` runs **once, over the whole
|
||||||
|
finished site**, as a blocking item on `docs/06`'s cutover checklist. Pouya's
|
||||||
|
reasoning, and it is a calibration and not an erosion: nothing has shipped, so
|
||||||
|
every claims finding so far has been about a page no visitor can reach — the risk
|
||||||
|
is deferred to cutover anyway, and one pass over twenty finished pages catches
|
||||||
|
**more** than nine passes over drafts, because it sees the site as a reader does.
|
||||||
|
The `/med-arb/` ADRIC gloss is the proof: no individual claim was false, the
|
||||||
|
defect was **adjacency**, and adjacency does not exist until the pages sit next to
|
||||||
|
each other. The code reviewer stays per step because what it catches **compounds**
|
||||||
|
— an accessibility or crawlability defect propagates into the next page built on
|
||||||
|
it, and a claims defect does not; it sits there until someone reads it.
|
||||||
|
|
||||||
|
**What it costs is recorded in `AGENTS.md` D20, not summarised away here.** Read
|
||||||
|
it before proposing any further relaxation: `claims-auditor` has caught defects
|
||||||
|
that would have been serious on a live page, and D20 accepts that such a defect
|
||||||
|
may now live in an unpublished draft for weeks. Two things carry that risk in the
|
||||||
|
meantime — **`npm run check:claims`, which is unchanged and runs on every build
|
||||||
|
and both deploy paths**, and **Pouya reading the copy as it is built**. Neither is
|
||||||
|
optional, and neither is a substitute for the cutover pass.
|
||||||
|
|
||||||
## Commands
|
## Commands
|
||||||
|
|
||||||
@@ -221,6 +252,16 @@ argument and the comparison never ran. Prefer `git grep`, quote or array-expand
|
|||||||
anything you pass as flags, and re-check any result whose shape is "uniformly
|
anything you pass as flags, and re-check any result whose shape is "uniformly
|
||||||
bad".
|
bad".
|
||||||
|
|
||||||
|
**And re-check "uniformly GOOD" too — that is the dangerous half.** *Added
|
||||||
|
2026-08-30.* The same `set -- $pair` loop recurred while confirming nine restored
|
||||||
|
files matched a saved copy, and this time it printed **`same` on all nine**:
|
||||||
|
`shasum` was handed both filenames as one argument, errored, and left both
|
||||||
|
variables empty, so `"" = ""` passed. **The `DIFFER` version announces itself
|
||||||
|
because it is alarming; a false pass is the answer you wanted and it ends the
|
||||||
|
check.** A comparison must **assert that both things it compares exist** before
|
||||||
|
comparing them, and `git grep` silently misses untracked files — so a clean sweep
|
||||||
|
across new work means nothing until the files are staged.
|
||||||
|
|
||||||
**A parent cannot style a child component's root element.** Astro does not pass
|
**A parent cannot style a child component's root element.** Astro does not pass
|
||||||
a parent's scope attribute down, so `<Button class="header-cta" />` compiles the
|
a parent's scope attribute down, so `<Button class="header-cta" />` compiles the
|
||||||
parent's rule to `.header-cta[data-astro-cid-<parent>]` while the rendered `<a>`
|
parent's rule to `.header-cta[data-astro-cid-<parent>]` while the rendered `<a>`
|
||||||
@@ -339,6 +380,46 @@ sweep; instances survived all three, and one of them was inside
|
|||||||
`.claude/agents/claims-auditor.md` — the definition of the agent whose job is to
|
`.claude/agents/claims-auditor.md` — the definition of the agent whose job is to
|
||||||
catch exactly that. Recall is not evidence.
|
catch exactly that. Recall is not evidence.
|
||||||
|
|
||||||
|
**And sweep the VOCABULARY, not only the subject.** *Added 2026-08-30, from the
|
||||||
|
Q.Arb amendment.* `git grep 'Q.Arb'` is line-anchored, so it could not find **ten
|
||||||
|
lines in `docs/03` that were entirely about Q.Arb and never named it** — an
|
||||||
|
unstruck, imperative block still instructing the struck form, eleven lines below
|
||||||
|
that change set's own strike notice on the same bullet. The sweep was a real
|
||||||
|
command and its output was read honestly. It was still the wrong command.
|
||||||
|
|
||||||
|
So after sweeping the term, sweep the words its claims are **made of** — here,
|
||||||
|
the stage vocabulary (`commenced`, `in progress`, `pathway`, `not yet`) with no
|
||||||
|
mention of the designation. This is R8's sharpest edge, and it is the one that
|
||||||
|
survives an honest reader: a sweep can pass every test in the rule above and
|
||||||
|
still miss everything, because the anchor you chose is not the anchor the text
|
||||||
|
uses. The same session also excluded `docs/reference/` as "sourced extracts" —
|
||||||
|
half right. The quotations there are evidence; **the commentary around them is
|
||||||
|
this repository's voice**, and three lines of it still asserted the struck row.
|
||||||
|
|
||||||
|
|
||||||
|
**`check:claims` IS FROZEN. It is a tripwire, not a program.** *Pouya's ruling,
|
||||||
|
2026-08-30.* Round 2 of the Q.Arb amendment found **five defects in round 1's own
|
||||||
|
fixes to that script, two of which made it worse than before the pattern
|
||||||
|
existed** — a dedup key that reported two breaches of the same string as one (the
|
||||||
|
check truncating its own output), and a collapsed-text view whose window leapt
|
||||||
|
paragraph boundaries onto approved copy while its comment claimed it could not.
|
||||||
|
At that point it was generating defects at roughly the rate it caught them.
|
||||||
|
|
||||||
|
The rule, and it has no exceptions:
|
||||||
|
|
||||||
|
- **A pattern is added only after a real breach has reached `dist/`.** Never
|
||||||
|
speculatively, never to close a gap you can imagine.
|
||||||
|
- **Each addition ships with a probe** — an injected page proving it catches the
|
||||||
|
actual breach — **and a negative fixture** proving it stays silent on the
|
||||||
|
approved copy nearest to it.
|
||||||
|
- **No refactors. No coverage improvements. No tidying.** If a pattern is wrong,
|
||||||
|
change that pattern deliberately, with a Change Log entry. Do not rewrite the
|
||||||
|
scanner around it.
|
||||||
|
|
||||||
|
Under D20 this script is the only per-step claims control, which is an argument
|
||||||
|
for keeping it **correct**, not for growing it. It catches the §4 breaches that
|
||||||
|
are greppable and makes no claim about the ones that are not.
|
||||||
|
|
||||||
**Comments record decisions, not history — D19.** *"X because D13"* stays.
|
**Comments record decisions, not history — D19.** *"X because D13"* stays.
|
||||||
*"This was Y, then flagged, then became X"* belongs in the `AGENTS.md` Change
|
*"This was Y, then flagged, then became X"* belongs in the `AGENTS.md` Change
|
||||||
Log, which is where a reader looks for how something got here. **A comment
|
Log, which is where a reader looks for how something got here. **A comment
|
||||||
|
|||||||
+14
-3
@@ -213,7 +213,11 @@ to an appointment. This page carries the verifiable record.
|
|||||||
**Job:** convert counsel who have already decided on mediation and are choosing a
|
**Job:** convert counsel who have already decided on mediation and are choosing a
|
||||||
neutral.
|
neutral.
|
||||||
**Search intent:** `commercial mediator Toronto`, `ADRIC mediation rules`,
|
**Search intent:** `commercial mediator Toronto`, `ADRIC mediation rules`,
|
||||||
`what happens at mediation Ontario`.
|
`what happens at mediation Ontario`. **These are queries, not the page's scope —
|
||||||
|
Q56, 2026-08-30.** The mediation offering is **not** scoped commercial (§4's row
|
||||||
|
is unscoped; the arbitration scope is a legal gate and does not transfer). Do not
|
||||||
|
read the first query back into the `<title>` or the copy, which is where
|
||||||
|
*"Commercial Mediation"* came from in the first place.
|
||||||
|
|
||||||
1. What the service is; the neutral's role stated plainly.
|
1. What the service is; the neutral's role stated plainly.
|
||||||
2. **Formats:** full-day, half-day, shuttle, remote, hybrid.
|
2. **Formats:** full-day, half-day, shuttle, remote, hybrid.
|
||||||
@@ -544,8 +548,15 @@ are shared between parties; payment terms. A real page with real numbers, or a
|
|||||||
**Job:** serve the self-represented tier without diluting the counsel-facing
|
**Job:** serve the self-represented tier without diluting the counsel-facing
|
||||||
pages. Plain language, short sentences, no jargon.
|
pages. Plain language, short sentences, no jargon.
|
||||||
|
|
||||||
What mediation is · what it is not · who the mediator is and is not (not your
|
What mediation is · what it is not · who the mediator is and is not —
|
||||||
lawyer, not a judge) · what happens on the day · what it costs · what happens if
|
**render `NEUTRAL_ROLE_LINE`, and read `docs/03` §For parties before writing a
|
||||||
|
word of it.** ⚠️ **THIS LINE READ *"(not your lawyer, not a judge)"* UNTIL
|
||||||
|
2026-08-30 AND IT INSTRUCTED A FORM STRUCK ON 2026-08-28.** *"Not your lawyer"*
|
||||||
|
**presupposes lawyer status**, which §4 Forbidden bars and D13 treats as hard as
|
||||||
|
assertion — a negation still carries the presupposition. `docs/03` struck it
|
||||||
|
with that reasoning two days earlier and the sweep never reached this file;
|
||||||
|
build step 6 is the step that consumes this line, and it was found here by
|
||||||
|
`adversarial-reviewer` while the page itself avoided the trap · what happens on the day · what it costs · what happens if
|
||||||
you do not settle · how to prepare.
|
you do not settle · how to prepare.
|
||||||
|
|
||||||
### `/insights/` and `/insights/[slug]/`
|
### `/insights/` and `/insights/[slug]/`
|
||||||
|
|||||||
+49
-1
@@ -92,6 +92,38 @@ detect padding instantly and discount everything after it.
|
|||||||
scoped; found by `claims-auditor` on re-audit, one file over from the same
|
scoped; found by `claims-auditor` on re-audit, one file over from the same
|
||||||
defect fixed in `docs/04` earlier the same day.
|
defect fixed in `docs/04` earlier the same day.
|
||||||
|
|
||||||
|
⚠️ **AND THE MEDIATION HALF IS THE OPPOSITE — Q56, ruled by Pouya 2026-08-30.
|
||||||
|
DO NOT MIRROR THIS SCOPE ONTO MEDIATION.** The scope above exists because of a
|
||||||
|
**legal gate**: family arbitration in Ontario requires prescribed training, so
|
||||||
|
"in commercial matters" is load-bearing there. **Mediation has no such gate,
|
||||||
|
§4's mediation row is unscoped on purpose.** Pouya's list of what he mediates
|
||||||
|
— *"commercial, construction, insurance/SABS, shareholder and cross-cultural
|
||||||
|
matters"* — is **illustrative of breadth, not a closed set**: the site
|
||||||
|
publishes **six** areas and every one of them offers mediation
|
||||||
|
(`src/data/practice-pages.ts`), technology and energy included. Do not read it
|
||||||
|
as the authorised subject-matter list; §4's Q35 gate governs that.
|
||||||
|
|
||||||
|
The site-wide *"Commercial Mediation"* framing was **under-describing the
|
||||||
|
offering**, and it was corrected rather than ratified as positioning. The
|
||||||
|
asymmetry between the two halves is designed; a later editor tidying them into
|
||||||
|
a matching pair would be reintroducing the defect.
|
||||||
|
|
||||||
|
⚠️ **AND DO NOT TREAT ANY LIST OF THE CORRECTED SURFACES AS COMPLETE.** Q56
|
||||||
|
named four. The sweep that implemented it changed **thirteen shipped strings
|
||||||
|
across five files**, and `adversarial-reviewer` then found **three more it had
|
||||||
|
missed** — the worst on `/practice/`, where *"These describe the process the
|
||||||
|
parties are choosing between, in commercial matters"* scoped mediation with
|
||||||
|
the two words never appearing in the same element, so no proximity grep could
|
||||||
|
reach it. The command, and its limit:
|
||||||
|
|
||||||
|
```
|
||||||
|
git grep -nEi 'commercial[^.]{0,60}mediat|mediat[^.]{0,60}commercial' -- src/
|
||||||
|
```
|
||||||
|
|
||||||
|
That finds the **adjacent** form only. For the split form there is no pattern —
|
||||||
|
read every occurrence of `commercial` in `src/` and in `dist/`, and ask what
|
||||||
|
each one is scoping.
|
||||||
|
|
||||||
⚠️ **TEN LINES WERE DELETED HERE ON 2026-08-30, AND THE DELETION IS THE
|
⚠️ **TEN LINES WERE DELETED HERE ON 2026-08-30, AND THE DELETION IS THE
|
||||||
POINT.** They read *"'Pathway', never 'designation'"*, cited the **struck**
|
POINT.** They read *"'Pathway', never 'designation'"*, cited the **struck**
|
||||||
Forbidden row as live, instructed that *"the limit being named is the stage of
|
Forbidden row as live, instructed that *"the limit being named is the stage of
|
||||||
@@ -430,7 +462,23 @@ Drafted by Claude, **every word reviewed by Pouya before publication**:
|
|||||||
## Compliance checklist — before any page ships
|
## Compliance checklist — before any page ships
|
||||||
|
|
||||||
- [ ] Every factual claim appears in `AGENTS.md` §4 Verified
|
- [ ] Every factual claim appears in `AGENTS.md` §4 Verified
|
||||||
- [ ] No matter counts, settlement rates, dollar figures, or time-to-award stats
|
- [ ] No matter counts, settlement rates, claimed matter values, or
|
||||||
|
time-to-award stats. ⚠️ **SCOPED 2026-08-30, and it read "dollar figures"
|
||||||
|
until then.** What this bars is the **fabricated-statistic family** the old
|
||||||
|
site carried — *"420+ matters"*, *"$3.8B resolved"*, *"93% settled"*. It
|
||||||
|
does **not** bar the **rate card**: D8 commits to publishing it in full and
|
||||||
|
D14 confirms the numbers `[verified 2026-08-26 — Pouya]`, so `/fees/`
|
||||||
|
publishes all of them and `/for-parties/` publishes the two mediation rates
|
||||||
|
because `docs/01` requires that page to answer *"what it costs"*. Read
|
||||||
|
literally, the old wording forbade the page the architecture spec commits
|
||||||
|
to. **§4's own row was never wrong** — it reads *"Aggregate value resolved;
|
||||||
|
any dollar figure attached to **past matters**"*, and this checklist
|
||||||
|
dropped the qualifier when it mirrored it. A duplicated fact is a fact that
|
||||||
|
will eventually be wrong in one place, and the copy that goes stale is the
|
||||||
|
one nobody re-reads. **Third instance of an unscoped checklist line flagging the copy the
|
||||||
|
spec requires** — the other two are the testimonials item
|
||||||
|
immediately below and the capacity-phrasing item further down, and in both
|
||||||
|
cases the checklist is what gets grepped
|
||||||
- [ ] No testimonials, endorsements, or third-party quotes **about the practice
|
- [ ] No testimonials, endorsements, or third-party quotes **about the practice
|
||||||
or about Pouya**. Scope matters: `docs/01` §`/med-arb/` **directs** the page
|
or about Pouya**. Scope matters: `docs/01` §`/med-arb/` **directs** the page
|
||||||
to quote ADRIC's own framing of med-arb, and `/mediation/` and
|
to quote ADRIC's own framing of med-arb, and `/mediation/` and
|
||||||
|
|||||||
+18
-1
@@ -342,7 +342,24 @@ Then invalidate `/*`.
|
|||||||
## Cutover checklist — D11 is a single shot, so run all of it
|
## Cutover checklist — D11 is a single shot, so run all of it
|
||||||
|
|
||||||
**Content and compliance**
|
**Content and compliance**
|
||||||
- [ ] Every claim traced to `AGENTS.md` §4 Verified
|
|
||||||
|
> ⚠️ **THE FIRST TWO ITEMS ARE THE PROJECT'S ONLY FULL CLAIMS PASS — D20, Pouya,
|
||||||
|
> 2026-08-30.** `claims-auditor` no longer runs per build step; `/build` Phase 3
|
||||||
|
> is `adversarial-reviewer` alone. Everything the register is meant to prevent
|
||||||
|
> therefore lands here. `AGENTS.md` D20 records both the reasoning and what
|
||||||
|
> deferring it costs — read it before treating either item as a formality, and do
|
||||||
|
> not tick one because `npm run check:claims` is green. That script is a greppable
|
||||||
|
> tripwire; it cannot read a page.
|
||||||
|
|
||||||
|
- [ ] **`claims-auditor` run over EVERY page in `dist/`, findings resolved.**
|
||||||
|
**This is the project's only full claims pass. Nothing publishes until it
|
||||||
|
is clean.** Not per-page in isolation — the pass exists here because the
|
||||||
|
defects worth catching late are the ones that only exist once the pages sit
|
||||||
|
next to each other. Give it the whole built site and the reading order a
|
||||||
|
visitor takes.
|
||||||
|
- [ ] **Pouya has read every page against `AGENTS.md` §4.** The human pass. It is
|
||||||
|
the other half of D20 and it is not delegable — his reading is what the
|
||||||
|
per-step audit was traded for.
|
||||||
- [ ] **Memberships RE-CONFIRMED AGAIN, on the day of cutover** — `AGENTS.md`
|
- [ ] **Memberships RE-CONFIRMED AGAIN, on the day of cutover** — `AGENTS.md`
|
||||||
§12 **R10**, which is now an **event trigger and cutover is one of its two
|
§12 **R10**, which is now an **event trigger and cutover is one of its two
|
||||||
events.** Q44 closed 2026-08-28 and the group is published on `/about/`
|
events.** Q44 closed 2026-08-28 and the group is published on `/about/`
|
||||||
|
|||||||
@@ -14,9 +14,9 @@ it does not need restating in every prompt.
|
|||||||
|
|
||||||
That single command runs: plan → implement → adversarial review → resolve →
|
That single command runs: plan → implement → adversarial review → resolve →
|
||||||
verify → record. It requests deep reasoning, reads `AGENTS.md` and the specs,
|
verify → record. It requests deep reasoning, reads `AGENTS.md` and the specs,
|
||||||
stops if the task conflicts with a locked decision, invokes two independent
|
stops if the task conflicts with a locked decision, invokes `adversarial-reviewer`
|
||||||
reviewers on the finished diff, resolves what they find, runs the checks, and
|
on the finished diff, resolves what it finds, runs the checks, and appends the
|
||||||
appends the Change Log entry.
|
Change Log entry.
|
||||||
|
|
||||||
You do not need to ask for thinking, for review, or for the record to be updated.
|
You do not need to ask for thinking, for review, or for the record to be updated.
|
||||||
Those are the agreement, not the request.
|
Those are the agreement, not the request.
|
||||||
@@ -26,29 +26,53 @@ Those are the agreement, not the request.
|
|||||||
| Command | Does |
|
| Command | Does |
|
||||||
|---|---|
|
|---|---|
|
||||||
| `/build <task>` | The full loop. Use for every substantive change |
|
| `/build <task>` | The full loop. Use for every substantive change |
|
||||||
| `/review [scope]` | The review pass alone, on the working tree or a named scope. Reports; fixes nothing without your say-so |
|
| `/review [scope]` | The **code** review alone, on the working tree or a named scope. Reports; fixes nothing without your say-so. Under D20 it does not run the claims pass |
|
||||||
| `/wrap` | End of session — updates `AGENTS.md` under its constitution and leaves the tree clean |
|
| `/wrap` | End of session — updates `AGENTS.md` under its constitution and leaves the tree clean |
|
||||||
|
|
||||||
## The two reviewers
|
## The two reviewers, and when each of them runs — D20
|
||||||
|
|
||||||
Both are defined in `.claude/agents/` and run in parallel on the diff.
|
Both are defined in `.claude/agents/`. **They no longer run together.**
|
||||||
|
|
||||||
**`adversarial-reviewer`** reads the code: correctness and edge cases,
|
**`adversarial-reviewer` runs on every build step.** It reads the code:
|
||||||
accessibility, crawlability, performance budgets, security, and whether a
|
correctness and edge cases, accessibility, crawlability, performance budgets,
|
||||||
materially simpler correct version exists.
|
security, and whether a materially simpler correct version exists.
|
||||||
|
|
||||||
**`claims-auditor`** reads the copy against `AGENTS.md` §4 and nothing else. It
|
**`claims-auditor` runs once, at cutover, over the whole finished site.** It reads
|
||||||
extracts every factual assertion — credentials, roles, numbers, languages,
|
the copy against `AGENTS.md` §4 and nothing else — extracting every factual
|
||||||
locations, capabilities, and the JSON-LD — and traces each to the Verified table.
|
assertion (credentials, roles, numbers, languages, locations, capabilities, and
|
||||||
Anything untraceable is reported and does not ship.
|
the JSON-LD) and tracing each to the Verified table. Anything untraceable is
|
||||||
|
reported and does not ship. `docs/06`'s cutover checklist carries it as a blocking
|
||||||
|
item, alongside your own read of every page against §4.
|
||||||
|
|
||||||
It is a separate agent on purpose. A general-purpose reviewer will happily
|
It is a separate agent on purpose. A general-purpose reviewer will happily
|
||||||
approve elegant code containing a claim that should never have been published,
|
approve elegant code containing a claim that should never have been published,
|
||||||
because professional-conduct compliance is not what it is looking at. On this
|
because professional-conduct compliance is not what it is looking at. On this
|
||||||
project that is the highest-stakes failure mode, so it gets its own pass.
|
project that is the highest-stakes failure mode, so it keeps its own pass.
|
||||||
|
|
||||||
**Verifying they are loaded.** `.claude/agents/` is the correct location. To
|
### Why the claims pass moved, and what it costs
|
||||||
confirm the agents are live, invoke one directly:
|
|
||||||
|
Your ruling, 2026-08-30. `AGENTS.md` D20 carries it in full; the short form:
|
||||||
|
|
||||||
|
- **Nothing has shipped.** Every claims finding to date has been about a page no
|
||||||
|
visitor can reach. The risk is deferred to cutover whether or not the audit is.
|
||||||
|
- **One pass over twenty finished pages catches more than nine over drafts**,
|
||||||
|
because it reads the site as a visitor does. The `/med-arb/` ADRIC gloss is the
|
||||||
|
proof: no individual claim was false, the defect was **adjacency**, and
|
||||||
|
adjacency does not exist until the pages sit next to each other.
|
||||||
|
- **The code reviewer stays per step because what it catches compounds.** An
|
||||||
|
accessibility or crawlability defect propagates into the next page built on it.
|
||||||
|
A claims defect does not compound; it sits there until someone reads it.
|
||||||
|
|
||||||
|
**What it costs, stated rather than glossed:** a claims defect can now live in an
|
||||||
|
unpublished draft for weeks. Two things carry that risk in the meantime, and
|
||||||
|
neither is a substitute for the cutover pass — **`npm run check:claims`**, which
|
||||||
|
is unchanged and runs on every build and both deploy paths, and **you reading the
|
||||||
|
copy as it is built.**
|
||||||
|
|
||||||
|
## Verifying the agents are loaded
|
||||||
|
|
||||||
|
**`.claude/agents/` is the correct location.** To confirm the agents are live,
|
||||||
|
invoke one directly:
|
||||||
|
|
||||||
```
|
```
|
||||||
Use the claims-auditor agent to audit README.md against AGENTS.md §4.
|
Use the claims-auditor agent to audit README.md against AGENTS.md §4.
|
||||||
@@ -57,20 +81,29 @@ Use the claims-auditor agent to audit README.md against AGENTS.md §4.
|
|||||||
A verdict table back means both are wired. "No such agent" means the frontmatter
|
A verdict table back means both are wired. "No such agent" means the frontmatter
|
||||||
needs looking at.
|
needs looking at.
|
||||||
|
|
||||||
|
**Agent definitions load at session start.** An edit to `.claude/agents/*.md`
|
||||||
|
does not reach a running session — the version in force is the one that was on
|
||||||
|
disk when the session began. So after changing a brief, restart before relying on
|
||||||
|
it, and **say in the report which version actually ran.** This is not theoretical:
|
||||||
|
the gloss lens was added to `claims-auditor` on 2026-08-30 and the agent
|
||||||
|
reconstructed it from the Change Log rather than having it in its brief, because
|
||||||
|
the edit and the run were in the same session.
|
||||||
|
|
||||||
**Both are instructed to treat uncertainty as a defect.** They will sometimes be
|
**Both are instructed to treat uncertainty as a defect.** They will sometimes be
|
||||||
wrong. That is the intended trade: explaining why a finding is mistaken costs
|
wrong. That is the intended trade: explaining why a finding is mistaken costs
|
||||||
minutes, and a missed defect on this project's public marketing pages
|
minutes, and a missed defect on this project's public marketing pages
|
||||||
costs a great deal more.
|
costs a great deal more. **This weighs heavier on the cutover pass, not lighter**
|
||||||
|
— there is nothing behind it, so D19's two-round cap does not apply there.
|
||||||
|
|
||||||
## The rule that makes it work
|
## The rule that makes it work
|
||||||
|
|
||||||
**The reviewers are given the diff and the specs — never the implementer's
|
**A reviewer is given the diff and the specs — never the implementer's
|
||||||
explanation of why the work is correct.**
|
explanation of why the work is correct.**
|
||||||
|
|
||||||
A rationale anchors the reviewer. Told why something is right, a reviewer looks
|
A rationale anchors the reviewer. Told why something is right, a reviewer looks
|
||||||
for confirmation and finds it; given only the artefact, it forms an independent
|
for confirmation and finds it; given only the artefact, it forms an independent
|
||||||
view. That independence is the entire mechanism. Every other detail of this
|
view. That independence is the entire mechanism. Every other detail of this
|
||||||
protocol is adjustable. This one is not.
|
protocol is adjustable — D20 just adjusted one of them. This one is not.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -135,3 +168,7 @@ see that judgement was exercised rather than the finding missed.
|
|||||||
**A check reported as passing that was not run.** "Should pass" is not a result.
|
**A check reported as passing that was not run.** "Should pass" is not a result.
|
||||||
If a build, a Lighthouse run, or a JavaScript-disabled render was not actually
|
If a build, a Lighthouse run, or a JavaScript-disabled render was not actually
|
||||||
executed, it must say so.
|
executed, it must say so.
|
||||||
|
|
||||||
|
**A report that says "reviewed" without naming which agent ran.** Under D20 a
|
||||||
|
build step gets `adversarial-reviewer` and not the claims pass; "reviewed" reads
|
||||||
|
as both. The report must name the one that ran.
|
||||||
|
|||||||
+45
-23
@@ -203,7 +203,7 @@ export function professionalServiceNode(imageUrl?: string) {
|
|||||||
slogan: SITE.tagline,
|
slogan: SITE.tagline,
|
||||||
url: `${SITE.url}/`,
|
url: `${SITE.url}/`,
|
||||||
description:
|
description:
|
||||||
'Commercial mediation and arbitration for construction, technology, ' +
|
'Mediation and commercial arbitration for construction, technology, ' +
|
||||||
'energy, insurance, shareholder and cross-border disputes. Toronto, ' +
|
'energy, insurance, shareholder and cross-border disputes. Toronto, ' +
|
||||||
'by appointment. Q.Med and Q.Arb designations held.',
|
'by appointment. Q.Med and Q.Arb designations held.',
|
||||||
provider: { '@id': PERSON_ID },
|
provider: { '@id': PERSON_ID },
|
||||||
@@ -416,25 +416,58 @@ export function practiceAreaGraph(opts: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* `/practice/` — the index. **The Person node and nothing else.**
|
* A page that offers no `Service` of its own — the Person node alone.
|
||||||
*
|
*
|
||||||
* NO `Service` NODES FOR THE SIX AREAS (each page emits its own), NONE FOR THE
|
* `/practice/` and `/process/` are both this shape: they describe how the
|
||||||
* "also offered" STRIP, AND NO `CollectionPage`. The strip is the constraint to
|
* practice works rather than offering something a crawler should lift as a
|
||||||
* keep: all three are PUBLISHABLE (§4, Q46(a)) but gate 1 on each reads
|
* service. `/process/` in particular must NOT emit one — the five timings are
|
||||||
* `[Pouya's stated basis]`, not `[verified]`, and ENE is §4's "offering nearest
|
* publishable only under Q43's framing sentence, and a `Service` node would
|
||||||
* the NOT-NEGOTIABLE boundary" — a visible strip read in context is not the
|
* carry the numbers into a field where no framing travels with them.
|
||||||
* same claim as a machine-readable service type a crawler lifts alone. Adding
|
|
||||||
* any of them needs docs/04 changed first, not this file.
|
|
||||||
*
|
*
|
||||||
* No `BreadcrumbList`: one hop from the root, no visible trail.
|
* No `BreadcrumbList` on either: one hop from the root, no visible trail.
|
||||||
*/
|
*/
|
||||||
export function practiceIndexGraph(imageUrl?: string) {
|
export function pageGraph(imageUrl?: string) {
|
||||||
return {
|
return {
|
||||||
'@context': 'https://schema.org',
|
'@context': 'https://schema.org',
|
||||||
'@graph': [personNode(imageUrl)],
|
'@graph': [personNode(imageUrl)],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** `FAQPage` — built from the array the page renders, never a second copy. */
|
||||||
|
function faqNode(path: string, faq: ReadonlyArray<{ q: string; a: string }>) {
|
||||||
|
return {
|
||||||
|
'@type': 'FAQPage',
|
||||||
|
'@id': `${SITE.url}${path}#faq`,
|
||||||
|
mainEntity: faq.map((item) => ({
|
||||||
|
'@type': 'Question',
|
||||||
|
name: item.q,
|
||||||
|
acceptedAnswer: { '@type': 'Answer', text: item.a },
|
||||||
|
})),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* `/for-parties/` — the Person node and a `FAQPage`. **No `Service` node.**
|
||||||
|
*
|
||||||
|
* docs/04 lists `FAQPage` for this page, under the condition that decides it:
|
||||||
|
* *"Only where the visible page genuinely is Q&A. Never fabricate questions to
|
||||||
|
* farm a rich result."* The page is written as questions a party actually asks,
|
||||||
|
* and this node is built from the same array it renders — so a question cannot
|
||||||
|
* enter the structured data without appearing on the page.
|
||||||
|
*
|
||||||
|
* The Service nodes for mediation live on `/mediation/`. This page explains a
|
||||||
|
* process to the party on the other side of it; it is not a second offer of it.
|
||||||
|
*/
|
||||||
|
export function forPartiesGraph(opts: {
|
||||||
|
faq: ReadonlyArray<{ q: string; a: string }>;
|
||||||
|
imageUrl?: string;
|
||||||
|
}) {
|
||||||
|
return {
|
||||||
|
'@context': 'https://schema.org',
|
||||||
|
'@graph': [personNode(opts.imageUrl), faqNode('/for-parties/', opts.faq)],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* `/med-arb/`'s graph — the Service, the Person, and a `FAQPage`.
|
* `/med-arb/`'s graph — the Service, the Person, and a `FAQPage`.
|
||||||
*
|
*
|
||||||
@@ -460,17 +493,6 @@ export function medArbGraph(opts: {
|
|||||||
});
|
});
|
||||||
return {
|
return {
|
||||||
...base,
|
...base,
|
||||||
'@graph': [
|
'@graph': [...base['@graph'], faqNode('/med-arb/', opts.faq)],
|
||||||
...base['@graph'],
|
|
||||||
{
|
|
||||||
'@type': 'FAQPage',
|
|
||||||
'@id': `${SITE.url}/med-arb/#faq`,
|
|
||||||
mainEntity: opts.faq.map((item) => ({
|
|
||||||
'@type': 'Question',
|
|
||||||
name: item.q,
|
|
||||||
acceptedAnswer: { '@type': 'Answer', text: item.a },
|
|
||||||
})),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
+12
-3
@@ -481,9 +481,18 @@ export const FEES = {
|
|||||||
currency: 'CAD',
|
currency: 'CAD',
|
||||||
taxNote: 'All fees are plus HST.',
|
taxNote: 'All fees are plus HST.',
|
||||||
mediation: {
|
mediation: {
|
||||||
/** Prep is bundled AND stated on the page — [verified 2026-08-26].
|
/** Prep is bundled AND stated IN HOURS on the page — [verified 2026-08-26].
|
||||||
* Do not hide it: at these rates, saying preparation is included is the
|
* `docs/07`: *"'including 2 hours of preparation'… Do not quietly fold it
|
||||||
* point, not a detail. */
|
* into the hours figure."* The allowance is CAPPED, so the unqualified
|
||||||
|
* "preparation included" sells an uncapped one. `/for-parties/` shipped
|
||||||
|
* that form for one pass and `prepIncluded` had no consumer anywhere.
|
||||||
|
*
|
||||||
|
* ⚠️ `hours` IS NOT DOCUMENTED AS THE LENGTH OF THE DAY — §9 Q58, OPEN.
|
||||||
|
* `docs/07`'s card reads "Half day — up to 3.5 h, INCLUDING 2 h
|
||||||
|
* preparation", which makes 3.5 the billed envelope and the room time
|
||||||
|
* 1.5 h. Against that: 3.5 and 7 are exactly 2×, which they would not be
|
||||||
|
* if prep sat inside them. One of the two is wrong. **Do not publish this
|
||||||
|
* number as a duration until Q58 is answered.** */
|
||||||
halfDay: { amount: 2000, hours: 3.5, prepIncluded: 2 },
|
halfDay: { amount: 2000, hours: 3.5, prepIncluded: 2 },
|
||||||
fullDay: { amount: 4000, hours: 7, prepIncluded: 3 },
|
fullDay: { amount: 4000, hours: 7, prepIncluded: 3 },
|
||||||
additionalParty: 500, // each party beyond two
|
additionalParty: 500, // each party beyond two
|
||||||
|
|||||||
+9
-12
@@ -304,22 +304,19 @@ const CREDENTIAL_GROUPS = [
|
|||||||
precisely because this page is where the framing now does its
|
precisely because this page is where the framing now does its
|
||||||
heaviest work.
|
heaviest work.
|
||||||
|
|
||||||
"I MEDIATE COMMERCIAL DISPUTES" STAYS, and a round-2 finding against
|
THE MEDIATION HALF CARRIES NO SCOPE, AND THE ASYMMETRY IS
|
||||||
it was declined rather than missed. The objection: the same ground
|
DELIBERATE — Q56, ruled 2026-08-30. Arbitration is scoped commercial
|
||||||
that struck "The matters I take are commercial" from the biography
|
because of a legal gate (Q39: family arbitration in Ontario requires
|
||||||
should reach this sentence too. It does not. **That one was a
|
prescribed training). Mediation has no such gate and §4's row is
|
||||||
universal** — it said nothing he takes is non-commercial, which is an
|
unscoped. Do not restore "commercial" to the mediation half to make
|
||||||
exclusion §4 has no row for. **This one is existential**: he mediates
|
the two read as a pair. */
|
||||||
commercial disputes, which §4 Offerings' mediation row supports and
|
|
||||||
which excludes nothing. A narrower claim than the row grants is
|
|
||||||
safe; a claim the row does not reach is not. */
|
|
||||||
}
|
}
|
||||||
<p class="hero-lede">
|
<p class="hero-lede">
|
||||||
I am {ROLE.title} at {ROLE.at}, with {ROLE.litigationLine} across{' '}
|
I am {ROLE.title} at {ROLE.at}, with {ROLE.litigationLine} across{' '}
|
||||||
{ROLE.litigationAreas.slice(0, -1).join(', ')} and{' '}
|
{ROLE.litigationAreas.slice(0, -1).join(', ')} and{' '}
|
||||||
{ROLE.litigationAreas.at(-1)}. I mediate commercial disputes and I
|
{ROLE.litigationAreas.at(-1)}. I mediate. I accept arbitration
|
||||||
accept arbitration appointments in commercial matters. I also work as
|
appointments in commercial matters. I also work as a machine-learning
|
||||||
a machine-learning and infrastructure engineer.
|
and infrastructure engineer.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,250 @@
|
|||||||
|
---
|
||||||
|
/**
|
||||||
|
* `/for-parties/` — build step 6. Spec: docs/01 §`/for-parties/`, docs/03 §For
|
||||||
|
* parties. The one page written in the second person, at a grade-9 reading
|
||||||
|
* level, for a party who may be arriving without counsel.
|
||||||
|
*
|
||||||
|
* ⚠️ THIS IS THE PAGE `docs/03` NAMES AS THE PLACE THE BARRED PHRASING FEELS
|
||||||
|
* MOST NATURAL AND IS MOST WRONG. Two forms are struck and must never come
|
||||||
|
* back: *"the mediator is not your lawyer"* — which presupposes lawyer status,
|
||||||
|
* and D13 treats implication as hard as assertion — and *"cannot give you legal
|
||||||
|
* advice"*, a denial of a capacity §4 records as `[unestablished]` and
|
||||||
|
* instructs this repository to answer neither way. `NEUTRAL_ROLE_LINE` is the
|
||||||
|
* ratified pattern: role, then consequence for the reader, no verb of capacity.
|
||||||
|
* It is rendered, never retyped, and it took three attempts and two audits.
|
||||||
|
*
|
||||||
|
* ⚠️ AND THE WORD "LAWYER" DOES NOT APPEAR ON THIS PAGE, DELIBERATELY. §4 bars
|
||||||
|
* it *used of Pouya*, and every natural use here is about the READER — "do I
|
||||||
|
* need my own lawyer", "coming without a lawyer". Those are compliant on §4's
|
||||||
|
* wording and `check:claims` still fails the build on them, because a bare
|
||||||
|
* `\blawyer\b` cannot tell whose. The gate is not wrong: this is the page
|
||||||
|
* `docs/03` names as where the barred phrasing is most tempting, and a broad
|
||||||
|
* pattern is the right shape there. The copy moved instead — "your own legal
|
||||||
|
* advice", which is `NEUTRAL_ROLE_LINE`'s own wording. Same call, and the same
|
||||||
|
* direction, as "my client" → "our client" on `/med-arb/`.
|
||||||
|
*
|
||||||
|
* ⚠️ THE FAQ ARRAY IS THE ONLY SOURCE. It is rendered visibly AND fed to the
|
||||||
|
* `FAQPage` node, because docs/04 allows the node here "only where the visible
|
||||||
|
* page genuinely is Q&A" — so a question cannot reach the structured data
|
||||||
|
* without appearing on the page, and the two cannot drift.
|
||||||
|
*
|
||||||
|
* ⚠️ THE FEE FIGURES ARE INTERPOLATED FROM `FEES`, NOT TYPED. D14's card is one
|
||||||
|
* source; a second hand-typed copy on the page a party reads is the copy that
|
||||||
|
* goes stale, and it goes stale silently.
|
||||||
|
*
|
||||||
|
* ⚠️ AND THE BUNDLED PREPARATION IS STATED IN HOURS, NEVER AS "PREPARATION
|
||||||
|
* INCLUDED". `docs/07` §All parameters confirmed is explicit: *"Preparation time
|
||||||
|
* is bundled and MUST be stated on the page — 'including 2 hours of
|
||||||
|
* preparation'… Do not quietly fold it into the hours figure."* The allowance is
|
||||||
|
* CAPPED, so the unqualified form sells an uncapped one. This page shipped
|
||||||
|
* "with preparation included" for one pass; `adversarial-reviewer` found it, and
|
||||||
|
* `prepIncluded` had been declared in `site.ts` with no consumer anywhere.
|
||||||
|
*
|
||||||
|
* ⚠️ AND THIS PAGE DOES NOT STATE HOW LONG A MEDIATION DAY IS — see §9 Q58.
|
||||||
|
* `docs/07`'s card reads *"Half day — up to 3.5 h, INCLUDING 2 h preparation"*,
|
||||||
|
* which makes 3.5 the billed envelope and the room time 1.5 h. `FEES.mediation
|
||||||
|
* .halfDay.hours` documents neither reading. A draft answered "what happens on
|
||||||
|
* the day" with "about 3.5 hours", which is the envelope presented as the day,
|
||||||
|
* to the reader least able to check it. Do not restore a duration here until
|
||||||
|
* Q58 is answered.
|
||||||
|
*/
|
||||||
|
import BaseLayout from '../layouts/BaseLayout.astro';
|
||||||
|
import Button from '../components/Button.astro';
|
||||||
|
import ContactBand from '../components/ContactBand.astro';
|
||||||
|
import Eyebrow from '../components/Eyebrow.astro';
|
||||||
|
import SectionHeading from '../components/SectionHeading.astro';
|
||||||
|
import Undertaking from '../components/Undertaking.astro';
|
||||||
|
import { getImage } from 'astro:assets';
|
||||||
|
import ogDefault from '../assets/og-portrait.jpg';
|
||||||
|
import { forPartiesGraph } from '../data/schema';
|
||||||
|
import { CONDUCT_UNDERTAKINGS, FEES, NEUTRAL_ROLE_LINE } from '../data/site';
|
||||||
|
|
||||||
|
const ldImage = await getImage({
|
||||||
|
src: ogDefault,
|
||||||
|
format: 'jpeg',
|
||||||
|
width: 1200,
|
||||||
|
height: 630,
|
||||||
|
});
|
||||||
|
|
||||||
|
const money = (amount: number) =>
|
||||||
|
new Intl.NumberFormat('en-CA', {
|
||||||
|
style: 'currency',
|
||||||
|
currency: FEES.currency,
|
||||||
|
maximumFractionDigits: 0,
|
||||||
|
}).format(amount);
|
||||||
|
|
||||||
|
const FAQ = [
|
||||||
|
{
|
||||||
|
q: 'What is a mediation?',
|
||||||
|
a: 'It is a meeting to try to settle a dispute without a hearing. Everyone involved comes. I run the meeting. I do not decide who is right.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
q: 'Are you on anyone’s side?',
|
||||||
|
a: 'No. I run the process for everyone in the room at once. If I ran it for one side it would settle nothing, and the other side would be right not to come.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
q: 'Should I get my own legal advice?',
|
||||||
|
a: 'What you sign at the end of a mediation is an agreement, so it is worth having someone look at your own position before the day rather than after it. If nobody is advising you, say so at the start.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
q: 'What happens on the day?',
|
||||||
|
a: 'I usually start with everyone in one room. After that the parties often sit separately and I move between them. Some matters run that way from the beginning, with the parties never in the same room. You book either a half day or a full day, and which one you need is settled before the date is fixed.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
q: 'Does what I say stay private?',
|
||||||
|
a: 'The terms everyone signs at the start deal with confidentiality. A caucus is when I meet one side on their own, without the other side there. One part of what happens in it is mine rather than the document’s:',
|
||||||
|
/* Rendered through <Undertaking> below, not as body prose — §4's third
|
||||||
|
class gets one treatment across the site so a reader can tell a promise
|
||||||
|
from a description. The graph gets lead and promise as one answer. */
|
||||||
|
undertaking: CONDUCT_UNDERTAKINGS.mediationCaucus,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
q: 'What does it cost, and who pays?',
|
||||||
|
a: `${money(FEES.mediation.halfDay.amount)} for a half day, including ${FEES.mediation.halfDay.prepIncluded} hours of preparation, and ${money(FEES.mediation.fullDay.amount)} for a full day, including ${FEES.mediation.fullDay.prepIncluded} hours. ${FEES.taxNote} ${FEES.terms[0]}`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
q: 'What if we do not settle?',
|
||||||
|
a: 'Then the mediation ends without an agreement. Nothing you said becomes a ruling, because I do not make one. What gets written down is only what everyone agrees to write down.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
q: 'How do I get ready?',
|
||||||
|
a: 'Bring the documents that matter, not all of them. Know the number you would accept and the number you would walk away at. Bring someone who can agree to a settlement on the day, or be able to reach them quickly. Expect to be asked what the weakest part of your own case is.',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
/* ONE SOURCE, TWO SHAPES. The page renders the lead-in and the undertaking as
|
||||||
|
separate elements; a `FAQPage` answer is plain text, so the node gets them
|
||||||
|
joined. Neither is typed twice. */
|
||||||
|
const graph = forPartiesGraph({
|
||||||
|
faq: FAQ.map(({ q, a, undertaking }) => ({
|
||||||
|
q,
|
||||||
|
a: undertaking ? `${a} ${undertaking}` : a,
|
||||||
|
})),
|
||||||
|
imageUrl: new URL(ldImage.src, Astro.site).href,
|
||||||
|
});
|
||||||
|
---
|
||||||
|
|
||||||
|
<BaseLayout
|
||||||
|
title="For Parties · What Happens at a Mediation · Pouya Lajevardi"
|
||||||
|
description="What happens at a mediation, in plain language: who the mediator is, what the day looks like, what it costs and who pays, and how to get ready."
|
||||||
|
jsonLd={graph}
|
||||||
|
>
|
||||||
|
{/* ---- 1. Hero -------------------------------------------------------- */}
|
||||||
|
<section class="section hero">
|
||||||
|
<div class="wrap">
|
||||||
|
<Eyebrow dot>For parties</Eyebrow>
|
||||||
|
<h1 class="display hero-h">What happens at a mediation.</h1>
|
||||||
|
<p class="hero-lede">
|
||||||
|
This page is for you if you are going to a mediation and nobody has
|
||||||
|
explained what one is. It is the same day the rest of this site
|
||||||
|
describes, written without the shorthand.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* ---- 2. The role, before anything else ------------------------------ */}
|
||||||
|
{
|
||||||
|
/* NEUTRAL_ROLE_LINE gets its own section rather than a slot in the FAQ.
|
||||||
|
docs/03 requires this page to say it explicitly, and the sentence a party
|
||||||
|
most needs is not one to make them scroll for. */
|
||||||
|
}
|
||||||
|
<section class="section section-alt reveal">
|
||||||
|
<div class="wrap">
|
||||||
|
<div class="section-head">
|
||||||
|
<SectionHeading eyebrow="First" level={2}>
|
||||||
|
<span slot="heading">Who I am in the room.</span>
|
||||||
|
</SectionHeading>
|
||||||
|
</div>
|
||||||
|
<div class="prose">
|
||||||
|
<p class="statement">{NEUTRAL_ROLE_LINE}</p>
|
||||||
|
<p>
|
||||||
|
I also do not decide who is right. There is no ruling at the end of a
|
||||||
|
mediation. There is either an agreement everyone signs, or there is
|
||||||
|
not one.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* ---- 3. The questions ----------------------------------------------- */}
|
||||||
|
<section class="section reveal">
|
||||||
|
<div class="wrap">
|
||||||
|
<div class="section-head">
|
||||||
|
<SectionHeading
|
||||||
|
eyebrow="Questions"
|
||||||
|
level={2}
|
||||||
|
lede="The ones parties ask most often, answered plainly."
|
||||||
|
>
|
||||||
|
<span slot="heading">What you probably want to know.</span>
|
||||||
|
</SectionHeading>
|
||||||
|
</div>
|
||||||
|
<div class="faq">
|
||||||
|
{
|
||||||
|
FAQ.map((item) => (
|
||||||
|
<div class="faq-item">
|
||||||
|
<h3 class="faq-q">{item.q}</h3>
|
||||||
|
<p class="faq-a">{item.a}</p>
|
||||||
|
{item.undertaking && (
|
||||||
|
<Undertaking>{item.undertaking}</Undertaking>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
))
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
<div class="cta">
|
||||||
|
<Button href="/fees/" variant="gold">The full rate card →</Button>
|
||||||
|
<Button href="/process/" variant="ghost">The five steps →</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<ContactBand />
|
||||||
|
</BaseLayout>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.hero {
|
||||||
|
padding-block-start: var(--space-9);
|
||||||
|
}
|
||||||
|
.hero-h {
|
||||||
|
margin-block: var(--space-4) var(--space-5);
|
||||||
|
font-size: var(--text-6xl);
|
||||||
|
}
|
||||||
|
.hero-lede {
|
||||||
|
max-inline-size: 58ch;
|
||||||
|
font-size: var(--text-lg);
|
||||||
|
line-height: var(--leading-body);
|
||||||
|
color: var(--text-secondary);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The compliance sentence, set larger than the paragraph under it. A party
|
||||||
|
who reads one line on this page should read this one. */
|
||||||
|
.statement {
|
||||||
|
font-size: var(--text-lg);
|
||||||
|
line-height: var(--leading-body);
|
||||||
|
}
|
||||||
|
|
||||||
|
.faq {
|
||||||
|
display: grid;
|
||||||
|
gap: var(--space-7);
|
||||||
|
max-inline-size: var(--width-prose);
|
||||||
|
}
|
||||||
|
.faq-q {
|
||||||
|
margin-block-end: var(--space-2);
|
||||||
|
font-family: var(--font-serif);
|
||||||
|
font-size: var(--text-xl);
|
||||||
|
line-height: var(--leading-tight);
|
||||||
|
}
|
||||||
|
.faq-a {
|
||||||
|
line-height: var(--leading-body);
|
||||||
|
color: var(--text-secondary);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* A row of standalone CTAs, not prose: WCAG 2.5.8's inline-link exception
|
||||||
|
does not cover them, so `.btn` carries the 44px target. */
|
||||||
|
.cta {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: var(--space-3) var(--space-4);
|
||||||
|
margin-block-start: var(--space-8);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
+19
-41
@@ -86,7 +86,7 @@ const graph = homeGraph(new URL(ldImage.src, Astro.site).href);
|
|||||||
|
|
||||||
<BaseLayout
|
<BaseLayout
|
||||||
title={`${SITE.name} · ${SITE.tagline}`}
|
title={`${SITE.name} · ${SITE.tagline}`}
|
||||||
description="Commercial mediation and arbitration in Toronto. Construction, technology, energy, insurance and shareholder disputes, read as contracts and as engineering."
|
description="Mediation and commercial arbitration in Toronto. Construction, technology, energy, insurance and shareholder disputes, read as contracts and as engineering."
|
||||||
imageAlt={PORTRAIT.alt}
|
imageAlt={PORTRAIT.alt}
|
||||||
jsonLd={graph}
|
jsonLd={graph}
|
||||||
preloadSerifItalic
|
preloadSerifItalic
|
||||||
@@ -114,49 +114,27 @@ const graph = homeGraph(new URL(ldImage.src, Astro.site).href);
|
|||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
{
|
{
|
||||||
/* TWO CORRECTIONS FROM `claims-auditor`, 2026-08-27, both about
|
/* THREE CONSTRAINTS ON THIS PARAGRAPH. Trimmed to them under D19; the
|
||||||
implication rather than assertion — which is where D13 says the risk
|
history is in the `AGENTS.md` Change Log.
|
||||||
actually lives.
|
|
||||||
|
|
||||||
(a) This read "I mediate and arbitrate commercial disputes". §4
|
1. ARBITRATION STAYS OFFERING-SHAPED. §4 verifies that he ACCEPTS
|
||||||
verifies that he ACCEPTS arbitral appointments, and separately
|
arbitral appointments and separately verifies completed sole
|
||||||
verifies "multiple completed sole mediations" — there is no
|
mediations; there is no completed-arbitration row. A present
|
||||||
counterpart row for a completed arbitration. Present-indicative
|
indicative beside "mediate" invites a track record §4 does not
|
||||||
"arbitrate" beside "mediate" invites the reader to supply a track
|
hold.
|
||||||
record for both. The offering-shaped form is what the register
|
2. NO COMPARATIVE CLAIM ABOUT OTHER NEUTRALS — Q41(b), closed
|
||||||
actually holds, and it is already the form the arbitration card
|
2026-08-27, and struck from `docs/03`'s positioning statement too.
|
||||||
below uses.
|
3. THE TAIL IS POUYA'S WORDING, VERBATIM: *"built for disputes that
|
||||||
|
turn on the contract, the code, and the engineering documents"*.
|
||||||
(b) "facts most neutrals take on faith" is a COMPARATIVE assertion
|
Its echo of the `<h1>`'s triad is deliberate. */
|
||||||
about a population of third parties, and **Q41(b) CLOSED 2026-08-27:
|
|
||||||
it is not restored, and the reason is not only compliance.** Pouya:
|
|
||||||
*"That is an unverifiable empirical claim about other practitioners,
|
|
||||||
and comparative claims must be factual and verifiable. It is also
|
|
||||||
weaker copy: assert his capability, not the field's incapability."*
|
|
||||||
It is struck from `docs/03`'s core positioning statement too — the
|
|
||||||
approved-copy defence is gone, because the approved copy changed.
|
|
||||||
|
|
||||||
His replacement wording is used verbatim: *"built for disputes that
|
|
||||||
turn on the contract, the code, and the engineering documents"*. The
|
|
||||||
interim ("the documents rather than the pleadings") is also gone; it
|
|
||||||
said nothing about other neutrals but it still worked by contrast.
|
|
||||||
|
|
||||||
ON THE ECHO OF THE HEADLINE, because it is deliberate and one edit
|
|
||||||
from being reversed if he reads it as a stumble. The `<h1>` ends
|
|
||||||
"the contract, the code, and the room"; this sentence re-runs the
|
|
||||||
triad and swaps the third term for "the engineering documents". Two
|
|
||||||
of three words repeat forty words apart. Read as a rhyme it does the
|
|
||||||
work of the whole positioning statement in one move; read as an
|
|
||||||
oversight it looks careless. Judged the first, flagged as the
|
|
||||||
second. */
|
|
||||||
}
|
}
|
||||||
<p class="hero-lede">
|
<p class="hero-lede">
|
||||||
I mediate commercial disputes from Toronto, and I accept commercial
|
I mediate from Toronto, and I accept commercial arbitration
|
||||||
arbitration appointments. I also practise as a machine-learning and
|
appointments. I also practise as a machine-learning and infrastructure
|
||||||
infrastructure engineer, so the matters I take are the ones that turn
|
engineer, so the matters I take are the ones that turn on the
|
||||||
on the contract, the code, and the engineering documents: the change
|
contract, the code, and the engineering documents: the change order,
|
||||||
order, the model card, the System Impact Assessment, and the
|
the model card, the System Impact Assessment, and the regulatory
|
||||||
regulatory overlay around them.
|
overlay around them.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div class="hero-cta">
|
<div class="hero-cta">
|
||||||
|
|||||||
+10
-10
@@ -33,11 +33,11 @@ const ldImage = await getImage({
|
|||||||
});
|
});
|
||||||
const graph = serviceGraph({
|
const graph = serviceGraph({
|
||||||
path: '/mediation/',
|
path: '/mediation/',
|
||||||
name: 'Commercial mediation',
|
name: 'Mediation',
|
||||||
serviceType: 'Mediation',
|
serviceType: 'Mediation',
|
||||||
description:
|
description:
|
||||||
'Sole-mediator appointments in commercial disputes. Half day or full ' +
|
'Sole-mediator appointments. Half day or full day, in person, by ' +
|
||||||
'day, in person, by video, or shuttle.',
|
'video, or shuttle.',
|
||||||
imageUrl: new URL(ldImage.src, Astro.site).href,
|
imageUrl: new URL(ldImage.src, Astro.site).href,
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -70,8 +70,8 @@ const FORMATS = [
|
|||||||
---
|
---
|
||||||
|
|
||||||
<BaseLayout
|
<BaseLayout
|
||||||
title="Commercial Mediation · Pouya Lajevardi · Q.Med · Toronto"
|
title="Mediation · Pouya Lajevardi · Q.Med · Toronto, Ontario"
|
||||||
description="Sole mediator for commercial disputes in Toronto. Q.Med through ADRIC and ADRIO. Session formats, the ADRIC National Mediation Rules, and what to bring."
|
description="Sole mediator in Toronto, half day or full day. Q.Med through ADRIC and ADRIO. Session formats, the ADRIC National Mediation Rules, and what to bring."
|
||||||
jsonLd={graph}
|
jsonLd={graph}
|
||||||
>
|
>
|
||||||
{/* ---- 1. Hero -------------------------------------------------------- */}
|
{/* ---- 1. Hero -------------------------------------------------------- */}
|
||||||
@@ -107,10 +107,10 @@ const FORMATS = [
|
|||||||
}
|
}
|
||||||
<p>{NEUTRAL_ROLE_LINE}</p>
|
<p>{NEUTRAL_ROLE_LINE}</p>
|
||||||
<p>
|
<p>
|
||||||
What I bring to a commercial file is that I read the contract and the
|
What I bring to a file is that I read the contract and the technical
|
||||||
technical record underneath it — the change orders, the schedule, the
|
record underneath it — the change orders, the schedule, the model
|
||||||
model card, the system impact assessment — rather than either side's
|
card, the system impact assessment — rather than either side's summary
|
||||||
summary of them.
|
of them.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -240,7 +240,7 @@ const FORMATS = [
|
|||||||
<SectionHeading
|
<SectionHeading
|
||||||
eyebrow="Subject matter"
|
eyebrow="Subject matter"
|
||||||
level={2}
|
level={2}
|
||||||
lede="Where a commercial mediation usually turns on something technical."
|
lede="Where a mediation usually turns on something technical."
|
||||||
>
|
>
|
||||||
<span slot="heading">Six areas.</span>
|
<span slot="heading">Six areas.</span>
|
||||||
</SectionHeading>
|
</SectionHeading>
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ import PracticeCard from '../components/PracticeCard.astro';
|
|||||||
import SectionHeading from '../components/SectionHeading.astro';
|
import SectionHeading from '../components/SectionHeading.astro';
|
||||||
import { getImage } from 'astro:assets';
|
import { getImage } from 'astro:assets';
|
||||||
import ogDefault from '../assets/og-portrait.jpg';
|
import ogDefault from '../assets/og-portrait.jpg';
|
||||||
import { practiceIndexGraph } from '../data/schema';
|
import { pageGraph } from '../data/schema';
|
||||||
import { NEUTRAL_ROLE_LINE, PRACTICE_AREAS } from '../data/site';
|
import { NEUTRAL_ROLE_LINE, PRACTICE_AREAS } from '../data/site';
|
||||||
|
|
||||||
const ldImage = await getImage({
|
const ldImage = await getImage({
|
||||||
@@ -46,7 +46,18 @@ const ldImage = await getImage({
|
|||||||
width: 1200,
|
width: 1200,
|
||||||
height: 630,
|
height: 630,
|
||||||
});
|
});
|
||||||
const graph = practiceIndexGraph(new URL(ldImage.src, Astro.site).href);
|
/* THE PERSON NODE AND NOTHING ELSE, and the reason is about this page rather
|
||||||
|
than about graph shape — which is why it lives here now and not in
|
||||||
|
`schema.ts`. NO `Service` NODES FOR THE SIX AREAS (each area page emits its
|
||||||
|
own), NONE FOR THE "also offered" STRIP, AND NO `CollectionPage`. The strip
|
||||||
|
is the constraint to keep: all three are PUBLISHABLE (§4, Q46(a)) but gate 1
|
||||||
|
on each reads `[Pouya's stated basis]`, not `[verified]`, and ENE is §4's
|
||||||
|
"offering nearest the NOT-NEGOTIABLE boundary" — a visible strip read in
|
||||||
|
context is not the same claim as a machine-readable service type a crawler
|
||||||
|
lifts alone. Adding any of them needs docs/04 changed first.
|
||||||
|
|
||||||
|
No `BreadcrumbList`: one hop from the root, no visible trail. */
|
||||||
|
const graph = pageGraph(new URL(ldImage.src, Astro.site).href);
|
||||||
|
|
||||||
/* THREE, NOT FOUR. Each has a §4 Offerings row reading PUBLISHABLE (Q46(a),
|
/* THREE, NOT FOUR. Each has a §4 Offerings row reading PUBLISHABLE (Q46(a),
|
||||||
2026-08-28). Do not add a fourth without a row, and do not restore the one
|
2026-08-28). Do not add a fourth without a row, and do not restore the one
|
||||||
@@ -69,7 +80,7 @@ const ALSO_OFFERED = [
|
|||||||
|
|
||||||
<BaseLayout
|
<BaseLayout
|
||||||
title="Practice Areas · Pouya Lajevardi · Mediation and Arbitration"
|
title="Practice Areas · Pouya Lajevardi · Mediation and Arbitration"
|
||||||
description="Six areas where a commercial dispute usually turns on something technical: construction, technology, energy, insurance, shareholder, and cross-border matters."
|
description="Six areas where a dispute usually turns on something technical: construction, technology, energy, insurance, shareholder, and cross-border matters."
|
||||||
jsonLd={graph}
|
jsonLd={graph}
|
||||||
>
|
>
|
||||||
{/* ---- 1. Hero -------------------------------------------------------- */}
|
{/* ---- 1. Hero -------------------------------------------------------- */}
|
||||||
@@ -78,10 +89,10 @@ const ALSO_OFFERED = [
|
|||||||
<Eyebrow dot>Practice</Eyebrow>
|
<Eyebrow dot>Practice</Eyebrow>
|
||||||
<h1 class="display hero-h">Six areas, one reason.</h1>
|
<h1 class="display hero-h">Six areas, one reason.</h1>
|
||||||
<p class="hero-lede">
|
<p class="hero-lede">
|
||||||
Each of these is a place where a commercial dispute turns on a document
|
Each of these is a place where a dispute turns on a document somebody
|
||||||
somebody has to actually read — a subcontract, a system impact
|
has to actually read — a subcontract, a system impact assessment, a
|
||||||
assessment, a processing agreement, a benefits file. The process is
|
processing agreement, a benefits file. The process is mediation or
|
||||||
mediation or arbitration. The area is the context it runs in.
|
arbitration. The area is the context it runs in.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
@@ -181,7 +192,7 @@ const ALSO_OFFERED = [
|
|||||||
<div class="prose">
|
<div class="prose">
|
||||||
<p>
|
<p>
|
||||||
The area pages describe the disputes. These describe the process the
|
The area pages describe the disputes. These describe the process the
|
||||||
parties are choosing between, in commercial matters.
|
parties are choosing between.
|
||||||
</p>
|
</p>
|
||||||
<p class="onward">
|
<p class="onward">
|
||||||
<a href="/mediation/">Mediation →</a>
|
<a href="/mediation/">Mediation →</a>
|
||||||
|
|||||||
@@ -0,0 +1,248 @@
|
|||||||
|
---
|
||||||
|
/**
|
||||||
|
* `/process/` — build step 6. Spec: docs/01 §`/process/`, docs/03 §Process.
|
||||||
|
*
|
||||||
|
* ⚠️ `PROCESS_FRAMING` IS THE CONDITION ON WHICH THE FIVE TIMINGS MAY BE
|
||||||
|
* PUBLISHED AT ALL — Q43, Pouya 2026-08-27 — and it renders ADJACENT TO THE
|
||||||
|
* NUMBERS, never in the section lede above them: a reader who scans the strip
|
||||||
|
* and skips the lede has read a commitment. `/` renders the same constant under
|
||||||
|
* the same steps, so neither page can drift from the other.
|
||||||
|
*
|
||||||
|
* ⚠️ THE TWO UNDERTAKINGS HERE ARE RENDERED, NEVER RETYPED — §4's conduct
|
||||||
|
* class, Q54. Softening one is a change to a published commitment, not a copy
|
||||||
|
* edit, and nothing in a build fails when a promise gets smaller.
|
||||||
|
*
|
||||||
|
* ⚠️ AND NOTHING ON THIS PAGE MAY ADD A SEVENTH. §4's gate: an undertaking is
|
||||||
|
* publishable only where Pouya has made it **in terms** — not "would obviously
|
||||||
|
* agree to", not "follows from the process". That is why §Conflicts says when
|
||||||
|
* the check happens and what it needs, and then stops. See the TODO below.
|
||||||
|
*/
|
||||||
|
import BaseLayout from '../layouts/BaseLayout.astro';
|
||||||
|
import Button from '../components/Button.astro';
|
||||||
|
import ContactBand from '../components/ContactBand.astro';
|
||||||
|
import Eyebrow from '../components/Eyebrow.astro';
|
||||||
|
import ProcessStep from '../components/ProcessStep.astro';
|
||||||
|
import SectionHeading from '../components/SectionHeading.astro';
|
||||||
|
import Undertaking from '../components/Undertaking.astro';
|
||||||
|
import { getImage } from 'astro:assets';
|
||||||
|
import ogDefault from '../assets/og-portrait.jpg';
|
||||||
|
import { pageGraph } from '../data/schema';
|
||||||
|
import {
|
||||||
|
CONDUCT_UNDERTAKINGS,
|
||||||
|
MEMBERSHIP_ORGS,
|
||||||
|
PROCESS,
|
||||||
|
PROCESS_FRAMING,
|
||||||
|
} from '../data/site';
|
||||||
|
|
||||||
|
const ldImage = await getImage({
|
||||||
|
src: ogDefault,
|
||||||
|
format: 'jpeg',
|
||||||
|
width: 1200,
|
||||||
|
height: 630,
|
||||||
|
});
|
||||||
|
const graph = pageGraph(new URL(ldImage.src, Astro.site).href);
|
||||||
|
---
|
||||||
|
|
||||||
|
<BaseLayout
|
||||||
|
title="The Shape of an Engagement · Pouya Lajevardi · Toronto"
|
||||||
|
description="The five steps from the intake call to minutes of settlement or an award: timing, conflicts, confidentiality, and what happens if a matter does not settle."
|
||||||
|
jsonLd={graph}
|
||||||
|
>
|
||||||
|
{/* ---- 1. Hero -------------------------------------------------------- */}
|
||||||
|
<section class="section hero">
|
||||||
|
<div class="wrap">
|
||||||
|
<Eyebrow dot>Process</Eyebrow>
|
||||||
|
<h1 class="display hero-h">The shape of an engagement.</h1>
|
||||||
|
<p class="hero-lede">
|
||||||
|
Booking a neutral commits a client to a date, a cost and a process. This
|
||||||
|
is the whole of it: the five steps, what each one needs from the
|
||||||
|
parties, and what happens if the matter does not settle.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* ---- 2. The five steps ---------------------------------------------- */}
|
||||||
|
<section class="section section-alt reveal">
|
||||||
|
<div class="wrap">
|
||||||
|
<div class="section-head">
|
||||||
|
<SectionHeading
|
||||||
|
eyebrow="Step by step"
|
||||||
|
level={2}
|
||||||
|
lede="Intake to conclusion, with the timing each step usually takes."
|
||||||
|
>
|
||||||
|
<span slot="heading">Five steps.</span>
|
||||||
|
</SectionHeading>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<ol class="steps" role="list">
|
||||||
|
{
|
||||||
|
PROCESS.map((step, i) => (
|
||||||
|
<ProcessStep n={i + 1} title={step.title} timing={step.timing}>
|
||||||
|
{step.body}
|
||||||
|
</ProcessStep>
|
||||||
|
))
|
||||||
|
}
|
||||||
|
</ol>
|
||||||
|
|
||||||
|
{
|
||||||
|
/* Q43, and it is not a disclaimer: it is the condition on which the
|
||||||
|
numbers above may appear. Directly under them, never in the lede. */
|
||||||
|
}
|
||||||
|
<p class="process-framing">{PROCESS_FRAMING}</p>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* ---- 3. Conflicts --------------------------------------------------- */}
|
||||||
|
{
|
||||||
|
/* TODO(pouya): what happens when a conflicts check turns something up? Any
|
||||||
|
sentence naming the outcome is a SEVENTH conduct undertaking, and §4's
|
||||||
|
gate requires that you have made it in terms — so it is not written here.
|
||||||
|
AGENTS.md §9 Q57. */
|
||||||
|
}
|
||||||
|
<section class="section reveal">
|
||||||
|
<div class="wrap">
|
||||||
|
<div class="section-head">
|
||||||
|
<SectionHeading eyebrow="Conflicts" level={2}>
|
||||||
|
<span slot="heading">Checked at step one.</span>
|
||||||
|
</SectionHeading>
|
||||||
|
</div>
|
||||||
|
<div class="prose">
|
||||||
|
<p>
|
||||||
|
Conflicts are run on the intake call, before anything is agreed. The
|
||||||
|
check needs the full legal name of every party, the parent or
|
||||||
|
affiliate actually behind the dispute where that is a different
|
||||||
|
entity, and the names of counsel on each side.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Send those with the request rather than at the call. An intake call
|
||||||
|
that stops to collect names is an intake call that gets repeated.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* ---- 4. Confidentiality --------------------------------------------- */}
|
||||||
|
<section class="section section-inverse reveal">
|
||||||
|
<div class="wrap">
|
||||||
|
<div class="section-head">
|
||||||
|
<SectionHeading eyebrow="Confidentiality" level={2}>
|
||||||
|
<span slot="heading">What stays in the room.</span>
|
||||||
|
</SectionHeading>
|
||||||
|
</div>
|
||||||
|
<div class="prose">
|
||||||
|
{
|
||||||
|
/* SOURCED, NOT ASSERTED. An earlier draft read "confidentiality is
|
||||||
|
settled in the terms of appointment at step two" — a claim about
|
||||||
|
what MY engagement documents contain, which §4 does not row and
|
||||||
|
which no reader could check. What replaced it is a quotation from an
|
||||||
|
artefact committed to this repository
|
||||||
|
(`docs/reference/adr-institution-names.md`, retrieved 2026-08-29,
|
||||||
|
with its URL) plus a membership §4 verifies.
|
||||||
|
|
||||||
|
AND THE SENTENCE AROUND THE QUOTE STAYS INSIDE IT — the gloss lens,
|
||||||
|
which caught a second draft here. It read "on this it is ONE
|
||||||
|
SENTENCE", a completeness claim about a third party's Code that the
|
||||||
|
extract cannot support: the extract is a scrape of one web page
|
||||||
|
carrying three quoted lines, and eighteen lines above it records a
|
||||||
|
SEPARATE instrument — ADRIC's Code of Conduct for Mediators — that
|
||||||
|
bears on the same subject. The artefact cited as the source supplied
|
||||||
|
the counter-example. Same shape as the LAT ellipsis and the IESO
|
||||||
|
"connection allocation". It now says only "it says".
|
||||||
|
|
||||||
|
The Code establishes an obligation on members. It does NOT establish
|
||||||
|
what my appointment terms say, what any rule set provides, or that
|
||||||
|
the undertaking below is required by it. That undertaking is
|
||||||
|
introduced as mine, which is what it is.
|
||||||
|
|
||||||
|
THE MEMBERSHIP IS RENDERED FROM `MEMBERSHIP_ORGS`, not typed. R10's
|
||||||
|
re-confirm trigger sweeps the constants; a hand-typed copy here
|
||||||
|
would keep asserting the membership after a lapse, which is the OCNI
|
||||||
|
shape R10 was written from. */
|
||||||
|
}
|
||||||
|
<p>
|
||||||
|
I am a member of the {MEMBERSHIP_ORGS[0]}. Its <a
|
||||||
|
href="https://adric.ca/rules-codes/code-of-ethics/"
|
||||||
|
>Code of Ethics</a
|
||||||
|
> applies to every member, and it says: <q
|
||||||
|
>A Member shall be faithful to the relationship of trust and
|
||||||
|
confidentiality inherent in the office of arbitrator or mediator.</q
|
||||||
|
>
|
||||||
|
</p>
|
||||||
|
<p>That is the obligation. This is mine, in a mediation:</p>
|
||||||
|
</div>
|
||||||
|
<Undertaking>{CONDUCT_UNDERTAKINGS.mediationCaucus}</Undertaking>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* ---- 5. If it does not settle --------------------------------------- */}
|
||||||
|
<section class="section section-alt reveal">
|
||||||
|
<div class="wrap">
|
||||||
|
<div class="section-head">
|
||||||
|
<SectionHeading
|
||||||
|
eyebrow="The other outcome"
|
||||||
|
level={2}
|
||||||
|
lede="The question counsel ask before committing a client's day."
|
||||||
|
>
|
||||||
|
<span slot="heading">If it does not settle.</span>
|
||||||
|
</SectionHeading>
|
||||||
|
</div>
|
||||||
|
<div class="prose">
|
||||||
|
<p>
|
||||||
|
Then it does not settle, and that is an outcome the day is built to
|
||||||
|
reach cleanly rather than a failure of it. What gets recorded is what
|
||||||
|
the parties agree to record — the issues that closed and the ones that
|
||||||
|
did not. A matter narrowed to two questions is worth having even when
|
||||||
|
it is not what you came for.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Where parties want a binding end if the mediation does not produce
|
||||||
|
one, that is med-arb — and it is agreed at the start rather than
|
||||||
|
reached for at the end:
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<Undertaking>{CONDUCT_UNDERTAKINGS.medArbSwitch}</Undertaking>
|
||||||
|
<div class="cta">
|
||||||
|
<Button href="/med-arb/" variant="gold">How med-arb runs →</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<ContactBand />
|
||||||
|
</BaseLayout>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.hero {
|
||||||
|
padding-block-start: var(--space-9);
|
||||||
|
}
|
||||||
|
.hero-h {
|
||||||
|
margin-block: var(--space-4) var(--space-5);
|
||||||
|
font-size: var(--text-6xl);
|
||||||
|
}
|
||||||
|
.hero-lede {
|
||||||
|
max-inline-size: 58ch;
|
||||||
|
font-size: var(--text-lg);
|
||||||
|
line-height: var(--leading-body);
|
||||||
|
color: var(--text-secondary);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ONE PER ROW, unlike `/`'s compressed strip. This page is the full account,
|
||||||
|
so each step gets the width to be read rather than scanned. */
|
||||||
|
.steps {
|
||||||
|
display: grid;
|
||||||
|
gap: var(--space-6);
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Same treatment as `/`, deliberately: one condition, one look, so a reader
|
||||||
|
who has seen it on the home page recognises it here. */
|
||||||
|
.process-framing {
|
||||||
|
margin-block-start: var(--space-6);
|
||||||
|
max-inline-size: var(--width-prose);
|
||||||
|
font-size: var(--text-sm);
|
||||||
|
color: var(--text-secondary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.cta {
|
||||||
|
margin-block-start: var(--space-7);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -391,6 +391,23 @@ a:hover {
|
|||||||
.section-accent :focus-visible {
|
.section-accent :focus-visible {
|
||||||
outline-color: var(--gold-l);
|
outline-color: var(--gold-l);
|
||||||
}
|
}
|
||||||
|
/* AND THE LINK COLOUR, for the same reason and measured the same way. `--link`
|
||||||
|
is --maroon-l, documented at 8.95:1 ON CREAM and never overridden for an
|
||||||
|
inverse ground: on --ink it measures 1.88:1, and :hover (--maroon-d) 1.10:1.
|
||||||
|
That is WORSE than the gold-on-cream 2.10:1 this project treats as the defect
|
||||||
|
that must never ship. `SiteFooter` sets its own `.footer-col a` colour, which
|
||||||
|
is the only reason this had not fired before — `/process/` shipped the site's
|
||||||
|
first body link on a dark band. Values: gold-l 11.09:1 on ink, cream 16.81:1.
|
||||||
|
Here rather than in the page, because the next inverse-ground link hits the
|
||||||
|
same hole. Found by `adversarial-reviewer`, 2026-08-30. */
|
||||||
|
.section-inverse a:not(.btn),
|
||||||
|
.section-accent a:not(.btn) {
|
||||||
|
color: var(--text-inverse-2);
|
||||||
|
}
|
||||||
|
.section-inverse a:not(.btn):hover,
|
||||||
|
.section-accent a:not(.btn):hover {
|
||||||
|
color: var(--text-inverse);
|
||||||
|
}
|
||||||
/* The eyebrow's dot is a --accent (maroon) box, so recolouring only the TEXT
|
/* The eyebrow's dot is a --accent (maroon) box, so recolouring only the TEXT
|
||||||
for an inverse ground leaves the dot at 1.21:1 on ink and 1.00:1 on the
|
for an inverse ground leaves the dot at 1.21:1 on ink and 1.00:1 on the
|
||||||
accent band — present in the markup, invisible on the page. Colour never
|
accent band — present in the markup, invisible on the page. Colour never
|
||||||
|
|||||||
Reference in New Issue
Block a user