baldart 4.18.0 → 4.21.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.
Files changed (45) hide show
  1. package/CHANGELOG.md +47 -0
  2. package/README.md +15 -9
  3. package/VERSION +1 -1
  4. package/framework/.claude/agents/REGISTRY.md +3 -2
  5. package/framework/.claude/agents/api-perf-cost-auditor.md +2 -3
  6. package/framework/.claude/agents/code-reviewer.md +2 -2
  7. package/framework/.claude/agents/codebase-architect.md +31 -52
  8. package/framework/.claude/agents/coder.md +1 -2
  9. package/framework/.claude/agents/doc-graph-aligner.md +72 -0
  10. package/framework/.claude/agents/doc-reviewer.md +3 -39
  11. package/framework/.claude/agents/plan-auditor.md +2 -3
  12. package/framework/.claude/agents/prd-card-writer.md +1 -1
  13. package/framework/.claude/agents/qa-sentinel.md +1 -2
  14. package/framework/.claude/agents/security-reviewer.md +2 -3
  15. package/framework/.claude/agents/senior-researcher.md +2 -3
  16. package/framework/.claude/agents/wiki-curator.md +19 -74
  17. package/framework/.claude/commands/codexreview.md +5 -6
  18. package/framework/.claude/skills/bug/SKILL.md +9 -8
  19. package/framework/.claude/skills/capture/SKILL.md +12 -14
  20. package/framework/.claude/skills/context-primer/SKILL.md +21 -69
  21. package/framework/.claude/skills/graph-align/SKILL.md +80 -0
  22. package/framework/.claude/skills/graphify-bootstrap/SKILL.md +125 -0
  23. package/framework/.claude/skills/issue-review/SKILL.md +1 -1
  24. package/framework/.claude/skills/new/SKILL.md +1 -1
  25. package/framework/.claude/skills/new/references/implement.md +1 -1
  26. package/framework/.claude/skills/prd/SKILL.md +12 -11
  27. package/framework/.claude/skills/prd/references/discovery-phase.md +79 -5
  28. package/framework/.claude/skills/simplify/SKILL.md +3 -0
  29. package/framework/agents/code-graph-protocol.md +108 -0
  30. package/framework/agents/code-search-protocol.md +27 -21
  31. package/framework/agents/index.md +4 -2
  32. package/framework/agents/llm-wiki-methodology.md +42 -78
  33. package/framework/docs/CODE-GRAPH-LAYER.md +104 -0
  34. package/framework/docs/LSP-LAYER.md +6 -6
  35. package/framework/docs/MCP-INTEGRATION.md +4 -4
  36. package/framework/docs/PROJECT-CONFIGURATION.md +11 -0
  37. package/framework/routines/doc-graph-align.routine.yml +53 -0
  38. package/framework/routines/index.yml +14 -4
  39. package/framework/routines/wiki-review.routine.yml +8 -5
  40. package/framework/templates/baldart.config.template.yml +32 -5
  41. package/package.json +1 -1
  42. package/src/commands/configure.js +67 -1
  43. package/src/commands/doctor.js +91 -0
  44. package/src/commands/update.js +6 -0
  45. package/src/utils/graphify-installer.js +239 -0
@@ -10,7 +10,7 @@
10
10
  - If `DONE` (or the user chose "proceed anyway") → continue.
11
11
  2b. **Claim** — only now set the card status to `IN_PROGRESS` and assign yourself. **→ Visibility**: TaskUpdate this card's spine task → `in_progress`, and emit a Progress Bar (card change) per § "Progress Visibility".
12
12
  2c. **Trivial-card classification (BLOCKING gate for steps 3–4)** — evaluate `IS_TRIVIAL(card)` per § "Trivial-card fast-lane". Note: condition 3 (non-source diff) cannot be fully evaluated until the coder has produced the diff, so at this point compute the **provisional** trivial flag from conditions 1+2 only (`review_profile == skip` AND no Step-A trigger sourced from the card YAML text + `files_likely_touched` extensions — if EVERY path in `files_likely_touched` is non-source, condition 3 is provisionally satisfied). If provisionally trivial → **SKIP steps 3, 3a, and 4** (architecture grounding); log `trivial: architecture grounding skipped (review_profile=skip + non-source files_likely_touched + 0 triggers)` and jump to Phase 2. Re-confirm `IS_TRIVIAL` on the ACTUAL committed diff at the review gates (Phase 2.55/3.5/3.7); if the coder unexpectedly touched a source file, the guard flips the card back onto the normal review path there. If NOT provisionally trivial → run steps 3, 3a, 4 as normal.
13
- 3. **(skip when provisionally trivial — see 2c)** 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 identifier-shaped lookups — this needs NO handoff from the orchestrator: the architect reads `features.has_lsp_layer` from `baldart.config.yml` directly (the flag is ambient) per `agents/code-search-protocol.md`. The orchestrator does NOT propagate the flag. (Earlier doc versions numbered this step 4; the step that read project-status BEFORE the architect was removed because it persisted pre-analysis context — see step 3a.)
13
+ 3. **(skip when provisionally trivial — see 2c)** 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 identifier-shaped lookups — this needs NO handoff from the orchestrator: the architect reads `features.has_lsp_layer` from `baldart.config.yml` directly (the flag is ambient) per `agents/code-search-protocol.md`. Likewise, when `features.has_code_graph: true`, the architect uses the Graphify code graph for structural/relational lookups (ambient flag) per `agents/code-graph-protocol.md`. The orchestrator does NOT propagate either flag. (Earlier doc versions numbered this step 4; the step that read project-status BEFORE the architect was removed because it persisted pre-analysis context — see step 3a.)
14
14
  3a. Update `${paths.references_dir}/project-status.md` Active Code Context (skip when the file does not exist in the project) — do this AFTER the codebase-architect run (step 3) so the "Active Code Context" reflects the architect's findings (which files are actually in scope), not just the card YAML's `files_likely_touched`. Writing it before the architect run would persist pre-analysis claims that downstream agents (e.g. a parallel card) would then read as truth.
