Skip to content

feat(use-apply): pre-generate commit msg before activation - #628

Open
cooper (czxtm) wants to merge 1 commit into
push-ostwkruyyxvofrom
push-vrqxytmztspo
Open

feat(use-apply): pre-generate commit msg before activation#628
cooper (czxtm) wants to merge 1 commit into
push-ostwkruyyxvofrom
push-vrqxytmztspo

Conversation

@czxtm

Copy link
Copy Markdown
Member

Fire generateCommitMessage() as an unawaited side effect at the start of
handleApply — the diff is final before activation starts, and the save
panel can regenerate on failure. An inference failure must not block or
delay activation.

Merge-section's existing effect must not clobber the in-flight
suggestion: short-circuit when commitMessageSuggestion is already set.

Fire generateCommitMessage() as an unawaited side effect at the start of
handleApply — the diff is final before activation starts, and the save
panel can regenerate on failure. An inference failure must not block or
delay activation.

Merge-section's existing effect must not clobber the in-flight
suggestion: short-circuit when commitMessageSuggestion is already set.
@darkmatter

darkmatter Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

🎨 Storybook preview

Open Storybook preview

Updated for e317587


⚠️ Detected UI changes (1)

These stories' HTML snapshots changed. I've added screenshots + links to the changed stories below. Review them carefully then accept the changes to regenerate baselines and include them in this PR:

Flows/Evolve › Playground

Flows/Evolve › Playground


Accept UI changes

  • Click here to accept these changes

Alternatively, you can run bun run test:update-snapshots locally to re-generate the baselines and then push the changes to this PR.

What does this do?

The screenshots above show UI changes detected by the Storybook
snapshot tests run on this PR. Each image is the rendered output of
a Storybook story from the code in this PR branch; the snapshot
test compared it against the committed baseline in
__snapshots__/ and flagged the difference.

Checking the box tells the darkmatter[bot] to regenerate the
baselines from this PR's current code and commit them directly to
this branch. The new baselines become the source of truth for
future runs — only accept after confirming the visual changes are
intentional.

Comparison baseline: the committed __snapshots__/ files on this
PR branch (carried forward from develop). Accept updates them in
place on this branch.

@prelint

prelint Bot commented Aug 1, 2026

Copy link
Copy Markdown

Ship it Commit message inference starts at apply-click instead of save-panel-open

Product decisions in this change

Agree with concerns 1. Commit message generation begins when the user clicks Apply, running in parallel with the build rather than waiting until the successful save panel opens.

The premise is sound: the diff is locked in before activation starts, so inference can run against it immediately without any risk of producing a stale result. The speedup is real when inference is slower than the build — the message is ready the moment the save panel opens.

The concern is that the optimization is probabilistic, not guaranteed. When the build finishes faster than inference (fast local Nix eval, or slow LLM), the save panel opens while generation is still in flight. The guard in merge-section sees commitMessageSuggestion as still null and starts its own generation. Two concurrent generations then run against the same diff. The last write wins, but the result is identical — the only cost is a redundant API call. This is the current behavior and is not a regression; it just means the optimization is a best-effort improvement rather than a guaranteed one.

Scenario With this change Without this change
Build slower than inference Message ready on save-panel open Message generated after save-panel open
Build faster than inference Two concurrent generations (current behavior) One generation after save-panel open
Build fails Inference ran but is discarded; next Apply regenerates No inference ran

The probabilistic nature is worth acknowledging but does not change the recommendation — degraded behavior is identical to the status quo.

Agree 2. An inference failure is silently swallowed and never surfaces to the user during the apply flow; the save panel's regenerate button is the recovery path.

Commit message suggestion is an enhancement on top of the save flow, not a gating requirement. If the LLM call fails, activation still completes, the save panel still opens, and the user can regenerate manually. Blocking or surfacing an error for a non-critical enhancement would create disproportionate friction. The trade-off is that users may occasionally open the save panel with no pre-populated suggestion and no explanation — but a regenerate affordance makes this graceful.

Agree with concerns 3. The save panel skips re-generation when a suggestion is already present, preventing it from clobbering an in-flight or completed pre-generated message.

