Skip to content

Add Investor Signals + Sales Enrichment recipe#53

Merged
georgeatparallel merged 7 commits into
parallel-web:mainfrom
jliounis:add-investor-signals-recipe
Jul 20, 2026
Merged

Add Investor Signals + Sales Enrichment recipe#53
georgeatparallel merged 7 commits into
parallel-web:mainfrom
jliounis:add-investor-signals-recipe

Conversation

@jliounis

@jliounis jliounis commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

What this adds

A full-stack Python + React recipe under python-recipes/parallel-investor-signals, built on the Parallel Task and Monitor APIs. Two workflows sharing one Python core:

  1. Investor Signals pipeline — you pick the VC funds to track. One daily event_stream Monitor per fund detects new AI-native rounds (seed–Series B); each detection is chain-verified by a follow-up Task (previous_interaction_id), scored by a priority policy, checked against your CRM, and delivered to Slack via a weekly cron digest or a real-time webhook receiver.
  2. Sales Enrichment app — FastAPI + Vite/React app that turns a company into a fully-cited account brief (two concurrent Task runs), with a server-side credibility rule that returns null rather than fabricating any uncited value.

Why someone would fork it

  • Bring your own watchlist — no funds are hardcoded. Users copy monitor/investors.example.jsonmonitor/investors.json (gitignored) and list their own funds (or set an INVESTORS env override).
  • Bring your own CRM — the CRM check is a small pluggable adapter seam (backend/crm.py). Attio ships as the reference adapter; adding HubSpot/Salesforce/etc. is one adapter file implementing three functions.
  • One-command agent onboardingAGENTS.md is a paste-in prompt that walks a coding agent from clone → running, including prompting for the user's CRM and wiring up an adapter from that CRM's API docs.
  • Detailed human setup + Vercel deploy in the README.

APIs & surfaces

Task · Monitors · Webhooks · Cron — plus structured output with per-field research basis (citations + confidence) and the monitor→task verification chain.

Safety / hygiene

  • No secrets or private data committed: .env, generated monitor artifacts (monitors.json, signals.json, state.json), the derived portfolio_names.json, and investors.json are all gitignored. Only .example fixtures ship.
  • Registered in both README.md (Scheduled Research & Webhooks) and website/cookbook.json.
  • MIT licensed, lockfile committed.

Verification

ruff clean · 39 backend (pytest) + 9 frontend (vitest) tests pass · tsc -b && vite build clean.

James Liounis and others added 4 commits July 15, 2026 18:45
A full-stack Python + React recipe on the Parallel Task & Monitor APIs:

- Investor Signals pipeline: one daily event_stream Monitor per fund the user
  chooses, each detection chain-verified by a follow-up Task
  (previous_interaction_id), scored, CRM-checked, and delivered to Slack via a
  weekly cron digest or a real-time webhook receiver.
- Sales Enrichment app: FastAPI + Vite/React app that turns a company into a
  fully-cited account brief (two concurrent Task runs) with a credibility rule
  that never fabricates uncited values.

Built to be forked:
- Watchlist is user-owned via monitor/investors.json (gitignored); no funds
  hardcoded. investors.example.json ships as the sample.
- CRM is pluggable via a small adapter seam (backend/crm.py); Attio ships as the
  reference adapter, and AGENTS.md walks an agent through wiring up any CRM.
- AGENTS.md is a paste-in, one-command onboarding prompt for coding agents.
- No secrets or private data: .env, generated monitor artifacts, and derived
  portfolio lists are all gitignored; only .example fixtures are committed.

Registered in README.md (Scheduled Research & Webhooks) and website/cookbook.json.

Verified: ruff clean, 39 backend + 9 frontend tests pass, tsc + vite build clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KwAHtpTsa3PyXfb7kdhUfc
Ran the cookbook-writing verification pass over the recipe's prose docs.
The canonical recipe (vendor-intelligence) uses zero em dashes; these four
docs had 97. Replaced them with colons/commas/periods as the sentence needs,
preserving en dashes in ranges (seed–Series B, 1–10). Also aligned the two
"Fast lookup" latency figures. Markdown docs only; Python source docstrings
are left as-is (reproduced source).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KwAHtpTsa3PyXfb7kdhUfc
P1 fixes:
- Webhook signature verification (new webhook_verify.py): verify Standard
  Webhooks HMAC over webhook-id.timestamp.body against the account secret
  (whsec_), with replay tolerance. The receiver now FAILS CLOSED — no secret
  or a bad/missing signature is rejected, never processed. Dropped the old
  ?key= URL-secret scheme (also removed from monitors.py set-webhook).
- Webhook idempotency: dedupe retries by webhook-id so a redelivery can't
  re-run the verification Task (spend) or double-post; documented the
  ack-fast/enqueue pattern for production.
- Webhook now runs the CRM check + shared qualification, so a company already
  in the CRM is no longer mis-scored as net-new.
- Cron fails closed: /api/signals/weekly-digest requires Bearer CRON_SECRET
  and is disabled (503) when unset — no open, credit-spending route.
- Domain credibility gate: an uncited model domain is dropped (was fed to the
  website + email synthesis); trusted only if cited or user-supplied.
- Bulk guarded on serverless: backend returns 501 and the Bulk tab is hidden
  on deploys (in-memory job state can't survive instance hops).

P2 fixes:
- Cron schedule documented as fixed UTC with the DST caveat (no "9 AM PT").
- Attio: relabel associated deals (all stages) as such, not "active"; note
  Deal.owner; stop claiming pipeline state the API didn't establish.
- CSV formula-injection: prefix cells starting with = + - @ / control chars.
- Pagination: follow next_cursor for monitors + events (live, digest, CLI).

Design: extracted one qualify_signal() used by the CLI drain, the local web
drain, the weekly digest, and the webhook — killing the drift where the local
refresh omitted CRM checks, pipeline label, and priority.

Tests: new test_security.py (signature verify, CSV safety, domain gate,
qualification); updated gate/label tests. ruff clean; 54 backend + 9 frontend
pass; tsc + vite build clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KwAHtpTsa3PyXfb7kdhUfc
@georgeatparallel
georgeatparallel self-requested a review July 20, 2026 15:47
@georgeatparallel
georgeatparallel merged commit a1a1a6a into parallel-web:main Jul 20, 2026
1 check 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.

2 participants