Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

CHECK Assessment

2026-10-02 (commit 2d7e886b)

Chatter aims to provide sensible, understandable CHAT validation, not to imitate every behavior of CLAN CHECK. Grammar rejection and typed-model invariants can satisfy the same requirement with different diagnostics. Deliberate, justified divergences are resolved decisions, not unfinished work.

Current baseline

Inventoried assessment complete: 164 of 164 entries adjudicated; 0 unresolved gaps.

DispositionEntries
parity131
divergence10
no_obligation23
gap0

Completion means every entry in this finite CHECK assessment inventory has been adjudicated. It does not certify every CHECK emission path, all possible CHAT input, 100% code coverage, or Chatter 1.0 readiness. The inventory is maintained against the committed CLAN source reference; it is not a claim about an unexamined upstream revision.

When to reopen

Reopen an obligation only for a concrete, independently justified CHAT requirement and evidence that Chatter misses invalid input or rejects legitimate input. A different diagnostic code, wording, count, order or rejection stage is not a gap. Upstream changes prompt scoped source and intent review, not automatic imitation.

Developer contract

Assess CHECK source and intent before adopting suspicious behavior. Keep recovery and reporting idiomatic to the tree-sitter CST and typed AST, with source-bound evidence and producer-owned context. Never add parallel parsers, reparsing or raw-text diagnostic classifiers to mimic CHECK. When available structural evidence cannot prove a narrower fault, report an honest broader error. Preserve invalid-input rejection and valid controls. Experimental re2c agreement is not a completion prerequisite.

Authority and verification

The single authored authority is crates/talkbank-parser-tests/tests/check_parity/manifest.json. This page is its generated view; counts and completion are derived, never entered separately. The shared talkbank-spec-vocabulary::check_assessment types are used by the report, fixture harness and spec-status command.

Regenerate with just check-mapping-gen (also included in just regen). Run cargo test -p talkbank-parser-tests --test integration check_mapping_audit to detect stale generated documentation. The normal integration suite includes that check.

chatter_matches_check tests the manifest’s fixture expectations; manifest_agrees_with_clan_reference checks source-reference consistency. Neither a generated page nor an adjudication count is a fresh runtime receipt. clan_check_grounding separately checks an identified CHECK executable through CHATTER_CLAN_RUN; it does not establish that CHECK’s policy is correct.

The separate docs/audits/check-parity-audit.md is only a code-mapping index, not a second assessment or completion authority. Missing mappings do not mean missing validation.

Adjudication ledger

The codes below pin current regression expectations, not a requirement to reproduce CHECK diagnostics. Each rationale belongs to the manifest.

CHECK 1 — parity

First substantive byte is an invalid top-level line start (x) before an otherwise ordinary CHAT file. CLAN emits CHECK 1; chatter rejects the bad line start with E316.

Fixture: CHECK_001_bad_initial_character.cha. Chatter regression codes: E316.

CHECK 2 — parity

A complete CHAT preamble is followed by a main tier whose speaker code is not terminated by a colon. CLAN emits CHECK 2; chatter rejects the malformed line with E316.

Fixture: CHECK_002_missing_main_tier_colon.cha. Chatter regression codes: E316.

CHECK 3 — parity

The character after the speaker-tier colon must be whitespace (check.cpp ~1756: !isSpace after check_FoundText); the fixture writes *CHI:hello . with no tab. CLAN emits CHECK 3; chatter rejects the line as unparsable content (E316).

Fixture: CHECK_003_no_space_after_colon.cha. Chatter regression codes: E316.

CHECK 4 — parity

A space instead of a TAB after the speaker code (*CHI: hi). CLAN 4; chatter requires the tab in-grammar and surfaces the recovery node as E316.

Fixture: CHECK_004_space_after_tier.cha. Chatter regression codes: E316.

CHECK 5 — parity

@Begin: (a stray colon on the no-colon @Begin header) parses as a valid @Begin followed by a stray : ERROR node. A whole-tree recovery-node backstop in parse_lines_with_old_tree surfaces any ERROR node that streaming lowering would drop as E316 UnparsableContent (recovery is not validity); the AST is still produced. CLAN rejects the file (codes 5 and 6), and so does chatter. CLAN CHECK 5 (co-emitted with 6).

Fixture: CHECK_005_begin_illegal_colon.cha. Chatter regression codes: E316.

CHECK 6 — parity

@Begins (a misspelled @Begin) parses as @Begin plus a trailing s ERROR node, which the whole-tree recovery-node backstop surfaces as E316. CLAN rejects it (codes 6 and 17). CLAN CHECK 6 (co-emitted with 17).

Fixture: CHECK_006_begin_malformed.cha. Chatter regression codes: E316.

CHECK 7 — parity

File has no @End header at all. CLAN 7 (@End missing at end of file); chatter E502 MissingEndHeader.

Fixture: CHECK_007_missing_end.cha. Chatter regression codes: E502.

CHECK 8 — parity

A body line that does not begin with @, %, * or TAB (free text). CLAN 8 (expected @ %% * TAB); chatter E326 surfaces the unparsable main-tier start.

Fixture: CHECK_008_bad_line_start.cha. Chatter regression codes: E326.

CHECK 9 — parity

Speaker/tier name before the colon exceeds SPEAKERLEN=1024 characters (check.cpp:2395, first pass). chatter rejects via undeclared-speaker (E522/E308/W108) and speaker-ID-length E307 (max 7 chars), not via a dedicated raw length cap; CHECK aborts first pass (second pass not attempted).

Fixture: CHECK_009_tier_name_too_long.cha. Chatter regression codes: E307, E308, E522.

CHECK 10 — divergence

UTTLINELEN buffer bound (18000): a logical tier whose text across continuation lines exceeds 18000 chars draws check_err(10) in the check_OverAll char scan (check.cpp 2403). A SINGLE physical line over 18000 instead hits a separate hard-exit guard (check.cpp 2329, ‘Speaker turn is longer then’, cutt_exit(1), no (NN) code), so the fixture splits ~20k chars over tab continuation lines. Adjudication: the limit is a fixed C buffer size, an implementation artifact, not CHAT semantics; chatter has no tier-length limit by design (long tiers are valid and supported) and intentionally accepts.

Fixture: CHECK_010_tier_text_too_long.cha. Chatter regression codes: none.

CHECK 11 — divergence

External depfile membership is not a universal CHAT validity requirement. Empty POS fields are a separate structural fault, rejected by morphology recovery (E702; see the E760 examples).

Fixture: CHECK_011_undeclared_symbol_pct_fac.cha. Chatter regression codes: none.

CHECK 12 — parity

An @ID tier whose 3rd field (speaker code) or 8th field (role) is empty (check.cpp:5060/5084). E511 ‘ID header speaker field cannot be empty’ is the direct equivalent. CLAN also emits 142 on the same fixture.

Fixture: CHECK_012_missing_speaker_in_id.cha. Chatter regression codes: E511, E523.

CHECK 13 — parity

Same speaker declared twice in @Participants. chatter E549 DuplicateSpeakerDeclaration.

Fixture: CHECK_013_duplicate_speaker.cha. Chatter regression codes: E549.

CHECK 13 — parity

Two @ID lines naming the same speaker (CHI). Distinct from the @Participants-duplicate variant (CHECK_013_duplicate_speaker.cha): CLAN 13 fires for duplicate @ID lines too; chatter reports E549 via check_duplicate_id_headers. CLAN CHECK 13.

Fixture: CHECK_013_duplicate_id.cha. Chatter regression codes: E549.

CHECK 14 — parity

Leading spaces before the *tier code. CLAN 14 (also 4); chatter E326.

Fixture: CHECK_014_spaces_before_tier.cha. Chatter regression codes: E326.

CHECK 15 — parity

An @ID tier whose role field does not match any role listed in the depfile @Participants template (check.cpp:5087). E532 ‘Invalid participant role’ is the direct equivalent. CLAN also emits 142 on the same fixture.

Fixture: CHECK_015_illegal_role.cha. Chatter regression codes: E532.

CHECK 16 — parity

A speaker CODE containing non-printable-ASCII in @Participants (cnt==0 field scan, chars outside 33..126; check.cpp 2084-2086). Emits via the check_trans_err MACRO (check.cpp 74-79), invisible to the literal check_err(N,) counter. Empirically grounded: real CLAN emits (16) on this fixture. Non-ASCII speaker IDs are invalid by the 2026-09-23 maintainer ruling. Chatter reports syntax code E307 through the shared speaker assessment, not the unrelated E522 participant-join code; header recovery can emit additional diagnostics.

Fixture: CHECK_016_extended_chars_speaker_code.cha. Chatter regression codes: E307.

CHECK 17 — parity