15
15
  4. **Plan-auditor grounding check** — but first, a **provenance skip (since v4.7.0 — mirror of Step 3d)**: the `/prd` Step 6.6 holistic audit already ran a per-card grounding pass when the card was authored. Re-grounding here is only worth a plan-auditor spawn if something changed since. Skip the plan-auditor when **BOTH** hold:
16
16
  - **P1 — provenance present**: the card has `metadata.holistic_audit` with non-empty `audited_at`, `audited_commit`, `audited_set`.
@@ -39,7 +39,7 @@ message. You ask questions, wait for answers, and iterate.
39
39
  | 0 | Context Recovery | [discovery-phase.md](references/discovery-phase.md) |
40
40
  | 1 | Kickoff | [discovery-phase.md](references/discovery-phase.md) |
41
41
  | 1.6 | Mockup Intake | [discovery-phase.md](references/discovery-phase.md) |
42
- | 2 | Discovery Question Loop | [discovery-phase.md](references/discovery-phase.md) |
42
+ | 2 | Discovery Question Loop (+ Codex completeness cross-check at exit, v4.19.0) | [discovery-phase.md](references/discovery-phase.md) |
43
43
  | 2→CR | Change Request (auto/manual) | the canonical **`prd-add` skill** ([../prd-add/SKILL.md](../prd-add/SKILL.md)) — worktree-aware (`references/prd-add-phase.md` is a redirect stub, not the implementation) |
44
44
  | 2.5 | Research (opzionale) | [research-phase.md](references/research-phase.md) |
45
45
  | 3 | UI Design (3a-3d) | [ui-design-phase.md](references/ui-design-phase.md) |
@@ -299,16 +299,17 @@ Before entering the discovery loop, load codebase context using the **context-pr
299
299
  1. Extract 2-4 keywords from the user's feature description.
300
300
  2. Invoke the `Skill` tool with `skill: "context-primer"` passing the keywords
301
301
  (e.g., `args: "prize scanning scratch card wheel"`).
302
- 3. The context-primer launches `codebase-architect` which searches RAG, docs,
303
- backlog, source code, and git history — returning a compact summary. When
304
- `features.has_lsp_layer: true`, the symbol-lookup tier is automatically used
305
- for identifier-shaped queries (transitive via `agents/code-search-protocol.md`).
306
- 4. Additionally, use `search_docs` MCP tool (if available) with `mode: "hybrid"` for the feature domain
307
- to surface related PRDs, ADRs, and specs not covered by context-primer. The
308
- active retrieval layer is Obsidian-first LightRAG; use Obsidian hits for
309
- concept and decision context, then verify implementation and stateful claims
310
- against repo docs/code. If MCP is unavailable, fall back to targeted
311
- canonical docs plus `rg` over `${paths.references_dir}/`, `${paths.backlog_dir}/`, and `.claude/agents/`.
302
+ 3. The context-primer launches `codebase-architect` which routes through the
303
+ canonical registry, docs, backlog, source code, and git history — returning a
304
+ compact summary. When `features.has_lsp_layer: true`, the symbol-lookup tier is
305
+ automatically used for identifier-shaped queries (transitive via
306
+ `agents/code-search-protocol.md`); when `features.has_code_graph: true`, the
307
+ architect uses the Graphify code graph for structural/relational queries
308
+ (transitive via `agents/code-graph-protocol.md`).
309
+ 4. Additionally, route through `${paths.references_dir}/ssot-registry.md` and `rg`
310
+ over `${paths.references_dir}/`, `${paths.backlog_dir}/`, and `.claude/agents/`
311
+ for the feature domain to surface related PRDs, ADRs, and specs not covered by
312
+ context-primer. Verify implementation and stateful claims against repo docs/code.
312
313
  5. Check `${paths.references_dir}/traceability-matrix.md` for source-to-doc mappings (if the project maintains one — skip when absent).
313
314
 
314
315
  The loaded context lives in conversation history and informs ALL subsequent
@@ -106,12 +106,11 @@ this is a fresh session (no existing state file).
106
106
  2-4 keywords extracted from the user's feature description and
107
107
  `task_type: "new-feature"` (always explicit — do NOT let context-primer
108
108
  default to `"query"` for domain keywords, which produces a narrower
109
- RAG-only context). context-primer internally calls `codebase-architect`
110
- which runs `search_docs mode: hybrid`, checks docs, backlog, source code,
109
+ context). context-primer internally calls `codebase-architect`
110
+ which routes through the canonical registry, checks docs, backlog, source code,
111
111
  and git history. The returned context informs all subsequent discovery
112
- dimensions. **Do NOT issue a separate `search_docs` call** — context-primer
113
- already covers it, and a second call with the same query wastes context
114
- window and doubles wiki_log telemetry entries.
112
+ dimensions. **Do NOT issue a separate redundant retrieval pass** — context-primer
113
+ already covers it, and a second pass with the same query wastes context window.
115
114
  8. Mark clearly irrelevant dimensions as "N/A" with reason
116
115
  (e.g., backend-only -> UI impact = N/A).
117
116
  If UI impact is N/A, immediately mark task 2 as `completed` ("Skipped — no UI").
