The Deal Service

The running jobjob_7Hq5 · won · msa-northwind.pdf · $11,100.00 charged, held to 2027-03-09

services/deal.ts, step by step. AI sources, qualifies, books, meets and negotiates; a warm reply sends the booking to a setter; the deal's value, a buying committee or the seller's ask sends the meeting and everything after it to one closer. The gate holds the meeting to someone attending and the close to the seller's floor, and the closer works the account in the seller's name.

sales's wordsdeal is a jobaccount is a subjectgig is a taskcloser is a memberseller is a clientseller is a buyer

Each step is AI's until its escalate names a role, so a person books, meets or closes only where one pays off.

humans_from, setter and stall_days bind the mechanics, so the seller or its agent moves them. floor binds the merits: only the seller sets it.

Run
cat services/deal.ts
magic values: none
  policy: {
    floor: { word: 'number', default: 0.8, min: 0.1, max: 1, binds: 'merits', note: 'the least share of list a close may take' },
    humans_from: { word: 'money', default: 50_000, note: 'a closer takes deals at or above this value' },
    setter: { word: ['ai', 'on_warm', 'person'], default: 'on_warm', note: 'who books the meeting' },
    stall_days: { word: 'number', default: job => (job.input.motion === 'B2C' ? 7 : 14), min: 3, max: 90 },

An order past a bound hears every violation at once, with next.fill naming each field:

Call
→ POST /deals {"account":{"name":"Northwind Freight"},"value":80000,"offer":"https://harbor.example/route-planner","policy":{"floor":1.2,"stall_days":2},"max_usd":12000,"key":"northwind-2"}
magic values: none
  "code": "policy_invalid",
  "reason": "The policy breaks 2 bounds: floor must be at most 1; stall_days must be at least 3.",
    "fill": ["policy.floor", "policy.stall_days"],
StepWhoWhat moves it on
sourceAIfinds the contacts at the account
qualifyAIfit goes to book; no fit ends the deal lost, no_fit
bookAI, or a setter on warma meeting on the account's calendar; the setter's gig stays open until it is held
meetAI, or a closer from humans_from, committee or persona meeting the guard accepts as held, which pays the setter $250
propose, negotiateAI, or the same closerthe proposal, then the terms and redlines, each committed at the gate; the gig stays claimed
closeAI, or the same closera committed closed_value with the seller's invoice is won; none is lost, with its reason
nurturea nurturer, routedgone_dark brings it here; revived returns to the step it left, dead ends it lost, dark

A closer's span is one gig, from the meeting to the close, and only the close fulfills it:

Run
cat services/deal.ts
magic values: none
const setter = job => job.policy.setter === 'person' || (job.policy.setter === 'on_warm' && job.signals.warm)
const person = job => job.input.value >= job.policy.humans_from || job.signals.committee || job.signals.person
    closer: { pool: closers, span: ['meet', 'propose', 'negotiate', 'close'], revive: { first_call: '24h' },
  signals: {
    warm: job => job.record.replies > 0, committee: { inbound: true }, person: { inbound: true },
    gone_dark: { silent: job => `${job.policy.stall_days}d`, of: 'account', goto: 'nurture' } },
    book: { by: 'ai', escalate: { to: 'setter', when: setter } },
    meet: { by: 'ai', escalate: { to: 'closer', when: person }, when: job => job.input.motion !== 'B2A',
    propose: { by: 'ai' }, negotiate: { by: 'ai' },
    nurture: { by: 'nurturer', routed: true, next: job => (job.output.revived ? job.record.interrupted : 'lost') },

The setter is paid for the meeting, not the booking: the pay waits on meet.held, the guard that reads the calendar for someone from the account staying 10 minutes. A meeting nobody attended is refused, rebooked and paid once.

Run
cat services/deal.ts
magic values: none
    setter: { pool: closers, pay: { usd: 250, on: 'meet.held' } },
      guard: { held: (m, job) => m.attended(job.input.account) >= 10 || 'no one from the account stayed 10 minutes' } },

talk puts the closer in the client's place: she writes from the seller's domain and calls from its number, so the account deals with the seller alone:

Run
cat services/deal.ts
magic values: none
      talk: { as: 'client', mail: 'client_domain', calls: 'bridged' } },
Run
npx services.dev check --connections   # every outside system the sales folder reads, and what stands in for it on localhost
magic values: none
services/deal.ts:31   roles.closer.talk.mail     the seller's sending domain      https://mail.example.test/sellers/{seller}
services/deal.ts:31   roles.closer.talk.calls    the seller's calling number      https://calls.example.test/bridge

Each touch renews the claim, and only the account's own reply resets gone_dark:

Call
→ GET /gigs/tsk_7Hq5/thread   # as mbr_7Hq4, on closers.deals
200 · tsk_7Hq5 · Northwind Freight · touches 4 to 10, since the claim · each renewed it · magic values: none
  touch 4   9 Nov 11:30   mail · dana@harbor.example confirms the meeting the setter booked
  touch 5  10 Nov 11:00   meeting · bridged from Harbor's number · ops@northwind.example stayed 34 min · held
  touch 6  11 Nov 16:00   mail · dana@harbor.example → ops@northwind.example · proposal-northwind.pdf
  touch 7  13 Nov 10:15   reply · ops@northwind.example · "the CFO wants three years priced" · resets gone_dark
  touch 8  18 Nov 14:10   mail · redlines on the MSA, a three-year term
  touch 9  25 Nov 16:20   call · bridged · 31 min · they asked for 40% off
  touch 10  3 Dec 09:45   reply · "approved: year one at $74,000, net 30"
  hold      yours while Northwind talks · released only by gone_dark, an end or giving it back
  sent as   Harbor Labs · mail from harbor.example, calls from Harbor's number · Northwind never sees closers.deals

close.guard refuses a close below the floor, from AI or a closer alike. The terms and the floor freeze at the claim, and a refused close leaves the gig claimed:

Run
cat services/deal.ts
magic values: none
      guard: { closed_value: (v, job) => v >= job.input.value * job.policy.floor || 'below the floor you set' } },
