baldart 3.8.2 → 3.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -5,6 +5,67 @@ All notable changes to BALDART will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [3.10.0] - 2026-05-23
9
+
10
+ BALDART grows an **LSP symbol-search layer**. When enabled, `codebase-architect` and the code-exploration skills (`context-primer`, `bug`, `prd`, `new`, `simplify`) prefer LSP `find-references` / `go-to-definition` over Grep for identifier-shaped queries. The filtering happens **before** Claude reads files — a function-name search that previously returned thousands of textual matches now resolves to the actual callsites of the same symbol. Grep remains the fallback for free-text queries and when the LSP layer is unavailable, so existing flows degrade gracefully.
11
+
12
+ The layer is opt-in: at install / update / configure, BALDART asks "Enable LSP symbol-search layer?" and (on yes) detects the project's languages and installs the matching language servers — npm devDeps for TypeScript and Python, system commands printed for Go, Rust, Ruby.
13
+
14
+ ### Added
15
+
16
+ - **`baldart.config.yml` → `features.has_lsp_layer`** — new boolean (default `false`). Gates the LSP retrieval tier in agents and skills. When `true`, also populates the new `lsp` section with the installed language servers.
17
+ - **`baldart.config.yml` → `lsp.installed_servers` + `lsp.auto_verify`** — new top-level section tracking which language servers are recorded for the project and whether `baldart doctor` should re-verify them on every run.
18
+ - **`framework/agents/code-search-protocol.md`** — new protocol module defining the retrieval hierarchy (RAG hybrid → LSP for symbols → Grep → Git), query-type discrimination, LSP budget (max 3 calls/task), and fallback rules. Referenced from `framework/agents/index.md`.
19
+ - **`framework/.claude/skills/lsp-bootstrap/SKILL.md`** — new invokable skill (`/lsp-bootstrap`) that runs the install + verify flow as a standalone workflow. Refuses to run when `features.has_lsp_layer: false`. Idempotent.
20
+ - **`src/utils/lsp-adapters/`** — new pluggable adapter registry (TypeScript, Python via Pyright, Go via gopls, Rust via rust-analyzer, Ruby via ruby-lsp). Each adapter exposes `detect(cwd)`, `installCommand()`, `verifyCommand()`, and `claudePluginId()`. Same pattern as `src/utils/tool-adapters/`. Add a new language by dropping in a `<lang>.js` file and registering it in `index.js`.
21
+ - **`src/utils/lsp-installer.js`** — high-level installer used by `configure.js` and the `doctor` LSP step. `detectLanguages()` / `recommend()` / `installServers()` / `verifyServers()`. Pure detection has no side effects; install ops respect `--non-interactive`.
22
+ - **`src/commands/configure.js` LSP block** — when the user opts in, autodetects languages, prompts per server, installs npm-mode adapters in-process, prints system-mode install commands, verifies binaries, and persists `lsp.installed_servers`. Re-running configure on an existing project re-detects and updates the list.
23
+ - **`src/commands/doctor.js` LSP step** — new "LSP layer" line in the diagnostic table + a `lsp-fix` action that reinstalls broken servers. Surfaces missing binaries without breaking other doctor flows.
24
+ - **`framework/templates/overlays/agents/codebase-architect.lsp-example.md`** — starter overlay demonstrating how to add project-specific LSP tuning (monorepo quirks, generated-code exclusions, callsite thresholds) on top of the shipped protocol.
25
+
26
+ ### Changed
27
+
28
+ - **`framework/.claude/agents/codebase-architect.md`** — Investigation Protocol step 3 now points at `agents/code-search-protocol.md` for LSP escalation. Behavior under `features.has_lsp_layer: false` is unchanged.
29
+ - **`framework/.claude/agents/REGISTRY.md`** — `codebase-architect` row gains "LSP symbol resolution (when `features.has_lsp_layer: true`)" as a specialization.
30
+ - **`framework/.claude/skills/context-primer/SKILL.md`** — step 3 of the retrieval loop redirects to the code-search protocol for symbol-shaped queries when the flag is on.
31
+ - **`framework/.claude/skills/bug/SKILL.md`** — Phase 0 step 3 references the protocol; `codebase-architect` now automatically uses LSP for symbol lookups during code-path mapping.
32
+ - **`framework/.claude/skills/simplify/SKILL.md`** — deduplication step 3 uses LSP `find-references` to confirm callsites before recommending consolidation; eliminates false positives from textual name collisions and dead-code candidates.
33
+ - **`framework/.claude/skills/prd/SKILL.md` / `new/SKILL.md`** — one-line note that LSP usage is transitive via `context-primer` / `codebase-architect` when the flag is on.
34
+ - **`framework/templates/baldart.config.template.yml`** — adds `features.has_lsp_layer` and the new `lsp:` block with inline documentation.
35
+ - **`framework/docs/PROJECT-CONFIGURATION.md`** — new § 4.5 row for `has_lsp_layer` and a new § 4.6 documenting the `lsp.*` keys, per-adapter install modes, and the fallback contract.
36
+
37
+ ### Notes
38
+
39
+ - **Schema-change propagation** (matches the `v3.9.0` pattern): the new key is wired into the template, the configure prompt, the update-detector, the doctor table, the relevant skills, and the changelog.
40
+ - **Backwards-compatible.** Pre-v3.10 consumers running `npx baldart update` see the standard "new config keys" warning (`has_lsp_layer`) and are offered `configure`. Agents and skills behave exactly as before when the flag is absent or `false`.
41
+ - **Fallback contract.** When the layer is enabled but a server is missing, broken, or returns no references for a known symbol, agents silently fall back to Grep. Code search never fails because of LSP issues; `baldart doctor` surfaces the mismatch.
42
+ - **Languages out of scope** (Java, C/C++, PHP, Elixir, …) can be added by dropping a new file under `src/utils/lsp-adapters/`. No core change required.
43
+
44
+ ## [3.9.0] - 2026-05-22
45
+
46
+ `worktree-manager` (`/mw`) gains a configurable merge strategy. The previous flow forced every consumer through `gh pr create` + `gh pr merge`; in repos where `develop` is not protected on GitHub, that roundtrip is unnecessary and was observed to stall (PR opened, never merged). The new `git.merge_strategy` key lets each project pick its lane.
47
+
48
+ ### Added
49
+
50
+ - **`baldart.config.yml` → `git.merge_strategy`** — new top-level config section with one key (default `pr`):
51
+ - `pr` (default, backwards-compatible) — push feature branch, open PR via `gh pr create`, merge via `gh pr merge`. Required if `develop` is protected on origin.
52
+ - `local-push` — after the rebase in `/mw` step 4b, fast-forward push the feature branch directly to `origin/develop` (`git push origin <feat>:develop`). No PR, no `gh` dependency. Fails hard with a clear hint if `develop` is protected on origin.
53
+ - **`framework/.claude/skills/worktree-manager/SKILL.md` step 4c** — fully rewritten into two clearly labelled strategies (A: `pr`, B: `local-push`) plus a shared local-develop-sync block. Both strategies remain strictly worktree-isolated — neither runs `git checkout` / `git switch` / `git branch` on the main repo.
54
+ - **Programmatic API output** — `/mw` now returns `strategy: "pr"|"local-push"`. `prNumber` is `null` in `local-push` mode.
55
+
56
+ ### Changed
57
+
58
+ - **`framework/.claude/skills/new/SKILL.md`** — Phase 6 description and fail-safe rules reference the configured strategy instead of hard-coding `gh pr merge`.
59
+ - **`worktree-manager` Project Context header** — added at the top of the skill, citing `git.merge_strategy` + `paths.backlog_dir` per the always-ask-never-assume contract in `framework/agents/project-context.md`.
60
+ - **`src/commands/configure.js`** — gained autodetection + interactive prompt for `git.merge_strategy`. The probe runs `gh api repos/:o/:r/branches/develop/protection` to recommend `pr` (when develop is protected) or `local-push` (when not). Falls back to `pr` safely when `gh` is missing or the remote is unreachable. The detection reason is surfaced inline so the user knows *why* a strategy is recommended.
61
+ - **`src/commands/update.js`** — schema-drift detection now also covers new top-level sections (currently `git.*`). When new keys are detected, `update` proactively offers to run `configure` instead of just warning. This means an existing consumer running `npx baldart update` will be **asked** about the new `git.merge_strategy` key, not silently defaulted.
62
+
63
+ ### Notes
64
+
65
+ - No migration is required for existing consumers. `git.merge_strategy` defaults to `pr` when the key is absent, preserving the v3.4.0+ behaviour exactly.
66
+ - On `npx baldart update`, existing consumers are **prompted** to run `configure`, where the merge-strategy autodetection probes their repo and recommends `pr` or `local-push` with a one-line reason. The user picks; nothing is auto-applied.
67
+ - `develop` remains the only supported integration branch; configurable `base_branch` is out of scope for this release.
68
+
8
69
  ## [3.8.2] - 2026-05-22
