Skip to content

core: does Trick still earn its place? (no production consumers since #8) #11

Description

@valmathieu

Since #8 collapsed the Round trick mirror onto PlayState, contrai_core.trick.Trick has no
production consumers left
. The only reference in any src/ tree is the re-export in
contrai_core/__init__.py. This issue is to decide whether it stays.

Where it stands

  • Production: zero call sites. The engine stopped importing it; nothing else ever did.
  • Tests: its own packages/contrai-core/tests/test_trick.py, plus
    packages/contrai-engine/tests/test_view/test_recap.py, where it is only a fixture convenience
    (a builder for "a pile of plays" handed to a stub play state) rather than a real dependency.
  • Exceptions: TrickStateError is raised by TrickRecord.__new__ as well, so removing Trick
    would not orphan it.

Every capability has a live equivalent

Trick offers Replacement
mutable, incremental 0–4 plays PlayState.current_tricktuple[Play, ...]
get_current_winner on a partial trick module-level current_winner(plays, trump_suit) — which get_current_winner only delegates to
get_led_suit PlayObservation.led_suit / TrickRecord.led_suit
get_cards / get_plays the tuple itself
is_complete / __len__ len(plays) == 4

The one property only Trick has is being mutable and built up play by play — which is exactly
the shape #8 removed. The mirror existed because a mutable accumulator was kept in lock-step with an
immutable state, and it drifted: the running "Round pts" line sat a frame behind the play state.

The argument for keeping it

The scraper (#7) will materialize observed games into core objects, and it watches a live table play
by play, so an accumulator is a plausible fit. But even there the better shape looks like a plain
list[Play] closed into a TrickRecord at the boundary — what PlayState already does, and what
feeds the play state and supervised learning with no conversion step.

Proposal

Defer the decision to whenever #7's persistence schema lands: that is the moment Trick's only
hypothetical consumer either materializes or doesn't. Deleting it today is a breaking change to a
public core API for no functional gain; leaving it costs nothing but a docs caveat, which
docs/core/index.md and class_core.puml now carry.

If we do remove it

Roughly one self-contained commit:

  • delete the class from packages/contrai-core/src/contrai_core/trick.py and drop it from
    __init__.py's imports and __all__;
  • in test_trick.py, drop the TestTrick* classes and keep TestTrickRecord* /
    TestCurrentWinnerParity;
  • re-point test_view/test_recap.py's fixtures at Play tuples (test_view/test_trick.py already
    works this way);
  • refresh the Trick box and note in class_core.puml, plus the trick.py row in
    docs/core/index.md.

Metadata

Metadata

Assignees

No one assigned

    Labels

    questionFurther information is requested

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions