baldart 3.40.0 → 4.0.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 (51) hide show
  1. package/CHANGELOG.md +51 -0
  2. package/README.md +1 -1
  3. package/VERSION +1 -1
  4. package/framework/.claude/agents/REGISTRY.md +74 -24
  5. package/framework/.claude/agents/api-perf-cost-auditor.md +12 -5
  6. package/framework/.claude/agents/code-reviewer.md +30 -23
  7. package/framework/.claude/agents/codebase-architect.md +47 -43
  8. package/framework/.claude/agents/coder.md +29 -18
  9. package/framework/.claude/agents/doc-reviewer.md +55 -28
  10. package/framework/.claude/agents/plan-auditor.md +77 -12
  11. package/framework/.claude/agents/prd-card-writer.md +43 -13
  12. package/framework/.claude/agents/prd.md +22 -3
  13. package/framework/.claude/agents/qa-sentinel.md +75 -29
  14. package/framework/.claude/agents/security-reviewer.md +65 -10
  15. package/framework/.claude/agents/senior-researcher.md +8 -1
  16. package/framework/.claude/agents/ui-expert.md +22 -7
  17. package/framework/.claude/commands/check.md +31 -11
  18. package/framework/.claude/commands/codexreview.md +48 -29
  19. package/framework/.claude/commands/new.md +29 -328
  20. package/framework/.claude/commands/qa.md +62 -37
  21. package/framework/.claude/skills/context-primer/SKILL.md +29 -8
  22. package/framework/.claude/skills/doc-writing-for-rag/SKILL.md +36 -36
  23. package/framework/.claude/skills/frontend-design/SKILL.md +10 -8
  24. package/framework/.claude/skills/new/SKILL.md +413 -302
  25. package/framework/.claude/skills/prd/SKILL.md +67 -38
  26. package/framework/.claude/skills/prd/assets/card-template.yml +22 -26
  27. package/framework/.claude/skills/prd/assets/epic-template.yml +5 -5
  28. package/framework/.claude/skills/prd/assets/state-template.md +25 -3
  29. package/framework/.claude/skills/prd/references/api-perf-gate.md +143 -33
  30. package/framework/.claude/skills/prd/references/audit-phase.md +48 -34
  31. package/framework/.claude/skills/prd/references/backlog-phase.md +38 -11
  32. package/framework/.claude/skills/prd/references/discovery-phase.md +121 -44
  33. package/framework/.claude/skills/prd/references/impact-analysis.md +127 -23
  34. package/framework/.claude/skills/prd/references/prd-add-phase.md +18 -214
  35. package/framework/.claude/skills/prd/references/prd-writing-phase.md +52 -42
  36. package/framework/.claude/skills/prd/references/research-phase.md +105 -19
  37. package/framework/.claude/skills/prd/references/ui-design-phase.md +20 -8
  38. package/framework/.claude/skills/prd/references/validation-phase.md +97 -72
  39. package/framework/.claude/skills/prd-add/SKILL.md +70 -20
  40. package/framework/.claude/skills/simplify/SKILL.md +22 -12
  41. package/framework/.claude/skills/ui-design/SKILL.md +26 -7
  42. package/framework/.claude/skills/webapp-testing/SKILL.md +6 -4
  43. package/framework/.claude/skills/worktree-manager/SKILL.md +206 -143
  44. package/framework/agents/coding-standards.md +85 -0
  45. package/framework/agents/index.md +2 -1
  46. package/framework/agents/skills-mapping.md +85 -82
  47. package/framework/agents/testing.md +28 -0
  48. package/framework/templates/baldart.config.template.yml +29 -7
  49. package/package.json +1 -1
  50. package/src/commands/configure.js +43 -9
  51. package/framework/.claude/skills/prd-add/references/impact-analysis.md +0 -233
@@ -86,6 +86,91 @@ if (error) {
86
86
  }