9
70
 
10
71
  `baldart` (smart doctor) no longer double-confirms safe actions. Previously, running `baldart` with a remote-ahead state would ask *"Run: Pull N commit(s)?"* and then the `update` command would ask *"Proceed with update?"* immediately after — two prompts for the same intent.
package/README.md CHANGED
@@ -183,18 +183,22 @@ Skills always-ask when required keys are missing — never silently default.
183
183
  never overwrites your file. Full guide:
184
184
  [`framework/docs/PROJECT-CONFIGURATION.md`](framework/docs/PROJECT-CONFIGURATION.md).
185
185
 
186
- ### Skills (new in v2.0.0 — 22 portable skills)
186
+ ### Skills (23 portable skills)
187
187
 
188
188
  Skills live under `.claude/skills/` and are auto-discovered by Claude Code.
189
189
  Bundled skills:
190
190
 
191
191
  - **Workflow**: `new`, `prd`, `prd-add`, `bug`, `simplify`, `worktree-manager`, `issue-review`, `context-primer`
192
- - **Code quality**: `skill-creator`, `find-skills`, `webapp-testing`, `playwright-skill`
192
+ - **Code quality**: `skill-creator`, `find-skills`, `webapp-testing`, `playwright-skill`, `lsp-bootstrap` (v3.10.0)
193
193
  - **Design**: `frontend-design`, `ui-design`, `motion-design`, `gamification-design`
194
194
  - **Product**: `seo-audit`, `copywriting`, `api-design-principles`
195
195
  - **Knowledge**: `doc-writing-for-rag`, `capture` (LLM wiki overlay)
196
196
  - **Integration**: `kie-ai`, `remotion-best-practices`
197
197
 
198
+ ### LSP Symbol Search Layer (new in v3.10.0)
199
+
200
+ When `features.has_lsp_layer: true`, `codebase-architect` and the code-exploration skills (`context-primer`, `bug`, `prd`, `new`, `simplify`) prefer LSP `find-references` / `go-to-definition` over Grep for identifier-shaped queries — the filtering happens **before** Claude reads files, so a common function name no longer dumps thousands of textual matches into context. Opt-in at `baldart configure`; BALDART installs the matching language servers (npm devDeps for TypeScript/Python, system commands printed for Go/Rust/Ruby). Grep remains the fallback for free-text queries and degraded states. See [`framework/agents/code-search-protocol.md`](framework/agents/code-search-protocol.md).
201
+
198
202
  ### Commands
199
203
 
200
204
  - **/new**: Batch orchestrator with QA validation, production readiness checklist, and context recovery (also available as a skill)
package/VERSION CHANGED
@@ -1 +1 @@
1
- 3.8.2
1
+ 3.10.0
@@ -8,7 +8,7 @@ Quick-reference for all custom agents. Use this to route tasks to the right spec
8
8
 
9
9
  | Agent | Category | When to Use | Specialization | Can Edit Code | Key Tools |
10
10
  |-------|----------|-------------|----------------|---------------|-----------|
11
- | **codebase-architect** | Architecture | **MANDATORY** before planning/implementing changes | Platform analysis, system design, canonical-source resolution via Linking Protocol v1 | No | Code navigation, pattern tracing |
11
+ | **codebase-architect** | Architecture | **MANDATORY** before planning/implementing changes | Platform analysis, system design, canonical-source resolution via Linking Protocol v1, LSP symbol resolution (when `features.has_lsp_layer: true`) | No | Code navigation, pattern tracing, LSP find-references / go-to-definition |
12
12
  | **plan-auditor** | Architecture | Review implementation plans before coding begins | Risk assessment, gap detection | Yes | Multi-persona review (eng/security/SRE) |
