Workbench

devour

A fresh agent walks into a codebase like a tourist. devour makes it learn the city first: where things live, when they get busy, and what else moves when one street closes.

Stage
Understand
Since
Jun 2026
Leaves
MAP.md
“My pain problem is every time I start fresh with an agent, I asked it to 'DEVOUR' the codebase.”
Me, Jun 2026

Know the city before you build in it

Every new session starts from zero. The agent can open fifty files and summarize each one, and still have no idea that changing a helper in one corner breaks a page in another. I kept typing the same word at the start of every session, so I turned it into a skill.

The brief I wrote for it was about a city. A local knows the streets, and also knows the rhythm: which roads jam at eight, which ones are empty at noon. Opening many files doesn't count. The agent has to be able to answer practical questions about a change, with evidence.

“Think of it like going through every crack of a city. Not only are they spatially aware, they're also timely aware: where is packed, where is quiet, what time is busy.”
Me, Jun 2026
  1. 1 · Spatial

    Where does everything live?

    Packages, boundaries, entrypoints, routes, schemas, shared modules, config, scripts, generated code.

  2. 2 · Temporal

    When does it get busy?

    Boot order, the request lifecycle, state transitions, jobs, retries, caches, deploys, and which areas churn.

  3. 3 · Intuition

    If this moves, what else does?

    The likely callers, consumers, side effects, tests and fragile assumptions around any piece you touch.

The three layers devour builds. The third one is what the first two are for.

If you touch this, inspect that

The most useful line in a map is a warning. Here is a small one for the site you are reading. Pick a file and see what it reaches. Every edge was checked against this repo's imports.

If you touch

projectPath()decides where a project link goes.

Inspect these first

  • Home project rowsEvery row's href comes from it.
  • Command paletteProject commands push to it.
  • /projectsThe list links through it.
  • profile.tsBuilds each project's public URL with it.
  • site-discovery.tsBuilds each project's sitemap URL with it.

Then one step further out

  • /ai-profile.jsonShips the project URLs profile.ts built.
  • sitemap.xmlWhat search engines crawl.
  • /site-infoMirrors the sitemap for people.

The map flagged this one. On 26 October it said the home rows and the palette each hardcoded /projects#slug, so a dedicated project page would have to change both. Both moved onto this one helper that day.

Blast radius on hadimulia.com. Inner ring: files that import the one you touched. Outer ring: what those files feed.

Trace a route from trigger to consequence

A list of folders tells you where code lives. A route tells you what happens. devour traces the important ones end to end, from what sets them off to what comes back. Here is the route an AI crawler takes when it asks this site who I am.

  1. 01 Trigger

    GET /llms.txt

    An AI reader asks what the site is.

  2. 02 Entrypoint

    app/llms.txt/route.ts

    A GET handler, marked force-static.

  3. 03 Domain logic

    getLlmIndex()

    site-discovery.ts assembles the sections.

  4. 04 Data

    profile.json, skill-pages.ts

    Read at build time. No database, no network.

  5. 05 Side effects

    None per request

    Rendered once per deploy and served from the cache.

  6. 06 Response

    text/plain

    The same text every reader gets until the next deploy.

trigger → entrypoint → domain logic → data → side effects → response, traced through this repo.

How time moves through it

Architecture diagrams are frozen. Real systems have a clock: what runs before anything else, what is cached and for how long, what fires on a schedule. This layer is what turns knowing the layout into knowing how the system behaves.

  1. Before first paintlayout.tsx

    An inline script applies the stored theme so the page never flashes the default.

  2. Each deployVercel, on push to main

    Static routes like /llms.txt and /ai-profile.json are rendered once.

  3. Daily, 06:00scripts/ai-stats

    A launchd job on my Mac collects AI usage and uploads aggregates.

  4. Hourlylib/ai-stats.ts

    The AI activity panel refetches those aggregates. If the fetch fails, the panel hides.

  5. Every 30 sSpotifyNowPlaying.tsx

    The Spotify pill polls now-playing. The route itself caches for 20 seconds.

This site's temporal map, from the rarest event to the most frequent.

The blank regions stay on the map

One rule in the skill does a lot of work: a map that hides its blank regions is worse than no map. A stranger trusts a clean-looking map and walks straight into the part nobody checked. So the unknowns get their own section, each with the probe that would close it.

  • MoroMailMapped

    Renderer, stores, packages

    51 bundled packages, the write path, the startup sequence.

  • MoroMailUnknown

    Native sync engine

    Task handlers, migrations, schema changes and retry rules live outside this checkout.

  • FleetwatchMapped

    Fleet screen

    Launched and rendered live against three real machines.

  • FleetwatchUnknown

    Cloud view

    Never seen rendered. A macOS privacy prompt sat over the window and was deliberately left unanswered.

  • hadimuliaMapped

    Sitemap and llms discovery

    Checked live after deploy.

  • hadimuliaUnknown

    Bot traffic by IP

    Source IPs weren't in the request logs available, so verified crawler access stays unproven.

Real entries from three of my atlases. Hatched regions are the ones the map admits it hasn't seen.

Eight questions decide whether it's devoured

Before the agent can say it knows the codebase, it has to answer these eight with evidence. If it can't, it says the repo is partially devoured and lists what to probe next. That sentence is allowed. Rounding up is not.

