The delivery portal

The running jobjob_7Hq2 · delivered · document.fr-CA.pdf · $49.00 charged

Every Pool gets a portal for its members, phone-first. It opens on the Pool's terms for them; Tasks are offered, never assigned; the packet shows the document they sign; and each act runs only in the member's own session, paid at the act whether they sign, send it back or decline. Their dates sit beside their Tasks, with the clocks they acknowledge.

The delivery portal is where the people in a Pool take the Tasks your Services offer them. AI does the work; a member reviews, signs or advises where your rules give the step to a credentialed person. It serves phone-first on the Pool's door:

Run
npx services.dev dev --members 12 --market tight --no-try
magic values: client.email = signs@example.test
  attorneys           http://localhost:8787/attorneys · join at /attorneys/join, or npx services.dev signers add attorneys <email>

legal's wordsmatter is a jobasset is a subjectreview is a tasksigner is a membernetwork is a pooloutcome is a end

Every Pool holds these terms, from the member charter, each proved:

TermWhat enforces itProved in
You are never charged to work: no fee per Task, per lead or by a share.No ledger line charges a member. The one member charge a Pool may carry is a flat software fee, shown before you join.check fails member_charged on any line that charges a member to work
Every act the gate accepts is paid: an attestation, a send-back, a decline or a completed visit.Pay accrues at the act (pay.accrued), is payable 2d later and is paid on the Pool's schedule. Only a contest ruling that records bad faith takes it back: Pay.member-acts, legal-decline: pay.accrued at each act
Your no is final.A decline is paid and never scored. Only the client directs what happens next, and the member who declined can never be named for it again.legal-decline: needs_direction, and the decliner refused when named
No one reads your conflicts.Your ledger holds HMACs under a key that is yours alone. The owner reads that a check ran, never what it found.member-ledger: the owner reads no hash of it
Your contact never reaches a party.Everything between you and a party goes through the job thread, and an email or phone number in it is withheld both ways.ask-the-client: the email withheld
A pass is free, and never scored.A pass counts against the Task. Only a quorum of passes for one reason moves its fee, due date or reach.task-sheet: passes counted on the Task
A fee never drops.The fee is fixed when the Task posts. The fill ladder only raises it.legal-fill: the ladder raises, never lowers
A job that ends under you after you cleared its Task pays 50% of the fee.The kill share (kill: '50%') accrues when a cleared Task is withdrawn, or a claimed visit is cancelled inside notice.the Pool's kill, accrued as pay.accrued at the withdrawal

The same terms open the Pool's /join, before anyone gives an email:

Delivery portal/attorneys/joinnothing waiting

A member is offered nothing until the verifier writes what it checked. Their portal shows the card:

Delivery portal/attorneysnothing waiting

Each screen is drawn from the operations registry rows a member's own session calls; no key, agent or console acts for the member. Each act and its pay: what a person can do.

