Lane 10 PR 4b: reactions and taking back (#736) #883

Merged
claude-bot merged 7 commits from build/lane10-4b-reactions into main 2026-09-27 20:39:16 +00:00
Collaborator

Part of #736 (lane 10). Stacked on #876 (4a posts). It merges with that stack in the train.

What it builds

  • The vote reply's slate (EX-024). The bot's vote route now returns your_answers, so the bot's reply names the voter's whole current slate: "your yes for Option B is recorded — A and B work for you."

  • ❔ maybe on a confirmed session (EX-023).

    • rsvp: yes|maybe|no joins BotAttendanceRequest, and attended is now optional. A maybe sets rsvp_status and never touches attended.
    • The confirmed post is seeded with ✅ ❌ ❔. The three are mutually exclusive, on a best-effort basis that depends on the bot having Manage Messages.
    • The confirmed footer now says "❔ if you might".

    4a's note declining a third reaction is about the per-slot time poll (ten emoji on a five-slot poll), not this single attendance ❔.

  • Taking back (O10, D157).

    • shelf_reveals records the Discord message it was posted as. POST /api/bot/reveals/{id}/message is new, and the bot reports where the embed landed.
    • revoke_reveal publishes reveal_taken_back, and the bot deletes its own post. That is best-effort and silent on 404 or Forbidden.
    • A second revoke does nothing.
    • DM handouts are lane 8's shape and get the same columns when lane 8's migration lands.
  • A reveal_taken_back bell row for the campaign's other GMs, excluding the actor, on the GM-tasks row. It uses the same shape as member_joined.

Migration

10b2c3d4e5f6_reveal_discord_message on 10d4e5f6a7b8:

  • it adds the two message columns;
  • ck_notifications_kind gains reveal_taken_back and remains the union of all earlier kinds.

Up → down → up is clean on Postgres 16. The one-head pin moved to the new migration's test.

Bot contract

Additive; it stays at v2. The new surface:

  • an optional field (rsvp);
  • a new response field (your_answers);
  • a new route;
  • a new stream event type, which older bots log and drop.

check_version_sync.py passes.

Checks

  • Bot suite: 625 passed.
  • Backend: 337 passed across every touched module. The full backend suite was not run locally because another agent's suite held the slot; CI runs it.
  • Frontend: vitest 2605 passed (NOTE_KIND covers the new kind). eslint reports 0 errors.
  • ruff: clean. The bot/ directory was not reformatted.
  • Changelog: a changelog.d/ fragment.

Question for the owner

The bell audience for reveal_taken_back (co-GMs, excluding the actor) was inferred, not specified. It's on the questions page as B11.

🤖 Generated with Claude Code

Part of #736 (lane 10). **Stacked on #876 (4a posts).** It merges with that stack in the train. ## What it builds - **The vote reply's slate (EX-024).** The bot's vote route now returns `your_answers`, so the bot's reply names the voter's whole current slate: "your yes for Option B is recorded — A and B work for you." - **❔ maybe on a confirmed session (EX-023).** - `rsvp: yes|maybe|no` joins `BotAttendanceRequest`, and `attended` is now optional. A maybe sets `rsvp_status` and never touches `attended`. - The confirmed post is seeded with ✅ ❌ ❔. The three are mutually exclusive, on a best-effort basis that depends on the bot having Manage Messages. - The confirmed footer now says "❔ if you might". 4a's note declining a third reaction is about the **per-slot time poll** (ten emoji on a five-slot poll), not this single attendance ❔. - **Taking back (O10, D157).** - `shelf_reveals` records the Discord message it was posted as. `POST /api/bot/reveals/{id}/message` is new, and the bot reports where the embed landed. - `revoke_reveal` publishes `reveal_taken_back`, and the bot deletes its own post. That is best-effort and silent on 404 or Forbidden. - A second revoke does nothing. - DM handouts are lane 8's shape and get the same columns when lane 8's migration lands. - **A `reveal_taken_back` bell row** for the campaign's *other* GMs, excluding the actor, on the GM-tasks row. It uses the same shape as `member_joined`. ## Migration `10b2c3d4e5f6_reveal_discord_message` on `10d4e5f6a7b8`: - it adds the two message columns; - `ck_notifications_kind` gains `reveal_taken_back` and remains the union of all earlier kinds. Up → down → up is clean on Postgres 16. The one-head pin moved to the new migration's test. ## Bot contract **Additive; it stays at v2.** The new surface: - an optional field (`rsvp`); - a new response field (`your_answers`); - a new route; - a new stream event type, which older bots log and drop. `check_version_sync.py` passes. ## Checks - **Bot suite:** 625 passed. - **Backend:** 337 passed across every touched module. The full backend suite was not run locally because another agent's suite held the slot; CI runs it. - **Frontend:** vitest 2605 passed (`NOTE_KIND` covers the new kind). eslint reports 0 errors. - **ruff:** clean. The `bot/` directory was not reformatted. - **Changelog:** a `changelog.d/` fragment. ## Question for the owner The bell audience for `reveal_taken_back` (co-GMs, excluding the actor) was inferred, not specified. It's on the questions page as B11. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
WIP: migration 10b2c3d4e5f6 (shelf_reveals.discord_message_id/channel_id,
ck_notifications_kind + reveal_taken_back); the bot vote reply carries
your_answers so an ack can name a voter's whole slate (EX-024); attendance
reactions gain ❔ maybe with mutual exclusion against ✅/❌ (EX-023, D50),
carried as BotAttendanceRequest.rsvp without touching attended; the bot
reports a shelf_reveal's message id back (POST /api/bot/reveals/{id}/message)
so revoke_reveal tells the bot to delete it (O10) and notifies the campaign's
other GMs. All additive: BOT_CONTRACT_VERSION stays 2.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ruff format on the four backend files that needed it; the reveal-discord-
message migration test's _use_it step must be sync, not async, to actually
run (alembic's Operations.context calls it plain); the idempotency test
patches publish_bot_event_async around both revokes instead of only the
second. changelog.d/736-lane10-reactions.changed.md.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
claude-bot changed target branch from build/lane10-4a-posts to main 2026-09-27 11:48:59 +00:00
Merge main into build/lane10-4b-reactions
Some checks failed
CI / Bot/backend version sync (pull_request) Successful in 31s
CI / Backend lint (ruff) (pull_request) Successful in 33s
CI / Feedback site tests (pull_request) Successful in 47s
CI / Does this change touch the recording path? (pull_request) Successful in 25s
CI / Synthetic session harness (no GPU, no LLM) (pull_request) Has been skipped
CI / Summarisation accuracy eval harness (stub provider) (pull_request) Successful in 2m32s
CI / Docker image build (pull_request) Successful in 2m39s
CI / Bot tests and audit (pull_request) Successful in 4m15s
CI / End-to-end journeys (desktop, phone, keyboard-only) (pull_request) Failing after 3m28s
CI / Backend migration, tests, and audit (pull_request) Failing after 10m51s
CI / Frontend tests, audit, and build (pull_request) Successful in 26m58s
71026dd134
test(backend): the discussions migration's kinds are a historical fact without reveal_taken_back (#736)
Some checks failed
CI / Summarisation accuracy eval harness (stub provider) (pull_request) Successful in 56s
CI / Does this change touch the recording path? (pull_request) Successful in 20s
CI / Synthetic session harness (no GPU, no LLM) (pull_request) Has been skipped
CI / Docker image build (pull_request) Successful in 1m21s
CI / Bot/backend version sync (pull_request) Successful in 1m23s
CI / Backend lint (ruff) (pull_request) Successful in 1m30s
CI / Bot tests and audit (pull_request) Successful in 1m57s
CI / Feedback site tests (pull_request) Successful in 2m12s
CI / Backend migration, tests, and audit (pull_request) Failing after 10m46s
CI / Frontend tests, audit, and build (pull_request) Has been cancelled
CI / End-to-end journeys (desktop, phone, keyboard-only) (pull_request) Has been cancelled
ae35271182
test_discussion_notifications_migration (from lane 8 PR 1, merged after this
PR was built) compares its migration's kind CHECK to the model minus later
kinds; reveal_taken_back is one more, added by 10b2c3d4e5f6.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
test(backend): the safety and server-owner migrations' kinds are historical facts without reveal_taken_back (#736)
All checks were successful
CI / Summarisation accuracy eval harness (stub provider) (pull_request) Successful in 52s
CI / Backend lint (ruff) (pull_request) Successful in 1m19s
CI / Feedback site tests (pull_request) Successful in 44s
CI / Bot tests and audit (pull_request) Successful in 1m49s
CI / Does this change touch the recording path? (pull_request) Successful in 20s
CI / Synthetic session harness (no GPU, no LLM) (pull_request) Has been skipped
CI / Bot/backend version sync (pull_request) Successful in 1m2s
CI / Docker image build (pull_request) Successful in 4m26s
CI / Backend migration, tests, and audit (pull_request) Successful in 14m11s
CI / End-to-end journeys (desktop, phone, keyboard-only) (pull_request) Successful in 41m31s
CI / Frontend tests, audit, and build (pull_request) Successful in 49m28s
e3a3917429
The same exclusion as the discussions migration's test; every
kinds-versus-model test now passes (269, run as one set).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign in to join this conversation.
No description provided.