fix(#6932): move seenResult flag after successful unmarshal - #6935
Conversation
|
🤖 Finished Review · ✅ Success · Started 10:04 PM UTC · Completed 10:14 PM UTC Commit: Runtime: claude · Model: opus → claude-opus-4-6 · Effort: high · Cost: $2.50 |
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
|
Risk Assessment: low (1/5) DetailsRe-review: Tier 1 signals (2 files, 66 lines, no protected/dependency paths, bot author, 0.50 test ratio) are unchanged from the prior assessment, and the PR's own files are byte-identical to the prior head SHA — the only intervening change is an unrelated merge commit from main. Tier 2 churn on claude_progress.go remains elevated but was already priced into the prior score, so the composite anchors to the prior score of 1 (low). Previous runRisk Assessment: low (1/5) DetailsRe-review: production file unchanged since prior assessment; only the test file was rewritten to fix the test-adequacy finding, so Tier 1 signals (file count, line count, no protected/dependency paths, bot author) are unchanged from the prior run. Tier 2 churn history on claude_progress.go is unchanged and was already priced into the prior score. Composite anchors to the prior score of 1 (low). Previous run (2)Risk Assessment: low (1/5) DetailsMinimal 2-file change (1 production line + 55 test lines) with excellent test ratio, no protected paths, no dependencies, bot author. Tier 2 slightly elevated by high regression history on claude_progress.go but offset by very recent code age and no reverts. Composite rounds to 1 (low). |
|
Looks good to me Previous runLooks good to me Previous run (2)ReviewThe production fix itself is correct: moving FindingsMedium
Next steps:
Previous run (3)Looks good to me |
The seenResult flag was set before json.Unmarshal validated the result event fields. If the unmarshal failed (e.g., usage field has an unexpected type), the continue statement skipped the ResultEvent emission but the flag was already set, suppressing the deferred fallback TokensEvent at stream EOF. This made the outcome strictly worse than pre-#6908 behavior: zero tokens instead of best-effort cumulative tokens. Move seenResult = true to after the successful unmarshal, immediately before onEvent(ResultEvent{...}), so a failed unmarshal preserves the deferred fallback path. Add TestParseClaudeStreamMalformedResultFallsBackToTokensEvent to verify the deferred TokensEvent fires when the result event has valid outer JSON but malformed inner fields. Note: pre-commit could not fetch remote hook repos (sandbox network restriction). Ran gofmt, go vet, and go build directly; all passed. Closes #6932
2263842 to
6a4c3f1
Compare
|
🤖 Finished Review · ✅ Success · Started 11:48 AM UTC · Completed 12:05 PM UTC Commit: Runtime: pi · Model: sonnet → claude-sonnet-5 · Effort: high · Cost: $2.00 |
Superseded by updated review
|
🤖 Finished Fix · ✅ Success · Started 12:07 PM UTC · Completed 12:16 PM UTC Commit: Runtime: claude · Model: sonnet → claude-sonnet-5 · Effort: high · Cost: $0.81 |
…ed TokensEvent The fixture in TestParseClaudeStreamMalformedResultFallsBackToTokensEvent totaled 5100 tokens, at/above tokenThreshold (5000), so the message_delta handler already emitted an incremental TokensEvent before EOF. The deferred fallback (total > lastEmittedTotal) never fired, so the test passed even with the #6932 bug reintroduced (seenResult set before a successful unmarshal) — it wasn't guarding against the regression it was written for. Lower the fixture's cumulative total to 1550, well under tokenThreshold, mirroring TestParseClaudeStreamFinalTokensEventOnCancel. Assert exactly one TokensEvent fires (the deferred one). Verified by temporarily reverting the fix locally: the updated test correctly fails against the pre-fix code and passes against the fix. Addresses #6935
🔧 Fix agent — iteration 1 (bot-triggered)Fixed the single medium-severity test-adequacy finding: the new regression test's fixture total crossed tokenThreshold, causing an incremental TokensEvent to mask the deferred-event assertion, so the test passed even with the #6932 bug reintroduced. Lowered the fixture below threshold and tightened the assertion to require exactly one (deferred) TokensEvent. Verified locally by reverting the production fix and confirming the test now fails as expected, then restored the fix and confirmed the test (and full package suite) pass. Fixed (1):
Tests: passed Decision points
Next steps:
|
|
🤖 Finished Review · ✅ Success · Started 12:18 PM UTC · Completed 12:30 PM UTC Commit: Runtime: pi · Model: sonnet → claude-sonnet-5 · Effort: high · Cost: $1.04 |
Superseded by updated review
|
🤖 Finished Review · ✅ Success · Started 7:19 AM UTC · Completed 7:29 AM UTC Commit: Runtime: pi · Model: sonnet → claude-sonnet-5 · Effort: high · Cost: $1.28 |
Superseded by updated review
|
/fs-fix fix test-adequance issue |
|
🤖 Finished Fix · ✅ Success · Started 7:47 AM UTC · Completed 7:52 AM UTC Commit: Runtime: claude · Model: sonnet → claude-sonnet-5 · Effort: high · Cost: $0.31 |
🔧 Fix agent — iteration 2 (human-triggered)Investigated the human instruction to fix the 'test-adequacy' finding on PR #6935. Found it was already resolved in a prior fix iteration: TestParseClaudeStreamMalformedResultFallsBackToTokensEvent now uses a fixture total (1550) below tokenThreshold and asserts exactly one deferred TokensEvent. Verified correctness by reverting the production fix locally and confirming the test fails as expected, then restoring it and confirming all internal/runtime tests pass. No further code changes were required. Disagreed (1):
Tests: passed Decision points
Next steps:
|
|
🤖 Finished Retro · ✅ Success · Started 9:19 AM UTC · Completed 9:28 AM UTC Commit: Runtime: claude · Model: sonnet → claude-sonnet-5 · Effort: high · Cost: $1.73 |
|
PR #6935 (closes #6932) was a correct, minimal one-line fix to Proposals filed |
…dence Address review feedback on PR #7311: the #6935 evidence entry quoted the fixture sum as originally reviewed (5100) without noting a same-branch follow-up commit corrected it to 1550 before merge, which would read as wrong against the test on main today. Also add the missing contextual backlink from trustworthiness-evidence.md's "Historical track record" passage to the new runtime/configuration comparison evidence, matching the backlinks already added elsewhere. Addresses #7311
Summary
Move
seenResult = truefrom beforejson.Unmarshalto after the successful unmarshal inparseClaudeStream. This fixes a flag-before-validation ordering bug where a failed result event unmarshal would suppress the deferred fallbackTokensEvent, producing zero tokens instead of best-effort cumulative tokens.Related Issue
Closes #6932
Changes
seenResult = trueto after the successfuljson.Unmarshalcall in thecase "result"branch ofparseClaudeStream(internal/runtime/claude_progress.go)TestParseClaudeStreamMalformedResultFallsBackToTokensEventto verify the deferredTokensEventfires when the result event has valid outer JSON but malformed inner fieldsTesting
TestParseClaudeStreamMalformedResultFallsBackToTokensEventpasses, confirming deferred emission fires on unmarshal failureparseClaudeStreamandprogressParsertests pass (31 tests)TestProgressParserResultOverwritesIncrementalTokensstill confirms valid result events suppress deferred emissiongo vet,gofmt,go buildpassCloses #6932
Post-script verification
agent/6932-move-seenresult-after-unmarshal)8a593ad7b64875c0c4016f8f3bd151cc6c83df8a..HEAD)