nisse-review failed to review #156, and its turn log shows why. This PR fixes the reviewer's side; it goes ahead of #156, which will then be rebased and pushed so it gets a review on this code.
What went wrong
Long files were cut off.read_file stopped at 20,000 characters, with no way to read on. Every main file in #156 is longer than that: review.py is 31k characters with line numbers, and gitea.py, test_review.py and scheduler.py are 25k–26k. So the reviewer:
spent about 20 of its 40 turns on search_code for single definitions (def _point, def _clean, …), each returning one line;
re-read the same files three or four times, getting the same first 20k each time.
The retry carried the first attempt's transcript. That was 97 tool results, about 575 KB. One model call took longer than the 600-second timeout.
Both drafts were lost. Four comments, then two.
Changes
read_file takes an optional start line. It returns up to 20,000 characters in whole lines, says which lines it showed out of the total, and ends with read on with start=N if there's more.
Each run starts fresh from its brief. The new Transcript.since(event_id) in nisse-core limits the view to what comes after the brief, and the log keeps everything before it. ask_expert already scoped its questions this way.
A run that runs out of turns posts its drafted points as a review that says it's partial and ends with no overall view. With nothing drafted, it fails and retries as before.
Tests
New tests:
reading a 1,000-line file in parts gives every line exactly once;
an out-of-range start is refused;
a retry's first call sees one brief and nothing of the failed run;
running out of turns with drafts posts a partial review, and without drafts is a failed run;
Transcript.since.
Mutation checks: removing the fresh view or the partial post fails its test.
Not here
The context trimming, which is shared with nisse-dev, needs its own design work (operator). It cuts by age, so files read earlier drop out of view and get re-read. I've filed a separate issue.
nisse-review failed to review #156, and its turn log shows why. This PR fixes the reviewer's side; it goes ahead of #156, which will then be rebased and pushed so it gets a review on this code.
## What went wrong
- **Long files were cut off.** `read_file` stopped at 20,000 characters, with no way to read on. Every main file in #156 is longer than that: `review.py` is 31k characters with line numbers, and `gitea.py`, `test_review.py` and `scheduler.py` are 25k–26k. So the reviewer:
- spent about 20 of its 40 turns on `search_code` for single definitions (`def _point`, `def _clean`, …), each returning one line;
- re-read the same files three or four times, getting the same first 20k each time.
- **The retry carried the first attempt's transcript.** That was 97 tool results, about 575 KB. One model call took longer than the 600-second timeout.
- **Both drafts were lost.** Four comments, then two.
## Changes
- **`read_file` takes an optional `start` line.** It returns up to 20,000 characters in whole lines, says which lines it showed out of the total, and ends with `read on with start=N` if there's more.
- **Each run starts fresh from its brief.** The new `Transcript.since(event_id)` in nisse-core limits the view to what comes after the brief, and the log keeps everything before it. `ask_expert` already scoped its questions this way.
- **A run that runs out of turns posts its drafted points** as a review that says it's partial and ends with no overall view. With nothing drafted, it fails and retries as before.
## Tests
- **New tests:**
- reading a 1,000-line file in parts gives every line exactly once;
- an out-of-range `start` is refused;
- a retry's first call sees one brief and nothing of the failed run;
- running out of turns with drafts posts a partial review, and without drafts is a failed run;
- `Transcript.since`.
- **Mutation checks:** removing the fresh view or the partial post fails its test.
## Not here
The context trimming, which is shared with nisse-dev, needs its own design work (operator). It cuts by age, so files read earlier drop out of view and get re-read. I've filed a separate issue.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
https://claude.ai/code/session_01J5Utyfzw7gF7UhjRDEtjTk
From its failed review of #156: read_file stopped at 20,000 characters
with no way on, so the reviewer hunted each file's end a definition at a
time and ran out of turns; its retry carried every read before it, and a
model call timed out. Both drafts were lost.
- read_file takes a start line and says where the next part starts.
- Each run's view starts at its brief (Transcript.since); the log keeps
the rest.
- A run out of turns with points drafted posts them as a partial review.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01J5Utyfzw7gF7UhjRDEtjTk
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
nisse-review failed to review #156, and its turn log shows why. This PR fixes the reviewer's side; it goes ahead of #156, which will then be rebased and pushed so it gets a review on this code.
What went wrong
read_filestopped at 20,000 characters, with no way to read on. Every main file in #156 is longer than that:review.pyis 31k characters with line numbers, andgitea.py,test_review.pyandscheduler.pyare 25k–26k. So the reviewer:search_codefor single definitions (def _point,def _clean, …), each returning one line;Changes
read_filetakes an optionalstartline. It returns up to 20,000 characters in whole lines, says which lines it showed out of the total, and ends withread on with start=Nif there's more.Transcript.since(event_id)in nisse-core limits the view to what comes after the brief, and the log keeps everything before it.ask_expertalready scoped its questions this way.Tests
startis refused;Transcript.since.Not here
The context trimming, which is shared with nisse-dev, needs its own design work (operator). It cuts by age, so files read earlier drop out of view and get re-read. I've filed a separate issue.
🤖 Generated with Claude Code
https://claude.ai/code/session_01J5Utyfzw7gF7UhjRDEtjTk