Build it
The sales brand's folder, one file at a time. Its words, then the closers' Pool on an existing door, then the Deal Service, with check after each one.
sales's wordsdeal is a jobaccount is a subjectgig is a taskcloser is a memberseller is a clientseller is a buyer
The brand is a folder of three files. Write them in this order and run check after each. The count it prints is lines of code, comments left out.
The brand's words, so every surface says deal, account, gig and closer, and names the seller where the core says client and buyer. check prints the plan each file needs, and the domain is the line that sets Launch. Brand() covers each key.
cat brand.tsimport { Brand } from 'services.dev'
// A sales brand shaped like api.forsale, proving Money and Outcome. Its words render every surface its sellers,
// agents and closers read: /deals, deal.ordered, get_deal. A seller pays nothing on effort: 5% of the closed value
// at won, or 15% when a closer takes the deal, the closer's 10% passed through whole, proven by the payment.
export default Brand({
domain: 'api.forsale',
words: { job: 'deal', subject: 'account', task: 'gig', member: 'closer', client: 'seller', buyer: 'seller' },
})npx services.dev check # after brand.tsbrand.ts · 2 lines · sales · api.forsale · words job → deal, subject → account, task → gig, member → closer, client and buyer → seller
plan Launch (services.dev) · Brand.domain at :7
No Services here.
next npx services.dev initOne Pool for the three roles a deal escalates to. It lists on closers.deals, a door another account runs, so each gig it fills carries a placement line, never taken from a closer's pay. A claim lasts while the closer works the account, and staff rule on a contested outcome. The closers' Pool reads each line.
$ cat pools/closers.ts
import { Pool } from 'services.dev'
// One Pool for every role a deal escalates to: setters book the meeting, closers take it to won or lost, and
// nurturers revive a deal gone quiet. The Pool lists on closers.deals, an existing door for B2B sellers, whose
// consumer face is closers.sale, so the door's roster, /join and verifier are the Pool's, with a placement line on
// each gig its members fill. A claim lasts as long as the closer works the account. Tiers follow deal size, a
// firm enrolls its bench under its own name, and staff rule on a contested outcome within 14 days.
export const closers = Pool({
npx services.dev check # after pools/closers.tspools/closers.ts · 14 lines · closers · 3 roles: setter, closer, nurturer · joins in 3 steps on closers.deals · feed, ranked by fit, then track · hold 48h to a first touch, then each touch renews it
door closers.deals · operated by another account · closers.sale is its consumer face · placement $25.00 a filled gig
plan Team (services.dev) · Pool.rank at :17 · Pool.tiers at :18 · Pool.firms at :19
No Services here.
next npx services.dev initThe deal, at 42 lines: three roles and their pay, the closer's span from the meeting and how she reaches the account, the seller's policy, four signals, seven steps and a routed one, two guards, two ends with the reason a deal is lost, the outcome with its proof, and the price with its referral line. The Deal Service walks it step by step.
$ cat services/deal.ts
import { Service } from 'services.dev'
import { closers } from '../pools/closers.ts'
// A deal, worked from first touch to the account's payment. AI sources, qualifies, books, meets and negotiates.
// A warm reply sends the booking to a setter, paid once the meeting is held. A deal of $50,000 and up, a buying
// committee or a seller who asks sends the meeting to a closer, who keeps the deal to the end. An account that goes
// quiet sends the deal to a nurturer, and a revived deal returns to the step it left. The gate refuses a close below
// the seller's floor, from AI or a person. Won is proven by the account paying the seller's own invoice.
check now reads the whole folder. Before the first order it prints what a won deal leaves you, what a lost one costs, the win rate where the two break even on each track, and the plan each file needs. Every way a deal ends, and its ledger, is on the money:
npx services.dev check # after services/deal.ts plan Launch (services.dev) · Brand.domain at :7
plan Team (services.dev) · Pool.rank at :17 · Pool.tiers at :18 · Pool.firms at :19
services/deal.ts · 42 lines · nothing on effort; 5% of closed_value at won, proven by the account's payment, held 60 days by bank, 120 by card.
roles setter · from closers · books the meeting · $250 when it is held, at meet.held · paid by api.forsale, won or lost
closer · from closers · meet, propose, negotiate and close · 10% of closed_value at won · charged to the seller · held with the 5%
policy floor · merits, the seller's alone · 0.8 of value · 0.1 to 1
outcome proof payment, read through services.dev's Stripe app on the seller's account · matched on the account's customer and metadata.deal · collect first, or each invoice when billing is monthly · due 90d · window 60d by bank, 120d by card, from each collection · tail 90d
ledger +$11,100.00 at won on $74,000 · closer $7,400.00 (share, from the seller) · setter $250.00 · placement $50.00 · AI $11.34 (example) · you $3,388.66
lost +$0.00 · setter $250.00 when the meeting was held · placement $50.00, the setter's gig and the closer's · AI up to $40.00 · you −$340.00 when a closer loses it
odds each track at the deal it takes · AI alone, $30,000: won $1,490.88, lost −$40.00 · breaks even at 2.6% won
a setter, then AI, $40,000: won $1,714.52, lost −$315.00 · breaks even at 15.5% won, the worst bet
a closer, $74,000: won $3,388.66, lost −$340.00 · breaks even at 9.1% won (about 1 in 11)
gone quiet, a closer's deal: won $3,213.66, lost −$515.00 with the nurturer's $150.00 and its placement · breaks even at 13.8% won
plan Team (services.dev) · pay: { share } at :30, the closer's 10% at won · the referrer's 1% at :52
✓ ready to sell · 1 Service · AI closes a deal under $50,000 alone · nothing charged before wonIts plans shows which keys need which plan.