Running Sally

Last updatedView as Markdown

The jobs that come up while Sally is running, for admins and PMs. Most are a button in the admin at sally.linchpin.com/admin. Where it says People or Health, only admins can do it.

Switch someone on

  1. Add them

    Add a row for them to scripts/seed-people.sql (name, email, role and ClickUp user id) and run it. It only inserts people who aren’t there yet, and everyone starts switched off and in dry run.

  2. They connect

    They run /sally connect in Slack and approve ClickUp. Sally links their Slack account by the email address on their Slack profile.

  3. Check their draft

    On Preview, build their standup. Nothing is sent. Compare it with what they actually did.

  4. Switch them on

    On People, select Switch on. Check-ins start at their next prompt, still in dry run.

  5. Go live

    Once a few drafts match what they did, select Go live. From then on their answers are written to ClickUp as them.

To pause someone, select Switch off on People. Their check-ins stop at the next prompt; nothing already written is changed.

Mark someone out

  • For one day, they select I'm out today on that day's standup. Sally notes it on the Daily Standup and stops asking until their next working day.
  • Ahead of time, add the days on People with Add a day off.
  • For everyone, add the date to Rules › Calendar › Company holidays.

Out days and holidays get no check-ins, and look-backs skip them.

Change a rule

On Rules, change the value and save. It takes effect from the next check-in. Every save is versioned: pick Restore an earlier version… to put one back. Every rule is in the Configuration reference.

To send the digest to a channel, invite @Sally to it, then set Rules › Slack › Team channel to the channel's id. It starts with C. Until it's set, admins get the digest by DM.

Stop Sally writing

  • For one person, select Dry run on People. Sally keeps drafting and asking, and logs what it would have written instead of writing it.
  • For everyone, set DRY_RUN to "true" in wrangler.jsonc and ship it. It's the kill switch, and it overrides everyone's own setting.

A job that kept failing

Health › Failed jobs lists every background job that failed all its retries, such as a submit during a ClickUp outage. Retry sends it back to the queue; Dismiss drops it. Both are logged.

The ClickUp webhook

The webhook tells Sally who changed what in ClickUp, for "worked on" and for redrawing open check-ins.

  • First time: Health › ClickUp webhook › Register webhook. It's registered with your own ClickUp connection.
  • Failing or suspended: when Health shows it as failing or suspended, select Reactivate.

Someone needs to reconnect

Health › Connections and People show each person as Connected, Needs reconnecting or Not connected. When ClickUp stops accepting someone's connection, Sally DMs them to run /sally connect. Until they do, Sally writes nothing for them, and their answers show as not in ClickUp yet.

Draft a check-in again

The person runs /standup fresh (or /eod fresh). Sally drafts it again from ClickUp and marks the old thread as replaced. What their answers already changed in ClickUp stays.

Look into something

The Activity log has everything Sally did, newest first, in plain English, with links to the task and the Slack message. Each row has a ref. When Slack says something like "didn't work (ref 20dc27f2)", the same ref is on the row that explains it.

Ship a change

  1. Merge to main

    Conventional commits scoped to the ClickUp task, such as fix(LINCHPIN-5818): …. CI runs the checks on every PR.

  2. Merge the release PR

    release-please keeps chore(main): release x.y.z open with the changelog. Merging it tags the version and publishes the release.

  3. The release deploys

    Deploy to Cloudflare runs npm run check, applies any new migrations, then deploys. Watch it in the Actions tab.

Deploying by hand: run Deploy to Cloudflare from the Actions tab, on main. Never wrangler deploy from a laptop or a branch, or production stops matching a release. See Setting Sally up for what the workflows need.

A database change is a new numbered file in migrations/. The release applies it before the new code goes out, so code never runs against an old schema. Never edit a migration that has already been applied.

Rotate a secret

Get the new value, store it in 1Password under Sally (sally.linchpin.com), then:

Replace a secret bash
npx wrangler secret put SLACK_BOT_TOKEN --name sally

It takes effect straight away, with no deploy. The secrets are listed in the Configuration reference.

Work on Sally locally

npm install
cp .dev.vars.example .dev.vars        # fill in what you need
npm run db:migrate:local
npx wrangler d1 execute sally --local --file scripts/seed-people.sql
Run Sally on your machine bash
npm run dev:admin-as

Then open http://localhost:8787/admin/. It acts as [email protected]; set SALLY_DEV_EMAIL to be someone else. The override is ignored whenever CF_ACCESS_AUD is set, so it can't open production. Plain npm run dev shows the real behaviour: the admin fails closed.

Slack and ClickUp can't reach your machine, so send signed commands instead:

npx wrangler d1 execute sally --local --command "UPDATE people SET slack_user_id='U_AARON' WHERE id='aaron'"
node scripts/slack-local.mjs /sally status U_AARON

Before a PR, run the same checks as CI: npm run check, npm run lint, npm run build and npx wrangler deploy --dry-run.

Have a question about this page?

Linchpin assistant

Was this helpful?