A CV does not differentiate for GTM and growth roles; a working agent built around the hiring company's own job description does. Rebuilding one by hand cost a day per company, and the rules that keep a demo defensible in front of a founder — never invent a person, never let the model emit a dollar figure, never prospect the company's own customers — kept getting forgotten between builds. The first generic version had a further weakness: a hiring manager could get most of it by typing the same prompt into a chat window.
What I built
A Claude Code skill (/signal-engine, preceded by the simpler jd-to-agent skill and a Python/FastAPI prototype) that runs the flow from pasted JD to verified live URL: research the hiring company into a brief with a URL per claim, pick which buying-signal sources fit their customers, propose concepts, write a PRD as an approval gate, customise a bundled Next.js template, author the business-case coefficients in code, deploy to Vercel, and exercise the live endpoints logged out before handing over. The template is a working reference engine rather than generated code: a two-phase scan (a tool loop over Exa job-board and ATS search, a live VC deal feed and public complaint search, then a structuring pass into typed lead cards), a per-card enrich step that finds a named decision maker on public pages and drafts outreach, a deterministic ROI module, and a Kanban pipeline board fed over NDJSON with a Gmail compose deep link — nothing is ever auto-sent. The skill document carries 24 numbered guardrails, a per-file customisation map, and a verification checklist: at least three real leads with one stacked signal, a named contact whose source URL resolves (or an honest empty array), and every link opening in a private window at phone width.
Highlights
The model never emits money. The lead schema exposes only integers it counted plus one headcount estimate; every figure on a card is computed in code, and an estimate with no observed evidence is capped at 8 FTE and labelled 'estimated'. Written after an early build rendered a seven-figure business case on nothing but a guessed headcount.
Assumption labels must be interpolated from the same constants the arithmetic multiplies; the spec rejects any label carrying a literal digit without a {value} placeholder. The reference build had the uplift rate in one constant and typed by hand into the headline and the outreach prompt, so changing it would have made the UI and the email lie.
Exclusions and proof points are two lists. Customers, in-flight deals and competitors can never appear as leads; only customers with a published metric can be cited, and each metric is pinned to its customer. The reference build had conflated the two and told the model every named customer was citable.
Signal sources are validated with real queries before they are wired in, and dropped if they return fewer than about three usable companies. The engine's thesis is that a company showing two independent signals outranks one showing one, so a dead source silently turns every lead single-signal; below two live signals, ship a different concept.
A skill instead of a web app, on purpose: with one user, an app would be auth, key storage and deploy orchestration wrapped around a form, while the hard part — the research and defending each coefficient — is LLM work either way. The runtime model was benchmarked on the real workload, then a 6–8 tool-call research protocol was mandated in the scan prompt because the faster model did two tool calls where the slower one did ten and returned weaker leads.
Nine demo agents
Each one built to a company's own job description and shipped as a live URL.
telli Signal Engine
Live raise, hiring and pain signals stacked into a drag-and-drop outreach pipeline.
A deterministic euro ROI model in code: the LLM only reports the phone roles it actually saw, unevidenced headcount is capped at 8 FTE, and every card renders its assumptions alongside the figure.
One inbound demo request in; enrichment, fit score, drafted reply and founder brief out.
A Monday Queue page runs six overnight demo requests concurrently in the browser and auto-ranks them by demo-bottleneck fit, so Karumi's own 'reply while intent is hot' pitch is performed on Karumi's own funnel.
Finds lenders paying humans and engineers for the same document problem.
Runs itself nightly via launchd behind a deploy-safety script that refuses to ship a dirty tree or an empty scan, on top of a business case whose coefficients validate their own sources at module load.
Finds companies whose customers are publicly failing their AI agent, sizes the hand-testing hours, drafts the email.
A one-click board audit that re-fetches every source, detects closed ATS reqs, catches exclusion leaks and recomputes each card's business case — the pipeline tests itself before anything sends.
Finds funded, hiring B2B SaaS that still gates the product behind a demo form.
A domain-scoped demo-gate tool that separates 'form found' from 'self-serve confirmed' from 'evidence thin', so the gate is a filter rather than a keyword hit — and the page itself has no contact form, only an agent.
Type a company: live signal scan, fit score, decision maker, draft — or triage an inbound lead.
Blueprint mode redraws a finished run as a Gumloop-style node graph — Trigger → Web Agent → AI steps → Router → Human-in-the-loop → Outputs — populated with that run's real searches, score and contact.
Runs Orange Slice's own outbound motion, on Orange Slice's own ICP.
Outreach is drafted with the target's own published cold-email guide as the system prompt, and every enriched lead card ships the prospect's first Orange Slice workflow, paste-ready for their CLI.
Mines Crustdata's own API for postable data stories, with a receipt on every number.
No language model anywhere: numbers are computed from API responses and drafts are template-assembled, so a made-up stat is impossible by construction, and each figure links to the exact API call that produced it.
A LinkedIn engine that scores the reader's own feed first, then drafts the next post.
Opens on the reader's real posts scored against a six-beat framework with statistical guards (announcements held out, medians, four-per-side minimum, null-not-false), then generates hooks that are regex-grounded against real deal data before a post is written.
Money figures on the two signal engines are never LLM-emitted. The model reports counts it saw; every euro or dollar figure is computed in lib/roi.ts from coefficients that each carry a source. Unevidenced headcount is capped (8 FTE on telli; 6 FTE and at most 3x observed reqs on Extend) and stays labelled 'estimated' everywhere it travels, including inside the outreach prompt. Extend's coefficient table validates itself at module load: a factor without a source, or a label containing a literal digit instead of an interpolated value, throws before any card can render.
Prompt guards became code guards after they lost in testing. On Extend, a structured scope check runs before the tool budget and is enforced in code, so an off-topic request costs one small call and returns an empty board; an email survives only if it appears verbatim in fetched evidence (the model had pattern-guessed a plausible one); source URLs are validated; the customer and competitor exclusion list is re-applied in code after the structuring pass.
Honesty over synthesized precision. telli's 0-100 lead score was removed as invented precision; ranking is array order plus a marker for leads with two or more stacked signals. Case-study metrics are pinned as fixed customer-to-metric pairs because the model cross-wired them. German output was built, then deleted, because copy that cannot be checked should not be sent. Extend's document teardown draws redaction bars instead of fake values and renders a 'representative mock, not their actual document' caption inside the PNG so it travels with the file.
No LinkedIn scraping, by design and by structure. Contacts come from Exa's public index and legally mandated German Impressum pages; company and person links are Google-scoped searches that resolve for a logged-out reader, after finding that LinkedIn search URLs 307 to a login wall.
Ops discipline on a demo. Extend's public routes sit behind a client token plus a per-IP and global sliding-window rate limit because they spend real API keys. A nightly self-run (launchd, mkdir-based lock) scans production, diffs against the previous snapshot and redeploys, but refuses to ship a dirty working tree or overwrite a good snapshot with an empty run. Karumi's fallback synthesis is gated on output structure, not emptiness, so a run that exhausts its step budget mid-research never ships interstitial narration as the answer.
Perch audits its own board. One click re-fetches every source URL, fails a card whose ATS req has closed (Greenhouse's 'no longer accepting applications' marker), catches exclusion-list leaks, recomputes each business case from the card's own inputs and diffs it, and lints absence-signals and vague PAIN labels; bot walls (403/429/999) warn rather than fail. For a QA vendor the pitch writes itself: they test agents before they ship; this tests the pipeline before it sends.
The business case is denominated in the buyer's own unit. Bluejay's buyer is the engineer who owns the agent, so the waste is engineer-hours spent hand-testing; Hobbes's is the demo-facing FTE, stated as a cost line with no revenue claim because a cost line is defensible line by line. Perch's value line is a strict fraction of its cost line, so the ratio cannot exceed 1; the Form Index has no value line at all. In both, coefficients validate at import (a label without a {value} placeholder or a sourced coefficient without a URL throws), unevidenced headcount is capped, and with nothing observed the card shows no figure at all rather than $0k.
'Exactly one number in the email' had to leave the model's hands. Drafts kept carrying both the business case and a cited customer's metric until the enrich route chose the one permitted figure in code and handed the model only that one. Same pattern for greetings: the model once greeted a name while returning an empty people array, so the route now strips salutations deterministically whenever nobody was verified — prompt rules alone had not stopped it.
The demo-gate tool turns a keyword search into a filter. Scoped to the prospect's own domain, it separates a demo-request page found (signal), public pricing or signup found (self-serve, disqualified), and thin evidence (no signal, rank lower), with docs, blog and gallery paths excluded so a 'demo apps' page cannot pass as a form. It was validated on live queries before wiring, including a correct negative, and the Form Index page practises the thesis: no contact form, only an 'Ask, don't fill a form' agent grounded in the same facts the UI renders.
Connectors without custody. Credentials stay in the viewer's browser and ride along per push; the server proxy exists only for CORS and a strict host allowlist (hooks.slack.com, Salesforce Web-to-Lead, *.atlassian.net), so it cannot be an open relay. One payload builder serves both the client preview and the server send, so an unconfigured connector shows byte-for-byte what would be transmitted. Gumloop's action bar does the same with zero OAuth: Gmail compose deep link, Salesforce Lightning new-Lead prefill, webhook Slack, copy-as-Jira.
Surface has no language model in it. Every number is computed in code from an API response, drafts are template-assembled around those values, and each fact carries provenance (endpoint, exact request body, fetchedAt) rendered as a receipt. Failures are typed: a credit-limit response is a CreditLimitError, auth/rate-limit/5xx/network failures are UpstreamError, and neither is rendered as 'no data' or stored in the 24h per-domain cache. Snapshots are {fetchedAt, data} wrappers because Vercel resets file mtimes and a naive age label once read 'fetched 68,335h ago'.
Signal never scores what the source cannot show. The public index flattens line breaks, so opener geometry returns null (never false) and a null never counts as a miss; truncated bodies return null for the closing ask. Announcements are held out because one 'I've joined' post at several times the median hit five of six beats and made every beat look magic on a mean; statistics are medians, and a per-beat engagement lift is only reported with at least four posts per side, otherwise the row stays blank and says why. Prevalence leads ('2 of 44 posts contain a journey') because the reader can check it by scrolling.
Signal's grounding guard exists because the first end-to-end run wrote '$40M robotics rounds are closing weekly' and invented clients. Dollar figures must match a real round, first against the rendered string the model saw, then within 2% numerically; the dollar sign is optional because '352M raised in one week' (two real rounds summed) slipped past a $-only regex; capitalised names outside the deal's companies and investors are listed for the reader to check rather than flagged, because every name flag seen live was a false positive and only money drives the hard flag; every percentage and first-person claim is surfaced as 'you must confirm'. Ungrounded hooks take a 22-point penalty and sort below every grounded one, and the regression test file is built from the false positives found live. Cultural hooks work the same way: every headline is fetched and dated, never recalled by the model, and a claimed headline must share distinctive words with the hook or it is dropped.
Zest's business case is cost-only and self-suppressing. The model reports only integers it observed (open roles) plus one headcount estimate; all arithmetic runs in lib/roi.ts with every assumption returned alongside the result, an estimate with no observed roles is capped at 2 FTE and may exceed observed evidence by at most 3x, there is deliberately no revenue-upside line, and when nothing is observed or estimable the card renders no dollar figure at all. Its four connectors (Gmail compose, Slack, Jira, Salesforce new-Lead deep link) keep credentials in the visitor's localStorage, and the two server proxies are regex-locked to hooks.slack.com and *.atlassian.net so they cannot be used as open relays.
Models chosen by measurement on the real prompt. Signal's angle pass was benchmarked across eight models on the real ~2.6k-token prompt; the winner ran in 3.3s at $0.0015 versus ~80–90s for the reasoning model it replaced, the cheaper sibling was rejected for returning 35 of 40 deal ids as 'evidence', and the retry tier is deliberately a different model family. Product decisions follow the same discipline: five hooks not fifteen, scores hidden so the reader trusts their ear, tapping a hook expands a brief rather than generating, and card type never drops below 34px because a 1080px card renders at about a third of its size in a phone feed.
Numbers
24 numbered guardrails (G1–G24), framed as each preventing a specific observed failure
The demo fleet these skills codify spans 10 hiring companies; all 11 deployed demos passed a send-readiness audit on 2026-08-06
Unevidenced headcount capped at 8 FTE; an estimate may exceed observed evidence by at most 3× (default estimateStretch)
Runtime model benchmarked at ~0.7s per tool-call decision vs ~4.4s and ~187 tok/s vs ~54 tok/s on this workload — roughly a 30s scan instead of 75s
Generalisation audit flagged the reference build's value chain at an 11.2× value-to-cost ratio, which became the capture-haircut guardrail (G6)
Scan budget 6–8 tool calls with an 8-step stop, max 8 leads per scan; drafted email capped at 120 words in the enrich prompt and schema
Screenshots
The reference engine the template was cut from: sample scan prompts, a free-text scan box, and the four-column pipeline board before a scan has run.