Skip to content

fix(p0): SessionStatus enum — add INACTIVE + REDIRECTED states#23

Merged
SolshineCode merged 1 commit into
mainfrom
fix/p0-session-status-enum
May 8, 2026
Merged

fix(p0): SessionStatus enum — add INACTIVE + REDIRECTED states#23
SolshineCode merged 1 commit into
mainfrom
fix/p0-session-status-enum

Conversation

@SolshineCode
Copy link
Copy Markdown
Owner

Summary

Closes P0 #1 from the 2026-05-08 CTO audit. Adds the two missing PRD-mandated SessionStatus values (INACTIVE, REDIRECTED) plus the surrounding state-machine behavior.

  • PermissionDeniedREDIRECTED (transient state) + momentum=0
  • REDIRECTEDACTIVE on next productive event (TaskCompleted, UserPromptSubmit)
  • REDIRECTED sessions keep earning base reward (PRD "no negative balance")
  • INACTIVE distinct from SUSPENDED (BS-7)

Closes

PRD §BR-1, §BS-7, §TU-4. References: PR #22 (audit), kanban t_26404be3.

Test plan

  • pytest -q → 159 passed (was 149; adds 10)
  • PRD invariants: redirect resets momentum AND marks status; goals/tokens NOT clawed back; redirected session still earns base+goal+token; momentum=0 means culture=0

…BR-1, §BS-7)

Closes the P0 #1 issue from the 2026-05-08 CTO audit. The PRD requires
six classification states (Inactive, Active, WaitingHuman, Completed,
Redirected, Suspended); we previously had four. Without REDIRECTED as
a state, the audit log can't carry the redirect signal cleanly. Without
INACTIVE distinct from SUSPENDED, BS-7's "game open, no work" vs
"game closed" distinction wasn't representable.

bridge/session_state.py:
- Adds INACTIVE and REDIRECTED to SessionStatus
- Docstring documents the full state semantics + the BS-7 distinction
- get_active_sessions now includes REDIRECTED (no clawback rule)

bridge/scoring.py:
- SimpleScoringStrategy treats REDIRECTED like ACTIVE for base reward.
  Culture falls to 0 because momentum is 0, but production / gold /
  science still flow — that's the PRD's "no negative balance" rule
  in action.

bridge/hook_listener.py:
- _handle_permission_denied now marks the session REDIRECTED in
  addition to zeroing momentum; emits 1 or 2 StateChange records
  depending on whether momentum was already zero.
- _handle_task_completed flips REDIRECTED → ACTIVE (productive event
  ends the redirect period). _handle_user_prompt_submit already
  covers WAITING/REDIRECTED/INACTIVE → ACTIVE via the existing
  generic transition.

bridge/tests/test_economy.py:
- Updates test_redirect_via_hook_listener_permission_denied to expect
  the new 2-change emission.

bridge/tests/test_hook_listener.py:
- Updates test_permission_denied_with_zero_momentum to assert the
  new "still marks REDIRECTED" behavior (single status change, no
  momentum change since already zero).

bridge/tests/test_redirected_state_machine.py — 10 new tests:
- Enum has all six PRD-mandated states
- INACTIVE + REDIRECTED serialize through SaveExchange round-trip
- PermissionDenied → REDIRECTED + momentum=0
- REDIRECTED → ACTIVE on UserPromptSubmit
- REDIRECTED → ACTIVE on TaskCompleted
- Redirected sessions keep earning base reward (no clawback)
- get_active_sessions includes REDIRECTED
- get_active_sessions excludes INACTIVE + SUSPENDED
- INACTIVE and SUSPENDED are distinct (BS-7)

Total: 159 passing (was 149; adds 10).

Refs: kanban t_26404be3 (P0 audit issues followup), PR #22 (audit doc).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@SolshineCode SolshineCode merged commit 6a9c13d into main May 8, 2026
1 check passed
@SolshineCode SolshineCode deleted the fix/p0-session-status-enum branch May 8, 2026 17:03
Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request implements the INACTIVE and REDIRECTED session states, updating the state machine to handle transitions during permission denials and task completions. It also ensures REDIRECTED sessions earn base rewards in the scoring logic. Feedback recommends broadening the transition to ACTIVE in _handle_task_completed for consistency and updating the SessionStatus docstring to correctly reflect that both ACTIVE and REDIRECTED states contribute to rewards.

Comment thread bridge/hook_listener.py
Comment on lines +254 to +257
if session.status == SessionStatus.REDIRECTED:
changes.append(listener._set_status(
session, SessionStatus.ACTIVE, note="task_completed_resumes_active"
))
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The current logic only transitions a session from REDIRECTED to ACTIVE upon task completion. However, for consistency with _handle_user_prompt_submit (line 210), any productive event should resume activity if the session is in a non-active state (like WAITING or INACTIVE).

Suggested change
if session.status == SessionStatus.REDIRECTED:
changes.append(listener._set_status(
session, SessionStatus.ACTIVE, note="task_completed_resumes_active"
))
# A productive event ends a non-active period — flip back to ACTIVE.
if session.status != SessionStatus.ACTIVE:
changes.append(listener._set_status(
session, SessionStatus.ACTIVE, note="task_completed_resumes_active"
))

Comment thread bridge/session_state.py
"""Status of a Claude session.

Per PRD §BR-1, sessions are classified as one of these states.
All states except ACTIVE contribute zero base value per turn (BR-4).
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This docstring is now inaccurate. With the introduction of the REDIRECTED state, ACTIVE is no longer the only state that contributes base value per turn. As seen in bridge/scoring.py and get_active_sessions, REDIRECTED sessions also earn rewards.

Suggested change
All states except ACTIVE contribute zero base value per turn (BR-4).
All states except ACTIVE and REDIRECTED contribute zero base value per turn (BR-4).

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.

1 participant