Open with AI
Connected repositories
A decision in one project often rests on one made in another. A service follows the platform team’s logging directive; a product builds on a shared framework. When you connect the other repository, entries in your graph can reference its entries directly, and you and your agent can search and read its graph next to your own.
A connection runs one way. Your graph depends on the other graph, and the other graph knows nothing about yours.
Repository identity
Section titled “Repository identity”Every graph has a repo_id, a URL-shaped name such as github.com/acme/platform. sdd init derives it from the origin remote and writes it to .sdd/config.yaml. A repository without an origin remote has no repo_id, and no other graph can connect to it until it has one.
An entry in another graph is referenced by the graph’s repo_id, a colon and the entry ID:
Connect a repository
Section titled “Connect a repository”In your project, run sdd repo add with the other repository’s clone URL. SSH and HTTPS URLs both work, and the clone uses your git credentials.
The command:
- clones the repository into a cache on your machine, under
~/.cache/sdd/<repo_id> - reads the
repo_idthe repository declares in its.sdd/config.yamland checks it against the URL - records the connection in your user-global config,
~/.config/sdd/config.yaml - adds the
repo_idtodependenciesin your project’s.sdd/config.yamland commits that change assdd: repo add <repo_id>
sdd repo list shows every repository connected on your machine, across all your projects, and whether each has a cache.
What is shared and what stays on your machine
Section titled “What is shared and what stays on your machine”sdd keeps two records:
dependenciesin.sdd/config.yamlis committed. It lists the graphs this graph references, like the requirements in ago.modfile. Everyone who clones the project gets it.reposin~/.config/sdd/config.yamlis yours. It records how your machine reaches each repository: itsrepo_idand the clone URL you chose.
When a colleague clones the project and runs sdd init, sdd names each declared dependency that is not connected on their machine and suggests a clone URL. They run sdd repo add with the URL they use. The dependency is already declared, so the command only connects it.
The configuration reference describes both keys.
A connected graph is what was pushed
Section titled “A connected graph is what was pushed”sdd never reads another repository’s working tree. The cache is a clone of the remote’s default branch. An entry recorded in the platform repository reaches your project only after two things happen:
- Someone commits and pushes it to the platform repository’s default branch.
- Your cache pulls it.
These commands pull the caches before reading them, at most once every 15 minutes per repository:
sdd searchandsdd viewwith--repoor--all-repossdd showwith a full<repo_id>:<entry-id>sdd indexwith--repoor--all-repos
If a pull fails, for example offline, sdd warns and reads the cache as it stands. sdd show with a short ID reads the cache without pulling, and so does the sdd server your agent works through. Before you ask your agent to reference an entry that was pushed recently, pull the caches yourself:
The same holds in the other direction. For another project to reference your entries, commit and push them.
sdd repo sync only touches the caches. sdd sync --pull is a different command, which merges upstream changes into your own repository.
References across graphs
Section titled “References across graphs”You rarely type a reference yourself. Your agent drafts references when it records an entry, and you confirm them. Before the entry is written, sdd checks two rules:
- The target repository must be in
dependencies. If it is not, sdd blocks the entry and namessdd repo addas the fix. - A reference to an entry the new one builds on, such as
grounded-inorbuilds-on, must point to an entry that exists in the cache. Onlysurfacesandrequired-bymay point to an entry that does not exist yet.
The entry file stores the full form:
A reference across graphs links two entries. It cannot close or supersede an entry in the other graph; those links work only within one graph.
sdd show takes the full form or a short ID. A short ID resolves when it matches exactly one entry in your graph and its dependencies; when it matches several, sdd lists them.
Search across graphs
Section titled “Search across graphs”sdd search and sdd view read your own graph unless you add --repo <repo_id>, which you can repeat, or --all-repos:
--all-repos reaches the dependency closure: your dependencies, their dependencies, and so on. A repository connected on your machine but outside that closure is never read, and naming it with --repo is an error. Each repository in the closure needs a connection on your machine; sdd skips one without a connection and warns.
sdd search merges the hits from all graphs into one ranked list and prefixes each hit from a dependency with its repo_id. sdd view renders the layout for your graph, then once for each selected dependency under a repo: heading.
Your agent’s search and view tools offer the same choice, so you can ask it to look in the platform graph.
Search by meaning across graphs
Section titled “Search by meaning across graphs”Search by meaning compares embeddings, so all graphs must be embedded with the same model. For a search across graphs, sdd embeds every graph, your own included, with the embedding settings in your user-global config. Set them there; without them, sdd uses your project’s settings. The configuration reference lists the keys.
The first search embeds each dependency’s entries, which takes a while for a large graph. To build the indexes ahead of time:
sdd index --repo <repo_id> --force rebuilds a dependency’s index from scratch. sdd keeps one index per repository and embedding setup on your machine, shared by every project that depends on that repository.
Remove a dependency
Section titled “Remove a dependency”This removes the repo_id from dependencies and commits the change. It refuses while any entry in your graph references the repository and lists those references. --force removes the dependency anyway and names each reference it leaves unresolvable. The connection in your user-global config and the cache stay in place.
When something does not resolve
Section titled “When something does not resolve”| What you see | Cause | Fix |
|---|---|---|
entry not found: <repo_id>:<entry-id>, or a new entry blocked because its target is absent from the repository’s default branch |
The entry is not pushed, or your cache predates it | Push it in the other repository, then run sdd repo sync |
[unresolved: repo <repo_id>] in sdd show, or a warning that a dependency is not connected on this machine |
Your project declares the dependency, but your machine has no connection | sdd repo add <clone-url> |
not in the project's dependency closure |
The repository is connected on your machine, but this project does not depend on it | sdd repo add <clone-url> in this project |
declares no repo_id in .sdd/config.yaml |
The other repository has no identity yet | Add an origin remote there, run sdd init, commit and push |
declares repo_id …, but its clone URL derives … |
The URL points to a fork, a mirror or another repository | Use the URL of the repository that declares that repo_id |
sdd lint reports a reference into a repository that is not a declared dependency |
The dependency was removed with --force |
Declare it again with sdd repo add |
| Every read warns that a pull failed with a non-fast-forward error | The other repository rewrote its history | Delete the cache directory under ~/.cache/sdd/ and run sdd repo sync to clone it again |