13
13
  | **doc-reviewer** | Architecture | Audit/write docs after feature implementation | Macro feature identification, SSOT sync, linking-protocol resolution, doc debt tracking, gap analysis | Yes | Doc writing, TaskCreate (doc debt), token optimization |
14
14
  | **wiki-curator** | Documentation | Maintain the derived LLM wiki overlay under `docs/wiki/` (concept pages, syntheses, dashboards, reading guides) without creating new canonicals. See `agents/llm-wiki-methodology.md`. | Synthesis pages, provenance hygiene, freshness, derived-link checks, auto-learning loop | Yes | `docs/wiki/`, wiki lint, reindex follow-up |
@@ -163,6 +163,14 @@ Before providing any architectural guidance or implementation advice, follow thi
163
163
  3. **Targeted grep** (only if RAG was weak/empty): grep for 2-3 specific identifiers
164
164
  (function names, file patterns), NOT broad keyword sweeps across the entire codebase.
165
165
 
166
+ **LSP escalation (since v3.10.0):** when `features.has_lsp_layer: true` in
167
+ `baldart.config.yml` AND the query is a symbol/identifier (function, type, class,
168
+ variable name), prefer LSP `find-references` / `go-to-definition` over Grep — it
169
+ filters textual collisions before you read anything. Cap at 3 LSP calls per task,
170
+ then escalate to direct file reads. Falls back to Grep silently when the LSP tool
171
+ isn't loaded or returns nothing. See `framework/agents/code-search-protocol.md`
172
+ for the full hierarchy and query-type discrimination.
173
+
166
174
  4. **Targeted verification** — DO NOT read entire files. Instead:
167
175
  - For files **<200 lines**: read in full.
168
176
  - For files **200-500 lines**: read the first 50 lines (imports + exports) + the
@@ -38,7 +38,11 @@ Argument: optional bug description (e.g., `/bug feature X is not saving`).
38
38
  - **Data/Firestore** → MCP Firestore tools + transaction tracing
39
39
  - **Auth** → authMiddleware.ts + auth error codes
40
40
  - **Build/Deploy** → Vercel logs + build output
41
- 3. Launch `codebase-architect` agent to map the affected code paths — do NOT start debugging blind
41
+ 3. Launch `codebase-architect` agent to map the affected code paths — do NOT start debugging blind.
42
+ When `features.has_lsp_layer: true` and the symptom names a concrete symbol
43
+ (function/type/handler), `codebase-architect` will use LSP find-references /
44
+ go-to-definition to locate the exact callsites instead of grepping. See
45
+ `framework/agents/code-search-protocol.md`.
42
46
  4. Search doc-rag for related patterns: `mcp__doc-rag__search_docs` with bug keywords
43
47
  - always use `mode="hybrid"` (vector + knowledge graph) for richer context retrieval
44
48
  - if results come from Obsidian, treat them as context only and verify runtime behavior against repo docs/code before fixing
@@ -78,6 +78,10 @@ SEARCH STRATEGY — RAG-first, verify-only-if-needed:
78
78
 
79
79
  3. ONLY IF RAG was empty — broader search:
80
80
  a. Grep the project's source root for 2-3 specific identifiers from steps 1-2.
81
+ When `features.has_lsp_layer: true` AND the identifier is a symbol (function /
82
+ type / class name, not a free-text phrase), prefer LSP `find-references` /
83
+ `go-to-definition` over Grep — it filters textual collisions before any file
84
+ read. Cap at 3 LSP calls, then fall back. See `framework/agents/code-search-protocol.md`.
81
85
  b. Read key file headers (first 50 lines) to identify structure.
82
86
  DO NOT read `${paths.prd_dir}/` or `${paths.references_dir}/` files in full —
83
87
  RAG already indexes them. Only read a specific doc section if RAG
