Skip to content

fix: preserve common abbreviation continuations - #155

Merged
mldangelo-oai merged 37 commits into
mainfrom
mdangelo/codex/rouge-abbreviation-continuations-20260824
Sep 15, 2026
Merged

mldangelo-oai merged 37 commits into
mainfrom
mdangelo/codex/rouge-abbreviation-continuations-20260824

Conversation

@mldangelo-oai

@mldangelo-oai mldangelo-oai commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

Summary

Keeps standard versus comparisons and U.S. Senate/Commission phrases together while preserving supported terminal-versus boundaries. Both existing spellings, vs. and v.s., share the same rules, including numeric and lowercase line wraps. Question/exclamation marks and explicit paragraphs outside open delimiters remain sentence boundaries.

Terminal versus inside completed ASCII/Treebank quotations releases a following letter- or number-starting sentence; existing quantity fragments stay attached. Complete standalone bracket clauses can end a sentence. Quoted labels respect pending enclosing quotations and brackets. Embedded main-sentence comparisons such as He noted (Linux vs.\n\nWindows) today. remain attached across paragraphs. Bracket state ignores quoted literal brackets in double, Treebank, paired plain-single, and existing smart quotation forms while separate omission-marker evidence preserves quoted [...] behavior.

The broad comma-clause guess was removed. Versus-specific continuation checks use existing copula/pronoun evidence, and other abbreviations retain their prior continuation inputs and Unicode case-folded evidence. Genuine terminal-versus statements clear provisional bracket context; other bare abbreviations retain enclosing context. Spaced Treebank closers, escaped angle quotations, and embedded parentheses across physical line wraps are covered.

Angle matching uses a byte mask and scalar depths, with linear scans and no nesting cap. Quotation scans reuse validated closer positions and monotone cursors, skip matched spans, respect odd/even escape parity, and prevent bounded leading elisions from borrowing a closer across a later independent quotation.

Bracket tracking reuses the existing matched-quote recognizer and monotone cursor, retaining contraction, possessive, and leading-elision controls without changing general quotation-boundary policy.

An inner single or double quote cannot release a pending recognized outer quotation; fully consumed outer and Treebank closers retain boundary behavior. Cached escape validation prevents repeated backslash-run scans across leading-elision candidates. The bounded leading-elision forms include tis/twas, numeric prefixes, cause/em/til/till; genuinely paired quotations with those spellings remain recognized.

Confirmed unspaced bracket boundaries retain their identity through abbreviation handling. Wrapped final embedded clauses normalize with their prefix, and unmatched unquoted > markers stay with following text. Quoted literal markers retain their existing behavior. Later-opener checks use the same escape-aware quote recognizer as the angle scan.

Paired closing quotation marks remain attached when followed immediately by an opening bracket; the unspaced boundary shortcut reuses the existing paired closing offset.

Isolated paired single backticks protect literal angle operators; doubled Treebank quotes keep precedence. Provisional versus context uses the same leading-delimiter normalization as the existing pronoun continuation rule.

Confirmed paired quotation endpoints protect escaped literal brackets and keep inner ASCII/Treebank closers from releasing a pending outer span. Sparse source chunk metadata prevents the versus paragraph override from splitting a still-pending paired quotation. Ordinary copular periods can still divide a multi-sentence quotation; only consuming an inner closer requires the outer endpoint to be complete.

The pronoun continuation rule requires the existing pronoun to end before any Unicode identifier or dash continuation. Hyphenated and accented opponent names stay attached, while genuine pronouns and apostrophe contractions retain their supported boundary.

