Run it
Set the project up as Installation describes. Copy the file withbriefs/, contacts/ and decisions.json beside it,
sign in to Claude Code, and run it from that directory. decisions.json
carries what the person decided on the last pass; set OUTREACH_SEND_URL
to your CRM’s endpoint, or leave the fictional default:
Terminal
Output, from the offline proof
history/ holds one line per contact in sent.jsonl,
refused.jsonl or waiting.jsonl, and each contact’s run has its own
record under records/.
The file
The brief says what a first note is and what it never does, and a person reads every draft:briefs/outreach.md
dag() run of three steps. The draft seat writes
outbox/<contact>.md; the person’s decision is an approval step; the send
is a command that runs only when the decision was yes:
examples/use-cases/sales/draft-then-send.ts (excerpt)
answer, so the run
carries on from it. Without one, approval has no answer to give: the step
pauses with the question on the record, and the send never runs. A no fails
the step with the person’s note as its summary, and the send never runs
either. The host then files each contact by what happened:
examples/use-cases/sales/draft-then-send.ts (excerpt)
records/<contact>.jsonl under its own run id, so a
later pass can reopen exactly the run that is waiting when the person
decides, and the sent and refused ones are untouched.
Full file
Full file
examples/use-cases/sales/draft-then-send.ts
The team’s shape
What the run did
The proof runs the file against a scripted seat and a stand-in forcurl,
and checks what the page says: three drafts on disk, one call to the CRM
and only for the approved note, the refusal’s note on the record, and the
third run stopped on its question. Obversa recorded each contact’s run as
its own event log, so the record for the refused note shows the draft, the
question, and the person’s reason in order, and the record for the waiting
note ends on the question.
The person’s decisions here are read from a file, because the file has to
run offline. In use, the answer comes through the callbacks client from a
page that asks one question, and a run started again
with resume: true finds it, as A person decides
shows. Either way the send is a step the person owns, and the drafts that
never got a yes are still on disk to read.
Next steps
- A person decides: the decision step, and how an answer reaches a paused run.
- A command decides the path: the send as a command whose exit code is the result.
- Contract review: a model’s drafts and a person’s decision in another field.