All 34 operations
OperationDoesHTTP
job.send_backSend a job back with a note, and the AI redoes it: a delivered one as the buyer, a waiting one as the person at the line.POST /jobs/:id/send_back
job.approveApprove, sign or do a job waiting on a person: a proposal the gate commits or refuses, as it does the AI's. A key or a tool never can.POST /:portal/jobs/:id/approve
member.joinJoin a Pool, email first and resumable: each call takes the answers it brings, one step of the application at a time, and once it's whole the verifier runs. The owner adds a member the same way.POST /:portal/join
member.availabilitySet your availability: on, off or away. Only a member who is on is offered work.POST /me/availability
member.ledger.getRead your conflicts ledger: hashes only, salted with your id, never pooled and never seen by the brand.GET /me/ledger
member.ledger.addAdd a party to your conflicts ledger: its name, email and organization are each hashed before anything is kept. A Task's parties are checked against it, mechanically.POST /me/ledger
member.ledger.checksEvery check of your conflicts ledger: the Task it ran for, when, how many parties, and whether one matched. You see every one, and no one else sees any.GET /me/ledger/checks
member.missedThe open Tasks your own declarations kept from you, each naming the one (your minimum fee, your areas, your hours), and never one eligibility kept from you; with the last 30 days of your Pool, in a line.GET /me/missed
member.earningsYour pay, act by act: when each accrued, when it is payable, the payout that moved it, and a line per brand. One payout account across every Pool and brand.GET /me/earnings
member.trackYour track record, yours to carry: your counts per Pool and brand, with each Task's hash, signed by the door and naming no party.GET /me/track
task.listYour feed: every open Task offered to you that you can take, newest first, as teasers. The owner console reads every Task.GET /tasks
task.getRead a Task's teaser: its teaser fields, the estimate, the rate and when it's due. Never a party name.GET /tasks/:id
task.sheetRead a Task's sheet: the teaser, its sheet fields with the parties, and what you attest to clear it. One member at a time, and every view is logged.GET /tasks/:id/sheet
task.passPass on a Task: free, with an optional reason, counted against the Task and never against you. Under `cascade` it goes to the next member at once.POST /tasks/:id/pass
task.claimClaim a Task: the eligibility predicates run in order, and it is held for you until the Pool's hold runs out.POST /tasks/:id/claim
task.clearClear a held Task: the conflict check runs again, and you attest each statement on its sheet. The packet opens, and the job waits on you.POST /tasks/:id/clear
task.packetRead a cleared Task's packet: the summary, the AI's artifacts and their diff, the review reports, the checklist, the record, the signals, the clock and the hash you attest.GET /tasks/:id/packet
task.releaseGive a held Task back before it is done: it opens again at the fee it was posted at, and the dispatch runs on.POST /tasks/:id/release
task.arriveCheck in at a work-register Task's site: the device's fix must fall inside the Pool's site radius, between its early and late marks around the window. Counted, it reads on_site.POST /tasks/:id/arrive
task.completeComplete a work-register Task you are on site for: every evidence item the step names, each stamped with time and place and hashed together, for the gate to commit. Paid per completed Task.POST /tasks/:id/complete
task.attestAttest the Task you claimed and cleared: your proposal, for the gate to commit, freezing who, the credential, where, the hash and the rules on the record. With reservation, qualified: it travels with the output. Paid.POST /tasks/:id/attest
task.send_backSend the work back with its defects: paid, and the job returns to the step you name, by default the one before. That work is redone and the step posts a new Task.POST /tasks/:id/send_back
task.declineDecline the Task, with a reasoned memo only the client reads: paid and never scored. The job waits on the client's direction: another member, or an end.POST /tasks/:id/decline
task.recuseStep aside from a Task you hold, for a conflict: nothing accrues and nothing is scored, and it reopens at once. The parties you name join your own ledger, and you are screened from every Task on the subject. The client reads that a professional stepped aside, never why.POST /tasks/:id/recuse
task.extendExtend your hold on a Task, once: by as long again as it first held, never past its due date.POST /tasks/:id/extend
task.contestContest a send-back your attested work received, with a reason. A peer with the same credential rules it on a reserved act; staff rule the rest.POST /tasks/:id/contest
task.messageReach the client through the job's thread, by kind: a question (an answer ask that pauses your hold and the step's clock until they reply), a note (no reply expected), or a flag (a named signal the owner sees, which never blocks). Their email and phone never reach you, nor yours them.POST /tasks/:id/messages
member.subjectsThe subjects where you are of record: you stay of record across jobs until you withdraw.GET /me/subjects
subject.withdrawWithdraw as the member of record, naming your successor: a member who holds the role's credential takes the seat.POST /subjects/:id/withdraw
clock.listThe clocks your jobs and their subjects run: each one's date, who answers for it, its rungs and where it stands. A member reads the ones they answer for.GET /clocks
clock.getRead a clock: its date, who answers for it, each rung and when it falls due, what moved it, and at its date the owner's options.GET /clocks/:id
clock.ackAcknowledge a clock you answer for: inside its ack daily window, the day's acknowledgement, so the day is never missed. Only its owner can.POST /clocks/:id/ack
clock.satisfyClose a clock you answer for, on evidence on the record: a file you send, or a receipt or file the job holds. A recurring clock rolls on to its next date.POST /clocks/:id/satisfy
clock.chooseChoose one of a clock's lapse options at its date, unsatisfied, and the clock closes. A step's name runs that step, through the gate.POST /clocks/:id/choose
PathShows
/<pool>One inbox in fixed groups: Needs you, Your dates, Offered to you, Waiting on the client, Done this week, then the subjects where the member is of record. Above it, the member's card, availability, earnings and the tier
/<pool>/joinThe terms, then the application, one step at a time, resumed by email
/tasks/:id/sheetThe parties and the kind of work, and what clearing attests; then claim or pass
/tasks/:id/packetOnce cleared: what they sign, each file by its hash with its versions and what changed, what the review found, the client's answers, the pay and the clock; then the acts
/tasks/:id/visitIn a work register: the window, the site once claimed, check in, each evidence item, the party's sign-off on the member's phone, and check out
/<pool>/earningsEvery accrual: its act, its fee, when it's payable, and the payout that moved it, a line per brand
/<pool>/trackThe tier rule, and how far the next tier is
/me/missedThe open Tasks a member's own declarations kept from them

