Skip to content

Check-ins that can always look, pause all, and a Bot's routines on its page and in its conversations - #1561

Open
guidovizoso wants to merge 37 commits into
mainfrom
guido/check-in-gaps
Open

guidovizoso wants to merge 37 commits into
mainfrom
guido/check-in-gaps

Conversation

@guidovizoso

Copy link
Copy Markdown
Collaborator

What a person saw

An audit of check-ins (OpenBot's answer to proactive agents) on a personal and a team server found the mechanism sound and the experience around it failing:

  1. A check-in could be turned on for something it could never read. A Bot offered one on a GitHub releases page it had read in its browser. The card said it checked the page once a day; it was skipped on every run, and nobody was told.
  2. New routine's Only tell you asked where it "posts" and made an empty conversation for it. Nothing was ever posted there, and deleting that conversation silently stopped the check-in.
  3. Several sentences said the wrong thing:
    • A task still being worked on sat under Waiting on you as "waiting since now".
    • The ping said "Start or hide them" next to buttons named Work on it and Dismiss.
    • The personal edition's Notifications page named Slack and Teams, which that edition has off.
    • A Bot with a check-in and an open task read "No tasks, routines or goals yet".
  4. There was no way to pause every Bot at once.
  5. A Bot's page didn't show what it does by itself. People asked for this. The page listed at most three lined-up items of any kind and left check-ins out.
  6. Nothing in a conversation showed what its Bot does by itself.

Spec: docs/superpowers/specs/2026-11-13-check-in-gaps-and-pause-all-design.md (not checked in). It planned one PR per part; the commits here are grouped by part, in the spec's order, so it can be split if that is easier to review.

What changed

Part 4: wording

  • The ping's last line now reads "Open OpenBot to work on it or dismiss it." The Admin › Routines acceptance sentence says "worked on" and "dismissed".
  • In the personal edition, Notifications names only push and text messages.
  • A Bot's Activity row counts check-ins that are on as scheduled and open tasks as in progress.
  • Needs you has a third half, Working on it, for tasks still being worked on, and the header says "1 working".

Part 3: a check-in belongs to its Bot

  • proactive_settings.channel_id is nullable. New check-ins store no conversation. The API still accepts channelId, ignores it, and answers it as null.
  • A check-in's reach check is now canUseBot: the person isn't revoked and can still use the Bot. No conversation is read at create, at each run, or at Work on it.
  • A ping's push is filed under the Bot of its newest item the person can still use, and is authorised by that same check when it is sent. delivery_outbox.channel_id and thread_id are nullable.
  • New routine's Only tell you no longer asks "Posts in" and makes no conversation. The offer card and Turn on check-ins work anywhere.

Part 1: a check-in can always look

  • Each check-in records what it reads, in source_kind (apps, app or page) and source_server_id. Every existing row becomes apps.
  • offer_check_in takes readWith, the tool the Bot read the thing with, and the server works out what the check-in reads from it. Anything read another way (the browser, the computer, a Shared app, an app on the admin's key) is answered "Nothing to offer", and no card is drawn.
  • A check-in on one app is offered that app's reads only (scopeForRun).
  • engine.create refuses a check-in that could never look, with the spec's sentences.
  • New routine gains It watches, which reads GET /api/proactive/readable.
  • A new check-in is due at once instead of one interval out. Rows adopted from defaults keep their delay.
  • GET /api/proactive/settings adds health (why it can't look, and the fix) and reads to each check-in. "Can't look" shows on the check-in's row (which sorts first), as the first row of its Bot's group under Needs you, on its page, and as the Bots badge's dot. It isn't counted in the badge's number and sends no ping.

Part 2: watching a public web page

  • The engine reads source_link itself, through the Bot's page-read tool, as the person and under the run's initiator.
    • The first read is kept as the baseline, and nothing is raised.
    • An unchanged page makes no model call.
    • A changed page runs one turn, given the earlier and the new text as quoted data. Its only tools are suggest_next_step and clear_next_step.
  • A page run forms no memory and gets no Learning container.
  • At the tool-call door, callTool admits a page-read call only when it comes from a running page check-in and asks for exactly that check-in's address. That holds on the free and the keyed web-search entries alike.

Part 5: pause all

  • readPause answers paused when the Bot is paused or the person paused all (users.preferences.pausedAllAt). Every caller of isBotPaused and guardBotTurn honours it, and each Bot's own pause is kept.
  • Check-ins: the sweep claims none of that person's check-ins, and Run now answers paused_all. The skip-reason check constraint is widened to allow it.
  • PUT /api/bots/pause-all sets it, and GET /api/bots/attention answers pausedAll.
  • Work on it is refused up front while the Bot is paused, whether by itself or with all. Before, the task was made and its turn was then refused.
  • In the app: an All Bots active row on Routines, and a Resume all banner on Bots, Routines and each Bot's page while everything is paused. In the OpenDots skin, the top bar's pause control now pauses every Bot.

Part 6: a Bot's page lists its routines

  • A Routines section between For you and Activity. It uses the Routines page's own rows and lists only what is on: running now first, then any that can't look or failed, then by what starts next, then goals that wait to be asked. It shows at most five, then All routines with the total.
  • Its header counts them: running, scheduled and on demand.
  • Activity on that page no longer repeats the Bot's routines and goals.

Part 7: a clock in a conversation's header

  • In a one-Bot conversation, before the computer and the gear: a muted pill with a clock and the number of routines on. The number matches the Bot's page, and turns amber when one can't look or failed.
  • It opens the Bot's Routines list in a dialog. A routine opened from there goes back to the conversation (?from=).

Migrations: 0092–0095 add or loosen columns only. No existing row is rewritten. They are listed in the changelog's "Before upgrading".

Tests

  • Server, new: check-in-belongs-to-bot, check-in-can-look, check-in-page (engine page runs, plus the door with a real plugin store on exa and exa-authenticated), and pause-all cases in bot-lifecycle and bot-lifecycle-routes. Existing proactive and delivery suites were updated.
  • App, new: bot-routines, routines-clock, pause-all, plus additions to needs-you, check-in-row, check-in-offer-card, new-routine-form, routines-merged, update-routing-settings and skins-opendots-frame.
  • Run locally: the server suites for proactive, check-in, delivery, memory, bot-lifecycle, routine, admin, plugin, task, group and activity: 1,164 pass. The app suite: 3,692 pass. typecheck, typecheck:tests (no change to the baseline), biome and drizzle-kit check are clean.

Not checked

  • Nothing has been tried by hand in a running app yet.
  • No real page was read through Parallel or Exa; the door test uses a stubbed vendor.
  • No test reaches the in-app turn path, so "a Bot still answers in a one-to-one conversation while all are paused" is untested.

…e says worked on or dismissed, and a Bot that can read nothing says to connect one in Connections
…ot, and its ping's push is filed under that Bot
…reads that app alone, and each says when it can't look
…wn pause is, and refuse Work on it while paused

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant