Part 3 · Ambient context

Prelode

Context that loads itself

Removing the setup ritual: the refactor where a personal context system stopped waiting to be configured.

Part three of the Prelode case study: the four-layer composer gives way to a small always-on baseline and specialized context that arrives when the task calls for it, compiled from one source into Claude Code and Codex.

This is the third movement of the Prelode case study. Part one decomposed the system into composable files and pressure-tested it. Part two gave those files an interface. This one is about the refactor that took the composer off the common path, once I started asking why I was selecting most of this context at all.

I opened the Prelode repo in July, after leaving it alone since May, and found I had quietly gone back to copying files by hand.

The desktop app had gone stale, and more to the point it had stopped being useful to me. Most of my work now happens in Claude Code and Codex, pointed at a repository. Prelode had reverted to its original form in my actual practice: a folder of Markdown documents I hand-selected and dropped into new sessions.

That still worked. It also meant I had to remember the system before the system could help me. Every new session opened with the same small negotiation. Which Core fits this work? The short Mode or the full one? Is this a design session, a coding session, or both? Will I want my writing voice later? I could answer all of it. The repetition made me answer it badly, or skip it.

The failure was ordinary enough to be easy to miss. No broken build, no dramatic model error. I was tired of loading files, and sometimes I forgot.

The first fix preserved the burden

The obvious answer was to move Prelode into the tools I actually use. So that is what I built first: a zero-dependency npm package, a terminal command, and native commands for Claude Code and Codex. A repository could run an init command, get a small configuration file, and expose its selected stack. The four-layer model came along intact. Core, Mode, Profile, Project, with presets to make the common combinations faster.

Technically it worked. The package installed, both hosts saw the commands, a status command could report the configured stack.

Then I tried to use it.

I invoked the status command in Claude and watched a spinner without getting a useful visible result. My next question exposed the real problem: how do I choose the parts individually? I had lost the interface and kept the configuration burden. I had translated the composer into slash commands, which saved me from opening the desktop app, and still required me to know the architecture, decide what the model needed, and operate Prelode before doing the work that brought me into the session.

I had automated file loading without removing context selection from my job.

That was the turn. The useful question was no longer how to make the selector faster. It was why I was selecting most of this context at all.

Core stopped being the center

The original Core files made sense when Prelode had to define the whole session. One Core told the model to think with me, another told it to code, another handled writing. The selected file named what kind of room I had entered.

Claude Code and Codex already know what room they are in. They know they are coding agents. Repeating that in a large preload adds weight without adding much direction.

My work also refuses to stay inside one Core. I design in coding sessions. I code my way through a design problem. I can spend most of a session engineering a feature and then ask for help drafting a short note to a client. Calling the whole session design, build, or writing forces a clean category onto work that changes shape while I am inside it.

So the durable behaviors became additive practices. Design frames a product or interface decision, Engineering governs implementation, and Public Writing supplies a method when the output is meant for an audience. More than one can be active at once. They support the task in front of the model. They do not label the session.

What loads now

The new model is a small baseline plus a set of contexts that arrive only when they earn their place.

ME + LITE is the baseline. It carries the minimum useful context about how I work and how much response I usually want, and LITE is finally true to the name. It is preloaded. FULL stays available as an explicit, one-request change when I want the longer treatment.

Everything else waits. Design, Engineering, and Public Writing activate from the task, so I can move between them in one session without rebuilding a stack. Voice stays out of a routine coding exchange and becomes available the moment I ask for a client message or a public post. Competency arrives when an explanation enters a part of the stack where my fluency is uneven, so the model is not carrying my whole technical profile through a conversation that never needs it.

Project context is the rail that changed most. Working in the Ionite repo does not by itself mean I need the Ionite project document. The code in front of the model already supplies the local context. A project file earns its place when I ask about a different project, or when the task needs history the repository cannot provide.

Always on
ME/LITE
Follows the task
DesignEngineeringPublic Writing
Follows the subject
VoiceCompetencyProject domains
Explicit only
FULL
Four load conditions where there used to be one composed stack. The baseline is guaranteed by the host's session-start mechanism; the other three are available, and arrive only when the task or the subject calls for them.

