Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion .agents/skills/sdd/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ allowed-tools: Read Grep Bash(sdd *)
compatibility: Designed for OpenAI Codex
description: Work with the SDD decision graph. Check in on project state, capture signals, make decisions, evaluate completed work. Use when starting a session, capturing observations, or making project decisions.
metadata:
sdd-content-hash: 1870280cb5840da0e6dfd3a71ed7b20a1396f2b352c5630b4dfc76e95bbc875d
sdd-content-hash: 9d13bc30e49c05613821b8ad47bf9ec302a5e06312e7d8bb04a7f42ccdd9e7a9
sdd-version: dev
name: sdd
---
Expand Down Expand Up @@ -189,6 +189,12 @@ See [CLI reference](references/cli-reference.md) for full command syntax and fla
- **Kind for signals**: Default is gap. Use `--kind done` for completion records (must carry `closes` or `refs`). Use `--kind fact`, `question`, or `insight` when the narrative is unambiguously observational, an open question, or a synthesis. Use `--kind actor` for a first-class participant identity — canonical name in frontmatter, prose covers stable identity facts (affiliation, background, domain expertise) that hold independent of any project frame.
- **Acceptance criteria for plan decisions**: `--kind plan` decisions must include an `## Acceptance criteria` section in the description (not the attachment) with `- [ ]` checklist items. Each AC is a single verifiable outcome — not an implementation detail. ACs are the contract between plan author, implementing agent, and pre-flight validator. Pre-flight flags a missing AC section on a plan decision as high.

### Reference across repos when reasoning does

