The report arrived with nine dimensions. All nine were empty.

Four value axes โ technology, investment, timeliness, reference โ each scored 0 out of 5. A risk matrix with six rows covering technical, market, operational, regulatory, competitive and narrative exposures, every cell returning N/A. Five security checkboxes: unaudited code, centralized sequencer, excessive admin keys, high technical complexity, no peer review. Unchecked, all five. A token supply table with four categories โ team, early investors, community, treasury โ and no numbers in any of them. The footer read INCOMPLETE โ BLOCKED BY EMPTY INPUT.
I read it twice, because the first pass did not feel like an error. It felt like a dossier. Nine headings. Fourteen tables. A Howey four-element test. An upstream-to-downstream transmission map. Set in professional type, with consistent row heights and a glossary at the back defining FDV, TVL, TGE, and Wells notices. Every structural marker of rigorous work was present except the work.
This is the most instructive artifact I have seen this quarter, and it contains zero information about any asset.
Context first. Since late 2025, a meaningful share of crypto due diligence has migrated into two-stage automated pipelines. Stage one extracts: it fetches a source, strips the HTML, and emits a structured list of information points โ claims, numbers, entities, dates. Stage two analyzes: it consumes that list and produces the nine-dimension report a fund's investment committee expects to see. The architecture is sound in principle. It enforces consistency, which human analysts do not, and it produces an audit trail, which human analysts also do not.
The failure mode is equally structural. When stage one hits a paywall, a JavaScript-rendered page, a rate limiter, or a document that is mostly an image, it does not throw. It returns an empty array. Stage two, which is doing exactly what it was told, walks its template and fills every slot with the only honest value available: insufficient information. The pipeline then ships, because no assertion anywhere in the chain said "stop."
The report I read is that failure, rendered at full production quality. What makes it worth dissecting is not the emptiness. It is that the emptiness was formatted.
Three nulls are being collapsed into one. In serious data engineering, absence has gradations. There is not extracted โ the source contained the fact but our tooling missed it. There is unknown โ nobody on earth has this fact yet. There is not applicable โ the protocol genuinely has no token, no team, no admin key. A risk register must distinguish all three, because the remediation differs: re-run the crawler, hire an investigator, or close the item forever.
This report maps all three onto a single string. The consequence is quiet and severe. A protocol with no admin key and a protocol whose admin key nobody checked produce identical output. One is a strength. One is an unquantified liability. The document cannot tell you which one you are holding.
I learned this on a forty-point audit checklist in 2017. The rule on that checklist was never "skip." Every line had to resolve to PASS, FAIL, or BLOCK. A line you could not resolve became BLOCK, and BLOCK carried the same weight as FAIL, because from a capital allocation standpoint an unverifiable claim and a false claim cost the same amount of money. We once rejected a well-subscribed sale on a vesting contract with an integer overflow in the unlock arithmetic. We rejected it because a line resolved to FAIL, not because a line sat empty. Empty lines on that checklist were treated as failures by default. That default is the entire design.
The star table is the dangerous part. Zero out of five, four times, with a legend explaining that zero means "cannot rate" rather than "poor quality." Inside the document, that distinction is explicit and honest. Outside the document it evaporates. Any downstream consumer โ a ranking script, a spreadsheet, a human skimming a summary row โ sees a numeric field. Numerics sort. Numerics average into a composite score. A fund aggregating forty of these reports will produce a mean quality figure in which unrated assets drag the number down, or, depending on sign convention, where a zero risk score reads as no risk at all.
Nothing in the pipeline's type system prevented that. My 2020 yield-farming stack handled it the other way. Whenever the price oracle returned null, the strategy halted and liquidated nothing, because the one thing we never allowed was a default value flowing into a sizing calculation. A missing price is not a price of zero. A missing risk score is not a risk score of zero. Both errors are cheap to prevent and expensive to discover.
Fourteen unchecked boxes are not fourteen clean boxes. A checked box and an unchecked box are visually distinct. An unchecked box and a box nobody could evaluate are visually identical. On a trading desk, an unchecked pre-trade control means the order does not go out. In this report, unchecked means the analyst could not determine the answer, and the report still went out. Same glyph, opposite epistemics. The document's own methodology note flags this explicitly โ advising that all five be treated as pending and assumed worst-case until verified. That note is correct, and it is also buried, and buried correct notes do not survive contact with a dashboard.
I want to be precise about what actually worked here. The report refused to invent. It did not manufacture a competitor comparison, did not assign a plausible-sounding team profile, did not round an unknown into a neutral-sounding "moderate." In a market where a great many polished research notes are essays with a price target stapled on, a document that says I have nothing is behaving better than most of its peers. Ledger lines don't lie, and a blank ledger line is an honest admission rather than a false balance.
The contrarian read is that the parser is not the problem. Everyone's instinct is to fix stage one โ upgrade the headless browser, rotate the proxies, retry on 403. Do that; it is cheap. But the parser will fail again, on a different source, next week. Failure is the normal state of web extraction, not an exception to engineer away.
The defect sits one layer up. A schema that permits a fully rendered, fully formatted, nine-dimensional report to exist on zero inputs is a schema that has no concept of validity. The template should be unsatisfiable when the information-point list is empty. Not warned. Not annotated. Refused.
And the human version of this bug is older than the automation. I have read due diligence memos with hollow team sections that were signed off, because a heading with a paragraph under it reads as covered ground. A heading with three sentences of hedge under it reads as a judgment call. The machine did not create this failure. It made it legible, at scale, in a font we trust.
Smart contracts execute, they do not empathize. Neither do the spreadsheets downstream of this report.
Takeaway. Three changes, and none of them are model upgrades. Enforce a hard assertion at the stage boundary: if the information-point list is shorter than a defined minimum, throw and quarantine the asset rather than emit a container. Make the risk register tri-state โ verified, failed, unresolved โ and let unresolved block the item from any allocation list. And forbid zero from occupying a numeric risk field; if a value cannot be scored, the field must be null and the sort must break, not default.
Audit the code, then audit the team, then sleep. But first audit the schema that decides what an empty answer is allowed to look like.

The question worth carrying into next week: how many assets in your current book are rated on fields that were never extracted โ and how would you know, if the report came back formatted and calm and green?