Last updated September 27, 2026
Aspects
An aspect is a typed detail of your architecture, such as a table, an endpoint or a rule, attached to the node it belongs to. You use aspects to see what an app's code contains, to annotate it, and to anchor work items to a specific table or endpoint.
An app board's Aspects screen lists them by kind. The hub counts them and, card by card, shows what needs a look.
Set up
The code plugin extracts aspects from the repo bound to the board. The board has to be mapped first, because every aspect attaches to a node:
- In the repo, run
/analyze, then/sync, with the code plugin. - Run
/adopt --aspect <kind>for each kind you want:
Two kinds work differently. Boundary rules are declared on the board rather than extracted. An app's routes, /adopt --aspect ui.pages, have their own Pages screen.
Until a kind is adopted, its tab says so and names the command.
The kinds
The Aspects rail lists the kinds in the order below. Select one to see its rows; select a row to open it in the inspector on the right.
Database
The tab draws the schema as a diagram: each table with its columns, and a line for each foreign key. Open a table to see its dialect, ORM, primary key, estimated rows, columns, foreign keys and indexes.
You can mark a table deprecated, and give each column a Classification: public, internal, confidential, pii or secret.
Endpoints
The tab groups the endpoints by method, as cards sorted by path. A card shows the path and the auth the endpoint needs: public, an API key, a bearer token or OAuth scopes. It also lists the parameters, response codes, rate limit, paging and any sunset date. Select the path to find the endpoint's owner node on the canvas.
Called by lists the other apps whose code calls the endpoint, read from the root board's call map. You can mark an endpoint deprecated.
Clients
The tab lists the other services this app's code calls, grouped by the service they call. Open a client to see its base address, its name in the code, and the calls it names. A client that names no call depends on the whole service.
Events
The tab groups the event channels by broker. A card shows the channel's ordering, delivery guarantee, dead-letter queue, and how many producers and consumers it has.
Open a channel for its event types, subscriptions, producers and consumers. You can add owners and write the channel's Description, Usage notes, Rationale, Runbook URL and Notes.
AuthZ
The tab shows the board's authorization registry in three views:
- Matrix: roles against resource types, with the actions each role may take
- Roles: how roles inherit from each other
- Policies: each policy's source text, as the code declares it
Boundaries
The rules you declare for which nodes may depend on which, each checked against the code. See Boundary rules.
Annotate an aspect
Whatever the code plugin extracts, the code decides, so most fields are read-only. Hover a locked field to see why: "Derived from source analysis — edit it in the code and re-sync."
What you can change is the judgment the code doesn't hold: deprecating a table or an endpoint, classifying a column, a channel's owners and notes, a rule's rationale. Changes wait in the save bar; Undo and Redo step through them, and Save changes writes them. Only rows you created, such as a boundary rule, can be deleted. A row the code plugin extracted goes away the next time you adopt, once the code no longer has it; /adopt --mode merge adds rows without removing any.
Each row also has Add to work item, which anchors a work item to that table, endpoint or rule.
Aspects on the hub
The hub's Aspects card counts every kind the board holds. Each kind also has a card of its own in the hub's Add widget menu: Database, Endpoints, Pages, Events, AuthZ, Boundaries and Clients.
A kind's card leads with its count and a status line. At three rows high it adds a few numbers and a small chart. Taller, it lists the rows that need a look, worst first, and counts any it can't fit. With nothing needing a look, it lists the kind's top rows instead. Select a row to open it.
Only a violated boundary rule is marked as a warning, because a check proved it. The other looks are worth a question, not a verdict: an unguarded page may still be protected by its API, for instance.
An empty card says what it will show and the step that fills it. That's the /adopt command to copy, or Draft in chat for boundary rules. On a board no repo is bound to, it asks you to bind one first.
Aspects on the root board
The root board is the map of your systems, so its Aspects screen shows only what passes between them: Clients, Events and Boundaries. Clients and Events are folded from every app's own aspects each time you open them. See Aspects Across Systems.
FAQ
Why can't I edit an endpoint's path or a table's columns?
They come from the code, and the next /adopt would put them back. Change them in the code, then adopt again.
Does
No. /adopt never touches the rows you created or the fields you can edit, so your classifications, owners and notes survive every adoption.
A kind's hub card is empty, but the repo is bound. Why?
That kind hasn't been adopted yet. The card names the command; run it in the repo.
What's next
The Code Plugin
/adopt in full: every kind, its flags, and what it reads.
Boundary Rules
Declare which parts of a board may depend on which, and see every crossing.
Aspects Across Systems
The events and calls that pass between your apps, on the root board.
Pages
An app's routes, captures and guards, on a screen of their own.