Spatial
  • Where does the app start?
Temporal
  • How does a primary user action move through UI, API, data, and side effects?
  • Where is state stored, cached, transformed, and invalidated?
Intuition
  • Which modules are safe extension points?
  • Which modules are risky because they are shared, temporal, or under-tested?
  • If a schema, route, component, helper, or config file changes, what else must be inspected?
Proof
  • Which commands verify the important paths?
  • What did live probes prove, and what did they fail to prove?
All eight, with evidence

Devoured. Ready for the changes the map supports.

Any gap

Partially devoured, with the next probes listed.

MAP.md is a checkpoint

The study ends in one file at the repo root, so the next session starts from a checkpoint. The rules keep it honest. It is one file, readable in one sitting. Every update is stamped with what was studied and against which revision. A later run reads it as claims to verify, and a refresh sorts every old claim into one of four buckets.

Session one

Study

Census, topology, routes, time, blast radius, probes.

MAP.md
  • stamp: mode
  • stamp: date
  • stamp: source revision
  • stamp: scope
  • stamp: dirty paths
A later session

Refresh

Reads the map first as claims to verify, then studies only what changed.

  • Newly verified

    Checked again against the current code.

  • Invalidated

    No longer true. Replaced or marked stale.

  • Inherited, not rechecked

    Kept with its old date. Never restamped as fresh.

  • Unresolved

    Still open, with the probe that would settle it.

Read next bybedrock to orient its audit walkpotential as the structure to dream fromvision as the building as it standsthe next devour as its starting point

A refresh that refused to guess

This site's own map is a good example. When I refreshed it on 26 October, the old atlas had a date and no commit. The refresh wrote: “An exact committed delta cannot be reconstructed,” and checked the current routes directly instead of pretending to know what had changed.

The four buckets exist because maps drift. My Fleetwatch atlas still carries one: its provenance says the app was launched during the refresh, while an older line under Unknowns says it never was.

Two brains and a conductor

Two copies of the same model miss the same things. One Claude and one Codex miss different things. In collab mode each maps the code alone, then they trade written atlases through a conductor that never maps anything itself. They never chat live. A conversation would let them anchor on each other, and the whole point is that each builds a complete picture first.

“It's like sending two geniuses, but obviously two brains are better than one.”
Me, Jun 2026
  1. 1Independent

    ClaudeWrites an atlas alone

    CodexWrites an atlas alone

    Neither sees the other. Every claim cites file:line.

  2. 2Critique

    ClaudeChecks Codex's atlas

    CodexChecks Claude's atlas

    What did they catch that I missed? What is wrong, with proof? What did we both miss?

  3. 3Rebuttal

    ClaudeAnswers the critique of its own atlas

    CodexAnswers the critique of its own atlas

    Concede or defend, with evidence.

  4. 4Reconcile

    The conductor writes MAP.md: Agreed, Resolved, and Contested.

Four rounds. The conductor owns every file write; both brains stay read-only.

Run: MoroMail, two maps that didn't agree

MoroMail is my fork of the Mailspring desktop mail client. On 30 June I ran a collab devour on the whole repo, with Codex conducting. The two atlases disagreed in six places, and every disagreement was settled by going back to the code.

  • How many packages

    ClaudeCorrectedAbout 49

    CodexHeld up51, counted: 44 features and 7 themes

  • Install model

    ClaudeCorrectedTwo npm workspaces

    CodexHeld upRoot tooling plus a nested app/ install, no workspaces

  • Missing sync engine

    ClaudeCorrectedThe UI still boots

    CodexHeld upStartup blocks before any window opens

  • The startup error dialog

    ClaudeHeld upQuit is the only option for a missing engine

    CodexCorrectedIt offers quit or rebuild

  • Who runs a task

    ClaudeCorrectedJS performLocal and performRemote

    CodexHeld upSerialized task models. The native engine does the work

  • Where a thread click lands

    ClaudeCorrectedthread-list-store.ts:48

    CodexHeld upThat line is a focus reset. The click runs through ThreadList

The six claims the critique round settled. Each side was corrected at least once.

The conductor's summary was that Claude traced the application's nervous system better, and Codex caught more of the operational, security and rebrand landmines. One question stayed open: the native sync engine lives outside the checkout, so neither brain could see it. The map files that under Contested, where a person looks first.

“Wait, are you serious? They both spotted something different.”
Me, Jun 2026

When it stays quiet

  • A small, concrete task. If the context is already enough, ordinary targeted reading is the right tool. Touching a repo is no reason to devour it.
  • Anything that changes the project. devour reads, runs bounded checks and writes MAP.md. Code edits, migrations, pushes and deploys wait for an explicit switch from study to building.
  • Collab without being asked. It costs roughly twice a solo run, so it only happens when I say collab. A refresh never turns it on by itself.

How a run is graded

  1. 1All eight questions answered with file references, or the repo declared partially devoured with the next probes.
  2. 2Routes traced end to end, including what probes proved and what they failed to prove.
  3. 3A blast-radius map written as warnings a stranger could act on.
  4. 4Unknowns listed honestly, each with the evidence that would close it.
  5. 5MAP.md stamped with mode, date, revision and scope, and still readable in one sitting.

A tour of the files with no warnings and no unknowns is the generic summary this skill was written to replace.