← Work

Work / App Production

AVGO Thesis Monitor: scoring the evidence before earnings

AVGO Thesis Monitor is a personal decision-support web app for one stock thesis. It keeps an evidence ledger, scores what is eligible before the next earnings date, and lets Claude propose new evidence from daily news for me to approve. It never trades and its score is illustrative, not advice.

Demonstration data. Invented data; the AI scan uses live news headlines.

AVGO Thesis Monitor is a personal web app for tracking one investment thesis ahead of an earnings date. I log each piece of evidence once, say whether it supports the bull, base or bear case and how much it matters, and the app scores only what is still eligible. It never places a trade. Its own banner says the score is illustrative and the data is entered by hand.

The dashboard after a scorecard run: total score, classification, action status, scenario probabilities, category scores, evidence counts and report history
Figure 1. The dashboard after one scorecard run, with invented evidence, price and allocations. The action status is the app’s rule output for these inputs.

At a glance

  • Status: production. It runs every day and reports to me.
  • Built: 29 June to 3 August 2026, 18 commits including documentation updates in October.
  • Platform: a web app on Cloudflare Pages with a Supabase back end.
  • Stack: Vite and TypeScript with no UI framework, Supabase (Postgres, row level security, authentication, Edge Functions), Vitest.
  • Built with: Claude Code.
  • AI inside the product: yes, in one place. Claude Haiku 4.5 reads daily news and proposes evidence. It never writes to the ledger.

One scorecard run

Video 1. From the empty dashboard through the evidence ledger, market snapshot and position planner to one scorecard run and its result, all on invented data.
Text version of the video
  1. The dashboard shows eight evidence items and no scorecard yet.
  2. The Evidence Ledger lists each item with direction, materiality, source tier and a freshness label relative to the last earnings date.
  3. The Market tab and the Position tab show the invented price snapshot and allocation targets, given as percentages.
  4. On the Reports tab, "Run Scorecard Now" scores six eligible items. The report shows a total of +0.70, the classification Base-to-bull, the action status Add candidate and scenario probabilities of 39%, 50% and 11%.
  5. Back on the dashboard the same result is the current read.

A thesis is a set of claims that new information either supports or weakens. The tool keeps the evidence in one place, scores each item once under rules written down in advance, and frames its output as a prompt for my own judgement, not an instruction.

The evidence ledger and the scoring rules

The core is the Evidence Ledger. Each item carries a date, a source tier from official filings down to blogs, a direction (bull, neutral or bear), a materiality and the thesis indicators it bears on.

The Evidence Ledger listing eight invented items with direction, materiality, source tier and freshness relative to the last earnings date
Figure 2. The ledger with invented items. The freshness column says whether an item came before, on or after the last earnings date, which decides whether it can be scored.

Five plain rules decide whether an item is eligible: it must be dated at or after the last earnings date (or be flagged as reinterpreting earlier news), it must not predate the previous report, it must not already have been scored, its materiality must be medium or high, and its source tier must be 1 to 3. Each eligible item becomes a score from minus two to plus two from its direction and materiality, the scores are averaged within six weighted categories, and the weighted total falls into one of five bands from Bull to Bear.

A scorecard report: total score, classification, action status, category breakdown, six items used and two excluded with the stated reason
Figure 3. A scorecard report on invented evidence. Two items were left out, and the report says why: one had too low a materiality, one came from a source tier that is too low. Nothing is dropped silently.

The Position planner holds allocation, target and maximum as percentages, plus planned buy and trim tranches, and shows a concentration warning. An action status comes from combining the score band with whether the price looks extended and whether the position sits below target.

The Position Planner with current, target and maximum allocation and planned tranches, all as invented percentages
Figure 4. The position planner with invented percentages. The tool works in percentages and can also hold shares and cost.

Letting Claude help without letting it decide

News arrives daily and I will not read all of it carefully. A language model can read it. The design question was how to use that without a confident model quietly filling my ledger with judgements I never made.

