How it works

How Optic works

Signals and inbound come in. Each one is scored against the brain of the product it's for. Plays turn the good ones into drafts that open with the product's own read on the prospect's news, and nothing sends until a person approves it. Everything that happens is an event.

Pipeline

One path from a headline to a sent email.

MCP tools, webhooks and the coming web UI call the same service functions, so no surface has logic the agents can't reach.

  1. In

    Sources

    • SEC EDGAR 8-Ks Built
    • News search Built
    • Newsroom feeds Built
    • IR pages Built
    • Inbound forms Building next
  2. Engine

    Normalize, enrich, score

    Dedupe per workspace, score against the live brain, store the reasons. Built

  3. Play

    Draft with the hook

    Run the product on their news; the result becomes the first line. Building next

  4. You

    Approval inbox

    Review from Claude: list_approvals Built, approve and reject Building next

  5. Out

    Send

    Inside the send window and caps, from the workspace's own domain. Building next

Events, append-only. Every signal, submission, draft, approval, email, reply, meeting and stage change. They feed the timeline, the daily digest, outgoing webhooks and per-play metrics.

Signals Built

Signals that say why they fired.

Import your accounts and Optic gives each one the sources its brain needs. A job fetches the ones that are due every hour in production.

Signal sources
SourceWhat it catches
SEC EDGAR8-K items 2.02 (earnings), 2.01 (completed M&A), 5.02 (officer or director change)
News searchComms-leader hires, M&A, rebrands, launches, funding, crisis volume
Newsroom feedAnything in the company's own RSS or Atom feed
IR pageNew article links on an investor-relations listing page
  • Detection is rules, not a model. The company has to be the subject of the headline, and market commentary ("3 reasons to buy…") is skipped.
  • The score is weight × account fit × persona fit × freshness, and every factor is stored with the signal.
  • One event, one signal. While a signal is fresh, more coverage of the same type for the same account joins it.
  • Crisis is volume: a minimum number of outlets in 48 hours with crisis terms in the headline.
  • Runs are safe to repeat. One run at a time, capped in minutes, and a source's first run only records a baseline.
Known limits. Name collisions get through ("AI Maverick Intel acquires…" counts for Intel); the fix is a cheap model check on each candidate. Some signal types, like job posts, have no detector yet. Free news search is slow, so each hourly run covers part of the list.

Brains Built

A brain per product, in YAML.

The brain holds everything product-specific: who to sell to, how to sound, what to offer, which signals matter and how fast to go. The engine holds none of it.

  • optic push <workspace> validates the brain and every play, then writes them in one transaction.
  • A file only gets a new version when its content changes. Drafts and signals record the version they used.
  • Validation fails on unknown keys, bad durations or time zones, unknown event types, offers or personas the brain doesn't define, and auto plays under a brain that requires approval.
# brains/northlight.yaml (a made-up product)
workspace: northlight

icp:
  accounts:
    tier: target
    description: Mid-market fintechs with an in-house comms team
  personas:
    - id: comms_lead
      priority: 1
      titles: [Head of Communications, VP Communications]

voice:
  tone: Peer to peer. Specific. No hype.
  rules:
    - Open with their news, never with us.
    - Under 90 words, one ask.
  banned: [hope this finds you well, circle back]

offers:
  - id: read_on_their_news
    hook: Our read on how their announcement is landing
    cta: Want the full read?

signals:
  act_above: 0.7
  types:
    exec_hire:   { weight: 1.0, personas: [comms_lead], fresh_for: 60 days }
    m_and_a:     { weight: 0.8, fresh_for: 30 days }
    funding:     { weight: 0.6, fresh_for: 21 days }

pace:
  mode: approve
  new_contacts_per_day: 10
  per_account_per_30_days: 1
  send_window: { days: [tue, wed, thu], hours: "09:00-12:00", timezone: recipient }
A made-up product's brain, trimmed. Real brains add follow-up timing, pipeline stages and notifications.

Plays

Plays put the product in the first line.

