You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Event feed: emit an event when an automatic check-in question is asked (and when a new unread notification arrives) #904
We run agents that live in a Basecamp project and answer an Automatic Check-in ("What did you ship yesterday?", every day at 08:00). They should answer as soon as the question is asked, the way a person answers when they see it.
What's missing
The live event feed (/events.json and the stream ticket that bc-watch uses) only has two check-in events:
question.created, when the question is first set up
question.answer.created, when someone answers
Nothing is emitted when a scheduled check-in is asked. So a watcher on the feed never learns that a new round has opened, and agents fall back to a cron job that guesses the time.
Request
Emit an event when a check-in question is asked, e.g. question.asked. Include the question id, the questionnaire and bucket, and the group date the answers will belong to. Ideally this is the same moment the "Question" notification lands for each person who is asked.
Related: notifications aren't in the feed either. Basecamp already creates an unread notification for the people a question asks (and for mentions, pings and so on). basecamp notifications can read these, but the live feed carries none of them, so a watcher has to poll the notifications endpoint. A feed event when a new unread reading is created for the current user (e.g. reading.created with readable_type and readable_id) would cover check-ins and every other "you should look at this" moment, without polling.
Either one would let agents react in real time instead of polling or scheduling.
Environment
basecamp CLI 0.13.2 (macOS)
bc-watch from the agent skill, with --kind checkin (event types: question.created, question.answer.created)
Confirming the gap with CLI 0.13.2. The documented behavior holds: a stream ticket response has only ticket, url and expires_in, with no channel list. Subscribing a ticket connection to ReadingsChannel, NotificationsChannel and Readings::Channel returns reject_subscription for each one, as the event feed doc says ("Subscriptions to any other channel are rejected"). So a person principal has no live route to unreads today. The only route is polling basecamp notifications (/my/readings), which caps at 100 unreads.
We also tried basecamp inbox, the "someone addressed you" lane. It is agent-only, and a person login gets forbidden.
A suggested shape that fits the existing contract: add reading.created (and ideally reading.read, so a watcher can drop an item once it's read somewhere else) to the event catalog. Deliver it on the existing EventsChannel, scoped to the current user, since readings are per person. Keep it a thin pointer like the other events, with details carrying readable_type, readable_id and the reason (mention, question asked, assignment, ping). That avoids a second channel, which the one-subscription-per-ticket rule doesn't allow.
If the plan is that agents should use the inbox lane instead, it would help to know whether that lane will include check-in questions being asked, and how a CLI login becomes an agent principal.
Activity
notolivaresf commentedon Oct 14, 2026
Confirming the gap with CLI 0.13.2. The documented behavior holds: a stream ticket response has only
ticket,urlandexpires_in, with no channel list. Subscribing a ticket connection toReadingsChannel,NotificationsChannelandReadings::Channelreturnsreject_subscriptionfor each one, as the event feed doc says ("Subscriptions to any other channel are rejected"). So a person principal has no live route to unreads today. The only route is pollingbasecamp notifications(/my/readings), which caps at 100 unreads.We also tried
basecamp inbox, the "someone addressed you" lane. It is agent-only, and a person login getsforbidden.A suggested shape that fits the existing contract: add
reading.created(and ideallyreading.read, so a watcher can drop an item once it's read somewhere else) to the event catalog. Deliver it on the existingEventsChannel, scoped to the current user, since readings are per person. Keep it a thin pointer like the other events, withdetailscarryingreadable_type,readable_idand the reason (mention, question asked, assignment, ping). That avoids a second channel, which the one-subscription-per-ticket rule doesn't allow.If the plan is that agents should use the inbox lane instead, it would help to know whether that lane will include check-in questions being asked, and how a CLI login becomes an agent principal.