How I work

The machine behind the output

I ship more than one person should be able to. This page describes the system that makes that possible, and the checks that stop it producing confident nonsense.

The argument

Anyone can get an agent to write code

An agent, here, means an AI tool given a task and allowed to act on its own for a while — reading files, writing code, running commands — rather than answering one question at a time. Getting one to produce code is easy; knowing when to believe the result is not, and that does not come from better prompting. It comes from structure: written contracts, provenance requirements, limits enforced in code, and independent verification.

What follows is the architecture I run, not a description of best practice.

Architecture

One orchestrator, many narrow workers

A single orchestrator running the strongest model available holds the plan and makes the judgement calls. It does not do the work. It delegates almost everything, and the reason is the single most important design constraint in the whole system.

The orchestrator topology One orchestrator holds the plan. It delegates reading and implementation to subagents that fan out in parallel, each with its own model tier and permission scope, and returns conclusions rather than file contents. owns the plan and the judgement calls; deliberately keeps its own context lightorchestratorstrongest model per-repo and per-agent context: structure, conventions, what must never be touchedcontext filesconventions · hard rules explore: fast · read-onlyexplorefast · read-only implement: mid · write, no gitimplementmid · write, no git review: strong · read-onlyreviewstrong · read-only verify: fast · read-onlyverifyfast · read-only a barrier is used only when a stage genuinely needs every prior result at oncebarrieronly where earned anything irreversible or public stops herehuman gate → merge results return as conclusions, not file dumps
What you're looking at: the shape of a run. Context files feed the orchestrator what it needs to know about the repository before it starts. Work fans out to subagents in parallel, each with its own model tier and its own permission scope. Results come back as conclusions rather than file contents, and anything irreversible stops at a human gate. The architecture as run · hover any box for its scope

Context discipline is the design constraint, not an optimisation

An agent's attention is finite, and as its context fills, quality degrades gradually and invisibly. No error, no warning, just steadily worse judgement — the one failure mode you cannot catch by watching, so it has to be designed against up front.

So the orchestrator is instructed to keep its own context light. It delegates reading rather than reading into itself, and subagents return conclusions instead of file dumps. An orchestrator that has absorbed forty files is blunt. One that has absorbed forty summaries is still sharp, and can still hold the whole plan.

Context budget over a session Conceptual, not measured. An orchestrator that reads everything itself fills its context and degrades; one that delegates reading and receives summaries stays sharp for far longer. reads everything itself delegates reading full empty session length → CONCEPTUAL — the shape of the problem, not measured data the failure mode is gradual and invisible, so it is designed against up front
What you're looking at: the shape of the problem, drawn rather than measured. One curve is an orchestrator that reads everything itself and fills up early; the other delegates reading and stays usable for far longer. This is a conceptual diagram and is labelled as such — there is no dataset behind it, and on this site that distinction matters. Conceptual · not measured data

Context files as durable infrastructure

An agent that rediscovers a codebase every session wastes most of its budget doing it, so each repository and agent role carries a context file: where things live, the conventions, the hard rules, what must never be touched. The repository-structure map is a maintained artifact, not a byproduct.

Two of these are real and public in effect. One is the operating contract for my knowledge base, described below. The other is the rules file in the repository for this website, which carries a table of six figures that were retired as wrong — so that a future agent editing this site cannot quietly reintroduce them. The constraint lives where it will be enforced, not where it will be remembered.

Dispatch by difficulty

Not every task deserves the strongest model. Renames, greps, boilerplate, mechanical refactors and formatting go to fast cheap models at low reasoning effort. Ordinary implementation goes to the middle tier. The strongest model at the highest effort is reserved for architecture, ambiguous debugging and adversarial review. The orchestrator makes that call per task rather than the whole session running at one setting.

The economics are not subtle: running everything at maximum is slow and expensive, and a rename does not benefit from deeper reasoning.

The dispatch ladder Task difficulty decides the model tier and the reasoning effort. Mechanical work goes to fast cheap models; the strongest model is reserved for architecture, ambiguous debugging and adversarial review. mechanical: renames · greps · formatting · boilerplatemechanical renames · greps · formatting · boilerplate fast model, low effort standard: implement a described change · write testsstandard implement a described change · write tests mid model, medium effort hard: architecture · ambiguous debugging · reviewhard architecture · ambiguous debugging · review strongest model, high effort the orchestrator makes this call per task, not once per session
What you're looking at: which kind of work goes to which tier. The examples on each row are real categories from my own runs, not illustrations. Dispatch policy as configured

Parallelism, with barriers only where they are earned

Independent work fans out concurrently. The instinct is then to wait for all of it before the next stage, and that instinct is usually wrong. A barrier is only justified when a stage genuinely needs every prior result at once: deduplicating across a complete set, or exiting early because there was nothing to find.

Otherwise the work pipelines, so one item can be in its third stage while another is still in its first. The wall-clock cost is then the slowest single chain rather than the sum of the slowest step in each stage. Where agents would edit the same files, each gets an isolated copy of the repository so they cannot collide.

Permissions scoped per agent

Every agent class gets the narrowest scope that still lets it work. Read-only explorers cannot write. Implementers can write but cannot touch version control. Anything irreversible or public — a push, a deploy, a deletion, a published document — stops at an explicit human gate.

Permissions and gates Each agent class gets the narrowest scope that lets it work. Anything irreversible or public stops at an explicit human gate. read write git publish explorer yes no no no implementer yes yes no no reviewer yes no no no me yes yes yes yes push · deploy · delete · publish → always a human gate this site was built across five rounds on a branch never pushed unreviewed
What you're looking at: what each class of agent may touch, and where the gates sit. The dashed column on the right is the set of actions no agent performs unattended. Permission model as configured

This website was built across five rounds on a branch never pushed without my review. Not caution theatre — the control that makes the autonomy safe to grant.

Provenance

Every claim carries its source, and "not found" is a legal answer

Anything the agent writes into my knowledge base is tagged with its source: a dated attribution, a version-control log, a file path. Unconfirmed claims are marked as such.

The rule doing the real work is that the agent must never invent a fact, a number or a date, and that NOT FOUND is a valid and preferred answer. Hallucination is not prompted against; it is designed out by making the absence of a fact something the output format can express.

The contract the knowledge base runs under

I produce thought; the agent owns structure. It files, links and propagates, and never asks me where something goes. Autonomy is stated up front as file freely, report after: placement is the agent's call and I veto afterwards. Ambiguous items stay queued rather than placed — an unfiled note is recoverable, a misfiled one vanishes — so the agent is told which way to err. Routing keys on what kind of fact something is rather than its topic, which makes it decidable. Questions are batched to the end and capped at five.

It also names its own anti-patterns. One tracking file is capped at five rows, because I once over-built a nineteen-item registry with a dashboard and retired it; if it wants to grow, that is a signal to raise with me. The tag vocabulary is closed at five: one that grows without resistance stops separating anything. Blast radius is bounded too — two directories frozen, two files append-only, no version-control access.

Guardrails

Enforce it in code, because a prompt is a hope

The clearest example is the market-data portal. Telling a model not to leak internal material is a hope; a build gate that fails the build when it happens is a guarantee. That gate exists because two real leaks got past an earlier exclusion operating at the rendering layer rather than the build layer.

tools/check_no_leaks.mjs — the gate that fails the build

let leaks = 0;
for await (const file of walk(distDir)) {
  const text = await readFile(file, 'utf8');
  for (const { pattern, why } of FORBIDDEN) {
    const match = text.match(pattern);
    if (match) {
      console.error(`LEAK  ${relative('.', file)}\n      matched "${match[0]}" — ${why}`);
      leaks++;
    }
  }
}
if (leaks) {
  console.error(`\n${leaks} leak(s). Internal material must not ship. Fix before deploying.`);
  process.exit(1);
}

tools/extract_sample.py — refusing to guess

    raise NotImplementedError(
        "Archive layout unknown — see docs/schema.md 'File layout' [VERIFY]. "
        "Do not guess a partition scheme; confirm it first."
    )

Eight functions in that file raise rather than return. A half-built extractor emitting a plausible sample is worse than one that does not run: the sample is what a buyer checks the dataset against.

Acceptance criteria

Decide what counts as success before the run

In the research work this is literal pre-registration: a written specification committed to version control, with a timestamp, before any result exists. It is what let me report that my own model failed its primary test rather than re-cutting the metric until something passed.

