@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/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
- - [ ] Searched for N+1 query patterns (loops with data access)
117
- - [ ] Reviewed database schemas for missing indexes (if applicable)
118
- - [ ] Identified over-fetching or under-fetching patterns
119
- - [ ] Found repeated lookups that could be cached
120
- - [ ] Checked for sequential operations that could be batched
121
- - [ ] Verified connection/resource cleanup is handled properly
122
- - [ ] Proposed ideas for any data access improvements identified
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
- - [ ] Identified all coverage exclusions in the project
157
- - [ ] Documented the reason each exclusion exists
158
- - [ ] Evaluated whether each exclusion is still necessary
159
- - [ ] Identified exclusions that could be removed through decoupling
160
- - [ ] Proposed ideas for refactoring where feasible
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
- - [ ] Searched for repeated patterns across the codebase
193
- - [ ] Identified copy-pasted or near-duplicate code
194
- - [ ] Evaluated each case for whether extraction would be beneficial
195
- - [ ] Considered whether similar code serves different purposes that may evolve independently
196
- - [ ] Proposed ideas only for extractions where duplication is truly about the same concept
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
- - [ ] Reviewed file sizes and organization for context window fit
228
- - [ ] Verified test coverage is sufficient for agent verification
229
- - [ ] Measured feedback loop speed (time from change to check result)
230
- - [ ] Confirmed debugging tools and structured logging are in place
231
- - [ ] Proposed ideas for any improvements identified
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
- - [ ] Ran static analysis tools to find unused exports
263
- - [ ] Identified files with no incoming imports
264
- - [ ] Listed unused dependencies
265
- - [ ] Reviewed commented-out code blocks
266
- - [ ] Created list of code safe to remove
267
- - [ ] Verified removal won't break dynamic imports or reflection
268
- - [ ] Proposed ideas for any dead code worth removing
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
- - [ ] Read each fact file in \`.dust/facts/\`
299
- - [ ] Verified each fact against current codebase
300
- - [ ] Identified outdated or inaccurate facts
301
- - [ ] Listed missing facts that would help agents
302
- - [ ] Updated or removed stale facts
303
- - [ ] Proposed ideas for any facts improvements needed
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
- - [ ] Reviewed commits from the last 20 commits
334
- - [ ] Identified patterns or shortcuts worth addressing
335
- - [ ] Listed TODO comments added in recent commits
336
- - [ ] Noted areas where changes could be generalized
337
- - [ ] Proposed follow-up ideas for any issues identified
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
- - [ ] Read each principle file in \`.dust/principles/\`
368
- - [ ] Analyzed codebase for alignment with each principle
369
- - [ ] Listed gaps between current state and principle intent
370
- - [ ] Proposed new ideas for unmet or underserved principles
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
- - [ ] Identified high-churn files (modified in 3+ commits since last audit)
417
- - [ ] Flagged files exceeding 300 lines that grew significantly
418
- - [ ] Noted commits with concerning message patterns
419
- - [ ] Provided specific refactoring suggestions for each opportunity
420
- - [ ] Created ideas for any substantial refactoring work identified
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
- - [ ] Measured startup time for common commands
452
- - [ ] Profiled memory usage during typical operations
453
- - [ ] Identified slow commands or operations
454
- - [ ] Listed optimization opportunities by impact
455
- - [ ] Proposed ideas for any performance improvements identified
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
- - [ ] Searched for hardcoded secrets (API keys, passwords, tokens)
487
- - [ ] Reviewed input validation and sanitization
488
- - [ ] Checked authentication and authorization logic
489
- - [ ] Verified sensitive data is not logged or exposed
490
- - [ ] Ran dependency audit for known vulnerabilities
491
- - [ ] Documented any findings with severity ratings
492
- - [ ] Proposed ideas for any security issues found
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
- - [ ] Listed all ideas with their last modification date
523
- - [ ] Identified ideas unchanged for 50+ commits
524
- - [ ] Reviewed each stale idea for current relevance
525
- - [ ] Promoted actionable ideas to tasks
526
- - [ ] Deleted ideas that are no longer relevant
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
- - [ ] Identified modules with low or no test coverage
558
- - [ ] Listed critical paths that lack tests
559
- - [ ] Prioritized areas by risk and importance
560
- - [ ] Proposed ideas for any test coverage gaps identified
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
- - [ ] Searched for empty catch blocks and silent error swallowing
610
- - [ ] Identified patterns that discard error details
611
- - [ ] Found fire-and-forget promises without error handling
612
- - [ ] Reviewed error messages for actionability
613
- - [ ] Compared error handling consistency across similar operations
614
- - [ ] Proposed ideas for any error handling improvements identified
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
- - [ ] Searched for module-level mutable variables (let/var outside functions)
665
- - [ ] Identified singleton patterns and getInstance methods
666
- - [ ] Found global registries (Maps, Sets, Arrays modified at module level)
667
- - [ ] Located functions with implicit dependencies on module-level state
668
- - [ ] Checked for scattered process.env access
669
- - [ ] Documented impact of each global state instance on testing
670
- - [ ] Proposed ideas for refactoring global state to explicit dependencies
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
- - [ ] \`.dust/repository.md\` exists and is up to date
715
- - [ ] Document describes what the project does without referencing specific files
716
- - [ ] Key capabilities and features are listed
717
- - [ ] Design philosophy or guiding approach is captured
718
- - [ ] Document is concise enough to fit comfortably in an agent context window
719
- - [ ] A new agent reading only this document could make sensible high-level suggestions
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
- - [ ] Ran test suite with timing information
773
- - [ ] Listed tests exceeding duration thresholds (100ms unit, 1s integration)
774
- - [ ] Identified tests using sleep/setTimeout/delay patterns
775
- - [ ] Found tests with unmocked I/O (network, database, file system)
776
- - [ ] Reviewed beforeEach/beforeAll for optimization opportunities
777
- - [ ] Checked test parallelization configuration
778
- - [ ] Proposed ideas for optimizing the slowest tests
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
- - [ ] Reviewed high-confidence factory/constructor naming consistency for equivalent creation APIs
830
- - [ ] Constrained findings to \`build*\`, \`create*\`, \`make*\`, and \`new*\` naming variants with clearly equivalent intent
831
- - [ ] Documented each finding with locations, inconsistent term set, canonical proposal, and migration strategy
832
- - [ ] Chose incremental or one-shot migration strategy for each canonical proposal
833
- - [ ] Avoided speculative broad renames
834
- - [ ] Avoided artifact-list ordering/shape checks and broad terminology drift
835
- - [ ] Proposed ideas for naming consistency improvements identified
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
- - [ ] Reviewed high-confidence existing-type drift for domain string literals and numeric magic values
905
- - [ ] Constrained findings to cases where canonical domain types or clear constant/wrapper opportunities already exist
906
- - [ ] Documented each finding with locations, primitive pattern, constant/type opportunity, and incremental migration path
907
- - [ ] Documented numeric findings with locations, numeric pattern, constant/type opportunity, and incremental migration path
908
- - [ ] Preserved Functional Core, Imperative Shell boundaries in recommendations
909
- - [ ] Avoided speculative introduction of entirely new types
910
- - [ ] Proposed ideas for primitive obsession improvements identified
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
- - [ ] Reviewed high-confidence function-level findings where 3+ distinct responsibilities are combined
972
- - [ ] Included runtime code and test helpers in scope
973
- - [ ] Documented each finding with location, responsibility split, severity, and suggested extraction plan
974
- - [ ] Preserved Functional Core, Imperative Shell boundaries in recommendations
975
- - [ ] Kept recommendations high-confidence only with clear concern boundaries
976
- - [ ] Proposed ideas for substantial responsibility-splitting work identified
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
- - [ ] Identified key domain terms from project documentation
1025
- - [ ] Reviewed recent commits for terminology consistency
1026
- - [ ] Compared code naming against documentation vocabulary
1027
- - [ ] Checked user-facing text for alignment with code terms
1028
- - [ ] Documented any terminology drift or inconsistencies found
1029
- - [ ] Proposed ideas for standardizing inconsistent terminology
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
- - [ ] Identified the application type (web, terminal, hybrid, or no UI)
1093
- - [ ] Listed key user scenarios
1094
- - [ ] Captured screenshots or output at each stage of key scenarios
1095
- - [ ] Reviewed evidence for UX issues
1096
- - [ ] Documented findings with evidence and recommendations
1097
- - [ ] Included verification criteria for each issue
1098
- - [ ] Created ideas for any UX improvements needed
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).sort(([a], [b]) => a.localeCompare(b)).map(([name, render]) => {
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")).sort();
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()).sort((a, b) => a.name.localeCompare(b.name));
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();