cap-pro 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/README.md +26 -0
- package/.claude-plugin/marketplace.json +24 -0
- package/.claude-plugin/plugin.json +24 -0
- package/LICENSE +21 -0
- package/README.ja-JP.md +834 -0
- package/README.ko-KR.md +823 -0
- package/README.md +806 -0
- package/README.pt-BR.md +452 -0
- package/README.zh-CN.md +800 -0
- package/agents/cap-architect.md +269 -0
- package/agents/cap-brainstormer.md +207 -0
- package/agents/cap-curator.md +276 -0
- package/agents/cap-debugger.md +365 -0
- package/agents/cap-designer.md +246 -0
- package/agents/cap-historian.md +464 -0
- package/agents/cap-migrator.md +291 -0
- package/agents/cap-prototyper.md +197 -0
- package/agents/cap-validator.md +308 -0
- package/bin/install.js +5433 -0
- package/cap/bin/cap-tools.cjs +853 -0
- package/cap/bin/lib/arc-scanner.cjs +344 -0
- package/cap/bin/lib/cap-affinity-engine.cjs +862 -0
- package/cap/bin/lib/cap-anchor.cjs +228 -0
- package/cap/bin/lib/cap-annotation-writer.cjs +340 -0
- package/cap/bin/lib/cap-checkpoint.cjs +434 -0
- package/cap/bin/lib/cap-cluster-detect.cjs +945 -0
- package/cap/bin/lib/cap-cluster-display.cjs +52 -0
- package/cap/bin/lib/cap-cluster-format.cjs +245 -0
- package/cap/bin/lib/cap-cluster-helpers.cjs +295 -0
- package/cap/bin/lib/cap-cluster-io.cjs +212 -0
- package/cap/bin/lib/cap-completeness.cjs +540 -0
- package/cap/bin/lib/cap-deps.cjs +583 -0
- package/cap/bin/lib/cap-design-families.cjs +332 -0
- package/cap/bin/lib/cap-design.cjs +966 -0
- package/cap/bin/lib/cap-divergence-detector.cjs +400 -0
- package/cap/bin/lib/cap-doctor.cjs +752 -0
- package/cap/bin/lib/cap-feature-map-internals.cjs +19 -0
- package/cap/bin/lib/cap-feature-map-migrate.cjs +335 -0
- package/cap/bin/lib/cap-feature-map-monorepo.cjs +885 -0
- package/cap/bin/lib/cap-feature-map-shard.cjs +315 -0
- package/cap/bin/lib/cap-feature-map.cjs +1943 -0
- package/cap/bin/lib/cap-fitness-score.cjs +1075 -0
- package/cap/bin/lib/cap-impact-analysis.cjs +652 -0
- package/cap/bin/lib/cap-learn-review.cjs +1072 -0
- package/cap/bin/lib/cap-learning-signals.cjs +627 -0
- package/cap/bin/lib/cap-loader.cjs +227 -0
- package/cap/bin/lib/cap-logger.cjs +57 -0
- package/cap/bin/lib/cap-memory-bridge.cjs +764 -0
- package/cap/bin/lib/cap-memory-confidence.cjs +452 -0
- package/cap/bin/lib/cap-memory-dir.cjs +987 -0
- package/cap/bin/lib/cap-memory-engine.cjs +698 -0
- package/cap/bin/lib/cap-memory-extends.cjs +398 -0
- package/cap/bin/lib/cap-memory-graph.cjs +790 -0
- package/cap/bin/lib/cap-memory-migrate.cjs +2015 -0
- package/cap/bin/lib/cap-memory-pin.cjs +183 -0
- package/cap/bin/lib/cap-memory-platform.cjs +490 -0
- package/cap/bin/lib/cap-memory-prune.cjs +707 -0
- package/cap/bin/lib/cap-memory-schema.cjs +812 -0
- package/cap/bin/lib/cap-migrate-tags.cjs +309 -0
- package/cap/bin/lib/cap-migrate.cjs +540 -0
- package/cap/bin/lib/cap-pattern-apply.cjs +1203 -0
- package/cap/bin/lib/cap-pattern-pipeline.cjs +1034 -0
- package/cap/bin/lib/cap-plugin-manifest.cjs +80 -0
- package/cap/bin/lib/cap-realtime-affinity.cjs +399 -0
- package/cap/bin/lib/cap-reconcile.cjs +570 -0
- package/cap/bin/lib/cap-research-gate.cjs +218 -0
- package/cap/bin/lib/cap-scope-filter.cjs +402 -0
- package/cap/bin/lib/cap-semantic-pipeline.cjs +1038 -0
- package/cap/bin/lib/cap-session-extract.cjs +987 -0
- package/cap/bin/lib/cap-session.cjs +445 -0
- package/cap/bin/lib/cap-snapshot-linkage.cjs +963 -0
- package/cap/bin/lib/cap-stack-docs.cjs +646 -0
- package/cap/bin/lib/cap-tag-observer.cjs +371 -0
- package/cap/bin/lib/cap-tag-scanner.cjs +1766 -0
- package/cap/bin/lib/cap-telemetry.cjs +466 -0
- package/cap/bin/lib/cap-test-audit.cjs +1438 -0
- package/cap/bin/lib/cap-thread-migrator.cjs +307 -0
- package/cap/bin/lib/cap-thread-synthesis.cjs +545 -0
- package/cap/bin/lib/cap-thread-tracker.cjs +519 -0
- package/cap/bin/lib/cap-trace.cjs +399 -0
- package/cap/bin/lib/cap-trust-mode.cjs +336 -0
- package/cap/bin/lib/cap-ui-design-editor.cjs +642 -0
- package/cap/bin/lib/cap-ui-mind-map.cjs +712 -0
- package/cap/bin/lib/cap-ui-thread-nav.cjs +693 -0
- package/cap/bin/lib/cap-ui.cjs +1245 -0
- package/cap/bin/lib/cap-upgrade.cjs +1028 -0
- package/cap/bin/lib/cli/arg-helpers.cjs +49 -0
- package/cap/bin/lib/cli/frontmatter-router.cjs +31 -0
- package/cap/bin/lib/cli/init-router.cjs +68 -0
- package/cap/bin/lib/cli/phase-router.cjs +102 -0
- package/cap/bin/lib/cli/state-router.cjs +61 -0
- package/cap/bin/lib/cli/template-router.cjs +37 -0
- package/cap/bin/lib/cli/uat-router.cjs +29 -0
- package/cap/bin/lib/cli/validation-router.cjs +26 -0
- package/cap/bin/lib/cli/verification-router.cjs +31 -0
- package/cap/bin/lib/cli/workstream-router.cjs +39 -0
- package/cap/bin/lib/commands.cjs +961 -0
- package/cap/bin/lib/config.cjs +467 -0
- package/cap/bin/lib/convention-reader.cjs +258 -0
- package/cap/bin/lib/core.cjs +1241 -0
- package/cap/bin/lib/feature-aggregator.cjs +423 -0
- package/cap/bin/lib/frontmatter.cjs +337 -0
- package/cap/bin/lib/init.cjs +1443 -0
- package/cap/bin/lib/manifest-generator.cjs +383 -0
- package/cap/bin/lib/milestone.cjs +253 -0
- package/cap/bin/lib/model-profiles.cjs +69 -0
- package/cap/bin/lib/monorepo-context.cjs +226 -0
- package/cap/bin/lib/monorepo-migrator.cjs +509 -0
- package/cap/bin/lib/phase.cjs +889 -0
- package/cap/bin/lib/profile-output.cjs +989 -0
- package/cap/bin/lib/profile-pipeline.cjs +540 -0
- package/cap/bin/lib/roadmap.cjs +330 -0
- package/cap/bin/lib/security.cjs +394 -0
- package/cap/bin/lib/session-manager.cjs +292 -0
- package/cap/bin/lib/skeleton-generator.cjs +179 -0
- package/cap/bin/lib/state.cjs +1032 -0
- package/cap/bin/lib/template.cjs +231 -0
- package/cap/bin/lib/test-detector.cjs +62 -0
- package/cap/bin/lib/uat.cjs +283 -0
- package/cap/bin/lib/verify.cjs +889 -0
- package/cap/bin/lib/workspace-detector.cjs +371 -0
- package/cap/bin/lib/workstream.cjs +492 -0
- package/cap/commands/gsd/workstreams.md +63 -0
- package/cap/references/arc-standard.md +315 -0
- package/cap/references/cap-agent-architecture.md +101 -0
- package/cap/references/cap-gitignore-template +9 -0
- package/cap/references/cap-zero-deps.md +158 -0
- package/cap/references/checkpoints.md +778 -0
- package/cap/references/continuation-format.md +249 -0
- package/cap/references/contract-test-templates.md +312 -0
- package/cap/references/feature-map-template.md +25 -0
- package/cap/references/git-integration.md +295 -0
- package/cap/references/git-planning-commit.md +38 -0
- package/cap/references/model-profiles.md +174 -0
- package/cap/references/phase-numbering.md +126 -0
- package/cap/references/planning-config.md +202 -0
- package/cap/references/property-test-templates.md +316 -0
- package/cap/references/security-test-templates.md +347 -0
- package/cap/references/session-template.json +8 -0
- package/cap/references/tdd.md +263 -0
- package/cap/references/user-profiling.md +681 -0
- package/cap/references/verification-patterns.md +612 -0
- package/cap/templates/UAT.md +265 -0
- package/cap/templates/claude-md.md +175 -0
- package/cap/templates/codebase/architecture.md +255 -0
- package/cap/templates/codebase/concerns.md +310 -0
- package/cap/templates/codebase/conventions.md +307 -0
- package/cap/templates/codebase/integrations.md +280 -0
- package/cap/templates/codebase/stack.md +186 -0
- package/cap/templates/codebase/structure.md +285 -0
- package/cap/templates/codebase/testing.md +480 -0
- package/cap/templates/config.json +44 -0
- package/cap/templates/context.md +352 -0
- package/cap/templates/continue-here.md +78 -0
- package/cap/templates/copilot-instructions.md +7 -0
- package/cap/templates/debug-subagent-prompt.md +91 -0
- package/cap/templates/discussion-log.md +63 -0
- package/cap/templates/milestone-archive.md +123 -0
- package/cap/templates/milestone.md +115 -0
- package/cap/templates/phase-prompt.md +610 -0
- package/cap/templates/planner-subagent-prompt.md +117 -0
- package/cap/templates/project.md +186 -0
- package/cap/templates/requirements.md +231 -0
- package/cap/templates/research-project/ARCHITECTURE.md +204 -0
- package/cap/templates/research-project/FEATURES.md +147 -0
- package/cap/templates/research-project/PITFALLS.md +200 -0
- package/cap/templates/research-project/STACK.md +120 -0
- package/cap/templates/research-project/SUMMARY.md +170 -0
- package/cap/templates/research.md +552 -0
- package/cap/templates/roadmap.md +202 -0
- package/cap/templates/state.md +176 -0
- package/cap/templates/summary.md +364 -0
- package/cap/templates/user-preferences.md +498 -0
- package/cap/templates/verification-report.md +322 -0
- package/cap/workflows/add-phase.md +112 -0
- package/cap/workflows/add-tests.md +351 -0
- package/cap/workflows/add-todo.md +158 -0
- package/cap/workflows/audit-milestone.md +340 -0
- package/cap/workflows/audit-uat.md +109 -0
- package/cap/workflows/autonomous.md +891 -0
- package/cap/workflows/check-todos.md +177 -0
- package/cap/workflows/cleanup.md +152 -0
- package/cap/workflows/complete-milestone.md +767 -0
- package/cap/workflows/diagnose-issues.md +231 -0
- package/cap/workflows/discovery-phase.md +289 -0
- package/cap/workflows/discuss-phase-assumptions.md +653 -0
- package/cap/workflows/discuss-phase.md +1049 -0
- package/cap/workflows/do.md +104 -0
- package/cap/workflows/execute-phase.md +846 -0
- package/cap/workflows/execute-plan.md +514 -0
- package/cap/workflows/fast.md +105 -0
- package/cap/workflows/forensics.md +265 -0
- package/cap/workflows/health.md +181 -0
- package/cap/workflows/help.md +660 -0
- package/cap/workflows/insert-phase.md +130 -0
- package/cap/workflows/list-phase-assumptions.md +178 -0
- package/cap/workflows/list-workspaces.md +56 -0
- package/cap/workflows/manager.md +362 -0
- package/cap/workflows/map-codebase.md +377 -0
- package/cap/workflows/milestone-summary.md +223 -0
- package/cap/workflows/new-milestone.md +486 -0
- package/cap/workflows/new-project.md +1250 -0
- package/cap/workflows/new-workspace.md +237 -0
- package/cap/workflows/next.md +97 -0
- package/cap/workflows/node-repair.md +92 -0
- package/cap/workflows/note.md +156 -0
- package/cap/workflows/pause-work.md +176 -0
- package/cap/workflows/plan-milestone-gaps.md +273 -0
- package/cap/workflows/plan-phase.md +857 -0
- package/cap/workflows/plant-seed.md +169 -0
- package/cap/workflows/pr-branch.md +129 -0
- package/cap/workflows/profile-user.md +449 -0
- package/cap/workflows/progress.md +507 -0
- package/cap/workflows/quick.md +757 -0
- package/cap/workflows/remove-phase.md +155 -0
- package/cap/workflows/remove-workspace.md +90 -0
- package/cap/workflows/research-phase.md +82 -0
- package/cap/workflows/resume-project.md +326 -0
- package/cap/workflows/review.md +228 -0
- package/cap/workflows/session-report.md +146 -0
- package/cap/workflows/settings.md +283 -0
- package/cap/workflows/ship.md +228 -0
- package/cap/workflows/stats.md +60 -0
- package/cap/workflows/transition.md +671 -0
- package/cap/workflows/ui-phase.md +298 -0
- package/cap/workflows/ui-review.md +161 -0
- package/cap/workflows/update.md +323 -0
- package/cap/workflows/validate-phase.md +170 -0
- package/cap/workflows/verify-phase.md +254 -0
- package/cap/workflows/verify-work.md +637 -0
- package/commands/cap/annotate.md +165 -0
- package/commands/cap/brainstorm.md +393 -0
- package/commands/cap/checkpoint.md +106 -0
- package/commands/cap/completeness.md +94 -0
- package/commands/cap/continue.md +72 -0
- package/commands/cap/debug.md +588 -0
- package/commands/cap/deps.md +169 -0
- package/commands/cap/design.md +479 -0
- package/commands/cap/init.md +354 -0
- package/commands/cap/iterate.md +249 -0
- package/commands/cap/learn.md +459 -0
- package/commands/cap/memory.md +275 -0
- package/commands/cap/migrate-feature-map.md +91 -0
- package/commands/cap/migrate-memory.md +108 -0
- package/commands/cap/migrate-tags.md +91 -0
- package/commands/cap/migrate.md +131 -0
- package/commands/cap/prototype.md +510 -0
- package/commands/cap/reconcile.md +121 -0
- package/commands/cap/review.md +360 -0
- package/commands/cap/save.md +72 -0
- package/commands/cap/scan.md +404 -0
- package/commands/cap/start.md +356 -0
- package/commands/cap/status.md +118 -0
- package/commands/cap/test-audit.md +262 -0
- package/commands/cap/test.md +394 -0
- package/commands/cap/trace.md +133 -0
- package/commands/cap/ui.md +167 -0
- package/hooks/dist/cap-check-update.js +115 -0
- package/hooks/dist/cap-context-monitor.js +185 -0
- package/hooks/dist/cap-learn-review-hook.js +114 -0
- package/hooks/dist/cap-learning-hook.js +192 -0
- package/hooks/dist/cap-memory.js +299 -0
- package/hooks/dist/cap-prompt-guard.js +97 -0
- package/hooks/dist/cap-statusline.js +157 -0
- package/hooks/dist/cap-tag-observer.js +115 -0
- package/hooks/dist/cap-version-check.js +112 -0
- package/hooks/dist/cap-workflow-guard.js +175 -0
- package/hooks/hooks.json +55 -0
- package/package.json +58 -0
- package/scripts/base64-scan.sh +262 -0
- package/scripts/build-hooks.js +93 -0
- package/scripts/cap-removal-checklist.md +202 -0
- package/scripts/prompt-injection-scan.sh +199 -0
- package/scripts/run-tests.cjs +181 -0
- package/scripts/secret-scan.sh +227 -0
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: cap:test-audit
|
|
3
|
+
description: Analyze test quality -- assertion density, coverage, mutation testing, anti-patterns, and trust score.
|
|
4
|
+
argument-hint: "[--coverage] [--mutations N] [--critical auth,payment] [--no-mutations]"
|
|
5
|
+
allowed-tools:
|
|
6
|
+
- Read
|
|
7
|
+
- Write
|
|
8
|
+
- Edit
|
|
9
|
+
- Bash
|
|
10
|
+
- Glob
|
|
11
|
+
- Grep
|
|
12
|
+
- AskUserQuestion
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
<!-- @cap-feature(feature:F-TEST-AUDIT) Test audit command -- orchestrates test quality analysis and generates trust score report. -->
|
|
16
|
+
<!-- @cap-decision Test audit combines assertion analysis, coverage, mutation testing, spot-checks, and anti-pattern detection into a single trust score. -->
|
|
17
|
+
|
|
18
|
+
<objective>
|
|
19
|
+
Analyze test quality across the project. Produces a trust score from 0-100 based on assertion density, code coverage, mutation testing results, and anti-pattern detection.
|
|
20
|
+
|
|
21
|
+
**Arguments:**
|
|
22
|
+
- `--coverage` -- force coverage analysis (default: auto-detect c8)
|
|
23
|
+
- `--no-coverage` -- skip coverage analysis
|
|
24
|
+
- `--mutations N` -- number of random mutations to apply (default: 10)
|
|
25
|
+
- `--no-mutations` -- skip mutation testing
|
|
26
|
+
- `--critical NAME,NAME` -- comma-separated critical path keywords (default: auth,payment,booking,rls,security)
|
|
27
|
+
- `--target FILE,FILE` -- comma-separated files for mutation testing (default: auto-detect from critical paths)
|
|
28
|
+
</objective>
|
|
29
|
+
|
|
30
|
+
<context>
|
|
31
|
+
$ARGUMENTS
|
|
32
|
+
|
|
33
|
+
@FEATURE-MAP.md
|
|
34
|
+
@.cap/SESSION.json
|
|
35
|
+
</context>
|
|
36
|
+
|
|
37
|
+
<process>
|
|
38
|
+
|
|
39
|
+
## Step 0: Parse flags
|
|
40
|
+
|
|
41
|
+
Check `$ARGUMENTS` for:
|
|
42
|
+
- `--coverage` / `--no-coverage`
|
|
43
|
+
- `--mutations N` / `--no-mutations`
|
|
44
|
+
- `--critical NAME,NAME`
|
|
45
|
+
- `--target FILE,FILE`
|
|
46
|
+
|
|
47
|
+
Set defaults:
|
|
48
|
+
- `runCoverage = true` (unless --no-coverage)
|
|
49
|
+
- `mutationCount = 10` (unless --no-mutations sets it to 0)
|
|
50
|
+
- `criticalPaths = ['auth', 'payment', 'booking', 'rls', 'security']`
|
|
51
|
+
- `targetFiles = []` (auto-detect below)
|
|
52
|
+
|
|
53
|
+
## Step 1: Detect test framework
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
node -e "
|
|
57
|
+
const fs = require('node:fs');
|
|
58
|
+
const path = require('node:path');
|
|
59
|
+
const cwd = process.cwd();
|
|
60
|
+
const result = { framework: 'node:test', testDir: 'tests', extension: '.test.cjs', testCommand: 'node --test tests/' };
|
|
61
|
+
|
|
62
|
+
if (fs.existsSync(path.join(cwd, 'package.json'))) {
|
|
63
|
+
const pkg = JSON.parse(fs.readFileSync(path.join(cwd, 'package.json'), 'utf8'));
|
|
64
|
+
const allDeps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
65
|
+
if (allDeps.vitest) { result.framework = 'vitest'; result.testCommand = 'npx vitest run'; }
|
|
66
|
+
else if (allDeps.jest) { result.framework = 'jest'; result.testCommand = 'npx jest'; }
|
|
67
|
+
if (allDeps.c8) result.hasC8 = true;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const testDirs = ['tests', 'test', '__tests__', 'spec'];
|
|
71
|
+
for (const d of testDirs) {
|
|
72
|
+
if (fs.existsSync(path.join(cwd, d))) { result.testDir = d; break; }
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
console.log(JSON.stringify(result));
|
|
76
|
+
"
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Store as `test_config`.
|
|
80
|
+
|
|
81
|
+
## Step 2: Auto-detect mutation target files
|
|
82
|
+
|
|
83
|
+
If `--target` not specified, find files matching critical path keywords:
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
node -e "
|
|
87
|
+
const fs = require('node:fs');
|
|
88
|
+
const path = require('node:path');
|
|
89
|
+
const criticalPaths = $CRITICAL_PATHS_JSON;
|
|
90
|
+
const cwd = process.cwd();
|
|
91
|
+
const targets = [];
|
|
92
|
+
|
|
93
|
+
function walk(dir) {
|
|
94
|
+
let entries;
|
|
95
|
+
try { entries = fs.readdirSync(dir, { withFileTypes: true }); } catch(_) { return; }
|
|
96
|
+
for (const e of entries) {
|
|
97
|
+
const full = path.join(dir, e.name);
|
|
98
|
+
if (e.isDirectory() && !['node_modules','.git','dist','build','coverage','.cap'].includes(e.name)) {
|
|
99
|
+
walk(full);
|
|
100
|
+
} else if (e.isFile() && ['.js','.cjs','.ts'].some(ext => e.name.endsWith(ext)) && !e.name.includes('.test.')) {
|
|
101
|
+
const lower = e.name.toLowerCase();
|
|
102
|
+
if (criticalPaths.some(cp => lower.includes(cp))) {
|
|
103
|
+
targets.push(path.relative(cwd, full));
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
walk(cwd);
|
|
109
|
+
console.log(JSON.stringify(targets));
|
|
110
|
+
"
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Store as `targetFiles`.
|
|
114
|
+
|
|
115
|
+
## Step 3: Run assertion analysis
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
node -e "
|
|
119
|
+
const audit = require('./cap/bin/lib/cap-test-audit.cjs');
|
|
120
|
+
const result = audit.analyzeAssertions(process.cwd());
|
|
121
|
+
console.log(JSON.stringify(result, null, 2));
|
|
122
|
+
"
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
Display:
|
|
126
|
+
```
|
|
127
|
+
ASSERTIONS
|
|
128
|
+
Total tests: {totalTests}
|
|
129
|
+
Total assertions: {totalAssertions}
|
|
130
|
+
Assertion density: {assertionDensity} per test
|
|
131
|
+
Empty tests: {emptyTests.length}
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
## Step 4: Run coverage analysis (if enabled)
|
|
135
|
+
|
|
136
|
+
If `runCoverage` and `test_config.hasC8`:
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
node -e "
|
|
140
|
+
const audit = require('./cap/bin/lib/cap-test-audit.cjs');
|
|
141
|
+
const result = audit.analyzeCoverage(process.cwd(), '$TEST_COMMAND');
|
|
142
|
+
console.log(JSON.stringify(result, null, 2));
|
|
143
|
+
"
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
Display:
|
|
147
|
+
```
|
|
148
|
+
COVERAGE
|
|
149
|
+
Lines: {lines}% Branches: {branches}% Functions: {functions}%
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
## Step 5: Run mutation testing (if enabled)
|
|
153
|
+
|
|
154
|
+
If `mutationCount > 0` and `targetFiles.length > 0`:
|
|
155
|
+
|
|
156
|
+
```bash
|
|
157
|
+
node -e "
|
|
158
|
+
const audit = require('./cap/bin/lib/cap-test-audit.cjs');
|
|
159
|
+
const result = audit.runMutationTests(
|
|
160
|
+
process.cwd(),
|
|
161
|
+
$TARGET_FILES_JSON,
|
|
162
|
+
'$TEST_COMMAND',
|
|
163
|
+
{ mutations: $MUTATION_COUNT, timeout: 30000 }
|
|
164
|
+
);
|
|
165
|
+
console.log(JSON.stringify(result, null, 2));
|
|
166
|
+
"
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
Display:
|
|
170
|
+
```
|
|
171
|
+
MUTATION SCORE
|
|
172
|
+
Mutations: {mutationsTotal} applied, {mutationsCaught} caught ({mutationScore}%)
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
## Step 6: Run spot-check generation
|
|
176
|
+
|
|
177
|
+
```bash
|
|
178
|
+
node -e "
|
|
179
|
+
const audit = require('./cap/bin/lib/cap-test-audit.cjs');
|
|
180
|
+
const result = audit.generateSpotChecks(process.cwd(), {
|
|
181
|
+
count: 3,
|
|
182
|
+
criticalPaths: $CRITICAL_PATHS_JSON
|
|
183
|
+
});
|
|
184
|
+
console.log(JSON.stringify(result, null, 2));
|
|
185
|
+
"
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
## Step 7: Run anti-pattern detection
|
|
189
|
+
|
|
190
|
+
```bash
|
|
191
|
+
node -e "
|
|
192
|
+
const audit = require('./cap/bin/lib/cap-test-audit.cjs');
|
|
193
|
+
const result = audit.detectAntiPatterns(process.cwd());
|
|
194
|
+
console.log(JSON.stringify(result, null, 2));
|
|
195
|
+
"
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
## Step 8: Generate trust score and write report
|
|
199
|
+
|
|
200
|
+
```bash
|
|
201
|
+
node -e "
|
|
202
|
+
const audit = require('./cap/bin/lib/cap-test-audit.cjs');
|
|
203
|
+
const fs = require('node:fs');
|
|
204
|
+
const path = require('node:path');
|
|
205
|
+
|
|
206
|
+
const report = audit.generateAuditReport(process.cwd(), {
|
|
207
|
+
testCommand: '$TEST_COMMAND',
|
|
208
|
+
criticalPaths: $CRITICAL_PATHS_JSON,
|
|
209
|
+
targetFiles: $TARGET_FILES_JSON,
|
|
210
|
+
coverage: $RUN_COVERAGE,
|
|
211
|
+
mutations: $RUN_MUTATIONS,
|
|
212
|
+
mutationCount: $MUTATION_COUNT,
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
// Write markdown report
|
|
216
|
+
const capDir = path.join(process.cwd(), '.cap');
|
|
217
|
+
if (!fs.existsSync(capDir)) fs.mkdirSync(capDir, { recursive: true });
|
|
218
|
+
|
|
219
|
+
const markdown = audit.formatAuditReport(report, '$PROJECT_NAME');
|
|
220
|
+
fs.writeFileSync(path.join(capDir, 'TEST-AUDIT.md'), markdown, 'utf8');
|
|
221
|
+
console.log(markdown);
|
|
222
|
+
"
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
## Step 9: Update session
|
|
226
|
+
|
|
227
|
+
```bash
|
|
228
|
+
node -e "
|
|
229
|
+
const session = require('./cap/bin/lib/cap-session.cjs');
|
|
230
|
+
session.updateSession(process.cwd(), {
|
|
231
|
+
lastCommand: '/cap:test-audit',
|
|
232
|
+
lastCommandTimestamp: new Date().toISOString(),
|
|
233
|
+
step: 'test-audit-complete'
|
|
234
|
+
});
|
|
235
|
+
"
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
## Step 10: Final report
|
|
239
|
+
|
|
240
|
+
Display the full formatted audit report to the user.
|
|
241
|
+
|
|
242
|
+
```
|
|
243
|
+
cap:test-audit complete.
|
|
244
|
+
|
|
245
|
+
Report written to: .cap/TEST-AUDIT.md
|
|
246
|
+
Trust score: {trustScore}/100
|
|
247
|
+
|
|
248
|
+
{If trustScore >= 80:}
|
|
249
|
+
High confidence -- tests are thorough and catch mutations.
|
|
250
|
+
{Else if trustScore >= 50:}
|
|
251
|
+
Moderate confidence -- review the spot-check guide and address anti-patterns.
|
|
252
|
+
{Else:}
|
|
253
|
+
Low confidence -- significant testing gaps detected. Address empty tests, weak assertions, and coverage gaps.
|
|
254
|
+
{End if}
|
|
255
|
+
|
|
256
|
+
Next steps:
|
|
257
|
+
- Review spot-check suggestions manually
|
|
258
|
+
- Address anti-patterns flagged above
|
|
259
|
+
- Run /cap:test to generate more tests for uncovered features
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
</process>
|
|
@@ -0,0 +1,394 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: cap:test
|
|
3
|
+
description: Write or extend RED-GREEN tests for a Feature Map entry's acceptance criteria. TRIGGER when a feature is in state `prototyped` and the user wants to verify it works, says "test this / write tests for F-XXX / add coverage / cover this with tests", or after `/cap:prototype` or `/cap:iterate` when code is in place but the feature isn't in state `tested` yet. Auto-detects framework (vitest, jest, node:test). --red-only stops after RED phase (TDD); --deep also runs test-audit (mutation, assertion-density, anti-patterns). DO NOT trigger for one-off test fixes — just edit the test file. Spawns cap-validator MODE: TEST.
|
|
4
|
+
argument-hint: "[--features NAME] [--red-only] [--deep]"
|
|
5
|
+
allowed-tools:
|
|
6
|
+
- Read
|
|
7
|
+
- Write
|
|
8
|
+
- Edit
|
|
9
|
+
- Bash
|
|
10
|
+
- Task
|
|
11
|
+
- Glob
|
|
12
|
+
- Grep
|
|
13
|
+
- AskUserQuestion
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
<!-- @cap-context CAP v2.0 test command -- orchestrates test generation against Feature Map ACs. Spawns cap-validator agent, collects test results, updates Feature Map test status. -->
|
|
17
|
+
<!-- @cap-decision Tests derive from Feature Map ACs, not from code inspection. This ensures tests verify the specification, not the implementation. -->
|
|
18
|
+
<!-- @cap-pattern --red-only flag stops after RED phase -- useful for TDD workflows where developer writes GREEN implementation manually. -->
|
|
19
|
+
|
|
20
|
+
<objective>
|
|
21
|
+
<!-- @cap-todo(ref:AC-52) /cap:test shall invoke the cap-validator agent with a RED-GREEN discipline mindset. -->
|
|
22
|
+
|
|
23
|
+
Spawns cap-validator to write tests against Feature Map acceptance criteria. Tests must demonstrate RED (fail against stubs) before GREEN (pass against implementation).
|
|
24
|
+
|
|
25
|
+
**Arguments:**
|
|
26
|
+
- `--features NAME` -- scope to specific Feature Map entries
|
|
27
|
+
- `--red-only` -- stop after RED phase (tests written, confirmed failing)
|
|
28
|
+
- `--deep` -- run test audit after tests pass (assertion density, coverage, mutations, anti-patterns, trust score). If trust score < 70%, shows prioritized improvement suggestions.
|
|
29
|
+
</objective>
|
|
30
|
+
|
|
31
|
+
<context>
|
|
32
|
+
$ARGUMENTS
|
|
33
|
+
|
|
34
|
+
@FEATURE-MAP.md
|
|
35
|
+
@.cap/SESSION.json
|
|
36
|
+
</context>
|
|
37
|
+
|
|
38
|
+
<process>
|
|
39
|
+
|
|
40
|
+
## Step 0: Parse flags
|
|
41
|
+
|
|
42
|
+
Check `$ARGUMENTS` for:
|
|
43
|
+
- `--features NAME` -- if present, store as `feature_filter`
|
|
44
|
+
- `--red-only` -- if present, set `red_only = true`
|
|
45
|
+
- `--deep` -- if present, set `deep_mode = true`
|
|
46
|
+
|
|
47
|
+
## Step 1: Read Feature Map and extract ACs for test generation
|
|
48
|
+
|
|
49
|
+
<!-- @cap-todo(ref:AC-54) cap-validator shall write tests that verify the acceptance criteria from the Feature Map entry for the active feature. -->
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
node -e "
|
|
53
|
+
const fm = require('./cap/bin/lib/cap-feature-map.cjs');
|
|
54
|
+
const session = require('./cap/bin/lib/cap-session.cjs');
|
|
55
|
+
// @cap-todo(ac:F-081/AC-4 iter:2) Migrated to {safe: true} opt-in to preserve CLI on duplicate-ID FEATURE-MAP.
|
|
56
|
+
// @cap-decision(F-081/iter2) Warn on parseError; continue with partial map for read-only display.
|
|
57
|
+
const featureMap = fm.readFeatureMap(process.cwd(), undefined, { safe: true });
|
|
58
|
+
if (featureMap && featureMap.parseError) {
|
|
59
|
+
console.warn('cap: test load — duplicate feature ID detected, target list uses partial map: ' + String(featureMap.parseError.message).trim());
|
|
60
|
+
}
|
|
61
|
+
const s = session.loadSession(process.cwd());
|
|
62
|
+
console.log(JSON.stringify({
|
|
63
|
+
activeFeature: s.activeFeature,
|
|
64
|
+
features: featureMap.features.map(f => ({
|
|
65
|
+
id: f.id, title: f.title, state: f.state,
|
|
66
|
+
acs: f.acs, files: f.files
|
|
67
|
+
}))
|
|
68
|
+
}));
|
|
69
|
+
"
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
**Scope features:**
|
|
73
|
+
- If `feature_filter`: filter to matching IDs
|
|
74
|
+
- Else if active feature: use only that feature
|
|
75
|
+
- Else: use all features with state `prototyped`
|
|
76
|
+
|
|
77
|
+
Store as `test_features`. Collect all ACs as `test_specs`.
|
|
78
|
+
|
|
79
|
+
If `test_features` is empty: STOP and report:
|
|
80
|
+
> "No prototyped features found. Run /cap:prototype first, or specify --features."
|
|
81
|
+
|
|
82
|
+
## Step 2: Detect test framework
|
|
83
|
+
|
|
84
|
+
<!-- @cap-todo(ref:AC-56) cap-validator shall use node:test for CJS code and vitest for SDK TypeScript code. -->
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
node -e "
|
|
88
|
+
const fs = require('node:fs');
|
|
89
|
+
const path = require('node:path');
|
|
90
|
+
const cwd = process.cwd();
|
|
91
|
+
const result = { framework: 'node:test', testDir: 'tests', extension: '.test.cjs' };
|
|
92
|
+
|
|
93
|
+
// Check package.json
|
|
94
|
+
if (fs.existsSync(path.join(cwd, 'package.json'))) {
|
|
95
|
+
const pkg = JSON.parse(fs.readFileSync(path.join(cwd, 'package.json'), 'utf8'));
|
|
96
|
+
const allDeps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
97
|
+
if (allDeps.vitest) result.framework = 'vitest';
|
|
98
|
+
else if (allDeps.jest) result.framework = 'jest';
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Check for existing test patterns
|
|
102
|
+
const testDirs = ['tests', 'test', '__tests__', 'spec'];
|
|
103
|
+
for (const d of testDirs) {
|
|
104
|
+
if (fs.existsSync(path.join(cwd, d))) { result.testDir = d; break; }
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// Check for SDK directory (vitest scope)
|
|
108
|
+
if (fs.existsSync(path.join(cwd, 'sdk'))) {
|
|
109
|
+
result.sdkTestFramework = 'vitest';
|
|
110
|
+
result.sdkTestDir = 'sdk/src';
|
|
111
|
+
result.sdkExtension = '.test.ts';
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// Detect extension from existing tests
|
|
115
|
+
try {
|
|
116
|
+
const existing = fs.readdirSync(path.join(cwd, result.testDir));
|
|
117
|
+
const testFile = existing.find(f => f.includes('.test.'));
|
|
118
|
+
if (testFile) result.extension = path.extname(testFile).replace('.', '.test.');
|
|
119
|
+
} catch (_) {}
|
|
120
|
+
|
|
121
|
+
console.log(JSON.stringify(result));
|
|
122
|
+
"
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
Store as `test_config`.
|
|
126
|
+
|
|
127
|
+
## Step 3: Spawn cap-validator agent
|
|
128
|
+
|
|
129
|
+
<!-- @cap-todo(ref:AC-53) cap-validator shall approach testing with a "how do I break this?" adversarial mindset. -->
|
|
130
|
+
<!-- @cap-todo(ref:AC-57) Green tests shall replace the need for a separate VERIFICATION.md artifact. -->
|
|
131
|
+
|
|
132
|
+
Spawn `cap-validator` via Task tool:
|
|
133
|
+
|
|
134
|
+
```
|
|
135
|
+
**MODE: TEST**
|
|
136
|
+
|
|
137
|
+
$ARGUMENTS
|
|
138
|
+
|
|
139
|
+
**RED-GREEN DISCIPLINE**
|
|
140
|
+
{If red_only:} Stop after RED phase -- write tests that FAIL. Do not implement GREEN.
|
|
141
|
+
{Else:} Full RED-GREEN cycle -- write failing tests, then make them pass.
|
|
142
|
+
|
|
143
|
+
**Test framework:** {test_config.framework}
|
|
144
|
+
**Test directory:** {test_config.testDir}
|
|
145
|
+
**Test extension:** {test_config.extension}
|
|
146
|
+
{If test_config.sdkTestFramework:}
|
|
147
|
+
**SDK tests:** {test_config.sdkTestFramework} in {test_config.sdkTestDir} ({test_config.sdkExtension})
|
|
148
|
+
{End if}
|
|
149
|
+
|
|
150
|
+
**Features under test:**
|
|
151
|
+
{For each test_feature:}
|
|
152
|
+
Feature: {feature.id} - {feature.title} [{feature.state}]
|
|
153
|
+
Implementation files: {feature.files.join(', ')}
|
|
154
|
+
Acceptance criteria:
|
|
155
|
+
{For each AC:}
|
|
156
|
+
{ac.id}: {ac.description} [{ac.status}]
|
|
157
|
+
{End for}
|
|
158
|
+
{End for}
|
|
159
|
+
|
|
160
|
+
**Testing obligations:**
|
|
161
|
+
1. Each AC produces AT LEAST one test case
|
|
162
|
+
2. Adversarial mindset: "how do I break this?"
|
|
163
|
+
3. Test edge cases, error paths, and boundary conditions
|
|
164
|
+
4. For CJS code: use node:test (require('node:test'), require('node:assert'))
|
|
165
|
+
5. For SDK TypeScript: use vitest
|
|
166
|
+
6. Name test files: {feature.id.toLowerCase()}-{slug}.test.{ext}
|
|
167
|
+
7. Annotate untested code paths with @cap-risk tags
|
|
168
|
+
|
|
169
|
+
**RED phase (mandatory):**
|
|
170
|
+
- Write all tests
|
|
171
|
+
- Run them to confirm they FAIL against stubs or missing implementation
|
|
172
|
+
- Report RED results
|
|
173
|
+
|
|
174
|
+
{If NOT red_only:}
|
|
175
|
+
**GREEN phase:**
|
|
176
|
+
- Implement minimum code to make tests pass
|
|
177
|
+
- Run tests to confirm GREEN
|
|
178
|
+
- Report GREEN results
|
|
179
|
+
{End if}
|
|
180
|
+
|
|
181
|
+
**Return format:**
|
|
182
|
+
=== TEST RESULTS ===
|
|
183
|
+
PHASE: {RED or GREEN}
|
|
184
|
+
TESTS_WRITTEN: N
|
|
185
|
+
TESTS_PASSING: N
|
|
186
|
+
TESTS_FAILING: N
|
|
187
|
+
FILES_CREATED: [list]
|
|
188
|
+
UNTESTED_PATHS: [list of code paths without test coverage]
|
|
189
|
+
=== END TEST RESULTS ===
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
Wait for cap-validator to complete. Parse results.
|
|
193
|
+
|
|
194
|
+
## Step 4: Run tests and capture results
|
|
195
|
+
|
|
196
|
+
```bash
|
|
197
|
+
node --test {test_config.testDir}/*.test.cjs 2>&1 | tail -20
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
Store exit code and output.
|
|
201
|
+
|
|
202
|
+
## Step 5: Update Feature Map status
|
|
203
|
+
|
|
204
|
+
<!-- @cap-todo(ref:AC-55) cap-validator shall update the feature state in FEATURE-MAP.md from prototyped to tested when all tests pass. -->
|
|
205
|
+
|
|
206
|
+
If all tests pass and `red_only` is false:
|
|
207
|
+
|
|
208
|
+
```bash
|
|
209
|
+
node -e "
|
|
210
|
+
const fm = require('./cap/bin/lib/cap-feature-map.cjs');
|
|
211
|
+
const targetIds = {JSON.stringify(target_feature_ids)};
|
|
212
|
+
for (const id of targetIds) {
|
|
213
|
+
const result = fm.updateFeatureState(process.cwd(), id, 'tested');
|
|
214
|
+
console.log(id + ': ' + (result ? 'updated to tested' : 'state unchanged'));
|
|
215
|
+
}
|
|
216
|
+
"
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
Update session:
|
|
220
|
+
|
|
221
|
+
```bash
|
|
222
|
+
node -e "
|
|
223
|
+
const session = require('./cap/bin/lib/cap-session.cjs');
|
|
224
|
+
session.updateSession(process.cwd(), {
|
|
225
|
+
lastCommand: '/cap:test',
|
|
226
|
+
lastCommandTimestamp: new Date().toISOString(),
|
|
227
|
+
step: 'test-complete'
|
|
228
|
+
});
|
|
229
|
+
"
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
## Step 6: Final report
|
|
233
|
+
|
|
234
|
+
<!-- @cap-feature(feature:F-023) Emoji-Enhanced AC Status and Human Verification Checklist -->
|
|
235
|
+
|
|
236
|
+
```
|
|
237
|
+
cap:test complete.
|
|
238
|
+
|
|
239
|
+
Phase: {RED or GREEN}
|
|
240
|
+
Tests written: {tests_written}
|
|
241
|
+
Tests passing: {tests_passing}
|
|
242
|
+
Tests failing: {tests_failing}
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
<!-- @cap-todo(ac:F-023/AC-2) Display AC table with emoji status after test -->
|
|
246
|
+
<!-- @cap-todo(ac:F-023/AC-6) Emojis in terminal output only -->
|
|
247
|
+
|
|
248
|
+
**Display the AC status table with emojis (terminal output only):**
|
|
249
|
+
|
|
250
|
+
```bash
|
|
251
|
+
node -e "
|
|
252
|
+
const fm = require('./cap/bin/lib/cap-feature-map.cjs');
|
|
253
|
+
// @cap-todo(ac:F-081/AC-4 iter:2) Migrated to {safe: true} opt-in to preserve CLI on duplicate-ID FEATURE-MAP.
|
|
254
|
+
// @cap-decision(F-081/iter2) Warn on parseError; continue with partial map for read-only display.
|
|
255
|
+
const featureMap = fm.readFeatureMap(process.cwd(), undefined, { safe: true });
|
|
256
|
+
if (featureMap && featureMap.parseError) {
|
|
257
|
+
console.warn('cap: test AC-table — duplicate feature ID detected, table uses partial map: ' + String(featureMap.parseError.message).trim());
|
|
258
|
+
}
|
|
259
|
+
const targetIds = {JSON.stringify(target_feature_ids)};
|
|
260
|
+
for (const id of targetIds) {
|
|
261
|
+
const f = featureMap.features.find(feat => feat.id === id);
|
|
262
|
+
if (!f) continue;
|
|
263
|
+
console.log('\n ' + f.id + ': ' + f.title + ' [' + f.state + ']');
|
|
264
|
+
for (const ac of f.acs) {
|
|
265
|
+
const emoji = ac.status === 'tested' ? '✅' : ac.status === 'prototyped' ? '🔨' : ac.status === 'partial' ? '⚠️' : '📋';
|
|
266
|
+
console.log(' ' + emoji + ' ' + ac.id + ': ' + ac.description);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
"
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
```
|
|
273
|
+
{If red_only:}
|
|
274
|
+
RED phase complete. Tests are written and confirmed failing.
|
|
275
|
+
Run /cap:iterate to implement, then re-run /cap:test without --red-only.
|
|
276
|
+
{Else if all_pass:}
|
|
277
|
+
GREEN phase complete. All tests pass.
|
|
278
|
+
Feature state updated: {feature_ids} -> tested
|
|
279
|
+
{Else:}
|
|
280
|
+
Some tests failing. Fix implementation and re-run /cap:test.
|
|
281
|
+
{End if}
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
{If untested_paths:}
|
|
285
|
+
```
|
|
286
|
+
Untested code paths flagged with @cap-risk:
|
|
287
|
+
{For each path: - path}
|
|
288
|
+
```
|
|
289
|
+
{End if}
|
|
290
|
+
|
|
291
|
+
<!-- @cap-todo(ac:F-023/AC-3) Auto-generate Human Verification Checklist after test -->
|
|
292
|
+
<!-- @cap-todo(ac:F-023/AC-4) Derive checklist items from ACs that aren't fully automatable -->
|
|
293
|
+
<!-- @cap-todo(ac:F-023/AC-5) Format as markdown checkboxes -->
|
|
294
|
+
|
|
295
|
+
## Step 7: Human Verification Checklist
|
|
296
|
+
|
|
297
|
+
**If all tests pass and NOT `red_only`:**
|
|
298
|
+
|
|
299
|
+
Generate a verification checklist from the feature's ACs. For each AC, determine if it requires human verification (anything involving visual output, user flow, permissions, external services, or cross-device behavior).
|
|
300
|
+
|
|
301
|
+
**Display to user (terminal output with emojis):**
|
|
302
|
+
|
|
303
|
+
```
|
|
304
|
+
🔍 Human Verification Checklist — {feature.id}: {feature.title}
|
|
305
|
+
|
|
306
|
+
{For each target_feature:}
|
|
307
|
+
{For each AC — categorize and generate checklist items:}
|
|
308
|
+
|
|
309
|
+
{If AC involves visual/UI behavior:}
|
|
310
|
+
🌐 Browser / Visual
|
|
311
|
+
- [ ] {Derived check from AC, e.g., "Verify error message displays correctly when module is missing"}
|
|
312
|
+
{End if}
|
|
313
|
+
|
|
314
|
+
{If AC involves user interaction/flow:}
|
|
315
|
+
🔍 Manual Verification
|
|
316
|
+
- [ ] {Derived check, e.g., "Run npx code-as-plan@latest --force and verify clean install completes"}
|
|
317
|
+
{End if}
|
|
318
|
+
|
|
319
|
+
{If AC involves permissions/security:}
|
|
320
|
+
🔐 Security / Permissions
|
|
321
|
+
- [ ] {Derived check, e.g., "Verify non-root user can install without sudo"}
|
|
322
|
+
{End if}
|
|
323
|
+
|
|
324
|
+
{If AC involves performance/timing:}
|
|
325
|
+
⚡ Performance
|
|
326
|
+
- [ ] {Derived check, e.g., "Verify install completes in under 30 seconds on cold cache"}
|
|
327
|
+
{End if}
|
|
328
|
+
|
|
329
|
+
{If AC involves cross-platform/environment:}
|
|
330
|
+
💻 Cross-Platform
|
|
331
|
+
- [ ] {Derived check, e.g., "Test on Linux with symlinked $HOME"}
|
|
332
|
+
{End if}
|
|
333
|
+
|
|
334
|
+
{If AC is purely automatable (covered by unit tests):}
|
|
335
|
+
✅ {ac.id}: Covered by automated tests
|
|
336
|
+
{End if}
|
|
337
|
+
|
|
338
|
+
{End for}
|
|
339
|
+
{End for}
|
|
340
|
+
|
|
341
|
+
Status: [ ] All checks passed [ ] Issues found
|
|
342
|
+
Verified by: ________________ Date: ________________
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
**Note:** The checklist is displayed in the terminal only. If the user wants to save it, they can run `/cap:review` which writes it to `.cap/MANUAL-TESTS.md`.
|
|
346
|
+
|
|
347
|
+
## Step 8: Deep audit (if --deep)
|
|
348
|
+
|
|
349
|
+
If `deep_mode` is true and tests passed (not `red_only`):
|
|
350
|
+
|
|
351
|
+
```bash
|
|
352
|
+
node -e "const a = require('./cap/bin/lib/cap-test-audit.cjs'); const r = a.generateAuditReport(process.cwd()); const fs = require('fs'); fs.writeFileSync('.cap/TEST-AUDIT.md', a.formatAuditReport(r), 'utf8'); console.log(JSON.stringify({ trustScore: r.trustScore, assertions: r.assertions.totalAssertions, density: r.assertions.assertionDensity, emptyTests: r.assertions.emptyTests.length, antiPatterns: r.antiPatterns.flags.length, coverageLines: r.coverage ? r.coverage.lines : null }));"
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
Store as `audit`.
|
|
356
|
+
|
|
357
|
+
Display the audit summary:
|
|
358
|
+
|
|
359
|
+
```
|
|
360
|
+
Test Audit (--deep)
|
|
361
|
+
Trust score: {audit.trustScore}/100
|
|
362
|
+
Assertions: {audit.assertions} total ({audit.density} per test)
|
|
363
|
+
Empty tests: {audit.emptyTests}
|
|
364
|
+
Anti-patterns: {audit.antiPatterns}
|
|
365
|
+
Coverage: {audit.coverageLines ?? 'not available'}%
|
|
366
|
+
Report: .cap/TEST-AUDIT.md
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
**If `audit.trustScore < 70`:**
|
|
370
|
+
|
|
371
|
+
Read and display the IMPROVEMENT SUGGESTIONS section from `.cap/TEST-AUDIT.md`:
|
|
372
|
+
|
|
373
|
+
```bash
|
|
374
|
+
node -e "const fs = require('fs'); const c = fs.readFileSync('.cap/TEST-AUDIT.md', 'utf8'); const idx = c.indexOf('IMPROVEMENT SUGGESTIONS'); if (idx >= 0) console.log(c.substring(idx, c.indexOf('Generated:', idx))); else console.log('No suggestions — score is adequate.');"
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
Display suggestions and ask the user:
|
|
378
|
+
> "Trust score is {audit.trustScore}/100 (target: 70+). Want me to address the top suggestion now?"
|
|
379
|
+
|
|
380
|
+
If user agrees, implement the top suggestion (add assertions, fix empty tests, or address anti-patterns) and re-run the audit.
|
|
381
|
+
|
|
382
|
+
**If `audit.trustScore >= 70`:**
|
|
383
|
+
|
|
384
|
+
```
|
|
385
|
+
Trust score {audit.trustScore}/100 — tests are reliable.
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
```
|
|
389
|
+
Next steps:
|
|
390
|
+
- Work through the verification checklist above
|
|
391
|
+
- Run /cap:review to verify code quality and save checklist
|
|
392
|
+
```
|
|
393
|
+
|
|
394
|
+
</process>
|