Skip to content

Draw each record's forms Before and After on the Semantic Diff page - #8908

Open
cristianoc wants to merge 1 commit into
masterfrom
cristianoc/commit-records-v2
Open

cristianoc wants to merge 1 commit into
masterfrom
cristianoc/commit-records-v2

Conversation

@cristianoc

@cristianoc cristianoc commented Oct 19, 2026 •

Copy link
Copy Markdown
Collaborator

Each commit's message describes what the commit changes in a form suited to what it changes, and the Semantic Diff page draws those forms.

  • A change to the parse tree is written as the tree Before and After, a typed tree likewise, Lambda and generated JavaScript as code, a diagnostic as its text, a typing rule as an inference rule, the match compiler's split as a clause matrix, and a runtime representation as a mapping.
  • Each form has a drawing: trees with connectors, highlighted code, text, rules, matrices and mappings. Before and After sit side by side, on aligned rows, with the changed lines shaded.
  • A small commit is a subject and a line or two, with no forms.
  • The page draws each commit's message: its subject, prose, object blocks with their example and forms, and Review and Breaking sections.

.claude/skills/records/SKILL.md defines the message format, the kinds and forms, and how each form is written. scripts/recordRender.js parses and draws a message. scripts/commitRecords.js writes the page for a range of commits, and make semantic-diff renders master..HEAD.

Examples. #8909, the draft PR stacked on this one, re-applies six merged changes, and each commit message is written in this format. Its Semantic Diff link shows a parse tree, a clause matrix, Lambda, generated JavaScript, formatter output and a diagnostic, all drawn from the commit messages.

Related

Test plan

  • node --test scripts/commitRecords.test.js: 23 passing.
  • npx biome check scripts/, npx tsc and scripts/format_check.sh: clean.
  • The examples PR's page, rendered by this PR's renderer.

🤖 Generated with Claude Code

@pkg-pr-new

pkg-pr-new Bot commented Oct 19, 2026 •

Copy link
Copy Markdown

Open in StackBlitz

rescript

npm i https://pkg.pr.new/rescript@8908

@rescript/belt

npm i https://pkg.pr.new/@rescript/belt@8908

@rescript/darwin-arm64

npm i https://pkg.pr.new/@rescript/darwin-arm64@8908

@rescript/linux-arm64

npm i https://pkg.pr.new/@rescript/linux-arm64@8908

@rescript/linux-x64

npm i https://pkg.pr.new/@rescript/linux-x64@8908

@rescript/runtime

npm i https://pkg.pr.new/@rescript/runtime@8908

@rescript/win32-x64

npm i https://pkg.pr.new/@rescript/win32-x64@8908

commit: 0308018

@github-actions

Copy link
Copy Markdown

@cristianoc
cristianoc added this pull request to stack #8911 October 19, 2026 05:03
@cristianoc
cristianoc requested a review from cknitt October 19, 2026 05:06
@cknitt

cknitt commented Oct 19, 2026

Copy link
Copy Markdown
Member

@codex review

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 19, 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-10-19T08:25:14.991401Z 56c69ba Manual request
ℹ️ 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.

@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: 56c69ba029

ℹ️ 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 scripts/recordRender.js Outdated
Comment on lines +377 to +378
const lhs = [...g.slice(0, at), ...(left.trim() ? [g[at]] : [])];
const rhs = [...(right.trim() ? [g[at]] : []), ...body];

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Shade only the changed side of inline rewrites

When two rewrite forms have an identical left-hand side but a changed right-hand side, lineDiff marks the entire source line and including g[at] in lhs causes that unchanged left-hand side to receive del/add shading in both versions. For example, the tested (+ x 0) ⇝ (+ x 0) to (+ x 0) ⇝ x rewrite visually reports (+ x 0) itself as changed, making the semantic diff inaccurate; compare and shade the split left and right fragments independently.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Fixed: the terms of a rewrite pair are compared position by position, so (+ x 0) ⇝ (+ x 0) against (+ x 0) ⇝ x shades only the right side. Covered by "a pair of rewrites shades each side where it changes".

@cknitt cknitt left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks, the forms and drawings read well, and the escaping holds up (I tried HTML in the subject, author, captions, trees, matrices and mappings). I ran recordRender.js on some message shapes outside the tests and found a few parser problems. The first three seem worth fixing before merge.

1. Trailers other than Signed-off-by / Co-Authored-By end the trailer block early (trailerStart, TRAILER)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_x
Signed-off-by: A <a@b>

