Featured image of post The Cartographer's Trade

The Cartographer's Trade

Practice Architecture Advice Process on the Ground.

Every spike starts the same way: an idea worth testing, and a blank repository. What happens between those two moments is where this post lives. Treated as a disposable throwaway, a spike teaches a technology and nothing else — the knowledge leaves with whoever ran it. Treated as a discipline — artifacts (a C4 model, ADRs, a technology radar), a method (the spike itself, run with the rigor of an Enabler Story rather than a side quest), a tool that makes the whole thing composable from the first commit (.NET Aspire as Composition Root), and a process for turning individual exploration into collective advice (the Architecture Advice Process) — the same spike becomes something the whole team can build on long after it’s done. The Art of Spiking, a curated playbook on running disciplined spikes, is full of practical habits in that same spirit — version control as a safety net, exploration on separate branches, checking the team’s radar before re-spiking something already investigated.

Add AI into that mix, and its contribution stops being limited to the writing that normally gets skipped. Prompted properly — in plan mode, reasoning surfaced, running a genuine Q&A sequence against the spike’s instigator rather than taking the first answer — it can stand in for both personas the Architecture Advice Process asks a decision to canvas: the expert whose domain knowledge the call should rest on, and the person affected by it, pushing back where the approach touches their world. This post is what happens when an agent is asked to actually occupy both personas, not just record the outcome, built from a real spike rather than a thought experiment.

A trade built on maps, not monuments

Whether navigating well-charted technical routes — improving the journey, reducing friction — or pushing into unmapped territory to gauge the shape of what comes next, the goal is the same: equip the navigators downstream with methods, tools, and maps they can use long after I’ve moved on.

Hands-on. Then hand over. That is the mantra this practice is built on.

This is the story of putting that mantra into practice through the Architecture Advice Process (AAP), as popularized by Andrew Harmel-Law: a model where anyone can make an architectural decision, provided they seek advice from those affected and those with relevant expertise. No ivory tower. No single hero tech lead carrying every call alone.

My own practice rests on four pillars, each addressing a distinct failure mode of decision-making at scale:

  • C4 model as ubiquitous language. Advice is given against a shared picture of the system, not four different mental models in the same room.

  • Technology Radar as living knowledge base. Scattered, individual tech-watch becomes a collective, queryable asset — checked before a spike starts, not only written up after it ends, so a topic already explored a year ago gets revisited on purpose rather than rediscovered by accident.

  • ADRs to track decisions in context. Not just what was decided, but why — so advice given today stays legible a year later.

  • Spikes, used intensively. Technology is tested before a vendor’s landing page is trusted — advice grounded in evidence, not marketing. But evidence alone does not travel well: every spike is a different journey, and without someone keeping the trace — a guide, a narrator — the lessons stay locked in whoever ran it. The story of the exploration matters as much as its outcome.

AI changes the resolution of the map: faster spikes, assisted ADR writing, a radar that updates itself. It changes the pace at which advice can be sought and given. It does not change the intent. Architecture stays a servant function, in service of the decision-makers, not above them.

The AppHost as composition root

A spike is where the four pillars are hardest to justify and easiest to skip — there is no budget line for documentation on something disposable. .NET Aspire changes that calculus. Its AppHost acts as a Composition Root, as described above: the single place where every component of the distributed application is registered, resolved, and released. Nothing about that pattern restricts it to business services.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
// Living architecture record for this spike (ADRs, C4 model, narrative doc)
// Clio is the Muse of History, daughter of Mnemosyne - she narrates what Mnemosyne remembers
var clio = builder.AddContainer("clio", "structurizr/lite:2025.11.08")
    .WithHttpEndpoint(name: "http", targetPort: 8080)
    .WithUrlForEndpoint("http", url =>
    {
        url.DisplayText = "C4 model";
    })
    .WithBindMount("../_archi", "/usr/local/structurizr")
    .WithLifetime(ContainerLifetime.Persistent);

// Technology-usage timeline (assess/trial/adopt) for every dependency this spike introduces
// Themis, Titaness of order and prophecy, fits for a resource that forecasts technology adoption trends.
var themis = builder.AddJavaScriptApp("themis", "../_radar", "serve")
    .WithParentRelationship(clio)
    .WithNpm()
    .WithHttpEndpoint(name: "http", targetPort: 3000, env: "PORT")
    .WithUrlForEndpoint("http", url =>
    {
        url.DisplayText = "Tech Radar";
    });

This is the actual top of Tartarus’s Hades/AppHost.cs, before any services are even registered. The C4 model and the tech-radar are resources exactly like those that follow. There is no separate documentation pipeline to maintain, no static site deployed out of band. The same seam that later lets a spike swap AddKeycloak for AddExternalService lets it treat “the architecture story” as just another dependency, wired in on day one and evolved alongside the code. That is what makes scaffolding-first practical rather than aspirational.

Case: Tartarus

Tartarus is a disposable Aspire spike exploring Keycloak-backed OIDC login and role-based authorization, guarding the gate between a Blazor app and a protected API — much like Cerberus guards the gate to the underworld. The initial intent was narrow: prove the OIDC login and the role-based authorization, nothing more. Spikes rarely stay that narrow once hands-on work starts surfacing adjacent concerns. Persisting the Underworld’s structural data instead of hardcoding it in two services pulled in a Postgres dependency; tracing a soul’s arrival asynchronously across Charon and Minos pulled in a RabbitMQ broker. Neither was the original point of the exploration, yet both earned a place in the method the moment they appeared — same scaffolding, same loop, same capture discipline, no separate “enrichment” process to bolt on. It is a small spike, but it exercises the full method end to end, following a refined /spiker skill.

