# Effect coverage and starter reachability

Reviewed 2026-11-01. This inventory covers every operation and condition fact
declared by effect schema `0.1.0`. It tracks focused assertions, not Python
line coverage. A full-game replay passing through an operation does not prove
its boundary cases. A dash means no dedicated tutorial is claimed here.

Test names below omit the `test_` prefix. `engine`, `tutorials`, `recursion`,
`deck_choices`, `draw_exhaustion`, `teaser`, `stage_drop` and `redirection` refer
to the files under `tests/test_*.py`.
The linked guides identify saved traces and checkpoints. **Gap** marks work
still needed; a named test does not claim exhaustive coverage.

## Operations

| Operation | Focused assertion or gap | Seeded teaching evidence / boundary |
| --- | --- | --- |
| `add-counter` | engine: `scene_replacement_and_activated_cost_modifier_resolve`; redirection: `scandal_threshold_discards_before_draw_and_stops_star_income` | [Recursion](recursion.v0.md) puts a Teaser on entry; [redirection](redirection-scandal.v0.md) gives one Scandal. Scandal 2→3 requires controlled setup. |
| `change-tone` | tutorials: `own_hex_priority_cost_tone_and_damage_lifecycle`; engine: `subtitle_rechecks_scene_tone_and_skips_only_invalid_action` | [Subtitle](subtitle-reversal.v0.md); source-tone choice remains unresolved. |
| `choose-one` | engine: `main_choice_exposes_only_legal_option`, `damage_response_prevents_damage_then_resolution_resumes` | [Redirection](redirection-scandal.v0.md) reaches Rumor's main-only draw choice. |
| `counter-card` | engine: `counter_payment_is_unavailable_below_two_fandom`; tutorials: counter branch checkpoints | [Counter/prevention](counter-prevention.v0.md): pay and decline from one prefix. |
| `deal-damage` | engine: prevention, counter and Composure-loss tests; tutorials: Subtitle damage lifecycle | [Subtitle](subtitle-reversal.v0.md) and [counter/prevention](counter-prevention.v0.md). |
| `draw` | engine: `turn_shell_refills_fandom_and_skips_only_the_first_draw`; deck_choices: empty turn draw; draw_exhaustion: last card versus empty deck, fatal Rumor choice, Umbrella loss, multi-card/all-player terminal interruption | [Recursion](recursion.v0.md): Streaming Party draws on both casts. [Group Chat](group-chat.v0.md): choice changes the next draw. [Draw exhaustion](draw-exhaustion.v0.md): seeded Watch Party condition and empty draw. Multi-card/all-player draws use validated test-only variants; DR-1 is fixed. |
| `gain-resource` | recursion: `lightstick_scene_bonus_obeys_pool_cap_on_each_gain`; engine: terminal tests | [Recursion](recursion.v0.md) shows ordered Fandom/Trend gains. Cap boundary is controlled, without a dedicated overflow tutorial. |
| `look-at-top` | deck_choices: `look_observer_and_move_follow_controller_in_either_seat`, `empty_and_singleton_decks_preserve_order_without_exhaustion`, `capped_fandom_does_not_skip_look_or_choice` | [Group Chat](group-chat.v0.md): identities and observer recorded before the choice; look is not draw. Empty decks are controlled. |
| `lose-resource` | engine: `composure_loss_bypasses_damage_prevention`, `source_specific_prevention_spares_other_damage_and_expires` | [Subtitle](subtitle-reversal.v0.md): rainy end-step/pass comparison. |
| `modify-cost` | engine: static reductions; teaser: nonmatching/opponent casts, countered Hex, stacked zero floor, source replacement and expiry | [Teaser](teaser-discounts.v0.md): activation payment, resolution, then next-Hex consumption. Multiple counters and cross-deck ownership require controlled setup. [Subtitle](subtitle-reversal.v0.md) uses Rain's static confession discount. |
| `move-counter` | redirection: original Photo target restrictions; teaser: `transfer_conserves_counters_including_self_and_opponent_source`, `partial_target_loss_skips_transfer_but_only_total_loss_skips_gain` | [Teaser](teaser-discounts.v0.md): self-transfer versus transfer to an own Star. Opponent-held Teasers, extra counters and response-window target removal are controlled. |
| `move-top-to-bottom` | tutorials: `group_chat_choice_changes_only_own_order_and_next_draw`; deck_choices: controller scoping, invalid choices, empty/singleton order | [Group Chat](group-chat.v0.md): move/leave branches and both players' subsequent draws. Empty/singleton choices are controlled no-ops. |
| `prevent-damage` | engine: damage response, source-specific shield and countered Feint tests | [Counter/prevention](counter-prevention.v0.md) and [Subtitle](subtitle-reversal.v0.md). |
| `redirect-target` | redirection: controller, card-pattern, counter, use-limit and revalidation tests | [Redirection](redirection-scandal.v0.md); some filters require controlled variants. |
| `remove-counter` | teaser: `activation_pays_immediately_and_zero_counter_rejects_reuse`, `multiple_activations_stack_and_all_consume_at_zero_cost` | [Teaser](teaser-discounts.v0.md): payment before response priority and modifier resolution. Zero-counter reuse is rejected; repeat activation requires controlled extra counters. |
| `return-card` | recursion: own discard/type/cost filters, no-Scene return, target revalidation; tutorials: recursion checkpoints | [Recursion](recursion.v0.md): both Comeback Fandom targets. Discard removal/control change during a response requires controlled setup. |