@@ -928,6 +927,81 @@ appendix or extended context, not for the signal table):
928
927
  If yes, launch in foreground and process. If no, mark skipped.
929
928
  4. **No research needed** → exit normally.
930
929
 
930
+ **Before exiting, run the Discovery Completeness Cross-Check (Codex — since v4.19.0):**
931
+
932
+ This is the **final, single cross-model sweep** of discovery, run ONLY once all the
933
+ gates above pass (99% comprehension OR user-proceed, mockup gaps resolved, research
934
+ resolved) and BEFORE flipping the status to `ui-design`. Its purpose is the one thing
935
+ the 99% formula structurally cannot do: catch the questions that *should* have been
936
+ asked but weren't. The formula measures coverage of the **predefined** dimensions; a
937
+ different model reading the discovery transcript catches the **questioner's own blind
938
+ spots** — latent ambiguities, missing NFRs, unhandled error/edge paths, data lifecycle,
939
+ permission boundaries, integration touchpoints that no dimension modelled. Catching a
940
+ requirements gap HERE (pre-design) is far cheaper than at the Step 6.6d plan audit
941
+ (post-PRD, post-cards). [DESIGN-CHOICE: cross-model diversity has its highest marginal
942
+ value against the blind spots of the model that conducted the interview]
943
+
944
+ **Once-per-session guard (MUST — prevents a re-sweep loop).** The exit condition is
945
+ re-evaluated every time the loop tries to exit; addressing a surfaced gap re-enters the
946
+ question loop and then re-reaches this point. So FIRST: if the Discovery Log already
947
+ contains a `discovery-completeness:` entry (from a prior pass this session), **skip this
948
+ block entirely and proceed to exit** — the cross-check is run AT MOST ONCE per discovery
949
+ session, never re-run after its gaps have been processed. Only if no such entry exists do
950
+ you run the sweep below.
951
+
952
+ **This check is NEVER a hard block** (unlike the mockup-gap check, which gates on physical
953
+ screens). It surfaces gaps and lets the user decide; it never STOPs the exit on its own.
954
+
955
+ ```bash
956
+ SESSION_ID="${SESSION_ID:-$(date +%s%N | md5sum | head -c8)}" && \
957
+ CHECK_FILE="/tmp/codex-discovery-check-<slug>-${SESSION_ID}.md" && \
958
+ CODEX_SCRIPT="$(ls -d ~/.claude/plugins/marketplaces/openai-codex/plugins/codex/scripts/codex-companion.mjs ~/.claude/plugins/cache/openai-codex/codex/*/scripts/codex-companion.mjs 2>/dev/null | sort -V | tail -1)" && \
959
+ [ -z "$CODEX_SCRIPT" ] && echo "CODEX_NOT_FOUND" && exit 1; \
960
+ node "$CODEX_SCRIPT" task --wait "
961
+ <task>
962
+ Adversarial DISCOVERY-completeness review — a pre-design quality gate (review-only, DO NOT edit).
963
+ Claude has just finished interviewing the user to scope a feature. Your job is to find the
964
+ questions that SHOULD have been asked but were NOT, and the requirements that remain ambiguous —
965
+ the blind spots of the interviewer. Default to skepticism; assume the interview missed something.
966
+
967
+ Read the discovery state file below — it contains the dimensions, the answers, the Discovery Log,
968
+ AND the original kickoff brief in its '## Kickoff' section (everything you need is in this one file):
969
+ ${STATE_FILE_PATH}
970
+ </task>
971
+
972
+ <attack_surface>
973
+ - Unasked questions: a concern specific to THIS feature that none of the standard dimensions captured.
974
+ - Latent ambiguity: an answer marked 'covered' that is actually vague, shallow, or under-specified.
975
+ - Non-functional requirements never raised: performance budgets, scale/limits, concurrency, auth/permission boundaries, data retention/lifecycle, privacy/PII, observability.
976
+ - Missing error/edge/failure paths (the interview only covered the happy path).
977
+ - Integration touchpoints not discussed: external systems, webhooks, third-party APIs, downstream consumers.
978
+ - Conflicting or unbounded requirements ('all', 'every', no limit) accepted without a boundary.
979
+ </attack_surface>
980
+
981
+ <grounding_rules>
982
+ Every finding MUST quote the exact dimension/answer (or note its absence) from the state file.
983
+ Do not invent gaps without evidence. Prefer a few strong, high-cost gaps over many weak ones.
984
+ Suppress a finding when the strongest argument that it is already covered is convincing.
985
+ </grounding_rules>
986
+
987
+ <structured_output_contract>
988
+ For each genuine gap, one line:
989
+ - **Gap title** — what is missing/ambiguous. (Severity: HIGH/MEDIUM/LOW) [Target: <dimension or topic>]
990
+ > Evidence: exact state-file quote or 'no dimension covers X'
991
+ > Suggested question: the discovery question that closes it
992
+ End with: 'COMPLETE — no material gaps' if the discovery is genuinely sufficient.
993
+ </structured_output_contract>
994
+ " 2>&1 | tee "$CHECK_FILE"
995
+ ```
996
+
997
+ - `${STATE_FILE_PATH}` = `$WORKTREE_PATH/${paths.prd_dir}/sessions/YYYY-MM-DD-<slug>-state.md` (the single artifact Codex reads — it already embeds the kickoff brief in its `## Kickoff` section, so no separate brief file is passed). **Timeout**: `timeout: 300000` (5 min).
998
+ - **Present + process the findings (ONE pass):**
999
+ - **Presentation is ONE message** (an explicit, documented exception to HARD RULE 6's one-question-per-turn, exactly like the mockup-gap presentation): show the gaps as a single concise completeness summary, grouped by severity. This summary is a *report*, not a discovery question, so it does not violate the one-question rule.
1000
+ - For each HIGH/MEDIUM gap the user chooses to address, it becomes the **next Discovery question** and follows the **normal per-iteration flow** — asked one-per-turn (HARD RULE 6), its answer folded into the state file, and run through the **Scope Expansion Check** like any other answer (so a gap whose answer reveals new scope routes to `/prd-add` exactly as a normal answer would — no special-casing, no double-trigger). Any gap the user declines → record in the Discovery Log as `"skipped — <reason>"`. LOW gaps are advisory: log them, never block.
1001
+ - **Respect explicit user intent**: if the user reached this point by explicitly saying *proceed* / *basta domande* (the OR-branch of the 99% gate), keep the check **advisory-only** — present the one summary, default to recording every gap as `skipped — user proceeded`, and do NOT re-open the interrogation unless the user opts in. Do not turn an explicit "proceed" into a fresh question loop.
1002
+ - **After processing (whatever the outcome), write ONE `discovery-completeness:` entry to the Discovery Log** (e.g. `discovery-completeness: 2 gaps asked, 1 skipped` / `COMPLETE — no material gaps`). This entry is the once-per-session guard above — its presence means the sweep has run and MUST NOT run again this session.
1003
+ - **Fallback (Codex unavailable — `$CHECK_FILE` empty, contains `CODEX_NOT_FOUND`, or holds no parseable findings)**: **skip the cross-check** and log `discovery-completeness: SKIPPED (Codex unavailable)` in the Discovery Log (this also satisfies the once-per-session guard). This gate is **additive** — the 99% formula + mockup + research gates already gate exit. Do NOT fall back to a same-model Claude pass: the entire value here is cross-model diversity, and Claude just conducted the interview (it carries the very blind spot this check exists to catch), so a Claude self-review adds little and is not worth the spawn. Proceed to exit.
1004
+
931
1005
  When loop exits: mark task 1 as `completed`. Update state file status to
932
1006
  `ui-design` (or `specs-confirmed` if UI is N/A).
933
1007
 
@@ -55,6 +55,9 @@ For each new piece of code in the diff:
55
55
  names overcounts because of collisions). See `framework/agents/code-search-protocol.md`.
