Case Studies
Engineering Case Study

Signal Monitor: Commercial Intelligence for the Events Sector

An automated monitoring pipeline that replaces hours of manual industry tracking with a structured five-minute weekly brief. Built for the UK exhibitions and events sector, it monitors over thirty companies across RSS, websites, LinkedIn, careers boards, and regulatory feeds, extracts commercially relevant signals with AI classification, and every Friday morning emails the finished brief, with a branded A4 report attached, to distribution lists the client manages himself. He runs the whole thing from a web portal: which companies are watched, who receives the report, an archive of every issue, and a dry preview of any company before it goes live.

Type Engineering Case Study
Client Momentum Works
Domain AI · Commercial Intelligence · Automation
Status Live · Weekly
30+
companies monitored
6
source types per company
5 min
weekly read time
Friday
email + PDF to client lists
Problem
A commercial director tracking thirty-odd competitors by hand and forwarding what he found to his own clients. Coverage drifted; weeks got missed.
What changed
Every Friday a pipeline reads six source types per company, a language model extracts and classifies the signals, and a branded brief lands in his clients’ inboxes as email and PDF. He manages the watchlist and the recipient lists himself.
Result
Several hours of weekly checking became minutes of pipeline time and a five-minute read. No week missed since; my involvement in a normal week is zero.
How it ran
Started as a proof of concept posting to a Discord channel, tested by the client from the first week, and grown in phases as each version showed the next gap.

The Problem

In the UK exhibitions sector, the moves that matter tend to happen quietly. A competitor picks up a niche organiser. A new commercial director arrives from a rival. A venue operator announces a show format that overlaps with yours. None of this lands in a single place, and by the time it surfaces in a general news feed, the window for responding has often passed.

Fragmented sources

Relevant signals appear across company newsrooms, industry publications such as Exhibition News, RSS feeds from trade bodies, LinkedIn posts by senior executives, and events calendars. There is no single feed or database that aggregates this at a useful level of specificity.

High noise, low signal

Even when a team subscribes to all the relevant feeds, the volume of content is significant. Most of it is irrelevant: event recaps, generic marketing copy, sponsor announcements, procedural updates. Extracting the material from the noise is itself a time-consuming task.

Manual tracking does not scale

A researcher tracking thirty companies across four or five source types per company is dealing with 120 to 150 distinct data points per week. Keeping that up, every week, without gaps, is not a realistic expectation of any individual. Coverage drifts. Sources get missed. Signals arrive late or not at all.

Time sensitivity

Signals like a new hire, a confirmed acquisition, or a market entry announcement have a short window of relevance. Intelligence that arrives late, or is buried in an unsorted inbox, has diminished value.

Aggregation alone does not solve the problem. The requirement was a system that filtered for commercial relevance, ran without manual intervention on a fixed schedule, and delivered output that needed no further processing before it could be used.

The Solution

The goal was to take humans out of the loop between source and report. That meant building ingestion, classification, and delivery as a single automated pipeline with no manual steps between them.

Automated weekly monitoring

The pipeline runs on a fixed schedule, Friday morning London time, covering all target companies in a single pass, with no manual intervention required.

Multi-source aggregation

For each company, the system pulls from multiple source types: RSS feeds, company websites, LinkedIn posts via search APIs, events-specific content, careers boards, and regulatory announcement feeds for listed entities. Industry news sources are treated as global feeds and scanned for company mentions.

AI-powered signal classification

A two-stage language model pipeline handles extraction and reporting. Stage 1 identifies and categorises signals using strict criteria. Stage 2 synthesises the output into a structured weekly brief.

Branded delivery

The finished brief goes out by email to recipient lists the client manages, one send per list with recipients in bcc, so no client ever sees another's address. A Soltech-styled A4 report rides along as an attachment, every issue is archived in the web app, and operational summaries and source-health alerts still post to Discord.

Self-serve administration

The system started as a report the client read; it is now a product he operates. From the portal he adds or pauses watched companies, previews what a new company would yield before the next run, manages which of his clients receive the weekly email, and browses the full archive. No config files, no asking me.

Architecture