Repository location is a weak proxy for intent. A task can cross domains in one sentence, and mine do. Prelode now routes on what I am asking the model to do and what I am asking it to talk about.

One source, two hosts

The canonical source is still Markdown. I wanted to keep the inspectability that made Prelode worth building in the first place, where every instruction can be read, edited, versioned, and traced to one file. What changed is the delivery system around it.

Prelode now keeps a catalog describing the baseline, the practices, the profiles, the domains, and the routing cues. A compiler turns that catalog into self-contained plugins for Claude Code and Codex. One sync command rebuilds the generated adapters from the canonical files, and the generated version is tied to its content, so the desktop apps get a fresh identity when the underlying context changes instead of holding an old cached copy. The compiler and the templates are the part that can be shared. My profile, my voice contract, and my project context stay on my machine.

Claude Code supports a session-start hook, so the baseline loads when a session begins, and the task-specific contexts sit in skills that stay lazy. Codex needed another round of testing. My first implementation treated the baseline as a generic always-on skill, and a clean session showed the model would not reliably invoke it.

A baseline that usually loads is an aspiration, not a baseline.

So I moved the small always-on instructions into the global instruction file Codex reads at session start, inside a marked block Prelode manages and nothing else. The richer contexts stay as skills the task can activate. Same system, delivered through the mechanism each host actually supports.

Both hosts now print a compact receipt when specialized context activates. A line like Prelode: ENGINEERING + PRELODE makes the invisible routing visible without turning every response into a configuration report. It is a debugging surface and a trust surface at once. I can watch the system reach for context, then get back to work.

The proof was a client message

The first satisfying test happened inside an existing Ionite session. I had been working through the difference between OEM and ISV naming in a partner portal, which is product design and domain reasoning. No writing profile had been selected. There was no writing session.

Draft a short message to Elena asking about the OEM vs. ISV naming.
Ran skill /prelode:voice
Mid-session, in a product design conversation. I did not choose Voice and I did not switch the session into a writing Core. I asked for the work, and the system recognized that the words were meant for another person.

That one line was the behavior I had been reaching for through every earlier version of the system. Part two ended with an interface that showed me the stack it was running. This ends with a system that picks the stack and tells me what it picked. Prelode finally behaves like background infrastructure.

What this resolves

Each stage of this system solved a real problem and exposed the next one. The Markdown files solved repeated explanation. The composer made the stack visible and checkable. The first command-line version brought the system into the tools I use now. This refactor removes the setup ritual from the common path.

  1. Part 1

    A folder of Markdown

    Files I could read, edit, and version in one place.Before the work: Pick the right handful and paste them into a new session.
  2. Part 2

    The desktop composer

    An interface that printed the composed stack and ran the session on it.Before the work: Choose a Core, a Mode, the Profile files, and a Project.
  3. Part 3

    Ambient context

    A baseline that loads itself, specialized context the model reaches for, and a receipt when it does.Before the work: Nothing. Open the tool and start.
Three deliveries of the same canonical files. The bottom line of each stage is the one that changed: what I still had to do before the work could start.

The composer from part two still runs. It is an escape hatch now, and a record of the architecture that led here.

The open edge

The routing layer is soft on purpose. A model reads the task and decides which specialized context applies. I tested the obvious paths, including engineering work, explicit layer selection, and the mid-session Voice request. Those tests prove the mechanism works. They do not turn heuristic judgment into structural enforcement, which is the same boundary part one landed on and the same one I keep deferring.

For now the line is clear enough to state. The baseline is guaranteed, because it rides the host's own session instruction mechanism. It does not depend on the model choosing to invoke it. Everything above the baseline is available, locally compiled, and observable when it activates. FULL stays a deliberate request. The system can be quiet through ordinary work and show itself at the moment it has something specific to contribute.

The biggest change is the part I no longer do. Every earlier version of this system made context selection faster. This one took most of it away. I open the tool, point it at the work, and begin.

Tom Swain

Let’s talk.

The work I care about is the kind where designing it and shipping it are the same job. Email is the best way to reach me.

Location
Glendale, Arizona