56
56
  Also use LSP `find-references` on candidate "existing" utilities to confirm they're
57
57
  really in use and not abandoned dead code before recommending them as the canonical version.
58
+ When `features.has_code_graph: true`, `graphify affected "<symbol>"` gives the same
59
+ reverse-impact set from the graph (and `graphify-out/GRAPH_REPORT.md` surfaces
60
+ duplicated god-node clusters) — see `framework/agents/code-graph-protocol.md`.
58
61
  4. **Flag components that wrap the same underlying element** with minor style/prop differences.
59
62
 
60
63
  Classify each finding as:
@@ -0,0 +1,108 @@
1
+ # Code Graph Protocol
2
+
3
+ ## Purpose
4
+
5
+ Define when and how agents/skills use the **code knowledge graph** (Graphify)
6
+ for **structural / relational** code questions — the kind Grep and even LSP
7
+ answer poorly: "what connects auth to the database", "what breaks if I change
8
+ this", "which modules form a cluster", "show the path between these two pieces".
9
+ The graph filters the codebase to the relevant *subgraph* before Claude reads
10
+ anything, the same economy principle as the LSP and (former) RAG tiers.
11
+
12
+ ## Scope
13
+
14
+ **In**: choosing the graph vs LSP vs Grep vs Git for code retrieval; the native
15
+ Graphify commands to call; fallback rules.
16
+ **Out**: single-symbol reference/definition lookups (see
17
+ `agents/code-search-protocol.md` → LSP tier); documentation synthesis (see
18
+ `agents/llm-wiki-methodology.md`).
19
+
20
+ ## Gating
21
+
22
+ Conditional on `features.has_code_graph: true` in `baldart.config.yml`. When the
23
+ flag is `false`/missing **or** the `graphify` CLI is not installed, agents **fall
24
+ back silently** to the LSP → Grep → Git hierarchy. Never block a task on the
25
+ graph being absent — surface setup gaps through `baldart doctor`
26
+ (`Code graph` line + `graph-install` / `graph-rebuild` actions), not mid-task.
27
+
28
+ Graphify is a single language-agnostic tool (tree-sitter, 28 languages,
29
+ local/offline). The graph lives at `${graph.output_dir}/graph.json` (default
30
+ `graphify-out/graph.json`); a stale graph (built from an older commit than HEAD)
31
+ is rebuilt by doctor / the native post-commit hook, not by the querying agent.
32
+
33
+ ## Composition with Graphify's native always-on mode
34
+
35
+ Graphify ships its **own** Claude/Codex integration: `graphify <platform> install`
36
+ writes a graph-first section to the tool's instruction file + a pre-tool hook
37
+ that nudges the assistant to query the graph before grepping, and a native
38
+ `/graphify` skill. **This protocol does not duplicate that** — it tells BALDART's
39
+ own agents *when* the graph is the right tier and *which* native command to run.
40
+ Prefer the native skill / MCP when present; the CLI commands below always work
41
+ post-install with no registration.
42
+
43
+ ## Retrieval hierarchy (relational queries first)
44
+
45
+ For a **structural / relational** query, the order is:
46
+
47
+ 1. **Code graph** — `graphify query`/`path`/`explain`/`affected` (or the
48
+ `graphify-mcp` MCP tools when registered). Best for multi-hop relationships,
49
+ blast-radius, clustering, "how do these connect".
50
+ 2. **LSP** — when it collapses to a single symbol's references/definition
51
+ (`features.has_lsp_layer: true`). See `agents/code-search-protocol.md`.
52
+ 3. **Grep** — textual patterns (comments, magic strings, config keys).
53
+ 4. **Git log** — when/why something changed.
54
+
55
+ For a **symbol or textual** query, skip the graph and start at LSP/Grep per the
56
+ code-search-protocol — the graph adds nothing there.
57
+
58
+ ## Native commands (all offline, 0 API cost)
59
+
60
+ Run via Bash (the CLI is on `$PATH` once installed); `--graph` defaults to
61
+ `graphify-out/graph.json`:
62
+
63
+ | Need | Command |
64
+ |------|---------|
65
+ | Free-text traversal for a question | `graphify query "how does auth reach the DB"` |
66
+ | Path between two nodes | `graphify path "LoginController" "UserRepository"` |
67
+ | Explain a node + its neighbours | `graphify explain "SessionService"` |
68
+ | Blast radius (reverse impact) | `graphify affected "computeBaseFileSha"` |
69
+ | Cluster / hub overview | read `graphify-out/GRAPH_REPORT.md` (god nodes, communities) |
70
+
71
+ `graphify query` accepts `--budget N` (token cap, default 2000) and `--dfs`.
72
+ `graphify affected` accepts `--depth N` and `--relation R`.
73
+
74
+ ## Query-type discrimination
75
+
76
+ | Query shape | Start with |
77
+ |-------------|------------|
78
+ | "what connects X to Y" / "path from X to Y" | code graph (`path`/`query`) |
79
+ | "what breaks if I change X" / impact | code graph (`affected`) |
80
+ | "which parts form a cluster / the core abstractions" | code graph (`GRAPH_REPORT.md`) |
81
+ | `handleSubmit`, `UserSchema` (single symbol refs/def) | LSP |
82
+ | `"TODO: …"`, a config key, a regex | Grep |
83
+ | "when did X change" | Git log |
84
+
85
+ ## Budget
86
+
87
+ - **Graph**: up to **3 graph commands per task** for a relational question. If
88
+ still unclear, read the specific files the graph pointed to — don't keep
89
+ traversing. `--budget` caps `query` output.
90
+ - Falls back to the existing LSP/Grep budgets when the graph is unavailable.
91
+
92
+ ## Fallback rules
93
+
94
+ - `graphify` not installed / `has_code_graph: false` → silent fallback to
95
+ LSP → Grep → Git. No prompt mid-task.
96
+ - `graph.json` missing or stale → still usable; note the staleness in reasoning
97
+ and let doctor/the hook rebuild it. Don't rebuild inline during a read task
98
+ (rebuild is a side effect owned by `doctor` / `graphify-bootstrap` / the
99
+ nightly `doc-graph-align` routine).
100
+ - A graph command errors / returns nothing → fall back to LSP/Grep for that query.
101
+
102
+ ## See also
103
+
104
+ - `framework/.claude/skills/graphify-bootstrap/SKILL.md` — install + verify + build.
105
+ - `framework/.claude/skills/graph-align/SKILL.md` — on-demand doc/graph alignment.
106
+ - `framework/agents/code-search-protocol.md` — LSP/Grep/Git hierarchy.
107
+ - `framework/agents/llm-wiki-methodology.md` — how `GRAPH_REPORT.md` feeds the wiki.
108
+ - `framework/docs/CODE-GRAPH-LAYER.md` — install lifecycle, schema, invariants.
@@ -10,7 +10,7 @@ burns context; LSP returns only the references that point to the same symbol.
10
10
 