87
87
  ```
88
88
 
89
+ ## Reference-Aliasing Mutation Patterns
90
+
91
+ > **SSOT.** This section is the canonical policy for reference-aliasing mutation
92
+ > hazards. It is cited as the source of truth by `coder.md`
93
+ > (§ Reference-Aliasing Mutation Hazards), `code-reviewer.md` (review checklist),
94
+ > and `.claude/skills/new/SKILL.md` (Phase 2.5 step 5c deterministic detector +
95
+ > Phase 3.7 trigger #6). When those files cite "§ Reference-Aliasing Mutation
96
+ > Patterns", they mean this section.
97
+
98
+ ### The hazard
99
+
100
+ A call site pairs a helper invocation with in-place mutation of an input
101
+ array/object, where the helper *may return the input reference unchanged*
102
+ (early-return, fallback, or no-op guard path). When the returned value and the
103
+ input are the same reference, an in-place reset of the input also empties the
104
+ "result", and the subsequent re-populate pushes nothing:
105
+
106
+ ```ts
107
+ const result = filterHelper(input, ...);
108
+ input.length = 0; // ← wipes BOTH input AND result when result === input
109
+ input.push(...result); // ← pushes zero elements (result was just emptied)
110
+ ```
111
+
112
+ The TypeScript signature does **not** encode reference identity — a function
113
+ typed `(xs: T[]) => T[]` may still return its argument unchanged. Unit tests on
114
+ the helper in isolation pass; the defect only manifests end-to-end at the call
115
+ site. This is the class of bug that motivated this policy (a filter helper that
116
+ returned its input reference on most paths, paired with an unguarded
117
+ `length = 0; push(...result)` reset, collapsing a list to empty in production).
118
+
119
+ ### The 3-question detector
120
+
121
+ Before writing — or while reviewing — any call site that mutates an input array
122
+ in place after a helper call, answer:
123
+
124
+ 1. **Does the helper return an array or object?** If yes, continue.
125
+ 2. **Could the helper return the input reference unchanged** on any path?
126
+ Read every `return` statement in the helper body. If yes, continue.
127
+ 3. **Does the call site mutate the input in place** via `arr.length = 0`,
128
+ `arr.splice(0)`, `Object.assign(input, result)`, or similar? If yes — and
129
+ (1)+(2) were also yes — you have an alias-mutation hazard.
130
+
131
+ ### Required remediation (apply exactly one)
132
+
133
+ - **Identity guard** at the call site:
134
+ ```ts
135
+ const result = filterHelper(input, ...);
136
+ if (result !== input) {
137
+ input.length = 0;
138
+ input.push(...result);
139
+ }
140
+ ```
141
+ - **Defensive clone** before the call: `filterHelper([...input], ...)` (or
142
+ `input.slice()`).
143
+ - **Refactor the helper** to always return a new array on every path
144
+ (preferred when the helper is exported and consumed by 2+ callers). Document
145
+ the immutability contract in the helper's JSDoc, e.g.
146
+ `@returns a NEW array — never the input reference`, so reviewers can trust it
147
+ without re-reading every branch.
148
+
149
+ ### Test contract
150
+
151
+ When a guard or clone is applied, ALSO write a regression test on the **caller
152
+ pattern** — not only on the helper in isolation. The test MUST include:
153
+
154
+ - An assertion on the post-call state of the input (e.g. its length/contents
155
+ after the helper invocation), and
156
+ - A **negative-control case** that documents the failure mode that would recur
157
+ if the guard/clone were removed.
158
+
159
+ Place caller-pattern reference tests under your project's test root (the same
160
+ path the card's `paths.*` test convention uses); cite that reference test from
161
+ the helper's JSDoc so future editors find the contract.
162
+
163
+ ### Enforcement layers
164
+
165
+ - **This section** — full policy + JSDoc contract + remediation menu.
166
+ - `coder.md § Reference-Aliasing Mutation Hazards` — pre-implementation check.
167
+ - `code-reviewer.md` review checklist — flags un-guarded patterns at review time.
168
+ - `.claude/skills/new/SKILL.md § Phase 2.5 step 5c` — deterministic detector
169
+ that flags un-guarded patterns as `[ALIAS-MUTATION] BLOCKER` in
170
+ `## Issues & Flags`.
171
+ - `.claude/skills/new/SKILL.md § Phase 3.7 trigger #6` — a mutation-after-helper
172
+ call invokes a per-card adversarial cross-model review before commit.
173
+
89
174
  ## Commit Message Format
