Skip to content

review: clearer failure reason when findings aren't saved - #1185

Merged
peyton-alt merged 6 commits into
mainfrom
feat/review-manifest-diagnostic
May 13, 2026
Merged

review: clearer failure reason when findings aren't saved#1185
peyton-alt merged 6 commits into
mainfrom
feat/review-manifest-diagnostic

Conversation

@peyton-alt

@peyton-alt peyton-alt commented May 12, 2026

Copy link
Copy Markdown
Contributor

https://entire.io/gh/entireio/cli/trails/360

Summary

Two related fixes to the entire review post-run path:

  1. Diagnostic — When the post-review manifest comes up empty, the warning now identifies which filter rejected the sessions (5 possible causes) instead of always blaming env-handshake.
  2. Gemini naming — Aligns the geminicli reviewer with the agent registry so review-session adoption actually works for gemini (and gemini appears in the picker).

Why

When a review run completes but no findings persist, users see:

Note: review skills ran but findings were not persisted.
Reason: review session was not tagged as a review (env-var handshake did not reach the hook)

That message is correct for one cause out of at least five — but it always blamed the env-handshake. Real failure modes include worktree-path mismatch, BaseCommit≠StartingSHA, agent type mismatch, or stale session state. Without an accurate reason in the user's terminal, every report became a guessing game.

While auditing the env-handshake side, found that geminicli/reviewer.go hardcodes "gemini-cli" for both ReviewerTemplate.AgentName and the AppendReviewEnv argument, but the agent registry registers gemini under AgentNameGemini = "gemini". The lifecycle hook's adoptReviewEnv compares ENTIRE_REVIEW_AGENT against string(ag.Name()), so adoption silently returned for every gemini review. The skilldiscovery registry had the same drift, so gemini never appeared in the picker either.

What changed

Commit 1 — manifest diagnostic

  • New explainEmptyManifest inspects candidate session states in the same filter order as matchReviewSessionState and reports the cause that actually applied, including observed-vs-expected values.
  • 5 causes covered: no session states, none tagged as review, worktree path mismatch, BaseCommit mismatch, started outside the run window, AgentType mismatch.
  • writePostReviewManifest now calls the helper instead of using a static reason string.
  • 6 unit tests cover every branch + a debug DumpAllReasons test prints the actual wording.

Commit 2 — gemini naming alignment

  • geminicli/reviewer.go: both AgentName and AppendReviewEnv argument now use string(agent.AgentNameGemini). Adoption will now match string(ag.Name()) in the hook.
  • skilldiscovery/registry.go: rekeys gemini-cligemini so IsEligible returns true and gemini shows in the configure picker.
  • agent_group.go: help text example updated from entire agent add gemini-cli (which fails) to entire agent add gemini (which works).
  • Regression guard: all three launchable reviewers (claude-code, codex, gemini) now have a *_NameMatchesRegistryKey test that locks the reviewer's declared name to the corresponding agent.AgentName* constant. Drift between them silently breaks review-session tagging — this test makes the failure loud.
  • Trailing doc-comment cleanups across review/types/{reviewer,template}.go, review/cmd.go, review/marker_fallback.go to drop stale gemini-cli references.

Test plan

  • mise run fmt && mise run lint — clean
  • go test ./cmd/entire/cli/agent/... ./cmd/entire/cli/review/... — all pass
  • go test -tags=integration ./cmd/entire/cli/integration_test/ -run "Review|Manifest|Lifecycle.*Review" — pass
  • Visual smoke: TestExplainEmptyManifest_DumpAllReasons -v prints all 5 reasons cleanly
  • Binary smoke: /tmp/entire-handshake agent list shows gemini (not gemini-cli)
  • Binary smoke: /tmp/entire-handshake agent add gemini --help example now matches the actual registry key
  • Real review run completes happy path on this branch — Review complete. footer renders, no regression

Out of scope

  • Reproducing the user-reported "skills ran but findings were not persisted" warning on claude-code+codex — the new diagnostic will identify the cause when the user hits it again. Once we have a concrete filter cause, follow-up PR addresses the root issue.
  • Scope-detection picking the wrong base branch — fixed separately by fix(review): default scope to main, add --base flag #1175.

🤖 Generated with Claude Code


Note

Medium Risk
Medium risk because it changes the effective registry key for Gemini from gemini-cli to gemini, which can affect existing configs/CLI usage, and adjusts post-run manifest generation/warnings that run after every review.

