Will ChenWill Chen
← writing

Project Cyborg$27k of compute pointed at my own life

system design9 min

A startup I had left behind me came with $150,000 of Azure credits. They were down to $27,000 by the spring, with an expiry date on them, and I could not think of a single thing to do with them that I actually wanted.

The problem is stranger than it sounds. I write about wanting leverage constantly. I had fifteen years of my own writing sitting in a folder, indexed and embedded. I had agents that could run in parallel without supervision. And I sat there with a working superpower and no idea what to point it at.

Below is what I did about it, and what forty days of pointing compute at my own life actually returned.

The constraint was never compute

The first thing I had to give up was the assumption that the credits were the scarce thing.

Compute stopped being a limiting resource some time ago. If I want a hundred thousand model calls I can write a script this afternoon and have them by morning. I could not say what those calls should be for. Everything I actually wanted turned out to need a system around the calls rather than more of them, and a system is the part that costs attention.

Attention is the resource in genuinely short supply, and it is the one thing more calls cannot buy. Ask a vague question ten thousand times and you get ten thousand vague answers, which is a reading problem stacked on top of whatever problem you started with. The credits could produce text far faster than I could ever read it.

So the question stopped being what to build with the credits and became something narrower: what kind of system converts compute into value reliably enough that adding more compute adds more value?

I ended up calling that compute market fit. A system has it when the only thing standing between it and more output is more compute. Most systems do not have it. You drive compute into them and they produce noise, or they produce good work that nobody has the attention to consume, and either way the marginal dollar buys nothing.

Finding one of those systems was the actual experiment. Everything else was apparatus.

Deploy it in chunks small enough to abandon

$27,000 is not an amount to deploy cleverly. Cleverness needs a plan, a plan needs a hypothesis, and I had no hypothesis worth $27,000.

It is fifty-four separate experiments at $500 each. That number is chosen for one property: $500 is enough compute to get a real answer from a real corpus, and small enough that I will abandon the approach without arguing for it. Run one a day, write down what happened, and let the next day's design come from the last day's result.

Forty days of that, one experiment a day, each one written up. The commitment was to the cadence rather than to any particular idea, because I did not have a particular idea and pretending otherwise would have produced a plan I defended instead of a search I ran.

Three things were ruled out from the start, and ruling them out is most of what made the rest tractable.

  • No product. Turning credits into a thing to sell converts an open question into a roadmap, and I had no evidence yet about which direction was worth committing to.
  • No revenue. Compute goes into capability, never into a business model. A credit spent proving that a structure works is worth more than the same credit spent generating billable output, because the structure survives the credits.
  • No forward observation. Nothing waits for new data. Every program reads history.

That last one is the one that made the whole thing possible, and it deserves its own section.

Compute over history rather than over the future

Most systems that watch you are forward-looking. They observe from the moment you install them and get more useful as they accumulate. Which means the day you turn one on, it knows nothing, and the interesting results are months away.

I already had the accumulation. Fifteen years of journals, chat logs, voice transcripts and notes, dense and already embedded. So the experiment could run backwards: compute over history rather than over forward observations, which turns a cold start into a warm one and makes the corpus the asset rather than the schedule.

That inverts what compute is for. Instead of watching and waiting, the system samples what already exists, many times, from many angles. I had been doing a version of this by hand for a while, running three hundred subagents to pre-generate syntheses of things I might need the next day and then sampling from them. Project Cyborg is that instinct with an accounting layer attached.

The accounting comes before the research

The ledger was built before any research program, because an experiment that cannot say what it spent is not an experiment.

Every model call goes through one wrapper, which appends one line to a file:

interface LedgerEntry {
  ts: string;              // ISO timestamp at completion
  runId: string;
  program: string;
  model: string;
  inputTokens: number;
  cachedInputTokens: number;
  outputTokens: number;
  costUsd: number;
  ms: number;
  ok: boolean;
  error?: string;
}

Nothing else is allowed to be the source of truth. A database exists for querying and gets rebuilt from the file, so a disagreement between them is settled by throwing the database away. Failed calls land there too, since a run that errored still cost tokens.

Three append-only files hold everything the engine knows about itself, and their line counts are the shape of the experiment:

engine/data/ledger.jsonl       6,211   one line per model call, with its cost
engine/data/runs.jsonl        12,282   lifecycle: run_start, run_end
engine/data/frontier.jsonl       413   one line per open question

The lifecycle file carries 6,211 run_end events against 6,061 run_start events. The gap is the useful part: a hundred and fifty runs ended without a recorded start, because I restarted the engine five times mid-flight. A file that recorded only completions would have shown a clean number and hidden every interruption.

The runner enforces a hard stop well below the available credits, computed from estimates rather than billed figures, because in the first engine those two diverged by a large factor. The watchdog sits where being wrong by that factor still cannot spend real money.

Repetition across independent samples is the cheapest signal detector

Ten programs ran. The one that mattered most is the simplest.

ensemble asks the same question many times, each from a different sample of the corpus, independently, and then counts. An idea appearing in one run is a model producing plausible text. An idea appearing in most of them is a property of the material.

Only someone with compute to burn can do this. A single expensive answer and forty cheap independent ones cost about the same, and only the second tells you whether the answer is in the corpus or in the model. Independent repetition converts surplus compute directly into confidence, which is as close to compute market fit as anything I found.

The other programs are variations on where to point it: connections across documents I never stated in one place, mechanisms for frictions that keep recurring, ideas that must come back with a test and a kill criterion, and a synthesis pass every forty runs or so over everything produced since the last one.

Models are routed rather than pooled. The strongest model gets the fewest slots and the questions needing a mechanism; the cheapest gets the most slots and the questions needing volume:

export interface Program {
  name: string;
  model: string;
  weight: number;                     // scheduler weight
  charBudget: number;                 // packet size, ~4 chars per token
  maxOutputTokens: number;
  weights?: Record<string, number>;   // packet collection mix
  buildSystem: () => string;
  buildPrompt: (packet: Packet, seed: number, extra?: string) => string;
}

The corpus is a read-only local snapshot, and the sampler that draws from it is seeded and reproducible. An experiment that mutates the material it studies cannot be re-run, and this material is the record I actually live in.

The sampler weights are where I got it wrong, and the comment I left when I fixed it is the finding:

// Weights are per-COLLECTION, so per-file draw odds = weight / file count. logs (79 files)
// and profile (~100) were being oversampled ~19x/file vs claude (5,225 files) at the old
// 0.10/0.05 weights — thousands of redundant re-reads of the same few dense files.

A weight that reads as a preference between collections is a preference between files once you divide by how many files each collection holds. Nothing reports it. Every draw is legal, every packet looks varied, and the only symptom is the same material arriving under different seeds.

What it returned

The output is a file of attractors: claims that kept re-emerging across independent samples, each with the number of waves it survived and a pointer to its strongest evidence.

1) Append-only trace/artifact substrate is the missing primitive     12 waves   stable
2) The product wedge is a source map for intelligence                 5 waves   strengthening
3) The right unit is a persistent executable artifact, not chat      11 waves   stable
4) The stall is failure to freeze one minimal runtime contract        9 waves   stable
5) Reality contact belongs in a compiler or gate, not a philosophy   12 waves   stable
6) The trust membrane is a receipt and checkpoint layer                8 waves   stable

Two of those changed what I did next.

The fourth one is about me, and I did not ask for it. Nine independent waves converged on the same diagnosis: the repeated stall is not a lack of architecture, it is reaching the right abstraction and then refusing to pin one boring end-to-end contract and one proving case. I have been told versions of that by people. Hearing it from nine independent samples of my own writing is different, because the evidence is entirely mine and the reading has no stake in being kind.

The first and third together decided the next year of building. An append-only substrate where runs, documents, decisions and learnings are all first-class artifacts with lineage, and a persistent executable object rather than a chat, are the two things that show up everywhere I have built since.

So $27,000 of compute bought me a small number of claims about my own work, each one having survived being sampled from many angles, with the wave counts attached so I can tell how hard each is to dislodge. It bought no product, no revenue and no body of essays.

The engine could not learn between waves

For most of its life the thing was open-loop, and the ledger could not see it.

Synthesis generated exactly three questions for the next wave and kept a short list of unresolved ones. Those questions went into a markdown file, and nothing read them.

Every indicator said the system was healthy. Runs completed, artifacts got written, syntheses produced good questions about those artifacts. The failure was visible only in the content of successive waves: the same five convergences kept re-emerging, so marginal insight per dollar was falling while spend held flat.

The question that named it, put to my own system, is the one worth stealing: are we making an agent or just making random calls? An open-loop controller acts without measuring what its action achieved, which describes a heater with no thermostat and described this engine exactly. Every wave started at a fresh random sample, because the sampler had no access to anything the synthesizer had learned.

The fix is one harvester scraping questions out of the synthesis prose into a line-delimited file:

{"ts":"2026-06-11T19:13:28.725Z",
 "q":"What is the minimal process primitive that unifies organs, documents, triggers, and agent runs?",
 "source":"2026-06-11181420-synthesis-00193.md"}

The source field is what makes it a loop rather than a queue, because every question walks back to the artifact that raised it. Two programs consume it, and each returns a verdict rather than prose:

frontier-chase   answered | needs-data | wrong-question
deepen           promote  | revise     | kill

Three verdicts, not two. A binary forces every question into settled or unsettled, and the third option in each row carries the information the pair throws away. A needs-data verdict has to design the experiment that would settle the question, so the cheap answer of declaring more evidence necessary costs something to give.

It seeded with 134 questions pulled from 26 synthesis files and now holds 413. The mechanism transfers: a feedback loop needs a machine-readable channel between its halves, and prose is not one. The synthesis output was always full of good questions embedded in paragraphs, which is a format only a human can act on, and a human acting on it was exactly what the experiment could not afford.

What I would tell someone with a block of expiring credits

Compute buys one person very little on its own. The binding constraint is attention, and no quantity of calls relieves it.

Compute buys the ability to run a structure many times, which makes the only question worth asking which structures survive that treatment. These did, in the order they mattered:

  • an accounting layer you trust, built before any research program
  • a corpus the engine cannot write to, and a sampler reproducible from a seed
  • history rather than forward observation, so the system starts warm
  • independent repetition rather than single answers, since repetition is what separates a property of the material from a plausible sentence
  • a machine-readable path from what the system learned back to what it does next
  • trajectory capture, which the ledger still does not provide and which belongs above every research program on this list

The last one is the gap I named on the first night and never closed. The ledger records that a call happened and what it cost, and nothing about how the run got there, so a good run and a lucky run are indistinguishable in the record and nothing downstream can learn what made a program work.

The first engine had most of that list, ran well, and could not accumulate. The distance between a system that produces and a system that improves was one file and a consumer for it, which is the cheapest item here and the one everything else was waiting on.