A play is a trigger, an audience and steps. The analyze step runs your product on the prospect (a read on their coverage, a demo of their app) and its output becomes the draft's hook.

  • Plays are validated with the brain Built. Running them, with drafting and sending, is building next.
  • New plays start as status: draft; nothing runs until a play says active.
  • exit_on ends the play on a reply, a meeting or a bounce. The database enforces the reply rule even if a play forgets it.
# plays/northlight/new-comms-lead.yaml
slug: new-comms-lead
mode: approve

trigger:
  type: signal
  signal_types: [exec_hire]
  min_score: 0.7

audience:
  who: signal.person
  exclude:
    lifecycle: [engaged, meeting, customer, disqualified]

steps:
  - enrich: { require: email_valid }
  - analyze: { tool: northlight.read, input: { company: "{{company.domain}}" } }
  - draft: { offer: read_on_their_news, max_words: 90 }
  - send
  - wait: 5 days
  - draft: { style: bump, max_words: 40 }
  - send

exit_on: [email.received, meeting.booked, email.bounced]
A play for the made-up product above.

Approval and sending

Drafts wait for you. Rules don't wait for anyone.

Drafts are messages with status = 'pending_approval'. The approval inbox shows each one with the person, company, play and the signal that triggered it.

Approve from Claude

list_approvals is live Built. approve accepts edits and keeps the original for the edit-rate metric Building next.

Send inside the lines

One sending vendor first, inside each brain's send window and each sender's daily cap Building next.

Replies stop everything

Gmail sync brings replies in Building next; the database then ends the play and cancels queued automated drafts Built.

Events and webhooks

Everything is an event.

Events are named noun.past_tense and carry typed references to the person, company, deal, signal, play and message, so timelines and metrics need no JSON digging.

  • The append-only event log and the webhook outbox are in the schema Built. Each delivery is queued in the same transaction as its event.
  • Inbound forms post to POST /v1/inbound/{workspace}/{form}, signed per form Building next.
  • The outgoing dispatcher retries at 1m, 5m, 30m, 2h, 6h and 24h, then marks a delivery dead Planned.
{
  "id": "6f1c…",
  "type": "email.received",
  "workspace": "northlight",
  "occurred_at": "2026-10-18T14:02:11Z",
  "data": { "person_id": "…", "subject": "Re: …" }
}
An outgoing webhook. Signed with Optic-Signature: t=<unix>,v1=<hmac_sha256>; consumers dedupe on id.

Vendor seams

Vendors behind interfaces.

The engine codes against interfaces, and each workspace picks its vendor. The first vendors are still being chosen.

Vendor interfaces
InterfaceDoesFirst vendor
ContactDataFind people at a company, enrich, verify emailApollo or Prospeo
SenderSend a message, check its statusInstantly or Smartlead
MailboxSync messages with a thread keyGmail
MeetingsList meetings, pull action items as tasksGranola
CrawlerFetch a source, return candidate signalsFirecrawl, plus our IR and link crawlers
NotifyPush an event to a personSlack or email

What's built

Where the build is.

The first version is a two-week plan: one engine, two brains and a working Claude interface. The web UI waits.

  1. Days 1–2BuiltSchema on Postgres, the push CLI with validation, key auth and the first MCP tools, deployed on Cloud Run
  2. Days 3–4BuiltSignal layer: SEC filings and news search for the starter accounts, deduped and scored, running hourly
  3. Days 5–6Building nextDrafting with the product hook, plus the approve and search MCP tools
  4. Days 7–8Building nextSending from a fresh domain through one vendor, and Gmail sync for replies
  5. Day 9Building nextInbound webhook for demo forms and the demo-request play
  6. Day 10Building nextA second product's brain live, then a review of play performance
  7. LaterPlannedWeb UI with Firebase Auth, Granola sync, CRM sync to Attio or HubSpot, billing

Optic runs our own GTM today.

It isn't for sale yet. If you'd run it for your product, tell us what you sell and which signals matter, and we'll talk when drafting and sending are done.