/** * Site-wide constants. * * Anything marked TODO(pouya) is an unanswered question in AGENTS.md §9. * Do not guess a value to make the build pass — an unanswered question is * supposed to be visible. See CLAUDE.md. */ export const SITE = { name: 'Pouya Lajevardi', tagline: 'Mediation · Arbitration · Toronto', url: 'https://adr.smlcompany.ca', locale: 'en_CA', /** * The footer's copyright line, in full. Q30 is CLOSED. * * Two facts were being conflated in the string this replaces * (`'SML Company Ltd. · Ontario, Canada'`), which read as a jurisdiction of * incorporation and named the wrong one: * * - Jurisdiction of incorporation — **federal, under the CBCA** * `[verified 2026-08-26 — Pouya]`, recorded in AGENTS.md §4. * - Place of business — Toronto, Ontario. That is `CONTACT.location`, * and it belongs in the contact block, not in the entity line. * * **Neither appears in the footer.** Pouya's direction, 2026-08-26: the line * is `© SML Company Ltd` and nothing else. The incorporation fact is * verified and available — it is simply not published. Do not "complete" this * line by adding it back. * * No corporation number: we do not have one and the line does not need one. * * Spelling note so it does not read as a typo and get "fixed": AGENTS.md §4 * writes *SML Company Ltd.* with a terminal period. Pouya specified the * rendered footer string twice, both times without it. His wording governs * what ships. */ entity: 'SML Company Ltd', } as const; /** * Verified credentials only — mirrors AGENTS.md §4. * Adding a line here without adding it there is a bug. * * D13: the site asserts the JD and makes NO licensure claim. Do not add * 'lawyer', 'called to the bar', 'licensed', or any post-nominal implying a * licence — and do not imply it either. See AGENTS.md §4 Forbidden. */ export const CREDENTIALS = { designations: ['Q.Med (ADRIC / ADRIO)'], inProgress: ['Q.Arb — commenced August 2026'], // [verified 2026-08-26] /** * "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', /* "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-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, 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 * claims joined by a "so" that does not follow — and the widened form * ("all four renew annually") then propagated into `schema.ts`, into * `/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. * * **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 * either. */ memberships: [ 'ADR Institute of Canada (ADRIC)', 'ADR Institute of Ontario (ADRIO)', 'Ontario Bar Association — Construction & Infrastructure, ADR, and Civil Litigation sections', 'Canadian Tax Foundation', ], } as const; /** * The Toronto boutique is NEVER named — AGENTS.md D16. Use this string. * Do not infer a name from an email domain or anywhere else. */ export const BOUTIQUE = 'a Toronto litigation and ADR boutique' 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. * * Neither had a constant until 2026-08-26, which meant `/about/` (step 3) and * the `Person` JSON-LD (docs/04) were both going to hand-type them. A claim * written by hand in a component is a claim nobody re-checks against §4 — and * these are the two where the wording IS the compliance. */ export const ROLE = { /** * §4 verbatim, and it is the VISIBLE role only. * * NO LONGER THE JSON-LD `jobTitle` — Q47, ruled 2026-08-28. This string was * both the visible role line and the Person node's `jobTitle`, which put * "Director of Firm Operations" on a node whose `url` is this ADR practice's * `/about/` — so a consumer could attach the boutique title to this entity. * Pouya's ruling splits them: the graph carries PRACTICE_JOB_TITLE below, * while this string stays exactly where it was in visible copy ("I am * {ROLE.title} at {ROLE.at}"). * * **The graph carries NO `worksFor`.** This sentence said it did — "the graph * now carries PRACTICE_JOB_TITLE below and `worksFor: SML Company Ltd`" — * which was true for one pass and was reverted the same day (Q49(b)). Verified * 2026-08-28: zero live `worksFor` properties in `src`. */ title: 'Director of Firm Operations', // [verified 2026-08-25 — strategy brief §I] /** Always rendered with BOUTIQUE, never with a firm name (D16). */ at: BOUTIQUE, /** * D13's approved phrasing, and the only approved phrasing. The alternative * he approved is 'involvement in litigation and ADR matters'. * * NEVER "practice" in this context — that is the exact word D13 bars in the * exact context it bars it, and §4 records that this register itself once * carried the wrong word here while quoting the strategy brief verbatim. * "Practice" describing Pouya's OWN ADR practice is correct and unaffected. * * Explicitly interim — AGENTS.md R1. Raise it; do not let it settle in. */ litigationLine: 'active litigation exposure', // [verified 2026-08-26 — D13] /** The matter types behind that exposure. §4 verbatim; do not extend this * list without a §4 row to extend it from. */ litigationAreas: [ 'personal injury', 'construction', 'regulatory (POA)', 'insurance (SABS)', ], } as const; /** * The Person node's `jobTitle` — Q47, ruled by Pouya 2026-08-28. * * NOT `ROLE.title`, and that separation IS the ruling. §4's row is one fact with * two halves — *"Director of Firm Operations, Toronto litigation and ADR * boutique"* — and visible copy always pairs them. The JSON-LD emitted only the * first half, on a `Person` whose `url` is this practice's `/about/`, so a * consumer could attach the boutique title to this entity. `worksFor` could not * fix it, because D16 bars naming the boutique and there was no value it could * take. * * His ruling breaks the bind by changing what the field is about: *"jobTitle * describes this practice, not the boutique role, which D16 keeps unnamed"* — * and that half holds: this constant names no boutique. * * **THE `worksFor` HALF OF THE RULING IS NOT IMPLEMENTED — Q49(b).** This * paragraph said *"`worksFor` becomes SML Company Ltd — verified, federally * incorporated, and the entity the practice operates through. Both are set"*. * Two defects, both found by `claims-auditor` on re-audit: **"Both are set" is * false** (reverted the same day), and *"the entity the practice operates * through"* was listed inside a run of verified attributes when **§4 rows only * "Operator of SML Company Ltd. `alongside` the practice"** — a different * structural relation, and precisely what Q49(b) is open on. Do not restate the * ruling's phrasing as though the register carried it. * * ⚠️ **IT SHIPPED FOR ONE PASS AS "Mediator and Commercial Arbitrator" AND THAT * WAS WRONG FOR A REASON I HAD NOT SEEN.** Both review agents found it * independently on 2026-08-28, which is this loop's strongest signal. * * The string `claims-auditor` struck from **this same node's `description`** on * 2026-08-27 was *"Mediator and commercial arbitrator in Toronto"*. The value * ruled for `jobTitle` is the same words minus the city — **in the most * role-asserting field in the vocabulary**, thirty lines below the comment in * `schema.ts` that explains why the words were struck. §4 verifies *"Has * completed multiple sole mediations"* and has **no counterpart row for a * completed arbitration** — only that appointments are *accepted*. Consumers * render `jobTitle` beside `name`: *Pouya Lajevardi — Mediator and Commercial * Arbitrator*, which invites the reader to supply a track record for both halves. * * **I flagged the wrong thing.** My note argued about scoping ("Commercial"), * and neither the note nor I noticed the whole string had already been struck on * different grounds. A flag aimed at the wrong defect reads as diligence and * provides none. * * **So this ships as the narrowest form §4 actually rows**, and Q47's purpose is * still served: Pouya's ruling was that `jobTitle` describe *this practice* * rather than the boutique role, and "Mediator" does exactly that. Nothing is * lost from the graph — `description` ("accepting commercial arbitration * appointments") and `serviceType` ("Commercial arbitration") both carry the * arbitration **offering**, and both cleared audit. Only the role-assertion is * gone. * * **AGENTS.md Q49 asks Pouya for the row.** If he wants the fuller title it * needs either a §4 row for arbitrator-as-practised-role, or an offering-shaped * value — `adversarial-reviewer` proposed `'Mediator; accepts commercial * arbitration appointments'`, which is honest and reads oddly for a job title. * His call, not one to take by tidying. */ // [derived from §4 — "Q.Med designation through ADRIC / ADRIO" + "Has completed // multiple sole mediations". NOT a row stamp: §4 has no row reading "Mediator", // and the row-level wording is what Q49(a) is open on. The 2026-08-25 date this // comment first carried was inherited from ROLE.title's row.] export const PRACTICE_JOB_TITLE = 'Mediator' as const; /* `PRACTICE_ENTITY` LIVED HERE FOR ONE PASS AND IS DELETED WITH `worksFor`. * * It existed only to populate `Person.worksFor`, which is withheld pending a §4 * row (Q49). `adversarial-reviewer` found the defect that decided it, and it is * one the "name only, nothing else" scoping did **not** address: the * ProfessionalService node's `provider` **is** this Person, so * `provider → Person → worksFor → SML Company Ltd` asserts transitively exactly * what `src/pages/about.astro` declines to assert in prose — that the practice * and the company are the same entity. **The referent matters and the first * version of this sentence got it wrong:** it said "the comment four lines above * it", pointing at `aboutGraph`'s note in `schema.ts`, which covers * `ProfilePage`, `BreadcrumbList` and `memberOf` and says **nothing** about SML * Company Ltd. `adversarial-reviewer` read it and found the citation empty — * *"a claim whose referent cannot be reached is unverifiable by construction"*, * this repo's own rule, applied to the argument for a revert. The real referent * is `about.astro`'s deleted sentence: *"the company through which the * engineering work is done" — a corporate-structure claim.* The transitive * argument stands on its own; the evidence offered for it did not. * * Two further grounds, both recorded so this is not re-added casually: * - §4's row says "Operator of SML Company Ltd **alongside** the practice". * Q47's ruling says "the entity the practice **operates through**". Those are * different structural relations and the second has no §4 row. * - `/about/` already **removed** a sentence of this exact class from visible * copy — see about.astro: *"the company through which the engineering work is * done" — a corporate-structure claim*. Publishing it machine-readably while * declining it in prose is the stricter-in-public, looser-in-metadata shape. * * The original omission had TWO grounds — "either names the boutique (D16) **or * misstates the employer**". Q47 answers the first. The second is Q49. * * `SITE.entity` already carries the string for the footer. Re-adding a second * constant for the same name would be 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."* * * It was hand-typed into `/` and then into `/about/`, and **the two copies had * already diverged** — `/` used a comma ("one side, a working engineering * practice on the other"), `/about/` used full stops — within the same session * that wrote both. This is the sentence Q41(a) makes responsible for making the * licence implication *"impossible rather than merely absent"*, so a silent * divergence in it is the highest-consequence drift on the site. * * Pouya's ruling, 2026-08-27, kept because it is the finding rather than the fix: * * "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 is only half of it — a reader supplies the missing * symmetry from silence, and for the legal half the missing half is a licence. * Naming that half **training** is what forecloses it. Do not tidy this into a * parallel, do not shorten it to fit a layout, and do not retype it into a page. */ export const ASYMMETRY_LINE = 'The two halves are not the same kind of thing, and the asymmetry is the ' + 'honest part. A law degree on one side. A working engineering practice on ' + 'the other. One is training I hold. The other is work I still do.'; /** The three credential slots. Never matter counts — AGENTS.md §4. */ export const CREDENTIAL_ROW = [ { value: 'Q.Med', label: 'ADRIC / ADRIO designation' }, /** * Q37 CLOSED 2026-08-27. This label read 'Law and engineering' and it is now * 'Legal training and engineering practice'. Pouya's reasoning, kept because * 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 JD is a degree. Engineering is a practice, and a verified one (§4). * Setting the two in parallel invited the reader to supply the symmetry, and * for 'Law' the missing half is a licence — which D13 bars by implication as * hard as by assertion. * * IT IS DELIBERATELY LOPSIDED AND LONGER. Do not tidy it back into a * parallel, and do not shorten it to fit a layout; change the layout. */ { value: 'JD + ML', label: 'Legal training and engineering practice' }, { value: 'EN · FA', label: 'Bilingual practice' }, ] as const; /** * The FOURTH credential slot — separate on purpose, so a three-slot layout * cannot be handed four by accident and a page has to opt in. * * docs/03: 'Fourth slot where the layout has one: Q.Arb — commenced August * 2026. Use that wording, not "in progress"' — the weaker form drifts toward * 'nearly complete', which §4 Forbidden bars outright. * * REQUIRED on any page that offers arbitration, not decorative. §4 Offerings * carries a paired-disclosure condition: the site may make the offering only * while 'stating the second plainly', and 'neither half may be dropped'. The * footer's designation strip satisfies it site-wide; a page whose opening * sentence says 'arbitrator' should not make the reader scroll to the footer * for the stage. * * The em-dash in docs/03's string is carried by the layout (value over label), * not by the text. Same wording, same pairing. */ export const CREDENTIAL_ROW_ARB = { value: 'Q.Arb', label: 'Commenced August 2026', } as const; // [verified 2026-08-26 — Pouya] /** Analytics: privacy-first and cookieless (D15). No GA4, no consent banner. */ export const ANALYTICS = { /** * Q31 CLOSED — **Plausible**, decided rather than defaulted. Pouya checked * 2026-08-26: Fathom is Canadian-owned but stores non-EU traffic on US * servers, isolating 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. D15 amended to match. * * The union type stays — `/legal/privacy/` has to name the processor, and a * change of processor is a copy change on that page, not just a config edit. */ provider: 'plausible' as 'plausible' | 'fathom', domain: 'adr.smlcompany.ca', } as const; export const CONTACT = { email: 'info@smlcompany.ca', // [verified 2026-08-26] /** No public phone by choice. Render 'By scheduled call' wherever a number * would go — do not leave the field visually empty. */ phone: null as string | null, // [verified 2026-08-26] phoneFallback: 'By scheduled call', location: 'Toronto · Ontario · By appointment', /** [verified 2026-08-26 — Pouya, AGENTS.md Q27]. A PUBLIC COMMITMENT: this * wording must match /contact/, the inquirer confirmation email, and any * bio. Change it here and sweep — never edit one copy. */ responseTime: 'Inquiries are answered within two business days.', /** The same fact in sentence-fragment form, for the confirmation email and * any inline use. Derived, so the two cannot drift. */ responseTimeShort: 'within two business days', linkedin: 'https://www.linkedin.com/in/pouyalajevardi/', // [verified 2026-08-26] /** Booking parked 2026-08-26 (AGENTS.md R6). Build /contact/ with the intake * form and a reserved slot so an embed drops in later without a rebuild. */ bookingUrl: null as string | null, } as const; /** Portrait assets. Astro derives AVIF/WebP variants from the master at build. */ export const PORTRAIT = { master: 'src/assets/pouya-lajevardi.jpg', // 1600x1600 og: 'src/assets/og-portrait.jpg', // 1200x630, cropped high alt: 'Pouya Lajevardi', } as const; /** Shown on /contact/ and with the booking embed. Do not reword casually. */ export const NO_RETAINER_NOTICE = 'Submitting this form does not create a retainer, does not appoint a neutral, ' + 'does not itself establish a mediator–party relationship, and does not itself ' + 'create a conflict check.'; /** * Rate card — AGENTS.md D14, confirmed by Pouya 2026-08-26. * One rate for all mediation matters. All figures PLUS HST. * Full research and reasoning: docs/07-fees.md */ export const FEES = { currency: 'CAD', taxNote: 'All fees are plus HST.', mediation: { /** Prep is bundled AND stated on the page — [verified 2026-08-26]. * Do not hide it: at these rates, saying preparation is included is the * point, not a detail. */ halfDay: { amount: 2000, hours: 3.5, prepIncluded: 2 }, fullDay: { amount: 4000, hours: 7, prepIncluded: 3 }, additionalParty: 500, // each party beyond two overtimePerHour: 500, // [verified 2026-08-26] }, arbitration: { perHour: 500, hearingDay: 4000, documentsOnlySimple: 6500, // flat documentsOnlyComplex: 9500, // flat // No tribunal-secretary rate — removed by Pouya 2026-08-26. }, /** * THREE services at this rate, not four. Q42 CLOSED 2026-08-27 by Pouya: * early neutral evaluation, dispute-system design, and pre-dispute technical * advisory each gained a §4 Offerings row; **settlement counsel was REMOVED** * — his words: *"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."* Do not restore * it, and do not price it. */ hourly: 500, // [verified 2026-08-26] cancellation: [ { window: 'More than 30 days before', fee: 'No fee. Disbursements only.' }, { window: '15 to 30 days before', fee: '50% of the booked fee.' }, { window: 'Fewer than 15 days before', fee: '100% of the booked fee.' }, ], cancellationNotes: [ 'Rescheduling at the time of cancellation, with a new date fixed, is not charged.', 'The cancellation fee is waived if the reserved time is filled by another matter of equal or greater value.', ], terms: [ 'Fees are shared equally between the parties unless they agree otherwise in writing.', 'Accounts are payable on rendering. Interest accrues on overdue accounts at 5% per annum.', 'Video and in-person sessions are charged at the same rate.', ], } as const; /** * Slugs as their own literal tuple so consumers keep the union type. * Deriving them with `.map()` and casting to `[string, ...string[]]` widens * them back to `string`, and a mistyped slug then survives `astro check`. */ export const PRACTICE_SLUGS = [ 'construction', 'technology', 'energy', 'insurance', 'shareholder', 'cross-cultural', ] as const; export type PracticeSlug = (typeof PRACTICE_SLUGS)[number]; /** * The six areas, with the one-line blurb each card renders. * * THE BLURBS LIVE HERE, not in the pages, because `/` and `/practice/` both * render them and two copies of a claim-bearing sentence is one copy that will * eventually be wrong. Same reasoning as ROLE and CREDENTIAL_ROW above. * * EVERY BLURB IS DISPUTE TYPES, NOT HISTORY. docs/03: "Frame as positioning, * not as history" — 'Built to facilitate ... on Ontario's megaproject pipeline', * never 'extensive experience resolving'. AGENTS.md §4 (Q35, 2026-08-27) makes * that condition 2 of the publication gate for naming a practice area at all. * A blurb that claims volume fails the gate even though the label passes. * * Nothing here may carry a count, a value, a settlement rate, or a superlative * (§4 Forbidden). Dispute types are not claims of caseload. */ export const PRACTICE_AREAS = [ { slug: 'construction', name: 'Construction & Infrastructure', chip: 'Construction', blurb: 'Liens, delay and change-order claims, scheduling, subcontract and ' + "deficiency disputes. Built for Ontario's megaproject pipeline.", }, { slug: 'technology', name: 'Technology, AI & Data', chip: 'Technology', blurb: 'Software contracts, SLA and MSA breakdowns, data residency and ' + 'processing, AI vendor diligence, IP and licensing.', }, { slug: 'energy', name: 'Energy, Grid & Regulatory', chip: 'Energy', blurb: 'Grid connection and allocation, leave-to-construct, ' + 'proponent–municipality disputes, IESO market participation.', }, { slug: 'insurance', name: 'Insurance, SABS & LAT', chip: 'Insurance', /** * Q41(c) CLOSED 2026-08-27 — and the verification changed the wording again. * * `LAT pre-hearing mediation` (a SEARCH INTENT in `docs/01`, never an * offering) must never be published. Pouya's ruling: *"imprecise and must * not imply appointment by the tribunal. Verify against LAT's own materials * how its case-conference process is conducted and who conducts it."* * * Verified 2026-08-28 against the LAT Rules and the LAT-AABS process page, * both extracted into `docs/reference/lat-case-conference.md`: * * - Rule 2.4: *"'Case Conference' has the same meaning as 'Pre-Hearing * Conference' as defined in the SPPA."* **"Pre-hearing" is the * Tribunal's own label**, and what it names is a case conference. * - Rule 14.3: a **Member** presides, and is then disqualified from the * hearing panel. Rule 14.6: parties must attend. The neutral is the * Tribunal's, and a privately retained one cannot be appointed to it. * - The Rules contain **zero** occurrences of `mediat` or `arbitrat` * (0 in 66,593 characters). The concept is not in them. * * The interim read "private mediation of matters before the LAT", which is * ambiguous in the one word that matters: `before` reads as *pending at* as * easily as *prior to*. Replaced with the temporal frame the Tribunal's own * page endorses — *"you may want to consider negotiation or mediation * services... before filing at the LAT-AABS, and continuing... after a * claim has been filed."* * * `/practice/insurance/` at step 5 must say the mediation is PRIVATE and is * not the Tribunal's case conference. */ blurb: 'Accident benefits and SABS entitlement, MIG disputes, and private ' + 'mediation alongside a LAT application, before filing or after.', }, { slug: 'shareholder', name: 'Shareholder & Family Business', chip: 'Shareholder', /** * "Family Business" means COMMERCIAL disputes among family shareholders. * The blurb says "family-held companies" and names commercial dispute types * for that reason — AGENTS.md Q39, 2026-08-27. * * The explicit exclusion — family law matters are not accepted — belongs on * the PAGE, one sentence, at build step 5 (docs/01 §/practice/shareholder/). * Pouya scoped it there. Do not add it to this blurb: on a six-card grid it * unbalances the row and reads defensively, and the wording here already * makes the area unambiguously commercial. */ blurb: 'Shareholder and partnership disputes, co-founder breakdowns, and ' + 'business succession in family-held companies.', }, { slug: 'cross-cultural', name: 'Cross-Border & Diaspora', chip: 'Cross-cultural', blurb: 'Diaspora business succession, dual-jurisdiction shareholder disputes, ' + 'and cross-cultural commercial matters. Conducted in English or Farsi.', }, ] as const satisfies ReadonlyArray<{ slug: PracticeSlug; name: string; chip: string; blurb: string; }>; /** * Compile-time completeness check, both directions. * * `satisfies` above catches a slug in PRACTICE_AREAS that is not in * PRACTICE_SLUGS. This catches the reverse — a slug with no area — which would * otherwise let an article declare a practice area that has no page, no nav * child and no chip, producing a dead link at step 7. Deriving the areas from * the slugs used to make that structurally impossible; keeping two literals is * what buys the literal types back, so the check has to be explicit. * * Type-only. Nothing runs, nothing ships. */ type _AssertNever = T; type _SlugsWithoutAnArea = Exclude< PracticeSlug, (typeof PRACTICE_AREAS)[number]['slug'] >; export type _SlugCoverage = _AssertNever<_SlugsWithoutAnArea>; /** * 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: * `/` renders a compressed strip of these and `/process/` renders them in full * at build step 6, so a copy typed into one page is a copy that will eventually * disagree with the other. The proof is already in the history — the step-3 body * below carried a fee claim that the same session's claims audit found to be * wrong against `docs/07`, and it existed in exactly one place. After step 6 it * would have existed in two. * * TIMINGS ARE `docs/01` §`/process/`'s, verbatim: "confidential intake (day 0) · * engagement and framing (1–7) · pre-session exchange (7–21) · the session * (21–30) · binding conclusion (30+)". * * **Q43 CLOSED 2026-08-27, and the ruling went the other way from this * comment's previous reasoning.** It read: *"`docs/03` §Process requires them * REAL rather than illustrative, so they are not softened to 'typically'."* * Pouya ruled that the five timings are **service commitments, the same class * as Q27's response time** — not facts about him, so they need framing rather * than 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." * * The NUMBERS ARE UNCHANGED — softening was never the fix, and inventing them * was never on. What changed is that they now ship with `PROCESS_FRAMING` * below, which is **not optional**: any page rendering these steps renders it * too. `docs/03` §Process has been amended to record the override. * * Step 5 is labelled from the spec but its body says what actually concludes — * minutes of settlement in a mediation, an award where the process is arbitral. * "Binding conclusion" alone would read as though a mediation binds, which it * does not until the parties sign. * * NO FEE CLAIM IN ANY BODY. `docs/07` bundles a CAPPED preparation allowance * (2 h in the half day, 3 h in the full day) and says in terms that it "must be * stated on the page... Do not quietly fold it into the hours figure." A * five-word strip cannot state it properly, and stating it improperly * misdescribes money. `/fees/` at step 9. */ export const PROCESS = [ { title: 'Confidential intake', timing: 'Day 0', body: 'A scheduled call to scope the matter, identify the parties, and run conflicts.', }, { title: 'Engagement and framing', timing: 'Days 1–7', body: 'Terms of appointment, the issues in dispute, and who attends.', }, { title: 'Pre-session exchange', timing: 'Days 7–21', body: 'Briefs and documents, exchanged in advance so the session starts informed.', }, { title: 'The session', timing: 'Days 21–30', body: 'Half day or full day, in person or by video.', }, { title: 'Conclusion', timing: 'Day 30 onward', body: 'Minutes of settlement — or an award, where the process is arbitral.', }, ] as const; /** * THE FRAMING THAT MAKES THE TIMINGS PUBLISHABLE — Q43, Pouya 2026-08-27. * * Not decoration and not a disclaimer bolted on: it is the condition on which * the five numbers above may appear at all. *"Published as typical, they are * honest and useful; published as commitments, the first matter that slips * makes the page false."* * * RENDER IT ADJACENT TO THE STEPS, on every page that renders them — `/` now, * `/process/` at step 6. A reader who sees `Days 21–30` and not this sentence * has read a commitment. First person, per `docs/03` §Voice. */ export const PROCESS_FRAMING = 'This is the typical shape of an engagement, not a commitment. Timing ' + 'depends on party and counsel availability, which I do not control.'; /** Seven items is the ceiling before a nav stops being scannable. */ export const PRIMARY_NAV = [ { href: '/about/', label: 'About' }, { href: '/mediation/', label: 'Mediation' }, { href: '/arbitration/', label: 'Arbitration' }, { href: '/practice/', label: 'Practice', children: PRACTICE_AREAS }, { href: '/fees/', label: 'Fees' }, { href: '/insights/', label: 'Insights' }, { href: '/contact/', label: 'Contact' }, ] as const; /** Linked contextually rather than from the primary nav. */ export const SECONDARY_NAV = [ { href: '/process/', label: 'How I work' }, { href: '/med-arb/', label: 'Med-Arb' }, { href: '/for-parties/', label: 'For parties' }, ] as const; export const LEGAL_NAV = [ { href: '/legal/privacy/', label: 'Privacy' }, { href: '/legal/terms/', label: 'Terms' }, ] as const;