forge-server 0.1.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/hooks/worktree-create.sh +64 -0
- package/.claude/hooks/worktree-remove.sh +57 -0
- package/.claude/settings.local.json +29 -0
- package/.forge/knowledge/conventions.yaml +1 -0
- package/.forge/knowledge/decisions.yaml +1 -0
- package/.forge/knowledge/gotchas.yaml +1 -0
- package/.forge/knowledge/patterns.yaml +1 -0
- package/.forge/manifest.yaml +6 -0
- package/CLAUDE.md +144 -0
- package/bin/setup-forge.sh +132 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +553 -0
- package/dist/cli.js.map +1 -0
- package/dist/context/codebase.d.ts +57 -0
- package/dist/context/codebase.d.ts.map +1 -0
- package/dist/context/codebase.js +301 -0
- package/dist/context/codebase.js.map +1 -0
- package/dist/context/injector.d.ts +147 -0
- package/dist/context/injector.d.ts.map +1 -0
- package/dist/context/injector.js +533 -0
- package/dist/context/injector.js.map +1 -0
- package/dist/context/memory.d.ts +32 -0
- package/dist/context/memory.d.ts.map +1 -0
- package/dist/context/memory.js +140 -0
- package/dist/context/memory.js.map +1 -0
- package/dist/context/session-index.d.ts +54 -0
- package/dist/context/session-index.d.ts.map +1 -0
- package/dist/context/session-index.js +265 -0
- package/dist/context/session-index.js.map +1 -0
- package/dist/context/session.d.ts +42 -0
- package/dist/context/session.d.ts.map +1 -0
- package/dist/context/session.js +121 -0
- package/dist/context/session.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +37 -0
- package/dist/index.js.map +1 -0
- package/dist/ingestion/chunker.d.ts +19 -0
- package/dist/ingestion/chunker.d.ts.map +1 -0
- package/dist/ingestion/chunker.js +189 -0
- package/dist/ingestion/chunker.js.map +1 -0
- package/dist/ingestion/embedder.d.ts +45 -0
- package/dist/ingestion/embedder.d.ts.map +1 -0
- package/dist/ingestion/embedder.js +152 -0
- package/dist/ingestion/embedder.js.map +1 -0
- package/dist/ingestion/git-analyzer.d.ts +77 -0
- package/dist/ingestion/git-analyzer.d.ts.map +1 -0
- package/dist/ingestion/git-analyzer.js +437 -0
- package/dist/ingestion/git-analyzer.js.map +1 -0
- package/dist/ingestion/indexer.d.ts +79 -0
- package/dist/ingestion/indexer.d.ts.map +1 -0
- package/dist/ingestion/indexer.js +766 -0
- package/dist/ingestion/indexer.js.map +1 -0
- package/dist/ingestion/markdown-chunker.d.ts +19 -0
- package/dist/ingestion/markdown-chunker.d.ts.map +1 -0
- package/dist/ingestion/markdown-chunker.js +243 -0
- package/dist/ingestion/markdown-chunker.js.map +1 -0
- package/dist/ingestion/markdown-knowledge.d.ts +21 -0
- package/dist/ingestion/markdown-knowledge.d.ts.map +1 -0
- package/dist/ingestion/markdown-knowledge.js +129 -0
- package/dist/ingestion/markdown-knowledge.js.map +1 -0
- package/dist/ingestion/parser.d.ts +20 -0
- package/dist/ingestion/parser.d.ts.map +1 -0
- package/dist/ingestion/parser.js +429 -0
- package/dist/ingestion/parser.js.map +1 -0
- package/dist/ingestion/watcher.d.ts +28 -0
- package/dist/ingestion/watcher.d.ts.map +1 -0
- package/dist/ingestion/watcher.js +147 -0
- package/dist/ingestion/watcher.js.map +1 -0
- package/dist/knowledge/hydrator.d.ts +37 -0
- package/dist/knowledge/hydrator.d.ts.map +1 -0
- package/dist/knowledge/hydrator.js +220 -0
- package/dist/knowledge/hydrator.js.map +1 -0
- package/dist/knowledge/registry.d.ts +129 -0
- package/dist/knowledge/registry.d.ts.map +1 -0
- package/dist/knowledge/registry.js +361 -0
- package/dist/knowledge/registry.js.map +1 -0
- package/dist/knowledge/search.d.ts +114 -0
- package/dist/knowledge/search.d.ts.map +1 -0
- package/dist/knowledge/search.js +428 -0
- package/dist/knowledge/search.js.map +1 -0
- package/dist/knowledge/store.d.ts +76 -0
- package/dist/knowledge/store.d.ts.map +1 -0
- package/dist/knowledge/store.js +230 -0
- package/dist/knowledge/store.js.map +1 -0
- package/dist/learning/confidence.d.ts +30 -0
- package/dist/learning/confidence.d.ts.map +1 -0
- package/dist/learning/confidence.js +165 -0
- package/dist/learning/confidence.js.map +1 -0
- package/dist/learning/patterns.d.ts +52 -0
- package/dist/learning/patterns.d.ts.map +1 -0
- package/dist/learning/patterns.js +290 -0
- package/dist/learning/patterns.js.map +1 -0
- package/dist/learning/trajectory.d.ts +55 -0
- package/dist/learning/trajectory.d.ts.map +1 -0
- package/dist/learning/trajectory.js +200 -0
- package/dist/learning/trajectory.js.map +1 -0
- package/dist/memory/memory-compat.d.ts +100 -0
- package/dist/memory/memory-compat.d.ts.map +1 -0
- package/dist/memory/memory-compat.js +146 -0
- package/dist/memory/memory-compat.js.map +1 -0
- package/dist/memory/observation-store.d.ts +57 -0
- package/dist/memory/observation-store.d.ts.map +1 -0
- package/dist/memory/observation-store.js +154 -0
- package/dist/memory/observation-store.js.map +1 -0
- package/dist/memory/session-tracker.d.ts +81 -0
- package/dist/memory/session-tracker.d.ts.map +1 -0
- package/dist/memory/session-tracker.js +262 -0
- package/dist/memory/session-tracker.js.map +1 -0
- package/dist/pipeline/engine.d.ts +179 -0
- package/dist/pipeline/engine.d.ts.map +1 -0
- package/dist/pipeline/engine.js +691 -0
- package/dist/pipeline/engine.js.map +1 -0
- package/dist/pipeline/events.d.ts +54 -0
- package/dist/pipeline/events.d.ts.map +1 -0
- package/dist/pipeline/events.js +157 -0
- package/dist/pipeline/events.js.map +1 -0
- package/dist/pipeline/parallel.d.ts +83 -0
- package/dist/pipeline/parallel.d.ts.map +1 -0
- package/dist/pipeline/parallel.js +277 -0
- package/dist/pipeline/parallel.js.map +1 -0
- package/dist/pipeline/state-machine.d.ts +65 -0
- package/dist/pipeline/state-machine.d.ts.map +1 -0
- package/dist/pipeline/state-machine.js +176 -0
- package/dist/pipeline/state-machine.js.map +1 -0
- package/dist/query/graph-queries.d.ts +84 -0
- package/dist/query/graph-queries.d.ts.map +1 -0
- package/dist/query/graph-queries.js +216 -0
- package/dist/query/graph-queries.js.map +1 -0
- package/dist/query/hybrid-search.d.ts +34 -0
- package/dist/query/hybrid-search.d.ts.map +1 -0
- package/dist/query/hybrid-search.js +263 -0
- package/dist/query/hybrid-search.js.map +1 -0
- package/dist/query/intent-detector.d.ts +35 -0
- package/dist/query/intent-detector.d.ts.map +1 -0
- package/dist/query/intent-detector.js +115 -0
- package/dist/query/intent-detector.js.map +1 -0
- package/dist/query/ranking.d.ts +57 -0
- package/dist/query/ranking.d.ts.map +1 -0
- package/dist/query/ranking.js +109 -0
- package/dist/query/ranking.js.map +1 -0
- package/dist/server.d.ts +3 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +291 -0
- package/dist/server.js.map +1 -0
- package/dist/storage/falkordb-store.d.ts +73 -0
- package/dist/storage/falkordb-store.d.ts.map +1 -0
- package/dist/storage/falkordb-store.js +346 -0
- package/dist/storage/falkordb-store.js.map +1 -0
- package/dist/storage/file-cache.d.ts +32 -0
- package/dist/storage/file-cache.d.ts.map +1 -0
- package/dist/storage/file-cache.js +115 -0
- package/dist/storage/file-cache.js.map +1 -0
- package/dist/storage/interfaces.d.ts +151 -0
- package/dist/storage/interfaces.d.ts.map +1 -0
- package/dist/storage/interfaces.js +7 -0
- package/dist/storage/interfaces.js.map +1 -0
- package/dist/storage/qdrant-store.d.ts +110 -0
- package/dist/storage/qdrant-store.d.ts.map +1 -0
- package/dist/storage/qdrant-store.js +467 -0
- package/dist/storage/qdrant-store.js.map +1 -0
- package/dist/storage/schema.d.ts +4 -0
- package/dist/storage/schema.d.ts.map +1 -0
- package/dist/storage/schema.js +136 -0
- package/dist/storage/schema.js.map +1 -0
- package/dist/storage/sqlite.d.ts +35 -0
- package/dist/storage/sqlite.d.ts.map +1 -0
- package/dist/storage/sqlite.js +132 -0
- package/dist/storage/sqlite.js.map +1 -0
- package/dist/tools/collaboration-tools.d.ts +111 -0
- package/dist/tools/collaboration-tools.d.ts.map +1 -0
- package/dist/tools/collaboration-tools.js +174 -0
- package/dist/tools/collaboration-tools.js.map +1 -0
- package/dist/tools/context-tools.d.ts +293 -0
- package/dist/tools/context-tools.d.ts.map +1 -0
- package/dist/tools/context-tools.js +437 -0
- package/dist/tools/context-tools.js.map +1 -0
- package/dist/tools/graph-tools.d.ts +129 -0
- package/dist/tools/graph-tools.d.ts.map +1 -0
- package/dist/tools/graph-tools.js +237 -0
- package/dist/tools/graph-tools.js.map +1 -0
- package/dist/tools/ingestion-tools.d.ts +96 -0
- package/dist/tools/ingestion-tools.d.ts.map +1 -0
- package/dist/tools/ingestion-tools.js +90 -0
- package/dist/tools/ingestion-tools.js.map +1 -0
- package/dist/tools/learning-tools.d.ts +168 -0
- package/dist/tools/learning-tools.d.ts.map +1 -0
- package/dist/tools/learning-tools.js +158 -0
- package/dist/tools/learning-tools.js.map +1 -0
- package/dist/tools/memory-tools.d.ts +183 -0
- package/dist/tools/memory-tools.d.ts.map +1 -0
- package/dist/tools/memory-tools.js +197 -0
- package/dist/tools/memory-tools.js.map +1 -0
- package/dist/tools/phase-tools.d.ts +954 -0
- package/dist/tools/phase-tools.d.ts.map +1 -0
- package/dist/tools/phase-tools.js +1215 -0
- package/dist/tools/phase-tools.js.map +1 -0
- package/dist/tools/pipeline-tools.d.ts +140 -0
- package/dist/tools/pipeline-tools.d.ts.map +1 -0
- package/dist/tools/pipeline-tools.js +162 -0
- package/dist/tools/pipeline-tools.js.map +1 -0
- package/dist/tools/registration-tools.d.ts +220 -0
- package/dist/tools/registration-tools.d.ts.map +1 -0
- package/dist/tools/registration-tools.js +391 -0
- package/dist/tools/registration-tools.js.map +1 -0
- package/dist/util/circuit-breaker.d.ts +75 -0
- package/dist/util/circuit-breaker.d.ts.map +1 -0
- package/dist/util/circuit-breaker.js +159 -0
- package/dist/util/circuit-breaker.js.map +1 -0
- package/dist/util/config.d.ts +23 -0
- package/dist/util/config.d.ts.map +1 -0
- package/dist/util/config.js +164 -0
- package/dist/util/config.js.map +1 -0
- package/dist/util/logger.d.ts +13 -0
- package/dist/util/logger.d.ts.map +1 -0
- package/dist/util/logger.js +45 -0
- package/dist/util/logger.js.map +1 -0
- package/dist/util/token-counter.d.ts +24 -0
- package/dist/util/token-counter.d.ts.map +1 -0
- package/dist/util/token-counter.js +48 -0
- package/dist/util/token-counter.js.map +1 -0
- package/dist/util/types.d.ts +525 -0
- package/dist/util/types.d.ts.map +1 -0
- package/dist/util/types.js +5 -0
- package/dist/util/types.js.map +1 -0
- package/docker-compose.yml +20 -0
- package/docs/plans/2026-02-27-swarm-coordination/architecture.md +203 -0
- package/docs/plans/2026-02-27-swarm-coordination/vision.md +57 -0
- package/docs/plans/completed/2026-02-26-forge-plugin-bundling/architecture.md +1 -0
- package/docs/plans/completed/2026-02-26-forge-plugin-bundling/vision.md +300 -0
- package/docs/plans/completed/2026-02-27-forge-swarm-learning/architecture.md +480 -0
- package/docs/plans/completed/2026-02-27-forge-swarm-learning/verification-checklist.md +462 -0
- package/docs/plans/completed/2026-02-27-git-history-atlassian/git-jira-plan.md +181 -0
- package/package.json +39 -0
- package/plugin/.claude-plugin/plugin.json +8 -0
- package/plugin/.mcp.json +15 -0
- package/plugin/README.md +134 -0
- package/plugin/agents/architect.md +367 -0
- package/plugin/agents/backend-specialist.md +263 -0
- package/plugin/agents/brainstormer.md +122 -0
- package/plugin/agents/data-specialist.md +266 -0
- package/plugin/agents/designer.md +408 -0
- package/plugin/agents/frontend-specialist.md +241 -0
- package/plugin/agents/inspector.md +406 -0
- package/plugin/agents/knowledge-keeper.md +443 -0
- package/plugin/agents/platform-engineer.md +326 -0
- package/plugin/agents/product-manager.md +268 -0
- package/plugin/agents/product-owner.md +438 -0
- package/plugin/agents/pulse-checker.md +73 -0
- package/plugin/agents/qa-strategist.md +500 -0
- package/plugin/agents/self-improver.md +310 -0
- package/plugin/agents/strategist.md +360 -0
- package/plugin/agents/supervisor.md +380 -0
- package/plugin/commands/brainstorm.md +25 -0
- package/plugin/commands/forge.md +88 -0
- package/plugin/docs/atlassian-integration.md +110 -0
- package/plugin/docs/workflow.md +126 -0
- package/plugin/skills/agent-development/.skillfish.json +10 -0
- package/plugin/skills/agent-development/SKILL.md +415 -0
- package/plugin/skills/agent-development/examples/agent-creation-prompt.md +238 -0
- package/plugin/skills/agent-development/examples/complete-agent-examples.md +427 -0
- package/plugin/skills/agent-development/references/agent-creation-system-prompt.md +207 -0
- package/plugin/skills/agent-development/references/system-prompt-design.md +411 -0
- package/plugin/skills/agent-development/references/triggering-examples.md +491 -0
- package/plugin/skills/agent-development/scripts/validate-agent.sh +217 -0
- package/plugin/skills/agent-handoff/SKILL.md +335 -0
- package/plugin/skills/anti-stub/SKILL.md +317 -0
- package/plugin/skills/brainstorm/SKILL.md +31 -0
- package/plugin/skills/debugging/SKILL.md +276 -0
- package/plugin/skills/fix/SKILL.md +62 -0
- package/plugin/skills/frontend-design/.skillfish.json +10 -0
- package/plugin/skills/frontend-design/SKILL.md +42 -0
- package/plugin/skills/gotchas/SKILL.md +61 -0
- package/plugin/skills/graph-orchestrator/SKILL.md +38 -0
- package/plugin/skills/history/SKILL.md +58 -0
- package/plugin/skills/impact/SKILL.md +59 -0
- package/plugin/skills/implementation-execution/SKILL.md +291 -0
- package/plugin/skills/index-repo/SKILL.md +55 -0
- package/plugin/skills/interviewing/SKILL.md +225 -0
- package/plugin/skills/knowledge-curation/SKILL.md +393 -0
- package/plugin/skills/learn/SKILL.md +69 -0
- package/plugin/skills/mcp-integration/.skillfish.json +10 -0
- package/plugin/skills/mcp-integration/SKILL.md +554 -0
- package/plugin/skills/mcp-integration/examples/http-server.json +20 -0
- package/plugin/skills/mcp-integration/examples/sse-server.json +19 -0
- package/plugin/skills/mcp-integration/examples/stdio-server.json +26 -0
- package/plugin/skills/mcp-integration/references/authentication.md +549 -0
- package/plugin/skills/mcp-integration/references/server-types.md +536 -0
- package/plugin/skills/mcp-integration/references/tool-usage.md +538 -0
- package/plugin/skills/nestjs/.skillfish.json +10 -0
- package/plugin/skills/nestjs/SKILL.md +669 -0
- package/plugin/skills/nestjs/drizzle-reference.md +1894 -0
- package/plugin/skills/nestjs/reference.md +1447 -0
- package/plugin/skills/nestjs/workflow-optimization.md +229 -0
- package/plugin/skills/parallel-dispatch/SKILL.md +308 -0
- package/plugin/skills/project-discovery/SKILL.md +304 -0
- package/plugin/skills/search/SKILL.md +56 -0
- package/plugin/skills/security-audit/SKILL.md +362 -0
- package/plugin/skills/skill-development/.skillfish.json +10 -0
- package/plugin/skills/skill-development/SKILL.md +637 -0
- package/plugin/skills/skill-development/references/skill-creator-original.md +209 -0
- package/plugin/skills/tdd/SKILL.md +273 -0
- package/plugin/skills/terminal-presentation/SKILL.md +395 -0
- package/plugin/skills/test-strategy/SKILL.md +365 -0
- package/plugin/skills/verification-protocol/SKILL.md +256 -0
- package/plugin/skills/visual-explainer/CHANGELOG.md +97 -0
- package/plugin/skills/visual-explainer/LICENSE +21 -0
- package/plugin/skills/visual-explainer/README.md +137 -0
- package/plugin/skills/visual-explainer/SKILL.md +352 -0
- package/plugin/skills/visual-explainer/banner.png +0 -0
- package/plugin/skills/visual-explainer/package.json +11 -0
- package/plugin/skills/visual-explainer/prompts/diff-review.md +68 -0
- package/plugin/skills/visual-explainer/prompts/fact-check.md +63 -0
- package/plugin/skills/visual-explainer/prompts/generate-slides.md +18 -0
- package/plugin/skills/visual-explainer/prompts/generate-web-diagram.md +10 -0
- package/plugin/skills/visual-explainer/prompts/plan-review.md +86 -0
- package/plugin/skills/visual-explainer/prompts/project-recap.md +61 -0
- package/plugin/skills/visual-explainer/references/css-patterns.md +1188 -0
- package/plugin/skills/visual-explainer/references/libraries.md +470 -0
- package/plugin/skills/visual-explainer/references/responsive-nav.md +212 -0
- package/plugin/skills/visual-explainer/references/slide-patterns.md +1403 -0
- package/plugin/skills/visual-explainer/templates/architecture.html +596 -0
- package/plugin/skills/visual-explainer/templates/data-table.html +540 -0
- package/plugin/skills/visual-explainer/templates/mermaid-flowchart.html +435 -0
- package/plugin/skills/visual-explainer/templates/slide-deck.html +913 -0
- package/src/cli.ts +655 -0
- package/src/context/.gitkeep +0 -0
- package/src/context/codebase.ts +393 -0
- package/src/context/injector.ts +797 -0
- package/src/context/memory.ts +187 -0
- package/src/context/session-index.ts +327 -0
- package/src/context/session.ts +152 -0
- package/src/index.ts +47 -0
- package/src/ingestion/.gitkeep +0 -0
- package/src/ingestion/chunker.ts +277 -0
- package/src/ingestion/embedder.ts +167 -0
- package/src/ingestion/git-analyzer.ts +545 -0
- package/src/ingestion/indexer.ts +984 -0
- package/src/ingestion/markdown-chunker.ts +337 -0
- package/src/ingestion/markdown-knowledge.ts +175 -0
- package/src/ingestion/parser.ts +475 -0
- package/src/ingestion/watcher.ts +182 -0
- package/src/knowledge/.gitkeep +0 -0
- package/src/knowledge/hydrator.ts +246 -0
- package/src/knowledge/registry.ts +463 -0
- package/src/knowledge/search.ts +565 -0
- package/src/knowledge/store.ts +262 -0
- package/src/learning/.gitkeep +0 -0
- package/src/learning/confidence.ts +193 -0
- package/src/learning/patterns.ts +360 -0
- package/src/learning/trajectory.ts +268 -0
- package/src/memory/.gitkeep +0 -0
- package/src/memory/memory-compat.ts +233 -0
- package/src/memory/observation-store.ts +224 -0
- package/src/memory/session-tracker.ts +332 -0
- package/src/pipeline/.gitkeep +0 -0
- package/src/pipeline/engine.ts +1139 -0
- package/src/pipeline/events.ts +253 -0
- package/src/pipeline/parallel.ts +394 -0
- package/src/pipeline/state-machine.ts +199 -0
- package/src/query/.gitkeep +0 -0
- package/src/query/graph-queries.ts +262 -0
- package/src/query/hybrid-search.ts +337 -0
- package/src/query/intent-detector.ts +131 -0
- package/src/query/ranking.ts +161 -0
- package/src/server.ts +352 -0
- package/src/storage/.gitkeep +0 -0
- package/src/storage/falkordb-store.ts +388 -0
- package/src/storage/file-cache.ts +141 -0
- package/src/storage/interfaces.ts +201 -0
- package/src/storage/qdrant-store.ts +557 -0
- package/src/storage/schema.ts +139 -0
- package/src/storage/sqlite.ts +168 -0
- package/src/tools/.gitkeep +0 -0
- package/src/tools/collaboration-tools.ts +208 -0
- package/src/tools/context-tools.ts +493 -0
- package/src/tools/graph-tools.ts +295 -0
- package/src/tools/ingestion-tools.ts +122 -0
- package/src/tools/learning-tools.ts +181 -0
- package/src/tools/memory-tools.ts +234 -0
- package/src/tools/phase-tools.ts +1452 -0
- package/src/tools/pipeline-tools.ts +188 -0
- package/src/tools/registration-tools.ts +450 -0
- package/src/util/.gitkeep +0 -0
- package/src/util/circuit-breaker.ts +193 -0
- package/src/util/config.ts +177 -0
- package/src/util/logger.ts +53 -0
- package/src/util/token-counter.ts +52 -0
- package/src/util/types.ts +710 -0
- package/tests/context/.gitkeep +0 -0
- package/tests/integration/.gitkeep +0 -0
- package/tests/knowledge/.gitkeep +0 -0
- package/tests/learning/.gitkeep +0 -0
- package/tests/pipeline/.gitkeep +0 -0
- package/tests/tools/.gitkeep +0 -0
- package/tsconfig.json +21 -0
- package/vitest.config.ts +10 -0
- package/vscode-extension/.vscodeignore +7 -0
- package/vscode-extension/README.md +43 -0
- package/vscode-extension/out/edge-collector.js +274 -0
- package/vscode-extension/out/edge-collector.js.map +1 -0
- package/vscode-extension/out/extension.js +264 -0
- package/vscode-extension/out/extension.js.map +1 -0
- package/vscode-extension/out/forge-client.js +318 -0
- package/vscode-extension/out/forge-client.js.map +1 -0
- package/vscode-extension/package-lock.json +59 -0
- package/vscode-extension/package.json +71 -0
- package/vscode-extension/src/edge-collector.ts +320 -0
- package/vscode-extension/src/extension.ts +269 -0
- package/vscode-extension/src/forge-client.ts +364 -0
- package/vscode-extension/tsconfig.json +19 -0
|
@@ -0,0 +1,365 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: test-strategy
|
|
3
|
+
description: >
|
|
4
|
+
This skill should be used when designing test strategies, planning test coverage, or determining
|
|
5
|
+
what and how to test. Used by the qa-strategist agent and referenced by implementation agents
|
|
6
|
+
for test-first development approaches.
|
|
7
|
+
user-invocable: false
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Test Strategy Skill
|
|
11
|
+
|
|
12
|
+
## The Test Pyramid: Structure for Sustainable Quality
|
|
13
|
+
|
|
14
|
+
Adopt a layered testing strategy modeled on the test pyramid. The pyramid is not a suggestion — it is a structural requirement for a test suite that remains fast, stable, and meaningful as the codebase grows.
|
|
15
|
+
|
|
16
|
+
### Unit Tests (Base Layer — Many, Fast)
|
|
17
|
+
|
|
18
|
+
Unit tests form the foundation. Write the most of these. Each unit test exercises a single unit of business logic — a function, a method, a transformation, a validation rule — in complete isolation from external systems.
|
|
19
|
+
|
|
20
|
+
Characteristics of a good unit test:
|
|
21
|
+
|
|
22
|
+
- Execute in under 50ms. If a unit test takes longer, it is probably not a unit test.
|
|
23
|
+
- Have zero I/O: no network, no filesystem, no database, no external services.
|
|
24
|
+
- Mock only at the boundary. If the unit under test calls a service interface, mock that interface. Never mock internal methods of the unit itself.
|
|
25
|
+
- Be deterministic. No random values, no wall-clock time, no environment-dependent behavior. Supply all inputs explicitly.
|
|
26
|
+
|
|
27
|
+
Target: aim for hundreds of unit tests per module. They should run in seconds, not minutes.
|
|
28
|
+
|
|
29
|
+
### Integration Tests (Middle Layer — Moderate, Thorough)
|
|
30
|
+
|
|
31
|
+
Integration tests verify that components work together correctly across service boundaries. These tests exercise real connections — real database queries, real HTTP calls between services, real message queue interactions — but within a controlled environment.
|
|
32
|
+
|
|
33
|
+
Characteristics of a good integration test:
|
|
34
|
+
|
|
35
|
+
- Use real database connections (test databases, Docker containers, or in-memory alternatives where faithful).
|
|
36
|
+
- Test API contracts: send a real HTTP request to the endpoint, verify the response shape, status codes, and headers.
|
|
37
|
+
- Test database queries: execute the actual Drizzle query, verify the returned data against known seed state.
|
|
38
|
+
- Test service-to-service interactions: verify that a service call produces the expected side effects.
|
|
39
|
+
- Run in a test environment with known state. Set up fixtures before each test or test group. Tear down after.
|
|
40
|
+
|
|
41
|
+
Target: tens to low hundreds of integration tests per service. They will take longer (seconds each) but must remain reliable.
|
|
42
|
+
|
|
43
|
+
### End-to-End Tests (Top Layer — Few, Comprehensive)
|
|
44
|
+
|
|
45
|
+
E2E tests validate complete user flows through the entire system. These are the most expensive to write, the slowest to run, and the most fragile — so write few of them, but make each one count.
|
|
46
|
+
|
|
47
|
+
Characteristics of a good E2E test:
|
|
48
|
+
|
|
49
|
+
- Model a real user journey: login, navigate, perform action, verify outcome, logout.
|
|
50
|
+
- Use Playwright for browser-based E2E. Target user-visible behavior, not DOM structure.
|
|
51
|
+
- Cover only critical paths: the flows that, if broken, would make the product unusable.
|
|
52
|
+
- Accept some brittleness as the cost of realistic testing, but minimize it through good selector strategies (data-testid attributes, ARIA roles — never CSS classes or tag hierarchies).
|
|
53
|
+
|
|
54
|
+
Target: tens of E2E tests per product. Each one should represent a user story from the vision document.
|
|
55
|
+
|
|
56
|
+
## Contract Testing: Test the Interface, Not the Implementation
|
|
57
|
+
|
|
58
|
+
The single most important principle in test design: **if a stub passes the test, the test is wrong.**
|
|
59
|
+
|
|
60
|
+
This means:
|
|
61
|
+
|
|
62
|
+
- Test observable behavior, not internal mechanics. A test for a sorting function should verify the output order, not that `Array.prototype.sort` was called.
|
|
63
|
+
- Test the contract a module promises to fulfill, not how it fulfills it. If a service promises to return a paginated list of users, test the response shape and pagination behavior. Do not test that it used a specific SQL query.
|
|
64
|
+
- Refactoring should not break tests. If changing the internal implementation of a function (without changing its inputs or outputs) causes tests to fail, those tests are testing implementation details and must be rewritten.
|
|
65
|
+
- Assert on results, not on call counts. `expect(service.save).toHaveBeenCalledTimes(1)` is almost always a test of implementation, not behavior. Instead, assert that the data was actually persisted by reading it back.
|
|
66
|
+
|
|
67
|
+
### Contract Tests for API Boundaries
|
|
68
|
+
|
|
69
|
+
For services that expose APIs consumed by other services or frontends:
|
|
70
|
+
|
|
71
|
+
- Define the contract explicitly (OpenAPI spec, TypeScript interface, or Zod schema).
|
|
72
|
+
- Write tests that validate the response against the contract, not against a hardcoded expected object.
|
|
73
|
+
- When the contract changes, update the contract definition first, then update the implementation. Tests against the old contract should fail — that is the point.
|
|
74
|
+
|
|
75
|
+
## Test Data Strategy
|
|
76
|
+
|
|
77
|
+
Test data quality directly determines test quality. Lazy test data produces lazy coverage.
|
|
78
|
+
|
|
79
|
+
### Principles
|
|
80
|
+
|
|
81
|
+
- **Use realistic data.** Names should be actual names ("Elena Rodriguez"), not placeholders ("test123", "foo bar", "John Doe" for every record). Emails should look like emails. Dates should be plausible.
|
|
82
|
+
- **Exercise edge cases through data.** Include: empty strings, maximum-length strings, Unicode characters (CJK, emoji, RTL scripts), null values where nullable, zero and negative numbers, dates at epoch and at year boundaries, deeply nested objects.
|
|
83
|
+
- **Use factory functions, not hardcoded fixtures.** Create a `createTestUser(overrides?)` factory that generates a realistic user with defaults, allowing individual fields to be overridden per test. This keeps tests concise while ensuring realistic data.
|
|
84
|
+
- **Generate data deterministically.** If using random data, seed the generator so tests are reproducible. Flaky tests from random data are worse than no tests.
|
|
85
|
+
- **Match production shapes.** If production data has 50 fields, test data should have 50 fields. Do not test against a 3-field subset and assume it generalizes.
|
|
86
|
+
|
|
87
|
+
### Test Database State
|
|
88
|
+
|
|
89
|
+
For integration tests involving databases:
|
|
90
|
+
|
|
91
|
+
- Use a dedicated test database. Never run tests against development or production data.
|
|
92
|
+
- Seed known state before each test suite. Use explicit seed scripts, not shared mutable state.
|
|
93
|
+
- Clean up after tests. Use transactions that roll back, or truncate tables between tests.
|
|
94
|
+
- Avoid test-order dependencies. Each test must work in isolation, regardless of execution order.
|
|
95
|
+
|
|
96
|
+
## E2E Testing with Playwright
|
|
97
|
+
|
|
98
|
+
### Focus on User Flows, Not Components
|
|
99
|
+
|
|
100
|
+
Playwright tests should model complete user journeys that cross component and page boundaries. A Playwright test is not a component test — it is a simulation of what a real user does.
|
|
101
|
+
|
|
102
|
+
Structure each E2E test as a flow:
|
|
103
|
+
|
|
104
|
+
1. **Arrange**: Navigate to the starting point, authenticate if needed, set up preconditions.
|
|
105
|
+
2. **Act**: Perform the sequence of user actions (click, type, navigate, wait).
|
|
106
|
+
3. **Assert**: Verify the final state from the user's perspective (visible text, URL, downloaded file, notification).
|
|
107
|
+
|
|
108
|
+
### Selector Strategy
|
|
109
|
+
|
|
110
|
+
Use selectors in this priority order:
|
|
111
|
+
|
|
112
|
+
1. `data-testid` attributes — explicit, stable, decoupled from presentation.
|
|
113
|
+
2. ARIA roles and accessible names — `getByRole('button', { name: 'Submit' })` — good for accessibility too.
|
|
114
|
+
3. Text content — `getByText('Welcome back')` — acceptable for static text.
|
|
115
|
+
4. **Never**: CSS classes, tag names, DOM hierarchy, or nth-child selectors. These break on any style or layout change.
|
|
116
|
+
|
|
117
|
+
### Handling Asynchrony
|
|
118
|
+
|
|
119
|
+
- Use Playwright's built-in waiting mechanisms (`waitForSelector`, `waitForURL`, `waitForResponse`). Never use `sleep()` or fixed timeouts.
|
|
120
|
+
- Assert against final states, not intermediate states. The UI may transition through loading/skeleton states — wait for the final rendered state.
|
|
121
|
+
- For network-dependent assertions, intercept and assert on network requests/responses rather than UI text alone.
|
|
122
|
+
|
|
123
|
+
### Test Isolation
|
|
124
|
+
|
|
125
|
+
- Each E2E test must be independent. Use fresh authentication state (Playwright storage state), clean data (API-based setup/teardown), and no shared session state between tests.
|
|
126
|
+
- Use Playwright's test fixtures for reusable setup (authenticated page, seeded database, etc.).
|
|
127
|
+
|
|
128
|
+
## Integration Test Design
|
|
129
|
+
|
|
130
|
+
### Service Boundary Testing
|
|
131
|
+
|
|
132
|
+
Test where services meet:
|
|
133
|
+
|
|
134
|
+
- **HTTP boundaries**: Send actual requests to controller endpoints. Verify status codes, response shapes, error formats, and headers (CORS, cache control, content type).
|
|
135
|
+
- **Database boundaries**: Execute actual queries through the repository/service layer. Verify correct data is read and written, including edge cases (empty results, constraint violations, concurrent access).
|
|
136
|
+
- **External service boundaries**: Use WireMock, MSW, or Nock to simulate external APIs. Verify the integration handles success, failure, timeout, and unexpected response shapes.
|
|
137
|
+
|
|
138
|
+
### What to Cover in Integration Tests
|
|
139
|
+
|
|
140
|
+
- Request validation: malformed requests return 400 with descriptive error messages.
|
|
141
|
+
- Authentication and authorization: unauthenticated requests return 401; unauthorized requests return 403; valid tokens grant access.
|
|
142
|
+
- Database constraint enforcement: unique violations, foreign key violations, not-null violations produce appropriate application-level errors.
|
|
143
|
+
- Pagination: first page, last page, empty page, out-of-range page.
|
|
144
|
+
- Concurrent operations: two simultaneous writes to the same resource produce a consistent outcome.
|
|
145
|
+
|
|
146
|
+
## Unit Test Design
|
|
147
|
+
|
|
148
|
+
### What to Test
|
|
149
|
+
|
|
150
|
+
- **Business logic**: calculations, transformations, state machines, decision trees.
|
|
151
|
+
- **Validations**: input validation rules, schema enforcement, constraint checking.
|
|
152
|
+
- **Data transformations**: mappers, serializers, formatters, parsers.
|
|
153
|
+
- **Error handling paths**: verify that specific inputs produce specific error types with correct messages.
|
|
154
|
+
- **Conditional logic**: every branch in an if/else or switch should have at least one test.
|
|
155
|
+
|
|
156
|
+
### What to Mock
|
|
157
|
+
|
|
158
|
+
Mock only at external boundaries:
|
|
159
|
+
|
|
160
|
+
- Database clients/repositories (when testing service logic, not query correctness).
|
|
161
|
+
- HTTP clients (when testing a service that calls an external API).
|
|
162
|
+
- File system access (when testing logic that reads/writes files).
|
|
163
|
+
- Clock/time (when testing time-dependent logic).
|
|
164
|
+
|
|
165
|
+
Never mock:
|
|
166
|
+
|
|
167
|
+
- Internal methods of the class under test.
|
|
168
|
+
- Utility functions that are part of the same module.
|
|
169
|
+
- Language/framework primitives.
|
|
170
|
+
|
|
171
|
+
## Coverage Strategy
|
|
172
|
+
|
|
173
|
+
100% code coverage is a vanity metric. A codebase with 100% coverage can still be full of bugs if the tests assert nothing meaningful.
|
|
174
|
+
|
|
175
|
+
### What to Cover (Prioritized)
|
|
176
|
+
|
|
177
|
+
1. **Happy paths**: the primary success scenarios for each feature. Non-negotiable.
|
|
178
|
+
2. **Error paths**: what happens when things go wrong — invalid input, missing data, service unavailable, timeout. Non-negotiable.
|
|
179
|
+
3. **Edge cases**: boundary values, empty inputs, maximum sizes, Unicode, null/undefined. High priority.
|
|
180
|
+
4. **Security-relevant paths**: authentication, authorization, input sanitization, token validation, rate limiting. Non-negotiable.
|
|
181
|
+
5. **Regression paths**: any bug that was found and fixed gets a test that would have caught it. Non-negotiable.
|
|
182
|
+
|
|
183
|
+
### What NOT to Cover
|
|
184
|
+
|
|
185
|
+
- Trivial getters and setters with no logic.
|
|
186
|
+
- Framework-generated code (NestJS decorators, Drizzle schema definitions).
|
|
187
|
+
- Third-party library behavior (do not test that `dayjs` parses dates correctly).
|
|
188
|
+
- Configuration-only files (module imports, provider registrations with no logic).
|
|
189
|
+
|
|
190
|
+
### Coverage Targets
|
|
191
|
+
|
|
192
|
+
Set practical targets, not vanity targets:
|
|
193
|
+
|
|
194
|
+
- Business logic modules: 90%+ line coverage, 85%+ branch coverage.
|
|
195
|
+
- API controllers: 80%+ (focus on request/response contract, not framework plumbing).
|
|
196
|
+
- Utility/helper modules: 95%+ (these are pure functions — easy to test thoroughly).
|
|
197
|
+
- Overall project: 80%+ as a floor, not a ceiling. Below 80% indicates gaps; above 95% indicates possible over-testing of trivial code.
|
|
198
|
+
|
|
199
|
+
## Test Naming Conventions
|
|
200
|
+
|
|
201
|
+
Test names must describe behavior, not method names. A test name is a sentence that describes what the system does under specific conditions.
|
|
202
|
+
|
|
203
|
+
### Pattern
|
|
204
|
+
|
|
205
|
+
```
|
|
206
|
+
should [expected behavior] when [condition]
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
### Good Examples
|
|
210
|
+
|
|
211
|
+
- `should reject expired tokens with 401 status`
|
|
212
|
+
- `should return empty array when no users match the filter`
|
|
213
|
+
- `should paginate results with correct next cursor`
|
|
214
|
+
- `should trim whitespace from email before validation`
|
|
215
|
+
- `should cascade delete child records when parent is removed`
|
|
216
|
+
|
|
217
|
+
### Bad Examples
|
|
218
|
+
|
|
219
|
+
- `testValidateToken` — describes nothing about expected behavior.
|
|
220
|
+
- `test1`, `test2` — meaningless.
|
|
221
|
+
- `should work` — what does "work" mean?
|
|
222
|
+
- `should call repository.save` — testing implementation, not behavior.
|
|
223
|
+
|
|
224
|
+
### Test Organization
|
|
225
|
+
|
|
226
|
+
Group tests by behavior, not by method:
|
|
227
|
+
|
|
228
|
+
```typescript
|
|
229
|
+
describe('UserService', () => {
|
|
230
|
+
describe('registration', () => {
|
|
231
|
+
it('should create a new user with hashed password', ...);
|
|
232
|
+
it('should reject duplicate email addresses', ...);
|
|
233
|
+
it('should send a verification email on success', ...);
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
describe('authentication', () => {
|
|
237
|
+
it('should return a JWT for valid credentials', ...);
|
|
238
|
+
it('should reject invalid passwords with 401', ...);
|
|
239
|
+
it('should lock account after 5 failed attempts', ...);
|
|
240
|
+
});
|
|
241
|
+
});
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
## What NOT to Test
|
|
245
|
+
|
|
246
|
+
Avoid wasting effort on tests that provide no meaningful coverage:
|
|
247
|
+
|
|
248
|
+
- **Framework internals**: do not test that NestJS dependency injection works, that decorators apply metadata, or that middleware chains execute in order. Trust the framework.
|
|
249
|
+
- **Trivial code**: a getter that returns `this.name` does not need a test. A setter that assigns a value does not need a test. Add a test only when logic is involved.
|
|
250
|
+
- **Third-party library behavior**: do not test that `bcrypt.hash()` produces a hash or that `zod.parse()` validates schemas. Test that YOUR code uses these libraries correctly at the boundaries.
|
|
251
|
+
- **Type system assertions**: if TypeScript's type checker prevents a class of bugs, do not write runtime tests for those same bugs. Let the compiler do its job.
|
|
252
|
+
- **Test infrastructure**: do not test test utilities, test factories, or mock setup code. If test infrastructure needs tests, it is too complex.
|
|
253
|
+
|
|
254
|
+
## Anti-Patterns to Avoid
|
|
255
|
+
|
|
256
|
+
### Testing Implementation Details
|
|
257
|
+
|
|
258
|
+
If a test breaks when the internal implementation changes but the external behavior stays the same, the test is coupled to implementation. Symptoms:
|
|
259
|
+
|
|
260
|
+
- Asserting on method call counts (`toHaveBeenCalledTimes`).
|
|
261
|
+
- Asserting on internal state (`expect(service._cache.size).toBe(3)`).
|
|
262
|
+
- Asserting on intermediate steps rather than final outcomes.
|
|
263
|
+
|
|
264
|
+
### Over-Mocking
|
|
265
|
+
|
|
266
|
+
If a test has more mock setup code than assertion code, it is over-mocked. Symptoms:
|
|
267
|
+
|
|
268
|
+
- Mocking 5+ dependencies for a single test.
|
|
269
|
+
- Mock return values that are themselves mocked objects.
|
|
270
|
+
- Tests that pass regardless of what the function under test does, because the mocks control the entire flow.
|
|
271
|
+
|
|
272
|
+
### Testing the Mock
|
|
273
|
+
|
|
274
|
+
If a test asserts behavior that is entirely determined by mock configuration, it is testing the mock, not the code. Example: mocking `findUser` to return `null`, then asserting that the service returns `null` — this tests the mock setup, not the service logic.
|
|
275
|
+
|
|
276
|
+
### Fragile E2E Selectors
|
|
277
|
+
|
|
278
|
+
CSS class selectors (`'.btn-primary'`), deeply nested selectors (`'div > ul > li:nth-child(3) > span'`), or auto-generated class names (`'.css-1a2b3c'`) produce E2E tests that break on every style change.
|
|
279
|
+
|
|
280
|
+
### Shared Mutable Test State
|
|
281
|
+
|
|
282
|
+
Tests that modify shared variables, database state, or global configuration without cleanup create order-dependent test suites that pass individually but fail when run together.
|
|
283
|
+
|
|
284
|
+
## Test Plan Document Format
|
|
285
|
+
|
|
286
|
+
For each feature or project, produce a test plan document at:
|
|
287
|
+
|
|
288
|
+
```
|
|
289
|
+
docs/plans/YYYY-MM-DD-{TITLE}/test-plan.md
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
Use the following structure:
|
|
293
|
+
|
|
294
|
+
```markdown
|
|
295
|
+
# Test Plan: {Feature Title}
|
|
296
|
+
|
|
297
|
+
**Date**: YYYY-MM-DD
|
|
298
|
+
**Status**: Draft | Active | Completed
|
|
299
|
+
**Author**: {Agent name}
|
|
300
|
+
**Vision Reference**: docs/plans/YYYY-MM-DD-{TITLE}/vision.md
|
|
301
|
+
|
|
302
|
+
## Scope
|
|
303
|
+
|
|
304
|
+
[What is being tested and what is explicitly excluded]
|
|
305
|
+
|
|
306
|
+
## Test Pyramid Allocation
|
|
307
|
+
|
|
308
|
+
| Layer | Count (est.) | Focus Areas |
|
|
309
|
+
|-------|-------------|-------------|
|
|
310
|
+
| Unit | ... | ... |
|
|
311
|
+
| Integration | ... | ... |
|
|
312
|
+
| E2E | ... | ... |
|
|
313
|
+
|
|
314
|
+
## Unit Test Plan
|
|
315
|
+
|
|
316
|
+
### Module: {module-name}
|
|
317
|
+
| Test Case | Type | Priority |
|
|
318
|
+
|-----------|------|----------|
|
|
319
|
+
| should ... when ... | happy path | P0 |
|
|
320
|
+
| should ... when ... | error path | P0 |
|
|
321
|
+
| should ... when ... | edge case | P1 |
|
|
322
|
+
|
|
323
|
+
[Repeat for each module]
|
|
324
|
+
|
|
325
|
+
## Integration Test Plan
|
|
326
|
+
|
|
327
|
+
### Boundary: {service-to-service or service-to-database}
|
|
328
|
+
| Test Case | Dependencies | Priority |
|
|
329
|
+
|-----------|-------------|----------|
|
|
330
|
+
| should ... | [db, external API, etc.] | P0 |
|
|
331
|
+
|
|
332
|
+
[Repeat for each boundary]
|
|
333
|
+
|
|
334
|
+
## E2E Test Plan
|
|
335
|
+
|
|
336
|
+
### Flow: {user-story-name}
|
|
337
|
+
| Step | Action | Expected Outcome |
|
|
338
|
+
|------|--------|-----------------|
|
|
339
|
+
| 1 | Navigate to ... | Page loads with ... |
|
|
340
|
+
| 2 | Click ... | Modal appears with ... |
|
|
341
|
+
|
|
342
|
+
[Repeat for each critical flow]
|
|
343
|
+
|
|
344
|
+
## Test Data Requirements
|
|
345
|
+
|
|
346
|
+
[Describe factories, seed data, and fixtures needed]
|
|
347
|
+
|
|
348
|
+
## Environment Requirements
|
|
349
|
+
|
|
350
|
+
[Database, external services, environment variables, Docker containers needed]
|
|
351
|
+
|
|
352
|
+
## Coverage Targets
|
|
353
|
+
|
|
354
|
+
| Module | Line Target | Branch Target |
|
|
355
|
+
|--------|------------|---------------|
|
|
356
|
+
| ... | ...% | ...% |
|
|
357
|
+
|
|
358
|
+
## Risks and Mitigations
|
|
359
|
+
|
|
360
|
+
| Risk | Mitigation |
|
|
361
|
+
|------|------------|
|
|
362
|
+
| ... | ... |
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
Populate the test plan from the vision document's success criteria and user stories. Every success criterion must trace to at least one test case. Every user story must trace to at least one E2E flow.
|
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: verification-protocol
|
|
3
|
+
description: This skill should be used when verifying that implementation work is complete and correct — checking wiring, anti-stub compliance, XD conformance, code quality, test quality, and security. Used primarily by the inspector agent as the unified quality gate, and referenced by all implementation agents for self-verification before handoff.
|
|
4
|
+
user-invocable: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Verification Protocol
|
|
8
|
+
|
|
9
|
+
The verification protocol is the unified quality gate for the forge system. Nothing passes without evidence that it works. Reading code is insufficient — run commands, test endpoints, verify output.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Core Principle
|
|
14
|
+
|
|
15
|
+
> If it cannot be proven to work, it does not pass.
|
|
16
|
+
|
|
17
|
+
Verification means executing, not reading. A function that "looks correct" is not verified. A function whose output has been observed and matches expectations is verified.
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## The Seven Checks
|
|
22
|
+
|
|
23
|
+
Every piece of work passes through all seven checks. Partial passes are failures. A single blocker in any check means the entire deliverable is blocked.
|
|
24
|
+
|
|
25
|
+
### Check 1: Wiring Verification
|
|
26
|
+
|
|
27
|
+
Confirm that all parts of the system are actually connected.
|
|
28
|
+
|
|
29
|
+
**API Wiring:**
|
|
30
|
+
- Every controller endpoint calls a real service method
|
|
31
|
+
- Every service method calls real data access (Drizzle queries, external APIs)
|
|
32
|
+
- Every data access returns real data from a real source
|
|
33
|
+
- Response DTOs match the actual data shape returned
|
|
34
|
+
- Error responses are properly typed and returned (not swallowed)
|
|
35
|
+
|
|
36
|
+
**Frontend Wiring:**
|
|
37
|
+
- Every component that displays data calls a real API endpoint
|
|
38
|
+
- API base URLs and paths resolve to actual backend routes
|
|
39
|
+
- Authentication tokens are attached to protected requests
|
|
40
|
+
- Loading, error, and empty states are handled (not just the happy path)
|
|
41
|
+
- Navigation/routing connects all pages
|
|
42
|
+
|
|
43
|
+
**Database Wiring:**
|
|
44
|
+
- Schema matches the migration output (run `db:generate`, verify SQL)
|
|
45
|
+
- Seed data inserts successfully
|
|
46
|
+
- Foreign keys reference existing tables
|
|
47
|
+
- Indexes exist for queried columns
|
|
48
|
+
- JSONB columns have explicit TypeScript types
|
|
49
|
+
|
|
50
|
+
**Verification commands:**
|
|
51
|
+
```bash
|
|
52
|
+
# Backend starts without errors
|
|
53
|
+
npm run start:dev
|
|
54
|
+
|
|
55
|
+
# Frontend builds without errors
|
|
56
|
+
npm run build
|
|
57
|
+
|
|
58
|
+
# All migrations apply cleanly
|
|
59
|
+
npm run db:migrate
|
|
60
|
+
|
|
61
|
+
# Seed data loads
|
|
62
|
+
npm run db:seed
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Check 2: Anti-Stub Enforcement
|
|
66
|
+
|
|
67
|
+
Search production code for incomplete implementations. Any hit is a blocker unless explicitly justified.
|
|
68
|
+
|
|
69
|
+
**Detection patterns (grep for these):**
|
|
70
|
+
```
|
|
71
|
+
TODO|FIXME|HACK|PLACEHOLDER|STUB|NOT.IMPLEMENTED
|
|
72
|
+
return \[\]|return \{\}|return null|return ''
|
|
73
|
+
lorem ipsum|coming soon|under construction
|
|
74
|
+
console\.log\(.*error|catch.*\{\s*\}
|
|
75
|
+
throw new Error\('Not implemented'\)
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
**Manual inspection targets:**
|
|
79
|
+
- Service methods that return hardcoded arrays or objects
|
|
80
|
+
- API endpoints that return 200 with empty or static bodies
|
|
81
|
+
- Components that render placeholder text instead of real data
|
|
82
|
+
- Error handlers that swallow exceptions silently
|
|
83
|
+
- Functions with commented-out implementation
|
|
84
|
+
|
|
85
|
+
**Acceptable exceptions:**
|
|
86
|
+
- Mock data in test files (not production code)
|
|
87
|
+
- Loading states and empty states (these are real UI features)
|
|
88
|
+
- Feature flags gating incomplete features (the flag is real, the stub is not)
|
|
89
|
+
- Graceful degradation for unavailable external services (must log and surface)
|
|
90
|
+
|
|
91
|
+
### Check 3: XD Compliance
|
|
92
|
+
|
|
93
|
+
Compare implementation against the Designer's XD plan (`xd-plan.md`).
|
|
94
|
+
|
|
95
|
+
**Component compliance:**
|
|
96
|
+
- Correct atomic level used (atom, molecule, organism)
|
|
97
|
+
- Component names match the XD plan's naming convention
|
|
98
|
+
- Props match the defined component contracts
|
|
99
|
+
- Variant system follows the established pattern
|
|
100
|
+
- No ad-hoc components that bypass the design system
|
|
101
|
+
|
|
102
|
+
**Style compliance:**
|
|
103
|
+
- No inline styles (`style={{}}`) — all styling through the design system
|
|
104
|
+
- Color values come from theme tokens, not hardcoded hex/rgb
|
|
105
|
+
- Spacing uses the defined scale (not arbitrary pixel values)
|
|
106
|
+
- Typography uses the defined scale (not arbitrary font sizes)
|
|
107
|
+
- Layout follows the grid system from xd-plan.md
|
|
108
|
+
|
|
109
|
+
**Interaction compliance:**
|
|
110
|
+
- Hover, focus, active, disabled states match the XD plan
|
|
111
|
+
- Transitions and animations follow the defined patterns
|
|
112
|
+
- Form validation displays errors as specified
|
|
113
|
+
- Responsive breakpoints match the defined set
|
|
114
|
+
|
|
115
|
+
### Check 4: Code Quality
|
|
116
|
+
|
|
117
|
+
Review for clean patterns, maintainability, and correctness.
|
|
118
|
+
|
|
119
|
+
**Structural quality:**
|
|
120
|
+
- No circular dependencies between modules
|
|
121
|
+
- Imports resolve correctly (no broken paths)
|
|
122
|
+
- No unused imports, variables, or functions
|
|
123
|
+
- Consistent naming conventions throughout
|
|
124
|
+
- Files are in the correct directories per project convention
|
|
125
|
+
|
|
126
|
+
**NestJS-specific:**
|
|
127
|
+
- Modules properly import and export providers
|
|
128
|
+
- Guards and interceptors are applied correctly
|
|
129
|
+
- DTOs use class-validator decorators for input validation
|
|
130
|
+
- Services are injectable and properly scoped
|
|
131
|
+
- Environment variables read through ConfigService or lazy initialization (not top-level process.env)
|
|
132
|
+
|
|
133
|
+
**TypeScript quality:**
|
|
134
|
+
- No `any` types in production code (except justified edge cases)
|
|
135
|
+
- Interfaces exported when used as return types (avoids TS4053)
|
|
136
|
+
- Generics used appropriately (not over-engineered)
|
|
137
|
+
- Strict null checks honored (no non-null assertions without justification)
|
|
138
|
+
|
|
139
|
+
### Check 5: Test Quality
|
|
140
|
+
|
|
141
|
+
Verify that tests exercise real behavior and would catch regressions.
|
|
142
|
+
|
|
143
|
+
**The stub test litmus test:**
|
|
144
|
+
> If production code were replaced with a hardcoded return value, would the test still pass? If yes, the test is insufficient.
|
|
145
|
+
|
|
146
|
+
**Test quality checklist:**
|
|
147
|
+
- Tests describe behavior, not method names
|
|
148
|
+
- Tests use realistic data (not "foo", "bar", "test123")
|
|
149
|
+
- Tests cover: happy path, error path, edge cases
|
|
150
|
+
- Tests are independent (no shared mutable state between tests)
|
|
151
|
+
- Integration tests use real service boundaries
|
|
152
|
+
- E2E tests exercise user-visible flows, not internal APIs
|
|
153
|
+
- Mocks are at external boundaries only (HTTP calls, database), not internal methods
|
|
154
|
+
|
|
155
|
+
**Coverage assessment:**
|
|
156
|
+
- Critical paths (auth, data mutation, payment) have comprehensive coverage
|
|
157
|
+
- Edge cases (empty input, max length, special characters) are tested
|
|
158
|
+
- Error paths (network failure, invalid data, unauthorized) are tested
|
|
159
|
+
- Security-relevant paths (token validation, access control) are tested
|
|
160
|
+
|
|
161
|
+
### Check 6: Security Review
|
|
162
|
+
|
|
163
|
+
Scan for OWASP Top 10 vulnerabilities and common security mistakes.
|
|
164
|
+
|
|
165
|
+
**Quick scan checklist:**
|
|
166
|
+
- [ ] No hardcoded secrets, tokens, passwords, or API keys
|
|
167
|
+
- [ ] All user input validated and sanitized before use
|
|
168
|
+
- [ ] Authentication checks on all protected endpoints
|
|
169
|
+
- [ ] Authorization checks enforce ownership/role requirements
|
|
170
|
+
- [ ] No sensitive data in logs (tokens, passwords, PII)
|
|
171
|
+
- [ ] CORS configured with specific origins (not wildcard `*`)
|
|
172
|
+
- [ ] Rate limiting on public-facing endpoints
|
|
173
|
+
- [ ] SQL injection prevented (parameterized queries via Drizzle)
|
|
174
|
+
- [ ] XSS prevented (React escaping, no dangerouslySetInnerHTML with user data)
|
|
175
|
+
- [ ] Dependencies checked for known vulnerabilities (`npm audit`)
|
|
176
|
+
|
|
177
|
+
**Infrastructure security (if applicable):**
|
|
178
|
+
- IAM policies follow least privilege
|
|
179
|
+
- Secrets stored in AWS Secrets Manager (not env files in repos)
|
|
180
|
+
- Network policies restrict pod-to-pod communication
|
|
181
|
+
- IRSA roles scoped to specific service accounts
|
|
182
|
+
|
|
183
|
+
### Check 7: Build and Runtime Verification
|
|
184
|
+
|
|
185
|
+
Prove the system works by running it.
|
|
186
|
+
|
|
187
|
+
**Build verification:**
|
|
188
|
+
```bash
|
|
189
|
+
# TypeScript compiles without errors
|
|
190
|
+
npx tsc --noEmit
|
|
191
|
+
|
|
192
|
+
# Application builds successfully
|
|
193
|
+
npm run build
|
|
194
|
+
|
|
195
|
+
# All tests pass
|
|
196
|
+
npm run test
|
|
197
|
+
|
|
198
|
+
# Linting passes
|
|
199
|
+
npm run lint
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
**Runtime verification:**
|
|
203
|
+
```bash
|
|
204
|
+
# Application starts and responds
|
|
205
|
+
npm run start:dev
|
|
206
|
+
# Hit health check endpoint
|
|
207
|
+
curl http://localhost:3000/health
|
|
208
|
+
|
|
209
|
+
# Frontend dev server starts
|
|
210
|
+
npm run dev
|
|
211
|
+
# Verify page loads in browser
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
---
|
|
215
|
+
|
|
216
|
+
## Failure Reporting Format
|
|
217
|
+
|
|
218
|
+
Report each finding with:
|
|
219
|
+
|
|
220
|
+
```
|
|
221
|
+
## [BLOCKER|MAJOR|MINOR] — [Check Name] — [Location]
|
|
222
|
+
|
|
223
|
+
**File:** path/to/file.ts:line
|
|
224
|
+
**Finding:** Clear description of what is wrong
|
|
225
|
+
**Evidence:** The specific code, output, or behavior observed
|
|
226
|
+
**Fix:** Suggested remediation
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
- **BLOCKER:** Prevents delivery. Must be fixed before passing. (Stubs, broken wiring, security vulnerabilities)
|
|
230
|
+
- **MAJOR:** Significant quality issue. Should be fixed before delivery. (Missing error handling, poor test coverage, XD drift)
|
|
231
|
+
- **MINOR:** Improvement opportunity. Can be noted and addressed later. (Naming inconsistency, missing edge case test)
|
|
232
|
+
|
|
233
|
+
---
|
|
234
|
+
|
|
235
|
+
## Verdict Criteria
|
|
236
|
+
|
|
237
|
+
**PASS:** All seven checks pass with zero blockers and zero majors. Minors documented.
|
|
238
|
+
|
|
239
|
+
**PASS WITH WARNINGS:** All seven checks pass with zero blockers. Majors documented with explicit acknowledgment from the Strategist.
|
|
240
|
+
|
|
241
|
+
**FAIL:** Any blocker exists. Work returns to the responsible agent with the failure report.
|
|
242
|
+
|
|
243
|
+
---
|
|
244
|
+
|
|
245
|
+
## Re-Verification After Fixes
|
|
246
|
+
|
|
247
|
+
After fixes are applied, run the FULL protocol again — not just the failed items. Fixes can introduce new issues. The only exception: if the fix is a single-line change to a minor finding, re-run only the affected check.
|
|
248
|
+
|
|
249
|
+
---
|
|
250
|
+
|
|
251
|
+
## Reporting to Strategist and Knowledge Keeper
|
|
252
|
+
|
|
253
|
+
After verification completes:
|
|
254
|
+
|
|
255
|
+
1. **Strategist** receives: verdict, summary of findings, list of blockers/majors, recommendation (pass/iterate/escalate)
|
|
256
|
+
2. **Knowledge Keeper** receives: patterns observed (recurring issues, new gotchas discovered, conventions violated), suggestions for CLAUDE.md updates
|