The guard correctly prevents the common double-inference case: if Apply-time inference finishes before the save panel opens, the existing suggestion is preserved and no redundant call is made. Adding commitMessageSuggestion to the effect dependency array means the guard correctly re-arms if the suggestion is later cleared (e.g., by a user-triggered regenerate).

The concern is narrow: the guard is implemented as a React effect early-return, which means it only fires once the component mounts. If the save panel is mounted while generation is still in flight (suggestion is still null), the guard does not fire and merge-section starts its own generation. This is the same race noted in the main decision — the guard handles the 'inference faster than build' case well but offers no protection in the reverse case.

Agree 4. A stale commit message suggestion from a failed Apply attempt persists until the user clicks Apply again, at which point the new apply-click call regenerates it.

If Apply fails and the user edits their config before trying again, the suggestion from the first attempt sits in state. When they click Apply again, useApply fires generateCommitMessage() unconditionally, which updates the suggestion regardless of what was there before. The save panel's merge-section short-circuit fires for any in-progress inference, but the direct call from useApply runs independently of the effect and is the source of truth. The user sees the correct message by the time the save panel opens. No action needed.

Agree 5. The save panel's regenerate handler is unchanged, meaning it continues to work identically as the fallback for any pre-generation miss or failure.

The PR correctly treats regeneration as the invariant safety net and does not disturb it. Every failure mode — inference timeout, network error, build-faster-than-inference race, Apply failure followed by config change — ultimately resolves via the same regenerate button that existed before. The change adds an optimization path without narrowing the fallback.

Open questions

  • When the user clicks Apply and it fails, the suggestion from that attempt remains in state. If the user makes config changes before retrying, what does the save panel show between the moment Apply is clicked (second time) and when the new inference completes? Is there a visible flash of the old message?

  • Is there a maximum time the user waits on the save panel before giving up and regenerating manually? If inference is slow (>5s), does the panel indicate that generation is in progress, or does it appear empty until the result arrives?

  • Does generateCommitMessage() without the clear option overwrite an existing suggestion in place, or does it clear it first and then write? If it clears first, there is a window where the save panel shows an empty field on every new Apply, undoing the optimization's user-visible benefit.

Recommendation

Ship it
The optimization is directionally correct: moving inference earlier reduces latency on the happy path, and every failure mode degrades gracefully to the existing behavior with no regression. The guard prevents the most common double-inference case. The open questions are about edge-case UX polish rather than structural correctness.

@prelint prelint Bot added the ship it label Aug 1, 2026

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

Warning

apps/native/src/components/widget/layout/merge-section.tsx (line 32) [behavior_change]: Adding commitMessageSuggestion to the useEffect dependency array creates a duplicate-request loop during regeneration. generateCommitMessage() uses clear: true by default (use-summary.ts line 18), which synchronously sets the suggestion to null; that null triggers the effect again (short-circuit on line 26 does not fire for falsy values), launching a second concurrent network call alongside the one already started by handleRegenerate. Pre-PR, clicking Regenerate fired exactly one call; post-PR it fires two concurrent calls on every regeneration, with the last-response-wins outcome being silent and untested.

@github-actions

github-actions Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor
Warnings
⚠️

PR description is missing a ## Test Plan (or ## Testing Instructions) section. Add one describing how a reviewer can verify your change, or check No test plan needed if no testing is needed.

⚠️

No Linear issue ID found in this PR's title, description, or branch name (expected something like ENG-123). Add one so this work is traceable in Linear, or add #no-linear to the PR description to acknowledge it's intentionally untracked.

📋 PR Overview

Lines changed 43 (+42 / -1)
Files 0 added, 3 modified, 0 deleted
Draft / WIP no
Has Test Plan no
Linear issue no
No Test Plan Needed no
New UI components no
New Storybook stories no
New Rust modules no
New TS source files no
New tests no
package.json touched no
Cargo.toml touched no
Infra / CI touched no

🔬 Coverage

Report Lines Statements Functions Branches
apps/native/coverage/coverage-summary.json 36.4% 36.1% 31.7% 30.7%

Generated by 🚫 dangerJS against e317587

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants