Skip to content

Fix Claude review stream parsing and clean verdict findings - #12

Draft
MuskanPaliwal wants to merge 73 commits into
mainfrom
fix-claude-review-stream-parser
Draft

MuskanPaliwal wants to merge 73 commits into
mainfrom
fix-claude-review-stream-parser

Conversation

@MuskanPaliwal

Copy link
Copy Markdown
Owner

https://entire.io/gh/MuskanPaliwal/cli/trails/12

This draft pull request was opened by Entire after CI was requested for the linked trail. Feel free to edit the title or body — the link above is what keeps the trail and PR connected.

Soph added 7 commits October 8, 2026 15:45
Entire-Checkpoint: 01M4DW5ATDNVNSC62BZ0T4W77W
Entire-Checkpoint: 01M4DXARWJH9KRTNKZH56V5CVH
Entire-Checkpoint: 01M4FWC12TC3DG8AS11R11H42G
Entire-Checkpoint: 01M4R3R06JVPJEZFBTFC0MWWE1
Entire-Checkpoint: 01M4RK629NZZR3W6R4KFQ9V3HG
Entire-Checkpoint: 01M4RKGF9BBKRWKXXXYVDSQMWT
@MuskanPaliwal
MuskanPaliwal force-pushed the fix-claude-review-stream-parser branch from c42fcb7 to e42158b Compare October 13, 2026 09:57
Soph and others added 19 commits October 13, 2026 17:24
A redirect loop matched ErrRequestPolicy, so a looping cached replica was never marked failed and the warm path refused to fall back to the entry URL. Fetch and push then failed until the 24h replica cache expired. A loop is now an ordinary node failure, and the warm path falls back to the HTTPS entry URL after any failure, including a policy rejection. The server's Location after an entry-domain redirect is still refused on policy errors.

Plain-HTTP data-API discovery rewrote every request to http, including the cluster listing at the discovered core that carries the login JWT, beneath a redirect policy that only saw https. It now rewrites only the data origin's own host.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Entire-Checkpoint: 01M4TXTK26WE7WZ1APCKMCNB8F
Address the remaining review items on the redirect guard:

- Callbacks no longer re-run CheckSecureRedirect; httpclient.New applies it once per hop. A shared-policy rejection now wins over a callback's own error (ErrUseLastResponse still passes through), so a downgrade always reports ErrInsecureRedirect.
- Policy sentinels no longer repeat their parents' text, and the failover error uses fmt instead of errors.Join so git's error output stays on one line.
- requireSameOrigin errors match httpclient.ErrRequestPolicy.
- A source guard rejects replacing a constructed client's CheckRedirect or Transport outside audited files.
- Document the Options, CheckSecureRedirect, WithSecureRedirects, NewClientWithTransport and requireHTTPS contracts, and tighten the redirect tests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Entire-Checkpoint: 01M4TXVJGXG3RKECS4NN430R0W
Composes the existing origin-remote -> cell-placement resolution so plugins
(entire-brain's 'connect') can discover the region-local repo ULID, cell API
URL, and jurisdiction without reimplementing placement logic. Stdout carries
exactly the JSON object; errors go to stderr. Without --json the command
refuses, keeping the human-facing surface uncommitted.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Trail entireio#1555 finding: resolveForgeRepoCellPlacement's errors carry the repo
reference, so the extra wrap printed it twice — the anti-pattern
explain_repo.go's newCrossRepoReader already documents avoiding.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
root.go silences usage globally, so the per-command set was a no-op, and its
placement after the --json check misled two reviewers into expecting a usage
dump on the refusal path. Verified against the built binary: the refusal
prints exactly one stderr line.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…eanups

The repo group's persistent --insecure-http-auth was accepted but never
applied: every sibling relaxes the HTTPS guard via runCoreClient before the
token manager is built, so whereami silently failed against a plain-HTTP dev
control plane. Apply it with the same ordering contract, pinned through a
test seam.

Also from review: route test git setup through testutil.InitRepo/AddRemote
(global git config isolation, per gitenv.go/COR-394), wrap the JSON encode
error and document the deliberate compact-output divergence from printJSON,
and cross-reference whereami in the cli-conventions 'no URL-printing verb'
paragraph.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
`entire enable --force` on a repo that is already set up routes to the
agent picker, which reinstalls nothing non-interactively. Status, doctor,
docs and comments now print `entire agent add <name> --force`, built by
one helper, refreshAgentHooksCommand.

Claude Code's SessionStart banner now also warns when the repo's Entire
hooks are out of date. Only Claude Code: its drift check is a positive
"required hook missing" test, while OpenCode, Pi and Copilot compare the
whole generated file and would false-positive across teammates' CLI
versions.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Entire-Checkpoint: 01M4VN8HR5NF2AQDERCMXRAXGZ
- README: drop the disable/enable round trip (it reinstalls no agent
  hooks) and describe `enable --force` as the Cobra help does.
- Claude Code comments and claude-hooks-integration.md: say what a plain
  install does versus --force, and which installs prune the retired
  post-todo hook.
- Test the outdated-hooks append in handleLifecycleSessionStart; drop
  the string-concatenation test for refreshAgentHooksCommand.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Entire-Checkpoint: 01M4VNWG9SQ1DWZC1353ABT75C
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 7.0.1 to 7.0.2.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](actions/upload-artifact@043fb46...cf430e0)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-version: 7.0.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Entire-Checkpoint: 01M4T8WKYSHZY18PD441EADSA7
Entire-Checkpoint: 01M4TEQ8WT27YGM1M85ZMWCTK7
…a trailing approve

Entire-Checkpoint: 01M4TQHPXAQTF9XT8M53D2RXQZ
Entire-Checkpoint: 01M4TTKCQWHJWATJ9XFYGKCKKA
… issues

Entire-Checkpoint: 01M4TXJTCVC98GS212EYVRNMAJ
…ator

Entire-Checkpoint: 01M4TY6QX208VNY1QCYKDJAKDF
…re a trailing approve

Entire-Checkpoint: 01M4TZ80Q89EW6TEB5B3A5P9Q2
…ing verdict prose

Entire-Checkpoint: 01M4WF8MGE3K3J9R0KCTJ9T9PT
@MuskanPaliwal
MuskanPaliwal force-pushed the fix-claude-review-stream-parser branch from 74e0293 to 5741eb8 Compare October 14, 2026 05:53
MuskanPaliwal and others added 2 commits October 14, 2026 11:58
Keep streamed Pi text from different messages or retry attempts on
separate lines, so a verdict after a tool call still starts its own
line and the clean-review check sees it.

Treat labeled verdicts, feedback labels such as "Nits:", and priority
markers such as "[p1]" as findings when the comments array is empty.

Skip comments with a blank body instead of rejecting the whole array.

Let the judge's comments alone decide what is posted, drop reviewer
JSON lines from the judge prompt, and keep the "Nothing to report"
notice free of internal wording.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Entire-Checkpoint: 01M4WHHZMDTX7F060GG58DRDZJ
Entire-Checkpoint: 01M4WZZMVDVRRQAKSPF84SWMG6
Soph and others added 30 commits October 14, 2026 17:38
…omplete-findings

fix(runners): make trail-review report every issue in one pass
The text-generation prompt carries condensed transcript content. Pi got it
as a positional argument, where other local users can read it from the
process table (ps, /proc/<pid>/cmdline) for the length of the run. Pi reads
the message from stdin in --print mode when none is given on the command
line (verified live on pi 1.1.0), so pipe it the way Codex, Copilot, Cursor,
OpenCode and Claude Code already do.

PiAgent gains a CommandRunner so the transport is unit-tested; an opt-in
ENTIRE_PI_SMOKE test checks the real CLI.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Entire-Checkpoint: 01M4XKQ4GK1SG6SRRJKS576120
The text-generation prompt carries condensed transcript content. agy got it
as the -p value, where other local users can read it from the process table
(ps, /proc/<pid>/cmdline) for the length of the run. agy ignores stdin in
text print mode (since 1.2.7), but `--input-format stream-json` (1.1.15+)
reads NDJSON user messages from stdin. GenerateText now runs
`agy --input-format stream-json --output-format stream-json --print=`,
writes the prompt as one user message, and takes the reply from the final
result event, failing on an ERROR status, a missing result, or an empty
response. Verified live on agy 1.3.3, including a 151 KB prompt and the
isolated home.

stdin also lifts the Linux 128 KiB per-argument and Windows ~32 KiB
command-line limits; the summarize budget comments no longer cite argv,
and the budget itself stays as a cost bound.

The sign-in hint now matches stream-json's lowercase "authentication
required", and an agy too old for --input-format gets a hint naming 1.1.15
rather than a fallback to argv. An opt-in ENTIRE_ANTIGRAVITY_SMOKE test
checks the real CLI.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Entire-Checkpoint: 01M4XM80GZGPGZSMX6K1V4QP4S
Entire-Checkpoint: 01M4XPA6T2M1NSVQ7YN0CRZ64W
The sign-in hint matched stderr only. stream-json also reports the failure
in the result event ("authentication failed or timed out"), and a run that
reported it there alone, exiting 0 with empty stderr, lost the hint. Match
the returned error as well, and accept both wordings.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Entire-Checkpoint: 01M4XPR3NJH7F1MGSDNWQTYXA6
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Entire-Checkpoint: 01M4XPRHVTPX977QFRG0ARK0T5
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Entire-Checkpoint: 01M4XPW4R4YE1BQ9F82VDHKRC3
RunIsolatedTextGeneratorCLI returned stderr only when the process failed.
Antigravity (stream-json) and OpenCode parse a successful exit's output and
can find a failure in it, an ERROR result after exit 0, and their
TextGenerationError then carried no stderr for `entire explain` to show.
Return the captured stderr on every path, including empty output.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Entire-Checkpoint: 01M4XQQHGND2JGJFH4CKW0HS9J
…posting the headings

