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.
- package/CHANGELOG.md +51 -0
- package/README.md +1 -1
- package/VERSION +1 -1
- package/framework/.claude/agents/REGISTRY.md +74 -24
- package/framework/.claude/agents/api-perf-cost-auditor.md +12 -5
- package/framework/.claude/agents/code-reviewer.md +30 -23
- package/framework/.claude/agents/codebase-architect.md +47 -43
- package/framework/.claude/agents/coder.md +29 -18
- package/framework/.claude/agents/doc-reviewer.md +55 -28
- package/framework/.claude/agents/plan-auditor.md +77 -12
- package/framework/.claude/agents/prd-card-writer.md +43 -13
- package/framework/.claude/agents/prd.md +22 -3
- package/framework/.claude/agents/qa-sentinel.md +75 -29
- package/framework/.claude/agents/security-reviewer.md +65 -10
- package/framework/.claude/agents/senior-researcher.md +8 -1
- package/framework/.claude/agents/ui-expert.md +22 -7
- package/framework/.claude/commands/check.md +31 -11
- package/framework/.claude/commands/codexreview.md +48 -29
- package/framework/.claude/commands/new.md +29 -328
- package/framework/.claude/commands/qa.md +62 -37
- package/framework/.claude/skills/context-primer/SKILL.md +29 -8
- package/framework/.claude/skills/doc-writing-for-rag/SKILL.md +36 -36
- package/framework/.claude/skills/frontend-design/SKILL.md +10 -8
- package/framework/.claude/skills/new/SKILL.md +413 -302
- package/framework/.claude/skills/prd/SKILL.md +67 -38
- package/framework/.claude/skills/prd/assets/card-template.yml +22 -26
- package/framework/.claude/skills/prd/assets/epic-template.yml +5 -5
- package/framework/.claude/skills/prd/assets/state-template.md +25 -3
- package/framework/.claude/skills/prd/references/api-perf-gate.md +143 -33
- package/framework/.claude/skills/prd/references/audit-phase.md +48 -34
- package/framework/.claude/skills/prd/references/backlog-phase.md +38 -11
- package/framework/.claude/skills/prd/references/discovery-phase.md +121 -44
- package/framework/.claude/skills/prd/references/impact-analysis.md +127 -23
- package/framework/.claude/skills/prd/references/prd-add-phase.md +18 -214
- package/framework/.claude/skills/prd/references/prd-writing-phase.md +52 -42
- package/framework/.claude/skills/prd/references/research-phase.md +105 -19
- package/framework/.claude/skills/prd/references/ui-design-phase.md +20 -8
- package/framework/.claude/skills/prd/references/validation-phase.md +97 -72
- package/framework/.claude/skills/prd-add/SKILL.md +70 -20
- package/framework/.claude/skills/simplify/SKILL.md +22 -12
- package/framework/.claude/skills/ui-design/SKILL.md +26 -7
- package/framework/.claude/skills/webapp-testing/SKILL.md +6 -4
- package/framework/.claude/skills/worktree-manager/SKILL.md +206 -143
- package/framework/agents/coding-standards.md +85 -0
- package/framework/agents/index.md +2 -1
- package/framework/agents/skills-mapping.md +85 -82
- package/framework/agents/testing.md +28 -0
- package/framework/templates/baldart.config.template.yml +29 -7
- package/package.json +1 -1
- package/src/commands/configure.js +43 -9
- 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
|
-
###
|
|
30
|
+
### prd
|
|
27
31
|
|
|
28
32
|
**When to use**:
|
|
29
33
|
|
|
30
|
-
- Starting new
|
|
31
|
-
- Unclear requirements
|
|
32
|
-
- Multiple possible approaches
|
|
33
|
-
-
|
|
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
|
-
- "
|
|
38
|
-
- "
|
|
39
|
-
- "
|
|
40
|
-
- "How should I..."
|
|
41
|
+
- "Plan [feature]"
|
|
42
|
+
- "Crea un PRD"
|
|
43
|
+
- "Nuova funzionalità"
|
|
44
|
+
- "How should I scope..."
|
|
41
45
|
|
|
42
|
-
###
|
|
46
|
+
### context-primer
|
|
43
47
|
|
|
44
48
|
**When to use**:
|
|
45
49
|
|
|
46
|
-
-
|
|
47
|
-
-
|
|
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
|
-
-
|
|
53
|
-
-
|
|
54
|
-
- For documented requirements
|
|
55
|
+
- "/cont [keywords]"
|
|
56
|
+
- Auto-invoked by `/prd` at kickoff
|
|
55
57
|
|
|
56
|
-
###
|
|
58
|
+
### new
|
|
57
59
|
|
|
58
60
|
**When to use**:
|
|
59
61
|
|
|
60
|
-
- Implementing
|
|
61
|
-
-
|
|
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
|
-
-
|
|
67
|
-
-
|
|
68
|
-
-
|
|
67
|
+
- "/new CARD-IDS"
|
|
68
|
+
- "Implementa le card"
|
|
69
|
+
- "Esegui le card"
|
|
69
70
|
|
|
70
|
-
###
|
|
71
|
+
### bug
|
|
71
72
|
|
|
72
73
|
**When to use**:
|
|
73
74
|
|
|
74
75
|
- Bug investigation
|
|
75
|
-
- Test failures
|
|
76
|
-
-
|
|
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
|
-
###
|
|
87
|
+
### simplify
|
|
87
88
|
|
|
88
89
|
**When to use**:
|
|
89
90
|
|
|
90
|
-
-
|
|
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
|
-
-
|
|
97
|
-
-
|
|
98
|
-
-
|
|
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
|
-
-
|
|
111
|
-
-
|
|
112
|
-
|
|
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-
|
|
120
|
+
### ui-design
|
|
131
121
|
|
|
132
122
|
**When to use**:
|
|
133
123
|
|
|
134
|
-
-
|
|
135
|
-
-
|
|
136
|
-
-
|
|
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
|
-
-
|
|
141
|
-
-
|
|
142
|
-
- Design system
|
|
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-
|
|
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
|
-
-
|
|
181
|
-
-
|
|
182
|
-
- User-facing content
|
|
187
|
+
- User-facing content, marketing copy, microcopy
|
|
188
|
+
- Tone/voice refinement
|
|
183
189
|
|
|
184
190
|
**Triggers**:
|
|
185
191
|
|
|
186
|
-
-
|
|
187
|
-
-
|
|
188
|
-
-
|
|
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/
|
|
211
|
-
|-- YES -->
|
|
212
|
-
| Then
|
|
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 -->
|
|
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 -->
|
|
226
|
+
|-- YES --> /ui-design (mockups/options) or frontend-design
|
|
224
227
|
|
|
|
225
228
|
v
|
|
226
229
|
Is it browser testing?
|
|
227
|
-
|-- YES -->
|
|
230
|
+
|-- YES --> playwright-skill or webapp-testing (E2E via /e2e-review)
|
|
228
231
|
|
|
|
229
232
|
v
|
|
230
|
-
Is
|
|
231
|
-
|-- YES -->
|
|
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
|
-
-
|
|
245
|
+
- /prd → /new (the orchestrator runs `code-reviewer` + `qa-sentinel` gates per card)
|
|
244
246
|
|
|
245
247
|
2. **Bug Fix**:
|
|
246
|
-
-
|
|
248
|
+
- /bug → (fix lands through the bug skill's verify phase)
|
|
247
249
|
|
|
248
250
|
3. **UI Feature**:
|
|
249
|
-
-
|
|
251
|
+
- /prd → /ui-design → /new → playwright-skill (or /e2e-review for blocking E2E)
|
|
250
252
|
|
|
251
253
|
4. **Refactoring**:
|
|
252
|
-
-
|
|
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
|
|
260
|
+
- Skip `/prd` scoping for "simple" multi-part features
|
|
259
261
|
- Start coding before planning
|
|
260
|
-
- Skip
|
|
261
|
-
-
|
|
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
|
|
218
|
+
# branch back into the integration trunk.
|
|
203
219
|
git:
|
|
204
|
-
#
|
|
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
|
|
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
|
|
211
|
-
# fast-forward push the feature branch directly to
|
|
212
|
-
#
|
|
213
|
-
# No PR, no `gh` dependency. FAILS hard if
|
|
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
|
@@ -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/
|
|
58
|
-
return { value: 'pr', protected: true, reason:
|
|
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
|
|
63
|
-
return { value: 'local-push', protected: false, reason:
|
|
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:
|
|
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
|
|
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
|
|
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
|
|