The system is structured as a sequential pipeline with clearly separated concerns: fetch, classify, deduplicate, report.

Watchlist
30+ Target Companies
Organisers · Venue operators · Media brands · Industry associations · Held in SQLite and edited from the portal; new companies added without code changes
Source Types
6 Fetcher Types
RSS (feedparser) · Websites (Trafilatura + BeautifulSoup fallback) · LinkedIn (Serper, Brave and SerpAPI search chain) · Events feeds · Careers boards (adapters for eight ATS platforms) · Regulatory RNS feeds · Plus industry news global sources
  1. Checksum Filtering
    Content is checksummed on ingestion; unchanged content is skipped, avoiding redundant processing and unnecessary token usage
  2. Stage 1: Signal Extraction
    Structured prompt extracts signals with category, confidence, summary, commercial significance, evidence, and named entities · Low-confidence signals discarded early · A 14-day freshness gate is applied in code, not by the model
  3. Entity-Level Deduplication
    Signals matched on company, category, primary entity, and time bucket; multi-source announcements collapse to a single signal · 12-week rolling persistence
  4. Stage 2: Report Generation
    Structured signals transformed into a formatted, category-based weekly brief · Synthesis and formatting only, not classification
  5. Output Layer
    Email delivery per recipient list via Resend · Issue archive in the web app · PDF generation via ReportLab · Operational logging and source health alerts to Discord
Email: weekly report to client lists
Web: issue archive + admin portal
PDF: formatted archive
Discord: operational summaries + source health

Signal categories

Stage 1 classifies against predefined categories to ensure consistency across runs: executive appointments, mergers and acquisitions, product launches, and expansion activity. Signals that do not meet confidence thresholds are discarded before persistence.

Scheduling and operation

The pipeline runs every Friday at 08:30 London time under its own launchd agent on the production host. The watchlist lives in SQLite alongside the portal's own state (lists, issues, deliveries, a change log); the pipeline's working memory (seen signals, source checksums, failure counts) stays in JSON files it owns. Both sides read the same watchlist, so a company added in the portal on Tuesday is fetched on Friday with nothing redeployed. A dry-run mode and a 205-test suite cover the pipeline and the web app.

AI Integration

Language models are used selectively, only where deterministic approaches break down. The signals targeted do not follow predictable linguistic patterns and require contextual judgement; a rules-based classifier would be brittle and expensive to maintain.

Stage 1: Signal extraction

The extraction layer is designed for high selectivity. The prompt enforces strict criteria: signals must be recent, commercially relevant, and actionable. Low-confidence outputs are discarded before persistence. Global industry news sources are processed with company attribution logic, allowing a single feed to contribute signals across multiple monitored organisations.

Stage 2: Report generation

Stage 2 operates on structured data, not raw content. It performs formatting and synthesis only, presenting signals coherently within the weekly brief format, not making classification decisions. This separation keeps each stage’s responsibility narrow and its output predictable.

What the model is not asked to do

Anything a rule can decide, a rule decides. The 14-day freshness gate runs in code after extraction. Careers boards are filtered for seniority before a posting ever reaches the prompt, so a junior vacancy costs no tokens. Deduplication is a fingerprint, not a judgement call. The model's job is narrowed to the one thing it is good at: reading a press release and saying what, if anything, just happened.

Stage 1 runs on Groq's Llama 3.3 70B with a four-deep fallback chain (Gemini Flash, Mistral, two OpenRouter routes) that also fires when a provider returns malformed JSON, not only when it errors. Stage 2 runs on Claude Sonnet, deliberately on a paid pool, because Stage 1 has usually drained the free tiers by the time the report is written.

The Portal

For its first five months Signal Monitor was a script that posted to Discord and a YAML file only I could edit. Adding a company meant a message to me. That is fine for a proof of concept and wrong for something a commercial director wants to put in front of his own clients. The portal is what turned it from my tool into his.

Signal Monitor portal front page: Soltech wordmark and a rail of dated issues on the left; on the right the headline Everything they announced this week, a live countdown to the next Friday issue, a Read the latest issue button, and four columns headed Collect, Extract, Refuse, Publish
The front page. A rail of dated issues, a countdown to the next run, and the four gates a signal has to pass. The 14 days and 12 weeks are read from live config, so the copy moves if the rules do.

