Full developer documentation for SDD. Individual pages are also available at .md for targeted access.
---
# What is SDD?
> The problem SDD solves, how it works, what it gives you, and who it is for today.
**SDD is a new way of working for people and AI agents on a project.** Agents have changed the speed of work: code and other output arrive faster than ever, and the decisions and shared understanding behind them have to keep pace. In SDD, people make the decisions and understand and shape the why behind them, with agents helping at every step. We believe that lets people and agents do better and more autonomous work.
Knowledge builds up while you work. As you work with your agents through SDD, what anyone notices becomes a signal, dialogue turns signals into decisions, and the work follows. Dialogue between people, in a meeting or a chat, can be distilled into the graph the same way. Everything confirmed lands in a graph that acts as agent-native memory for the whole project, so every person and every agent starts from what was decided and why. The graph also shapes the work: the procedures your agent follows are entries in it, so a project adapts how it works the same way it records what it decided. It is information and process at once.
## The problem
A session with an AI agent produces reasoning: what you noticed, which options you weighed, what you decided and why. When the session ends, that reasoning is gone. The next session, yours or a colleague's, starts from the project files and whatever you remember to tell the agent. Decisions made in meetings and chat fare no better. They get argued again, and every newcomer rebuilds the picture by asking around.
In our experience, tools that try to keep this reasoning fall short in one of two ways. Some record everything and leave a searchable pile of what was said, with no way to tell what was decided. Others spread the project's state across documents, plans, roadmaps and tickets that repeat each other and drift apart.
## How SDD works
SDD stands for Signal, Dialogue, Decision. It keeps a project's reasoning in a graph: a network of small entries linked to each other. There are two types of entry:
- A **signal** records something noticed, such as a problem, a fact, an open question or finished work.
- A **decision** records something committed to, such as a direction, a plan or a standing rule.
Each entry states its reasoning and links to the entries it builds on. Entries are plain text files in your project's git repository, readable without SDD, and sdd commits each one. When the work a decision asked for is done, a done entry records it and closes the decision.
You take part by talking. The agent reads what the graph holds on the subject before it answers, drafts an entry when something is worth keeping, and plays it back to you. Nothing reaches the graph until you confirm it.
This is the move that happens in every session: a dialogue starts from the graph's current picture of the project and ends by capturing what changed in it. Session by session, the graph comes closer to the project's actual state and to what the people in it understand.
## What you get
- **Agents start from what was decided.** When a session opens, the `sdd` server gives your agent the project's direction, focus, participants and recent changes, so you don't explain the project again.
- **A confirmed record of why.** You confirm every entry, and a pre-flight check compares it with the graph and stops the write on a serious problem such as a contradiction.
- **Status nobody maintains.** Entries are never edited. A later entry closes or replaces an earlier one, and what is open, active or closed follows from those links. There is no status field to update.
- **A briefing when you return or join.** Ask where things stand, and the agent briefs you from the graph: current focus, recently finished work, open questions and gaps, work in progress.
- **Parallel work without overwrites.** Entries are only ever added, so several people and agents can write to the graph at once.
## Who it is for today
SDD runs inside coding agents, currently Claude Code and Codex, on a project kept in git. It is for developers and teams who work with those agents, alone or together. Typically you work with an agent such as Claude Code that uses SDD and the graph to augment your own work. SDD's open source core, the `sdd` program and its server, is on [GitHub](https://github.com/networkteam/sdd) under the MIT license.
The aim reaches further. Product owners, designers and domain experts should take part directly, through chat, voice or a hosted version that needs no setup. And the more of a project's decisions and guidelines the graph holds, the more freedom you have to let agents work on their own where you choose to: some things can simply be done and looked after, instead of being discussed in theory first. Throughout, the point is better decisions, made by being better informed. Parts of this are directions, not shipped features. The [Vision](/sdd/vision/landscape/) marks what works today and what is still being built.
## What SDD is not
- **Not a recorder.** The graph holds the project's shared current understanding, not a recording of how it was reached. An entry can carry the dialogue behind it, such as a transcript, as an attachment, but what the graph says is what you confirmed.
- **Not a ticket system or a set of documents to maintain by hand.** Nobody keeps status fields, queues or boards up to date. Overviews are derived from the graph: today the agent's briefings and `sdd view` layouts, later boards and similar views. The raw graph quickly grows too large for people to work through directly, so agents read much more of it and align with you on what matters right now, and that dialogue captures the updated picture back into the graph.
- **Not an agent writing your record on its own.** The agent reads, drafts and runs the steps. Today you confirm every entry, and only you can override a pre-flight finding.
## Next steps
- [Getting started](/sdd/getting-started/) installs sdd, sets up a project and walks you through a first dialogue.
- [Working modes](/sdd/working-modes/) describes the moves your agent offers in a session.
---
# Getting started
> Install sdd, set up a project, found its graph through a first dialogue, and record your first observation.
By the end of this page your project has an SDD graph, founded in a first dialogue, and holds your first recorded observation. You work in Claude Code or Codex. Your agent does the graph work through the `sdd` server; you take part by talking with it.
## Before you start
- **A git repository with a branch checked out.** For a new project, `git init` is enough. sdd commits everything it records, so git needs your `user.name` and `user.email`.
- **Claude Code or Codex.**
- **An API key for a model provider**, such as Anthropic, OpenAI or the Opper gateway, or a local [Ollama](https://ollama.com). Step 2 shows where it goes.
## 1. Install sdd
With Homebrew:
```bash
brew install networkteam/tap/sdd
```
Or with the install script, which puts the binary in `~/.local/bin`:
```bash
curl -sL https://github.com/networkteam/sdd/releases/latest/download/install.sh | sh
```
Check that it is on your `PATH`:
```bash
sdd --version
```
Your agent starts sdd as the plain command `sdd serve`, so a binary outside your `PATH` will not be found.
## 2. Connect a language model and search
sdd uses a language model whenever it records an entry: to check the draft's wording, to check it against the graph, and to write its one-line summary. An embedding model makes the graph searchable by meaning, not only by keyword. Set both once for your user, and they apply to every project. `sdd config set` writes to `~/.config/sdd/config.yaml`; add `--local` to set a value for the current project on this machine only.
### Language model
For example, with the Anthropic API:
```bash
sdd config set llm.provider anthropic
sdd config set llm.model claude-sonnet-4-6
sdd config set llm.api_keys.anthropic
```
For hosted open-weight models, or one key for many models, use an AI gateway such as [Opper](https://opper.ai) through its OpenAI-compatible route:
```bash
sdd config set llm.provider openai
sdd config set llm.endpoint https://api.opper.ai/v3/compat/chat/completions
sdd config set llm.model greenpt/glm-5.3-flash
sdd config set llm.api_keys.openai
```
The other providers are `openai` for OpenAI itself, and `ollama` for models running on your machine. [Language model providers](/sdd/reference/configuration/#language-model-providers) has a configuration for each.
Every check asks the model for a fixed response format, so the provider and model must support structured output. With one that does not, such as Ollama Cloud, the checks fail.
Without a provider, sdd falls back to `claude-cli`, which runs every check through your local Claude Code installation. It needs no key, but it is slow, and checks can time out.
### Embedding model
For example, with OpenAI:
```bash
sdd config set embedding.provider openai
sdd config set embedding.model text-embedding-3-small
sdd config set embedding.api_keys.openai
```
The embedding model needs its own key setting, even when the language model uses the same OpenAI key. For embeddings on your machine with Ollama, see [Embedding providers](/sdd/reference/configuration/#embedding-providers).
Without an embedding model, search by keyword still works. When you join a project that already has entries, run `sdd index` once to make them searchable by meaning; new entries are added as they are recorded.
### Check the result
```bash
sdd config
```
This lists every effective setting and where it comes from. The `sdd` server reads the configuration when it starts, so restart your agent after a change.
## 3. Set up the project
Run `sdd init` in the project root:
```bash
sdd init
```
On a new project it asks for:
1. the graph directory, `.sdd/graph` by default
2. the graph language, `en` by default
3. where to install the skill: choose **project**
4. your participant name, by default your git user name
5. which agents to set up: Claude Code, Codex, or both
It then writes these files and commits them as `sdd: init .sdd/ metadata directory`:
| File | What it is |
| --- | --- |
| `.sdd/config.yaml` | Project settings, shared through git |
| `.sdd/config.local.yaml` | Your participant name, on this machine only |
| `.claude/skills/sdd/` or `.agents/skills/sdd/` | The `sdd` skill for your agent |
| `.mcp.json` and `.claude/settings.json` | Claude Code: starts the `sdd` server and allows its tools |
| `.codex/config.toml` | Codex: starts the `sdd` server |
In a repository that already uses SDD, `sdd init` only asks for your name and installs the skill as the project has it configured.
If you chose **user** instead of project for the skill, sdd does not register the server. Register it yourself, for Claude Code with `claude mcp add sdd -- sdd serve`.
:::note[What just happened]
The graph is empty so far. The skill is only a pointer: it tells your agent to open a session with the `sdd` server. The working process itself, how a capture or a check-in runs step by step, ships inside the sdd binary and is served to the agent as the session goes on.
:::
## 4. Open a session
Start your agent in the project directory. If Claude Code asks whether to enable the project's `sdd` server, approve it. Then type:
- `/sdd` in Claude Code
- `$sdd` in Codex
The agent opens a session. The server gives it an orientation: the working principles, the project's direction, what is in focus, who takes part, and what changed recently. On a new project most of that is empty. From here on, you talk; you don't need to know any commands.
## 5. Found the graph with bootstrap
On an empty graph the agent suggests bootstrap, the dialogue that founds the graph. You can also ask for it: "Let's bootstrap this project."
Bootstrap runs as an interview:
- It first asks whether you already know SDD, and explains what you need as it comes up.
- In an existing repository, the agent reads the README, docs and recent history first, so you correct its picture instead of starting from nothing.
- It asks one question at a time: what the project is, how it is approached, why it exists, who is part of it.
- When an answer forms a coherent piece, the agent plays it back as the text it would record. You accept it, reshape it, or set it aside.
- Accepted pieces become entries, recorded one by one. Typically these are an actor entry for you, your role on the project, and the aspirations and directives that frame it.
- After the first entries, the agent proposes a few topic labels, such as `product/vision`, so related entries can be found together.
- It ends with a check-in: a short briefing on the new graph.
A sparse bootstrap is fine. One participant and one entry that frames the project are enough to start; you can deepen it in any later session.
:::note[What just happened]
These first entries are what every later session starts from. When the agent opens a session, it reads the project's direction and participants from the graph, so you do not explain the project again.
:::
## 6. Record your first observation
Tell the agent something you noticed, in plain words, for example that a step in your setup fails and what you expected instead. The agent recognizes an observation and starts a capture:
1. **Draft.** The agent searches the graph for related entries, reads them, and drafts the entry: its kind (a gap, for something that falls short of what was expected), its text, and links to the entries it relates to.
2. **Writing check.** A separate model reads the draft as a stranger would and points out what is unclear. The agent revises.
3. **Playback.** The agent shows you the exact entry. You confirm it, ask for changes, or drop it. Nothing is written before you confirm.
4. **Pre-flight check.** Another check compares the entry with the graph, for example for contradictions with the entries it links to. A serious finding stops the write: you revise the entry, or override the check. Overriding is your call alone, never the agent's.
5. **Write.** sdd generates a one-line summary, writes the entry as a markdown file under `.sdd/graph/`, and commits it as `sdd: capture `. The agent compares the summary with the entry and corrects it if it drifted.
If a model call fails, the step stops and the agent tells you. Nothing half-done is written.
:::note[What just happened]
The gap is now open in the graph. The next check-in lists it among the things the project owes attention, until a decision or a completed piece of work closes it. The [entry kinds](/sdd/reference/entry-kinds/) reference explains what each kind is for.
:::
## How knowledge flows
One loop drives the graph. A signal, something noticed, meets dialogue and becomes a decision, something committed to. When the work is done, a done entry records it and closes the decision, and what the work turned up feeds the next signals.
- **The graph prepares the dialogue.** Before drafting or answering, the agent reads what the graph holds on the subject, so a conversation starts from the project's recorded state instead of your memory.
- **The dialogue moves the graph.** Nothing is recorded without your confirmation, and every entry links to the entries it builds on.
- **Entries are never edited.** A later entry closes or replaces an earlier one. What is open, active or closed is worked out from those links, and git keeps the full history.
## Next steps
Ask your agent in plain words; it recommends the right move:
- "Where do we stand?" gives a check-in: what is in focus, what changed, what is open.
- Naming an entry, or "let's work on this", digs into it and offers the next steps.
- Agreed work runs as an implementation, which ends with a done entry citing the commits.
- Finished work can be evaluated, and the graph can be groomed of entries that are resolved but still open.
[Working modes](/sdd/working-modes/) describes each move. To look up what an entry kind is for, see [Entry kinds](/sdd/reference/entry-kinds/); for every setting, see [Configuration](/sdd/reference/configuration/). For where SDD is heading, see the [Vision](/sdd/vision/landscape/).
---
# Working modes
> The moves your agent offers in an SDD session, when to use each, and what it leaves in the graph.
In an SDD session you don't pick a mode or type commands. You talk with your agent. When a move fits what you are doing, the agent recommends it, and you decide whether to start it. A move runs step by step, served by the `sdd` server, and anything it writes to the graph is played back to you first and needs your confirmation.
## How a session opens and ends
Type `/sdd` in Claude Code or `$sdd` in Codex. The agent opens a session, and the `sdd` server gives it an orientation: the project's direction, what is in focus, who takes part, and what changed recently. You can talk in any language; entries are written in the graph language set for the project.
Questions about the graph need no move: the agent searches and reads entries as you ask. When you ask for a move directly, for example to record something, the agent starts it. Otherwise it suggests one and waits for your answer.
A running move can be parked and picked up later in the same session. When something comes up that you want to record later, the agent can start a capture and park it, so it waits as an open thread instead of a promise.
At a natural stop, the agent offers to wrap up and names each thread that is still open. Wrapping up ends the session for good and leaves open threads behind, so finish or drop them first. If you leave without wrapping up, the session stays open, and your agent can resume it when you give it the session ID.
## Catch-up
Use it when you want to know where things stand: "Where are we?" or "What changed this week?" The agent recommends it for that. It does not run by itself when a session opens.
- The server gathers a fresh view of the graph: the current focus, recently finished work, active work drawing attention, commitments not yet acted on, open questions and gaps, and work marked as in progress.
- The agent turns this into a short briefing grouped by the project's main threads, with numbered items and their entry IDs.
- Below the threads it lists other open areas you can ask to drill into.
- It ends with one question: what do you want to move forward?
- Your answer usually starts an engage on the entry you picked, or a capture.
A catch-up only reads. It leaves nothing in the graph.
## Capture
Use it when you notice something or settle something: "The export drops rows without a date" or "Let's release every two weeks." A [plan](/sdd/reference/entry-kinds/#plan) is captured the same way, with acceptance criteria: the outcomes that must be true when the work is done.
- The agent searches the graph and drafts one entry: its [kind](/sdd/reference/entry-kinds/), its text, and links to the entries it builds on.
- A separate model reads the draft as a stranger would and points out what is unclear. The agent revises.
- The agent plays back the exact entry. You confirm it, ask for changes, or drop it.
- A pre-flight check compares the entry with the graph. A serious finding stops the write until you revise the entry or override the check. Only you can override.
- sdd writes the entry with a generated one-line summary and commits it. The agent checks the summary against the entry.
It leaves one new entry. The entry can also close or replace an earlier one, and then says why. [Getting started](/sdd/getting-started/#6-record-your-first-observation) walks through a first capture.
## Engage
Use it to work on one specific entry: "Let's look at the onboarding plan", or an entry ID such as `d-tac-ry0`. Picking an item from a catch-up usually leads here. Closed entries work too, for example to look back on finished work.
- If you describe the entry, the agent searches and lets you pick from the candidates.
- It reads the entry and the entries around it in full.
- It gives you a brief shaped by the entry and your goal. For a plan you want to build, that is a table of its acceptance criteria: done, partly done or open. For an observation, it is what happened since and what it needs.
- It proposes next moves. Some act on the entry, such as implementing, replacing or closing it. Others check other work against it, for example against an [aspiration](/sdd/reference/entry-kinds/#aspiration).
- You pick one, and it runs as its own move.
Engage itself writes nothing. The move you pick may.
## Implementation
Use it when work is ready to build, usually a [plan](/sdd/reference/entry-kinds/#plan), a [directive](/sdd/reference/entry-kinds/#directive) or an [activity](/sdd/reference/entry-kinds/#activity). A [gap](/sdd/reference/entry-kinds/#gap) you want fixed or another entry works too. "Let's implement the export plan."
- The agent reads what the work must deliver, including later decisions that add to it, and says whether enough is decided to start. If a decision is missing, you capture it first.
- You choose how to run it: on the main branch, on a separate branch, in a separate git worktree, or as a quick change too small to track. Except for a quick change, the entry is marked as in progress.
- The agent builds in slices and checks in between them. A choice no decision covers stops the work until you settle it together, and what you settle is captured.
- At the end it commits, records a done entry, and shows which criteria are met. You give the go-ahead to land it, and it offers an evaluation.
It leaves a [done](/sdd/reference/entry-kinds/#done) entry citing the commits, plus any decisions captured along the way. A done that covers everything closes the entry it implements; a partial one says what remains.
## Evaluate
Use it to judge finished work: "Did the new export hold up?" The agent offers it when an implementation ends, and you can start it later on any done entry.
- The agent reads the work and what happened since it landed, including earlier evaluations.
- It proposes which lens this run covers. The inner lens asks whether the work is sound by the project's own standards. The outer lens asks whether it is the right thing, working in use for the people it serves. One lens is enough, and your project's guidelines define what each means.
- The agent inspects and runs the work, and asks for your judgment or other people's feedback, which count as evidence.
- It tells you what held and what didn't.
- You decide whether to record the evaluation and which findings to keep.
Recorded, it leaves a done entry for the evaluation that names the lens it covered, plus one entry for each finding you chose. A clean pass is worth recording too.
## Groom
Use it when the graph's status looks out of date: "Let's tidy up the graph." Grooming decides nothing new. It records what the graph already implies.
- The agent sweeps the graph for entries that look resolved but are still open, in-progress markers on work that has ended, entries a newer one restates without replacing them, and directives that contradict each other.
- It shows a numbered table: each candidate with its evidence and a proposed cleanup.
- You go through it together, most valuable first.
- Each cleanup you agree to is an ordinary capture, such as a done that closes finished work or a decision that replaces an older one, played back for your confirmation. A stale in-progress marker needs no entry; the agent removes it once you agree.
It leaves the closing and replacing entries for the cleanups you agreed to. A clean sweep with nothing to fix is a fine result.
## Interview
Use it when you hold knowledge the graph doesn't, or when things don't fit together: "Interview me about how pricing should work." For a quick check, the agent restates its understanding and asks you to confirm instead.
- The agent first searches the graph and notes the assumptions it wants you to correct.
- It asks one open question per turn, with a few sentences of background.
- It checks each answer against the graph, connecting it to entries or pushing back where it conflicts with them.
- When nothing is left to ask, it sums up what became clear and what stays open. You correct the summary.
- You choose which outcomes to record.
Each outcome you choose becomes its own capture, such as a decision, an [insight](/sdd/reference/entry-kinds/#insight) or a [gap](/sdd/reference/entry-kinds/#gap). An interview can also end with shared understanding and nothing recorded.
## Bootstrap
Use it when the graph is new or still thin. The agent suggests it then, or you ask: "Let's bootstrap this project." [Getting started](/sdd/getting-started/#5-found-the-graph-with-bootstrap) walks through a first run.
- The agent asks whether you know SDD and adjusts how much it explains.
- In an existing repository it first reads the README, docs and recent history, and asks you to correct its picture.
- It asks one question at a time about what the project is, how it is approached, why it exists and who is part of it, following your lead.
- When a group of entries has formed, it plays back the text it would record. You accept it, reshape it or set it aside.
- It records accepted entries one by one. After each group you choose to continue or stop.
It typically leaves an [actor](/sdd/reference/entry-kinds/#actor) and a [role](/sdd/reference/entry-kinds/#role) for each person taking part, the [aspirations](/sdd/reference/entry-kinds/#aspiration) and [directives](/sdd/reference/entry-kinds/#directive) that frame the project, and a first set of topic labels. It ends with a catch-up. You can run it again later to go deeper.
---
# Working with coding agents
> Practical do's and don'ts for SDD sessions in Claude Code and Codex, covering forks, rewinds, compaction, resuming and wrapping up.
When you work with SDD in Claude Code or Codex, two sessions run side by side. Most surprises come from mixing them up.
- **The agent session** is your conversation with Claude Code or Codex. It holds what the agent remembers.
- **The sdd session** is the dialogue the `sdd` server tracks: which moves are running, at which step, and what they have collected so far. `/sdd` opens one, and its session ID is the only thing the agent needs to continue it.
The agent keeps the two in step by carrying the session ID and following what the server serves. The tips below are about the situations where they drift apart.
## Capture what matters
An sdd session is scaffolding, not a record. Only entries in the graph last. Anything worth keeping, a decision, an open point, the state of unfinished work, belongs in an entry. A capture you want to finish later can be started and parked, so it shows up as an open thread instead of living in the agent's memory.
## One sdd session per conversation
- **Don't let two conversations drive the same sdd session.** If you fork or branch an agent conversation, both copies carry the same session ID. Each would advance the same moves while believing it is at its own position. Keep the sdd session in one copy, and run `/sdd` in the other to open a new session.
- **Parallel agents each get their own session.** Several agents can work on one graph at the same time, each in its own sdd session. The graph is append-only and lives in git, so their entries do not overwrite each other.
- **Tell the agent when you switch branches.** The agent declares which branch the session works on, so reads and captures land on the right branch. If you switch branches or move into a worktree yourself, say so.
## Don't rewind past a step sdd has taken
Claude Code and Codex let you jump back in the conversation and continue from an earlier message. The sdd session does not jump back with you: a move that advanced stays advanced, and an entry that was written stays written and committed. After a rewind past such a step, the agent's memory and the session no longer match.
- Rewind only to a point after the last sdd step. A move started before that point keeps running in the session even if the conversation no longer remembers it.
- If you rewound too far, ask the agent to resume the sdd session. It then receives the current position again and continues from there.
- To undo an entry, record a new one that closes or replaces it. Entries are never edited or deleted.
## Compaction
When a conversation grows long, the agent compacts it into a summary. The sdd session survives this, as long as the session ID survives:
- After compaction the agent should resume the sdd session, which serves every running move at its current step together with its instructions.
- If the agent carries on from memory instead, skipping steps or answering for you, remind it: "Resume the sdd session first."
- If the summary lost the session ID, the agent cannot find the session by itself. Give it the ID, or start a new session with `/sdd`.
In practice it often works better to avoid compaction in long work. Capture the current state, for example as progress notes on the implementation or a partial done, and continue in a fresh agent session.
## Resume a session in a fresh agent session
A session you did not wrap up stays open. In a new agent session, give the agent the session ID and ask it to resume that session. It receives the open moves at their current steps and can continue an unfinished capture or implementation where the old conversation stopped. Ask your agent for the session ID before you close a conversation you may want to continue.
How best to hand work between agent sessions this way is still being worked out. Capturing the state as entries first is the safer path.
## Wrap up sessions
At a natural stop, the agent offers to wrap up and names every thread that is still open. Wrapping up ends the session for good: an open thread left behind cannot be resumed afterwards. Finish the threads worth finishing, drop the others with a reason, and keep the session open if something should continue. Leaving without wrapping up costs nothing; the session stays resumable by its ID.
## In the dialogue
- **Read the playback.** Confirming writes exactly what the agent showed. Ask for changes until it says what you mean.
- **Override the pre-flight check only on purpose.** A serious finding stops the write; overriding is your call alone and is recorded on the entry.
- **Say it in your own words.** The agent turns it into an entry and asks when something is unclear. You don't need to know the [entry kinds](/sdd/reference/entry-kinds/) or the [working modes](/sdd/working-modes/) by name.
---
# Teams and processes
> How teams use SDD today in product development and IT operations, the ways of working that hold up, what you learn by using it, and what is still rough.
This page collects how teams work with SDD today. It describes what works now. Where SDD is heading is on the Vision page [How will that feel?](/sdd/vision/scenes/). The page grows as SDD does.
## What teams use it for
Most use is in product development with software development, in small teams of two or three people and, more recently, in larger setups. Teams use SDD to:
- work out requirements, UX and technical concepts until they become plans that go into development [step by step](#working-in-small-steps),
- build those plans with their coding agent inside the session, [on a branch](#implementing-on-a-branch) when the work needs one,
- turn meetings into recorded decisions and [shared understanding](#meetings-and-dialogue-between-people),
- get new people oriented by [asking the agent](#sharing-work-with-your-team),
- write tickets and merge request descriptions [with the background included](#issue-trackers-as-a-projection),
- keep IT operations knowledge, meaning what happened to the systems and how problems were solved, next to a [reference wiki](#operations-knowledge-with-a-wiki).
Each person works in their own sessions with their own agent. The graph is what they share.
## Who takes part
Developers, and more and more people in product, UX and project lead roles. They run the same kind of agent session but start from a different question. Not "How can I implement that?" but "This is the customer need. Why does the customer need it? What do we have? How could we do it? What are the approaches?" Ask why again of each answer until you understand the background well. That understanding helps the team align later.
That gives them direct access to the technical background, so they can shape requirements without involving a developer at every point. What they work out goes back into the graph as observations, questions and directives.
Bringing in people without a technical background has only started. It is too early to describe how that works.
## Ways of working
### Sharing work with your team
- **Push and pull the graph.** sdd commits every entry it records, but it does not push or pull. Do that with git, as you do for code.
- **New entries reach running sessions.** When entries land in the graph while a session runs, for example after a pull, the agent sees them among the recent changes and can bring them into the dialogue.
- **Answer with an entry ID.** When someone asks about something that is already captured, send them the entry ID. They open a session with it, for example `/sdd let's look at d-tac-ry0`, and get the entry together with how it connects and the reasoning around it.
- **Ask the agent.** To find your way into a topic, tell the agent your goal and what you need to understand. It searches the graph and answers from what it finds. If the answer is not there, record a [question](/sdd/reference/entry-kinds/#question). It stays open and shows up in catch-ups until someone answers it.
### Meetings and dialogue between people
Dialogue between people works well with SDD, and transcripts carry it into the graph. A loop that works well:
1. Prepare the meeting in a session. Name the topic and the participants, and let the agent gather what the graph holds on it and what is open.
2. Hold the meeting with that preparation.
3. Transcribe the meeting, work through the transcript in a session, and apply it to the graph.
4. Follow up with sessions for targeted captures.
This turns even a dense two-hour meeting into focused entries and puts the shared understanding in the graph. When you apply a transcript, name the people who took part so the entries list them as participants, and attach the passages an entry rests on. No move is dedicated to transcripts yet. The agent proposes entries in the dialogue, and you confirm each capture as usual.
A second pattern helps when some people in a team have gone deeper into a topic than the others. They work through it with their agents, prepare a document for a dialogue with the others, hold that dialogue, and bring the feedback back into the graph. It aligns understanding, carries knowledge across the team and leads to better decisions made together.
Clients are not connected directly yet. Their input arrives through tickets, calls and meetings and takes the same path into the graph.
### Working in small steps
The graph tracks work, but not the way an issue tracker does. No entry moves through states. Instead the graph grows: new knowledge, experiences and decisions come up while you work, and you record them as they appear. Starting from one [directive](/sdd/reference/entry-kinds/#directive), a typical sequence is:
1. Write a first [plan](/sdd/reference/entry-kinds/#plan) from what you know now.
2. Work on it in iterations.
3. Record [done](/sdd/reference/entry-kinds/#done) entries, partial ones too.
4. Hold a new dialogue or run an [evaluation](/sdd/working-modes/#evaluate).
5. Shape the next plan.
6. Refine earlier decisions where needed.
The pull toward planning everything up front is always there. Plan from what you understand now, take the next step that teaches you more, and check that you are still heading where the aspirations and strategic directives point.
### Implementing on a branch
Development runs inside the sdd session too. With the [implementation](/sdd/working-modes/#implementation) move, your coding agent builds agreed work. It can start from a plan, a directive, a gap to fix or another entry, and work on the main branch, on a separate branch or in a separate git worktree.
On a branch, capture what comes up during the development there: a decision settled while building, a gap found on the way, the done at the end. These entries reach the main graph only when the branch is merged, together with the code. Entries pushed to main before the code would describe a state of the project that nobody else can see yet. The entry being implemented is marked as in progress on the main branch when the work starts, so the others see that it is taken once you push.
Tell the agent when you switch branches or move into a worktree, so its captures land on the right branch. [Working with coding agents](/sdd/guides/working-with-coding-agents/#one-sdd-session-per-conversation) has more on this.
Merging graph branches rarely conflicts, because entries are never edited and each one is a new file with its own ID. If the same thing was captured twice, or an entry was closed twice, nothing breaks. You can join them later, for example with one entry that replaces both and carries what each said. The [groom](/sdd/working-modes/#groom) move finds such cases.
### Issue trackers as a projection
Teams can still use issue trackers, but as a projection of the graph. Once the graph holds a good picture of something, the agent writes the issue or merge request description from it, with the background included. With the tracker's CLI or MCP server available, the agent creates them directly. Tickets keep people who don't use SDD up to date, and the graph stays the source of truth. A team that works fully with SDD would not need an issue tracker.
### Operations knowledge with a wiki
For IT operations, one setup keeps the graph and a Markdown wiki, for example an Obsidian vault, in the same repository. The team browses the wiki for hosts, services and applications. The agent uses both to answer questions about problems. The graph holds what happened, what was observed and how earlier problems were solved, so recurring problems become visible. The wiki gives an overview that costs little work. Together they help new people get started, let the team share responsibility, and let agents take on more operations work, because they understand the legacy systems and the plans to change them.
A coding agent sets this up in a few minutes. What matters is a few rules in the agent's instruction file, such as `AGENTS.md` or `CLAUDE.md`:
- **The graph is the source of truth.** It holds what happened, what was observed and what was decided, in order. Measurements are evidence for entries.
- **The wiki describes the current state.** It holds reference material such as host lists, versions and network details, and links to entry IDs instead of retelling history. A sentence that is only true as of a past date belongs in the graph.
- **Wiki pages stay small.** A page covers what is not obvious and points to the configuration or the graph for the rest.
- **Every change updates the wiki.** When work changes the current state, the agent updates the affected pages, commits them, and references them in the entry it records, for example the done.
- **The agent researches both.** Before it states a fact about the systems, it reads the graph and the wiki.
## What you learn by using it
### You choose the ceremony
You are in the driver's seat. Tell the agent what you want from the session, and it works out how to get there from the guidance sdd serves. Sometimes you only want to record your current understanding as it is, without working the material further. Other times you dig deep, research and follow several directions. That can pull you into a rabbit hole where it feels like you could never stop, which helps and hurts.
The agent can also propose more structure than the work needs: three entries where one would do, or a plan for a gap you could simply fix and close with a done. Say what you want instead, for example "Capture this as one entry" or "Let's just fix this gap".
There is no wrong way. Use whatever gets you to the next step while you keep the knowledge and decisions in the graph current.
### Step back from the details
You also steer the level a session works at. When it gets dragged into details, tell the agent to step back and look at the bigger picture. Work that picture out first, then decide where to go deeper, possibly in follow-up sessions.
### One angle per session
A graph with many open threads can be a lot at once. It is better to focus on one angle at a time. A terminal multiplexer with coding agent integration, such as [Herdr](https://herdr.dev/), makes splitting easy. Start one session for an overview, sort out what is open and group it, then ask the agent to start a few sdd sessions, one per group, each with a handoff. Each session then follows one thread. As in any parallel work, [each agent gets its own sdd session](/sdd/guides/working-with-coding-agents/#one-sdd-session-per-conversation).
### You think more about the why
Working this way leads you to ask why more often. Why do we do this? What exactly is wrong? "Something doesn't work" is not a good [gap](/sdd/reference/entry-kinds/#gap). A good one sets what is actually the case against what was expected. Over time this makes your own thinking more structured.
### Let information flow
Let information and knowledge flow freely, and look for the points where they don't. Copying information from one tool to another by hand is such a point. With a tool's CLI or MCP server available, the agent acts on it directly. The aim is not to automate everything. People stay in the loop, make the decisions and build the understanding. Less friction lets a team choose how much it hands to agents.
## What is still rough
- **Sync.** Everyone pushes and pulls the graph by hand. Automatic sync is decided but not built.
- **Forwarding.** Nothing notifies people when the graph needs them, so you forward entry IDs yourself. Notifications are planned.
- **Who may decide what.** Nothing checks who may record which decision. Agree on it in the team. A [role](/sdd/reference/entry-kinds/#role) entry can state it, but nothing enforces it.
- **Setup.** Everyone needs git, sdd and a coding agent on their machine. A hosted version is being built, so someone in a non-technical role only connects their agent to it over MCP. The [Vision](/sdd/vision/landscape/) marks where it stands.
---
# Connected repositories
> Reference, search and read the entries of another project's graph, such as a shared platform graph, from your own.
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
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:
```text
github.com/acme/platform:20261107-100000-d-cpt-abc
```
## 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.
```bash
sdd repo add https://github.com/acme/platform.git
```
The command:
1. clones the repository into a cache on your machine, under `~/.cache/sdd/`
2. reads the `repo_id` the repository declares in its `.sdd/config.yaml` and checks it against the URL
3. records the connection in your user-global config, `~/.config/sdd/config.yaml`
4. adds the `repo_id` to `dependencies` in your project's `.sdd/config.yaml` and commits that change as `sdd: repo add `
`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
sdd keeps two records:
- `dependencies` in `.sdd/config.yaml` is committed. It lists the graphs this graph references, like the requirements in a `go.mod` file. Everyone who clones the project gets it.
- `repos` in `~/.config/sdd/config.yaml` is yours. It records how your machine reaches each repository: its `repo_id` and 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](/sdd/reference/configuration/#connected-repositories) describes both keys.
## 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:
1. Someone commits and pushes it to the platform repository's default branch.
2. Your cache pulls it.
These commands pull the caches before reading them, at most once every 15 minutes per repository:
- `sdd search` and `sdd view` with `--repo` or `--all-repos`
- `sdd show` with a full `:`
- `sdd index` with `--repo` or `--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:
```bash
sdd repo sync # every connected repository
sdd repo sync github.com/acme/platform # one repository
```
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
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 names `sdd repo add` as the fix.
- A reference to an entry the new one builds on, such as `grounded-in` or `builds-on`, must point to an entry that exists in the cache. Only `surfaces` and `required-by` may point to an entry that does not exist yet.
The entry file stores the full form:
```yaml
refs:
- id: github.com/acme/platform:20261107-100000-d-cpt-abc
kind: grounded-in
desc: the platform logging directive
```
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.
```bash
sdd show github.com/acme/platform:20261107-100000-d-cpt-abc
sdd show d-cpt-abc
```
## Search across graphs
`sdd search` and `sdd view` read your own graph unless you add `--repo `, which you can repeat, or `--all-repos`:
```bash
sdd search --term logging --all-repos
sdd search --query "how services ship their logs" --repo github.com/acme/platform
sdd view --layout='top(20)' --repo github.com/acme/platform
```
`--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
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](/sdd/reference/configuration/#embedding) 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:
```bash
sdd index --all-repos
```
`sdd index --repo --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
```bash
sdd repo remove github.com/acme/platform
```
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
| What you see | Cause | Fix |
| --- | --- | --- |
| `entry not found: :`, 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 ]` 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 ` |
| `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 ` 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 |
---
# Browsing the graph
> Read the decision graph yourself, from the entry files to sdd show, sdd search, sdd view and sdd info.
Your agent reads the graph for you in every session. You can read it yourself too: to check what the agent works from, to look something up, or to get an overview before a dialogue. Every command on this page only reads.
## Entries are markdown files
Each entry is one markdown file under `.sdd/graph/`, filed by the date it was recorded:
```text
.sdd/graph/2026/11/07-123911-d-tac-ims.md
```
This file holds the entry `20261107-123911-d-tac-ims`. The ID reads as date and time, type, layer and a random suffix:
- type: `s` for a signal, something noticed, or `d` for a decision, something committed to
- layer: `stg` strategic, `cpt` conceptual, `tac` tactical, `ops` operational, `prc` process
The file starts with YAML frontmatter: type, kind, layer, confidence, references to other entries, participants, topics and the one-line summary. The entry text follows. An entry with attachments has a directory of the same name next to its file. `.sdd/graph/wip/` holds the markers for work in progress.
You can read the files in an editor or on your git host. Do not edit them. An entry never changes after it is written; a later entry closes or supersedes it. The file also does not say whether the entry is still open. For that, use `sdd show`.
## Read one entry
```bash
sdd show 20261107-123911-d-tac-ims
sdd show d-tac-ims
```
The short form drops the date and time. When it matches more than one entry, sdd lists the candidates. You can pass several IDs at once.
`sdd show` prints the entry's frontmatter with its current `status`, the entry text, and two lists:
- `upstream`: the entries it references, and the entries those reference, two levels deep
- `downstream`: the entries that reference it, one level deep
Each line in those lists gives the reference kind, the other entry's ID, its kind and status, and its summary. The line below, marked `↳`, says why the two entries are linked. To widen or narrow the lists:
```bash
sdd show d-tac-ims --up 4 --down 3
sdd show d-tac-ims --up 0 --down 0 # the entry alone
```
In a terminal the output is styled; piped to another program, it is plain markdown. `--format text` forces plain markdown.
## Search
`sdd search` finds entries by keyword, by meaning, or both:
```bash
sdd search --term importer # keyword
sdd search --query "how imports handle variants" # by meaning
sdd search --term importer --query "variants" # both
```
- `--term` is a regular expression, matched without regard to case. Repeat it to require every term. It works without any setup.
- `--query` searches by meaning and needs an embedding provider, set up as the [configuration reference](/sdd/reference/configuration/#embedding) describes. In a project that already has entries, run `sdd index` once. After that, each search adds new entries to the index.
- With both, sdd merges the keyword and the meaning ranking into one list.
Under each entry line, sdd shows the best matching passage, where it sits, such as the summary, a section or an attachment, and its score relative to the top hit. `--limit` changes the number of hits, 10 by default. `--type`, `--layer` and `--kind` filter them. Superseded entries are left out unless you add `--include-superseded`.
## Overviews with layouts
`sdd view` renders lists of entries from a layout. Several layouts rank by heat: each reference an entry receives adds to its heat, and references from recent entries add more. These layouts are a good start:
| Layout | Shows |
| --- | --- |
| `top(20)` | the 20 active entries with the most heat |
| `focus` | the active focus decisions, with the entries each covers and their state |
| `signals` | the open gaps and questions, grouped by kind |
| `topic("product/vision")` | one topic's entries, ranked by heat |
| `since("7d"):rank(by(date)):as-list` | everything recorded in the last seven days, newest first |
```bash
sdd view --layout='top(20)'
sdd view --layout='focus,signals'
sdd view --layout='topic("product/vision"):brief'
```
A comma starts another section, so `focus,signals` prints both lists. `brief` shortens each line to the ID, kind and first summary sentence. Quote topic paths, dates and names inside the layout, and wrap the whole layout in single quotes for the shell. `sdd view --help` lists every filter, ranking and output form, with examples.
A full line reads: ID, layer, kind and type, confidence, participants, status, score, topics, summary.
## Check your setup
```bash
sdd info
```
```text
Local participant: Dana
Search: vector,text
```
`sdd info` shows your participant name, the graph language when the project sets one, and which searches work. `text` alone means keyword search only; `vector,text` means search by meaning works too.
## What you are looking at
**Status is derived.** No file records whether an entry is open, active, closed or superseded. sdd works it out from the links: an entry is closed once a later entry closes it, and superseded once a later entry replaces it. That is why `sdd show` reports a status, such as `closed-by 20260708-213621-s-tac-cjr`, that the file does not contain.
**Summaries are pointers.** A model writes the one-line summary when the entry is recorded. It tells you whether an entry is worth reading, and it can miss a condition or a limit the entry states. Read the full entry with `sdd show` before you rely on it.
**References carry the reasoning.** Follow upstream to see what an entry rests on, and downstream to see what came of it.
To check the graph for problems such as references to entries that do not exist, run `sdd lint`. To read the graphs your project depends on as well, add `--repo` or `--all-repos` to `sdd search` and `sdd view`; see [Connected repositories](/sdd/guides/connected-repositories/).
---
# Entry kinds
> What each kind of graph entry is for, when to choose it over its neighbors, and how it ends.
Everything in an SDD graph is an entry, and every entry has a type and a kind. There are two types:
- A **signal** records something noticed.
- A **decision** records something committed to.
The type is the first test. An entry that commits to what will be done is a decision; everything else is a signal. The kind then says which question the entry answers.
You rarely pick a kind yourself. When your agent drafts an entry it proposes a kind, and you confirm or correct it when the agent plays the entry back to you. This page is for looking up what a kind means.
Entries are never edited. An entry ends when a later entry closes it, saying why it no longer applies, or supersedes it with a replacement. Each card says how its kind ends.
## Signals
A gap records a deviation: what is actually the case set against what was expected, where the difference calls for action. Each side names its source: how the observation was made, and where the expectation comes from, whether a recorded decision, a customer's request or plain common sense. Open gaps show where the project owes attention. A gap records what is wrong, not the fix; a chosen remedy belongs in a decision.
A gap stays open until something closes it: usually a decision that addresses it, a done when the fix needed no choice, or any entry showing that the situation changed and the gap no longer applies. A sharper understanding of the same deviation replaces it with a refined gap. A gap can itself close an earlier entry that its deviation shows no longer holds.
The March invoices went out on the 9th; the agreed schedule says invoices go out by the 3rd.
A fact records knowledge about the world with the source or method behind it, so a later reader can check it again. It informs later work without demanding any, and later decisions build on it as a premise. A claim that is hard to verify may be recorded, marked as such; a claim with nothing behind it may not.
Nothing completes a fact. When the world changes or a better measurement arrives, a corrected fact supersedes it; when it stops holding and no successor exists, any entry that says what changed closes it, except a question, actor or annotation. A fact can itself close a question by answering it, as long as it restates what the question asked.
The venue contract caps attendance at 120 guests, per clause 4.
A question records something the project needs to know and does not. Asking puts the unknown on record; an unasked question gets answered anyway, silently, by whatever the work happens to do. Open questions sit beside open gaps as things the project owes, carried into every session until something answers them. A question names the work that needs the answer and may suggest candidate answers, marked as unsettled, to seed the dialogue that settles it.
A question stays open until something answers it: usually a decision with its reasons, or a fact, insight or done that answers it with no choice needed. A decision may also close a question the project will not pursue, saying why, and a sharper version of the same question supersedes it. A question never closes anything itself.
Before the new opening hours are set, which weekdays bring the most walk-in customers?
An insight records an understanding reached by connecting what the project has already recorded: a pattern across entries, a cause behind them, or a limit on an earlier claim. It points at the entries it reasons from and keeps the reasoning that connected them, so a later reader can reach the same conclusion. Open insights are the project's current understanding of itself. An insight earns its place by changing something, such as a coming choice or an assumption, yet it owes nothing and may wait until that work arrives.
Being acted on does not retire an insight, and neither does a finding that only narrows where it holds. A replacing understanding supersedes it, and any entry that says why the reading stopped holding closes it. An insight can itself close a question it answers, or a fact or earlier reading it overturns, saying why.
All five late deliveries this quarter came from suppliers outside the region; none of the local ones ran late.
A done records that an act of work happened: a meeting held, a message sent, a release published. It is always in the past, never a plan or work still underway. It points at what the act completes and cites the most specific trace the act left, such as a document version, an attached file, or a participant's own word when nothing lasting changed. One act makes one done.
A done is final: nothing closes it, and a wrong one is corrected by a new done that supersedes it. It closes what the act resolved, such as the commitment it fulfills, the gap it fixes or a question its record settles; partial progress closes nothing and says what remains.
Printed and posted the spring newsletter, completing the mailing activity; the final PDF is attached.
An actor declares who a participant is: a person, a team or an AI model family, any identity the project attributes work to. Its canonical name is the one the record already uses for them; it also lists any aliases they sign or chat under and says in a sentence who they are and what they bring from outside. Someone who took part once needs no actor; listing them among that entry's participants is enough.
When the identity shifts, such as a changed name or a new alias, a new actor entry supersedes it. When the participant leaves, an entry stating why, usually a directive, closes it, and that also retires every role they held. The canonical name is never reused for anyone else, and an actor closes nothing itself.
Dana is a certified accountant with ten years at a regional firm; she signs invoices as D. Reyes and appears in the team chat as Dee.
An annotation adds no claim of its own. It puts topic labels such as `suppliers/delivery` on entries already written, so a thread running through them can be found in one search; each entry then counts as carrying the label from the start. Labeling an entry as it is written is the usual path; an annotation adds labels afterwards and leaves the original entries untouched.
An annotation can stay open indefinitely; that is its normal state, and it closes nothing. When the grouping is no longer wanted, any entry stating why retires it, and sharper labels usually arrive as a new annotation beside the old one.
Groups the three entries about late supplier deliveries under `suppliers/delivery-times`.
## Decisions
A directive records a decision on how to go forward: what was decided, which options were weighed, and the reasoning that carried the choice. It reflects current understanding, and new input can change it. A directive can also sharpen an open plan without replacing it, or retire another decision with the reason it no longer holds.
Every directive states its intent, and the three behave almost like separate kinds:
- **Pending.** Something still has to happen because of it, and a reader can tell what would fulfill it. Later plans and decisions work out the details.
- **Guiding.** A guideline that keeps applying. Work is expected to follow it, and a breach can be seen.
- **Settled.** Deciding was the whole of it. Nothing follows, and the entry says why.
A pending directive is closed by the done that records its delivery, closed by a later directive that says why nothing will be built, or superseded by a replacement. A guiding directive is never finished by work; a new guideline supersedes it, or a directive closes it with the reason it stopped holding. A settled directive is finished when written and can only be superseded.
Every change is reviewed by a second person before it is published, because errors caught later cost far more to fix.
An activity commits that one specific piece of work happens, such as a review held or a set of samples tested. How to do it was already decided elsewhere, in the plan it runs under, an earlier decision, or the conversation that shaped it. The entry says what work is sent, when it counts as finished, and what it leaves behind. Research and trials are activities too; what they find comes back as separate entries.
A done recording the work closes it, and that done accounts for every part of the activity: delivered, or the deviation named with its reason. Work that gets partway points at the activity without closing it. If the work will not happen, a directive that states why closes it.
Compare the three shortlisted suppliers; finished when each has a written verdict.
A plan records what must be true when a piece of work is done. It states the end result in plain words, then breaks it into acceptance criteria, each a single point a finished piece of work can be checked against. It describes an outcome, not the steps or deliverables that produce it. Work that needs breaking down earns a plan; work clear enough to just do needs none.
A done that covers the whole commitment closes it: every criterion met with evidence, or a deviation named with its reason. Partial deliveries move it forward without closing it. A directive can sharpen an open plan in place; a change of direction gets a successor plan that supersedes it, and a plan that will never be built is closed by a directive stating why.
Onboarding is done when every new member can, on their first day, name who to ask for help and find the work waiting for them.
An aspiration records a direction the work is pulled toward, a quality the project keeps moving toward without ever arriving. It binds no single piece of work, so nothing can comply with it or break it. Work is judged by how well it aligns, never by pass or fail, and tension with an aspiration is a reason to talk, never a reason to block. A project holds a few at once, and they often pull against each other.
Nothing completes an aspiration. It ends only when an evolved direction supersedes it, or when a directive closes it with the reason the direction stopped holding.
Newcomers find their own way into the project without someone guiding them.
A focus records what the project is working on right now and who carries each piece. It points at existing entries, usually plans and decisions, and adds who is engaged and for what period; the work itself stays in those entries. Several people can share one piece, and a piece can be left open for whoever picks it up. It also says what was deliberately set aside for this period and why, the part only a conversation between the people involved can settle.
A new focus supersedes it when priorities shift, or a done closes it when the period has run its course; whoever writes the ending picks which. Its targets need not be finished, but the closing entry says so.
Through March the team attends to the website relaunch, with Sam on content and Alex on testing; the pricing review waits until April.
A role records the part one named person plays in this project: what they hold, which decisions are theirs, and when work or questions should come to them. It points at a person already recorded as an actor; the actor entry says who they are, the role says what they do here. The part is agreed with the person, not assigned in their absence. One person may hold several roles.
When the part changes, a new role supersedes it. When the person leaves and their actor entry is closed, all their roles end with it, and no separate entries are needed. A directive can also close a role directly, stating why, though that is unusual.
Alex holds the budget and approves every purchase above the standing limit; routine spending runs without them.
A procedure defines a repeatable way of working that SDD runs step by step with your agent, such as recording a new entry or preparing a release. SDD holds its structure: no step can be skipped, and where a step asks you something, everything waits for your answer. It is an advanced kind, written only to define how a move runs; a move is one of the routines you start with your agent. SDD ships its own procedures, and a project can add its own beside them or replace a shipped one.
A new version supersedes it under the same short name, and that name is never reused for a different procedure. A practice that ends without replacement is closed by a directive that says why it is no longer how work happens.
The release routine takes every new version through final checks, packaging and announcement, in that order.
---
# Configuration
> Every sdd configuration key, where it lives, and how to set up the language model and embedding providers.
sdd reads its settings from three YAML files and merges them. `sdd config` shows the merged result and the file each value comes from.
## Configuration files
| Layer | File | Applies to |
| --- | --- | --- |
| User-global | `~/.config/sdd/config.yaml`, or `$XDG_CONFIG_HOME/sdd/config.yaml` when that variable is set | You, in every project on this machine |
| Project | `.sdd/config.yaml` | Everyone on the project. Committed to git. |
| Local | `.sdd/config.local.yaml` | You, in this checkout only. `sdd init` adds it to `.gitignore`. |
A later row overrides an earlier one: local wins over project, project wins over user-global, and user-global wins over the built-in default. A file sets only the keys it names and inherits the rest. Maps merge entry by entry, so `llm.api_keys.openai` in the local file keeps `llm.api_keys.anthropic` from the user-global file. A list replaces the whole list below it. Command-line flags such as `--model` or `--embedding-provider` override every file for that one command.
### Which keys go where
| Keys | Belong in | Notes |
| --- | --- | --- |
| `participant`, `llm.*`, `embedding.*`, `sync.*` | User-global | Any file works. Use the local file to override a value for one project. A value in the project file applies to everyone on the project and overrides their user-global value. |
| `sessions.retention` | User-global | sdd currently ignores it in the project files. |
| `graph_dir`, `default_branch`, `repo_id`, `language`, `skill_scope`, `supported_agents`, `dependencies` | Project | These describe the repository. sdd ignores them in the user-global file. |
| `repos` | User-global | sdd ignores it in the project files. |
:::caution[Keep API keys out of the project file]
`.sdd/config.yaml` is committed and shared. sdd reads `api_keys` from any file and does not stop you, so put keys in the user-global or the local file. `sdd config set` writes only to those two.
:::
sdd skips a key it does not know, including a key in a file where it does not belong. Every command then warns `ignoring unknown config key` and names the key and the file, and `sdd config` lists these keys at the end. A file written by a newer sdd version therefore still works with an older one.
## The sdd config command
| Command | What it does |
| --- | --- |
| `sdd config` | Lists every effective value with its source: `default`, `global`, `project` or `local`. Masks API keys. Add `--format json` for JSON. |
| `sdd config get ` | Prints one effective value without formatting, for use in scripts. |
| `sdd config get ` | Lists the values under a prefix, such as `llm`. Without an argument, lists all values. |
| `sdd config set ` | Writes the key to the user-global file and creates the file if needed. Works outside a project. |
| `sdd config set --local ` | Writes the key to `.sdd/config.local.yaml`. Works only inside an sdd project. |
| `sdd config unset [--local] ` | Removes the key from the user-global file, or with `--local` from the local file. |
- Keys are dotted paths, such as `llm.api_keys.openai`.
- `set` refuses a key that does not belong in the target file, such as `graph_dir` without `--local`.
- `set` writes `8`, `0.5`, `true` and `false` as numbers and booleans, and everything else as text. Edit list values, such as `supported_agents`, in the file.
- `set` and `unset` change only the named key and keep the rest of the file, comments included.
- No command writes `.sdd/config.yaml` directly. `sdd init` creates it, `sdd repo add` and `sdd repo remove` change `dependencies`, and you edit the rest by hand and commit it.
:::note[Restart your agent after a change]
Your agent starts the sdd server, `sdd serve`, which reads the configuration once when it starts. Restart the agent after a change so the server picks it up. In Claude Code it is enough to run `/mcp` and restart the sdd server there. sdd commands in a terminal read the configuration on every run.
:::
## Keys
Durations use the units `s`, `m` and `h`, such as `90s`, `5m` or `1h30m`.
### Project
`sdd init` writes these keys to `.sdd/config.yaml`.
| Key | Default | Meaning |
| --- | --- | --- |
| `graph_dir` | `.sdd/graph` | Directory of the entry files, relative to the repository root, or an absolute path. |
| `default_branch` | The branch checked out during `sdd init` | A session that names no branch works on the branch checked out in the project directory, and on this branch when none is checked out. `sdd serve` does not start without it. |
| `repo_id` | Derived from the `origin` remote | The project's identity, such as `github.com/acme/platform`. Other graphs reference an entry here as `:`. Empty for a repository without a remote. Do not change it by hand. |
| `language` | English | Language of the entry text, as a locale code such as `en`, `de` or `de-DE`. Translated SDD vocabulary ships for `de`. |
| `skill_scope` | Asked by `sdd init` | `project` installs the skill into the repository, such as `.claude/skills/`. `user` installs it into your home directory, such as `~/.claude/skills/`. |
| `supported_agents` | `[claude]` | The agents `sdd init` installs the skill for: `claude`, `codex` or both. |
| `dependencies` | None | The `repo_id`s of other graphs this graph references. See [connected repositories](#connected-repositories). |
### Participant
| Key | Default | Meaning |
| --- | --- | --- |
| `participant` | None | Your name, recorded as the author of the entries you capture. `sdd init` asks for it, offers your git `user.name`, and writes it to `.sdd/config.local.yaml` unless another file already sets it. Every command warns while it is missing. |
### Language model
| Key | Default | Meaning |
| --- | --- | --- |
| `llm.provider` | `claude-cli` | `anthropic`, `openai`, `ollama` or `claude-cli`. See [language model providers](#language-model-providers). |
| `llm.model` | `claude-sonnet-4-6` | Model name as the provider spells it. sdd uses the default with any provider, so set a model whenever you change the provider. |
| `llm.api_keys.` | None | API key for a provider. Required for `anthropic` and `openai`. Optional for `ollama`, which receives it as a bearer token. |
| `llm.endpoint` | The vendor's public API | Base URL of a gateway or compatible service, for `openai` and `anthropic` only. Accepts the host, a URL ending in `/v1`, or the full URL ending in `/chat/completions` for `openai` or `/messages` for `anthropic`. |
| `llm.ollama_endpoint` | `http://localhost:11434` | Ollama server for the `ollama` provider. |
| `llm.timeout` | `2m` | Time limit for one model call. |
| `llm.params.` | None | Provider settings that sdd adds unchanged to every request body, such as `reasoning_effort` set to `low`. `claude-cli` ignores them. |
| `llm.rate_limit_rps` | See below | Maximum requests per second to `anthropic` or `openai`. Raise it on a higher account tier or for a gateway that allows more. |
| `llm.retry.max_attempts` | `5` | Attempts per call, counting the first. `1` turns retries off. |
| `llm.retry.base_delay` | `2s` | Wait before the first retry. The wait grows with each further retry. |
| `llm.retry.max_delay` | `60s` | Longest wait between two retries. |
| `llm.concurrency` | `4` | Not applied in this version. `sdd summarize --all` takes its worker count from `--concurrency`, which defaults to 4. |
sdd retries a call that failed with a temporary error, such as a rate limit or a dropped connection, and waits as long as the provider asks when it names a time. `claude-cli` ignores the rate limit and retry keys, since the `claude` command retries on its own.
Default rate limits:
| Provider | Model name contains | Requests per second |
| --- | --- | --- |
| `anthropic` | `opus` | 0.5 |
| `anthropic` | `haiku` | 2 |
| `anthropic` | anything else | 1 |
| `openai` | `mini` or `nano` | 2 |
| `openai` | anything else | 1 |
| `ollama`, `claude-cli` | any | no limit |
### Embedding
| Key | Default | Meaning |
| --- | --- | --- |
| `embedding.provider` | None | `openai` or `ollama`. Without a provider, search matches keywords only. |
| `embedding.model` | None | Embedding model, such as `text-embedding-3-small` or `qwen3-embedding:8b`. Required with a provider. |
| `embedding.api_keys.openai` | None | API key, required for `openai`. sdd does not fall back to `llm.api_keys.openai`. |
| `embedding.endpoint` | `https://api.openai.com` | Base URL of an OpenAI-compatible embeddings service, for `openai` only. sdd appends `/v1/embeddings`, so leave `/v1` off. |
| `embedding.ollama_endpoint` | `http://localhost:11434` | Ollama server for the `ollama` provider. Independent of `llm.ollama_endpoint`. |
| `embedding.timeout` | `2m` | Time limit for one request. |
| `embedding.batch_size` | `100` for `openai`, `64` for `ollama` | Texts sent in one request. |
| `embedding.dimensions` | The model's own size | Shorter vectors, for `openai` models that support it, such as `text-embedding-3-small`. `ollama` ignores it. |
| `embedding.rate_limit_rps` | `5` for `text-embedding-3` models, `3` for other `openai` models | Maximum requests per second to `openai`. `ollama` has no limit. |
| `embedding.query_template` | None | Template for search queries. See [query and document templates](#query-and-document-templates). |
| `embedding.document_template` | None | Template for entries when sdd indexes them. |
### Sync and sessions
| Key | Default | Meaning |
| --- | --- | --- |
| `sync.cooldown` | `15m` | Every sdd command except `sdd init` runs `git fetch` in the background at most once per this interval, and reports when your branch is behind or ahead of its upstream. An invalid value counts as `15m`. |
| `sessions.retention` | `14d` | When `sdd serve` starts, it deletes the logs of sessions that ended longer ago than this. Accepts days, such as `14d`, or a duration, such as `336h`. Set it in the user-global file. An invalid value stops `sdd serve` from starting. |
### Connected repositories
| Key | File | Default | Meaning |
| --- | --- | --- | --- |
| `dependencies` | Project | None | The `repo_id`s of the graphs this graph references. `sdd repo add` adds one and commits the change. `sdd repo remove` removes one. |
| `repos` | User-global | None | How this machine reaches each connected repository, as a list of `repo_id` and `clone_url` pairs. `sdd repo add` writes it. |
```yaml
# ~/.config/sdd/config.yaml
repos:
- repo_id: github.com/acme/platform
clone_url: git@github.com:acme/platform.git
```
sdd keeps a clone of each connected repository under `~/.cache/sdd/`. A read that needs it pulls the clone at most once every 15 minutes. This interval is fixed.
## Language model providers
sdd calls the language model three times when it records an entry:
- The writing check reads the draft and points out unclear text.
- The pre-flight check compares the entry with the graph.
- The summary step writes the entry's one-line summary.
:::caution[The model must support structured output]
The writing check and the pre-flight check ask the model for a fixed response format, a JSON schema the provider must enforce. sdd sends the schema through each provider's structured output feature and never falls back to reading free text, so a provider or model without structured output fails the checks. Ollama Cloud ignores the schema and does not work. The summary is plain text and works with any model.
:::
| Provider | Sends requests to | Schema sent as | API key |
| --- | --- | --- | --- |
| `anthropic` | The Anthropic Messages API, or `llm.endpoint` | `output_config.format` | `llm.api_keys.anthropic` |
| `openai` | OpenAI chat completions, or any compatible service at `llm.endpoint` | `response_format` of type `json_schema`, strict | `llm.api_keys.openai` |
| `ollama` | The Ollama server at `llm.ollama_endpoint` | The `format` field | Optional |
| `claude-cli` | The local `claude` command, run as `claude -p` | `--json-schema` | None, uses your Claude Code login |
A gateway or compatible service must honor the schema field in the third column for the checks to work.
### Anthropic
```bash
sdd config set llm.provider anthropic
sdd config set llm.model claude-sonnet-4-6
sdd config set llm.api_keys.anthropic
```
```yaml
llm:
provider: anthropic
model: claude-sonnet-4-6
api_keys:
anthropic:
```
### OpenAI
```bash
sdd config set llm.provider openai
sdd config set llm.model gpt-5-mini
sdd config set llm.api_keys.openai
```
```yaml
llm:
provider: openai
model: gpt-5-mini
api_keys:
openai:
```
### Opper and other OpenAI-compatible services
With `llm.endpoint` set, the `openai` provider sends its requests to any service that implements the OpenAI chat completions protocol. [Opper](https://opper.ai) is a gateway that serves hosted open-weight models this way. The SDD evals run this model through this route:
```bash
sdd config set llm.provider openai
sdd config set llm.endpoint https://api.opper.ai/v3/compat/chat/completions
sdd config set llm.model greenpt/glm-5.3-flash
sdd config set llm.api_keys.openai
```
```yaml
llm:
provider: openai
endpoint: https://api.opper.ai/v3/compat/chat/completions
model: greenpt/glm-5.3-flash
api_keys:
openai:
```
The Opper key goes under `openai` because the provider is `openai`. The default limit of 1 request per second assumes OpenAI's lowest account tier. Raise `llm.rate_limit_rps` if the service allows more.
### Ollama
Runs models on your machine. The Ollama server must be running when sdd starts, or sdd stops with `provider unreachable`.
```bash
sdd config set llm.provider ollama
sdd config set llm.model gemma4:26b
```
```yaml
llm:
provider: ollama
model: gemma4:26b
ollama_endpoint: http://localhost:11434
```
Ollama Cloud does not work, because it ignores the response schema.
### Claude Code CLI
`claude-cli` is the fallback when no provider is set. It runs every call through `claude -p` with your Claude Code login, so it needs no API key, only the `claude` command on your `PATH`. Each call starts a new Claude Code process, which is slow, and checks can hit the 2 minute limit. If they do, raise `llm.timeout` or set up another provider.
```bash
sdd config set llm.provider claude-cli
sdd config set llm.model claude-sonnet-4-6
```
```yaml
llm:
provider: claude-cli
model: claude-sonnet-4-6
```
## Embedding providers
An embedding model turns each entry into a vector, so search finds entries by meaning. Without one, search matches keywords. `sdd info` shows `Search: vector,text` with an embedding provider and `Search: text` without.
Set the embedding provider in the user-global file. A search across connected repositories embeds every repository, the current one included, with the user-global embedding settings, so all results share one vector space.
### OpenAI
```bash
sdd config set embedding.provider openai
sdd config set embedding.model text-embedding-3-small
sdd config set embedding.api_keys.openai
```
```yaml
embedding:
provider: openai
model: text-embedding-3-small
api_keys:
openai:
```
`embedding.api_keys.openai` is separate from `llm.api_keys.openai`. Set it even when the language model uses the same key.
### OpenAI-compatible services
For another service that implements `POST /v1/embeddings`, set `embedding.endpoint` to its base URL without `/v1`. The `openai` provider always sends `embedding.api_keys.openai`, so for a service without authentication, set any value.
```bash
sdd config set embedding.provider openai
sdd config set embedding.endpoint http://localhost:8000
sdd config set embedding.model
sdd config set embedding.api_keys.openai
```
```yaml
embedding:
provider: openai
endpoint: http://localhost:8000
model:
api_keys:
openai:
```
### Ollama
```bash
sdd config set embedding.provider ollama
sdd config set embedding.model qwen3-embedding:8b
```
```yaml
embedding:
provider: ollama
model: qwen3-embedding:8b
ollama_endpoint: http://localhost:11434
query_template: |-
Instruct: Given a query phrase, retrieve related entries from a knowledge graph
Query:{text}
```
The next section explains `query_template`.
### Query and document templates
Some embedding models expect an instruction or a prefix before the text. A template wraps the text, and `{text}` stands for it.
- `embedding.query_template` applies to search queries.
- `embedding.document_template` applies to entries when sdd indexes them.
Qwen3 embedding models expect an instruction on queries only, so set `query_template` as in the Ollama example above and leave `document_template` empty. Models with a prefix on both sides, such as E5 with `query: ` and `passage: ` or Nomic with `search_query: ` and `search_document: `, need both templates. OpenAI models need none.
A changed `query_template` applies to the next search. A changed `document_template`, provider, model or `dimensions` starts a new, empty index, which sdd fills on the next search or with `sdd index`.
### The search index
- `sdd index` embeds every entry the index does not hold yet. Run it once after you set up an embedding provider, or when you join a project with existing entries, so the first search does not have to wait.
- Every search by meaning, in the terminal or through your agent, first embeds the entries the index lacks, so new entries need no extra step.
- `sdd index --force` embeds every entry again.
- `sdd index --repo ` or `sdd index --all-repos` also builds the indexes of connected repositories.
The index lives in `~/.cache/sdd/index/`, or `$XDG_CACHE_HOME/sdd/index/` when that variable is set, with one directory per project and embedding setup. A project's directory is named after its `repo_id`, or after a hash of the repository path when it has none.
The index only grows. It keeps every embedded version of every entry, so sdd versions that share it do not remove each other's work. `sdd index gc` lists the stored versions by group, `sdd index gc --drop ` deletes one group, and `--drop stale` deletes every version this checkout does not search.
## Environment variables
| Variable | Default | Effect |
| --- | --- | --- |
| `XDG_CONFIG_HOME` | `~/.config` | The user-global file is `$XDG_CONFIG_HOME/sdd/config.yaml`. |
| `XDG_CACHE_HOME` | `~/.cache` | Search indexes and clones of connected repositories live under `$XDG_CACHE_HOME/sdd`. |
| `XDG_STATE_HOME` | `~/.local/state` | Session logs live under `$XDG_STATE_HOME/sdd`. Must be an absolute path. |
| `SDD_SERVE_TOKEN` | None | The bearer token `sdd serve --transport http` requires on every request. Same as `--auth-token`. |
---
# The SDD Landscape
> Where the Signal, Dialogue, Decision idea stands and where it is heading: regions of connected ideas, each opening with why we want it, marked honestly by maturity.
A map for people joining the conversation: where the Signal, Dialogue, Decision idea stands and where it is heading. The landscape shows SDD as regions of connected ideas. Each region opens with why we want it, then what SDD's answer is, and closes with an honest maturity mark. Nothing here is polished away; the open edges are part of the picture, and nothing that merely has a foundation is rounded up to "done".
## The map
Six regions around one shared picture of the project. Everything we are working on sits somewhere on this map, including the parts that are still only an idea.
## The six regions
### 1. A shared context
Ask three people what the project's state is, and why it is that way, and you get three answers. Decisions live in chat threads, meeting minutes, documents, and heads. The reasoning evaporates, gets re-litigated, and every newcomer rebuilds the picture by asking around.
SDD keeps one shared context: a graph of small, linked entries. Things noticed (signals) and things committed to (decisions), each keeping its reasoning, its alternatives, and its links to what it builds on. Nothing is ever edited; direction changes by adding an entry that supersedes an older one, so the current picture is derived, never stale by neglect, and honest about open questions and tensions. Every participant, human or agent, reads from and adds to the same picture. And the picture is made to be read: you can search it by meaning, asking in your own words and finding the entries that matter without knowing where they live, and compose views that collect what belongs together for a purpose. Connected graphs let separate organizations, yours and a client's, each keep their own record while referencing each other's.
This serves one pull: one record instead of scattered copies, with the why preserved.
**Maturity: works today.** The graph, its immutability, derived status, search by meaning, composed views, and cross-organization references are in daily use.
### 2. Thinking in dialogue
Writing things up after the fact is a chore nobody does well; forms capture fields, not thinking. And coming back after a week away costs half a day of reconstructing where things stand.
In SDD, the dialogue is the work. Sometimes it starts from something you noticed: you say it, your agent drafts it grounded in what already stands, plays it back in your words, and you confirm before anything is recorded. Just as often it is sparring: thinking through a concept or a design with your agent asking the questions, until the outcome is clear enough to capture. Either way the results land in the graph, where other people and agents can act on them. The conversation is the filter: it separates what matters from noise, which is why the record stays small and true instead of becoming a pile. When you return, a briefing meets you at the edge of the thinking, telling you what moved and what waits for you instead of a generic status dump. Finished work is evaluated the same way: checked against what was committed, put in front of users, and the findings flow back in as new signals.
The aspiration behind this: decisions emerge from dialogue, and every tool serves the conversation. None replaces it.
**Maturity: works today**, inside coding-agent sessions, which are the current surface (see Surfaces).
### 3. Everyone working together
Keeping a team aligned usually costs meetings, standups, status rounds, sync calls, and still someone starts work that's already in progress elsewhere, or decides past a decision made last week.
SDD treats three kinds of participants as equals: people, people in dialogue with their agent, and agents working autonomously over the graph. Because direction, agreements, and constraints are visible to everyone in the shared context, each participant can decide autonomously in their own domain, confident the decision will fit. An agent contributes to the graph and to the work according to rules and guidelines that live in the graph itself, and what it does varies with the project and its process: watching for tensions, bringing information in, carrying work out. Meetings are elevated rather than replaced. Everyone arrives better prepared because their assistant, drawing on the shared context, did the groundwork. The meeting stays what it is for, alignment between people, and afterwards it feeds back into the graph, with humans curating the notes so the captured knowledge stays true to what was said and its subtext.
Two aspirations pull here, deliberately in tension: stay coherent as one project, and let everyone decide autonomously in their own domain.
**Maturity: mixed.** Parallel working sessions, participants and roles as entries, and in-progress markers **work today**. Automatic sharing of each other's movement is **decided and taking shape**. Autonomous agents that watch for contradictions, route questions to whoever holds the knowledge, and tailor briefings to each person are **ideas in dialogue**.
### 4. The world flowing in
Between what a customer actually said and the issue that finally describes the work, most of the meaning is lost to compression. The full input rarely survives into the record, and with it goes the reasoning a later decision would need.
The decided model treats outside channels (email, chat, meeting notes, an issue tracker) as transport. An agent picks each item up and proposes it as a candidate: already connected to related entries, carrying its source and the agent's reasoning. Only dialogue promotes a candidate into the shared context, so nothing lands unseen. After a meeting there is still follow-up, but of a different kind: instead of one protocol document that flattens everything, the notes are sorted into entries that reflect the new shared understanding, and where something stayed unclear, a question or an open gap can honestly say so. And where a team runs an issue tracker as its current system of record, SDD connects to it rather than fighting it: a transitional bridge, because with the right views the graph itself provides that information.
The aspiration: the record grows out of ongoing work. No separate bookkeeping mode, no dedicated capture sessions.
**Maturity: decided and taking shape.** The intake model is committed; the machinery is not yet built. Treating user research and usability findings as input is still an open, unexplored edge.
### 5. Extending the process
Every team works differently, and most tools force their process on you, while the team's actual way of working sits scattered across silos of different tools where information cannot flow and connect.
In SDD the process itself lives in the graph and is changed the same way everything else is: through dialogue, not code. It takes three forms. Procedures are runnable ways of working; the built-in moves ship this way, and a project can add its own or override a shipped one. Rules are learnings that resurface and enforce themselves at the right moments. Facts are reference knowledge, findable when needed and adaptable per project. A further case sits on the exploratory edge: making a project's own business domain explicit, as shared vocabulary whose meaning is settled once and referenced everywhere, by humans and agents alike; a graph ontology is one rough idea for that. SDD already does exactly this for its own working vocabulary, which is the proof the pattern works.
The pull behind this: the way of working belongs to the team, and adapting it is part of the same dialogue as everything else.
**Maturity: mixed.** Facts and the built-in procedures **work today**; project-authored procedures and the rule system are **decided and taking shape**; explicit domain vocabulary is an **idea in dialogue**.
### 6. Surfaces: the ways in
The people whose knowledge shapes a project (owners, domain experts, designers, operators) usually don't live in a terminal. Today, that is still where SDD's main surface is.
The path runs from what exists toward less friction, step by step. Today SDD is used through coding agents in the terminal (e.g. Claude Code, Codex). Underneath, an engine already serves complete working sessions over an open protocol: the technical foundation for other applications to host the same dialogue. Desktop apps like Claude or ChatGPT can already connect to it, a first step out of the terminal, though the setup still takes developer-level work. The honest line: foundation built, the low-friction ways in are not there yet. What will follow is a hosted version, so a non-technical participant joins through chat with no setup at all; its runtime is chosen. Beyond that come voice, and visual views and reports tailored to each role: the surfaces that let questions like "what's open, who's on it, what's next" be answered from the graph instead of a separate tool.
The aspiration: everyone participates directly, through surfaces they already use.
**Maturity: a thread.** Terminal use and the engine foundation **work today**; desktop-app connections work, but only with developer-level setup; the hosted version is **decided and taking shape**; voice and visual role-tailored views are **ideas in dialogue**.
## The collaboration view
People take part through whichever surface suits them. Each has an agent as a thinking partner, and agents also work autonomously over the shared picture, within the rules and guidelines the graph itself carries. Dialogue is what connects all of it: between a person and their agent, between two people, and between the agents and the record.
How does that feel in practice? [Three scenes](/sdd/vision/scenes/) tell it from the inside: a product owner, a project lead, and a designer.
## The work lifecycle
One motion moves the shared picture: talking through what is missing, settling what we want, planning how. That is real work, not overhead; it is what keeps the picture true to the project. The other motion moves the world: building, acting, talking to people. What changes out there comes back as something newly noticed.
---
*Draft for dialogue: the landscape itself is not finished and deliberately shows ideas next to shipped work.*
{/*
Maintainer map — region → backing graph entries (short IDs, resolve with `sdd show`).
Source plan: d-tac-okx; its attachment vision-landscape-synthesis.md holds the full synthesis and reading lists.
1 A shared context: d-stg-3k0, s-stg-miu, s-stg-ob9, s-prc-way, s-tac-cr0, d-stg-com
2 Thinking in dialogue: d-stg-beb, d-stg-qlt, s-cpt-p6f, d-prc-cap, d-prc-cat, d-prc-evl, d-prc-int, d-prc-dlg
3 Everyone working together: d-stg-7lu, d-stg-qlt, d-cpt-9of, s-cpt-w80, d-cpt-kvb, d-cpt-r8k, s-cpt-ji9, s-cpt-5jk, s-cpt-dnh, s-cpt-s37
4 The world flowing in: d-cpt-fbi, d-stg-2wb, s-cpt-5ox, s-cpt-jnr, s-cpt-yve, d-stg-com, s-stg-erj
5 Extending the process: d-cpt-dtv, d-cpt-rh6, d-cpt-30v, d-tac-eho, s-prc-tso, s-prc-way, s-cpt-b44
6 Surfaces: d-stg-x0l, d-stg-6za, d-cpt-8k5, s-cpt-4v3, s-cpt-r57, s-tac-7kh, s-tac-bta
*/}
---
# How will that feel?
> Three scenes from the intended future of working with SDD, told from three roles: a product owner, a project lead, and a UX designer. Each with an honest note on what works today.
Three scenes from the intended future of working with SDD. They are not fiction about a distant system: each scene ends with an honest note naming what already works today and what is still being built or discussed. The names and settings come from a digital-agency world, because that is where our first partners work; the pattern in each scene belongs to any team that decides together.
## The product owner
Jana runs a relaunch project for a retail client at her agency. Tuesday morning, the client's marketing lead sends an email: legal now requires a cookie-less analytics setup, and the go-live date cannot move.
In the old workflow this email would start a chain: forward it to the tech lead, write a ticket from memory, schedule a meeting to find out what it actually means. Instead, the email arrives in the project's shared record as a candidate. An assistant has already read it, connected it to the analytics decision from June and to the go-live commitment, and written down what it thinks the email changes, and what it isn't sure about. Nothing is final; the candidate waits for a person.
Jana opens a short dialogue over her first coffee. The assistant lays out the connection: the June decision assumed the current analytics tool, and the email contradicts that assumption. Together they settle what this is. A new constraint, recorded with the client's exact words and a link to the email. And an open question for the tech lead: which cookie-less options fit the budget? Five minutes. The record has grown, and the tension between the new constraint and the June decision is now visible to everyone, not just to Jana.
The client's own issue tracker doesn't go away. The client team lives in it, so the agreed follow-up appears there as a ticket, generated from the recorded question, carrying a plain-language summary rather than the whole reasoning. When the ticket closes, its status flows back. The tracker stays what it is for the client: their familiar surface. The shared record stays what it is for the project: the place where the reasoning lives.
:::note[Today]
Recording constraints and questions through a confirmed dialogue works. Email arriving as an already-connected candidate is decided in shape but not built, and the ticket round-trip with a client's tracker is still an open design question.
:::
*The same scene plays out wherever outside requirements land in somebody's inbox: a supplier's price change, a new regulation, a customer request.*
## The project lead
Marek leads a team working three streams of a client project at once. His morning starts without a standup. He opens his briefing, shaped to him: what moved in his streams since yesterday, which decisions landed, and where something waits on his answer. A designer carried the onboarding flow forward; an agent finished a data migration overnight and recorded exactly what it did and why; one decision needs his read before the eleven o'clock call. Nobody recites yesterday. Nobody waits for a sprint boundary. The work moves as many small loops, each closing when it closes, and the shared record keeps them coherent instead of a ceremony.
When Marek checks what to push next, the priorities carry their why. The payment flow doesn't just say "high": it says the contract carries a penalty date, and links the reasoning. Yesterday a developer had to choose between two tasks and chose right without asking him, because the why was readable.
At eleven, the client meeting. Beforehand, the record prepared the ground: the two decisions that need the client's sign-off and three open questions only they can answer, in plain words, no internal vocabulary. The meeting is short. Afterwards Marek drops the notes in; a short dialogue sorts them. Two answers close their questions, one new wish becomes an observation for the design stream, and one misunderstanding is recorded as exactly that. He confirms each item once, so what lands stays true to what was said. Nothing gets typed into three systems.
:::note[Today]
Briefings and confirmed capture work inside a developer-set-up session, and concurrent work over one shared record is real. Briefings shaped to each person, assisted sorting of meeting notes, and movement flowing automatically between participants are decided direction or ideas still taking shape.
:::
*The same morning exists for anyone coordinating people who decide: a head of operations, a clinic manager, a restaurant owner.*
## The UX designer
Carla runs a usability test on the checkout redesign. While packing up, she speaks her findings into her assistant the way she would tell a colleague: three of five participants missed the save action; two described the new wizard as "filling in a form, not being guided". A short dialogue later, both observations sit in the shared record, connected to the checkout decisions they touch, in her words, with the test session as their source.
Weeks later, someone proposes trimming the confirmation step down to an icon-only button. The proposal gets flagged before it lands: it contradicts Carla's recorded finding that participants missed icon-only actions. The tension surfaces to Carla and the proposer together, both entries side by side. Not as a rejection, but as a conversation that has to happen. They talk; the proposal changes shape. Nobody had to remember the finding. The record did.
The same week, Carla joins a second project mid-flight. The navigation is a side drawer, and her instinct says tabs. Instead of asking around (who decided this? was it deliberate?), she reads the decision: what was tried in the first round, why tabs broke on the seller dashboard, which customer feedback grounded the call. Her instinct updates in ten minutes, and her next question is a better one: has the seller dashboard constraint survived the latest redesign? She records it as an open question, and it finds the person who knows.
:::note[Today]
Recording observations through dialogue and reading the reasoning behind decisions both work. Speaking findings in naturally and automatic contradiction-flagging are still ideas; right now a person has to notice such tensions, and nothing in the graph treats user research as input yet.
:::
*The same protection exists for any team whose hard-won observations must outlive the moment they were made: field research, customer interviews, clinical practice.*
---
# About these docs
> How the SDD documentation site is built and made available to people and agents.
The SDD documentation site is under construction. It covers getting started, the entry kinds and the vision so far.
## Agent-friendly access
Every documentation page is also available as raw Markdown. Use **Copy Markdown** or **Open with AI** above to try the agent-friendly controls on this page.
Site-wide manifests are available as [`llms.txt`](/sdd/llms.txt), [`llms-full.txt`](/sdd/llms-full.txt), and [`llms-small.txt`](/sdd/llms-small.txt).
---
# SDD documentation
> The user documentation for Signal, Dialogue, Decision.
SDD (Signal, Dialogue, Decision) keeps a project's thinking in a graph of signals and decisions, grown through dialogue between you and your agents.
- [What is SDD?](/sdd/what-is-sdd/): the problem it solves, how it works and what it gives you.
- [Getting started](/sdd/getting-started/): install sdd, set up a project and hold your first dialogue.
- [Entry kinds](/sdd/reference/entry-kinds/): what each kind of entry is for, when to choose it and how it ends.
- [Vision](/sdd/vision/landscape/): where SDD stands and where it is heading.
The source and the README are in the [SDD repository](https://github.com/networkteam/sdd).