Documented ambiguities

  • Unmarked remains vs. Tomorrow... and vs.Tigers retain comparison precedence; a broad following-clause rule would split valid Android vs. Windows is common. comparisons.
  • Terminal copular The abbreviation is vs. can end a sentence within a longer quotation, including a missing final quote. This preserves the original vs. behavior; v.s. standardization intentionally adopts that preference. A complete quotation may contain multiple sentences.
  • Existing IT/it pronoun ambiguity remains. Copular is v.s. rather than versus retains the terminal preference in neutral mode.
  • Outside quantity-fragment guards, quoted versus followed by 2 days later and 2 days passed shares the numeric-sentence preference.
  • Provisional U.S. (He wrote vs.) Alice replied. remains one span, consistently with v.s. and protected e.g./Co. parentheticals. This is an introduced conservative attachment tradeoff for vs.; the claimed intermediate U.S. split did not reproduce.
  • Existing titlecase line-wrap inference may normalize a single newline before a heading/list prefix, such as The Giants vs.\n# Results are below.; this PR does not add Markdown parsing.
  • Standalone (android vs.\n\nwindows) retains the base paragraph split, unlike an embedded clause in a main sentence.
  • Ambiguous s-ending apostrophes retain first-compatible-closer precedence; importing an uppercase possessive cue would introduce neutral-case divergence.
  • Unmarked paired mathematical signs and literal angle delimiters, and some same-family quotation/elision interpretations, remain structurally ambiguous. Neutral Co. followed by a physical line break retains its prior boundary preference.

Angle matching uses lexical paired delimiters. The established Treebank pair and isolated single-backtick cue do not constitute a Markdown or HTML parser; arbitrary backtick-run lengths and HTML element contents retain that ambiguity. Exact multi-backtick and HTML cross-sentence examples keep their baseline output.

Word-final apostrophes such as rockin' can be elisions or real quotation closers. The introduced quoted-versus policy retains closing-quote priority, as required by actual quoted words followed by independent versus sentences; no growing word-final elision vocabulary guesses the intended reading.

Paired single-backtick literals reuse the existing quote endpoint cache for all surrounding bracket types, so literal bracket marks cannot prematurely release a quoted versus boundary. Unpaired backticks remain ordinary punctuation under the existing rule. The original unmatched compact-angle comparison before a blank paragraph still follows the conservative buffer delimiter policy; this baseline limitation is separate from matched-angle recognition.

Backslash parity keeps escaped bracket marks literal in the source bracket state and matched-angle prepass. German low-double/low-single quotations share the existing endpoint cache in both scans; complete inner English pairs retain their role before a compatible German closer. The existing reverse angle-mask phase is unchanged. Quotation-role ambiguity still uses bounded structural preferences.

Second-person You retains the original comparison preference: both Me vs. You won the match. and a possible new sentence beginning You remain joined without stronger evidence. The bounded supported pronoun rule is not a full subject parser; no new vocabulary is added for this baseline ambiguity.

Unquoted copular-versus boundaries retain the original cased-start gate; numeric starts such as The abbreviation is vs. 2026 brought changes. remain joined. Standalone smart-quote terminals and smart-quoted next starts retain the original general boundary policy, including the unspaced form. Smart paired endpoint recognition in this change protects enclosing quotation/bracket context and does not add a general smart-quote terminal parser.

Single guillemets (‹…›) now share the existing quote endpoint cache in both bracket and angle scans. Literal brackets inside these quotations stay quoted; real surrounding closers and escape parity retain their existing roles.

An unterminated tail after a physical wrap, such as android vs.\nWindows or 2026 U.S.\nSenate, retains the inherited two-fragment result. The supported completed-sentence wraps normalize to one span; this change does not add a general fragment parser.

Integration and validation

This head incorporates the landed #156/#169/#173 fixes. The parser preserves list-marker ownership, full Unicode initial context, whole-summary case folding, and both ROUGE-L work limits. A terminal guard uses an early continue to keep the combined scanner within the existing complexity limit.

  • Combined validation: 1,343 tests passed, single process; 98.32% branch coverage. Source/test types, strict installed Biome, Markdown, build, and packed CJS/ESM/TypeScript consumers passed.
  • Independent retention review preserves all 441 original PR test groups and all 515 dependency groups, including the separate Sigma regression; 598 combined groups, including 10 new single-guillemet cases.
  • The existing local toolchain was reused. Declared Biome 2.5.13 and Node types 24.13.4 were not installed on this devbox; the published-head CI matrix validates the lockfile and supported Node versions.
  • Original angle-mask comparisons and memory evidence remain recorded for unchanged implementation bytes; they are not presented as new executions.
  • Final current-head code/security/Copilot reviews and CI are required before merge. The resulting fix: retain combining marks in dotted identifiers #169 main commit has passed all applicable CI.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Aug 24, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-15T11:13:10.188906Z 9d97d7b Manual request
🔒 Security Review Completed 2026-09-15T11:15:29.226202Z 9d97d7b Manual request

Security findings