11
11
  ## Scope
12
12
 
13
- **In**: How agents/skills should choose between RAG, LSP, Grep, and Git when
13
+ **In**: How agents/skills should choose between LSP, Grep, and Git when
14
14
  searching for code. Fallback rules when a tier is unavailable.
15
15
  **Out**: Documentation search (see `agents/llm-wiki-methodology.md`), test
16
16
  discovery (see `agents/testing.md`).
@@ -19,7 +19,7 @@ discovery (see `agents/testing.md`).
19
19
 
20
20
  This protocol is **conditional** on `features.has_lsp_layer: true` in
21
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.
22
+ the Grep → Git flow and skip the LSP tier entirely.
23
23
 
24
24
  Adapters for installed servers live under `src/utils/lsp-adapters/`; the
25
25
  current set of servers BALDART has wired in this project is recorded at
@@ -27,20 +27,27 @@ current set of servers BALDART has wired in this project is recorded at
27
27
 
28
28
  ## Retrieval Hierarchy (in order)
29
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,
30
+ 0. **Code graph (Graphify)** — when the query is **structural / relational**
31
+ ("what connects X to Y", impact/blast-radius, clusters) and
32
+ `features.has_code_graph: true`. This tier sits *above* LSP for relationship
33
+ questions only; for a single-symbol or textual query, skip it and start at
34
+ LSP/Grep below. Full contract in `agents/code-graph-protocol.md`. Falls back
35
+ silently to the tiers below when the graph is unavailable.
36
+ 1. **LSP symbol search** — when the query is an identifier (function, type,
34
37
  class, variable name) and `features.has_lsp_layer: true`. Use the LSP tool
35
38
  (`ToolSearch("LSP")` in Claude Code) for:
36
39
  - **find references**: every callsite of a symbol across the project.
