Skip to content

refactor(e2e): parse the fuzz summary table with the mdast GFM table stack - #566

Merged
Vivswan merged 1 commit into
mainfrom
refactor/fuzz-mdast-tables
Oct 27, 2026
Merged

Vivswan merged 1 commit into
mainfrom
refactor/fuzz-mdast-tables

Conversation

@Vivswan

@Vivswan Vivswan commented Oct 26, 2026

Copy link
Copy Markdown
Owner

What this changes

summaryTableProblems: a first-pipe-block table finder, a backslash-run pipe counter, a delimiter-row regex
  ->  fromMarkdown + gfmTable, the first table node, each row's cell count against the header's

differential, old against new, verdict and problem kind:
  700 summaries through the engine's own renderers, hostile cells (pipes, backslashes, code spans, <br>)   0 mismatches
  262 real summaries from fuzz scenarios and the curated corpus                                             0 mismatches
  75 malformed inputs + 10,501 mutations: every split is a shape the engine cannot write

How

  • A malformed delimiter row now reads as no table, which is what GFM and GitHub's renderer make of it; the old finder named the separator row.
  • mdast keeps a row's excess cells where the HTML renderer drops them, so a raw pipe shows as four cells under a three-cell header; the check stands on that.
  • Library: the mdast GFM table stack already declared and used by .github/scripts/lib/generated-regions.ts.

Proof

  • Tests: fuzz 9 pass; e2e 373/373; a ten-iteration fuzz run.
  • Gates: typecheck, fleet biome 0, member-shape 0, knip, line cap.
Technical details
  • Wording of three fuzz diagnostics moved: the missing-table message covers a malformed delimiter row, the rows message counts data rows, the cells message numbers the data row.
  • Out of scope: shapes the engine cannot write (an indented table, a row without its leading or closing pipe, text glued to the table, a destroyed first table in a multi-target summary).
  • No unit test: fuzz.ts runs main() at import, so its functions cannot be imported; a follow-up could guard it with import.meta.main and pin the excess-cell fact.
  • Files: test/e2e/fuzz.ts.

The fuzzer's summaryTableProblems found the step summary's table by hand (the first run of lines opening with a pipe), counted each row's unescaped pipes with a backslash-run state machine, checked the delimiter row against a regex, and compared the pipe counts. The mdast GFM table stack already in the repository (mdast-util-from-markdown with micromark-extension-gfm-table and mdast-util-gfm-table, as generated-regions.ts uses it) reads the table as GitHub renders it: it recognizes the table only when the header and delimiter row agree, treats an escaped pipe as cell text and a pipe after an escaped backslash as a delimiter, and keeps each row's real cell count. What remains compares each row's cell count to the header's and reports a missing table, which a malformed delimiter row now also becomes.

Differential check, the old function against the new over engine-rendered summaries: 700 generated through writeSummary, writeMultiSummary, writeSnapshotDirSummary, and writeRenderSummary with cells drawn from the hostile names plus raw pipes, lone and trailing backslashes, code spans, and blank cells; 200 real summaries from generated fuzz scenarios run through the runner with the oracle's predicted section count; 62 real summaries from a sample of the curated corpus. All 962 agree on the verdict and on the problem kinds. Of 75 hand-made malformed inputs and 10501 mutations (a delimiter row dropped or emptied, an escape broken, a row dropped, a cell appended, the table removed or indented, a leading pipe stripped, a raw pipe inserted, a blank line inserted, the text truncated), the verdicts agree on 8580 mutations, and every split is a shape the engine cannot write: an indented table, a row without its leading or trailing pipe, text glued to the table, or a multi-target summary with its first table destroyed. The fuzz passes this function single-run summaries alone.

The diagnostics change wording: a malformed delimiter row reads "summary carries no markdown table" rather than naming the separator row, the row-count message counts data rows, and the cell-count message numbers the data row. No engine-produced summary changes verdict.
Copilot AI balanced review requested due to automatic review settings October 26, 2026 20:35
@github-actions

Copy link
Copy Markdown
Contributor

File size check

0 over a hard cap (fails), 6 warning(s).

File Size Tier Cap
src/engine/diff.ts:56 11 comment lines warn 10
src/github/api-error.ts:9 11 comment lines warn 10
src/problem.ts:73 18 comment lines warn 10
src/sections/contract/errors.ts:13 11 comment lines warn 10
src/sections/contract/module.ts:55 12 comment lines warn 10
src/sections/shared/list/decl.ts:265 14 comment lines warn 10

Split the file, wrap the line, shorten or exempt the comment, or list the path in .file-size-allow.local with a # reason.

5 managed file(s) skipped; repo-platform owns them.

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.

🟢 Approval recommended

The focused test-only refactor preserves the intended validation checks, with no unresolved defects identified.

No open issues 🎉

What changed in this PR

Replaces the end-to-end fuzzer's custom Markdown table parser with the existing mdast GFM table stack, aligning summary validation with GFM parsing.

Changes:

  • Parses the first table and checks its data-row count and cell widths against expectations.
  • Updates diagnostics for missing tables, insufficient rows, and mismatched cell counts.
File Description
test/​e2e/​fuzz.ts Uses mdast GFM parsing for summary-table validation and updates diagnostics.

Review effort: Balanced

@Vivswan
Vivswan marked this pull request as ready for review October 26, 2026 20:40
@Vivswan
Vivswan merged commit 3b774f6 into main Oct 27, 2026
29 checks passed
@Vivswan
Vivswan deleted the refactor/fuzz-mdast-tables branch October 27, 2026 07:19
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