Hyprland experience click to change the experience
Chapitre 3

The context explosion

Going back to AI hard: the first context architectures.

Period : early 2025 to June 2025

I move from scattered rules to the first systems. I try to automate context, hit my hardware’s limits fast, and keep one idea that sticks: one source, several derived formats.

Automatic context generation

I throw myself back into AI experiments, but with a sharper obsession: how do you make AI understand a project without drowning it, and without letting it work blind? Give it too little, it misses the shape of the system. Give it everything, it gets lost.

So I start from a simple idea: break the project into organized pieces, like a book with chapters and subchapters. Each folder would carry its own summary, and the whole would form a global view. AI could move from general (the overview) down to specific (file-level detail).

I turn the idea into a script: a bottom-up recursion inspired by the visitor pattern (old reflex from a compilers class), walking the tree, summarizing each chunk, then climbing back up toward an overall view.

Project/
├── src/
│   ├── utils/
│   │   ├── helper.js          → scan + summary by Ollama
│   │   ├── config.js          → scan + summary by Ollama
│   │   └── analyzed.yaml      ← "utils/ holds helpers and config"
│   │
│   ├── components/
│   │   ├── Button.jsx         → scan + summary by Ollama
│   │   ├── Form.jsx           → scan + summary by Ollama
│   │   └── analyzed.yaml      ← "components/ holds React UI"
│   │
│   └── analyzed.yaml          ← aggregation: utils/ + components/

└── analyzed.yaml              ← global view: "React project with utils and UI"

Flow: files → Ollama → analyzed.yaml summaries → bottom-up aggregation

Algorithm:

For each file:
  read the contents
  ask Ollama for a structured summary
  write that summary into the folder's analyzed.yaml

Then, walking back up the tree:
  read the subfolders' analyzed.yaml
  aggregate them into the parent folder's analyzed.yaml
  repeat up to the project root

I like the principle: each file leaves a structured trace (type, functions, dependencies, complexity), each folder aggregates its children’s traces into a context file (an analyzed.yaml), and the project ends up producing its own map. I can drop from global down to detail without loading everything at once.

In practice, it jams up fast. Everything’s sequential: one HTTP call per file to Ollama, on a reasoning model (DeepSeek R1 8B) that thinks before answering. On a small project, I’m already waiting around fifteen minutes. On a big project, the time explodes. The principle still holds, but it doesn’t scale on my hardware. I pause the project. The code’s still there, frozen mid-refactor.

What I keep isn’t the script. It’s the idea of a context that can rebuild itself through passes: a first reading gives a rough map, then later ones pick up from that map to correct and sharpen.

I also had in mind a small language to describe the project, with increasingly specialized scans and several models leaning on their strengths: summary, structure, semantics. On paper, each pass made the next one less blind. In practice, the first pass was already too slow. Adding passes made the system unworkable.

I never take it all the way, but the lesson sticks. I clarify for myself why hierarchical breakdown matters, why selective aggregation matters, and why a context that builds through successive passes matters.

Cursor, Sonnet 3.7 (during the push)

I keep using Cursor heavily. Sonnet 3.7 (Anthropic) impresses me on certain coding tasks — I gradually switch over to Anthropic for more reliable generation. A stronger model changes the experience but doesn’t fix everything: how reliable it is still depends on the rules and context I’m feeding it.

I start spreading rules across the project: .cursorrules, then .cursor/rules. I’m less hunting for the right prompt than for the right place to put the conventions.

Meanwhile, a personal project grows. It starts as a plain website. Then it turns into a full app, with assets, workflows, folder-level conventions. The rules stop being theoretical: I see right away when they help, when they’re missing, and when I have to re-explain everything. That’s when I get that Cursor rules and folder-level organization can become a real production surface.

The rules themselves become a system to maintain: human conventions, technical constraints, placement in the tree, the format each tool expects.

Sonnet 4 and Opus 4 (another leap)

When Anthropic announces Claude Sonnet 4 and Claude Opus 4, the leap is immediate. Claude Code already existed in preview — I’d heard of it, but I really start using it at this point: the tool goes generally available, the IDE integrations land, and the whole thing settles into my dev routine. I test the models as soon as they ship and subscribe to Claude Max so I can iterate freely.

In one intensive session, I build a full React site, DB included (a personal POC, to see how far it goes). Let’s be clear: this is still vibe coding — quick and dirty. Great POC, impossible to keep in production as-is.

Past the technical side, a certain “AI culture” starts to wear on me: emoji-heavy answers, fake-cool tone, pointless filler. I want sober, effective tools, not a chatbot patting me on the back.

When I move to Claude Code, I don’t start from scratch. I take what I already have: my Cursor rules. I copy the .cursorrules, then some .cursor/rules files, into CLAUDE.md to keep the same frame on the Anthropic side.

The duplication grates fast. Two files tell the same story, with different names and formats. So I create AI.md as a neutral source: the master context lives there, the tools adapt around it.

For Claude Code, it’s simple: CLAUDE.md can point at AI.md through a symlink. On the Cursor side, a symlink isn’t enough. The rules have their own format, their metadata, their globs. So I generate .mdc files from the same source, instead of maintaining a second version by hand.

So I set up a generation script:

  • based on where an AI.md file sits in the tree, the script builds an .mdc with the right globs, the right local scope, and the right rule type;
  • inside the .mdc body, I drop a reference to the AI.md contents, which stays the single source;
  • I set up symlinks for CLAUDE.md in the right places so Claude loads the same context.

With this system, Cursor loads the rule fitted to the folder, and Claude picks up the same content through the symlink. I’m no longer maintaining two competing texts. That’s where the reliability comes from: one source, several derived formats.

Inside Claude Code, I also experiment with auto-including context files. That’s where the “lazy-loading” idea emerges: load only what’s needed, when it’s needed.

This unification pushes me toward what comes next: a system that starts light and drops down through context layers when the task calls for it.