Wing: the top-level grouping in agent memory
2 min read
A wing is the outermost partition of DevPilot's memory model. Everything an agent can recall lives inside one.
export interface Wing {
id: string; slug: string; name: string;
wingType: WingType; // 'project' | 'persona' | 'scratch'
repo?: string;
}
The three types, and why they are separate
project memory is bound to a repository. What the planner learned decomposing
work in this codebase should not leak into an unrelated one — the file paths
alone would be meaningless, and the decomposition patterns misleading.
persona memory is about the conductor rather than the code: preferences that
hold across repositories, such as how wide they like waves or which task types
they always review by hand.
scratch is deliberately disposable. Somewhere to put working notes that must
not accumulate into long-term recall.
Why partitioning comes first
A single undifferentiated memory store is easy to build and gets worse as it grows: recall returns things that are true but irrelevant, and irrelevant context is worse than no context because it consumes budget and biases the planner.
The wing is the first cut. Recall never crosses one unless a tunnel explicitly says it may.
What it is not
A wing is not an access-control boundary. It organises recall; it does not enforce isolation between customers. Cross-organisation learning is out of scope by design, and that is enforced elsewhere — not by this type.
Inside a wing, storage is divided into rooms.
repo is optional, and that is deliberate
Only project wings are meaningfully bound to a repository. A persona wing
describes the conductor and follows them across every codebase they work in;
binding it to one would be wrong.
Making the field optional rather than splitting the type keeps the partitioning uniform — everything is a wing, and recall does not need a separate path per kind.
Slug and name
Both exist because they serve different readers. slug is the stable
identifier things reference; name is what a human sees. Collapsing them means
either the display name cannot change without breaking references, or the
identifier drifts as the name is edited.
That is a small decision with a long tail, and it is the kind of thing that is much cheaper to get right at schema-design time than to retrofit once anything stores a reference.
