Case StudiesRetreat
AboutCareersBook a Conversation
Workflows/OperationsBuilt

Daily Check-in Agent

The stand-up is the meeting everyone attends and nobody needs, because the answers already live on the Workboard. This agent reads them off the cards every weekday morning, posts a three-line check-in per team, and names the people whose cards went quiet so a human can follow up.

Source Workboard cards + commentsCadence Weekdays 09:00 and 09:30 (+07)Human touchpoints The card, the Run now button

Cards in, check-ins out

This rail is the orientation, not the workflow. Real life branches and fails; the diagrams below are the truth, drawn branch by branch.

0109:00 weekdays
Time to Check In
System
02Thirty minutes, on the Workboard
Cards Move
Team
0309:30 weekdays
Check-ins Gathered
System
04Product Team, EO
Posted to the Chat
System
05Settings → Agents
Run Logged
System

The morning check-in, every branch

Five boxes in the rail; three decisions, two aborts and one quiet ending in reality. The 09:00 message is the only warning anyone gets; thirty minutes later the agent reads the board as it stands. The check-in itself is the easy part: done yesterday is any card that moved into Done in the last 24 hours, doing today is every open card, blockers are the unresolved blockers written on the cards. The interesting work is the silence: telling booked leave from a forgotten board, and naming only the latter, in the post itself, so the team lead sees it without the agent ever DMing anyone.

thirty minutes to update cardsyesnoyesnoyesnopending09:00 (+07) the reminder firesevery weekday, both teamspost to both chats:time to update your cards09:30 (+07) the check-in firesthirty minutes later, or Run nowweekend, or alreadyposted today?skipped, logged:nothing sentload the active directorymark anyone on booked leaveread fails: abort,post nothingread the Workboardevery board, card, comment and blockerno boards: abort,post nothingcard moved orcommented in 24h?leave booked today?listed as off, never chasedtagged quiet:listed as pendingin the post, not a DMcompose one line per persondone, doing, blockers, off the cardspost to the roster’s Lark chatProduct Team, then EO; unset webhook: skippedlog the run: routine_runsdate, rosters posted, card count
The 09:00 reminder and the 09:30 agent. The first decision is the idempotency check: a weekend or a day that already posted ends the run before it reads anything. The red box on the right is not a DM; it is the pending line at the foot of the team post.
schedule firesdecisionhuman touchpointrun log writeflag a humanquiet end

What one person’s day looks like to the agent

Underneath the morning run sits one entity with rules: a person on a given day. Everyone starts stale at 09:30. A move or a comment on one of their cards in the last 24 hours makes them fresh; leave booked over the date makes them off; anything else makes them pending. All three reach the post: fresh people get their three lines, off people are listed with their leave type, pending people get their three lines tagged and their name at the foot. Only the human move, updating a card, is dashed. The agent never marks anyone fresh on its own, and it never looks again until the next morning.

moves or comments on a cardin the postleave bookedno leave, no move in 24htagged, at the footlisted as offstalefreshpostedoffpending
Green arrows are agent moves; the dashed arrow is the one thing only the person can do. Every state reaches the post; the difference is how the person is named in it.
agent may movehuman only (dashed)

Every exception has an owner

An automation is defined by what happens off the happy path. Each row here is a real condition the agent hits, what it does about it, and where a human hears about it. Silence is only ever by design.

ConditionWhat happensWhere you hear about it
No card moved or commented in 24 hoursBooked leave checked; if none, the line is tagged quiet and the person is listed as pendingThe team post
Approved or taken leave covers the run dateListed as off with the leave type, never chasedThe team post
No cards assigned at allListed under no cards, no three lines writtenThe team post
Card moved by someone other than the assigneeCounts as activity for the assigneeThe team post
Blocker written on a cardSurfaces under Blockers until it is resolvedEvery post until it clears
Weekend, by Vietnam timeNo run, no messageRun log, marked skipped
Team directory or Workboard read failsRun aborts before any messageRun log, marked failed; the missing post is the tell
A team chat webhook is not configuredThat post is skipped with a warning; the other still goesRun log
Same day seen again (a retry, or Run now after the cron)No-op: one post per day, never a duplicateRun log, marked skipped
A missed morningA super admin presses Run now on Settings → Agents; the same run posts under the same routineThe team post, whenever it is pressed

Data, timing, and how we know it works

Reads and writes

  • Reads: the active team directory with departments; approved or taken leave over the run date; every Workboard card with its lane, last move, comments and blockers; the day’s routine runs
  • Writes: one reminder and one check-in per team per weekday, and one routine run row per run, whether it posted, skipped or failed
  • Idempotency key: the date. The check-in looks for a successful run that already posted today before it reads anything, so a retry or a Run now after the cron sends nothing
  • The reminder has no key: it reads nothing and posts one fixed line, so it cannot fail on data

Timing model

  • 09:00 (+07) weekdays: the reminder, thirty minutes before the board is read
  • 09:30 (+07) weekdays: the check-in, after the first coffee, before the first meeting
  • The activity window is the 24 hours before the run, so a Monday post reads Sunday morning onward, not the whole weekend
  • A line names up to three card titles, then says how many more
  • Both run as Vercel crons on UTC schedules; a missed morning is re-run by hand from Settings → Agents, and the date key makes that safe

How we know it works

  • A weekday with no post in either chat is itself the alarm
  • Every post lists who is off and who is pending, so a quiet board is visible the same day
  • Settings → Agents shows every run with its result: the rosters posted, the head count per roster, the cards read
  • Weekly eyeball: people pending three days running, cards in Doing for over a week. Zero of each is the target

The seven elements

Every workflow we document has the same anatomy: seven elements, each assigned to a human, a machine, or both. This is the Centaur Map from our workflow design method.

01 TriggerMachine

Time. 09:00 (+07) every weekday for the reminder, 09:30 for the check-in, both scheduled on Vercel. Nobody calls a meeting.

02 InputsMachine

The Workboard: each person’s cards, when they last moved, the comments on them and the blockers written on them. Booked leave from the time-off table. The active team directory for the rosters.

03 DecisionBoth

The agent decides whether a person has been active in the 24-hour window and whether silence is booked leave. It never decides what someone did; it reads it off the cards.

04 RoutingMachine

Two rosters, two chats. Product Development and Operations make the Product Team post; EO makes the EO post. Anyone in neither department gets no check-in rather than the wrong team’s.

05 OutputMachine

One reminder and one check-in message per team per weekday, and a routine run row per run.

06 DeliveryMachine

Plain-text Lark messages in each team chat. Pending, off and no-cards people are named at the foot of the post; there are no DMs and no thread replies.

07 MeasurementHuman

A weekday with no post is the alarm. Every post names who is pending and who is off, so the gaps are visible daily, not at the retro. Settings → Agents keeps every run.

This is the same pattern as Lark Scheduler to CRM Updates: a scheduled agent reading systems that already hold the truth, writing one message a human actually reads, and refusing to guess. The cards are the stand-up; the agent only reads them out.