It is deliberately boring engineering: FastAPI serving server-rendered Jinja templates with HTMX for the interactive bits. No JavaScript build step, no Node on the production host. It runs on the same machine as the pipeline, binds to localhost only, and reaches the internet through a Cloudflare Tunnel with Cloudflare Access as the identity gate. Access blocks unauthenticated requests at the edge; the app verifies the signed assertion again at the origin and refuses to start at all if the Access configuration is missing, so a misconfigured tunnel is a closed door rather than an open one. It is styled in the same design system as this website, light theme only, no icon library, mono uppercase labels doing the wayfinding.

Signal Monitor Companies page: a table of watched companies with source chips such as Website, Careers, LinkedIn and Events, last signal date, signal count, a Watched status dot, and Edit and Pause actions. In the left rail a teal box reads Takes effect Friday 08:30, Paused Clarion Events
The watchlist. Every edit is logged with who made it and shows in the rail as a pending change with the date it takes effect. A dry preview on any company fetches its sources and runs Stage 1 exactly as Friday would, and commits nothing.

Companies carry their sources as chips and can be paused without being deleted. Recipient lists are either internal or client; client lists receive the same brief with no link back to the tool, so what lands in a client inbox is a finished report, not an invitation to log in somewhere. Any list can be sent the latest issue on demand. Each archived issue shows its signals grouped by category with jump links, the events diary, a download button for the PDF, and a receipt for every list it was delivered to. A Health page shows the last twelve runs and any source that has failed three weeks running.

Signal Monitor issue page for the week ending 14 August 2026: 23 signals across 9 companies, a Download report button, a jump-link bar reading Hiring 5, Product 3, M&A 4, Expansion 4, Industry 7, Events 4, and the first Hiring signals with company, headline, why it matters, evidence quote, confidence and source link
An archived issue. Category counts double as jump links; every signal carries its evidence quote, confidence, source type and a link to where it was found.

The Report

The thing Giles's clients actually see is the PDF, and until August it was a default ReportLab document that looked like a script wrote it. It was rebuilt in the Soltech design system: DM Sans and DM Mono embedded, the wordmark drawn from its SVG paths rather than typed, one teal accent on the numbering spine, and the confidence level carried in ink weight instead of colour. Page one is the whole week at a glance, one ruled line per signal in confidence order, so a reader can decide in thirty seconds whether page two is worth their time.

Page one of the Signal Monitor A4 report for the week ending 14 August 2026: Soltech wordmark, Weekly Intelligence label, prepared date, 24 companies watched, 23 signals across 18 companies, and a table headed The Week at a Glance listing numbered signals with category, company, one-line summary and confidence
Page one of a real issue. The same PDF is attached to every list email, downloadable from the portal behind Access, and still posted to Discord.

The email that carries it is a 640px table with every style inline, because that is what survives Outlook. The wordmark travels as an inline attachment rather than an SVG or data URI, for the same reason. Above eighteen signals only the high-confidence ones get inline detail and the rest defer to the PDF, which keeps the message under Gmail's clipping limit. The subject line carries the count, so a week with nothing to report says so before it is opened.

The Journey

The current architecture did not arrive fully formed. Each phase fixed a failure mode in what came before.

  1. Phase 1
    Manual monitoring
    Manual review of company websites and trade publications. Output depended on who had time that week, which meant inconsistent cadence and gaps in coverage.
  2. Phase 2
    Feed aggregation
    RSS feeds and newsletters cut the navigation overhead. But the volume of content grew faster than the ability to filter it: more to read, not more to act on.
  3. Phase 3
    Web scraping
    Scraping extended coverage beyond what feeds provided. Page structure varies, access constraints are real, and getting stable extraction working took iteration. Ingestion eventually settled.
  4. Phase 4
    AI classification
    AI classification moved the bottleneck. Human review became the exception, only needed when the model flagged low-confidence signals or a source went dark. Coverage across all thirty companies became consistent for the first time.
  5. Phase 5
    Accuracy and efficiency refinements
    Entity-level deduplication collapsed multi-source announcements into single signals. Checksum-based filtering meant unchanged content skipped processing entirely, cutting token usage and run time.
  6. Phase 6
    From report to product
    Delivery moved from a Discord channel to email with a redesigned PDF, and administration moved from YAML files on the host to a web portal behind Cloudflare Access. The client now controls coverage and distribution himself; the maintainer's involvement in a normal week is zero.

