Compare commits

..
3 Commits
Author SHA1 Message Date
Pouya LajevardiandClaude Opus 5 2282183b4b fix: remove the duplicated Change Log block introduced in 77a7b41
Build and deploy / build-and-deploy (push) Failing after 4s
Every entry from (x) back to 2026-08-25 appeared twice: 51 headings, 26 unique.
`git show` on each commit locates it — c576b9a has one copy, 77a7b41 has two —
so the previous session's commit introduced it, almost certainly a patch script
that appended where it should have replaced.

Removal proven lossless before writing: the second block is a strict prefix of
the first (3,252 identical lines, then it stops), every one of its lines is
either blank or byte-identical to the first block at the same index, and a
set comparison against HEAD reports 0 non-blank lines present before and absent
after. No entry heading changed.

This is not deleting history under the §12 constitution — it is removing a
mechanical duplicate of history that was corrupting every sweep over the file.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0148NztQskLKKApP5SzAA78e
2026-08-28 15:53:53 -04:00
Pouya LajevardiandClaude Opus 5 fd5f610982 feat: D19 bounds the review loop; apply nine rulings; close Q46(a) and Q48–Q53
D19 into §3 and swept to all six destinations Pouya named: both agent briefs
(scope + severity filter), /build Phases 2–4 (non-gating questions, scope, stop
signal, two-round cap), /wrap, and CLAUDE.md (comments record decisions, not
history). Sweep verified by command, not recalled.