Undeclared dependent tier %zzz: (neither %x* nor a chatter-supported standard tier). chatter rejects it via E605 UnsupportedDependentTier (Error severity). The supported set deliberately excludes the legacy %grt/%tra/%trn/%umor tiers retired with the UD-%mor consolidation, so chatter is intentionally stricter than CLAN there (documented divergence). %x* is always valid. CLAN CHECK 17.

Fixture: CHECK_017_undeclared_dep_tier.cha. Chatter regression codes: E605.

CHECK 18 — parity

An @ID tier whose speaker code is not declared on the @Participants tier (check.cpp:5062). E523 ‘@ID header for X but speaker not in @Participants’ is the direct equivalent. Note CLAN prints the literal tier name ‘@ID’ in the message (quirk of check_mess case 18 printing utterance->speaker).

Fixture: CHECK_018_id_speaker_not_in_participants.cha. Chatter regression codes: E522, E523.

CHECK 19 — parity

A token (here the retrace code ‘[/]’) is immediately followed by a non-space, non-delimiter character with no space between (check.cpp:4590/4592); also fires for a time bullet glued to a word. Full CLAN message is two lines: ‘Illegal use of delimiter in a word.’ + ‘Or a SPACE should be added after it.(19)’. Grounded also with a bullet glued to a word (u019d.cha). chatter rejects it with E757 (CodeGluedToFollowingContent), by span-adjacency on the retrace span, which covers the marker brackets. Wild-data impact: zero kept files.

Fixture: CHECK_019_code_glued_to_word.cha. Chatter regression codes: E757.

CHECK 20 — divergence

Documented divergence (maintainer ruling, 2026-07-12): a depfile-membership check. A token undeclared in a corpus optional/global depfile is not universally invalid CHAT; chatter validates universal CHAT-format validity, never external-config membership (CHAT validity must never depend on any config file). chatter deliberately accepts.

Fixture: CHECK_020_undeclared_suffix_compound.cha. Chatter regression codes: none.

CHECK 21 — parity

A main tier with text but no utterance terminator (check.cpp:4921; tier UTD==1, no delimiter found). E305 is chatter’s missing-terminator error.

Fixture: CHECK_021_missing_terminator.cha. Chatter regression codes: E305.

CHECK 22 — parity

An unclosed replacement scope remains invalid. The grammar rejects the fixture with E316; no raw-text replacement scanner or dedicated E311 diagnostic is required. This witnesses the unclosed replacement shape, not every CHECK 22 emission site.

Fixture: CHECK_022_unclosed_replacement.cha. Chatter regression codes: E316.

CHECK 23 — parity

Unmatched closing bracket is rejected by grammar recovery (E316); no bracket interpretation is reconstructed from recovery text.

Fixture: CHECK_023_unmatched_close_bracket.cha. Chatter regression codes: E316.

CHECK 24 — parity

Unmatched < on a main tier (open angle, no close). CLAN 24 (also 160); chatter surfaces the recovery node as E316. CLAN fires reliably here; the grounding helper guards against a depfile-load miss.

Fixture: CHECK_024_unmatched_lt.cha. Chatter regression codes: E316.

CHECK 25 — parity

Unmatched > on a main tier. CLAN 25; chatter surfaces the tree-sitter recovery node as E316 UnparsableContent.

Fixture: CHECK_025_unmatched_gt.cha. Chatter regression codes: E316.

CHECK 26 — parity

Unmatched { on a main tier. CLAN 26 (also 11, 48); chatter E316.

Fixture: CHECK_026_unmatched_open_brace.cha. Chatter regression codes: E316.

CHECK 27 — parity

Unmatched } on a main tier. CLAN 27 (also 48); chatter surfaces the recovery node as E316 UnparsableContent.

Fixture: CHECK_027_unmatched_close_brace.cha. Chatter regression codes: E316.

CHECK 28 — no_obligation

Call site commented out since 11-02-98 (check.cpp 4992, inside the dated comment block); unix and GUI builds alike can never emit it. Unbalanced parentheses surface through other codes today.

Exclusion reason: CommentedOut.

CHECK 29 — no_obligation

Call site commented out since 11-02-98 (check.cpp 4993, same comment block as CHECK 28); never emitted by any current build.

Exclusion reason: CommentedOut.

CHECK 30 — no_obligation

Compiled but unreachable in file mode: firing requires check_MatchTierName to return a colon-less declared header (ts->col FALSE) for a line that ALSO carries trailing text, but the match (check.cpp 1706, partcmp pattern mode) compares the WHOLE trimmed line against the declared name, so any trailing text makes the lookup fail first (empirically: ‘@Blank extra’, ‘@New Episode extra’, and tab-separated variants all emit (17) tier-not-declared, plus (132) for the tab forms, never (30)). No stock-depfile colon-less header contains a pattern wildcard that could match a longer line.

Exclusion reason: UnreachableInFileMode.

CHECK 31 — parity

A declared tier with a colon but no text after it (check.cpp:1748); ‘@’ headers are exempt (‘to always allow empty header tiers’), so the fixture uses an empty dependent tier ‘%fac:’. chatter answers E756 ‘Empty dependent tier’, which states the rule CHECK 31 is about. A 2026-08-15 maintainer ruling made E756 cover every free-text tier. An empty ‘*CHI:’ main tier instead yields CLAN (21)+(70), not (31). Whitespace-only content is E756 on every free-text tier, matching check_FoundText (check.cpp:1639), which skips ASCII space, tab and newline before looking for text. Two deliberate divergences, chatter stricter in both: CHECK exempts user-defined %x tiers from 31 and chatter reports them; chatter’s whitespace is Unicode whitespace, so a payload of non-breaking spaces alone is E756 while CHECK (verified 2026-09-08) reports nothing.

Fixture: CHECK_031_missing_text_after_colon.cha. Chatter regression codes: E756.

CHECK 32 — divergence

Documented divergence (maintainer ruling, 2026-07-12): a depfile-membership check. A token undeclared in a corpus optional/global depfile is not universally invalid CHAT; chatter validates universal CHAT-format validity, never external-config membership (CHAT validity must never depend on any config file). chatter deliberately accepts.

Fixture: CHECK_032_undeclared_dollar_code.cha. Chatter regression codes: none.

CHECK 33 — no_obligation

Compiled but unreachable with the stock depfile: check_matchplate returns 33 only when a tier’s declared pattern list mixes an @d/@t date-time pattern with OTHER patterns after it and the value fails everything (check.cpp 1543); when the date-time pattern is last, the specific codes 34/35 return instead. Every stock depfile @d/@t list is date-time-only (@Date, @Birth of #, @Time Duration, %tim), so failures yield (34)/(35), never (33): empirically @Date/@Birth/@ID garbage all emit (34). Reachable only via a custom user depadd.

Exclusion reason: UnreachableInFileMode.

CHECK 34 — parity

@Date is not a valid date (‘notadate’). CLAN 34 (illegal date representation); chatter E518 InvalidDateFormat.

Fixture: CHECK_034_bad_date.cha. Chatter regression codes: E518.

CHECK 35 — parity

@Time Duration 99:99:99 is shape-valid (HH:MM:SS) but out of clock range. chatter validates the shape, and TimeDurationValue::has_out_of_range_component flags components outside hours 0-23 / minutes,seconds 0-59 and emits E540. CLAN range rule grounded empirically: 25:00:00, 99:30:00, 12:60:00, 12:00:60 all CLAN 35; 23:59:59 OK. CLAN CHECK 35.

Fixture: CHECK_035_time_duration_out_of_range.cha. Chatter regression codes: E540.

CHECK 36 — parity

Utterance-delimiter followed by more material on the main tier (check.cpp:4394/4396; DelFound set, then a non-bullet, non-[ token appears). E316 (unparsable/misplaced content) rejects the same shape.

Fixture: CHECK_036_delimiter_not_at_end.cha. Chatter regression codes: E316.

CHECK 37 — parity

INCIDENTAL parity, reached by chatter’s own reasoning rather than CHECK’s. The 2026-07-12 divergence ruling still governs the RULE: CHECK 37 is a depfile-membership check, a token undeclared in a corpus depfile is not universally invalid CHAT, and chatter never validates external-config membership. The parity comes from this FIXTURE. Its word a+un#go carries a word-internal prefix marker in an English utterance, and E763 rejects the marker in any language that does not use it (heb, ara). Same verdict as CHECK on this input, different and independent grounds. A depfile-undeclared prefix in Hebrew or Arabic would still be accepted, which is the divergence the 2026-07-12 ruling protects.

Fixture: CHECK_037_undeclared_prefix.cha. Chatter regression codes: E763.

CHECK 38 — parity

A word starting with a digit on a main tier (excluding ‘0’-forms) that matches no depfile number pattern (check.cpp:4811 via check_matchnumber). E220 is chatter’s digits-in-word error. CLAN also emits (47) on the same fixture.

Fixture: CHECK_038_digits_in_utterance.cha. Chatter regression codes: E220.

CHECK 39 — no_obligation

No emission path anywhere in clan/ or lib/ (whole-source sweep 2026-07-24 covering check_err, the check_trans_err macro, and helper return-code channels); only the case-39 printer in the check_mess table exists. Tier-ordering violations surface through other codes today.

Exclusion reason: NoEmissionPath.

CHECK 40 — no_obligation

No emission path anywhere in clan/ or lib/ (whole-source sweep 2026-07-24, same method as code 39). chatter models per-tier duplication rules on its own terms where they make sense.

Exclusion reason: NoEmissionPath.

CHECK 41 — no_obligation

No emission path anywhere in clan/ or lib/ (whole-source sweep 2026-07-24). Parenthesis misuse surfaces via codes 55/111 (grounded elsewhere in this manifest); modern CHAT parenthetical shortenings are a parsed construct in chatter.

Exclusion reason: NoEmissionPath.

CHECK 42 — parity

Malformed ampersand and parenthesis input is rejected by grammar recovery (E316), without reconstructing annotation syntax.

Fixture: CHECK_042_amp_and_parens.cha. Chatter regression codes: E316.

CHECK 43 — parity

No @Begin header. chatter rejects with E504 (Missing required @Begin header in file preamble). Grounded vs real CLAN CHECK 43; audit name-matcher had marked it a gap.

Fixture: CHECK_043_missing_begin.cha. Chatter regression codes: E504.

CHECK 44 — parity

Speaker content after the @End tier. CLAN 44 (file must end with @End); chatter flags E502 MissingEndHeader (and E501). Both reject the file.

Fixture: CHECK_044_content_after_end.cha. Chatter regression codes: E502.

CHECK 45 — parity

At end of file, one or more @Bg tiers were never closed by a matching @Eg (check.cpp:5758); CHECK lists the unmatched @Bg contents after the message. E526 is chatter’s unmatched-@Bg error.

Fixture: CHECK_045_bg_without_eg.cha. Chatter regression codes: E526.

CHECK 46 — parity

An @Eg tier with no open @Bg carrying the same text (check.cpp:5391/5400). E527 is chatter’s unmatched-@Eg error.

Fixture: CHECK_046_eg_without_bg.cha. Chatter regression codes: E527.

CHECK 47 — parity

A digit inside a word (he11o). CLAN 47 (numbers not allowed inside words); chatter E220. This fixture agrees, not every scoped-language case: E220 examples 7/8 retain a paired enclosing-language substitution. CHECK 21-Sep-2026 rejects both with 47, while Chatter accepts the zho-span control under its established governing-language policy and rejects the eng-span mutation. Direct mixed/ambiguous word markers in E220 examples 3-6 agree with CHECK.

Fixture: CHECK_047_number_in_word.cha. Chatter regression codes: E220.

CHECK 48 — parity

A standalone illegal character on a main tier; ‘|’ between words reaches CHECK 48. The original bare-pipe acceptance gap was closed 2026-07-16 by E243. CLAN also emits 11 on that fixture. The separately grounded semicolon shape is covered by E769 specs: current HTML CHAT disallows main-tier semicolons, and CHECK 21-Sep-2026 rejects top-level, nested, and retraced cases with 48. Other CHECK-48 shapes remain adjudicated per-shape; this row is not a blanket claim for every call site.

Fixture: CHECK_048_illegal_char_pipe.cha. Chatter regression codes: E243.

CHECK 49 — no_obligation

Call site commented out 2019-04-23 (‘do not check for upper case letters’, check.cpp 3447 inside that comment block); never emitted by current builds. chatter’s own capitalization rules live in the validator, adjudicated separately.

Exclusion reason: CommentedOut.

CHECK 50 — parity

A second utterance delimiter after one was already found on a main tier (check.cpp:4351/4354/4554). E316 rejects ‘hello . .’.

Fixture: CHECK_050_redundant_delimiter.cha. Chatter regression codes: E316.

CHECK 51 — parity

CLAN prints this message WITHOUT a (51) suffix (format string lacks (%d)); grounding matches by message text. A ‘<…>’ angle group not followed by a ‘[…]’ code, detected at end of tier or at the next word (check.cpp:4376/4568, anb flag from check_CheckBrakets). QUIRK: CLAN prints this message WITHOUT the numeric ‘(51)’ suffix; check_mess case 51 (check.cpp) has no (%d) in its format string. Grounding is the verbatim unique message text. chatter names the same construct as a missing required element: the grammar requires a code after the group, tree-sitter inserts a MISSING placeholder for it, and the whole-tree pass reports E342. The annotation decoder skips MISSING nodes, so the group stays bare and E342 is the whole verdict (a decoder that read the placeholder’s kind would build a Full retrace nobody wrote and add E370 to a construct the file does not contain).

Fixture: CHECK_051_angle_without_square.cha. Chatter regression codes: E342.

CHECK 52 — parity

A postfix retrace has no preceding material. The grammar rejects it and source-bound recovery reports E316. Dedicated CHECK-style classification adds no validity enforcement.

Fixture: CHECK_052_retrace_without_text.cha. Chatter regression codes: E316.

CHECK 53 — parity

The duplicate-begin fixture is rejected by grammar recovery (E316); duplicate-header semantics remain on typed header validation.

Fixture: CHECK_053_duplicate_begin.cha. Chatter regression codes: E316.

CHECK 54 — no_obligation

The duplicate-end fixture is rejected by grammar recovery (E316); a recovery prefix alone does not prove a second parsed end header.

Fixture: CHECK_054_duplicate_end.cha. Chatter regression codes: E316.

Exclusion reason: UnreachableInFileMode.

CHECK 55 — parity

More ‘(’ than ‘)’ inside a single word (check.cpp:4571, pb>lpb after word scan). chatter rejects ‘ab(c d .’ via unparsable-content/terminator errors. E305 REMOVED 2026-08-11: it was a spurious “missing terminator” on a line that ends with one, caused by the lowering discarding the tier_body an ERROR node displaced. See docs/audits/2026-08-11-utterance-initial-annotation-adjudication.md.

Fixture: CHECK_055_unmatched_open_paren_word.cha. Chatter regression codes: E316.

CHECK 56 — parity

More ‘)’ than ‘(’ inside a single word (check.cpp:4572, pb<lpb). chatter rejects ‘ab)c d .’ via unparsable-content/terminator errors. E305 REMOVED 2026-08-11: it was a spurious “missing terminator” on a line that ends with one, caused by the lowering discarding the tier_body an ERROR node displaced. See docs/audits/2026-08-11-utterance-initial-annotation-adjudication.md.

Fixture: CHECK_056_unmatched_close_paren_word.cha. Chatter regression codes: E316.

CHECK 57 — parity

The word-glued pause fixture is rejected with E751. The grammar retains a word and a separate pause; model validation check_pause_glued_to_word compares their source spans in the typed content walk (spec E751). This is structural evidence, not a scan or reparse of recovery text. Under the architecture-native assessment contract, rejection stage and diagnostic identity are not parity obligations. CLAN also emits 48 on the retained fixture; no new CLAN observation is claimed.

Fixture: CHECK_057_pause_glued_to_word.cha. Chatter regression codes: E751.

CHECK 58 — no_obligation

No emission path anywhere in clan/ or lib/ (whole-source sweep 2026-07-24). The 8-character tier-name limit is a retired-era constraint; chatter’s tier-name rules are its own.

Exclusion reason: NoEmissionPath.

CHECK 59 — parity

A time bullet (\x15) opened but never closed before end of scan; hidenc stays TRUE at word end (check.cpp:4049/4797). Fixture: ‘%pho:\thello \x15123’ with no closing \x15. QUIRK: on the unix build CLAN prints the error banner with an EMPTY message line: check_mess case 59’s printf is inside ‘#if _MAC_CODE/#elif _WIN32’, so no (59) trailer and no message text ever appear. Grounded banner_only: run restricted to ‘+e59’ (block prints) and cross-checked ‘+e1’ (clean), re-confirmed 2026-07-09.

Fixture: CHECK_059_unclosed_bullet.cha. Chatter regression codes: E316.

CHECK 60 — parity

File has no @ID header. CLAN 60; chatter E522 (missing @ID header).

Fixture: CHECK_060_missing_id.cha. Chatter regression codes: E522.

CHECK 61 — parity

No @Participants header. chatter rejects with E504 (Missing required @Participants header), plus E543/E522. Grounded vs real CLAN CHECK 61.

Fixture: CHECK_061_missing_participants.cha. Chatter regression codes: E504.

CHECK 62 — parity

An @ID tier with an empty language (first) field (check.cpp:5054; also 2536 for an empty ‘word@s:’ language marker and 5023). E510 is chatter’s empty-@ID-language error. CLAN prints (62) twice on the fixture.

Fixture: CHECK_062_missing_language_in_id.cha. Chatter regression codes: E510.

CHECK 63 — parity

Empty corpus field (2nd) in @ID. chatter E514 EmptyIDCorpus. The corpus field is a required CorpusName like its siblings, and the Validate trait flags empty. CLAN CHECK 63.

Fixture: CHECK_063_empty_corpus.cha. Chatter regression codes: E514.

CHECK 64 — parity

@ID sex field is neither ‘male’ nor ‘female’ (‘x’). CLAN 64; chatter E542 UnsupportedSex. Requires CLAN’s depfile loaded (auto-resolved from the lib dir).

Fixture: CHECK_064_bad_gender.cha. Chatter regression codes: E542.

CHECK 65 — parity

A trailing @ in hello@ remains rejected by grammar recovery with E316. This witnesses one of CHECK 65’s 31 emission sites, not every special-form or morphology-marker case. E202 remains independently available at the model-validation boundary.

Fixture: CHECK_065_trailing_at_sign.cha. Chatter regression codes: E316.

CHECK 66 — parity

The ampersand-inside-word fixture is rejected by grammar recovery (E316), without guessing a word annotation or repair.

Fixture: CHECK_066_amp_inside_word.cha. Chatter regression codes: E316.

CHECK 67 — parity

A word-final ‘+’ (or ‘-’) followed by end-of-word / certain punctuation must be followed by text (check.cpp 3319/3338; the CA-char site 3025 is inside #ifndef UNX). Grounded via ‘hey+ .’; CLAN message spans two output lines, recorded with embedded newline.

Fixture: CHECK_067_trailing_plus.cha. Chatter regression codes: E233.

CHECK 68 — divergence

Deliberate divergence, resolved July 8: CHECK’s non-default +g2 option requires a CHI Target_Child participant unless @Options: notarget is present. Default-mode CHECK accepts the retained fixture, and Chatter intentionally accepts it. This option-specific requirement is not a baseline CHAT obligation. The open-policy question is resolved; clan_flags preserves the grounding configuration.

Fixture: CHECK_068_no_target_child.cha. Chatter regression codes: none.

CHECK 69 — parity

File has no @UTF8 header. CLAN 69; chatter E503 MissingUTF8Header.

Fixture: CHECK_069_missing_utf8.cha. Chatter regression codes: E503.

CHECK 70 — parity

A speaker tier containing no text word (only delimiters/pauses/brackets and not the ‘0’ placeholder) at tier end (check.cpp 4984, isTextFound never set). Fixture ‘*CHI:\t.’; chatter rejects with three codes including E306 (no meaningful content). SCOPE (2026-07-24, empirically verified live): CLAN 70 does NOT fire on pause-only ((.) .) or event-only (&=laughs .) utterances; both validators ACCEPT those shapes, so the old ‘pause-only utterance’ policy-gap framing was wrong.

Fixture: CHECK_070_no_text.cha. Chatter regression codes: E253, E306, E342.

CHECK 70 — parity

An annotation-only utterance ([=! laughs] .) is rejected by structural recovery, E316 and E342. CHECK grounding emits 73 and 70. Pause-only and event-only utterances were separately accepted by both validators; this case does not establish their invalidity. No missing-terminator or missing-whitespace claim is inferred.

Fixture: CHECK_070_annotation_only_utterance.cha. Chatter regression codes: E316, E342.

CHECK 71 — parity

INCIDENTAL parity, reached by chatter’s own reasoning rather than CHECK’s. The 2026-07-12 divergence ruling still governs the RULE: CHECK 71 enforces an ORDERING between [/] and the legacy # pause marker, a construct chatter does not have (chatter uses (.)/(..)/(…)), so chatter does not implement that ordering rule and never will. The parity comes from this FIXTURE. Its main tier is he # [/] he ., where the standalone # sits inside the retrace scope, and E762 rejects a word that is nothing but the prefix marker in any language. Same verdict as CHECK on this input, unrelated grounds. The fixture fails because word validation recurses into retraces and validates the # inside the retrace.

Fixture: CHECK_071_retrace_after_pause.cha. Chatter regression codes: E762.

CHECK 72 — parity

A pause ‘(…)’ or non-postcode ‘[…]’ item appearing after the utterance delimiter (check.cpp 4740/4744). Fixture ‘hey . (.)’; chatter rejects (unparsable content after terminator).

Fixture: CHECK_072_pause_after_delim.cha. Chatter regression codes: E316.

CHECK 73 — parity

A bracketed code as the first item of a tier with nothing before it (also bullets not preceded by text; multiple sites: check.cpp 4045, 4781, 4861; CA sites 3030/3033 are #ifndef UNX). Fixture ‘[x 2] hey .’; chatter rejects it via E316 (grammar recovery). CLAN additionally emits (11). (E747 is BlankLineNotAllowed and is not the expectation here.) Additional leading-bullet grounding is owned by spec/errors/E770.md: simple, retraced-group, linker-prefixed and repeated leading bullets report E770; explicit-zero, event, pause and preceding-group-material controls do not. CHECK 21-Sep-2026 corroborates these shapes. Parse-recovered main tiers retain their parse diagnostic rather than an E770 absence claim. This row’s bracket fixture alone does not prove every CHECK 73 site: empty inter-bullet scope and legacy multi-option behavior are not adjudicated by this fixture. They remain outside this finite baseline, not demonstrated validation defects or queued diagnostic-emulation work. A concrete independently justified CHAT requirement is needed to open a new obligation.

Fixture: CHECK_073_bracket_first.cha. Chatter regression codes: E316.

CHECK 74 — no_obligation

Sole call site commented out on 2004-04-27 (check.cpp 1762, ‘// 2004-04-27 if (check_err(74,…))’): deliberately retired 22 years ago; no build can emit it. chatter’s tier-separator rules (single :\t) are enforced by the grammar.

Exclusion reason: CommentedOut.

CHECK 75 — parity

A postcode ‘[+ …]’ occurring before the utterance delimiter (check.cpp 4747). Fixture ‘hey [+ exc] .’; chatter rejects (postcode only legal after terminator).

Fixture: CHECK_075_postcode_before_delim.cha. Chatter regression codes: E305, E316.

CHECK 76 — no_obligation

An ‘@l’ letter-marker word whose stem is more than one letter. RETIRED ON BOTH SIDES. CLAN retired error 76 on 2026-08-07 (“CHECK: allow multiple characters before @l”); check_isOneLetter and its call site sit inside a dated comment block, so no unix build emits it. chatter retired its own E754 on 2026-08-11, independently and for a stated reason: the rule counted CHARACTERS, a digraph is one letter written with two (Welsh ‘ll’, Dutch ‘ij’), so it reported a spurious error on valid CHAT and could not do better because it never saw the word’s language. Both validators accept the construct, so expected_chatter_codes is empty and the fixture pins that agreement.

Fixture: CHECK_076_multi_letter_at_l.cha. Chatter regression codes: none.

Exclusion reason: CommentedOut.

CHECK 77 — parity

File has no @Languages header. CLAN 77 (also 61); chatter E504 MissingRequiredHeader. chatter uses one generic missing-required-header code where CLAN has per-header codes; parity is on validity.

Fixture: CHECK_077_missing_languages.cha. Chatter regression codes: E504.

CHECK 78 — parity

A special delimiter word ‘+,’ ‘+“’ ‘+^’ ‘+<’ ‘++’ (exactly two chars) appearing after the first word of the tier (check.cpp 4769). Fixture ‘hey +, you .’; chatter rejects (unparsable ’ +’). Expected codes refreshed 2026-07-30 (E316 -> E766): the misplaced-linker grammar change names this construct E766 (linker not utterance-initial), the direct counterpart of CHECK 78’s message.

Fixture: CHECK_078_pluscomma_mid.cha. Chatter regression codes: E766.

CHECK 79 — parity

A %mor word with two | separators (n|dog|cat). CLAN 79 (only one | per word); chatter surfaces the malformed %mor item as E702 (a recovery node below the tier’s direct children is classified with the tier’s name).

Fixture: CHECK_079_mor_two_pipes.cha. Chatter regression codes: E702.

CHECK 80 — parity

A %mor word with no | separator (bare ‘dog’). CLAN 80 (must be at least one |); chatter E702.

Fixture: CHECK_080_mor_no_pipe.cha. Chatter regression codes: E702.

CHECK 81 — no_obligation

Call site commented out 2025-07-04 (check.cpp 4791, dated comment block); bullet-placement validity is covered by the still-live bullet codes (73, 118 was also retired the same day).

Exclusion reason: CommentedOut.

CHECK 82 — parity

A media bullet whose END time is <= its BEG time (check.cpp 3879, new-format path with @Media header). Bullet \x15500_100\x15. Note @Media file name must match the .cha basename or CLAN adds (157) noise.

Fixture: CHECK_082_end_before_beg.cha. Chatter regression codes: E362.

CHECK 83 — parity

A tier’s first bullet BEG earlier than the previous tier’s first-bullet BEG (check_tierBegTime), reachable only from the third bulleted tier on because tEndTime==0 skips the block on the first (check.cpp 3885/3890). Needs three tiers (1000_2000, 3000_4000, then 2500_2600): with only two, the tracking variable is still 0 and no error fires; a two-tier same-speaker attempt yields (133) instead. CLAN message has no trailing period.

Fixture: CHECK_083_beg_backwards.cha. Chatter regression codes: E362.

CHECK 84 — divergence

Deliberate divergence, resolved July 8: CHECK +c0 rejects a current tier’s begin time before the previous tier’s end (check.cpp:3901). Default-mode CHECK accepts the retained fixture, and Chatter intentionally permits conversational overlap. This cross-tier option-specific restriction does not replace Chatter’s independent same-speaker timing rules. clan_flags preserves the grounding configuration.

Fixture: CHECK_084_overlap.cha. Chatter regression codes: none.

CHECK 85 — divergence

Deliberate divergence, resolved July 8: CHECK +c0 rejects a gap between successive tiers’ bullets (check.cpp:3905). Default-mode CHECK accepts the retained fixture, and Chatter intentionally permits gaps. Requiring continuous coverage of the recording is not a baseline CHAT obligation. clan_flags preserves the grounding configuration.

Fixture: CHECK_085_gap.cha. Chatter regression codes: none.

CHECK 86 — parity

Shape-scoped agreement: U+E000 inside a word produces CHECK 86 and E243. Chatter independently rejects Unicode private-use scalars and noncharacters in lexical words, including supplementary planes, with no CLAN-internal exemption. Ordinary assigned high-BMP characters and U+10000 are not rejected by this policy. The recorded 21-Sep-2026 CHECK U+10000 rejection remains an intentional divergence. Canonical E243_unicode_boundaries examples cover all noncharacters, private-use endpoints, former exemption endpoints and valid controls; this row does not claim universal Unicode parity or new CHECK observations.

Fixture: CHECK_086_private_use_char.cha. Chatter regression codes: E243.

CHECK 87 — parity

A %mor/%xmor/%trn (or %cnl) word whose compound structure is malformed: a ‘+’ not in canonical ‘pfx|+a|b’ shape drives numOfCompounds to -2 or 0 (check.cpp 3592/3646). Fixture ‘%mor: n|cat+n|fish .’ (compound missing the ‘|+’ marker after the head POS). chatter rejects: E702 on the item and E600 at the tier.

Fixture: CHECK_087_malformed_compound.cha. Chatter regression codes: E702.

CHECK 88 — no_obligation

Call site commented out since 2009-06-08 (check.cpp 3414, dated comment block); never emitted by current builds. chatter’s compound/form-marker rules are adjudicated per live CHECK codes 65/66 instead.

Exclusion reason: CommentedOut.

CHECK 89 — parity

A new-format bullet whose content is not digits_digits (e.g. wrong separator) (check.cpp 3863, res==2 from check_getMediaTagInfo). Bullet \x15100x200\x15 with @Media header. chatter rejects.

Fixture: CHECK_089_bad_bullet_char.cha. Chatter regression codes: E316, E544.

CHECK 90 — parity

A bullet time component written with a leading zero before another digit, e.g. 012 (check.cpp check_getMediaTagInfo res==3, call site 3865). Fixture: \x15012_200\x15 with @Media header. chatter emits E748 at parse time from the raw component text (both bullet paths in talkbank-parser media_bullet.rs; token scan in talkbank-parser-re2c file.rs). Spec: E748.md. A bare 0 stays legal. ADJUDICATED (maintainer decision, 2026-07-10): STYLE error. Leading-zero bullet times are unambiguous; kept as an error by project policy: style violations are errors.

Fixture: CHECK_090_leading_zero_time.cha. Chatter regression codes: E748.

CHECK 91 — parity

A blank line in the transcript (CLAN flags one between utterances AND between headers, verified). CLAN CHECK 91. The grammar’s newline is a single line break (/\r\n|[\r\n]/) and a blank_line CST node represents the blank line; the parser emits E747 BlankLineNotAllowed from that node (helpers.rs line dispatch), with no source or line scan. (A fused newline: /[\r\n]+/ would erase the blank line before any node could represent it.) chatter rejects via E747.

Fixture: CHECK_091_blank_line.cha. Chatter regression codes: E747.

CHECK 92 — parity

Comma not followed by space or end-of-line on a speaker tier (check.cpp 4309-4320, with CA-mark exemptions). GAP CLOSED 2026-07-09: model validation check_comma_glued_to_next (span adjacency over walk_content; dummy spans skipped) plus a re2c token-stream mirror. Spec: E749.md. Narrowed to word-next: constructs placing their own character after the comma are exempt, matching CLAN. ADJUDICATED (maintainer decision, 2026-07-10): STYLE error. Comma-glue is unambiguous under our grammar; kept as an error by project policy: style violations are errors.

Fixture: CHECK_092_comma_no_space.cha. Chatter regression codes: E749.

CHECK 93 — parity

‘[’ immediately preceded by ‘>’ or ‘]’ with no space (check.cpp 4469/4472; CA start-marks site 3179 is #ifndef UNX). Fixture <hey>[/] hey .; CLAN also emits (161). chatter rejects via E316. (E747 is BlankLineNotAllowed and is not the expectation here.)

Fixture: CHECK_093_bracket_no_space.cha. Chatter regression codes: E316.

CHECK 94 — parity

%mor tier whose utterance delimiter differs from the speaker tier’s recorded delimiter (check.cpp 4338 simple delimiters; 4522 ‘+…’-style). ‘*CHI: hey .’ with ‘%mor: co|hey ?’. chatter rejects with the dedicated E716.

Fixture: CHECK_094_mor_delim_mismatch.cha. Chatter regression codes: E716.

CHECK 95 — no_obligation

Call site commented out (check.cpp 3300, undated comment block guarding check_err(95) behind the retired capWFound flag, itself part of the 2019-04-23 upper-case retirement); never emitted by current builds.

Exclusion reason: CommentedOut.

CHECK 96 — no_obligation

Compiled but unreachable: the emit site (check.cpp 3462) is the @Languages branch of check_CheckWords, but @Languages values are validated by check_isLangMatch (check.cpp 2165), which deliberately SPLITS each token at ‘=’ and validates only the language-code part, accepting the legacy word-color suffix; the word-level walker never visits @Languages in file mode. Empirically ‘@Languages: eng=blue’ and ‘eng, fra=blue’ pass unix CHECK clean. chatter rejects the construct as malformed header content (E320), correctly stricter.

Fixture: CHECK_096_word_color_languages.cha. Chatter regression codes: E320.

Exclusion reason: UnreachableInFileMode.

CHECK 97 — parity

‘@’ encountered inside parentheses within a word on a speaker tier (check.cpp 3360, paransFound). Fixture ‘c(a@b)t .’; CLAN also emits (147). Chatter rejects the structural error with E316; recovery does not establish an independent form-marker node for E203.

Fixture: CHECK_097_at_in_parens.cha. Chatter regression codes: E316.

CHECK 98 — parity

An old-format bullet (no @Media header) ‘\x15%snd:“NAME”_B_E\x15’ whose media file name contains a space (check.cpp 3923 via res==4; also reachable in the new-format path 3867). chatter rejects the old-style %snd bullet outright (E360), so anything CHECK flags inside it is also rejected; parity by strictness.

Fixture: CHECK_098_space_in_name.cha. Chatter regression codes: E360.

CHECK 99 — parity

Media file name ending with an extension: in old-format bullets (check.cpp 3925 via res==5, used here), in new-format path (3869), or on the @Media header (5589). Grounded via old-format bullet ‘\x15%snd:“test.wav”_100_200\x15’; chatter rejects the %snd bullet (E360). The @Media-header variant of (99) was not separately grounded.

Fixture: CHECK_099_extension_in_name.cha. Chatter regression codes: E360.

CHECK 100 — parity

Trailing comma at end of @Participants. The grammar already surfaces the dangling comma as a tree-sitter ERROR node inside the participants header; the parser reports it as E550 TrailingCommaInParticipants (parse-stage diagnostic). CLAN CHECK 100.

Fixture: CHECK_100_trailing_comma_participants.cha. Chatter regression codes: E550.

CHECK 101 — no_obligation

GUI-only: the sole call site (check.cpp 3016) sits inside the #ifndef UNX CA-character region of check_CheckWords, so unifdef -DUNX blanks it and no unix binary contains it. DERIVABLE: the generator runs unifdef before scanning, so the reference reports zero live sites and this reason is checked rather than trusted.

Fixture: CHECK_101_ca_marker_no_stem.cha. Chatter regression codes: E316.

Exclusion reason: GuiOnly.

CHECK 102 — parity

Any character carrying the italic text attribute, encoded in the file as ATTMARKER 0x02 + 0x03 (italic start) / 0x02 + 0x04 (italic end) (check.cpp: multiple is_italic() sites, e.g. 4289/4433). Fixture embeds raw bytes \x02\x03hey\x02\x04; CLAN emits (102) twice (once per attributed char run). chatter names each of the four control bytes as E315 (the lexical rule permits only the underline pairs 0x02 0x01 / 0x02 0x02) and the broken word as E316, so legacy attribute encoding cannot pass.

Fixture: CHECK_102_italics.cha. Chatter regression codes: E315, E316.

CHECK 103 — parity

@Options header (which must immediately follow @Participants) listing both ‘CA’ and ‘IPA’ (check.cpp 5478/5537). First attempt placed @Options after @ID and got first-pass (125) instead; @Options must sit right after @Participants. CLAN also emits (11) because IPA is not in the depfile @Options template. chatter rejects with E534.

Fixture: CHECK_103_ca_and_ipa.cha. Chatter regression codes: E534.

CHECK 104 — no_obligation

Both call sites commented out (check.cpp 5483/5542, inside comment blocks); the font-selection advice is GUI-editor-era and never emitted by current builds. Fonts are not a CHAT-validity property; chatter has no analogue by design.

Exclusion reason: CommentedOut.

CHECK 105 — no_obligation

Both call sites commented out (check.cpp 5487/5546, same comment blocks as CHECK 104); never emitted. Same adjudication as 104: font choice is not validity.

Exclusion reason: CommentedOut.

CHECK 106 — parity

A scoped code split across a newline ([% comment then a continuation line continued]) leaves an ERROR node in the main-tier content, which the whole-tree recovery-node backstop surfaces as E316. CLAN CHECK 106.

Fixture: CHECK_106_code_spans_newline.cha. Chatter regression codes: E316.

CHECK 107 — parity

Three or more consecutive commas on a speaker tier (check.cpp 4322; two commas give (156) instead). Fixture ‘hey ,,, you .’; CLAN also emits (156). chatter rejects (E258 twice).

Fixture: CHECK_107_triple_comma.cha. Chatter regression codes: E258.

CHECK 108 — parity

A postcode [+ trn] placed after the final time bullet leaves an ERROR node in the utterance, which the whole-tree recovery-node backstop surfaces as E316. CLAN rejects it (codes 108 and 112). CLAN CHECK 108 (co-emitted with 112).

Fixture: CHECK_108_postcode_after_bullet.cha. Chatter regression codes: E316.

CHECK 109 — divergence

A postcode-shaped token [+ trn] on a dependent tier (%com). CLAN CHECK 109 (“Postcodes are not allowed on dependent tiers”, check_CheckWords, check.cpp:3471-3690) flags it on any non-%x dependent tier. chatter does not model postcodes on dependent tiers: ordinary dependent tiers like %com parse as TextTier with no Postcode AST node, so there is nothing typed to detect, and flagging it would require a banned raw-text scan. Empirically (2026-06-25) CLAN’s own analysis tools do not choke on dependent-tier postcodes: FREQ and MLU exclude the [+ ...] token from counts exactly as on the main tier, KWAL displays the line; only CHECK flags it. CHECK 109 is a CLAN-internal pedantic check, not a CHAT-validity rule, so chatter deliberately diverges (accepts) per the parity mandate’s ‘unless CHECK is buggy / not a real validity rule’ clause. Divergence (chatter intentionally looser), not a gap.

Fixture: CHECK_109_postcode_on_deptier.cha. Chatter regression codes: none.

CHECK 110 — divergence

Deliberate divergence, resolved July 8: with non-default +cN, CHECK requires a bullet on every speaker tier (check.cpp:4915). Default-mode CHECK accepts the retained fixture, and Chatter intentionally accepts an untimed tier. Universal timing is not a baseline CHAT obligation. The retained observation uses +c1, recorded in clan_flags.

Fixture: CHECK_110_no_bullet.cha. Chatter regression codes: none.

CHECK 111 — parity

An illegal pause format: (5) (digits with no dot) instead of (.)/(..)/(…)/(n.). CLAN 111 (pause must have ‘.’); chatter rejects with E209 (also E220).

Fixture: CHECK_111_illegal_pause.cha. Chatter regression codes: E209.

CHECK 112 — parity

Timing without an @Media header is rejected by E752 (spec E752). The original CLI acceptance defect was closed July 15 under the independently justified media-declaration rule. Since September 8 the timing-evidence union includes bullets inside utterances as well as terminal bullets. CHECK also counts inline bullets; Chatter additionally counts %wor timing. These differences do not create an obligation to copy CHECK’s text scan.

Fixture: CHECK_112_missing_media.cha. Chatter regression codes: E752.

CHECK 113 — parity

A comma-separated field after the file name on @Media that is not a depfile-listed keyword (audio/video/unlinked/…). E536 is the same rule (Unsupported @Media status: ‘junkword’). E531 is extra chatter strictness: media filename ‘test’ vs fixture file name.

Fixture: CHECK_113_media_bad_keyword.cha. Chatter regression codes: E536.

CHECK 114 — parity

@Media names a media file but lists neither ‘audio’ nor ‘video’; CLAN emits (114) on the @Media line. FIXTURE REPAIRED 2026-07-09: the survey-batch copy was truncated mid-@Media-line (no utterance, no @End), so CLAN aborted first-pass with (7) and could never reach 114; the drift guard caught it. chatter rejects the keywordless @Media at parse time (E316 unparsable header line; an incidental E747 blank-line cascade fires on the newline the recovery leaves behind, deliberately not asserted).

Fixture: CHECK_114_media_no_keyword.cha. Chatter regression codes: E316.

CHECK 115 — parity

With an @Media header present, a time bullet whose content starts with %s/%m, i.e. the old ‘%snd:“file”_beg_end’ bullet format. Old-format bullet is unparsable to chatter (E316) and the file then has no timing info (E544). E531 is fixture-name noise.

Fixture: CHECK_115_old_bullet_format.cha. Chatter regression codes: E316, E544.

CHECK 116 — parity

A legacy per-line font directive is not a valid scoped comment. Grammar recovery rejects the fixture with E316; raw-text prefix classification is unnecessary.

Fixture: CHECK_116_fnt_code.cha. Chatter regression codes: E316.

CHECK 117 — parity

A pairwise CA marker (faster U+2206, slower, creaky, whisper, left-arrow-circle U+21AB, etc.) occurring an odd number of times on a main tier. Dedicated chatter code: E230 ‘Unbalanced CA delimiter (Faster): missing closing delimiter’. CLAN tracks 15 pair-wise marker types; fixture uses faster U+2206. This fixture’s parity does not imply identical replacement-scope behavior: E230 examples 2/3 retain Chatter’s once-per-authored-marker pairing. CHECK 21-Sep-2026 scans replacement text twice in check_ParseWords (whole bracket token, then target-word re-entry), cancelling a single target marker and inverting the paired/unpaired verdicts. See E230’s source-path analysis.

Fixture: CHECK_117_unmatched_faster.cha. Chatter regression codes: E230.

CHECK 118 — no_obligation

Call site commented out 2025-07-04 (check.cpp 4623, dated comment block, retired together with 81); never emitted by current builds. Delimiter-before-bullet ordering remains covered by the live bullet/delimiter codes.

Exclusion reason: CommentedOut.

CHECK 119 — parity

Retrace marker [/] with nothing after it. chatter E370 StructuralOrderError.

Fixture: CHECK_119_dangling_retrace.cha. Chatter regression codes: E370.

CHECK 120 — parity

A 2-letter (or 2-letter plus dash subtag) language code where a 3-letter ISO-639 code is expected, on @Languages, the @ID language field, [- lng] precodes, or @s codes. Dedicated chatter code: E519 “Language code ‘en’ should be 3 characters (got 2)”. Fixture uses en consistently on @Languages and @ID.

Fixture: CHECK_120_two_letter_lang.cha. Chatter regression codes: E519.

CHECK 121 — parity

An UNASSIGNED three-letter code (qzz, outside the qaa-qtz private-use range) on @Languages/@ID. CLAN emits (121) from its legacy language table; chatter rejects via the full ISO 639-3 registry (E519, InvalidLanguageCode), the authoritative modern standard. PARITY per the 2026-07-14 ruling; fixture re-grounded 2026-07-15 from qqq to qzz because qqq is registry-VALID (private use), which the original fixture conflated; see the companion private-use divergence entry.

Fixture: CHECK_121_unknown_lang.cha. Chatter regression codes: E519.

CHECK 121 — divergence

A PRIVATE-USE code (qqq, inside ISO 639-3’s reserved qaa-qtz range) on @Languages/@ID. CLAN’s fixed table lacks the private-use range and emits (121); the ISO 639-3 registry defines qaa-qtz as valid codes reserved for local use, so chatter accepts them: an intentional registry-grounded divergence, not a gap. Wild grounding 2026-07-15: no kept file uses a private-use code (typed scan of every data-json languages field), so the divergence is currently theoretical.

Fixture: CHECK_121_private_use_lang.cha. Chatter regression codes: none.

CHECK 122 — parity

@ID declares language ‘eng’ that is not present in the @Languages header (which declares ‘fra’). CLAN 122; chatter E519. NOTE: code 122 has n_call_sites=0 in the generated catalogue (emitted via an indirect call the literal check_err grep misses) but IS emittable: verified vs real file-mode CLAN. The 8-code ‘dead’ list therefore needs empirical re-verification.

Fixture: CHECK_122_id_lang_not_declared.cha. Chatter regression codes: E519.

CHECK 123 — parity

In a non-CA file, a space immediately after the speaker-prefix TAB is rejected by E758. The acceptance defect was closed July 16; @Options: CA permits alignment whitespace. The retained source analysis distinguishes the live check.cpp:1669 site from the unreachable 1673 branch. This row preserves that scoped decision, not a raw-text implementation requirement.

Fixture: CHECK_123_tab_space.cha. Chatter regression codes: E758.

CHECK 124 — parity

@Media declares unlinked but the main tier has a time bullet, so the media is in fact linked. chatter emits E552 MediaUnlinkedWithTiming via check_media_unlinked_has_no_timing, the inverse of the existing E544 (linkage without timing). Grounded empirically: unlinked+bullet -> CLAN 124; unlinked+no-bullet and linked+bullet -> no 124. CLAN CHECK 124.

Fixture: CHECK_124_media_unlinked_with_bullet.cha. Chatter regression codes: E552.

CHECK 125 — parity

@Options placed after @ID instead of immediately after @Participants. chatter E551 OptionsHeaderOutOfOrder, mirroring the @ID rule (E548/CHECK 126). CLAN CHECK 125.

Fixture: CHECK_125_options_after_id.cha. Chatter regression codes: E551.

CHECK 126 — parity

A changeable header (@Comment) sits between @Participants and the @ID block.

Fixture: CHECK_126_id_header_out_of_order.cha. Chatter regression codes: E548.

CHECK 127 — parity

A changeable header sits between the @ID block and @Birth of.

Fixture: CHECK_127_constant_header_out_of_order.cha. Chatter regression codes: E547.

CHECK 128 — parity

Group-start marker U+2039 opened on a main tier and never closed (gm > 0 at end of tier). No dedicated code; unmatched opener makes the tier unparsable (E316).

Fixture: CHECK_128_unmatched_group_start.cha. Chatter regression codes: E316.

CHECK 129 — parity

Group-end marker U+203A encountered with no open U+2039 (gm goes negative). Rejected at parse level: E316 unparsable content on the stray closer plus E305 missing terminator. Expected codes refreshed 2026-07-30 (E305, E316 -> E316): the 2026-07-29/30 stack (parse-taint cascade gate, finer recovery, specific codes) changed which codes fire; the fixture is still rejected.

Fixture: CHECK_129_unmatched_group_end.cha. Chatter regression codes: E316.

CHECK 130 — parity

Sign-group-start marker U+3014 opened and never closed (sgm > 0 at end of tier). No dedicated code; rejected as unparsable (E316).

Fixture: CHECK_130_unmatched_sign_group_start.cha. Chatter regression codes: E316.

CHECK 131 — parity

Sign-group-end marker U+3015 with no opener (sgm goes negative). Rejected at parse level (E316 + E305). Expected codes refreshed 2026-07-30 (E305, E316 -> E316): the 2026-07-29/30 stack (parse-taint cascade gate, finer recovery, specific codes) changed which codes fire; the fixture is still rejected.

Fixture: CHECK_131_unmatched_sign_group_end.cha. Chatter regression codes: E316.

CHECK 132 — parity

A tab in the middle of a main tier. chatter rejects it (E370, unexpected tab). Grounded vs real CLAN CHECK 132.

Fixture: CHECK_132_tab_midline.cha. Chatter regression codes: E370.

CHECK 133 — parity

With linked media, a bullet whose BEG time is more than 500 ms earlier than the same speaker’s previous bullet END time. Dedicated chatter code: E704 ‘Speaker CHI overlaps with self: utterance 1 ends at 5000ms…’. E531 is fixture-name noise. CLAN threshold is >500ms (check.cpp:3892-3896); chatter’s exact threshold not probed by this survey.

Fixture: CHECK_133_overlap_same_speaker.cha. Chatter regression codes: E704.

CHECK 134 — parity

A %mor/%trn (or %cnl) item of the form unk|xxx, unk|yyy, or *|www (mor output for untranscribed material). chatter rejects via alignment (E706: main tier has 0 alignable items, %mor has 1) because xxx is not %mor-alignable; there is no dedicated unk|xxx rule. A hypothetical fixture where counts still align was not probed.

Fixture: CHECK_134_mor_unk_xxx.cha. Chatter regression codes: E706.

CHECK 135 — parity

A main-tier word that is exactly ‘xx’ or ‘yy’ (case-insensitive); %cnl tiers also flag bare ‘gen’ and ‘^’. Dedicated chatter code: E241 ‘“xx” is not legal; did you mean to use “xxx”?’. Only the main-tier xx call site (check.cpp:3138) was grounded; the %cnl sites (3613, 3632) were not separately probed.

Fixture: CHECK_135_bare_xx.cha. Chatter regression codes: E241.

CHECK 136 — parity

Open curly quote U+201C on a tier with no matching close quote (qt > 0 at end of tier). E242 is decided from CST structure and names the unmatched OPEN quote as well as the close-quote case (CHECK 137).

Fixture: CHECK_136_unmatched_open_quote.cha. Chatter regression codes: E242.

CHECK 137 — parity

Close curly quote U+201D with no preceding open quote (qt goes negative). Dedicated chatter code: E242 ‘Unmatched curly quote ” found on the tier’. Expected codes refreshed 2026-07-30 (E242, E305 -> E242): the 2026-07-29/30 stack (parse-taint cascade gate, finer recovery, specific codes) changed which codes fire; the fixture is still rejected.

Fixture: CHECK_137_unmatched_close_quote.cha. Chatter regression codes: E242.

CHECK 138 — parity

A right single curly quote U+2019 inside a word. CLAN 138; chatter E256 IllegalCurlyQuote (both parsers reject U+2018/U+2019).

Fixture: CHECK_138_curly_u2019.cha. Chatter regression codes: E256.

CHECK 139 — parity

A left single curly quote U+2018 at the start of a word. CLAN 139; chatter E256 IllegalCurlyQuote.

Fixture: CHECK_139_curly_u2018.cha. Chatter regression codes: E256.

CHECK 140 — parity

%mor tier does not align item-for-item with its speaker tier (createMorUttline sets mor_link.error_found). Dedicated chatter code: E705 ‘Main tier has 2 alignable items, but %mor tier has 1 items’.

Fixture: CHECK_140_mor_size_mismatch.cha. Chatter regression codes: E705.

CHECK 141 — parity

A [: text] replacement preceded by a group ‘>’, another ‘]’, nothing, a pause, or an &/+ form instead of exactly one plain word. chatter’s grammar does not accept a replacement after a group, so it rejects at parse level (E316 on <big dog> [: doggy]); no dedicated code. Expected codes refreshed 2026-07-30 (E316, E747 -> E316): the 2026-07-29/30 stack (parse-taint cascade gate, finer recovery, specific codes) changed which codes fire; the fixture is still rejected.

Fixture: CHECK_141_replacement_after_group.cha. Chatter regression codes: E316.

CHECK 142 — parity

The role field (field 8) of @ID differs from the role declared for that speaker on @Participants. Dedicated chatter code: E532 “Speaker ‘CHI’ has role ‘Mother’ on @ID but ‘Target_Child’ on @Participants”.

Fixture: CHECK_142_id_role_mismatch.cha. Chatter regression codes: E532.

CHECK 143 — parity

@ID line whose pipe-separated field count is not exactly 10. chatter rejects via E342 (missing required ‘pipe’), a parse-level equivalent.

Fixture: CHECK_143_id_field_count.cha. Chatter regression codes: E342.

CHECK 144 — parity

@ID SES field is an undeclared value (‘XYZ’). CLAN 144 (illegal SES / not declared in depfile); chatter E546 UnsupportedSesValue. The parity claim covers unknown tokens, not identical separator policy. CHECK’s check_ses skips commas/whitespace and validates each remaining token against either vocabulary (check_matchplate/check_SES_item); it has no pair-completeness check. E546_vocabulary records acceptance of ‘,MC’, ‘White,’ and comma-only input by CHECK 21-Sep-2026, versus Chatter’s existing stricter complete-pair policy.

Fixture: CHECK_144_bad_ses.cha. Chatter regression codes: E546.

CHECK 145 — no_obligation

Call site commented out 2019-04-17 with the comment ‘leave this to CHATTER’ (check.cpp 4602): CLAN explicitly delegated this rule’s future to this project. Never emitted by current builds. If the paired-marker interaction rule is wanted, it is a fresh chatter rule to design, not a parity obligation.

Exclusion reason: CommentedOut.

CHECK 146 — parity

A main-tier word that is exactly ‘&=’ with no code after the equals sign. Rejected at parse level: E316 ’Unparsable content on main tier: &= ’. Expected codes refreshed 2026-07-30 (E305, E316 -> E316): the 2026-07-29/30 stack (parse-taint cascade gate, finer recovery, specific codes) changed which codes fire; the fixture is still rejected.

Fixture: CHECK_146_bare_amp_eq.cha. Chatter regression codes: E316.

CHECK 147 — parity

An undeclared special-form marker foo@zzz. CLAN CHECK 147. The grammar intentionally consumes @zzz as one form_marker token (parse-don’t-validate), and the conversion requires the @z: colon (the only valid user-defined form is @z:label); @zXXX without the colon falls through to the E203 InvalidFormType branch in both the tree-sitter and re2c conversions. chatter rejects it via E203.

Fixture: CHECK_147_undeclared_form_marker.cha. Chatter regression codes: E203.

CHECK 148 — parity

Space before the comma in @Media. Chatter has its own named rule for it, E767, so the header parses and the diagnostic names the space (a header that failed to parse would fall back to E525, unknown header type, about a header chatter had recognised, plus E330, missing media_type, on a line visibly ending in , audio). Both validators reject, and both say why.

Fixture: CHECK_148_media_space_before_comma.cha. Chatter regression codes: E767.

CHECK 149 — parity

A skip character other than space/comma/‘<’/‘>’/newline (e.g. an utterance terminator ‘.’) sitting between a word and a following […] code. Fixture ‘dog . [: doggy] .’ also draws CLAN (50) extra-delimiter noise; chatter rejects the same configuration as unparsable (E316 on ‘[: …’).

Fixture: CHECK_149_char_before_code.cha. Chatter regression codes: E316.

CHECK 150 — parity

A ‘)’ with no matching ‘(’ in the non-skip material scanned back from a […] code. chatter rejects ‘dog) [/] dog’ as unparsable (E316 on ‘) [/] dog’). E305 REMOVED 2026-08-11: it was a spurious “missing terminator” on a line that ends with one, caused by the lowering discarding the tier_body an ERROR node displaced. See docs/audits/2026-08-11-utterance-initial-annotation-adjudication.md.

Fixture: CHECK_150_paren_before_code.cha. Chatter regression codes: E316.

CHECK 151 — no_obligation

Compiled into the unix build but never reached. Not gui_only: the check_err(151,…) site is at check.cpp 2980, inside helper check_isThereStem, which ends before the #ifndef UNX region begins at 2991. The site therefore survives unifdef -DUNX. What the region excludes is the helper’s ONLY caller, at 3013, so under -DUNX the function is compiled and never invoked. The emit path does not sit behind the #ifndef UNX region; only the caller does.

Fixture: CHECK_151_only_repetition_segments.cha. Chatter regression codes: E753.

Exclusion reason: UnreachableInFileMode.

CHECK 152 — parity

A [- CODE] utterance precode whose language is absent from @Languages. CLAN emits (152) via the indirect check_isLangMatch(wh=152) call at check.cpp 4194/5501, which the reference JSON’s literal check_err(N,) counter misses, so 152 is not in the dead list (the coverage tool auto-reclassifies once this entry exists). Adjudicated MEANINGFUL and closed as E755 per the @s-declaration ruling (docs design 2026-07-15, part 3): utterance-level presence is substantial and belongs in @Languages; wild grounding 0 of 7,167 precode-bearing files violate. Deliberate contrast: word-level @s:CODE carries NO declaration requirement (part 1 of the same ruling; the pre-2019 CHECK behavior and the retired E254 warning are explicitly NOT adopted: CLAN itself relaxed @s in 2019). SECOND FACET (2026-07-24): the other call site (check.cpp 5501) validates each token of an @New Language: header against CLAN’s static language table; @New Language is extinct in the kept corpus (0 files, rg sweep), and chatter rejects the whole header as unknown (E525 + E316), strictly subsuming the language-table facet.

Fixture: CHECK_152_undeclared_precode_lang.cha. Chatter regression codes: E755.

CHECK 153 — parity

@ID age with a component missing its leading zero (2;6. instead of 2;06.). CLAN 153; chatter E517 InvalidAgeFormat.

Fixture: CHECK_153_age_no_leading_zero.cha. Chatter regression codes: E517.

CHECK 154 — no_obligation

Call site commented out after four days in service (‘in 2018-10-03 out 2018-10-07’, check.cpp 5752); never emitted by current builds. Media/bullet consistency is adjudicated under the live codes (112 ruling of 2026-07-14 covers the meaningful direction: bullets require @Media).

Exclusion reason: CommentedOut.

CHECK 155 — parity

A non-pause word fully wrapped in parentheses, ‘(word)’, which should be written 0word (in a non-CA file). chatter rejects via E209 ‘Word has no spoken content’ (a fully-parenthesized word has no spoken material); not a dedicated use-0word rule but the same construct is refused.

Fixture: CHECK_155_paren_word.cha. Chatter regression codes: E209.

CHECK 156 — parity

A literal ‘,,’ (exactly two commas) on a main tier where the tag marker U+201E is required. Dedicated chatter code: E258 ‘Consecutive commas in utterance’.

Fixture: CHECK_156_double_comma.cha. Chatter regression codes: E258.

CHECK 157 — parity

@Media filename (‘differentname’) does not match the datafile basename. chatter has E531 MediaFilenameMismatch, which runs through the CLI because the file stem is threaded through validate_single_file_streaming. CLAN exempts remote URL @Media (verified: @Media: "https://..." -> no 157), so E531 exempts URLs too. CLAN CHECK 157.

Fixture: CHECK_157_media_name_mismatch.cha. Chatter regression codes: E531.

CHECK 158 — parity

A [: replacement] whose content is 0…, xxx/xx, yyy/yy, or www/ww instead of a real word. Dedicated chatter code: E391 ‘Replacement word cannot be untranscribed (xxx, yyy, www)’.

Fixture: CHECK_158_replacement_xxx.cha. Chatter regression codes: E391.

CHECK 159 — parity

A pause before its retrace marker is rejected by the grammar with E316. Canonical E375 pause-order controls retain valid marker-before-pause forms. No dedicated pause-order diagnostic or inferred missing-space advice is required.

Fixture: CHECK_159_pause_before_retrace.cha. Chatter regression codes: E316.

CHECK 160 — parity

Space directly after ‘<’ or before ‘>’ in an angle group (check.cpp 4300/4306, main + %wor tiers). The grammar models the tolerated whitespace as explicit optional CST nodes; the group parser reports E750 at each (both sides) rather than silently dropping them (which would also silently rewrite the text on normalize); re2c mirrors via LessThan/Whitespace/GreaterThan token windows. Spec: E750.md. Main-tier groups covered; %wor angle groups not separately grounded. ADJUDICATED (maintainer decision, 2026-07-10): STYLE error, no ambiguity whatsoever; legitimately caught as style discipline; kept as an error.

Fixture: CHECK_160_space_in_angle.cha. Chatter regression codes: E750.

CHECK 161 — parity

The grammar requires whitespace before a replacement. The glued fixture is rejected by E316; the spaced form remains legal. No replacement parser is reconstructed from recovery text.

Fixture: CHECK_161_no_space_before_replacement.cha. Chatter regression codes: E316.


This page last changed: 2026-10-02 (commit 2d7e886b). The whole book last changed: 2026-10-07 (commit 5e895791).