Skip to content
Back to skills

Spec Sync

ASecurity

Spec-driven development loop for buildd. Keeps docs/SPEC.md as the single source of truth and reconciles downstream artifacts (buildd-docs, buildd-site, knowledge-base) against it. Use when re-grounding the product spec, auditing doc drift, after major schema/route changes, or before a docs/site refresh.

  • 2 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added October 5, 2026
ai-agentsrustgoshellbashgitapidatabasebackend

Works with

  • api
  • mcp

Security analysis

A100/100

Pro scans all 3 files and shows the line behind each finding

Scanned October 5, 2026

npx -y skills add buildd-ai/buildd --skill spec-sync --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Spec Sync?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Spec Sync
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/buildd-ai-spec-sync/badge)](https://www.skillsdirectory.com/skills/buildd-ai-spec-sync)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: spec-sync
description: "Spec-driven development loop for buildd. Keeps docs/SPEC.md as the single source of truth and reconciles downstream artifacts (buildd-docs, buildd-site, knowledge-base) against it. Use when re-grounding the product spec, auditing doc drift, after major schema/route changes, or before a docs/site refresh."
author: buildd
---

# Spec-Sync

Spec-driven development for buildd. **Code is the source of truth; `docs/SPEC.md`
is its canonical written form; the doc/site repos are outputs.** This skill keeps
that chain from rotting.

## Mental model

```
code (schema + routes + runner)  ──►  docs/SPEC.md  ──►  buildd-docs / buildd-site
        (truth)                        (canonical)         (downstream outputs)
                         ▲                                        │
                         └──────────── drift tasks ◄──────────────┘
```

Never edit SPEC.md to match the docs. Edit it to match the **code**, then fix the
docs to match SPEC.md.

## When to use

- Re-grounding the spec after drift has accumulated.
- After a schema (`packages/core/db/schema.ts`) or API-route change that alters the
  domain model — update SPEC.md §2/§4 in the same PR.
- Before refreshing `buildd-docs` or `buildd-site`.
- Periodic drift audit (regenerate `docs/reports/doc-drift-punchlist.md`).

## The loop (proven pipeline)

```
ingest (clean code corpus)  →  retrieve (surface candidates)  →  JUDGE (agent reads evidence)  →  emit drift
```

1. **Re-derive truth.** `schema.ts` (tables/enums), `api/**` routes, `apps/runner/src/backends/`
   are ground truth. Don't trust the doc repos. Keep `docs/SPEC.md` matching them.
2. **Ingest a CLEAN code corpus.** Exclude history — migrations and tests keep removed
   features semantically "alive" (a `CREATE TABLE objectives` migration makes "objectives"
   look implemented forever). Always ingest the code side with:
   `INGEST_SKIP_DIRS=drizzle,__tests__ INGEST_SKIP_TESTS=1` (see ingest section).
3. **Retrieve, don't trust scores.** `spec-drift.ts` surfaces top code/doc matches per probe.
   **Scores SURFACE; they do NOT decide.** A reranker always returns a best match, so a
   documented-not-built feature still scores moderately against its semantic neighbor
   (proven: "objectives" matches the *missions* table at ~0.45). Never gate drift on a
   threshold — it reports false-green.
4. **Judge the evidence.** Run `spec-drift.ts <ns> --evidence` and pass the JSON to a judge —
   a `Task` agent interactively, or `claude -p` headless in CI. The judge rules, per term:
   *do the CODE snippets actually implement it (real table/route/impl), or are they only
   semantic neighbors?* This is the step that catches drift; the retrieval is just its input.
5. **Reconcile** docs/site *against SPEC.md* — never the reverse. Optionally file confirmed
   drift as buildd tasks.

## The embedding corpus (unified workspace store)

`spec_compare` reads the **unified workspace store** — the same store that `recall`
(scope=code|docs) queries. Two corpora within the workspace:

| Corpus | Namespace | What it holds |
|--------|-----------|--------------|
| `code` | `{workspaceId}:code` | Source files |
| `docs` | `{workspaceId}:docs` | Prose: `docs/SPEC.md`, `docs/**`, and any `.md`/`.mdx` in a bound repo |

**There is no `:spec` namespace.** `classifyIngestCorpus` returns only
`code | docs`, and every ingest path goes through it, so nothing has ever written
`spec`. `spec_compare` used to read it and therefore returned an empty prose side.

**Ingestion is in-app and event-driven, not CI.** A merged PR on any repo bound to a
workspace enqueues a diff ingest job per workspace (`enqueueMergedPrIngestJobs` in the
GitHub webhook), executed via `after()` with a lease so a lost run is reclaimed by the
next trigger. Beyond the attempt ceiling the row parks in `error` and a full ingest
recovers it. Full-repo ingests are claimed by runners at
`/api/knowledge/ingest-jobs/claim`. So **the corpus is current as of the last merged
PR** — there is no workflow to re-run, and a stale corpus means the job queue is stuck,
not that a cron was missed. Check the workspace config's Knowledge Health section.

For local or ad-hoc ingestion of the sibling doc repos (which are only covered by the
in-app path if they are bound to a workspace), use:

```bash
SPEC_WORKSPACE_ID=<workspace-uuid> \
DATABASE_URL=<target-db> \
VOYAGE_API_KEY=<key>            # omit -> lexical-only (BM25), still usable \
  bash .claude/skills/spec-sync/scripts/ingest-spec-corpus.sh
```

The corpus is **rebuildable** — each file's prior chunks are cleared before re-chunk
(idempotent on `(namespace, source_id)`).

### Prerequisites / gotchas
- `VOYAGE_API_KEY` is **not** in `.env`/shell by default — without it you get lexical-only
  (no semantic search). Confirm before claiming "embedded."
- `spec_compare` resolves the workspace from the MCP connection context. Connect with
  `?workspace=<id>` when calling the remote MCP endpoint.

## Non-negotiables

- SPEC.md changes follow the code, never the marketing.
- A feature absent from `schema.ts`/routes does **not** exist — remove it from docs.
- Removed concepts (Objectives, Recipes, heartbeat-as-feature, `observations`,
  `codex_credentials`) stay removed. See SPEC.md §8.

Files in this skill

  • SKILL.md5.3 KB
  • scripts/ingest-spec-corpus.sh2.5 KB
  • scripts/spec-drift.ts5.2 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.