On a Sunday morning in Istanbul, a Phase 2 analysis report landed in my review queue. Fourteen fields. Every one of them returned the same string: "N/A โ insufficient information."
No title. No source. No information points. No named protocols. No risk rating. No confidence score. A document that was structurally complete, correctly formatted, and substantively empty.
That is the anomaly. Not a reentrancy bug, not a bridge drain, not a governance capture executed through a flash loan. A two-stage pipeline that ran to completion, produced a valid artifact, and told the truth: it had nothing to analyze. Stage 1 โ the deconstruction layer โ returned null across every field. Stage 2 โ the nine-dimension analysis layer โ detected the nulls, refused to fill them, and halted with a documented manifest of what it would need to proceed.
Most systems in this industry would not have halted. They would have completed the request. And that difference is the entire story.
Context: the two-stage contract
Reconstructing the protocol from first principles, the pipeline is two contracts joined by one interface.
Stage 1 is a deconstructor. Its function is extraction. It reads a source document and emits a structured record: title, source, category, domain tags, an ordered list of information points, named projects and protocols, time sensitivity, and a source-quality assessment.
Stage 2 is an analyzer. Its function is interpretation. It consumes that record and maps it across nine analytical dimensions โ technical, tokenomic, market, ecosystem position, regulatory, team and governance, risk, narrative and expectation, and supply-chain transmission โ producing judgments with explicit confidence markers.
The interface between them is a schema. And a schema is a promise: every field either carries a value or carries an explicit null. What the schema in this case did not specify โ what no schema specifies by default โ is the behavior on null. That omission is the gap. The gap is where the entire incident lives.
I have spent thirteen years watching this gap open and close. In 2017, I spent two months comparing the Ethereum whitepaper's EVM architecture against early testnet implementations, cross-referencing the theoretical gas-cost model with actual transaction data from Parity clients. The interesting finding was never the theory or the implementation in isolation. It was the space between them โ the places where the spec was silent and the client had to guess. Every guess was a latent divergence, and latent divergences have a habit of becoming consensus splits.
The pipeline in front of me was the same shape. Stage 1 was silent. Stage 2 had to decide what silence meant. It chose to halt. That choice is worth dissecting at the code level, because the alternative โ the one most production systems take โ is the reason so much of this industry's "analysis" cannot be trusted.
Core: three behaviors on null
When a schema field arrives null, an analysis engine has exactly three possible behaviors. They look similar from the outside. They are not similar at all.
The first is silent null propagation. The engine carries the null forward, produces output where every dependent field is also null, and returns a structurally valid document. This is the most common behavior and the most dangerous, because the output looks complete. A reader who does not check every field sees a finished report. They do not see that the report is a lattice of holes.
The second is silent fabrication. The engine, biased toward completion, fills the nulls with the most statistically probable values. A missing project name becomes a plausible project name. A missing risk rating becomes a plausible risk rating. The output is fluent, confident, and invented. This is the behavior that the entire generative-content economy is optimized to produce, and it is the reason I stopped reading most "deep dives" two years ago.
The third is explicit halt. The engine detects the nulls, refuses to proceed, and returns a manifest of the minimum inputs required to continue. This is the rarest behavior, because it is the only one that produces a worse-looking artifact than the request implied. It is also the only one that is correct.
The report in my queue took the third path. Fourteen fields, all marked insufficient. And then โ this is the part that matters โ it appended, dimension by dimension, the minimum input list. Technical analysis required four inputs: layer classification, core technical approach, development stage, audit status. Tokenomics required five. Market required four. Every dimension declared exactly what it needed and refused to guess.
That manifest is the artifact. It is more valuable than any analysis the pipeline could have fabricated, because it is a precise specification of a failure. A confident wrong answer destroys capital; a documented missing input merely costs time.
Why engines fabricate: the completion bias
To understand why the halt is rare, you have to understand the pressure that produces the other two behaviors. Autoregressive systems are trained to complete sequences. Their objective function rewards plausible continuation, not verified truth. When a field is null, the path of least resistance is to continue as if it were not. The model does not experience this as lying. It experiences it as finishing.
This is a mechanical property, not a moral one. The same property that makes these systems useful โ the ability to produce coherent structure from partial input โ is the property that makes them dangerous when the partial input is mistaken for complete input. The mechanism does not distinguish between "the source said X" and "X would fit here."
I watched the same mechanism operate in a different medium after the Terra collapse in early 2022. I spent six weeks reverse-engineering the LUNA stabilization mechanism, tracing recursive debt accumulation through the smart-contract call graph. The system's documentation described a peg maintained by arbitrage incentives. The code described a peg maintained by an assumption of infinite liquidity on the buy side. That assumption was never stated as a parameter. It was implied by the structure โ the same way a fabricated field is implied by the structure of a report. When the buy side stopped being infinite, the mechanism did not degrade gracefully. It inverted. The debt accumulated recursively until the peg was a memory.
The Terra mechanism and the fabricating analysis engine fail identically. Both substitute a plausible default for an explicit input. Both are structurally incapable of halting. The ledger remembers what the narrative forgets: the peg was never maintained; the buy side was merely assumed.
The zero-address problem
There is a precise on-chain analogue to the null-handling question, and it is one every Solidity developer meets in their first month: the zero value.
In Solidity, an uninitialized storage slot reads as zero. An unset address is the zero address. An unset boolean is false. The language provides no distinction between "this value is zero" and "this value was never set." Both read identically. This is not a design flaw so much as a design omission, and it has produced an entire genus of exploits โ uninitialized storage pointers, phantom approvals, logic that treats a sentinel as a measurement.
Consider a stableswap invariant. In 2020, during the DeFi Summer, I worked with a small security team auditing Curve Finance's stableswap. We found a rounding error in the virtual price calculation โ a discrepancy of a few basis points that, under high volatility, could bleed value from liquidity providers into the hands of arbitrageurs. The magnitude was tiny. The mechanism was everything. The invariant assumed inputs that were exact; the EVM delivered inputs that were rounded. The gap between the assumption and the implementation was where the value lived. I documented it in a private report to the founders before any public disclosure, because the point was to protect the liquidity providers, not to collect the credit.
Null handling is the same class of problem at the analysis layer. When a field is empty, is that field zero, or is it missing? If the engine cannot distinguish, it will eventually treat a missing input as a measured one. And the exploit โ the fabricated conclusion โ executes silently, because there is no assertion that fires. There is no revert. There is only a document that reads well.
The pipeline in my queue resolved the ambiguity by refusing to resolve it. It did not treat the null as zero. It did not treat it as missing-but-inferable. It treated it as a stop condition, and it said so.
The round-trip test
I keep one principle for any extraction pipeline, and I will state it here because it is the closest thing to a formal check on the fabrication problem: the round-trip test.
Take the output record and attempt to reconstruct the input source from it. If the reconstruction succeeds โ if you can regenerate the substance of the original from the structured fields โ the extraction captured signal. If the reconstruction is empty or generic, the extraction captured noise dressed as signal.
In the case of the null record, the round trip is trivially informative. You cannot reconstruct a source document from fourteen nulls. That is not a failure of the record; it is proof that the record is not a lossy compression of the article. It is a faithful record of an absence. The pipeline passed its own round-trip test by failing it loudly. Most fabricated reports fail the round trip silently, and no one runs the test, because the output looks finished.
Building the halt
Building the halt is not hard, but it is not free. It requires three things most pipelines omit. First, required-field markers in the schema โ an explicit declaration that certain fields cannot be defaulted. Second, a confidence gate โ a rule that no downstream judgment may carry higher confidence than the least-confident field it depends on. Third, a halt handler โ a defined output for the null case, so the engine has somewhere to go other than completion. The report in my queue had all three. Its schema marked every field required; its judgments inherited the null confidence; and its halt output was the manifest itself. Most pipelines have none of them, and so their default behavior on null is fabrication, whether or not anyone intended it.
Stability is not a feature; it is a discipline
The reason this matters beyond one pipeline is that the same failure shape recurs everywhere in the stack, and in every case the fix is a discipline rather than a feature.
An oracle that returns a stale price is not broken in the way a reverted call is broken. It returns a number. The number is wrong. Downstream contracts consume it as if it were fresh, because the interface offers no way to say "this is a default, not a measurement." The Chainlink-style heartbeat and deviation thresholds exist precisely to force the missing-input case into an explicit halt โ to make the contract revert rather than consume a plausible fiction. Every oracle design is a null-handling policy in disguise.
An empty block proposed to a consensus layer is the same shape. It is structurally valid. It contains no transactions. If the proposer's client cannot distinguish "I have nothing to include" from "I failed to gather," it will propose the empty block as if it were a full one, and the chain will accept it. The halt โ the decision not to propose โ is the security control. Stability under load is not a property the system has. It is a behavior the system practices, block by block, and it degrades the moment the discipline lapses.
In 2024, as a core contributor to the Pectra upgrade review, I focused on the EIP-7702 account-abstraction implementation. The relevant finding was a potential reentrancy in the signature-validation logic โ a path where, under specific gas-pricing conditions, an unauthorized state change could slip through validation. What made it subtle was not the reentrancy itself. It was that the validation logic treated an absent authorization as an implicit approval under one code path. An empty field read as a yes. We patched the testnet client before mainnet activation, quietly, because the value of the fix was in the network not noticing.
That is the pattern. The vulnerability is almost never the missing check. It is the missing distinction between empty and zero.
Contrarian: the halt is the security control
Here is the counter-intuitive angle, and it is the one I want a reader to carry away.
The pipeline did not "fail" when Stage 1 returned null. Stage 1 failing is an input condition. The pipeline succeeded when Stage 2 detected the nulls and halted. The failure would have been the fabricated report โ the fourteen-field document that reads like analysis and contains none.
This inverts the usual framing. We treat a halt as an outage. We treat a completed request as a success. In analysis, in oracles, in consensus, in account abstraction, that framing is exactly backwards. The completed request is the attack surface. The halt is the defense.
The industry is structurally biased against this. Content systems are rewarded for throughput. Analysts are rewarded for output. Protocols are rewarded for uptime. Every incentive points toward completion. And so the fabricating behavior โ the plausible default, the inferred field, the stale price served as fresh โ is not a bug that slips through. It is the behavior the system is optimized to produce. It is a feature until the moment it is an exploit.
The blind spot is that this failure mode has no error signal. A reverted transaction is loud. A fabricated analysis is silent. It looks exactly like a correct one, because it was generated by the same process that generates correct ones. There is no assertion to catch it, no revert to observe, no log line to grep. The only defense is the discipline of refusing to complete โ and that discipline has to be built into the engine, because it will never emerge from the reward function.
Protecting the user
Who does the halt protect? In the abstract, it protects the reader from acting on fiction. Concretely, it protects the retail participant โ the person who reads a "deep dive," sees a confident risk rating, and sizes a position on it. That person cannot audit the pipeline. They cannot tell a fabricated field from a verified one. The only thing standing between them and a fluent lie is an engine that would rather return nothing than return something invented.
That is why the manifest matters. The report did not just refuse. It told the reader exactly what was missing and exactly what would be needed to proceed โ four inputs for the technical dimension, five for tokenomics, four for market, and so on, down the list. A reader who receives that manifest knows the state of the analysis precisely. They know it is suspended, not wrong. They know the difference between "no signal" and "false signal," which is a distinction most of this industry never bothers to make.
Takeaway: provable absence
The forward-looking question is not whether this pipeline will be fixed. It is what happens when the same principle has to be enforced cryptographically rather than editorially.
In 2026, I led a pilot integrating AI agents with ZK-proof verification for autonomous transactions โ a protocol where AI-generated transactions were signed and verified inside zero-knowledge circuits, processing ten thousand automated transactions with zero failures. The design constraint that mattered most was not proving that an agent did the right thing. It was proving what the agent did not do. An agent that acts on a null input is a fabricating engine with a private key. The only durable defense is a circuit that can prove absence โ a null proof, as rigorous as a proof of inclusion.
We are not there yet. Today, the halt is a discipline. Tomorrow, it will need to be a constraint, enforced at the protocol layer, verifiable by anyone, invisible to no one.
So the question I leave open: when the agents sign their own transactions and the proofs verify their own outputs, who audits the null? Because the ledger remembers what the narrative forgets โ and right now, the narrative is the only place most systems record that a field was ever empty at all.