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
-
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. -
They connect
They run
/sally connectin Slack and approve ClickUp. Sally links their Slack account by the email address on their Slack profile. -
Check their draft
On Preview, build their standup. Nothing is sent. Compare it with what they actually did.
-
Switch them on
On People, select Switch on. Check-ins start at their next prompt, still in dry run.
-
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_RUNto"true"inwrangler.jsoncand 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
-
Merge to main
Conventional commits scoped to the ClickUp task, such as
fix(LINCHPIN-5818): …. CI runs the checks on every PR. -
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.
-
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:
npx wrangler secret put SLACK_BOT_TOKEN --name sallyIt 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
npm run dev:admin-asThen 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.