A model with many surfaces
An IDE is organised around files because, historically, a file was expensive to produce and expensive to change. Generation inverts that. When a file can be rewritten on request, the file is the cheap part, and organising the whole tool around it means organising it around the one thing that no longer holds still.
AI-DE puts the model at the centre instead. A repository is indexed into an append-only store of attributed facts; every view is a projection over those facts; and the code viewer is one projection among fifteen, with no more claim to being the real thing than the class diagram or the search index.
The pipeline
Seven extractor families read a repository. Each emits immutable evidence assertions of the form subject, predicate, object, against a scope snapshot pinned to the exact source revision it read. Nothing is written in place. Projections are built from those facts and can be deleted and rebuilt at any time; a test does exactly that on every run, rebuilding every current projection from an empty cache and comparing it to the stored one.
One node, seven surfaces
Below is a single node from this codebase, the class WeaveScorer, rendered the
way each surface would ask about it. Nothing about the node changes. What changes is the
question the surface is asking.
AiDe.Core.Watcher.WeaveScorer
7 of 15 surface kinds
An illustration, not a screenshot. The node, its file, its members, and the predicate vocabulary are read from this repository. The layout is drawn for the web; the application renders these in docked panes.
The fifteen surfaces
A surface's identity, state and content are independent of where it is docked. One factory maps a surface kind to its content, so adding a kind never means touching the layout model, and an unknown kind still gets an honest pane rather than a blank one.
| Kind | The question it answers | Reads |
|---|---|---|
codeviewer | What does the text say? | node content projection |
canvas | What is this near, and what reaches it? | graph + paths projections |
classdiagram | What shape is this type, and what does it inherit? | has_member, has_type |
sequence | In what order do these components talk? | calls_at interaction projection |
contexts | Which bounded context owns this language? | context projection |
joins | Where do two models meet, and on what key? | join projection |
search | Where does this string live, and why did it match? | content search projection |
view / inspector | What is asserted about this node, and how confident is it? | evidence read |
terminal | What is the agent doing right now? | ConPTY session |
prompt | What am I about to send, and to which session? | prompt drafts |
sessions | Which agents are alive, in which repositories? | watcher liveness |
board | What have the agents told each other? | message board |
leaderboard | Which harness and model does better here? | scored episodes |
diagnostics | Is the machinery itself healthy? | daemon, health, MCP |
Fourteen rows for fifteen kinds: view and inspector share a row
because they share a reader. The list is a published constant the application checks itself
against, so a surface cannot exist without appearing here.
Why the model is edited through agents, not surfaces
The temptation with a diagram tool is to make the diagram editable. Drag a box, rename a class, and have the code follow. It is the feature everyone asks for, and it is the one this project refuses.
A derived view that can be written through is a second source of truth. The moment two places can define the same thing, they disagree, and the disagreement is silent, because both look authoritative. The repository carries this as a standing rule with its own architecture decision record, and the modelling reviewer holds a veto over any editable derived view.
Fact tables reject UPDATE and DELETE through
BEFORE UPDATE / BEFORE DELETE RAISE(ABORT) triggers,
and the writer forbids INSERT OR REPLACE / upsert conflict resolution on fact
tables. This is required, not optional: with the default
recursive_triggers=0, INSERT OR REPLACE silently
deletes-and-replaces a fact row without firing the delete trigger.
sqlite-fact-store, case S4
So the write path runs the other way. You direct an agent; the agent changes the repository; the extractors observe the change and append new facts; the projections rebuild; every surface updates because every surface was only ever a question asked of the same store. The model is transient in the sense that any particular state of it can be thrown away and reconstructed, and durable in the sense that the facts, and the record of how they got there, are the thing that is kept.
- A correction is a superseding fact. Nothing is rewritten, so the history of what was believed, and when, survives the correction.
- Extraction is pinned. Every assertion carries the scope snapshot and source revision it was read at, so a stale answer is detectable rather than merely wrong.
- Coverage is declared. When an extractor cannot analyse a language, the graph says so rather than looking complete. A graph that silently omits package types looks finished and gives the reader no way to know it is not.
- Rebuild is tested, not assumed. A fixture replay rebuilds every current projection from an empty cache and compares it to the stored one. If projections could drift, that test fails.
Read further
- Conceptual domain model: bounded contexts, aggregate invariants, the declared grain of every fact, and the history rule per attribute.
- Architecture: the component map, the trust boundaries, the command protocol and the delivery semantics.
- Component · layered · sequence · class diagrams, every node and edge traced to a declaration.
- Spec — AI-native IDE: the functional, UX and UI layers of the workbench.
- Docs explorer: all 543 artifacts as a navigable typed graph.