## Condition facts

| Fact | Focused assertion or gap | Seeded teaching evidence / boundary |
| --- | --- | --- |
| `all-players-control` | **Gap:** Finale Kiss Cut with zero, one and two occupied Scene slots | —; both players having Scenes is reachable. |
| `any-player-controls` | recursion: `return_without_scene_and_bonus_from_either_players_scene`, `scene_bonus_is_checked_at_resolution` | [Recursion](recursion.v0.md) shows the positive case. Scene entry/removal while Spark is pending is controlled. |
| `cards-cast-this-turn` | stage_drop: `bloom_counts_itself_at_two_three_and_repeated_cast_boundary`, failed-cast and opponent/prior-turn exclusions, terminal interruption | [Stage Drop](stage-drop.v0.md): Bloom as second versus fourth cast, including a normal Lightstick return/recast. Three events from two identities requires a controlled return; canonical recursion also casts Spark. |
| `controller-controls` | recursion: Lightstick cap test; engine: Subtitle Scene ownership tests | [Recursion](recursion.v0.md) gives Lightstick's bonus; **gap:** dedicated Lightstick own/opponent/no-Scene comparison. |
| `event-count` | tutorials: `response_cast_counts_for_rain_end_step_even_on_opponent_turn` | [Subtitle](subtitle-reversal.v0.md): both players' Hex counts and end-step iteration. |
| `pending-damage` | engine: `main_choice_exposes_only_legal_option`, `damage_response_prevents_damage_then_resolution_resumes` | [Redirection](redirection-scandal.v0.md): prevention option absent in main. |
| `resource-changed-this-turn` | tutorials: counter and Subtitle histories exercise Chorus after a gain; **gap:** explicit gain/loss/player/time negative cases | [Counter/prevention](counter-prevention.v0.md) supplies the positive case. |
| `resource-lost-this-turn` | recursion: `watch_party_draw_requires_own_composure_loss_this_turn`; tutorials: `watch_party_empty_turn_draw_enables_another_empty_draw` | [Draw exhaustion](draw-exhaustion.v0.md): legal Watch Party positive/negative condition and pass comparison. Controlled tests distinguish player, resource, direction, zero change and turn. |
| `source-counter` | engine: `static_cost_reductions_apply_with_a_zero_floor`; redirection: Scandal threshold tests | [Redirection](redirection-scandal.v0.md): 0 versus 1 Scandal changes the Encore discount. |
| `trigger-source-card` | stage_drop: resource/cause/player filters, either-seat controller, once-per-turn/reset, counter/fizzle non-consumption and terminal interruption; tutorials: `stage_drop_order_changes_bonus_and_bloom_cast_threshold` | [Stage Drop](stage-drop.v0.md): Spark is a Hex Line, Bloom an Encore; first gain consumes the trigger. Other source/resource types and controller swaps are controlled. |

Streaming Party's Hex-count **amount expression** is distinct from the
`cards-cast-this-turn` condition. The recursion tutorials check zero and one
Hex, including a recast Fandom card; the controlled test checks turn reset.
Bloom's separate three-card threshold now has focused tests in `stage_drop`.

## Next coverage increments

1. Resolve Subtitle's source-tone contract before testing tone-sensitive changes.
2. Cover the remaining condition facts: both-player Scenes, actual Fandom gains
   and Lightstick's own/opponent/no-Scene comparison. Stage Drop's source type
   and Bloom's cast threshold now have focused tests, including recasts.
3. Add legal overflow and Scene-replacement tutorials. Retain controlled tests
   for prerequisites the starter cannot produce, especially three Scandal and
   discard-target removal during Spark's response window.

Resolved counter transfer, next-card modifier consumption/expiry, card-effect
exhaustion and multi-card/all-player draw interruption now have focused tests.
Only single-card/controller draws and one Teaser are reachable from canonical
starter effects. The coverage above does not imply every schema variation or
compound interaction has a dedicated test.

No passing test here clears a balance gate. Seed-43 replication, policy
attribution and table evidence remain separate requirements in the
[pre-tuning protocol](pre-tuning-gates.v0.md).
