Conversation
Two sessions on one repository -- one armed via `bin/oss-workspace`, one a
bare `claude` subscribed to nothing -- can hold genuinely different,
simultaneously correct channel readings, and the cache was keyed on the
repository alone. Whichever session's reading landed last was rendered as
every session's own state.
`channel_status` gains a fifth `cannot_determine` reason, `other-session`,
checked right after `not-asked` and before attribution or staleness. The
cache document's `channel` dict gains a `session` field, threaded from
`gather()`'s own `payload.get("session_id")` through `_fork_refresh`'s new
`--session-id` argv into `refresh()`. Every other cached field stays shared
exactly as before -- only the channel reading gains the new dimension. A
cache written before this fix carries no `session` key and self-heals at the
next refresh, the same convention #754's own `attribution` migration used.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QYm4rkixzFWu3MXm2r9hhG
…review) The Explore self-review spawn found that `_fork_refresh` forwarded `session_id` straight into `subprocess.Popen`'s argv with no type check, and the surrounding `except (OSError, ValueError)` does not catch the `TypeError` a non-str/bytes/PathLike argv element raises -- so a malformed statusline payload (`session_id` arriving as an int or a dict) would crash the ENTIRE status line render, not just the channel field it was meant to help. Guarded at both the write site (`_fork_refresh` only forwards a truthy `str`) and the read site (`gather()` coerces a non-string `session_id` to `None` before it reaches either `_fork_refresh` or `channel_status`), the same "untrusted value becomes absent, never a crash" treatment this module already gives a malformed `.supertool.json`. New test: `test_fork_refresh_a_non_string_session_id_does_not_crash_the_whole_render`, red before this commit, green after. `fix_commit_scope.py --file scripts/statusline.py --file tests/test_statusline_channel_session_1362.py` -> within-scope, no second review pass needed. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QYm4rkixzFWu3MXm2r9hhG
… own fix CI (PR #1388, macos-latest/3.12 and windows-latest/3.12) failed with `TypeError: <lambda>() got an unexpected keyword argument 'session_id'` at `main()`'s `refresh(root, session_id=session_id)` call. The earlier commits in this branch widened every monkeypatched `_fork_refresh` lambda (six files) but missed two sites that monkeypatch `refresh` itself: - tests/test_statusline_mark_stale_receipt_1346.py::test_refresh_root_as_last_argument_does_not_raise - tests/test_triage_board_stale_1313.py::test_refresh_alone_is_not_the_same_event_and_does_not_write_stale_after Both widened to accept and ignore the new optional `session_id` parameter, the same shape as the other six. Grepped tests/ once more for every remaining `monkeypatch.setattr(statusline, "refresh"|"_fork_refresh", ...)` call site -- none left uncovered. Full targeted set (11 files) plus these two: 244 passed. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QYm4rkixzFWu3MXm2r9hhG
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #1362.
Problem
scripts/statusline.py's cache is keyed on the repository alone, and for almost every field (prs,issues,latest,pr_checks, etc.) one shared reading per repository is exactly right. Thechannelfield is not such a fact:raw_state'sforwardingvsnot_subscribeddistinction comes fromchannel:health's ownsession:row -- whether the session that took the reading is subscribed to the socket. Two sessions on one repository (one armed viabin/oss-workspace, one a bareclaudesubscribed to nothing) can hold genuinely different, simultaneously correct answers, and whichever session's reading landed last was rendered as every session's own state -- a measurement taken by a different session, rendered as this session's own, which is this repository's own defect class landing on the instrument whose job is tellingunknownfromknown.Fix
channel_status()gains a fifthcannot_determinereason,other-session, via two new optional kwargs (session,current_session). Checked right after the existingnot-askedcheck and before attribution/staleness -- a reading from a different session is untrustworthy regardless of how sound it otherwise looks.channeldict gains asessionfield, written byrefresh()(new optionalsession_idparam) on a fresh reading, threaded fromgather()'s ownpayload.get("session_id")(Claude Code's own statusline JSON payload) through_fork_refresh's new--session-idargv.sessionkey and self-heals at the next refresh, the same convention statusline: a repo that must declare a short watch_name can never render anything butch?#754's ownattributionmigration used.Self-review finding, fixed in place
The self-review
Explorespawn found that a malformedsession_id(a non-string value from a malformed payload) would reachsubprocess.Popen's argv unchecked and raise an uncaughtTypeError, crashing the entire statusline render rather than costing only the channel field its answer. Fixed at both the write site (_fork_refreshonly forwards a truthystr) and the read site (gather()coerces a non-string value toNoneat the source), with a new red/green test.fix_commit_scope.pyreportedwithin-scope, so no second review round was needed. Theoss:auditorspawn's four-class checklist (absence handling, guard-not-run, untrusted-text boundary, cross-platform) returned clean.Tests
New file
tests/test_statusline_channel_session_1362.py: must-fire/must-not-fire pairs for theother-sessionreason at both thechannel_status()unit level and thegather()integration level, a backward-compat control for a cache with nosessionkey recorded,refresh()/_fork_refresh()/main()argv-threading tests, and the self-review's non-string-session_idregression test. Six pre-existing test files were touched only to widen a monkeypatched_fork_refreshlambda's signature to accept the new optional third parameter.Not pushed, not opened as a PR by this session -- both commits are on
fix/1362, ready for the maintainer to push and open.🤖 Generated with Claude Code
https://claude.ai/code/session_01QYm4rkixzFWu3MXm2r9hhG
[AI-generated]