Playbook › Playbook
A multiple-form trim silently inherits whatever is wrong with the vendor P/E field it is derived from
Claim
site.py's trim_from_multiple() backs EPS out of the cached profile:
EPS = price / prof["forwardPE"] (basis "fwd") or price / prof["trailingPE"] ("ttm")
dollar = multiple x EPS
There is no independent EPS field. The trim therefore inherits every defect in the vendor P/E
it is derived from, and the failure is invisible on inspection — the watchlist still reads
Trim 28x fwd, which is the correct judgment; only the rendered dollar is wrong.
Before writing a multiple-trim, verify the specific vendor field that basis will use.
Choosing fwd vs ttm is not a stylistic choice — it selects which vendor field the number
depends on, and the two fail independently.
Evidence — SPGI, 2026-08-12
SPGI spun off Mobility on 2026-07-01. Yahoo's forwardPE of 20.18 still divided a
pre-spin EPS (~$20.24) into a post-spin price; the true forward multiple on guided
post-spin EPS of $17.50–17.75 was 23.2x.
The valuation judgment was 28x forward adjusted ≈ 28 × $17.625 ≈ $494. Written as
Trim 28x fwd, the site rendered:
| Value | |
|---|---|
| Intended trim | $494 |
| Rendered trim | $566.15 |
| Error | +15% — the exact size of the vendor's forward-EPS error |
$566 is 39% above spot and ~32x real earnings — the site would have advised holding a winner far past the point the analysis called it expensive. This is the same class of failure as [[pitfall-multiple-trim-inverts-on-peak-cycle-cyclicals]], but arriving through a broken field rather than a cyclical earnings peak.
The fix — switch the basis to the field that is verified good. SPGI's trailingPE of 24.86
was correct (EPS ttm $16.43 ties exactly: 14.66 + 8.81 − 7.04). Restating the same $494 judgment
on the trailing basis gives 30x ttm → $493.2. ✅
Note the multiple number had to change (28 → 30) because trailing GAAP EPS sits below forward adjusted EPS — GAAP carries ~$1B/yr of IHS Markit amortisation. The multiple written in the file is basis-specific and is not portable between bases.
How to apply
- Before writing
Trim NNx <basis>, check that basis's vendor field. Runpython .mcp/fin.py TICKER --quoteand confirmPE(fwd)/PE(ttm)against guided or reported EPS. If the field is broken, use the other basis. - Then verify the rendered dollar, don't assume it:
python .mcp/site.py→ grepk-trimin.site-html/t/TICKER.html. If it does not match the intended level, the basis or the multiple is wrong. - When you switch basis, recompute the multiple — 28x forward-adjusted and 30x trailing-GAAP can be the same dollar. Never carry the number across unchanged.
- Document the substitution in the watchlist entry, as NLCP and SPGI both do, so the next analysis knows the written multiple is a rendering of a different underlying judgment.
- Re-set both at the next
/analyze. A basis substitution has a shelf life — SPGI's trailing EPS drops once Q3 moves Mobility to discontinued ops, stepping the trim down.
The three known ways this convention misfires, all requiring the same check: - the earnings base is at a cyclical peak → [[pitfall-multiple-trim-inverts-on-peak-cycle-cyclicals]] - the right denominator is not GAAP EPS (AFFO for REITs, NII for BDCs) → the NLCP case - the vendor P/E field for the chosen basis is simply wrong → this note
What would falsify this — ✅ BUILT 2026-09-28
This note asked for "site.py gaining an EPS field sourced independently of the vendor P/E
(e.g. guided EPS carried in the watchlist entry itself)." That now exists.
Trim 42x fwd($5.47) renders 42 × 5.47 = $229.74 exactly, never touching forwardPE.
Trim 20x fwd with no basis keeps the legacy vendor path, so nothing already written broke.
The note stays live, not retired, for two reasons: the legacy path is still the default
and still wrong in the same way (CRUS and DOCU carry bare multiples today), and the defect it
describes — a vendor ratio that does not say which fiscal year it means — is unchanged. What
changed is that there is now a correct thing to do about it. Retire this note only when no
watchlist trim relies on the vendor path.
History
- 2026-08-12 — found during the SPGI
/analyze, caught by verifying the rendered dollar after the site build rather than trusting the written multiple. Related: [[pitfall-vendor-forward-eps-is-the-wrong-fiscal-year]], [[pitfall-post-spin-consensus-basis-mismatch]], [[principle-primary-source-beats-vendor]]. - 2026-09-28 — three further instances in one afternoon, and the first where the corrupting
defect is a fiscal-year mismatch rather than a spin-off mismatch. MANH's 8/27 trim
46x fwdwas written against the FY26 guide-mid ($5.47) while Yahoo'sforwardPEdivides FY27 EPS ($6.14); the site rendered $284 against an intended $252 for 32 days. The note predated that error by fifteen days. Same pass: BR20x fwdrenders ~10% high (vendor fwd P/E 14.05 implies FY28 EPS $11.59 against the FY27 guide mid $10.56) and LDOS13.5x fwdrenders ~3.1% high (vendor 9.54 implies $12.75 against a $12.35 guide mid). - 2026-09-28 — the workaround is now itself a hazard. Two agents hit this bug in the same
session and resolved it in opposite directions: one encoded a deliberately wrong multiple
(37x instead of 42x) so the broken divisor would render the intended dollar, and wrote
"do not correct this to 42x" into the file; the other refused to re-base and handed the
choice back. The encoded form is dangerous precisely because it works — the moment
site.pyis fixed, every compensated multiple silently becomes wrong, and the instruction not to correct it is what a future reader would most want to override. Resolved in favour of honest multiples: MANH carries 42x, BR carries 20x, LDOS carries 13.5x, each with the render error noted in the watchlist entry rather than compensated into the number. This makes the fix named under "What would falsify this" — an EPS carried in the watchlist entry itself — the actual open remedy, not a hypothetical one. - 2026-09-28 (later same day) — fixed at the builder, not in the data.
TRIM_MULT_REgained an optional($EPS)group,trim_from_multiple()gained anepsparameter that wins over the vendor P/E, and the label renders42× fwd × $5.47so the basis is visible on the page. Four selftest cases cover it: stated EPS wins, stated EPS needs no profile at all,eps=0falls back rather than dividing by zero, and a bare multiple still parses witheps=None. MANH, BR and LDOS re-encoded to honest multiples with an explicit basis — all three now render at 0.00% error against intent (they were +12.4%, +9.6%, +3.2%). The compensated-37x workaround is gone. ⚠️ One near-miss worth recording: the first attempt applied BR's$10.56basis to CRUS as well, because both lines carried the identical string**Trim 20x fwd.**— a blind string replace across a shared file will silently stamp one company's earnings onto another. Caught by auditing which tickers each match belonged to. Match on the ticker's line, never on the multiple alone.