baldart 5.0.1 → 5.1.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 (32) hide show
  1. package/CHANGELOG.md +80 -0
  2. package/README.md +3 -3
  3. package/VERSION +1 -1
  4. package/framework/.claude/agents/CHANGELOG.md +45 -0
  5. package/framework/.claude/agents/REGISTRY.md +3 -3
  6. package/framework/.claude/agents/senior-researcher.md +166 -151
  7. package/framework/.claude/skills/prd/CHANGELOG.md +16 -0
  8. package/framework/.claude/skills/prd/SKILL.md +1 -1
  9. package/framework/.claude/skills/prd/references/discovery-phase.md +5 -1
  10. package/framework/.claude/skills/prd/references/research-phase.md +32 -12
  11. package/framework/.claude/skills/research/CHANGELOG.md +9 -0
  12. package/framework/.claude/skills/research/SKILL.md +94 -0
  13. package/framework/.claude/skills/research/assets/report-compare.template.md +50 -0
  14. package/framework/.claude/skills/research/assets/report-decision.template.md +42 -0
  15. package/framework/.claude/skills/research/assets/report-deep.template.md +61 -0
  16. package/framework/.claude/skills/research/assets/report-regulatory.template.md +44 -0
  17. package/framework/.claude/skills/research/references/playbook.md +112 -0
  18. package/framework/.claude/skills/research/scripts/rebuild-research-index.mjs +77 -0
  19. package/framework/agents/index.md +2 -0
  20. package/framework/agents/research-protocol.md +228 -0
  21. package/framework/agents/skills-mapping.md +17 -0
  22. package/framework/docs/PROJECT-CONFIGURATION.md +23 -0
  23. package/framework/templates/baldart.config.template.yml +6 -0
  24. package/framework/templates/research-index.template.md +13 -0
  25. package/framework/templates/research-sources.CHANGELOG.md +14 -0
  26. package/framework/templates/research-sources.template.md +31 -0
  27. package/package.json +1 -1
  28. package/src/commands/configure.js +26 -0
  29. package/src/commands/doctor.js +82 -0
  30. package/src/commands/update.js +48 -1
  31. package/src/utils/research-library.js +92 -0
  32. package/src/utils/symlinks.js +3 -0
@@ -78,12 +78,26 @@ Trigger as soon as confidence is HIGH (typically at ~75% comprehension).
78
78
  > `BACKGROUND_RUN=true` directive so the agent knows to begin research
79
79
  > immediately. Add this as the first line of the prompt.
80
80
 
81
+ > **Profile + output path (v5.1.0)**: the researcher runs `PROFILE=decision`
82
+ > (`PROFILE=regulatory` when signal S2 matched) — the per-topic,
83
+ > recommendation-first contract of `agents/research-protocol.md
84
+ > SECTION=profiles`, which matches "Processing Findings" below byte-for-byte.
85
+ > /prd PRE-ALLOCATES the exact output path so the exit-check poll stays
86
+ > deterministic: when `paths.research_dir` is set, the report lands in the
87
+ > research library — `${paths.research_dir}/<category>/RES-<YYYYMMDD>-<slug>.md`
88
+ > (pick the closest category: architecture | integrations | regulatory |
89
+ > ux-patterns | algorithms | tooling); when the key is missing/empty
90
+ > (consumer not yet reconfigured post-update), fall back to the legacy path
91
+ > `${paths.prd_dir}/<slug>/research-<slug>-<session-id>.md`. Either way the
92
+ > prompt carries ONE known path.
93
+
81
94
  ```
82
95
  Task tool:
83
96
  subagent_type: "senior-researcher"
84
97
  run_in_background: true
85
98
  prompt: |
86
99
  BACKGROUND_RUN=true — skip the FIRST MESSAGE TEMPLATE preamble entirely.
100
+ PROFILE=decision (use PROFILE=regulatory when launched off signal S2)
87
101
  Begin research immediately without waiting for acknowledgment.
88
102
 
89
103
  Research the following topics for a PRD we're writing for feature
@@ -99,20 +113,16 @@ Trigger as soon as confidence is HIGH (typically at ~75% comprehension).
99
113
  1. <question>
100
114
  2. <question>
101
115
 
102
- For each topic, provide:
103
- - Summary of best practices (with sources)
104
- - Recommended approach for the project stack above
105
- - Key gotchas or anti-patterns to avoid
106
- - If applicable: regulatory checklist or compliance requirements
107
-
108
116
  OUTPUT CONTRACT (mandatory):
109
117
  Write your complete research report to the file:
110
- ${paths.prd_dir}/<slug>/research-<slug>-<session-id>.md
111
- where <session-id> is a short UUID you generate at start.
112
- Log the exact output path as the FIRST line of your report:
118
+ <pre-allocated path — library path, or the prd_dir fallback above>
119
+ Log the exact output path as the FIRST line of the report body
120
+ (right after the frontmatter):
113
121
  RESEARCH_OUTPUT_PATH: <full path>
114
- This path is how the PRD orchestrator will read your findings.
115
- Be concise but thorough.
122
+ ALWAYS write a file at that path on FULL_REUSE, write the pointer
123
+ stub defined in agents/research-protocol.md SECTION=reuse instead of
124
+ a new report. This path is how the PRD orchestrator will read your
125
+ findings. Be concise but thorough.
116
126
  ```
