Ship two members
landed the member registry (cb_core/members.py) it needs; QA's single-tagged-user scenario describes behaviour v1 never had - see docs/contracts/fun_ship.md
/ship/shippar/shipp- v1 scenarios
- 3
- Ported
- 7
- Green
- 8
- Failing
- —
landed the member registry (cb_core/members.py) it needs; QA's single-tagged-user scenario describes behaviour v1 never had - see docs/contracts/fun_ship.md
UserRegisters.py:216-250What it does
/shipp picks two members of the group at random and declares them a couple:
a relationship dynamic drawn from the group's language pool, a number of
children between zero and three, and a divorce probability. Naming two people
yourself — /shipp alice bob — ships those two instead, whoever they are.
The bot can only ship people it has heard from. It learns who is in a group by watching messages, the same way v1 did, so a group it has just joined ships nobody until two people talk.
Behaviour that must not change
Three spellings all work and always must: /shippar and /ship (v1's) and
/shipp (the QA spec's). The reply is a reply, not a fresh message, and it
carries a ❤️ reaction on the original — including when there are too few
members and the answer is "I haven't seen enough members to ship yet!".
Two quirks are deliberate, not oversights. A single tagged user is ignored:
v1 only reads arguments when two are given, so /shipp @user1 ships two random
members and discards the tag. And an @ you type is not stripped, because the
message template adds its own — /shipp @alice @bob renders @@alice, as it
always has.
Turning fun functions off in /config makes the bot answer with the
"fun functions are off" text rather than staying silent.
The full behaviour contract lives in docs/contracts/fun_ship.md.
How to verify it
qa/features/fun_ship.feature — eight scenarios, run with
python scripts/cb.py test. By hand in the sandbox: have two accounts send any
message in the group first (that is what registers them), then /shipp.
Random media from the group
MediaService.random() done and tested; handler not written
Age guess (agify.io)
GET agify.io?name=, timeout+Breaker per doomlist.py's pattern; fun-gated with v1's fun_off reply. Argument comes from ParsedCommand.args rather than v1's replace-chain, which crashed on a lone trailing space; an agify timeout/error/malformed body/open breaker answers the same not_know text as count == 0, since v1 never handles that case at all (silence). QA authored, not ported