Status: Implemented as Variant B and disabled by default in new databases. Enabling it is a separate, room-specific operator decision; database provisioning does not establish live-runtime qualification.
Anonymous Whisperer is a room-scoped guessing game for adults. Participants opt in, one participant privately answers a curated prompt, and the bot publishes that answer without naming its author. Other opted-in participants may each accuse one present room member. A correct accusation identifies the submitter; otherwise a configured one-time credit bonus is awarded only when the accusation quorum is met.
I CONSENT TO PUBLISH: phrase. The
submitted text is shown to the room and may be retained by Bondage Club; do
not submit identifying details, another person’s private information, or
unsafe or non-consensual material.dispatched_unconfirmed; an emit does not prove delivery.Commands work as !whisperer ... or /bot whisperer ..., with submissions as
the sole private-only exception:
| Command | Behavior |
|---|---|
!whisperer join |
Confirm adult status and opt in for the next round. |
!whisperer leave |
Withdraw before a round starts. |
!whisperer start |
Start a round as the submitter after enough opted-in players are present. |
!whisperer submit I CONSENT TO PUBLISH: <response> |
Send as a direct private Whisper to the bot before the submission deadline. |
!whisperer accuse <memberNumber> |
Accuse one present room member by positive member number. |
The bot privately dispatches one selected database prompt to the submitter; delivery is unconfirmed. Each round snapshots the opted-in participant roster. The submitter cannot accuse; accusers must be different participants and must still be present. The bot, the accuser, absent targets, and duplicate accusations are rejected.
Startup idempotently creates a disabled default in the selected runtime database:
prototypePartyGameConfigsmain:anonymous-whisperermainanonymous-whispererThe prompt-based party games share the unique { roomKey: 1, gameId: 1 }
configuration index. New databases use party_game_config_room_game; startup also accepts
the legacy whisperer_room_game_config name with the same keys and unique
option. Neither existing indexes nor configuration documents are replaced.
The default round settings are three minimum players, twenty maximum players,
two-minute submission and accusation windows, a 280-character submission
limit, a two-accusation quorum, a 10-credit bonus, and disabled follow-up.
Code-level bounds are three to twenty players, 30 seconds to ten minutes per
window, 280 Unicode characters and 1,024 UTF-8 bytes per submission, and zero
to 100 bonus credits. Invalid configuration fails closed. The game also stays
disabled unless adultsOnlyRoomConfirmed is explicitly true.
For an approved test-room enablement, update only the fixed test runtime database’s seeded document, increment its revision, and restart the runtime so the setting is reloaded:
db.prototypePartyGameConfigs.updateOne(
{ _id: "main:anonymous-whisperer", revision: 1 },
{
$set: {
enabled: true,
adultsOnlyRoomConfirmed: true,
revision: 2,
updatedAt: new Date(),
},
},
);
Use the exact database selected by RUNTIME_TARGET; never use the source
database. Production enablement requires separate operator review and
qualification. Runtime config changes are read at startup, not watched live.
followupMode currently supports only disabled.
The party-game provisioning workflow can populate and explicitly activate all five prompt-based games in one approved runtime database. It preserves existing settings and prompt edits, checks catalog readiness, and increments existing config revisions only when activation changes their state. A restart is required for Whisperer to reload its configuration.
Startup seeds these ten reviewed, non-identifying adult conversation prompts
into prototypeWhispererPrompts using stable IDs adult-01 through adult-10.
Existing prompt records are preserved on later startups. A round chooses one
enabled prompt; the submitter supplies a response, not a prompt ID.
Prompt documents are bounded and validated at the repository edge. Review changes before enabling prompts; never put player submissions or private information in the curated catalog.
prototypeWhispererSessions stores room/config metadata, prompt ID, participant
and accusation member numbers, deadlines, phase, outcome, bonus metadata, stable
settlement ID, and timestamps—never submission text. A unique sparse active-room
key and revision compare-and-set transitions prevent parallel rounds and
duplicate timer/vote outcomes. Terminal sessions expire after 30 days; pending
bonuses remain durable until settled.
prototypeWhispererLeases holds one renewable owner lease per room. The lease is
renewed every ten seconds and expires after 30 seconds. A second process cannot
serve the same room while the lease is valid.
flowchart LR
Root["start.ts"] --> Plugin["AnonymousWhispererPlugin"]
Plugin --> Commands["WhispererCommandSuite"]
Plugin --> Input["WhispererSubmissionHandler"]
Plugin --> Service["WhispererService"]
Commands --> Service
Input --> Service
Service --> Repo["MongoWhispererRepository"]
Service --> Economy["EconomyPort"]
Service --> Comms["WhispererCommunicationPort"]
Repo --> Config[("prototypePartyGameConfigs")]
Repo --> Prompts[("prototypeWhispererPrompts")]
Repo --> Sessions[("prototypeWhispererSessions")]
Repo --> Lease[("prototypeWhispererLeases")]
Service -. "bounded ephemeral submission only" .-> Memory["Process memory"]
stateDiagram-v2
[*] --> Disabled
Disabled --> Lobby: enabled config + adults-only confirmation
Lobby --> Submission: enough opted-in members; lease held
Submission --> Accusation: valid private consented response dispatched
Submission --> Voided: timeout / author leaves / restart / disconnect / lease loss
Accusation --> Identified: correct observed-member accusation
Accusation --> Voided: deadline without quorum
Accusation --> BonusPending: quorum; no correct accusation
BonusPending --> Complete: stable idempotent grant applied or replayed
BonusPending --> BonusPending: grant failure; retry same operation ID
Identified --> Complete
Voided --> Complete
Complete --> [*]
Disconnect, graceful shutdown, lease loss, and process restart void an active round, clear the in-memory submission, and do not award a bonus. After a restart, the old text is not reconstructed from BC history. A durable bonus-pending outcome is retried with the same economy operation ID. New rounds are blocked while a previous bonus remains unsettled. A missing accusation quorum voids the economic result; a correct guess identifies the author immediately and never earns a bonus. Plug-in shutdown still calls the service to release its lease if a listener or command disposer fails; cleanup errors are reported together.
| Collection | Owner | Contents / retention |
|---|---|---|
prototypePartyGameConfigs |
Whisperer repository | Typed room config; disabled baseline; no TTL. |
prototypeWhispererPrompts |
Whisperer repository | Curated prompts and revisions; no TTL. |
prototypeWhispererSessions |
Whisperer repository | Metadata only; terminal records have 30-day TTL; pending bonuses remain durable. |
prototypeWhispererLeases |
Whisperer repository | Per-room owner and lease expiry; lease is application-enforced, not TTL-deleted. |
prototypeEconomyAccounts / prototypeEconomyLedger |
Shared economy | Submitter award through grantOnce; stable session-derived operation ID and approved whisper_bonus reason. |