117
127
 
118
128
  3. **Continue discovery** — do NOT wait for the researcher. Ask remaining
@@ -200,6 +210,11 @@ Questo aggiunge qualche minuto ma produce decisioni piu informate.
200
210
 
201
211
  When `senior-researcher` returns:
202
212
 
213
+ 0. **Reuse stub?** If the file at the pre-allocated path is a `FULL_REUSE`
214
+ pointer stub (`REUSE: FULL_REUSE -> <path>`), read the pointed report —
215
+ the library already had this research, treat it as an instant completion.
216
+ A `DELTA` report reads normally (it IS the updated research).
217
+
203
218
  1. **Store findings** in state file under `## Research Findings`:
204
219
  ```
205
220
  ## Research Findings
@@ -208,15 +223,20 @@ When `senior-researcher` returns:
208
223
  Topics researched: [list]
209
224
 
210
225
  ### Topic 1: <title>
226
+ **Recommended approach**: <for our stack — the report's recommendation line>
211
227
  **Best practice**: <summary>
212
- **Recommended approach**: <for our stack>
213
228
  **Gotchas**: <anti-patterns to avoid>
229
+ **Contradictions & Unknowns**: <where evidence disagrees or is missing — or "none">
214
230
  **Sources**: <references>
215
231
 
216
232
  ### Topic 2: <title>
217
233
  ...
218
234
  ```
219
235
 
236
+ (mirrors the `decision`-profile report structure — recommendation first,
237
+ contradictions never dropped: they are the findings that change a design
238
+ direction.)
239
+
220
240
  2. **Evaluate if findings reveal gaps** in the discovery:
221
241
  - Do the findings introduce new dimensions or considerations NOT covered
222
242
  by existing discovery answers?
