Skip to content

feat: report how the review base was built - #139

Open
Svilen-Stefanov wants to merge 2 commits into
mainfrom
feat/base-provenance
Open

Svilen-Stefanov wants to merge 2 commits into
mainfrom
feat/base-provenance

Conversation

@Svilen-Stefanov

@Svilen-Stefanov Svilen-Stefanov commented Oct 7, 2026 •

Copy link
Copy Markdown
Contributor

What changed and why

A review's base graph comes from one of three places: the saved codeboarding-base-<cfg>-<merge_base> artifact, the .codeboarding/ baseline committed at the merge base (caught up incrementally), or a full analysis in this run. Nothing reported which one ran, so a review that took ten minutes because it built main from scratch looked the same as one that took two.

This records it and reports it, per the base-provenance contract shared with the webview:

  • analyze.sh records base_source (saved / committed / computed), base_reason (no_baseline / incompatible, only with computed), base_from_sha, catchup_commits, base_seconds and head_seconds, and emits them as step outputs. incompatible means a candidate existed (a saved artifact or committed baseline with another depth cap, or a committed baseline the engine refused with requiresFullAnalysis). base_seconds includes the artifact lookup step's own time, which fetch-state.sh now reports.
  • Committed baselines: base_from_sha is the commit the baseline describes: the parent of the sync commit that wrote it, pushed directly or on the second-parent side of a merged sync PR. Only a commit sync made counts (its bot committer, nothing but .codeboarding/); a squash or hand edit leaves it empty rather than guessing. History is deepened to 101 commits. catchup_commits counts first-parent commits from there to the merge base whose diff against their first parent changes code, so a --no-ff merge counts and a sync or .gitattributes-only commit does not. Empty means unknown.
  • Review metadata.json gains the six keys, all strings, empty when not applicable.
  • Comment marker gains base=… base_reason=… base_seconds=… head_seconds=… after the existing keys; base_reason= is omitted when empty.
  • Final comment gains one Base: line with measured times.
  • Progress comment: when the base is computed, analyze.sh rewrites the sticky progress comment (found by the sticky action's own marker, which the edit keeps) into two steps, and refreshes the elapsed minutes every 60 s from a background ticker. The ticker stops through a stop file and is waited for, and each edit re-checks the file just before it is sent, so a stale "running" edit cannot land after step 2. It then marks step 1 done with the measured time. Elapsed only, no estimate. A fork's read-only token makes the edit fail silently, as the progress step already does.
  • docs/COMMIT_STRATEGY.md: metadata table gains the six keys plus the missing kind and analysed_files_changed rows.
  • New action output base_source.

What it looks like

This PR changes nothing visible in the web platform UI by itself. The comment text on GitHub changes:

Progress comment while the base is built:

### CodeBoarding review · analyzing…

1. ⏳ Building the diagram of `main` @a1b2c3d from scratch · running for 3 min
   `main` has no saved diagram yet, so this review builds one first. Once a diagram of `main` is saved, reviews start from it and skip this step.
2. Analysing this PR's changes

Final comment, one of:

<sub>Base: built from scratch (no saved diagram), 8 m 54 s · changes 3 m 12 s</sub>
<sub>Base: saved diagram of main @a1b2c3d · changes 2 m 39 s</sub>
<sub>Base: caught up 4 commits from main @a1b2c3d, 41 s · changes 2 m 39 s</sub>
<sub>Base: saved diagram of main, caught up, 41 s · changes 2 m 39 s</sub>   (catch-up unknown)

Marker:

<!-- codeboarding: platform_url=… changed=3 analysed_files_changed=2 head=abc123 base=computed base_reason=no_baseline base_seconds=534 head_seconds=192 -->

How it was tested

  • New tests: --no-ff merges counted as catch-up, a merged sync PR's analysed commit, an unknown-origin baseline left empty, .gitattributes not counted, the unknown and ancestor comment lines, the stopped ticker; each base path's metadata (saved, computed/no_baseline, three incompatible cases, committed at the merge base with catch-up 0, committed with 2 commits caught up), the progress comment rewrite (and no rewrite for a saved base), post-progress.sh copy and lookup caching, the Base: line for every source, and the marker keys.
  • python -m unittest discover -s tests: 204 tests, all pass except test_sync_without_baseline_uses_configured_depth_directly, which fails identically on main locally because macOS ships bash 3.2 (${FORCE_FULL,,}); CI runs bash 5.
  • Black 25.9.0 (pre-commit hook), shellcheck on all action scripts.

🤖 Generated with Claude Code

A review's base comes from a saved artifact, a baseline committed at the
merge base, or a full analysis in this run, and nothing said which. The
slow path is the last one, and a reader had no way to tell why a run took
ten minutes instead of two.

analyze.sh now records base_source (saved, committed, computed), base_reason
(no_baseline, incompatible), base_from_sha, catchup_commits, base_seconds and
head_seconds. They go into the review metadata.json as strings, onto the
comment's machine-readable marker, and into one "Base:" line in the comment.
While a base is computed, the sticky progress comment is rewritten into two
steps with the elapsed time and the reason, never an estimate.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Review follow-ups on the base provenance:

- code_paths_changed diffs against the first parent, so a --no-ff merge on
  the first-parent chain counts as the change it brought in; diff-tree
  printed nothing for merges and catch-up read 0. .gitattributes is not
  code either.
- base_from_sha for a committed baseline comes only from a commit sync
  made (its bot committer, nothing but .codeboarding/): pushed directly,
  or on the second-parent side of a merged sync pull request. Anything
  else (a squash, a hand edit) leaves it empty rather than guessing.
- An empty sha or count is unknown, not 0: the comment then says
  "saved diagram of <branch>, caught up" without a sha, and an ancestor
  never reads as "saved".
- The progress ticker stops through a stop file and is waited for, and
  post-progress.sh checks the file right before editing, so a stale
  "running" edit cannot land after step 2.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@codeboarding-review

codeboarding-review Bot commented Oct 7, 2026 •

Copy link
Copy Markdown
Contributor

CodeBoarding review

Status: 0 changed components (no analysed file changed)

See the full change in CodeBoarding.

Base: saved diagram of main @a976e0a · changes 35 s

graph LR
    n_action_scripts["action_scripts"]
    classDef added fill:#1f883d,stroke:#0b5d23,color:#ffffff;
    classDef modified fill:#bf8700,stroke:#7d4e00,color:#ffffff;
    classDef deleted fill:#cf222e,stroke:#82071e,color:#ffffff,stroke-dasharray:5 3;
Loading

download artifacts · run 37644317031

@ivanmilevtues

ivanmilevtues commented Oct 8, 2026 •

Copy link
Copy Markdown
Member

[blockerish] Can we simplify the base-analysis reporting to:

  • base_analysis_method: reused / full / incremental (instead of base_source).
  • base_analysis_reason: explain the method:
    • reused: #base_commit already has an associated analysis.
    • full: no usable analysis was available, or the existing analysis was incompatible / could not be updated incrementally.
    • incremental: updated an existing analysis to #base_commit; when the actual starting commit is known, say #start_commit → #base_commit and include how many commits were caught up, if known.
  • base_seconds: time to obtain the base analysis.
  • head_seconds: time to obtain the PR-head analysis.

The result is always an up-to-date analysis of the comparison-base commit, which we compare with the PR-head analysis—not a diff against the historical starting commit. Keep the starting SHA/count as optional detail in the incremental message rather than separate reporting fields. Don’t say “no analysis in the last 100 commits”: the current 100-commit lookup identifies the baseline origin, not searches for an analysis.

@ivanmilevtues ivanmilevtues 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.

I wrote coments after looking at the change + trying to udnerstand it, i think it is a bit overcomplicating and the wording is misleading.

I wrote a general comment with a suggestion on what I believe the wording should look like (maybe).

Would love to bounce ideas if needed on this but i think the current wording of params is confusing the word base is used many times ;d, and some commits and so on.

TO me in a PR context there is the base commit and the head commit and that is it.

Comment thread scripts/action/analyze.sh

# How far below the merge base this run looks for the commit a saved analysis
# describes. Past it, a catch-up count is reported as unknown.
CATCHUP_BOUND=100

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.

even 100 sounds quite a lot to me, but if it is not too slow, it's okay i suppose.

I was thinking more like 20 but 100 commits if you are bit squashiung can happen quickly I suppose.

fi
;;
esac
[ -z "$BASE_LINE" ] || printf '\n<sub>%s</sub>\n' "$BASE_LINE" >> "$BODY"

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.

[please address] Please move the Base: line below the diagram, immediately above the artifacts/run footer, while keeping it wrapped in <sub>. This is supporting metadata, similar to the artifacts and run links, so the final result and diagram should come first.

Expected final layout:

### CodeBoarding review

**Status:** 3 changed components

See the full change in [CodeBoarding](…).

[Existing diagram appears here]

<sub>Base: built from scratch (no saved diagram), 8 m 54 s · changes 3 m 12 s</sub>

<sub>[download artifacts](…) · run [123456](…)</sub>

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