90
175
 
91
176
  - **Format**: `[TYPE-XXX] Brief description` or adapt to your project convention
@@ -22,7 +22,8 @@ Route agents to the right module with minimal reading.
22
22
  - If touching design-review workflows or UI guidelines -> read `agents/design-review.md` and project-specific UI guidelines.
23
23
  - If touching architecture, auth, or tech stack -> read `agents/architecture.md`.
24
24
  - If touching workflow/process/commits/backlog -> read `agents/workflows.md`.
25
- - If touching testing or QA issues -> read `agents/testing.md`.
25
+ - If touching testing or QA issues -> read `agents/testing.md` (also documents the scope-aware,
26
+ profile-driven test-selection strategy consumed by `qa-sentinel`).
26
27
  - If touching GitHub issues or issue workflow -> read `agents/github-issue-subagent.md`.
27
28
  - If touching terminology or naming -> read `agents/coding-standards.md`.
28
29
  - If touching env vars or scripts -> read `agents/runbook.md` and `agents/env-reference.md`.
@@ -21,95 +21,85 @@ Map Claude Code skills to project domains and provide guidance on when to use ea
21
21
  - Use wrong skill for the task
22
22
  - Rationalize not using applicable skills
23
23
 
24
+ > This map references **only skills shipped under `framework/.claude/skills/`**.
25
+ > Confirm a skill exists (its directory is present) before routing to it; never
26
+ > route to a skill name that has no directory.
27
+
24
28
  ## Core Development Skills
25
29
 
26
- ### brainstorming
30
+ ### prd
27
31
 
28
32
  **When to use**:
29
33
 
30
- - Starting new features
31
- - Unclear requirements
32
- - Multiple possible approaches
33
- - Design decisions needed
34
+ - Starting a new feature (scoping + planning)
35
+ - Unclear or multi-part requirements
36
+ - Multiple possible approaches / design decisions needed
37
+ - Need a PRD + UI design + atomic backlog cards before implementation
34
38
 
35
39
  **Triggers**:
36
40
 
37
- - "Add [feature]"
38
- - "Build [component]"
39
- - "Implement [functionality]"
40
- - "How should I..."
41
+ - "Plan [feature]"
42
+ - "Crea un PRD"
43
+ - "Nuova funzionalità"
44
+ - "How should I scope..."
41
45
 
42
- ### writing-plans
46
+ ### context-primer
43
47
 
44
48
  **When to use**:
45
49
 
46
- - After brainstorming
47
- - Multi-step implementation needed
48
- - Complex feature development
50
+ - Before starting work on an unfamiliar area of the codebase
51
+ - Need existing patterns/architecture loaded silently into context
49
52
 
50
53
  **Triggers**:
51
54
 
52
- - After design approval
53
- - Before starting implementation
54
- - For documented requirements
55
+ - "/cont [keywords]"
56
+ - Auto-invoked by `/prd` at kickoff
55
57
 
56
- ### test-driven-development
58
+ ### new
57
59
 
58
60
  **When to use**:
59
61
 
60
- - Implementing new features
61
- - Fixing bugs
62
- - Adding testable functionality
62
+ - Implementing one or more approved backlog cards end-to-end
63
+ - Multi-step implementation across a worktree with review/QA/commit per card
63
64
 
64
65
  **Triggers**:
65
66
 
66
- - New feature implementation
67
- - Bug fix with test case
68
- - Refactoring with tests
67
+ - "/new CARD-IDS"
68
+ - "Implementa le card"
69
+ - "Esegui le card"
69
70
 
70
- ### systematic-debugging
71
+ ### bug
71
72
 
72
73
  **When to use**:
73
74
 
74
75
  - Bug investigation
75
- - Test failures
76
- - Unexpected behavior
76
+ - Test failures / unexpected behavior
77
+ - Regression hunting
77
78
 
78
79
  **Triggers**:
79
80
 
81
+ - "/bug"
80
82
  - "Fix [bug]"
81
- - "Why is [X] not working?"
82
- - Test failure analysis
83
+ - "Non funziona" / "Why is [X] not working?"
83
84
 
84
85
  ## Code Quality Skills
85
86
 
86
- ### code-review
87
+ ### simplify
87
88
 
88
89
  **When to use**:
89
90
 
90
- - Before merging
91
- - After major implementation
92
- - PR review process
91
+ - Reducing complexity in a changed area (reuse, dedup, altitude cleanups)
92
+ - After major implementation, before commit
93
93
 
94
94
  **Triggers**:
95
95
 
96
- - Feature completion
97
- - Before deployment
98
- - Pull request review
99
-
100
- ### verification-before-completion
101
-
102
- **When to use**:
103
-
104
- - Claiming work is complete
105
- - Before marking card done
106
- - Before creating PR
107
-
108
- **Triggers**:
96
+ - "/simplify"
97
+ - "Semplifica"
98
+ - "Reduce duplication"
109
99
 
110
- - "Done"
111
- - "Fixed"
112
- - "Tests passing"
100
+ > Code review and pre-merge gates are run by the `/new` orchestration
101
+ > (`code-reviewer` agent + `qa-sentinel` gate run) and the `/codexreview`
102
+ > command — not by a standalone "code-review" skill. Route review tasks there.
113
103
 
114
104
  ## UI/UX Skills
115
105
 
@@ -127,19 +117,24 @@ Map Claude Code skills to project domains and provide guidance on when to use ea
127
117
  - "Build [component]"
128
118
  - "Design [interface]"
129
119
 
130
- ### ui-ux-pro-max
120
+ ### ui-design
131
121
 
132
122
  **When to use**:
133
123
 
134
- - Professional UI/UX design
135
- - Design system work
136
- - Polished interfaces
124
+ - Designing new pages or components (context-aware mockups)
125
+ - The `/prd` skill reaches its UI design phase
126
+ - Redesigning existing pages / creating design options for review
137
127
 
138
128
  **Triggers**:
139
129
 
140
- - Design-heavy features
141
- - Visual refinement needed
142
- - Design system development
130
+ - "/ui-design"
131
+ - "Design UI" / "mockup" / "opzioni di design"
132
+ - Design-heavy features, visual refinement, design-system work
133
+
134
+ > `ui-ux-pro-max` is a **tool used inside** the `ui-expert` agent / `ui-design`
135
+ > skill (see REGISTRY.md — listed as a Key Tool of `ui-expert`), not a
136
+ > standalone invocable BALDART skill. Route UI work through `ui-design` /
137
+ > `ui-expert`, not to `ui-ux-pro-max` directly.
143
138
 
144
139
  ## Testing Skills
145
140
 
@@ -173,19 +168,30 @@ Map Claude Code skills to project domains and provide guidance on when to use ea
173
168
 
174
169
  ## Documentation Skills
175
170
 
176
- ### writing-clearly-and-concisely
171
+ ### doc-writing-for-rag
172
+
173
+ **When to use**:
174
+
175
+ - Writing/rewriting dense reference documentation optimized for RAG indexing
176
+ - Creating endpoint/reference docs in `${paths.references_dir}`
177
+
178
+ **Triggers**:
179
+
180
+ - "doc per RAG" / "dense documentation"
181
+ - "template endpoint" / "compattare docs"
182
+
183
+ ### copywriting
177
184
 
178
185
  **When to use**:
179
186
 
180
- - Writing documentation
181
- - Creating specs
182
- - User-facing content
187
+ - User-facing content, marketing copy, microcopy
188
+ - Tone/voice refinement
183
189
 
184
190
  **Triggers**:
185
191
 
186
- - Documentation updates
187
- - README writing
188
- - Technical writing
192
+ - "Scrivi la copy"
193
+ - "Migliora il testo"
194
+ - Landing/marketing content
189
195
 
