Every release, every meaningful change. Updated when something ships, not when marketing remembers to mention it.
v4.5
Read feeds on your own machine, check a feed before you add it, and let the brain read replies
addedClient-side reading. Feeds can be read by your own OpenClaw plugin or daemon instead of by us: they fetch the posts on your machine and send them to the brain, which scores them exactly as if its own scout had read them.
addedFeed preview. Before you add a station, the brain reads the feed, its judges read the best-matching posts, and it answers with a verdict fixed in advance: viable, marginal, on topic but not in market, no buyers, or no data. Nothing is saved. Available as an API call, an MCP tool, a plugin tool and a daemon command.
addedReplies the brain can read. Hand it what a prospect wrote back and it reads the intent and any objection, updates their stage, and stops drafting for anyone who asked not to be contacted. It also says whether the reply invited a private message, the consent Reddit and X require before an app sends one. The capability existed, but no tool could reach it.
addedScoring takes context. Send the post or thread a reply answers and the judges read the reply in that light, while still scoring its own author: a short “same problem here” under a buyer’s post reads as a buyer, and a vendor pitching under the same post does not. Every result now also says what the judges concluded.
addedSet-up and upkeep without help: edit or pause a product, pause, re-point or remove a station, and see each station’s health, from your agent. The plugin also gains anchor suggestions and a way to record replies you sent by hand.
addedQuiet hours per account, set in the console. They are off by default, so new posts are read around the clock; before this, every account shared one overnight pause set in UTC, which fell in the US evening.
changedPublic Reddit comments join X replies and DMs: none is ever sent without a person approving it, whatever the account settings. Reddit and X require a person behind each one. The console’s auto-send setting is gone for that reason.
changedThe daily limit on panel reviews now follows your plan, so a Growth account can use the volume it pays for in bursts.
fixedOne very long post in a feed could make the scout skip every post in that feed, on every cycle, until it aged out. Now only that post is shortened, and the rest are scored.
fixedStation feed addresses are checked: http or https, on a public host, when a station is added and on every fetch.
fixedBuying keywords match whole words, so a short keyword no longer fires inside unrelated words.
fixedThree background features that had never worked because they read data that did not exist: best-time-to-send statistics, anchor refresh from approved leads, and public usage stats.
v4.4
The demo goes public, and the scoring API stops over-sharing
addedThe live demo at /demo is now indexed and arrives with a worked example already on it — a real post, the three judges with their reasoning, and the verdict. Previously it opened as an empty box, which meant you had to commit before you could see anything work. The seeded example is captured from the production endpoint, not written by hand.
changedThe scoring API no longer returns internal per-judge numerics. It returns each judge’s stance and whether the panel split, which is what is actually useful when you are deciding whether to trust a verdict. The raw numbers were undocumented, were never part of the contract, and could be used to reconstruct how the panel is weighted.
fixedA safety rail on the scout so an overlapping batch can no longer start while the previous one is still running. This was a latent risk rather than an observed failure, but a double-running scout wastes fetch budget against rate-limited feeds.
v4.3
Precision: four scoring defects found by measurement, not by reading
fixedPhrase matching now respects word boundaries. It had been matching on bare substrings, so a phrase like ‘api’ registered inside ‘therapist’. Across a 400-lead audit a substantial share of leads carried at least one phantom match, silently inflating their score.
fixedDuplicate entries in the phrase lists were counted more than once, so a single occurrence of a common word like ‘budget’ could score as though it had appeared three times.
changedRemoved 41 phrases that only made sense for B2B software sales. They were quietly penalising every tenant selling something else, which is the opposite of what a general-purpose scoring engine should do. Matching now leans on your own anchor sentences instead of on our assumptions about your category.
fixedCompetitor detection was matching on a four-character prefix, so a competitor named ‘instantly’ matched ‘instead’ and ‘install’. Of the leads flagged as competitor mentions in the audit, most were junk. The prefix rule is deleted rather than tuned.
changedThe panel no longer discards a buyer for being a builder. A rule intended to filter out competitors was catching people who build software and also want to buy some — which is most of the developer-tools market. Someone describing a real problem is judged on that, not on what they happen to work on.
fixedA judge that failed to run no longer counts as a vote. Previously an outage in one provider path could quietly shift a verdict.
changedA post’s popularity no longer influences which voice the reply is written in. Upvotes measure reach, not intent, and the two are often anti-correlated — the most-upvoted post in a business community is usually a success story, and a success story is not a buyer.
v4.2
Multi-tenant MCP, self-serve setup, and telemetry for what the gate drops
addedThe MCP endpoint authenticates and executes as the calling tenant, so any MCP client — Claude.ai, Claude Code, Cursor, Windsurf — works with your own operator key and sees only your data.
addedSelf-serve product setup that survives first contact: your agent walks you through what you sell, who buys it, and what those buyers sound like when they are looking.
addedTelemetry on near-miss leads, so we can measure what the qualifying threshold is discarding instead of guessing at it. Several of the v4.3 fixes exist because this data made them visible.
fixedClosed a billing hole where certain Stripe subscription states were not mapped, allowing a lapsed trial to keep working.
fixedStation fetches are paced, and a feed that returns nothing now says so rather than failing silently. A rate-limited feed and a dead feed used to look identical.
v4.1
Universal scoring, a public demo endpoint, and security hardening
addedBorderline text gets a second look from the full panel rather than being dropped on the content score alone. This matters most for score_signal, where there is no feed history to lean on.
addedFinnish joins the multilingual urgency scoring, alongside English, Spanish, French, German and Portuguese.
addedA public, verdict-only demo endpoint — rate-limited and capped, and it returns no internal numerics. This is what powers /demo.
fixedHardened the OAuth authorize flow and how client IPs are resolved for rate limiting.
fixedCron authentication uses a stable secret on internal routes, so rotating an operator key can no longer silently kill the scout.
v4.0
Multi-tenant, self-serve, and the sender moves to your side
addedFull tenant scoping across every handler. Leads, prospects and products are isolated per account.
addedStripe subscriptions with automatic operator-key issuance.
addedA streaming mission feed, so the daemon receives approved work as it is approved rather than polling.
addedsignalpipe-daemon 1.0.0 — an open-source, user-side sender that posts approved messages from your own Reddit or X accounts. The judgement runs on us; the sending runs on you, and we never hold your platform credentials.
changedReddit first contact routes to a public comment on the post. The cold-DM path is gone — a DM is something you earn, not an opening move.
changedScoring and drafting moved inline into the hunt, cutting a hop out of every lead.
v3.7.21
Vertical relevance gate
addedLeads from the wrong domain are dropped before the panel runs, which cuts cost and stops obviously-irrelevant posts reaching your queue.
fixedNeutral competitor mentions no longer force a lead to a fixed score, which had been both promoting noise and capping genuine competitor-switch posts.
fixedEnded a mission drought caused by an over-aggressive suppression rule that was discarding legitimate signals along with weak ones.
v3.7.14
Cross-poster dedup at lead-insert + judgement variance pinned
addedCross-poster dedup runs at lead-insert. When the same author posts a normalized-title-equivalent piece across multiple stations within 72h, the duplicate candidate is dropped before the swarm fires. Kills 3× LLM waste, 3× operator review burden, and 3× RL penalty distribution per cross-post. Emits a cross_post_dropped event referencing the original lead so audits of "where did that mission go?" land at the right answer. The window is configurable.
fixedSwarm classifier temperature now set to 0.2 across all three provider paths (Anthropic / OpenAI / Gemini). Pre-fix none of them pinned it, so all three ran on provider defaults and injected avoidable variance into every judgement. Draft generation is unaffected and still samples freely, so outreach copy keeps sounding human.
v3.7.13
Scout cron extracted from the schema file + cadence corrected to 10 minutes
changedThe pg_cron heartbeat that calls /scout/launch_batch lives in Supabase, not Railway. v3.7.13 extracted the cron.schedule() block out of supabase_schema.sql (which had been shipping with YOUR-RAILWAY-URL / YOUR-OPERATOR-KEY placeholders — a footgun on fresh-DB setups) into a separate _cron_setup.sql deployment artifact. Schema file now declares only the pg_cron / pg_net extensions; the actual schedule with real values is a one-time-per-environment ops step.
fixedCadence corrected from `0 */2 * * *` (every 2h — an operator testing artifact) to `*/10 * * * *` (every 10 min — design cadence). 12× more cron fires per day. The 2h gap had been producing many feed-dry cycles where buying signals expired before the next scout, masquerading as a calibration regression.
fixed_cron_setup.sql uses `select cron.unschedule(jobid) from cron.job where jobname = X` instead of `delete from cron.job where jobname = X` — the latter fails on Supabase with ERROR 42501 (the cron schema is privileged; cron.unschedule() is SECURITY DEFINER so it bypasses table-level RBAC). Idempotent for both first installs and rotations.
fixedMissions surfaced over MCP were reading a score field that never existed, so every mission looked identically calibrated in your agent. They now carry their real score, including a legitimate zero.
changedThe check that screens out on-topic-but-wrong-intent posts was broadened. It now recognises several distinct ways a post can look relevant while being useless to you: someone asking how to BUILD the thing you sell, someone asking for generic startup advice with no real operation behind it, and a competing tool’s author framing a pitch as a question. Previously these were clearing the bar.
changedThe check that filters out people selling rather than buying was broadened to cover more of the ways a seller shows up in a feed. It distinguishes wanting to buy from wanting to build, while preserving genuine buyer frustration, which reads superficially similar and must still score.
addedWeaker leads no longer get a cold direct message without you looking first — they are downgraded to manual review. Public replies are unaffected, and genuinely warm leads flow normally.
addedStartup notice when an active product has no buy-signal keywords set, so the behaviour is deliberate rather than accidental. (Superseded: empty is now the recommended default — a guessed keyword list silently drops buyers who worded it differently.)
v3.7.11
Sidecar ack now writes prospects.last_signal + schema file resynced to prod
fixedThe /actions/ack=success path now writes prospects.last_signal = "message_sent" + last_contact_at = now() (mirrors the companion_track / record_reply pattern). Closes the last leg of the v3.7.10 audit-trail repair: outbound interactions, prospect lifecycle, and dashboard signal all stay in sync regardless of which write path produced the send.
changedsupabase_schema.sql fully rewritten against information_schema. Was frozen at v3.5, missing ~15 columns and 4 tables (events, send_windows, public_stats, product_anchor_history). The schema file is now a reliable grep target for future migration authors — the upstream cause of the v3.7.10 backfill scope bug was that nobody could trust the file.
v3.7.10
Sidecar /actions/ack audit-trail gap closed (plus a same-day backfill correction)
fixedWhen the sidecar ack'd a mission as sent, no interaction row was written. Dashboard, analytics, and the RL loop all read interactions as the canonical send record, so a successful send produced zero downstream signal. Added _record_outbound_message() called from the success branch of /actions/ack.
fixedSame-day backfill correction shipped as v3.7.10_backfill_correction.sql (commit f892d72). The original backfill swept missions.status="sent" but ignored missions.outreach_channel, producing 3 false positives where channel="manual" missions (operator-completed via the native platform UI) were back-filled as automated sends. Correction drops those 3; future backfills must filter on outreach_channel.
fixedcompanion_track() and record_reply() were both reading prospect["last_signal"] via .get() — but the column did not exist on the prospects table. Both .get() calls silently returned None, breaking the mode-transition rule that depends on the latest named signal. v3.7.9 adds the column, patches both write sites (companion_track, record_reply) to populate it, and aligns the read sites accordingly. The fix arrived together with v3.7.10 because the two bugs were structurally siblings — both manifestations of "schema drifted; reads assumed a column that wasn't there".
v3.7.8
Mode transitions are now intent-based — first-touch prospects stay in Nurture
fixedBrand-new contacts who had received exactly one message — first touch, no reply yet — were being treated as if they had gone cold, so day-2 follow-ups opened with "I know it's been a while…" to someone who had never engaged at all. Fresh prospects now stay in the first-touch state and get a value-first voice until they actually engage or actually go quiet. Re-engagement language is reserved for people who genuinely did both.
changedPublic temperature-model docs updated across the guide, README, llms-full.txt, OpenAPI surface, and MCP get_pipeline tool description. The model is now described as intent + temperature, not pure temperature. Nurture mode is documented as the default first-touch state for the first time.
addedv3.7.8_migration.sql resets prospects currently stuck in Recovery without any engagement or cooling signal history — these were misclassified by the old rule and the fix moves them back to Nurture so the next outreach picks the correct persona.
v3.7.7
Per-station reinforcement learning — feed-level demotion replaces global product weight
changedWhat the system learns from your approvals and rejections is now tracked per listening feed rather than for the product as a whole. One noisy subreddit gets demoted on its own instead of dragging every other source down with it — which is exactly what had been happening, quietly suppressing good leads from good feeds.
changedRejections are now attributed to the feed the lead actually came from, so the learning lands on the right source. Older leads predating this change are recorded but do not move any weights, since their origin cannot be resolved reliably after the fact.
fixedEvery path that records feedback — the scout loop, the reject action, and the fallback recorder — now writes to the same place. Covered by new unit tests.
v3.7.6
Confidence bar raised + low-confidence missions cleaned up automatically
changedRaised the confidence a lead must reach before it is allowed to interrupt you. Below the new bar, no placeholder draft is uploaded at all — the mission is cleaned up silently instead of sitting in your queue. Paired with the previous release's station deactivation: raise the bar AND stop polling the worst feeds.
changedDeactivated 5 additional noise stations identified in the 2026-05-17 queue audit (r/VintageStory, r/EmailMarketingIndia, r/ObsidianMD, r/VirtualAssistant, u_Independent-Tap-323) — communities with zero buyer signal for SignalPipe.
v3.7.5
Noise station purge + idempotent approve RL
changedDeactivated 7 noise stations that produced almost all the queue noise (r/jobhuntify, r/WhiteLabelSEOAgencies, r/AISEOInsider, r/RampPlatform, r/openclaw, plus two single-user brand-promo feeds). Soft-deleted via active=false so per-station history stays queryable and re-enabling is one UPDATE away.
fixed/actions/approve is now idempotent — replaying an approval no longer double-applies the RL weight bump. Critical for sidecar retries.
v3.7.4
Universal score_signal + value_prop covers all channels
addedsignalpipe_score_signal — universal text classifier callable from any MCP client. Scores arbitrary text from any channel the host agent reads (Gmail, Slack, Discord, Telegram, LinkedIn, TikTok, Instagram, support tickets, transcripts) against any configured product profile. Same engine the scout uses on Reddit/HN posts; SignalPipe never touches the source platform — the user's agent does.
changedSignalPipe product row's value_prop and target_audience rewritten so the judges know the system also covers TikTok, Instagram, Slack, Gmail, etc. via score_signal. Fixes the case where the educator persona recommended competitor monitoring tools to a TikTok/Instagram question because its own product description only mentioned Reddit/HN.
changedEducator persona prompts hardened with no-competitor-recommendation directive (_NO_COMPETITOR_REC).
fixedMCP /mcp endpoint returned 421 "Invalid Host header" on every authenticated request — caused by the MCP Python SDK's DNS rebinding protection rejecting any Host other than localhost. Fixed by configuring TransportSecuritySettings with the public + Railway hostnames whitelisted.
fixedBehind Railway's TLS-terminating edge, FastAPI emitted 307 redirects with Location: http:// (HTTPS→HTTP downgrade), causing MCP clients to strip the Authorization header and fall back to OAuth. Added uvicorn --proxy-headers --forwarded-allow-ips=* so X-Forwarded-Proto is honored.
fixed/oauth/token rejected base64url codes with stripped padding (the standard OAuth client encoding). Re-pad before decoding so both padded and unpadded codes work.
fixedreject_mission silently broken — the rejection_reason column was referenced in code but never added to the missions table, so every reject returned PostgREST PGRST204. RL learning quality degrades without per-reason penalties; v3.7.3 migration adds the column + NOTIFY pgrst.
changedMCP response contract: get_missions defaults include_context=False (verbose context is opt-in via draft_mission), all read-tool projections cap user-content strings server-side (snippet 220, draft 500, value_prop 200, last_signal 80).
changedMCP tool docstrings rewritten as presentation guidance for the host LLM — explicit when-to-use vs companion tools (e.g. reject vs delete), full reason taxonomy with penalty intent, no-shell-introspection directives.
v3.7.2
Swarm low-confidence flag for the operator queue
addedMissions the judges were not confident about are now flagged as such, so the console can tuck them behind an expander rather than either hiding them entirely or letting them clutter the main queue.
addedThat flag is exposed over MCP too, so your agent can filter the low-confidence tier out of what it shows you.
v3.7.1
Educator skeptic softened, regression test repaired
changedEducator-tier skeptic now only vetoes leads that are entirely off-topic — was previously vetoing borderline-tier signals that the analyst should have been allowed to judge.
fixedRegression tests for the drafting layer updated to track the new cues.
Client-side drafting + remote MCP server + operator console
addedRemote MCP server at api.signalpipe.io/mcp exposing 15 tools (missions: 6 · pipeline: 4 · products: 4 · scout: 1) for Claude Code, Cursor, and Windsurf.
addedDrafts are now calibrated to how strong the signal actually is, rather than using one voice for everything — an open request and a passing question no longer get the same reply.
addedDrafts are written to fit the channel they will go out on, so a public reply and a direct message are no longer the same length.
added/dashboard operator console — bring-your-own-key approval UI with draft length against budget.
changedCalibration is now driven by what the post itself says rather than by the final score, so a misread competitor mention can no longer promote a weak post to the most direct voice.
changedCron cadence reconciled to 2 hours across schema and README. Feed-fetch limit raised to 50 entries per station.
fixedCompetitor floor was hijacking misclassified leads — now scoped to genuine signal.
fixedReddit RSS user-agent now identifies as a polite bot to avoid 429 blocks.
v3.6
Correctness, hardening, lethality
changedTightened scoring edge cases — leads missing a dimension entirely no longer destabilise the score.
changedCORS scoped to signalpipe.io / www.signalpipe.io for dashboard requests.
fixedSidecar idle poll now logs an explicit "queue empty" message so Railway logs reflect liveness when missions are absent.
v3.5
Batch embeddings + multi-factor signal
addedFreshness, engagement, and author-reputation multipliers in the signal score.
addedReply capture — outcomes feed back into the RL loop.
addedSwarm disagreement metric exposed on missions.
changedEmbedding calls batched per scout cycle — significant cost reduction on busy stations.
v3.0
Multi-factor scoring + adaptive RL
addedMulti-dimensional scoring replaces the single-component score.
addedScoring now tunes itself from your approve / reject feedback.
addedProspect temperature momentum and time decay for the nurture engine.
v2.0
Mission control + interactions ledger
addedMissions table — every scored lead becomes a reviewable mission with draft, status, and outcome.
addedAnti-spam ledger — interactions table prevents the same URL being processed twice per product.
addedAuto-approve threshold (configurable, off by default).
For the technical surfaces these versions changed, see the API reference or the glossary.