37
40
  - **go to definition**: the single authoritative declaration.
38
41
  - **type info / hover**: signature, parameters, return type.
39
42
  - **document/workspace symbols**: enumerate top-level symbols.
40
- 3. **Grep** — for textual patterns that aren't symbols (a comment, a magic
43
+ 2. **Grep** — for textual patterns that aren't symbols (a comment, a magic
41
44
  string, a regex match, a config key, a TODO marker). Also the fallback when
42
45
  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
46
+ For free-text / conceptual questions ("how does session token storage
47
+ work"), start from the canonical docs router (`ssot-registry.md` →
48
+ reference docs / ADRs) and Grep over `docs/`, then read the matched
49
+ sections.
50
+ 3. **Git log** — `git log --oneline -20 --grep="keyword"` to find when and why
44
51
  code changed. Last resort, but cheap when you suspect a regression.
45
52
 
46
53
  ## Query-type discrimination
@@ -49,21 +56,21 @@ Before picking a tier, classify the query:
49
56
 
50
57
  | Query shape | Start with |
51
58
  |----------------------------------------|------------|
59
+ | "what connects X to Y" / impact / clusters | code graph (if `has_code_graph`) — see `code-graph-protocol.md` |
52
60
  | `handleSubmit`, `UserSchema`, `useAuth`| LSP |
53
61
  | `"TODO: encrypt tokens"` | Grep |
54
62
  | `/api/v1/users` route handler | Grep then LSP on the handler name |
55
- | "how is auth wired" | RAG hybrid |
63
+ | "how is auth wired" | canonical docs router + Grep over `docs/` |
56
64
  | "when did we change session storage" | Git log |
57
- | Mixed (refactor a function used in 5 places) | RAG LSP find-references |
65
+ | Mixed (refactor a function used in 5 places) | Grep to disambiguate, then LSP find-references |
58
66
 
59
67
  ## Budget
60
68
 
61
69
  - **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
70
+ the picture is still unclear, escalate to a direct file read
63
71
  don't keep ping-ponging through references.
64
72
  - **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.
73
+ - **Git**: no hard budget.
67
74
 
68
75
  ## Fallback rules
69
76
 
@@ -88,21 +95,20 @@ Before picking a tier, classify the query:
88
95
 
89
96
  ### Refactor: rename a function used across the repo
90
97
 
91
- 1. RAG hybrid: confirm the function is the right one and not a name collision.
98
+ 1. Grep to confirm the function is the right one and not a name collision.
92
99
  2. LSP find-references on the symbol → exact callsite list (file + line +
93
100
  column).
94
101
  3. Read each callsite, propose the rename, apply edits.
95
102
 
96
- Why this beats Grep: a project with both `handleSubmit` in a form component
97
- and `handleSubmit` in a CLI utility gets two semantically distinct sets from
98
- LSP, but a single conflated list from Grep.
103
+ Why this beats Grep alone: a project with both `handleSubmit` in a form
104
+ component and `handleSubmit` in a CLI utility gets two semantically distinct
105
+ sets from LSP, but a single conflated list from Grep.
99
106
 
100
107
  ### Bug: trace where a value originates
101
108
 
