Skip to content

The agents/ folder: one file and what it compiles to

What one agents/ file holds, what each key compiles to, and the checks that read it.

One agents/ file is one seat’s contract: who fills it, its number, its standards, limits and approvals. SalesBuilder compiles it, and show traces every key.

agents/sales/prospector.mdx
---
worker: agent
aliases: [SDR]
results: [{ metric: opened-deals-and-trials, baseline: 2, target: 6, deadline: 2026-12-31 }]
standards: { response: 60m }
limits: { messages: 40 }
autonomy: assist
approvals: { to: founder }
---
The SDR seat: research, first drafts and follow-ups, with every send approved until it earns more.
show
$ npx startup-builder show agents/sales/prospector.mdx
worker     agent                                                                     agents/sales/prospector.mdx:2
aliases    [SDR]                                                                     agents/sales/prospector.mdx:3
results    [{ metric: opened-deals-and-trials, baseline: 2, target: 6, deadline: 2…  agents/sales/prospector.mdx:4
standards  { response: 60m }                                                         agents/sales/prospector.mdx:5
limits     { messages: 40 }                                                          agents/sales/prospector.mdx:6
autonomy   assist                                                                    agents/sales/prospector.mdx:7
approvals  { to: founder }                                                           agents/sales/prospector.mdx:8
owner      SalesBuilder
leaseline.app
leaseline.app/
├── plays/
│   ├── cold-email.mdx
│   ├── warm-intros.mdx
│   ├── signup-interviews.mdx
│   ├── lead-reactivation.mdx
│   └── events-and-webinars.mdx
├── audiences/
│   ├── small-property-managers.mdx
│   ├── lapsed-leads.mdx
│   └── renewal-season.mdx
├── sequences/
│   └── cold-email-thread-founder.mdx
├── funnels/
│   └── signup.mdx
├── workflows/
│   └── outbound.mdx
├── agents/   ← this folder
│   ├── sales/prospector.mdx
│   └── marketing/content-lead.mdx
├── systems/
│   └── sequences.mdx
├── domains/
│   └── leaseline.app.mdx
├── offers/
│   ├── pro.mdx
│   └── team.mdx
├── content/
│   └── webinars/60-day-notices.mdx
├── metrics/
│   ├── q4.mdx
│   └── positive-reply-rate.mdx
└── startups.lock

The file

KeyOn the pageCompiles toChecked by
workerWho fills itPOST /{namespace}/roles/{role}/staff: an agent or a person; a hire takes the seat with its queue and number—
aliasesTitlethe title pages show for the seat—
resultsYour numberthe seat’s Key Result, a node or leaf of the ARR tree inside its bandS9
standardsStandardsthe times a Stop reads, such as the 60-minute answer—
limitsLimitscount- and time-based caps; crossing one pauses the Play (POST /{namespace}/limits/{limit}/raise)—
autonomyAutonomythe starting rung: you approve each one, until 48 of its last 50 pass—
approvalsApprovalswho answers an Approval when a call passes its Limit (POST /{namespace}/approvals/{approval}/approve)—

Checks

CheckIt holdsWhat dev prints
S4The budget fits the Mandate, or opens an Approval.plays/lead-reactivation.mdx:5 S4 budget: 48 USD a month is over Dana’s Mandate of 0. Sign it with Mandate.authorize, or the first send waits on an Approval.
S9Each Key Result names a node or leaf of the ARR tree, and a seat’s Key Result sits in its band.agents/sales/prospector.mdx:4 S9 results: reply-count is not a node or leaf of the ARR tree. Did you mean positive-reply-rate?

Refusals

CodeFix, then the call that clears it
batch-capSplit the batch, or approve the larger one. Then POST /{namespace}/approvals/{approval}/approve.
claimCut the line, or cite the Offer term that grants it. Then POST /{namespace}/conversations/{conversation}/answer.
clinician-holdAsk the Compliance Officer to approve the invitation; it waits until then. Then POST /{namespace}/approvals/{approval}/approve.
comparison-claimApprove the changed claim once; it publishes after the approval. Then POST /{namespace}/approvals/{approval}/approve.
concentrationApprove it as a long deal above the cap, or add creators first. Then POST /{namespace}/approvals/{approval}/approve.
creditRaise the credit Limit, or block the key drawing from 2 accounts. Then POST /{namespace}/limits/{limit}/raise.
deploy-freezeShip it after day 5, or ship an approved fix in steps; reverts always run. Then POST /{namespace}/approvals/{approval}/approve.
domainConfirm the viewer yourself, or keep the report held. Then POST /{namespace}/tasks/next.
draft-matchApprove the changed Order again; the old Card voids. Then POST /{namespace}/approvals/{approval}/approve.
editorialPass it before the deadline, or the week records checked, nothing to send. Then POST /{namespace}/approvals/{approval}/approve.
exclusiveWait for the first offer to be declined or expire, then offer the next. Then POST /{namespace}/tasks/next.
field-scopeAsk the admin once in writing; the field joins on their yes. Then POST /{namespace}/conversations/{conversation}/answer.
fraud-holdDecide pay or void on the Approval. Then POST /{namespace}/approvals/{approval}/approve.
gift-approvalApprove it in your queue; a gift never sends on a timeout. Then POST /{namespace}/approvals/{approval}/approve.
invitation-restWait 60 days, or 180 days after 2 unanswered invitations. Then POST /{namespace}/tasks/next.
keep-firstLet their CSM reach them first, then ask again once they are healthy. Then POST /{namespace}/tasks/next.
late-sendApprove the next window sooner, or promote the cell; the expired send never goes. Then POST /{namespace}/approvals/{approval}/approve.
license-allowlistReplace the dependency, or add its license to the allowlist with your OK. Then POST /{namespace}/approvals/{approval}/approve.
no-cash-or-travelSend a take-home gift through gift delivery under the class cap, with its Approval. Then POST /{namespace}/approvals/{approval}/approve.
payout-limitApprove the run, or split it at the Limit. Then POST /{namespace}/approvals/{approval}/approve.
pending-ceilingWithdraw requests pending 14 days or more. Then POST /{namespace}/tasks/next.
pilot-capWait in the queue for the dated start, or end a running pilot first. Then POST /{namespace}/tasks/next.
portfolio-capsTake the next open date the caps allow. Then POST /{namespace}/tasks/next.
priceGet the discount approved, or quote at the floor. Then POST /{namespace}/approvals/{approval}/approve.
probe-limitApprove the raise, or keep the probe at its line. Then POST /{namespace}/approvals/{approval}/approve.
reconcileClear the Stripe mismatch, then send again. Then POST /{namespace}/tasks/next.
recording-holdAnnounce it at the start, under the host’s grant. Then POST /{namespace}/tasks/next.
rival-nameCite a dated fact for the rival, then approve the phrase. Then POST /{namespace}/approvals/{approval}/approve.
role-unstaffedStaff the Role, or leave it: its routes come to you. Then POST /{namespace}/roles/{role}/staff.
screeningReview the hit yourself; nothing is released until you clear it. Then POST /{namespace}/tasks/next.
session-gateSend from the tray yourself; no connector gets your login. Then POST /{namespace}/tasks/next.
store-billedLink the store’s own refund path; no button or guarantee shows. Then POST /{namespace}/conversations/{conversation}/answer.
terms-holdClear the partner’s terms; the build stays private until then. Then POST /{namespace}/tasks/next.
tier-gateWait for the 28-day region read, then approve the raise. Then POST /{namespace}/approvals/{approval}/approve.
verificationReview the List; send to the verified addresses only. Then POST /{namespace}/tasks/next.
viewer-limitApprove the new viewer, or keep the list as it is. Then POST /{namespace}/approvals/{approval}/approve.
window-closeSend the pitch inside its window; a late one drops. Then POST /{namespace}/tasks/next.
spend-limitRaise the Limit, or wait for the month to reset. Then POST /{namespace}/limits/{limit}/raise.
unanswered-positiveAnswer the reply, then approve the resume. Then POST /{namespace}/approvals/{approval}/approve.

Calls

agents/ compiledMode try
You, to your agent

Seat the agent as our SDR and show me its first task, as a dry run.

curl -X POST "https://api.sb/leaseline.app/roles/role_1/staff?mode=try" \
  -H "Authorization: Bearer $STARTUP_BUILDER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"worker":"worker_1"}'

curl -X POST https://api.sb/leaseline.app/tasks/next \
  -H "Authorization: Bearer $STARTUP_BUILDER_API_KEY"
import { $ } from 'startup-builder'

await $.Role.staff({ role: 'role_1', worker: 'worker_1' }, { mode: 'try' })   // agents/sales/prospector.mdx
return await $.Task.next()   // the seat’s queue
npx startup-builder do Role.staff --json '{"role":"role_1","worker":"worker_1"}' --try
npx startup-builder do Task.next
{
  "name": "do",
  "arguments": {
    "code": "await $.Role.staff({ role: 'role_1', worker: 'worker_1' }, { mode: 'try' })   // agents/sales/prospector.mdx\nreturn await $.Task.next()   // the seat’s queue",
    "mode": "try"
  }
}
Response200application/json
{
  "task": {
    "$id": "https://api.sb/leaseline.app/tasks/task_1",
    "$type": "Task",
    "status": "pending",
    "mode": "try"
  },
  "action": {
    "$id": "https://api.sb/leaseline.app/actions/action_1",
    "operation": "Task.next",
    "status": "done"
  }
}
sample
CallWhat it does
POST /{namespace}/roles/{role}/staffStaff fills a Role with a Worker, human or agent, who then performs the Role’s Verbs under its Permissions. Emits Role.staffed.
POST /{namespace}/mandates/authorizeAuthorize grants an Agent a standing Mandate to perform a Verb within a Limit, without asking each time. Emits Mandate.authorized.
POST /{namespace}/mandates/{mandate}/spendSpend pays an outside party for a Startup with a single-use card, within a Mandate and its Limit. Emits Mandate.spent.
POST /{namespace}/approvals/{approval}/approveApprove allows the pending Action an Approval holds, and that Action runs. Emits Approval.approved.
POST /{namespace}/limits/{limit}/raiseRaise lifts a Limit after an Approval allows it, and the Action that waited on it proceeds. Emits Limit.raised.
POST /{namespace}/tasks/nextNext returns the oldest open Task the calling Worker’s Roles may claim, without claiming it. Emits Task.offered.
POST /{namespace}/actions/{action}/redirectRedirect changes a pending Action’s inputs or target inside its delay window, before it runs. Emits Action.redirected.
POST /{namespace}/conversations/{conversation}/answerAnswer replies in a Conversation through the Channel it arrived on and closes the reply Task it opened. Emits Conversation.answered.

Compiled, not written: edit the records it reads (compile table; cap), then regenerate. Every step runs from a sentence or a line of code. In your words: the CRM words you know, and where each lives here.

Contents