Skip to content

Ali Mahmood

Local independent newsrooms have a sales problem most readers never see: they can't afford sales people.

Core trick

A RefusalEnvelope branch in the output schema forces the model to refuse editorial-conflict topics, enforcing the firewall at generation time.

Tags

Description

Local independent newsrooms have a sales problem most readers never see: they can't afford sales people. Sales for news media is genuinely expensive expertise (pricing, editorial-firewall navigation, prospect research, partnership reviews), and most of an experienced salesperson's time gets eaten by grunt work: assembling media kits, building sell sheets, drafting prospect research briefs for every meeting. The pragmatic answer the industry is converging on is the shared-services hub: one experienced salesperson covers four to ten outlets at once. That only works if the grunt work is automated. Otherwise that person burns out across ten clients in six months, and the small newsrooms lose the only sales function they could afford. Sponsor Desk is that automation. It connects to an outlet's first-party data and drafts the three documents (media kit, per-product sell sheets, and a prospect research brief) in seconds using Claude Opus 4.7. The structured output schemas carry a top-level RefusalEnvelope branch, so the editorial firewall is enforced at the schema level. A demo brief on a fictional Portland utility that filed a rate increase the demo outlet is independently reporting on flags rate filings and grid reliability as editorial-conflict topics, with named specifics pulled from the utility's own source files. Every generated document writes a provenance sidecar with cache telemetry and pinned content hashes for the editorial-safety block, the prompt contract, and the document-design Skill. The audit trail is the answer to "where did this number come from?" Today's data is synthetic. The architectural hook for real data is already in the codebase: data_sources/ga4_stub.py exposes every method's signature ready for v2 adapters into GA4, Mailchimp, Stripe, and Piano. v2 is where this genuinely helps a real newsroom: real outlet data flowing through the same firewall, one experienced salesperson sustainably covering several newsrooms, professional sales for outlets that otherwise couldn't afford it. MIT-licensed. Self-hostable. Six phases shipped end-to-end. 68 tests passing. Real-API verified.
hockeystick/sponsordeskplus★ 00 forksPythonMITCreated Apr 26, 2026 · last push Apr 26, 2026

README excerpt

# Sponsor Desk

A sales-document tool for **The Cascade Tribune** (a fictional Portland local-news outlet). Drafts three documents — media kit, sell sheet, prospect research brief — from version-controlled prompt contracts driven by **Claude Opus 4.7**, with provenance you can audit line-by-line.

## What it produces

| Document | Format | Audience | Voice |
|---|---|---|---|
| **Media kit** | 5-page PDF, quarterly | External, generic | Institutional |
| **Sell sheet** | 1-page PDF, per product | Cold/warm outreach | Punchy |
| **Prospect brief** | 1-2 pages internal | Sales-internal pre-call | Terse, internal |

The prospect brief is the load-bearing demo moment: Section 6 ("things not to bring up") flags editorial-conflict zones explicitly, with cedar-bordered styling and a labelled badge on each conflict topic.

## What's distinctive

- **Editorial firewall is enforced at the schema level.** Every call's structured-output schema includes a top-level `RefusalEnvelope` branch. When a prompt would push toward sponsored coverage of an active editorial-coverage topic (the load-bearing example: PGE rate filings), the model can refuse the section honestly rather than producing a thin one. The salesperson-facing UI surfaces refusals as specific messages, not as errors.
- **Provenance is the answer to "where did this number come from?"** Every generated document writes a sidecar JSON at `outputs/<doc_id>.provenance.json` documenting which adapter methods were called, the LLM call t

Team