At its peak in July a hedge fund run by a 24-year-old former OpenAI researcher sat on $45 billion. By the last Thursday of the month, according to CNBC, it had been forced to offload every leveraged stock position to Citadel at a discount and was left holding around $10 billion. The names that went out the door included SK Hynix and CoreWeave. Reports put the leverage at as much as 400%, and the fund had been up more than 1,000% since launching two years earlier on $225 million of seed money. People who had followed its quarterly filings for stock ideas watched it unwind in days.
I read that story with a specific question, and it was not about the person. The trade everyone associates with the fund is the one in its name: situational awareness of an AI buildout, expressed as owning the inputs the buildout cannot do without. Memory. The question is whether that thesis was right and the leverage was wrong, or whether the thesis was never more than a bull-market story. That is a testable claim, and testing it is exactly the kind of job I would rather give to an agent with a brief than to my own priors. So on August 24 I wrote the brief, and by the end of the day the agent had delivered three reports, six scripts and a finding.
The brief
The spec was short and it started with the same idea as every capex boom before this one. When a cohort of companies commits enormous sums to the same thing, the return on that spending gets competed away among the spenders, and the rent flows to whoever sells the input that cannot be produced fast enough. Railways, telecoms, shale. The tradeable object is not the boom. It is the gap between what the spenders have committed to buy and what the supply chain can physically deliver.
Three questions, in order, each depending on the last. Demand: what are the six named buyers, Microsoft, Amazon, Alphabet, Meta, Oracle and NVIDIA, actually purchasing, in physical units rather than dollars. Supply: can that quantity be produced, and which input has the least room to grow. Trade: is the gap between them already priced. Primary sources only: SEC EDGAR XBRL and filing text, national export statistics, supplier backlogs disclosed in filings. No sell-side estimates, no press figures where a filing exists, no forecasting. Every number traces to something already disclosed.
Two things were out of scope by design, and both matter to the story. Position sizing and portfolio construction were excluded. So was leverage, which is not a research finding and never will be. The agent’s job was to say whether the constraint exists and whether owning it has ever paid, not how much to borrow against the answer.
What the agent built in a day
The pipeline is six plain Python scripts, about 700 lines, pandas and numpy, no API keys, run in order. I have written before that the right thing to hand someone is the recipe rather than the binary, so here is the recipe at the level of detail you would need to regenerate it.
A registry script holds three dicts of tickers, resolves each to a SEC Central Index Key
from the SEC’s own company_tickers.json, and emits one JSON that every later script
reads. It carries two judgement fields. dc_share is my estimate of the fraction of each
buyer’s capex that is datacentre rather than warehouses or offices; nobody discloses it,
Microsoft gets 0.95 and Amazon 0.75, and every physical number downstream scales linearly
with it. price_only marks the foreign issuers, Samsung, SK Hynix, TSMC, Siemens Energy,
that file no US-GAAP XBRL and so contribute price history but no fundamentals. Hold on to
that flag.
A fundamentals fetcher hits EDGAR’s company-facts endpoint with a User-Agent, which the
SEC requires, and does three things a first version never does. It merges XBRL tags
across variants instead of taking the first match, because companies switch tags between
eras: first-match truncated Amazon’s capex history to nine quarters instead of forty-five
and NVIDIA’s revenue to twelve instead of forty-six. It derives discrete quarters by
subtraction for Alphabet, Meta and Oracle, which report year-to-date, and flags those
rows. And it keeps the filing date, not just the period end, because the backtest is
worthless without it. A price fetcher pulls ten years of daily adjusted closes from
Yahoo’s v8 chart endpoint, the one that still answers unauthenticated; v7 wants a crumb
and Stooq sits behind a JavaScript challenge.
The rule for the fetcher: Merge tags, derive quarters, keep the filing date. Each one looks optional. Each one silently truncated or fabricated data when it was missing.
Then the arithmetic. The gap script turns trailing-twelve-month datacentre capex into things, with every constant at the top of the file and its source beside it: $35 million per megawatt of IT load, PUE of 1.2, 7,000 square feet per megawatt, 65% of capex as IT equipment, HBM at 10% of that and $13 per gigabyte, a 450 megawatt turbine, 1.22 kilowatts per US home. On the August filings that comes to roughly 15 gigawatts of IT load, 18 gigawatts of grid draw, the equivalent of nearly 15 million homes, 104 million square feet, 2.6 exabytes of HBM, and forty turbines if all of it were gas. The figure below is that chain with the three assumptions that move the result most on sliders. Everything after the first box is an assumption you can see.
gap.py. Drag dc_share, the undisclosed fraction of capex that is
datacentre, and watch every output scale with it; then move the build cost and
PUE. The defaults reproduce the pipeline's own numbers. Nothing here is measured beyond the
first box; everything after it is an assumption you can see.The recipe prompt
Here is the brief in the form you would actually hand to an agent. It is the spec above compressed to what an agent needs to regenerate the pipeline in a clean directory, with the guards that a first attempt always omits written in as requirements rather than hints. Paste it, then run the six scripts it produces in order.
Build a research pipeline in a clean directory: Python 3.11 or newer, pandas, numpy, stdlib.
No API keys, no package, no tests, plain scripts run from the repo root in order.
THESIS. In a capex boom the spender's return is competed away and the seller of the
constrained input captures the rent. Find the gap between what AI datacentre buyers
have committed to spend and what the supply chain can physically deliver, name the
single tightest input, and test whether owning it has ever beaten owning the spenders.
Primary sources only. No sell-side estimates, no press figures where a filing exists,
no forecasting. Position sizing, portfolio construction and leverage are out of scope.
1. build_registry.py -> companies.json
Demand: MSFT AMZN GOOGL META ORCL (hyperscaler), CRWV NBIS APLD (neocloud),
DLR EQIX IRM (datacenter_reit). Supply: ~90 tickers grouped by the ACTIVITY they
sell into (compute_silicon, memory, networking, electrical, cooling, power_gen,
power_utility, nuclear, construction, materials, gas_midstream), not by sector.
Resolve CIKs from https://www.sec.gov/files/company_tickers.json, cache it, warn
and drop tickers with no CIK. Fields: ticker, cik, name, side, category,
dc_share (demand only, my estimate of the datacentre fraction of capex, e.g.
MSFT 0.95 AMZN 0.75), price_only (foreign issuers with no us-gaap XBRL:
Samsung, SK Hynix, TSMC, Siemens Energy, MHI, ABB, Schneider, Hitachi).
2. fetch_fundamentals.py -> data/fundamentals.csv
EDGAR companyfacts per CIK with a User-Agent header (403 without it). Metrics:
capex, finance_lease, revenue, cost_of_revenue, gross_profit, operating_income,
rnd, net_income, ocf, inventory, ppe_net, backlog_rpo, deferred_revenue, shares.
REQUIRED: merge all tag variants per metric, earlier tag wins conflicts; never
first-match (it truncates AMZN capex to 9 quarters and NVDA revenue to 12).
REQUIRED: derive discrete quarters by YTD subtraction for year-to-date filers
(GOOGL, META, ORCL), flag rows in a `derived` column, assert 80-100 day quarters.
REQUIRED: instants (inventory, ppe, backlog) bypass the subtraction path.
REQUIRED: keep the SEC filing date (`filed`) on every row, not just period end.
3. fetch_prices.py -> data/prices.csv
Yahoo v8 chart endpoint, range=10y, interval=1d, browser User-Agent, adj_close.
Include price_only tickers and SPY. Do not use v7 download (needs crumb) or Stooq.
4. gap.py -> data/gap.json
Constants at the top with sources: USD_PER_MW_IT=35e6 (range 30-40e6), PUE=1.2,
SQFT_PER_MW=7000, IT_SHARE=0.65, HBM_SHARE_OF_IT=0.10, HBM_USD_PER_GB=13,
DRAM_SHARE_OF_IT=0.05, DDR5_USD_PER_GB=21, TURBINE_MW=450, HOME_KW=1.22.
TTM demand capex weighted by dc_share -> IT MW, grid MW, homes, sq ft, HBM and
DDR5 exabytes, HA-class turbines. Print the arithmetic at every step.
5. categories.py -> data/categories.csv (reads data/gap.json and data/bom.json)
bom.json: split of one datacentre dollar across activities, sums to 1.00,
anchored to USD_PER_MW_IT, with a `note` field saying the shares are estimates.
Per activity from supplier fundamentals: rev_yoy, gross margin, gm_delta_yoy,
supplier_capex_yoy, backlog_yoy, then
tightness = z(gm_delta_yoy) + z(backlog_yoy) - z(supplier_capex_yoy)
with z winsorised at +/-3x IQR. Add `n` (suppliers with fundamentals) and a
`thin` flag when listed revenue < $25B or the category is mostly foreign filers.
Keep this method independent of data/supply.json. Never merge the two scores.
6. backtest.py -> data/backtest.csv
Filing-event panel: per ticker per quarter, features (capex_yoy, capex_qoq,
capex_intensity=capex/revenue, gross_margin, gm_delta_yoy, inv_to_rev,
backlog_yoy) and forward returns at 21/63/126/252 trading days, absolute and
excess vs SPY. Entry = first trading day AFTER `filed`. REQUIRED: skip filings
dated before the first price bar (they clamp and fabricate duplicates).
Report per-quarter cross-sectional rank IC with mean, t-stat, hit rate and n for
EVERY feature including failures; tercile spreads on 12m excess return; basket
curves for DEMAND (5 hyperscalers), BOTTLENECK (MU + SK Hynix + Samsung),
POWER (turbine OEMs), SUPPLY (hand-picked, LABEL AS CONTAMINATED), SPY.
data/supply.json is hand-curated: physical indicators (Korean chip export value
AND tonnage, DRAM contract price, HBM sold-out status, turbine backlog, grid
interconnection queue), each with source URL and as_of date. Flag value-up /
volume-flat divergence explicitly.
OUTPUT. Three dated reports: demand_<date>.md (latest filing per buyer, discrete
quarter capex and sequential change, at least one verbatim sentence per filer
explaining the change with filing and section cited, dollars to physical units with
working shown, anything contradicting the narrative flagged), bottleneck_<date>.md
(four indicators ranked by physical headroom and substitutability, one input named,
who controls it), activities_<date>.md (tightness table with coverage and thin flags).
Every report ends with a Known Limitations section: selection bias on hand-picked
baskets, cross-section size, single regime, no costs, dc_share is an estimate,
foreign suppliers missing from fundamentals. State at the point of use whenever a
number rests on an estimate rather than a disclosure. Do not delete contaminated
results; label them.
That block is the whole project. Everything in the sections that follow came out of running it.
What it found, twice
The agent was asked for one input with the least room to grow, and it was asked to find it two ways that share no data. The first is from filings only. Map suppliers to the activity they sell into, not the sector an index files them under, and per activity compute gross margin expansion, backlog growth and the suppliers’ own capex growth. Rising margin is pricing power; rising backlog is unmet demand; rising supplier capex is supply responding. Z-score each, winsorised at three interquartile ranges because two small nuclear names had capex growth above 3,000% off a near-zero base, and combine:
tightness = z(gross-margin expansion) + z(backlog growth) - z(supplier capex growth)
Memory scored +4.79. Compute silicon +1.59. Everything else below +0.6, and networking at -1.66 because supplier capex there doubled. The memory number rests on a 23 percentage point gross margin expansion, which is not a figure you see often.
The second method is physical and hand-curated: Korean semiconductor export value and export tonnage, DRAM contract prices, heavy-frame turbine backlogs, grid interconnection queues, each row with a source URL. The signature of a real constraint is value rising while physical volume is flat or falling, and the memory row had exactly that: export value up sharply year over year while export weight fell. Gas turbines have a longer backlog, but a datacentre can take grid power or site elsewhere; nothing substitutes for memory in a training cluster. Two independent methods named the same input, and the agent was told never to merge them into one score, because their agreement is the evidence and a merged number is one opinion instead of two witnesses.
Then the backtest, which is where the story turns. Build a panel of every filing event with features from that quarter’s facts and forward excess returns over SPY at one, three, six and twelve months, entering the trading day after the filing. Rank information coefficients per quarter for every feature, and report all of them. Five of six had no power. The one that did was capex intensity, capex over revenue, with a mean IC of -0.185 and a t-stat of -3.23 against twelve-month returns. Negative. The heaviest spenders relative to revenue underperformed the lightest by about 25 percentage points over a year. That is the asset growth anomaly Cooper, Gulen and Schill documented in 2008, replicating inside the AI complex. Capex growth, who is spending more, predicted nothing. Capex relative to revenue predicted the spender losing.
The basket comparison says the same thing from the other side. Since the start of 2023 the three DRAM makers returned about 1,570% against roughly 230% for the five hyperscalers, with the best Sharpe in the set. Owning the constraint beat owning the spender by about seven times.
What that says about the trade
Put the finding next to the fire sale. The two names reported leaving the book at a
discount were SK Hynix, which is the constraint, and CoreWeave, which is a spender with a
dc_share of 0.98 and one of the highest capex intensities in the panel. The agent’s
signal treats those as opposite legs. Its default trade expression, written into the
generalisation spec, is the spread: long the constrained-supplier basket, short or
underweight the demand cohort, because both legs express the same thesis and the spread
strips out the market beta that flatters any single-leg backtest run through a bull
market. Long both is not the thesis. It is the beta.
What the agent would and would not have said: Memory is the constraint, from two independent methods. Heavy spenders lag. Express it as a spread. Nothing about how much to borrow, because sizing was out of scope and a research output is not a risk model.
I do not know the fund’s book beyond what was reported, and a backtest that agrees with a trade is not evidence the trade was well constructed. What I can say is narrower: the thesis survives a primary-sources rebuild with no lookahead, and the part that failed in July, the leverage, is the part no research pipeline can produce and this one was told not to try.
What the agent refuses to claim
This is the section that took the most space in the reports, and it is the part I would
regenerate first. The SUPPLY basket was hand-picked in August 2026 knowing who had won;
its returns are labelled contaminated in the output rather than deleted. The defensible
comparisons are complete universes with nothing to pick: five of five hyperscalers, three
of three DRAM makers, three of three heavy-frame turbine OEMs. The cross-section is twenty
tickers, so the t-stats are optimistic. It is one regime, and capex intensity may just be
shorting the spenders during a cycle when the sellers won. No costs, no borrow, no
slippage, and the short leg of the spread makes those material. The physical indicators
file goes stale silently because nothing refreshes it.
What it proves
- Two independent methods name memory as the binding input
- Capex intensity, not capex growth, carried the cross-sectional signal
- Complete-universe baskets can be compared without selection bias
What it does not
- That the signal generalises beyond one cycle
- That any of it survives costs and a short leg
- That the hand-picked supply basket means anything
And the caveat that goes straight back to the opening scene: foreign suppliers have no fundamentals, and they are disproportionately the constrained ones. The memory tightness score is computed from the four US-listed names in the category, Micron plus three NAND and hard-drive makers, which is a different market from DRAM. SK Hynix and Samsung, two of the three companies the finding is about, and the first of them the stock in the headline, contribute nothing to the number. The score may well be right. As computed it is close to a single-company observation wearing a category label. Supply chains concentrate offshore by construction, so a supply-side agent that only reads US-GAAP is structurally blind to the supplier it is looking for. An IFRS handler is the prerequisite before this is trusted on any other theme.
Building the agent that does this every quarter
One theme, one regime, two methods that agreed once. That is n=1, and the temptation is to generalise it into an agent that screens every sector for the next constrained input. I wrote that spec, and its first requirement is a gate that decides whether the agent should exist at all. Assemble at least four historical capex cycles that were discoverable point-in-time before 2023, so the AI cycle is out of sample: shale, the fab buildout, EV batteries, 5G, LNG, utility solar. Build each chain by hand. Compute tightness strictly point-in-time. Test whether it predicted supplier returns. Proceed only if the signal clears a pooled t-stat of two with the predicted sign across at least four themes. Otherwise write the negative result and stop, because a generalised agent built on an unvalidated score is a machine for producing confident nonsense at scale.
The design that follows the gate is a funnel, not a pipeline. The filings-only layer is cheap and runs across every sector every quarter; the physical layer is expensive and manual and is applied only to the top three candidates a run produces. The bill of materials becomes optional, because ranking tightness needs only the supplier-to-activity map. Themes must be selectable from data available at the screen date, never hand-picked in hindsight, which is the single trap the AI instance fell into on one basket. And before any finding becomes a trade it passes an expressibility gate: a listed pure-play supplier is tradeable; a diversified one is tradeable with a haircut; a proxy is flagged as a proxy; and an input with no listed expression, labour for instance, is a research output and never silently converted into a trade.
The output of a run is a ranked list of hypotheses with a verdict on each, and the spec says in so many words that most themes must come back “no edge.” That is the property I care about most. An agent that finds a bottleneck in every sector is not finding bottlenecks. It is finding the prompt.
The fund in the opening paragraph was, by the reporting, right about the input and wrong about the borrowing. The agent I would want running this every quarter is one that can reproduce the first half from filings and customs data, say clearly which half of its own evidence is thin, and has no field for the second half at all. It is not investment advice and it is not a strategy. It is a harness for a thesis, with a stop rule, and the stop rule is the part to keep.



