feat: Q.Arb is held; strike C.Med-Arb entirely; dissolve the paired disclosure
Build and deploy / build-and-deploy (push) Failing after 4s

Pouya's ruling, 2026-08-29. Treated as D3-class and swept accordingly.

§4
  Q.Arb becomes a HELD designation. Obtained July 2026 — recorded in the
  register, deliberately not published. Public copy carries "Q.Arb (ADRIC /
  ADRIO)" beside Q.Med and nothing more. Every stage form is struck:
  "commenced", "in progress", "pathway", "not yet".

  C.Med-Arb as a stated goal is struck. This DEVIATES FROM THE STRATEGY BRIEF,
  which made it "the explicit long-term professional narrative"; the brief is
  not in this repository, so the deviation is recorded in four places so nobody
  reinstates it from a document no reader can open. The designation stays in
  §11 as a definition — what is struck is its status as a goal of his.

  The paired-disclosure condition dissolves. It existed only because Q.Arb was
  in progress; there is no stage left to disclose, and a condition with no
  subject cannot be half-kept.

Pages
  /about/'s credentialing arc is DELETED, not rewritten — two held designations
  are not a journey. /arbitration/ loses its stage section and its "Available
  now, and open about the stage" h1. /med-arb/'s endpoint section is rewritten.
  Deleting CREDENTIALS.goal/goalName rather than emptying them turned every
  consumer into a build error, which is how the last two surfaced.

  hasCredential now maps CREDENTIALS.designations instead of indexing [0];
  _DesignationRowParity pins the visible credential row to the same constant.

check:claims
  q-arb-as-a-stage (inverted from the predecessor, which barred Q.Arb reading
  as HELD) and c-med-arb-struck. Each page is now scanned twice — as published,
  and with inline tags collapsed — because [^<] cannot cross <strong>, which
  this site sets in prose.

Two open questions for Pouya, neither blocking:
  Q55 — the acquisition date. §4 says obtained July 2026; the Change Log of
  2026-08-26 records "commenced August 2026", both stamped [verified — Pouya].
  They cannot both be true. Nothing published turns on it.
  Q56 — is the mediation offering scoped commercial? §4 leaves it unscoped;
  four surfaces say "commercial mediation"; /practice/insurance/ offers
  mediation in insured-versus-insurer SABS matters.

Two review rounds, all findings applied or declined with a stated reason.
Round 2 found ten lines in docs/03 still instructing the struck form — the
2026-08-29 sweep missed them because `git grep 'Q.Arb'` is line-anchored and
the block never names it. Sweep the vocabulary, not only the subject.