Advisory findings (1)

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@mldangelo-oai

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Security review completed. No security issues were found in this pull request.

Reviewed commit: 99614ba7e9

View security finding report

Only the user who started this review can view the report in Codex.

ℹ️ About Codex security reviews in GitHub

This is an experimental Codex feature. Security reviews are triggered when:

  • You comment "@codex security review"
  • A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review

Once complete, Codex will leave suggestions, or a comment if no findings are found.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 99614ba7e9

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/utils.ts
Comment thread src/constants.ts
Comment thread src/utils.ts
@mldangelo-oai

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Security review completed. No security issues were found in this pull request.

Reviewed commit: 106f403ffe

View security finding report

Only the user who started this review can view the report in Codex.

ℹ️ About Codex security reviews in GitHub

This is an experimental Codex feature. Security reviews are triggered when:

  • You comment "@codex security review"
  • A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review

Once complete, Codex will leave suggestions, or a comment if no findings are found.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 106f403ffe

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/utils.ts Outdated
Comment thread src/utils.ts Outdated
@mldangelo-oai

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Security review completed. No security issues were found in this pull request.

Reviewed commit: 3064f92f53

View security finding report

Only the user who started this review can view the report in Codex.

ℹ️ About Codex security reviews in GitHub

This is an experimental Codex feature. Security reviews are triggered when:

  • You comment "@codex security review"
  • A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review

Once complete, Codex will leave suggestions, or a comment if no findings are found.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3064f92f53

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/utils.ts Outdated
Comment thread src/utils.ts Outdated
@mldangelo-oai

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Security review completed. No security issues were found in this pull request.

Reviewed commit: 6042c78239

View security finding report

Only the user who started this review can view the report in Codex.

ℹ️ About Codex security reviews in GitHub

This is an experimental Codex feature. Security reviews are triggered when:

  • You comment "@codex security review"
  • A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review

Once complete, Codex will leave suggestions, or a comment if no findings are found.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

Four unresolved moderate findings in src/utils.ts need to be addressed.

Pull request overview

Fixes sentence segmentation for vs. continuations and U.S. geographic phrases.

Changes:

  • Adds vs to abbreviation tables.
  • Updates handling for U.S. Senate and U.S. Commission.
  • Adds segmentation and ROUGE-L regression tests.
File summaries
File Summary
test/tests.ts Adds regression coverage for abbreviation and geographic phrase handling.
src/utils.ts Updates boundary logic. Four unresolved moderate findings (1 vote each) affect paragraph preservation, unspaced U.S. splits, vs. proper-name handling, and geographic continuation logic.
src/constants.ts Registers vs abbreviations.
Review details

Suppressed comments (4)

src/utils.ts:367

  • The paragraph exception is not reached when the wrap contains two line terminators: abbreviation still ends in \n/\r\n, so abbrvReg.test(abbreviation) is false and execution falls through to the startsWithTitleCase merge branch. As a result, inputs such as the new U.S.\n\nSenate cases are joined instead of preserving the paragraph boundary. Trim all whitespace before the abbreviation match while retaining the original suffix for the paragraph check.
            !/[\r\n][^\S\r\n]*[\r\n]/.test(suffix.replace(/\r\n/g, '\n'))

src/utils.ts:799

  • The new unspaced U.S.Senate/U.S.Commission cases still cannot split at the U.S. period. isUnspacedSentenceBoundary reaches this branch with isAbbreviationException false, but the later dottedIdentifier condition matches the S. suffix followed by the capitalized continuation and suppresses the boundary. Exclude geographic acronyms from that dotted-identifier suppression so the expected unspaced-boundary assertions can pass.
    abbrvReg.test(gateSuffix) && isAbbreviationException(gateSuffix, following);

src/utils.ts:141

  • This broad independent-sentence check misclassifies proper-name continuations after vs.. For example, The Giants vs. Boston Celtics, which was televised. matches Boston Celtics, and therefore splits at vs., even though the comma-terminated phrase is the opponent name. Please narrow the terminal-sentence heuristic or add a proper-name guard before treating this continuation as independent.
        independentSentenceReg.test(continuation) ||
        /^(?:this|that|these|those|it|we|they|he|she|i)\b/i.test(continuation))