The same device works on agent output. Decide what done means after seeing the output and you will grade it on whatever it happened to do. This is worth one sentence of context, because it is not obvious from outside: reporting a result that went against you is rare, and the reason is an incentive. When something comes out flat, the quiet option is to adjust the measurement and try again until it looks convincing, and nobody can tell afterwards. Fixing the target in advance removes that option.

Fan out, then reconcile

I surveyed 53 project directories across parallel agents, each entry recording the surveying agent, a confidence rating, and a flag for credentials or personal data. What mattered was the reconciliation afterwards: twelve ambiguities resolved by hand — which checkout was current, whether two repositories were one project, three similarly-named directories that proved unrelated. Fan-out is the cheap half; skipping reconciliation is how you get a confident, internally inconsistent answer.

Propagation, not filing

The agent's real task is checking new facts against what is already recorded. Two catches, both against me.

Contradiction caught

A note about running an investment fund contradicted a career file that still listed starting one as a future goal. The goal was wrong; the fund already existed.

Overstatement caught, corrected downward

A build inventory claimed two founded ventures. Checking found that one was a five-person university course project and the other a solo side product with no revenue. Both CV bullets were rewritten downward, and both now read that way on this site.

Open source

The contract itself,
public and MIT.

Gates that refuse an unproven claim

The contract above is written down and published rather than re-improvised per task. default-fail is git hooks, subagent definition files, criteria files and shell scripts — nothing imports it and nothing runs a supervisor process. Every criterion starts at fail, and only a citation that resolves moves it: a file:line I can open, or a command with its real output. The grader is a read-only subagent working from a context that never saw the work being produced. Until the hooks are installed none of it is enforced, and the repository says so in those words rather than implying otherwise.

The part worth reading is not the workflow, though. It is that the instruments get tested too. A claim-checker I had written to catch fabricated numbers returned ok on the exact fabrication it was built to catch: its mask for version-like tokens was \d+\.\d+, which also matches 0.66 and 0.001 — every p-value in the corpus. Masked tokens are stripped before comparison, so it deleted the entire class of number it existed to check, then reported success having examined nothing. It printed tokens it checked: [], which nobody read.

That one is written up with the rest, including the gates found broken while the proof suite was still green. The repository carries the detail; this page does not try to.

default-fail on GitHub →

Case study

This website, and the six errors the pipeline caught

This site was built by the system described above, across five rounds. The point of the list below is not that the agent was right — it is that these were found, by checks that existed before the work started.

  • A verification harness that lied. The mobile-overflow check reported failures that were not real, because headless Chrome on Windows clamps the window size and crops the screenshot instead of reflowing the page. Rebuilt on the browser's debugging protocol so the viewport is genuinely emulated.
  • Five of eight figures silently broken. The chart generator emitted unclosed elements — harmless while the markup sat inside a page, fatal once the same file was loaded as an image and parsed strictly. Caught in a dark-mode screenshot showing alt text where a chart should have been. The generator now validates every figure before writing it.
  • Identifiers leaking on an embargoed page. Shortened market identifiers are effectively unique within the corpus, so publishing them alongside per-market statistics would have identified specific markets. Pseudonymised, and the page now forbids pasting the raw documents in.
  • A contrast failure no amount of tuning could fix. A colour-shaded table could not hold legible text in both light and dark themes at any shade. Replaced with a value-and-bar encoding at 18:1.
  • Two numbers that disagreed. Prose said one figure was 27 times another; the published data divided to 28. One had been computed on averages and the other on medians. A reader could have checked it in seconds.
  • Content hidden behind JavaScript. A scroll animation hid every below-fold section and handed visibility back via script — what the rules forbid. Caught by the check that loads every page with scripting disabled.

Verification

Check what the agent says it did

Gates run before anything merges: contrast across every colour pair in both themes, layout at two widths, prohibited-content sweeps, and idempotence checks on every generator so a stale figure is detectable rather than silent. The agent proposes; I merge.

Just as important, the agent reports what it did not verify: no Lighthouse score appears on this site, because Lighthouse was never run.

Where I am taking it next

Planned, not built. The next piece is a knowledge graph agents can navigate instead of searching: entities and relationships across repositories and notes, so an agent asks what depends on a thing and traverses to the answer rather than grepping and hoping.

It does not exist yet. I am labelling it that way deliberately — a page arguing for trustworthy process that overstated its own maturity would refute itself.