Financebotresearch desk研究台

Playbook › Playbook

kb.py find searched only Knowledge/, so "has this been analyzed?" was unanswerable

static 2026-08-10

The failure

A portfolio-specific passage was removed from the public build.

Item Existing report Verdict already reached
"Run /analyze NVO" analyze-2026-08-05.md — day after the Q2 print HOLD [5.5], raised from 5.0
"Run /analyze ORCL" analyze-2026-07-23.md (+ 07-09) HOLD [7], explicit do-nothing band
"FISV is unscored" analyze-2026-07-09.md HOLD [5.5], full live thesis
"Run /analyze ARCC" analyze-2026-08-03.md, off the Q2 10-Q HOLD [5.5], coverage 0.979x

Worse than wasted effort: the report stated larger red flags than the evidence supported. It called the NVO thesis broken while the dedicated post-print analysis had raised conviction; it scored ORCL 3.5 Weak and asked "value trap forming?" when that question had been answered ("honest coin-flip, hold small"); and it reported ARCC's payout as "143%" — the GAAP-EPS figure the ARCC analysis explicitly flags as the wrong denominator, against a real base coverage of 0.979x.

Three causes, stacked

  1. cmd_find iterated load_notes() and never load_reports(). kb.py find NVO structurally could not return Output/Stocks/Healthcare/NVO/analyze-2026-08-05.md. This is the primary cause and it was silent — the command returned plausible note hits, so it looked like it had worked.
  2. STALE.md surfaced the superseded report and hid the current one. NVO's July 31 analysis was overdue (recheck 2026-08-05) so it appeared in the stale queue; the Aug 5 analysis was not due (recheck 2026-11-05) so it did not appear anywhere. The staleness queue shows what is old, which is the opposite of what is current — reading it as a coverage map inverts the signal.
  3. 81% of reports (180 of 220) carry no YAML frontmatter, so they render with blank verdict/conviction in Output/INDEX.md and can never be surfaced by kb.py stale. Both ORCL files and the FISV file were in that set.

Fix applied 2026-08-10

cmd_find now also matches reports on path/ticker/command/sector and prints them newest-first under a READ THE NEWEST BEFORE RE-DERIVING header, with verdict and conviction, or no frontmatter where absent. Frontmatter backfilled for the three reports tied to open action items; 177 reports still lack it.

Deliberately not done: adding "also read Output/INDEX.md" as a fourth protocol step in CLAUDE.md. Fixing find makes the protocol correct as written. A process step that must be remembered is weaker than a tool that cannot fail silently.

The transferable lesson

A knowledge check that returns results is not the same as a knowledge check that works. kb.py find NVO returned two genuine note hits — glp1-obesity-pharma and the DYT pitfall — which read as confirmation the search had run. Nothing signalled that an entire corpus was outside its scope. When a search tool returns something, the absence of the thing you were actually looking for is invisible.

Concretely, before writing any verdict on a name: - ls Output/Stocks/*/TICKER/ costs nothing and cannot silently under-report. Do it regardless of what find returned. - A portfolio-wide command touches 58 names — it will not deep-check each one. That is the exact condition under which stale or absent priors get restated as fresh findings. State explicitly which names were checked against existing reports and which were not. - Never let a mechanical scorecard overwrite a dedicated analysis. They measure different things; when they disagree, say so and cite both, rather than publishing the harsher one as the finding. See [[principle-primary-source-beats-vendor]] — a full /analyze is the primary source relative to a screen-level score.

History

  • 2026-08-10 — failure observed across four names in one report; cmd_find fixed the same day; addendum appended to the health report correcting all four action items.