Skip to content

feat: report how the review base analysis was obtained - #139

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

Svilen-Stefanov wants to merge 3 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 compares the analysis of the pull request's base commit (the merge base) with the analysis of its head. The base analysis 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:

  • analyze.sh emits four step outputs:
    • base_analysis_method: reused (the merge base already has an analysis: its saved artifact, or a committed baseline with nothing to catch up), incremental (an earlier commit's analysis updated to the merge base) or full.
    • base_analysis_reason: the method in words. reused: a1b2c3d already has a saved analysis. incremental: updated the analysis of 9f8e7d6 to a1b2c3d, 4 commits caught up when the starting commit and count are known, updated an existing analysis to a1b2c3d when not. full: no usable analysis was available, or the existing analysis was incompatible or could not be updated incrementally (another depth cap, or the engine demanded a full run).
    • base_seconds: time to obtain the base analysis, including the artifact lookup step, which fetch-state.sh now reports.
    • head_seconds: time to obtain the head analysis.
  • Whichever method ran, the result is an analysis of the merge base itself, so where an incremental run started is detail in the reason, not a field of its own.
  • Committed baselines: the starting commit 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 unknown rather than guessing. History is deepened to 101 commits to find it. The count is 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.
  • Review metadata.json gains the four keys, all strings, empty from an older run.
  • Comment marker gains base_analysis_method=… base_seconds=… head_seconds=… after the existing keys. The reason is prose, so it stays in the metadata.
  • Final comment gains one Base: line under the diagram, just above the artifacts/run footer, with measured times.
  • Progress comment: when the base is a full analysis, 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 four keys plus the missing kind and analysed_files_changed rows.
  • New action output base_analysis_method.

Since the first review

Per @ivanmilevtues: base_source / base_reason / base_from_sha / catchup_commits became base_analysis_method + base_analysis_reason, and the Base: line moved under the diagram. The "too far behind" and "ancestor" wording that had leaked in from #140 is gone from this PR.

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:

### CodeBoarding review

**Status:** 3 changed components

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

[diagram]

<sub>Base: full in 8 m 54 s (no usable analysis was available) · changes 3 m 12 s</sub>

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

The Base: line is one of:

<sub>Base: reused (a1b2c3d already has a saved analysis) · changes 2 m 39 s</sub>
<sub>Base: incremental in 41 s (updated the analysis of 9f8e7d6 to a1b2c3d, 4 commits caught up) · changes 2 m 39 s</sub>
<sub>Base: incremental in 41 s (updated an existing analysis to a1b2c3d) · changes 2 m 39 s</sub>
<sub>Base: full in 8 m 54 s (the existing analysis was incompatible or could not be updated incrementally) · changes 3 m 12 s</sub>

Marker:

<!-- codeboarding: platform_url=… changed=3 analysed_files_changed=2 head=abc123 base_analysis_method=full base_seconds=534 head_seconds=192 -->

How it was tested

  • Tests for each base path's method and reason: reused from a saved artifact and from a baseline committed at the merge base, full for lack of one, three incompatible cases, incremental with 2 commits caught up, --no-ff merges counted, a merged sync PR's analysed commit, an unknown-origin baseline (no starting commit named), .gitattributes not counted. Also the progress comment rewrite (and none for a reused base), post-progress.sh copy and lookup caching, the stopped ticker, the Base: line for each method and its position under the diagram, the marker keys and the metadata keys.
  • python -m unittest discover -s tests: 207 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,,}; feat: catch up the review base from the nearest saved ancestor #140 fixes it); 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.

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

Base: reused (a976e0a already has a saved analysis) · changes 31 s

download artifacts · run 37991967659

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

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Kept it at 100 for now. The walk only happens on a review that would otherwise analyze the base from scratch (8 to 10 min), it's a git deepen plus usually one or two artifact-list calls, so a few seconds at most. With squash merges 20 commits can be a single busy week, and then we'd fall back to a full run exactly where the catch-up helps most. Happy to lower it if we see it being slow in practice.

Comment thread scripts/action/build-review-comment.sh Outdated
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>

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done in 6b46ac3: the Base: line now sits under the diagram, right above the artifacts/run footer, still in <sub>.

Review feedback: base_source/base_reason/base_from_sha/catchup_commits used
"base" for too many things. A review compares the base commit's analysis with
the head's; what matters is how the base analysis was obtained.

- base_analysis_method: reused | incremental | full (replaces base_source).
  A committed baseline with nothing to catch up is reused.
- base_analysis_reason: the method in words; the starting commit and the
  number of commits caught up are detail in it, not fields of their own.
- base_seconds / head_seconds unchanged.
- The comment's Base: line moves under the diagram, above the run links,
  and the marker carries base_analysis_method instead of base/base_reason.
- Drops the too_far_behind and ancestor wording, which belong to the
  ancestor lookup in the next PR.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Svilen-Stefanov Svilen-Stefanov changed the title feat: report how the review base was built feat: report how the review base analysis was obtained Oct 9, 2026
@Svilen-Stefanov

Copy link
Copy Markdown
Contributor Author

Thanks, went with your proposal in 6b46ac3:

  • base_analysis_method: reused / incremental / full (replaces base_source). A committed baseline with nothing to catch up counts as reused.
  • base_analysis_reason: the method in words, e.g. a1b2c3d already has a saved analysis, updated the analysis of 9f8e7d6 to a1b2c3d, 4 commits caught up, no usable analysis was available, the existing analysis was incompatible or could not be updated incrementally. Start sha and count only appear inside the incremental message when known.
  • base_seconds / head_seconds unchanged.
  • base_from_sha, catchup_commits and base_reason are gone as fields. The comment marker carries base_analysis_method= plus the two times; the reason stays in metadata.json since it's prose.

Also took out the "too far behind" / "ancestor" wording that had leaked in here from #140, so this PR only reports what it implements. #140 is rebased on top and its ancestor path just reports incremental.

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