Written 2026-09-08. A tool in service of the one goal (buy something good at a cheap price, repeatedly).
It lifts the semiconductor framework (2026-09-03) to any business, and
turns the pattern already used by hand in the RDDT and INTC theses into a fixed procedure.
Run it with /judge TICKER. This file lives under output/ so the site serves it;
resources/judgment-framework.md is a symlink to it.
Input: one ticker. Output: a verdict, the price at which the name turns cheap, the exit ladder, the
kill list, a risk profile, the research points to keep watching, and a players ledger. Files:
output/graham/scores/{TICKER}_thesis.md, {TICKER}_plan.json, and the pm watch add lines.
What the output is never: "buy today". Rule-001 says attention is late; even a CANDIDATE waits for the same-day red-flag check (rule-007) on the day an order is placed, and every entry alert names its funding source (rule-006: no settled cash in DEGIRO, no buy).
Different models have different "good" and different "cheap". Classify first, then measure. The first
section of every thesis writes the model as three or four multiplications in a table with four columns:
layer, question, numbers to watch, where it breaks (see RDDT_thesis.md §1 and INTC_thesis.md §1).
| Model | Examples | Value comes from | What "good" looks like | Primary cheap gauge |
|---|---|---|---|---|
| Platform / advertising | RDDT, META, GOOGL | users × monetisation × profit after SBC | Users the platform owns (not a search engine's), ARPU rising, GAAP operating margin, SBC share of revenue falling | Graham on GAAP EPS; P/(FCF − SBC); scenarios |
| Subscription / software | ADBE, NFLX, PAYC | retained revenue × gross margin × profit after SBC | Net revenue retention > 100%, churn disclosed and stable, GM > 70%, SBC < 15% of revenue and falling | P/(FCF − SBC); reverse DCF; Graham on SBC-adjusted EPS |
| Consumer brand / staple | RI.PA, BF.B, AM.PA | volume × price/mix × brand margin | Organic growth with volume positive, GM stable through input-cost swings, inventory days flat, dividend covered by FCF | Graham on normalised EPS; yield vs own 10-year range; rule-005 base check first |
| Bank / insurer / captive finance | AGN.AS, AIG, QQ.L | book value growth + distributions, priced on ROE vs cost of equity | Capital ratio (CET1, Solvency II) with buffer above requirement, combined ratio < 100 or NIM stable, ROE > 10%, reserves not released to make the quarter. Strip policyholder and matched liabilities before judging leverage (rule-003) | P/TBV vs justified P/B = (ROE − g)/(r − g) at r = 10%; dividend + buyback yield |
| Cyclical industrial / commodity / chemicals | AKE.PA, Maersk, IDR.MC | mid-cycle margin × volume, cycle position decides everything | Positive FCF in the trough year, net debt / mid-cycle EBITDA < 1x, capex discipline at the peak, share not lost through the cycle | P/normalised EPS; P/B vs own 5-year range; EV / mid-cycle EBITDA |
| Pharma / medtech with revenue | NVO, INMD | patent-protected revenue × margin, minus the cliff | Revenue at risk from patent expiry inside 5 years < 30%, pipeline replacing it visible in phase 3, pricing pressure quantified, no reliance on one drug > 40% | Graham on EPS with the cliff modelled; scenario EV with cliff timing |
| Retail / distribution | ARW, distributors | inventory turns × gross margin × store or channel productivity | Same-store sales positive on volume, inventory growing slower than sales, working-capital days flat, no lease-adjusted leverage surprise | Graham on EPS; EV / EBIT lease-adjusted; P/B for asset-heavy |
| Turnaround / inflection | INTC, GFS | survival and funding × milestone delivery × what the price already assumes | Self-funding capex, milestones met on dates the company itself gave, insiders buying, no dilution | Scenario EV/price only; Graham fails at a loss-to-profit inflection (rule-004); P/TBV as the floor |
| Semiconductors | any chip name | see the sector doc | semiconductor-framework.md steps 0-3 replace steps 0-3 here | as the sector doc |
| Speculation | pre-revenue biotech, squeezes, memes | a binary event or a crowd | Closed category (rule-013). Output DISCARD with the reason. The tooling stays for recognising junk | none |
A name that fits two rows (a conglomerate, a bank with a large asset manager) gets judged segment by segment and summed; the sum-of-parts is then a C7 scenario, not a reason on its own.
Rule-005: cheap on a shrinking base is a trap. Pull the last eight quarters (four halves for EU names that report semi-annually) of revenue growth by segment. If any major segment's decline is accelerating, the verdict cannot be CANDIDATE this pass; write the deceleration you need to see and set a calendar check.
Cyclicals take the five gauges from the semiconductor doc (revenue vs 5-year trend, gross margin vs range, inventory days, capex / revenue vs history, P/B vs own range) and output one word: Trough / Early / Mid / Late / Peak. A Peak name can only be cheap on normalised numbers.
Secular names output one word too: Growing / Stable / Shrinking-decelerating / Shrinking-accelerating.
| # | Test | Pass (2) | Amber (1) | Fail (0) |
|---|---|---|---|---|
| G1 | Cash after SBC | FCF − SBC positive in each of the last 3 years, including the worst one | Positive on a 3-year sum, negative in one year | Negative on a 3-year sum, or positive only with grants, disposals or partner cash |
| G2 | Moat, measured | Gross margin stable or rising over 5 years, share stable or rising, price increases stick (ASP or price/mix up on flat volume) | One of the three | Margin falling and share falling |
| G3 | Returns on capital | 5-year average ROIC > 15% (financials: ROE above cost of equity, about 10%, in each of 5 years) | ROIC 10-15% | ROIC < 10%, or returns only positive because of leverage |
| G4 | Balance sheet survives a bad year | Net cash, or net debt / EBITDA < 1x on trough EBITDA; no maturity wall inside 2 years; financials: capital ratio with a buffer of 2 points or more above requirement | Net debt 1-2x; a refinancing due but covered | Needs the market to fund itself; covenants or capital ratio within reach of a bad year |
| G5 | Not funding itself with shares | Share count flat or down over 5 years, buybacks exceed SBC, SBC < 5% of revenue (hardware, staples) or < 15% (software, platforms) | Share count up < 5% over 5 years, SBC above threshold but falling | Share count up > 5%; active ATM; converts within 2-3x of the price; bond-for-equity swaps; serial reverse splits |
| G6 | Insiders | Open-market buys by officers or directors in the last 12 months, no discretionary sales | Sales only under pre-set plans, or small discretionary sales by officers below CEO / CFO / COO, and no buys | Cluster selling (CEO + CFO + one more officer within 90 days), or a discretionary sale by the CEO, CFO or COO after a run-up. Owner's deal-breaker. |
| G7 | Story matches the numbers | The growth driver management talks about shows up as disclosed segment revenue and margin; guidance met 4 quarters running; cash flow tracks net income | Revenue shows it, margins do not (or the reverse); one guide missed | The claim is absent from the filings after two quarters; two of the last four guides missed; Schilit red flags (pm/frameworks/schilit.py) |
| G8 | Concentration and external dependence | No customer > 15% of revenue; no single channel, platform or geography the business does not control above 30%; no subsidy or one regulator the P&L depends on | One exposure above threshold | Two or more, or a live regulatory or channel action that removes > 10% of revenue |
Good = 12 or more out of 16 with no zero on G1, G5 or G6. A zero on G6 ends the analysis regardless of
score (owner's rule, 2026-09-02). Graham's 7 filters (pm graham screen, or analyze_stock for one name)
remain the coarse first pass; their score is context, never the verdict, because they fail every quality
growth business on P/E and P/B by construction.
| # | Test | How | Cheap reads |
|---|---|---|---|
| C1 | Normalised EPS | Cyclicals: 5-year average EPS, or 5-year median operating margin × current revenue ÷ shares. Secular growers: forward consensus with a 10-15% haircut. Inflections: scenario EPS two years out. Always GAAP or SBC-adjusted | (input to C2) |
| C2 | Graham sensitivity | V = EPS × (8.5 + 2g) at g = 0 / 3 / 5 / 7.5 / 10 / 15%, on normalised and forward EPS. Read off the break-even g the price implies | Break-even g at least 5 points below the growth the business has delivered over 5-7 years, with 25% margin of safety at that rate |
| C3 | Implied-growth gap | (P/E − 8.5) / 2 on trailing and on forward P/E | Gap under 5 points. A gap over 10 points prices an inflection, not growth (rule-004) |
| C4 | Cash yield | (FCF − SBC) / market cap; also EV / (FCF − SBC). Use PEGY when dividend yield > 3% | Yield above the 10-year government bond of the trading currency (US ~4.2%, Bund ~2.6% in 2026) for a mature name; above 2.5% for a name growing 20%+ |
| C5 | Reverse DCF | 10-year FCF CAGR the price needs at a 10% discount rate, 3% terminal growth, fading linearly to terminal in years 6-10 | Required CAGR below the demonstrated 5-year FCF CAGR, with room |
| C6 | Book value (capital-heavy and financials) | P/B or P/TBV vs justified P/B = (ROE − g) / (r − g) with r = 10%; P/B vs own 5-year range | P/B below justified, or in the bottom third of its own range |
| C7 | Scenario expected value | Bear / base / bull EPS two years out × a multiple that fits the model, probabilities stated, EV ÷ price | EV/price ≥ 1.25 = cheap; 0.90-1.25 = fair; < 0.90 = expensive |
Verdict rule. CHEAP requires all three of: C2 break-even growth cleared with 25% room, C5 required CAGR below demonstrated, C7 ≥ 1.25. FAIR when C7 is 0.90-1.25 and nothing in C2 or C5 is absurd. EXPENSIVE when C7 < 0.90. CHEAP-ON-PARTS when C7 ≥ 1.25 but C2 or C5 fails: the value sits in cash, assets or a run-off, not in earnings; treat it as TRAP? under rule-005 until the base stops shrinking and the cash has a named route to shareholders (first case: TRIP 2026-09-08). The cheap price is the price at which C7 = 1.25 with the thesis intact; that number is the alert level in step 4, and it is the one line of the output the owner acts on.
| Good? | Cheap? | Verdict | Action |
|---|---|---|---|
| Good | Cheap | CANDIDATE | Same-day red-flag check (rule-007), funding source, starter tranche 25-30% (rule-006), ladder set at buy time (rule-008) |
| Good | Fair | WATCH | Write the cheap price. pm watch REVIEW alert there. Walk away |
| Good | Expensive | WATCH (far) | Same, alert further down. Quality compounders live here most of the time |
| Not good | Cheap | TRAP? | Usually rule-005. Ask why. No buy without a second look at G1 and G5 |
| Not good | Any | DISCARD | Or HOLD-ONLY with a kill list if already owned |
Names already held do not get a buy/avoid verdict; they get HOLD / TRIM-ON-RUNG / EXIT under rule-008. The sign of the P&L is never a reason. A kill condition overrides a loss; a rung overrides a gain you would rather keep. Adds to a held name need the same CANDIDATE verdict as a new name, plus the rule-006 cap check (20% of a year's contributions in one name).
Ladder (rule-008), set at thesis time so it exists before any fill: three rungs at conservative, base and optimistic value. Default anchors: TP1 = Graham V at the growth rate actually demonstrated; TP2 = base scenario value; TP3 = bull scenario value. Sell in thirds. Compounders: a rung means re-assess. Positions bought without a thesis: trim mechanically.
Price is the sum of everyone's actions. The rough measure that answers "what is happening" splits a move into what the people who know the business did and what everyone else did:
ΔP/P ≈ ΔEPS/EPS + ΔPE/PE (forward consensus EPS and the multiple on it; add FX for a EUR owner)
| Consensus EPS | Multiple | Reading |
|---|---|---|
| down | down | Fundamental break. Re-run steps 1-2 before anything else |
| flat | down | Sentiment. The name got cheaper; if G holds, the cheap price is closer |
| up | up | Attention. Rule-001: write the cheap price, do not chase |
| up | down | De-rating despite delivery. The interesting quadrant; check G8 for what the market fears |
Behind the split, each player leaves a trace. Score each row −2 to +2 over the last 90 days (−2 = acting strongly against the thesis, +2 = strongly for it, 0 = no read). The sum is the players net, −16 to +16. It is context for the thesis, never a signal on its own; the only row with a hard rule is P1.
| # | Player | What they can do to the price or the business | Observable | Source and lag | In the repo |
|---|---|---|---|---|---|
| P1 | Officers and directors | Know the business first | Open-market buys vs sales by role; plan (10b5-1 / MAR) vs discretionary; cluster inside 90 days; buys after a fall | Form 4 within 2 business days (US); PDMR notification within 3 (EU) | G6, rule-003 test 4; Finnhub insider transactions; yfinance insider_transactions |
| P2 | The company | Shrink or grow the share count; meet or miss its own guide | Buyback pace and average price vs current; share count trend; ATM / converts; guidance record | 10-Q / half-year report; 8-K | G5, G7; analyst agent |
| P3 | Institutions | Move the price for weeks; force change via activism | Net change in number of holders and shares held; any 13D / 13G; top-10 holder changes | 13F quarterly, 45-day lag; 13D within 10 days | yfinance institutional_holders, major_holders (not systematic) |
| P4 | Short sellers | Informed bears when they add into a fall | Short % of float and its direction; days to cover; borrow cost if available | Twice monthly (FINRA), 2-week lag | rule-013 squeeze mechanics; yfinance sharesShort, sharesShortPriorMonth, shortPercentOfFloat |
| P5 | Sell-side analysts | Move consensus, which moves the split above | Direction of EPS revisions over 30 and 90 days, not the level; rating and target changes | Continuous | yfinance eps_trend, eps_revisions, upgrades_downgrades, analyst_price_targets |
| P6 | Retail and attention | Late by construction | Weighted reddit mentions and sentiment; Google Trends; options volume | Daily scrape | pm pipeline reddit (rule-001: lead generation only) |
| P7 | Customers, suppliers, competitors | Change the demand or the price the business gets | Largest-customer disclosures (> 10% named in the 10-K); customer capex guides; competitor gross margin and pricing; channel inventory days; monthly revenue prints (Taiwan-listed suppliers) | Filings, earnings calls, monthly (TW) | G8; semiconductor-supply-chain.md for chips |
| P8 | Regulators and politicians | Remove revenue or add cost by decree | Export controls, antitrust, platform rules (DSA), tariffs; congressional trades | Announcements; congressional trades 30-45 days late | G8, rule-001 (a politician's trade is attention, not analysis) |
Data notes. Finnhub's free tier covers insider transactions and company news; short interest and estimates are paywalled there, so take them from yfinance. All P3 data is at least six weeks old when published; treat it as a description of the last quarter, not of today. P6 and P8 are lagging by construction, which is why rule-001 exists.
| Field | Content |
|---|---|
| Risk type | one or two of: cycle, dilution, concentration, regulatory, balance sheet, execution, key person, FX, channel dependence |
| Largest single risk | one sentence, with the number that would show it |
| Bear case | value and probability from C7; the drawdown from the current price |
| Kill conditions | the list from the section below, fundamental only |
| Sizing | EUR band 250-750, cap 20% of a year's contributions, current share of the single-name book |
| Liquidity and venue | average daily volume, DEGIRO venue and FX cost, ADR or local line |
| Overlap | weight in VWCE (a direct buy is a deliberate overweight), sector overlap with names held |
| Horizon and next dated event | the holding period the thesis needs, and the next earnings, ex-dividend, AGM, deal or regulatory date |
Each row of the step-0 layer table yields one or two numbers with a disclosure cadence. Those numbers, the
dated calendar, and the P1 / P4 / P5 traces go into the plan under monitoring.watch so the weekly monitor
and the next session know what to check without re-deriving the thesis.
{TICKER}_thesis.md, sections fixed so theses compare across names:
{TICKER}_plan.json, keys the weekly monitor reads and that must stay stable (conv-003):
kill_conditions_fundamental_only (list), targets (list of {id, price, anchor, action, watch_key}),
review_level ({price, watch_key, note}), monitoring.next_earnings, monitoring.watch. Add
verdict_YYYY_MM_DD (good score, cheap verdict, EV/price, action) so re-runs append rather than overwrite,
risk_profile (step-6 fields), players (P1-P8 scores, net, date), valuation (the C-test inputs).
Alerts. One pm watch add line per rung and one for the review or entry level, note in the form
TYPE. ACTION AT TRIGGER. FUNDING. SOURCE. Keys {TICKER}-TP1..3, {TICKER}-REVIEW{price},
{TICKER}-ENTRY. Alerts committed in a worktree are not live until main is merged and pulled in the
primary checkout the daemon reads.
Verdict line, last line of every run:
VERDICT {TICKER} {date}: good {n}/16 (G6 {pass|amber|FAIL}) · {CHEAP|CHEAP-ON-PARTS|FAIR|EXPENSIVE} EV/price {x.xx} · cheap at {ccy price} · players net {±n} · {CANDIDATE|WATCH|TRAP?|DISCARD|HOLD|TRIM|EXIT}
Any one fires: re-score within five trading days; exit unless the thesis survives on the new numbers.
dividendYield scaling is inconsistent (a yield above 20% is a bug) and priceToBook is wrong
for ADRs; take balance-sheet ratios from the filing.