Files
Codeman/test/respawn-scenarios.md
T

1460 lines
32 KiB
Markdown
Raw Permalink Normal View History

# Respawn Controller Test Scenarios
This document identifies edge cases and scenarios not currently covered by the existing test suite in `test/respawn-controller.test.ts`. These scenarios are designed to find gaps in test coverage and ensure robust behavior.
---
## Table of Contents
1. [State Transition Scenarios](#state-transition-scenarios)
2. [AI Idle Checker Integration Scenarios](#ai-idle-checker-integration-scenarios)
3. [AI Plan Checker Integration Scenarios](#ai-plan-checker-integration-scenarios)
4. [Timeout and Cooldown Scenarios](#timeout-and-cooldown-scenarios)
5. [Error Recovery Scenarios](#error-recovery-scenarios)
6. [Concurrent Operation Scenarios](#concurrent-operation-scenarios)
7. [Configuration Change Scenarios](#configuration-change-scenarios)
8. [Buffer and Memory Scenarios](#buffer-and-memory-scenarios)
9. [Edge Cases in Pattern Detection](#edge-cases-in-pattern-detection)
10. [Event Emission and Listener Scenarios](#event-emission-and-listener-scenarios)
---
## State Transition Scenarios
### STS-001: Full Cycle with All Steps Enabled
**Description**: Complete respawn cycle traversing all states when sendClear, sendInit, and kickstartPrompt are all enabled.
**Initial State**: `watching` with all config options enabled
**Actions**:
1. Start controller with `sendClear: true`, `sendInit: true`, `kickstartPrompt: 'continue'`
2. Simulate completion message
3. Wait for confirmation
4. Simulate completion for each step without triggering work after /init
**Expected Behavior**:
- States visited in order: watching -> confirming_idle -> ai_checking -> sending_update -> waiting_update -> sending_clear -> waiting_clear -> sending_init -> waiting_init -> monitoring_init -> sending_kickstart -> waiting_kickstart -> watching
- All stepSent/stepCompleted events emitted
- Cycle count increments
**Priority**: HIGH
---
### STS-002: Cycle Skipping Clear Step
**Description**: Respawn cycle when sendClear is disabled.
**Initial State**: `watching` with `sendClear: false`, `sendInit: true`
**Actions**:
1. Trigger idle detection
2. Complete update step
**Expected Behavior**:
- Should skip directly from waiting_update to sending_init
- No 'clear' step events emitted
**Priority**: MEDIUM
---
### STS-003: Cycle Skipping Init Step
**Description**: Respawn cycle when sendInit is disabled.
**Initial State**: `watching` with `sendClear: true`, `sendInit: false`
**Actions**:
1. Trigger idle detection
2. Complete update step
3. Complete clear step
**Expected Behavior**:
- Should complete cycle after clear
- No 'init' step events emitted
- Should not enter monitoring_init state
**Priority**: MEDIUM
---
### STS-004: Cycle with Neither Clear nor Init
**Description**: Respawn cycle when both sendClear and sendInit are disabled.
**Initial State**: `watching` with `sendClear: false`, `sendInit: false`
**Actions**:
1. Trigger idle detection
2. Complete update step
**Expected Behavior**:
- Cycle completes immediately after update
- Only update step events emitted
**Priority**: MEDIUM
---
### STS-005: Work Triggered During monitoring_init
**Description**: When /init actually triggers Claude to start working.
**Initial State**: `monitoring_init` with kickstartPrompt configured
**Actions**:
1. Reach monitoring_init state
2. Simulate working patterns (e.g., "Thinking...")
**Expected Behavior**:
- Should emit stepCompleted for 'init'
- Should NOT enter sending_kickstart
- Should complete cycle and return to watching
- Log message: "/init triggered work, skipping kickstart"
**Priority**: HIGH
---
### STS-006: State Transition During Step Timer
**Description**: Stopping controller while step delay timer is pending.
**Initial State**: `sending_update` (during interStepDelayMs wait)
**Actions**:
1. Start controller and trigger idle
2. While in sending_update (during delay), call stop()
**Expected Behavior**:
- Step timer should be cleared
- No stepSent event emitted
- State transitions to stopped cleanly
**Priority**: MEDIUM
---
### STS-007: Clear Fallback Timer Trigger
**Description**: /clear step completes via fallback timer when no prompt detected.
**Initial State**: `waiting_clear`
**Actions**:
1. Send /clear command
2. Do NOT simulate prompt detection
3. Wait for CLEAR_FALLBACK_TIMEOUT_MS (10s)
**Expected Behavior**:
- Fallback timer fires
- Logs "clear fallback: proceeding to /init"
- Proceeds to sendInit (or completeCycle if sendInit false)
- stepCompleted event emitted for 'clear'
**Priority**: MEDIUM
---
### STS-008: Clear Fallback Timer Cancelled by Prompt
**Description**: Clear fallback timer is cancelled when prompt is detected.
**Initial State**: `waiting_clear`
**Actions**:
1. Send /clear command
2. Simulate prompt detection before fallback timeout
**Expected Behavior**:
- Fallback timer cancelled with reason "prompt detected"
- timerCancelled event emitted for 'clear-fallback'
- Normal flow continues
**Priority**: MEDIUM
---
### STS-009: Multiple Rapid State Transitions
**Description**: Rapid cycling through multiple states without settling.
**Initial State**: `watching`
**Actions**:
1. Simulate completion message
2. Before confirmation completes, simulate working
3. Immediately after, simulate completion again
4. Repeat several times rapidly
**Expected Behavior**:
- Controller handles transitions gracefully
- No duplicate state entries
- Timers properly cleaned up
- No memory leaks from orphaned timers
**Priority**: HIGH
---
### STS-010: Resume from Non-Watching State
**Description**: Calling resume() when in a state other than watching.
**Initial State**: `sending_update` or any non-watching state
**Actions**:
1. Pause controller
2. Call resume()
**Expected Behavior**:
- Should remain in current state
- Should not call checkIdleAndMaybeStart
- Only watching state triggers idle check on resume
**Priority**: LOW
---
## AI Idle Checker Integration Scenarios
### AIC-001: AI Checker Returns IDLE Verdict
**Description**: AI idle check completes successfully with IDLE verdict.
**Initial State**: `ai_checking`
**Actions**:
1. Trigger AI check via completion message + silence
2. Mock AI checker to return IDLE
**Expected Behavior**:
- aiCheckCompleted event emitted with IDLE verdict
- onIdleConfirmed called
- Respawn cycle begins
- No cooldown started
**Priority**: HIGH
---
### AIC-002: AI Checker Returns WORKING Verdict
**Description**: AI idle check completes with WORKING verdict.
**Initial State**: `ai_checking`
**Actions**:
1. Trigger AI check
2. Mock AI checker to return WORKING
**Expected Behavior**:
- aiCheckCompleted event emitted
- State returns to watching
- Cooldown started (aiIdleCheckCooldownMs)
- aiCheckCooldown event emitted
- No respawn cycle started
**Priority**: HIGH
---
### AIC-003: AI Checker Returns ERROR Verdict
**Description**: AI idle check fails with ERROR verdict.
**Initial State**: `ai_checking`
**Actions**:
1. Trigger AI check
2. Mock AI checker to return ERROR
**Expected Behavior**:
- aiCheckFailed event emitted
- State returns to watching
- consecutiveErrors incremented
- Pre-filter and no-output timers restarted
**Priority**: HIGH
---
### AIC-004: AI Checker Throws Exception
**Description**: AI idle check throws an exception during execution.
**Initial State**: `ai_checking`
**Actions**:
1. Trigger AI check
2. Mock AI checker to throw Error
**Expected Behavior**:
- Exception caught
- aiCheckFailed event emitted
- State returns to watching
- Controller remains stable
**Priority**: HIGH
---
### AIC-005: AI Checker Cancelled Mid-Check
**Description**: AI check cancelled by new working patterns.
**Initial State**: `ai_checking`
**Actions**:
1. Start AI check
2. Before completion, simulate working pattern
**Expected Behavior**:
- AI check cancelled
- Log: "Working patterns detected during AI check, cancelling"
- State returns to watching
- AI check result ignored when it arrives
**Priority**: HIGH
---
### AIC-006: AI Checker Cancelled by Substantial Output
**Description**: AI check cancelled when substantial (>2 chars) output arrives.
**Initial State**: `ai_checking`
**Actions**:
1. Start AI check
2. Simulate output longer than 2 characters (after ANSI stripping)
**Expected Behavior**:
- AI check cancelled
- Log includes "Substantial output during AI check"
- State returns to watching
**Priority**: MEDIUM
---
### AIC-007: AI Checker on Cooldown - Check Skipped
**Description**: AI check attempt while on cooldown from previous WORKING verdict.
**Initial State**: `watching` with AI checker on cooldown
**Actions**:
1. Get WORKING verdict (starts cooldown)
2. Immediately trigger another pre-filter pass
**Expected Behavior**:
- AI check not started
- Log: "AI check on cooldown (Xs remaining), waiting..."
- Controller stays in watching state
**Priority**: HIGH
---
### AIC-008: AI Checker Cooldown Expires
**Description**: Controller behavior when AI checker cooldown expires.
**Initial State**: `watching` with AI checker on cooldown
**Actions**:
1. Wait for cooldown to expire
2. Check that pre-filter timer is restarted
**Expected Behavior**:
- aiCheckCooldown event emitted (false, null)
- Pre-filter timer restarted
- Next idle signal can trigger AI check
**Priority**: MEDIUM
---
### AIC-009: AI Checker Disabled After Max Consecutive Errors
**Description**: AI checker auto-disables after too many errors.
**Initial State**: `watching` with AI check enabled
**Actions**:
1. Cause maxConsecutiveErrors (3) failures
2. Attempt another idle detection
**Expected Behavior**:
- AI checker status becomes 'disabled'
- disabled event emitted with reason
- Falls back to noOutputTimeoutMs for detection
- Log: "AI check unavailable (disabled)"
**Priority**: HIGH
---
### AIC-010: AI Checker Re-enabled via Config Update
**Description**: Re-enabling AI checker after it was disabled.
**Initial State**: AI checker disabled
**Actions**:
1. Call updateConfig({ aiIdleCheckEnabled: true })
**Expected Behavior**:
- AI checker status becomes 'ready'
- disabledReason cleared
- Next idle detection can use AI check
**Priority**: MEDIUM
---
### AIC-011: AI Check Triggered via No-Output Fallback
**Description**: AI check triggered by noOutputTimeoutMs when no output at all.
**Initial State**: `watching` with no output received
**Actions**:
1. Start controller
2. Wait for noOutputTimeoutMs without any terminal output
**Expected Behavior**:
- AI check triggered via no-output fallback path
- aiCheckStarted event emitted
- Log: "No-output fallback: Xs silence"
**Priority**: MEDIUM
---
### AIC-012: AI Check via Pre-Filter Path (No Completion Message)
**Description**: AI check triggered by pre-filter timer without completion message.
**Initial State**: `watching` with output received but no completion message
**Actions**:
1. Receive some output (sets lastOutputTime)
2. Wait for completionConfirmMs of silence
3. Wait for working patterns to be absent for 3s
4. Wait for tokens to be stable
**Expected Behavior**:
- Pre-filter passes
- AI check started
- Works even without completion message detection
**Priority**: MEDIUM
---
### AIC-013: State Change During AI Check - Result Ignored
**Description**: AI check result arrives after state has changed.
**Initial State**: `ai_checking`
**Actions**:
1. Start AI check
2. Stop controller before result arrives
3. AI check completes
**Expected Behavior**:
- Result ignored
- Log: "AI check result ignored (state is now stopped)"
- No state transition attempted
**Priority**: MEDIUM
---
## AI Plan Checker Integration Scenarios
### APC-001: Plan Check Returns PLAN_MODE
**Description**: AI plan check confirms plan mode, triggers auto-accept.
**Initial State**: `watching` with plan mode UI in buffer
**Actions**:
1. Simulate plan mode output (numbered list + selector)
2. Wait for autoAcceptDelayMs
3. Mock plan checker to return PLAN_MODE
**Expected Behavior**:
- planCheckCompleted event emitted
- Enter sent via writeViaScreen
- autoAcceptSent event emitted
- hasReceivedOutput reset to false
**Priority**: HIGH
---
### APC-002: Plan Check Returns NOT_PLAN_MODE
**Description**: AI plan check determines not plan mode.
**Initial State**: `watching` with ambiguous output
**Actions**:
1. Simulate output that passes pre-filter
2. Mock plan checker to return NOT_PLAN_MODE
**Expected Behavior**:
- planCheckCompleted event emitted
- No Enter sent
- Cooldown started (aiPlanCheckCooldownMs)
**Priority**: HIGH
---
### APC-003: Plan Check Already Checking
**Description**: Plan check attempt while already checking.
**Initial State**: Plan checker status = 'checking'
**Actions**:
1. Start a plan check
2. Trigger another auto-accept attempt before first completes
**Expected Behavior**:
- Second check skipped
- Log: "plan check already in progress"
- Only one check runs
**Priority**: MEDIUM
---
### APC-004: Plan Check Cancelled by New Output
**Description**: New output during plan check cancels it.
**Initial State**: Plan check running
**Actions**:
1. Start plan check
2. Simulate new terminal output
**Expected Behavior**:
- Plan check cancelled
- Log: "New output during plan check, cancelling (stale)"
- Result discarded
**Priority**: HIGH
---
### APC-005: Plan Check Result Stale (Output During Check)
**Description**: Plan check completes but output arrived during check.
**Initial State**: Plan check running
**Actions**:
1. Start plan check
2. Record planCheckStartTime
3. Simulate output (updates lastOutputTime)
4. Plan check returns PLAN_MODE
**Expected Behavior**:
- Result discarded (lastOutputTime > planCheckStartTime)
- Log: "Result discarded (output arrived during check)"
- No Enter sent
**Priority**: HIGH
---
### APC-006: Plan Check Result When State Changed
**Description**: Plan check returns PLAN_MODE but state is no longer watching.
**Initial State**: Plan check running
**Actions**:
1. Start plan check
2. Trigger respawn cycle (state changes to sending_update)
3. Plan check returns PLAN_MODE
**Expected Behavior**:
- Result not acted upon
- Log includes "state is X, not sending Enter"
- No auto-accept
**Priority**: MEDIUM
---
### APC-007: Pre-Filter Blocks - No Numbered Options
**Description**: Pre-filter rejects output without numbered options.
**Initial State**: `watching`
**Actions**:
1. Simulate output without numbered list pattern
2. Wait for autoAcceptDelayMs
**Expected Behavior**:
- Pre-filter fails (PLAN_MODE_OPTION_PATTERN not matched)
- Log: "pre-filter did not match plan mode patterns"
- No plan check started
**Priority**: MEDIUM
---
### APC-008: Pre-Filter Blocks - No Selector Arrow
**Description**: Pre-filter rejects output without selector indicator.
**Initial State**: `watching`
**Actions**:
1. Simulate numbered list without selector (no ">" or arrow)
2. Wait for autoAcceptDelayMs
**Expected Behavior**:
- Pre-filter fails (PLAN_MODE_SELECTOR_PATTERN not matched)
- No plan check started
**Priority**: MEDIUM
---
### APC-009: Pre-Filter Blocks - Working Pattern After Selector
**Description**: Pre-filter rejects when working pattern appears after selector.
**Initial State**: `watching`
**Actions**:
1. Simulate: "1. Yes\n> 1.\nThinking..."
2. Wait for autoAcceptDelayMs
**Expected Behavior**:
- Pre-filter fails (working pattern after selector)
- No plan check started
**Priority**: MEDIUM
---
### APC-010: Pre-Filter Passes - Working Pattern Before Selector
**Description**: Pre-filter allows working patterns if they appear before the selector.
**Initial State**: `watching` with AI plan check disabled
**Actions**:
1. Simulate: "Thinking...\nDone.\n> 1. Yes\n 2. No"
2. Wait for autoAcceptDelayMs
**Expected Behavior**:
- Pre-filter passes (working pattern is before selector)
- Auto-accept triggered (since AI plan check disabled)
**Priority**: MEDIUM
---
### APC-011: Plan Check on Cooldown
**Description**: Plan check skipped when on cooldown.
**Initial State**: Plan checker on cooldown
**Actions**:
1. Get NOT_PLAN_MODE verdict (starts cooldown)
2. Simulate plan mode output
3. Wait for autoAcceptDelayMs
**Expected Behavior**:
- Plan check skipped
- Log: "plan checker on cooldown (Xs remaining)"
- No auto-accept
**Priority**: MEDIUM
---
## Timeout and Cooldown Scenarios
### TC-001: Step Confirmation Timer Interrupted by Working
**Description**: Step confirmation timer cancelled by working patterns.
**Initial State**: `waiting_update` with step confirm timer running
**Actions**:
1. Simulate completion message in waiting_update
2. Before confirmation timer fires, simulate working pattern
**Expected Behavior**:
- Step confirm timer cancelled
- Log: "Step confirmation cancelled (working detected)"
- Remains in waiting_update, waiting for real completion
**Priority**: HIGH
---
### TC-002: Completion Confirm Timer Interrupted by Output
**Description**: Confirmation timer restart when output arrives during confirmation.
**Initial State**: `confirming_idle` with timer running
**Actions**:
1. Detect completion message
2. Timer fires but lastOutputTime changed
**Expected Behavior**:
- Timer restarts instead of confirming
- Log: "Output during confirmation, resetting"
- State remains confirming_idle
**Priority**: MEDIUM
---
### TC-003: Multiple Cooldowns Active Simultaneously
**Description**: Both AI idle checker and plan checker on cooldown.
**Initial State**: Both checkers on cooldown
**Actions**:
1. Trigger WORKING verdict on idle checker
2. Trigger NOT_PLAN_MODE on plan checker
3. Try to trigger both checks
**Expected Behavior**:
- Both checks skipped
- Controller falls back appropriately
- Cooldowns expire independently
**Priority**: MEDIUM
---
### TC-004: Zero-Duration Timers
**Description**: Configuration with zero-duration timeouts.
**Initial State**: `watching` with `completionConfirmMs: 0`, `interStepDelayMs: 0`
**Actions**:
1. Trigger completion message
2. Complete full cycle
**Expected Behavior**:
- Timers fire immediately (or within next event loop)
- Cycle completes without hanging
- No errors from zero-duration setTimeout
**Priority**: LOW
---
### TC-005: Very Long Timeout Values
**Description**: Configuration with extremely long timeouts.
**Initial State**: `watching` with `noOutputTimeoutMs: 3600000` (1 hour)
**Actions**:
1. Start controller
2. Stop before timeout
**Expected Behavior**:
- Timer properly cleared on stop
- No dangling timers
- Memory not leaked
**Priority**: LOW
---
### TC-006: Timer Tracking Accuracy
**Description**: Active timer info reflects actual remaining time.
**Initial State**: Timer running
**Actions**:
1. Start a tracked timer (e.g., completion-confirm)
2. Call getActiveTimers() at various intervals
3. Check remainingMs decreases appropriately
**Expected Behavior**:
- remainingMs decreases over time
- Never negative
- Removed from list after firing
**Priority**: LOW
---
## Error Recovery Scenarios
### ER-001: Session Event Handler Throws
**Description**: Exception thrown in terminal data handler.
**Initial State**: `watching`
**Actions**:
1. Cause handleTerminalData to throw (via malformed input)
2. Continue sending normal output
**Expected Behavior**:
- Controller should not crash
- Should handle exception gracefully
- Should continue processing subsequent events
**Priority**: HIGH
---
### ER-002: writeViaScreen Fails
**Description**: Writing to session fails during step send.
**Initial State**: `sending_update`
**Actions**:
1. Mock writeViaScreen to return false or throw
2. Let step delay timer fire
**Expected Behavior**:
- Error should be caught
- Controller should emit error event
- Should not hang in sending state indefinitely
**Priority**: MEDIUM
---
### ER-003: Recovery After Partial Cycle Failure
**Description**: Controller recovers after failing mid-cycle.
**Initial State**: `waiting_clear` when error occurs
**Actions**:
1. Simulate error during waiting_clear
2. Controller returns to watching or stopped
3. Try to start new cycle
**Expected Behavior**:
- Clean state for new cycle
- No leftover timers or state
- New cycle works normally
**Priority**: MEDIUM
---
### ER-004: AI Checker Process Spawn Failure
**Description**: Screen process fails to spawn for AI check.
**Initial State**: `ai_checking`
**Actions**:
1. Trigger AI check
2. Mock screen spawn to fail
**Expected Behavior**:
- Error caught
- aiCheckFailed event emitted
- consecutiveErrors incremented
- Falls back gracefully
**Priority**: MEDIUM
---
### ER-005: Temp File Cleanup Failure
**Description**: Temp file deletion fails in AI checker cleanup.
**Initial State**: AI check completing
**Actions**:
1. Complete AI check
2. Mock unlink to throw
**Expected Behavior**:
- Exception caught (best effort cleanup)
- Check still completes
- No crash
**Priority**: LOW
---
## Concurrent Operation Scenarios
### CO-001: Start Called While Stopping
**Description**: Calling start() immediately after stop().
**Initial State**: Transitioning from running to stopped
**Actions**:
1. Call stop()
2. Immediately call start()
**Expected Behavior**:
- Clean restart
- No duplicate listeners
- Single watching state
**Priority**: MEDIUM
---
### CO-002: Multiple Terminal Events in Same Tick
**Description**: Multiple terminal events processed synchronously.
**Initial State**: `watching`
**Actions**:
1. Emit multiple 'terminal' events without yielding
2. Check state consistency
**Expected Behavior**:
- All events processed in order
- State remains consistent
- No race conditions in timer management
**Priority**: HIGH
---
### CO-003: Config Update During AI Check
**Description**: Updating AI config while check is in progress.
**Initial State**: `ai_checking`
**Actions**:
1. Start AI check
2. Call updateConfig({ aiIdleCheckEnabled: false })
3. AI check completes
**Expected Behavior**:
- Pending check completes
- Future checks use new config
- No crash
**Priority**: LOW
---
### CO-004: Pause During AI Check
**Description**: Pausing controller while AI check is running.
**Initial State**: `ai_checking`
**Actions**:
1. Start AI check
2. Call pause()
3. AI check completes
**Expected Behavior**:
- Timers cleared by pause
- AI check result may arrive but timers won't fire
- Resume can restart monitoring
**Priority**: LOW
---
### CO-005: Buffer Append During Trim
**Description**: New data arrives while buffer is being trimmed.
**Initial State**: Buffer near MAX_RESPAWN_BUFFER_SIZE
**Actions**:
1. Fill buffer to trigger trim
2. Simultaneously append more data
**Expected Behavior**:
- Buffer stays within limits
- No data corruption
- Append operation completes
**Priority**: LOW
---
## Configuration Change Scenarios
### CC-001: Disable Respawn While Running
**Description**: Setting enabled to false while controller is running.
**Initial State**: `watching` with cycle in progress
**Actions**:
1. Call updateConfig({ enabled: false })
2. Check controller behavior
**Expected Behavior**:
- Config updated (for reference)
- Controller continues current operation
- On restart, start() will be no-op
**Priority**: LOW
---
### CC-002: Change updatePrompt During Cycle
**Description**: Changing update prompt while cycle is in progress.
**Initial State**: `waiting_update`
**Actions**:
1. Call updateConfig({ updatePrompt: 'new prompt' })
2. Start next cycle
**Expected Behavior**:
- Current cycle uses old prompt (already sent)
- Next cycle uses new prompt
**Priority**: LOW
---
### CC-003: Toggle sendClear Mid-Cycle
**Description**: Changing sendClear while in waiting_update.
**Initial State**: `waiting_update` with sendClear: true
**Actions**:
1. Call updateConfig({ sendClear: false })
2. Update step completes
**Expected Behavior**:
- Should use updated config value
- Skip clear and proceed appropriately
**Priority**: MEDIUM
---
### CC-004: Change Timeout Values During Wait
**Description**: Modifying timeout values while timer is running.
**Initial State**: Timer running with completionConfirmMs: 10000
**Actions**:
1. Call updateConfig({ completionConfirmMs: 1000 })
2. Check when timer fires
**Expected Behavior**:
- Current timer uses old value
- Next timer uses new value
- No crash or undefined behavior
**Priority**: LOW
---
### CC-005: Update kickstartPrompt to Undefined
**Description**: Removing kickstart prompt during monitoring_init.
**Initial State**: `monitoring_init` with kickstartPrompt set
**Actions**:
1. Call updateConfig({ kickstartPrompt: undefined })
2. /init doesn't trigger work
**Expected Behavior**:
- Should check config at decision time
- May skip kickstart or use stale value
- (Behavior should be defined)
**Priority**: LOW
---
## Buffer and Memory Scenarios
### BM-001: Buffer Trim at Exact Boundary
**Description**: Buffer exactly at MAX_RESPAWN_BUFFER_SIZE.
**Initial State**: Buffer at exactly 1MB
**Actions**:
1. Fill buffer to exactly 1MB
2. Append 1 more character
**Expected Behavior**:
- Trim triggered
- Buffer reduced to RESPAWN_BUFFER_TRIM_SIZE (512KB)
- Most recent data preserved
**Priority**: LOW
---
### BM-002: Continuous High-Volume Output
**Description**: Sustained high-volume terminal output.
**Initial State**: `watching`
**Actions**:
1. Send 1MB of data per second for 10 seconds
2. Check memory usage and behavior
**Expected Behavior**:
- Buffer stays bounded
- No memory growth over time
- Detection still functions
**Priority**: MEDIUM
---
### BM-003: Buffer Clear During Pattern Match
**Description**: Buffer cleared while pattern detection is occurring.
**Initial State**: Processing terminal data
**Actions**:
1. Process data that triggers completeCycle
2. completeCycle clears buffer
3. More data arrives in same handler
**Expected Behavior**:
- New data appended to fresh buffer
- No stale data patterns matched
**Priority**: LOW
---
### BM-004: Action Log Growth
**Description**: Action log entries accumulating over time.
**Initial State**: Many cycles completed
**Actions**:
1. Run many cycles (>20)
2. Check recentActions length
**Expected Behavior**:
- Limited to 20 entries max
- Oldest entries discarded
- Memory stable
**Priority**: LOW
---
## Edge Cases in Pattern Detection
### PD-001: Completion Message Without "Worked"
**Description**: Time duration pattern without "Worked" prefix.
**Initial State**: `watching`
**Actions**:
1. Simulate: "Waiting for 5s before retry"
2. Check if completion detected
**Expected Behavior**:
- NOT detected as completion (requires "Worked" prefix)
- No false positive
**Priority**: HIGH
---
### PD-002: Nested Working Patterns in Text
**Description**: Working pattern words in non-working context.
**Initial State**: `watching`
**Actions**:
1. Simulate: "The 'Thinking' file was created"
2. Check workingDetected status
**Expected Behavior**:
- Currently: Would detect as working (false positive)
- Expected: Should not detect (pattern in quotes)
- (This is a known limitation)
**Priority**: LOW (known limitation)
---
### PD-003: Unicode Prompt Variants
**Description**: Various Unicode prompt characters.
**Initial State**: `watching`
**Actions**:
1. Test: Regular '>' vs Unicode '>' vs fullwidth '>'
2. Check promptDetected
**Expected Behavior**:
- Standard patterns detected
- Variant characters may not be detected
- (Document which are supported)
**Priority**: LOW
---
### PD-004: ANSI Codes Splitting Patterns
**Description**: ANSI escape codes inserted within patterns.
**Initial State**: `watching`
**Actions**:
1. Simulate: "Wor\x1b[32mked\x1b[0m for 2m 46s"
2. Check completion detection
**Expected Behavior**:
- Pattern may not match (ANSI in middle of "Worked")
- (This is edge case behavior)
**Priority**: LOW
---
### PD-005: Token Count at Boundary Values
**Description**: Token counts with k/M suffixes.
**Initial State**: `watching`
**Actions**:
1. Simulate: "999.9k tokens" -> "1.0M tokens"
2. Check lastTokenCount value
**Expected Behavior**:
- 999.9k = 999900
- 1.0M = 1000000
- Token change detected
**Priority**: LOW
---
### PD-006: Empty String Token Pattern
**Description**: Token pattern with malformed numbers.
**Initial State**: `watching`
**Actions**:
1. Simulate: "tokens", " tokens", ".k tokens"
2. Check extractTokenCount returns
**Expected Behavior**:
- Returns null for invalid patterns
- No crash
**Priority**: LOW
---
### PD-007: Multiple Completion Messages Same Data
**Description**: Multiple "Worked for Xm Xs" in single terminal chunk.
**Initial State**: `watching`
**Actions**:
1. Simulate: "Worked for 1s... Worked for 2m 30s"
2. Check behavior
**Expected Behavior**:
- First match triggers detection
- completionMessageTime set
- Single confirmation timer started
**Priority**: LOW
---
### PD-008: Spinner Character in Normal Text
**Description**: Spinner Unicode character in regular output.
**Initial State**: `watching`
**Actions**:
1. Simulate: "The sequence is: ⠋ ⠙ ⠹"
2. Check workingDetected
**Expected Behavior**:
- Currently: Detects as working
- This is expected behavior (conservative)
**Priority**: LOW (expected behavior)
---
## Event Emission and Listener Scenarios
### EE-001: No Listeners Registered
**Description**: Events emitted with no listeners.
**Initial State**: Controller with no event listeners
**Actions**:
1. Start controller
2. Run through cycle
**Expected Behavior**:
- No errors
- Events still emitted (just not handled)
- Controller functions normally
**Priority**: LOW
---
### EE-002: Listener Throws Exception
**Description**: Event listener throws during event handling.
**Initial State**: Listener registered that throws
**Actions**:
1. Register listener: on('stateChanged', () => { throw Error })
2. Cause state change
**Expected Behavior**:
- Exception propagates (EventEmitter default)
- (May want to catch in production)
**Priority**: MEDIUM
---
### EE-003: Listener Removes Itself
**Description**: Listener that removes itself during event handling.
**Initial State**: Self-removing listener registered
**Actions**:
1. Register one-time listener
2. Cause event
**Expected Behavior**:
- Listener called once
- Properly removed
- No memory leak
**Priority**: LOW
---
### EE-004: DetectionUpdate Interval Cleanup
**Description**: Detection update interval properly cleaned up.
**Initial State**: Controller running with detection updates
**Actions**:
1. Start controller (starts 500ms interval)
2. Stop controller
3. Check interval cleared
**Expected Behavior**:
- detectionUpdateTimer cleared on stop
- No interval continuing after stop
- No memory leak
**Priority**: MEDIUM
---
### EE-005: Timer Events During Stop
**Description**: Timer fires during stop() execution.
**Initial State**: Multiple timers running
**Actions**:
1. Call stop()
2. Timer fires during cleanup
**Expected Behavior**:
- Timer callback checks state
- No action taken if stopped
- Clean shutdown
**Priority**: LOW
---
## Summary
### Priority Distribution
| Priority | Count | Description |
|----------|-------|-------------|
| HIGH | 18 | Critical functionality and common paths |
| MEDIUM | 24 | Important edge cases and integrations |
| LOW | 22 | Rare edge cases and nice-to-have coverage |
### Coverage Gaps Identified
1. **Full cycle with all steps enabled** - No test covers the complete path through all states
2. **Clear fallback timer** - Not tested (10s timeout when no prompt detected)
3. **AI checker consecutive errors leading to disable** - Not integration tested
4. **Plan checker result discarding** - Stale result handling not fully tested
5. **Step confirmation timer** - The completionConfirmMs wait after each step not tested
6. **Working pattern detection during waiting states** - Limited coverage
7. **Buffer edge cases** - Trim behavior not tested
8. **Timer tracking for UI** - getActiveTimers() accuracy not verified
9. **Event listener error handling** - Not tested
10. **Elicitation flag lifecycle** - Partial coverage
### Recommended Test Implementation Order
1. STS-001 (Full cycle) - Establishes complete flow understanding
2. AIC-001, AIC-002, AIC-003 - Core AI checker verdicts
3. APC-001, APC-004, APC-005 - Core plan checker scenarios
4. STS-005 (Work during monitoring_init) - Important flow branch
5. TC-001 (Step confirm interrupted) - Timer reliability
6. ER-001 (Handler throws) - Robustness
7. CO-002 (Multiple events same tick) - Concurrency safety