Gates, exit statuses read directly, never through a pipe:
  npm run check        exit=0  (0 errors, 0 warnings, 0 hints)
  npm run lint         exit=0
  npm run build        exit=0  (12 pages)
  npm run check:claims exit=0  (11 patterns, 26 approved strings)
  npm audit            exit=0

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Md3GndFqWPzK78xAoebsg5
This commit is contained in:
Pouya Lajevardi
2026-08-30 10:37:19 -04:00
co-authored by Claude Opus 5
parent 79b19a7bd0
commit 610edc24fd
20 changed files with 1063 additions and 606 deletions
+206 -23
View File
@@ -177,14 +177,72 @@ const PATTERNS = [
re: /\bS\.?\s?M\.?\s+Lawrence\b|\b07452218\b/gi,
},
{
id: 'q-arb-as-held',
rule: '§4 Forbidden — Q.Arb must never read as held, imminent, or nearly complete.',
id: 'q-arb-as-a-stage',
rule: '§4 — Q.Arb is HELD. It must never read as a stage, a pathway, or pending.',
incident:
'It commenced August 2026. The recurring drift is one word: docs/03 said ' +
'the Q.Arb "designation commenced in August 2026" — which reads as in ' +
'force since then, i.e. HELD — in copy an implementer is told to lift ' +
'verbatim. Found by claims-auditor 2026-08-28. §4 requires "pathway".',
re: /Q\.?\s?Arb\s+designation\b|\b(holds?|holding|awarded|conferred|earned|achieved)\s+(the\s+|a\s+)?Q\.?\s?Arb\b|Q\.?\s?Arb[^.<]{0,60}\b(nearly|almost) complete\b|Q\.?\s?Arb[^.<]{0,60}\bin progress\b/gi,
'THIS PATTERN WAS INVERTED ON 2026-08-29 AND ITS PREDECESSOR IS GONE. It ' +
'used to bar Q.Arb reading as HELD, because §4 recorded it as "commenced ' +
'August 2026"; Pouya ruled it held (obtained July 2026, date NOT ' +
'published), so every stage word now understates a real credential. The ' +
'site carried the struck forms on six surfaces — an h1 reading "Available ' +
'now, and open about the stage", a whole /arbitration/ section headed ' +
'"Where I am in the arc", /about/\'s arc section, the footer strip, and ' +
'both JSON-LD nodes. Publish "Q.Arb (ADRIC / ADRIO)" and nothing more.',
/* ~50 characters either side, per Pouya's specification. The window stops at
the next TAG boundary so it cannot leap a paragraph. It stopped at a
sentence boundary too (`[^.<]`) until the fixture below proved that too
tight: "Qualified Arbitrator. Newly commenced" splits the anchor from the
stage word across a full stop, 22 characters apart, and that is precisely
the copy this pattern exists for. The self-test caught the regression.
⚠️ THE ANCHOR MATCHES THE EXPANSION TOO, and it did not on the first
draft. Tested against the nine strings this change set removed: it caught
seven and MISSED "Qualified Arbitrator. Newly commenced — not held, and
not nearing completion." — /about/'s own arc body, which never wrote the
abbreviation. An abbreviation-only anchor cannot see copy that spells the
designation out, and prose is exactly where it gets spelled out.
KNOWN LIMIT, stated rather than papered over: this cannot catch a stage
expressed without naming the designation at all. The h1 it replaced —
"Available now, and open about the stage" — matches nothing here and no
regex over shipped HTML would catch it without firing on ordinary copy.
That one is `claims-auditor`'s. */
/* WHAT EACH ALTERNATIVE IS FOR, because none is obvious from the regex:
(1) stage word after the designation, (2) before it, (3) an acquisition
DATE near it — §4 records July 2026 and bars publishing it, and docs/03
cited this script as enforcing that before it did (the Q22 shape) —
(4) "once/when I hold it", which must take the designation as its object
or it fires on "when I hold a preliminary conference".
THE ANCHOR MATCHES THE EXPANSION because `docs/03` authorises "Qualified
Arbitrator" as publishable prose, and prose is where it gets spelled out.
KNOWN LIMIT, stated rather than papered over: this cannot catch a stage
expressed without naming the designation. The h1 it replaced — "Available
now, and open about the stage" — matches nothing here, and no regex over
shipped HTML would catch it without firing on ordinary copy. That one is
`claims-auditor`'s. */
re: /(?:Q\.?\s?Arb|Qualified Arbitrator)\b[^<\uE000]{0,50}?\b(commenc\w*|in progress|pathway|not yet|not held|nearing completion|pending|working toward|under ?way)\b|\b(commenc\w*|in progress|pathway|not yet|not held|nearing completion|pending|working toward|under ?way)\b[^<\uE000]{0,50}?\b(?:Q\.?\s?Arb|Qualified Arbitrator)\b|(?:Q\.?\s?Arb|Qualified Arbitrator)\b[^<\uE000]{0,50}?\b(?:January|February|March|April|May|June|July|August|September|October|November|December)\s+20\d\d\b|\b(?:January|February|March|April|May|June|July|August|September|October|November|December)\s+20\d\d\b[^<\uE000]{0,50}?\b(?:Q\.?\s?Arb|Qualified Arbitrator)\b|\b(?:once|when)\s+(?:I|he)\s+(?:holds?|obtains?|receives?|completes?)\s+(?:it\b|the\s+)?(?:Q\.?\s?Arb|designation)\b/gi,
},
{
id: 'c-med-arb-struck',
rule: 'C.Med-Arb is out entirely — it appears on no page (Pouya, 2026-08-29).',
incident:
'It was the strategy brief\'s "explicit long-term professional narrative" ' +
'and it shipped on /, /about/, /arbitration/ and /med-arb/ as the endpoint ' +
'of a credentialing arc. Pouya dispensed with it: he holds Q.Med and ' +
'Q.Arb, which is what med-arb requires. THE DESIGNATION IS STILL REAL and ' +
'stays in AGENTS.md §11 as a definition — this bars naming it in shipped ' +
'output, not knowing what it is. Barred in every spelling both ' +
'institutions use, because the reinstatement risk is a well-meaning ' +
'implementer reading the brief, not a typo.',
/* ⚠️ THE LEADING \b AND THE MANDATORY DOT ARE BOTH LOAD-BEARING, and this
pattern shipped without them for one run. `C\.?\s?Med-Arb` matched
"ADRIC Med-Arb Rules" as "C Med-Arb" — the C of ADRIC, a space, then the
real rule-set name — and failed the build on approved copy on /med-arb/.
The abbreviation always carries the dot; "C Med-Arb" is not a form either
institution uses. The fixture below pins it. */
re: /\bC\.\s?Med-Arb(?:itrat(?:or|ion))?s?\b|\bChartered Med-Arb(?:itrat(?:or|ion))?s?\b/gi,
},
{
id: 'struck-universal-q39',
@@ -252,11 +310,36 @@ const FIXTURES = {
'the best mediator',
],
'fabricated-founder': ['S. M. Lawrence', 'Co. № 07452218'],
'q-arb-as-held': [
'the Q.Arb designation',
'holds Q.Arb',
'Q.Arb is nearly complete',
'Q.Arb, in progress',
'q-arb-as-a-stage': [
'The Q.Arb pathway commenced in August 2026',
'Q.Arb is in progress',
'Q.Arb — not yet held',
'once I hold Q.Arb',
'my Q.Arb pathway',
/* The expansion, which the first draft of this pattern missed. */
'Qualified Arbitrator. Newly commenced — not held, and not nearing completion.',
/* The acquisition date, which no stage word caught. */
'Q.Arb, obtained July 2026',
'Q.Arb (ADRIC / ADRIO), held since July 2026',
/* The `rule` line above named these and the regex never matched them —
a documented control not covering what it is cited for (Q22's shape). */
'Q.Arb is pending',
'Q.Arb — the designation I am working toward',
'the Q.Arb process is under way',
],
'c-med-arb-struck': [
'C.Med-Arb is the endpoint',
'Chartered Med-Arbitrator',
'the ADRIC Chartered Med-Arb designation',
/* The blend §11's own expansion invites, which the trailing \b in the
first draft made invisible: `C\.Med-Arb\b` cannot match when the next
character is a word char. */
'the C.Med-Arbitrator designation',
'Chartered Med-Arbitration',
/* Plurals: the trailing \b survived the first repair and blocked these. */
'Chartered Med-Arbitrators',
'C.Med-Arbitrators',
'C.Med-Arbitration',
],
'struck-universal-q39': [
'Anyone may be appointed an arbitrator in Ontario',
@@ -286,8 +369,26 @@ const FIXTURES = {
inside <style>. */
'<style>.hero-lede{line-height:var(--leading-body);color:var(--text-secondary)}</style>',
'Software contracts, SLA and MSA breakdowns, data residency and processing, AI vendor diligence, IP and licensing.',
'The Q.Arb pathway commenced in August 2026; C.Med-Arb is the endpoint.',
'Chartered Med-Arbitrator',
/* The approved replacements for the two negatives struck on 2026-08-29,
which were 'The Q.Arb pathway commenced in August 2026; C.Med-Arb is
the endpoint.' and a bare 'Chartered Med-Arbitrator'. Both are now
breaches, and both moved to mustMatch. */
'Q.Med (ADRIC / ADRIO) · Q.Arb (ADRIC / ADRIO)',
/* The expansion in approved use — §11 definitional, no stage word. */
'Q.Arb stands for Qualified Arbitrator, an ADRIC and ADRIO designation.',
/* `once` and `when` were BARE stage words for one run, and all four of these
compliant sentences failed the build. They now require a hold-verb. */
'I hold Q.Med and Q.Arb, and I say so when a party asks',
'Q.Arb (ADRIC / ADRIO), which is what parties look at when they appoint',
'Once appointed, I hold Q.Arb and act as sole arbitrator',
'Q.Arb, and when the parties agree the process runs on that basis',
/* `hold` is a common verb on an arbitration page with a different object;
the repair narrowed `once|when` rather than closing it, and this shipped
past it for one run. The hold-verb must now take the designation. */
'I hold Q.Arb, and when I hold a preliminary conference the parties attend',
'I hold the Q.Med and Q.Arb designations through the ADR Institute of Canada and the ADR Institute of Ontario.',
/* The false positive the first form of `c-med-arb-struck` produced. */
'The ADR Institute of Canada publishes ADRIC Med-Arb Rules, developed by a task force.',
'The ADRIC National Mediation Rules.',
'adopted a new edition effective 1 March 2025',
'Commercial arbitration in Ontario. I do not accept family arbitration.',
@@ -364,6 +465,53 @@ function publishedText(html) {
);
}
/**
* THE SECOND VIEW, AND IT EXISTS BECAUSE `<strong>` DEFEATED THE GATE.
*
* `publishedText` leaves tags in place, and several patterns use `[^<]` as a
* window boundary so they cannot leap a paragraph. That boundary also stops
* them crossing INLINE markup: `<strong>Q.Arb</strong> — the pathway commenced
* in August 2026` matched nothing, and this site sets `<strong>` in prose on
* `/arbitration/` and `/`. Found by `adversarial-reviewer` 2026-08-30.
*
* So every page is scanned TWICE — once as published, once with inline tags
* collapsed to a single space. Block-level tags collapse to a full stop
* instead, which preserves the "do not leap a paragraph" property that made the
* `[^.<]` window worth having in the first place. Matches are deduplicated by
* the matched text, so a hit visible in both views is reported once.
*/
const BLOCK_TAGS =
/<\/?(?:p|div|section|article|header|footer|nav|main|aside|h[1-6]|li|ul|ol|dl|dt|dd|table|tr|td|th|blockquote|figure|figcaption|br|hr)\b[^>]*>/gi;
/**
* ⚠️ THE BLOCK BOUNDARY IS A SENTINEL (`\uE000`), NOT A FULL STOP, AND THAT IS
* WHAT LETS ONE REGEX SERVE BOTH VIEWS.
*
* First attempt substituted `' . '` and the windows were written `[^<]` — but
* collapsed text contains no `<` at all, so the window was bounded by nothing
* and leapt three block boundaries to join an `<h2>Q.Arb</h2>` to a paragraph
* reading "took effect on 1 March 2025" — approved copy that ships. Measured by
* `adversarial-reviewer`.
*
* Writing the windows `[^.<]` instead would fix that and reintroduce the defect
* the collapsed view exists for: a real sentence period inside one paragraph
* ("Qualified Arbitrator. Newly commenced") must still be crossable.
*
* A sentinel separates the two jobs. `[^<\uE000]` is bounded by `<` in the
* published view and by `\uE000` in the collapsed one; neither character occurs
* in the other view, and a full stop bounds neither. Every window in PATTERNS
* uses that class.
*/
const BLOCK_BOUNDARY = '\uE000'; // Private Use Area: never occurs in real content,
// and unlike \u0000 it is not a control character, which `no-control-regex` bars.
function collapsedText(html) {
return publishedText(html)
.replace(BLOCK_TAGS, BLOCK_BOUNDARY)
.replace(/<[^>]+>/g, ' ')
.replace(/[ \t]+/g, ' ');
}
function contextAt(text, index, length) {
const from = Math.max(0, index - 55);
const to = Math.min(text.length, index + length + 55);
@@ -404,7 +552,15 @@ function selfTest() {
);
}
for (const negative of FIXTURES.mustNotMatch) {
const hits = scan(publishedText(negative), p.re);
/* ⚠️ BOTH VIEWS. This read `publishedText` only, which left the entire
false-positive surface of `collapsedText` untested — and that is
exactly where the loosening happened: the collapsed view leapt three
block boundaries onto approved copy and the instrument check could not
see it. Found by `adversarial-reviewer`. */
const hits = [
...scan(publishedText(negative), p.re),
...scan(collapsedText(negative), p.re),
];
if (hits.length > 0) {
failures.push(
`${p.id}: matched APPROVED copy — ${JSON.stringify(hits[0].match)} in ${JSON.stringify(negative)}`,
@@ -483,14 +639,41 @@ console.log(` pages: ${pages.length}\n`);
for (const p of PATTERNS) {
const hits = [];
for (const page of pages) {
const text = publishedText(readFileSync(page, 'utf8'));
for (const hit of scan(text, p.re)) {
hits.push({
page: rel(page),
line: lineOf(text, hit.index),
match: hit.match,
context: contextAt(text, hit.index, hit.match.length),
});
const raw = readFileSync(page, 'utf8');
/* ⚠️ DEDUPE BY OCCURRENCE COUNT, NEVER BY TEXT. The first version keyed a
Set on the matched string, so `He is a lawyer.` twice on one page was
reported ONCE and the count said 1 — the check truncating its own
output, which is the one thing CLAUDE.md says a check must never do.
Measured by `adversarial-reviewer` on a two-line fixture.
The published view is authoritative; the collapsed view only ever ADDS
occurrences the tags hid, so a collapsed hit counts only where it exceeds
what the published view already found for that same text. */
const counted = new Map();
const bump = (key) => {
const n = (counted.get(key) ?? 0) + 1;
counted.set(key, n);
return n;
};
const publishedCounts = new Map();
for (const [viewIndex, text] of [
publishedText(raw),
collapsedText(raw),
].entries()) {
for (const hit of scan(text, p.re)) {
const key = hit.match.replace(/\s+/g, ' ').trim().toLowerCase();
if (viewIndex === 0) {
publishedCounts.set(key, (publishedCounts.get(key) ?? 0) + 1);
} else if (bump(key) <= (publishedCounts.get(key) ?? 0)) {
continue;
}
hits.push({
page: rel(page),
line: lineOf(text, hit.index),
match: hit.match,
context: contextAt(text, hit.index, hit.match.length),
});
}
}
}