@joshski/dust 0.1.93 → 0.1.95
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/dist/artifacts/index.d.ts +18 -11
- package/dist/artifacts/workflow-tasks.d.ts +4 -1
- package/dist/artifacts.js +114 -104
- package/dist/audits/checks-audit.d.ts +55 -0
- package/dist/audits.js +1641 -132
- package/dist/bucket/command-events-proxy.d.ts +1 -0
- package/dist/bucket/events.d.ts +7 -9
- package/dist/bucket/paths.d.ts +4 -12
- package/dist/bucket/repository-loop.d.ts +2 -1
- package/dist/bucket/repository.d.ts +8 -0
- package/dist/bucket/server-messages.d.ts +1 -0
- package/dist/bucket/tool-prompt.d.ts +10 -1
- package/dist/cli/commands/next.d.ts +6 -0
- package/dist/cli/types.d.ts +2 -0
- package/dist/config/settings.d.ts +4 -3
- package/dist/dust.js +4429 -2489
- package/dist/env-config.d.ts +103 -0
- package/dist/logging/index.d.ts +20 -1
- package/dist/logging.js +19 -10
- package/dist/loop/events.d.ts +52 -0
- package/dist/loop/git-pull.d.ts +9 -0
- package/dist/loop/iteration.d.ts +42 -0
- package/dist/loop/wire-events.d.ts +5 -0
- package/dist/proxy/claude-api-proxy.d.ts +28 -0
- package/dist/session.d.ts +4 -2
- package/dist/validation/index.d.ts +4 -1
- package/dist/validation.js +61 -33
- package/lib/istanbul/minimal-reporter.cjs +1 -1
- package/package.json +2 -2
- package/dist/cli/commands/loop.d.ts +0 -118
- /package/dist/cli/{commands → shared}/agent-shared.d.ts +0 -0
package/dist/audits.js
CHANGED
|
@@ -62,6 +62,94 @@ function dedent(strings, ...values) {
|
|
|
62
62
|
`).trim();
|
|
63
63
|
}
|
|
64
64
|
|
|
65
|
+
// lib/audits/checks-audit.ts
|
|
66
|
+
function checksAuditTemplate() {
|
|
67
|
+
return dedent`
|
|
68
|
+
# Checks Audit
|
|
69
|
+
|
|
70
|
+
Analyze the project's technology ecosystem and suggest appropriate checks for \`.dust/config/settings.json\`.
|
|
71
|
+
|
|
72
|
+
## Scope
|
|
73
|
+
|
|
74
|
+
This audit examines the project structure to identify:
|
|
75
|
+
|
|
76
|
+
1. **Tech stack detection** - Identify languages, frameworks, and tools based on config files
|
|
77
|
+
2. **Existing checks review** - Read \`.dust/config/settings.json\` to understand current coverage
|
|
78
|
+
3. **CI configuration analysis** - Parse CI configs to find checks that run in CI but not locally
|
|
79
|
+
4. **Gap identification** - Compare configured checks against what's appropriate for the detected stack
|
|
80
|
+
|
|
81
|
+
## Check Categories to Evaluate
|
|
82
|
+
|
|
83
|
+
For each detected ecosystem, consider these categories:
|
|
84
|
+
|
|
85
|
+
### JavaScript/TypeScript
|
|
86
|
+
- Linting (ESLint, oxlint, Biome)
|
|
87
|
+
- Formatting (Prettier, oxfmt, Biome)
|
|
88
|
+
- Type checking (tsc)
|
|
89
|
+
- Build verification
|
|
90
|
+
- Unit tests (Vitest, Jest)
|
|
91
|
+
- Unused code detection (Knip)
|
|
92
|
+
|
|
93
|
+
### Python
|
|
94
|
+
- Linting (Ruff, Pylint, Flake8)
|
|
95
|
+
- Formatting (Ruff, Black)
|
|
96
|
+
- Type checking (mypy, pyright)
|
|
97
|
+
- Unit tests (pytest)
|
|
98
|
+
|
|
99
|
+
### Go
|
|
100
|
+
- Linting (golangci-lint)
|
|
101
|
+
- Formatting (gofmt)
|
|
102
|
+
- Build verification
|
|
103
|
+
- Unit tests
|
|
104
|
+
- Vetting (go vet)
|
|
105
|
+
|
|
106
|
+
### Rust
|
|
107
|
+
- Linting (Clippy)
|
|
108
|
+
- Formatting (rustfmt)
|
|
109
|
+
- Build verification
|
|
110
|
+
- Unit tests
|
|
111
|
+
|
|
112
|
+
## Analysis Steps
|
|
113
|
+
|
|
114
|
+
1. List all config files in the repository root to detect tech stack
|
|
115
|
+
2. Read \`.dust/config/settings.json\` to identify configured checks
|
|
116
|
+
3. Search for CI configuration files and parse them for check commands
|
|
117
|
+
4. For each missing check category, create an idea file proposing it
|
|
118
|
+
5. If CI has checks not in dust config, note the discrepancy
|
|
119
|
+
|
|
120
|
+
## Output
|
|
121
|
+
|
|
122
|
+
Create separate idea files for each missing check category. Each idea should include:
|
|
123
|
+
- The detected stack indicators
|
|
124
|
+
- The suggested check command
|
|
125
|
+
- Alternative tool options
|
|
126
|
+
- Configuration snippet for settings.json
|
|
127
|
+
|
|
128
|
+
When multiple ecosystems are detected, create separate ideas for each ecosystem's checks.
|
|
129
|
+
|
|
130
|
+
## Principles
|
|
131
|
+
|
|
132
|
+
- [Batteries Included](../principles/batteries-included.md) - Dust should provide everything required for an agent to be productive
|
|
133
|
+
- [Easy Adoption](../principles/easy-adoption.md) - Help users configure checks without deep research into each tool
|
|
134
|
+
- [Stop the Line](../principles/stop-the-line.md) - Comprehensive checks catch problems at source
|
|
135
|
+
- [Lint Everything](../principles/lint-everything.md) - Static analysis should cover as much as possible
|
|
136
|
+
- [Comprehensive Test Coverage](../principles/comprehensive-test-coverage.md) - Tests are critical for agent confidence
|
|
137
|
+
|
|
138
|
+
## Blocked By
|
|
139
|
+
|
|
140
|
+
(none)
|
|
141
|
+
|
|
142
|
+
## Definition of Done
|
|
143
|
+
|
|
144
|
+
- [ ] Identified all tech stack indicators in the project
|
|
145
|
+
- [ ] Reviewed existing checks in settings.json
|
|
146
|
+
- [ ] Parsed CI configuration files for check commands
|
|
147
|
+
- [ ] Created ideas for each missing check category
|
|
148
|
+
- [ ] For multi-ecosystem projects, created separate ideas per ecosystem
|
|
149
|
+
- [ ] Each idea includes suggested command and alternatives
|
|
150
|
+
`;
|
|
151
|
+
}
|
|
152
|
+
|
|
65
153
|
// lib/audits/stock-audits.ts
|
|
66
154
|
var ideasHint = "Review existing ideas in `./.dust/ideas/` to understand what has been proposed or considered historically, then create new idea files in `./.dust/ideas/` for any issues you identify, avoiding duplication.";
|
|
67
155
|
function dataAccessReview() {
|
|
@@ -113,13 +201,13 @@ function dataAccessReview() {
|
|
|
113
201
|
|
|
114
202
|
## Definition of Done
|
|
115
203
|
|
|
116
|
-
-
|
|
117
|
-
-
|
|
118
|
-
-
|
|
119
|
-
-
|
|
120
|
-
-
|
|
121
|
-
-
|
|
122
|
-
-
|
|
204
|
+
- Searched for N+1 query patterns (loops with data access)
|
|
205
|
+
- Reviewed database schemas for missing indexes (if applicable)
|
|
206
|
+
- Identified over-fetching or under-fetching patterns
|
|
207
|
+
- Found repeated lookups that could be cached
|
|
208
|
+
- Checked for sequential operations that could be batched
|
|
209
|
+
- Verified connection/resource cleanup is handled properly
|
|
210
|
+
- Proposed ideas for any data access improvements identified
|
|
123
211
|
`;
|
|
124
212
|
}
|
|
125
213
|
function coverageExclusions() {
|
|
@@ -153,11 +241,11 @@ function coverageExclusions() {
|
|
|
153
241
|
|
|
154
242
|
## Definition of Done
|
|
155
243
|
|
|
156
|
-
-
|
|
157
|
-
-
|
|
158
|
-
-
|
|
159
|
-
-
|
|
160
|
-
-
|
|
244
|
+
- Identified all coverage exclusions in the project
|
|
245
|
+
- Documented the reason each exclusion exists
|
|
246
|
+
- Evaluated whether each exclusion is still necessary
|
|
247
|
+
- Identified exclusions that could be removed through decoupling
|
|
248
|
+
- Proposed ideas for refactoring where feasible
|
|
161
249
|
`;
|
|
162
250
|
}
|
|
163
251
|
function componentReuse() {
|
|
@@ -189,11 +277,11 @@ function componentReuse() {
|
|
|
189
277
|
|
|
190
278
|
## Definition of Done
|
|
191
279
|
|
|
192
|
-
-
|
|
193
|
-
-
|
|
194
|
-
-
|
|
195
|
-
-
|
|
196
|
-
-
|
|
280
|
+
- Searched for repeated patterns across the codebase
|
|
281
|
+
- Identified copy-pasted or near-duplicate code
|
|
282
|
+
- Evaluated each case for whether extraction would be beneficial
|
|
283
|
+
- Considered whether similar code serves different purposes that may evolve independently
|
|
284
|
+
- Proposed ideas only for extractions where duplication is truly about the same concept
|
|
197
285
|
`;
|
|
198
286
|
}
|
|
199
287
|
function agentDeveloperExperience() {
|
|
@@ -224,11 +312,182 @@ function agentDeveloperExperience() {
|
|
|
224
312
|
|
|
225
313
|
## Definition of Done
|
|
226
314
|
|
|
227
|
-
-
|
|
228
|
-
-
|
|
229
|
-
-
|
|
230
|
-
-
|
|
231
|
-
-
|
|
315
|
+
- Reviewed file sizes and organization for context window fit
|
|
316
|
+
- Verified test coverage is sufficient for agent verification
|
|
317
|
+
- Measured feedback loop speed (time from change to check result)
|
|
318
|
+
- Confirmed debugging tools and structured logging are in place
|
|
319
|
+
- Proposed ideas for any improvements identified
|
|
320
|
+
`;
|
|
321
|
+
}
|
|
322
|
+
function agentInstructionQuality() {
|
|
323
|
+
return dedent`
|
|
324
|
+
# Agent Instruction Quality
|
|
325
|
+
|
|
326
|
+
Review agent instruction files (AGENTS.md, CLAUDE.md) for clarity and completeness.
|
|
327
|
+
|
|
328
|
+
${ideasHint}
|
|
329
|
+
|
|
330
|
+
## Context
|
|
331
|
+
|
|
332
|
+
Agent instruction files directly impact agent effectiveness. Poor instructions lead to wasted context, confusion, and suboptimal decisions. This audit focuses on the instruction artifacts themselves.
|
|
333
|
+
|
|
334
|
+
## Scope
|
|
335
|
+
|
|
336
|
+
Focus on these areas:
|
|
337
|
+
|
|
338
|
+
1. **Contradictory instructions** - Find conflicting guidance across instruction files
|
|
339
|
+
2. **Stale references** - Identify instructions that reference removed code or features
|
|
340
|
+
3. **Missing context** - Detect areas where agents frequently need information not provided
|
|
341
|
+
4. **Verbose instructions** - Flag overly long sections that waste context window space
|
|
342
|
+
5. **Linter-replaceable rules** - Identify instructions that could be enforced by linter rules instead
|
|
343
|
+
|
|
344
|
+
## Analysis Steps
|
|
345
|
+
|
|
346
|
+
### 1. Locate Instruction Files
|
|
347
|
+
|
|
348
|
+
Search for agent instruction files:
|
|
349
|
+
- \`CLAUDE.md\` (Claude Code instructions)
|
|
350
|
+
- \`AGENTS.md\` (general agent instructions)
|
|
351
|
+
- \`.cursorrules\` (Cursor rules)
|
|
352
|
+
- \`copilot-instructions.md\` (GitHub Copilot instructions)
|
|
353
|
+
- Any other agent-specific configuration files
|
|
354
|
+
|
|
355
|
+
### 2. Check for Contradictory Instructions
|
|
356
|
+
|
|
357
|
+
For each instruction file:
|
|
358
|
+
1. Extract all directives, rules, and guidance statements
|
|
359
|
+
2. Compare against directives in other instruction files
|
|
360
|
+
3. Flag cases where:
|
|
361
|
+
- One file says "always do X" and another says "never do X"
|
|
362
|
+
- Instructions give conflicting guidance for the same scenario
|
|
363
|
+
- Priority or ordering conflicts exist
|
|
364
|
+
|
|
365
|
+
Example finding:
|
|
366
|
+
\`\`\`markdown
|
|
367
|
+
### Contradiction: Commit message format
|
|
368
|
+
- **CLAUDE.md:45** says "Use conventional commits (feat:, fix:, etc.)"
|
|
369
|
+
- **AGENTS.md:23** says "Use imperative mood without prefixes"
|
|
370
|
+
- **Impact**: Agents may produce inconsistent commit messages
|
|
371
|
+
- **Suggestion**: Align both files on a single commit message convention
|
|
372
|
+
\`\`\`
|
|
373
|
+
|
|
374
|
+
### 3. Detect Stale References
|
|
375
|
+
|
|
376
|
+
For each instruction file:
|
|
377
|
+
1. Extract references to files, functions, directories, or features
|
|
378
|
+
2. Verify each reference exists in the codebase
|
|
379
|
+
3. Flag references to:
|
|
380
|
+
- Deleted or renamed files/directories
|
|
381
|
+
- Removed functions, classes, or APIs
|
|
382
|
+
- Deprecated features or workflows
|
|
383
|
+
- Outdated tool names or commands
|
|
384
|
+
|
|
385
|
+
Example finding:
|
|
386
|
+
\`\`\`markdown
|
|
387
|
+
### Stale reference: src/legacy/parser.ts
|
|
388
|
+
- **Location**: CLAUDE.md:78
|
|
389
|
+
- **Instruction**: "Use the parser from src/legacy/parser.ts for..."
|
|
390
|
+
- **Reality**: src/legacy/ directory was removed in commit abc123
|
|
391
|
+
- **Impact**: Agents will fail to follow this instruction
|
|
392
|
+
- **Suggestion**: Update to reference the new parser location
|
|
393
|
+
\`\`\`
|
|
394
|
+
|
|
395
|
+
### 4. Identify Missing Context
|
|
396
|
+
|
|
397
|
+
Review instruction files for gaps:
|
|
398
|
+
1. Check if common agent tasks are covered (setup, testing, deployment)
|
|
399
|
+
2. Look for areas where instructions assume knowledge not documented
|
|
400
|
+
3. Identify patterns where agents might need guidance but none exists
|
|
401
|
+
4. Consider what questions a new agent would have that aren't answered
|
|
402
|
+
|
|
403
|
+
Signals of missing context:
|
|
404
|
+
- Instructions reference concepts without explanation
|
|
405
|
+
- Workflows have steps that require undocumented knowledge
|
|
406
|
+
- Common failure modes have no troubleshooting guidance
|
|
407
|
+
|
|
408
|
+
Example finding:
|
|
409
|
+
\`\`\`markdown
|
|
410
|
+
### Missing context: Environment setup
|
|
411
|
+
- **Gap**: No instructions for required environment variables
|
|
412
|
+
- **Impact**: Agents may fail setup or produce incorrect configuration
|
|
413
|
+
- **Suggestion**: Add section documenting required env vars and their purpose
|
|
414
|
+
\`\`\`
|
|
415
|
+
|
|
416
|
+
### 5. Flag Verbose Sections
|
|
417
|
+
|
|
418
|
+
Analyze instruction file sections for efficiency:
|
|
419
|
+
1. Measure section lengths (line count, word count)
|
|
420
|
+
2. Flag sections over 50 lines that could be condensed
|
|
421
|
+
3. Identify redundant explanations or excessive examples
|
|
422
|
+
4. Look for sections that repeat information found elsewhere
|
|
423
|
+
|
|
424
|
+
Verbosity signals:
|
|
425
|
+
- Multiple examples where one would suffice
|
|
426
|
+
- Lengthy explanations of concepts that could be linked
|
|
427
|
+
- Repeated disclaimers or caveats
|
|
428
|
+
- Inline documentation that duplicates code comments
|
|
429
|
+
|
|
430
|
+
Example finding:
|
|
431
|
+
\`\`\`markdown
|
|
432
|
+
### Verbose: Testing guidelines
|
|
433
|
+
- **Location**: CLAUDE.md:120-220 (100 lines)
|
|
434
|
+
- **Issue**: Includes 15 code examples; 3 would suffice
|
|
435
|
+
- **Context cost**: ~2000 tokens that could be reclaimed
|
|
436
|
+
- **Suggestion**: Condense to key patterns, link to test files for examples
|
|
437
|
+
\`\`\`
|
|
438
|
+
|
|
439
|
+
### 6. Find Linter-Replaceable Rules
|
|
440
|
+
|
|
441
|
+
Identify instructions that describe rules enforceable by static analysis:
|
|
442
|
+
1. Search for instructions about code formatting (spacing, quotes, semicolons)
|
|
443
|
+
2. Look for naming convention rules (camelCase, PascalCase, etc.)
|
|
444
|
+
3. Find import ordering or organization requirements
|
|
445
|
+
4. Identify type annotation requirements
|
|
446
|
+
|
|
447
|
+
For each candidate:
|
|
448
|
+
- Verify whether an ESLint, Biome, or similar rule exists
|
|
449
|
+
- Check if the rule is already configured in the project
|
|
450
|
+
- If not configured, recommend adding the linter rule
|
|
451
|
+
|
|
452
|
+
Example finding:
|
|
453
|
+
\`\`\`markdown
|
|
454
|
+
### Linter-replaceable: Import ordering
|
|
455
|
+
- **Location**: CLAUDE.md:34
|
|
456
|
+
- **Instruction**: "Always order imports: external, then internal, then relative"
|
|
457
|
+
- **Linter rule**: \`import/order\` or \`@ianvs/prettier-plugin-sort-imports\`
|
|
458
|
+
- **Current state**: Not configured in .eslintrc
|
|
459
|
+
- **Suggestion**: Add linter rule to enforce automatically
|
|
460
|
+
\`\`\`
|
|
461
|
+
|
|
462
|
+
## Output
|
|
463
|
+
|
|
464
|
+
For each issue found, document:
|
|
465
|
+
- **Location** - File path and section/line number
|
|
466
|
+
- **Type** - One of: contradictory, stale, missing, verbose, linter-replaceable
|
|
467
|
+
- **Impact** - How this affects agent effectiveness
|
|
468
|
+
- **Suggested improvement** - Specific fix or action
|
|
469
|
+
|
|
470
|
+
## Principles
|
|
471
|
+
|
|
472
|
+
- [Agent Autonomy](../principles/agent-autonomy.md) - Clear instructions enable autonomous work
|
|
473
|
+
- [Context Window Efficiency](../principles/context-window-efficiency.md) - Concise instructions leave room for reasoning
|
|
474
|
+
- [Actionable Errors](../principles/actionable-errors.md) - Instructions should guide agents toward correct actions
|
|
475
|
+
- [Lint Everything](../principles/lint-everything.md) - Prefer static analysis over runtime guidance where possible
|
|
476
|
+
|
|
477
|
+
## Blocked By
|
|
478
|
+
|
|
479
|
+
(none)
|
|
480
|
+
|
|
481
|
+
## Definition of Done
|
|
482
|
+
|
|
483
|
+
- [ ] Located all agent instruction files in the repository
|
|
484
|
+
- [ ] Reviewed for contradictory instructions across files
|
|
485
|
+
- [ ] Checked all file/code references for staleness
|
|
486
|
+
- [ ] Identified gaps where context is missing
|
|
487
|
+
- [ ] Flagged verbose sections that waste context window space
|
|
488
|
+
- [ ] Found instructions that could be replaced by linter rules
|
|
489
|
+
- [ ] Documented each issue with location, type, impact, and suggestion
|
|
490
|
+
- [ ] Created ideas for substantial instruction improvements
|
|
232
491
|
`;
|
|
233
492
|
}
|
|
234
493
|
function deadCode() {
|
|
@@ -259,13 +518,132 @@ function deadCode() {
|
|
|
259
518
|
|
|
260
519
|
## Definition of Done
|
|
261
520
|
|
|
262
|
-
-
|
|
263
|
-
-
|
|
264
|
-
-
|
|
265
|
-
-
|
|
266
|
-
-
|
|
267
|
-
-
|
|
268
|
-
-
|
|
521
|
+
- Ran static analysis tools to find unused exports
|
|
522
|
+
- Identified files with no incoming imports
|
|
523
|
+
- Listed unused dependencies
|
|
524
|
+
- Reviewed commented-out code blocks
|
|
525
|
+
- Created list of code safe to remove
|
|
526
|
+
- Verified removal won't break dynamic imports or reflection
|
|
527
|
+
- Proposed ideas for any dead code worth removing
|
|
528
|
+
`;
|
|
529
|
+
}
|
|
530
|
+
function documentationDrift() {
|
|
531
|
+
return dedent`
|
|
532
|
+
# Documentation Drift
|
|
533
|
+
|
|
534
|
+
Review code documentation for accuracy against current implementation.
|
|
535
|
+
|
|
536
|
+
${ideasHint}
|
|
537
|
+
|
|
538
|
+
## Context
|
|
539
|
+
|
|
540
|
+
Code-level documentation (JSDoc, README sections, inline comments) can drift from reality over time. Outdated docs mislead agents who may trust incorrect parameter descriptions, wrong return types, or stale code examples. This audit complements the facts-verification audit by focusing on code-level documentation rather than \`.dust/facts/\`.
|
|
541
|
+
|
|
542
|
+
## Scope
|
|
543
|
+
|
|
544
|
+
Focus on these areas:
|
|
545
|
+
|
|
546
|
+
1. **JSDoc descriptions** - Check if function descriptions match actual behavior
|
|
547
|
+
2. **Parameter documentation** - Identify docs for removed or renamed parameters
|
|
548
|
+
3. **Return type documentation** - Find return type docs that contradict actual types
|
|
549
|
+
4. **README code examples** - Verify that code examples compile and run
|
|
550
|
+
5. **Inline comments** - Review comments describing code that has changed
|
|
551
|
+
|
|
552
|
+
## Analysis Steps
|
|
553
|
+
|
|
554
|
+
### 1. JSDoc Description Accuracy
|
|
555
|
+
|
|
556
|
+
For key functions with JSDoc comments:
|
|
557
|
+
1. Read the JSDoc \`@description\` or opening sentence
|
|
558
|
+
2. Read the function implementation
|
|
559
|
+
3. Flag cases where the description doesn't match what the function actually does
|
|
560
|
+
4. Common drift patterns: descriptions that mention removed features, describe old algorithms, or omit new behavior
|
|
561
|
+
|
|
562
|
+
### 2. Parameter Documentation
|
|
563
|
+
|
|
564
|
+
For functions with \`@param\` documentation:
|
|
565
|
+
1. List all documented parameters
|
|
566
|
+
2. List all actual function parameters
|
|
567
|
+
3. Flag documented parameters that don't exist in the function signature
|
|
568
|
+
4. Flag actual parameters missing from documentation (if the function has any \`@param\` docs)
|
|
569
|
+
|
|
570
|
+
### 3. Return Type Documentation
|
|
571
|
+
|
|
572
|
+
For functions with \`@returns\` or \`@return\` documentation:
|
|
573
|
+
1. Read the documented return type and description
|
|
574
|
+
2. Check the actual return type (TypeScript type or inferred from implementation)
|
|
575
|
+
3. Flag mismatches between documented and actual return types
|
|
576
|
+
4. Flag return descriptions that don't match actual return behavior
|
|
577
|
+
|
|
578
|
+
### 4. README Code Examples
|
|
579
|
+
|
|
580
|
+
For code blocks in README.md and other documentation:
|
|
581
|
+
1. Extract code examples that appear to be runnable (not pseudocode)
|
|
582
|
+
2. Check if imports/requires reference files or modules that exist
|
|
583
|
+
3. Check if function calls use correct signatures
|
|
584
|
+
4. Flag examples that reference renamed or removed APIs
|
|
585
|
+
|
|
586
|
+
### 5. Inline Comment Review
|
|
587
|
+
|
|
588
|
+
For inline comments that describe specific code behavior:
|
|
589
|
+
1. Read the comment
|
|
590
|
+
2. Read the adjacent code
|
|
591
|
+
3. Flag comments where the described behavior doesn't match the implementation
|
|
592
|
+
4. Common patterns: "TODO" comments for work that's done, "HACK" comments for code that's been cleaned up
|
|
593
|
+
|
|
594
|
+
## Output
|
|
595
|
+
|
|
596
|
+
For each drift found, document:
|
|
597
|
+
|
|
598
|
+
- **Location** - File path and line number
|
|
599
|
+
- **What the documentation claims** - Quote or summarize the documentation
|
|
600
|
+
- **What the code actually does** - Describe the actual behavior
|
|
601
|
+
- **Suggested fix** - One of:
|
|
602
|
+
- \`update\` - Update the documentation to match the code
|
|
603
|
+
- \`remove\` - Remove stale documentation entirely
|
|
604
|
+
- \`add\` - Add missing documentation (only if partial docs exist)
|
|
605
|
+
|
|
606
|
+
Example findings:
|
|
607
|
+
|
|
608
|
+
\`\`\`markdown
|
|
609
|
+
### lib/parser.ts:42 - JSDoc description drift
|
|
610
|
+
|
|
611
|
+
- **Documentation claims**: "Parses the input string and returns an AST with source locations"
|
|
612
|
+
- **Code actually does**: Returns an AST without source locations (that feature was removed)
|
|
613
|
+
- **Fix**: update - Remove "with source locations" from the description
|
|
614
|
+
|
|
615
|
+
### README.md:156 - Stale code example
|
|
616
|
+
|
|
617
|
+
- **Documentation claims**: \`import { parseFile } from './lib/parser'\`
|
|
618
|
+
- **Code actually does**: \`parseFile\` was renamed to \`parse\`
|
|
619
|
+
- **Fix**: update - Change import to \`import { parse } from './lib/parser'\`
|
|
620
|
+
|
|
621
|
+
### lib/utils.ts:89 - Outdated inline comment
|
|
622
|
+
|
|
623
|
+
- **Documentation claims**: "// HACK: workaround for Node 14 bug"
|
|
624
|
+
- **Code actually does**: Clean implementation with no workaround; min Node version is now 18
|
|
625
|
+
- **Fix**: remove - Delete the obsolete comment
|
|
626
|
+
\`\`\`
|
|
627
|
+
|
|
628
|
+
## Principles
|
|
629
|
+
|
|
630
|
+
- [Agent Autonomy](../principles/agent-autonomy.md) - Accurate documentation enables agents to work without trial and error
|
|
631
|
+
- [Context Window Efficiency](../principles/context-window-efficiency.md) - Incorrect docs waste context on misleading information
|
|
632
|
+
- [Maintainable Codebase](../principles/maintainable-codebase.md) - Up-to-date documentation reduces maintenance burden
|
|
633
|
+
|
|
634
|
+
## Blocked By
|
|
635
|
+
|
|
636
|
+
(none)
|
|
637
|
+
|
|
638
|
+
## Definition of Done
|
|
639
|
+
|
|
640
|
+
- [ ] Reviewed JSDoc descriptions for accuracy against function behavior
|
|
641
|
+
- [ ] Checked parameter documentation for removed or renamed parameters
|
|
642
|
+
- [ ] Verified return type documentation matches actual return types
|
|
643
|
+
- [ ] Tested README code examples for correctness (imports, function signatures)
|
|
644
|
+
- [ ] Reviewed inline comments for outdated descriptions
|
|
645
|
+
- [ ] Documented each drift finding with location, claim, reality, and suggested fix
|
|
646
|
+
- [ ] Created ideas for any substantial documentation updates needed
|
|
269
647
|
`;
|
|
270
648
|
}
|
|
271
649
|
function factsVerification() {
|
|
@@ -295,12 +673,155 @@ function factsVerification() {
|
|
|
295
673
|
|
|
296
674
|
## Definition of Done
|
|
297
675
|
|
|
298
|
-
-
|
|
299
|
-
-
|
|
300
|
-
-
|
|
301
|
-
-
|
|
302
|
-
-
|
|
303
|
-
-
|
|
676
|
+
- Read each fact file in \`.dust/facts/\`
|
|
677
|
+
- Verified each fact against current codebase
|
|
678
|
+
- Identified outdated or inaccurate facts
|
|
679
|
+
- Listed missing facts that would help agents
|
|
680
|
+
- Updated or removed stale facts
|
|
681
|
+
- Proposed ideas for any facts improvements needed
|
|
682
|
+
`;
|
|
683
|
+
}
|
|
684
|
+
function feedbackLoopSpeed() {
|
|
685
|
+
return dedent`
|
|
686
|
+
# Feedback Loop Speed
|
|
687
|
+
|
|
688
|
+
Measure and report on check/test execution times to identify bottlenecks.
|
|
689
|
+
|
|
690
|
+
${ideasHint}
|
|
691
|
+
|
|
692
|
+
## Context
|
|
693
|
+
|
|
694
|
+
The [Fast Feedback Loops](../principles/fast-feedback-loops.md) principle emphasizes that the primary feedback loop—write code, run checks, see results—should be as fast as possible. Agents especially benefit because they operate in tight loops of change-and-verify; slow feedback wastes tokens and context window space on waiting rather than working.
|
|
695
|
+
|
|
696
|
+
This audit focuses specifically on measuring the development feedback loop speed to help identify which checks consume the most time.
|
|
697
|
+
|
|
698
|
+
## Scope
|
|
699
|
+
|
|
700
|
+
Measure timing data for each component of the feedback loop:
|
|
701
|
+
|
|
702
|
+
1. **\`dust check\` total time** - Aggregate time for all checks
|
|
703
|
+
2. **Per-check breakdown** - Time spent on each individual check configured in \`dust check\`
|
|
704
|
+
3. **Test suite execution time** - Total time and identification of slowest individual tests
|
|
705
|
+
4. **Type checking duration** - Time spent on TypeScript/type checking
|
|
706
|
+
5. **Linting duration** - Time spent on lint checks
|
|
707
|
+
6. **Build time** - Time to compile/bundle if applicable
|
|
708
|
+
|
|
709
|
+
## Analysis Steps
|
|
710
|
+
|
|
711
|
+
### 1. Measure \`dust check\` Timing
|
|
712
|
+
|
|
713
|
+
Run \`dust check\` and capture timing for each check:
|
|
714
|
+
|
|
715
|
+
\`\`\`bash
|
|
716
|
+
time bin/dust check
|
|
717
|
+
\`\`\`
|
|
718
|
+
|
|
719
|
+
Alternatively, if the output shows timing per check, extract those values.
|
|
720
|
+
|
|
721
|
+
### 2. Measure Test Suite Timing
|
|
722
|
+
|
|
723
|
+
Depending on the test framework:
|
|
724
|
+
|
|
725
|
+
- **Vitest**: Run \`npx vitest run --reporter=verbose\` to see per-test timing
|
|
726
|
+
- **Jest**: Run \`jest --verbose\` or \`jest --json\` for timing data
|
|
727
|
+
- **Bun test**: Run \`bun test --verbose\` and parse output
|
|
728
|
+
- **Other frameworks**: Use the framework's timing/verbose output option
|
|
729
|
+
|
|
730
|
+
Identify the slowest individual tests by duration.
|
|
731
|
+
|
|
732
|
+
### 3. Measure Type Checking Duration
|
|
733
|
+
|
|
734
|
+
\`\`\`bash
|
|
735
|
+
time npx tsc --noEmit
|
|
736
|
+
\`\`\`
|
|
737
|
+
|
|
738
|
+
### 4. Measure Linting Duration
|
|
739
|
+
|
|
740
|
+
\`\`\`bash
|
|
741
|
+
time npx eslint .
|
|
742
|
+
# or
|
|
743
|
+
time npx oxlint .
|
|
744
|
+
\`\`\`
|
|
745
|
+
|
|
746
|
+
### 5. Measure Build Time (if applicable)
|
|
747
|
+
|
|
748
|
+
\`\`\`bash
|
|
749
|
+
time npm run build
|
|
750
|
+
# or
|
|
751
|
+
time bun run build
|
|
752
|
+
\`\`\`
|
|
753
|
+
|
|
754
|
+
### 6. Calculate Time Distribution
|
|
755
|
+
|
|
756
|
+
For each check, calculate:
|
|
757
|
+
- Absolute duration (seconds)
|
|
758
|
+
- Percentage of total \`dust check\` time
|
|
759
|
+
- Flag checks consuming >30% of total time as dominant
|
|
760
|
+
|
|
761
|
+
## Output
|
|
762
|
+
|
|
763
|
+
Report timing data in a structured format:
|
|
764
|
+
|
|
765
|
+
### Summary
|
|
766
|
+
|
|
767
|
+
| Check | Duration | % of Total |
|
|
768
|
+
|-------|----------|------------|
|
|
769
|
+
| lint | 2.1s | 12% |
|
|
770
|
+
| typecheck | 4.5s | 26% |
|
|
771
|
+
| tests | 8.3s | 48% |
|
|
772
|
+
| build | 2.4s | 14% |
|
|
773
|
+
| **Total** | **17.3s** | **100%** |
|
|
774
|
+
|
|
775
|
+
### Dominant Checks
|
|
776
|
+
|
|
777
|
+
Flag any check that consumes a disproportionate amount of time (>30% of total):
|
|
778
|
+
|
|
779
|
+
- **tests** (48% of total) - Consider investigating slow tests
|
|
780
|
+
- See the \`slow-tests\` audit for detailed test timing analysis
|
|
781
|
+
|
|
782
|
+
### Slowest Individual Tests
|
|
783
|
+
|
|
784
|
+
List the top 5 slowest tests:
|
|
785
|
+
|
|
786
|
+
| Test | Duration |
|
|
787
|
+
|------|----------|
|
|
788
|
+
| "integration: full workflow" | 3.2s |
|
|
789
|
+
| "parses large file" | 1.8s |
|
|
790
|
+
| ... | ... |
|
|
791
|
+
|
|
792
|
+
## Interpretation Guidelines
|
|
793
|
+
|
|
794
|
+
This audit reports raw timing data without prescribing specific thresholds. Different projects have different acceptable speeds depending on:
|
|
795
|
+
|
|
796
|
+
- Codebase size
|
|
797
|
+
- Team workflow (local vs CI-heavy)
|
|
798
|
+
- Test strategy (unit-heavy vs integration-heavy)
|
|
799
|
+
|
|
800
|
+
Use the data to:
|
|
801
|
+
- Identify which checks to optimize first
|
|
802
|
+
- Track feedback loop speed over time
|
|
803
|
+
- Make informed decisions about parallelization or caching
|
|
804
|
+
|
|
805
|
+
## Principles
|
|
806
|
+
|
|
807
|
+
- [Fast Feedback Loops](../principles/fast-feedback-loops.md) - Directly measures feedback loop speed
|
|
808
|
+
- [Fast Feedback](../principles/fast-feedback.md) - Identifies bottlenecks in feedback delivery
|
|
809
|
+
- [Agent Autonomy](../principles/agent-autonomy.md) - Faster feedback means agents can iterate more within context limits
|
|
810
|
+
|
|
811
|
+
## Blocked By
|
|
812
|
+
|
|
813
|
+
(none)
|
|
814
|
+
|
|
815
|
+
## Definition of Done
|
|
816
|
+
|
|
817
|
+
- [ ] Measured total \`dust check\` execution time
|
|
818
|
+
- [ ] Measured time for each individual check (lint, typecheck, tests, build, etc.)
|
|
819
|
+
- [ ] Identified test suite total execution time
|
|
820
|
+
- [ ] Identified slowest individual tests (top 5)
|
|
821
|
+
- [ ] Calculated percentage of total time for each check
|
|
822
|
+
- [ ] Flagged dominant checks (>30% of total time)
|
|
823
|
+
- [ ] Documented findings in summary table format
|
|
824
|
+
- [ ] Created ideas for any feedback loop speed improvements identified
|
|
304
825
|
`;
|
|
305
826
|
}
|
|
306
827
|
function ideasFromCommits() {
|
|
@@ -330,11 +851,11 @@ function ideasFromCommits() {
|
|
|
330
851
|
|
|
331
852
|
## Definition of Done
|
|
332
853
|
|
|
333
|
-
-
|
|
334
|
-
-
|
|
335
|
-
-
|
|
336
|
-
-
|
|
337
|
-
-
|
|
854
|
+
- Reviewed commits from the last 20 commits
|
|
855
|
+
- Identified patterns or shortcuts worth addressing
|
|
856
|
+
- Listed TODO comments added in recent commits
|
|
857
|
+
- Noted areas where changes could be generalized
|
|
858
|
+
- Proposed follow-up ideas for any issues identified
|
|
338
859
|
`;
|
|
339
860
|
}
|
|
340
861
|
function ideasFromPrinciples() {
|
|
@@ -364,10 +885,10 @@ function ideasFromPrinciples() {
|
|
|
364
885
|
|
|
365
886
|
## Definition of Done
|
|
366
887
|
|
|
367
|
-
-
|
|
368
|
-
-
|
|
369
|
-
-
|
|
370
|
-
-
|
|
888
|
+
- Read each principle file in \`.dust/principles/\`
|
|
889
|
+
- Analyzed codebase for alignment with each principle
|
|
890
|
+
- Listed gaps between current state and principle intent
|
|
891
|
+
- Proposed new ideas for unmet or underserved principles
|
|
371
892
|
`;
|
|
372
893
|
}
|
|
373
894
|
function refactoringOpportunities() {
|
|
@@ -413,11 +934,11 @@ function refactoringOpportunities() {
|
|
|
413
934
|
|
|
414
935
|
## Definition of Done
|
|
415
936
|
|
|
416
|
-
-
|
|
417
|
-
-
|
|
418
|
-
-
|
|
419
|
-
-
|
|
420
|
-
-
|
|
937
|
+
- Identified high-churn files (modified in 3+ commits since last audit)
|
|
938
|
+
- Flagged files exceeding 300 lines that grew significantly
|
|
939
|
+
- Noted commits with concerning message patterns
|
|
940
|
+
- Provided specific refactoring suggestions for each opportunity
|
|
941
|
+
- Created ideas for any substantial refactoring work identified
|
|
421
942
|
`;
|
|
422
943
|
}
|
|
423
944
|
function performanceReview() {
|
|
@@ -448,11 +969,11 @@ function performanceReview() {
|
|
|
448
969
|
|
|
449
970
|
## Definition of Done
|
|
450
971
|
|
|
451
|
-
-
|
|
452
|
-
-
|
|
453
|
-
-
|
|
454
|
-
-
|
|
455
|
-
-
|
|
972
|
+
- Measured startup time for common commands
|
|
973
|
+
- Profiled memory usage during typical operations
|
|
974
|
+
- Identified slow commands or operations
|
|
975
|
+
- Listed optimization opportunities by impact
|
|
976
|
+
- Proposed ideas for any performance improvements identified
|
|
456
977
|
`;
|
|
457
978
|
}
|
|
458
979
|
function securityReview() {
|
|
@@ -483,13 +1004,13 @@ function securityReview() {
|
|
|
483
1004
|
|
|
484
1005
|
## Definition of Done
|
|
485
1006
|
|
|
486
|
-
-
|
|
487
|
-
-
|
|
488
|
-
-
|
|
489
|
-
-
|
|
490
|
-
-
|
|
491
|
-
-
|
|
492
|
-
-
|
|
1007
|
+
- Searched for hardcoded secrets (API keys, passwords, tokens)
|
|
1008
|
+
- Reviewed input validation and sanitization
|
|
1009
|
+
- Checked authentication and authorization logic
|
|
1010
|
+
- Verified sensitive data is not logged or exposed
|
|
1011
|
+
- Ran dependency audit for known vulnerabilities
|
|
1012
|
+
- Documented any findings with severity ratings
|
|
1013
|
+
- Proposed ideas for any security issues found
|
|
493
1014
|
`;
|
|
494
1015
|
}
|
|
495
1016
|
function staleIdeas() {
|
|
@@ -519,11 +1040,11 @@ function staleIdeas() {
|
|
|
519
1040
|
|
|
520
1041
|
## Definition of Done
|
|
521
1042
|
|
|
522
|
-
-
|
|
523
|
-
-
|
|
524
|
-
-
|
|
525
|
-
-
|
|
526
|
-
-
|
|
1043
|
+
- Listed all ideas with their last modification date
|
|
1044
|
+
- Identified ideas unchanged for 50+ commits
|
|
1045
|
+
- Reviewed each stale idea for current relevance
|
|
1046
|
+
- Promoted actionable ideas to tasks
|
|
1047
|
+
- Deleted ideas that are no longer relevant
|
|
527
1048
|
`;
|
|
528
1049
|
}
|
|
529
1050
|
function testCoverage() {
|
|
@@ -554,10 +1075,10 @@ function testCoverage() {
|
|
|
554
1075
|
|
|
555
1076
|
## Definition of Done
|
|
556
1077
|
|
|
557
|
-
-
|
|
558
|
-
-
|
|
559
|
-
-
|
|
560
|
-
-
|
|
1078
|
+
- Identified modules with low or no test coverage
|
|
1079
|
+
- Listed critical paths that lack tests
|
|
1080
|
+
- Prioritized areas by risk and importance
|
|
1081
|
+
- Proposed ideas for any test coverage gaps identified
|
|
561
1082
|
`;
|
|
562
1083
|
}
|
|
563
1084
|
function errorHandling() {
|
|
@@ -606,12 +1127,12 @@ function errorHandling() {
|
|
|
606
1127
|
|
|
607
1128
|
## Definition of Done
|
|
608
1129
|
|
|
609
|
-
-
|
|
610
|
-
-
|
|
611
|
-
-
|
|
612
|
-
-
|
|
613
|
-
-
|
|
614
|
-
-
|
|
1130
|
+
- Searched for empty catch blocks and silent error swallowing
|
|
1131
|
+
- Identified patterns that discard error details
|
|
1132
|
+
- Found fire-and-forget promises without error handling
|
|
1133
|
+
- Reviewed error messages for actionability
|
|
1134
|
+
- Compared error handling consistency across similar operations
|
|
1135
|
+
- Proposed ideas for any error handling improvements identified
|
|
615
1136
|
`;
|
|
616
1137
|
}
|
|
617
1138
|
function globalState() {
|
|
@@ -661,13 +1182,13 @@ function globalState() {
|
|
|
661
1182
|
|
|
662
1183
|
## Definition of Done
|
|
663
1184
|
|
|
664
|
-
-
|
|
665
|
-
-
|
|
666
|
-
-
|
|
667
|
-
-
|
|
668
|
-
-
|
|
669
|
-
-
|
|
670
|
-
-
|
|
1185
|
+
- Searched for module-level mutable variables (let/var outside functions)
|
|
1186
|
+
- Identified singleton patterns and getInstance methods
|
|
1187
|
+
- Found global registries (Maps, Sets, Arrays modified at module level)
|
|
1188
|
+
- Located functions with implicit dependencies on module-level state
|
|
1189
|
+
- Checked for scattered process.env access
|
|
1190
|
+
- Documented impact of each global state instance on testing
|
|
1191
|
+
- Proposed ideas for refactoring global state to explicit dependencies
|
|
671
1192
|
`;
|
|
672
1193
|
}
|
|
673
1194
|
function repositoryContext() {
|
|
@@ -711,12 +1232,12 @@ function repositoryContext() {
|
|
|
711
1232
|
|
|
712
1233
|
## Definition of Done
|
|
713
1234
|
|
|
714
|
-
-
|
|
715
|
-
-
|
|
716
|
-
-
|
|
717
|
-
-
|
|
718
|
-
-
|
|
719
|
-
-
|
|
1235
|
+
- \`.dust/repository.md\` exists and is up to date
|
|
1236
|
+
- Document describes what the project does without referencing specific files
|
|
1237
|
+
- Key capabilities and features are listed
|
|
1238
|
+
- Design philosophy or guiding approach is captured
|
|
1239
|
+
- Document is concise enough to fit comfortably in an agent context window
|
|
1240
|
+
- A new agent reading only this document could make sensible high-level suggestions
|
|
720
1241
|
`;
|
|
721
1242
|
}
|
|
722
1243
|
function slowTests() {
|
|
@@ -769,13 +1290,13 @@ function slowTests() {
|
|
|
769
1290
|
|
|
770
1291
|
## Definition of Done
|
|
771
1292
|
|
|
772
|
-
-
|
|
773
|
-
-
|
|
774
|
-
-
|
|
775
|
-
-
|
|
776
|
-
-
|
|
777
|
-
-
|
|
778
|
-
-
|
|
1293
|
+
- Ran test suite with timing information
|
|
1294
|
+
- Listed tests exceeding duration thresholds (100ms unit, 1s integration)
|
|
1295
|
+
- Identified tests using sleep/setTimeout/delay patterns
|
|
1296
|
+
- Found tests with unmocked I/O (network, database, file system)
|
|
1297
|
+
- Reviewed beforeEach/beforeAll for optimization opportunities
|
|
1298
|
+
- Checked test parallelization configuration
|
|
1299
|
+
- Proposed ideas for optimizing the slowest tests
|
|
779
1300
|
`;
|
|
780
1301
|
}
|
|
781
1302
|
function namingConsistency() {
|
|
@@ -826,13 +1347,13 @@ function namingConsistency() {
|
|
|
826
1347
|
|
|
827
1348
|
## Definition of Done
|
|
828
1349
|
|
|
829
|
-
-
|
|
830
|
-
-
|
|
831
|
-
-
|
|
832
|
-
-
|
|
833
|
-
-
|
|
834
|
-
-
|
|
835
|
-
-
|
|
1350
|
+
- Reviewed high-confidence factory/constructor naming consistency for equivalent creation APIs
|
|
1351
|
+
- Constrained findings to \`build*\`, \`create*\`, \`make*\`, and \`new*\` naming variants with clearly equivalent intent
|
|
1352
|
+
- Documented each finding with locations, inconsistent term set, canonical proposal, and migration strategy
|
|
1353
|
+
- Chose incremental or one-shot migration strategy for each canonical proposal
|
|
1354
|
+
- Avoided speculative broad renames
|
|
1355
|
+
- Avoided artifact-list ordering/shape checks and broad terminology drift
|
|
1356
|
+
- Proposed ideas for naming consistency improvements identified
|
|
836
1357
|
`;
|
|
837
1358
|
}
|
|
838
1359
|
function primitiveObsession() {
|
|
@@ -901,13 +1422,13 @@ function primitiveObsession() {
|
|
|
901
1422
|
|
|
902
1423
|
## Definition of Done
|
|
903
1424
|
|
|
904
|
-
-
|
|
905
|
-
-
|
|
906
|
-
-
|
|
907
|
-
-
|
|
908
|
-
-
|
|
909
|
-
-
|
|
910
|
-
-
|
|
1425
|
+
- Reviewed high-confidence existing-type drift for domain string literals and numeric magic values
|
|
1426
|
+
- Constrained findings to cases where canonical domain types or clear constant/wrapper opportunities already exist
|
|
1427
|
+
- Documented each finding with locations, primitive pattern, constant/type opportunity, and incremental migration path
|
|
1428
|
+
- Documented numeric findings with locations, numeric pattern, constant/type opportunity, and incremental migration path
|
|
1429
|
+
- Preserved Functional Core, Imperative Shell boundaries in recommendations
|
|
1430
|
+
- Avoided speculative introduction of entirely new types
|
|
1431
|
+
- Proposed ideas for primitive obsession improvements identified
|
|
911
1432
|
`;
|
|
912
1433
|
}
|
|
913
1434
|
function singleResponsibilityViolations() {
|
|
@@ -968,12 +1489,12 @@ function singleResponsibilityViolations() {
|
|
|
968
1489
|
|
|
969
1490
|
## Definition of Done
|
|
970
1491
|
|
|
971
|
-
-
|
|
972
|
-
-
|
|
973
|
-
-
|
|
974
|
-
-
|
|
975
|
-
-
|
|
976
|
-
-
|
|
1492
|
+
- Reviewed high-confidence function-level findings where 3+ distinct responsibilities are combined
|
|
1493
|
+
- Included runtime code and test helpers in scope
|
|
1494
|
+
- Documented each finding with location, responsibility split, severity, and suggested extraction plan
|
|
1495
|
+
- Preserved Functional Core, Imperative Shell boundaries in recommendations
|
|
1496
|
+
- Kept recommendations high-confidence only with clear concern boundaries
|
|
1497
|
+
- Proposed ideas for substantial responsibility-splitting work identified
|
|
977
1498
|
`;
|
|
978
1499
|
}
|
|
979
1500
|
function ubiquitousLanguage() {
|
|
@@ -1021,12 +1542,520 @@ function ubiquitousLanguage() {
|
|
|
1021
1542
|
|
|
1022
1543
|
## Definition of Done
|
|
1023
1544
|
|
|
1024
|
-
-
|
|
1025
|
-
-
|
|
1026
|
-
-
|
|
1027
|
-
-
|
|
1028
|
-
-
|
|
1029
|
-
-
|
|
1545
|
+
- Identified key domain terms from project documentation
|
|
1546
|
+
- Reviewed recent commits for terminology consistency
|
|
1547
|
+
- Compared code naming against documentation vocabulary
|
|
1548
|
+
- Checked user-facing text for alignment with code terms
|
|
1549
|
+
- Documented any terminology drift or inconsistencies found
|
|
1550
|
+
- Proposed ideas for standardizing inconsistent terminology
|
|
1551
|
+
`;
|
|
1552
|
+
}
|
|
1553
|
+
function designPatterns() {
|
|
1554
|
+
return dedent`
|
|
1555
|
+
# Design Patterns
|
|
1556
|
+
|
|
1557
|
+
Identify refactoring opportunities to recognized design patterns using code smell triggers.
|
|
1558
|
+
|
|
1559
|
+
${ideasHint}
|
|
1560
|
+
|
|
1561
|
+
## Scope
|
|
1562
|
+
|
|
1563
|
+
This audit surfaces opportunities to apply design patterns systematically using code smell triggers rather than structural heuristics. Use a low threshold for flagging patterns and let users filter relevance.
|
|
1564
|
+
|
|
1565
|
+
## Code Smell Triggers
|
|
1566
|
+
|
|
1567
|
+
Flag patterns based on code smells that suggest pattern opportunities:
|
|
1568
|
+
|
|
1569
|
+
1. **Switch statements on type** - Multiple switch/if-else chains branching on a type field suggest **Strategy** pattern (or discriminated unions in functional codebases)
|
|
1570
|
+
2. **Repeated object construction** - Similar multi-step object creation scattered across files suggests **Factory** pattern
|
|
1571
|
+
3. **Inconsistent interfaces** - Multiple implementations of similar behavior with different method signatures suggest interface **formalization**
|
|
1572
|
+
4. **Complex conditional creation logic** - Functions with many parameters or conditional object assembly suggest **Builder** pattern
|
|
1573
|
+
5. **State with multiple transitions** - Objects with mode/status fields and complex state transition logic suggest **State** pattern
|
|
1574
|
+
6. **Notification chains** - Manual event propagation or callback chains suggest **Observer** pattern
|
|
1575
|
+
|
|
1576
|
+
## Analysis Steps
|
|
1577
|
+
|
|
1578
|
+
1. Search for switch statements and if-else chains that branch on type/kind/mode fields
|
|
1579
|
+
2. Look for similar object construction patterns repeated across multiple files
|
|
1580
|
+
3. Identify classes/interfaces with inconsistent method signatures for similar operations
|
|
1581
|
+
4. Find functions with 4+ parameters for object creation or complex conditional assembly
|
|
1582
|
+
5. Search for status/state/mode fields with multiple transition conditions
|
|
1583
|
+
6. Look for manual notification or callback propagation patterns
|
|
1584
|
+
|
|
1585
|
+
## Output Per Finding
|
|
1586
|
+
|
|
1587
|
+
For each finding, provide:
|
|
1588
|
+
- **Location** - File and line range
|
|
1589
|
+
- **Code smell** - What triggered this recommendation (switch on type, repeated construction, etc.)
|
|
1590
|
+
- **Recommended pattern** - The suggested design pattern (Gang of Four name where applicable, or modern alternative)
|
|
1591
|
+
- **Trade-off analysis** - Pros (e.g., "Easier to add new types without modifying existing code") and cons (e.g., "Adds indirection, may be overkill for 2-3 cases")
|
|
1592
|
+
- **Migration complexity** - Low/Medium/High estimate with brief rationale
|
|
1593
|
+
|
|
1594
|
+
## Tech-Stack Considerations
|
|
1595
|
+
|
|
1596
|
+
- Mention Gang of Four patterns by name where applicable
|
|
1597
|
+
- Note when patterns may not apply:
|
|
1598
|
+
- **Strategy** is less relevant in functional codebases where functions are first-class
|
|
1599
|
+
- **Visitor** can often be replaced with discriminated unions and exhaustive pattern matching
|
|
1600
|
+
- **Observer** may be superseded by reactive frameworks or event emitters
|
|
1601
|
+
- Suggest modern alternatives where appropriate (e.g., discriminated unions, higher-order functions, dependency injection)
|
|
1602
|
+
|
|
1603
|
+
## Principles
|
|
1604
|
+
|
|
1605
|
+
- [Functional Core, Imperative Shell](../principles/functional-core-imperative-shell.md) - Preserve pure core and thin shell boundaries in recommendations
|
|
1606
|
+
- [Make the Change Easy](../principles/make-the-change-easy.md) - Pattern adoption should simplify future changes
|
|
1607
|
+
- [Decoupled Code](../principles/decoupled-code.md) - Patterns should reduce coupling, not add complexity
|
|
1608
|
+
- [Design for Testability](../principles/design-for-testability.md) - Pattern recommendations should improve testability
|
|
1609
|
+
|
|
1610
|
+
## Blocked By
|
|
1611
|
+
|
|
1612
|
+
(none)
|
|
1613
|
+
|
|
1614
|
+
## Definition of Done
|
|
1615
|
+
|
|
1616
|
+
- Searched for switch statements on type/kind/mode fields
|
|
1617
|
+
- Identified repeated object construction patterns
|
|
1618
|
+
- Found inconsistent interfaces for similar behavior
|
|
1619
|
+
- Located complex conditional creation logic
|
|
1620
|
+
- Searched for state fields with multiple transitions
|
|
1621
|
+
- Identified notification chain patterns
|
|
1622
|
+
- Documented each finding with location, code smell, recommended pattern, trade-offs, and migration complexity
|
|
1623
|
+
- Noted tech-stack considerations where Gang of Four patterns may or may not apply
|
|
1624
|
+
- Proposed ideas for any design pattern improvements identified
|
|
1625
|
+
`;
|
|
1626
|
+
}
|
|
1627
|
+
function testAssertions() {
|
|
1628
|
+
return dedent`
|
|
1629
|
+
# Test Assertions
|
|
1630
|
+
|
|
1631
|
+
Review test assertions for quality signals beyond comprehensive assertions.
|
|
1632
|
+
|
|
1633
|
+
${ideasHint}
|
|
1634
|
+
|
|
1635
|
+
## Background
|
|
1636
|
+
|
|
1637
|
+
The [Comprehensive Assertions](../principles/comprehensive-assertions.md) principle covers asserting whole objects rather than fragments. The [Self-Diagnosing Tests](../principles/self-diagnosing-tests.md) principle covers making failure messages informative. This audit addresses complementary assertion quality signals not covered by existing principles.
|
|
1638
|
+
|
|
1639
|
+
## Scope
|
|
1640
|
+
|
|
1641
|
+
### Deterministic Assertions
|
|
1642
|
+
|
|
1643
|
+
Assertions should produce the same result regardless of execution timing or environment. Anti-patterns include:
|
|
1644
|
+
|
|
1645
|
+
- Asserting on timestamps or dates without mocking time
|
|
1646
|
+
- Asserting on random values without seeding
|
|
1647
|
+
- Asserting on iteration order of unordered collections (objects, Sets, Maps)
|
|
1648
|
+
- Asserting on process IDs, file handles, or other system-allocated values
|
|
1649
|
+
|
|
1650
|
+
Example:
|
|
1651
|
+
\`\`\`javascript
|
|
1652
|
+
// Non-deterministic: order depends on JS engine
|
|
1653
|
+
expect(Object.keys(result)).toEqual(['a', 'b', 'c'])
|
|
1654
|
+
|
|
1655
|
+
// Deterministic: sort before comparison
|
|
1656
|
+
expect(Object.keys(result).sort()).toEqual(['a', 'b', 'c'])
|
|
1657
|
+
\`\`\`
|
|
1658
|
+
|
|
1659
|
+
### Fixed Delay Anti-patterns
|
|
1660
|
+
|
|
1661
|
+
Tests should not use arbitrary fixed delays (\`setTimeout\`, \`sleep\`) to wait for async operations. Fixed delays are:
|
|
1662
|
+
|
|
1663
|
+
- Flaky (may fail on slower machines or under load)
|
|
1664
|
+
- Slow (must wait the full delay even when the operation completes early)
|
|
1665
|
+
- Non-deterministic (timing varies across environments)
|
|
1666
|
+
|
|
1667
|
+
Instead, tests should:
|
|
1668
|
+
- Use promise resolution (\`await\`/\`.then()\`)
|
|
1669
|
+
- Poll with short intervals until a condition is met
|
|
1670
|
+
- Use test framework utilities (\`vi.useFakeTimers()\`, \`waitFor()\`)
|
|
1671
|
+
- Inject controllable time dependencies
|
|
1672
|
+
|
|
1673
|
+
Example:
|
|
1674
|
+
\`\`\`javascript
|
|
1675
|
+
// Bad: arbitrary 50ms delay
|
|
1676
|
+
await new Promise(r => setTimeout(r, 50))
|
|
1677
|
+
expect(state).toBe('ready')
|
|
1678
|
+
|
|
1679
|
+
// Better: wait for the condition
|
|
1680
|
+
await vi.waitFor(() => expect(state).toBe('ready'))
|
|
1681
|
+
|
|
1682
|
+
// Best: control time explicitly
|
|
1683
|
+
vi.useFakeTimers()
|
|
1684
|
+
vi.advanceTimersByTime(50)
|
|
1685
|
+
expect(state).toBe('ready')
|
|
1686
|
+
\`\`\`
|
|
1687
|
+
|
|
1688
|
+
### Precise but Not Exhaustive Assertions
|
|
1689
|
+
|
|
1690
|
+
Assertions should verify the behavior under test without over-constraining implementation details. Exhaustive assertions that check every property can:
|
|
1691
|
+
|
|
1692
|
+
- Couple tests tightly to implementation
|
|
1693
|
+
- Require test updates for unrelated changes
|
|
1694
|
+
- Obscure what the test is actually verifying
|
|
1695
|
+
|
|
1696
|
+
This works in tension with [Comprehensive Assertions](../principles/comprehensive-assertions.md). Let context determine the balance:
|
|
1697
|
+
- Public API contracts → comprehensive assertions
|
|
1698
|
+
- Internal implementation tests → precise assertions
|
|
1699
|
+
- Snapshot tests → consider \`toMatchSnapshot()\` with care
|
|
1700
|
+
|
|
1701
|
+
Example:
|
|
1702
|
+
\`\`\`javascript
|
|
1703
|
+
// Exhaustive: breaks if any internal field changes
|
|
1704
|
+
expect(result).toEqual({
|
|
1705
|
+
id: 'abc',
|
|
1706
|
+
name: 'test',
|
|
1707
|
+
_internal: {},
|
|
1708
|
+
_meta: { version: 1 },
|
|
1709
|
+
_cache: null,
|
|
1710
|
+
})
|
|
1711
|
+
|
|
1712
|
+
// Precise: verifies only the relevant properties
|
|
1713
|
+
expect(result).toMatchObject({
|
|
1714
|
+
id: 'abc',
|
|
1715
|
+
name: 'test',
|
|
1716
|
+
})
|
|
1717
|
+
\`\`\`
|
|
1718
|
+
|
|
1719
|
+
### One Logical Assertion Per Test
|
|
1720
|
+
|
|
1721
|
+
Tests should ideally verify one behavior or scenario. When a test has multiple unrelated assertions, a failure in the first masks all subsequent ones.
|
|
1722
|
+
|
|
1723
|
+
This does not mean "one \`expect\` call per test". A single logical assertion may require multiple \`expect\` calls to express (especially for complex state). The [Comprehensive Assertions](../principles/comprehensive-assertions.md) principle often allows collapsing multiple calls into one whole-object assertion.
|
|
1724
|
+
|
|
1725
|
+
The anti-pattern to avoid:
|
|
1726
|
+
\`\`\`javascript
|
|
1727
|
+
test('user validation', () => {
|
|
1728
|
+
// Multiple unrelated behaviors in one test
|
|
1729
|
+
expect(validateEmail('bad')).toBe(false)
|
|
1730
|
+
expect(validateEmail('good@example.com')).toBe(true)
|
|
1731
|
+
expect(validatePassword('short')).toBe(false)
|
|
1732
|
+
expect(validatePassword('LongEnough123!')).toBe(true)
|
|
1733
|
+
})
|
|
1734
|
+
\`\`\`
|
|
1735
|
+
|
|
1736
|
+
Prefer separate tests for separate behaviors:
|
|
1737
|
+
\`\`\`javascript
|
|
1738
|
+
test('rejects invalid email format', () => {
|
|
1739
|
+
expect(validateEmail('bad')).toBe(false)
|
|
1740
|
+
})
|
|
1741
|
+
|
|
1742
|
+
test('accepts valid email format', () => {
|
|
1743
|
+
expect(validateEmail('good@example.com')).toBe(true)
|
|
1744
|
+
})
|
|
1745
|
+
\`\`\`
|
|
1746
|
+
|
|
1747
|
+
## Analysis Steps
|
|
1748
|
+
|
|
1749
|
+
1. Search for assertions on \`Date.now()\`, \`new Date()\`, or timestamp fields without fake timers
|
|
1750
|
+
2. Look for assertions on \`Object.keys()\` or property iteration without sorting
|
|
1751
|
+
3. Find \`setTimeout\`, \`sleep\`, or fixed delays in test files
|
|
1752
|
+
4. Identify tests with many unrelated assertions covering multiple behaviors
|
|
1753
|
+
5. Review snapshot usage for overly broad snapshots that capture internal details
|
|
1754
|
+
6. Check for assertions on random or system-allocated values (PIDs, UUIDs without seeding)
|
|
1755
|
+
|
|
1756
|
+
## Output
|
|
1757
|
+
|
|
1758
|
+
For each finding, provide:
|
|
1759
|
+
- **Location** - File path and line number
|
|
1760
|
+
- **Pattern** - Which category of issue (non-deterministic, fixed delay, exhaustive, multiple behaviors)
|
|
1761
|
+
- **Impact** - How this affects test reliability or maintainability
|
|
1762
|
+
- **Suggestion** - Specific fix (sort keys, use fake timers, split test, use toMatchObject, etc.)
|
|
1763
|
+
|
|
1764
|
+
## Principles
|
|
1765
|
+
|
|
1766
|
+
- [Comprehensive Assertions](../principles/comprehensive-assertions.md) — Tension with "precise but not exhaustive"; balance depends on context
|
|
1767
|
+
- [Self-Diagnosing Tests](../principles/self-diagnosing-tests.md) — Informative failures require precise assertions
|
|
1768
|
+
- [Keep Unit Tests Pure](../principles/keep-unit-tests-pure.md) — Determinism is essential for purity
|
|
1769
|
+
- [Reproducible Checks](../principles/reproducible-checks.md) — Deterministic assertions support reproducibility
|
|
1770
|
+
- [Test Isolation](../principles/test-isolation.md) — Fixed delays can cause race conditions between tests
|
|
1771
|
+
|
|
1772
|
+
## Blocked By
|
|
1773
|
+
|
|
1774
|
+
(none)
|
|
1775
|
+
|
|
1776
|
+
## Definition of Done
|
|
1777
|
+
|
|
1778
|
+
- Searched for non-deterministic assertions (timestamps, object key order, random values)
|
|
1779
|
+
- Identified fixed delay patterns in test files
|
|
1780
|
+
- Reviewed assertions for over-constraining internal details
|
|
1781
|
+
- Found tests covering multiple unrelated behaviors
|
|
1782
|
+
- Documented each finding with location, pattern, impact, and suggestion
|
|
1783
|
+
- Proposed ideas for any assertion quality improvements identified
|
|
1784
|
+
`;
|
|
1785
|
+
}
|
|
1786
|
+
function algorithms() {
|
|
1787
|
+
return dedent`
|
|
1788
|
+
# Algorithms
|
|
1789
|
+
|
|
1790
|
+
Evaluate algorithmic complexity and identify performance bottlenecks.
|
|
1791
|
+
|
|
1792
|
+
${ideasHint}
|
|
1793
|
+
|
|
1794
|
+
## Scope
|
|
1795
|
+
|
|
1796
|
+
Focus on these areas:
|
|
1797
|
+
|
|
1798
|
+
1. **Nested loops or recursive calls** - Functions with O(n²) or worse complexity due to nested iteration
|
|
1799
|
+
2. **Linear search inside loops** - Use of \`.includes()\`, \`.indexOf()\`, or \`.find()\` inside loops (potential O(n²))
|
|
1800
|
+
3. **Missing Map/Set usage** - Repeated lookups in arrays where O(1) data structures would help
|
|
1801
|
+
4. **Repeated string operations in loops** - Substring, split, join operations creating unnecessary allocations
|
|
1802
|
+
5. **Missing early returns or break conditions** - Loops that continue processing after the result is found
|
|
1803
|
+
6. **Graph/tree operations without cycle protection** - Recursive traversals that may infinite loop on cyclic structures
|
|
1804
|
+
|
|
1805
|
+
## Analysis Steps
|
|
1806
|
+
|
|
1807
|
+
1. Search for nested \`for\`/\`while\`/\`forEach\` loops and recursive functions
|
|
1808
|
+
2. Look for \`.includes()\`, \`.indexOf()\`, \`.find()\` calls inside loop bodies
|
|
1809
|
+
3. Identify arrays used for repeated membership testing that could be Sets
|
|
1810
|
+
4. Find string operations (\`substring\`, \`split\`, \`join\`, \`+\` concatenation) inside loops
|
|
1811
|
+
5. Check loops for opportunities to \`break\` or \`return\` early
|
|
1812
|
+
6. Review recursive functions for visited/seen tracking in graph-like structures
|
|
1813
|
+
|
|
1814
|
+
## Output Per Finding
|
|
1815
|
+
|
|
1816
|
+
For each finding, provide:
|
|
1817
|
+
- **Function name and location** - File path, line number, and function name
|
|
1818
|
+
- **Current complexity analysis** - Big-O notation with explanation (e.g., "O(n²) due to nested iteration over items array")
|
|
1819
|
+
- **Data structures involved** - What collections are being processed
|
|
1820
|
+
- **Suggested optimization** - Specific fix (e.g., "Convert users array to Set for O(1) lookup", "Add visited Set to prevent cycles")
|
|
1821
|
+
- **Acceptable complexity assessment** - Whether the current complexity is acceptable given expected input sizes (e.g., "Acceptable for small configs (<100 items), problematic for large datasets")
|
|
1822
|
+
|
|
1823
|
+
## Principles
|
|
1824
|
+
|
|
1825
|
+
- [Fast Feedback Loops](../principles/fast-feedback-loops.md) — Efficient algorithms contribute to fast feedback
|
|
1826
|
+
- [Maintainable Codebase](../principles/maintainable-codebase.md) — Understanding complexity aids maintenance
|
|
1827
|
+
- [Context-Optimised Code](../principles/context-optimised-code.md) — Simple, efficient code is easier to understand
|
|
1828
|
+
- [Functional Core, Imperative Shell](../principles/functional-core-imperative-shell.md) — Keep pure analysis logic separate from output formatting
|
|
1829
|
+
|
|
1830
|
+
## Blocked By
|
|
1831
|
+
|
|
1832
|
+
(none)
|
|
1833
|
+
|
|
1834
|
+
## Definition of Done
|
|
1835
|
+
|
|
1836
|
+
- Searched for nested loops and recursive functions
|
|
1837
|
+
- Identified linear search operations inside loops
|
|
1838
|
+
- Found arrays that could benefit from Set/Map conversion
|
|
1839
|
+
- Located repeated string operations in loops
|
|
1840
|
+
- Reviewed loops for missing early exit conditions
|
|
1841
|
+
- Checked recursive graph/tree operations for cycle protection
|
|
1842
|
+
- Documented each finding with function name, location, complexity, data structures, optimization, and acceptability assessment
|
|
1843
|
+
- Proposed ideas for any algorithmic improvements identified
|
|
1844
|
+
`;
|
|
1845
|
+
}
|
|
1846
|
+
function loggingAndTraceability() {
|
|
1847
|
+
return dedent`
|
|
1848
|
+
# Logging and Traceability
|
|
1849
|
+
|
|
1850
|
+
Review logging practices for runtime observability and diagnostic usefulness.
|
|
1851
|
+
|
|
1852
|
+
${ideasHint}
|
|
1853
|
+
|
|
1854
|
+
## Scope
|
|
1855
|
+
|
|
1856
|
+
Focus on these areas:
|
|
1857
|
+
|
|
1858
|
+
1. **Runtime observability** - Is it easy to understand what's happening when the application runs?
|
|
1859
|
+
2. **Diagnostic usefulness** - Is it easy for agents and humans to use logs to diagnose issues at development time?
|
|
1860
|
+
3. **Log levels** - Are appropriate log levels used (debug, info, warn, error)?
|
|
1861
|
+
4. **Contextual information** - Do logs include enough context to trace execution flow?
|
|
1862
|
+
5. **Structured logging** - Are logs structured (e.g., JSON) for easy parsing?
|
|
1863
|
+
6. **Log consistency** - Do similar operations produce similar log output?
|
|
1864
|
+
|
|
1865
|
+
## Analysis Steps
|
|
1866
|
+
|
|
1867
|
+
1. Identify logging calls throughout the codebase (\`console.log\`, \`logger.info\`, etc.)
|
|
1868
|
+
2. Review error handling paths for appropriate error logging
|
|
1869
|
+
3. Check if logs include enough context (operation name, relevant IDs, timestamps)
|
|
1870
|
+
4. Look for silent failures - catch blocks without logging
|
|
1871
|
+
5. Evaluate whether running the application produces understandable output
|
|
1872
|
+
6. Test whether logs help diagnose common failure scenarios
|
|
1873
|
+
|
|
1874
|
+
## Output
|
|
1875
|
+
|
|
1876
|
+
For each finding, provide:
|
|
1877
|
+
- **Location** - File path and line number
|
|
1878
|
+
- **Category** - Which area of concern (observability, diagnostic usefulness, log levels, context, structure, consistency)
|
|
1879
|
+
- **Issue** - What's missing or problematic
|
|
1880
|
+
- **Impact** - How this affects debugging or understanding system behavior
|
|
1881
|
+
- **Suggestion** - Specific improvement (add logging, change level, add context, etc.)
|
|
1882
|
+
|
|
1883
|
+
## Principles
|
|
1884
|
+
|
|
1885
|
+
- [Development Traceability](../principles/development-traceability.md) - Structured logging helps agents understand system behavior
|
|
1886
|
+
- [Debugging Tooling](../principles/debugging-tooling.md) - Agents need effective tools for diagnosing issues
|
|
1887
|
+
- [Actionable Errors](../principles/actionable-errors.md) - Error logs should guide next steps
|
|
1888
|
+
|
|
1889
|
+
## Blocked By
|
|
1890
|
+
|
|
1891
|
+
(none)
|
|
1892
|
+
|
|
1893
|
+
## Definition of Done
|
|
1894
|
+
|
|
1895
|
+
- Reviewed logging coverage across the codebase
|
|
1896
|
+
- Identified silent failures (catch blocks without logging)
|
|
1897
|
+
- Evaluated log levels for appropriateness
|
|
1898
|
+
- Checked logs for sufficient context (operation names, IDs, relevant state)
|
|
1899
|
+
- Assessed whether running the application produces understandable output
|
|
1900
|
+
- Tested whether logs help diagnose common failure scenarios
|
|
1901
|
+
- Proposed ideas for any logging improvements identified
|
|
1902
|
+
`;
|
|
1903
|
+
}
|
|
1904
|
+
function testPyramid() {
|
|
1905
|
+
return dedent`
|
|
1906
|
+
# Test Pyramid
|
|
1907
|
+
|
|
1908
|
+
Evaluate whether tests follow the test pyramid pattern.
|
|
1909
|
+
|
|
1910
|
+
${ideasHint}
|
|
1911
|
+
|
|
1912
|
+
## Background
|
|
1913
|
+
|
|
1914
|
+
The test pyramid model suggests:
|
|
1915
|
+
- **Many fast unit tests** (base) — pure, isolated, testing single units
|
|
1916
|
+
- **Fewer integration tests** (middle) — testing interactions between components
|
|
1917
|
+
- **Minimal end-to-end tests** (top) — slow, broad tests exercising full systems
|
|
1918
|
+
|
|
1919
|
+
Projects with an inverted pyramid suffer from slow feedback loops and difficulty isolating failures.
|
|
1920
|
+
|
|
1921
|
+
## Scope
|
|
1922
|
+
|
|
1923
|
+
### Test Classification
|
|
1924
|
+
|
|
1925
|
+
Determine test types by examining project structure. Common patterns include:
|
|
1926
|
+
|
|
1927
|
+
- **Directory conventions**: \`unit/\`, \`integration/\`, \`e2e/\`, or co-located tests vs \`system-tests/\`
|
|
1928
|
+
- **Test runners**: Different runners for different types (e.g., vitest for unit, bun test for system)
|
|
1929
|
+
- **Configuration**: Look at test config files for exclusions or separate setups
|
|
1930
|
+
|
|
1931
|
+
First identify how this specific project organizes tests, then classify accordingly.
|
|
1932
|
+
|
|
1933
|
+
### Time Analysis
|
|
1934
|
+
|
|
1935
|
+
Include execution time per tier, not just test count. A pyramid with 100 unit tests taking 10 seconds each and 10 e2e tests taking 1 second each has problems the count alone wouldn't reveal.
|
|
1936
|
+
|
|
1937
|
+
Guidance on obtaining timing:
|
|
1938
|
+
- For vitest: \`npx vitest run --reporter=json\` provides per-test duration
|
|
1939
|
+
- For jest: \`jest --json\` provides timing data
|
|
1940
|
+
- For bun test: parse verbose output
|
|
1941
|
+
|
|
1942
|
+
## Analysis Steps
|
|
1943
|
+
|
|
1944
|
+
1. Examine project structure to understand how tests are organized
|
|
1945
|
+
2. Identify the test classification strategy used (directories, config files, runners)
|
|
1946
|
+
3. Count tests in each category (unit, integration, e2e)
|
|
1947
|
+
4. Run tests with timing output to measure execution time per tier
|
|
1948
|
+
5. Look for "unit" tests that perform I/O (process spawning, network calls, file system access)
|
|
1949
|
+
6. Evaluate pyramid shape based on counts and timing
|
|
1950
|
+
|
|
1951
|
+
## Output
|
|
1952
|
+
|
|
1953
|
+
Report the following:
|
|
1954
|
+
|
|
1955
|
+
1. **Test distribution** — counts and percentages per category
|
|
1956
|
+
2. **Time distribution** — total execution time per tier
|
|
1957
|
+
3. **Pyramid health** — flag obvious inversions:
|
|
1958
|
+
- More e2e tests than unit tests
|
|
1959
|
+
- More time spent in integration/e2e than unit tests
|
|
1960
|
+
4. **Miscategorized tests** — tests that appear to be in the wrong tier based on their behavior (e.g., "unit" tests with I/O)
|
|
1961
|
+
5. **Recommendations** — specific actions to improve the pyramid shape
|
|
1962
|
+
|
|
1963
|
+
## Relative Guidance
|
|
1964
|
+
|
|
1965
|
+
Flag obvious problems without prescribing exact ratios. Examples of problems:
|
|
1966
|
+
- More end-to-end tests than unit tests
|
|
1967
|
+
- More time spent in integration/e2e than unit tests
|
|
1968
|
+
- Unit tests that perform I/O (process spawning, network calls, file system access)
|
|
1969
|
+
|
|
1970
|
+
## Principles
|
|
1971
|
+
|
|
1972
|
+
- [Fast Feedback Loops](../principles/fast-feedback-loops.md) — Unit-heavy pyramids enable fast feedback
|
|
1973
|
+
- [Keep Unit Tests Pure](../principles/keep-unit-tests-pure.md) — Defines what makes a test a "unit test"
|
|
1974
|
+
- [Unit Test Coverage](../principles/unit-test-coverage.md) — Values unit tests for specific, fast feedback
|
|
1975
|
+
- [Design for Testability](../principles/design-for-testability.md) — Testable code enables unit tests; untestable code forces integration tests
|
|
1976
|
+
- [Functional Core, Imperative Shell](../principles/functional-core-imperative-shell.md) — Keep audit definition pure
|
|
1977
|
+
|
|
1978
|
+
## Blocked By
|
|
1979
|
+
|
|
1980
|
+
(none)
|
|
1981
|
+
|
|
1982
|
+
## Definition of Done
|
|
1983
|
+
|
|
1984
|
+
- Identified how this project organizes and classifies tests
|
|
1985
|
+
- Counted tests per category (unit, integration, e2e)
|
|
1986
|
+
- Measured execution time per tier
|
|
1987
|
+
- Flagged obvious pyramid inversions (more e2e than unit, more time in e2e)
|
|
1988
|
+
- Identified miscategorized tests (e.g., unit tests with I/O)
|
|
1989
|
+
- Provided specific recommendations to improve pyramid shape
|
|
1990
|
+
- Proposed ideas for any substantial test restructuring needed
|
|
1991
|
+
`;
|
|
1992
|
+
}
|
|
1993
|
+
function idiomaticStyle() {
|
|
1994
|
+
return dedent`
|
|
1995
|
+
# Idiomatic Style
|
|
1996
|
+
|
|
1997
|
+
Review recent changes to ensure implementation follows idiomatic practices for the technology stack.
|
|
1998
|
+
|
|
1999
|
+
${ideasHint}
|
|
2000
|
+
|
|
2001
|
+
## Scope
|
|
2002
|
+
|
|
2003
|
+
Focus on these areas:
|
|
2004
|
+
|
|
2005
|
+
1. **Language idioms** - Does code follow language-specific patterns and conventions? (e.g., Python comprehensions, JavaScript destructuring, TypeScript type narrowing)
|
|
2006
|
+
2. **Framework patterns** - Are framework/library APIs used as intended? (e.g., React hooks rules, Express middleware patterns, test framework best practices)
|
|
2007
|
+
3. **Style consistency** - Do recent changes match the established code style in this codebase?
|
|
2008
|
+
4. **Anti-patterns** - Are common pitfalls for this stack being avoided?
|
|
2009
|
+
5. **Modern alternatives** - Are deprecated or outdated approaches being used where better alternatives exist?
|
|
2010
|
+
|
|
2011
|
+
## Analysis Steps
|
|
2012
|
+
|
|
2013
|
+
1. Identify the technology stack by examining package.json, config files, or file extensions
|
|
2014
|
+
2. Review recent commits (last 10-20 commits) to understand what changed
|
|
2015
|
+
3. For each change, evaluate against idiomatic practices for that language/framework
|
|
2016
|
+
4. Check for deviations from established patterns in the existing codebase
|
|
2017
|
+
5. **IMPORTANT**: If uncertain about current best practices (e.g., due to stale training data), consult official documentation or authoritative sources for the latest guidance before flagging issues
|
|
2018
|
+
|
|
2019
|
+
## Output
|
|
2020
|
+
|
|
2021
|
+
For each finding, provide:
|
|
2022
|
+
- **Location** - File path and line numbers
|
|
2023
|
+
- **Pattern** - What the code is currently doing
|
|
2024
|
+
- **Idiom issue** - How this deviates from idiomatic practice
|
|
2025
|
+
- **Best practice** - What the idiomatic approach would be (with reference to documentation if applicable)
|
|
2026
|
+
- **Impact** - Why this matters (readability, performance, maintainability, community expectations)
|
|
2027
|
+
|
|
2028
|
+
## Tech-Stack Considerations
|
|
2029
|
+
|
|
2030
|
+
Be specific to the detected stack. Examples:
|
|
2031
|
+
|
|
2032
|
+
- **TypeScript**: Prefer type narrowing over type assertions, use \`const\` assertions, leverage discriminated unions
|
|
2033
|
+
- **React**: Follow hooks rules, prefer controlled components, avoid inline function definitions in JSX for performance
|
|
2034
|
+
- **Node.js**: Use async/await over callbacks, prefer native ES modules, handle streams properly
|
|
2035
|
+
- **Testing**: Use framework-specific matchers, follow Arrange-Act-Assert pattern, avoid test interdependence
|
|
2036
|
+
|
|
2037
|
+
When the technology or its ecosystem is evolving rapidly, explicitly note when findings should be verified against current documentation.
|
|
2038
|
+
|
|
2039
|
+
## Principles
|
|
2040
|
+
|
|
2041
|
+
- [Context-Optimised Code](../principles/context-optimised-code.md) - Idiomatic code is easier for agents and humans to understand
|
|
2042
|
+
- [Maintainable Codebase](../principles/maintainable-codebase.md) - Following conventions reduces cognitive load
|
|
2043
|
+
- [Consistent Naming](../principles/consistent-naming.md) - Naming should follow language conventions
|
|
2044
|
+
- [Boy Scout Rule](../principles/boy-scout-rule.md) - Leave code better than you found it
|
|
2045
|
+
|
|
2046
|
+
## Blocked By
|
|
2047
|
+
|
|
2048
|
+
(none)
|
|
2049
|
+
|
|
2050
|
+
## Definition of Done
|
|
2051
|
+
|
|
2052
|
+
- Identified the technology stack in use
|
|
2053
|
+
- Reviewed recent commits for idiom issues
|
|
2054
|
+
- Checked code against language and framework best practices
|
|
2055
|
+
- Verified current documentation for any uncertain cases
|
|
2056
|
+
- Evaluated code style consistency with rest of codebase
|
|
2057
|
+
- Identified anti-patterns or deprecated approaches
|
|
2058
|
+
- Proposed ideas for any idiomaticity improvements identified
|
|
1030
2059
|
`;
|
|
1031
2060
|
}
|
|
1032
2061
|
function uxAudit() {
|
|
@@ -1089,26 +2118,504 @@ function uxAudit() {
|
|
|
1089
2118
|
|
|
1090
2119
|
## Definition of Done
|
|
1091
2120
|
|
|
1092
|
-
-
|
|
1093
|
-
-
|
|
1094
|
-
-
|
|
1095
|
-
-
|
|
1096
|
-
-
|
|
1097
|
-
-
|
|
1098
|
-
-
|
|
2121
|
+
- Identified the application type (web, terminal, hybrid, or no UI)
|
|
2122
|
+
- Listed key user scenarios
|
|
2123
|
+
- Captured screenshots or output at each stage of key scenarios
|
|
2124
|
+
- Reviewed evidence for UX issues
|
|
2125
|
+
- Documented findings with evidence and recommendations
|
|
2126
|
+
- Included verification criteria for each issue
|
|
2127
|
+
- Created ideas for any UX improvements needed
|
|
2128
|
+
`;
|
|
2129
|
+
}
|
|
2130
|
+
function dependencyHealth() {
|
|
2131
|
+
return dedent`
|
|
2132
|
+
# Dependency Health
|
|
2133
|
+
|
|
2134
|
+
Review project dependencies for maintenance and security concerns beyond CVE scanning.
|
|
2135
|
+
|
|
2136
|
+
${ideasHint}
|
|
2137
|
+
|
|
2138
|
+
## Context
|
|
2139
|
+
|
|
2140
|
+
Healthy dependencies require more than security patches. Unmaintained packages, version drift, and deprecated packages all impact project health and can introduce agent confusion when outdated documentation or APIs don't match reality.
|
|
2141
|
+
|
|
2142
|
+
## Scope
|
|
2143
|
+
|
|
2144
|
+
Focus on these areas:
|
|
2145
|
+
|
|
2146
|
+
1. **Packages with no recent releases** - Identify dependencies that haven't been updated in 2+ years (potential abandonment)
|
|
2147
|
+
2. **Major version drift** - Find dependencies more than 2 major versions behind latest (missing features, eventual migration pain)
|
|
2148
|
+
3. **Deprecated packages** - Detect packages marked as deprecated on npm
|
|
2149
|
+
4. **Better-maintained alternatives** - Flag packages with known successors (e.g., \`request\` → \`node-fetch\` or \`got\`)
|
|
2150
|
+
|
|
2151
|
+
## Analysis Steps
|
|
2152
|
+
|
|
2153
|
+
### 1. Check Package Release Dates
|
|
2154
|
+
|
|
2155
|
+
For each dependency in \`package.json\`:
|
|
2156
|
+
|
|
2157
|
+
1. Run \`npm view <package-name> time --json\` to get release history
|
|
2158
|
+
2. Check the date of the latest release
|
|
2159
|
+
3. Flag packages where the latest release is more than 2 years old
|
|
2160
|
+
|
|
2161
|
+
Example:
|
|
2162
|
+
\`\`\`bash
|
|
2163
|
+
npm view lodash time --json | jq -r 'to_entries | sort_by(.value) | last | .value'
|
|
2164
|
+
\`\`\`
|
|
2165
|
+
|
|
2166
|
+
### 2. Identify Major Version Drift
|
|
2167
|
+
|
|
2168
|
+
Compare installed versions against latest:
|
|
2169
|
+
|
|
2170
|
+
1. Run \`npm outdated --json\` to see current vs latest versions
|
|
2171
|
+
2. Parse version numbers to identify major version differences
|
|
2172
|
+
3. Flag dependencies more than 2 major versions behind
|
|
2173
|
+
|
|
2174
|
+
Example output to parse:
|
|
2175
|
+
\`\`\`json
|
|
2176
|
+
{
|
|
2177
|
+
"example-package": {
|
|
2178
|
+
"current": "2.1.0",
|
|
2179
|
+
"wanted": "2.5.0",
|
|
2180
|
+
"latest": "5.0.0"
|
|
2181
|
+
}
|
|
2182
|
+
}
|
|
2183
|
+
\`\`\`
|
|
2184
|
+
|
|
2185
|
+
In this case, the package is 3 major versions behind (2.x → 5.x).
|
|
2186
|
+
|
|
2187
|
+
### 3. Detect Deprecated Packages
|
|
2188
|
+
|
|
2189
|
+
Check deprecation status:
|
|
2190
|
+
|
|
2191
|
+
1. Run \`npm view <package-name> deprecated\` for each dependency
|
|
2192
|
+
2. If the field exists and is non-empty, the package is deprecated
|
|
2193
|
+
3. The deprecation message often suggests an alternative
|
|
2194
|
+
|
|
2195
|
+
Example:
|
|
2196
|
+
\`\`\`bash
|
|
2197
|
+
npm view request deprecated
|
|
2198
|
+
# Output: "request has been deprecated..."
|
|
2199
|
+
\`\`\`
|
|
2200
|
+
|
|
2201
|
+
### 4. Identify Better-Maintained Alternatives
|
|
2202
|
+
|
|
2203
|
+
Known package migrations to check for:
|
|
2204
|
+
|
|
2205
|
+
| Deprecated/Unmaintained | Recommended Alternative |
|
|
2206
|
+
|------------------------|------------------------|
|
|
2207
|
+
| \`request\` | \`node-fetch\`, \`got\`, \`axios\` |
|
|
2208
|
+
| \`moment\` | \`date-fns\`, \`dayjs\`, \`luxon\` |
|
|
2209
|
+
| \`uuid\` v3 or earlier | \`uuid\` v8+ or \`crypto.randomUUID()\` |
|
|
2210
|
+
| \`rimraf\` | \`fs.rm\` (Node 14.14+) |
|
|
2211
|
+
| \`mkdirp\` | \`fs.mkdir\` with \`recursive: true\` |
|
|
2212
|
+
| \`node-fetch\` | native \`fetch\` (Node 18+) |
|
|
2213
|
+
| \`colors\` | \`chalk\`, \`picocolors\` |
|
|
2214
|
+
| \`faker\` | \`@faker-js/faker\` |
|
|
2215
|
+
| \`left-pad\` | \`String.prototype.padStart()\` |
|
|
2216
|
+
| \`underscore\` | \`lodash\` or native methods |
|
|
2217
|
+
|
|
2218
|
+
Search for these packages in \`package.json\` and flag any matches.
|
|
2219
|
+
|
|
2220
|
+
## Output
|
|
2221
|
+
|
|
2222
|
+
For each concern found, document:
|
|
2223
|
+
|
|
2224
|
+
- **Package name** - The npm package name
|
|
2225
|
+
- **Current version** - Version installed in the project
|
|
2226
|
+
- **Type of concern** - One of: \`unmaintained\`, \`outdated\`, \`deprecated\`, \`superseded\`
|
|
2227
|
+
- **Details** - Last release date, version gap, deprecation message, or successor package
|
|
2228
|
+
- **Suggested action** - One of:
|
|
2229
|
+
- \`update\` - Upgrade to latest version
|
|
2230
|
+
- \`replace\` - Migrate to a successor package
|
|
2231
|
+
- \`remove\` - Remove if no longer needed
|
|
2232
|
+
- \`accept\` - Accept the risk with documented rationale
|
|
2233
|
+
|
|
2234
|
+
Example findings:
|
|
2235
|
+
|
|
2236
|
+
\`\`\`markdown
|
|
2237
|
+
### moment (v2.29.4)
|
|
2238
|
+
|
|
2239
|
+
- **Concern**: superseded
|
|
2240
|
+
- **Details**: moment is in maintenance mode; the team recommends date-fns, Luxon, or Day.js for new projects
|
|
2241
|
+
- **Action**: replace with \`date-fns\` for tree-shaking benefits, or \`dayjs\` for API compatibility
|
|
2242
|
+
|
|
2243
|
+
### request (v2.88.2)
|
|
2244
|
+
|
|
2245
|
+
- **Concern**: deprecated
|
|
2246
|
+
- **Details**: Package deprecated in February 2020. Message: "request has been deprecated"
|
|
2247
|
+
- **Action**: replace with \`node-fetch\` (for simple cases) or \`got\` (for advanced features)
|
|
2248
|
+
|
|
2249
|
+
### some-legacy-lib (v1.0.0)
|
|
2250
|
+
|
|
2251
|
+
- **Concern**: unmaintained
|
|
2252
|
+
- **Details**: Last release was 3 years ago (2021-01-15)
|
|
2253
|
+
- **Action**: evaluate if still needed; if so, consider forking or finding alternative
|
|
2254
|
+
\`\`\`
|
|
2255
|
+
|
|
2256
|
+
## Principles
|
|
2257
|
+
|
|
2258
|
+
- [Minimal Dependencies](../principles/minimal-dependencies.md) - Avoid coupling to specific tools; healthy dependencies are easier to swap
|
|
2259
|
+
- [Maintainable Codebase](../principles/maintainable-codebase.md) - Maintained dependencies reduce maintenance burden
|
|
2260
|
+
- [Agent Autonomy](../principles/agent-autonomy.md) - Agents benefit from up-to-date dependencies with accurate documentation
|
|
2261
|
+
|
|
2262
|
+
## Blocked By
|
|
2263
|
+
|
|
2264
|
+
(none)
|
|
2265
|
+
|
|
2266
|
+
## Definition of Done
|
|
2267
|
+
|
|
2268
|
+
- [ ] Checked package release dates for all dependencies
|
|
2269
|
+
- [ ] Identified packages with no releases in 2+ years
|
|
2270
|
+
- [ ] Ran \`npm outdated\` to find major version drift
|
|
2271
|
+
- [ ] Flagged packages more than 2 major versions behind
|
|
2272
|
+
- [ ] Checked deprecation status of all dependencies
|
|
2273
|
+
- [ ] Searched for packages with known better-maintained alternatives
|
|
2274
|
+
- [ ] Documented each concern with package name, version, type, and suggested action
|
|
2275
|
+
- [ ] Created ideas for any dependency health improvements needed
|
|
2276
|
+
`;
|
|
2277
|
+
}
|
|
2278
|
+
function ciDevelopmentParity() {
|
|
2279
|
+
return dedent`
|
|
2280
|
+
# CI / Development Parity
|
|
2281
|
+
|
|
2282
|
+
Identify discrepancies between checks run locally via \`dust check\` and those run in CI.
|
|
2283
|
+
|
|
2284
|
+
${ideasHint}
|
|
2285
|
+
|
|
2286
|
+
## Context
|
|
2287
|
+
|
|
2288
|
+
When developers run different checks locally than CI runs remotely, several problems emerge:
|
|
2289
|
+
|
|
2290
|
+
1. **False confidence** - CI might pass while local checks fail, or vice versa
|
|
2291
|
+
2. **Wasted cycles** - Developers push code that passes locally only to have CI fail
|
|
2292
|
+
3. **Agent confusion** - AI agents rely on consistent feedback; discrepancies trigger incorrect debugging paths
|
|
2293
|
+
|
|
2294
|
+
The [Reproducible Checks](../principles/reproducible-checks.md) principle ensures the same checks run everywhere.
|
|
2295
|
+
|
|
2296
|
+
## Scope
|
|
2297
|
+
|
|
2298
|
+
This audit performs a bidirectional comparison:
|
|
2299
|
+
|
|
2300
|
+
1. **Checks in dust but not in CI** (local-only checks)
|
|
2301
|
+
2. **Checks in CI but not in dust** (CI-only checks)
|
|
2302
|
+
|
|
2303
|
+
## Analysis Steps
|
|
2304
|
+
|
|
2305
|
+
### 1. Detect Local Checks
|
|
2306
|
+
|
|
2307
|
+
Read \`.dust/config/settings.json\` to identify checks configured for \`dust check\`:
|
|
2308
|
+
|
|
2309
|
+
\`\`\`json
|
|
2310
|
+
{
|
|
2311
|
+
"checks": [
|
|
2312
|
+
{ "name": "lint", "command": "eslint ." },
|
|
2313
|
+
{ "name": "typecheck", "command": "tsc --noEmit" },
|
|
2314
|
+
{ "name": "test", "command": "vitest run" }
|
|
2315
|
+
]
|
|
2316
|
+
}
|
|
2317
|
+
\`\`\`
|
|
2318
|
+
|
|
2319
|
+
Extract check names and commands for comparison.
|
|
2320
|
+
|
|
2321
|
+
### 2. Parse CI Configuration
|
|
2322
|
+
|
|
2323
|
+
Search for CI workflow files and parse them for check commands:
|
|
2324
|
+
|
|
2325
|
+
- \`.github/workflows/*.yml\` (GitHub Actions)
|
|
2326
|
+
- \`.gitlab-ci.yml\` (GitLab CI)
|
|
2327
|
+
- \`.circleci/config.yml\` (CircleCI)
|
|
2328
|
+
|
|
2329
|
+
Look for these check categories in CI:
|
|
2330
|
+
|
|
2331
|
+
- **linting** - eslint, oxlint, biome lint, ruff, golangci-lint
|
|
2332
|
+
- **formatting** - prettier, oxfmt, biome format, black, gofmt
|
|
2333
|
+
- **type-checking** - tsc, mypy, pyright
|
|
2334
|
+
- **build** - npm/bun/yarn build, go build, cargo build
|
|
2335
|
+
- **unit-tests** - vitest, jest, pytest, go test, cargo test
|
|
2336
|
+
- **unused-code** - knip
|
|
2337
|
+
|
|
2338
|
+
### 3. Follow Indirect References
|
|
2339
|
+
|
|
2340
|
+
When CI runs commands like \`npm run check\` or \`./scripts/check.sh\`, follow one level of indirection:
|
|
2341
|
+
|
|
2342
|
+
1. If CI runs \`npm run check\`, check \`package.json\` scripts for what \`check\` executes
|
|
2343
|
+
2. If CI runs a script file, read that script to identify the actual checks
|
|
2344
|
+
3. Map these resolved commands back to check categories
|
|
2345
|
+
|
|
2346
|
+
Example indirect reference resolution:
|
|
2347
|
+
\`\`\`yaml
|
|
2348
|
+
# CI workflow runs:
|
|
2349
|
+
- run: npm run check
|
|
2350
|
+
\`\`\`
|
|
2351
|
+
|
|
2352
|
+
\`\`\`json
|
|
2353
|
+
// package.json scripts section:
|
|
2354
|
+
"check": "eslint . && tsc --noEmit"
|
|
2355
|
+
\`\`\`
|
|
2356
|
+
|
|
2357
|
+
This resolves to: linting and type-checking in CI.
|
|
2358
|
+
|
|
2359
|
+
### 4. Bidirectional Comparison
|
|
2360
|
+
|
|
2361
|
+
Compare check categories between local (dust) and CI:
|
|
2362
|
+
|
|
2363
|
+
| Category | In Dust | In CI | Gap |
|
|
2364
|
+
|----------|---------|-------|-----|
|
|
2365
|
+
| linting | ✓ | ✓ | None |
|
|
2366
|
+
| type-checking | ✓ | ✗ | CI missing |
|
|
2367
|
+
| tests | ✗ | ✓ | Dust missing |
|
|
2368
|
+
|
|
2369
|
+
## Output
|
|
2370
|
+
|
|
2371
|
+
For each gap found, create an idea file with:
|
|
2372
|
+
|
|
2373
|
+
### For Local-Only Checks (in dust, not in CI)
|
|
2374
|
+
|
|
2375
|
+
\`\`\`markdown
|
|
2376
|
+
# Add [Check Name] to CI
|
|
2377
|
+
|
|
2378
|
+
The \`[check-name]\` check runs locally via \`dust check\` but is not run in CI.
|
|
2379
|
+
|
|
2380
|
+
## Impact
|
|
2381
|
+
|
|
2382
|
+
- Developers may push code that passes locally but fails CI on other checks
|
|
2383
|
+
- CI provides no coverage for [check category]
|
|
2384
|
+
- The [Stop the Line](../principles/stop-the-line.md) principle is violated - problems aren't caught before merge
|
|
2385
|
+
|
|
2386
|
+
## Suggested Fix
|
|
2387
|
+
|
|
2388
|
+
Add to \`.github/workflows/ci.yml\`:
|
|
2389
|
+
|
|
2390
|
+
\`\`\`yaml
|
|
2391
|
+
- name: [Check Name]
|
|
2392
|
+
run: [command]
|
|
2393
|
+
\`\`\`
|
|
2394
|
+
|
|
2395
|
+
Or ensure CI runs \`dust check\` which includes this check.
|
|
2396
|
+
\`\`\`
|
|
2397
|
+
|
|
2398
|
+
### For CI-Only Checks (in CI, not in dust)
|
|
2399
|
+
|
|
2400
|
+
\`\`\`markdown
|
|
2401
|
+
# Add [Check Name] to dust check
|
|
2402
|
+
|
|
2403
|
+
The \`[check-name]\` check runs in CI but is not configured in \`dust check\`.
|
|
2404
|
+
|
|
2405
|
+
## Impact
|
|
2406
|
+
|
|
2407
|
+
- Developers don't get [check category] feedback until CI runs
|
|
2408
|
+
- [Fast Feedback Loops](../principles/fast-feedback-loops.md) are broken - local checks give incomplete picture
|
|
2409
|
+
- Agents may make changes that pass local checks but fail CI
|
|
2410
|
+
|
|
2411
|
+
## Suggested Fix
|
|
2412
|
+
|
|
2413
|
+
Add to \`.dust/config/settings.json\`:
|
|
2414
|
+
|
|
2415
|
+
\`\`\`json
|
|
2416
|
+
{ "name": "[check-name]", "command": "[command]" }
|
|
2417
|
+
\`\`\`
|
|
2418
|
+
\`\`\`
|
|
2419
|
+
|
|
2420
|
+
## Principles
|
|
2421
|
+
|
|
2422
|
+
- [Reproducible Checks](../principles/reproducible-checks.md) - Ensures same checks run everywhere
|
|
2423
|
+
- [Stop the Line](../principles/stop-the-line.md) - Problems are caught at source, not downstream
|
|
2424
|
+
- [Fast Feedback Loops](../principles/fast-feedback-loops.md) - Developers get consistent feedback locally before pushing
|
|
2425
|
+
- [Agent Autonomy](../principles/agent-autonomy.md) - Agents can trust that passing local checks means CI will pass
|
|
2426
|
+
|
|
2427
|
+
## Blocked By
|
|
2428
|
+
|
|
2429
|
+
(none)
|
|
2430
|
+
|
|
2431
|
+
## Definition of Done
|
|
2432
|
+
|
|
2433
|
+
- [ ] Read \`.dust/config/settings.json\` and extracted check categories
|
|
2434
|
+
- [ ] Parsed CI configuration files for check commands
|
|
2435
|
+
- [ ] Followed indirect references (npm run scripts, shell scripts) one level deep
|
|
2436
|
+
- [ ] Identified local-only checks (in dust but not CI)
|
|
2437
|
+
- [ ] Identified CI-only checks (in CI but not dust)
|
|
2438
|
+
- [ ] Created idea files for each gap with suggested fix
|
|
2439
|
+
- [ ] Each idea links to relevant principles
|
|
2440
|
+
`;
|
|
2441
|
+
}
|
|
2442
|
+
function commitMessageQuality() {
|
|
2443
|
+
return dedent`
|
|
2444
|
+
# Commit Message Quality
|
|
2445
|
+
|
|
2446
|
+
Review recent commits for message quality and traceability issues.
|
|
2447
|
+
|
|
2448
|
+
${ideasHint}
|
|
2449
|
+
|
|
2450
|
+
## Context
|
|
2451
|
+
|
|
2452
|
+
The [Traceable Decisions](../principles/traceable-decisions.md) principle emphasizes that commit history should explain why changes were made. Good commit messages help agents understand project history and make better decisions. This audit evaluates commit message quality itself, not the code changes.
|
|
2453
|
+
|
|
2454
|
+
## Scope
|
|
2455
|
+
|
|
2456
|
+
Analyze the last 50 commits for these quality issues:
|
|
2457
|
+
|
|
2458
|
+
1. **Generic messages** - Non-descriptive messages like "fix", "update", "WIP", "changes", "stuff", "misc"
|
|
2459
|
+
2. **Missing why** - Messages that describe what changed but not why
|
|
2460
|
+
3. **Breaking changes** - Breaking commits without explanation of impact
|
|
2461
|
+
4. **Multi-concern commits** - Commits that bundle unrelated changes
|
|
2462
|
+
5. **Missing links** - Commits without links to related issues, tasks, or context
|
|
2463
|
+
|
|
2464
|
+
## Analysis Steps
|
|
2465
|
+
|
|
2466
|
+
### 1. Gather Recent Commits
|
|
2467
|
+
|
|
2468
|
+
Run \`git log -50 --pretty=format:"%H|%s|%b---END---"\` to get recent commits with their full messages.
|
|
2469
|
+
|
|
2470
|
+
### 2. Detect Generic Messages
|
|
2471
|
+
|
|
2472
|
+
Flag commits where the subject line:
|
|
2473
|
+
- Is a single word like "fix", "update", "changes", "WIP", "stuff", "misc", "cleanup"
|
|
2474
|
+
- Starts with generic verbs without context: "Fix bug", "Update file", "Change code"
|
|
2475
|
+
- Is very short (under 10 characters) without meaningful content
|
|
2476
|
+
|
|
2477
|
+
Example findings:
|
|
2478
|
+
\`\`\`markdown
|
|
2479
|
+
### Generic: abc1234
|
|
2480
|
+
- **Message**: "fix"
|
|
2481
|
+
- **Issue**: Single-word message provides no context
|
|
2482
|
+
- **Suggestion**: Describe what was fixed and why, e.g., "Fix null pointer when user has no email"
|
|
2483
|
+
\`\`\`
|
|
2484
|
+
|
|
2485
|
+
### 3. Detect Missing "Why"
|
|
2486
|
+
|
|
2487
|
+
Flag commits where:
|
|
2488
|
+
- The subject describes what changed but the body is empty or doesn't explain motivation
|
|
2489
|
+
- Technical changes lack business or user context
|
|
2490
|
+
- Refactoring commits don't explain why the refactoring was needed
|
|
2491
|
+
|
|
2492
|
+
Look for these patterns that suggest missing "why":
|
|
2493
|
+
- "Add X" without explaining why X was needed
|
|
2494
|
+
- "Remove X" without explaining why X was unnecessary
|
|
2495
|
+
- "Refactor X" without explaining what problem the refactoring solves
|
|
2496
|
+
|
|
2497
|
+
Example finding:
|
|
2498
|
+
\`\`\`markdown
|
|
2499
|
+
### Missing Why: def5678
|
|
2500
|
+
- **Message**: "Add caching to API calls"
|
|
2501
|
+
- **Issue**: Doesn't explain why caching was added (performance problem? rate limits? user experience?)
|
|
2502
|
+
- **Suggestion**: Include the motivation, e.g., "Add caching to API calls to reduce rate limit errors during high traffic"
|
|
2503
|
+
\`\`\`
|
|
2504
|
+
|
|
2505
|
+
### 4. Flag Breaking Changes Without Impact
|
|
2506
|
+
|
|
2507
|
+
Identify breaking changes by looking for:
|
|
2508
|
+
- Subject contains "BREAKING", "breaking", or "!"
|
|
2509
|
+
- Changes to public APIs, configuration schemas, database migrations
|
|
2510
|
+
- Removal of features or options
|
|
2511
|
+
|
|
2512
|
+
Flag if the body doesn't explain:
|
|
2513
|
+
- What exactly breaks
|
|
2514
|
+
- Who is affected
|
|
2515
|
+
- How to migrate
|
|
2516
|
+
|
|
2517
|
+
Example finding:
|
|
2518
|
+
\`\`\`markdown
|
|
2519
|
+
### Breaking Without Impact: ghi9012
|
|
2520
|
+
- **Message**: "BREAKING: Remove legacy auth"
|
|
2521
|
+
- **Issue**: Doesn't explain impact or migration path
|
|
2522
|
+
- **Suggestion**: Add body explaining: "Removes support for v1 auth tokens. Users must regenerate tokens via /settings. This affects deployments using tokens created before 2024."
|
|
2523
|
+
\`\`\`
|
|
2524
|
+
|
|
2525
|
+
### 5. Detect Multi-Concern Commits
|
|
2526
|
+
|
|
2527
|
+
Use \`git show --stat <hash>\` to get changed files per commit.
|
|
2528
|
+
|
|
2529
|
+
Flag commits that appear to bundle unrelated changes:
|
|
2530
|
+
- Files across multiple unrelated modules or directories
|
|
2531
|
+
- Mix of feature code and unrelated refactoring
|
|
2532
|
+
- Multiple distinct logical changes in one commit
|
|
2533
|
+
|
|
2534
|
+
Look for signals like:
|
|
2535
|
+
- Changes to both frontend and backend for unrelated features
|
|
2536
|
+
- Test files for different features modified together
|
|
2537
|
+
- Configuration changes bundled with unrelated code changes
|
|
2538
|
+
|
|
2539
|
+
Example finding:
|
|
2540
|
+
\`\`\`markdown
|
|
2541
|
+
### Multi-Concern: jkl3456
|
|
2542
|
+
- **Message**: "Add user dashboard and fix email validation"
|
|
2543
|
+
- **Files Changed**: src/dashboard/*, src/email/*, tests/email/*
|
|
2544
|
+
- **Issue**: Bundles unrelated features - dashboard addition and email validation fix
|
|
2545
|
+
- **Suggestion**: Split into atomic commits: one for the dashboard feature, one for the email fix
|
|
2546
|
+
\`\`\`
|
|
2547
|
+
|
|
2548
|
+
### 6. Check for Missing Links
|
|
2549
|
+
|
|
2550
|
+
Flag commits that reference issues or tasks without links:
|
|
2551
|
+
- Mentions "the bug", "the issue", "the task" without a link or ID
|
|
2552
|
+
- Describes a problem without linking to where it was reported
|
|
2553
|
+
- References external context without providing a way to access it
|
|
2554
|
+
|
|
2555
|
+
Also note commits for significant features or bug fixes that lack any external reference.
|
|
2556
|
+
|
|
2557
|
+
Example finding:
|
|
2558
|
+
\`\`\`markdown
|
|
2559
|
+
### Missing Link: mno7890
|
|
2560
|
+
- **Message**: "Fix the authentication bug reported last week"
|
|
2561
|
+
- **Issue**: References a bug report but doesn't link to it
|
|
2562
|
+
- **Suggestion**: Include issue reference, e.g., "Fix authentication timeout (fixes #123)" or link to discussion
|
|
2563
|
+
\`\`\`
|
|
2564
|
+
|
|
2565
|
+
## Output
|
|
2566
|
+
|
|
2567
|
+
For each quality issue found, create an idea file documenting:
|
|
2568
|
+
|
|
2569
|
+
1. **Commit hash and message** - The specific commit with the issue
|
|
2570
|
+
2. **Type of issue** - One of: generic, missing-why, breaking-without-impact, multi-concern, missing-link
|
|
2571
|
+
3. **Suggested improvement** - Concrete guidance for future commits
|
|
2572
|
+
|
|
2573
|
+
Group related issues into a single idea file if they suggest a systemic pattern (e.g., "Multiple commits lack issue links" rather than one idea per commit).
|
|
2574
|
+
|
|
2575
|
+
## Principles
|
|
2576
|
+
|
|
2577
|
+
- [Traceable Decisions](../principles/traceable-decisions.md) - Commit history should explain why changes were made
|
|
2578
|
+
- [Atomic Commits](../principles/atomic-commits.md) - Each commit should tell a complete story
|
|
2579
|
+
- [Agent Autonomy](../principles/agent-autonomy.md) - Agents learn from commit history to understand project patterns
|
|
2580
|
+
|
|
2581
|
+
## Blocked By
|
|
2582
|
+
|
|
2583
|
+
(none)
|
|
2584
|
+
|
|
2585
|
+
## Definition of Done
|
|
2586
|
+
|
|
2587
|
+
- [ ] Reviewed last 50 commits for quality issues
|
|
2588
|
+
- [ ] Identified commits with generic/non-descriptive messages
|
|
2589
|
+
- [ ] Identified commits missing "why" context
|
|
2590
|
+
- [ ] Identified breaking changes without impact documentation
|
|
2591
|
+
- [ ] Identified commits bundling unrelated changes
|
|
2592
|
+
- [ ] Identified commits missing links to issues/tasks
|
|
2593
|
+
- [ ] Created idea files for patterns found
|
|
2594
|
+
- [ ] Each idea includes concrete suggestions for improvement
|
|
1099
2595
|
`;
|
|
1100
2596
|
}
|
|
1101
2597
|
var stockAuditFunctions = {
|
|
1102
2598
|
"agent-developer-experience": agentDeveloperExperience,
|
|
2599
|
+
"agent-instruction-quality": agentInstructionQuality,
|
|
2600
|
+
algorithms,
|
|
2601
|
+
"checks-audit": checksAuditTemplate,
|
|
2602
|
+
"ci-development-parity": ciDevelopmentParity,
|
|
2603
|
+
"commit-message-quality": commitMessageQuality,
|
|
2604
|
+
"dependency-health": dependencyHealth,
|
|
2605
|
+
"documentation-drift": documentationDrift,
|
|
1103
2606
|
"component-reuse": componentReuse,
|
|
1104
2607
|
"coverage-exclusions": coverageExclusions,
|
|
1105
2608
|
"data-access-review": dataAccessReview,
|
|
1106
2609
|
"dead-code": deadCode,
|
|
2610
|
+
"design-patterns": designPatterns,
|
|
1107
2611
|
"error-handling": errorHandling,
|
|
1108
2612
|
"facts-verification": factsVerification,
|
|
2613
|
+
"feedback-loop-speed": feedbackLoopSpeed,
|
|
1109
2614
|
"global-state": globalState,
|
|
1110
2615
|
"ideas-from-commits": ideasFromCommits,
|
|
1111
2616
|
"ideas-from-principles": ideasFromPrinciples,
|
|
2617
|
+
"idiomatic-style": idiomaticStyle,
|
|
2618
|
+
"logging-and-traceability": loggingAndTraceability,
|
|
1112
2619
|
"naming-consistency": namingConsistency,
|
|
1113
2620
|
"performance-review": performanceReview,
|
|
1114
2621
|
"primitive-obsession": primitiveObsession,
|
|
@@ -1118,12 +2625,14 @@ var stockAuditFunctions = {
|
|
|
1118
2625
|
"single-responsibility-violations": singleResponsibilityViolations,
|
|
1119
2626
|
"slow-tests": slowTests,
|
|
1120
2627
|
"stale-ideas": staleIdeas,
|
|
2628
|
+
"test-assertions": testAssertions,
|
|
1121
2629
|
"test-coverage": testCoverage,
|
|
2630
|
+
"test-pyramid": testPyramid,
|
|
1122
2631
|
"ubiquitous-language": ubiquitousLanguage,
|
|
1123
2632
|
"ux-audit": uxAudit
|
|
1124
2633
|
};
|
|
1125
2634
|
function loadStockAudits() {
|
|
1126
|
-
return Object.entries(stockAuditFunctions).
|
|
2635
|
+
return Object.entries(stockAuditFunctions).toSorted(([a], [b]) => a.localeCompare(b)).map(([name, render]) => {
|
|
1127
2636
|
const template = render();
|
|
1128
2637
|
const description = extractOpeningSentence(template);
|
|
1129
2638
|
return { name, description, template };
|
|
@@ -1173,7 +2682,7 @@ function buildAuditsRepository(fileSystem, dustPath) {
|
|
|
1173
2682
|
}
|
|
1174
2683
|
if (fileSystem.exists(userAuditsPath)) {
|
|
1175
2684
|
const files = await fileSystem.readdir(userAuditsPath);
|
|
1176
|
-
const mdFiles = files.filter((f) => f.endsWith(".md")).
|
|
2685
|
+
const mdFiles = files.filter((f) => f.endsWith(".md")).toSorted();
|
|
1177
2686
|
for (const file of mdFiles) {
|
|
1178
2687
|
const name = basename(file, ".md");
|
|
1179
2688
|
const filePath = `${userAuditsPath}/${file}`;
|
|
@@ -1195,7 +2704,7 @@ function buildAuditsRepository(fileSystem, dustPath) {
|
|
|
1195
2704
|
return {
|
|
1196
2705
|
async listAudits() {
|
|
1197
2706
|
const auditsMap = await loadAllAudits();
|
|
1198
|
-
return Array.from(auditsMap.values()).
|
|
2707
|
+
return Array.from(auditsMap.values()).toSorted((a, b) => a.name.localeCompare(b.name));
|
|
1199
2708
|
},
|
|
1200
2709
|
async parseAudit(options) {
|
|
1201
2710
|
const auditsMap = await loadAllAudits();
|