A Task arrives as an offer event carrying only its teaser, never a party. It lands in the inbox while the member is on; away or off, nothing is offered:

Call
→ GET /reviews/tsk_7Hq2   # as mbr_eligible
200 · magic values: client.email = signs@example.test, member = mbr_eligible
{
  "id": "tsk_7Hq2",
  "object": "task",
  "livemode": false,
  "pool": "attorneys",
  "role": "attorney",
  "status": "open",
  "fields": {
    "act": "sign",
    "region": "US-NY",
    "fee_usd": 75,
    "signals": [
      "collections",
      "recipient_elsewhere"
    ]
  },
  "est": {
    "minutes": 30,
    "from": "step"
  },

A cascade offer is the member's alone for its window. A window let close moves to the next member and is never scored.

A pass is free and counted against the Task, never the member. A quorum of passes for one reason fires the matching rung early: three fee passes raise the fee now, not at two hours:

Call
→ GET /reviews/tsk_7Hq2/sheet   # as mbr_7Hq4
magic values: client.email = signs@example.test, member = mbr_eligible
← 200 sheet · fee $75.00
→ POST /reviews/tsk_7Hq2/pass {"reason":"fee"}   # as mbr_7Hq4
← 200 tsk_7Hq2 · open · attorney · sign · US-NY · $82.50 · signals collections, recipient_elsewhere · 30 min · $165.00 an hour · due 2026-10-27 14:02

→ GET /owner/reviews/tsk_7Hq2   # the owner console
← passes {"fee":3} · viewers 3 · posted $75.00, now $82.50
  fired  raise 10% 2h · 14:02 · raised to $82.50 · jumped

What their own minimum fee, areas or hours kept from them is at /me/missed, and what they are offered is theirs to set:

Delivery portal/me/missednothing waiting

The inbox, the sheet, then the packet once the member claimed and cleared it. Every screen, in order walks the rest.

Delivery portal/attorneystsk_7Hq2 · open
Delivery portal/reviews/tsk_7Hq2/sheettsk_7Hq2 · open

The packet opens on the document itself: each file the AI wrote, by hash, with its versions and what changed. The attestation binds the packet's hash:

Delivery portal/reviews/tsk_7Hq2/packetjob_7Hq2 · waiting at sign · with the member

Your dates puts each open Task's due date beside its job's clocks, with every clock the member answers for, late first, then today, this week and later. Each line is read from the clock's own keys:

The clock declaresThe member readsTheir control
owner: 'of_record' with them of record, a role they did on the job, or the owner console's assignyoursthe two below, on that clock only
rungs: ['notice 30d']the next rung's date: notice 16 Mar—
rungs: ['ack daily 7d']acknowledge each day from that dateAcknowledge today, inside the window
rungs: ['run tentative 3d']the step that runs itself, and when—
lapse: [...]was due, at the date, unsatisfiedone button per option, a choice
moves: { extend: '6mo after due' }the new date, and the one it moved from—
lives_on: 'subject'the date stays with the subject after the job ends—

A clock no one can answer for never reaches a member; the owner console raises it.

Delivery portal/attorneysno clock

In the tax example, an extension moved a date, and the portal says from when. The subjects the member is of record on follow:

Delivery portal/practitionerstsk_7Hq1 done · after the extension

/<pool>/earnings lists every accrual with its act, its fee and when it's payable, under the terms above:

Delivery portal/attorneys/earningsnothing waiting

Payouts land on the Pool's schedule, to one payout account for every Pool and brand. Pay has every schedule.

Worked in: closing on closers.deals.