Skip to content
Back to skills

Beads Onboard

ASecurity

This skill should be used when the user asks to "onboard beads", "set up beads conventions", "configure beads for this project", "set up project labels", "improve my beads quality", "run beads onboard", "upgrade beads conventions", "re-run beads onboard", or when a project has .beads/ but no .beads/conventions/ directory. Provides an interactive interview that generates per-project quality conventions for beads issue tracking.

  • 2 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added October 10, 2026
ai-agentstypescriptgoshellnodegitdatabasedocumentation

Works with

  • claude code
  • cursor
  • cli

Security analysis

A100/100

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

Scanned October 10, 2026

npx -y skills add seanmartinsmith/sms-public-mkt --skill beads-onboard --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Beads Onboard?

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

Security grade badge for Beads Onboard
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/seanmartinsmith-beads-onboard/badge)](https://www.skillsdirectory.com/skills/seanmartinsmith-beads-onboard)

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: beads-onboard
description: This skill should be used when the user asks to "onboard beads", "set up beads conventions", "configure beads for this project", "set up project labels", "improve my beads quality", "run beads onboard", "upgrade beads conventions", "re-run beads onboard", or when a project has .beads/ but no .beads/conventions/ directory. Provides an interactive interview that generates per-project quality conventions for beads issue tracking.
---

# Beads Onboard

Set up project-specific quality conventions for beads through an interactive interview. Analyze the codebase, ask targeted questions, and generate convention files plus inline integration content (in AGENTS.md or CLAUDE.md, per user choice) that make agents produce high-quality, searchable, non-redundant beads — without needing to read a separate conventions file before every action.

Run once per project, or re-run to upgrade conventions with improved guidance. Always offers a review pass on re-run.

**Onboard version:** v0.3.0

**Surface:** inline integration block (AGENTS.md or CLAUDE.md, user-chosen) with translation matrix and load-bearing rules. Multi-axis labels: `area:*` + `view:*` sub-areas + cross-cutting (`concern:*`, `platform:*`, `workflow:*`) + universal `mode:*` workflow-mode + conditional `contrib:*`. Dolt-primary PRIME.md preamble with explicit sync, search, notes and cross-project rules, under a size budget. Starter formula. Pre-seeded `bd remember` entries. `--parent` alone for new children of an epic. `labels.md` carries explicit multi-area composition patterns. `bd lint` surfaced as a named quality-gate primitive (auto-lint at create + corpus audit).

**Bootstrap:** Phase 0 auto-bridges `bd init` with detection-aware flags. Backwards-compat snapshot when upgrading across major versions. Global PRIME.md carries a version marker with a five-branch path (regenerate / review / upgrade / upgrade-from-unknown / foreign). Platform-aware config paths (Linux / macOS / Windows).

**Self-detection (Phase 4):** verb-level (5a), flag-level (5b) and mutual-exclusion (5c) bd CLI surface checks; internal version-string drift check (known-targets + unknown-position sweep); `bd init` `.gitignore` leak warning when `--setup-exclude` is in use; starter-formula parse check.

**v0.3.0 (2026-10-09)**: bd 1.3.0 alignment; requires bd 1.3.0 or later. (1) The generated PRIME files and integration block state bd's working rules in full, self-contained: beads and code sync on separate channels (`git push` never ships bead data), explicit session close (`bd sync`, then `git pull --rebase && git push`), consent-gated adoption of git origin as the Dolt remote (never a public repo), consented schema migrations with one designated migrator, title-and-ID-only `bd search`, `--notes` replaces while `--append-notes` appends, cross-project filing with `bd -C`. (2) Corrected statements that are false at bd 1.3.0: labels hold state and `bd set-state` adds an event bead (the `events` table is per-machine); actor chain is `--actor` → `$BEADS_ACTOR` → git `user.name` → `$USER`; timer gates take `--timeout`, not the nonexistent `--until` (calendar dates go through `bd defer --until`); `bd dolt fetch` removed; new child of an epic is `--parent` alone, since bd rejects `--id` + `--parent`. New matrix rows for `bd defer`, `bd state list`, `bd history --events`, `bd conflicts`, `bd recompute-blocked`, `gate create --title`. (3) Size budgets: global and per-project PRIME under 6,000 characters each, and the per-project PRIME does not restate the integration target file. (4) Global PRIME gains a `foreign` branch for markers with a newer major (a stale install no longer overwrites a newer global silently); markers now carry `source: sms:beads-onboard`. (5) File 7 adds bd 1.3.0's `*.gate.lock*` root rule; File 9 starter formulas rewritten in the format bd 1.3.0 parses, with a `bd formula show` check. (6) Phase 4 adds the mutual-exclusion check (5c) and tracks bd 1.3.0's global flags. Re-onboard offers the standard review pass.

**v0.2.0 (2026-05-21)**: Three onboard improvements. (1) Phase 0 global PRIME.md detection enumerates Linux/macOS/Windows config-dir paths explicitly (confirmed via bd source's `os.UserConfigDir()` resolution: `~/.config/beads/` on Linux respecting `$XDG_CONFIG_HOME`, `~/Library/Application Support/beads/` on macOS, `%APPDATA%\beads\` on Windows). (2) New **Q8: Integration Target** lets users choose where the beads integration block lives — `AGENTS.md` (tool-agnostic, default for multi-tool setups) or `CLAUDE.md` directly (for Claude-Code-only users); Phase 0 detection (`claude_md_substantial`, `agents_md_has_content`) drives the default, Phase 3 generation branches on the answer, and Phase 4 step 9 migration recommendation becomes contextual (only fires on Option A + substantial CLAUDE.md). (3) New **Q9: Lint at Create Time** wires `bd lint` as a per-project quality gate via `bd config set validation.on-create warn`; Phase 0 step 8 detects the current setting, the Phase 3 post-table step applies it on opt-in, File 5 gains a "Quality gates" callout, File 4 gains a "Lint at create time" section, and Phase 4 step 8 always recommends a one-time `bd lint` corpus sweep regardless of Q9 answer.

## When to Use

- First time using beads in a project (`.beads/` exists but no `.beads/conventions/`)
- After upgrading beads and wanting to adopt new convention guidance
- When bead quality is inconsistent and needs calibration
- When the user explicitly asks to set up or improve beads conventions

## Phase Overview

Six phases. Execute in order.

### Phase 0: State Detection

Detect the current project state before starting the interview. Order matters: repo-type detection runs first because step 2's init bridge consumes it.

1. **Detect repo type** (auto) — runs first because step 2's init bridge needs it.
   - Run `gh repo view --json owner,name,isPrivate,viewerPermission 2>$null` (PowerShell) or `2>/dev/null` (POSIX). If `gh` is missing or the directory isn't a gh-tracked repo, mark `repo_type_candidate: unknown`.
   - `viewerPermission` is `ADMIN` or `MAINTAIN` → candidate `owned`
   - `viewerPermission` is `WRITE` or lower on a fork or upstream you contribute to → candidate `contributor`
   - Save candidate + confidence for step 2's init flag selection AND for Q7 confirmation. User confirms in Phase 2.

2. **Check `.beads/` directory** — hard gate.
   - **If `.beads/` exists**: skip to step 3.
   - **If missing**: auto-bridge to `bd init` with detection-aware flags. Do not stop at "offer" — propose the command, confirm with the user, run it, then continue. This is the most common new-project case.

     Map step 1's repo-type candidate to `bd init` flags:

     | repo_type_candidate | bd init invocation |
     |---|---|
     | `owned` | `bd init --skip-agents --quiet` |
     | `contributor` or `both` | `bd init --contributor --skip-agents --setup-exclude --quiet` |
     | `unknown` | Ask user; default `bd init --skip-agents --quiet`. Offer `--setup-exclude` for the fork case. |

     Rationale (state inline when confirming with the user, so the flag choice isn't magic):
     - `--skip-agents` — this skill's Phase 3 owns AGENTS.md/CLAUDE.md exclusively. Bare `bd init` would write embedded prohibitive language (`do NOT use TaskCreate`, `do NOT use MEMORY.md`) that directly contradicts the complementary stance and the user's global PRIME.md.
     - `--setup-exclude` (contributor) — writes `.beads/` to `.git/info/exclude` so beads files stay local on a fork; no leak into upstream PRs.
     - `--contributor` — runs the OSS contributor wizard (sets the beads role to contributor for upstream work). Note: `--contributor` requires interaction even with `--quiet`; if Phase 0 is running fully non-interactive, fall back to `bd init --skip-agents --setup-exclude --quiet --role contributor` and surface a one-line note that the wizard was skipped.
     - `--quiet` — suppress bd init's normal output so the skill stays in control of user-facing messaging.

     After invoking:
     - Verify `.beads/` now exists. If `bd init` returned non-zero, surface stdout/stderr and STOP — do not continue with a half-initialized project.
     - Record in working state for downstream phases: `bd_init_invoked: true`, `bd_init_flags: [...]`, `setup_exclude_used: true|false`. Phase 3 File 7 (.gitignore) branches on `setup_exclude_used`; File 8 (.onboard-state.yaml) records all three.
     - If `bd init` is interactive in the chosen invocation despite `--quiet` (e.g., it asks a config question), surface the prompt to the user — do not type into it blind.

3. **Read `.beads/config.yaml`** for the issue prefix.
4. **Check `.beads/conventions/.onboard-state.yaml`** for re-onboard detection:
   - No state file + no conventions dir: first-time onboard
   - State file exists with an older major version: **cross-major upgrade path** — snapshot existing files to `.beads/backup/<old-major>/` and offer a review pass with prior answers as defaults
   - State file exists with version starting `v0` (`v0.1.0`, `v0.1.1`, `v0.2.0`, `v0.3.0`, future minor/patch versions): **always offer a review pass** — re-run is non-destructive; no backup snapshot needed for same-major-version updates
   - If convention files were manually edited after generation, warn about custom edits in Phase 4 summary
5. **Check AGENTS.md** for the `<!-- BEGIN BEADS INTEGRATION` marker prefix (interop with `bd setup` AND bare `bd init` which writes a richer `<!-- BEGIN BEADS INTEGRATION v:1 profile:minimal hash:X -->` variant). Use prefix-match, not full-string equality — see File 5 marker strategy. Also check CLAUDE.md for the same prefix if AGENTS.md has no marker — a prior Q8 = Option B run would have written it there instead.
6. **Check CLAUDE.md** for `@AGENTS.md` reference. Flag if CLAUDE.md has substantial content (>5 non-empty lines beyond the reference). Record detection result for Q8 default resolution:
   - `claude_md_substantial: true|false` (true = >5 non-empty lines beyond `@AGENTS.md`)
   - `agents_md_has_content: true|false` (true = AGENTS.md exists with any content)
   These two flags drive the Q8 default in Phase 2 (see `references/interview-questions.md` → Q8 default resolution table).
7. **Run `bd doctor --agent 2>&1 || bd doctor 2>&1 || true`** — capture output for later recommendations.
8. **Check `bd config get validation.on-create 2>&1`** — capture current lint-gate state. Record in working state:
   - `validation_on_create: warn | error | unset | error-reading` (use `unset` when the command returns `none` or empty; `error-reading` when the command exits non-zero)
   This drives Q9's default in Phase 2: if already set to `warn`, default to "keep current setting" rather than re-prompting.
9. **Check global PRIME.md version** at the platform-appropriate location:
   - **Linux**: `~/.config/beads/PRIME.md` (respects `$XDG_CONFIG_HOME` if set — resolves to `$XDG_CONFIG_HOME/beads/PRIME.md`)
   - **macOS**: `~/Library/Application Support/beads/PRIME.md`
   - **Windows**: `%APPDATA%\beads\PRIME.md`

   bd resolves the path with Go's `os.UserConfigDir` (see File 1 for the per-OS table). The file is per-machine and nothing syncs it, so each machine regenerates its own copy by running this step there.

   Read the first non-empty line and parse for the version marker:

   ```
   <!-- onboard-version: vMAJOR.MINOR[.PATCH] | generated: YYYY-MM-DD | source: sms:beads-onboard [| g1: <value> | g2: <value>] -->
   ```

   Branch on what you find:

   | State | `global_prime_action` | G1/G2 in Phase 2 | Snapshot |
   |---|---|---|---|
   | File missing | `regenerate` | ask fresh | n/a |
   | Marker present, same major (current is v0 → marker is v0.x.x) | `review` | present marker's `g1`/`g2` as defaults; ask fresh if marker lacks them | none (same-major review is non-destructive, mirrors the per-project review pass in step 4) |
   | Marker present, older major | `upgrade` | ask fresh | snapshot to `<config-dir>/beads/backup/<old-major>/PRIME.md.bak` before any write (Linux: `~/.config/beads/backup/` or `$XDG_CONFIG_HOME/beads/backup/`; macOS: `~/Library/Application Support/beads/backup/`; Windows: `%APPDATA%\beads\backup\`) |
   | File exists, marker missing | `upgrade-from-unknown` | ask fresh | snapshot to `<config-dir>/beads/backup/unknown/PRIME.md.<YYYY-MM-DD>.bak` before any write; **explicitly confirm with the user** before overwriting an unversioned file |
   | Marker present, newer major than this skill (another copy of this skill, or a newer release of it) | `foreign` | ask fresh | **explicitly confirm with the user** first, and offer to leave the global alone; if they decline, set `global_prime_action: none` and write nothing. Otherwise snapshot to `<config-dir>/beads/backup/foreign/PRIME.md.<YYYY-MM-DD>.bak` before any write |

   Record working state for downstream phases:
   - `global_prime_action: regenerate | review | upgrade | upgrade-from-unknown | foreign | none`
   - `global_prime_old_version: <version-string-or-null>`
   - `global_prime_old_marker_g1: <value-or-null>` (only populated on `review` when marker carried g1)
   - `global_prime_old_marker_g2: <value-or-null>` (only populated on `review` when marker carried g2)
   - `global_prime_snapshot_path: <path-or-null>`

   Notes:
   - **Parsing tolerance:** the marker may carry additional pipe-delimited keys (e.g. future `g3`); match on `<!-- onboard-version: v` prefix, parse the rest as `key: value` pairs split on `|`. Strict equality on the literal example would miss future shapes.
   - **Same-major review is non-destructive.** Patch and minor bumps within the same major do not need a snapshot; the existing content is reviewable and the user-facing offer is "review and re-confirm" not "wholesale rewrite". The per-project review pass (step 4) is the precedent.
   - **`upgrade-from-unknown` is the case for any global that lacks a version marker (e.g., generated by a tool other than this skill, or by a pre-marker version).** Once any marker-emitting run completes, future runs see the marker and route to `review` or `upgrade`.
   - **Branch on the version, not on `source`.** Markers written by v0.1.0–v0.2.0 carry a different `source` value; a v0.x marker is this skill's own whatever its `source` says. A newer major means another copy of this skill wrote the file (or a newer release did, and this install is stale), so `foreign` never overwrites it without the user's say-so.
   - **Snapshot path consideration:** if the user has the platform config dir (`~/.config/beads/` on Linux, `~/Library/Application Support/beads/` on macOS, `%APPDATA%\beads\` on Windows) under version control as part of dotfiles, the `backup/` subdirectory should be gitignored in that repo. The skill does not modify the user's dotfiles `.gitignore`; surface this in the Phase 4 summary when a snapshot was taken.
10. **Detect project state**: existing project (>5 source files), planned project (has docs/), or empty project.

Do not block on doctor results. The hard gates are step 1's detection (best-effort; `unknown` is acceptable) and step 2's `.beads/` existence (must succeed after the init bridge).

### Phase 1: Analyze the Project

Gather defaults for the interview questions. Adapt detection based on project state.

**For existing projects (has code):**
1. List top-level directories, map each to candidate `area:*` labels
2. Within each candidate area, propose `view:*` sub-area candidates by examining subdirectory structure (only for areas where structure suggests meaningful sub-divisions; skip for areas that map cleanly to one thing)
3. **Propose multi-area composition patterns** based on which areas Phase 1 found. For each pair (or triple) of areas where the project shape suggests boundary-crossing work, propose a labeled pattern with a one-line rationale (e.g., `area:infra,area:harness,view:hooks` for "hook activation in install scripts"; `area:config,area:shell` for "config + shell integration"; `area:docs,area:harness,view:memory` for "convention + documentation"). These patterns surface in File 3 labels.md "Multi-area composition" section, where they teach agents which area combinations are real cross-cutting work vs single-area beads with a sloppy label. Cap at 3–5 patterns to avoid noise.
4. Detect languages and frameworks from file extensions and package files
5. Read last 20 commit messages for commit convention detection
6. Auto-detect cross-cutting label dimensions (platform, concern, workflow:browser)
7. Detect project type (production app, library, CLI tool, personal/internal)
8. Surface candidate insights for `bd remember` pre-seed (e.g., "monorepo with N workspaces", "Windows-first project", "uses Y framework with quirk Z" — only when the insight has a "future agent will trip on this" feel)

**For planned projects (has docs, minimal code):**
- Read planning docs to extract project description, tech stack, planned structure
- Derive candidate `area:*` and `view:*` from planned structure

**For empty projects:**
- Use universal defaults. Area: `area:core` (placeholder). No `view:*` sub-areas yet.

Audit for reinvented conventions: check CLAUDE.md, AGENTS.md, and any project docs for ad-hoc patterns that duplicate built-in bd features (especially ad-hoc human-decision flagging that should use `bd label add <id> human` or `bd gate create --type=human`, ad-hoc dependency tracking that should use `bd dep`, custom label systems that duplicate the universal axes).

### Phase 2: Interview

Ask questions **one at a time** using AskUserQuestion. Wait for each answer before proceeding.

**Global preference questions (G1, G2)** are asked when Phase 0 step 9 set `global_prime_action` to anything other than `none`:

- `regenerate` (file missing, first time ever): ask both fresh.
- `review` (same major, marker present): ask both with the marker's `g1`/`g2` values as **defaults** if present. If the marker pre-dates the g1/g2 keys, ask fresh — the existing file content is not parsed to infer values.
- `upgrade` (cross-major): ask both fresh.
- `upgrade-from-unknown` (file exists, marker missing): ask both fresh after the explicit overwrite confirmation from Phase 0 has been obtained.
- `foreign` (marker with a newer major): ask both fresh after the explicit overwrite confirmation from Phase 0 has been obtained. If the user chose to leave the global alone, Phase 0 set `none`.

Questions:
- G1: Tasks stance (complementary with beads, or beads-only?)
- G2: MEMORY.md stance (use alongside `bd remember`, or `bd remember` only?)

Skip Phase 2 G1/G2 entirely when `global_prime_action: none` (today only a declined `foreign` overwrite sets it; every other detected state triggers at least a review).

Then ask per-project questions:
- Q1: Project description (generate 3 options from analysis)
- Q2: Area labels (present detected list, offer to modify)
- Q2b: Sub-area `view:*` (per area where candidates exist — see interview-questions.md for the per-area subloop)
- Q3: Commit format (4 options, context-aware for open source vs personal)
- Q4: Code change policy (changelog-worthy, all changes, or multi-session only)
- Q5: Beads + CC Tasks integration — **skip if global PRIME.md already has complementary stance**.
- Q6: Close outcome template (default 6-field, simplified, or custom)
- Q7: Repo type — confirm Phase 0 auto-detect (`owned` / `contributor` / `both`). Only generates `contrib:*` axis when `contributor` or `both`.
- Q8: Integration target — where should the beads block live? `AGENTS.md` (Option A, default for most cases) or directly in `CLAUDE.md` (Option B, for Claude-Code-only users). Default driven by Phase 0 step 6 detection (`claude_md_substantial` and `agents_md_has_content` flags). See `references/interview-questions.md` → Q8 for the full default resolution table.
- Q9: Enable `bd lint` as a quality gate at `bd create` time? (`validation.on-create = warn`). Default driven by Phase 0 step 8 `validation_on_create` state: if already set, default to "keep current setting"; if unset, default to "yes (recommended)". See `references/interview-questions.md` → Q9.

Note: **workflow-mode (`mode:design`/`ready`/`iterative`) is universal**, not per-project. No interview question for it — values come from global convention, propagated to every project via the inline integration block (AGENTS.md or CLAUDE.md).

Read `references/interview-questions.md` before starting this phase. It contains the full question specifications, options, and preview content.

### Phase 3: Generate

Create or update these files using interview answers. Read `references/file-templates.md` before starting this phase. It contains the complete generation templates for all output files.

**Before any write**, if Phase 0 detected an older-major state, copy each file that will be overwritten to `.beads/backup/<old-major>/<filename>.bak` first.

| File | Purpose |
|------|---------|
| Global PRIME.md (Linux: `~/.config/beads/PRIME.md`; macOS: `~/Library/Application Support/beads/PRIME.md`; Windows: `%APPDATA%\beads\PRIME.md`) | Global bd prime override with complementary Tasks/MEMORY language + Dolt-primary architecture preamble + explicit sync, search, notes and cross-project rules + version marker on first line; under 6,000 characters. Driven by Phase 0 step 9's `global_prime_action`; snapshot before write when `upgrade`, `upgrade-from-unknown` or `foreign`; untouched when `none`. See File 1 in `references/file-templates.md`. |
| `.beads/PRIME.md` | Per-project bd prime override with project-specific labels and conventions; replaces the global for this project, does not restate the integration target file, under 6,000 characters. See File 2. |
| `.beads/conventions/labels.md` | Multi-axis label taxonomy: area + view:* + cross-cutting + universal `mode:*` + (conditional) `contrib:*` |
| `.beads/conventions/reference.md` | Quality reference: full bd primitive table, close template, `.beads/tmp/` staging, description structure by type, priority semantics, paired-IDs / cross-project conventions, parent-vs-suffix filing rules |
| **Integration block (Q8-branched)** | **Inline load-bearing content**: translation matrix + label axes + title convention + close template example + session rules (≤250 lines hard cap, 200 soft cap). **Option A** (Q8 = `agents`): write between `<!-- BEGIN/END BEADS INTEGRATION -->` markers in `AGENTS.md`. **Option B** (Q8 = `claude`): write between the same markers directly in `CLAUDE.md`; skip AGENTS.md write entirely. |
| `CLAUDE.md` | **Option A**: add `@AGENTS.md` if missing. **Option B**: integration block already written here by the row above; no further CLAUDE.md edit needed. |
| `.gitignore` | Branches on Phase 0 `setup_exclude_used`: if true (contributor + `--setup-exclude` used), append only `tmp/` (plus `*.gate.lock*` to `.git/info/exclude`); otherwise append `.beads/tmp/`, `tmp/`, `.beads/backup/`, and `*.gate.lock*` (bd 1.3.0's root `.beads.gate.lock`). See File 7 for the rationale. |
| `.beads/formulas/starter.formula.toml` | Starter formula scaffold (a simple bug-investigation or session-close template) — teaches molecule/formula workflow at install time |
| `.beads/conventions/.onboard-state.yaml` | Saved answers for re-onboard detection (current version: v0.3.0) |
| `~/.beads/onboard-status.jsonl` | Append one record per successful run: `{project, path, onboard_version, run_at, actor, axes_authored, repo_type}` |
| `bd remember` entries | Pre-seeded kv from Phase 1 candidate insights (only the ones flagged "future agent will trip on this") |
| `.beads/backup/<old-major>/<filename>.bak` | Snapshot of each file before in-place overwrite (only on cross-major upgrade) |

**Quality-gate config (Q9 = yes only):** run `bd config set validation.on-create warn`. Verify with `bd config get validation.on-create` returns `warn`. If the command fails, surface the error and continue — do not halt the onboard. Skip entirely when Phase 0 step 8 already detected `validation_on_create: warn` and the user chose "keep current setting".

**Integration block marker strategy (applies to both Option A and Option B targets):**

Detection uses **prefix-match**, not full-string equality. Match opening markers that begin with `<!-- BEGIN BEADS INTEGRATION` (regardless of trailing attributes); match closing markers that begin with `<!-- END BEADS INTEGRATION`. This handles both:

- Onboard's plain marker: `<!-- BEGIN BEADS INTEGRATION -->`
- bd init / bd setup's attributed marker: `<!-- BEGIN BEADS INTEGRATION v:1 profile:minimal hash:X -->` (and any future attribute additions like `v:2`, alternate profiles, or different hashes)

Strategy (apply to the Q8-chosen target file — `AGENTS.md` for Option A, `CLAUDE.md` for Option B):
- **If a prefix-matching opening marker exists in the target file**: replace everything from the opening marker line through the closing marker line (inclusive) with the onboard plain marker form. Do not preserve bd init's `v:1 profile:minimal hash:X` attributes — onboard owns this section now.
- **If no marker exists in the target file**: append the section with onboard plain markers for `bd setup` interoperability.
- **If the target file does not exist** (Option A and no AGENTS.md): create it with onboard plain markers.

Full-string equality on `<!-- BEGIN BEADS INTEGRATION -->` would miss bd init's variant and produce a double-integration section (one from bd init bare, one appended by onboard) — the failure mode that prompted this prefix-match rule.

**Pre-seed `bd remember` policy:**

Only call `bd remember "<insight>" --key=<key>` for insights where a future agent would meaningfully benefit. Examples: "this is a monorepo with N workspaces under `packages/`", "Windows-first project — assume PowerShell, paths use backslashes". Counter-examples (do NOT pre-seed): "uses TypeScript" (obvious from package.json), "is a Node project" (obvious from files).

Signature reminder: `bd remember` takes a single positional `"<insight>"` and an optional `--key <key>` flag (auto-generated from content if omitted). The two-positional form `bd remember <key> "<value>"` does NOT work — bd 1.0.4 rejects with `Error: accepts 1 arg(s), received 2`. See File 11 in `references/file-templates.md` for the correct call pattern.

Cap pre-seed at ~5 entries. More than that risks noise and dilutes the signal of legitimate later memories.

### Phase 4: Validation

After generating all files:

1. Read back each file to verify successful writes. If File 9 wrote a starter formula, run `bd formula show <name>`: it must print the formula name and every step id (see File 9). Measure the generated PRIME files against their size budgets (File 1 / File 2).
2. Show summary table of what was generated and which files (if any) were snapshotted to `.beads/backup/`
3. If Phase 0 step 2 invoked the init bridge, surface:
   - The exact `bd init` command run (flag set)
   - Whether `--setup-exclude` is in effect — and if so, the verification command to confirm: `cat .git/info/exclude` (POSIX) or `Get-Content .git/info/exclude` (PowerShell) should show beads entries
   - Confirm `git status` is clean — bare `bd init` would have auto-committed; with `--skip-agents --setup-exclude` it should not have. `?? .beads.gate.lock` alone means the File 7 `*.gate.lock*` rule is missing (bd 1.3.0 workspace gate file), not a failed init
   - **When `setup_exclude_used = true`, detect `bd init`'s `.gitignore` pollution:** run `git diff .gitignore` (or `git diff HEAD .gitignore` if `.gitignore` was newly tracked) and grep for the known pollution patterns (`.dolt/`, `*.db`, `.beads-credential-key`, `.beads/proxieddb/`, and since bd 1.3.0 `*.gate.lock*` — the full list is `ProjectGitignorePatterns` in bd's `cmd/bd/doctor/gitignore.go`). If any match, emit a Phase 4 warning naming the exact lines `bd init` added and the rationale: `bd init --setup-exclude` writes these to `.gitignore` even though its stated purpose is to keep beads files local. For upstream-bound contributor forks, those lines surface in PR diffs to the upstream maintainer — recommend removing them from `.gitignore` (they're already in `.git/info/exclude` from `--setup-exclude`'s primary effect). The skill does NOT auto-clean the leakage; surfacing the warning is the safe default. File an upstream beads issue requesting `--setup-exclude` route ALL storage artifacts to `.git/info/exclude` only if not already filed. (See File 7 Branch A for the empirical context.)
4. **Global PRIME upgrade summary.** Always surface the table when `global_prime_action` is set (i.e., on every onboard run, since every run touches the global to at least review it). Use "unchanged: <value>" and "n/a" for cells where nothing happened — the table doubles as a one-glance audit of "what did this run do to the global?".

   | Field | Value |
   |---|---|
   | Action | `regenerate` / `review` / `upgrade` / `upgrade-from-unknown` / `foreign` / `none` (left alone) |
   | Old version | `global_prime_old_version` (or "(none — first generation)" or "(unknown — pre-marker file)") |
   | New version | The onboard version that wrote the new marker (current: v0.3.0) |
   | Snapshot path | `global_prime_snapshot_path` (or "n/a" when no snapshot) |
   | G1 (Tasks stance) | `<previous-value> → <new-value>` or "unchanged: <value>" or "new: <value>" (use "new: <value>" when there was no preserved default — first generation OR review against a marker that pre-dates the g1/g2 keys) |
   | G2 (MEMORY.md stance) | same form as G1 |

   When `global_prime_snapshot_path` is non-null, additionally surface a one-line gitignore reminder: "If your platform config dir (`~/.config/beads/` on Linux, `~/Library/Application Support/beads/` on macOS, `%APPDATA%\beads\` on Windows) is under version control as part of your dotfiles, add `backup/` to that repo's `.gitignore` — the skill does not modify dotfile gitignores."

5. **Verify `bd <verb>` AND `--<flag>` surfaces in the generated integration block and reference.md.** Grep both for `bd <verb>` lines (between the beads markers in the Q8 target file — AGENTS.md for Option A, CLAUDE.md for Option B — and the full body of reference.md). For each unique `bd <verb>` mentioned, run `bd <verb> --help` (capture stdout+stderr) and verify two things:

   **5a. Verb existence.** Confirm the cited verb itself exists — i.e. `bd <verb> --help` returns 0 and prints help text, not `Error: unknown command`. Emit a "**spec drift detected (verb)**" warning naming the file, line, and cited surface if missing.

   **5b. Flag-token existence.** For each `bd <verb>` invocation cited in the spec, extract every `--<word>` token that follows it on the same line (regex `--[a-z][a-z0-9-]*` after the verb, until the next backtick / pipe / end-of-line). For each extracted flag, grep the `bd <verb> --help` output (also captured during step 5a) for the literal flag string (`grep -F -- "--<flag>"`). If the flag is absent from the help output, emit a "**spec drift detected (flag)**" warning of the form:

   ```
   spec drift detected (flag): <file>:<line>
     cited: bd <verb> ... --<flag>
     bd <verb> --help does not list --<flag>
     known siblings in help: <list any --<word> in the help that share a prefix with the cited flag, if any — e.g. "--body-file" when "--description-file" was cited>
   ```

   Per-flag warnings (not just per-verb) are the point: `bd create --description-file=path` would pass the verb check (`bd create` is real) but should fail the flag check (no `--description-file` flag).

   **5c. Flag mutual-exclusion.** Verb-exists (5a) and flag-exists (5b) can both pass while the CLI still rejects the *combination*: `bd create --parent=<epic> --id=<epic>.<N>` cites two real flags, yet bd rejects it with `Error: cannot specify both --id and --parent flags`. For each `bd <verb>` invocation in the spec that cites two or more non-cross-cutting `--<flag>` tokens (apply the 5d exclusion list), confirm the combination is accepted:
   - **Verb has a non-destructive validate** (`--dry-run` / `--check` / read-only equivalent shown in `bd <verb> --help`): run `bd <verb> <cited-flags> --dry-run` and treat `cannot specify both` / `mutually exclusive` / `cannot be used with` as drift. `bd create` has `--dry-run` at bd 1.3.0, and its `--id`/`--parent` check runs before the preview, so the dry run reports the conflict without creating anything.
   - **No safe validate** (the verb has no dry-run, and running it would write — do NOT execute it): grep `bd <verb> --help` for a documented exclusion phrase near the cited flags, and check the cited pair against the known mutual-exclusion set — currently **`bd create`: `--id` ⊥ `--parent`**. Extend the set as new pairs surface.

   On a detected conflict emit:

   ```
   spec drift detected (mutual-exclusion): <file>:<line>
     cited: bd <verb> ... --<flag-A> ... --<flag-B>
     rejects the combination: <error text or known-conflict note>
     fix: <which flag to drop / the correct alternative form>
   ```

   Current known case: for a new child of an epic use `--parent=<epic-id>` ALONE (bd auto-derives the `.N` suffix and adds the parent-child edge); `--id=<epic-id>.<N>` alone is retroactive/custom-suffix only. See File 4 / `translation-matrix.md` "File new child of an epic".

   **5d. Cross-cutting flags excluded from the checks.** Skip flags that come from bd's persistent flag block — they appear on every verb's help output but are not the spec's responsibility: `--actor`, `--cpu-profile`, `--database`, `--db`, `--directory`/`-C`, `--dolt-auto-commit`, `--global`, `--ignore-schema-skew`, `--json`, `--mem-profile`, `--no-color`, `--quiet`/`-q`, `--readonly`, `--sandbox`, `--verbose`/`-v`, `--version`/`-V`, `--help`/`-h` (the `Global Flags:` block of `bd --help` at 1.3.0; `--profile` was renamed `--cpu-profile` with no alias). Comparing them per-verb (5b) or counting them toward the mutual-exclusion trigger (5c) is noise.

   **5e. Triage.** Any mismatch (verb, flag, OR mutual-exclusion) means the skill's own spec is wrong — report it against the onboard skill (an issue on the skill's repository), not against the local project's generated artifacts, which are downstream of the spec; correct the local copy only as a stopgap. Title shape: `onboard: fix CLI drift for <verb> --<flag>` (verb/flag level) or `onboard: fix CLI mutual-exclusion for <verb> --<flag-A>+--<flag-B>` (combination level).

   This step applies the rule "verify any tool's CLI surface against its `--help`, never from memory" to the skill's own generated artifacts.

6. **Verify internal version-string consistency across the skill.** Same self-detection shape as step 5, but for literal version strings in the spec itself instead of bd CLI surfaces. The drift class this catches: a maintainer bumps the SKILL.md frontmatter version but misses one of the template-emit positions (File 8 yaml, File 10 jsonl, marker example) — the skill ships, downstream projects inherit stale state markers, the next dogfood discovers it.

   **6a. Extract authoritative version.** Read SKILL.md line matching `\*\*Onboard version:\*\* v(\d+\.\d+\.\d+)`. This is the single source of truth.

   **6b. Known-target check.** For each of the eight known emit locations, verify the cited value matches the authoritative version:

   | Target | File | Match shape |
   |---|---|---|
   | Frontmatter | `SKILL.md` | `**Onboard version:** v<auth>` (the source — trivially passes; included for completeness) |
   | Phase 0 step 4 enumeration | `SKILL.md` | The version `v<auth>` appears in the explicit enumeration list on that line |
   | Phase 3 file table | `SKILL.md` | `(current version: v<auth>)` literal in the `.onboard-state.yaml` row |
   | Phase 4 step 4 table caption | `SKILL.md` | `(current: v<auth>)` literal |
   | File 1 marker example | `references/file-templates.md` | `onboard-version: v<auth>` inside the HTML-comment marker example |
   | File 4 register example | `references/file-templates.md` | `"onboard_version": "v<auth>"` inside the reference.md template's Onboard-Status Register |
   | File 8 yaml template | `references/file-templates.md` | `version: "v<auth>"` literal |
   | File 10 jsonl template | `references/file-templates.md` | `"onboard_version": "v<auth>"` literal |

   On mismatch, emit:

   ```
   spec drift detected (version-string): <file>:<line>
     expected: v<auth>
     cited:    v<other>
     target:   <target name from table above>
   ```

   **6c. Unknown-position sweep.** Run `grep -rn -E 'v[0-9]+\.[0-9]+\.[0-9]+' <path-to-this-skill>/` and subtract:
   - **Changelog header lines** matching `^\*\*v\d+\.\d+\.\d+ \(\d{4}-\d{2}-\d{2}\)\*\*` (these intentionally name past releases)
   - **Inline historical references** inside any prose — heuristic: the version is preceded by a word like "previous", "before", "written by", "dogfood", "earlier marker"; these describe past behavior, not present spec
   - **All eight known-target lines** already covered by step 6b
   - **Phase 0 step 4 enumeration** entries other than the authoritative current (e.g., `v0.1.0` is a valid older-version reference in that list)

   Any remaining unknown-position occurrence is suspect — surface as:

   ```
   spec drift candidate (version-string): <file>:<line>
     cited: v<version>
     authoritative: v<auth>
     verify intent (historical reference, new emit location, or actual drift?)
   ```

   **6d. Triage.** Any step 6b mismatch means the most recent version bump missed a fan-out location — report it against the onboard skill, as in 5e. Title shape: `onboard: bump version-string in <target name>` (or list multiple targets if more than one). Any step 6c surfacing is for human review — could be a legitimate historical reference that needs a tighter exclude rule, or it could be an unrecognized template-emit position.

   The step is **warn-not-fail**: emit warnings, do not block the onboard run. Onboard outputs are still usable; the warnings are signal for the next patch.

7. Highlight the label taxonomy (axes table) and translation matrix preview
8. Surface doctor recommendations from Phase 0. Additionally, always recommend a one-time `bd lint` sweep over the existing bead corpus: "Run `bd lint` to audit existing beads for missing template sections (Acceptance Criteria, Steps to Reproduce, etc.). This is a one-time pass; `validation.on-create` covers new beads going forward."
9. **Contextual AGENTS.md migration note (only fires when Q8 = Option A AND `claude_md_substantial` = true):** "Your CLAUDE.md has substantial project instructions. Consider moving them to AGENTS.md (outside the beads markers) — single source of truth across all tools." Do NOT emit this note when Q8 = Option B (the user explicitly chose to keep everything in CLAUDE.md).
10. Flag any reinvented conventions found in Phase 1 (e.g., ad-hoc human-decision patterns that should use `bd label add <id> human` or `bd gate create --type=human --blocks <id>`)
11. Surface the pre-seeded `bd remember` entries — let the user override or remove any that landed wrong
12. Offer to create a P3 reminder bead to verify conventions after 30 beads
13. Remind: "These conventions are now active. Re-run to upgrade later. `bd lint` audits template gaps on demand; the integration block's 'Auditing existing beads' section lists the other drift checks."

### Phase 5: Cross-Reference

After validation, surface adjacent work that this onboard run unblocks or relates to:

1. **For owned projects**: mention that mode-based routing becomes possible once enough beads carry `mode:*` labels via `bd set-state`.
2. **For contributor projects**: mention the `contrib:*` axis values and that upstream-policy changes can be reflected by bulk-relabeling beads.
3. **If global PRIME.md was generated for the first time OR upgraded from an unmarked file** (`global_prime_action` is `regenerate` or `upgrade-from-unknown`): mention that other projects can now re-run `beads-onboard` to inherit the global preferences and that the new version marker enables non-destructive re-onboard going forward. If the user works from several machines, each one needs its own run: the global is per-machine.
4. **For all projects**: point at `bd lint`, `bd stale` and `bd find-duplicates` for ad-hoc bead-quality reviews — separate from this skill.

## Key Design Principles

- **Inline beats pointers for load-bearing rules.** Agents do not read separate files before every action. The integration block (in AGENTS.md or CLAUDE.md) is where rules live inline. Conventions/ is depth on tap.
- **Universal axes are universal.** `mode:*` and the bd primitive matrix come from a single global source, not per-project. Drift across projects is the failure mode this skill aims to prevent.
- **Per-project axes stay flexible.** Area + view:* + cross-cutting per project. Repo-type conditional axis only when the project actually needs it.
- **Complementary, not combative.** Beads, CC Tasks, and auto-memory each serve different persistence horizons. Never prohibit host environment features.
- **AGENTS.md is the tool-agnostic option.** Works across Claude Code, Cursor, Codex — good default for multi-tool setups. CLAUDE.md is the right target if you're Claude-Code-only and already have substantial project instructions there.
- **Labels are highest leverage.** Multi-axis labels + close outcome template are the two outputs that most improve bead quality.
- **Density over length.** Bead descriptions should be dense and actionable. "If I `bd search` for this in 6 months, will it surface with enough context to act on?"
- **Onboard once, audit on demand.** This skill runs once per project (and on upgrade). `bd lint` and friends audit existing beads ad-hoc.
- **Self-contained, then lean.** The generated PRIME files state every rule an agent needs, because nothing guarantees another file does; within that, they stay under their size budgets and never restate the integration block loaded beside them.

## Additional Resources

### Reference Files

- **`references/interview-questions.md`** — Full G1-G2 + Q1-Q9 question details with options, previews, and recommendation logic
- **`references/file-templates.md`** — Complete generation templates for all output files
- **`references/translation-matrix.md`** — Canonical natural-language → bd CLI matrix, sourced into AGENTS.md per-project
- **`references/boundaries.md`** — Decision framework for beads vs Tasks vs auto-memory vs repo docs (when to use what)

Files in this skill

  • SKILL.md41.7 KB
  • references/boundaries.md7.6 KB
  • references/file-templates.md50.1 KB
  • references/interview-questions.md15.5 KB
  • references/translation-matrix.md17 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…