The scan stops at Claude-Session. The first two lines render as a prose paragraph on the card, and the co-author list comes out empty. Reviewed-by:, Fixes: and Closes: hit the same problem. Could the last paragraph count as trailers when every line is Key: value (or a continuation line), or could it go through git interpret-trailers --parse?

2. Content on the heading line produces a false "Before and After are equal" (forms)

JS modified (output):
Before (js): return x + 0 | 0;
After (js): return x;

Both texts become captions and both bodies are empty, so the pair compares equal. The page then says "Before and After are equal" for a change. Tab-indented bodies end up the same way, because only spaces count as indentation. Two empty bodies shouldn't produce the "equal" claim, or the captions should be part of the comparison.

3. A paragraph after Why: … / Breaking: … merges into that section (parseMessage, the blank-line branch)

Why: the problem.

A separate paragraph.

Breaking: old flag removed.

Another unrelated paragraph.

A blank line resets only unnamed sections. So "A separate paragraph." ends up in the Why box, and "Another unrelated paragraph." ends up in the Breaking banner. This only happens when the heading has text on the same line.

4. Blocks start at 2 spaces of indentation, but the skill says 4 (/^ {2,}\S/)

A wrapped bullet with a 2-space continuation line (the style of changes/ fragments) splits into a paragraph plus a detached block:

- first bullet that wraps
  onto a second line

5. Indented code under a plain paragraph renders as prose

The new output for:

    let f = x => x + 1
    let g = y => y

This renders as <p>let f = x => x + 1 let g = y => y</p>. prose() dedents first, so a uniformly indented block counts as text.

Smaller

  • A prose line starting with Example: (e.g. "Example: when the argument is constant, …") renders as a ReScript code block, even outside an object block.
  • In rules, a change anywhere shades the whole figure. The skill says "the changed parts shaded".
  • In code, a ⇝ b ⇝ c drops everything after the second ⇝.
  • Codex's open finding on rewrite shading (recordRender.js:378) still applies. I haven't repeated it here.

Most of these would make good additions to commitRecords.test.js.

Why:
    Reviewers reconstruct a change's effect on compiler objects (trees,
    Lambda, JavaScript, diagnostics, typing rules) from its code diff. A
    record states that effect in each object's own form, Before and After,
    and the review page draws it, so a reviewer reads the change at the
    level of the object it changes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Cristiano Calcagno <cristianoc@users.noreply.github.com>
@cristianoc
cristianoc force-pushed the cristianoc/commit-records-v2 branch from 56c69ba to 0308018 Compare October 19, 2026 14:40
@cristianoc

Copy link
Copy Markdown
Collaborator Author

Thanks, all fixed in the amended commit. Each case is now a regression test, and each of those tests fails on the previous renderer.

  1. Trailers: the message's last run of Key: value lines (with continuation lines) is its trailers, whatever the key: Claude-Session, Reviewed-by, Fixes and so on. Trailers are not drawn, and co-authors come from Co-Authored-By anywhere in that run. Why, Review, Breaking and Example directly above the sign-off still draw as sections.
  2. One-line forms: text on a Before/After heading line is the version itself when no block follows, so Before (js): return x + 0 | 0; and After (js): return x; draw as a change. With a block under the heading, the text is its caption. "Before and After are equal" needs equal, non-empty bodies. Tabs count as 4 columns.
  3. Sections: a blank line ends a named section whose text sits on its heading line, so the next paragraph is prose again.
  4. Indentation: a code block starts at 4 spaces, and a 2-space continuation stays in its paragraph or bullet.
  5. Indented code: a block indented under a plain paragraph is drawn as ReScript code.
  6. Smaller:
    • Example: heads a program only when it stands alone on its line.
    • Typing rules shade only the changed premise, conclusion, name or formula.
    • a ⇝ b ⇝ c draws every term.
    • Following the Codex finding, the terms of a rewrite pair are compared position by position, so only the side that changes is shaded.

The skill states the trailer, indentation, one-line form and Example: rules. The #8909 examples render byte-identical with the new parser.

@github-actions

Copy link
Copy Markdown

@codecov

codecov Bot commented Oct 19, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 81.03%. Comparing base (1869441) to head (0308018).
⚠️ Report is 6 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #8908      +/-   ##
==========================================
- Coverage   81.04%   81.03%   -0.01%     
==========================================
  Files         455      455              
  Lines       63508    63640     +132     
==========================================
+ Hits        51469    51573     +104     
- Misses      12039    12067      +28     

see 15 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

This branch has not been deployed

No deployments
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