The map · Part Two · The machine · Chapter 14 of 23
How the program is put together
Seven kinds of piece and the walls between them. The interesting part is not what each piece does but what it is forbidden from doing. About 9 minutes.
The program is a set of small parts, each with one job, and the design question was never "what should each part do" but "what must each part be unable to do". This chapter walks the parts as a picture and then names the walls. There is no code in it.
The seven kinds of piece
Fetching: bringing figures in from outside
One part fetches daily prices and keeps a copy on disk, so that when the price service is down the run has yesterday's figures marked as stale rather than nothing at all. Another reads the structured data American companies must file with their regulator. Two more read the Nordic exchanges' own disclosure feeds, which is where a Swedish or Norwegian company's reports actually appear. One reads a company's spreadsheet appendix through a map, committed with the code, that says which cell is which figure. One fetches a company's own report page and nothing else: it does not search, guess or follow links. And one hands a fetched document to a language model with a narrow instruction: pull out the stated figures and quote the sentence each came from; never derive, estimate or reconcile a figure, never decide whether something is material, never write prose.11Module descriptions in vss/fetch.py, vss/xbrl.py, vss/nordic.py, vss/oslo.py, vss/appendix.py, vss/source.py and vss/extract.py; README on the extractor: it 'never derives, estimates or reconciles a figure, never decides materiality, and never writes prose.'
The forbidden thing, for every fetcher: it may not judge what it fetched. It brings a figure in with its origin attached, and stops.
The record: keeping every figure
One part writes one row per company per run into a small database, so the history can be rebuilt later. One keeps the run record for each valuation, the eight things that must be declared before a value may be printed (chapter 15). One keeps a snapshot of every screening run, the raw prices and the list of names, so the run can be replayed exactly. One holds hand-entered figures for companies no feed serves, each marked as checked or not. One tests whether a price series is a real measurement or a feed artefact.22vss/store.py, vss/runrecord.py, vss/snapshot.py, vss/manual.py, vss/series_sanity.py.
The forbidden thing: the record never fills a gap. A figure that was not fetched is absent, and stays absent.
Computing: the arithmetic, kept pure
The parts that compute figures, apply the rules and solve the valuation do no input and no output. They do not read files, do not touch the network, and do not know what time it is; the date is always handed to them. This is a wall, not a convention: it means a computed figure can be reproduced later from the same inputs and will come out the same, because nothing in the computation could have depended on the world outside it.33The rules module: 'This module performs ZERO I/O. No file access, no network, no logging, and deliberately no datetime.now().' The metrics module is the same, with the as-of date always passed in.
Reporting: the report and the page
One part writes the nightly report in a fixed order: when the run happened and how fresh the data was; then blockers, the things that stopped a judgement; then actions, the things that need the owner; then the full table of every name. Another generates the one-page overview that reaches the phone (chapter 21). A third assembles a research briefing for a name being read, which is a collection of the figures and their sources, not a view.44vss/report.py, vss/overview.py, vss/briefing.py.
The forbidden thing: no report says buy, sell, or good. It says how far, how fresh, and what is missing.
The screen
The parts from chapter 4: the fixed list of names, the two filters, the ranking, and a wrapper that runs them on a Saturday morning. Plus one small part, and it is the only piece in the screener allowed to write into the owner's file: the one that enters a proposed name. It runs only when the owner starts it by hand.55vss/screen.py, vss/filters.py, vss/universe.py, vss/ranking.py, vss/screenwatch.py; vss/pipeline.py is 'the only module in the screener that writes to the file holding the owner's live positions', and the scheduled unit is started without the flag that would invoke it.
Watching
Two parts. One watches the disclosure feeds for the names on the waiting lists and reports only three kinds of document: a periodic report, a change to the company's own forecast, a profit warning. Everything else the exchange publishes is rejected and the rejection printed. The other watches the prices of the screener's top twenty against an indicative level and points, once, when a price crosses it. The level is a distance from a rough value, not a buy line, and the ruling says so.66vss/watch.py; vss/pricewatch.py, ruling E97: 'a distance, not a buy line'.
The heartbeat
One part whose only job is to make a run that did not happen look different from a run that had nothing to say. Chapter 18.
The runner
One part ties the nightly run together: load the owner's file, fetch, compute, assess, report. All the reading and writing of the run lives here and in the fetch, store and report parts, so that everything else can stay pure.77vss/runner.py: 'All I/O lives here and in fetch/store/report. rules.py and metrics.py stay pure.'
The two walls
The first wall is around the owner's file. It holds every status, every tier, every value, every stop: the decisions. No part that runs on a schedule may write to it. The refresh command asserts it did not. The scheduled screen's unit cannot write to the folder. A hand-typed buy price in the file fails the run outright, because a buy price must come from a value and a tier or it has no origin.88Rulings E92 and E93; README on the provenance conflict; the read-only configuration directory in deploy/vss-screen.service.
The second wall is around the arithmetic. Nothing that computes may fetch, and nothing that fetches may compute. A figure crosses from one side to the other only through the record, with its origin attached. This is what makes a number reproducible, and what makes a wrong number traceable to the fetch that brought it in rather than lost inside a calculation.
The commands, for the curious
The program is run from the command line as python -m vss followed by one of sixteen sub-commands. The ones a reader of this site has met: run (the nightly run), screen (the weekly screen), watch (disclosures), refresh (re-read a company's figures on a report date), earnings, xbrl, nordic, manual, appendix (the ways figures come in), briefing (assemble a reading), overview (the page), checkin (the heartbeat's own timer), sales (closed positions measured against the index), shadow (the shadow book). Every one of them prints a report to standard output and logs to standard error, and none of them writes a decision.
Sources for this chapter
- Module layout and each module's stated scope — read from this repository: vss/*.py module docstrings; vss/__main__.py; README.md
The slow way, made survivable. Built 2026-09-13 from the repository as it stood that day. NAME A and NAME B are fictional; no company, price or holding appears on this site. Not financial advice: one private investor's method, shared as it is.