Rulings applied:
  Q46(a) PUBLISHABLE — three §4 Offerings rows flipped; gate 1 records
         [Pouya's stated basis], never [verified]. Step 5 unblocked.
  Q48    closed, not site-relevant.
  Q49    one §4 row, "Mediator"; read as declining Q49(b), so worksFor stays out.
  Q50    DEVIATES — ships as name + slogan, not the concatenation. Flagged.
  Q51    OBA sections stay; the regulator/voluntary distinction recorded.
  Q52    docs/reference/deploy-credential-verification.md — 18 read-only AWS
         calls, re-run rather than transcribed, access key ID redacted.
  Q53    memberOf emitted on /about/'s Person node.

Two review rounds. The headline finding was this session's own: the Q53 sweep
was asserted and never run, leaving six in-scope records saying memberOf was
withheld — including §12 R10, which is read aloud every session. Round 2 then
found that round 1's simplification had put memberOf on / as well; the per-page
opt-in is restored, because Pouya's ruling turns on /about/'s visible HTML.

Also fixed: MEMBERSHIP_ORGS had orphaned BOUTIQUE's D16 JSDoc; /'s title now
derives from the constants; §7's deploy row stated and retracted three facts.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0148NztQskLKKApP5SzAA78e
2026-08-28 15:52:52 -04:00
Pouya LajevardiandClaude Opus 5 77a7b410b2 feat: apply six rulings; close Q22/Q44/Q45/Q46(b)/Q47; revert Q47's two graph fields
Pouya's rulings: Q44 (memberships current — ship the group), Q45 (PDF bio
deferred to step 9), Q46(a) (three offerings pass all gates), Q46(b) (§11
ratified as the source for definitional expansions, conditional on committing
the source), Q47 (set jobTitle and worksFor), the legal-advice formulation
ratified without change, and Q22 closed on his own execution evidence.

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

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

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

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

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

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

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

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0148NztQskLKKApP5SzAA78e
2026-08-28 13:50:58 -04:00
26 changed files with 2868 additions and 197 deletions
+44
View File
@@ -27,6 +27,35 @@ A diff or a set of files, and the specs in `docs/`. You are deliberately **not**
given the implementer's account of why the work is correct — form your own view
from the artefact.
## Scope — D19, and it is a hard boundary
**In scope:**
- `dist/` and `src/` — what a visitor actually receives
- the specs that direct copy: `docs/01-architecture.md`,
`docs/03-content-spec.md`, `docs/04-seo-spec.md`, `docs/07-fees.md`
- `AGENTS.md` **§3, §4, §7, §9, §12** — the operative sections
**Out of scope:**
- the `AGENTS.md` **Change Log**
- the agent briefs in `.claude/agents/`, including this one
- `AGENTS.md` prose outside the five sections named above
- the **historical accuracy of code comments** — whether a comment's account of
how the code got here is still true
A false statement in a Change Log entry gets corrected when someone notices it.
It does not get a review pass, because **no visitor reads it.** Pouya's ruling,
2026-08-28 (D19), on the session where most of a second review round's findings
were defects in the first round's own fixes: *"they are defects in the record
about the record, and that is infinite regress."*
**What this does not narrow.** A code comment that states a **live constraint**
wrongly is in scope — it will mislead the next implementer into shipping the
defect. What is out of scope is the comment's account of its own revision
history. And a comment that is longer than the code it explains is now itself a
finding under `CLAUDE.md`'s D19 convention: report it as **simplicity**, lens 6.
## Lenses — work all of them
**1. Correctness.** Does it do what `docs/01-architecture.md` and
@@ -84,5 +113,20 @@ For each finding:
rather than dressing up a preference as a bug.
- **The fix**, specifically
### Severity filter — D19
**Report blocking and should-fix. Raise a `consider` only if acting on it would
change what ships.**
The standing bias above says an approving review that misses a real defect is a
failure. This is its twin, and Pouya added it 2026-08-28: **a review that reports
twenty things in order to produce twenty small edits has spent more than it
saved.** Both failures are real and they pull in opposite directions. The
resolution is *not* to soften a genuine defect — it is to stop promoting
preferences into findings.
If you are uncertain whether something is a defect, the standing bias still
applies: report it, at the severity your confidence supports.
If you genuinely find nothing at a given severity, say which lenses you applied
and what you checked, so the gap is auditable. **"Looks good" is not a review.**
+58 -3
View File
@@ -13,6 +13,38 @@ 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
the control that stops that recurring.
## Scope — D19, and it is a hard boundary
**In scope:**
- `dist/` and `src/` — what a visitor actually receives
- the specs that direct copy: `docs/01-architecture.md`,
`docs/03-content-spec.md`, `docs/04-seo-spec.md`, `docs/07-fees.md`
- `AGENTS.md` **§3, §4, §7, §9, §12** — the operative sections
**Out of scope:**
- the `AGENTS.md` **Change Log**
- the agent briefs in `.claude/agents/`, including this one
- `AGENTS.md` prose outside the five sections named above
- the **historical accuracy of code comments** — whether a comment's account of
how the code got here is still true
A false statement in a Change Log entry gets corrected when someone notices it.
It does not get a review pass, because **no visitor reads it.** Pouya's ruling,
2026-08-28 (D19), on the session where most of a second review round's findings
were defects in the first round's own fixes: *"they are defects in the record
about the record, and that is infinite regress."*
**What this does not narrow, and read this carefully.** Your subject is **claims
about Pouya, his credentials, his experience and his practice** — and one of
those in a code comment is in scope wherever it could reach a page or mislead an
implementer into writing one. `src/data/site.ts` and `src/data/schema.ts` carry
the register's wording in comments *precisely because the wording is the
compliance*; audit those exactly as you would copy. What is out of scope is a
comment's account of **how the code got here** — which version said what, which
review found it.
## Method
1. Read `AGENTS.md` §4 in full — the Verified table, the Forbidden table, and
@@ -33,9 +65,21 @@ replaced with something verified.
**Licensure (D13).** The site asserts the JD and nothing further. Flag: "lawyer",
"called to the bar", "licensed", "my law practice", "my litigation practice",
"my clients", "acts for", "represents", "legal advice", or any post-nominal
implying a licence. **Flag implication as hard as assertion** — "my litigation
practice" claims licensure without the word.
"my clients", "acts for", "represents", or any post-nominal implying a licence.
**Flag implication as hard as assertion** — "my litigation practice" claims
licensure without the word.
**"legal advice" — FLAG IT ONLY WHERE IT ATTACHES A CAPACITY TO POUYA.** This
list carried a bare *"legal advice"* until 2026-08-28, which applied literally
flags the **ratified** sentence *"each party should have their own legal
advice"*. Flag *giving* legal advice, *practising law*, or *holding a licence*
predicated of him — not the phrase wherever it appears. `docs/03`'s
*"When a fact is `[unestablished]`"* section carries the pattern and the three
tests; the shipped sentence is its worked example of a **pass**.
*This is the fourth stale claim found inside this brief. The same correction
reached `docs/03`'s compliance checklist and did not reach here — the shape this
paragraph's own memberships note records two sections down.*
The approved phrasing for the boutique role is **"active litigation exposure"**
or **"involvement in litigation and ADR matters"**. The word **"practice"** in
@@ -93,6 +137,17 @@ machine-readable misrepresentation is still a misrepresentation.
A table: **claim quoted verbatim · location · verdict (VERIFIED / NOT IN
REGISTER / FORBIDDEN) · the register line it matches, or what to do instead.**
### Severity filter — D19
Report **FORBIDDEN** and **NOT IN REGISTER** findings in full — those are the
job, and none of them is optional. Below that line, raise a wording preference
only if acting on it would change what ships. Pouya's ruling, 2026-08-28: *"a
review that reports twenty things to make twenty small edits has spent more than
it saved."*
This does not soften the rule above it. **A claim not in the Verified table does
not ship**, at any count.
Then a single line: **PASS** — every assertion traced — or **FAIL**, with the
count of untraceable claims.
+36 -1
View File
@@ -19,7 +19,7 @@ does not apply, say which and why before moving on.
Reminders** and surface anything live to Pouya before you start.
2. Read the specs in `docs/` that bear on this task.
3. Restate the task in your own words, and name:
- which locked decisions (D1D18) it touches
- which locked decisions (D1D19) it touches
- which specs govern it
- which facts it needs from the §4 Verified register
4. **Stop and ask if you find a conflict** — between the task and a locked
@@ -36,6 +36,13 @@ hex, no magic numbers. Semantic HTML. Every page gets its metadata.
Where you need a fact you do not have: `TODO(pouya): <the exact question>` in the
source **and** a new numbered question in `AGENTS.md` §9. Do not invent it.
**But do not open a numbered question for something that gates nothing — D19.**
The Q-series is past 50 and most recent additions gate nothing. If an observation
does not block a page, a deploy or a claim, it is a **Change Log note**, not a
numbered question — and retire the non-gating ones you find. A `TODO(pouya)` in
source is not this case: it blocks the page it sits on, so it still gets a
number.
## Phase 3 — Adversarial review (this is not optional)
Invoke **both** review agents on the change, in parallel:
@@ -49,6 +56,22 @@ work is correct.** Your rationale anchors the reviewer and produces agreement
instead of review. They form their own view from the artefact; that independence
is the whole point of the phase.
### Scope — D19
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
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
same boundary — do not widen it in the prompt.
### The stop signal
**If a round's findings are predominantly about the record rather than the
output, stop the round and say so.** That is the symptom of the loop feeding on
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
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
so explicitly.
@@ -69,6 +92,18 @@ under review pressure is exactly where the second defect lives.
> launch articles. None of the four existed before the review started. Skip the
> re-review and you ship the repair, not the bug.
### Two rounds is the cap — D19
Round 1 reviews the change. Round 2 reviews the material fixes. **There is no
round 3: fix what round 2 finds, and ship.**
The measurement above is why round 2 exists. The measurement below is why round 3
does not. On 2026-08-28 two rounds produced **48 findings, and most of round
two's were defects in round one's own fixes** — so each further round both finds
and manufactures defects, and past two the manufacture rate exceeds the value of
the marginal finding. Pouya's ruling. **State this reasoning when you stop at
two**, so a later reader does not read the cap as laxness.
## Phase 5 — Verify — run it, do not assert it
```bash
+9 -3
View File
@@ -30,12 +30,18 @@ reasoning.
instances survived all three, one of them inside the definition of the agent
whose job is to catch it.
4. **Check §12 Standing Reminders.** Is anything now due? Should something new
4. **Do not open a numbered question for something that gates nothing — D19.**
The Q-series is past 50 and most recent additions gate nothing. If it does
not block a page, a deploy or a claim, it belongs in this entry as a note, not
in §9 as a number — and retire the non-gating ones you find while you are in
there. Pouya's ruling, 2026-08-28.
5. **Check §12 Standing Reminders.** Is anything now due? Should something new
be added — a decision Pouya parked, or one you made on his behalf that he has
not yet ratified?
5. **Leave the tree clean.** `git status` should show only intended changes. No
6. **Leave the tree clean.** `git status` should show only intended changes. No
stray build output, no `.env`, no credentials, no `aws-inventory.txt`.
6. Report: what changed in `AGENTS.md`, what is open, and the single most useful
7. Report: what changed in `AGENTS.md`, what is open, and the single most useful
next action.
+743 -26
View File
@@ -129,6 +129,7 @@ without an explicit instruction and a Change Log entry. `[verified 2026-08-25]`
| 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 |
| 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 |
| 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 24, `/wrap` and `CLAUDE.md` | Unbounded scope; a third round; reporting every "consider"; a numbered question per observation |
| 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
@@ -171,6 +172,7 @@ since May.
| Active litigation **exposure**: personal injury, construction, regulatory (POA), insurance (SABS) | `[verified 2026-08-26]`. **Wording corrected** — this row previously read "practice", the exact word D13 bars in exactly the context it bars it. The register was quoting the strategy brief verbatim and contradicting its own rule. The underlying fact is unchanged |
| 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 |
| **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 credentialing pathway — **commenced August 2026** | `[verified 2026-08-26 — Pouya]`. Describe as newly commenced, never as held or nearing completion |
| C.Med-Arb stated as long-term designation goal | `[verified 2026-08-25 — strategy brief §I, §IV]` |
| Kompass Arbitration Certificate Program — completed | `[verified 2026-08-25 — strategy brief §I]` |
@@ -180,7 +182,7 @@ since May.
| Iranian-Canadian; cross-cultural fluency with diaspora business communities | `[verified 2026-08-25 — strategy brief §I]` |
| Operator of SML Company Ltd. alongside the practice | `[verified 2026-08-25 — strategy brief §I]` |
| **SML Company Ltd — incorporated FEDERALLY, under the CBCA** | `[verified 2026-08-26 — Pouya, Q30]`. Two facts were being conflated and one of them was wrong: **jurisdiction of incorporation is federal (Canada)**; **place of business is Toronto, Ontario**. `src/data/site.ts` carried `'SML Company Ltd. · Ontario, Canada'`, which reads as a jurisdiction of incorporation and named the wrong one. **No corporation number** — none is held and the line does not need one. **Caution, and it is the point of this row:** "federally incorporated" says nothing about professional licensure, and nothing about where the practice may operate. It must not be read together with the **Licence status — NOT ESTABLISHED** row into an implication that neither row makes. **Not published:** on Pouya's direction the footer reads `© <year> SML Company Ltd` and nothing further — the fact is verified and available, it is simply not on a page |
| Memberships: **ADRIC**, **ADRIO**, **OBA — Construction & Infrastructure, ADR, and Civil Litigation sections**, and the **Canadian Tax Foundation** | `[verified 2026-08-26 — Pouya]`, **for now**. *CTF added 2026-08-26.* Both the OBA sections and the CTF renew yearly; every line here is a fact with a shelf life, tracked as R10. Re-confirm at renewal and before any page listing memberships ships. **CTF is a membership, not a practice area** — it is the one credential none of the six areas touch, and `docs/01-architecture.md` records why there is no seventh page at launch and when to revisit (R3) |
| Memberships: **ADRIC**, **ADRIO**, **OBA — Construction & Infrastructure, ADR, and Civil Litigation sections**, and the **Canadian Tax Foundation** | **`[verified 2026-08-28 — Pouya]` — RE-CONFIRMED, R10 DISCHARGED, AND NOW PUBLISHED ON `/about/`.** Q44 closed: *"All four are current as of today."* **Note on the stamp date, because it is a currency stamp and the date is the whole content:** Pouya's ruling said *"Stamp `[verified 2026-08-26 — Pouya]`"*, which is the date of the **original** confirmation. The stamp here reads **2026-08-28**, the date he actually re-confirmed — a stamp records when the assertion was made, and back-dating a re-confirmation by two days would understate the only thing the stamp is for. Flagged to him; one edit to change if he meant otherwise. **NO CURRENCY WARRANTY MAY BE PUBLISHED.** His words: *"List the memberships; promise nothing about their future state."* The struck sentence (*"Memberships are renewed annually and are listed as current"*) stays struck and nothing replaces it. **Renewal periods: the OBA sections and the CTF renew yearly. This record says NOTHING about ADRIC's or ADRIO's period** — an earlier form asserted "all four renew yearly" and that widened form propagated to four files. **He declined renewal-date tracking**, so R10 no longer fires on a date; it fires on an **event** — re-confirm before any cutover or major republish. **`memberOf` IS NOW EMITTED** on `/about/`'s Person node — Q53, ruled 2026-08-28; the withholding is dropped and this sentence said the opposite until the sweep that should have caught it was run. So the graph and the visible list assert the same four lines, and R10's event trigger covers both. `/`'s Person node omits it, because `/` shows no memberships. **CTF is a membership, not a practice area** — it is the one credential none of the six areas touch, and `docs/01-architecture.md` records why there is no seventh page at launch and when to revisit (R3) **Q51 CLOSED 2026-08-28 — the OBA sections STAY, and the distinction is structural.** Pouya: *"the Law Society is the regulator, so membership IS licensure; the OBA is a voluntary association."* That is why the `~~LSO~~` row below excludes one and this row publishes the other, and it holds **independently of eligibility details** — which is what made the question unanswerable inside this repo. Recorded so it is not re-litigated: a voluntary professional association admits members it does not license, so listing it carries no licensure implication; a regulator's membership roll *is* the licence. |
| ~~OCNI~~ | **Not current. Do not publish** `[verified 2026-08-26 — Pouya]` |
| ~~LSO~~ | **Do not publish.** Listing the Law Society among memberships implies licensure, which D13 bars. Excluded deliberately, not by oversight `[verified 2026-08-26]` |
| Toronto, Ontario; by appointment | `[verified 2026-08-26]` |
@@ -265,9 +267,29 @@ appointments now**, and that — his acceptance — is what the rows below recor
> **For an offering, ask about COMPETENCE. For a credential, ask about
> PERMISSION.** A credential claim needs a row in the Verified table because it
> asserts a fact about Pouya that is either true or false. An offering needs two
> things, and they are answered by different people:
> asserts a fact about Pouya that is either true or false. An offering needs
> **three** things, and they are answered by different people:
>
> 0. **Is this a role in which the practice is PARTISAN between the parties to a
> dispute?** — ***his call, and only his.*** It is a question about **role
> design**: what the practice holds itself out as doing, which is his to
> define. Not the register's, not an implementer's, not a reviewer's.
> **If the answer is yes, the offering is refused before the test starts**,
> and neither question below is reached. Numbered **0** because it runs first
> and disposes of the candidate on its own.
>
> *The owner was left unstated when this gate was numbered on 2026-08-28,
> while gates 1 and 2 both name one and the ENE row supplied one anyway
> ("it is his to answer"). `adversarial-reviewer`: the intro promises
> "answered by different people", and this section's whole failure history is
> gate 1 being closed by the wrong party — twice, both times caught by audit.
> An unowned gate recreates that opening.*
>
> It is the gate that disposed of **settlement counsel** — and the catch was
> **Pouya's**, not this register's. §4's own row records it: *"Pouya removed it
> as his own error in `docs/01`."* An earlier version of this bullet called it
> "this register's highest-value catch"; the register's credit is for keeping
> the worked example, not for making the catch.
> 1. **Is the activity gated?** — *a question for THIS REGISTER, not for the
> subject.* It needs a source that a reviewer can check, and it is answered
> per activity and per jurisdiction, never as a class. Until it is answered,
@@ -275,6 +297,15 @@ appointments now**, and that — his acceptance — is what the rows below recor
> 2. **Is he competent to do it?***his call, and only his.* Not the
> register's, not an implementer's, not a reviewer's.
>
> ⚠️ **GATE 0 WAS UNNUMBERED PROSE UNTIL 2026-08-28, AND IT LIVED ONLY IN THE
> WORKED EXAMPLE.** The rows in the Offerings table cited "gates 2 and 3" and
> quoted Pouya's ruling about *"all three gates"* while the section titled *The
> offering test* enumerated two — so an implementer at step 5 reading the
> definition would not find a third gate at all, and the partisan check was
> invisible from the place it is defined. Found by `adversarial-reviewer`.
> **The rows' "gate 3" is this gate 0.** Numbering it 0 rather than 3 records
> that it runs before the others rather than after them.
>
> **Question 1 is not his to answer**, and an earlier draft of this test said it
> was: it ended "That is his call, not the register's, and not an implementer's"
> attached to the *whole* preceding question, gating included. That hands a
@@ -345,9 +376,9 @@ never be read as one:
| **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 |
| ~~**Family arbitration** under the *Family Law Act*~~ | **NOT OFFERED — a scope exclusion, not a gating problem** `[verified 2026-08-27 — Pouya, Q39]`. Pouya has confirmed he does not do family arbitration. It is therefore out of scope by his choice, and the prescribed-training question never arises for this practice. Recorded because the register reasoned from a false universal for one day and must not do so again — see the box above and `docs/reference/ontario-family-arbitration-training.md`. **`Shareholder & Family Business` does not touch this:** it means commercial disputes among family shareholders — shareholder and partnership disputes, co-founder breakdowns, business succession — and its page must say plainly that family law matters are not accepted |
| **Early neutral evaluation (ENE)** | ⚠️ **COMPETENCE ANSWERED; GATING NOT ANSWERED — NOT YET PUBLISHABLE.** Question 2: *"A neutral assessment of merits sits inside a Q.Med's competence"* `[Pouya's stated basis 2026-08-27, Q42]`. Question 1 — **is the activity gated?** — is `[unestablished]`. An earlier version of this row read *"Ungated on the same footing as mediation — no designation is required to give a non-binding evaluation"* under a `[verified — Pouya]` stamp. That is **a proposition of Ontario law inside a stamp §4 says cannot carry one**, and it was the register doing exactly what the box above warns against, one paragraph after warning against it. Struck by `claims-auditor` on two consecutive passes. **ENE is also the offering nearest the gated side of the boundary** a neutral assessment of the *merits*, delivered to parties — so it is the one that most needs a source rather than an assertion. Q46. Priced hourly in `docs/07-fees.md`, which is a fee-page question, not a publication licence |
| **Dispute-system design** | ⚠️ **COMPETENCE ANSWERED; GATING NOT ANSWERED — NOT YET PUBLISHABLE.** Question 2: *"Consulting, no appointment, no neutrality question"* `[Pouya's stated basis 2026-08-27, Q42]`. **That sentence answers neutrality, not gating**, and an earlier version of this row presented it as though it answered both. Question 1 is `[unestablished]` and is not his to answer. Q46 |
| **Pre-dispute technical advisory** | ⚠️ **COMPETENCE ANSWERED; GATING NOT ANSWERED — NOT YET PUBLISHABLE.** Question 2, in three words: *"It is the moat"* `[Pouya's stated basis 2026-08-27, Q42]`. Question 1 is `[unestablished]`. Q46. **Caution that belongs with the row regardless:** advisory work for one organisation is the one item in this table that can create a conflict against a later appointment in the same matter. That is practice management rather than a publication gate — but no copy may imply it is free of that tension |
| **Early neutral evaluation (ENE)** | **PUBLISHABLE** — Pouya's second ruling on **Q46(a)**, 2026-08-28: *"ENE, dispute-system design and pre-dispute advisory pass all three gates. Flip the rows. Step 5 unblocked."* **Gate 0 (partisan?) — passes:** delivered *to the parties* as a neutral, not for one of them. **Gate 2 (competence) — passes:** *"A neutral assessment of merits sits inside a Q.Med's competence"* `[Pouya's stated basis 2026-08-27, Q42]`. **Gate 1 (is the activity gated?) — `[Pouya's stated basis 2026-08-28]`, NOT `[verified]`, and there is still no source in `docs/reference/`.** This register held the row for one day on the ground that gate 1 needs a source a reviewer can check. He has now ruled with that objection in front of him, and **it is his call**: gate 1 is a proposition of Ontario law about his own practice, and §4 bars this file from concluding one in either direction. Same treatment as the commercial-arbitration proposition above — the ruling is **attributed**, not verified, and a later reader should read it as one. **Still the offering nearest the NOT-NEGOTIABLE boundary:** a neutral assessment of the *merits*, delivered to parties, sits closest to *"providing legal services"*, so `/practice/`'s strip must frame it as an assessment delivered to **both** parties and never as advice to one. **What would still upgrade the evidence** (an improvement now, not a gate): the Ontario *Law Society Act* s. 1 definition of "providing legal services" and LSO By-Law 4, committed verbatim to `docs/reference/`, with the application to ENE left to Pouya or to counsel — never drawn by this register or by an implementer. §4's worked-example prose cites this row for it. Priced hourly in `docs/07-fees.md`; the line item may now ship |
| **Dispute-system design** | **PUBLISHABLE** — same ruling as the ENE row above; read it for how gate 1 was closed and on whose authority. **Gate 0 — passes:** it advises *an organisation* about its future disputes, so there is no party to be partisan between. **Gate 2 — passes:** *"Consulting, no appointment, no neutrality question"* `[Pouya's stated basis 2026-08-27, Q42]` — that sentence answers **neutrality**, which is gate 0, and it is not presented here as answering gating. **Gate 1 — `[Pouya's stated basis 2026-08-28]`.** Weakest gating concern of the three: advisory consulting to an organisation is furthest from the boundary |
| **Pre-dispute technical advisory** | **PUBLISHABLE** — same ruling as the ENE row above. **Gate 0 — passes:** it precedes any dispute, so there is no party to be partisan between. **Gate 2 — passes**, in three words: *"It is the moat"* `[Pouya's stated basis 2026-08-27, Q42]`. **Gate 1 — `[Pouya's stated basis 2026-08-28]`.** ⚠️ **The caution below is NOT a publication gate and does not lift with the ruling:** advisory work for one organisation is the one item in this table that can create a **conflict against a later appointment in the same matter**. That is practice management — but no copy may imply the offering is free of that tension, and `/practice/`'s strip at step 5 is where the temptation to imply it will arise |
| ~~**Settlement counsel**~~ | **NOT OFFERED, AND IT IS STRUCK RATHER THAN UNROWED** `[verified 2026-08-27 — Pouya, Q42]`. Pouya removed it as **his own error in `docs/01`**: *"Settlement counsel acts **FOR a party** in negotiation. That is a partisan role, and putting it on a site that (a) sells neutrality and (b) asserts no licensure under D13 is **wrong twice over**: it undercuts the brand's central claim and it edges into acting for a client."* **Note the ordering — the positioning objection comes first.** It would still be wrong on a site with no licensure question at all, which is why this row does not read as a D13 consequence. Struck from `docs/01` §`/practice/`, from `docs/07-fees.md`'s hourly list, and from the §4 scope enumeration above. Never priced, never listed, never restored |
| ~~Tribunal secretary~~ | **Not offered.** D14 removed the rate and bars offering it |
@@ -392,12 +423,19 @@ above.
candidates at once and one of them fails.** Pouya's instruction was literally
*"apply the offering test"*, and the outcome was 31.
| Candidate | Q1 — is the activity gated? *(the register's, with a source)* | Q2 — competence? *(his)* | Outcome |
|---|---|---|---|
| Early neutral evaluation | **`[unestablished]`** — no source. Q46 | *"sits inside a Q.Med's competence"* | **Not publishable yet** |
| Dispute-system design | **`[unestablished]`** — no source. Q46 | *"Consulting, no appointment, no neutrality question"* | **Not publishable yet** |
| Pre-dispute technical advisory | **`[unestablished]`** — no source. Q46 | *"It is the moat"* | **Not publishable yet** |
| Settlement counsel | **Never reached** | — | **STRUCK** |
| Candidate | **Gate 0 — partisan between the parties?** *(his)* | Gate 1 — is the activity gated? *(the register's, with a source)* | Gate 2 — competence? *(his)* | Outcome |
|---|---|---|---|---|
| Early neutral evaluation | **No** — delivered to the parties as a neutral | **`[Pouya's stated basis 2026-08-28]`** — ruled, no source. Q46(a) closed | *"sits inside a Q.Med's competence"* | **Publishable** |
| Dispute-system design | **No** — advises an organisation; no party to be partisan between | **`[Pouya's stated basis 2026-08-28]`** — ruled, no source. Q46(a) closed | *"Consulting, no appointment, no neutrality question"* | **Publishable** |
| Pre-dispute technical advisory | **No** — precedes any dispute | **`[Pouya's stated basis 2026-08-28]`** — ruled, no source. Q46(a) closed | *"It is the moat"* | **Publishable** |
| **Settlement counsel** | **YES — acts FOR a party. Disposed of here.** | *never reached* | *never reached* | **STRUCK** |
*The gate-0 column was added 2026-08-28. Without it the only STRUCK candidate's
disposition sat inside the Q1 cell ("Never reached — failed gate 0"), so the gate
that actually disposed of it was recorded under a different gate's heading — and
a reader running the table column by column ran gates 1 and 2 only. This table is
the operational artefact; `adversarial-reviewer` found it did not run the test it
demonstrates.*
**THE Q1 COLUMN WAS FILLED IN WITH HIS ANSWERS AND HAS BEEN EMPTIED.** The first
version of this table read *"No. A non-binding neutral assessment is not a
@@ -409,6 +447,33 @@ No jurisdiction was named for any of the three. `claims-auditor` caught this
substitution on 2026-08-26 in one place and again on 2026-08-28 in this table —
**the same defect, in the paragraph added to explain the defect.**
**THE COLUMN IS STILL EMPTY OF A SOURCE, AND THE ROWS ARE NEVERTHELESS
PUBLISHABLE. BOTH HALVES OF THAT ARE DELIBERATE.** Pouya ruled on 2026-08-28
that all three *"pass all three gates including the new partisan question"*.
Gates 0 and 2 are his and are answered. **Gate 1 is not usually his** — this
section says so twice, in bold, because it had twice been closed with his words
and both closures were caught by an audit rather than by the register.
**So the register declined to flip the rows, put that objection in front of him,
and he ruled a second time with it in view.** At that point the rows flip. Gate
1 asks a proposition of Ontario law about his own practice; §4 bars this file
from concluding one in either direction; and a register that holds a row against
a repeated, informed ruling is substituting its judgement for the architect's,
which is not what it is for.
**What survives, and it is the whole of the protection:** the gate-1 column
records **`[Pouya's stated basis 2026-08-28]`** and **never `[verified]`**. A
reviewer reading these rows sees an attributed position, not a sourced fact —
the same treatment §4 gives the commercial-arbitration proposition. Gate 1 was
never a veto; it was a requirement to say *whose* answer it is, and it still
does that.
**What would still improve it** is named in the ENE row: the *Law Society Act*
s. 1 definition of "providing legal services" and LSO By-Law 4, committed
verbatim, with the application left to Pouya or to counsel. That is now an
upgrade to the evidence rather than a gate on publication. **Step 5 is
unblocked.**
**The reason settlement counsel fails is the finding.** It did not fail question
1 and it did not fail question 2. It failed a prior question the test does not
ask: **is this a neutral's role at all?** Settlement counsel acts *for* a party.
@@ -556,7 +621,7 @@ the audience it targets. Revisit at month 1218. `[verified 2026-08-25 — dec
| Intake backend | API Gateway (HTTP API) → Lambda → DynamoDB, notifications via SES `[verified 2026-08-25 — AWS-Hosting-Guide.md]` |
| Repository | **`adr-sml`**, self-hosted **Gitea**. Local clone at `/Users/pouya/Dev/Websites/adr-sml` `[verified 2026-08-26]` |
| CI/CD | **Gitea Actions**, `.gitea/workflows/deploy.yml`. Instance **git.larsnolden.com, version 1.27.2** `[verified 2026-08-26 — /api/v1/version]` — well above the ~1.21 floor for the `vars` context. The GitHub OIDC workflow is kept as `docs/reference/github-actions-oidc.yml.example`, outside `.github/workflows/` so Gitea cannot fall back to it. **No OIDC available** — Gitea is not an AWS OIDC provider |
| **Deploy credential — NOT PROVISIONED** | `aws iam get-user --user-name adr-sml-deploy` returns **NoSuchEntity** `[verified 2026-08-26 — Q22]`. The scoped IAM user does not exist, no access key has been issued, and the Gitea secrets are unset. **No file may describe this credential as existing.** Creation commands are with Pouya; this is a to-do, not an open question |
| **Deploy credential — PROVISIONED** | IAM user **`adr-sml-deploy`**, created **2026-08-26T15:45:18Z**, `arn:aws:iam::327082975128:user/adr-sml-deploy` `[verified 2026-08-28]`. **No managed policies, no group memberships.** One inline policy, `adr-sml-deploy-minimal`: `s3:ListBucket` on the site bucket, `s3:PutObject` + `s3:DeleteObject` on `bucket/*`, `cloudfront:CreateInvalidation` on the distribution this section records. **One active access key, created 2026-08-26, NEVER USED**`AccessKeyLastUsed` returns `ServiceName: "N/A"` / `Region: "N/A"` with no `LastUsedDate` key at all, because deploys still run locally. **Verified by execution, not by reading**`iam simulate-principal-policy`, **nine** checks: `allowed` for the four intended actions (`s3:PutObject`, `s3:DeleteObject`, `s3:ListBucket`, `cloudfront:CreateInvalidation`); `implicitDeny` for the five that matter more — `s3:ListBucket` and `s3:GetObject` on the client-database backup bucket, `s3:DeleteBucket` on its own bucket, `s3:PutObject` on `meshkinilaw.ca`, and `iam:CreateUser` on `*`. **The resource side is checked too:** `get-bucket-policy` on the backup bucket exits **254** with `NoSuchBucketPolicy`, so no resource-based grant exists and IAM is the only path in — and the same call against the *site* bucket exits 0 with a real CloudFront OAC policy, which is what makes the first result an absence rather than a broken command. **✅ EVIDENCE IS IN THE REPOSITORY — R14 SATISFIED. `docs/reference/deploy-credential-verification.md`**, eighteen read-only calls, each with the command that produced it, the access key ID redacted; re-run 2026-08-28 rather than transcribed, and `adversarial-reviewer` independently reproduced every value including the `MatchedStatements` positions. Q52 closed. ⚠️ **GITEA ACTIONS SECRETS: `UNSET`** `[verified 2026-08-26]` — no access key has been placed in a repository secret on `git.larsnolden.com`, so the key exists in IAM and **nowhere on the jointly-administered instance**. That is a different fact from the key being unused: a key can sit on shared infrastructure without ever authenticating. **Rotation: §12 R17 carries the date and the procedure** — this row deliberately does not restate it |
| **How deploys actually happen today** | **Locally, via `npm run deploy`** (`scripts/deploy-local.sh`) — same guard, same three sync passes, same cache headers, same invalidation as the workflow. Gitea Actions needs `[actions] ENABLED` in `app.ini` and a registered `act_runner`, both of which need the instance's second administrator (Q23). At this scale the pipeline changes only **how a deploy is triggered**, not what it does `[verified 2026-08-26]` |
| **Interim auth — do not repeat in CI** | Pouya has been authenticating as **`user/pouya`**, the broadly-permissioned personal user the Q10 inventory captured. Acceptable for interactive work at a keyboard; **never** as a CI credential — see §10 `[verified 2026-08-26]` |
| Analytics | **Plausible** — cookieless, no personal data, no consent banner, **all data held in the EU** `[verified 2026-08-26 — D15 as amended, Q31]`. `src/data/site.ts` sets `ANALYTICS.provider`. Not yet installed: no script is on any page, and `/legal/privacy/` (step 10) is where the processor gets named |
@@ -591,7 +656,7 @@ Nothing below can be invented. Each needs an answer from Pouya.
| ~~Q25~~ | **ANSWERED 2026-08-26. Struck.** The §4 row permitting the boutique to be named is removed; D16 governs alone | — |
| ~~Q26~~ | **ANSWERED 2026-08-26.** §4 now carries an explicit **Licence status — NOT ESTABLISHED** row, and its opening no longer asserts that LSO rules apply. The register's rationale stands on the fabricated-credentials history alone | — |
| ~~Q24~~ | **ANSWERED 2026-08-26.** `AWS-Hosting-Guide.md` copied into `docs/reference/` — it is the only record of how the hand-built infrastructure was created. Scanned for credentials before copying: no access keys, no secrets, no account ID | — |
| ~~Q22~~ | **ANSWERED 2026-08-26 — it does not exist.** `aws iam get-user --user-name adr-sml-deploy` returns `NoSuchEntity`. Recorded in §7 as **NOT PROVISIONED**; creation commands are with Pouya, so it is now a **to-do**, not a question. Consequence while it is outstanding: deploys run locally (`npm run deploy`), and the quarterly rotation obligation in D3 still has no subject | — |
| ~~Q22~~ | **CLOSED ON EXECUTION 2026-08-28 — it exists, and it was verified by running the checks rather than by reading the policy.** IAM user `adr-sml-deploy` created 2026-08-26T15:45:18Z; one inline least-privilege policy; one active access key, never used. Full inventory and the **nine** `simulate-principal-policy` results are in §7. **Two things make this a closure rather than a status update.** (1) The scoped policy was the control §10 identified as *"the actual control standing between a shared Gitea instance and an AWS account holding another business's client-database backups"* — it now exists **and has been proven negative** against that bucket, not just positive against its own. (2) `get-bucket-policy` on the backup bucket returns `NoSuchBucketPolicy`, closing the gap that policy-reading alone could not: a resource-based grant would have been invisible from the IAM side. **The quarterly rotation obligation in D3 now has a subject and a date** — 2026-11-26, in §12 R17. Deploys still run locally; the key exists but is unused. **The tool output IS committed**`docs/reference/deploy-credential-verification.md`, Q52 closed 2026-08-28; R14 is satisfied for this row. | — |
| Q5 | Booking tool — **parked 2026-08-26 at Pouya's request.** Build `/contact/` with the form only and a clean slot for the embed. Now tracked as standing reminder R6 | `/contact/` — non-blocking |
| ~~Q6~~ | **ANSWERED 2026-08-26.** Supplied and committed: `src/assets/pouya-lajevardi.jpg` (1600×1600 master) and `src/assets/og-portrait.jpg` (1200×630 link-preview crop) | — |
| ~~Q7~~ | **ANSWERED 2026-08-26.** Pouya reverted to generic. The boutique is **never named**; refer to it as *a Toronto litigation and ADR boutique* throughout | — |
@@ -616,7 +681,7 @@ Nothing below can be invented. Each needs an answer from Pouya.
| ~~Q36-orig~~ | **Is co-arbitration work available now?** Asserted in three specs — `docs/01` §`/arbitration/`, `docs/03` §Voice as model copy, and `docs/07-fees.md`, which instructs *"The page must say so"* — and **it is in no §4 row.** §4 records the Q.Arb pathway as commenced August 2026 and nothing about what is available in the meantime. The sentence is offered under the heading *"Name the limits"*, so the unverified half travels inside advice about honesty, which is how it survived. All three files now cite this question; none has been deleted, because the *shape* of the sentence is right and only its second clause is unsourced. Raised by `claims-auditor`, 2026-08-26 | `/arbitration/` (step 4) and `/fees/` (step 9) |
| ~~Q37~~ | **ANSWERED 2026-08-27 — the label changes.** `JD + ML` is now labelled **"Legal training and engineering practice"**, not "Law and engineering". Pouya's reasoning, and it is the finding rather than the fix: *"The parallel was doing the implying — a degree and a practice under one noun. The asymmetry is the honest part."* A degree is not a practice, and a label that renders them as two instances of one thing invites the reader to supply the missing symmetry — which for "Law" is precisely the licensure implication D13 bars. The new label is longer and less tidy, deliberately. `docs/03`'s credential-row table is amended, and the `TODO(pouya)` is gone from `src/data/site.ts`. Original question follows | — |
| ~~Q37-orig~~ | **Is "Law and engineering" the right label under `JD + ML`?** §4's substitution principle supplies the three credential-row **values** (`Q.Med` / `JD + ML` / `EN · FA`); the labels come from `docs/03` and are not themselves registered. `claims-auditor` reads this one as a D13 implication risk: "engineering" is shorthand for a **verified practising** claim, so the parallel invites "Law" to be read the same way, and D13 bars implication as hard as assertion. Left as written — it is approved copy and changing approved copy is not an implementer's call — with a `TODO(pouya)` on it in `src/data/site.ts`. Nothing renders it yet. Raised by `claims-auditor`, 2026-08-26 | The credential row on `/` (step 2) and `/about/` (step 3) |
| ~~Q33~~ | **ANSWERED 2026-08-26 — the question rested on a false premise.** It assumed the constraint on describing arbitration was about *entitlement*. ADR designations are voluntary credentials, not licences, and **commercial arbitral appointment in Ontario is not gated behind a designation** — so the constraint was always positional, never legal, and it was Pouya's to answer. *(This row said "anyone may be appointed an arbitrator in Ontario" until 2026-08-27. **Pouya checked it and it is false as a universal** — family arbitration is gated; see Q39. Corrected in place, because §9 is Current Truth. The Change Log entries that quote the original stand unedited, which is where the history lives.)* He accepts arbitration appointments now. `Mediation · Arbitration · Toronto` is **restored to the masthead one-liner**, and `docs/04`'s specified home `<title>` stands as written. See **§4 Offerings**, added for exactly this class of statement. The original question text follows for the record | — |
| ~~Q33~~ | **ANSWERED 2026-08-26 — the question rested on a false premise.** It assumed the constraint on describing arbitration was about *entitlement*. ADR designations are voluntary credentials, not licences, and **commercial arbitral appointment in Ontario is not gated behind a designation** — so the constraint was always positional, never legal, and it was Pouya's to answer. *(This row said "anyone may be appointed an arbitrator in Ontario" until 2026-08-27. **Pouya checked it and it is false as a universal** — family arbitration is gated; see Q39. Corrected in place, because §9 is Current Truth. The Change Log entries that quote the original stand unedited, which is where the history lives.)* He accepts arbitration appointments now. `Mediation · Arbitration · Toronto` is **restored to the masthead one-liner**, and ~~`docs/04`'s specified home `<title>` stands as written~~**AMENDED 2026-08-28.** The literal is replaced by a composition of `SITE.name` + `SITE.tagline`, so the masthead constants and the title cannot drift; the shipped string is `Pouya Lajevardi · Mediation · Arbitration · Toronto`. Q33's substance is untouched — the unscoped masthead form is still ratified — only the instruction to keep a hand-typed literal is See **§4 Offerings**, added for exactly this class of statement. The original question text follows for the record | — |
| ~~Q33-orig~~ | **How is arbitration described in site-wide copy before Q.Arb is conferred?** Not a wording question — a positioning one, and it recurs on every page. §4 records the Q.Arb pathway as **commenced August 2026**, "never as held or nearing completion". `SITE.tagline` reads `Mediation · Arbitration · Toronto`, and `docs/01` specifies that exact string as the **Home hero eyebrow** — where the hero copy beneath it can qualify it. Build step 1 promoted it to a masthead line under Pouya's name on every page, where nothing qualifies it and it reads as a designation strip; `claims-auditor` flagged it and **it has been removed from the header**. But the question it exposed is still open and lands at build step 2: does the hero eyebrow keep `Arbitration` as specified, qualify it, or hold it until designation? `/arbitration/` (step 4) is separately specced to state the position plainly, which is the honest model — the issue is the one-line forms that have no room to. **Second pass, same day:** the removal from the header did not sweep the proof sheet, where the same string was **hand-typed** as a type specimen and rendered ten times at up to 96px. Both defects fixed — the specimen is now a neutral pangram — and the lesson is the sweep rule again: a removal is a `grep`, not a memory. The nav item `Arbitration` also survives, deliberately; that is Q35. Raised by `claims-auditor`, 2026-08-26 | The Home hero (step 2); `docs/04`'s specified home `<title>`; any bio or one-line descriptor |
| **Q34** | **Do §2's measurements of the previous build still hold, and were they measured against the deployed file?** Two of `claims-auditor`'s findings were unverified old-site assertions published in copy, which sent Claude Code to measure the live URL on 2026-08-26. What came back does not straightforwardly match §2. **Reproduced:** the response is a single **2,206,032-byte** file, and `<title>` is still `SML Company · Dispute Resolution`. **Could not be reproduced from the served HTML:** there are **zero** `base64,` occurrences anywhere in it — §2 records "two logo PNGs ~1 MB, base64-inlined" — and no reference to `unpkg` or a React development build. **Why this is a question and not a correction:** the served document is a *bundler harness*. 2,210,921 bytes of it are inline `<script>`, the real `<head>` sits JSON-escaped inside a `<script type="__bundler/template">`, and the application is loaded from **nine UUID-named script files that were not fetched**. The logos and the CDN references may well be in those bundles. So §2 may be right, may be stale, or may have been measured against the local source rather than the deployment — this record cannot tell which. **Why it matters beyond tidiness:** `docs/02` and `CLAUDE.md` both cite the base64-logo figure as the *reason* for a standing convention, and §12 R8 exists because unverified premises propagate. Nobody should quote these numbers in public copy until the question closes. Raised by Claude Code, 2026-08-26 | Nothing structural. It governs whether §2's figures may be cited as fact |
| ~~Q39~~ | **ANSWERED 2026-08-27 — and the answer is that the register's premise was FALSE.** Pouya checked it rather than defending it. His words: *"My assertion was FALSE as a universal."* **(a) Is it gated? YES.** Family arbitrators in Ontario must complete prescribed training — 14 hours on screening for domestic violence and power imbalances, 30 hours of Ontario family law for arbitrators outside the Ontario or another Canadian bar, and 10 hours ongoing per two-year period. **Sourced, and the source is now in the repo** per R14: `docs/reference/ontario-family-arbitration-training.md`, retrieved 2026-08-27 with provenance. **(b) Does the offering extend to it? NO** — and that is what actually disposes of the question. Pouya does not do family arbitration, so it is a **scope exclusion, not a gating problem**, and the prescribed-training requirement never bears on this practice. `Shareholder & Family Business` means **commercial disputes among family shareholders** — shareholder and partnership disputes, co-founder breakdowns, business succession — and its page must state plainly that family law matters are not accepted. *One sentence, not a section: Pouya's instruction is that it earns its place only by saving a wasted intake call.* **(c) One honest limit on the source.** The extract establishes the family gate directly and the commercial half only by absence — it neither mentions nor excludes commercial arbitration. §4 therefore carries *"commercial arbitration in Ontario requires no licence and no designation"* as **Pouya's stated position, unstamped**, not as a sourced fact. Do not let the footnote promote it. **Also swept:** the false universal survived in three live places outside the paragraph that was corrected — §4's NOT-NEGOTIABLE boundary bullet, §9's Q33 closure row, and a comment in `SiteHeader.astro`. All three fixed; the `grep` and its output are pasted in **Change Log entry (w), §Sweeps**. *(`adversarial-reviewer` flagged this citation while it still pointed at nothing: the entry was written at Phase 6, after review, so for the duration of the review a §9 row asserted in the present tense that evidence "is in the Change Log" before it was. Fair catch. The row now names the entry, and the reviewer independently re-ran the sweep and confirmed it was genuinely complete.)* Original question follows | — |
@@ -625,10 +690,17 @@ Nothing below can be invented. Each needs an answer from Pouya.
| ~~Q41~~ | **ANSWERED 2026-08-27 — all three, and two of the three interim wordings were wrong in a way the interim had not identified.** **(a) Q37's reasoning DOES extend to prose, and prose is held to a HIGHER bar, not a looser one.** Pouya: *"The implication test applies everywhere, not just to labels. Prose has more room, so it is easier to satisfy: **state the asymmetry explicitly** rather than relying on a parallel construction to carry it."* Deleting the parallel — which is all the interim did — was half the fix; a reader can still supply the missing symmetry from silence. Both pages now name both halves, from **one constant**`ASYMMETRY_LINE` in `src/data/site.ts`, which is where a claim-bearing sentence belongs (`ROLE`'s reasoning: *"these are the two where the wording IS the compliance"*). It was typed into `/` and then into `/about/`, and **the two copies had diverged inside the same session** — a comma on one, full stops on the other — which is why it is a constant and why this row cites it rather than quoting a variant. Calling the legal half **training** is what makes the licence implication impossible rather than merely absent. `docs/01` §`/` item 3 and `docs/03` §Home both carry a warning not to lift their own phrase *"law and engineering"* into copy. **(b) NOT restored, and the editorial reason outranks the compliance one.** Pouya: *"That is an unverifiable empirical claim about other practitioners… **It is also weaker copy: assert his capability, not the field's incapability.**"* His replacement is used verbatim — *"disputes that turn on the contract, the code, and the engineering documents"* — and it replaces the comparative in `docs/03`'s **core positioning statement**, so the approved-copy defence that had protected it is gone. The interim (*"the documents rather than the pleadings"*) is also gone: it said nothing about other neutrals but still worked by contrast. **(c) Verified, and the interim was ambiguous in the one word that mattered.** `docs/reference/lat-case-conference.md` `[verified 2026-08-28]`: LAT **Rule 2.4** makes *"Pre-Hearing Conference"* the Tribunal's own term for a **case conference**; **Rule 14.3** puts a **Member** in the chair and then disqualifies them from the hearing panel; **Rule 14.6** makes attendance mandatory; and the Rules contain **zero** occurrences of `mediat` or `arbitrat` in 66,593 characters. A privately retained neutral cannot be appointed to it. The affirmative basis is on the Tribunal's own AABS page: *"you may want to consider negotiation or mediation services… including before filing at the LAT-AABS, and continuing… after a claim has been filed."* The interim read *"private mediation of matters **before** the LAT"* — where `before` reads as *pending at* as readily as *prior to*. Published: *"private mediation alongside a LAT application, before filing or after."* No roster claim, because there is no row for one | — |
| ~~Q42~~ | **ANSWERED 2026-08-27 — 3 offered, 1 STRUCK, and the one that failed is the finding.** Pouya applied the offering test himself: **early neutral evaluation** (*"A neutral assessment of merits sits inside a Q.Med's competence"*), **dispute-system design** (*"Consulting, no appointment, no neutrality question"*) and **pre-dispute technical advisory** (*"It is the moat"*) each gained a §4 Offerings row and may now ship on `/practice/`. **Settlement counsel is struck**, as his own error in `docs/01`: *"Settlement counsel acts **FOR a party** in negotiation. That is a partisan role, and putting it on a site that (a) sells neutrality and (b) asserts no licensure under D13 is **wrong twice over**: it undercuts the brand's central claim and it edges into acting for a client."* **The positioning objection comes first** — it would be wrong on a site with no licensure question at all, so it is not a D13 consequence. **What it exposed about the test:** settlement counsel fails neither question 1 nor question 2. Run mechanically the test would have PASSED it. It fails a prior question the test does not ask — *is this a neutral's role at all?* — so §4 now records that the offering test **presumes** a neutral role, with the Q42 worked example kept as the 31 table. Swept by command: `docs/01` §`/practice/`, `docs/07-fees.md` (three services at the hourly rate, not four), `FEES.hourly`'s comment, and `/`'s areas-more comment. `AGENTS.md` lines 293 and 3298 are the §4 scope enumeration (fixed) and Change Log entry (d) (history, not edited) | — |
| ~~Q43~~ | **ANSWERED 2026-08-27 — and the ruling reversed the reasoning that had blocked it.** The interim shipped the five timings as bare numbers because `docs/03` §Process required them *"real"* rather than illustrative, which was read as **barring** the word "typical". Pouya: the timings are **service commitments, the same class as Q27's response time***"not facts about Pouya, so they need framing, not a Verified row. Present them as the TYPICAL shape of an engagement, explicitly not a guarantee: mediation timing depends on party and counsel availability, which he does not control. **Published as typical, they are honest and useful; published as commitments, the first matter that slips makes the page false.**"* So no §4 row, and **the numbers are unchanged** — softening them was never the fix. What ships is `PROCESS_FRAMING` in `src/data/site.ts`: *"This is the typical shape of an engagement, not a commitment. Timing depends on party and counsel availability, which I do not control."* **Not optional, and placed adjacent to the numbers rather than in a section lede above them** — a reader who scans the strip and skips the lede has read a commitment. `docs/03` §Process amended to record the override; `docs/01` §`/process/` requires the same rendering at step 6 | — |
| **Q44** | **R10 discharge — are all four memberships current TODAY, and in which month does each renew?** §4 verifies **ADRIC**, **ADRIO**, the three **OBA** sections (Construction & Infrastructure, ADR, Civil Litigation) and the **Canadian Tax Foundation** `[verified 2026-08-26 — Pouya]`, *for now*. **Only Claude Code can raise this; only Pouya can close it** — a two-day-old stamp is not a renewal receipt. **What §4 actually says about renewal, because an earlier version of this row said more:** the **OBA sections and the CTF** renew yearly. §4 records **nothing** about ADRIC's or ADRIO's renewal period, and this row asserted *"All renew yearly"* — a widened fact that had already propagated to `schema.ts`, `docs/06` and `/about/`'s own comment. Fixed in all four. **`/about/` DOES NOT PUBLISH THE MEMBERSHIPS.** An earlier version of this row said it did, and so did §12 R10, `docs/06` and `schema.ts` — four documents recording a page state that had been reversed and not swept, on the one credential class that has already lapsed once (OCNI). R10 is written as a **prohibition**, not a disclosure duty, so the group is withheld and `CREDENTIAL_GROUPS` carries a `TODO(pouya)` with this question. Designations, Education and Certifications ship. **Blocks the memberships block, not step 3.** Four yes/no answers and four renewal months closes it — and the months are what stop this recurring, because they turn R10 from a reminder into a date. Raised by Claude Code 2026-08-28; scope corrected the same day by `claims-auditor` | The Memberships group on `/about/`; `memberOf` in the Person JSON-LD; cutover |
| **Q45** | **The one-page PDF bio — generated, authored, or dropped?** `docs/01` §`/about/` item 7 lists it (brief §VIII: an asset for circulation with appointment proposals) and **it does not exist**; `/about/` therefore ships without a link to it, because a link to a missing file on the page an appointing body reads is worse than the absence. **Why it is a question and not a task:** it is a **credential document**, so every line traces to §4 exactly as a web page does — and it is circulated **detached from the site**, where no reviewer ever sees it again and no build can re-check it. That is the one artefact class this project's whole review apparatus cannot reach. Two decisions are his: (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. Raised by Claude Code, 2026-08-28 | Nothing on the site. It is a circulation asset, wanted before the first appointment proposal |
| **Q46** | **Two questions the offering test cannot close by itself, and one about the glossary.** **(a) Is early neutral evaluation gated in Ontario, and are dispute-system design and pre-dispute technical advisory?** Pouya answered question 2 (competence) for all three on 2026-08-27 and those answers stand. **Question 1 is the register's and it is `[unestablished]`** — §4: *"It needs a source that a reviewer can check, and it is answered per activity and per jurisdiction, never as a class."* No source exists in `docs/reference/` for any of the three (R14). It matters most for **ENE**, which is the offering nearest §4's NOT-NEGOTIABLE boundary: a neutral assessment of the **merits**, delivered to parties, sits closest to *"providing legal services"*, where the binding question is permission and the answer is not established. **Consequence today: none on the site** — the three appear only in comments — but the rows authorise `/practice/`'s "also offered" strip at step 5 and `docs/07-fees.md` prices them, so it blocks step 5, not step 3. Twice-flagged: `claims-auditor` found the register answering its own question 1 with the subject's words on 2026-08-26 and again on 2026-08-28, the second time inside the paragraph added to explain the first. **(b) May §11 Glossary be published as the source for DEFINITIONAL expansions** — what `Q.Med`, `Q.Arb`, `C.Med-Arb`, `POA`, `SABS`, `ADRIC` and `ADRIO` stand for? This is not a claim about Pouya; "he holds it" is the claim and that has a row. `/about/` currently publishes all four classes on this basis, and the alternative is to strip *"Provincial Offences Act"*, *"the ADR Institute of Canada and the ADR Institute of Ontario"* and `recognizedBy` from the JSON-LD as well — which serves no reader and reduces no risk. Sourcing them externally was tried and failed: `adric.ca/designations/` redirects to `/designations-cee/` and serves **zero** occurrences of `Q.Med`, `Qualified Mediator` or `Chartered Mediator` in 114,985 bytes. **This is the one place this session went against a review finding**, on a later finding that the standard was being applied inconsistently. Raised by Claude Code 2026-08-28 | (a) `/practice/` and its strip (step 5), `/fees/` (step 9). (b) `/about/`'s arc and the Person JSON-LD, live now |
| **Q47** | **`Person.jobTitle` is published without `worksFor`, and the two halves of one §4 row are separated in machine-readable form.** §4's row is *"Director of Firm Operations, **Toronto litigation and ADR boutique**"* — one row, one fact, two halves. Visible copy always pairs them (`/about/`: *"Director of Firm Operations at a Toronto litigation and ADR boutique"*). The JSON-LD emits `jobTitle: 'Director of Firm Operations'` with **`worksFor` deliberately omitted**, on a `Person` node whose `url` is this ADR practice's `/about/` — so a consumer may attach the title to **this** entity, which is not what the row says. **This is a structural bind, not an oversight:** `docs/04` instructs the omission and D16 bars naming the employer, so there is no value `worksFor` may take. The options are (i) drop `jobTitle` from the graph and let the visible copy carry the role, (ii) keep it and accept the implication, or (iii) get a §4 row for the half-claim. Flagged twice by `claims-auditor`, which declined to choose. Raised by Claude Code 2026-08-28 | Nothing visible. The Person node on `/` and `/about/`, live now |
| ~~Q44~~ | **ANSWERED 2026-08-28 — all four current; R10 DISCHARGED, and it changes shape rather than closing.** Pouya: *"All four are current as of today."* ADRIC, ADRIO, the three OBA sections, the CTF. §4 re-stamped and `/about/` now renders the Memberships group. **Two consequences came with the answer and both are applied:** (1) **no currency warranty on the page** the struck sentence stays struck and nothing replaces it, because he **declined renewal-date tracking** and so nothing in this repo could support one; (2) **R10 stays live and now fires on an EVENT, not a date** — re-confirm before any cutover or major republish. His reason, recorded because it is the general lesson: *"§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 this answer did NOT settle**, both flagged to him rather than assumed: the stamp date (he wrote 2026-08-26, the original confirmation; the stamp reads **2026-08-28**, when he re-confirmed — a currency stamp records when the assertion was made), and `memberOf` in the JSON-LD — **which Q53 then ruled should be emitted, 2026-08-28.** `/about/`'s Person node carries the four memberships as `Organization` nodes; this row said "still withheld" until that sweep was actually run. See §4, §12 R10, `src/data/schema.ts` | — |
| ~~Q45~~ | **DEFERRED 2026-08-28 with a recorded trigger — now §12 R16.** Pouya: *"The one-page PDF bio is a derived artifact — generating it before `/about/` and `/fees/` are final just means generating it twice. Ship it at step 9 alongside `/fees/`, since an appointment proposal needs both. Record the trigger so it doesn't become another quiet interim."* Same disposition and same reasoning as Q40/R15: deferred with a build-step trigger rather than left as an untracked gap. The two decisions the question raised — generated-at-build vs authored once, and whether it carries anything the site does not — are **not** answered by the deferral and travel with R16 to step 9. The reason it is a credential document rather than a marketing one also travels: it circulates **detached from the site**, where no reviewer sees it again and no build can re-check it | Nothing. Tracked as R16, due at build step 9 |
| ~~Q46(a)~~ | **RULED A SECOND TIME AND CLOSED 2026-08-28 — PUBLISHABLE, and gate 1 is closed by the architect rather than by a source.** Pouya: *"Q46(a) PUBLISHABLE — ENE, dispute-system design and pre-dispute advisory pass all three gates. Flip the rows. Step 5 unblocked."* The three §4 Offerings rows are flipped, the worked-example table's gate-1 column reads `[Pouya's stated basis 2026-08-28]`, and `docs/01` and `docs/07` no longer carry the 🚫 blocks. **What this register held out for, and why it yields:** gate 1 asks *is the activity gated?* and §4's own test says it *"needs a source that a reviewer can check"*; no source for any of the three exists in `docs/reference/`. Pouya ruled once, this file declined to flip the rows and put the objection in front of him, **and he ruled again**. That is the mechanism working as designed rather than failing: gate 1 is a proposition of Ontario law about his own practice, §4 bars this file from concluding one in either direction, and holding a row against a repeated ruling would be this file substituting its judgement for the architect's. **The trade is recorded in the rows themselves**`[Pouya's stated basis]`, never `[verified]` — so a reviewer sees an attributed position rather than a sourced fact. The framing constraints survive the ruling and are **not** discretionary: ENE is an assessment delivered to both parties, never advice to one; and the conflict caution on pre-dispute advisory is practice management, so no copy may imply the offering is free of it | — |
| ~~Q46(b)~~ | **(b) RATIFIED AND NOW SOURCED, 2026-08-28. (a) RULED, AND THE RULING DOES NOT CLOSE IT — now tracked as its own live row above.** **(b):** §11 Glossary is the source for **definitional expansions**; §4 remains the only source for claims about Pouya. Pouya: *"The line is the same one the Offerings ruling drew — 'Q.Med stands for Qualified Mediator' is a fact about the designation's name, not about him… You were right that one standard or the other had to apply."* He attached a condition — commit the source — and `docs/reference/adrio-designations.md` satisfies R14: all five expansions in ADRIO's own words, four independent fetches, reproducible sha256. **That fetch immediately earned itself** by catching that §11's `C.Med-Arb` expansion was wrong and had shipped to a public page. **(a):** he ruled that ENE, dispute-system design and pre-dispute technical advisory *"pass all three gates"*. Gates 0 and 2 are his and are answered. **Gate 1 is not his** — §4 says so twice — and it requires **an artefact, not a decision**: a checkable source, per activity and per jurisdiction. None existed and the ruling named none, so the three rows were held and the objection was put back to him as **Q46(a)****which he then ruled a second time, and Q46(a) is CLOSED. The rows are PUBLISHABLE and step 5 is unblocked;** gate 1 carries `[Pouya's stated basis 2026-08-28]`, not `[verified]`. Read the Q46(a) row above, not this sentence, for the disposition | Both closed |
| ~~Q47~~ | **ANSWERED 2026-08-28 — set both. THEN BOTH FIELDS WERE REVERTED THE SAME DAY, AND THE OPEN HALF IS Q49.** ⚠️ **Read this first, because the text below describes an implementation that does not exist.** Measured against `dist` 2026-08-28: the Person node ships `jobTitle: "Mediator"` and **no `worksFor` key at any depth**. `jobTitle`'s ruled value was struck by **both** review agents as the role-shaped claim `claims-auditor` had removed from this same node's `description` the previous day; `worksFor` was struck because §4 rows "**alongside** the practice" where the ruling says "operates **through**", and because `ProfessionalService.provider` is this Person, making the same-entity inference transitive. **Q49** carries both open rows. *This row was written describing the pre-revert state and not updated when the revert happened hours later — verbatim the failure Q44's own history records ("four documents recording a page state that had been reversed and not swept"), reproduced inside the change set that records it. Found by `adversarial-reviewer` on re-review.* **Pouya's ruling, and the reasoning that still stands, follows.** **ANSWERED 2026-08-28 — set both.** Pouya: *"A Person with a jobTitle and no worksFor is incomplete; a worksFor naming the boutique would breach D16. This satisfies both."* The bind is broken by changing what `jobTitle` is **about**: it now describes **this practice** rather than the boutique role, so `worksFor` can name **SML Company Ltd** — verified, federally incorporated, the entity the practice operates through — without going near D16. `ROLE.title` is unchanged and still carries "Director of Firm Operations" in **visible** copy; the graph gets its own constant (`PRACTICE_JOB_TITLE`), which is the separation the ruling actually turns on. **`worksFor` carries the NAME ONLY** — no address, no jurisdiction, no legal form: §4 verifies the federal incorporation and in the same row records it as *not published*, and cautions that it must never be read together with the **Licence status — NOT ESTABLISHED** row into an implication neither makes. A JSON-LD field is exactly where that pairing would travel unedited. **One flagged deviation:** he ruled `"Mediator and Arbitrator"`; it ships as **"Mediator and Commercial Arbitrator"**, because the same message instructs that *"Q39's struck universal must not reappear in any form"* and an unscoped "Arbitrator" is that form. One word to revert, deliberately | — |
| ~~Q48~~ | **CLOSED 2026-08-28 — not site-relevant, and that is a scope answer rather than an answer to the underlying question.** Pouya: *"ADRIO retention governs whether Pouya keeps a designation, not what the site may say about holding it."* He holds Q.Med today (§4, `[verified 2026-08-28]`), so `hasCredential` and the designation line are correct today, and the retention mechanics are his to manage rather than the register's to publish. **The asymmetry in ADRIO's materials is still real and still recorded**`docs/reference/adrio-designations.md` Finding 4 — and nothing was inferred from it in either direction. **Consequence applied:** the `memberOf` comment in `src/data/schema.ts` no longer carries Q48 as an argument, because Q53 removed the withholding that argument was attached to | — |
| ~~Q49~~ | **ANSWERED 2026-08-28 — ONE ROW, and it is the value already shipping.** Pouya: *"one row: 'Mediator', supported by Q.Med plus completed sole mediations."* §4 Verified now carries **Practised role — "Mediator"** with both supports named, so `Person.jobTitle` stands on a row instead of on a derivation. **(a) closed:** the narrow value is ratified; the reverted `"Mediator and Arbitrator"` is not restored, and *"Arbitrator"* as a practised role remains unrowed. **(b) declined by the same ruling** — one row was granted and the corporate relation was not it, so **`worksFor` stays out of the graph**. ⚠️ **Read as a decline rather than as silence, and flagged as such to Pouya**: Q49 asked for two rows, the ruling granted one and named which. One line reverses it if the reading is wrong | — |
| ~~Q50~~ | **ANSWERED 2026-08-28 — the masthead string, and one claim now has one form.** Pouya: *"`ProfessionalService.name` takes the ratified masthead string. Q33 reaches it; one claim should not have two forms."* `name` was a hand-typed third variant — *"Pouya Lajevardi — Mediation & Arbitration"*, em dash and ampersand — beside the masthead (*"Mediation · Arbitration · Toronto"*) and `/`'s `<title>`. ⚠️ **IMPLEMENTED AS TWO FIELDS, WHICH DEVIATES FROM THE LITERAL RULING AND NEEDS ONE LINE FROM POUYA.** What ships is `name: "Pouya Lajevardi"` and `slogan: "Mediation · Arbitration · Toronto"` — both read from `SITE.name` and `SITE.tagline`, so the hand-typed variant is gone either way, which is what the ruling was for. **Why not the concatenation:** on a `LocalBusiness`-family type `name` means the business's name, and a name plus a service list plus a city is the name-stuffing pattern a search engine discards a rich result for — on the one project whose entire purpose is crawlability. `areaServed` already carries Toronto and Ontario. schema.org has a field for each half of a masthead, so this is a decomposition rather than a refusal. **The half that is mitigated rather than answered:** `slogan` still carries an unscoped *"Arbitration"*, which was the second objection to the concatenation. Against that — the identical string already ships in `<title>`, `og:title`, `twitter:title` and `/`'s hero eyebrow, all ratified under Q33, so excluding it from one name-like field alone would be incoherent. `serviceType` stays scoped because it **enumerates services**. **One line reinstates the concatenation** if that reading is wrong | — |
| ~~Q51~~ | **ANSWERED 2026-08-28 — KEEP THE OBA SECTIONS. The distinction is structural, not evidentiary.** Pouya: *"the Law Society is the regulator, so membership IS licensure; the OBA is a voluntary association. Structural distinction, independent of eligibility details."* That last clause is what closes it: the question was raised as unanswerable inside this repo **because OBA eligibility is not established here** — and the ruling makes eligibility irrelevant. A voluntary association admits members it does not license, so listing it carries no licensure implication; a regulator's membership roll *is* the licence. Recorded in §4's memberships row and in `.claude/agents/claims-auditor.md` so it is not re-litigated, and removed from `docs/06`'s cutover checklist. **R1 is unaffected** — same page, same subject, different question, still live | — |
| ~~Q52~~ | **CLOSED 2026-08-28 — committed, and RE-RUN rather than transcribed.** Pouya: *"YES — commit the simulate results, the inline policy, and the `NoSuchBucketPolicy` response, access key ID redacted."* `docs/reference/deploy-credential-verification.md` — eighteen read-only calls, each with the command that produced it, generated from captured output with the key ID replaced by `AKIA…REDACTED`. **Every value in §7's row reproduced**, including all nine `simulate-principal-policy` decisions (four `allowed`, five `implicitDeny`). **Two things the re-run added that the original verification did not have.** (1) A **contrast call**: `get-bucket-policy` on the *site* bucket returns exit 0 and a real policy, which is what makes exit **254** / `NoSuchBucketPolicy` on the backup bucket a genuine absence rather than a command that failed to start — the rule `CLAUDE.md` records twice, applied to the evidence that closes a High risk. (2) A correction to §7's own wording on the key's `LastUsed` field shape. The **secret** access key was never requested; the API cannot return it | — |
| ~~Q53~~ | **ANSWERED 2026-08-28 — EMIT IT. The withholding is dropped.** Pouya: *"the memberships are already crawlable in `/about/`'s HTML, so withholding the triple reduces no exposure and only makes the graph less complete than the page."* Option (a) of the three the question offered. `src/data/schema.ts` now emits `memberOf` — the four §4 memberships as `Organization` nodes — **on `/about/` only**, which is where the page shows them, so the graph and the visible page assert the same set. **This ends a judgement that was restated three times and wrong twice:** cacheability proved too much (equally true of `hasCredential`, which ships), volatility did not survive the page already carrying the claim, and the widened *"yearly renewing"* premise it rested on was itself a §4 misstatement found on re-audit | — |
| **Q38** | **A true vector master for the infinity mark.** The mark is a shaded ribbon — variable-width band, maroon flowing into champagne, twisting in three dimensions and passing over itself at the crossing. That is gradient-mesh artwork, and there is no honest way to express it as the flat vector paths `docs/02` assumes. An SVG **is** held — `src/assets/brand/sml-logo-source.svg` — and **it renders faithfully**: rasterised at 8333 px it reproduces the master exactly, at the same 1.566:1 `[verified 2026-08-26 — rendered and measured]`. *The characterisation has now moved twice and Pouya has settled it.* This row first called the file **"a raster in a vector wrapper"**; a later draft withdrew that as unfair. **The withdrawal went too far, and Pouya's ruling of 2026-08-27 restores the substance:** *"It renders faithfully because it IS the raster. Your first characterisation was accurate and the walk-back went too far."* Both things are true at once and the row must hold both — the file is a faithful rendering **and** it is faithful because seven base64 PNGs are carried inside it, which is why fidelity was never the question. **The Canva SVG does not close this question.** Pouya: *"Keep it committed, keep the AVIF render path. R13 stays open for a true vector master."* What rules it out is **payload and composition**: 257,278 bytes against **3,063 B** for the AVIF a Retina browser takes in the header — **84×** — plus **seven embedded base64 PNGs** and a 1,225-stop gradient mesh, so inlining it would breach `CLAUDE.md`'s rule against base64-inlining images. *Restated 2026-08-27, because the single number stopped covering the case:* build step 2 added a **232 px** call site (the home page's approach section, rendering at 225.5 px) beside the existing 64 px one, and at that size a DPR-2 device takes **14,555 B** and DPR-3 **22,639 B** — a ratio of ~11×, not 84×. `adversarial-reviewer` caught the three copies of the old figure going stale together, which is the SES-DKIM duplication in a new place. Both ladders are in `docs/reference/brand-assets.md`; **quote the size with the call site, never on its own.** Also worth knowing before someone reads it as a regression: the PNG fallback at 232 px runs **38,094 / 91,618 / 150,215 B**. Nothing that negotiates content types takes it — a DPR-3 device with neither AVIF nor WebP does not exist in practice — and the AVIF above is what real clients fetch. Accepted deliberately rather than capped, because capping it would blunt the mark on the high-DPI desktops that are the only place the 696 px variant is used at all. What is wanted is a master that is faithful **and** light. **Pouya is commissioning a proper vector master.** Until it lands, `InfinityMark.astro` renders an optimised raster and that is a **documented, temporary exception to `docs/02`'s inline-SVG rule** (R13 keeps it from becoming permanent). When the master arrives: replace the component's `<Picture>` with inline SVG, regenerate the favicons from it, and delete the exception from `docs/02` and this row. Raised by Claude Code 2026-08-26; scoped by Pouya the same day | Nothing — the mark renders correctly. This is fidelity and payload, not function |
| ~~Q32~~ | **ANSWERED 2026-08-26 — and the answer was that the reconstruction was WRONG.** Pouya rendered the committed path against the master (`SML Company Just Logo Transparent.png`, 3000×3000) and rejected it on three counts. Two reproduce from the path alone: **(a) TANGENT, NOT CROSSING** — all four cubic branches meet the origin at exactly 90°, so the loops are mutually tangent on a vertical line and at stroke-width 28 render as *two kissing circles*, the one thing an infinity mark must not be `[verified 2026-08-26 — tangent vectors computed per segment, independently reproduced]`. Both lobes are strictly confined to their own half-plane (x is monotone on every segment), so the signed crossing number is **0** — they cannot cross anywhere, not merely at the node. Worse at the size actually shipped: the two strokes stay fused into one mass wherever the centreline separation `y²/192` is under 28, i.e. across **61% of the mark's height** — at 2rem that is a 16.8px blob out of a 27.4px-tall mark. No stroke-width, viewBox or scale change can produce a crossing from this centreline; **(b) WRONG PROPORTION** — the master's ink bounding box is **2668 × 1704 = 1.5657:1** `[verified 2026-08-26 — measured]`, and **(c)** the master is a shaded ribbon where the trace was two flat uniform strokes. ***1.23:1 — RECONCILED, and it was a real measurement, not a slip.*** It is the bounding box of the path's **coordinates** rather than of the **curve**. The control points sit at y = ±160 while the curve only reaches ±120 — the standard 3/4 pull-in of a cubic — so a coordinate-hull box is 400 × 320 = 1.2500, and with stroke-width 28 applied on all four sides it is **428 × 348 = 1.2299**. Pouya's figure to four significant figures, from one method applied consistently `[verified 2026-08-26 — derived]`. **It is a trap rather than a slip:** because x is monotone on every segment, the control points give the *correct* width (±200) and a 33% inflated height, so the obvious sanity check — "does the width look right?" — passes. Any tool that reads a bbox from parsed coordinates lands here; `getBBox()` would have returned 400 × 240. **And the direction is inverted from how it read:** measured from the curve, the traced path is 6.4% *wider and flatter* than the master, not squatter. **Consequence worth keeping:** the declared viewBox 440:280 = 1.5714 is within **0.35%** of the master's 1.566, so re-tuning the layout to the true ratio was ~0.18px of work at the shipped 2rem — and **re-tuning to 1.23 would have actively broken it** — at any given width 1.2299 allocates 1.5657/1.2299 = **27% more height** than the mark occupies, so the header would have been rebuilt around a box a quarter too tall. The ratio was never sufficient grounds on its own; **(a) tangency is, and it is exact.** **The traced path is deleted, not kept as a fallback**, on Pouya's instruction: *a wrong mark that renders is worse than a missing one, because it stops looking wrong.* Now closed by Q38 for the vector master | — |
| ~~Q32-orig~~ | *(superseded — the original wording of this question is preserved in entry (v))* | `src/components/InfinityMark.astro` is built from geometry lifted verbatim from the deployed site's own loading-thumbnail SVG — the element it labels `smlMark`, fetched from `https://adr.smlcompany.ca/` on 2026-08-26. Path, both stroke widths (28 / 6) and the 0.7 inner opacity are the source's; the only change is folding a `translate(60 0)` into the coordinates. So it is SML's own artwork rather than a redrawing — but a loading placeholder is not necessarily the canonical file, and D7 says the mark carries over *unchanged*. If a master SVG or AI/EPS exists, supply it and the component gets replaced. Raised by Claude Code, 2026-08-26 | Nothing — the mark renders. This is about fidelity, not a blocker |
@@ -644,22 +716,50 @@ Nothing below can be invented. Each needs an answer from Pouya.
| Personal data in the intake pipeline without a retention policy | Medium — PIPEDA | `docs/05-backend-spec.md` sets retention, and `/legal/privacy/` states it |
| Cutover breaks the live site (D11 is a single-shot deploy) | Medium | Full pre-cutover checklist in `docs/06-deployment.md`; CloudFront can be rolled back to the prior origin path |
| Twenty pages of thin copy rank worse than six good ones | Medium | Each page must justify itself with substantive content. Ship fewer pages rather than padded ones |
| **`user/pouya` is a broadly-permissioned personal IAM user, and it is what has been authenticating to this account.** Q22 confirms the scoped deploy user does not exist yet | **High** | Fine at an interactive keyboard; **never** in CI, never in a Gitea secret, never in `scripts/deploy-local.sh`. That script refuses to run if `sts get-caller-identity` returns `user/pouya`. Create `adr-sml-deploy` before the first automated deploy `[verified 2026-08-26]` |
| **The deploy secret will live on jointly-administered infrastructure.** git.larsnolden.com has a second administrator. An instance admin can generally reach repository secrets, or register a runner that receives them — that is inherent to how Actions runners are fed credentials, not a flaw in this setup | **High** | This does not change the plan; it changes **what the scoped IAM policy is for.** The policy is no longer hygiene — it is the actual control standing between a shared Gitea instance and an AWS account holding another business's client-database backups. Four actions, one bucket, one distribution. **Never widen it**, and treat any request to as a security decision, not a convenience one `[verified 2026-08-26]` |
| **Deploy-credential blast radius.** AWS account `327082975128` is not a single-project account. It also holds `meshkinilaw.ca` and its preview site, `demesne.media`, `orynenergy.ca`, `lajirugs.ca`, and **`mlp-clientdb-prod-backups-327082975128`** (recorded in an earlier entry with the account suffix; the short form `mlp-clientdb-prod-backups` is used elsewhere in the docs) — which **by its name** holds production client-database backups. Only the name was ever observed; the contents were not inspected and the owner is not established | **High** | A static deploy key for a personal website must never be able to reach a client database. The scoped IAM policy in `docs/06-deployment.md` grants four actions on one bucket and one distribution and nothing else — that narrowness is now load-bearing, not hygiene. Never widen it. Never reuse the `user/pouya` credentials in CI `[verified 2026-08-26 — inventory]` |
| **`user/pouya` is a broadly-permissioned personal IAM user, and it is what has been authenticating to this account.** *Q22 closed 2026-08-28: the scoped deploy user now **exists**, so the mitigation below is available rather than pending — but this risk does not close, because `user/pouya` still exists, is still broadly permissioned, and is still what runs the local deploy path* | **High****Medium** for CI; unchanged interactively | Fine at an interactive keyboard; **never** in CI, never in a Gitea secret, never in `scripts/deploy-local.sh`. That script refuses to run if `sts get-caller-identity` returns `user/pouya`. **`adr-sml-deploy` now exists and is verified least-privilege (§7), so there is no longer any reason to reach for `user/pouya` in an automated context** `[verified 2026-08-28 — Q22]` |
| **The deploy secret will live on jointly-administered infrastructure.** git.larsnolden.com has a second administrator. An instance admin can generally reach repository secrets, or register a runner that receives them — that is inherent to how Actions runners are fed credentials, not a flaw in this setup | **High** | This does not change the plan; it changes **what the scoped IAM policy is for.** The policy is no longer hygiene — it is the actual control standing between a shared Gitea instance and an AWS account holding another business's client-database backups. Four actions, one bucket, one distribution. **Never widen it**, and treat any request to as a security decision, not a convenience one `[verified 2026-08-26]`. **THE CONTROL NOW EXISTS AND HAS BEEN TESTED AGAINST THE THING IT PROTECTS**`adr-sml-deploy` returns `implicitDeny` for `s3:ListBucket` and `s3:GetObject` on the client-backup bucket under `simulate-principal-policy`, and that bucket has no bucket policy (§7, Q22) `[verified 2026-08-28]`. The severity stays **High** because the exposure is unchanged: a static key on shared infrastructure, and the key is only as narrow as the next person to edit the policy leaves it |
| **Deploy-credential blast radius.** AWS account `327082975128` is not a single-project account. It also holds `meshkinilaw.ca` and its preview site, `demesne.media`, `orynenergy.ca`, `lajirugs.ca`, and **`mlp-clientdb-prod-backups-327082975128`** (recorded in an earlier entry with the account suffix; the short form `mlp-clientdb-prod-backups` is used elsewhere in the docs) — which **by its name** holds production client-database backups. Only the name was ever observed; the contents were not inspected and the owner is not established | **High** | A static deploy key for a personal website must never be able to reach a client database. The scoped IAM policy in `docs/06-deployment.md` grants four actions on one bucket and one distribution and nothing else — that narrowness is now load-bearing, not hygiene. Never widen it. Never reuse the `user/pouya` credentials in CI `[verified 2026-08-26 — inventory]`. **TESTED 2026-08-28 (Q22), and both halves were tested, which is the part that matters:** `simulate-principal-policy` returns `implicitDeny` for `s3:ListBucket` and `s3:GetObject` on `mlp-clientdb-prod-backups-*`, **and** `get-bucket-policy` on that bucket returns `NoSuchBucketPolicy` — so there is no resource-based grant, IAM is the only path, and this user has none. A policy read alone could not have established the second half `[verified 2026-08-28 — Pouya]` |
| ~~SES is in the sandbox~~ | ~~High~~**RESOLVED 2026-08-26** | Q19 closed: production access granted in `ca-central-1`, confirmed in writing. Residual, tracked in §7: the `ses-alerts` SNS email subscription is **pending confirmation**, so the bounce and complaint alarms currently notify nobody `[verified 2026-08-26]` |
| ~~No SPF and no DMARC on `smlcompany.ca`~~ | ~~High~~**RESOLVED 2026-08-26** | Both records added by Pouya and independently verified (Q20). SPF authenticates Google Workspace mail; SES satisfies DMARC through DKIM alignment on the three resolving CNAMEs. DMARC sits at `p=none` — the residual task is to review reports and tighten to `quarantine`, which is monitoring, not a risk `[verified 2026-08-26 — DNS query]` |
## 11. Glossary
> ✅ **THIS SECTION IS A PUBLISHABLE SOURCE — for DEFINITIONAL EXPANSIONS ONLY.**
> Ratified by Pouya 2026-08-28 (Q46(b)): *"§11 Glossary is the source for
> DEFINITIONAL expansions; §4 remains the only source for claims about Pouya. The
> line is the same one the Offerings ruling drew — 'Q.Med stands for Qualified
> Mediator' is a fact about the designation's name, not about him."*
>
> So a page may expand an abbreviation on this section's authority. It may **not**
> say he holds the thing, has commenced it, or is progressing toward it — those
> are §4 Verified rows, and §4 remains the only gate for them.
>
> **The five ADR designations are sourced, not asserted here.**
> `docs/reference/adrio-designations.md` carries all five in ADRIO's own words
> with reproducible digests (R14). Pouya attached that fetch to the ratification
> as a condition, and it caught the error below.
>
> ⚠️ **CORRECTION, 2026-08-28 — `C.Med-Arb` WAS WRONG IN THIS TABLE FROM THE
> FILE'S CREATION.** It read *"Chartered Mediator-Arbitrator"*. ADRIO's term is
> **"Chartered Med-Arbitrator"**. Pouya raised it himself: *"I took the expansion
> from the strategy brief and never sourced it… It is the practice's stated
> long-term designation, so getting its name wrong on a public page is not
> cosmetic."* It **had** reached a public page — `/about/`'s credential arc, and
> `dist/about/index.html` — and four adversarial review passes read that string
> without catching it, because each checked whether it was *sourced*, not whether
> it was *right*. Swept from four files; the sweep command is in Change Log (y).
| Term | Meaning |
|---|---|
| ADR | Alternative dispute resolution |
| ADRIC | ADR Institute of Canada — national credentialing body |
| ADRIO | ADR Institute of Ontario — provincial affiliate |
| Q.Med | Qualified Mediator — ADRIC/ADRIO designation |
| Q.Arb | Qualified Arbitrator — ADRIC/ADRIO designation |
| C.Med-Arb | Chartered Mediator-Arbitrator — senior hybrid designation; the long-term goal |
| Q.Med | **Qualified Mediator** — ADRIC / ADRIO designation |
| Q.Arb | **Qualified Arbitrator** — ADRIC / ADRIO designation |
| C.Med | **Chartered Mediator** — ADRIC / ADRIO designation |
| C.Arb | **Chartered Arbitrator** — ADRIC / ADRIO designation |
| C.Med-Arb | **Chartered Med-Arbitrator** — ADRIC / ADRIO designation. *Do not write "Mediator-Arbitrator", and do not call it "senior" or "the senior hybrid designation": this row said that until 2026-08-28, and it is a ranking claim about a third party's credential structure with no source. ADRIO applies "most senior" to **C.Med**, not to this one — and §4 Forbidden bars superlatives on the site regardless of who said them first. That it is Pouya's long-term goal is a §4 row; that it ranks above anything is not.* |
| CTF | Canadian Tax Foundation |
| Med-Arb | Hybrid process: mediation that converts to binding arbitration if unresolved |
| SABS | Statutory Accident Benefits Schedule — Ontario auto insurance benefits |
| LAT | Licence Appeal Tribunal — hears Ontario SABS disputes |
@@ -688,12 +788,14 @@ 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 |
| 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 |
| R10 | **RAISED 2026-08-28 AND NOT DISCHARGED — AND THE PROHIBITION HELD.** Pouya's instruction for this session was *"R10 first: re-confirm the memberships, which now includes CTF"*. The re-confirmation is a fact only he holds, so it is now **Q44**, and `/about/` ships **without a memberships group** — this row is written as a prohibition on shipping such a page, and documenting a prohibition is not discharging it. *An earlier version of this row said `/about/` had shipped with all four; that was true for part of one session and was reversed on review. Three other documents recorded the same reversed state and have been corrected.* Four yes/no answers and four **renewal months** close it; the months are the part that matters, because they turn this row from a reminder into a date. Original text follows. **Annually-renewing memberships.** §4 verifies the **OBA sections** (Construction & Infrastructure, ADR, Civil Litigation) and the **Canadian Tax Foundation** as of 2026-08-26 — *for now*. Both renew yearly. *Widened 2026-08-26 when CTF was added; it was OBA-only before* | 2026-08-26 | A credential that lapses quietly is the failure mode §4 exists to prevent, and OCNI already did exactly this (§4 records it as "not current, do not publish"). Re-confirm at each renewal, and before any page listing memberships ships — `/about/` at build step 3 is the first one that will |
| 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 |
| 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 |
| 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 |
| R14 | **Anything a spec makes a claim about must be reachable from the repository.** If the artefact lives only in Drive, in a console, or on someone's disk, no reviewer can check the claim and the claim is unverifiable by construction — see the rule now in `CLAUDE.md` | 2026-08-26 | **This has now cost twice.** Q24 was `AWS-Hosting-Guide.md`, the only record of how the infrastructure was hand-built, living outside the repo. Q32 was the infinity mark: Claude Code traced it from the old site's *loading placeholder*, wrote a scrupulous provenance comment recording exactly that doubt — and **two adversarial review passes still could not catch it**, because the artwork they would have had to compare against was not in the repo. The doubt was correctly stated and structurally uncheckable. That is the failure mode: not a missing warning, a missing artefact |
| 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 36** | 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 |
| 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 |
| ~~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 | — |
@@ -701,6 +803,542 @@ never being raised again.
# Change Log
## 2026-08-28 (z) — D19 bounds the review loop; nine rulings applied; and the loop immediately proved the point by finding a sweep that was claimed and never run
**The session's own shape is the argument for D19.** Two review rounds, four
agent passes, and the two highest-consequence findings were both *this session's
fixes* — a partial sweep, and a simplification that silently reversed a scoping
four other files documented. D19 caps the loop at two rounds because the third
round's cost is defects like those, not findings.
### D19 — Pouya's ruling, and where it went
His measurement: *"48 findings across two rounds, most of round two being
defects in round one's fixes. 342 lines added to `src/` for 8 functional. Four
reviewer findings were stale statements inside comments written that same
session. A Change Log sweep that could not reproduce because writing it changed
the file it counted. 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."*
§3 D19 carries it. Six sweeps, all verified by command:
```console
$ python3 - <<'EOF' # each destination checked for its required text
.claude/agents/claims-auditor.md '## Scope — D19' x1
.claude/agents/claims-auditor.md 'Severity filter — D19' x1
.claude/agents/adversarial-reviewer.md '## Scope — D19' x1
.claude/agents/adversarial-reviewer.md 'Severity filter — D19' x1
.claude/commands/build.md '### Scope — D19' x1
.claude/commands/build.md '### The stop signal' x1
.claude/commands/build.md 'Two rounds is the cap — D19' x1
.claude/commands/build.md 'do not open a numbered question…' x1
.claude/commands/wrap.md 'Do not open a numbered question…' x1
CLAUDE.md 'Comments record decisions…D19' x1
AGENTS.md '| D19 | Bounding the review loop |' x1
EOF
D19 swept to all six destinations
```
`/build` Phase 1 also went `D1D18``D1D19`; that was the only stale
D-range reference in the repo (`git grep 'D1D18'`, 1 hit, fixed).
### The nine rulings
| # | Ruling | What changed |
|---|---|---|
| **Q46(a)** | PUBLISHABLE. Step 5 unblocked | Three §4 Offerings rows flipped; gate 1 records **`[Pouya's stated basis 2026-08-28]`**, never `[verified]`. §4's worked-example prose and `docs/01` / `docs/07`'s 🚫 blocks rewritten. Two framing constraints survive and are marked non-discretionary: ENE is an assessment **to both parties**, and pre-dispute advisory carries a conflict caution |
| **Q48** | Closed, not site-relevant | Struck. Removed as an argument from `schema.ts`; the ADRIO asymmetry stays recorded in `docs/reference/adrio-designations.md` Finding 4 |
| **Q49** | One row: *"Mediator"* | §4 Verified gains **Practised role — "Mediator"**, naming both supports. Read as **declining Q49(b)** — one row was granted and the corporate relation was not it — so `worksFor` stays out. Flagged as a reading, not an assumption |
| **Q50** | `name` takes the masthead string | **Deviates: shipped as `name` + `slogan`.** See the Q50 row — the concatenation is the name-stuffing pattern and `areaServed` already carries the city. One line reinstates it |
| **Q51** | Keep the OBA sections | §4's memberships row and `claims-auditor` now carry the structural distinction; the cutover-checklist item became a check rather than a question |
| **Q52** | Commit the evidence | `docs/reference/deploy-credential-verification.md`**re-run, not transcribed** |
| **Q53** | Emit `memberOf` | `/about/`'s Person node, four `Organization` nodes from `MEMBERSHIP_ORGS` |
| **Q23 / Q34 / Q38** | Unchanged | — |
### Q52 — re-run rather than transcribed, and the re-run added two things
Eighteen read-only AWS calls from the repository root, each with its command,
access key ID redacted. Every value in §7 reproduced; the nine
`simulate-principal-policy` decisions came back four `allowed` / five
`implicitDeny` unchanged, and `adversarial-reviewer` independently reproduced
them again including `MatchedStatements` positions.
1. **A contrast call.** `get-bucket-policy` on the *site* bucket exits 0 with a
real CloudFront OAC policy — which is what makes exit **254** /
`NoSuchBucketPolicy` on the backup bucket a genuine absence rather than a
command that failed to start. That call was not part of the original
verification, and without it the evidence was weaker than it read.
2. **A correction to §7's own wording.** The API returns no null `LastUsed`; it
returns `AccessKeyLastUsed` with `ServiceName`/`Region` = `"N/A"` and **no
`LastUsedDate` key**. Same conclusion, different field shape. Swept into §7,
§9 Q22 and §12 R17, which also went **eight → nine** checks.
### The headline finding: a sweep asserted and never run
Both agents found it independently. Q53 was applied to `schema.ts`, `docs/06`,
`docs/04`'s first half and §9 — and **six other in-scope records still said
`memberOf` was withheld**, including §4's memberships row and §12 **R10**, which
`CLAUDE.md` requires be read aloud to Pouya every session. `docs/04`'s Person
cell said *both*, in one table cell, directly below its own note about having
been caught doing exactly that with `worksFor`.
This is R8 — *a sweep is a command, not a claim* — and the claim was recall. The
sweep now exists and reads every match rather than counting them:
```console
$ # every in-scope memberOf statement, READ not counted
0 live stale claims
$ git grep -cn 'NOT YET PUBLISHABLE' -- ':!AGENTS.md' ; echo "exit=$?"
exit=1
```
### Two round-1 fixes that were themselves defects
**1. Simplifying `memberOf` reversed the scoping.** Round 1 argued the per-page
opt-in bought nothing (same `@id`, so a consumer merges) and it was removed.
Round 2 found the consequence: `memberOf` shipped on `/`, where no membership is
visible, and **six records said it did not**. The parameter is restored. The
deciding reason is not the mechanism but Pouya's: his Q53 ruling turns on *"the
memberships are already crawlable in `/about/`'s HTML"* — a page-specific
reason, so a page-specific field. `schema.ts` now carries a "do not delete this
as redundant" note, because the deletion argument is genuinely persuasive and
genuinely wrong.
**2. `MEMBERSHIP_ORGS` was inserted between `BOUTIQUE`'s JSDoc and `BOUTIQUE`.**
Verified by `adversarial-reviewer` against the TypeScript compiler API: the D16
warning — *"The Toronto boutique is NEVER named"* — became leading trivia for no
declaration, surfaced on hover for nothing. One of the two decisions that file
exists to protect, made invisible to tooling by a comment block landing four
lines too early. Moved below `BOUTIQUE`.
### Other findings resolved
- `/`'s `<title>` still hand-typed *"Mediation & Arbitration · Toronto"* while
Q50 claimed the variant was eliminated. Now `SITE.name` + `SITE.tagline`;
`docs/04`'s literal deleted and §9 Q33's *"stands as written"* amended.
- `about.astro` claimed the graph and the visible list *"cannot drift apart"*.
They can: different arrays, **length parity only**, content parity manual.
- The parity assertion was described as a build error. **Measured: it fails
`npm run check`, not `npm run build`** — the deploy path runs `check` first, so
it is covered, and the caveat is now written down. It was also probed rather
than assumed: adding a fifth entry produces `ts(2344)`.
- `MEMBERSHIP_ORGS` was said to differ from the display list on **one** line. It
differs on **three of four**.
- The `name`/`slogan` mapping was justified by the masthead rendering two
elements. **On `/` the masthead suppresses the tagline** (`!isHome`), and `/`
is the only page this node ships on. The true counterpart is the hero eyebrow.
- §12 R10 still cited Q48, closed in this same change set — a live reminder
pointing at a struck row, surfaced every session.
- §7's deploy row asserted three facts and retracted all three in the same cell.
Rewritten to state current facts once; the retractions live here.
- `docs/01` carried a second copy of a §4 currency stamp, already diverged
(2026-08-26 vs 2026-08-28). Replaced with a pointer.
### Declined
- **`memberOf`'s bare `Ontario Bar Association`.** `claims-auditor` notes the
section qualifiers are what visibly mark the OBA as voluntary. Declined: a
name that reconciles against no real entity gives up what the field buys, and
the short form is a **narrowing** of §4's row rather than an inference beyond
it. Q51's ruling — regulator versus voluntary association — is the substantive
answer and it is now recorded beside the array.
- **`slogan`'s unscoped "Arbitration".** Mitigated, not discharged, and said so
in the source. The identical string already ships in `<title>`, `og:title`,
`twitter:title` and `/`'s hero eyebrow, all ratified under Q33.
### D19 applied to this change set's own comments
Measured on the diff, not recalled: **`src/` net 6 lines, comments 56,
code +45.** Three narration blocks moved here from source — the withdrawal of
three superseded `memberOf` grounds, the `jobTitle` string's audit history, and
the account of the `name` variant that was replaced. The live constraints stayed:
do not widen `jobTitle`, do not put the tagline back in `name`, do not delete the
`memberOf` opt-in, the two membership arrays differ.
### Found and NOT fixed here — the Change Log was duplicated by entry (y)
`adversarial-reviewer` spotted it. Verified: 51 entry headings, **26 unique**;
everything from entry (x) back to 2026-08-25 appears twice. `git show` on each
commit locates it precisely — `c576b9a` has one copy, **`77a7b41` has two**, so
last session's own commit introduced it, almost certainly a patch script that
appended where it should have replaced. Block B is a strict prefix of block A
(3,252 identical lines, then B stops), so **nothing is lost by removing it**.
Removed in its own commit rather than buried in this one.
### Verified — run, not asserted
`npm run check` 0 errors / 0 warnings / 0 hints, 22 files · `eslint` clean ·
`prettier --check` clean · build 2 pages · **0 `.js` emitted** · non-JSON-LD
`<script>` tags **0** · minifier guard **0** hits, `animation-timeline` **5**
surviving in `dist` · `dist/about/` Person carries `memberOf` ×4, `dist/index.html`
Person does not · `jobTitle: "Mediator"`, no `worksFor` at any depth ·
`ProfessionalService` `name: "Pouya Lajevardi"`, `slogan: "Mediation · Arbitration ·
Toronto"` · credential scan over the full diff: 0 hits on seven patterns.
**NOT run:** Lighthouse — tool unavailable until step 7 (R11). HTML validator.
`.env.example` could not be re-read this session — the harness denies reads under
that path — so it is reported as *unchanged by this change set* (`git diff` and
`git status` both empty for it) rather than as re-verified safe.
### Open after this entry
**Q23**, **Q34**, **Q38** — and nothing else numbered. The Q-series went from
eleven live to three, which is D19 working. Live reminders: **R1** (surfaced
again), R2R6, R9, **R10** (event-triggered), **R11**, R12R16, **R17**
(2026-11-26).
---
## 2026-08-28 (y) — Six rulings applied; Q22 closed on execution; and the ruled value of Q47 was struck by both review agents the same day it was set
**Pouya's rulings this session:** Q44 (memberships current — ship the group),
Q45 (PDF bio deferred to step 9), Q46(a) (the three offerings pass all gates),
Q46(b) (§11 ratified as the source for definitional expansions — *fetch and
commit the source*), Q47 (set both `jobTitle` and `worksFor`), the
legal-advice formulation **ratified without change**, plus **Q22 closed on his
own execution evidence** and a new `CLAUDE.md` convention.
### The headline: a ruled value that reversed a standing audit correction
Q47 ruled `jobTitle: "Mediator and Arbitrator"`. It shipped for one pass as
**"Mediator and Commercial Arbitrator"** — and **both review agents struck it
independently**, which is this loop's strongest signal.
The reason is not the one Claude Code flagged. The implementation carried a
prominent note arguing about **scoping** ("Commercial", on the ground that Q39's
struck universal must not reappear) — and *"Mediator and commercial arbitrator in
Toronto"* is **the exact string `claims-auditor` struck from this same node's
`description` on 2026-08-27**, on entirely different grounds: §4 verifies *"Has
completed multiple sole mediations"* and has **no counterpart row for a completed
arbitration**, only that appointments are *accepted*. The reasoning was still
sitting in `schema.ts` thirty lines above the property that now said it.
**A flag aimed at the wrong defect reads as diligence and provides none.** That
is the lesson worth keeping: the note was scrupulous, specific, and pointed at a
real-but-secondary issue, and its presence made the diff look reviewed.
`worksFor` was set and reverted the same way, on a defect the careful "name
only, nothing else" scoping did not touch: **`ProfessionalService.provider` is
this Person**, so `provider → Person → worksFor → SML Company Ltd` asserts
transitively the same-entity claim that `about.astro` **deleted from visible prose** as *"a corporate-structure claim"*.
*Corrected on re-review: this paragraph first cited a guard in `aboutGraph`'s
comment as declining the same-entity claim. That comment covers `ProfilePage`,
`BreadcrumbList` and `memberOf` and says nothing about SML — **the citation was
empty**, in the argument for a revert. The transitive inference stands on its
own; the evidence offered for it did not. `adversarial-reviewer` read the
referent rather than the claim, which is the whole rule.*
Both now ship in the narrowest rowed form — `jobTitle: 'Mediator'`, no
`worksFor` — and **Q49** asks Pouya for the two §4 rows the ruling needs. Q47's
stated purpose still holds: `jobTitle` describes *this practice*, not the
boutique role.
### Q46(b): ratified, sourced, and the fetch immediately earned itself
`docs/reference/adrio-designations.md` — all five expansions in ADRIO's own
words, four independent fetches, reproducible sha256. R14 satisfied; §11 no
longer asserts its own content.
**It caught the error Pouya raised in the same message.** §11 had said *"Chartered
Mediator-Arbitrator"* since the file was created. ADRIO's term is **"Chartered
Med-Arbitrator"**, and the wrong form had reached a public page —
`dist/about/index.html` carried it. **Four adversarial review passes read that
string** and none caught it, because each checked whether it was *sourced*, not
whether it was *right*.
Three instrument notes, all recorded in the reference file:
- The URL Pouya gave **301-redirects**; the first fetch without `-L` wrote a
**0-byte file**, which reads as "the page is empty".
- Digests **are** stamped here where `lat-case-conference.md` could not stamp
them, and the difference was checked rather than assumed: no `__uzdbm` nonce,
and the 17 `?ver=` strings are **static plugin versions**, not rotating
cache-busters.
- The parent page extracts at **3.5%**, the `adric.ca` shell signature — but it
is not a shell; it is genuinely a stub. **Read the ratio against the page, not
against a threshold.**
### The review found a defect in this session's own artefact
`claims-auditor` noticed that the reference file argued a **Qualified-vs-Chartered**
retention asymmetry from a two-page sample, while having fetched a third Chartered
page and never run the count on it — **C.Med-Arb, the designation §4 records as
the practice's goal**, and the one most load-bearing for Q48. Run:
```
qualified-mediator-q-med / q-arb good standing 0 annual 0 maintain 0 retain 0
chartered-mediator-c-med 1 1 1 1
chartered-arbitrator-c-arb 1 1 1 1
chartered-med-arbitrator-c-med-arb 0 0 0 0
```
**The framing was wrong.** The split is by **page type** — long application FAQs
versus short descriptions that link out — not by designation level. And it cuts
the *opposite* way from how it was written: a stub page's silence is evidence
about the page, so Q.Med's silence is most likely "this page does not cover
retention", not "no condition exists". Finding 4 rewritten; **Q48 stands, better
explained.**
### Q22 — closed on execution, by Pouya, and the verification is the point
IAM user `adr-sml-deploy` exists (created 2026-08-26T15:45:18Z), one inline
least-privilege policy, one unused access key. §7 goes from **NOT PROVISIONED**
to provisioned; §9 Q22 closes; three §10 risk rows updated.
**Verified by execution rather than by reading** — eight
`simulate-principal-policy` calls, `allowed` on the four intended actions and
`implicitDeny` on the client-backup bucket, on `s3:DeleteBucket`, on another
site's bucket, and on `iam:CreateUser`. **And the one gap a policy read cannot
close was closed too:** `get-bucket-policy` on the backup bucket returns
`NoSuchBucketPolicy`, so no resource-based grant exists and IAM is the only path
in. §10's control now exists *and has been tested against the thing it protects*.
**Rotation has a date, not an intention** — key created 2026-08-26, first
rotation **2026-11-26**, in §12 **R17** on Pouya's explicit instruction.
Flagged back to him, unresolved: `implicitDeny` is the weakest form of "no" —
absence-of-Allow, not explicit Deny — so the protection is "nothing grants it"
rather than "something forbids it".
### New `CLAUDE.md` convention — never suppress stderr in a verification script
Pouya's, from that verification: `2>/dev/null` hid an `InvalidInput` error, all
eight checks returned empty, and **a cause was then guessed** (*"probably lacks
the permission"*) — which is the answer the check existed to produce, reached
without the check running. Actual cause: a **zsh parameter-expansion bug**,
`$ACCT:user/` parsing `:u` as a history modifier and yielding
`327082975128ser/`.
His framing: this is *a command that did not run is not evidence of absence* from
the other direction, and the more dangerous one — **suppression converts "it
failed" into "it found nothing", and those are opposite results.**
**Corroborated twice the same day, both in zsh, both while verifying this change
set:** `grep -rn $EX '…'` printed an option error and **no matches** (reads as
clean) because zsh does not word-split unquoted variables; and a digest
comparison using `set -- $pair` printed **`DIFFER` on all five rows** (reads as
"the source changed under me") because the loop body got one argument and the
comparison never ran.
### Q44 — shipped with a prohibition attached, and R10 re-armed rather than closed
All four memberships re-confirmed; the group renders on `/about/`. **No currency
warranty** — his words, *"list the memberships; promise nothing about their future
state"*. He **declined renewal-date tracking**, so **R10 fires on an event now,
not a date**: re-confirm before any cutover or major republish.
Two things flagged back rather than assumed: the **stamp reads 2026-08-28**, not
the 2026-08-26 his ruling wrote, because a currency stamp records when the
assertion was made; and **`memberOf` stays out of the JSON-LD**. The ground for
that was restated on `adversarial-reviewer`'s finding that the first version
**proved too much** — "a scraped claim is cached" applies equally to
`hasCredential`, which ships. The real distinction is **volatility**, and the
sharper consequence is recorded: *if Q48 resolves against Q.Med, `hasCredential`
carries the higher exposure of the two.*
### Review findings resolved — 23 across two agents
`claims-auditor`: **FAIL, 12** (5 published, 7 internal). `adversarial-reviewer`:
**2 blocking, 9 should-fix, 5 consider.** Fixed: the two Q47 fields; the
untracked reference file that **four places already cited** (`git commit -a` does
not pick up untracked files — R14 would have been unsatisfied in the Q24/Q32
shape); `"workshop series"` → §4's **"sequence"**; `"alongside both"`
**"alongside the practice"**; two §4-Forbidden breaches in specs where *"the Q.Arb
**designation** commenced"* reads as **held**, one of them model copy an
implementer is told to lift; a third unapproved D13 phrasing in the positioning
statement earmarked for the PDF bio; `docs/04`'s still-unscoped `serviceType`
and its restatement of a literal string with a live revert trigger on it; a §4
misquotation *inside the comment written to stop widened paraphrase of that exact
sentence*; a duplicated block in one comment whose two copies **already
disagreed** on the highest-stakes item.
Two structural fixes worth naming:
- **The offering test enumerated two questions while the rows cited three
gates.** The partisan question — this register's highest-value catch, the one
that struck settlement counsel — existed only as unnumbered prose in the worked
example, so an implementer reading *The offering test* would not have found it.
It is now **gate 0**, numbered to record that it runs first and disposes of a
candidate on its own.
- **§9 struck Q46 while half of it was live and blocking.** Split into
`~~Q46(b)~~` and a live **Q46(a)**; the worked-example table's citations
updated.
And one of this session's own additions failed its own test: the new
`[unestablished]` **checklist item would have failed the very sentence the
section exists to bless** — it greps for "do not", and the ratified copy is *"I
**do not** act for a party in a matter I take"*. Scoped to *giving legal advice,
practising law, or holding a licence*, with attempt 3 added as the worked pass.
### Sweeps — commands and output, per R8
> ⚠️ **THIS BLOCK'S FIRST VERSION COULD NEVER REPRODUCE, AND THE REASON IS
> STRUCTURAL: pasting a search pattern into `AGENTS.md` adds occurrences of that
> pattern to the file the sweep counts.** `Chartered Mediator-Arbitrator` went
> from 8 matches to 10 the moment this entry was written; `workshop series` and
> `designation commenced` went from 0 to 12. A later reader re-running them
> cannot distinguish that from drift — which defeats the entire point of R8, in
> the entry that invokes it. Found by both review agents independently.
>
> **Every sweep below therefore excludes `AGENTS.md`** via
> `':!AGENTS.md'`, so the commands reproduce as written. The excluded file's own
> occurrences are prohibitions and historical quotes; they were read.
```
$ git grep -c 'Chartered Mediator-Arbitrator' -- . ':!AGENTS.md'
docs/03-content-spec.md:1
docs/reference/adrio-designations.md:4
src/pages/about.astro:2
$ grep -ro 'Chartered Mediator-Arbitrator' dist/ | wc -l
0
-> all 7 read: every one a prohibition ("never write…") or a historical quote
inside a correction note. Zero live uses. dist clean.
$ git grep -c 'workshop series' -- . ':!AGENTS.md' -> 0
$ git grep -c 'designation commenced' -- . ':!AGENTS.md' -> 0
$ git grep -in 'in progress' -- . ':!AGENTS.md' | grep -ci arb -> 0
$ git grep -c 'alongside both' -- . ':!AGENTS.md'
docs/03-content-spec.md:1
src/pages/about.astro:1
-> both read: corrective comments naming the removed wording.
$ git grep -n -A1 'as in**Line-wrapping defeated an anchor or a sweep THREE times this session** — S5's
`as in\n * progress`, the `SiteFooter` masthead sentence, and `docs/03`'s
blockquote-wrapped phrase recorded in an earlier entry. Sweep the wrapped form.
### Verified
`astro check` **0 / 0 / 0**; `eslint` clean; `prettier --check` clean (noting
`.prettierignore` excludes `*.md` and `docs/reference/`, so it says nothing about
the new doc); `npm run build` 2 pages; **0 `.js` emitted**; the only `<script>`
on either page is `application/ld+json`; minifier guard silent and
`animation-timeline` intact in `dist` (longhands only; the sole `animation:`
shorthand is `animation:none!important` in the reduced-motion block); **no gold
text on cream** anywhere; one `<h1>` on `/about/` with h1→h2→h3 and no skips
across 17 headings; JSON-LD parses on both pages with `jobTitle: "Mediator"`, no
`worksFor`, no `memberOf`, `hasCredential` Q.Med-only, no `LegalService`; **no
currency-warranty phrasing in the built HTML** (`renewed annually`,
`listed as current`, `current as of`, `are current` — all 0).
Layout re-measured by `adversarial-reviewer` after it discarded its own first
instrument: **headless Chrome clamps `--window-size` to ~500px minimum on
macOS**, so its "320px" was really 500px. Via CDP `setDeviceMetricsOverride`:
320×800 DPR2, 1024 and 1280 → **0 document overflow**; at 320px with root
font-size 32px → 63px, **all of it the pre-existing header brand name**, with
every credential `<li>` right edge at 272 against a 320 viewport. The new
Memberships group contributes no overflow.
### NOT run, stated rather than omitted
- **Lighthouse — tool unavailable.** `@lhci/cli` removed 2026-08-26; returns at
step 7 under R11. Nothing here adds bytes to a route: no new images, no runtime
font request, no third-party script, no base64 inlining, JS still zero.
- **HTML validator — not run.** The duplicate-`1x` srcset conformance error from
step 2 stands.
- **Q46(a)'s gate 1 — no source fetched.** Deliberate: it is legal research, it
was not asked for, and §4 bars this register from concluding it. The candidate
source is named in the ENE row.
### The re-review found 25 more, and most were in the fixes
**Two full review rounds ran. The second found 14 (`claims-auditor`) and 16
(`adversarial-reviewer`) — and the majority were defects introduced by the first
round's fixes.** That is the pattern this project keeps paying for, and this
entry is the sharpest instance yet. Named, because the shape is the lesson:
- **The `memberOf` rationale, rewritten to be more rigorous, re-widened §4.** It
said a membership list is *"a set of **yearly renewing** facts"* — the widened
form, **fourth occurrence**, twenty lines above the same comment's own warning
that *"all four renew yearly… is still wrong and still must not be written"*.
And it was the stated ground for withholding `memberOf`, so the withholding
rested on a widened premise.
- **The argument for reverting `worksFor` cited a guard that does not exist.** It
said `aboutGraph`'s comment "explicitly declines" the same-entity claim; that
comment covers `ProfilePage`, `BreadcrumbList` and `memberOf` and never
mentions SML. **The citation was empty, in four places.** The real referent was
`about.astro`'s deleted *"corporate-structure claim"* sentence. This repo's own
rule — a claim whose referent cannot be reached is unverifiable by construction
— applied to the argument for a revert.
- **§9's `~~Q47~~` was struck as answered while describing the pre-revert
state.** Both its assertions were false against `dist` within hours. Verbatim
the failure Q44's history records — *"four documents recording a page state
that had been reversed and not swept"* — reproduced inside the change set that
records it.
- **The gate renumbering left two live "Gates 2 and 3" references, both written
in this same change set**, four paragraphs from the note explaining the
renumbering.
- **The new `[unestablished]` checklist item would have failed the sentence the
section exists to bless** — it greps for "do not", and the ratified copy is *"I
**do not** act for a party in a matter I take"*.
- **`SiteFooter.astro`: a five-line insertion landed in the middle of a
sentence**, leaving *"…third wrapping miss in one session; §4 permits the
arbitration half…"*. Unspliced, and the session diary removed with it.
**Three findings were one lift away from a public page, and none was in the
change set's own diff:**
- `docs/03`'s `/for-parties/` directive said the mediator *"is not your lawyer
and cannot give you legal advice"* — **both halves breach D13**: "not your
lawyer" presupposes lawyer status, and "cannot" is attempt 2 from that file's
own ratified table. It sat fifty lines below the warning added this session
that `/for-parties/` is *"the exact place the 'cannot' phrasing feels most
natural and is most wrong"*. **And `about.astro` cited it as the sanctioned
example**, quoting the half that suited and not the half that was struck.
- `docs/01` told an implementer the "also offered" strip **may ship** because
each offering "now has a §4 Offerings row" — all three rows read **NOT YET
PUBLISHABLE**. `docs/07` priced them at $500/hour with no gate note at all.
- Model copy in `docs/03` and `docs/07` offered arbitration **unscoped** — the
struck universal, one file over from the same defect fixed earlier the same day.
**And the sweep record itself could not reproduce** — see the block above. Plus
the count misread: `git grep -c` prints one line per *file*, and "3 hits" was 3
files.
### Structural criticism accepted, and acted on in part
`adversarial-reviewer` counted the diff: **342 lines added to `src/`, eight of
them functional** — a ratio near 42:1 — and named the concrete failure rather
than the aesthetics: **four of its own findings were stale or fabricated
statements living inside exactly those comments**, each duplicating something
`AGENTS.md` already records. Its rule: **keep the *rule* in the source, move the
*history* to the Change Log, and cite it.**
Acted on for `SiteFooter.astro` (five lines of session diary deleted) and for the
worst of `about.astro`. **Not yet done systematically**, and recorded here rather
than quietly dropped: the remaining comment mass in `about.astro`, `site.ts` and
`schema.ts` is a real maintenance liability on the same evidence, and step 4 is
the moment to trim it rather than extend the pattern across three new pages.
### Evidence committed that was previously unreachable
`docs/reference/adrio-extract/` — the extraction script and the five extracted
text files every term count in `adrio-designations.md` was run against. The
digests covered the **raw HTML** and said nothing about the extraction, so the
counts were unverifiable by construction even while the digests were not. The
committed extracts reproduce all four rows of Finding 4 exactly.
**The equivalent gap for Q22 is NOT closed and is now Q52:** §7 downgraded a
**High** §10 risk and declared the scoped policy "tested against the thing it
protects" on nine `simulate-principal-policy` results that exist nowhere in the
repository. `adversarial-reviewer` drew the contrast itself — it reproduced every
ADRIO digest independently and could reproduce nothing here. Only Pouya can close
it; he ran the commands.
### Open after this entry
**Q46(a)** (gate 1 unsourced — blocks step 5) · **Q48** (Q.Med retention vs
membership currency) · **Q49** (the two §4 rows Q47 needs) · **Q50**
(`ProfessionalService.name` scoping) · **Q51** (OBA and the D13 implication —
**now on the cutover checklist**) · **Q52** (commit the IAM verification output —
R14) · **Q53** (should `memberOf` be emitted after all?) · **Q23**, **Q34**,
**Q38**. Live reminders: **R1** (licensure — surfaced again,
and `/about/` is now the page that makes it live), **R10** (event-triggered),
**R11**, **R13**, **R14**, **R15**, **R16** (PDF bio, step 9), **R17** (key
rotation, 2026-11-26).
## 2026-08-28 (x) — Build step 3: `/about/` ships without its memberships. Q40Q43 close; four review passes found nine defects in their own predecessors' fixes
**Task, in Pouya's words:** rulings on **Q42**, **Q41(a)(b)(c)**, **Q43** and
@@ -3953,3 +4591,82 @@ page at launch (§6), on the reasoning recorded there. Flag this to him.
drafts; intake backend rework; CI/CD wiring; pre-cutover audit. Twelve blocking
questions are open in §9 — several pages cannot be written until they are
answered.
-- src docs | grep -B1 progress
src/pages/about.astro: * ...which ended "...stated openly as in
src/pages/about.astro- * progress" — so THIS FILE cited docs/03 as REQUIRING...
-> the one hit is the corrective note itself. THE WRAPPED FORM IS WHY THIS
SWEEP MISSED FIRST TIME: 'as in\n * progress' does not match a one-line
grep, and about.astro cited docs/03 as both requiring and barring the
phrase, six lines apart.
$ git grep -n 'worksFor' -- src | grep -cv '\*\|//'
0
-> ZERO live properties. 13 lines mention it, all comments.
THE FIRST VERSION OF THIS BLOCK REPORTED "3 hits" — which was the number of
FILES 'git grep -c' printed, read as a number of matches. The instrument
shape CLAUDE.md catalogues, in the entry documenting instrument misreads.
$ git grep -n 'NoSuchEntity|does not exist yet|has not been created|nobody owns that' -- README.md docs/
-> 2 hits, both inside the corrective notes added this session.
THIS SWEEP DID NOT EXIST IN THE FIRST VERSION OF THIS BLOCK, and that was
the gap: Q22's flip to PROVISIONED was swept in AGENTS.md and NOWHERE ELSE.
docs/06 still told an operator "adr-sml-deploy does not exist… Create it",
and README asserted the same in three places. An operator would have
created a SECOND IAM user, or hand-provisioned one outside the
least-privilege policy. Same shape as the SES-DKIM inversion; found by
adversarial-reviewer.
$ git show :docs/reference/adrio-designations.md | grep '^## Finding 4'
-> matches the working tree. THE STAGED COPY HAD THE FALSIFIED FINDING 4:
the file was 'git add'ed BEFORE the rewrite, so a staged-only commit would
have landed the version this entry claims to have fixed. The mirror of the
untracked-file hazard recorded above — once tracked, 'commit -a' works and
bare 'commit' does not. Verify with 'git diff --cached' before committing.
```
**Line-wrapping defeated an anchor or a sweep THREE times this session** — S5's
`as in\n * progress`, the `SiteFooter` masthead sentence, and `docs/03`'s
blockquote-wrapped phrase recorded in an earlier entry. Sweep the wrapped form.
### Verified
`astro check` **0 / 0 / 0**; `eslint` clean; `prettier --check` clean (noting
`.prettierignore` excludes `*.md` and `docs/reference/`, so it says nothing about
the new doc); `npm run build` 2 pages; **0 `.js` emitted**; the only `<script>`
on either page is `application/ld+json`; minifier guard silent and
`animation-timeline` intact in `dist` (longhands only; the sole `animation:`
shorthand is `animation:none!important` in the reduced-motion block); **no gold
text on cream** anywhere; one `<h1>` on `/about/` with h1→h2→h3 and no skips
across 17 headings; JSON-LD parses on both pages with `jobTitle: "Mediator"`, no
`worksFor`, no `memberOf`, `hasCredential` Q.Med-only, no `LegalService`; **no
currency-warranty phrasing in the built HTML** (`renewed annually`,
`listed as current`, `current as of`, `are current` — all 0).
Layout re-measured by `adversarial-reviewer` after it discarded its own first
instrument: **headless Chrome clamps `--window-size` to ~500px minimum on
macOS**, so its "320px" was really 500px. Via CDP `setDeviceMetricsOverride`:
320×800 DPR2, 1024 and 1280 → **0 document overflow**; at 320px with root
font-size 32px → 63px, **all of it the pre-existing header brand name**, with
every credential `<li>` right edge at 272 against a 320 viewport. The new
Memberships group contributes no overflow.
### NOT run, stated rather than omitted
- **Lighthouse — tool unavailable.** `@lhci/cli` removed 2026-08-26; returns at
step 7 under R11. Nothing here adds bytes to a route: no new images, no runtime
font request, no third-party script, no base64 inlining, JS still zero.
- **HTML validator — not run.** The duplicate-`1x` srcset conformance error from
step 2 stands.
- **Q46(a)'s gate 1 — no source fetched.** Deliberate: it is legal research, it
was not asked for, and §4 bars this register from concluding it. The candidate
source is named in the ENE row.
### Open after this entry
**Q46(a)** (gate 1 unsourced — blocks step 5) · **Q48** (Q.Med retention vs
membership currency) · **Q49** (the two §4 rows Q47 needs) · **Q50**
(`ProfessionalService.name` scoping) · **Q51** (OBA and the D13 implication) ·
**Q23**, **Q34**, **Q38**. Live reminders: **R1** (licensure — surfaced again,
and `/about/` is now the page that makes it live), **R10** (event-triggered),
**R11**, **R13**, **R14**, **R15**, **R16** (PDF bio, step 9), **R17** (key
rotation, 2026-11-26).
+42
View File
@@ -176,6 +176,32 @@ from a command that found nothing. Same family as *a sweep is a command, not a
claim*: the claim must rest on output you actually read, from a command that
actually ran.
**And never suppress stderr in a verification script.** *Pouya's convention,
2026-08-28, from verifying the deploy credential (`AGENTS.md` Q22).* This is the
rule above from the other direction, and it is the more dangerous direction:
**`2>/dev/null` converts "it failed" into "it found nothing", and those are
opposite results.** His first pass at eight `simulate-principal-policy` checks
returned empty for all eight; the suppression was hiding an `InvalidInput` error,
and the empty output was then explained with a guess — *"probably lacks the
permission"* — which is the answer the check was supposed to produce, arrived at
without the check running. The actual cause was a **zsh parameter-expansion bug**:
`$ACCT:user/` parses `:u` as a history modifier and yields `327082975128ser/`.
Braces fixed it.
So: no `2>/dev/null` in anything whose output you intend to believe, read the
exit status, and when a result is empty **remove the suppression and look before
proposing a cause.** A guessed explanation for an empty result is worse than no
result, because it closes the question.
*Corroborated the same day, twice, in the same session and both in zsh:*
`grep -rn $EX 'Mediator-Arbitrator'` printed an option error and no matches —
which reads as clean — because zsh does not word-split unquoted variables; and a
digest-comparison loop using `set -- $pair` printed **`DIFFER` on all five rows**,
which reads as "the source changed under me", because the loop body received one
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
bad".
**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
parent's rule to `.header-cta[data-astro-cid-<parent>]` while the rendered `<a>`
@@ -287,6 +313,22 @@ 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
catch exactly that. Recall is not evidence.
**Comments record decisions, not history — D19.** *"X because D13"* stays.
*"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
longer than the code it explains must justify itself. Trim on sight.**
Pouya's ruling, 2026-08-28, on his own measurement: **342 lines added to `src/`
in one session for 8 functional lines**, and four of that session's review
findings were stale statements living inside those comments. A comment that
narrates its own revision history becomes a second record to keep true, and then
a source of defects about the record rather than about the site.
This does **not** license deleting a comment that carries a live constraint. The
parent-scope trap, the `animation-timeline` minifier defect and the `as`-prop
hazard above are load-bearing and stay. The test is whether a future reader needs
it **to avoid breaking something** — not whether it is interesting.
**Commits.** Conventional Commits (`feat:`, `fix:`, `docs:`, `chore:`, `refactor:`).
One logical change per commit. Never commit secrets, `.env` files, or AWS
credentials. Gitea is not an AWS OIDC provider, so the deploy key is designed as
+20 -12
View File
@@ -59,11 +59,13 @@ both.
`.gitea/workflows/deploy.yml` is the CI pipeline — **Gitea Actions**, not GitHub
Actions. **It has never run**, for two reasons that are not oversights:
- The scoped IAM user does not exist. `aws iam get-user --user-name
adr-sml-deploy` returns `NoSuchEntity` (`AGENTS.md` Q22).
- Actions are not enabled and no runner is registered. The Gitea instance is
jointly administered, so both need its second administrator (Q23).
*(It previously listed a second reason — that the scoped IAM user did not exist.
**It exists**: `adr-sml-deploy`, created 2026-08-26, Q22 closed 2026-08-28. See
`AGENTS.md` §7 for the inventory and the least-privilege verification.)*
Its **first** step is a guard: the run aborts, naming what is missing, if any
required variable or either AWS secret is empty. Only emptiness is tested and no
value is echoed.
@@ -75,11 +77,14 @@ Gitea falls back to that directory when `.gitea/workflows` is absent, so a
workflow file left there with a `push` trigger would be only conditionally
inert. As an `.example` under `docs/` it cannot be picked up at all.
**The pipeline is designed around a long-lived AWS credential, and it does not
exist yet.** Gitea is not an AWS OIDC provider, so there is no role to assume:
deploys are *to* authenticate as a scoped IAM user, `adr-sml-deploy`, with its
access key in the repository's Gitea Actions secrets. `aws iam get-user`
confirms that user has not been created (Q22). In the meantime the local script
**The pipeline is designed around a long-lived AWS credential, and that
credential now exists.** Gitea is not an AWS OIDC provider, so there is no role
to assume: deploys authenticate as a scoped IAM user, `adr-sml-deploy`, with its
access key in the repository's Gitea Actions secrets. **The user was created
2026-08-26 and verified least-privilege by execution — `AGENTS.md` §7, Q22 closed
2026-08-28.** Its access key has **never been used** (`LastUsed` null), because
deploys still run locally. *(This paragraph asserted the user "has not been
created" until 2026-08-28.)* In the meantime the local script
**refuses to run as `user/pouya`**, the broadly-permissioned personal user —
see `AGENTS.md` §10. Two things are meant to bound the risk, and neither is in
place yet:
@@ -93,11 +98,14 @@ place yet:
narrowness is what keeps a compromised runner away from it, and it is
load-bearing rather than hygiene. See `AGENTS.md` §10. If a deploy step needs
a permission the policy lacks, question the step; do not widen the policy.
- **The key must be rotated quarterly, and nobody owns that yet.** Create a
second access key, update the Gitea secrets, confirm a deploy succeeds, then
delete the old one — rotation that leaves the old key active is not
rotation. OIDC would have removed the obligation entirely; it is
unavailable, so this is a standing calendar task still waiting on an owner.
- **The key must be rotated quarterly. It now has an owner and a date: first
rotation due 2026-11-26** (key created 2026-08-26) — `AGENTS.md` §12 **R17**.
Create a second access key, update the Gitea secrets, confirm a deploy
succeeds, **then** delete the old one — rotation that leaves the old key active
is not rotation, and deleting before verifying leaves no way to authenticate
the fix. OIDC would have removed the obligation entirely; it is unavailable, so
this is a standing calendar task. *(It read "nobody owns that yet" until
2026-08-28; R17 is the owner, and the date is the whole point of the row.)*
Full procedure, IAM policy, runner setup, and cutover checklist:
`docs/06-deployment.md`.
+37 -8
View File
@@ -99,7 +99,7 @@ Revisit at month 1218, once there is relationship history to point to.
## Not a practice area yet: tax-adjacent disputes
**Canadian Tax Foundation membership is verified** (`AGENTS.md` §4, 2026-08-26)
**Canadian Tax Foundation membership is verified** (`AGENTS.md` §4 — read the stamp there; a second copy of a currency stamp goes stale where nobody re-reads it, and this one had)
and it is the one credential none of the six areas above touch. Tax-adjacent
disputes are genuinely ADR territory — valuation and purchase-price disputes on
a share sale, indemnity and earn-out fights that turn on a tax position,
@@ -167,7 +167,8 @@ to an appointment. This page carries the verifiable record.
engineering, operating a company — told as one arc rather than three lists.
3. **Credentials**, structured and scannable: designations, education,
certifications, memberships. Every line from `AGENTS.md` §4 Verified.
4. **The credentialing arc.** Q.Med held → Q.Arb in progress → C.Med-Arb as the
4. **The credentialing arc.** Q.Med held → Q.Arb **commenced August 2026**
C.Med-Arb as the
endpoint. The brief (§V) treats the arc itself as part of the story; say so
openly rather than implying a finished state.
5. **Languages and cross-cultural practice.**
@@ -176,8 +177,14 @@ to an appointment. This page carries the verifiable record.
7. `Person` JSON-LD. Downloadable one-page PDF bio — brief §VIII lists this as
an asset for circulation with appointment proposals.
> **The PDF bio does NOT ship with build step 3, and the omission is stated
> rather than silent** — `AGENTS.md` Q45, opened 2026-08-28. No such file exists
> **The PDF bio ships at BUILD STEP 9, alongside `/fees/` — deferred by Pouya
> 2026-08-28 (Q45), tracked as `AGENTS.md` §12 **R16**.** 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. The two decisions below are **not** settled by the deferral and travel
> with R16. Original note follows, and its reasoning is why this is R16 rather
> than a to-do. **The PDF bio does NOT ship with build step 3, and the omission
> is stated rather than silent** — `AGENTS.md` Q45, opened 2026-08-28. No such file exists
> in the repo, and a link to one that does not exist is a broken link on the
> page an appointing body reads. It is also not a formatting job: a one-page bio
> is a **credential document** whose every line has to trace to §4 exactly as a
@@ -214,8 +221,11 @@ neutral.
2. **Tracks:** documents-only, expedited, full hearing.
3. **Rules:** ADRIC, ADR Chambers, ad hoc.
4. Awards — form, reasoning, timing.
5. **Credentialing status, stated plainly.** The Q.Arb pathway is in progress;
the page says so. **What is available now is all three forms — sole,
5. **Credentialing status, stated plainly.** The Q.Arb pathway **commenced
August 2026**; the page says so in those words. *"In progress" was the
wording here until 2026-08-28 and it is barred — `docs/06`'s own cutover
checklist says "§4's wording, not the looser 'in progress'", and this is the
spec for the page that has to get it right.* **What is available now is all three forms — sole,
party-appointed and co-arbitration** — and `AGENTS.md` §4 Offerings carries a
row for each `[verified 2026-08-26 — Pouya]`. The page states that alongside
the credentialing stage: Q.Arb commenced August 2026, C.Med-Arb is the
@@ -247,8 +257,27 @@ long-term narrative.
Six cards, one paragraph each, linking onward. Also the natural home for the
"also offered" strip: **early neutral evaluation, dispute-system design, and
pre-dispute technical advisory** — three, and each now has an `AGENTS.md` §4
Offerings row, which is what the strip needs before it may ship.
pre-dispute technical advisory** — three, and each has an `AGENTS.md` §4
Offerings row.
> ✅ **THE STRIP MAY SHIP — Q46(a) closed 2026-08-28, on Pouya's second
> ruling.** All three §4 Offerings rows now read **PUBLISHABLE**. Read the ENE
> row before writing the strip: gate 1 (*is the activity gated?*) is closed as
> **`[Pouya's stated basis 2026-08-28]`** and **not** as `[verified]`, because no
> source for any of the three exists in `docs/reference/`. That is a deliberate,
> attributed position of the architect's, not a sourced fact — do not describe it
> on the page or in a comment as settled law.
>
> **Two framing constraints survive the ruling and are not discretionary:**
>
> 1. **ENE is an assessment delivered to BOTH parties**, never advice to one. It
> is the offering nearest §4's NOT-NEGOTIABLE boundary — a neutral assessment
> of the *merits* sits closest to *"providing legal services"*.
> 2. **Pre-dispute advisory carries a conflict caution**, and it is practice
> management rather than a publication gate: advisory work for one
> organisation can conflict against a later appointment in the same matter.
> **No copy may imply the offering is free of that tension** — this strip is
> where the temptation to imply it will arise.
> **`settlement counsel` IS STRUCK FROM THIS STRIP AND MUST NOT BE RESTORED.**
> `AGENTS.md` Q42, 2026-08-27. Pouya struck it as his own error in this document:
+105 -11
View File
@@ -13,6 +13,47 @@ table before writing any number, statistic, or superlative. If you need a fact
you do not have, write `TODO(pouya): <exact question>` and log it in §9. Do not
infer, do not soften, do not carry anything over from the old site.
### When a fact is `[unestablished]`, write around the capacity question
**Ratified by Pouya 2026-08-28 as a reusable pattern, with the instruction that
it will recur.** §4 records licence status as `[unestablished]` and says: *do not
assert it, do not deny it.* Copy that addresses the question at all must
therefore pick neither side — and the trap is that **both obvious phrasings pick
one.**
The worked example, which took three attempts and two audits:
| Attempt | Copy | Why it failed |
|---|---|---|
| 1 | "I **do not** give legal advice" | *"Do not"* is an **election** — it implies entitlement withheld by choice. Flagged by audit 1 |
| 2 | "I **cannot** give legal advice" | *"Cannot"* is a **denial** of capacity. Flagged by audit 2 |
| 3 ✅ | "I act as a neutral. I do not act for a party in a matter I take, and each party should have their own legal advice." | Makes **no capacity claim at all** |
**Both audits were right, and that is why the third version works.** Attempts 1
and 2 are opposite answers to the same question, so flagging both is not
inconsistency — it is the correct finding twice. Pouya: *"'do not' elects,
'cannot' denies, and §4 says do neither. The shipped sentence makes no capacity
claim at all — it describes the role and points the reader somewhere useful."*
**The pattern, stated for reuse:**
> Do not look for a *softer* way to answer the capacity question. Any word that
> answers it — *cannot, do not, am not, is not permitted, is not qualified* —
> takes a side of a fact this register does not hold. Instead write the sentence
> so the question **does not arise**: state the **role**, state the
> **consequence** for the reader, and stop.
Three tests before shipping such a sentence. It fails if any is yes:
1. Could a reader infer from it that he **is** entitled to do the thing?
2. Could a reader infer from it that he is **not**?
3. Does it contain a verb of capacity or permission attached to him at all?
**Where this will come up next:** `/practice/` (step 5) and `/for-parties/`, both
of which have to tell an unrepresented party what the neutral will and will not
do for them — the exact place the "cannot" phrasing feels most natural and is
most wrong.
---
## Voice
@@ -38,8 +79,18 @@ detect padding instantly and discount everything after it.
The shape of the bullet still stands, so here is a sentence that fits it and
clears the register: *"I accept sole, party-appointed and co-arbitration
appointments. The Q.Arb designation commenced in August 2026; C.Med-Arb is the
endpoint."* The limit being named is the **stage of the arc**, stated plainly —
appointments **in commercial matters**. The Q.Arb **pathway** commenced in
August 2026; C.Med-Arb is the endpoint."* **"in commercial matters" is not
optional** — every §4 Offerings arbitration row is scoped commercial, family
arbitration has its own NOT OFFERED row, and §4's NOT-NEGOTIABLE boundary
records the unscoped class form as the struck universal (Q39). This model
sentence was unscoped until 2026-08-28 while the shipped page it feeds was
scoped; found by `claims-auditor` on re-audit, one file over from the same
defect fixed in `docs/04` earlier the same day. **"Pathway", never "designation"** — a *designation* that
"commenced in August 2026" reads as in force since then, i.e. **held**, which
§4 Forbidden bars outright. This model sentence said "designation" until
2026-08-28 and it is copy an implementer is told to lift; found by
`claims-auditor`. The limit being named is the **stage of the arc**, stated plainly —
Pouya's instruction is that being open about it is the differentiator, so do
not hedge it into vagueness and do not drop it. (**No tribunal-secretary
work** — D14
@@ -58,8 +109,12 @@ detect padding instantly and discount everything after it.
**The approved phrasing is "active litigation exposure" or "involvement in
litigation and ADR matters" — never "practice" in that context.** Pouya's
wording, 2026-08-26. So: *Director of Firm Operations at a Toronto litigation
and ADR boutique, with active exposure to construction, personal injury, POA,
and SABS matters.* Accurate, specific, and it claims nothing it should not.
and ADR boutique, with **active litigation exposure** across construction,
personal injury, POA, and SABS matters.* Accurate, specific, and it claims
nothing it should not. *(This example read "with active exposure to" until
2026-08-28 — a **third** variant of the phrasing, three lines below the
sentence naming the only two approved forms, in the one place where the wording
IS the compliance. Found by `claims-auditor` on re-audit.)*
This framing is **interim** — see `AGENTS.md` §12 R1. Raise it with Pouya
rather than letting it settle in by default.
@@ -83,7 +138,7 @@ detect padding instantly and discount everything after it.
Reused, adapted, across the hero, the About page, and the PDF bio:
> The dispute resolution practice of Pouya Lajevardi — a credentialed neutral
> who is also close to live litigation and a practising machine-learning and
> with active litigation exposure and a practising machine-learning and
> infrastructure engineer. Built for commercial, construction, energy,
> technology, and cross-cultural disputes that turn on the contract, the code,
> the engineering documents, and the regulatory overlay around them.
@@ -213,9 +268,16 @@ redrawing the loop into a line.* First person: "my mark", not "our mark".
400600 words of narrative, then structured credentials. Tell the three tracks
as one arc, not three lists: a JD and active litigation exposure; a parallel
career in machine learning and infrastructure engineering; a company run
alongside both. The arc is the point — the credentialing pathway from Q.Med
through Q.Arb to C.Med-Arb is stated openly as in progress. The brief treats
that arc as part of the story rather than something to obscure.
alongside the practice — §4's wording; "alongside both" was a concurrency claim
the register does not make. The arc is the point — the credentialing pathway from Q.Med
through Q.Arb to C.Med-Arb is stated openly, **with Q.Arb described as
commenced August 2026** and never as "in progress", which is looser than §4 and
is barred by `docs/06`'s cutover checklist. The brief treats that arc as part of
the story rather than something to obscure.
The designation names expand as **Qualified Mediator**, **Qualified Arbitrator**
and **Chartered Med-Arbitrator** — ADRIO's own forms, sourced in
`docs/reference/adrio-designations.md`. Never "Chartered Mediator-Arbitrator".
Omit any section that would be empty. No "Speaking" heading until there is a
talk to list.
@@ -272,9 +334,26 @@ evasions, no "contact for pricing" after promising a rate card.
### For parties
The one page in second person. Grade-9 reading level. Short sentences. Says
explicitly: the mediator is not your lawyer and cannot give you legal advice; the
mediator does not decide who is right. Answers what it costs and what happens if
you do not settle.
explicitly: **the mediator is a neutral and does not act for either party; each
party should have their own legal advice;** and the mediator does not decide who
is right. Answers what it costs and what happens if you do not settle.
> ⚠️ **THIS DIRECTIVE READ *"the mediator is not your lawyer and cannot give you
> legal advice"* UNTIL 2026-08-28, AND IT BREACHED D13 TWICE** — in the file that
> warns, fifty lines above, that `/for-parties/` is *"the exact place the
> 'cannot' phrasing feels most natural and is most wrong"*.
>
> 1. **"not your lawyer" presupposes lawyer status.** §4 Forbidden bars *the word
> "lawyer" used of Pouya*, and D13 treats implication as hard as assertion. A
> negation still carries the presupposition.
> 2. **"cannot give you legal advice" is attempt 2** in this file's own ratified
> table — *"a **denial** of capacity"* — and it fails test 3 and the
> compliance-checklist item, both added to this file in the same change set
> that left this line untouched.
>
> The replacement is the ratified pattern applied verbatim: **role, then
> consequence for the reader, and no verb of capacity.** Found by
> `claims-auditor` on re-audit; the original sweep did not reach this section.
### Insights
1,2001,800 words, monthly cadence (brief §VIII). Territories from §VII:
@@ -313,3 +392,18 @@ Drafted by Claude, **every word reviewed by Pouya before publication**:
- [ ] Contact page states that an inquiry creates no retainer and no
mediatorparty relationship
- [ ] Any comparative claim is factual and verifiable
- [ ] No sentence answers the licence-capacity question in **either** direction —
see *When a fact is `[unestablished]`* above. Check for *cannot*, *do not*,
*am not*, *not permitted*, *not qualified* **attached to giving legal
advice, practising law, or holding a licence.** The objection is to
answering the *capacity* question, not to the words themselves — the
approved sentence contains "do not" and passes: *"I act as a neutral. I do
not act for a party in a matter I take, and each party should have their
own legal advice."* That is **role conduct**, which he may state freely.
*(This item shipped unscoped for one pass and `adversarial-reviewer` showed
it would fail the exact sentence the section exists to bless — and the
checklist is what gets grepped.)*
- [ ] Abbreviations expanded on §11 Glossary's authority only — and expansions
for the five ADR designations checked against
`docs/reference/adrio-designations.md`, not from memory. "Chartered
**Med**-Arbitrator", never "Mediator-Arbitrator"
+8 -4
View File
@@ -48,8 +48,12 @@ D1.
Every page passes through one `SEO` component. A page without it is not finished.
```
title 5060 chars, unique. Pattern: "<Page> · Pouya Lajevardi"
Home: "Pouya Lajevardi · Mediation & Arbitration · Toronto"
title 5060 chars, unique. Pattern: "<Page> · Pouya Lajevardi".
`/` composes its own from the constants — `SITE.name` +
`SITE.tagline` — rather than a literal, so the masthead and
the title cannot drift. This spec carried the literal with an
ampersand after the composition shipped with interpuncts;
cite the constants, do not restate them (AGENTS.md §7 rule).
ARTICLES ARE THE EXCEPTION: no " · Pouya Lajevardi" suffix.
The suffix is 18 chars, so a headline that already reads
5060 renders at 6878 — over this ceiling. Measured against
@@ -101,8 +105,8 @@ JSON-LD only. Validate against Google's Rich Results Test before cutover.
| Type | Where | Notes |
|---|---|---|
| `Person` | `/about/`, referenced site-wide | `name`, `jobTitle`, `description`, `alumniOf` (Bond University), `knowsLanguage` (en, fa), `hasCredential` (Q.Med), `sameAs` (LinkedIn), `image`. **`jobTitle` = "Director of Firm Operations"; omit `worksFor`** — populating it either names the boutique (D16) or misstates the employer |
| `ProfessionalService` | Home | `areaServed` Toronto/Ontario, `serviceType` Mediation/Arbitration, `provider` → Person, `priceRange` once `/fees/` is real. **Never `LegalService`** — schema.org defines it as a business providing legal advice and *representation*, which asserts in machine-readable form exactly what D13 bars and §4 Forbidden calls out |
| `Person` | `/about/`, referenced site-wide | **Emitted:** `name`, `url`, `jobTitle`, `description`, `alumniOf` (Bond University), `knowsLanguage` (en, fa), `hasCredential` (Q.Med), `sameAs` (LinkedIn), `email`, `image`. **Emitted on `/about/` only:** `memberOf` — the four §4 memberships as `Organization` nodes (Q53, ruled 2026-08-28). `/` shows no memberships, so its Person node omits it: structured data represents the page it sits on. **Withheld:** `worksFor` — Q49(b) declined the row 2026-08-28; `provider → Person → worksFor` would assert a same-entity claim §4 does not row. *(This enumeration listed `worksFor` as emitted while the same cell said it was withheld, and omitted `url` and `email`, which are — wrong in both directions. The enumeration is the part an implementer copies. Found by `adversarial-reviewer`.)* **CHANGED 2026-08-28 — Q47.** This row read *"`jobTitle` = 'Director of Firm Operations'; omit `worksFor`"*, which put the boutique title on a node whose `url` is this ADR practice's `/about/` — so a consumer could attach it to this entity. Pouya's ruling reframes the field: `jobTitle` describes **this practice**, not the boutique role, which D16 keeps unnamed. The visible role line is unchanged and still reads "Director of Firm Operations at a Toronto litigation and ADR boutique". **THE VALUE IS `PRACTICE_JOB_TITLE` IN `src/data/site.ts` AND THIS ROW DOES NOT RESTATE IT** — §7's rule, applied to a string with a live revert trigger on it: this row carried the literal text for one pass, and `adversarial-reviewer` noted it would go stale the moment the constant moved. Cite, do not copy. **`worksFor` IS WITHHELD** — set for one pass under Q47, then reverted: `ProfessionalService.provider` is this Person, so `provider → Person → worksFor` asserts the same-entity claim `schema.ts` explicitly declines, and §4 says "alongside the practice" where the ruling says "operates through". **`memberOf` is emitted** — see the sentence above; Q53 closed 2026-08-28. *(This cell asserted `memberOf` was both emitted and withheld for one pass, which is the defect it already records itself being caught for on `worksFor`, in the opposite direction. The enumeration is the part an implementer copies.)* See `src/data/schema.ts` |
| `ProfessionalService` | Home | `areaServed` Toronto/Ontario, `serviceType` **Mediation / Commercial arbitration / Mediation-arbitration (med-arb)***scoped 2026-08-28 on `claims-auditor`'s finding; this row instructed the unscoped class form "Mediation/Arbitration" that Q39 struck and that `schema.ts` deliberately does not follow. Family arbitration carries prescribed training and has its own NOT OFFERED row, so unscoped "Arbitration" is the struck universal in a field nobody reads. Do not widen these strings without a §4 row to widen them from* `provider` → Person, `priceRange` once `/fees/` is real. **Never `LegalService`** — schema.org defines it as a business providing legal advice and *representation*, which asserts in machine-readable form exactly what D13 bars and §4 Forbidden calls out |
| `Service` | Each practice page | `serviceType`, `provider` → Person, `areaServed` |
| `Article` | Each article | `headline`, `description`, `datePublished`, `dateModified`, `author` → Person, `image` |
| `BreadcrumbList` | All nested pages | Matches visible breadcrumbs |
+46 -15
View File
@@ -34,13 +34,27 @@ cache headers, and the same invalidation as the workflow — at this scale the
pipeline changes only **how a deploy is triggered**, not what it does. Treat the
script and the workflow as one artefact in two places: change one, change both.
Two things block the workflow, and neither is a fact to look up:
One thing blocks the workflow, and it is not a fact to look up:
- **`adr-sml-deploy` does not exist** — `aws iam get-user` returns
`NoSuchEntity` (§7, Q22). Create it from *Create the user* below.
- **Actions are not enabled and no runner is registered** (Q23). The Gitea
instance is jointly administered, so both need its second administrator.
> ✅ **`adr-sml-deploy` EXISTS — created 2026-08-26, Q22 closed 2026-08-28.**
> **DO NOT CREATE IT.** This bullet said *"`adr-sml-deploy` does not exist —
> `aws iam get-user` returns `NoSuchEntity`… Create it from Create the user
> below"* until 2026-08-28, and an operator following it would have created a
> **second** IAM user, or hand-provisioned one with a different scope from the
> `adr-sml-deploy-minimal` policy §7 now records. §7 carries the inventory and
> the eight `simulate-principal-policy` results.
>
> *Found by `adversarial-reviewer`: the Q22 flip to PROVISIONED was swept in
> `AGENTS.md` and nowhere else, and the Change Log entry's sweep block covered
> the copy corrections only. Same shape as the SES-DKIM inversion — the stale
> copy instructed an action against a High-risk credential.*
>
> *Create the user* below is retained as the **record of how it was
> provisioned**, not as an instruction. Read it that way.
The script **refuses to run as `user/pouya`** — the broadly-permissioned
personal user that has been authenticating to this account. See §10.
@@ -329,18 +343,35 @@ Then invalidate `/*`.
**Content and compliance**
- [ ] Every claim traced to `AGENTS.md` §4 Verified
- [ ] **Memberships re-confirmed with Pouya, then published**`AGENTS.md` §12
**R10** and **Q44**. ADRIC, ADRIO, the three OBA sections and the Canadian
Tax Foundation are `[verified 2026-08-26]`. **§4 records yearly renewal for
the OBA sections and the CTF only** — it says nothing about ADRIC's or
ADRIO's period, and an earlier version of this line asserted "all renew
yearly", which §4 does not support. **`/about/` currently publishes NO
memberships group**: R10 is a prohibition and the re-confirmation was not
obtained, so the group is withheld behind a `TODO(pouya)`. OCNI already
lapsed quietly and §4 records it as "not current, do not publish" — that is
the failure mode, and a stamp is not a renewal receipt. Re-confirm,
re-stamp §4 and `CREDENTIALS.memberships`, restore the group to
`CREDENTIAL_GROUPS`, and add `memberOf` to the Person JSON-LD
- [ ] **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
events.** Q44 closed 2026-08-28 and the group is published on `/about/`
(ADRIC, ADRIO, the three OBA sections, the CTF, `[verified 2026-08-28 —
Pouya]`), so this item is no longer "publish them" — it is **"ask him
again, then re-stamp §4 with the cutover date."**
**Pouya declined renewal-date tracking**, which is exactly why this sits on
the checklist: there is no date on which anyone would otherwise re-check.
OCNI lapsed quietly and §4 records it as "not current, do not publish" —
found roughly a year late. A stamp is not a renewal receipt.
**Do NOT add a currency sentence to the page while you are here** — his
ruling is *"list the memberships; promise nothing about their future
state"*, and the struck sentence stays struck.
**`memberOf` IS EMITTED on `/about/`** — Q53 answered 2026-08-28 and the
withholding is dropped, so the graph asserts the same four memberships the
page shows. **This item therefore covers both**: re-confirming before
cutover means `src/data/schema.ts` as well as the visible list, and they
must not be allowed to diverge.
**§4 records yearly renewal for the OBA sections and the CTF only** — it
says nothing about ADRIC's or ADRIO's period, and an earlier version of
this line asserted "all renew yearly", which §4 does not support.
- [ ] **The OBA sections stay listed; the LSO stays out** — a check that nobody
has tidied the two into one list, not an open question. `AGENTS.md` **Q51
answered 2026-08-28**: the Law Society is the **regulator**, so membership
*is* licensure; the OBA is a **voluntary association**, which admits
members it does not license. Structural, and independent of eligibility
details — which is what made the question unanswerable inside this repo
before the ruling. **R1 is still live**: same page, same subject, different
question
- [ ] No `TODO(pouya)` remains in any shipped page
- [ ] No matter counts, rates, dollar figures, or testimonials anywhere
- [ ] Q.Arb described as **commenced August 2026** everywhere it appears — §4's
+17 -3
View File
@@ -104,13 +104,18 @@ All figures **plus HST**.
### Arbitration
Sole, party-appointed and co-arbitration appointments are all accepted now —
`AGENTS.md` §4 Offerings carries a row for each `[verified 2026-08-26 — Pouya]`.
Sole, party-appointed and co-arbitration appointments **in commercial matters**
are all accepted now — `AGENTS.md` §4 Offerings carries a row for each
`[verified 2026-08-26 — Pouya]`. *("in commercial matters" added 2026-08-28: the
line was unscoped, and every §4 arbitration row is scoped commercial with family
arbitration separately NOT OFFERED — Q39's struck universal.)*
*(This line previously read "sole appointments follow the Q.Arb designation",
which understated the offering, and carried a caveat against a since-closed
Q36.)* Whatever `/fees/` says about arbitration must state the Q.Arb stage
plainly alongside it — §4 Offerings, "neither half may be dropped": the Q.Arb
designation commenced August 2026, with C.Med-Arb as the endpoint. See
**pathway** commenced August 2026, with C.Med-Arb as the endpoint. *("pathway",
not "designation" — a designation that commenced reads as held, which §4
Forbidden bars. Corrected 2026-08-28 on `claims-auditor`'s finding.)* See
`03-content-spec.md` for the wording.
| Item | Fee |
@@ -128,6 +133,15 @@ offer tribunal-secretary work on the site.
Early neutral evaluation, dispute-system design, and pre-dispute technical
advisory: **$500 / hour**.
> ✅ **PUBLISHABLE — Q46(a) closed 2026-08-28.** All three §4 Offerings rows
> read PUBLISHABLE on Pouya's second ruling, so the line item may go on
> `/fees/`. **Read the §4 ENE row first:** gate 1 is closed as **`[Pouya's
> stated basis 2026-08-28]`**, not `[verified]` — there is still no source in
> `docs/reference/` — and the framing constraints in `docs/01` §`/practice/`
> travel with the offering onto this page. In particular, **ENE is priced as an
> assessment delivered to both parties**, and nothing on `/fees/` may read as a
> rate for advising one of them.
**THREE services, not four. `settlement counsel` is struck and must not be
priced** — `AGENTS.md` Q42, Pouya 2026-08-27, correcting his own entry in
`docs/01`:
+251
View File
@@ -0,0 +1,251 @@
# Reference — ADRIO's own expansions of the five ADR designations
**Why this file exists.** `AGENTS.md` Q46(b) asked whether §11 Glossary may be
published as the source for **definitional expansions** — what `Q.Med`, `Q.Arb`
and `C.Med-Arb` stand for. Pouya ratified the standard on 2026-08-28 and
attached a condition: *"Fetch and commit
https://adr-ontario.ca/members-practitioners/professional-designations to
docs/reference/ per R14."* This is that fetch.
It also settles a **correction Pouya raised in the same ruling**, and the
correction was his own: §11 had said *"Chartered Mediator-Arbitrator"* since the
file was created. ADRIO's term is **"Chartered Med-Arbitrator"**. See Finding 2.
---
## Provenance — read this before quoting anything below
| | |
|---|---|
| URL as given | `https://adr-ontario.ca/members-practitioners/professional-designations` |
| **Redirects to** | `https://adr-ontario.ca/professional-designations/` — HTTP **301**, one hop |
| Retrieved | **2026-08-28** |
| Method | `curl -sSL -o <file> '<url>'` — HTTP **200** on all five after the redirect |
**The redirect is recorded because the first fetch did not follow it.** `curl -sS`
without `-L` returned HTTP 301 and wrote a **0-byte file**, which a reader of
the output could easily have taken for "the page is empty". It is not; it is
one hop away. `CLAUDE.md`: *a command that did not run is not evidence of
absence* — and a command that ran and returned nothing useful looks the same.
### The five files, with digests
| Page | Bytes | Text | `sha256` |
|---|---|---|---|
| `professional-designations/` | 54,961 | 1,932 | `5eca45791b3629d16186dd2a10df43fdd5981cbe89a6ce23d8b43ec7c4c415a8` |
| `qualified-mediator-q-med-qualified-arbitrator-q-arb/` | 57,174 | 2,814 | `c8cb8ad556b7ffd193cb672f136d4c0b0bdffdcaa8ac20739f31c1ccef84301f` |
| `chartered-mediator-c-med/` | 58,929 | 4,151 | `47cb8edb20681865b55103e265c693405a8dfde369fd5f4eefd340fb58f0c056` |
| `chartered-arbitrator-c-arb/` | 58,013 | 3,524 | `44526cb40f3e99bec03e3b45b13d4dc4b6cb5fd4e13b388ed533f7baa6fb1199` |
| `chartered-med-arbitrator-c-med-arb/` | 55,966 | 2,504 | `4c3a3214383c80209884125703e89625e855b550f01ea8141df496603cdd69c7` |
*Text* = characters remaining after `<script>`/`<style>`/`<noscript>`/comments
and tags are stripped, entities unescaped, whitespace collapsed.
> 📁 **THE EXTRACTED TEXT AND THE SCRIPT THAT PRODUCED IT ARE COMMITTED** —
> `adrio-extract/`. Every term count in this file was run against those `.txt`
> files, and `extract.mjs` is the extraction. **The digests above cover the raw
> HTML; they said nothing about the extraction**, so the counts were unverifiable
> by construction (R14) even while the digests were not —
> `adversarial-reviewer`, 2026-08-28. `adrio-extract/README.md` carries the
> reproduction command and the caveat that a future digest mismatch is most
> likely a WordPress plugin bump rather than a changed designation name.
> ✅ **THESE DIGESTS ARE STAMPED, AND `lat-case-conference.md`'S ARE NOT — THE
> DIFFERENCE WAS CHECKED, NOT ASSUMED.** That file removed its hashes because the
> LAT pages could not reproduce one: `LAT-Rules.html` carries a per-request
> bot-detection nonce (`__uzdbm_1`, `__uzdbm_2`) and the AABS page carries
> rotating WordPress `?ver=` cache-busters.
>
> Both causes were looked for here and **both are absent**:
>
> - `__uzdbm` — **0 occurrences.**
> - `?ver=` — 17 occurrences, and they are **static plugin version strings**
> (`?ver=1.3.12`, `?ver=2.3.2`, `?ver=3.4.1`, `?ver=4.7.0`), not rotating
> values. Same string on every fetch.
>
> Then measured rather than reasoned about: **four independent fetches of each of
> the five URLs, and the file on disk re-hashed against a fresh fetch. All five
> MATCH.** The digests above are of the exact bytes the quotes below came from.
>
> **One instrument failure happened during that check and is recorded because of
> its shape.** The first comparison loop used `set -- $pair` under zsh, which
> does not word-split unquoted variables, so the loop body received one argument
> and every comparison silently failed — printing **`DIFFER` on all five rows**.
> That output reads exactly like *"the pages changed under me"*. It was the
> `timeout 60 ls "$DRIVE"` shape: the comparison had never run. Re-run with
> `while IFS=: read`, all five returned MATCH.
**Instrument note on JS-rendered shells.** The parent page extracts to **1,932
characters from 54,961 bytes — 3.5%**, which is the signature `adric.ca` produced
when it defeated an earlier attempt at this same sourcing (4,840 chars from
114,985). Here the low ratio is **not** a shell: the parent page really is nearly
empty — its body is a title and one sentence pointing elsewhere. The substance is
on the four child pages, which extract at 4.57.0% because ~1,800 characters of
the extraction on every page is the shared navigation. Read the ratio against the
page, not against a threshold.
---
## Finding 1 — all five expansions, verbatim
Present **twice** on the parent page (desktop and mobile navigation), and again
as the `<h1>` of each child page. ADRIO's own words, entities unescaped:
| Abbrev. | ADRIO's expansion | Source |
|---|---|---|
| `Q.Med` | **Qualified Mediator** | nav + child `<h1>` |
| `Q.Arb` | **Qualified Arbitrator** | nav + child `<h1>` |
| `C.Med` | **Chartered Mediator** | nav + child `<h1>` |
| `C.Arb` | **Chartered Arbitrator** | nav + child `<h1>` |
| `C.Med-Arb` | **Chartered Med-Arbitrator** | nav + child `<h1>` |
The navigation markup, verbatim:
```html
<a href="https://adr-ontario.ca/qualified-mediator-q-med-qualified-arbitrator-q-arb/">Qualified Mediator (Q.Med) &#038; Qualified Arbitrator (Q.Arb)</a>
<a href="https://adr-ontario.ca/chartered-mediator-c-med/">Chartered Mediator (C.Med)</a>
<a href="https://adr-ontario.ca/chartered-arbitrator-c-arb/">Chartered Arbitrator (C.Arb)</a>
<a href="https://adr-ontario.ca/chartered-med-arbitrator-c-med-arb/">Chartered Med-Arbitrator (C.Med-Arb)</a>
```
**The URL slugs corroborate independently of the link text**`chartered-med-arbitrator-c-med-arb`, not `chartered-mediator-arbitrator`.
## Finding 2 — the expansion this repo had wrong
`AGENTS.md` §11 read **"Chartered Mediator-Arbitrator"** from the file's creation
until 2026-08-28. Pouya's ruling: *"§11 has said 'Chartered Mediator-Arbitrator'
throughout. ADRIO's own term is 'Chartered Med-Arbitrator'. I took the expansion
from the strategy brief and never sourced it."*
**It had reached a public page.** `src/pages/about.astro`'s credential arc
rendered it as body copy, and `grep -c 'Chartered Mediator-Arbitrator'
dist/about/index.html` returned **1** — so the built artefact carried it too. Four
instances in the repo, swept 2026-08-28.
The child page's own heading and first two sentences, verbatim:
> **Chartered Med-Arbitrator (C.Med-Arb)**
>
> Med-Arb is a distinct, innovative standalone process that is not as well known
> or understood by consumers of ADR services compared to mediation and
> arbitration.
>
> Med-Arb is not merely the merging of separate mediation and arbitration
> processes, but a unique process designed to meet the needs of particular
> disputants. It involves nuances and complexities that can be fine-tuned to the
> needs of the parties as a customized dispute resolution process, which requires
> a high level of practitioner competence to do successfully.
## Finding 3 — how ADRIO characterises the Q-level designations
Verbatim, `qualified-mediator-q-med-qualified-arbitrator-q-arb/`:
> **Qualified Mediator (Q.Med) / Qualified Arbitrator (Q.Arb)**
>
> These designations are to recognize practitioners who have completed sufficient
> mediation / arbitration and related dispute resolution training to be qualified
> to practice. They are an intermediate step for practitioners working to receive
> their Chartered designation.
>
> *Q.Med criteria vary across affiliates. For the criteria specific to Ontario,
> be sure to read the checklist on the application form.*
⚠️ **Do not lift "qualified to practice" into copy, in any form.** It is ADRIO
describing its own designation, and on this site — where §4 records licence
status as `[unestablished]` and D13 bars any phrasing that *implies* entitlement
to practise law — the phrase would do work ADRIO never intended it to do. The
quote is here so a reviewer can see the full sentence, not so it can be reused.
The *"intermediate step … working to receive their Chartered designation"* half
is the sourced basis for describing the arc as an arc. It is a fact about the
designation structure, not about Pouya.
## Finding 4 — two of the four pages state a retention condition, and the split is by PAGE TYPE, not by designation level
> ⚠️ **THIS FINDING'S FIRST VERSION WAS FRAMED WRONG, AND THE PAGE THAT
> FALSIFIED IT WAS ONE THIS FILE HAD ALREADY FETCHED.** It was headed *"the two
> Chartered pages state a retention condition; the Q page does not"* and argued a
> **Qualified-vs-Chartered** asymmetry. There are **three** Chartered pages. The
> count was never run on `chartered-med-arbitrator-c-med-arb/` — the designation
> §4 records as the practice's stated goal, and therefore the one most
> load-bearing for Q48. Found by `claims-auditor`, 2026-08-28.
Counted on the extracted text of **all four** designation pages:
| Page | `good standing` | `annual` | `maintain` | `retain` | `member of the ADR Institute` |
|---|---|---|---|---|---|
| `qualified-mediator-q-med-qualified-arbitrator-q-arb/` | 0 | 0 | 0 | 0 | 0 |
| `chartered-mediator-c-med/` | 1 | 1 | 1 | 1 | 1 |
| `chartered-arbitrator-c-arb/` | 1 | 1 | 1 | 1 | 1 |
| `chartered-med-arbitrator-c-med-arb/` | **0** | **0** | **0** | **0** | **0** |
Verbatim, `chartered-mediator-c-med/`:
> There is an annual fee to maintain your C.Med designation, payable to ADR
> Institute of Canada, Inc. The national organization bills you every year. You
> must also remain a member in good standing with the ADR Institute of Ontario™
> to retain this designation.
`chartered-arbitrator-c-arb/` says the same of C.Arb.
**The corrected reading.** C.Med-Arb scores zero on every term, exactly like the
Q-level page — so the line does **not** fall between Qualified and Chartered. It
falls between **page types**: `chartered-mediator-c-med/` and
`chartered-arbitrator-c-arb/` are long application FAQs with numbered sections
("Are there prerequisites?", "Is there an ongoing cost?"), while the Q page and
the C.Med-Arb page are short descriptions that link out. The C.Med-Arb page says
so in as many words: *"To read more about the C.Med-Arb designation, including
how to apply, click here."*
**And that cuts the opposite way from how the first version read it.** A stub
page's silence is evidence about the *page*, not about the designation — so
Q.Med's silence is most likely "this page does not cover fees or retention", not
"no such condition exists". ADRIC bills annually for the two designations that
say so, and ADRIO notes that *"Q.Med criteria vary across affiliates"*.
**Still: this source does not answer it, in either direction, and must not be
read as doing so.** Raised as **Q48** — if `Q.Med` retention is contingent on
ADRIO membership currency, then §4's Q.Med row, this site's central credential,
inherits the shelf life of the memberships Pouya has declined to track by date
(R10). The answer needs the Q.Med criteria document or ADRIC/ADRIO directly.
## Finding 5 — two superlatives, deliberately not lifted
The Chartered pages call C.Med *"Canada's most senior official designation for
practising mediators"* and C.Arb *"Canada's only official designation for
practising Arbitrators"*. Both are ADRIO's words about its own designations and
both are quotable in principle.
**Neither goes on the site.** §4 Forbidden bars superlatives outright
(*"best", "leading", "top-rated"*), and the reason given there is not only
verifiability — it is that *"they read as insecure to the audience this site is
for"*. A superlative does not stop being one because a third party said it first,
and the credential arc does not need it: **"the designation this practice is built
toward"** is Pouya's own stated goal and has a §4 row.
---
## What this establishes, and what it does not
**Establishes:**
1. All five expansions, in ADRIO's own words, from ADRIO's own site, with
reproducible digests. **R14 is satisfied for Q46(b)** — the standard no longer
rests on §11 asserting its own content.
2. `C.Med-Arb` = **Chartered Med-Arbitrator**. The form this repo published was
wrong.
3. That the Q-level designations are, in ADRIO's characterisation, an
intermediate step toward the Chartered designations.
**Does not establish:**
- **Anything about Pouya.** Not that he holds Q.Med, not that he has commenced
Q.Arb, not that he is a member of ADRIO. Those are §4 Verified rows and this
file is not a substitute for one. The standard Pouya ratified is exactly this
split: *"§11 Glossary is the source for DEFINITIONAL expansions; §4 remains
the only source for claims about Pouya."*
- **Anything about gating** — see `AGENTS.md` §4's offering test, question 1.
ADRIO describes its designations as recognising completed training; it says
nothing about what any activity requires by law, and it is not a source that
could. Q46(a) is not advanced by this file.
- **Anything about Q.Med retention.** Finding 4. That is Q48.
+34
View File
@@ -0,0 +1,34 @@
# The extracted text behind `../adrio-designations.md`
**Why this directory exists.** `adversarial-reviewer` (2026-08-28, C10): the
`sha256` digests in that file cover the **raw HTML**, but Finding 4's term counts
were taken from **extracted text produced by an uncommitted script** — so the
counts were unverifiable by construction (R14) even though the digests were not.
`extract.mjs` is that script. `*.txt` are its outputs, which are what every
count in `../adrio-designations.md` was run against.
## Reproducing
```sh
curl -sSL -o <slug>.html "https://adr-ontario.ca/<slug>/"
node extract.mjs <slug>.html > <slug>.txt
```
The five slugs are listed in the provenance table of `../adrio-designations.md`,
which also carries each file's raw-HTML byte count and `sha256`.
**Expect small differences in the character totals if you re-implement the
extraction.** Both review agents reproduced every digest, every byte count and
every term count exactly; one got 1924 / 2806 / 4121 / 3510 / 2496 characters
against this script's 1932 / 2814 / 4151 / 3524 / 2504, because tag-stripping
inserts whitespace differently. **The term counts are the finding; the character
totals are only a size indicator.**
⚠️ **The digests are valid until ADRIO's next WordPress plugin update.** The
served HTML carries 17 `?ver=` strings that are static plugin versions today
(`?ver=1.3.12`, `?ver=2.3.2`, …) — which is *why* these pages hash reproducibly
where the LAT pages could not. Those strings will move when ADRIO updates a
plugin. **A future digest mismatch is most likely a plugin bump, not tampering
and not a changed designation name** — re-run the term counts before concluding
anything from a mismatch.
@@ -0,0 +1,100 @@
Chartered Arbitrator (C.Arb) The ADR Institute of Ontario
Skip to content
About
About Us
What is ADR?
Resolve a Dispute
ADRIO Board of Directors and Staff
Rules & Codes
ADRIO DEI Policy Framework
Professional Development
Event Calendar
Webcasts Recorded Events
Approved Courses
Lead a Professional Development Workshop with us!
Sections
Communities of Practice and Sections
Committees
Membership & Benefits
Member Portal
Benefits and Application Process
Practical Ethics for Working Mediators
Insurance
Rules & Codes
FAQ
Designations
The Path to your Professional ADR designation
ADRIC Accredited Courses
Qualified Mediator (Q.Med) & Qualified Arbitrator (Q.Arb)
Chartered Mediator (C.Med)
Chartered Arbitrator (C.Arb)
Chartered Med-Arbitrator (C.Med-Arb)
Insurance
FAQ
News & Blog
Blog
Updates
Newsletter
ADRIO E-Mailing List Signup
Presidents Circle
ADRIO STAR Award Recipients
Contact & Staff
About
- About Us
- What is ADR?
- Resolve a Dispute
- ADRIO Board of Directors and Staff
- Rules & Codes
- ADRIO DEI Policy Framework
Professional Development
- Event Calendar
- Webcasts - Recorded Events
- Approved Courses
- Lead a Professional Development Workshop with us!
Sections
- Communities of Practice and Sections
- Committees
Membership & Benefits
- Member Portal
- Benefits and Application Process
- Practical Ethics for Working Mediators
- Insurance
- Rules & Codes
- FAQ
Designations
- The Path to your Professional ADR designation
- ADRIC Accredited Courses
- Qualified Mediator (Q.Med) & Qualified Arbitrator (Q.Arb)
- Chartered Mediator (C.Med)
- Chartered Arbitrator (C.Arb)
- Chartered Med-Arbitrator (C.Med-Arb)
- Insurance
- FAQ
News & Blog
- Blog
- Updates
- Newsletter
- ADRIO E-Mailing List Signup
- Presidents Circle
- ADRIO STAR Award Recipients
Contact & Staff
Chartered Arbitrator (C.Arb)
Please do not mail your applications to our head office. Please email your application to membership@adr-ontario.ca
1. What is a Chartered Arbitrator (C.Arb) designation?
The C.Arb Or Chartered Arbitrator designation is Canadas only official designation for practising Arbitrators. Please click here for a more complete description of the requirements can be found.
2. Are there prerequisites?
The applicant must be a member of the ADR Institute of Ontario™ (or any other regional association).
There are extensive training and experience requirements which you should review before applying.
3. Where do I get the C.Arb Application Form?
The C.Arb application form is linked below.
4. Is there a fee for the C.Arb application?
Yes, the Application Fee is $500.00 (plus HST). This covers the costs of administering the accreditation process. This is a one-time application fee.
5. Is there an ongoing cost?
There is an annual fee to maintain your C.Arb designation. The national organization bills you every year. You must also remain a member in good standing with the ADR Institute of Ontario™ to retain this designation.
6. How do I apply?
Forward your completed application form, and payment along with any attachments necessary to verify the courses you have taken and the work you have done (think of it as marketing yourself to the accreditation committee), to:
Please do not mail your applications to our head office. Please email your application to membership@adr-ontario.ca
(Looking for courses that have been pre-approved to qualify for designation applications? Click here .)
View C.Arb Application Form
View C.Arb Criteria
Theme by Think Up Themes Ltd . Powered by WordPress .
@@ -0,0 +1,85 @@
Chartered Med-Arbitrator (C.Med-Arb) The ADR Institute of Ontario
Skip to content
About
About Us
What is ADR?
Resolve a Dispute
ADRIO Board of Directors and Staff
Rules & Codes
ADRIO DEI Policy Framework
Professional Development
Event Calendar
Webcasts Recorded Events
Approved Courses
Lead a Professional Development Workshop with us!
Sections
Communities of Practice and Sections
Committees
Membership & Benefits
Member Portal
Benefits and Application Process
Practical Ethics for Working Mediators
Insurance
Rules & Codes
FAQ
Designations
The Path to your Professional ADR designation
ADRIC Accredited Courses
Qualified Mediator (Q.Med) & Qualified Arbitrator (Q.Arb)
Chartered Mediator (C.Med)
Chartered Arbitrator (C.Arb)
Chartered Med-Arbitrator (C.Med-Arb)
Insurance
FAQ
News & Blog
Blog
Updates
Newsletter
ADRIO E-Mailing List Signup
Presidents Circle
ADRIO STAR Award Recipients
Contact & Staff
About
- About Us
- What is ADR?
- Resolve a Dispute
- ADRIO Board of Directors and Staff
- Rules & Codes
- ADRIO DEI Policy Framework
Professional Development
- Event Calendar
- Webcasts - Recorded Events
- Approved Courses
- Lead a Professional Development Workshop with us!
Sections
- Communities of Practice and Sections
- Committees
Membership & Benefits
- Member Portal
- Benefits and Application Process
- Practical Ethics for Working Mediators
- Insurance
- Rules & Codes
- FAQ
Designations
- The Path to your Professional ADR designation
- ADRIC Accredited Courses
- Qualified Mediator (Q.Med) & Qualified Arbitrator (Q.Arb)
- Chartered Mediator (C.Med)
- Chartered Arbitrator (C.Arb)
- Chartered Med-Arbitrator (C.Med-Arb)
- Insurance
- FAQ
News & Blog
- Blog
- Updates
- Newsletter
- ADRIO E-Mailing List Signup
- Presidents Circle
- ADRIO STAR Award Recipients
Contact & Staff
Chartered Med-Arbitrator (C.Med-Arb)
Med-Arb is a distinct, innovative standalone process that is not as well known or understood by consumers of ADR services compared to mediation and arbitration.
Med-Arb is not merely the merging of separate mediation and arbitration processes, but a unique process designed to meet the needs of particular disputants. It involves nuances and complexities that can be fine-tuned to the needs of the parties as a customized dispute resolution process, which requires a high level of practitioner competence to do successfully.
To read more about the C.Med-Arb designation, including how to apply, click here .
Theme by Think Up Themes Ltd . Powered by WordPress .
@@ -0,0 +1,100 @@
Chartered Mediator (C.Med) The ADR Institute of Ontario
Skip to content
About
About Us
What is ADR?
Resolve a Dispute
ADRIO Board of Directors and Staff
Rules & Codes
ADRIO DEI Policy Framework
Professional Development
Event Calendar
Webcasts Recorded Events
Approved Courses
Lead a Professional Development Workshop with us!
Sections
Communities of Practice and Sections
Committees
Membership & Benefits
Member Portal
Benefits and Application Process
Practical Ethics for Working Mediators
Insurance
Rules & Codes
FAQ
Designations
The Path to your Professional ADR designation
ADRIC Accredited Courses
Qualified Mediator (Q.Med) & Qualified Arbitrator (Q.Arb)
Chartered Mediator (C.Med)
Chartered Arbitrator (C.Arb)
Chartered Med-Arbitrator (C.Med-Arb)
Insurance
FAQ
News & Blog
Blog
Updates
Newsletter
ADRIO E-Mailing List Signup
Presidents Circle
ADRIO STAR Award Recipients
Contact & Staff
About
- About Us
- What is ADR?
- Resolve a Dispute
- ADRIO Board of Directors and Staff
- Rules & Codes
- ADRIO DEI Policy Framework
Professional Development
- Event Calendar
- Webcasts - Recorded Events
- Approved Courses
- Lead a Professional Development Workshop with us!
Sections
- Communities of Practice and Sections
- Committees
Membership & Benefits
- Member Portal
- Benefits and Application Process
- Practical Ethics for Working Mediators
- Insurance
- Rules & Codes
- FAQ
Designations
- The Path to your Professional ADR designation
- ADRIC Accredited Courses
- Qualified Mediator (Q.Med) & Qualified Arbitrator (Q.Arb)
- Chartered Mediator (C.Med)
- Chartered Arbitrator (C.Arb)
- Chartered Med-Arbitrator (C.Med-Arb)
- Insurance
- FAQ
News & Blog
- Blog
- Updates
- Newsletter
- ADRIO E-Mailing List Signup
- Presidents Circle
- ADRIO STAR Award Recipients
Contact & Staff
Chartered Mediator (C.Med)
Please do not mail your applications to our head office. Please email your application to membership@adr-ontario.ca
1. What is a Chartered Mediator (C.Med) designation?
The “C.Med” or “Chartered Mediator” designation is Canadas most senior official designation for practising mediators.
Clarification re Footnote #4 in the C.Med Criteria “The intended interpretation of Footnote #4 relating to a “Paid Mediation” is as follows: The criteria in Footnote #4 is intended to be applied individually to each of the 15 mediations presented by the applicant, and specifically where a mediation is not fee-paid, the RCMAC shall look at whether the mediation is demonstrably complex and involved, and may at its discretion accept the mediation being considered toward the 15 total mediations. There is no specific minimum number of fee paid mediations of the 15 total mediations required, providing this criteria is applied to each unpaid mediation.”
Use the Application for Chartered Mediator designation linked below.
2. Are there prerequisites?
The applicant must be a member of the ADR Institute of Ontario™.
There are extensive training and experience requirements which you should review before you consider applying.
3. Is there a fee for the C.Med application?
Yes, the Application Fee is $500.00 (plus HST) made payable to the ADR Institute of Ontario, Inc. This covers the costs of administering the accreditation process. This is a one-time application fee.
4. Is there an ongoing cost?
Yes. There is an annual fee to maintain your C.Med designation, payable to ADR Institute of Canada, Inc. The national organization bills you every year. You must also remain a member in good standing with the ADR Institute of Ontario™ to retain this designation.
6. How do I apply?
Forward your completed application form along with any attachments necessary to verify the courses you have taken and the work you have done (think of it as marketing yourself to the accreditation committee), to:
Please do not mail your applications to our head office. Please email your application to membership@adr-ontario.ca
(Looking for courses that have been pre-approved to qualify for designation applications? Click here .)
View C.Med Application Form
View C.Med Criteria
Theme by Think Up Themes Ltd . Powered by WordPress .
+14
View File
@@ -0,0 +1,14 @@
import { readFileSync } from 'node:fs';
const raw = readFileSync(process.argv[2], 'utf8');
let t = raw
.replace(/<script\b[\s\S]*?<\/script>/gi, ' ')
.replace(/<style\b[\s\S]*?<\/style>/gi, ' ')
.replace(/<noscript\b[\s\S]*?<\/noscript>/gi, ' ')
.replace(/<!--[\s\S]*?-->/g, ' ')
.replace(/<[^>]+>/g, ' ');
const ents = { amp:'&', lt:'<', gt:'>', quot:'"', apos:"'", nbsp:' ', ndash:'', mdash:'—', rsquo:'', lsquo:'', ldquo:'“', rdquo:'”' };
t = t.replace(/&([a-zA-Z]+);/g, (m,n)=> n in ents ? ents[n] : m)
.replace(/&#(\d+);/g, (_m,d)=> String.fromCodePoint(+d))
.replace(/&#x([0-9a-f]+);/gi, (_m,h)=> String.fromCodePoint(parseInt(h,16)));
t = t.replace(/[ \t ]+/g,' ').replace(/\s*\n\s*/g,'\n').replace(/\n{2,}/g,'\n').trim();
process.stdout.write(t);
@@ -0,0 +1,83 @@
Professional Designations The ADR Institute of Ontario
Skip to content
About
About Us
What is ADR?
Resolve a Dispute
ADRIO Board of Directors and Staff
Rules & Codes
ADRIO DEI Policy Framework
Professional Development
Event Calendar
Webcasts Recorded Events
Approved Courses
Lead a Professional Development Workshop with us!
Sections
Communities of Practice and Sections
Committees
Membership & Benefits
Member Portal
Benefits and Application Process
Practical Ethics for Working Mediators
Insurance
Rules & Codes
FAQ
Designations
The Path to your Professional ADR designation
ADRIC Accredited Courses
Qualified Mediator (Q.Med) & Qualified Arbitrator (Q.Arb)
Chartered Mediator (C.Med)
Chartered Arbitrator (C.Arb)
Chartered Med-Arbitrator (C.Med-Arb)
Insurance
FAQ
News & Blog
Blog
Updates
Newsletter
ADRIO E-Mailing List Signup
Presidents Circle
ADRIO STAR Award Recipients
Contact & Staff
About
- About Us
- What is ADR?
- Resolve a Dispute
- ADRIO Board of Directors and Staff
- Rules & Codes
- ADRIO DEI Policy Framework
Professional Development
- Event Calendar
- Webcasts - Recorded Events
- Approved Courses
- Lead a Professional Development Workshop with us!
Sections
- Communities of Practice and Sections
- Committees
Membership & Benefits
- Member Portal
- Benefits and Application Process
- Practical Ethics for Working Mediators
- Insurance
- Rules & Codes
- FAQ
Designations
- The Path to your Professional ADR designation
- ADRIC Accredited Courses
- Qualified Mediator (Q.Med) & Qualified Arbitrator (Q.Arb)
- Chartered Mediator (C.Med)
- Chartered Arbitrator (C.Arb)
- Chartered Med-Arbitrator (C.Med-Arb)
- Insurance
- FAQ
News & Blog
- Blog
- Updates
- Newsletter
- ADRIO E-Mailing List Signup
- Presidents Circle
- ADRIO STAR Award Recipients
Contact & Staff
Professional Designations
To read more about the path to designations, click here .
Theme by Think Up Themes Ltd . Powered by WordPress .
@@ -0,0 +1,91 @@
Qualified Mediator (Q.Med) & Qualified Arbitrator (Q.Arb) The ADR Institute of Ontario
Skip to content
About
About Us
What is ADR?
Resolve a Dispute
ADRIO Board of Directors and Staff
Rules & Codes
ADRIO DEI Policy Framework
Professional Development
Event Calendar
Webcasts Recorded Events
Approved Courses
Lead a Professional Development Workshop with us!
Sections
Communities of Practice and Sections
Committees
Membership & Benefits
Member Portal
Benefits and Application Process
Practical Ethics for Working Mediators
Insurance
Rules & Codes
FAQ
Designations
The Path to your Professional ADR designation
ADRIC Accredited Courses
Qualified Mediator (Q.Med) & Qualified Arbitrator (Q.Arb)
Chartered Mediator (C.Med)
Chartered Arbitrator (C.Arb)
Chartered Med-Arbitrator (C.Med-Arb)
Insurance
FAQ
News & Blog
Blog
Updates
Newsletter
ADRIO E-Mailing List Signup
Presidents Circle
ADRIO STAR Award Recipients
Contact & Staff
About
- About Us
- What is ADR?
- Resolve a Dispute
- ADRIO Board of Directors and Staff
- Rules & Codes
- ADRIO DEI Policy Framework
Professional Development
- Event Calendar
- Webcasts - Recorded Events
- Approved Courses
- Lead a Professional Development Workshop with us!
Sections
- Communities of Practice and Sections
- Committees
Membership & Benefits
- Member Portal
- Benefits and Application Process
- Practical Ethics for Working Mediators
- Insurance
- Rules & Codes
- FAQ
Designations
- The Path to your Professional ADR designation
- ADRIC Accredited Courses
- Qualified Mediator (Q.Med) & Qualified Arbitrator (Q.Arb)
- Chartered Mediator (C.Med)
- Chartered Arbitrator (C.Arb)
- Chartered Med-Arbitrator (C.Med-Arb)
- Insurance
- FAQ
News & Blog
- Blog
- Updates
- Newsletter
- ADRIO E-Mailing List Signup
- Presidents Circle
- ADRIO STAR Award Recipients
Contact & Staff
Qualified Mediator (Q.Med) & Qualified Arbitrator (Q.Arb)
Qualified Mediator (Q.Med) / Qualified Arbitrator (Q.Arb)
These designations are to recognize practitioners who have completed sufficient mediation / arbitration and related dispute resolution training to be qualified to practice. They are an intermediate step for practitioners working to receive their Chartered designation.
Please do not mail your applications to our head office. Please email your application to membership@adr-ontario.ca
(Looking for courses that have been pre-approved to qualify for designation applications? Click here .)
Read more by downloading the following resources:
Qualified Arbitrator (Q.Arb) Requirements
Qualified Arbitrator (Q.Arb) Application Form
Qualified Mediator (Q.Med) Criteria and Application Form*
*Q.Med criteria vary across affiliates. For the criteria specific to Ontario, be sure to read the checklist on the application form.
Theme by Think Up Themes Ltd . Powered by WordPress .
@@ -0,0 +1,559 @@
# Deploy credential — verification output
**What this is.** The tool output behind `AGENTS.md` §7's *Deploy credential —
PROVISIONED* row and the two risk downgrades in `AGENTS.md` §10. It exists because the row
was written on evidence that lived only in a terminal, which is the
**Q24 / Q32 shape** R14 exists for: a claim whose supporting artefact is
unreachable is unverifiable by construction, not merely unverified.
`AGENTS.md` **Q52**, ruled 2026-08-28: *"YES — commit the simulate results, the
inline policy, and the `NoSuchBucketPolicy` response, access key ID redacted."*
## Provenance
| | |
|---|---|
| Subject | IAM user `adr-sml-deploy`, AWS account `327082975128` |
| Retrieved | **2026-08-28**, re-run from the repository root |
| Calling identity | `arn:aws:iam::327082975128:user/pouya` — the broadly-permissioned personal user, **at an interactive keyboard**. `AGENTS.md` §7 and §10: acceptable interactively, **never** as a CI credential |
| Calls | 18 — all **read-only**. No `create`, `put`, `attach`, `delete`, or `update` |
| Redaction | The access key ID is replaced with `AKIA…REDACTED` throughout. Nothing else is redacted; `UserId` (`AIDA…`) is retained because it is the durable principal identifier that appears in CloudTrail and grants nothing. The **secret** access key was never requested and cannot be retrieved from the API at all |
| Method | `aws-cli/2.34.53`. Every command's exit status was read, and **no `2>/dev/null` anywhere** — see the `NoSuchBucketPolicy` section, where the error *is* the result |
**Re-run it.** Every command below is copy-pasteable. Nothing here is
transcribed from a session; this file was generated from the captured output.
---
## 1. The user
```console
$ aws iam get-user --user-name adr-sml-deploy
{
"User": {
"Path": "/",
"UserName": "adr-sml-deploy",
"UserId": "AIDAUYJ5KD6MHAAC4BOKD",
"Arn": "arn:aws:iam::327082975128:user/adr-sml-deploy",
"CreateDate": "2026-08-26T15:45:18+00:00"
}
}
```
Created **2026-08-26T15:45:18+00:00**, path `/`, no tags.
## 2. Nothing attached, no groups, one inline policy
```console
$ aws iam list-attached-user-policies --user-name adr-sml-deploy
{
"AttachedPolicies": []
}
$ aws iam list-groups-for-user --user-name adr-sml-deploy
{
"Groups": []
}
$ aws iam list-user-policies --user-name adr-sml-deploy
{
"PolicyNames": [
"adr-sml-deploy-minimal"
]
}
```
**This is the part policy-reading alone gets wrong.** An empty
`AttachedPolicies` proves nothing on its own — permissions can arrive through a
group, or through a resource-based policy that is invisible from the IAM side.
Both are checked: `Groups` is empty here, and **§6 below** checks the resource
side — §5 is the identity-side simulation and does not reach a bucket policy.
## 3. The inline policy — `adr-sml-deploy-minimal`
```console
$ aws iam get-user-policy --user-name adr-sml-deploy \
--policy-name adr-sml-deploy-minimal
{
"UserName": "adr-sml-deploy",
"PolicyName": "adr-sml-deploy-minimal",
"PolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ListSiteBucket",
"Effect": "Allow",
"Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::adr-smlcompany-site"
},
{
"Sid": "WriteSiteObjects",
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:DeleteObject"
],
"Resource": "arn:aws:s3:::adr-smlcompany-site/*"
},
{
"Sid": "InvalidateOneDistribution",
"Effect": "Allow",
"Action": "cloudfront:CreateInvalidation",
"Resource": "arn:aws:cloudfront::327082975128:distribution/E1OK7G98KNKUTA"
}
]
}
}
```
Four actions, one bucket, one distribution. **Never widen it**`AGENTS.md` §10
records why
in terms: this is the control standing between a shared Gitea instance and an
AWS account that also holds `mlp-clientdb-prod-backups-327082975128`. Treat any
request to widen it as a security decision, not a convenience one.
## 4. The access key — issued, never used
```console
$ aws iam list-access-keys --user-name adr-sml-deploy
{
"AccessKeyMetadata": [
{
"UserName": "adr-sml-deploy",
"AccessKeyId": "AKIA…REDACTED",
"Status": "Active",
"CreateDate": "2026-08-26T15:45:19+00:00"
}
]
}
$ aws iam get-access-key-last-used --access-key-id AKIA…REDACTED
{
"UserName": "adr-sml-deploy",
"AccessKeyLastUsed": {
"ServiceName": "N/A",
"Region": "N/A"
}
}
```
One key, `Active`, created **2026-08-26T15:45:19+00:00**.
⚠️ **A correction to `AGENTS.md` §7's wording, found by re-running the call.**
That row said
*"one active access key, `LastUsed` null"*. The API does not return null — it
returns `AccessKeyLastUsed` with **`ServiceName: "N/A"` and `Region: "N/A"`**,
and there is no `LastUsedDate` key at all. Same conclusion (the key has never
authenticated a request), different field shape, and a reader looking for a
literal `null` would not find one.
**Rotation is due 2026-11-26** — key created 2026-08-26, D3 commits to
quarterly. `AGENTS.md` §12 R17 carries the date; `docs/06-deployment.md` §Key rotation
carries the procedure. Create the second key, update the Gitea secrets, verify a
deploy, **then** delete the first.
## 5. `simulate-principal-policy` — nine checks, verified by execution
The point of this section is that it tests the **negative** half. A policy that
grants four actions is only a control if it can be shown not to grant the rest.
```bash
PRINCIPAL=arn:aws:iam::327082975128:user/adr-sml-deploy
sim() { aws iam simulate-principal-policy \
--policy-source-arn "$PRINCIPAL" --action-names "$1" --resource-arns "$2" ; }
```
| # | Action | Resource | `EvalDecision` |
|---|---|---|---|
| 1 | `s3:PutObject` | `arn:aws:s3:::adr-smlcompany-site/index.html` | **allowed** |
| 2 | `s3:DeleteObject` | `arn:aws:s3:::adr-smlcompany-site/old.html` | **allowed** |
| 3 | `s3:ListBucket` | `arn:aws:s3:::adr-smlcompany-site` | **allowed** |
| 4 | `cloudfront:CreateInvalidation` | `arn:aws:cloudfront::327082975128:distribution/E1OK7G98KNKUTA` | **allowed** |
| 5 | `s3:ListBucket` | `arn:aws:s3:::mlp-clientdb-prod-backups-327082975128` | **implicitDeny** |
| 6 | `s3:GetObject` | `arn:aws:s3:::mlp-clientdb-prod-backups-327082975128/anything` | **implicitDeny** |
| 7 | `s3:DeleteBucket` | `arn:aws:s3:::adr-smlcompany-site` | **implicitDeny** |
| 8 | `s3:PutObject` | `arn:aws:s3:::meshkinilaw.ca/anything` | **implicitDeny** |
| 9 | `iam:CreateUser` | `*` | **implicitDeny** |
Four `allowed`, five `implicitDeny`. `implicitDeny` rather than `explicitDeny`
is the correct and expected shape: the policy contains no `Deny` statement, so
everything outside its three `Allow` statements falls through to IAM's
default-deny. An `explicitDeny` here would mean a *different* policy was also in
play.
Raw output for each check, including the full `MatchedStatements` and
`MissingContextValues`, follows in **§7 of this file**. *(Bare `§n` here means a
section of this document; references to the working file are written
`AGENTS.md` §n.)*
## 6. The resource side — `NoSuchBucketPolicy`, and why the contrast call matters
IAM simulation covers identity-based policy. It does **not** cover a
resource-based grant on the backup bucket, which would be invisible from the
principal's side. So:
```console
$ aws s3api get-bucket-policy --bucket mlp-clientdb-prod-backups-327082975128
# exit status: 254
# stdout: 0 bytes
# stderr:
# aws: [ERROR]: An error occurred (NoSuchBucketPolicy) when calling the GetBucketPolicy operation: The bucket policy does not exist
```
**An error is the result here, and that is only legible because stderr was not
suppressed.** `CLAUDE.md`'s convention, from Pouya's own 2026-08-28 correction:
`2>/dev/null` converts *"it failed"* into *"it found nothing"*, and those are
opposite results. The exit status is **254** and stdout is **empty** — read the
status, not just stdout.
**And an empty result needs a working instrument.** The same command against the
site bucket, to prove the call itself resolves a policy when one exists:
```console
$ aws s3api get-bucket-policy --bucket adr-smlcompany-site
{
"Policy": "{\"Version\":\"2008-10-17\",\"Id\":\"PolicyForCloudFrontPrivateContent\",\"Statement\":[{\"Sid\":\"AllowCloudFrontServicePrincipal\",\"Effect\":\"Allow\",\"Principal\":{\"Service\":\"cloudfront.amazonaws.com\"},\"Action\":\"s3:GetObject\",\"Resource\":\"arn:aws:s3:::adr-smlcompany-site/*\",\"Condition\":{\"StringEquals\":{\"AWS:SourceArn\":\"arn:aws:cloudfront::327082975128:distribution/E1OK7G98KNKUTA\"}}}]}"
}
```
Exit **0**, a real policy returned — the CloudFront OAC grant, scoped to
distribution `E1OK7G98KNKUTA`. So `NoSuchBucketPolicy` on the backup bucket is a
**genuine absence**, not a command that failed to run. That contrast is the
whole reason this call is in the file: without it, an empty result from a broken
command looks exactly like an empty result from a bucket with no policy.
*(This contrast call was **not** part of the original Q22 verification. It was
added on re-run, and it closes the gap that made the original evidence weaker
than it read.)*
## 7. Raw `simulate-principal-policy` responses
### Check 1
```json
{
"EvaluationResults": [
{
"EvalActionName": "s3:PutObject",
"EvalResourceName": "arn:aws:s3:::adr-smlcompany-site/index.html",
"EvalDecision": "allowed",
"MatchedStatements": [
{
"SourcePolicyId": "user_adr-sml-deploy_adr-sml-deploy-minimal",
"SourcePolicyType": "IAM Policy",
"StartPosition": {
"Line": 6,
"Column": 55
},
"EndPosition": {
"Line": 9,
"Column": 57
}
}
],
"MissingContextValues": [],
"EvalDecisionDetails": {},
"ResourceSpecificResults": [
{
"EvalResourceName": "arn:aws:s3:::adr-smlcompany-site/index.html",
"EvalResourceDecision": "allowed",
"MatchedStatements": [
{
"SourcePolicyId": "user_adr-sml-deploy_adr-sml-deploy-minimal",
"SourcePolicyType": "IAM Policy",
"StartPosition": {
"Line": 6,
"Column": 55
},
"EndPosition": {
"Line": 9,
"Column": 57
}
}
]
}
]
}
]
}
```
### Check 2
```json
{
"EvaluationResults": [
{
"EvalActionName": "s3:DeleteObject",
"EvalResourceName": "arn:aws:s3:::adr-smlcompany-site/old.html",
"EvalDecision": "allowed",
"MatchedStatements": [
{
"SourcePolicyId": "user_adr-sml-deploy_adr-sml-deploy-minimal",
"SourcePolicyType": "IAM Policy",
"StartPosition": {
"Line": 6,
"Column": 55
},
"EndPosition": {
"Line": 9,
"Column": 57
}
}
],
"MissingContextValues": [],
"EvalDecisionDetails": {},
"ResourceSpecificResults": [
{
"EvalResourceName": "arn:aws:s3:::adr-smlcompany-site/old.html",
"EvalResourceDecision": "allowed",
"MatchedStatements": [
{
"SourcePolicyId": "user_adr-sml-deploy_adr-sml-deploy-minimal",
"SourcePolicyType": "IAM Policy",
"StartPosition": {
"Line": 6,
"Column": 55
},
"EndPosition": {
"Line": 9,
"Column": 57
}
}
]
}
]
}
]
}
```
### Check 3
```json
{
"EvaluationResults": [
{
"EvalActionName": "s3:ListBucket",
"EvalResourceName": "arn:aws:s3:::adr-smlcompany-site",
"EvalDecision": "allowed",
"MatchedStatements": [
{
"SourcePolicyId": "user_adr-sml-deploy_adr-sml-deploy-minimal",
"SourcePolicyType": "IAM Policy",
"StartPosition": {
"Line": 3,
"Column": 17
},
"EndPosition": {
"Line": 6,
"Column": 55
}
}
],
"MissingContextValues": [],
"EvalDecisionDetails": {},
"ResourceSpecificResults": [
{
"EvalResourceName": "arn:aws:s3:::adr-smlcompany-site",
"EvalResourceDecision": "allowed",
"MatchedStatements": [
{
"SourcePolicyId": "user_adr-sml-deploy_adr-sml-deploy-minimal",
"SourcePolicyType": "IAM Policy",
"StartPosition": {
"Line": 3,
"Column": 17
},
"EndPosition": {
"Line": 6,
"Column": 55
}
}
]
}
]
}
]
}
```
### Check 4
```json
{
"EvaluationResults": [
{
"EvalActionName": "cloudfront:CreateInvalidation",
"EvalResourceName": "arn:aws:cloudfront::327082975128:distribution/E1OK7G98KNKUTA",
"EvalDecision": "allowed",
"MatchedStatements": [
{
"SourcePolicyId": "user_adr-sml-deploy_adr-sml-deploy-minimal",
"SourcePolicyType": "IAM Policy",
"StartPosition": {
"Line": 9,
"Column": 57
},
"EndPosition": {
"Line": 12,
"Column": 83
}
}
],
"MissingContextValues": [],
"EvalDecisionDetails": {},
"ResourceSpecificResults": [
{
"EvalResourceName": "arn:aws:cloudfront::327082975128:distribution/E1OK7G98KNKUTA",
"EvalResourceDecision": "allowed",
"MatchedStatements": [
{
"SourcePolicyId": "user_adr-sml-deploy_adr-sml-deploy-minimal",
"SourcePolicyType": "IAM Policy",
"StartPosition": {
"Line": 9,
"Column": 57
},
"EndPosition": {
"Line": 12,
"Column": 83
}
}
]
}
]
}
]
}
```
### Check 5
```json
{
"EvaluationResults": [
{
"EvalActionName": "s3:ListBucket",
"EvalResourceName": "arn:aws:s3:::mlp-clientdb-prod-backups-327082975128",
"EvalDecision": "implicitDeny",
"MatchedStatements": [],
"MissingContextValues": [],
"EvalDecisionDetails": {},
"ResourceSpecificResults": [
{
"EvalResourceName": "arn:aws:s3:::mlp-clientdb-prod-backups-327082975128",
"EvalResourceDecision": "implicitDeny"
}
]
}
]
}
```
### Check 6
```json
{
"EvaluationResults": [
{
"EvalActionName": "s3:GetObject",
"EvalResourceName": "arn:aws:s3:::mlp-clientdb-prod-backups-327082975128/anything",
"EvalDecision": "implicitDeny",
"MatchedStatements": [],
"MissingContextValues": [],
"EvalDecisionDetails": {},
"ResourceSpecificResults": [
{
"EvalResourceName": "arn:aws:s3:::mlp-clientdb-prod-backups-327082975128/anything",
"EvalResourceDecision": "implicitDeny"
}
]
}
]
}
```
### Check 7
```json
{
"EvaluationResults": [
{
"EvalActionName": "s3:DeleteBucket",
"EvalResourceName": "arn:aws:s3:::adr-smlcompany-site",
"EvalDecision": "implicitDeny",
"MatchedStatements": [],
"MissingContextValues": [],
"EvalDecisionDetails": {},
"ResourceSpecificResults": [
{
"EvalResourceName": "arn:aws:s3:::adr-smlcompany-site",
"EvalResourceDecision": "implicitDeny"
}
]
}
]
}
```
### Check 8
```json
{
"EvaluationResults": [
{
"EvalActionName": "s3:PutObject",
"EvalResourceName": "arn:aws:s3:::meshkinilaw.ca/anything",
"EvalDecision": "implicitDeny",
"MatchedStatements": [],
"MissingContextValues": [],
"EvalDecisionDetails": {},
"ResourceSpecificResults": [
{
"EvalResourceName": "arn:aws:s3:::meshkinilaw.ca/anything",
"EvalResourceDecision": "implicitDeny"
}
]
}
]
}
```
### Check 9
```json
{
"EvaluationResults": [
{
"EvalActionName": "iam:CreateUser",
"EvalResourceName": "*",
"EvalDecision": "implicitDeny",
"MatchedStatements": [],
"MissingContextValues": []
}
]
}
```
---
## What this does and does not establish
**Establishes.** The user exists with the creation date `AGENTS.md` §7 records; it holds one
inline policy and nothing else; the policy grants four actions on one bucket and
one distribution; the four intended actions are `allowed`; five representative
out-of-scope actions — including two against the client-database backup bucket —
are denied; the backup bucket carries no resource-based policy that could grant
around IAM; and one key exists that has never authenticated a request.
**Does not establish.** That the key works (it has never been used, and testing
it would mean putting a real object in the bucket). That Gitea holds it —
`AGENTS.md` §7 records **`GITEA ACTIONS SECRETS: UNSET`**, and Q23 is open on whether a runner
exists at all. That the policy is sufficient for a deploy in practice: the
`s3:AbortMultipartUpload` omission is covered by asset sizes rather than by a
lifecycle rule, and `docs/06-deployment.md` records that with a revisit trigger.
**Not in scope of this file, and deliberately so.** The secret access key. It
must never reach the repository — D3, and `AGENTS.md` §10 on the jointly administered Gitea
instance, where an instance administrator can generally reach repository secrets
or register a runner that receives them.
+5 -4
View File
@@ -62,10 +62,11 @@ const aboutLinks = [
{
/* The designation strip carries the credentialing STAGE, not just the
held designation, and that is a §4 Offerings condition rather than a
flourish. The masthead says "Mediation · Arbitration · Toronto" on
every page; §4 permits the arbitration half on the condition that the
site "makes the first while stating the second plainly", and
"neither half may be dropped". Before this line rendered
flourish. The masthead names arbitration on every page except `/`,
where SiteHeader suppresses the tagline by design. §4 permits the
arbitration half on the condition that the site "makes the first while
stating the second plainly", and "neither half may be dropped".
Before this line rendered
CREDENTIALS.inProgress, that condition was unmet on every page that
ships — the constant existed in site.ts and was rendered nowhere.
Q.Arb reads as commenced, never as held (§4). */
+91 -24
View File
@@ -16,15 +16,28 @@
* 1. `LegalService` — NEVER. docs/04: schema.org defines it as a business
* providing legal advice and *representation*, which asserts in
* machine-readable form exactly what D13 bars. `ProfessionalService`.
* 2. `worksFor` — omitted. Populating it either names the boutique (D16) or
* misstates the employer. `jobTitle` carries the role on its own.
* 2. `worksFor` — **OMITTED, and Q49(b) declined it deliberately on
* 2026-08-28.** Two grounds, either sufficient. §4 rows "Operator of SML
* Company Ltd **alongside** the practice"; "the entity the practice
* **operates through**" is a different structural relation with no row.
* And `ProfessionalService.provider` is this Person, so `provider →
* Person → worksFor → SML` asserts **transitively** a same-entity claim
* that `src/pages/about.astro` deliberately removed from visible prose as
* *"a corporate-structure claim"* — scoping the value to a bare name does
* not reach that. See `PRACTICE_JOB_TITLE` in `site.ts`.
* 3. `priceRange` — omitted until `/fees/` exists (build step 9). docs/04
* gates it on that page being real.
*
* AND Q.Arb IS NOT IN `hasCredential`. It commenced August 2026 and is not
* held. Q.Med is. That asymmetry is the whole point of the property.
*/
import { CONTACT, CREDENTIALS, ROLE, SITE } from './site';
import {
CONTACT,
CREDENTIALS,
MEMBERSHIP_ORGS,
PRACTICE_JOB_TITLE,
SITE,
} from './site';
/** Stable node ids, so pages cross-reference rather than duplicate. */
export const PERSON_ID = `${SITE.url}/about/#person`;
@@ -57,13 +70,20 @@ export const SERVICE_ID = `${SITE.url}/#practice`;
* implication as hard as assertion, and a crawler summary is a place where an
* implication travels unedited.
*/
export function personNode(imageUrl?: string) {
export function personNode(
imageUrl?: string,
opts: { memberships?: boolean } = {},
) {
return {
'@type': 'Person',
'@id': PERSON_ID,
name: SITE.name,
url: `${SITE.url}/about/`,
jobTitle: ROLE.title,
/* PRACTICE_JOB_TITLE, not ROLE.title (Q47), and §4 now rows the value:
"Practised role — Mediator" [verified 2026-08-28 — Pouya, Q49]. Do not
widen it to include arbitration — see the constant in site.ts. No
`worksFor` beside it: Q49(b) declined the row. */
jobTitle: PRACTICE_JOB_TITLE,
description:
'Mediator in Toronto, accepting commercial arbitration appointments. ' +
'Q.Med designation through ADRIC and ADRIO; the Q.Arb pathway commenced ' +
@@ -83,6 +103,36 @@ export function personNode(imageUrl?: string) {
},
sameAs: [CONTACT.linkedin],
email: `mailto:${CONTACT.email}`,
/* `memberOf` — OPT-IN, AND ONLY `/about/` OPTS IN. Q53, ruled by Pouya
2026-08-28: *"the memberships are already crawlable in /about/'s HTML, so
withholding the triple reduces no exposure and only makes the graph less
complete than the page."* **The reason he gave is page-specific**, so the
field is too: /about/ shows the list, `/` does not.
⚠️ DO NOT DELETE THE `opts` PARAMETER AS REDUNDANT. It looks redundant —
both pages serve the same `@id`, so a consumer that fetches both merges
them and gets `memberOf` either way. It was deleted on exactly that
reasoning and had to be put back: the argument is about what a *consumer*
can derive, and the scoping is about what a *page* asserts on its own.
Six records in this repository state the `/about/` scoping; the deletion
made all six false at once, silently.
THE NAMES COME FROM `MEMBERSHIP_ORGS`, NOT FROM THE DISPLAY LIST, and the
two differ on three of four lines — see that constant in site.ts, which
carries the reason and the D13 exclusions that govern both. Only their
LENGTH is asserted at compile time. **Content parity is manual.**
R10 fires on an event, not a date: re-confirm before any cutover or major
republish, and re-stamp §4. That covers this field as well as the visible
list. */
...(opts.memberships
? {
memberOf: MEMBERSHIP_ORGS.map((name) => ({
'@type': 'Organization',
name,
})),
}
: {}),
...(imageUrl ? { image: imageUrl } : {}),
};
}
@@ -90,6 +140,36 @@ export function personNode(imageUrl?: string) {
/**
* `ProfessionalService` for the home page, with the Person as `provider`.
*
* THE MASTHEAD IS TWO FIELDS HERE, NOT ONE STRING — Q50, ruled by Pouya
* 2026-08-28: *"`ProfessionalService.name` takes the ratified masthead string.
* Q33 reaches it; one claim should not have two forms."*
*
* The masthead is not one string, and schema.org has a field for each half, so
* `name` + `slogan` is the mapping rather than a concatenation. Both read the
* constants, which is what kills the variant.
*
* ⚠️ AND ON `/` — THE ONLY PAGE THIS NODE SHIPS ON — THE MASTHEAD DOES NOT
* RENDER THE TAGLINE AT ALL. `SiteHeader.astro` gates it on `!isHome`,
* deliberately, so the header does not repeat the hero. `SITE.tagline` is
* visible on `/` as the **hero eyebrow** instead. That is the page-visible
* counterpart `slogan` mirrors; do not justify this mapping by the masthead.
*
* ⚠️ DO NOT PUT THE TAGLINE BACK INTO `name`. Two independent reasons.
* (1) On a `LocalBusiness`-family type `name` means the business's name; a name
* plus a service list plus a city is the name-stuffing pattern search engines
* discard a rich result for, and `areaServed` already carries Toronto and
* Ontario. (2) It put an **unscoped "Arbitration"** into the node's most
* prominent field — Q39's struck universal reappearing in machine-readable
* form.
*
* **Reason (2) is mitigated, not discharged**, and that is stated rather than
* glossed: the word is still in `slogan`. What makes it acceptable there is
* that the identical unscoped string already ships in `<title>`, `og:title`,
* `twitter:title` and the hero eyebrow, all ratified under Q33 — so excluding
* it from one name-like field alone would be incoherent. `serviceType` stays
* scoped because it **enumerates services**; a slogan and a title are names.
* §9 Q50 records this as a deviation awaiting Pouya's line.
*
* `serviceType` lists what §4 Offerings actually records as offered now —
* mediation, arbitration, med-arb. **Arbitration is scoped to commercial**
* (Q39, 2026-08-27): family arbitration in Ontario carries prescribed training
@@ -105,7 +185,8 @@ export function professionalServiceNode(imageUrl?: string) {
return {
'@type': 'ProfessionalService',
'@id': SERVICE_ID,
name: `${SITE.name} — Mediation & Arbitration`,
name: SITE.name,
slogan: SITE.tagline,
url: `${SITE.url}/`,
description:
'Commercial mediation and arbitration for construction, technology, ' +
@@ -159,27 +240,13 @@ export function homeGraph(imageUrl?: string) {
* no visible breadcrumb, and the header nav marks it as current — so
* emitting one would assert a navigation structure the page does not show.
* Breadcrumbs begin at the two-level pages: `/practice/<area>/`, `/insights/<slug>/`.
* 3. `memberOf` for the four memberships. Declined on R10 / **Q44** — and
* the visible page reached the same answer one round later, which is worth
* recording: `/about/` now publishes **no memberships group at all**,
* because R10 is a prohibition on shipping such a page and the
* re-confirmation was not obtained. So this field is not a stricter
* standard than the page; it is the same one.
*
* Two earlier versions of this comment were wrong on the facts. They said
* "the page publishes them visibly" (it does not, as of 2026-08-28) and
* "all four renew yearly" — §4 records yearly renewal for **the OBA
* sections and the CTF only** and says nothing about ADRIC or ADRIO. The
* widened form had propagated to four files.
*
* The reason a machine-readable membership claim is worse than a visible
* one stands regardless: a list on a page is corrected by editing the page,
* while a scraped claim is cached and re-served by systems that never
* re-read it. OCNI lapsed quietly once already. Add this when Q44 closes.
* 3. `memberOf` — **EMITTED HERE, and only here.** Q53, 2026-08-28. It is
* opted into by this function and by no other; `personNode` carries the
* constraint and the reason.
*/
export function aboutGraph(imageUrl?: string) {
return {
'@context': 'https://schema.org',
'@graph': [personNode(imageUrl)],
'@graph': [personNode(imageUrl, { memberships: true })],
};
}
+137 -13
View File
@@ -49,19 +49,42 @@ export const SITE = {
export const CREDENTIALS = {
designations: ['Q.Med (ADRIC / ADRIO)'],
inProgress: ['Q.Arb — commenced August 2026'], // [verified 2026-08-26]
goal: 'C.Med-Arb (Chartered Mediator-Arbitrator)',
/**
* "Chartered Med-Arbitrator" — ADRIO's own term
* (docs/reference/adrio-designations.md). This read "Chartered
* Mediator-Arbitrator" until 2026-08-28, which was wrong; Pouya caught it and
* it was his own error, carried from the strategy brief and never sourced.
*
* UNCONSUMED AS OF 2026-08-28 — nothing imports `CREDENTIALS.goal`. `/about/`'s
* credential arc hand-types all three designations instead, which is the drift
* shape this repo keeps paying for (see ContactBand's 52ch/46ch divergence).
* It is corrected rather than deleted because `/med-arb/` at build step 4 is
* its natural consumer: either that page uses it, or this line comes out.
*/
goal: 'C.Med-Arb (Chartered Med-Arbitrator)',
education: ['JD, Bond University'],
certifications: [
'Kompass Arbitration Certificate Program',
'Stitt Feld Handy negotiation and ADR workshop series',
/* "sequence", NOT "series" — §4: "Stitt Feld Handy negotiation and ADR
workshop **sequence** — completed". This list said "series" while the bio
prose on the same page said "sequence": one certification, two names, one
page. Found by `claims-auditor` 2026-08-28. Same shape as the C.Med-Arb
error — a third-party programme name that four review passes read without
checking it was right. */
'Stitt Feld Handy — negotiation and ADR workshop sequence',
],
languages: ['English', 'Farsi'],
/**
* [verified 2026-08-26 — Pouya, AGENTS.md Q28 and the CTF addition of the same
* [verified 2026-08-28 — Pouya, AGENTS.md Q44] — re-stamped when Q44 closed;
* the original confirmation was 2026-08-26 (Q28 plus the CTF addition of the same
* date] — and FOR NOW.
*
* WHAT §4 ACTUALLY SAYS ABOUT RENEWAL, because a widened version of it reached
* a public page. §4: *"Both the OBA sections and the CTF renew yearly."* It
* a public page. §4, quoted exactly: *"the OBA sections and the CTF renew
* yearly"* — NOT "Both the OBA sections…", which is how this comment quoted it
* until 2026-08-28. The substance was right and the quotation marks were not,
* in the comment written to stop a widened paraphrase of this exact sentence.
* Found by `claims-auditor`. It
* says **nothing** about ADRIC's or ADRIO's renewal period. An earlier form of
* this comment read "Both the OBA sections and the Canadian Tax Foundation
* renew yearly, so every line below is a fact with a shelf life", which is two
@@ -70,12 +93,21 @@ export const CREDENTIALS = {
* `/about/`, and into §9 Q44. Exactly the SES-DKIM duplication shape: the copy
* that goes stale is the one nobody re-reads, and this copy became public copy.
*
* **NOT PUBLISHED AS OF 2026-08-28 — R10 / Q44.** R10 requires a
* re-confirmation *"before any page listing memberships ships"*, `/about/` is
* that page, and the re-confirmation is a fact only Pouya holds. It was not
* obtained, so `/about/` ships its Credentials section WITHOUT a memberships
* group and carries a `TODO(pouya)`. Do not render this array on a public page
* until Q44 closes.
* **PUBLISHED FROM 2026-08-28 — Q44 CLOSED.** Pouya re-confirmed all four as
* current, which discharges R10's prohibition, and `/about/` now renders a
* Memberships group from this array. Re-stamped `[verified 2026-08-28 —
* Pouya]`; the earlier stamp was 2026-08-26.
*
* ⚠️ **RENDER THE LIST; NEVER RENDER A CLAIM ABOUT ITS CURRENCY.** No
* "renewed annually", no "current as of", no "listed as current", no stamp
* date in the markup. Pouya's ruling: *"List the memberships; promise nothing
* about their future state. The list is a snapshot, and only §4's stamp says
* when it was taken."* He declined renewal-date tracking, so there is no date
* behind such a sentence and nothing in this repo could support one.
*
* R10 stays live and now fires on an **event** rather than a date: re-confirm
* before any cutover or major republish. OCNI is why — §4 carries it as lapsed
* and unpublishable, and that was found roughly a year late.
*
* NOT OCNI (lapsed — §4: "not current, do not publish") and NOT the Law
* Society: listing the LSO implies licensure, which D13 bars. Do not add
@@ -95,6 +127,38 @@ export const CREDENTIALS = {
*/
export const BOUTIQUE = 'a Toronto litigation and ADR boutique' as const;
/**
* The GRAPH form of the memberships — `Person.memberOf` in `src/data/schema.ts`.
*
* ⚠️ SEPARATE FROM `CREDENTIALS.memberships` ON PURPOSE, AND THEY DIFFER ON
* THREE OF FOUR LINES: the display list carries the acronyms (`ADR Institute of
* Canada (ADRIC)`) and the OBA's three sections; this list names bare
* organisations. Only `Canadian Tax Foundation` is identical.
*
* **Why bare names:** `memberOf` points at an *organisation*, and nothing is
* named "Ontario Bar Association — Construction & Infrastructure, ADR, and
* Civil Litigation sections". A triple naming that cannot reconcile against the
* real entity gives up most of what the field buys. This is a **narrowing** of
* §4's row — §4 names the OBA as the body and then qualifies the sections — and
* not an inference beyond it. Do not read it the other way and "restore" the
* qualifiers into a name.
*
* ⚠️ THE SAME TWO EXCLUSIONS GOVERN THIS ARRAY, repeated here because this is
* where an addition would land: **NOT OCNI** (§4: not current, do not publish)
* and **NOT the Law Society**. Q51 is the distinction — the Law Society is the
* **regulator**, so membership is licensure, which D13 bars; the OBA is a
* **voluntary association**, which admits members it does not license.
*
* BOTH ARRAYS ARE THE SAME §4 ROW SEEN TWICE, so their lengths are asserted at
* compile time — see `_MembershipParity` below. **Their contents are not.**
*/
export const MEMBERSHIP_ORGS = [
'ADR Institute of Canada',
'ADR Institute of Ontario',
'Ontario Bar Association',
'Canadian Tax Foundation',
] as const;
/**
* The boutique role and the litigation line — the two highest-risk strings on
* the site, so they live here rather than being typed into a page.
@@ -105,9 +169,16 @@ export const BOUTIQUE = 'a Toronto litigation and ADR boutique' as const;
* these are the two where the wording IS the compliance.
*/
export const ROLE = {
/** §4 verbatim. docs/04: this is `jobTitle` in the Person JSON-LD, and
* `worksFor` is OMITTED — populating it either names the boutique (D16) or
* misstates the employer. */
/**
* §4 verbatim, and it is the VISIBLE role only. Rendered as
* "I am {ROLE.title} at {ROLE.at}", always paired with BOUTIQUE (D16).
*
* NEVER the JSON-LD `jobTitle` — that takes PRACTICE_JOB_TITLE below (Q47).
* §4's row is one fact with two halves and visible copy always pairs them;
* a graph field carrying only "Director of Firm Operations", on a node whose
* `url` is this practice's `/about/`, lets a consumer attach the boutique
* title to this entity.
*/
title: 'Director of Firm Operations', // [verified 2026-08-25 — strategy brief §I]
/** Always rendered with BOUTIQUE, never with a firm name (D16). */
at: BOUTIQUE,
@@ -133,6 +204,40 @@ export const ROLE = {
],
} as const;
/**
* The Person node's `jobTitle`. §4 Verified: **Practised role — "Mediator"**
* `[verified 2026-08-28 — Pouya, Q49]`, supported by the Q.Med row and by
* "Has completed multiple sole mediations".
*
* NOT `ROLE.title`, and the separation is Q47's ruling: this field describes
* *this practice*, the boutique role stays in visible copy, and D16 keeps the
* boutique unnamed either way.
*
* ⚠️ DO NOT WIDEN IT TO INCLUDE ARBITRATION. "Arbitrator" as a practised role
* has **no §4 row** — the register verifies completed sole mediations, and for
* arbitration only that appointments are *accepted*. `jobTitle` is the most
* role-asserting field in the vocabulary and consumers render it beside `name`,
* so "Mediator and Commercial Arbitrator" there invites the reader to supply a
* track record for both halves. The arbitration **offering** is carried by
* `description` and `serviceType`, which is where an offering belongs.
*/
export const PRACTICE_JOB_TITLE = 'Mediator' as const;
/* NO `PRACTICE_ENTITY`, AND NO `Person.worksFor` — Q49(b), declined 2026-08-28.
*
* §4 rows "Operator of SML Company Ltd **alongside** the practice". "The entity
* the practice **operates through**" is a different structural relation and has
* no row. Two further reasons it must not come back on a tidy-up:
*
* - `ProfessionalService.provider` IS this Person, so
* `provider → Person → worksFor → SML` asserts **transitively** that the
* practice and the company are the same entity — the claim `about.astro`
* deliberately removed from visible prose as "a corporate-structure claim".
* Scoping the value to a bare name does not reach this.
* - `SITE.entity` already holds the string for the footer. A second constant
* for the same name is the drift this file keeps paying for.
*/
/**
* THE Q41(a) SENTENCE. It lives here for the reason `ROLE` above lives here:
* *"these are the two where the wording IS the compliance."*
@@ -453,6 +558,25 @@ type _SlugsWithoutAnArea = Exclude<
>;
export type _SlugCoverage = _AssertNever<_SlugsWithoutAnArea>;
/**
* The two membership arrays must stay the same LENGTH — contents are not
* checked and cannot be. They are two views of ONE §4 row, and the failure mode
* is adding a membership to the page and not to the graph, which is otherwise
* silent.
*
* ⚠️ IT FAILS `npm run check`, NOT `npm run build` — measured. Both the deploy
* workflow and `scripts/deploy-local.sh` run `check` first, so the deploy path
* is covered; a bare `astro build` is not. And it depends on both arrays keeping
* `as const`: without it `length` widens to `number`, `number extends number` is
* true, and this assertion passes forever while checking nothing.
*/
type _AssertTrue<T extends true> = T;
export type _MembershipParity = _AssertTrue<
(typeof CREDENTIALS.memberships)['length'] extends (typeof MEMBERSHIP_ORGS)['length']
? true
: false
>;
/**
* The five process steps. **HERE, NOT IN THE PAGE**, for the reason written
* against PRACTICE_AREAS above and applied by `adversarial-reviewer` 2026-08-27:
+152 -69
View File
@@ -20,12 +20,22 @@
* section entirely until there is something in it. An empty 'Speaking' heading
* is worse than no heading." Nothing to list.
*
* ITEM 7'S PDF IS NOT SHIPPED, and the omission is stated rather than silent
* AGENTS.md Q45. No such file exists, and a link to a missing file on the page
* an appointing body reads is worse than its absence. It is also not a
* formatting job: a one-page bio is a credential document circulated DETACHED
* from the site, where no build and no reviewer ever re-checks it. Two
* decisions there are Pouya's.
* ITEM 7'S PDF IS NOT SHIPPED, and the omission is stated rather than silent.
* **Q45 CLOSED 2026-08-28 — deferred by Pouya to build step 9, alongside
* `/fees/`, and tracked as AGENTS.md §12 R16.** His reasoning: it is a derived
* artefact, so building it before this page and the fee card are final means
* building it twice. No such file exists yet, and a link to a missing file on
* the page an appointing body reads is worse than its absence.
*
* It is also not a formatting job: a one-page bio is a credential document
* circulated DETACHED from the site, where no build and no reviewer ever
* re-checks it. Two decisions travel with R16 and are NOT settled by the
* deferral — generated-at-build vs authored once, and whether it carries
* anything the site does not.
*
* This paragraph also comes out at step 9 (R16), which now lists this file.
* *(It pointed at Q45 after Q45 closed; `adversarial-reviewer` found that
* `grep -rn R16 src` returned nothing at all.)*
*
* THE PARENT/CHILD SCOPE TRAP, because this page uses <SectionHeading> four
* times. A parent CANNOT style a child component's root element — the rule
@@ -35,15 +45,25 @@
* components have had their `class` props deleted so passing one is a build
* error rather than a silent no-op.
*
* R10 / Q44 — THE MEMBERSHIPS GROUP IS NOT ON THIS PAGE. R10 is written as a
* prohibition — re-confirm *before* any page listing memberships ships — and
* `/about/` is the page it names. The re-confirmation is a fact only Pouya holds
* and was not obtained, so the group is withheld and a `TODO(pouya)` sits on
* CREDENTIAL_GROUPS below with the exact question. §4 is NOT re-stamped:
* nothing was re-checked. Q44.
* R10 / Q44 — THE MEMBERSHIPS GROUP SHIPS, AND IT CARRIES NO CURRENCY
* WARRANTY. Q44 closed 2026-08-28: Pouya re-confirmed all four as current, so
* R10's prohibition is discharged and the group renders. Two conditions came
* with that ruling and both are load-bearing on this page:
*
* A first version of this page published all four and disclosed the gap instead.
* Both review agents rejected that; the reasoning is on CREDENTIAL_GROUPS.
* 1. **Nothing here promises the memberships stay current.** The struck
* sentence ("Memberships are renewed annually and are listed as current")
* stays struck and nothing replaces it. His words: *"List the memberships;
* promise nothing about their future state."* The list is a snapshot, and
* only §4's stamp says when it was taken.
* 2. He declined renewal-date tracking, so **R10 no longer fires on a date —
* it fires on an event**: re-confirm before any cutover or major
* republish. That is why R10 stays live with the group shipped.
*
* The page held all three positions in three days — published-with-a-disclosure
* (rejected by both review agents), withheld-behind-a-TODO (correct while R10
* was undischarged), now published-with-no-warranty. The middle state was not a
* detour; it is what "a build that fails on an unanswered question is a correct
* build" looks like from the inside.
*/
import { Picture, getImage } from 'astro:assets';
import BaseLayout from '../layouts/BaseLayout.astro';
@@ -127,9 +147,20 @@ const designationLine = [
/**
* The credentialing arc — docs/01 item 4, and docs/03: "the credentialing
* pathway from Q.Med through Q.Arb to C.Med-Arb is stated openly as in
* progress. The brief treats that arc as part of the story rather than
* something to obscure."
* pathway from Q.Med through Q.Arb to C.Med-Arb is stated openly, **with Q.Arb
* described as commenced August 2026** and never as 'in progress', which is
* looser than §4 and is barred by docs/06's cutover checklist. The brief treats
* that arc as part of the story rather than something to obscure."
*
* ⚠️ THAT QUOTATION WAS STALE AND THE STALE HALF WAS THE BARRED PHRASE. It
* quoted docs/03's pre-2026-08-28 text, which ended "...stated openly as in
* progress" — so THIS FILE cited docs/03 as REQUIRING the phrase six lines
* above citing it as BARRING the phrase. Found by `adversarial-reviewer`.
*
* **And the Q.Arb-wording sweep missed it because the phrase was line-wrapped**
* as `as in\n * progress`: a grep for "in progress" on one line returns
* nothing. Same defect CLAUDE.md already records for a docs/03 phrase that
* wrapped behind a blockquote marker. Sweep the wrapped form too.
*
* `state` is the load-bearing column. "Commenced August 2026" is §4's exact
* wording and the ONLY permitted wording — docs/03: not "in progress", because
@@ -160,7 +191,12 @@ const designationLine = [
* credential structure, with no row and no source.
* 5. The expansions — "Qualified Mediator", "Qualified Arbitrator",
* "Chartered Mediator-Arbitrator". Flagged as being in §11 Glossary but
* not in §4 Verified.
* not in §4 Verified. **The third was also simply WRONG** — ADRIO's term
* is "Chartered Med-Arbitrator" — but that is not what this finding
* caught, and no review pass caught it either: four passes read the string
* and checked only whether it was *sourced*. Pouya caught it on
* 2026-08-28. The wrong form is quoted here because it is what was
* flagged; it is corrected in the arc below and swept from the repo.
*
* ⚠️ ITEM 5 WAS REMOVED AND IS NOW RESTORED, AND IT IS THE ONE PLACE THIS
* SESSION WENT AGAINST A REVIEW FINDING. The reason is a SECOND finding, from
@@ -170,22 +206,30 @@ const designationLine = [
* Institute of Ontario" — every one of them a §11 Glossary expansion, on exactly
* the ground the designation names were struck. *"One standard or the other."*
*
* The standard chosen is: **§11 Glossary is the source for DEFINITIONAL
* expansions** — what an abbreviation stands for — while §4 Verified remains the
* only source for claims ABOUT POUYA. Expanding `Q.Med` says nothing about him;
* "he holds it" is the claim, and that has a row. The alternative standard would
* have required stripping POA, SABS and the institute names from the prose and
* `recognizedBy` from the JSON-LD, which makes the page materially worse for a
* reader who does not already know the acronyms, in exchange for no reduction in
* risk. **Q46 asks Pouya to ratify that standard** and it is the only thing
* holding it up; if he declines, all four classes come out together.
* ✅ **RATIFIED BY POUYA 2026-08-28 (Q46(b)), AND NO LONGER RESTING ON §11
* ASSERTING ITS OWN CONTENT.** The standard: **§11 Glossary is the source for
* DEFINITIONAL expansions** — what an abbreviation stands for — while §4
* Verified remains the only source for claims ABOUT POUYA. Expanding `Q.Med`
* says nothing about him; "he holds it" is the claim, and that has a row. His
* words: *"the same line the Offerings ruling drew"*, and *"You were right that
* one standard or the other had to apply."*
*
* Sourcing them externally was tried first and failed: `adric.ca/designations/`
* redirects to `/designations-cee/` and its HTML contains **zero** occurrences
* of "Q.Med", "Qualified Mediator" or "Chartered Mediator" in 114,985 bytes —
* navigation only, body assembled client-side. So R14 cannot be met from the
* obvious URL, which is why this rests on §11 and on Q46 rather than on a
* committed extract.
* The alternative standard would have required stripping POA, SABS and the
* institute names from the prose and `recognizedBy` from the JSON-LD — making
* the page materially worse for a reader who does not already know the acronyms,
* in exchange for no reduction in risk.
*
* **R14 IS NOW SATISFIED, which it was not when this comment was first written.**
* Pouya's ruling attached a condition — fetch and commit the source — and
* `docs/reference/adrio-designations.md` is it: all five expansions in ADRIO's
* own words, four independent fetches, reproducible sha256. The earlier attempt
* had failed on the obvious URL (`adric.ca/designations/` redirects to
* `/designations-cee/` and serves **zero** occurrences of "Q.Med", "Qualified
* Mediator" or "Chartered Mediator" in 114,985 bytes — navigation only, body
* assembled client-side), and that failure is why this rested on §11 alone for
* one day. `adr-ontario.ca` serves them server-side. **The lesson is that one
* dead URL is not a sourcing dead end** — the national body's page was
* client-rendered and the provincial affiliate's was not.
*/
const ARC = [
{
@@ -209,8 +253,13 @@ const ARC = [
{
name: 'C.Med-Arb',
state: 'The endpoint',
/* "Chartered Med-Arbitrator", NOT "Chartered Mediator-Arbitrator". The
second form shipped in this string until 2026-08-28 and was in
dist/about/index.html; ADRIO's own term is the first
(docs/reference/adrio-designations.md, Finding 2). Pouya's correction,
and it was his own error carried from the strategy brief. */
body:
'Chartered Mediator-Arbitrator. The designation this practice is built ' +
'Chartered Med-Arbitrator. The designation this practice is built ' +
'toward.',
},
];
@@ -228,43 +277,56 @@ const ARC = [
* NOT PRESENT, AND EACH IS A §4 DIRECTIVE RATHER THAN A GAP:
* - The Law Society. Listing it implies licensure, which D13 bars. §4:
* "Excluded deliberately, not by oversight."
* - OCNI. Not current (§4), so it is not published.
* - OCNI. Not current (§4), so it is not published. **It is the precedent** —
* a membership lapsed quietly and the register now reads "not current, do
* not publish". Nothing told anyone when.
* - Any licence status, in either direction. §4 records it `[unestablished]`.
*
* TODO(pouya): Are ADRIC, ADRIO, the three OBA sections (Construction &
* Infrastructure, ADR, Civil Litigation) and the Canadian Tax Foundation all
* current TODAY, and in which month does each renew? — AGENTS.md Q44.
* ⚠️ MEMBERSHIPS RENDER, AND THE PAGE SAYS NOTHING ABOUT THEIR FUTURE STATE.
* That second clause is the whole ruling, so it is written here beside the
* array rather than in a change log nobody reads at edit time.
*
* ⚠️ MEMBERSHIPS ARE DELIBERATELY NOT RENDERED, AND THIS IS A REVERSAL.
* **Q44 closed 2026-08-28.** Pouya re-confirmed all four as current — ADRIC,
* ADRIO, the three OBA sections, and the Canadian Tax Foundation — which
* discharges R10's prohibition and puts the group back on the page. §4 is
* re-stamped `[verified 2026-08-28 — Pouya]`.
*
* The first version of this page published all four on §4's 2026-08-26 stamp and
* disclosed the outstanding re-confirmation in a note, in this comment, in
* `schema.ts`, in §9 Q44 and on the cutover checklist. Both review agents
* rejected that, and they are right. §12 **R10** is written as a PROHIBITION —
* *"Re-confirm at each renewal, **and before any page listing memberships
* ships** — `/about/` at build step 3 is the first one that will"* — and
* documenting a prohibition is not discharging it. `CLAUDE.md` gives the
* procedure for a fact you do not have, and it is this one: leave
* `TODO(pouya)`, log the question, let the gap be visible. *"A build that fails
* on an unanswered question is a correct build."*
* **DO NOT ADD A CURRENCY SENTENCE.** Not "renewed annually", not "current as
* of", not "listed as current", not a stamp date in the markup. His ruling is
* explicit: *"List the memberships; promise nothing about their future state.
* The list is a snapshot, and only §4's stamp says when it was taken."* The
* struck sentence is quoted in the comment further down this file with the
* three defects it carried; the second of those is now the live one.
*
* The alternative was to ship them and call it disclosed. It was taken once and
* is recorded here as the decision it was, not as an oversight — and it came
* with a second defect on top: the note asserted *"Memberships are renewed
* annually and are listed as current"*, which (a) warranted currency the
* register cannot vouch for and (b) widened §4, which records yearly renewal for
* the **OBA sections and the CTF only** and says nothing about ADRIC or ADRIO.
* **WHY THE ABSENCE OF A WARRANTY IS THE HONEST FORM AND NOT AN EVASION.**
* Pouya declined renewal-date tracking. Without renewal months there is no date
* on which anyone could re-check, so any sentence asserting continued currency
* would be asserting something nothing in this repo can support — which is the
* OCNI shape exactly: §4 carries OCNI as lapsed and unpublishable, and that was
* found roughly a year late. R10 therefore fires on an **event** now (before any
* cutover or major republish), not on a date. That is recorded in §12 R10 with
* this reasoning attached, because a stamp with no trigger behind it goes stale
* silently.
*
* OCNI is the precedent and it is in §4: a membership lapsed, quietly, and the
* register now reads "not current, do not publish". Nothing tells you when.
* "Canadian Tax Foundation" ships WITHOUT a "(CTF)" abbreviation, unlike ADRIC
* and ADRIO. Pouya's ruling wrote "(CTF)" when listing what to confirm, but the
* abbreviation appears nowhere else on this site — ADRIC and ADRIO earn their
* parentheses because "Q.Med (ADRIC / ADRIO)" uses them in the Designations
* group two entries above. An unused abbreviation is noise, so it is omitted;
* one word to reverse if he wants it.
*
* The other three groups ship. Restoring this one is one array entry, the moment
* Q44 closes — and re-stamp §4 and `CREDENTIALS.memberships` that day.
* `memberOf` IS EMITTED FROM THIS PAGE'S JSON-LD (Q53), AND FROM A DIFFERENT
* ARRAY. `src/data/schema.ts` builds it from `MEMBERSHIP_ORGS`, not from the
* `CREDENTIALS.memberships` this group renders: the graph names the bodies, the
* page also names the OBA's three sections. **Only their length is enforced, by
* a compile-time assertion — content parity is manual.** So editing this list
* means editing that one. They are the same §4 row seen twice.
*/
const CREDENTIAL_GROUPS = [
{ title: 'Designations', items: CREDENTIALS.designations },
{ title: 'Education', items: CREDENTIALS.education },
{ title: 'Certifications', items: CREDENTIALS.certifications },
{ title: 'Memberships', items: CREDENTIALS.memberships },
];
---
@@ -523,7 +585,17 @@ const CREDENTIAL_GROUPS = [
practice, the jurisdiction of incorporation and the place of
business — not which work runs through which vehicle. */
}
<p>I run SML Company Ltd alongside both.</p>
{
/* §4 VERBATIM: "Operator of SML Company Ltd. **alongside the
practice**." This read "alongside both", where "both" resolved to the
law track and the engineering track — a concurrency claim §4 does not
make, flagged by `claims-auditor` 2026-08-28. Two neighbouring
additions were deleted from this section for the same reason (see
below), and the wording had propagated from docs/03, now corrected
too. NOT a corporate-structure claim either — see schema.ts on why
`worksFor` is withheld. */
}
<p>I run SML Company Ltd alongside the practice.</p>
<p>
I have also completed the Kompass Arbitration Certificate Program and
the Stitt Feld Handy negotiation and ADR workshop sequence. Neither is
@@ -558,11 +630,19 @@ const CREDENTIAL_GROUPS = [
Both readings are correct and they point in opposite directions,
because both sentences make a claim about CAPACITY. So this one does
not: it states the ROLE and its consequence for the reader, which is
the form `docs/03` actually sanctions on `/for-parties/` (*"the
mediator is not your lawyer"* — role, not capacity) and the only one
that asserts nothing and denies nothing. The underlying question is
R1's. */
not: it states the ROLE and its consequence for the reader, and it is
the only form that asserts nothing and denies nothing. The underlying
question is R1's.
AN EARLIER VERSION OF THIS COMMENT CITED `docs/03`'s
`/for-parties/` directive as the sanctioned example — *"the mediator
is not your lawyer" — role, not capacity*. That was wrong twice:
"not your lawyer" PRESUPPOSES lawyer status, which §4 Forbidden bars
of Pouya and D13 bars by implication; and the half of that sentence
this comment did not quote was "cannot give you legal advice", which
is the denial the comment itself says was struck twelve lines above.
`docs/03` has since been corrected. Do not re-import an example from
a spec without reading the whole sentence it sits in. */
}
<p>
I act as a neutral. I do not act for a party in a matter I take, and
@@ -661,10 +741,13 @@ const CREDENTIAL_GROUPS = [
the OBA sections and the CTF only and says nothing about ADRIC
or ADRIO. The widened form had already propagated to four places.
(b) "listed as current" was an affirmative public WARRANTY of
currency stacked on top of an undischarged R10 — the reminder
whose entire purpose is that no such warranty be made without a
re-confirmation. The memberships group is now off the page
(Q44), so the sentence has nothing left to warrant either.
currency. **THIS IS NOW THE OPERATIVE DEFECT.** Q44 closed and
the group is back on the page, so the sentence has something to
warrant again — and it still must not return. Pouya, 2026-08-28:
*"NO CURRENCY WARRANTY on the page. The sentence you struck
stays struck, and nothing may replace it."* He declined renewal
tracking, which is exactly why the warranty cannot be made:
there is no date behind it. R10 fires on an event instead.
(c) "Nothing above asserts a licence to practise law, in either
direction" READS AS A DENIAL. §4 on licence status: "Do not
assert it, do not deny it, do not infer it from anything else
+1 -1
View File
@@ -85,7 +85,7 @@ const graph = homeGraph(new URL(ldImage.src, Astro.site).href);
---
<BaseLayout
title={`${SITE.name} · Mediation & Arbitration · Toronto`}
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."
imageAlt={PORTRAIT.alt}
jsonLd={graph}