equin. Vision Apps Foundations Story Guide Download equin on GitHub

Building equin

I worked 8 years at Google Brain/DeepMind as an AI research engineer. Then, one week, I tried Claude Opus (4.6), and everything changed. One month later, I quit Google to build an agentic project on my own. This is my reflection on how I got here.

First contact with AGI

My first real contact with agents was back in February 2026, with Claude Opus 4.6. Two things became obvious very quickly: my job was about to change forever, and something that looked like a new form of life was emerging.

I quickly started testing the limits of what the models of the time could do. My goal was to build self-evolving loops through modular, connected skills.

The idea was simple. When raw Claude fails a task, there are two possible reasons:

I wanted to see how far the second option could be pushed.

I noticed that when Claude failed, it was often because the agent had thought about the problem differently than a human would. So I started writing skills that would teach Claude to think more like us: the building blocks of cognition.

Two skills formed the foundation of the self-improvement loop.

Meta-fix. When you ask for a fix, there are always two levels to apply it at: the fix itself, which is what Claude does by default, and the meta-fix, whatever allowed the bug to appear in the first place. The second one is the most important to get right, because it prevents the same class of issue in the future.

Update skill, probably the most important one. It forces Claude into counterfactual reasoning to work out where and how to edit its own skills.

## Mental model: skills are a program graph

Skills are nodes. Cross-references between them are edges. `AGENTS.md` is
`main()` — it dispatches to top-level skills, which route to sub-skills.

When a situation arises, execution flows through this graph. A rule that isn't
on the current execution path is dead code — no matter how well written. This
means **placement determines whether a rule fires**, not just its content.

Consequences:

-   `AGENTS.md` should only list entry-point skills. Entry-point skills route to
    sub-skills. Keep the graph clean — like a well-structured call graph.
-   Cross-references are `import` statements, not comments. A missing
    cross-reference is a missing edge — the target skill becomes unreachable
    from that path.
-   Duplicating content across skills is copy-pasting a function. One copy
    drifts. Keep a single source of truth and route to it.
-   Skills can have as many abstraction levels as needed. Complex workflows
    benefit from decomposition, just like complex programs. The goal isn't fewer
    hops — the goal is that each skill fires at the right time.

## Phase 1: Diagnose (before any edit)

Something went wrong — a rule wasn't followed, a mistake was made, or the user
corrected you. Before writing or moving any content, diagnose *why*.

### 1. Define the expected behavior

State concretely what the correct action would have been. This is the target for
the counterfactual test at the end.

### 2. Trace the execution path

Walk the graph that was active when the error occurred:

-   What was the trigger? (user message, task phase, correction)
-   Which skills were in context? (loaded, cross-referenced, read)
-   What path did execution follow through the skill graph?

### 3. Classify the failure

| Failure type        | Symptom                                    | Typical fix                                                     |
| ------------------- | ------------------------------------------ | --------------------------------------------------------------- |
| **Routing failure** | Rule exists but wasn't on the path         | Fix the graph: add cross-reference, move rule to reachable node |
| **Content gap**     | No rule exists for this situation          | Add content (see Phase 2)                                       |
| **Ambiguous rule**  | Rule was triggered but led to wrong action | Rewrite the rule                                                |

For **routing failures**, dig deeper:

-   Was the rule in the wrong skill? (skill not triggered at the relevant moment)
-   Was the rule in the right skill but not prominent enough? (buried, too
    generic, skipped over)
-   Was a cross-reference missing between two skills that should connect?

## Phase 2: Fix (depends on diagnosis)

The diagnosis determines the fix. Don't skip ahead.

### Routing failure → fix the graph

Move the rule to a skill that's on the execution path at the moment it matters,
or add a cross-reference from the active skill to the one containing the rule.

### Content gap → add content

Before adding, answer these gates in order:

1.  **"When would I need this?"** The answer tells you *which skill it belongs
    to*. The trigger moment determines the home, not the topic.
    -   **Common trap:** placing a lesson where it *surfaced* instead of where
        it's *needed*.
    -   When placing **multiple lessons at once**, apply this gate to each one
        individually.
2.  **Hard gate: "Will this lesson attract siblings?"** Create a new skill
    when the lesson opens a category that will grow, or is accessed at a
    different time than the existing skill's content. Gravity-well check:
    existing content on a topic pulls new content in — but both may belong in
    a separate skill. Extract, don't expand.
3.  **Generalize to the broadest principle.** Never reference the specific
    example which triggered the error. Ask: "is this a special case of a
    broader rule?" But don't *over*-generalize: preserve the user's framing.
4.  **Check for cross-level patterns.** Is this rule an instance of a
    well-known pattern from another domain? Then it should be factored out.
5.  **Validate the lesson against the correction.** Re-read the user's exact
    words: does the extracted lesson address *their* point?
6.  **Dog-food the destination skill.** Re-read the target file and check the
    new rule follows the principles already in it.
7.  **Write procedures, not descriptions.** Imperative steps, not labels.
8.  **Environment info → `AGENTS.md`.** Paths and infrastructure belong there.

### Ambiguous/wrong rule → rewrite

Fix the rule in place. Make it concrete enough to produce the correct behavior
reliably.

### Update cross-references

Every skill modification requires updating the graph: `AGENTS.md` (entry
points only), any skill the content was extracted from, any skill that would
be active when the modified one triggers. Keep cross-references lean.

## Phase 3: Verify (counterfactual test)

Mentally replay the original scenario with the fix applied:

> "If the exact same situation occurred again, would the fixed skill graph
> produce the correct behavior?"

If the answer is no, the fix is wrong — go back to Phase 1. The fix must change
the outcome, not just add words.

Reduce friction, in a loop

Most of my work at Google could be summed up in a single objective: reduce friction.

The loop was: I’m trying to do my job, but I get frustrated. A workflow takes one extra click; expressing an idea takes too many lines of code; …

Me Friction My job

I would often spend more time trying to fix the friction, which became an objective in itself. And often, fixing that friction came with friction of its own.

Me Friction

By doing so, I would produce libraries and artifacts I could share with the team (some of which grew beyond my team, to be used by the rest of Google).

Working with agents quickly became exhausting. You constantly multitask, keep the individual workstreams in your head, and switch between conversations all day. At the time I had five or six conversations running in parallel.

As usual when I feel friction in my work, I embarked on a quest to fix the tooling, so I could work smoothly again.

Since I had access to the agent manager’s source code (an internal version of Google’s Antigravity), I started injecting a custom plugin system into it, to try out new UI ideas. The goal was a UI that would let me launch and monitor agents without the mental overhead.

I did not really have an end vision: each piece emerged organically from trying to fix the previous one.

This is when I started building the core pieces that would later evolve into equin:

A world without friction

In every project I have ever had, there is more to do than humans can accomplish. Tasks accumulate in an ever-growing list.

What happens when there is no more friction? All thoughts become reality, instantly.

A system that resolves TODOs faster than they are created: that is what I was trying to build.

Task list 0 open

Agents + no friction 0 open

Many changes were needed to remove friction, but the main workflow could be summarized as:

I felt I was creating the pieces of something powerful, and I wanted to keep ownership of it. At the time, I was on the Gemma team. I remember exactly: the Gemma 4 release (April 2, 2026) was the day the pieces I was building started to click together. I felt like, holy shit, what I was building was actually working. I remember the whole team celebrating the release, but I felt so disconnected from it, as if I was living in another world. All the projects I had ever worked on at Google belonged to the past.

One week later, I handed in my resignation.

And beyond

I spent my first weeks after leaving Google recreating my agent manager. The one I was using at Google, like all the code I had written, belonged to Google. So I had to start from scratch.

I started by reimplementing the core ideas as a small terminal-based agent manager, so I could manage multiple Claude Code sessions without the mental overhead.

A terminal list of Claude Code sessions, with New session and Resume session
My first terminal-based agent manager

Then I thought about building my agent manager on top of an existing IDE, like VS Code, but quickly realized I was fighting the IDE’s abstractions. So I started a greenfield project instead, to have full freedom.

April 11: a sidebar of Claude sessions next to a Claude Code terminal
The first versions of the UI were just wrappers around Claude Code

This second version was much more structured and principled than the one I had at Google. I was moving really fast. Within a week, I had a working prototype.

From there, the app grew organically. Each prompt simply fixed whatever friction I was having with the app at that moment.

With friction removed, I felt like I was in a constant productivity flow. That’s where I started to think about applying the building blocks I had built for my agent manager to other applications: reducing the friction in all the applications I’m using. The beginning of my custom operating system.

One app to rule them all

Before agents, I was a heavy user of Notion. Back in 2021, I started having a dream, something I could only make real with a billion dollars to pay an entire engineering team for years. What if Notion’s building-block idea were generalized and applied to the entire operating system?

Notion’s main power comes from the data view: a very generic primitive that can be customized to create mini apps. At its core, a data view is just a way to show the same data with:

Once I used data views, I wished they were everywhere. Take the Claude app for instance. The sidebar and the Artifacts page are both incomplete reimplementations of Notion’s data views, creating duplication and inconsistency.

My idea: implement the primitive well once, and reuse it everywhere. If I add infinite scrolling, every surface of every app, current and future, supports it. If I fix a bug, every app is fixed.

Data view was just one primitive, but I applied this principle to everything: build the building block once, cleanly, so it can be reused in every application, present and future.

What started as a project to help me manage my agents became an experiment: can I reimplement every app I use, shaped exactly the way I wish it had been designed?

To be continued…

equin. hello@equin.ai Source on GitHub