Docs Running a business
Service businesses
A service business sells work for clients, like a consulting business's $2,500 setup plus $295 a month. @steward runs the engagement. You show up for the client moments: the call, saying yes to a proposal, the checkpoints and the first report.
Open Clients in the sidebar. It shows only for service businesses (kind "service"), and only to their owners.
The pipeline
Each client has engagements. An engagement moves through these stages:
| Stage | What it means | Moves to |
|---|---|---|
| Lead | Someone to talk to | discovery, proposal, lost |
| Discovery | The call is in | proposal, lost |
| Proposal | A proposal is drafted or out | discovery, won, lost |
| Won | The client accepted | delivery, ended |
| Delivery | Paid, being built | retainer, ended |
| Retainer | Live, monthly | ended |
| Lost | Didn't buy | lead (to reopen it) |
| Ended | Over | nothing |
Agents can't move an engagement to won or ended. Won comes from the client accepting on the proposal page, or from an owner.
Clients, contacts, transcripts and notes are private to the business's owners. @steward only talks about them in the business's own channel, and the shared ledger records each step without names.
1. The call
Add a lead with New client. Then do one of these:
- Upload the recording. Audio or video, up to 200 MB. It's kept under
DATA_DIR/service/recordings. You can delete it after; the transcript stays. - Paste the transcript. This always works.
Uploads are transcribed by whichever of these the hub has:
- The OpenAI audio API, when
OPENAI_API_KEYis set. The model iswhisper-1, or setTRANSCRIBE_MODEL=gpt-4o-transcribe.TRANSCRIBE_URLpoints it at another OpenAI-style API (the default ishttps://api.openai.com/v1). The API takes files up to 25 MB, so export a long call as mono at 32 kbps (about 15 MB an hour). - The local whisper CLI (
pip install openai-whisper), when the hub findswhisperon its PATH (orWHISPER_BIN). The model isturbo, or setWHISPER_MODEL. This runs where the hub runs, so it's for a hub on your own Mac. A hosted hub can't reach your Mac's whisper: runwhisper call.m4a --model turbo --output_format txtyourself and paste the text. - Neither: the recording is kept and the page says to paste the transcript.
TRANSCRIBE=off turns transcription off, and TRANSCRIBE=whisper prefers the CLI over the API.
When the transcript is in, @steward:
- writes the discovery notes: the problem, goals, constraints, budget signals, who decides, and risks;
- drafts the proposal: summary, scope, deliverables, timeline, price and terms;
- hands a prototype brief to @maya-agent (or a specialist).
2. The proposal
The client's page is at /p/<business>/proposal/<token>. The server builds it from the proposal's fields. It has no scripts, isn't indexed, and shows nothing else: no notes, transcript, other clients or studio names.
- Owners approve it first. Until an owner approves it, the link doesn't exist. Approving it is the trust ladder's "show a client a proposal" (risk person, starting at suggest). A new draft needs its own yes.
- A price the charter doesn't name is a pricing card. The charter's price line is the standard ("$2,500 setup + $295/mo; $1,500 + $245/mo"). Any other price goes on a decision card with the topic pricing, so the charter's decision rights apply (for a business with two owners, both of them). This happens whatever the trust level.
- The client accepts on the page. They type their name and tick a box, and the server records the name and the time. The page works without scripts.
- Then billing. With Stripe on for the business, acceptance asks the gate to make a Stripe payment link: the setup fee once, plus the monthly retainer as a subscription. This is "bill a client with a Stripe payment link", risk money. The link shows on the client's page. The engagement is marked paid when Stripe shows the checkout paid. The revenue itself is recorded by the Stripe revenue sync, so it's never counted twice.
- Without Stripe, the channel says so. Bill the client yourselves, then press Mark paid, which records the revenue.
Paid moves the engagement to delivery.
3. The prototype
@steward hands @maya-agent a brief: who it's for, the 2-4 screens and the flow. @maya-agent builds a small static page set and uploads each page with curl -X PUT .../api/service/proto-upload/<key>/<page>.html. The key only writes this prototype, and it expires in 48 hours. A specialist on the bench uses the publish_prototype tool instead.
The prototype lives at /p/<business>/proto/<token>, and the proposal links to it. Pages can use inline CSS and script. They run sandboxed, with no network access and no cookies.
@maya-agent takes work from @steward only if its owner allows it (Settings, or AGENT_DELEGATES=maya-agent:steward). Otherwise the handoff card says it was declined.
4. Delivery
Once it's paid, @steward plans the delivery with plan_delivery. It sets up checkpoints with due dates, each with its tasks on the business's board. At each checkpoint it posts a card: Approve or Changes needed. Approving the last one takes the client live: onto the retainer if there's a monthly fee, otherwise ended.
5. The retainer
- Monitoring. Add the client's site under Edit price, source and site. It's checked every 15 minutes (
SERVICE_CHECK_MINUTES) during delivery and the retainer. Two failures in a row post an alert in the channel, and recovery posts once. - Requests. Add small change requests on the page. @steward can add them too (
add_client_request), and so can the support loop throughaddClientRequest(engagementId, { text, from, source })insrc/server/service.ts. Each one becomes a task on the board. - The monthly report. At the start of each month, @steward writes last month's report from the work done, the requests and the uptime. The first report for each client always waits for an owner's yes. After that, the trust ladder decides ("send a client their monthly report", risk person). The client reads it at
/p/<business>/report/<token>. Write this month's report now queues one early. - MRR. The sum of monthly fees on the retainer is the business's
mrrnumber. - The morning brief shows each service business's count per stage, its MRR, and how many engagements wait on an owner. It never shows client names, because the brief goes to #general.
Client requests stay on the business's own board, not in the product loop's feedback, because they're private to the client. The support loop calls addClientRequest() when an inbound email comes from a client's contact.
Private links
Each link is a random 32-character token. Proposal and prototype links expire after 30 days, and reports after 90. SERVICE_PROPOSAL_DAYS, SERVICE_PROTO_DAYS and SERVICE_REPORT_DAYS change that. On the page:
- Turn off revokes a link.
- New link replaces it. A prototype keeps its pages.
An expired or revoked link shows "This link isn't working."
Playbooks
Outcomes are recorded for the playbook network:
- Won or lost: tactic
lead source <source>, withwon(1 or 0),days_to_close(ordays_in_pipeline), and the price. Averaged over outcomes,wonis the close rate by lead source. - Going live: tactic
delivery, with planned and actual days,overrun_days, checkpoints and changes requested. - End of a retainer: tactic
retainer, with months retained, the monthly fee, requests and reports.
A won proposal's shape (price, timeline length and scope blocks) goes to the studio library without the client's name, so the next proposal starts from what worked.
Tools (for builders)
@steward's tools are list_clients, save_discovery_notes, draft_proposal, request_prototype, publish_prototype, set_engagement_stage, plan_delivery, checkpoint_ready, add_client_request and draft_client_report. They all respect the room's scope.
The gated actions are:
service.proposal_publish(person)service.invoice(money, needs Stripe)service.report_send(person; the first report for each client is capped at suggest)
The owners' API is under /api/service.