Build decision. Claude only proposes. The scanner function writes rows to a separate proposals table with the status “pending”. A row reaches the ledger, and therefore the score, only when I press Approve.

The scanner uses real news from a market-data feed. For each article it sends Claude the headline, source, date and summary, the list of my 16 thesis indicators, and the last earnings date. It does not send my position or any of my evidence. Claude returns a direction, a materiality, a source tier, a one-line summary, its reasoning and the single indicator the article most affects.

Build decision. The date arithmetic stays out of the prompt. The function compares the article date with the last earnings date in code and tells the model the answer, with a rule that news published before earnings is presumed already priced in and capped at low materiality unless it reinterprets the results. The comparison should not depend on a model getting date arithmetic right for every article.

Build decision. News feeds are scoped to one symbol, so a story about a cloud provider’s spending plans never appears under Broadcom’s feed, even though that spending is one of my thesis categories. The scanner therefore also pulls the feeds for four large cloud companies and judges those articles on thesis impact, not on whether Broadcom is named.

The scanner at work

The scanner classifies live news with Claude Haiku 4.5. The ledger around it is invented demonstration data.

Video 2. Pressing “Scan for evidence” in Settings, waiting about 50 seconds while Claude Haiku 4.5 classifies live news, then opening the nine pending proposals that result.
Text version of the video
  1. The Proposals screen is empty.
  2. In Settings, "Scan for evidence" is pressed and the page shows "Running".
  3. After about 50 seconds the result line reads: 9 proposed, 6 not relevant, 15 of 912 articles processed, 16 indicators loaded.
  4. The Proposals screen lists nine pending items, each with a direction, materiality, source tier, confidence, a summary, a collapsible "Claude's reasoning", a suggested indicator and Approve and Reject buttons. Scrolling shows more.
The Proposals screen showing two pending items from real news, each with direction, materiality, tier, confidence, summary, suggested indicator and Approve and Reject buttons
Figure 5. Live headlines classified by Claude Haiku 4.5, each with its direction, materiality, tier and reasoning, waiting for my decision. Headlines belong to their publishers.
The scan result line: 9 proposed, 6 not relevant, 0 dedup skipped, 15 of 912 articles processed, 16 indicators loaded
Figure 6. The result of that run. The scanner fetched 912 articles from five feeds over a seven-day window and processed the 15 most recent, because each run is capped at 15 to stay inside the function’s time limit. Older articles are picked up on later runs.

Under the hood

I built AVGO Thesis Monitor with Claude Code, starting from a product-context document that set out the product, the data model and the scoring rules, and working in phases: schema and evidence ledger, then the scoring engine, scorecard reports, market and analyst screens, and finally the earnings watch, settings, proposals screen and the daily pipeline. The project’s rules file tells the assistant to treat the data as more sensitive than the code, to use synthetic values in tests, and never to touch the live environment without asking.

LayerWhat I used
InterfaceVite and TypeScript, no UI framework
LogicScoring, eligibility, probability and action rules as small pure functions with no knowledge of where the data comes from
BackendSupabase Edge Functions for market data, news and the scanner, two of them running daily on a database schedule
DataSupabase Postgres, with row level security isolating each signed-in user’s rows
Runtime AIClaude Haiku 4.5, in the scanner only
HostingCloudflare Pages
TestsVitest, 33 unit tests
Architecture: server functions fetch market data and news, Claude proposes evidence, I approve it into the ledger, and four pure functions produce eligibility, category scores, scenario probabilities and an action status
Figure 7. How evidence becomes a score. The amber box is the only place a language model is used.

Keeping the rules as pure functions made them easy to test and let me add the news scanner later without touching them. The scenario probabilities are a fixed formula on the total score, clamped and normalised to 100. The browser app talks to Supabase with the public key, and the service key lives only in server functions. Analyst estimates are entered by hand.

What it shows

AVGO Thesis Monitor makes one consistent move: rules that can be written as code are written as code, and the language model is given only the part that is reading and judging text, with a person approving the result. That is the pattern I would use for any tool where a model should help me read but not decide.