review: a review past the output limit says so, and is never a silent Object (#202) #213

Merged
time merged 1 commits from claude/card-202-truncated-review-2wh43h into main 2026-10-21 03:08:46 +00:00
1 Commits
Author SHA1 Message Date
ClaudeandClaude Opus 5 98c82531e4 review: a review past the output limit says so, and is never a silent Object (#202)
heartbeat / tick (pull_request_review) Successful in 11s
ci / test (pull_request) Successful in 45s
haiku's review of PR #199 ended mid-word at "- **astra.py, `parked_c" and then the footer:
it ran into think()'s max_tokens: 4000. The verdict was Object, so the card went to
needs-human on a review whose last point nobody can read.

- think() returns a Reply: the text as before, carrying the API's stop reason
  (finish_reason: length in the engine's OpenAI shape, stop_reason: max_tokens from the
  Messages API), and takes a max_tokens. A caller that doesn't care uses it as the string
  it is, so nothing else changes.
- review_reply(): a cut-off review is asked once more with TIME_REVIEW_MAX_TOKENS
  (default 8000). Cut off again, it is posted with CUT_NOTE first, which keeps VERDICT
  from matching the half-written verdict, and post_review posts it as a COMMENT rather
  than REQUEST_CHANGES. So it casts no vote: the council waits or the tie-break seat
  votes, and a truncated review is never an Object on its own. The card's beat carries
  cut_off and its note says a review ran into the limit.
- The reviewer prompt asks for the verdict on the first line and at most five points,
  most important first, each a line or two. A longer, complete review might also have
  caught that its first point on PR #199 was wrong (router.pick_cloud does skip n is None).
- doctor lists TIME_REVIEW_MAX_TOKENS.
- Tests: a reply with finish_reason: length is retried at the higher limit (and at the
  value TIME_REVIEW_MAX_TOKENS sets); cut off twice it is posted with the note, as a
  COMMENT, matching no VERDICT, with or without a seat token; a complete reply votes as
  before in one call at 4000. test_time.py, test_seed.py and test_housekeeping.py green
  (the opt-in TIME_TEST_VENTURE suite fails the same way before this change).

Workflow change this needs, not made here (.github/workflows/ is not the worker's to
touch): in .github/workflows/heartbeat.yml, in the heartbeat step's env block, after the
TIME_REVIEW_QUORUM line, add

          TIME_REVIEW_MAX_TOKENS: ${{ vars.TIME_REVIEW_MAX_TOKENS }}   # a cut-off review is asked again with this (default 8000; #202)

Without it the 8000 default still applies; only setting it as an Actions variable needs
the line.

Closes #202

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016D3hR5GpJTPoN44WP3J7oM
2026-10-21 03:00:14 +00:00