Sharing the severity check with the bridge's prose splitter made a line
holding only a severity, such as "### High", start a finding of its own.
A reply that grouped its findings under severity headings posted each
heading as an empty finding.

A severity-only line now ends the current finding and sets the severity
of the findings below it; a marker on the finding itself still wins.
Text under such a heading that is not a list item is kept as a finding.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Entire-Checkpoint: 01M4XNKHCDQQSMY6NDCBNT7SXH
A reviewer that wrote its findings, ran a tool, and then sent the
contract line alone had only the JSON's summary checked against an empty
comments array, so its findings were reported as nothing to post.

When the text after the last tool call holds only the contract line, the
report also takes the text before that tool call.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Entire-Checkpoint: 01M4XNKJFD9AZM03E0XT527VTD
Conflicts in doctor.go, status.go and their tests resolved to main's
remedy wording and structure.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Entire-Checkpoint: 01M4XR056W6EZ2SB6SVWF2N3WE
Main's Claude CheckHookConfig now also reports stale commands and missing
timeouts, which fire when a teammate's newer CLI wrote the config. The
SessionStart banner now asks only claudecode.MissingRequiredHooks, the
half CheckHookConfig shares, and points at `entire agent add claude-code`
without --force. It is checked only when the banner is shown.

Remaining remedies follow main's style (`entire agent add <name>`, then
--force if that does not fix it), including the Codex project-layer
message that still said bare `entire enable`. refreshAgentHooksCommand
is gone, and the README --force row is main's again.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
TestInstallHooks_ForeignWrapperOverEntireDoesNotRecurse failed on CI with
"fork/exec .../commit-msg: text file busy". A parallel test that forks while
this process still has the hook open for writing leaves the child holding the
write descriptor, and the kernel refuses to exec the file until that child
execs (golang/go#22315). os/exec does not retry.

The hook is written by installHooks as well as by the test, so pausing forks
around the test's own writes would not cover it. Run the four hook-executing
tests through runHook, which retries Start on ETXTBSY.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Entire-Checkpoint: 01M4XRW67NQPHEXWM1WQM6WHV7
- Test that a repo without Entire's Claude Code hooks gets no banner, and
  that the stale-command test starts from a config that reads as current.
- MissingRequiredHooks: note that removing or renaming a required hook
  would make older CLIs warn about a newer config.
- agent-guide: Codex is among the checks kept out of the banner.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Entire-Checkpoint: 01M4XSK0T4MQCWRCGET799GG90
Warn Claude Code users when required Entire hooks are missing, and fix the remaining hook remedies
…ry-prompt-stdin

antigravity: pass the summary prompt on stdin, not argv
…-stdin

pi: pass the summary prompt on stdin, not argv
…-retry

hooks tests: retry hook exec on ETXTBSY
…reami

feat: expose hosted repo coordinates in repo view --json
…g by them

A line holding only a severity, such as "### High" or "**Low:**", ends
the current finding and is not posted as one. Findings under it no
longer take its severity, and text under it that is not a list item is
no longer kept as a finding. Main never grouped by heading, and the
skip alone is enough to keep headings out of the posted findings.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Entire-Checkpoint: 01M4ZCNSNFCS9F8VFHM421PCEH
When several reviewers' prose is posted together, each narrative starts
with a "## <reviewer>" heading. The splitter glued that heading and the
next reviewer's opening text onto the previous reviewer's last finding.

A top-level Markdown heading now ends the current finding and is not
posted. A heading that is itself a marked finding, such as
"### [medium] cache.go:7 — stale entry", still posts.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Entire-Checkpoint: 01M4ZES4QYSEERN604DBDD51A0
Ending a finding at every heading dropped the text after it unless a list
item followed. A reviewer whose combined section was all prose, or a
paragraph under a heading like "## Notes", was lost instead of posted.
A "# comment" line inside a code block also cut its finding short, and
diff lines like "- timeout := 0" in a block became findings of their own.

Text under a heading is now dropped only as preamble to a following
finding and otherwise posts as its own finding. Code blocks always
continue the current text.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Entire-Checkpoint: 01M4ZFW30ZD2RJ1JT80EZ1GGWC
…t a clean review

When the final message holds only the contract line, the report also
takes the text before the last tool call. That text is often
exploration narration, so its plain bullets ("I'll check:\n- retry.go")
contradicted an empty comments array and posted a clean review.

The borrowed text now contradicts the contract only through severity
markers or a feedback verdict such as "request changes" or "approve
with nits". A report written before the last tool call still posts.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Entire-Checkpoint: 01M4ZJ0MBKKFCEYSP4S8384BAJ
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.

5 participants