Skip to content

Make a company's published inbox the lead when its site names nobody - #71

Merged
ralyodio merged 1 commit into
mainfrom
feat/company-inbox-lead
Sep 13, 2026
Merged

ralyodio merged 1 commit into
mainfrom
feat/company-inbox-lead

Conversation

@ralyodio

Copy link
Copy Markdown
Contributor

Closes #70 (the product half; the dead model chain in that issue is a keys problem, not a code one).

The gap

A crawl of a site that names nobody recorded the company and its support@ and then stopped. A recommendation only ever hangs off a person, so a family-run store with one shared mailbox ended as a company row and an empty queue. instantpeptides.com surfaced it; vendor sites forwarded to bot@ for outreach are usually this shape.

What changes

  • people.kind (migration 0034, default person). A new value, company_inbox, marks the row that stands in for a company's published inbox. It is set deliberately by the crawl, never inferred from a scraped name; isLikelyRoleAccount still rejects "webmaster" and "admin".
  • The crawl queues the inbox as the lead when, and only when, the page named nobody and published an address. It walks the same chain as a named person: site identity at 0.9, a signal citing the address and the company's own description, scoring, a send_email card, policy, approval.
  • The address stays the company's. No email identity is written, so pickEmailRecipient resolves the company inbox as shared and every shared-inbox limit applies unchanged.
  • The composer writes to the team. For a company_inbox prospect the prompt names "the <company> team", says nobody specific is named, and grounds in what the site says rather than what a person said.
  • Sweeps leave it alone. proposeAddresses will not invent firstname@ from a company name; the photo sweep skips it.
  • UI: the approval card shows "Company inbox" where the title would be; kind is on the people list, person detail and card rows.
  • Also formats apps/web/public/.well-known/openaccess.json, which has had main's format check red since Serve an OpenAccess descriptor #69.

Tests

  • Crawl seam: an inbox-only page produces one company_inbox lead with no first name, no email identity, the company's contact_email, a signal naming the address, and a pending send_email card; a second crawl of the same site finds the same lead, not a second one.
  • A page that names someone does not also queue the inbox.
  • Composer: a company-inbox prospect is written to as the team; a named person is still written to by name.
  • bun run check green locally: format, typecheck (root and apps/web), 1472 tests.

Not verified in prod

Drafting still needs a working model key and every provider in the chain is dead as of 2026-09-12 (see #70). The crawl and the card do not need a model; the draft does.

🤖 Generated with Claude Code

https://claude.ai/code/session_01W7ec4VgoKNWeoESuvtKK3i

A crawl of a site that names no person recorded the company and its
support@ address and then stopped: a recommendation only ever hangs off a
person, so a family-run store with one shared mailbox ended as a company
row and an empty queue. Vendor sites forwarded for outreach are usually
exactly this shape (instantpeptides.com was the one that surfaced it,
issue #70).

The crawl now queues the inbox itself as a lead of a new kind,
`company_inbox`, when and only when the page named nobody. It walks the
same chain as a named person: site identity at 0.9 confidence, a signal
that cites the published address and the company's own description,
scoring, a `send_email` card, the policy engine and the approval queue.
Nothing about the address changes hands: no email identity is written, so
`pickEmailRecipient` still resolves the company inbox as shared and every
shared-inbox limit applies as before.

Where the row being an inbox rather than a person matters, the kind is
read: `isLikelyRoleAccount` is bypassed for this one deliberate, typed row
(scraped role words are still rejected); the composer writes to "the
<company> team" about what the site says instead of greeting a first name
and quoting nobody; `proposeAddresses` and the photo sweep leave it alone;
the approval card labels it "Company inbox".

Migration 0034 adds `people.kind` (default `person`). Also formats the
OpenAccess descriptor that has had `main`'s format check red since #69.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W7ec4VgoKNWeoESuvtKK3i
@ralyodio
ralyodio marked this pull request as ready for review September 13, 2026 00:00
@ralyodio
ralyodio merged commit 123a7f5 into main Sep 13, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Company-inbox outreach when a site names nobody; model chain dead in prod

1 participant