Join the Latticework AI Bootcamp and progress at your own pace. Participation is open to members and paid subscribers.
A note before we begin: This is the 15th lesson in a 16-lesson experiment. I am doing every lesson alongside you, on the same tools, with the same constraints. Some lessons will land cleanly. Some will lead to dead ends and need rework. We’ll figure out what works, together.
If you are catching up, here’s what came before today’s lesson:
Intro: Build Your Own Investment Idea Engine
Lesson 1: How LLMs Work, and How to Defend Against Hallucinations
Lesson 2: Prompt Patterns That Outperform Casual Prompting
Lesson 3: Tools, Agents, and Structured Output
Lesson 4: SEC EDGAR, the Primary Source
Lesson 5: FRED Macro and Sector Data, the Free Read
Lesson 6: FMP API Key and the First Checked Data Pull
Lesson 7: Other Data Sources, and Idea Engine Formats
Lesson 8: Spaces, Projects, and Connectors
Lesson 9: Memory, Sub-Agents, and Parallel Research
Lesson 10: Wide Research for Screening at Scale
Lesson 11: Iterating Prompts and Structured Idea Write-Ups
Lesson 12: Claude Code, and Building Your First Useful Script
Lesson 13: Git, GitHub, and a Real Screener on FMP
Lesson 14: Layer On EDGAR, FRED, and a Scoring Layer
Why This Matters for Investors
For the last three lessons the engine has been adding plumbing. We have a private repository, a .env file that holds the FMP key and the FRED key, a screener that hits FMP for fundamentals, an EDGAR layer that stamps every row with the most recent 10-K filing date, a FRED layer that stamps every row with five dated macro observations, a scoring config in YAML, and a composite 0-to-100 score column that ranks the names. The CSV is real and the columns audit cleanly. What we do not yet have is a written-down answer to the question, what is this thing actually trying to do for us, and how would future-us recognize when the engine is helping versus when it is just producing output. Today we write that down.
The one-page specification is the lesson’s first deliverable, and it is the part of the bootcamp where the personalization becomes binding. Every member of this cohort has the same scaffolding by now. After today, every member’s engine starts diverging from every other member’s engine, because the spec encodes universe, exclusions, source hierarchy, valuation lens, quality bar, schedule, delivery channel, and the maximum number of ideas we want to see per run. A generic spec produces generic ideas. A personal spec produces ideas we recognize as the kind of ideas we are willing to spend more time on.
The second deliverable is the narrative layer. The composite score sorts the CSV; the narrative layer earns the top three rows the right to be investigated. For each of the three names at the top of today’s run, we ask Claude, with the My Analyst system prompt from Lesson 2, to draft a one-paragraph qualitative take that answers four questions in our voice: why the name surfaced, what evidence in the columns supports the surfacing, what could be wrong with the surfacing, and what the next human check should be. The narrative layer does not recommend action. It earns the right to be investigated. That distinction is the entire reason we are writing it down rather than trusting our memory of the column values.
By the end of today the engine produces, in a single end-to-end run, a sorted CSV with provenance columns, a one-page spec saved alongside the screener, and three short qualitative paragraphs that turn the top three rows into a triage pack we can read over coffee. Tomorrow’s lesson schedules the engine so it runs without us, writes a README so future-us can change parameters without re-deriving today’s reasoning, and runs the first retrospective on what surprised us in the first week of output.
Let’s launch into today’s lesson.