Overview
Improves entire review post-run behavior when the local review manifest is empty by computing a specific, user-facing rejection reason (e.g., no session states, not tagged as review, worktree/SHA/time-window/agent-type mismatches) instead of always blaming the env-var handshake.

Aligns Gemini’s reviewer and skill-discovery identifiers to the registry-stable key gemini (including env-var tagging and picker eligibility), updates the agent add help example accordingly, and adds regression tests to ensure each launchable reviewer’s Name() stays in sync with its agent.AgentName* constant.

Reviewed by Cursor Bugbot for commit 93b82ae. Configure here.

peyton-alt and others added 2 commits May 11, 2026 22:48
…empty

The empty-manifest warning ("Note: review skills ran but findings were not
persisted") previously hardcoded "env-var handshake did not reach the hook"
as the reason. That message is correct for one of at least five causes:
missing review tag, worktree path mismatch, BaseCommit mismatch, session
started outside the run window, or AgentType mismatch.

Replaces the static reason with explainEmptyManifest, which inspects the
candidate session states in the same filter order as matchReviewSessionState
and reports the cause that actually applied — with observed-vs-expected
values where relevant. Users (and bug reports) now carry enough information
to identify the failure without enabling debug logging.

Also drops a stale "gemini-cli" reference in the package doc comment.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Entire-Checkpoint: 0fb4b41ca371
The geminicli reviewer hardcoded "gemini-cli" both as ReviewerTemplate.AgentName
and as the agentName argument to AppendReviewEnv, while the agent registry
registers gemini under AgentNameGemini = "gemini". The lifecycle hook's
review-env adoption compares ENTIRE_REVIEW_AGENT against string(ag.Name()),
so adoption silently returned without tagging the session for every gemini
review — manifests were always empty, findings were never persisted.

The skilldiscovery registry had the same drift ("gemini-cli" keys), so
IsEligible("gemini") returned false and gemini never appeared in the
configure picker. The `entire agent add` help text suggested
`entire agent add gemini-cli`, which fails because the registry only
knows the agent as "gemini".

Aligns all three sites to the registry constant. Adds a registry-key
regression test to all three launchable reviewers (claude-code, codex,
gemini) so future drift between the reviewer's declared name and
agent.AgentName* fails CI rather than silently breaking adoption.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Entire-Checkpoint: 0bb7377a4f07
Copilot AI review requested due to automatic review settings May 12, 2026 02:51
@peyton-alt
peyton-alt requested a review from a team as a code owner May 12, 2026 02:51

Copilot AI left a comment

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.

Pull request overview

This PR improves the entire review post-run flow by (1) providing a more specific user-facing diagnostic when the post-review manifest is empty, and (2) aligning Gemini reviewer naming with the agent registry so review-session adoption and picker eligibility work for Gemini.

Changes:

  • Add explainEmptyManifest and thread session states through manifest writing so the “manifest empty” warning can report the most likely rejection filter.
  • Align Gemini reviewer/env-handshake agent name to agent.AgentNameGemini and rekey skill discovery registries from gemini-cligemini.
  • Add regression tests ensuring reviewer Name() matches the agent registry key for Claude Code, Codex, and Gemini; update help/docs comments to use gemini.

Reviewed changes

Copilot reviewed 13 out of 13 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
cmd/entire/cli/review/types/template.go Update doc comment to refer to gemini (not gemini-cli).
cmd/entire/cli/review/types/reviewer.go Update interface docs/examples to use gemini.
cmd/entire/cli/review/marker_fallback.go Update doc comment to refer to gemini.
cmd/entire/cli/review/manifest.go Return session states from state loading and add explainEmptyManifest diagnostic helper.
cmd/entire/cli/review/manifest_test.go Update manifest warning test expectation; add unit tests covering all explainEmptyManifest branches.
cmd/entire/cli/review/cmd.go Use explainEmptyManifest output for the user-facing “manifest not written” reason and log it at debug.
cmd/entire/cli/agent/skilldiscovery/registry.go Re-key Gemini entries to gemini so eligibility/picker logic matches registry key.
cmd/entire/cli/agent/skilldiscovery/registry_test.go Update tests to expect gemini keys.
cmd/entire/cli/agent/geminicli/reviewer.go Use agent.AgentNameGemini for reviewer name and env handshake.
cmd/entire/cli/agent/geminicli/reviewer_test.go Add test locking Gemini reviewer name to registry constant; update expected name.
cmd/entire/cli/agent/codex/reviewer_test.go Add test locking Codex reviewer name to registry constant.
cmd/entire/cli/agent/claudecode/reviewer_test.go Add test locking Claude Code reviewer name to registry constant.
cmd/entire/cli/agent_group.go Update entire agent add help example from gemini-cli to gemini.

Comment thread cmd/entire/cli/review/manifest.go Outdated
Comment thread cmd/entire/cli/review/manifest.go Outdated
peyton-alt and others added 2 commits May 12, 2026 00:02
…t cleanup

Addresses review feedback on the empty-manifest diagnostic:

1. explainEmptyManifest now iterates summary.AgentRuns and names the
   specific agent whose AgentType has no matching tagged state, instead of
   blaming the first agent in the run list. In multi-agent runs with
   heterogeneous mismatches this prevents the diagnostic from misleading
   users into chasing the wrong filter.

2. Return signature extended to (reason, sentinel bool) so the caller can
   distinguish a known failure cause from the "no filter explained the
   rejection" terminal sentinel — the latter indicates matcher/explainer
   drift and now escalates to logging.Warn instead of being buried at
   Debug level.

3. New TestExplainEmptyManifest_MultiAgentNamesFailingAgent locks the
   per-agent iteration: a 2-agent run with one tagged Claude Code state
   must name "codex" (the failing agent) in the reason, not the first
   agent in the list.

4. New TestBuildLocalReviewManifestFromSummary_PartialMatch_NoWarning
   pins the intentional behavior that a partial-success run produces a
   non-empty manifest, so no warning fires. Future refactors that change
   this have to update the test, forcing the change to be deliberate.

5. Removes TestExplainEmptyManifest_DumpAllReasons — it asserted nothing
   (only t.Logf) and never could fail.

6. Trims comment rot per review: drops the past-bug reference from
   geminicli/reviewer.go and removes the hardcoded lifecycle.go path
   from the gemini test's doc comment so renames don't silently rot it.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Entire-Checkpoint: 3a7fbdf9ee71
Addresses Copilot's review comment that explainEmptyManifest returned on
the first state that failed any filter, even when other tagged states
passed that filter. Example: 2 tagged states where one fails worktree and
the other passes worktree but fails SHA. Old behavior reported "worktree
mismatch" against state-A; matcher actually rejected both — state-A by
worktree, state-B by SHA. The diagnostic blamed the wrong gate.

Refactors the worktree/SHA/StartedAt filters to apply cumulatively via a
new applyExplainerFilter helper. Each filter narrows the candidate set;
the function reports the filter that empties the set. AgentType still
iterates per-agent against the post-cumulative candidate set, so it
benefits from the narrowing too.

New TestExplainEmptyManifest_CumulativeFiltering locks this with the
exact scenario from the Copilot comment: state-A fails worktree, state-B
fails SHA — reported cause must be SHA, not worktree.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Entire-Checkpoint: fe04d8e831be
@peyton-alt peyton-alt changed the title fix(review): manifest-empty diagnostic + gemini reviewer naming alignment review: clearer failure reason when findings aren't saved May 12, 2026
peyton-alt and others added 2 commits May 12, 2026 15:38
… test

Three small follow-ups from review of this PR:

1. Model empty-SessionID as an explicit rejection cause. The matcher
   returns these states, but buildLocalReviewManifestFromSummary drops
   them on st.SessionID == "" before adding a manifest source. Without
   an explainer step the sentinel fired and surfaced a misleading
   "report this as a bug" Warn for what is really a partial-write or
   corrupt-state condition. New filter lives between the tagged-loop
   and the worktree filter so the cumulative-filter contract is
   preserved.

2. Accumulate and sort observed AgentTypes instead of overwriting. The
   diagnostic previously reported whichever mismatched type happened to
   be iterated last — non-deterministic across store.List orderings.
   The dedup + sort makes the rendered state field stable and faithful
   to the full set of mismatched types, which matters when ≥2 distinct
   types are tagged (e.g., both Codex and Gemini state present, agent
   looking for Claude Code).

3. picker_test.go: rename the "gemini-cli" literal to "gemini" so the
   test actually exercises the renamed gemini path. The "empty
   built-ins → Note" branch is generic to unknown agent names, but the
   test name and intent are gemini-specific.

Two new tests cover the explainer changes: empty-SessionID branch and
multi-type aggregation (with states intentionally listed in
reverse-sorted order so the test fails if the sort step is removed).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…diagnostic

# Conflicts:
#	cmd/entire/cli/review/manifest_test.go
@peyton-alt
peyton-alt merged commit c294d1a into main May 13, 2026
9 checks passed
@peyton-alt
peyton-alt deleted the feat/review-manifest-diagnostic branch May 13, 2026 19:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

3 participants