102
- 1. RAG hybrid on the symptom (free text).
103
- 2. LSP go-to-definition on the suspect variable authoritative source.
104
- 3. LSP find-references back from the definition call graph upstream.
105
- 4. Grep only if LSP cannot resolve (e.g. the value passes through a
109
+ 1. LSP go-to-definition on the suspect variable → authoritative source.
110
+ 2. LSP find-references back from the definitioncall graph upstream.
111
+ 3. Grep only if LSP cannot resolve (e.g. the value passes through a
106
112
  dynamically-typed boundary).
107
113
 
108
114
  ### Cleanup: remove a deprecated helper
@@ -15,6 +15,7 @@ Route agents to the right module with minimal reading.
15
15
  - **MANDATORY pre-read for any skill/agent that touches project-specific paths, identity, stack, or feature toggles** -> read `agents/project-context.md`. Skills consult `baldart.config.yml` + `.baldart/overlays/<skill>.md` instead of hard-coded paths; missing keys MUST be asked, never assumed.
16
16
  - If needing to understand codebase structure, existing patterns, or architecture before planning -> MUST invoke `codebase-architect` agent (via Task tool) first; do not proceed without architectural understanding.
17
17
  - If searching for a function/type/symbol (identifier-shaped query, not free text) and `features.has_lsp_layer: true` -> read `agents/code-search-protocol.md` and prefer LSP `find-references` / `go-to-definition` over Grep. Falls back to Grep when LSP is unavailable or the query is textual.
18
+ - If the question is STRUCTURAL / RELATIONAL (what connects X to Y, blast-radius/impact, clusters) and `features.has_code_graph: true` -> read `agents/code-graph-protocol.md` and prefer the Graphify code graph (`graphify query`/`path`/`explain`/`affected`) over LSP/Grep. Falls back silently to LSP -> Grep -> Git when the graph is unavailable.
18
19
  - If touching API endpoints or request/response shape -> read `agents/api-contracts.md` and `${paths.references_dir}/api/index.md` (then specific API module for your domain).
19
20
  - If touching database schema or fields -> read `agents/data-model.md` and `${paths.references_dir}/data-model.md`.
20
21
  - If touching UI pages/routes or flows -> read `${paths.references_dir}/ui/index.md` (then specific UI module for your domain).
@@ -59,9 +60,10 @@ When adding or updating agents, update REGISTRY.md — not this file.
59
60
  - `agents/github-issue-subagent.md`
60
61
  - `agents/design-review.md`
61
62
  - `agents/skills-mapping.md`
62
- - `agents/llm-wiki-methodology.md` — LLM wiki overlay methodology + auto-learning loop (since v2.0.0)
63
+ - `agents/llm-wiki-methodology.md` — LLM wiki overlay methodology (manual + scheduled maintenance; since v2.0.0)
63
64
  - `agents/project-context.md` — Project context protocol: `baldart.config.yml` + overlays + missing-key handling (since v3.0.0)
64
- - `agents/code-search-protocol.md` — Retrieval hierarchy for code search: RAG → LSP → Grep → Git (since v3.10.0, gated on `features.has_lsp_layer`)
65
+ - `agents/code-search-protocol.md` — Retrieval hierarchy for code search: LSP → Grep → Git (since v3.10.0, gated on `features.has_lsp_layer`)
66
+ - `agents/code-graph-protocol.md` — Structural/relational retrieval via the Graphify code knowledge graph (since v4.21.0, gated on `features.has_code_graph`)
65
67
  - `agents/design-system-protocol.md` — Registry-first discipline for UI work: BLOCKING cascade on `INDEX.md` + `tokens-reference.md` + `components/<Name>.md` (since v3.11.0, gated on `features.has_design_system`)
66
68
 
67
69
  ## Where to Document (Decision Tree)
@@ -8,9 +8,9 @@ layer of compiled pages (concepts, syntheses, dashboards, reading guides) that
8
8
  makes retrieval cheaper and reasoning more stable, **without ever becoming
9
9
  source-of-truth**.
10
10
 
11
- This module describes the contract, file layout, lifecycle, and auto-learning
12
- loop. The agent that maintains the overlay is `wiki-curator`. The skill that
13
- captures synthesis pages from live conversations is `/capture`.
11
+ This module describes the contract, file layout, and lifecycle of the overlay.
12
+ The agent that maintains it is `wiki-curator`. The skill that captures synthesis
13
+ pages from live conversations is `/capture`.
14
14
 
15
15
  ## Layered Knowledge Stack
16
16
 
@@ -20,7 +20,6 @@ The wiki overlay sits on top of an existing retrieval stack. A typical layout:
20
20
  |-------|------|-----------|
21
21
  | Canonical SSOT (`${paths.references_dir}/**`, `${paths.adrs_dir}/**`, code itself) | Source of truth | **Canonical** — never override from below |
22
22
  | External human knowledge (Obsidian vault, Notion, Confluence) | Human-readable narrative; optional | Mirrors canonical with extra context |
23
- | RAG / search layer (e.g. LightRAG, vector DB, full-text index) | Recall + cross-document discovery | Operational, not canonical |
24
23
  | **Wiki overlay** (`${paths.wiki_dir}/**`) | Compiled, navigable, stable | **Derived** — always cites canonical refs |
25
24
 
26
25
  Rules:
@@ -29,9 +28,6 @@ Rules:
29
28
  2. SSOT changes propagate down; wiki pages must be recompiled when canonicals
30
29
  change.
31
30
  3. If a wiki page conflicts with SSOT, SSOT wins and the wiki page is rewritten.
32
- 4. The RAG layer is fed both canonicals and wiki pages, but query verdicts
33
- reveal **gaps** in the canonical layer, which become candidates for new
34
- wiki syntheses (see § Auto-Learning Loop).
35
31
 
36
32
  ## Page Types
37
33
 
@@ -45,8 +41,8 @@ A complete overlay typically contains five page types:
45
41
  | **Reading Guide** | `${paths.wiki_dir}/reading-guides/` | Ordered paths into the corpus for specific tasks (onboarding, incident response) |
46
42
  | **Index** | `${paths.wiki_dir}/index.md` | Single navigation entry point listing the other pages |
47
43
 
48
- The `${paths.wiki_dir}/log.md` file is the **append-only event log** used by the
49
- auto-learning loop (see below).
44
+ The `${paths.wiki_dir}/log.md` file is an **append-only event log** recording
45
+ synthesis candidates and captures (see § Maintenance & Capture).
50
46
 
51
47
  ## Frontmatter Discipline (MANDATORY)
52
48
 
@@ -86,61 +82,10 @@ equivalent) before committing wiki edits.
86
82
  - The `wiki-curator` agent flags `WIKI_ANCHOR_BROKEN` on mismatch and fixes
87
83
  it in the same invocation when possible.
88
84
 
89
- ## Auto-Learning Loop (the core idea)
85
+ ## Maintenance & Capture
90
86
 