src/utils.ts:407

  • Adding senate and commission to this shared continuation regex also affects the normal abbreviation-merge branch below. For U.S.Senate/U.S.Commission, sentenceChunks creates a boundary at U.S., but nextChunk has no separating whitespace and this condition still classifies it as a geographic continuation, so the else branch appends it and defeats the new unspaced-boundary expectations. Restrict this guard to whitespace-separated chunks (or use a separate predicate) so those boundaries remain splits.
          !isAbbreviationException(gateSuffix, nextChunk) &&
          !(
            geographicAcronymReg.test(gateSuffix) &&
            geographicContinuationReg.test(nextChunk.trim())
          )
  • Files reviewed: 3/3 changed files
  • Comments generated: 0
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@mldangelo-oai

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

🛡️ Codex Security Review · Automatically triggered

Security review completed. No security issues were found in this pull request.

Reviewed commit: 0af2de6b6c

View security finding report

Only the user who started this review can view the report in Codex.

ℹ️ About Codex security reviews in GitHub

This is an experimental Codex feature. Security reviews are triggered when:

  • You comment "@codex security review"
  • A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review

Once complete, Codex will leave suggestions, or a comment if no findings are found.

@mldangelo-oai

Copy link
Copy Markdown
Contributor Author

Reviewed all four suppressed Copilot suggestions. Fixed the genuine opponent-name split in 0af2de6b6c64efdf75d9686d676b8bd942b10972: The Giants vs. Boston Celtics, which was televised. stays together after removing the broad comma-clause exception from the vs. helper.

The other three suggestions do not reproduce: CR/LF paragraph boundaries and U.S.Senate/U.S.Commission unspaced boundaries pass the existing regression tests in both segmentation modes, and direct bundled probes agree. The captured chunk boundaries already preserve the necessary context, so no additional guards are warranted. Full validation passes all 756 tests, types, Biome, and packed consumers.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0af2de6b6c

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/utils.ts Outdated

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Unresolved moderate issues remain around quoted continuations and paragraph-boundary detection.

Get a fresh assessment by requesting another Copilot review.

Review details

Suppressed comments (3)

src/utils.ts:367

  • These geographic continuation checks are bypassed for the normal line-wrap shape. sentenceChunks emits the separator (\n, \n\n, etc.) as its own chunk, so the pending buffer reaches this branch with gateSuffix ending in the newline; trimEnd() only removes spaces, making abbrvReg.test(abbreviation) false. The fallback chunk.startsWithTitleCase then merges both U.S.\nSenate and U.S.\n\nSenate, collapsing the paragraph boundary (and similarly the quoted case). Apply the blank-line-aware distinction on the pending-separator path before merging.
          !(
            geographicAcronymReg.test(abbreviation) &&
            geographicContinuationReg.test(nextChunk?.trimStart() ?? '') &&
            !/[\r\n][^\S\r\n]*[\r\n]/.test(suffix.replace(/\r\n/g, '\n'))
          )

src/utils.ts:356

  • vs is now treated as an exception for every title-cased continuation, but the line-wrap fallback does not distinguish a paragraph break. For The Giants vs.\n\nBoston Celtics, which was televised., isAbbreviationException makes the first branch false and the startsWithTitleCase fallback joins the chunks, losing the blank-line boundary. The paragraph check added for geographic continuations should also cover this vs. path (or the fallback should refuse to merge across a paragraph).
          !isAbbreviationException(abbreviation, nextSentence) &&

src/utils.ts:366

  • The paragraph test only works when both line terminators fit in SentenceBuffer.suffix, but that suffix is capped at sentenceSuffixLength (10 here). A formatted blank line such as U.S.\n \nSenate voted. truncates the first newline from the suffix, so this regex sees no paragraph and the new geographic continuation is merged into the preceding sentence. Detect the paragraph separator from the full buffered text (or carry that fact separately) rather than from the bounded suffix.
            !/[\r\n][^\S\r\n]*[\r\n]/.test(suffix.replace(/\r\n/g, '\n'))
  • Files reviewed: 3/3 changed files
  • Comments generated: 1
  • Review effort level: Lite

Comment thread src/utils.ts Outdated
@chatgpt-codex-connector

Copy link
Copy Markdown

🛡️ Codex Security Review · Automatically triggered

Security review completed. No security issues were found in this pull request.

Reviewed commit: eff69bcd83

View security finding report

Only the user who started this review can view the report in Codex.