Call
→ POST /gigs/tsk_7Hq5/complete {"closed_value":50000,"notes":"they asked for 40% off for a three-year term"}
magic values: none
  "code": "guard_refused",
  "reason": "closed_value: below the floor you set ($50,000 < $64,000). The gig stays yours: propose again, or give it back.",
  "gig": { "id": "tsk_7Hq5", "status": "claimed", "hold": "renewed by each touch", "terms": "frozen at the claim, 9 Nov" },
Call
→ POST /gigs/tsk_7Hq5/complete {"closed_value":74000,"term":36,"contract":"msa-northwind.pdf","pay_link":"https://invoice.stripe.com/i/acct_…H4rb/in_…8841","notes":"three years, the first at list less 7.5%"}
200 · tsk_7Hq5 · done · closer · close · committed · closed_value $74,000 · won · nothing is charged until Northwind pays in_…8841 · magic values: none
← 200 · tsk_7Hq5 · done · closer · close · committed · closed_value $74,000 · won · nothing is charged until Northwind pays in_…8841

When the account's best is under the floor, the closer asks, and only the seller answers, for this deal alone:

Call
→ POST /gigs/tsk_7Hu4/ask {"to":"floor","value":0.7,"why":"their budget is fixed at $58,000 for year one, on a three-year term"}
202 · ask_7Hu4 · to Harbor Labs · set the floor on job_7Hu4 · the gig stays yours while they decide · magic values: none
← 202 · ask_7Hu4 · to Harbor Labs · set the floor on job_7Hu4 · the gig stays yours while they decide
Call
→ POST /portal/deals/job_7Hu4/policy {"floor":0.7,"for":"deal"}   # Priya, in Harbor Labs' own session
200 · job_7Hu4 · floor 0.7 · this deal only · $56,000 · your other deals keep 0.8 · magic values: none
← 200 · job_7Hu4 · floor 0.7 · this deal only · $56,000 · your other deals keep 0.8
Call
→ POST /gigs/tsk_7Hu4/complete {"closed_value":58000,"term":36,"contract":"msa-coho.pdf","pay_link":"https://invoice.stripe.com/i/acct_…H4rb/in_…5806"}
200 · tsk_7Hu4 · done · closer · close · committed · closed_value $58,000 · won · over the floor you set for this deal ($58,000 ≥ $56,000) · magic values: none
← 200 · tsk_7Hu4 · done · closer · close · committed · closed_value $58,000 · won · over the floor you set for this deal ($58,000 ≥ $56,000)

won charges once the account's payment proves it. lost charges nothing and records one of five reasons, which the console counts without reading the deal. An end is forever, and again starts a new deal.

Run
cat services/deal.ts
magic values: none
    contract: 'file?', pay_link: 'url', notes: 'text', lost: ['no_fit', 'price', 'timing', 'competitor', 'dark'] },
  ends: { won: { charge: true }, lost: { charge: false, by: ['client', 'brand'] } },
  outcome: { amount: 'closed_value', proof: 'payment', match: { customer: 'account', metadata: 'deal' },
    window: { bank: '60d', card: '120d' }, tail: '90d', due: '90d', collect: job => (job.output.billing === 'monthly' ? 'each' : 'first') },
  price: { usd: 0, share: '5%', of: 'closed_value', on: 'won', ai: 40,
    lines: { referral: { share: '1%', of: 'closed_value', to: 'referrer', on: 'won' } } },

The money follows a won deal's dollars. Policy, signals and ends cover each key for any Service.