When an entry's reasoning genuinely builds on another repo's graph — a shared framework's directive, a platform team's decision — reference it across the boundary rather than re-deriving it or reducing it to a local paraphrase. Cross-repo refs take the `<repo-id>:<entry-id>` form in a `--refs` value; every ref kind may cross, but `--closes` / `--supersedes` stay within-graph (a decision can't retire an entry in another repo).

The target repo must be a **declared dependency** for the ref to resolve — the same resolve-or-block gate that guards local refs. If it isn't connected, offer to `sdd repo add <clone-url>` first; don't connect a repo the user hasn't signalled they want to depend on. Remember a foreign entry is visible only once it's committed *and pushed* (the cache is pushed state, refreshed by `sdd repo sync`). When you have only a short ID for a foreign entry, resolve it with `sdd show <short-id>` — a free read that resolves bare IDs across the local graph and its declared dependencies — and use the full `<repo-id>:<entry-id>` it prints in the `--refs` value. Full mechanics live in [cli-reference → Cross-repo references](references/cli-reference.md).

### Attachment assessment

The entry description is the summary. The attachment is the record. When the conversation that led to capture involved more than a brief exchange, the entry needs an attachment. **Default to attaching** when the dialogue produced any of these:
Expand Down
33 changes: 28 additions & 5 deletions .agents/skills/sdd/references/cli-reference.md
Original file line number Diff line number Diff line change
@@ -1,23 +1,27 @@
---
metadata:
sdd-content-hash: 811c581f825abe82c2dd5da8ba1ac7771ac105eb573131278384a1233e70741c
sdd-content-hash: 908e2569f24cb40ef23f4c46cac00a16596d2c2ceb441068358882a126ed2564
sdd-version: dev
---
# SDD CLI Reference

## Commands

- `sdd info` — session framing only: `Local participant: ...`, `Language: ...` (when configured), `Search: ...`. The session header surface for skill `!`sdd ...`` injections that need the agent to see who's local and which retrieval modes are available; also the bare-`sdd` default command.
- `sdd view --layout=<spec>` — composable pipeline of primitives (source, filter, transform, aggregate, rank, page, render) with named macros as sugar. The overview surface: `decisions` / `signals` / `aspirations` / `contracts` / `participants` / `insights` / `done` macros render the kind-grouped sections, and mechanical catch-up at scale. Bare `sdd view` prints help with vocabulary tables. See "`sdd view` pipeline" below.
- `sdd view --layout=<spec>` — composable pipeline of primitives (source, filter, transform, aggregate, rank, page, render) with named macros as sugar. The overview surface: `decisions` / `signals` / `aspirations` / `contracts` / `participants` / `insights` / `done` macros render the kind-grouped sections, and mechanical catch-up at scale. Bare `sdd view` prints help with vocabulary tables. `--repo <repo-id>` (repeatable) / `--all-repos` fan out across connected repos. See "`sdd view` pipeline" below.
- `sdd show <id>` — full entry plus its upstream (grounding) and downstream (consumers) chains. Both shown by default: upstream depth 2, downstream depth 1.
- `sdd show <id> [<id2> ...]` — multiple IDs in one call render their entries back to back (handy for comparing a cluster, e.g. the entries a new one will ref)
- `sdd show <id> --up N --down N` — set the upstream and downstream expansion depths independently. Defaults: `--up 2 --down 1` (downstream fans out faster, so it stays shallower). `0` turns a direction off; `--up 0 --down 0` is the primary entry alone. Increase (e.g. `--up 4 --down 3`) to see more of an entry's surroundings on demand.
- `sdd new <type> <layer> [flags] <description>` — create entries (output prints the new entry ID, file path, and the LLM-generated summary so the agent can verify fidelity)
- `sdd summarize <id>` — regenerate the named entry's summary unconditionally (summaries are derived on demand with no staleness tracking). `sdd summarize --all` fills only entries that have no summary yet; add `--force` to regenerate every entry.
- `sdd summarize <id> --text "<summary>"` — write a user-supplied summary directly, bypassing the LLM. Use `--text -` to read from stdin. Single entry only; rejected with `--all` or multiple IDs.
- `sdd lint` — check graph integrity (dangling refs, type mismatches, broken attachment links, missing summaries). When an embedding provider is configured, also reports the search index's fingerprint and drift count.
- `sdd index` — warm up the per-participant search index at `.sdd/index/` over every entry on disk. Skips entries whose stored hash and embedder fingerprint match the manifest; `--force` re-embeds everything regardless. Required only on a fresh clone or after deliberate full rebuilds — `sdd search` lazy-fills missing/stale entries on demand.
- `sdd search [--term <regex>...] [--query <phrase>] [--type d|s] [--layer ...] [--kind ...] [--include-superseded] [--limit N] [--max-citations N]` — three-mode retrieval. `--term` runs text mode (live grep with multi-term AND), `--query` runs vector mode, both flags together run hybrid (RRF fusion). At least one of `--term` / `--query` is required; vector and hybrid require `Search: vector,text` in the `sdd info` header. `--max-citations` caps the snippet sub-lines per entry (default 3); `--max-citations 0` suppresses them entirely, rendering entry headers only — the terse "which entries match, and what topics do they carry" lookup. See [search reference](search.md) for citation reading and mode selection guidance.
- `sdd lint` — check graph integrity (dangling refs, type mismatches, broken attachment links, missing summaries, and cross-repo references whose target repo isn't a declared dependency). When an embedding provider is configured, also reports the search index's fingerprint and drift count.
- `sdd index` — warm up the machine-global search index (content-addressed by repo identity and embedder fingerprint, outside the working tree) over every entry on disk. Skips entries whose stored hash and embedder fingerprint match the manifest; `--force` re-embeds everything regardless. `--repo <repo-id>` (repeatable) / `--all-repos` also eagerly build the connected repos' indexes so the first cross-repo search is warm; `--force` reaches those connected indexes too. Required only on a fresh clone or after deliberate rebuilds — `sdd search` lazy-fills missing/stale entries on demand.
- `sdd search [--term <regex>...] [--query <phrase>] [--type d|s] [--layer ...] [--kind ...] [--repo <repo-id>...] [--all-repos] [--include-superseded] [--limit N] [--max-citations N]` — three-mode retrieval. `--term` runs text mode (live grep with multi-term AND), `--query` runs vector mode, both flags together run hybrid (RRF fusion). At least one of `--term` / `--query` is required; vector and hybrid require `Search: vector,text` in the `sdd info` header. `--repo <repo-id>` (repeatable) / `--all-repos` fan out across connected repos and fuse results into one ranked list (see "Cross-repo references" below). `--max-citations` caps the snippet sub-lines per entry (default 3); `--max-citations 0` suppresses them entirely, rendering entry headers only — the terse "which entries match, and what topics do they carry" lookup. See [search reference](search.md) for citation reading and mode selection guidance.
- `sdd repo add <clone-url>` — connect another graph for cross-repo references: clone its graph into a machine-local cache, verify its declared `repo_id`, register the connection, and record + commit a `dependencies:` entry in `.sdd/config.yaml`. Re-running for an already-connected URL just ensures the dependency is declared.
- `sdd repo list` — connected repos and whether each is cached.
- `sdd repo sync [repo-id ...]` — refresh connected caches to their latest pushed state (all, or the named repos).
- `sdd repo remove <repo-id>` — drop a dependency from `.sdd/config.yaml` (project-scoped; the cache stays). Refuses when any local entry still references that repo — removal would strand those references — unless `--force`, which removes anyway and names each stranded reference.
- `sdd wip start <entry-id> --exclusive --participant <name> <description>` — create WIP marker
- `sdd wip start <entry-id> --branch --exclusive --participant <name> <description>` — create WIP marker, create git branch and check out to it
- `sdd wip done <marker-id>` — remove WIP marker (deletes branch if merged)
Expand All @@ -33,6 +37,15 @@ Every argument that takes an entry ID — positional args on `sdd show`, `sdd su

Short IDs are fine in user-facing narrative (catch-up tables, grooming summaries, dialogue). Never substitute them for full IDs in CLI calls you construct — a suffix collision would break the call later when the graph grows.

### Cross-repo IDs

When repos are connected (see "Cross-repo references" below), an entry ID can name an entry in another graph:

- **Cross-repo ID** (`<repo-id>:<entry-id>`, e.g. `github.com/acme/platform:20260709-...-d-cpt-abc`) — a target's canonical repo identity, then the entry within it. This is the form stored on disk for any cross-repo reference.
- **Bare ID across repos** — a short or unprefixed-full ID resolves against the union of the local graph and its declared dependencies, not just the local graph. A unique match resolves; a genuine collision across repos exits non-zero and lists the candidates (the local one bare, foreign ones fully prefixed). This applies wherever a typed ID is resolved — `sdd show` and the `show` MCP tool. Written references always expand to the full `<repo-id>:<entry-id>` form regardless of how you typed them.

When you have only a short ID for a possibly-foreign entry, resolve it with `sdd show <short-id>` (a free read) and use the full ID it prints in any CLI call you construct.

## `sdd view` pipeline

`sdd view` runs a layout pipeline over the graph. Each section is a colon-chained sequence of function calls; multiple sections separate with commas. Render is always the section's terminator. Filters intersect cumulatively; non-filter modifiers (rank, page, name, render) apply last-write-wins per kind.
Expand Down Expand Up @@ -334,3 +347,13 @@ echo "$PLAN" | sdd new d tac --kind plan --confidence high \

Use quoted `'EOF'` so markdown content with `$`, backticks, or backslashes is preserved verbatim. For scratch files you do want on disk, `.sdd/tmp/` is gitignored.

## Cross-repo references

References usually stay within one graph. When reasoning genuinely builds on another repo's graph, connect that repo and reference across the boundary instead of re-deriving or paraphrasing it locally.

- **Connect once** with `sdd repo add <clone-url>` — clones the repo's graph into a machine-local cache, verifies the `repo_id` it declares, and records + commits a `dependencies:` entry in `.sdd/config.yaml`. The dependency is the portable record (like `go.mod`); a colleague who clones the repo runs `sdd repo add` for the same URL to connect their own cache.
- **Reference by cross-repo ID** — `<repo-id>:<entry-id>` in a `--refs` value. Any ref kind may cross the boundary, but lifecycle edges (`--closes`, `--supersedes`) stay within-graph: a decision can't close an entry in another repo.
- **Declared-dependency precondition** — a cross-repo ref must resolve to a *declared* dependency when captured, the same resolve-or-block gate that guards local refs. If the target repo isn't connected, offer to `sdd repo add` it first (and confirm the target entry is pushed) rather than dropping the connection to a local paraphrase.
- **The cache is pushed state** — a connected cache is a clone of the remote's pushed branch, not a working tree. A foreign entry resolves only after it's committed *and pushed*; `sdd repo sync` (and cross-repo `sdd show`/`sdd search`) refresh the cache. When a cross-repo ref won't resolve, the target is usually unpushed or the cache is stale.
- **Search across repos** with `--repo <repo-id>`/`--all-repos` on `sdd search` and `sdd view` — results fuse into one ranked list under a single shared embedder. `sdd index --repo <repo-id>`/`--all-repos` pre-warms a connected index so the first cross-repo search isn't slow.

6 changes: 4 additions & 2 deletions .agents/skills/sdd/references/search.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
metadata:
sdd-content-hash: d1b377a84f9855ea2f041c5d19ff17942967db7e0b370f64545164ebe79565d8
sdd-content-hash: fc9f862a1117260d72b72b4c56ec1cfd09b4702b9e09bd66307d95ef45829656
sdd-version: dev
---
# sdd search
Expand Down Expand Up @@ -43,6 +43,8 @@ The `--type`, `--layer`, `--kind` filters (the same filter shape `sdd view` comp

`--limit N` caps the result count (default 10).

**Cross-repo scope.** `--repo <repo-id>` (repeatable) and `--all-repos` widen the search to connected repos, fusing every selected graph's hits into one ranked list. Vector search across repos builds and queries every connected index under the single user-global embedder, so all indexes share one vector space and scores stay comparable. The first cross-repo query embeds a connected graph on demand (slow); `sdd index --repo <repo-id>`/`--all-repos` pre-warms it. See the CLI reference's "Cross-repo references" section for connecting repos and the pushed-state cache model.

## Instruction templates

Instruction-tuned encoders (Qwen3, E5, Nomic, BGE) want a small instruction or prefix prepended to each input. The framework applies this transparently via two config keys:
Expand Down Expand Up @@ -92,7 +94,7 @@ If you switch templates after building, run `sdd index --force` to re-embed eage

## Lifecycle

Vector mode reads from a per-participant local index at `.sdd/index/` (gitignored). Two ways the index gets populated:
Vector mode reads from a machine-global index — a content-addressed store keyed by repo identity and embedder fingerprint, outside the working tree and shared across a repo's checkouts and worktrees. Two ways the index gets populated:

- **`sdd index`** — explicit warm-up: builds chunks for every entry on disk. Run once on a fresh clone, after a major batch of new entries, or after changing the embedding model. `--force` re-embeds everything regardless.
- **Lazy fill** — `sdd search` automatically chunks and embeds entries that are present on disk but missing from (or stale against) the index before the query runs. The first search after a branch switch or new captures may emit a few `lazy-indexed` lines; subsequent searches are fast.
Expand Down
8 changes: 7 additions & 1 deletion .claude/skills/sdd/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
allowed-tools: Read Grep Bash(sdd *)
description: Work with the SDD decision graph. Check in on project state, capture signals, make decisions, evaluate completed work. Use when starting a session, capturing observations, or making project decisions.
name: sdd
sdd-content-hash: 3ecb7e94e699f40f62b5be08378ef5257ddf147c3ca6779f3ad7c3e2c329cd1b
sdd-content-hash: 84d8cfafa3972f5a3ef5e758cd96a98df66ae1574ad9c91613f9fba7712041d5
sdd-version: dev
---

Expand Down Expand Up @@ -187,6 +187,12 @@ See [CLI reference](references/cli-reference.md) for full command syntax and fla
- **Kind for signals**: Default is gap. Use `--kind done` for completion records (must carry `closes` or `refs`). Use `--kind fact`, `question`, or `insight` when the narrative is unambiguously observational, an open question, or a synthesis. Use `--kind actor` for a first-class participant identity — canonical name in frontmatter, prose covers stable identity facts (affiliation, background, domain expertise) that hold independent of any project frame.
- **Acceptance criteria for plan decisions**: `--kind plan` decisions must include an `## Acceptance criteria` section in the description (not the attachment) with `- [ ]` checklist items. Each AC is a single verifiable outcome — not an implementation detail. ACs are the contract between plan author, implementing agent, and pre-flight validator. Pre-flight flags a missing AC section on a plan decision as high.

### Reference across repos when reasoning does

When an entry's reasoning genuinely builds on another repo's graph — a shared framework's directive, a platform team's decision — reference it across the boundary rather than re-deriving it or reducing it to a local paraphrase. Cross-repo refs take the `<repo-id>:<entry-id>` form in a `--refs` value; every ref kind may cross, but `--closes` / `--supersedes` stay within-graph (a decision can't retire an entry in another repo).

The target repo must be a **declared dependency** for the ref to resolve — the same resolve-or-block gate that guards local refs. If it isn't connected, offer to `sdd repo add <clone-url>` first; don't connect a repo the user hasn't signalled they want to depend on. Remember a foreign entry is visible only once it's committed *and pushed* (the cache is pushed state, refreshed by `sdd repo sync`). When you have only a short ID for a foreign entry, resolve it with `sdd show <short-id>` — a free read that resolves bare IDs across the local graph and its declared dependencies — and use the full `<repo-id>:<entry-id>` it prints in the `--refs` value. Full mechanics live in [cli-reference → Cross-repo references](references/cli-reference.md).

### Attachment assessment

The entry description is the summary. The attachment is the record. When the conversation that led to capture involved more than a brief exchange, the entry needs an attachment. **Default to attaching** when the dialogue produced any of these:
Expand Down
Loading
Loading