91
- The overlay is not static. It feeds itself from agent activity, closing a loop
92
- that surfaces documentation gaps and turns them into stable pages.
93
-
94
- ```
95
- ┌──────────────┐
96
- │ Agents query │
97
- │ RAG / search │
98
- └──────┬───────┘
99
- │ (instrumented: every search_docs call tags the invoker)
100
-
101
- ┌──────────────┐
102
- │ Telemetry log│ (${paths.wiki_dir}/log.md — append-only)
103
- └──────┬───────┘
104
- │ (verdicts: useful | weak | empty | fallback_degraded)
105
-
106
- ┌────────────────────────────┐
107
- │ Nightly wiki-review job │
108
- │ runs `wiki-curator` agent │
109
- └──────┬─────────────────────┘
110
- │ (proposes synthesis candidates from weak/empty verdicts)
111
-
112
- ┌────────────────────────────┐
113
- │ /capture skill writes │
114
- │ a new synthesis page after │
115
- │ user approval │
116
- └──────┬─────────────────────┘
117
-
118
-
119
- New wiki page → next RAG query gets a strong verdict.
120
- ```
121
-
122
- ### Tap points (instrumentation)
123
-
124
- Every agent that queries the RAG layer MUST pass an `invoker_agent` tag on its
125
- search calls, so telemetry attributes the query to the right agent. After each
126
- call, the agent inspects the telemetry verdict and — if it is `weak`, `empty`,
127
- or `fallback_degraded` — appends one entry to `${paths.wiki_dir}/log.md` via the
128
- project's log helper (e.g. `tools/<rag-impl>/wiki_log.py`).
129
-
130
- ```python
131
- from wiki_log import append_entry # project-specific helper
132
- append_entry(
133
- entry_type="query",
134
- title=<query_short>,
135
- agent=<invoker>,
136
- context={"verdict": verdict, "top_score": top_score, "count": count},
137
- refs=[],
138
- outcome=verdict,
139
- )
140
- ```
141
-
142
- **Graceful degrade**: if the helper fails or is missing, emit one stderr line
143
- and continue. Telemetry must never block real work.
87
+ The overlay is maintained on two paths a scheduled structural sweep and an
88
+ on-demand capture from live conversations.
144
89
 
145
90
  ### Synthesis candidates (nightly review)
146
91
 
@@ -151,8 +96,12 @@ The `wiki-curator` agent, running on a schedule (typically nightly), scans:
151
96
  contract) → propose a synthesis page.
152
97
  - PRD-led multi-card epics (≥4 cards in same parent epic) → propose an
153
98
  overview synthesis.
154
- - RAG queries with `verdict=weak|empty` repeated ≥3 times in
155
- `${paths.wiki_dir}/log.md` the topic is a documentation gap, propose synthesis.
99
+ - **(when `features.has_code_graph: true`)** Graphify's native
100
+ `${graph.output_dir}/GRAPH_REPORT.md` **god nodes** (highest-degree core
101
+ abstractions), **communities** (Leiden clusters), and the auto-generated
102
+ **suggested questions** — cross-checked against existing synthesis pages.
103
+ A god node or community with no corresponding wiki page → propose a synthesis
104
+ (this is the auto-learning signal, replacing the removed RAG verdicts).
156
105
 
157
106
  Candidates are appended to `${paths.wiki_dir}/log.md` with
158
107
  `entry_type: synthesis_candidate` and a small payload (title, source refs,
@@ -175,12 +124,32 @@ disable with a kill-switch file (`touch .claude/capture-queue/.disabled`).
175
124
  The skill requires explicit user approval before writing. Acceptance and
176
125
  rejection are both logged.
177
126
 
178
- ## Graph Community Synthesis (optional, advanced)
127
+ ### Auto-learning loop (Graphify-fed, when `has_code_graph: true`)
128
+
129
+ The original RAG-fed loop (weak/empty search verdicts → gap → synthesis) was
130
+ removed in v4.20.0. It is now **re-activated on the code graph** (v4.21.0): the
131
+ gap signal is structural, not retrieval-telemetry, and entirely **offline**
132
+ (no API cost).
133
+
134
+ ```
135
+ graphify update . (native, on commit via `graphify hook install`)
136
+
137
+
138
+ graphify-out/GRAPH_REPORT.md (god nodes · Leiden communities · suggested questions)
139
+ │ (cross-check vs ${paths.wiki_dir}/syntheses/*)
140
+
141
+ wiki-curator / doc-graph-align → propose synthesis for uncovered god nodes/communities
142
+
143
+
144
+ /capture writes the page → next graph review finds it covered
145
+ ```
179
146
 
180
- If the project's RAG layer ships a community-detection layer (e.g.
181
- Leiden/Louvain) on top of the entity graph, cluster summaries can be produced
182
- weekly and exposed via dedicated MCP tools. These cluster summaries are
183
- candidate inputs to `concept` pages.
147
+ The graph never becomes canonical synthesis pages still cite repo SSOT and the
148
+ `canonicality: derived` contract holds. When `has_code_graph: false` or Graphify
149
+ is absent, the loop is simply inactive and the overlay runs on the manual +
150
+ ADR/PRD-scheduled paths above (no regression). Engine details:
151
+ `docs/archive/rag-layer/rebind-to-graphify.md` and
152
+ `framework/agents/code-graph-protocol.md`.
184
153
 
185
154
  ## Roles & Responsibilities
186
155
 
@@ -198,15 +167,10 @@ To install the LLM wiki overlay in a new project:
198
167
  1. Create `${paths.wiki_dir}/` with the five page-type folders and an `index.md`.
199
168
  2. Add the frontmatter validator (or adapt your existing one) to check
200
169
  wiki frontmatter compliance.
201
- 3. Decide on a RAG layer (LightRAG, vector DB, or full-text). If using one,
202
- instrument every `search_docs` call with `invoker_agent` and a `wiki_log`
203
- append helper.
204
- 4. Schedule the `wiki-curator` agent to run on a nightly cadence
170
+ 3. Schedule the `wiki-curator` agent to run on a nightly cadence
205
171
  (cron / Claude Code remote agent / GitHub Action).
206
- 5. Enable the `/capture` skill for users and (optionally) the proactive hook.
207
- 6. Add `${paths.wiki_dir}/log.md` as an append-only log file under version control,
208
- with rotation rules if it grows large.
209
- 7. Document the overlay in your repo README so contributors know it exists
172
+ 4. Enable the `/capture` skill for users and (optionally) the proactive hook.
173
+ 5. Document the overlay in your repo README so contributors know it exists
210
174
  and is non-canonical.
211
175
 
212
176
  ## Related