@@ -0,0 +1,113 @@
1
+ ---
2
+ name: lsp-bootstrap
3
+ description: >
4
+ Install, verify, and document the LSP symbol-search layer for this project.
5
+ Detects languages (TypeScript, Python, Go, Rust, Ruby), installs the matching
6
+ language servers (npm devDep where possible, system command otherwise),
7
+ verifies binaries are reachable, and writes lsp.installed_servers to
8
+ baldart.config.yml. Use when the user says /lsp-bootstrap, "install LSP",
9
+ "set up symbol search", or after enabling features.has_lsp_layer for the
10
+ first time. Idempotent — re-running on an already-configured project
11
+ re-verifies and reports drift.
12
+ ---
13
+
14
+ # LSP Bootstrap
15
+
16
+ Set up the LSP (Language Server Protocol) layer that lets agents and skills
17
+ search by symbol instead of by string. Without this layer, code search burns
18
+ context on textual collisions; with it, references resolve to the same symbol
19
+ **before** Claude reads any file.
20
+
21
+ ## Project Context
22
+
23
+ **Reads from `baldart.config.yml`:** `features.has_lsp_layer`, `lsp.installed_servers`, `lsp.auto_verify`.
24
+ **Gated by features:** `features.has_lsp_layer` — this skill refuses to run when the flag is `false`, prompting the user to flip it via `npx baldart configure` first.
25
+ **Overlay:** loads `.baldart/overlays/lsp-bootstrap.md` if present — project-specific install commands (e.g. a system-managed pyright via uv, a non-standard gopls path).
26
+ **On missing keys:** ask the user; do not assume defaults. See `framework/agents/project-context.md` § 3.
27
+
28
+ ## What This Skill Does
29
+
30
+ 1. Reads `baldart.config.yml` and confirms `features.has_lsp_layer: true`.
31
+ 2. Probes the cwd via `src/utils/lsp-adapters/` to detect which languages are
32
+ present (markers: `tsconfig.json`, `pyproject.toml`, `go.mod`, `Cargo.toml`,
33
+ `Gemfile`, plus heuristic fallbacks).
34
+ 3. For each detected language:
35
+ - **npm-dev** adapters (TypeScript, Python via pyright): runs `npm install
36
+ --save-dev <pkg>` with user confirmation.
37
+ - **system** adapters (Go gopls, Rust rust-analyzer, Ruby ruby-lsp): prints
38
+ the install command for the user to run in a separate terminal. Does NOT
39
+ execute system-level installs automatically.
40
+ 4. Verifies each binary is reachable (`<binary> --version`).
41
+ 5. Updates `lsp.installed_servers` in `baldart.config.yml` with the verified
42
+ set. System-mode servers are recorded even if not yet reachable (the user
43
+ may have a pending install) — `baldart doctor` will flag the mismatch.
44
+ 6. Prints a summary table and points the user to
45
+ `framework/agents/code-search-protocol.md` for runtime behavior.
46
+
47
+ ## Workflow
48
+
49
+ 1. **Refusal check.** If `features.has_lsp_layer: false` (or missing):
50
+ ```
51
+ This project hasn't opted in to the LSP layer yet.
52
+ Run `npx baldart configure` and answer YES to "Enable LSP symbol-search layer?"
53
+ then re-run /lsp-bootstrap.
54
+ ```
55
+ Stop here. Do not proceed.
56
+
57
+ 2. **Probe.** Call the BALDART installer (internally `src/utils/lsp-installer.js`):
58
+ ```
59
+ node -e 'const L=require("./.framework/src/utils/lsp-installer"); console.log(JSON.stringify(new L().recommend(),null,2))'
60
+ ```
61
+ Show the detected languages with their `installMode`.
62
+
63
+ 3. **Confirm per server.** For each recommended server, ask the user. Skip the
64
+ ones already in `lsp.installed_servers` unless they fail verify.
65
+
66
+ 4. **Install.** Run the appropriate `installCommand()`. Capture failures into a
67
+ "Skipped" bucket — never abort the whole skill on one failure.
68
+
69
+ 5. **Verify.** For each installed server, call its `verifyCommand()`. Mark the
70
+ results.
71
+
72
+ 6. **Persist.** Update `baldart.config.yml`:
73
+ ```yaml
74
+ lsp:
75
+ installed_servers: [typescript, python]
76
+ auto_verify: true
77
+ ```
78
+
79
+ 7. **Output.** A compact one-line status, in the project's `identity.language`
80
+ from `baldart.config.yml` (English default). Matches the brevity of
81
+ `/cont` rather than its specific Italian phrasing.
82
+
83
+ ## Output Contract
84
+
85
+ A single short status block — never a multi-page report. Format:
86
+
87
+ ```
88
+ LSP bootstrap:
89
+ ✓ typescript-language-server (npm devDep, verified)
90
+ ✓ pyright (npm devDep, verified)
91
+ ⚠ gopls — run `go install golang.org/x/tools/gopls@latest`, then `baldart doctor`
92
+ · ruby — not detected (no Gemfile)
93
+ Config updated: baldart.config.yml lsp.installed_servers = [typescript, python, go]
94
+ Next: codebase-architect will now prefer LSP find-references over Grep for symbols.
95
+ ```
96
+
97
+ ## Notes
98
+
99
+ - This skill never edits source code or installs binaries that aren't language
100
+ servers — its only side effect is `npm install --save-dev <lsp-package>` and a
101
+ YAML write to `baldart.config.yml`.
102
+ - For Claude Code users: in addition to the binaries, you may need to load a
103
+ code-intelligence plugin (`/plugin` in Claude Code). That step is documented
104
+ in the printed output when applicable, but the skill does NOT manage Claude
105
+ Code plugins directly.
106
+ - Re-run safely. The skill diffs the current `lsp.installed_servers` against
107
+ recommended + verified, so additions / removals / repairs are all idempotent.
108
+
109
+ ## See Also
110
+
111
+ - `framework/agents/code-search-protocol.md` — runtime fallback rules
112
+ - `src/utils/lsp-adapters/` — per-language install/verify recipes
113
+ - `src/commands/configure.js` — same install flow when first enabling the flag
@@ -236,7 +236,7 @@ For each card, execute these phases in order:
236
236
  - If NOT `DONE` → HALT: log in `## Issues & Flags` and ask the user: "Card <CARD-ID> depends on <DEP-ID> which is `<status>`. Proceed anyway, or wait?" Do not start implementation until the user responds explicitly.
237
237
  - If `DONE` → continue.
238
238
  3. Update `${paths.references_dir}/project-status.md` Active Code Context (skip when the file does not exist in the project).
239
- 4. Invoke the **codebase-architect** agent (MUST per AGENTS.md) to understand the relevant codebase area, existing patterns, and architecture before any implementation.
239
+ 4. Invoke the **codebase-architect** agent (MUST per AGENTS.md) to understand the relevant codebase area, existing patterns, and architecture before any implementation. When `features.has_lsp_layer: true`, the architect uses LSP find-references for any identifier-shaped lookups inside the card (transitive via `agents/code-search-protocol.md`).
240
240
  4b. **Plan-auditor grounding check** — invoke the **plan-auditor** agent in QUICK mode with this prompt:
241
241
  ```
242
242
  Quick grounding check only (not a full audit). Verify this backlog card's requirements are grounded in the actual codebase.
@@ -1176,7 +1176,7 @@ After the final review passes AND all cards are committed in the worktree, deleg
1176
1176
  - The worktree path and branch from the tracker
1177
1177
  - `checksAlreadyPassed: true` (final review + QA already validated the build)
1178
1178
  - All card IDs for the commit message
1179
- 3. The skill handles: safety commit of any remaining uncommitted files (step 3), rebasing onto latest develop (step 4b — auto-resolves doc conflicts, stops on code conflicts), remote merge to develop via `gh pr merge` (step 4c — NEVER `git checkout develop` on the main repo; this respects the absolute terminal-isolation rule that many consumer projects declare in CLAUDE.md), post-merge verification, worktree removal, registry cleanup, and remote branch deletion.
1179
+ 3. The skill handles: safety commit of any remaining uncommitted files (step 3), rebasing onto latest develop (step 4b — auto-resolves doc conflicts, stops on code conflicts), merging into develop via the configured `git.merge_strategy` (step 4c — `pr` uses `gh pr merge`, `local-push` does a direct FF push to `origin/develop`; NEITHER runs `git checkout develop` on the main repo, respecting the absolute terminal-isolation rule), post-merge verification, worktree removal, registry cleanup, and remote branch deletion.
1180
1180
  4. **If code merge conflicts** → the skill STOPs and reports. Doc-only conflicts (ssot-registry.md, project-status.md, etc.) are auto-resolved by keeping both sides.
1181
1181
  5. **If post-merge build fails** → the skill STOPs and keeps the worktree intact for investigation.
1182
1182
  6. Record the merge commit hash and result in the tracker.
@@ -1245,8 +1245,8 @@ The most common failure mode is leaving cards IN_PROGRESS after merge. This crea
1245
1245
  **Why this exists**: Agents frequently skip the DONE marking in Phase 4 (step 27) due to context compaction, commit failures that interrupt the flow, or team mode where Step D.6 gets lost. This gate is the safety net that catches ALL of these cases.
1246
1246
 
1247
1247
  ### Fail-safe rules (enforced by worktree-manager skill)
1248
- - **Never `git checkout`, `git switch`, `git checkout -b`, or `git branch` on the main repo** from inside this orchestrator. The main repo is shared across parallel terminals. Use `gh pr merge` for develop merges and `git -C <main> pull --ff-only` (only when `HEAD = develop` already) for sync. See `/mw` step 4c.
1249
- - Never merge to `main` — only to `develop`, and only via `gh pr merge` (NOT local checkout).
1248
+ - **Never `git checkout`, `git switch`, `git checkout -b`, or `git branch` on the main repo** from inside this orchestrator. The main repo is shared across parallel terminals. Use the configured `git.merge_strategy` for develop merges and `git -C <main> pull --ff-only` (only when `HEAD = develop` already) for sync. See `/mw` step 4c.
1249
+ - Never merge to `main` — only to `develop`, via the configured `git.merge_strategy` (NOT local checkout).
1250
1250
  - Never force push to `main` or `develop`. `--force-with-lease` on feature branches after rebase is allowed.
1251
1251
  - Never delete a branch before successful merge verification.
1252
1252
  - Never remove a worktree before confirming develop is stable post-merge.
@@ -148,7 +148,9 @@ Before entering the discovery loop, load codebase context using the **context-pr
148
148
  2. Invoke the `Skill` tool with `skill: "context-primer"` passing the keywords
149
149
  (e.g., `args: "prize scanning scratch card wheel"`).
150
150
  3. The context-primer launches `codebase-architect` which searches RAG, docs,
151
- backlog, source code, and git history — returning a compact summary.
151
+ backlog, source code, and git history — returning a compact summary. When
152
+ `features.has_lsp_layer: true`, the symbol-lookup tier is automatically used
153
+ for identifier-shaped queries (transitive via `agents/code-search-protocol.md`).
152
154
  4. Additionally, use `search_docs` MCP tool (if available) with `mode: "hybrid"` for the feature domain
153
155
  to surface related PRDs, ADRs, and specs not covered by context-primer. The
154
156
  active retrieval layer is Obsidian-first LightRAG; use Obsidian hits for
@@ -39,6 +39,12 @@ For each new piece of code in the diff:
39
39
  1. **Start with `${paths.references_dir}/component-registry.md`** — the authoritative inventory of all UI primitives, shared components, hooks, and utility modules. Scan the relevant tables before grepping. Then search for existing utilities and helpers that could replace newly written code in the project's utility roots (e.g. `${paths.components_root}/shared/`, `${paths.components_primitives}/`, and `src/lib/`, `src/hooks/` if they exist), and files adjacent to the changed ones.
40
40
  2. **For each new component**, Grep the codebase for components with similar names, similar prop signatures, or similar JSX structure. Check for copy-pasted layout components (`layout.tsx` files with near-identical structure).
41
41
  3. **For each new function/hook**, search for functions with similar signatures or logic patterns elsewhere. Check for duplicated page-level patterns (similar data fetching, similar error boundaries, similar loading states).
42
+ When `features.has_lsp_layer: true`, run LSP `find-references` on each new exported
43
+ symbol before grepping — it tells you exactly which callsites would need to migrate
44
+ if you replaced the new code with an existing utility (textual grep over identifier
45
+ names overcounts because of collisions). See `framework/agents/code-search-protocol.md`.
46
+ Also use LSP `find-references` on candidate "existing" utilities to confirm they're
47
+ really in use and not abandoned dead code before recommending them as the canonical version.
42
48
  4. **Flag components that wrap the same underlying element** with minor style/prop differences.
43
49
 
44
50
  Classify each finding as:
@@ -14,6 +14,11 @@ description: >
14
14
 
15
15
  # Worktree Manager
16
16
 
17
+ **Project Context (resolved from `baldart.config.yml`)**:
18
+ - `git.merge_strategy` — `pr` (default, GitHub PR via `gh`) or `local-push` (direct fast-forward to `origin/develop`). Drives `/mw` step 4c.
19
+ - `paths.backlog_dir` — used for syncing untracked backlog cards (`/nw` step 3b).
20
+ - Protocol reference: `framework/agents/project-context.md`. Skills must ASK when a needed key is missing — never assume.
21
+
17
22
  **IMMEDIATE EXECUTION**: When invoked via `/nw`, `/mw`, `/lw`, or `/cw`, do NOT explain the process. Start executing the matching command flow immediately:
18
23
 
19
24
  - `/nw` → Ask for **slug** (required) and optionally a **card ID**, then execute all steps (pre-flight → create → install → build → report). If the user provided args, skip questions and use them directly. Supports three forms:
@@ -38,9 +43,13 @@ Output: `{ path: string, branch: string, port: number }`
38
43
  ### /mw programmatic
39
44
 
40
45
  Input: `{ worktreePath: string, checksAlreadyPassed?: boolean }`
41
- Output: `{ merged: boolean, developVerified: boolean, prNumber: number, mergeCommit: string }`
46
+ Output: `{ merged: boolean, developVerified: boolean, prNumber: number|null, mergeCommit: string, strategy: "pr"|"local-push" }`
47
+
48
+ The merge path depends on `git.merge_strategy` in `baldart.config.yml`:
49
+ - `pr` (default, since v3.4.0): merge via `gh pr create` + `gh pr merge`. `prNumber` is the PR number, `mergeCommit` is the SHA returned by the GitHub merge API.
50
+ - `local-push` (since v3.9.0): direct fast-forward push of the rebased feature branch to `origin/develop` — no PR, no `gh`. `prNumber` is `null`, `mergeCommit` is the local SHA of the feature branch tip.
42
51
 
43
- Note: since v3.4.0 the merge happens via `gh pr merge` against GitHub (NOT a local `git checkout develop` + `git merge`). `mergeCommit` is the SHA returned by the GitHub merge API. The orchestrator can use `prNumber` for follow-up (linking, deploy webhooks, etc.).
52
+ Neither path runs `git checkout` / `git switch` / `git branch` on the main repo. The orchestrator can branch on `strategy` if it needs PR linking (only meaningful in `pr` mode).
44
53
 
45
54
  ### /cw programmatic
46
55
 
@@ -435,16 +444,32 @@ npm run build
435
444
 
436
445
  If build fails after rebase → STOP and report. The rebase introduced incompatibilities.
437
446
 
438
- ### 4c. Remote merge via GitHub PR (NO main-repo checkout)
447
+ ### 4c. Land the feature branch onto develop (strategy-branched)
439
448
 
440
- **IMPORTANT — Remote merge only, NO local checkout/switch/branch on the main repo.** Consumer projects often share the main repo as a parallel resource across multiple terminals; running `git checkout develop` on it preempts whatever the other terminals are doing and breaks worktree-driven workflows. We therefore do the merge via the GitHub API (`gh pr create` + `gh pr merge`) — the main repo's `HEAD` is never touched.
449
+ **IMPORTANT — NO local checkout/switch/branch on the main repo, regardless of strategy.** Consumer projects share the main repo as a parallel resource across multiple terminals; running `git checkout develop` on it preempts whatever the other terminals are doing and breaks worktree-driven workflows. Both strategies below operate from the worktree and the main repo's `HEAD` is never touched.
441
450
 
442
- The previous local-merge flow caused: (a) classifier-blocked `git checkout develop` in projects with terminal-isolation rules in CLAUDE.md, (b) silent failure of the orchestrator's merge phase.
451
+ Read `git.merge_strategy` from `baldart.config.yml` (default: `pr`):
443
452
 
444
453
  ```bash
