Skip to content

feat: keep the previous Lean declarations diff visible while a new build runs#56

Open
adomani wants to merge 3 commits into
masterfrom
carry-forward-decls-diff
Open

feat: keep the previous Lean declarations diff visible while a new build runs#56
adomani wants to merge 3 commits into
masterfrom
carry-forward-decls-diff

Conversation

@adomani

@adomani adomani commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

Add carry_forward + a non-patching MODE=emit so the PR-summary comment keeps a previously-shown Lean diff (relabelled) instead of reverting to pending / unavailable.

Companion: leanprover-community/mathlib4#40486 · details in the Reference / Explanation / How-to comments below.

…ild runs

The `### PR summary` comment carries a Lean-aware declarations-diff region,
spliced in post-build by `updateDeclsDiffSection.py`. On every push, mathlib4's
pre-build `PR_summary.yml` rewrites the whole comment and resets that region to
the `(Lean -- pending)` placeholder, so a previously-computed diff disappears
until the next build finishes.

Add a `carry_forward(region, new_heading)` helper plus two ways to use it:

* a new non-patching `MODE=emit`, called by the pre-build to print the region
  content: it carries an existing real diff forward under `NEW_HEADING`
  (relabelled stale) instead of blanking it, else prints the pending placeholder;
* `MODE=warning` now carries a real diff forward under `NEW_HEADING` (surfacing
  the cache miss) rather than always replacing it with the unavailable block.

A "real diff" is recognised by its body stamp (`✅ **Lean-aware diff**`), not its
heading, so a once-shown diff survives repeated relabels without reverting to
pending. The success path is unchanged. Adds 6 tests (51 pass).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@adomani

adomani commented Jun 10, 2026

Copy link
Copy Markdown
Contributor Author

Companion mathlib4 PR: leanprover-community/mathlib4#40486

@adomani

adomani commented Jun 10, 2026

Copy link
Copy Markdown
Contributor Author

Reference

Information-oriented. The API surface, no rationale.

carry_forward(region: str, new_heading: str) -> str | None
Returns region with its #### Declarations diff (Lean…) heading line rewritten to new_heading, iff region contains the body stamp ✅ **Lean-aware diff**; otherwise None. Strips surrounding whitespace.

Module constants

  • LEAN_DIFF_STAMP = "✅ **Lean-aware diff**"
  • _HEADING_RE(?m)^#### Declarations diff \(Lean[^\n]*\)$
  • PENDING_PLACEHOLDER — the (Lean -- pending) block

Modes

  • emit (new) — non-patching. Prints the region content (carry-forward under NEW_HEADING, else PENDING_PLACEHOLDER) to stdout. Always exits 0. Env: REPO, NEW_HEADING, PR_NUMBER/PR_HEAD_SHA.
  • warning (changed) — carry-forward under NEW_HEADING if a real diff is present, else build_warning(DEFAULT_BRANCH).
  • success (unchanged).

Teststests/decls_diff/test_patch.py: +6 (51 total).

@adomani

adomani commented Jun 10, 2026

Copy link
Copy Markdown
Contributor Author

Explanation

Understanding-oriented. The design decisions.

The comment is split across two repos: mathlib4's workflows generate it, this script patches it post-build. Any fix to "what the comment shows across pushes" therefore touches both — that split is pre-existing.

A real diff is detected by its body stamp (✅ **Lean-aware diff**), not its heading. The heading is exactly what we rewrite (pendingstalecache miss), so keying detection on it would lose the diff after the first relabel; the stamp is invariant, so a once-shown diff survives any number of relabels and only a fresh successful build replaces it.

emit is deliberately non-patching: the pre-build step rebuilds the whole comment locally and posts it in one shot, so it needs the carried-forward region as text to embed, and it must read the live comment before its own post overwrites it. A patch-in-place mode would run too late — the prior diff would already be gone.

@adomani

adomani commented Jun 10, 2026

Copy link
Copy Markdown
Contributor Author

How-to: verify locally

Problem-oriented. Reproduce the behaviour before merging.

  1. Run the suite:
    python3 -m pytest tests/decls_diff/ -q
    
  2. Exercise emit against a stubbed comment that already shows a real diff, and confirm the heading is relabelled while the body is kept:
    printf '#!/usr/bin/env bash\necho '\''[{"id":1,"body":"### PR summary\n\n<!-- DECLS_DIFF_LEAN_BEGIN -->\n#### Declarations diff (Lean)\n\n> ✅ **Lean-aware diff**\n\n* **+3** new declarations\n<!-- DECLS_DIFF_LEAN_END -->"}]'\''\n' > /tmp/gh && chmod +x /tmp/gh
    PATH=/tmp:$PATH MODE=emit NEW_HEADING='#### Declarations diff (Lean -- stale, waiting for the new build)' \
      REPO=o/r PR_NUMBER=7 PR_HEAD_SHA=x python3 scripts/pr_summary/updateDeclsDiffSection.py
    
  3. Make the stub exit 1 and confirm emit still prints the pending placeholder and exits 0 (graceful degradation).

adomani and others added 2 commits June 11, 2026 00:17
…r-coupled test

Addresses review feedback on the declarations-diff carry-forward:

* find_summary_comment now requires the comment author to be
  github-actions[bot]. Under pull_request_target this script reads a
  '### PR summary' comment's Lean region and carries it forward; since anyone
  can post such a comment, requiring the bot author keeps attacker-authored
  region content (markers + forged stamp) out of that loop.
* carry_forward substitutes NEW_HEADING literally (via a lambda) instead of as
  a regex replacement template, so a heading containing '\' or '\g' cannot
  corrupt the output; it also warns on stderr when the diff stamp is present
  but no '(Lean…)' heading matched, surfacing NEW_HEADING / _HEADING_RE drift
  instead of silently no-op'ing.
* tests: assert a section from the real producer (render_override) satisfies
  carry_forward — guarding against stamp drift that the hand-written fixture
  cannot catch — plus literal-heading, non-bot-impostor and missing-user cases.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Drop the "Mathlib cache ... isn't on the server" jargon from `build_warning`
(it describes a missing built-master snapshot at the merge-base, not an olean
cache) and update the test heading constant to match the reworded
`(Lean -- stale; merge master and push to refresh)` used in mathlib4's
decls-diff.yml.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@bryangingechen

Copy link
Copy Markdown
Contributor

LGTM. Feel free to merge in a coordinated way with the downstream PR.

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