Scaffolding

Before any spike-specific code, the AppHost provisions the four pillars as resources in their own right: a C4 model (_archi/workspace.dsl, rendered live by the Structurizr Lite resource above), an ADR folder (_archi/adrs/), a tech-radar site (_radar), and a narrative landing page (_archi/docs/tartarus.md). Documentation is not a deliverable produced at the end. It is wired in at commit one, next to the code it describes.

This is architecture as code, not architecture about code. The C4 model, the ADRs, the radar, and the narrative doc live in the same repository as the services they describe, versioned by the same commits, reviewed through the same pull requests, and rendered by the same AppHost that runs the spike. There is no drift to reconcile between “the diagram” and “the system,” because there is only one set of artifacts, and it evolves with the code instead of trailing behind it.

The loop: plan, execute, capture

Everything after scaffolding follows the same repeatable pattern, run with an AI agent at every step:

  1. Plan with the agent, in both personas. Before touching code, run an actual Q&A with the agent — plan mode, reasoning surfaced, not a single prompt-and-go. Have it argue both sides AAP asks for: the expert whose domain knowledge the approach should rest on, and the person affected by it, pushing back where the change touches their world. Only once both have had their say does the plan separate the unknown being explored from the world already in place, and sketch the bridge between the two — then decide whether the change is sizable enough to warrant its own record.
  2. Execute. Wire the dependency, write the code, run the spike.
  3. Capture. Update whichever artifact the change actually touches: an ADR if a decision was made, a radar entry if a new technology entered, the C4 DSL if the model shifted, the narrative doc if the story changed. Not all four every time — only what the change earned.

Treat capture the way “write the test” or “update the docs” were treated once teams stopped considering them optional add-ons and made them a stage of the loop itself. The same move applies here: architecture capture is not a courtesy bolted onto delivery work, and it is not reserved for projects that have graduated past the exploratory phase. A spike is R&D activity, not a lesser cousin of “real” development — and R&D activity earns the same discipline. The habit has to run through the loop from the first commit, spike or not.

A few turns of that loop from Tartarus:

  • Wiring Aspire.Hosting.Keycloak with an auto-imported realm: radar entry for Keycloak plus a narrative-doc update describing the identity flow. No ADR — the choice was not contested, just documented.
  • Renaming the solution because the mythological persona naming taxonomy (Cerberus, Charon, Minos, Hades) collided with itself once resource names and project names diverged: ADR only — no new technology, no diagram change, just a decision with context, options considered, and tradeoffs that would otherwise have evaporated in a chat thread.
  • Wiring Aspire.Hosting.RabbitMQ for an async cross-service trace between Charon and Minos: ADR (why rely on the client’s built-in OpenTelemetry instrumentation instead of hand-rolled spans), radar entry for RabbitMQ, and a C4 complement adding the messaging relationship to the model.

Five ADRs and six radar entries came out of Tartarus this way — not written in a batch at the end, but as a byproduct of each plan/execute/capture pass. AI drafts the ADR, proposes the radar entry, sketches the DSL diff. It does not decide what is worth capturing.

This is not automatic documentation. A human still decides what counts as a decision worth recording, and whether the tradeoffs are stated honestly.

Curating

None of this runs unattended. Every ADR still carries the author’s name, not a model’s. AI narrows the gap between making a decision and documenting it; it does not get to decide what counts as a decision worth recording. That judgment stays with the architect, every time.

Two takeaways

Good habits start early. Do not wait for the big project to bring in method and discipline. A spike is R&D, not a lesser cousin of production work, and the loop applies from the first commit: C4 models, ADRs, and radar entries should already be a reflex here, not something bolted on once the stakes get high. By the time a decision needs advice from three teams, the habit has to already be muscle memory.

AI is a capable side-kick for the thinking as well as the writing. Run properly — plan-mode reasoning, a real Q&A with the person driving the spike — it can voice the expert case and the affected case before a decision is made, not just transcribe the decision afterward. The rationale lost every day — while prompting, while offloading work to an agentic fleet, while moving fast — is exactly the rationale AI is good at surfacing and capturing alongside the work, in near real time. Meaningful content stops being tribal knowledge and becomes a first-class artifact belonging to the codebase: something the whole team can refer to, build on, and challenge, to craft a better AI-powered engineering workflow.

A note on tooling

This post talks about skills, agents, and a refined /spiker workflow without naming any of them. That is deliberate. The plumbing underneath — which agent, which skill format, which harness — is evolving fast enough that pinning this diary of discipline to today’s tooling would date it within months, maybe even weeks. What an agentic crew needs right now will likely not be what it needs in a couple of months. So build your own tooling, shaped to how you actually work, rather than trusting someone else’s blindly. And prune it on a regular basis: tooling that only ever grows, never shrinks, turns into the same kind of baggage that a naming-taxonomy ADR gets written to clean up later. Read this, keep what echoes, evolve your own practice from there — and when you find a better trick, share it back so the whole community moves forward together.

Licensed under CC BY-NC-SA 4.0
Last updated on Oct 02, 2026 00:00 UTC
Built with Hugo
Theme Stack designed by Jimmy