Next step tracker
Every weekday morning each promise made on a recorded call, by your team or the customer, is read from the call log, recorded once, closed when the activity log shows it was kept, and flagged in Slack once it falls due or goes overdue.
Set up the next-step-tracker cookbook in this project.
1. If the Cargo CLI is not installed yet, follow every step in https://api.getcargo.io/INSTALL.md
2. From the Cargo project, run: cargo-ai cdk add cookbook/next-step-tracker
3. Then follow .claude/skills/next-step-tracker/SKILL.md. Stop for my approval before any paid call, and stop at "cargo-ai project plan" before deploying anything.$cargo-ai cdk add cookbook/next-step-trackerSay this to your agent
Every weekday morning, tell #deal-desk which promises from our calls are due or overdue.
Illustrative output #
Fictional records, to show the shape of what comes back.
:hourglass: *Next steps due — Thu Oct 8*
*Dana Ruiz*
• Fabrikam: "Send the Globex migration one-pager to Priya" — you promised on Oct 1,
due Oct 6 (2 days overdue). An email to Priya with the one-pager closes it.
• Northwind: "Legal will review the MSA by Friday" — they promised on Oct 2, due today.
Follow up with Sam; nothing to do for them.
*Lee Park*
• Contoso: "Share the SOC 2 report" — you promised on Oct 6, due today. An email with
the report attached closes it.
_Sources: cadence/log/calls/2026-10-01-fabrikam.md · cadence/log/calls/2026-10-02-northwind.md ·
cadence/log/calls/2026-10-06-contoso.md_
Eleven commitments were open; four closed overnight on logged activity, three were due and posted, and a second run that morning posted nothing.
What you will be asked #
| Input | Why | |
|---|---|---|
channelId (infra/agents/tracker.ts) | Asked | Nudges quote what customers said on calls. Locked so they never land in a customer shared channel. |
TRACKER_TIMEZONE and the cron (infra/agents/tracker.ts) | Asked | A timezone that disagrees with the cron makes “due today” yesterday’s list. |
Done when #
node --import tsx evals/contract.mjspassescargo-ai cdk planreports the agent, thecommitments,gtm_activitiesandgtm_accountsmodels, the three connectors and the two folders- the first run recorded one row per unchecked action in the last 30 days of call entries, each with a quoted promise, a due date and its source entry
- to test without a CRM, seed
gtm_activities(and agtm_accountsrow per test account) withcargo-ai storage record create-bulk --model-uuid <uuid> --records '[{"data":{…}}]', the model uuid read fromcargo-ai storage model list - every row it closed cites a
gtm_activitiesrow or a later call entry that plainly matches the promise, and a seeded activity that does not match closed nothing - one message landed in the locked channel listing only open rows due today or earlier, grouped by owner, with every source entry on the last line
- a second run the same morning added no row and posted nothing
- a promise the customer made is phrased as a follow-up to chase, not a task to do
git logon the default branch shows no commit and no pull request from the tracker
What it costs #
The evidence reads are SQL over workspace models and bill nothing. The post is slack.postMessage
on the bound connector; immediately before the plan, run
cargo-ai orchestration action list postMessage --kind connector --integration-slug slack and read
the current cost out loud. The recurring cost is the harness run itself, once each weekday, billed as
LLM tokens through the Anthropic connector. It scales with the number of call entries in the window
and open commitments to check, not with the size of the activity log, and the run posts at most once.
Every promise made on a recorded call, kept or chased. One Claude Code harness agent reads the call
log call-capture writes, records each commitment either side made in a ledger model, closes the
ones the activity log shows were kept, and posts what is due or overdue to one locked Slack channel, at most
once a day.
What it does #
- Reads
cadence/log/calls/from the last 30 days, on the default branch. - Records every specific, dated commitment (ours and theirs), quoted, once per entry and promise.
- Closes a commitment only when an email, meeting, note or task in the
gtm_activitiesmodel, or a later call entry, plainly shows it happened, and cites that record. - Posts the open ones due today or overdue, grouped by owner, then marks them nudged.
- Writes nothing to the repository and nothing to the evidence models.
What’s inside #
Adds 9 resources.
| File | Resource | Role |
|---|---|---|
infra/agents/tracker.ts | defineAgent (claudeCode) | the cron, the repository binding, the reads, the locked post |
infra/agents/tracker.prompt.ts | (not a resource) | extract, close on evidence, post what is due |
infra/models/commitments.ts | defineModel (native) | the ledger: one row per promise |
infra/connectors/git.ts | defineConnector (github) | the clone path; read only |
infra/models/gtm-activities.ts | defineModel (native) | the evidence a promise was kept; read-only |
infra/models/gtm-accounts.ts | defineModel (native) | who owns each account; read-only |
infra/connectors/slack.ts | defineConnector (slack) | the post path |
infra/connectors/anthropic.ts | defineConnector (anthropic) | the model the harness runs on |
infra/folders/index.ts | defineFolder ×2 | where the agent and the model are filed |
references/nudge.md | (not a resource) | the message shape and the rule for each line |
Why state in a model and not in the repository #
The call entries are call-capture’s record, reviewed through pull requests. Ticking their
checkboxes would rewrite that record and open a pull request every morning for the tracker’s own
bookkeeping. What changes daily (open, done, nudged today) lives in the commitments model, where
it can be queried and corrected without a review.
Why native models and not a CRM #
The example has as few dependencies as it can: the evidence is two native models declared in this
folder, filled by whatever already logs the team’s activity. A team on HubSpot, Salesforce or
Attio replaces them with connector-backed models of the same slugs (crm-backed in SKILL.md);
the agent and its prompt do not change, and no CRM action is ever added to the agent.
Placeholders (edit before deploy) #
channelIdininfra/agents/tracker.ts: the Slack channel id the nudges land in.TRACKER_TIMEZONEand the cron: keep the run after call-capture’s.languageModel: any Anthropic model the workspace’s connector can reach.
What it does not do #
It does not contact customers, write to any model but its ledger, commit to the repository, or post anywhere but the locked channel.