445
454
  MAIN=$(git -C "$WORKTREE_PATH" rev-parse --git-common-dir)/..
446
455
  MAIN=$(cd "$MAIN" && pwd)
447
456
 
457
+ # Resolve strategy from baldart.config.yml (default: pr)
458
+ STRATEGY=$(grep -A1 '^git:' "$MAIN/baldart.config.yml" 2>/dev/null \
459
+ | grep 'merge_strategy:' | head -1 \
460
+ | sed -E 's/.*merge_strategy:[[:space:]]*([a-z-]+).*/\1/' || echo "pr")
461
+ STRATEGY=${STRATEGY:-pr}
462
+ ```
463
+
464
+ If neither `pr` nor `local-push` resolves, ASK the user once which to use and suggest persisting the choice (per the always-ask, never-assume contract in `framework/agents/project-context.md`).
465
+
466
+ ---
467
+
468
+ #### Strategy A — `pr` (default, GitHub PR via `gh`)
469
+
470
+ Use this when `develop` is protected on origin (required status checks, reviews, merge queue) — a direct push would be rejected.
471
+
472
+ ```bash
448
473
  # 1. Push the feature branch to origin (force-with-lease in case of rebase in 4b).
449
474
  git -C "$WORKTREE_PATH" push --force-with-lease origin "$BRANCH"
450
475
 
@@ -464,10 +489,6 @@ fi
464
489
  echo "PR #$PR_NUMBER ready to merge."
465
490
 
466
491
  # 3. Merge via gh CLI. --delete-branch removes the remote branch on success.
467
- # The CLI may print a non-fatal warning if the LOCAL branch can't be deleted
468
- # (e.g. "fatal: 'develop' is already used by worktree at ..." when develop is
469
- # checked out in another worktree). The REMOTE merge happens regardless — we
470
- # swallow the local-cleanup warning.
471
492
  MERGE_OUTPUT=$(gh pr merge "$PR_NUMBER" --merge --delete-branch 2>&1) || MERGE_RC=$?
472
493
  echo "$MERGE_OUTPUT"
473
494
 
@@ -488,11 +509,63 @@ if [ "$PR_STATE" != "MERGED" ]; then
488
509
  exit 1
489
510
  fi
490
511
  echo "✅ PR #$PR_NUMBER merged to develop."
512
+ ```
513
+
514
+ If `gh` is not installed in the project, STOP and ask the user to install GitHub CLI (`brew install gh` or equivalent) and run `gh auth login`. Do NOT fall back to a local checkout — it violates terminal isolation.
515
+
516
+ If both gh CLI and REST API merge fail → STOP and report. Suggest switching to `merge_strategy: local-push` only if `develop` is NOT protected on origin.
517
+
518
+ ---
519
+
520
+ #### Strategy B — `local-push` (direct FF push, no PR)
521
+
522
+ Use this when `develop` is NOT protected on origin and the user wants to skip the GitHub PR roundtrip. After step 4b the feature branch is rebased onto `origin/develop`, so it can fast-forward `develop` on origin in a single push.
523
+
524
+ ```bash
525
+ # 1. Sanity: confirm the feature branch is strictly ahead of origin/develop
526
+ # (i.e. the rebase in step 4b succeeded and we can FF develop on origin).
527
+ git -C "$WORKTREE_PATH" fetch origin develop --quiet
528
+ AHEAD=$(git -C "$WORKTREE_PATH" rev-list --count "origin/develop..$BRANCH")
529
+ BEHIND=$(git -C "$WORKTREE_PATH" rev-list --count "$BRANCH..origin/develop")
530
+ if [ "$BEHIND" -ne 0 ]; then
531
+ echo "❌ local-push aborted: $BRANCH is $BEHIND commit(s) behind origin/develop." >&2
532
+ echo " Re-run step 4b (rebase onto origin/develop), then retry." >&2
533
+ exit 1
534
+ fi
535
+ if [ "$AHEAD" -eq 0 ]; then
536
+ echo "ℹ️ Nothing to push — $BRANCH is identical to origin/develop. Skipping."
537
+ else
538
+ echo "Fast-forwarding origin/develop by $AHEAD commit(s) via local-push…"
539
+ fi
540
+
541
+ # 2. Direct fast-forward push to develop on origin. No PR.
542
+ # If develop is protected on origin, this fails — surface the hint and stop.
543
+ if ! PUSH_OUTPUT=$(git -C "$WORKTREE_PATH" push origin "$BRANCH:develop" 2>&1); then
544
+ echo "$PUSH_OUTPUT"
545
+ if echo "$PUSH_OUTPUT" | grep -qiE "protected branch|required status|review required"; then
546
+ echo "❌ local-push rejected: 'develop' is protected on origin." >&2
547
+ echo " Switch baldart.config.yml → git.merge_strategy: pr, or remove the protection." >&2
548
+ fi
549
+ exit 1
550
+ fi
551
+ echo "✅ $BRANCH merged into develop on origin (fast-forward, no PR)."
491
552
 
492
- # 4. Sync local develop ONLY if the main repo's HEAD is already develop.
493
- # NEVER `git checkout develop` here that's the regression we're fixing.
494
- # If the user (or another terminal) had develop checked out, ff-only updates
495
- # it cleanly. Otherwise we leave their HEAD alone and they'll pull next time.
553
+ # 3. Delete the remote feature branch (best-effort never fatal).
554
+ git -C "$WORKTREE_PATH" push origin --delete "$BRANCH" 2>/dev/null || true
555
+
556
+ MERGE_SHA=$(git -C "$WORKTREE_PATH" rev-parse HEAD)
557
+ PR_NUMBER=""
558
+ ```
559
+
560
+ ---
561
+
562
+ #### Common — sync local develop ref (both strategies)
563
+
564
+ ```bash
565
+ # Sync local develop ONLY if the main repo's HEAD is already develop.
566
+ # NEVER `git checkout develop` here. If the user (or another terminal) had
567
+ # develop checked out, ff-only updates it cleanly. Otherwise we leave their
568
+ # HEAD alone and they'll pull next time.
496
569
  CURRENT_BRANCH=$(git -C "$MAIN" rev-parse --abbrev-ref HEAD 2>/dev/null || echo "")
497
570
  if [ "$CURRENT_BRANCH" = "develop" ]; then
498
571
  git -C "$MAIN" pull --ff-only origin develop || \
@@ -503,10 +576,6 @@ else
503
576
  fi
504
577
  ```
505
578
 
506
- If `gh` is not installed in the project, STOP and ask the user to install GitHub CLI (`brew install gh` or equivalent) and run `gh auth login`. Do NOT fall back to the legacy local-checkout flow — it violates terminal isolation in worktree-driven projects.
507
-
508
- If both gh CLI and REST API merge fail → STOP and report. Do NOT attempt a local checkout as fallback.
509
-
510
579
  ### 5. Post-merge verification
511
580
 
512
581
  ```bash
@@ -554,7 +623,9 @@ Remove the entry from `.worktrees/registry.json`.
554
623
  Merge complete:
555
624
  Card: <CARD-ID>
556
625
  Branch: <BRANCH> (deleted on remote; local-cleanup may have skipped if checked out elsewhere)
557
- PR: #<PR_NUMBER> merged via `gh pr merge`
626
+ Strategy: <pr | local-push>
627
+ PR: #<PR_NUMBER> merged via `gh pr merge` ← only in `pr` strategy
628
+ Push: fast-forward to origin/develop ← only in `local-push` strategy
558
629
  Worktree: <WORKTREE_PATH> (removed)
559
630
  develop: remote up to date; local main-repo synced only if HEAD was already develop