ℹ️ About Codex security reviews in GitHub

This is an experimental Codex feature. Security reviews are triggered when:

  • You comment "@codex security review"
  • A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review

Once complete, Codex will leave suggestions, or a comment if no findings are found.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

Four unresolved moderate findings remain in src/utils.ts, involving repeated scans and smart-quote boundary handling.

Review details

Suppressed comments (4)

src/utils.ts:687

  • This still becomes quadratic for the repeated leading-elision case: after the closer is cached, every candidate calls hasLaterAngleElisionOpening(input, start, found) and rescans all later openers. The 50,000-candidate regression input in test/tests.ts:3688 therefore repeatedly traverses the same suffix and can exceed its 3-second limit; cache the next valid elision opener or advance a shared cursor instead of scanning from each start (the claimed linear/monotone scan is not achieved here).
      return hasLaterAngleElisionOpening(input, start, found) ? -1 : found + closer.length;

src/utils.ts:1008

  • closingDelimiterEnd only consumes ASCII/Treebank closers, even though pairedBracketQuoteEnd now recognizes the smart-quote endpoints. For example, He wrote “vs.” Alice explained. stops at the period before ; the next character is neither whitespace nor a cased character, so the quoted-versus boundary is lost and the whole input remains one sentence. Consume the validated smart closer (including the spaced-closer path) and have closingDelimiterContext treat that endpoint as a completed quotation.
      closingDelimiterReg.test(input[end]) &&
      !isUnmatchedAngleCloser(input, end, quotePending, brackets)
    ) {

src/utils.ts:369

  • The new versus continuation path strips only ASCII quote/bracket openers from nextChunk. With a supported smart opener, The standard abbreviation is vs. “This is clearer.” leaves at the start, so both startsWithCasedCharacter and strIsTitleCase fail and the terminal vs. is merged with the next sentence. Normalize the same supported opening-quote set here and in the non-line-break path at line 424.
        const nextSentence = nextChunk?.replace(/^[\s"'([{<]+/, '');

src/utils.ts:1174

  • The unspaced-delimited shortcut still recognizes only ASCII opening quotes. Consequently Use vs.“Alice replied.” cannot take this path: sentenceEnd sees the non-whitespace after the period and rejects the boundary, so the two sentences stay joined. Share the supported quote-opener predicate (including the smart/Treebank forms recognized above) instead of hard-coding this narrower character class.
  if (
    insideQuotes ||
    index < brackets.bracketQuoteEnd ||
    brackets.depth > 0 ||
    !/["'([{<]/.test(input[next] ?? '')
  ) {
  • Files reviewed: 3/3 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: eff69bcd83

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/utils.ts
@mldangelo-oai

Copy link
Copy Markdown
Contributor Author

Individual dispositions of Copilot review PRR_kwDOMlO9es8AAAABNj7siQ at unchanged eff69bc:

  1. repeated leading-elision quadratic claim: REJECTED_FALSE_PERFORMANCE_CLAIM. The exact 50,000-candidate input cited from the regression test completes in148ms on the frozen eff69 bundle, preserving its250,003 characters and one span; the full952-test run also passed its3-second limit. Scaling controls with1k/2k/4k/8k curly and ASCII candidates remain linear. A curly candidate stops at the next valid opener; skipped escaped/word-internal marks cannot themselves become later valid candidates. For ASCII, the first compatible closer cannot cross a later valid unescaped opening mark. The shared closer cache therefore does not imply repeated whole-tail traversal in this routine.

  2. standalone smart-quote closer boundary: REJECTED_BASELINE_SCOPE_LIMIT. He wrote “vs.” Alice explained. and the v.s. sibling remain one span on originalbase, immediateparent andeff69 in both modes. The added smart endpoint recognition protects paired surrounding quotations/brackets; it does not replace the general standalone smart-quote terminal policy. The PR body now explicitly names the existing ASCII/Treebank quoted-terminal scope. Expanding smart terminal consumption would be a separate general quotation grammar change.

  3. smart opening quote after terminal copular versus: REJECTED_BASELINE_SCOPE_LIMIT. The standard abbreviation is vs. “This is clearer.” and its v.s. sibling remain one span on originalbase, immediateparent andeff69 in both modes. This is the same existing smart-delimiter start limitation, not a new versus continuation regression. The retained cased-start normalization and paired enclosure protection are documented separately; no global quote-opener vocabulary expansion is made.

  4. unspaced smart opening quote after versus: REJECTED_BASELINE_SCOPE_LIMIT. Use vs.“Alice replied.” and Use v.s.“Alice replied.” remain one span on originalbase, immediateparent andeff69 in both modes. The existing unspaced delimiter shortcut has not gained generic smart-terminal semantics through the bracket-only paired-quote support. Preserve and document this baseline limit rather than broaden all ordinary punctuation boundaries to quiet this report.

The final source remains the independently reviewed952-test tree. These dispositions preserve the declared boundary grammar and correct the inaccurate performance/parent-output claims.

Read the full marked initial with its complete Unicode predecessor while
retaining the existing identifier character categories and A/I boundary rule.
Cover circled and enclosed bases, long marks, and predecessor counterexamples.
@mldangelo-oai

Copy link
Copy Markdown
Contributor Author

@codex review

Please review the current integration at 75e13a2a6fb2894bd88c2cc61aaa89ed6f990e0e, including the configured security review. It combines this PR with the #169 dependency and retains the landed #156/#173 list, casing and callback-work limits. All 1,333 tests and local checks passed; please critically examine the combined quotation/list ownership, abbreviation boundary decisions and the flattened terminal guard. Prior finding dispositions remain available in the existing threads.

@chatgpt-codex-connector

Copy link
Copy Markdown

🛡️ Codex Security Review · Automatically triggered

Security review completed. No security issues were found in this pull request.

Reviewed commit: 75e13a2a6f

View security finding report

Only the user who started this review can view the report in Codex.

ℹ️ About Codex security reviews in GitHub

This is an experimental Codex feature. Security reviews are triggered when:

  • You comment "@codex security review"
  • A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review

Once complete, Codex will leave suggestions, or a comment if no findings are found.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 75e13a2a6f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/utils.ts
Comment thread src/utils.ts Outdated

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

Three moderate issues and one nit remain unresolved in src/utils.ts.

Review details

Suppressed comments (4)

src/utils.ts:423

  • A paragraph separator is appended to pending and then reaches this branch, where startsWithTitleCase merges it regardless of continuesAbbreviation. Consequently inputs covered by the new paragraph tests, such as The Giants vs.\n\nBoston Celtics won. and He said Linux vs.\n\nWindows today., are joined instead of retaining the paragraph boundary (the same happens for both casing modes). Gate the title-case line-wrap merge on the absence of a paragraph break, while carrying the recognized outer-quote state so paragraph breaks inside paired quotes still merge.
          (chunk.startsWithTitleCase ||
            continuesAbbreviation ||

src/utils.ts:397

  • The paragraph test is performed on suffix, but SentenceBuffer.suffix is intentionally capped at sentenceSuffixLength (8 here). A separator such as the new test case \n \n is longer than that window, so the first newline is discarded and this expression sees only one newline; the versus abbreviation is then treated as a single line wrap and merged instead of splitting. Detect paragraph breaks from the full separator chunk (or preserve separator metadata) rather than from the bounded suffix.
        const separator =
          suffix.slice(suffix.trimEnd().length) + (nextChunk?.match(/^\s*/)?.[0] ?? '');
        const continuesAbbreviation =
          !/\n[^\S\n]*\n/.test(separator.replace(/\r\n?/g, '\n')) &&

src/utils.ts:2003

  • The index < brackets.bracketQuoteEnd guard suppresses the early unspaced-boundary check when a terminal is followed by its recognized plain-single closing quote. sentenceEnd then consumes that quote, but isUnspacedSentenceBoundary sees the following ( / [ / { as next and rejects it because it only accepts a letter or number, so cases such as He wrote 'vs.'(Alice replied.) remain joined instead of producing the two sentences asserted by the new tests. The boundary logic needs to account for a completed quote before an unspaced opening delimiter.
    insideQuotes ||
    index < brackets.bracketQuoteEnd ||
    brackets.depth > 0 ||
    !/["'([{<]/.test(input[next] ?? '')

src/utils.ts:1492

  • The mask is allocated at the first <, before this scan knows whether any unquoted pair exists, and is then discarded when pairs === 0. Large inputs containing only unmatched or quoted angle marks therefore incur an unnecessary input.length allocation (potentially doubling peak memory); defer creating the mask until the first confirmed > or track pending opener positions until a pair is found.
      if (matched.length === 0) {
        matched = new Uint8Array(input.length);
      }
  • Files reviewed: 3/3 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

@mldangelo-oai

Copy link
Copy Markdown
Contributor Author

Critical dispositions of all four suppressed notes in Copilot review PRR_kwDOMlO9es8AAAABNnq2vg, checked against 75e13a2 and the exact 9d97d7b source:

  1. Paragraph merging: disproved. Both exact reported paragraphs split correctly in both modes and both versus spellings. Paired quotation controls stay one normalized span. The sentence scanner emits the paragraph boundary before the presumed buffer path.
  2. Long separator loss: disproved. LF plus twelve spaces plus LF also splits correctly. The existing precise regression passes; no full-buffer separator rewrite is needed.
  3. Attached apostrophe boundary: misstated fixture. The current test explicitly expects one span for He wrote 'vs.'(Alice replied.), and two when a space separates the opener. It protects retention of the paired apostrophe. All three bracket forms match those expectations. fix: preserve quotation boundaries and dialogue continuations #157's richer boundary policy is being reviewed independently.
  4. Angle-mask allocation: optional optimization declined. Mixed unquoted unmatched < and quoted > can allocate one byte per input character before discovering there is no unquoted pair. Inputs missing either angle return before allocation; fully quoted spans are skipped. This bounded linear-storage design is deliberate. Earlier actual mask comparisons and constrained-heap checks validate it; the replaced pending-position storage used 32 MiB more on the recorded balanced case. No failure or nonlinear growth was reproduced, so no new allocation algorithm is introduced for this nit.

The first three dispositions include 36 focused inputs and 144 actual API calls across the published and fixed source. All 1,343 tests and local checks pass. COMMENTED bot reviews are not formal approvals. Final-head code/security/Copilot reviews and CI remain required.

@mldangelo-oai

Copy link
Copy Markdown
Contributor Author

@codex review

Please review code and security on exact head 9d97d7b. The three-site single-guillemet ownership repair and its ten regression cases are the new change; all 1,343 local tests pass. Both prior Codex findings and all four suppressed Copilot claims have explicit evidence-based dispositions above. Review those critically and report any remaining actionable issue.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Keep them coming!

Reviewed commit: 9d97d7be58

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@chatgpt-codex-connector

Copy link
Copy Markdown

🛡️ Codex Security Review · Automatically triggered

Security review completed. No security issues were found in this pull request.

Reviewed commit: 9d97d7be58

View security finding report

Only the user who started this review can view the report in Codex.

ℹ️ About Codex security reviews in GitHub

This is an experimental Codex feature. Security reviews are triggered when:

  • You comment "@codex security review"
  • A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review

Once complete, Codex will leave suggestions, or a comment if no findings are found.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

Four moderate review findings remain unresolved in src/utils.ts.

Review details

Suppressed comments (4)

src/utils.ts:423

  • When a comparison vs. is followed by a blank paragraph, sentenceChunks does not emit a boundary (the comparison exception keeps the period pending), so the prefix and the following sentence arrive here as one line-wrapped chunk. Because chunk.startsWithTitleCase is true for inputs such as The Giants vs.\n\nBoston Celtics..., this branch joins across the paragraph and bypasses the paragraph guard above, contrary to the new paragraph-boundary cases. The title-case fallback needs to distinguish an enclosing recognized quote/bracket (which must keep embedded comparisons together, including Treebank quotes) from an unquoted paragraph before joining.
          (chunk.startsWithTitleCase ||
            continuesAbbreviation ||

src/utils.ts:1945

  • When a completed quotation makes delimitedVersus true, this admits numeric sentence starts, but the quantity guard only recognizes a unit when it is immediately followed by sentence punctuation/end. Consequently He wrote "vs." 100 times correctly. is treated as two sentences instead of staying attached, contradicting the new expectation at test/tests.ts:2591; extend the supported quantity-fragment check to cover the trailing words while keeping cases such as 2 days passed. split.
    (!abbrvReg.test(suffix) || delimitedVersus) &&
    !/^\S+(?:\s*%|\s+(?:time|year)s?\b|\s+(?:month|week|day|hour|minute|second|star|point|percent)s?(?=\s*[.!?](?:\s|$)|\s*$))/iu.test(
      input.slice(next),
    )

src/utils.ts:423

  • The new continuation path appends a wrapped abbreviation chunk to pending while the buffer still contains the CR/LF. On the next iteration there is no following chunk, so the hasLineBreaks fallback splits chunk.text() back into separate lines; lowercase comparisons and geographic continuations such as android vs.\nWindows and 2026 U.S.\nSenate therefore cannot normalize to one sentence as the added tests require. Normalize the buffer before storing it in pending (or otherwise mark the joined wrap as consumed).
          (chunk.startsWithTitleCase ||
            continuesAbbreviation ||

src/utils.ts:1406

  • This later-opener guard is stricter than angleQuoteCloser: it rejects an ASCII quote preceded by punctuation such as : or ,, even though angleQuoteCloser classifies that position as a valid opener. A leading elision such as 'Tis can therefore borrow that later quote as its closer, causing the scan to skip an intervening <...> span and leave its > unmatched. Use the same opener predicate here so punctuation-adjacent independent quotations are protected too.
      angleQuoteCloser(input, next) !== undefined &&
      (opener === '‘' || /^[\s([{<]$/.test(input[previous])) &&
      /\S/.test(input[next + 1] ?? '')
  • Files reviewed: 3/3 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

@mldangelo-oai

Copy link
Copy Markdown
Contributor Author

Critical dispositions of all four suppressed notes in final-head Copilot review PRR_kwDOMlO9es8AAAABNn9LNQ, verified on 9d97d7be5843f8d6a717976a5f43fcde7d2f0941:

  1. Blank paragraphs: disproved. Exact unquoted Giants/Linux comparisons preserve their paragraph boundary in both modes and both spellings. The full separator reaches the abbreviation branch before the alleged fallback; paired quotation controls remain attached.
  2. “100 times correctly”: disproved. The existing time|year regex alternative ends at a word boundary; it does not have the separate month/day/unit alternative's punctuation restriction. 100 times correctly. and 100% correctly. stay attached, while 2 days passed. starts a new sentence, as the existing tests require.
  3. Unterminated wrap fragments: reproduced, inherited limitation. Exact android vs.\nWindows and 2026 U.S.\nSenate do return two fragments. They do so on current main, original fix: preserve common abbreviation continuations #155 and this head, for LF/CRLF/CR in both modes. The report substitutes these unterminated tails for the completed-sentence regressions: Windows is common. and Senate meets. normalize correctly. The cited branch already calls normalizeWhitespace() before storing pending; a different tail path explains the fragment limitation. It is now explicit in the PR body. No unrelated fragment parser is added.
  4. Punctuation-led later quotation: retain the reviewed closer priority. A possible quote token is not by itself proof of a later independent opener. The deliberate stronger ASCII context preserves a real closer, including one after a colon/comma. A scratch implementation of the suggested broader predicate changes ambiguous opener examples, but also breaks valid controls such as He noted <('Tis > odd:') and "vs." Examples followed> today. from one span into two. Across six punctuation forms, 48 real-closer rows regress. The original helper and first-compatible-closer policy are unchanged; v.s. standardization inherits the existing vs. preference for these ambiguous readings. No new following-word grammar or blanket predicate replacement is adopted.

The bounded comparison made 616 actual API calls over 77 inputs on current main, original #155, this head and the isolated proposed predicate. All 154 case-mode outputs on this head match original #155 for these probes. The initial failed assumption about fragment joining is preserved in the local evidence; it is not counted as a passing test.

All 1,343 regression tests and all ten actual GitHub checks pass. Node 18/20/22/24 CI each checked out the exact main/head merge and passed installation, types, strict lint, build, packed consumers and tests. Codex code/security reviews are clean. These are critically reconciled COMMENTED reviews, not formal approving reviews; the user's authorized approval override is separate.

@mldangelo-oai
mldangelo-oai merged commit af16ea7 into main Sep 15, 2026
10 checks passed
@mldangelo-oai
mldangelo-oai deleted the mdangelo/codex/rouge-abbreviation-continuations-20260824 branch September 15, 2026 11:31
@mldangelo-oai
mldangelo-oai restored the mdangelo/codex/rouge-abbreviation-continuations-20260824 branch September 15, 2026 19:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants