A connection is stored like an import
A BaseHalf connection is saved once inside the downstream item, as a Markdown frontmatter `upstream:` list or `.bh/mirror/<path>/upstream.yaml`. Git can diff it. An agent that opens the file can read what it builds on.
You drag a handle from one card onto another and a line appears. The next questions are usually practical. Where did that connection go? Will git see it? If Claude Code or Codex opens the note later, how does it discover the link?
BaseHalf stores a connection the way a source file declares its imports: once, inside the file that uses the context. A → B is saved in B. A is upstream of B. There is no separate graph database, and nothing extra is written into A.

Where the list is written
The storage place depends on whether the downstream item can hold a list itself.
| Downstream item | Where the upstream list lives |
|---|---|
| A Markdown note | YAML frontmatter at the top of the file, under upstream:, with paths relative to the workspace folder |
| A note that cannot hold a list, for example one that starts with a horizontal rule | Kept by BaseHalf under .bh/mirror/<path>/upstream.yaml |
| A folder, PDF, image, video, or any other file that cannot hold a list | The same mirror file: .bh/mirror/<path>/upstream.yaml |
A Markdown note that had no frontmatter gets a block the first time BaseHalf needs to write one. It tells you once.
Here is the shape used in the connections docs, as an illustration:
---
upstream:
- research/interviews.md
- sources/survey-results.pdf
---
# Launch decisionThose paths are relative to the workspace folder. The list is plain text. You, an agent, or another editor can change it. BaseHalf uses whatever is saved. It also writes the list when you connect, disconnect, or reconnect on the canvas, edit the badge, create a connected item, or fix a broken entry. When an item moves, it rewrites the entries that name that item.
Downstream is never stored anywhere. The badge's Downstream list is computed from every upstream list in the workspace. Add Downstream on card A writes A into the other item's upstream list. There is one source of truth, and it lives in the files that consume context.
Markdown links never create these entries. Drawing a line or using Add Upstream does.
Why git and agents can both read it
Because the declaration sits in B, a git diff after you draw the line shows the new upstream: entry in the file you dropped onto. A teammate who never opens the canvas still sees what the note builds on. An agent that opens the note sees the same list, without a prompt dump of the whole workspace.
BaseHalf never injects those upstream files into an agent's prompt. Agents read files themselves. The BaseHalf skill tells them where descriptions and connections live, so they know to look at frontmatter or the mirror file. That is the same idea as putting agent context in upstream lists: the relationship is in the folder, not in a chat you will close.
Use a connection when B should keep building on A across sessions. Use selection when you only mean "this" for one ask.
What this storage model does not do
Changing what B draws on means editing B, or reconnecting on the canvas, which edits B. Deleting A does not rewrite B. The entry that named A stays, now broken, until you Relink, Relink Everywhere, or Remove it. Fix a broken upstream path covers that maintenance step.
Generated files keep the inputs that made them. Changing those inputs is refused. Drafts keep their inputs under the mirror path while they generate.
You can treat an upstream list the way you treat an import list: read it in the file that needs the context, commit it with that file, and let the next session discover it by opening the file.