190
196
  ## Project-Specific Skills
191
197
 
@@ -207,29 +213,25 @@ Add your project-specific skills here:
207
213
  START: User gives a task
208
214
  |
209
215
  v
210
- Is it a new feature/design task?
211
- |-- YES --> Use brainstorming skill first
212
- | Then writing-plans
213
- | Then implementation skills
216
+ Is it a new feature needing scope/plan?
217
+ |-- YES --> /prd (scopes + plans + writes cards)
218
+ | Then /new (implements the cards end-to-end)
214
219
  |
215
220
  v
216
221
  Is it a bug fix?
217
- |-- YES --> Use systematic-debugging
218
- | Then test-driven-development
219
- | Then verification-before-completion
222
+ |-- YES --> /bug (5-phase investigation + fix)
220
223
  |
221
224
  v
222
225
  Is it UI/visual work?
223
- |-- YES --> Use frontend-design or ui-ux-pro-max
226
+ |-- YES --> /ui-design (mockups/options) or frontend-design
224
227
  |
225
228
  v
226
229
  Is it browser testing?
227
- |-- YES --> Use playwright-skill or webapp-testing
230
+ |-- YES --> playwright-skill or webapp-testing (E2E via /e2e-review)
228
231
  |
229
232
  v
230
- Is work complete?
231
- |-- YES --> Use verification-before-completion
232
- | Then code-review
233
+ Is it cleanup/complexity reduction?
234
+ |-- YES --> /simplify
233
235
  |
234
236
  v
235
237
  Proceed with appropriate skill
@@ -237,29 +239,30 @@ Proceed with appropriate skill
237
239
 
238
240
  ## Skill Chaining
239
241
 
240
- Common skill chains:
242
+ Common skill chains (all skills below are shipped under `.claude/skills/`):
241
243
 
242
244
  1. **New Feature**:
243
- - brainstormingwriting-plans test-driven-development verification-before-completion code-review
245
+ - /prd/new (the orchestrator runs `code-reviewer` + `qa-sentinel` gates per card)
244
246
 
245
247
  2. **Bug Fix**:
246
- - systematic-debuggingtest-driven-development verification-before-completion
248
+ - /bug(fix lands through the bug skill's verify phase)
247
249
 
248
250
  3. **UI Feature**:
249
- - brainstormingfrontend-design → test-driven-development → playwright-skill code-review
251
+ - /prd/ui-design → /new → playwright-skill (or /e2e-review for blocking E2E)
250
252
 
251
253
  4. **Refactoring**:
252
- - code-review (identify issues) → test-driven-development verification-before-completion
254
+ - /simplify (identify + apply cleanups) → /new gates re-run lint/tsc/tests
253
255
 
254
256
  ## Anti-Patterns
255
257
 
256
258
  **Don't**:
257
259
 
258
- - Skip brainstorming for "simple" features
260
+ - Skip `/prd` scoping for "simple" multi-part features
259
261
  - Start coding before planning
260
- - Skip TDD because "I know how to fix it"
261
- - Skip verification before claiming completion
262
+ - Skip the per-card `qa-sentinel` gate run because "I know how to fix it"
263
+ - Claim completion before the `/new` review + gate cycle passes
262
264
  - Use wrong skill for the task
265
+ - Route to a skill name that has no directory under `.claude/skills/`
263
266
 
264
267
  **Do**:
265
268
 
@@ -9,6 +9,34 @@ Define required manual testing and QA issue workflow, including browser automati
9
9
  **In**: Manual testing steps, QA issue creation and handling, browser automation.
10
10
  **Out**: Performance testing strategy (see agents/performance.md).
11
11
 
12
+ ## Scope-aware Test Selection (Automated QA)
13
+
14
+ The automated QA gate (`qa-sentinel`) does **not** run the full test suite on every change. It runs
15
+ the depth dictated by the card's `review_profile`. The decision criteria for which profile a card
16
+ gets are **computed by `prd-card-writer` (Rule C)** — see `prd-card-writer.md` for the criteria;
17
+ this module only describes the profile→tier mapping qa-sentinel applies:
18
+
19
+ - **balanced → SCOPED**: run only the tests *related to the changed files* (test-impact selection),
20
+ not the whole suite. This is the default for ordinary features and refactors.
21
+ - **deep → FULL**: run the whole suite + security audit. Reserved for high-risk
22
+ changes (data model, security, broad blast radius). Blocking E2E for these changes is owned by the
23
+ separate `/e2e-review` skill (qa-sentinel does NOT run Playwright/E2E).
24
+ - **skip / light**: the gate is not invoked — these are handled upstream (docs/chore, or gates
25
+ already run during implementation).
26
+ - **Risk-drift escalation**: a `balanced` change is promoted to FULL only when the diff itself
27
+ reveals undeclared risk — paths touching auth, permissions, payment/billing, DB schema/migration,
28
+ or an API contract. Change *count* never escalates (it is advisory only).
29
+
30
+ Test selection is **heuristic**, not instrumented: it relies on file paths, naming, and the test
31
+ runner's native related-tests capability — no coverage maps, AST analysis, or ML. When no related
32
+ tests can be resolved for a logic change, the gate records a coverage-gap and lowers its confidence
33
+ rather than silently passing or falling back to the full suite. The concrete per-runner commands
34
+ live in the `qa-sentinel` agent (which is stack-aware); this module states the principle only.
35
+
36
+ > The executable tier table + runner cascade is owned by `qa-sentinel` (`.claude/agents/qa-sentinel.md`),
37
+ > kept stack-specific there. Optional smoke convention: a `test:smoke` script or `tests/smoke/`
38
+ > directory, if present, is used as a minimal sanity set — its absence is fine, not a misconfiguration.
39
+
12
40
  ## Do
13
41
 
14
42
  - Run project build command before marking a card done.
@@ -45,6 +45,22 @@ paths:
45
45
  # Test infrastructure.
46
46
  e2e_tests_dir: "" # e.g. tests/e2e
47
47
 
48
+ # Metrics output directory (used by /new Phase 8 + /prd metrics log).
49
+ # Default convention is "docs/metrics" — set explicitly to override.
50
+ metrics: "" # e.g. docs/metrics
51
+
52
+ # Optional telemetry tap for the wiki auto-learning loop. When set, skills
53
+ # append retrieval signal here; when empty, the tap is skipped with a
54
+ # WARNING (never a silent no-op). Only meaningful with has_wiki_overlay.
55
+ wiki_log: "" # e.g. tools/doc-rag/wiki_log.py
56
+
57
+ # High-risk module paths used by RISK DETECTORS (review-profile escalation,
58
+ # security/perf signal detection). A portable list of repo-relative globs
59
+ # the project considers sensitive (auth, payments, billing, core engines).
60
+ # When EMPTY, risk detectors that depend on it emit a one-line diagnostic
61
+ # and skip — they never fall back to hard-coded project paths.
62
+ high_risk_modules: [] # e.g. ["src/lib/auth/**", "src/app/api/**/billing/**"]
63
+
48
64
  # ─── IDENTITY ────────────────────────────────────────────────────────────
49
65
  # Brand and audience facts skills use when generating UI, copy, or motion.
50
66
  identity:
@@ -199,18 +215,24 @@ lsp:
199
215
 
200
216
  # ─── GIT ─────────────────────────────────────────────────────────────────
201
217
  # Controls how worktree-manager (`/mw`) integrates a worktree's feature
202
- # branch back into `develop`.
218
+ # branch back into the integration trunk.
203
219
  git:
204
- # How `/mw` lands the feature branch onto develop:
220
+ # Integration trunk branch the branch worktrees are created from and merged
221
+ # back into. NEVER hard-code "develop"/"main" in skills; they resolve this key.
222
+ # `baldart configure` autodetects it from `git symbolic-ref refs/remotes/origin/HEAD`
223
+ # (falling back to asking the user). Default kept as "develop" for back-compat.
224
+ trunk_branch: develop
225
+
226
+ # How `/mw` lands the feature branch onto the trunk:
205
227
  #
206
228
  # pr (default) — push feature branch, open a PR via `gh pr create`,
207
- # merge via `gh pr merge`. Required if `develop` is protected
229
+ # merge via `gh pr merge`. Required if the trunk is protected
208
230
  # on origin (status checks, required reviews, merge queue).
209
231
  #
210
- # local-push — after rebasing the feature branch onto `origin/develop`,
211
- # fast-forward push the feature branch directly to
212
- # `origin/develop` (`git push origin <feat>:develop`).
213
- # No PR, no `gh` dependency. FAILS hard if `develop` is
232
+ # local-push — after rebasing the feature branch onto `origin/<trunk>`,
233
+ # fast-forward push the feature branch directly to the trunk
234
+ # (`git push origin <feat>:<trunk_branch>`).
235
+ # No PR, no `gh` dependency. FAILS hard if the trunk is
214
236
  # protected on origin — switch back to `pr` in that case.
215
237
  #
216
238
  # Neither strategy ever touches the main repo's HEAD — both flows are
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "baldart",
3
- "version": "3.40.0",
3
+ "version": "4.0.0",
4
4
  "description": "Claude Agent Framework - Reusable framework for coordinating AI agents and humans in software projects",
5
5
  "bin": {
6
6
  "baldart": "./bin/baldart.js"
@@ -38,7 +38,7 @@ const IGNORED_DIRS = new Set([
38
38
  * Non-fatal: any failure returns `{ value: 'pr', protected: null }` so configure
39
39
  * keeps moving. The user can override in the interactive prompt.
40
40
  */
41
- function detectMergeStrategy(cwd = process.cwd()) {
41
+ function detectMergeStrategy(cwd = process.cwd(), trunk = 'develop') {
42
42
  try {
43
43
  const { execSync } = require('child_process');
44
44
  const opts = { cwd, stdio: ['ignore', 'pipe', 'ignore'], timeout: 5000, encoding: 'utf8' };
@@ -52,17 +52,17 @@ function detectMergeStrategy(cwd = process.cwd()) {
52
52
  } catch (_) {
53
53
  return { value: 'pr', protected: null, reason: 'no GitHub remote detected — defaulting to pr.' };
54
54
  }
55
- // Probe branch protection. 404 means "not protected" → local-push viable.
55
+ // Probe branch protection on the resolved trunk. 404 means "not protected" → local-push viable.
56
56
  try {
57
- execSync(`gh api repos/${nameWithOwner}/branches/develop/protection`, opts);
58
- return { value: 'pr', protected: true, reason: 'develop is protected on origin — PR strategy required.' };
57
+ execSync(`gh api repos/${nameWithOwner}/branches/${trunk}/protection`, opts);
58
+ return { value: 'pr', protected: true, reason: `${trunk} is protected on origin — PR strategy required.` };
59
59
  } catch (_) {
60
60
  // Could be 404 (not protected) OR branch doesn't exist. Check existence:
61
61
  try {
62
- execSync(`gh api repos/${nameWithOwner}/branches/develop -q .name`, opts);
63
- return { value: 'local-push', protected: false, reason: 'develop exists on origin and is not protected — local-push viable.' };
62
+ execSync(`gh api repos/${nameWithOwner}/branches/${trunk} -q .name`, opts);
63
+ return { value: 'local-push', protected: false, reason: `${trunk} exists on origin and is not protected — local-push viable.` };
64
64
  } catch (_) {
65
- return { value: 'pr', protected: null, reason: 'develop branch not found on origin — defaulting to pr.' };
65
+ return { value: 'pr', protected: null, reason: `${trunk} branch not found on origin — defaulting to pr.` };
66
66
  }
67
67
  }
68
68
  } catch (_) {
@@ -70,6 +70,34 @@ function detectMergeStrategy(cwd = process.cwd()) {
70
70
  }
71
71
  }
72
72
 
73
+ /**
74
+ * Autodetect the integration trunk branch (git.trunk_branch).
75
+ * Order: origin/HEAD symbolic-ref → existing local `develop` → existing local
76
+ * `main`/`master` → 'develop'. Non-fatal: any failure returns the 'develop'
77
+ * back-compat default so configure keeps moving; the user can override.
78
+ */
79
+ function detectTrunkBranch(cwd = process.cwd()) {
80
+ try {
81
+ const { execSync } = require('child_process');
82
+ const opts = { cwd, stdio: ['ignore', 'pipe', 'ignore'], timeout: 5000, encoding: 'utf8' };
83
+ try {
84
+ const ref = execSync('git symbolic-ref refs/remotes/origin/HEAD', opts).trim();
85
+ const name = ref.replace(/^refs\/remotes\/origin\//, '');
86
+ if (name) return { value: name, reason: `origin/HEAD points at ${name}.` };
87
+ } catch (_) { /* fall through to local branch probes */ }
88
+ const branches = (() => {
89
+ try { return execSync('git branch --format=%(refname:short)', opts).split('\n').map((s) => s.trim()); }
90
+ catch (_) { return []; }
91
+ })();
92
+ for (const cand of ['develop', 'main', 'master']) {
93
+ if (branches.includes(cand)) return { value: cand, reason: `local '${cand}' branch found.` };
94
+ }
95
+ return { value: 'develop', reason: 'no trunk detected — defaulting to develop.' };
96
+ } catch (_) {
97
+ return { value: 'develop', reason: 'probe failed — defaulting to develop.' };
98
+ }
99
+ }
100
+
73
101
  function detect(cwd = process.cwd()) {
74
102
  const exists = (p) => fs.existsSync(path.join(cwd, p));
75
103
  const findFirst = (...candidates) => candidates.find(exists) || '';
@@ -282,7 +310,8 @@ function detect(cwd = process.cwd()) {
282
310
  : (exists('cypress.config.ts') || exists('cypress.config.js') || hasDep('cypress')) ? 'cypress'
283
311
  : '';
284
312
 
285
- const mergeStrategyProbe = detectMergeStrategy(cwd);
313
+ const trunkBranchProbe = detectTrunkBranch(cwd);
314
+ const mergeStrategyProbe = detectMergeStrategy(cwd, trunkBranchProbe.value);
286
315
 
287
316
  // ---- Persistence layer (stack.database) --------------------------------
288
317
  let detectedDatabase = '';
@@ -344,6 +373,9 @@ function detect(cwd = process.cwd()) {
344
373
  references_dir: exists('docs/references') ? 'docs/references' : '',
345
374
  wiki_dir: exists('docs/wiki') ? 'docs/wiki' : '',
346
375
  e2e_tests_dir: e2eTestsDir,
376
+ metrics: exists('docs/metrics') ? 'docs/metrics' : '',
377
+ wiki_log: exists('tools/doc-rag/wiki_log.py') ? 'tools/doc-rag/wiki_log.py' : '',
378
+ high_risk_modules: [],
347
379
  },
348
380
  identity: {
349
381
  brand_name: brandName,
@@ -400,14 +432,16 @@ function detect(cwd = process.cwd()) {
400
432
  enabled: toolAdapters.defaultEnabled(cwd)
401
433
  },
402
434
  git: {
403
- // Set to a plain string — the structured probe details (`protected`,
435
+ // Set to plain strings — the structured probe details (`protected`,
404
436
  // `reason`) are kept on a sibling key so mergePreserving stays type-safe.
437
+ trunk_branch: trunkBranchProbe.value,
405
438
  merge_strategy: mergeStrategyProbe.value,
406
439
  },
407
440
  _probes: {
408
441
  // Internal scratchpad — never serialized to YAML. Used by
409
442
  // interactivePrompts to surface the autodetection reasoning.
410
443
  merge_strategy: mergeStrategyProbe,
444
+ trunk_branch: trunkBranchProbe,
411
445
  },
412
446
  };
413
447