Answer
Every jam ends in a brief someone else works from: the jam brief (the working document), the team brief (one per deliverable, written for a named recipient), a signed read-only page, a PDF and a publish pack; Brew sends the brief only to our team by email and never posts or runs anything itself.
Today
Three documents
| Document | What it is | Where it lives | Source |
|---|---|---|---|
| Jam brief | One Markdown document per jam (w.doc): starts as the card, grows as people jam, AI edits on request, replies fold in; readiness is a checklist, never a score |
the jam | brew/jam-brief.js:1-6 |
| Team brief | One AI pass turns the card, proof, plan, jam brief and final package into a brief with fixed editable sections and evidence per claim; final words verbatim; creatives attached | w.teamBriefs[changeId], one per deliverable tab (?ch=) |
brew/team-brief.js:1-7, 196-200 git 9fd1de4 |
| Hand-off | Everything about a jam for someone outside: card, options, Plays, brief, versions, assets, chats, open questions | /h/<token> read-only page, signed |
brew/handoff.js:1-10 |
TB_V 4: bump it when the team brief starts being written differently; every saved one is rewritten. brew/team-brief.js:17
Recipients
The "Send to…" sheet names a real recipient: your team, your agency, a designer, a media buyer, a creator, a video editor, or our team. brew/team-brief.js:20 memory brew-jam-rca-2026-10-26
Send routes
| Route | What happens | Source |
|---|---|---|
| Share with my team | Freezes the brief (BR-n, numbered per brand), copies it with the read-only link; nothing sent | brew/SCOPE.md brew/docs/handover/engineering/11-known-issues-and-debt.md |
| Send to our team | Freezes and emails the whole brief to SHOPOS_EMAIL (default hello@joinsquareup.com) every time; tracked status |
brew/jam-mail.js:104 brew/brief-status.js:1-6 |
| Download PDF | Chromium render, gen/brief-*.pdf |
memory brew-brief-mode |
| Open in Gmail, Mail or Outlook | Downloads the files and opens a compose page or an .eml draft from the person's own email; no Gmail scope | memory brew-brief-mode |
| Slack | Posts to the channel picked at connect with an Approve button; thread replies fold into the brief | memory brew-real-connectors |
| Publish pack | A zip per version for the team to post or apply by hand | brew/publish-pack.js:1-5 |
Status of a brief sent to our team
sent → received → in_progress → delivered, or needs_info (needs a note) and back. Only staff move it (POST /api/work/:wid/brief/status). Each move writes a jam line, a notification and an email to the sender; the top bar shows "N with the team". If the email did not go, the jam says "ready, paste it", never "sent". brew/brief-status.js:1-10 brew/docs/handover/engineering/12-ui2-service-api.md
Editing a brief
The team brief writes itself once the first draft is in. Selecting text or tapping a section opens "Change with AI"; there are no hand-edit boxes. Chat edits the brief only when the message is about the brief. Every change stamps a revision so teammates reload it. memory brew-team-brief-ai-edit In the Brief tab, people can comment on words and press "Fix with AI". memory brew-brief-mode
Link signing
Hand-off and ready links are HMAC-signed with HANDOFF_SECRET (production uses its own and opens nothing signed with the Anthropic key). The signature is 12 base64url characters. Links do not expire. brew/handoff.js:14-20 brew/jam2/ready.js:10-11
Guests
Guests cannot share, send or move a brief. The demo site sends no email. brew/SCOPE.md
Tomorrow
| Item | Version | Tag |
|---|---|---|
| One team brief per deliverable with a named recipient | v1 | Stays |
| Brew never sends to a brand's customers | v1 | Stays |
| Links that expire and can be revoked | v2 | New |
| Sending a brief to an agency by email from Brew | v2 | New, needs a send decision |
| Posting the final asset to the channel | v3 | New, only behind a person's yes |
How we do it
- A new brief kind gets its own sections in
team-brief.jsand a test intest/team-brief.test.js. - Never let the fact sheet or team-only card words into a shared brief;
unleak()andpublicViewguard this. memory brew-brief-mode memory brew-shopify-connector-qa - Check a status change end to end on staging with a staff account before relying on it.
Numbers
| Metric | Definition | Where measured |
|---|---|---|
| Briefs shared | Frozen briefs per brand per week | w.jamBrief (Proposed to count) |
| With our team | Briefs sent and not yet delivered | withTeam.n on /feed and /work brew/docs/handover/engineering/12-ui2-service-api.md |
| Time to delivered | Sent to delivered, per brief | w.jamBrief.history (Proposed) |
Open
- Should shared links expire? Proposal: 30 days by default, with revoke on the jam.
- Does the recipient "our team" stay now that Brew is kept independent? Proposal: keep it as is, add nothing new tied to it. memory brew-qa-round2-2026-10-24