@@ -0,0 +1,9 @@
1
+ # Changelog — research skill
2
+
3
+ ## 1.0.0 — 2026-07-03 (framework v5.1.0)
4
+
5
+ - Initial release. Interactive orchestrator over the research library:
6
+ scoping → profile/nature routing → reuse pre-flight → senior-researcher
7
+ launch (parallel fan-out on Claude, sequential on Codex) → filing +
8
+ INDEX ownership → source-matrix growth loop. THIN — all rules live in
9
+ `agents/research-protocol.md`, all report forms in `assets/`.
@@ -0,0 +1,94 @@
1
+ ---
2
+ name: research
3
+ effort: medium
4
+ version: 1.0.0
5
+ description: >
6
+ Interactive research orchestrator over the research library. Scopes the
7
+ question with the user, routes it to the right profile (decision / deep /
8
+ compare / regulatory) and source policy by research NATURE (scientific →
9
+ papers; dev → docs+forums; regulatory → normative texts; ux; market), checks
10
+ the library INDEX for reusable prior research BEFORE searching, then launches
11
+ the senior-researcher agent (parallel fan-out for composite questions), files
12
+ the report in ${paths.research_dir} and keeps INDEX.md correct. Closes the
13
+ source-matrix growth loop (SOURCE_MATRIX_CANDIDATE → local SOURCES.md and/or
14
+ upstream BALDART prompt). A THIN orchestrator — cites
15
+ agents/research-protocol.md for every rule, never duplicates it. Use when the
16
+ user says /research, "fai una ricerca", "ricerca best practice", "confronta X
17
+ e Y", "ricerca scientifica su", "è già stato ricercato?", "cosa dice la
18
+ letteratura su". NOT for /prd's embedded research step (prd spawns the agent
19
+ directly) and NOT a replacement for the agent (which stays directly
20
+ spawnable).
21
+ ---
22
+
23
+ # Research — orchestrated research over the library
24
+
25
+ ## Project Context
26
+
27
+ **Reads from baldart.config.yml:** `paths.research_dir` (the library),
28
+ `paths.docs_dir` (degrade target), `stack.*` (stack signature for the
29
+ recommendation binding).
30
+ **Writes:** research reports + INDEX rows under `${paths.research_dir}`;
31
+ optionally `SOURCES.md` `## Local additions`.
32
+ **Gated by features:** none — research is universal.
33
+ **On missing/empty keys:** `paths.research_dir` empty/absent → offer
34
+ `npx baldart configure` (or ask for a path and suggest persisting it); the
35
+ user may decline and run library-less (reports go to `${paths.docs_dir}/`,
36
+ no reuse pre-flight). Never hard-abort.
37
+ Protocol: `framework/agents/project-context.md`.
38
+
39
+ ## Effort
40
+
41
+ **Baseline:** `effort: medium` (frontmatter). **Inline override:** pass
42
+ `effort=<low|medium|high|xhigh|max>` anywhere in the invocation to scale
43
+ reasoning depth for this run — detect it once at kickoff and strip the token
44
+ before consuming user input. Level→behavior mapping, parsing contract, and
45
+ precedence caveats: `framework/agents/effort-protocol.md`.
46
+
47
+ ## Invocation
48
+
49
+ ```
50
+ /research <topic> # scoping → routed research
51
+ /research PROFILE=<decision|deep|compare|regulatory> <topic>
52
+ /research DEPTH=<1..3> <topic> # deep-profile iterative loop
53
+ /research status # library health: INDEX + expiring reports
54
+ ```
55
+
56
+ ## Flow
57
+
58
+ THIN orchestration — every rule below is DEFINED in
59
+ `agents/research-protocol.md` (read the cited SECTION only) and every output
60
+ FORM in `assets/`; this skill only sequences them. Full step-by-step detail,
61
+ scoping questions and recovery: `references/playbook.md`.
62
+
63
+ 1. **Scoping** — clarify question, research nature and purpose with the user
64
+ (max 3 questions via AskUserQuestion; ZERO when the request is already
65
+ specific). Build the stack signature from `stack.*`.
66
+ 2. **Routing** — purpose → `PROFILE=` (`SECTION=profiles`); nature → source
67
+ policy row (`SECTION=sources`). State the routing in one line before
68
+ launching.
69
+ 3. **Reuse check** — read `${paths.research_dir}/INDEX.md`, match per
70
+ `SECTION=reuse`. On a hit, present FULL_REUSE / DELTA to the user before
71
+ any new research is paid for.
72
+ 4. **Launch** — pre-allocate id + output path (`SECTION=library`) and spawn
73
+ `senior-researcher` with `PROFILE=` (+ `DEPTH=` if given), the stack
74
+ signature, the pre-allocated path, and `FILING=orchestrator` (this skill
75
+ owns the INDEX rows). Composite questions (2+ independent sub-questions) →
76
+ parallel fan-out, one spawn per sub-question, each with its own
77
+ pre-allocated path. **Codex**: no parallel subagent fan-out — spawn
78
+ sequentially by name (`agents/runtime-portability-protocol.md`).
79
+ 5. **Filing** — verify each report exists at its pre-allocated path with valid
80
+ frontmatter; append the INDEX rows (serialized, one writer: this skill).
81
+ On any mismatch run `scripts/rebuild-research-index.mjs` to reconcile.
82
+ 6. **Matrix loop** — if a report contains `## SOURCE_MATRIX_CANDIDATE`
83
+ (`SECTION=sources`), offer both: (a) apply it now to
84
+ `${paths.research_dir}/SOURCES.md` under `## Local additions`; (b) show the
85
+ ready-to-paste BALDART prompt for upstreaming the change to the framework
86
+ default matrix.
87
+ 7. **Return** — recommendation headline + `Report: <path>` (+ reuse decision,
88
+ + matrix candidate note). The report body stays on disk.
89
+
90
+ ## `/research status`
91
+
92
+ Read INDEX.md only: report totals per category, reports past `valid_until`
93
+ (refresh candidates → offer a DELTA run), and any INDEX↔frontmatter drift
94
+ (offer `scripts/rebuild-research-index.mjs`).
@@ -0,0 +1,50 @@
1
+ ---
2
+ id: RES-YYYYMMDD-slug
3
+ title: ""
4
+ category: tooling
5
+ tags: []
6
+ profile: compare
7
+ nature: market
8
+ stack_signature: ""
9
+ date: YYYY-MM-DD
10
+ valid_until: YYYY-MM-DD
11
+ status: current
12
+ questions: []
13
+ sources_count: 0
14
+ related: []
15
+ ---
16
+
17
+ RESEARCH_OUTPUT_PATH: <this file's path>
18
+ REUSE: NEW | DELTA -> <prior report path> <!-- a FULL_REUSE run writes the pointer stub (SECTION=reuse), not this template -->
19
+
20
+ # <Title> — <Option A> vs <Option B> [vs <Option C>]
21
+
22
+ ## Recommendation
23
+
24
+ <one decisive paragraph, bound to the stack signature; name the runner-up and when it wins instead>
25
+
26
+ ## Comparison matrix
27
+
28
+ <!-- Fixed axes; keep ≤ 8 columns — split rows, not columns, when options exceed the width. -->
29
+
30
+ | Axis | <Option A> | <Option B> | <Option C> |
31
+ |---|---|---|---|
32
+ | Performance | | | |
33
+ | Cost | | | |
34
+ | Complexity | | | |
35
+ | Risk | | | |
36
+ | Maturity | | | |
37
+ | Adoption | | | |
38
+
39
+ <!-- Every non-obvious cell claim carries a citation + evidence label. -->
40
+
41
+ ## When NOT to use
42
+
43
+ - **<Option A>**: <disqualifying conditions>
44
+ - **<Option B>**: …
45
+
46
+ ## Contradictions & Unknowns
47
+
48
+ ## Sources
49
+
50
+ - [Source Year] <title> — <url> (<date>) [evidence label]
@@ -0,0 +1,42 @@
1
+ ---
2
+ id: RES-YYYYMMDD-slug
3
+ title: ""
4
+ category: architecture # architecture|integrations|regulatory|ux-patterns|algorithms|tooling
5
+ tags: []
6
+ profile: decision
7
+ nature: dev # scientific|dev|regulatory|ux|market
8
+ stack_signature: ""
9
+ date: YYYY-MM-DD
10
+ valid_until: YYYY-MM-DD # date + category TTL (research-protocol.md SECTION=reuse)
11
+ status: current
12
+ questions: []
13
+ sources_count: 0
14
+ related: []
15
+ ---
16
+
17
+ RESEARCH_OUTPUT_PATH: <this file's path>
18
+ REUSE: NEW | DELTA -> <prior report path> <!-- a FULL_REUSE run writes the pointer stub (SECTION=reuse), not this template -->
19
+
20
+ # <Title>
21
+
22
+ <!-- One block per research question. Recommendation FIRST — the reader is
23
+ mid-decision; everything else is supporting material. -->
24
+
25
+ ## Topic 1: <question>
26
+
27
+ **Recommendation (for this stack):** <one decisive paragraph — what to do and why, bound to the stack signature>
28
+
29
+ **Best practices:**
30
+ - <practice> [Source Year] [STRONG|MODERATE|WEAK|OPINION]
31
+
32
+ **Gotchas / anti-patterns:**
33
+ - <gotcha and its cost> [Source Year]
34
+
35
+ **Contradictions & Unknowns:** <!-- MANDATORY, even when empty: say "None found — evidence is consistent." -->
36
+ - <where evidence disagrees or is missing, and what would resolve it>
37
+
38
+ **Sources:**
39
+ - [Source Year] <title> — <url> (<date>) [evidence label]
40
+
41
+ ## Topic 2: <question>
42
+
@@ -0,0 +1,61 @@
1
+ ---
2
+ id: RES-YYYYMMDD-slug
3
+ title: ""
4
+ category: architecture
5
+ tags: []
6
+ profile: deep
7
+ nature: scientific
8
+ stack_signature: ""
9
+ date: YYYY-MM-DD
10
+ valid_until: YYYY-MM-DD
11
+ status: current
12
+ questions: []
13
+ sources_count: 0
14
+ related: []
15
+ ---
16
+
17
+ RESEARCH_OUTPUT_PATH: <this file's path>
18
+ REUSE: NEW | DELTA -> <prior report path> <!-- a FULL_REUSE run writes the pointer stub (SECTION=reuse), not this template -->
19
+
20
+ # <Title>
21
+
22
+ <!-- Full §0–§11 contract — VERBATIM in senior-researcher.md § OUTPUT.
23
+ Every section opens with a 2–5 bullet Key Takeaways block. -->
24
+
25
+ ## §0 Retrieval Index
26
+ <keyword> → §N.M …
27
+
28
+ ## §1 Table of Contents
29
+
30
+ ## §2 Executive Summary
31
+ <!-- 10–20 bullets covering the entire report -->
32
+
33
+ ## §3 Problem Framing and Scope
34
+
35
+ ## §4 Research Landscape / Taxonomy
36
+ <!-- structured by approach, not by time -->
37
+
38
+ ## §5 Comparative Analysis
39
+ <!-- consistent axes: performance, cost, complexity, risk, robustness, maturity, adoption -->
40
+
41
+ ## §6 Key Findings
42
+ <!-- claims + citations + evidence labels -->
43
+
44
+ ## §7 Recommendation
45
+ <!-- one primary path + 1–2 alternatives, rationale, "when not to use" -->
46
+
47
+ ## §8 Risks & Limitations
48
+ <!-- gaps, conflicting evidence, unknowns -->
49
+
50
+ ## §9 Evidence Map
51
+ <!-- claim → sources → section IDs -->
52
+
53
+ ## §10 Annotated Bibliography
54
+ <!-- links/DOIs/arXiv IDs, dated, evidence-labeled -->
55
+
56
+ ## §11 Appendix
57
+ ### Search Log
58
+ | query | date/context | rationale | chosen (why) | rejected (why) |
59
+ |---|---|---|---|---|
60
+ ### Structured Reading Notes
61
+ ### Glossary
@@ -0,0 +1,44 @@
1
+ ---
2
+ id: RES-YYYYMMDD-slug
3
+ title: ""
4
+ category: regulatory
5
+ tags: []
6
+ profile: regulatory
7
+ nature: regulatory
8
+ stack_signature: ""
9
+ date: YYYY-MM-DD
10
+ valid_until: YYYY-MM-DD # regulatory TTL is SHORT (6 months) — rules move
11
+ status: current
12
+ questions: []
13
+ sources_count: 0
14
+ related: []
15
+ ---
16
+
17
+ RESEARCH_OUTPUT_PATH: <this file's path>
18
+ REUSE: NEW | DELTA -> <prior report path> <!-- a FULL_REUSE run writes the pointer stub (SECTION=reuse), not this template -->
19
+
20
+ # <Title>
21
+
22
+ **Jurisdiction(s):** <named explicitly — a regulatory report without one is invalid>
23
+
24
+ ## Summary & applicability
25
+
26
+ <does this regime apply to the project at all, and through which activities>
27
+
28
+ ## Obligation checklist
29
+
30
+ <!-- Obligations cite the PRIMARY legal text; implementation notes may cite secondary. -->
31
+
32
+ | # | Requirement | Source (primary) | Deadline / threshold | Implementation note |
33
+ |---|---|---|---|---|
34
+ | 1 | | [Reg Art. N] | | |
35
+
36
+ ## Sanctions & risk
37
+
38
+ ## Contradictions & Unknowns
39
+
40
+ <!-- diverging regulator guidance, pending rulings, transition periods -->
41
+
42
+ ## Sources
43
+
44
+ - [Source Year] <official title> — <url> (<date>) [STRONG]
@@ -0,0 +1,112 @@
1
+ # Research playbook — step-by-step detail
2
+
3
+ Companion to `SKILL.md`. Rules live in `agents/research-protocol.md` (cited by
4
+ SECTION); this playbook covers execution mechanics only.
5
+
6
+ ## 1. Scoping
7
+
8
+ Goal: a research brief precise enough that the worker never has to guess.
9
+ Skip entirely when the request already pins topic + purpose + constraints.
10
+
11
+ Ask AT MOST 3 of these (AskUserQuestion, one round):
12
+
13
+ - **Purpose** — "Decidere tra opzioni? Survey completa? Confronto puntuale?
14
+ Vincolo normativo?" → maps 1:1 to `PROFILE=` (decision/deep/compare/regulatory).
15
+ - **Nature** — scientific / dev / regulatory / ux / market → picks the source
16
+ policy row. Infer it when obvious ("paper su CRDT" = scientific;
17
+ "best practice Next.js" = dev) — ask only when ambiguous.
18
+ - **Constraints** — jurisdiction (regulatory), budget/timeline (market),
19
+ must-include candidates (compare).
20
+
21
+ Then assemble the brief: 1–3 research questions, stack signature
22
+ (`{{stack.framework}} + {{stack.database}} + {{stack.auth_provider}}`, empty
23
+ segments omitted), known internal context worth passing.
24
+
25
+ ## 2. Routing
26
+
27
+ One line to the user before launching, e.g.:
28
+ `Routing: PROFILE=compare, nature=dev (fonti: official docs → GitHub issues → engineering blogs). Library: 1 possibile riuso.`
29
+
30
+ Heuristics:
31
+
32
+ | Signal in the request | Profile |
33
+ |---|---|
34
+ | "quale scegliere", "ci serve per decidere", feeds a plan/PRD | `decision` |
35
+ | "survey", "stato dell'arte", "letteratura", open-ended learning | `deep` |
36
+ | exactly 2+ named candidates ("X vs Y") | `compare` |
37
+ | law/standard/compliance named or implied | `regulatory` |
38
+
39
+ `DEPTH=` (deep only): default 1. Suggest 2 when the topic is broad AND the
40
+ user asked for thoroughness; 3 only on explicit request (each level multiplies
41
+ cost).
42
+
43
+ ## 3. Reuse check
44
+
45
+ Per `SECTION=reuse` — the skill runs the lookup itself (INDEX.md only, never
46
+ walk the report dirs) so the user decides BEFORE a worker is paid for:
47
+
48
+ - Hit + fresh + same stack → propose **FULL_REUSE**: show the report path +
49
+ its Executive Summary/Recommendation; done if accepted.
50
+ - Hit but stale/stack-drifted → propose **DELTA**: the spawn prompt names the
51
+ prior report path and instructs "update only what expired; `related:` link".
52
+ - No hit → **NEW**.
53
+
54
+ The worker re-runs its own pre-flight anyway (BINDING in the agent) — the two
55
+ never conflict because both apply the same SECTION=reuse rules; the skill's
56
+ pass just moves the decision to the human.
57
+
58
+ ## 4. Launch
59
+
60
+ Spawn prompt skeleton (one per sub-question):
61
+
62
+ ```
63
+ PROFILE=<x> [DEPTH=<n>]
64
+ FILING=orchestrator — do not append INDEX rows; the skill files reports.
65
+ Research brief: <question(s)>
66
+ Stack signature: <sig>
67
+ Internal context: <paths / findings worth reading first>
68
+ Reuse decision from library lookup: NEW | DELTA (prior: <path>)
69
+ OUTPUT CONTRACT (mandatory):
70
+ Write the full report to: <pre-allocated path per SECTION=library>
71
+ First line: RESEARCH_OUTPUT_PATH: <that path>
72
+ Return COMPACT per your Return Contract.
73
+ ```
74
+
75
+ - Pre-allocate ids `RES-<YYYYMMDD>-<slug>`; two sub-questions same day → make
76
+ slugs distinct (never rely on a suffix race).
77
+ - Parallel fan-out (Claude): all spawns in ONE message. Codex: sequential
78
+ by-name spawns (`agents/runtime-portability-protocol.md`), same prompts.
79
+ - Foreground when the user is waiting; background (`run_in_background: true` +
80
+ `BACKGROUND_RUN=true` first line) only when the user asked to keep working.
81
+
82
+ ## 5. Filing
83
+
84
+ For each spawn: file exists at the pre-allocated path → frontmatter parses and
85
+ carries `id/category/tags/valid_until` → append its INDEX row (this skill is
86
+ the ONLY INDEX writer during the run). Failures:
87
+
88
+ - Missing file → re-read the worker's return; if it died, offer one relaunch
89
+ of THAT sub-question (never the whole batch).
90
+ - Frontmatter invalid → fix mechanically from the report content (id/path are
91
+ known; category from the pre-allocation; tags from the questions).
92
+ - INDEX drift (row exists, file moved, duplicate id) → run
93
+ `scripts/rebuild-research-index.mjs <research_dir>` and report what changed.
94
+
95
+ ## 6. Matrix loop
96
+
97
+ On `## SOURCE_MATRIX_CANDIDATE` in any report, per `SECTION=sources`:
98
+
99
+ 1. Show the candidate (nature, change, source, tier, evidence).
100
+ 2. Offer BOTH, independently: (a) apply now to `SOURCES.md` under
101
+ `## Local additions` (append a row — never touch the default matrix
102
+ section); (b) print the report's ready-to-paste BALDART prompt for the
103
+ maintainer session.
104
+ 3. Never apply silently; never emit candidates the report didn't contain.
105
+
106
+ ## Recovery
107
+
108
+ - Session died mid-run → `/research status` surfaces reports on disk that lack
109
+ INDEX rows (rebuild script reconciles) and pre-allocated paths never written
110
+ (relaunch those sub-questions only).
111
+ - Library missing entirely → `npx baldart doctor` (`create-research-dir`),
112
+ then resume.
@@ -0,0 +1,77 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * rebuild-research-index.mjs — deterministic INDEX.md reconciliation.
4
+ *
5
+ * Report frontmatter is the source of truth; INDEX.md is a regenerable view
6
+ * (research-protocol.md SECTION=library). Walks the category subdirectories
7
+ * (never _archive/), parses each report's frontmatter, and rewrites the INDEX
8
+ * table — preserving the header block above the table. Zero dependencies.
9
+ *
10
+ * Usage: node rebuild-research-index.mjs <research_dir> [--check]
11
+ * --check exit 1 (printing the diff summary) instead of writing.
12
+ */
13
+
14
+ import fs from 'node:fs';
15
+ import path from 'node:path';
16
+
17
+ const CATEGORY_DIRS = ['architecture', 'integrations', 'regulatory', 'ux-patterns', 'algorithms', 'tooling'];
18
+
19
+ const dir = process.argv[2];
20
+ const checkOnly = process.argv.includes('--check');
21
+ if (!dir || !fs.existsSync(dir)) {
22
+ console.error('Usage: node rebuild-research-index.mjs <research_dir> [--check]');
23
+ process.exit(2);
24
+ }
25
+
26
+ function parseFrontmatter(text) {
27
+ const m = text.match(/^---\n([\s\S]*?)\n---/);
28
+ if (!m) return null;
29
+ const out = {};
30
+ for (const line of m[1].split('\n')) {
31
+ const kv = line.match(/^(\w+):\s*(.*)$/);
32
+ if (!kv) continue;
33
+ let v = kv[2].trim().replace(/^["']|["']$/g, '');
34
+ if (v.startsWith('[') && v.endsWith(']')) {
35
+ v = v.slice(1, -1).split(',').map((s) => s.trim().replace(/^["']|["']$/g, '')).filter(Boolean).join(', ');
36
+ }
37
+ out[kv[1]] = v;
38
+ }
39
+ return out;
40
+ }
41
+
42
+ const rows = [];
43
+ const problems = [];
44
+ for (const cat of CATEGORY_DIRS) {
45
+ const catAbs = path.join(dir, cat);
46
+ if (!fs.existsSync(catAbs)) continue;
47
+ for (const f of fs.readdirSync(catAbs).filter((f) => f.endsWith('.md')).sort()) {
48
+ const rel = path.join(cat, f);
49
+ let fm;
50
+ try { fm = parseFrontmatter(fs.readFileSync(path.join(catAbs, f), 'utf8')); }
51
+ catch { problems.push(`${rel}: unreadable`); continue; }
52
+ if (!fm || !fm.id) { problems.push(`${rel}: missing frontmatter/id`); continue; }
53
+ if (fm.status === 'superseded') { problems.push(`${rel}: status superseded but not in _archive/`); continue; }
54
+ rows.push(`| ${fm.id} | ${fm.title || ''} | ${fm.category || cat} | ${fm.profile || ''} | ${fm.tags || ''} | ${fm.date || ''} | ${fm.valid_until || ''} | ${rel} |`);
55
+ }
56
+ }
57
+ rows.sort();
58
+
59
+ const indexPath = path.join(dir, 'INDEX.md');
60
+ const existing = fs.existsSync(indexPath) ? fs.readFileSync(indexPath, 'utf8') : '';
61
+ const tableStart = existing.search(/^\| id \|/m);
62
+ const header = tableStart >= 0
63
+ ? existing.slice(0, tableStart)
64
+ : '# Research Library — INDEX\n\n';
65
+ const headerRow = '| id | title | category | profile | tags | date | valid_until | path |\n|----|-------|----------|---------|------|------|-------------|------|\n';
66
+ const next = header + headerRow + rows.join('\n') + (rows.length ? '\n' : '');
67
+
68
+ if (next === existing) {
69
+ console.log(`INDEX.md in sync (${rows.length} report(s)).`);
70
+ } else if (checkOnly) {
71
+ console.error(`INDEX.md out of sync: ${rows.length} report(s) on disk.`);
72
+ process.exit(1);
73
+ } else {
74
+ fs.writeFileSync(indexPath, next, 'utf8');
75
+ console.log(`INDEX.md rebuilt: ${rows.length} report(s).`);
76
+ }
77
+ for (const p of problems) console.warn(`WARN ${p}`);
@@ -43,6 +43,7 @@ Route agents to the right module with minimal reading.
43
43
  - If authoring/auditing a subagent whose return would flood the orchestrator context (free-form analysis/audit/research) -> read `agents/return-contract-protocol.md` and bound its final message: COMPACT headline + `path:line` findings + disk pointer, persist the long form. The input-side twin of the effort protocol.
44
44
  - If authoring/editing an agent definition -> the shared operating procedures (injection guard, retrieval, memory, tool budget) live in `agents/agent-operating-protocol.md` and the reviewer verification passes (challenge/simulation/CoVe/risk) in `agents/review-protocol.md` — cite their sections, never re-inline them; keep only the 1-line binding versions in the agent body.
45
45
  - If a skill performs runtime-mechanical operations (spawn an agent, gate on the user, track state, accelerate a fan-out, run an adversarial review) and must work on BOTH Claude Code and Codex -> read `agents/runtime-portability-protocol.md`: bind each abstract operation to the runtime (Claude `Task`/`Workflow`/`AskUserQuestion`/task-spine ↔ Codex named-agent spawn / inline / plain prompt / file-backed queue), detect the runtime once at kickoff, never probe Claude-only primitives on Codex. Shared policy (delegation, no-silent-fallback, worktree isolation) stays in `AGENTS.md` — cited, not restated.
46
+ - If conducting research (technology evaluation, best practices, compliance survey), spawning `senior-researcher`, or managing the research library (`${paths.research_dir}/`) -> read `agents/research-protocol.md` (the matching `SECTION=` only): pass a `PROFILE=<decision|deep|compare|regulatory>` token, run the library reuse pre-flight BEFORE searching, and route sources by nature via the source matrix. Interactive channel: the `/research` skill.
46
47
  - If building or maintaining a derived LLM wiki overlay (`${paths.wiki_dir}/`) -> read `agents/llm-wiki-methodology.md` and invoke `wiki-curator` / `/capture`.
47
48
  - For day-to-day status -> read and update `${paths.references_dir}/project-status.md`.
48
49
  - For legacy context -> read `archive/project_full_legacy.md` if it exists.
@@ -85,6 +86,7 @@ When adding or updating agents, update REGISTRY.md — not this file.
85
86
  - `agents/agent-operating-protocol.md` — Shared operating procedures for the core agents (injection guard, doc-retrieval consumption, persistent-memory hygiene, tool-budget discipline), `SECTION=` dispatch, read only the matching section; agents keep 1-line binding versions inline (since v5.0.0)
86
87
  - `agents/review-protocol.md` — The shared verification engine for reviewers: Challenge + Actionability, Simulation (diff-walk / plan-walk), Chain-of-Verification, quantified risk scoring + absolute severity calibration, specialist-spawn discipline incl. orchestrated-mode `specialist_dispatch` suppression; `SECTION=` dispatch (since v5.0.0)
87
88
  - `agents/doc-audit-protocol.md` — doc-reviewer's audit-mode procedures (drift validator suite, topological generation, epistemic metadata, SCIP anchors, schema/registry drift, coverage gauges); read ONLY when invoked without card context; `SECTION=` dispatch (since v5.0.0)
89
+ - `agents/research-protocol.md` — Research discipline: `PROFILE=<decision|deep|compare|regulatory>` output contracts (+ `DEPTH=` iterative loop), the research library (`paths.research_dir` — layout, report frontmatter, INDEX, archive-not-delete), the reuse pre-flight (`FULL_REUSE`/`DELTA`/`NEW` + per-category TTLs), and the versioned source matrix with its growth loop (`SOURCE_MATRIX_CANDIDATE`); `SECTION=` dispatch. The research-side sibling of `analysis-profiles.md` (since v5.1.0)
88
90
 
89
91
  ## Where to Document (Decision Tree)
90
92