Challenges and Trade-offs

Challenge Approach
Signal precision versus coverage. Aggressive extraction increases recall but reduces reliability. System prioritises high-confidence signals, accepting that some lower-confidence content is excluded. Precision over recall.
Source reliability. Feeds and websites change unpredictably, creating silent coverage gaps. Failure tracking surfaces gaps early: a summary posts to a dedicated Discord channel after each run, and the portal's Health page lists any source that has failed three weeks running.
LinkedIn constraints. Direct API access is heavily restricted. Indirect retrieval through a chain of search providers (Serper, Brave, SerpAPI) with a scrape fallback, accepting a dependency on third-party indexing latency.
LLM cost versus quality. Higher-capability models improve extraction but increase operating cost. Multi-provider fallback chain balances cost and output quality, with providers selected based on performance and reliability per task type.
Batch scheduling. Weekly cadence limits recovery from a failed run to the next scheduled execution. Weekly execution simplifies operation and monitoring. The trade-off is accepted: the value window for most signals spans days, not hours.

Impact

Signal Monitor runs in production for Momentum Works. Each Friday morning, the pipeline processes over thirty companies across six source types and emails a structured intelligence brief to the client's distribution lists with no human involved between source pull and delivery.

What previously took several hours of manual checking takes the pipeline minutes. The brief itself takes under five minutes to read. Teams doing this work by hand were not keeping up with thirty companies at any consistent frequency; now coverage runs every week without gaps.

The rolling deduplication store means the same announcement does not appear twice across consecutive weeks. Archived reports are available for audit. When a source fails, it surfaces in a dedicated Discord channel the same morning, not discovered retroactively when someone notices a company went quiet.

The shift that matters most is who operates it: intelligence that used to be forwarded by hand out of Discord now lands directly in his clients' inboxes, from lists he controls.

Christophe built a signals monitoring tool for Momentum Works that helped change how my client prioritised key accounts. We needed a way to track public domain signals across a set group of companies without spending any time on manual research. After carefully listening to how I and my client actually work he built something specific rather than something generic and had a working version in front of me quickly enough to test properly. He also built it in such a way that he was able to add features and customisation into the solution. If you need someone who understands the commercial problem before writing any code Christophe is definitely worth talking to.

Giles Brown · Commercial Director, Momentum Works

Future Enhancements

  • Event-to-CRM integration Extending the events capture pipeline to push structured event data into a CRM via API, enabling agencies to automatically track upcoming shows, align outreach with event timelines, and embed market activity directly into commercial workflows.
  • Historical trend analysis. Extending the signal store to support time-series insights across companies and categories.
  • Entity resolution. Normalising entity references across signals to improve cross-source aggregation accuracy.
  • Alert prioritisation. Introducing urgency tiers to surface high-impact signals (such as M&A activity) above the standard weekly cadence.
  • Feedback loops. Capturing user feedback to refine extraction quality and signal taxonomy over time.
  • Additional sources. Expanding ingestion to include podcasts, press syndication feeds, and investor relations content.

Tech Stack

Signal Monitor: Intelligence Pipeline
Python feedparser Trafilatura BeautifulSoup Serper / Brave / SerpAPI Groq, Gemini, Mistral, OpenRouter, Anthropic ReportLab Discord webhooks launchd pytest
Admin Portal & Delivery
FastAPI Jinja2 HTMX uvicorn SQLite Cloudflare Tunnel Cloudflare Access Resend
Case Studies

Need a system like this?

The underlying approach, pulling from fragmented sources, classifying for commercial relevance, and delivering on a fixed schedule, applies well beyond the events sector. Any market with enough public signal and not enough time to watch it is a candidate.

If you are tracking competitors manually, or have a market you cannot follow closely enough, get in touch.