560
631
  ```
@@ -665,8 +736,8 @@ Cleanup complete:
665
736
 
666
737
  ## Safety Rules
667
738
 
668
- - **NEVER `git checkout`, `git switch`, `git checkout -b`, or `git branch` on the main repo from inside `/mw` / `/nw` / `/cw`.** The main repo is a shared resource across parallel terminals; touching its `HEAD` preempts other agents and breaks worktree-driven workflows. Many consumer projects (e.g. mayo) declare this as an absolute rule in CLAUDE.md and Claude Code's classifier will pattern-match and block these commands preemptively. Use `gh pr create` + `gh pr merge` for develop merges and `git -C <main> pull --ff-only` (only when `HEAD = develop` already) for sync. See `/mw` step 4c.
669
- - NEVER merge to `main` — only to `develop`, and only via `gh pr merge` (NOT local checkout).
739
+ - **NEVER `git checkout`, `git switch`, `git checkout -b`, or `git branch` on the main repo from inside `/mw` / `/nw` / `/cw`.** The main repo is a shared resource across parallel terminals; touching its `HEAD` preempts other agents and breaks worktree-driven workflows. Many consumer projects declare this as an absolute rule in CLAUDE.md and Claude Code's classifier will pattern-match and block these commands preemptively. Use the configured `git.merge_strategy` for develop merges and `git -C <main> pull --ff-only` (only when `HEAD = develop` already) for sync. See `/mw` step 4c.
740
+ - NEVER merge to `main` — only to `develop`, via the configured `git.merge_strategy` (`pr` → `gh pr merge`; `local-push` `git push origin <feat>:develop`). NEVER via local checkout.
670
741
  - NEVER force push from a worktree (`--force-with-lease` on the feature branch after rebase is the only allowed force variant).
671
742
  - NEVER `git add .` or `git add -A` — always explicit file names.
672
743
  - NEVER remove a worktree with uncommitted changes without explicit user confirmation.
@@ -0,0 +1,126 @@
1
+ # Code Search Protocol
2
+
3
+ ## Purpose
4
+
5
+ Define a deterministic retrieval hierarchy for agents and skills that need to
6
+ find code (identifiers, references, definitions, similar patterns) inside the
7
+ consumer repo. The goal is to filter noise **before** Claude reads files, not
8
+ after — Grep on a common function name returns thousands of textual matches and
9
+ burns context; LSP returns only the references that point to the same symbol.
10
+
11
+ ## Scope
12
+
13
+ **In**: How agents/skills should choose between RAG, LSP, Grep, and Git when
14
+ searching for code. Fallback rules when a tier is unavailable.
15
+ **Out**: Documentation search (see `agents/llm-wiki-methodology.md`), test
16
+ discovery (see `agents/testing.md`).
17
+
18
+ ## Gating
19
+
20
+ This protocol is **conditional** on `features.has_lsp_layer: true` in
21
+ `baldart.config.yml`. When the flag is `false` or missing, agents fall back to
22
+ the legacy RAG → Grep → Git flow and skip the LSP tier entirely.
23
+
24
+ Adapters for installed servers live under `src/utils/lsp-adapters/`; the
25
+ current set of servers BALDART has wired in this project is recorded at
26
+ `lsp.installed_servers` in `baldart.config.yml`.
27
+
28
+ ## Retrieval Hierarchy (in order)
29
+
30
+ 1. **RAG hybrid** — `search_docs(query, mode: "hybrid")` via the doc-rag MCP if
31
+ available. Best for free-text and conceptual queries ("how does session
32
+ token storage work").
33
+ 2. **LSP symbol search** — when the query is an identifier (function, type,
34
+ class, variable name) and `features.has_lsp_layer: true`. Use the LSP tool
35
+ (`ToolSearch("LSP")` in Claude Code) for:
36
+ - **find references**: every callsite of a symbol across the project.
37
+ - **go to definition**: the single authoritative declaration.
38
+ - **type info / hover**: signature, parameters, return type.
39
+ - **document/workspace symbols**: enumerate top-level symbols.
40
+ 3. **Grep** — for textual patterns that aren't symbols (a comment, a magic
41
+ string, a regex match, a config key, a TODO marker). Also the fallback when
42
+ LSP is unavailable or returns nothing for a symbol that clearly exists.
43
+ 4. **Git log** — `git log --oneline -20 --grep="keyword"` to find when and why
44
+ code changed. Last resort, but cheap when you suspect a regression.
45
+
46
+ ## Query-type discrimination
47
+
48
+ Before picking a tier, classify the query:
49
+
50
+ | Query shape | Start with |
51
+ |----------------------------------------|------------|
52
+ | `handleSubmit`, `UserSchema`, `useAuth`| LSP |
53
+ | `"TODO: encrypt tokens"` | Grep |
54
+ | `/api/v1/users` route handler | Grep then LSP on the handler name |
55
+ | "how is auth wired" | RAG hybrid |
56
+ | "when did we change session storage" | Git log |
57
+ | Mixed (refactor a function used in 5 places) | RAG → LSP find-references |
58
+
59
+ ## Budget
60
+
61
+ - **LSP**: up to **3 calls per task** for symbol resolution. If after 3 calls
62
+ the picture is still unclear, escalate to RAG or read the file directly —
63
+ don't keep ping-ponging through references.
64
+ - **Grep**: existing project budget (typically 15–25 calls per agent).
65
+ - **RAG / Git**: no hard budget, but verify the verdict (`rag_telemetry.verdict`
66
+ for RAG) before relying on it.
67
+
68
+ ## Fallback rules
69
+
70
+ - LSP tool not loaded / plugin missing → silently fall back to Grep with the
71
+ symbol name. Do **not** prompt the user mid-task — the missing tool is a
72
+ setup concern surfaced by `baldart doctor`.
73
+ - LSP returns zero references for a symbol you know exists → fall back to
74
+ Grep; the symbol may live in a file the LSP server hasn't indexed yet (e.g.
75
+ a path excluded by `tsconfig.json`).
76
+ - LSP times out (>8s) → fall back to Grep for this query, log the symptom in
77
+ the agent's reasoning so the user can re-run doctor.
78
+
79
+ ## Examples
80
+
81
+ ### Refactor: rename a function used across the repo
82
+
83
+ 1. RAG hybrid: confirm the function is the right one and not a name collision.
84
+ 2. LSP find-references on the symbol → exact callsite list (file + line +
85
+ column).
86
+ 3. Read each callsite, propose the rename, apply edits.
87
+
88
+ Why this beats Grep: a project with both `handleSubmit` in a form component
89
+ and `handleSubmit` in a CLI utility gets two semantically distinct sets from
90
+ LSP, but a single conflated list from Grep.
91
+
92
+ ### Bug: trace where a value originates
93
+
94
+ 1. RAG hybrid on the symptom (free text).
95
+ 2. LSP go-to-definition on the suspect variable → authoritative source.
96
+ 3. LSP find-references back from the definition → call graph upstream.
97
+ 4. Grep only if LSP cannot resolve (e.g. the value passes through a
98
+ dynamically-typed boundary).
99
+
100
+ ### Cleanup: remove a deprecated helper
101
+
102
+ 1. LSP find-references on the helper. Zero hits → safe to delete.
103
+ 2. Non-zero hits → migrate callsites first, then delete.
104
+
105
+ Skip Grep here: textual matches inside string literals or comments are not
106
+ true callsites and would falsely block the deletion.
107
+
108
+ ## When to skip LSP entirely
109
+
110
+ - Query is a phrase or comment, not a symbol.
111
+ - The project's `lsp.installed_servers` is empty for the relevant language.
112
+ - You are reading a single small file (under 200 lines) — direct Read is
113
+ cheaper than a tool call.
114
+
115
+ ## Maintenance
116
+
117
+ When adding a new language to `src/utils/lsp-adapters/`, no change is required
118
+ here unless the new language has special tooling caveats (e.g. multi-root
119
+ workspaces, monorepos). In that case, append a subsection below.
120
+
121
+ ## See also
122
+
123
+ - `framework/.claude/skills/lsp-bootstrap/SKILL.md` — install + verify flow.
124
+ - `framework/agents/project-context.md` — always-ask / never-assume contract.
125
+ - `framework/.claude/agents/codebase-architect.md` — primary consumer of this
126
+ protocol.