ma-agents 3.12.0 → 3.12.2
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/CONTRIBUTING.md +235 -235
- package/LICENSE +20 -20
- package/QUICK_START.md +154 -154
- package/README.md +731 -731
- package/SKILLS_STRUCTURE.md +392 -392
- package/bin/cli.js +1681 -1573
- package/docs/architecture.md +284 -284
- package/docs/deployment/vllm-nemotron.md +132 -132
- package/docs/development-guide.md +122 -122
- package/docs/index.md +48 -48
- package/docs/project-overview.md +56 -56
- package/docs/project-scan-report.json +50 -50
- package/docs/source-tree-analysis.md +84 -84
- package/docs/technical-notes/context-persistence-research.md +434 -434
- package/docs/validation/bundled-installation-validation.md +52 -52
- package/examples/programmatic-usage.js +62 -62
- package/index.js +22 -22
- package/lib/agents.js +370 -370
- package/lib/bmad-cache/bmb/.claude-plugin/marketplace.json +50 -50
- package/lib/bmad-cache/bmb/.markdownlint-cli2.yaml +36 -36
- package/lib/bmad-cache/bmb/.prettierignore +9 -9
- package/lib/bmad-cache/bmb/CNAME +1 -1
- package/lib/bmad-cache/bmb/LICENSE +30 -30
- package/lib/bmad-cache/bmb/README.md +75 -75
- package/lib/bmad-cache/bmb/_git_preserved/HEAD +1 -1
- package/lib/bmad-cache/bmb/_git_preserved/config +13 -13
- package/lib/bmad-cache/bmb/_git_preserved/description +1 -1
- package/lib/bmad-cache/bmb/_git_preserved/hooks/applypatch-msg.sample +15 -15
- package/lib/bmad-cache/bmb/_git_preserved/hooks/commit-msg.sample +24 -24
- package/lib/bmad-cache/bmb/_git_preserved/hooks/fsmonitor-watchman.sample +174 -174
- package/lib/bmad-cache/bmb/_git_preserved/hooks/post-update.sample +8 -8
- package/lib/bmad-cache/bmb/_git_preserved/hooks/pre-applypatch.sample +14 -14
- package/lib/bmad-cache/bmb/_git_preserved/hooks/pre-commit.sample +49 -49
- package/lib/bmad-cache/bmb/_git_preserved/hooks/pre-merge-commit.sample +13 -13
- package/lib/bmad-cache/bmb/_git_preserved/hooks/pre-push.sample +53 -53
- package/lib/bmad-cache/bmb/_git_preserved/hooks/pre-rebase.sample +169 -169
- package/lib/bmad-cache/bmb/_git_preserved/hooks/pre-receive.sample +24 -24
- package/lib/bmad-cache/bmb/_git_preserved/hooks/prepare-commit-msg.sample +42 -42
- package/lib/bmad-cache/bmb/_git_preserved/hooks/push-to-checkout.sample +78 -78
- package/lib/bmad-cache/bmb/_git_preserved/hooks/sendemail-validate.sample +77 -77
- package/lib/bmad-cache/bmb/_git_preserved/hooks/update.sample +128 -128
- package/lib/bmad-cache/bmb/_git_preserved/info/exclude +6 -6
- package/lib/bmad-cache/bmb/_git_preserved/packed-refs +2 -2
- package/lib/bmad-cache/bmb/_git_preserved/refs/heads/main +1 -1
- package/lib/bmad-cache/bmb/_git_preserved/refs/remotes/origin/HEAD +1 -1
- package/lib/bmad-cache/bmb/_git_preserved/refs/tags/v1.7.0 +1 -1
- package/lib/bmad-cache/bmb/_git_preserved/shallow +1 -1
- package/lib/bmad-cache/bmb/eslint.config.mjs +141 -141
- package/lib/bmad-cache/bmb/package-lock.json +15283 -15283
- package/lib/bmad-cache/bmb/package.json +86 -86
- package/lib/bmad-cache/bmb/prettier.config.mjs +32 -32
- package/lib/bmad-cache/bmb/samples/bmad-agent-code-coach/scripts/init-sanctum.py +288 -288
- package/lib/bmad-cache/bmb/samples/bmad-agent-creative-muse/scripts/init-sanctum.py +274 -274
- package/lib/bmad-cache/bmb/samples/bmad-agent-dream-weaver/assets/module-help.csv +9 -9
- package/lib/bmad-cache/bmb/samples/bmad-agent-dream-weaver/assets/module.yaml +8 -8
- package/lib/bmad-cache/bmb/samples/bmad-agent-dream-weaver/scripts/merge-config.py +408 -408
- package/lib/bmad-cache/bmb/samples/bmad-agent-dream-weaver/scripts/merge-help-csv.py +218 -218
- package/lib/bmad-cache/bmb/samples/bmad-agent-dream-weaver/scripts/recall_metrics.py +229 -229
- package/lib/bmad-cache/bmb/samples/bmad-agent-dream-weaver/scripts/seed_tracker.py +156 -156
- package/lib/bmad-cache/bmb/samples/bmad-agent-dream-weaver/scripts/symbol_stats.py +162 -162
- package/lib/bmad-cache/bmb/samples/bmad-agent-dream-weaver/scripts/tests/test_recall_metrics.py +115 -115
- package/lib/bmad-cache/bmb/samples/bmad-agent-dream-weaver/scripts/tests/test_seed_tracker.py +140 -140
- package/lib/bmad-cache/bmb/samples/bmad-agent-dream-weaver/scripts/tests/test_symbol_stats.py +113 -113
- package/lib/bmad-cache/bmb/samples/bmad-agent-sentinel/scripts/init-sanctum.py +285 -285
- package/lib/bmad-cache/bmb/samples/bmad-agent-sentinel/scripts/tests/test-init-sanctum.py +174 -174
- package/lib/bmad-cache/bmb/samples/bmad-excalidraw/scripts/generate_excalidraw.py +605 -605
- package/lib/bmad-cache/bmb/samples/bmad-excalidraw/scripts/tests/test_generate_excalidraw.py +360 -360
- package/lib/bmad-cache/bmb/samples/bmad-excalidraw/scripts/tests/test_validate_excalidraw.py +246 -246
- package/lib/bmad-cache/bmb/samples/bmad-excalidraw/scripts/validate_excalidraw.py +264 -264
- package/lib/bmad-cache/bmb/samples/sample-module-setup/assets/module-help.csv +16 -16
- package/lib/bmad-cache/bmb/samples/sample-module-setup/assets/module.yaml +13 -13
- package/lib/bmad-cache/bmb/samples/sample-module-setup/scripts/cleanup-legacy.py +259 -259
- package/lib/bmad-cache/bmb/samples/sample-module-setup/scripts/merge-config.py +408 -408
- package/lib/bmad-cache/bmb/samples/sample-module-setup/scripts/merge-help-csv.py +218 -218
- package/lib/bmad-cache/bmb/skills/bmad-agent-builder/assets/customize-template.toml +62 -62
- package/lib/bmad-cache/bmb/skills/bmad-agent-builder/assets/init-sanctum-template.py +277 -277
- package/lib/bmad-cache/bmb/skills/bmad-agent-builder/assets/sample-customize-analyst.toml +87 -87
- package/lib/bmad-cache/bmb/skills/bmad-agent-builder/references/sample-init-sanctum.py +274 -274
- package/lib/bmad-cache/bmb/skills/bmad-agent-builder/scripts/generate-html-report.py +534 -534
- package/lib/bmad-cache/bmb/skills/bmad-agent-builder/scripts/prepass-execution-deps.py +337 -337
- package/lib/bmad-cache/bmb/skills/bmad-agent-builder/scripts/prepass-prompt-metrics.py +425 -425
- package/lib/bmad-cache/bmb/skills/bmad-agent-builder/scripts/prepass-sanctum-architecture.py +385 -385
- package/lib/bmad-cache/bmb/skills/bmad-agent-builder/scripts/prepass-structure-capabilities.py +482 -482
- package/lib/bmad-cache/bmb/skills/bmad-agent-builder/scripts/process-template.py +190 -190
- package/lib/bmad-cache/bmb/skills/bmad-agent-builder/scripts/scan-path-standards.py +324 -324
- package/lib/bmad-cache/bmb/skills/bmad-agent-builder/scripts/scan-scripts.py +747 -747
- package/lib/bmad-cache/bmb/skills/bmad-bmb-setup/assets/module-help.csv +10 -10
- package/lib/bmad-cache/bmb/skills/bmad-bmb-setup/assets/module.yaml +20 -20
- package/lib/bmad-cache/bmb/skills/bmad-bmb-setup/scripts/cleanup-legacy.py +259 -259
- package/lib/bmad-cache/bmb/skills/bmad-bmb-setup/scripts/merge-config.py +408 -408
- package/lib/bmad-cache/bmb/skills/bmad-bmb-setup/scripts/merge-help-csv.py +218 -218
- package/lib/bmad-cache/bmb/skills/bmad-module-builder/assets/setup-skill-template/assets/module-help.csv +1 -1
- package/lib/bmad-cache/bmb/skills/bmad-module-builder/assets/setup-skill-template/assets/module.yaml +6 -6
- package/lib/bmad-cache/bmb/skills/bmad-module-builder/assets/setup-skill-template/scripts/cleanup-legacy.py +259 -259
- package/lib/bmad-cache/bmb/skills/bmad-module-builder/assets/setup-skill-template/scripts/merge-config.py +408 -408
- package/lib/bmad-cache/bmb/skills/bmad-module-builder/assets/setup-skill-template/scripts/merge-help-csv.py +218 -218
- package/lib/bmad-cache/bmb/skills/bmad-module-builder/assets/standalone-module-template/merge-config.py +408 -408
- package/lib/bmad-cache/bmb/skills/bmad-module-builder/assets/standalone-module-template/merge-help-csv.py +218 -218
- package/lib/bmad-cache/bmb/skills/bmad-module-builder/scripts/scaffold-setup-skill.py +124 -124
- package/lib/bmad-cache/bmb/skills/bmad-module-builder/scripts/scaffold-standalone-module.py +190 -190
- package/lib/bmad-cache/bmb/skills/bmad-module-builder/scripts/tests/test-scaffold-setup-skill.py +230 -230
- package/lib/bmad-cache/bmb/skills/bmad-module-builder/scripts/tests/test-scaffold-standalone-module.py +266 -266
- package/lib/bmad-cache/bmb/skills/bmad-module-builder/scripts/tests/test-validate-module.py +314 -314
- package/lib/bmad-cache/bmb/skills/bmad-module-builder/scripts/validate-module.py +293 -293
- package/lib/bmad-cache/bmb/skills/bmad-workflow-builder/assets/customize-template.toml +56 -56
- package/lib/bmad-cache/bmb/skills/bmad-workflow-builder/assets/sample-customize-product-brief.toml +51 -51
- package/lib/bmad-cache/bmb/skills/bmad-workflow-builder/scripts/generate-convert-report.py +406 -406
- package/lib/bmad-cache/bmb/skills/bmad-workflow-builder/scripts/generate-html-report.py +539 -539
- package/lib/bmad-cache/bmb/skills/bmad-workflow-builder/scripts/prepass-execution-deps.py +288 -288
- package/lib/bmad-cache/bmb/skills/bmad-workflow-builder/scripts/prepass-prompt-metrics.py +285 -285
- package/lib/bmad-cache/bmb/skills/bmad-workflow-builder/scripts/prepass-workflow-integrity.py +475 -475
- package/lib/bmad-cache/bmb/skills/bmad-workflow-builder/scripts/scan-path-standards.py +298 -298
- package/lib/bmad-cache/bmb/skills/bmad-workflow-builder/scripts/scan-scripts.py +745 -745
- package/lib/bmad-cache/bmb/skills/bmad-workflow-builder/scripts/tests/test_generate_convert_report.py +243 -243
- package/lib/bmad-cache/bmb/skills/module-help.csv +11 -11
- package/lib/bmad-cache/bmb/skills/module.yaml +20 -20
- package/lib/bmad-cache/bmb/tools/build-docs.mjs +448 -448
- package/lib/bmad-cache/bmb/tools/validate-doc-links.cjs +412 -412
- package/lib/bmad-cache/bmb/tools/validate-file-refs.mjs +657 -657
- package/lib/bmad-cache/bmb/website/astro.config.mjs +142 -142
- package/lib/bmad-cache/bmb/website/src/components/Banner.astro +57 -57
- package/lib/bmad-cache/bmb/website/src/components/Header.astro +94 -94
- package/lib/bmad-cache/bmb/website/src/components/MobileMenuFooter.astro +33 -33
- package/lib/bmad-cache/bmb/website/src/content/config.ts +6 -6
- package/lib/bmad-cache/bmb/website/src/lib/site-url.mjs +25 -25
- package/lib/bmad-cache/bmb/website/src/rehype-base-paths.js +88 -88
- package/lib/bmad-cache/bmb/website/src/rehype-markdown-links.js +117 -117
- package/lib/bmad-cache/bmb/website/src/styles/custom.css +502 -502
- package/lib/bmad-cache/cache-manifest.json +37 -37
- package/lib/bmad-cache/cis/.claude-plugin/marketplace.json +33 -33
- package/lib/bmad-cache/cis/.markdownlint-cli2.yaml +35 -35
- package/lib/bmad-cache/cis/.prettierignore +9 -9
- package/lib/bmad-cache/cis/CNAME +1 -1
- package/lib/bmad-cache/cis/LICENSE +26 -26
- package/lib/bmad-cache/cis/README.md +114 -114
- package/lib/bmad-cache/cis/_git_preserved/HEAD +1 -1
- package/lib/bmad-cache/cis/_git_preserved/config +13 -13
- package/lib/bmad-cache/cis/_git_preserved/description +1 -1
- package/lib/bmad-cache/cis/_git_preserved/hooks/applypatch-msg.sample +15 -15
- package/lib/bmad-cache/cis/_git_preserved/hooks/commit-msg.sample +24 -24
- package/lib/bmad-cache/cis/_git_preserved/hooks/fsmonitor-watchman.sample +174 -174
- package/lib/bmad-cache/cis/_git_preserved/hooks/post-update.sample +8 -8
- package/lib/bmad-cache/cis/_git_preserved/hooks/pre-applypatch.sample +14 -14
- package/lib/bmad-cache/cis/_git_preserved/hooks/pre-commit.sample +49 -49
- package/lib/bmad-cache/cis/_git_preserved/hooks/pre-merge-commit.sample +13 -13
- package/lib/bmad-cache/cis/_git_preserved/hooks/pre-push.sample +53 -53
- package/lib/bmad-cache/cis/_git_preserved/hooks/pre-rebase.sample +169 -169
- package/lib/bmad-cache/cis/_git_preserved/hooks/pre-receive.sample +24 -24
- package/lib/bmad-cache/cis/_git_preserved/hooks/prepare-commit-msg.sample +42 -42
- package/lib/bmad-cache/cis/_git_preserved/hooks/push-to-checkout.sample +78 -78
- package/lib/bmad-cache/cis/_git_preserved/hooks/sendemail-validate.sample +77 -77
- package/lib/bmad-cache/cis/_git_preserved/hooks/update.sample +128 -128
- package/lib/bmad-cache/cis/_git_preserved/info/exclude +6 -6
- package/lib/bmad-cache/cis/_git_preserved/packed-refs +2 -2
- package/lib/bmad-cache/cis/_git_preserved/refs/heads/main +1 -1
- package/lib/bmad-cache/cis/_git_preserved/refs/remotes/origin/HEAD +1 -1
- package/lib/bmad-cache/cis/_git_preserved/shallow +1 -1
- package/lib/bmad-cache/cis/eslint.config.mjs +141 -141
- package/lib/bmad-cache/cis/package-lock.json +17015 -17015
- package/lib/bmad-cache/cis/package.json +91 -91
- package/lib/bmad-cache/cis/prettier.config.mjs +32 -32
- package/lib/bmad-cache/cis/src/module-help.csv +7 -7
- package/lib/bmad-cache/cis/src/module.yaml +76 -76
- package/lib/bmad-cache/cis/src/skills/bmad-cis-agent-brainstorming-coach/customize.toml +38 -38
- package/lib/bmad-cache/cis/src/skills/bmad-cis-agent-creative-problem-solver/customize.toml +38 -38
- package/lib/bmad-cache/cis/src/skills/bmad-cis-agent-design-thinking-coach/customize.toml +39 -39
- package/lib/bmad-cache/cis/src/skills/bmad-cis-agent-innovation-strategist/customize.toml +38 -38
- package/lib/bmad-cache/cis/src/skills/bmad-cis-agent-presentation-master/customize.toml +73 -73
- package/lib/bmad-cache/cis/src/skills/bmad-cis-agent-storyteller/customize.toml +60 -60
- package/lib/bmad-cache/cis/src/skills/bmad-cis-design-thinking/customize.toml +41 -41
- package/lib/bmad-cache/cis/src/skills/bmad-cis-design-thinking/design-methods.csv +30 -30
- package/lib/bmad-cache/cis/src/skills/bmad-cis-innovation-strategy/customize.toml +41 -41
- package/lib/bmad-cache/cis/src/skills/bmad-cis-innovation-strategy/innovation-frameworks.csv +30 -30
- package/lib/bmad-cache/cis/src/skills/bmad-cis-problem-solving/customize.toml +42 -42
- package/lib/bmad-cache/cis/src/skills/bmad-cis-problem-solving/solving-methods.csv +30 -30
- package/lib/bmad-cache/cis/src/skills/bmad-cis-storytelling/customize.toml +41 -41
- package/lib/bmad-cache/cis/src/skills/bmad-cis-storytelling/story-types.csv +25 -25
- package/lib/bmad-cache/cis/tools/build-docs.mjs +456 -456
- package/lib/bmad-cache/cis/website/astro.config.mjs +172 -172
- package/lib/bmad-cache/cis/website/src/components/Banner.astro +71 -71
- package/lib/bmad-cache/cis/website/src/components/Header.astro +94 -94
- package/lib/bmad-cache/cis/website/src/components/MobileMenuFooter.astro +33 -33
- package/lib/bmad-cache/cis/website/src/content/config.ts +7 -7
- package/lib/bmad-cache/cis/website/src/content/i18n/zh-CN.json +28 -28
- package/lib/bmad-cache/cis/website/src/lib/locales.mjs +27 -27
- package/lib/bmad-cache/cis/website/src/lib/site-url.mjs +25 -25
- package/lib/bmad-cache/cis/website/src/rehype-base-paths.js +88 -88
- package/lib/bmad-cache/cis/website/src/rehype-markdown-links.js +117 -117
- package/lib/bmad-cache/cis/website/src/styles/custom.css +503 -503
- package/lib/bmad-cache/gds/.claude-plugin/marketplace.json +59 -59
- package/lib/bmad-cache/gds/.markdownlint-cli2.yaml +35 -35
- package/lib/bmad-cache/gds/.prettierignore +9 -9
- package/lib/bmad-cache/gds/CNAME +1 -1
- package/lib/bmad-cache/gds/LICENSE +26 -26
- package/lib/bmad-cache/gds/README.md +132 -132
- package/lib/bmad-cache/gds/_git_preserved/HEAD +1 -1
- package/lib/bmad-cache/gds/_git_preserved/config +13 -13
- package/lib/bmad-cache/gds/_git_preserved/description +1 -1
- package/lib/bmad-cache/gds/_git_preserved/hooks/applypatch-msg.sample +15 -15
- package/lib/bmad-cache/gds/_git_preserved/hooks/commit-msg.sample +24 -24
- package/lib/bmad-cache/gds/_git_preserved/hooks/fsmonitor-watchman.sample +174 -174
- package/lib/bmad-cache/gds/_git_preserved/hooks/post-update.sample +8 -8
- package/lib/bmad-cache/gds/_git_preserved/hooks/pre-applypatch.sample +14 -14
- package/lib/bmad-cache/gds/_git_preserved/hooks/pre-commit.sample +49 -49
- package/lib/bmad-cache/gds/_git_preserved/hooks/pre-merge-commit.sample +13 -13
- package/lib/bmad-cache/gds/_git_preserved/hooks/pre-push.sample +53 -53
- package/lib/bmad-cache/gds/_git_preserved/hooks/pre-rebase.sample +169 -169
- package/lib/bmad-cache/gds/_git_preserved/hooks/pre-receive.sample +24 -24
- package/lib/bmad-cache/gds/_git_preserved/hooks/prepare-commit-msg.sample +42 -42
- package/lib/bmad-cache/gds/_git_preserved/hooks/push-to-checkout.sample +78 -78
- package/lib/bmad-cache/gds/_git_preserved/hooks/sendemail-validate.sample +77 -77
- package/lib/bmad-cache/gds/_git_preserved/hooks/update.sample +128 -128
- package/lib/bmad-cache/gds/_git_preserved/info/exclude +6 -6
- package/lib/bmad-cache/gds/_git_preserved/packed-refs +2 -2
- package/lib/bmad-cache/gds/_git_preserved/refs/heads/main +1 -1
- package/lib/bmad-cache/gds/_git_preserved/refs/remotes/origin/HEAD +1 -1
- package/lib/bmad-cache/gds/_git_preserved/shallow +1 -1
- package/lib/bmad-cache/gds/eslint.config.mjs +141 -141
- package/lib/bmad-cache/gds/package.json +91 -91
- package/lib/bmad-cache/gds/prettier.config.mjs +32 -32
- package/lib/bmad-cache/gds/src/agents/gds-agent-game-architect/customize.toml +57 -57
- package/lib/bmad-cache/gds/src/agents/gds-agent-game-designer/customize.toml +59 -59
- package/lib/bmad-cache/gds/src/agents/gds-agent-game-dev/customize.toml +129 -129
- package/lib/bmad-cache/gds/src/agents/gds-agent-game-dev/gametest/qa-index.csv +18 -18
- package/lib/bmad-cache/gds/src/agents/gds-agent-game-solo-dev/customize.toml +60 -60
- package/lib/bmad-cache/gds/src/agents/gds-agent-tech-writer/customize.toml +65 -65
- package/lib/bmad-cache/gds/src/module-help.csv +36 -36
- package/lib/bmad-cache/gds/src/module.yaml +113 -113
- package/lib/bmad-cache/gds/src/workflows/1-preproduction/gds-brainstorm-game/customize.toml +41 -41
- package/lib/bmad-cache/gds/src/workflows/1-preproduction/gds-brainstorm-game/game-brain-methods.csv +25 -25
- package/lib/bmad-cache/gds/src/workflows/1-preproduction/gds-create-game-brief/customize.toml +41 -41
- package/lib/bmad-cache/gds/src/workflows/1-preproduction/research/gds-domain-research/customize.toml +41 -41
- package/lib/bmad-cache/gds/src/workflows/2-design/gds-create-gdd/customize.toml +41 -41
- package/lib/bmad-cache/gds/src/workflows/2-design/gds-create-gdd/game-types.csv +24 -24
- package/lib/bmad-cache/gds/src/workflows/2-design/gds-create-narrative/customize.toml +41 -41
- package/lib/bmad-cache/gds/src/workflows/2-design/gds-create-prd/customize.toml +41 -41
- package/lib/bmad-cache/gds/src/workflows/2-design/gds-create-prd/data/domain-complexity.csv +14 -14
- package/lib/bmad-cache/gds/src/workflows/2-design/gds-create-prd/data/project-types.csv +10 -10
- package/lib/bmad-cache/gds/src/workflows/2-design/gds-create-ux-design/customize.toml +41 -41
- package/lib/bmad-cache/gds/src/workflows/2-design/gds-edit-gdd/customize.toml +41 -41
- package/lib/bmad-cache/gds/src/workflows/2-design/gds-edit-prd/customize.toml +41 -41
- package/lib/bmad-cache/gds/src/workflows/2-design/gds-validate-gdd/customize.toml +41 -41
- package/lib/bmad-cache/gds/src/workflows/2-design/gds-validate-gdd/data/genre-complexity.csv +26 -26
- package/lib/bmad-cache/gds/src/workflows/2-design/gds-validate-prd/customize.toml +41 -41
- package/lib/bmad-cache/gds/src/workflows/2-design/gds-validate-prd/data/domain-complexity.csv +14 -14
- package/lib/bmad-cache/gds/src/workflows/2-design/gds-validate-prd/data/project-types.csv +10 -10
- package/lib/bmad-cache/gds/src/workflows/3-technical/gds-check-implementation-readiness/customize.toml +41 -41
- package/lib/bmad-cache/gds/src/workflows/3-technical/gds-create-epics-and-stories/customize.toml +41 -41
- package/lib/bmad-cache/gds/src/workflows/3-technical/gds-game-architecture/architecture-patterns.yaml +507 -507
- package/lib/bmad-cache/gds/src/workflows/3-technical/gds-game-architecture/customize.toml +41 -41
- package/lib/bmad-cache/gds/src/workflows/3-technical/gds-game-architecture/decision-catalog.yaml +340 -340
- package/lib/bmad-cache/gds/src/workflows/3-technical/gds-game-architecture/engine-mcps.yaml +270 -270
- package/lib/bmad-cache/gds/src/workflows/3-technical/gds-game-architecture/pattern-categories.csv +12 -12
- package/lib/bmad-cache/gds/src/workflows/3-technical/gds-generate-project-context/customize.toml +41 -41
- package/lib/bmad-cache/gds/src/workflows/4-production/gds-code-review/customize.toml +41 -41
- package/lib/bmad-cache/gds/src/workflows/4-production/gds-correct-course/customize.toml +41 -41
- package/lib/bmad-cache/gds/src/workflows/4-production/gds-create-story/customize.toml +41 -41
- package/lib/bmad-cache/gds/src/workflows/4-production/gds-dev-story/customize.toml +41 -41
- package/lib/bmad-cache/gds/src/workflows/4-production/gds-retrospective/customize.toml +41 -41
- package/lib/bmad-cache/gds/src/workflows/4-production/gds-sprint-planning/customize.toml +41 -41
- package/lib/bmad-cache/gds/src/workflows/4-production/gds-sprint-planning/sprint-status-template.yaml +55 -55
- package/lib/bmad-cache/gds/src/workflows/4-production/gds-sprint-status/customize.toml +41 -41
- package/lib/bmad-cache/gds/src/workflows/gametest/gds-e2e-scaffold/customize.toml +41 -41
- package/lib/bmad-cache/gds/src/workflows/gametest/gds-performance-test/customize.toml +41 -41
- package/lib/bmad-cache/gds/src/workflows/gametest/gds-playtest-plan/customize.toml +41 -41
- package/lib/bmad-cache/gds/src/workflows/gametest/gds-test-automate/customize.toml +41 -41
- package/lib/bmad-cache/gds/src/workflows/gametest/gds-test-design/customize.toml +41 -41
- package/lib/bmad-cache/gds/src/workflows/gametest/gds-test-framework/customize.toml +41 -41
- package/lib/bmad-cache/gds/src/workflows/gametest/gds-test-review/customize.toml +41 -41
- package/lib/bmad-cache/gds/src/workflows/gds-document-project/customize.toml +41 -41
- package/lib/bmad-cache/gds/src/workflows/gds-document-project/documentation-requirements.csv +12 -12
- package/lib/bmad-cache/gds/src/workflows/gds-document-project/templates/project-scan-report-schema.json +160 -160
- package/lib/bmad-cache/gds/src/workflows/gds-quick-flow/gds-quick-dev/customize.toml +41 -41
- package/lib/bmad-cache/gds/tools/build-docs.mjs +450 -450
- package/lib/bmad-cache/gds/website/astro.config.mjs +142 -142
- package/lib/bmad-cache/gds/website/src/components/Banner.astro +71 -71
- package/lib/bmad-cache/gds/website/src/components/Header.astro +94 -94
- package/lib/bmad-cache/gds/website/src/components/MobileMenuFooter.astro +33 -33
- package/lib/bmad-cache/gds/website/src/content/config.ts +6 -6
- package/lib/bmad-cache/gds/website/src/lib/site-url.mjs +25 -25
- package/lib/bmad-cache/gds/website/src/rehype-base-paths.js +88 -88
- package/lib/bmad-cache/gds/website/src/rehype-markdown-links.js +117 -117
- package/lib/bmad-cache/gds/website/src/styles/custom.css +503 -503
- package/lib/bmad-cache/tea/.claude-plugin/marketplace.json +33 -33
- package/lib/bmad-cache/tea/.coderabbit.yaml +40 -40
- package/lib/bmad-cache/tea/.github/CODE_OF_CONDUCT.md +128 -128
- package/lib/bmad-cache/tea/.github/FUNDING.yaml +15 -15
- package/lib/bmad-cache/tea/.github/ISSUE_TEMPLATE/config.yaml +11 -11
- package/lib/bmad-cache/tea/.github/ISSUE_TEMPLATE/feature_request.md +70 -70
- package/lib/bmad-cache/tea/.github/ISSUE_TEMPLATE/issue.md +61 -61
- package/lib/bmad-cache/tea/.github/workflows/docs.yaml +66 -66
- package/lib/bmad-cache/tea/.github/workflows/quality.yaml +117 -117
- package/lib/bmad-cache/tea/.husky/pre-commit +20 -20
- package/lib/bmad-cache/tea/.markdownlint-cli2.yaml +36 -36
- package/lib/bmad-cache/tea/.prettierignore +9 -9
- package/lib/bmad-cache/tea/CHANGELOG.md +241 -241
- package/lib/bmad-cache/tea/CONTRIBUTING.md +268 -268
- package/lib/bmad-cache/tea/LICENSE +26 -26
- package/lib/bmad-cache/tea/README.md +416 -416
- package/lib/bmad-cache/tea/SECURITY.md +85 -85
- package/lib/bmad-cache/tea/_git_preserved/HEAD +1 -1
- package/lib/bmad-cache/tea/_git_preserved/config +13 -13
- package/lib/bmad-cache/tea/_git_preserved/description +1 -1
- package/lib/bmad-cache/tea/_git_preserved/hooks/applypatch-msg.sample +15 -15
- package/lib/bmad-cache/tea/_git_preserved/hooks/commit-msg.sample +24 -24
- package/lib/bmad-cache/tea/_git_preserved/hooks/fsmonitor-watchman.sample +174 -174
- package/lib/bmad-cache/tea/_git_preserved/hooks/post-update.sample +8 -8
- package/lib/bmad-cache/tea/_git_preserved/hooks/pre-applypatch.sample +14 -14
- package/lib/bmad-cache/tea/_git_preserved/hooks/pre-commit.sample +49 -49
- package/lib/bmad-cache/tea/_git_preserved/hooks/pre-merge-commit.sample +13 -13
- package/lib/bmad-cache/tea/_git_preserved/hooks/pre-push.sample +53 -53
- package/lib/bmad-cache/tea/_git_preserved/hooks/pre-rebase.sample +169 -169
- package/lib/bmad-cache/tea/_git_preserved/hooks/pre-receive.sample +24 -24
- package/lib/bmad-cache/tea/_git_preserved/hooks/prepare-commit-msg.sample +42 -42
- package/lib/bmad-cache/tea/_git_preserved/hooks/push-to-checkout.sample +78 -78
- package/lib/bmad-cache/tea/_git_preserved/hooks/sendemail-validate.sample +77 -77
- package/lib/bmad-cache/tea/_git_preserved/hooks/update.sample +128 -128
- package/lib/bmad-cache/tea/_git_preserved/info/exclude +6 -6
- package/lib/bmad-cache/tea/_git_preserved/packed-refs +2 -2
- package/lib/bmad-cache/tea/_git_preserved/refs/heads/main +1 -1
- package/lib/bmad-cache/tea/_git_preserved/refs/remotes/origin/HEAD +1 -1
- package/lib/bmad-cache/tea/_git_preserved/shallow +1 -1
- package/lib/bmad-cache/tea/docs/404.md +20 -20
- package/lib/bmad-cache/tea/docs/explanation/engagement-models.md +767 -767
- package/lib/bmad-cache/tea/docs/explanation/fixture-architecture.md +484 -484
- package/lib/bmad-cache/tea/docs/explanation/knowledge-base-system.md +601 -601
- package/lib/bmad-cache/tea/docs/explanation/network-first-patterns.md +884 -884
- package/lib/bmad-cache/tea/docs/explanation/risk-based-testing.md +628 -628
- package/lib/bmad-cache/tea/docs/explanation/step-file-architecture.md +599 -599
- package/lib/bmad-cache/tea/docs/explanation/subagent-architecture.md +189 -189
- package/lib/bmad-cache/tea/docs/explanation/tea-overview.md +474 -474
- package/lib/bmad-cache/tea/docs/explanation/test-quality-standards.md +965 -965
- package/lib/bmad-cache/tea/docs/explanation/testing-as-engineering.md +115 -115
- package/lib/bmad-cache/tea/docs/glossary/index.md +160 -160
- package/lib/bmad-cache/tea/docs/how-to/brownfield/use-tea-for-enterprise.md +571 -571
- package/lib/bmad-cache/tea/docs/how-to/brownfield/use-tea-with-existing-tests.md +631 -631
- package/lib/bmad-cache/tea/docs/how-to/customization/configure-browser-automation.md +243 -243
- package/lib/bmad-cache/tea/docs/how-to/customization/extend-tea-with-custom-workflows.md +102 -102
- package/lib/bmad-cache/tea/docs/how-to/customization/integrate-playwright-utils.md +846 -846
- package/lib/bmad-cache/tea/docs/how-to/workflows/run-atdd.md +462 -462
- package/lib/bmad-cache/tea/docs/how-to/workflows/run-automate.md +693 -693
- package/lib/bmad-cache/tea/docs/how-to/workflows/run-nfr-assess.md +731 -731
- package/lib/bmad-cache/tea/docs/how-to/workflows/run-test-design.md +144 -144
- package/lib/bmad-cache/tea/docs/how-to/workflows/run-test-review.md +634 -634
- package/lib/bmad-cache/tea/docs/how-to/workflows/run-trace.md +966 -966
- package/lib/bmad-cache/tea/docs/how-to/workflows/setup-ci.md +763 -763
- package/lib/bmad-cache/tea/docs/how-to/workflows/setup-test-framework.md +122 -122
- package/lib/bmad-cache/tea/docs/how-to/workflows/teach-me-testing.md +302 -302
- package/lib/bmad-cache/tea/docs/index.md +65 -65
- package/lib/bmad-cache/tea/docs/reference/commands.md +356 -356
- package/lib/bmad-cache/tea/docs/reference/configuration.md +1144 -1144
- package/lib/bmad-cache/tea/docs/reference/knowledge-base.md +406 -406
- package/lib/bmad-cache/tea/docs/reference/troubleshooting.md +837 -837
- package/lib/bmad-cache/tea/docs/tutorials/learn-testing-tea-academy.md +266 -266
- package/lib/bmad-cache/tea/docs/tutorials/tea-lite-quickstart.md +465 -465
- package/lib/bmad-cache/tea/eslint.config.mjs +141 -141
- package/lib/bmad-cache/tea/package-lock.json +16046 -16046
- package/lib/bmad-cache/tea/package.json +118 -118
- package/lib/bmad-cache/tea/prettier.config.mjs +32 -32
- package/lib/bmad-cache/tea/src/agents/bmad-tea/SKILL.md +80 -80
- package/lib/bmad-cache/tea/src/agents/bmad-tea/customize.toml +104 -104
- package/lib/bmad-cache/tea/src/agents/bmad-tea/resources/knowledge/adr-quality-readiness-checklist.md +377 -377
- package/lib/bmad-cache/tea/src/agents/bmad-tea/resources/knowledge/api-request.md +563 -563
- package/lib/bmad-cache/tea/src/agents/bmad-tea/resources/knowledge/api-testing-patterns.md +915 -915
- package/lib/bmad-cache/tea/src/agents/bmad-tea/resources/knowledge/auth-session.md +548 -548
- package/lib/bmad-cache/tea/src/agents/bmad-tea/resources/knowledge/burn-in.md +273 -273
- package/lib/bmad-cache/tea/src/agents/bmad-tea/resources/knowledge/ci-burn-in.md +717 -717
- package/lib/bmad-cache/tea/src/agents/bmad-tea/resources/knowledge/component-tdd.md +486 -486
- package/lib/bmad-cache/tea/src/agents/bmad-tea/resources/knowledge/contract-testing.md +1066 -1066
- package/lib/bmad-cache/tea/src/agents/bmad-tea/resources/knowledge/data-factories.md +500 -500
- package/lib/bmad-cache/tea/src/agents/bmad-tea/resources/knowledge/email-auth.md +721 -721
- package/lib/bmad-cache/tea/src/agents/bmad-tea/resources/knowledge/error-handling.md +725 -725
- package/lib/bmad-cache/tea/src/agents/bmad-tea/resources/knowledge/feature-flags.md +750 -750
- package/lib/bmad-cache/tea/src/agents/bmad-tea/resources/knowledge/file-utils.md +456 -456
- package/lib/bmad-cache/tea/src/agents/bmad-tea/resources/knowledge/fixture-architecture.md +401 -401
- package/lib/bmad-cache/tea/src/agents/bmad-tea/resources/knowledge/fixtures-composition.md +382 -382
- package/lib/bmad-cache/tea/src/agents/bmad-tea/resources/knowledge/intercept-network-call.md +426 -426
- package/lib/bmad-cache/tea/src/agents/bmad-tea/resources/knowledge/log.md +426 -426
- package/lib/bmad-cache/tea/src/agents/bmad-tea/resources/knowledge/network-error-monitor.md +401 -401
- package/lib/bmad-cache/tea/src/agents/bmad-tea/resources/knowledge/network-first.md +486 -486
- package/lib/bmad-cache/tea/src/agents/bmad-tea/resources/knowledge/network-recorder.md +527 -527
- package/lib/bmad-cache/tea/src/agents/bmad-tea/resources/knowledge/nfr-criteria.md +670 -670
- package/lib/bmad-cache/tea/src/agents/bmad-tea/resources/knowledge/overview.md +286 -286
- package/lib/bmad-cache/tea/src/agents/bmad-tea/resources/knowledge/pact-broker-webhooks.md +237 -237
- package/lib/bmad-cache/tea/src/agents/bmad-tea/resources/knowledge/pact-consumer-di.md +310 -310
- package/lib/bmad-cache/tea/src/agents/bmad-tea/resources/knowledge/pact-consumer-framework-setup.md +704 -704
- package/lib/bmad-cache/tea/src/agents/bmad-tea/resources/knowledge/pact-mcp.md +205 -205
- package/lib/bmad-cache/tea/src/agents/bmad-tea/resources/knowledge/pactjs-utils-consumer-helpers.md +379 -379
- package/lib/bmad-cache/tea/src/agents/bmad-tea/resources/knowledge/pactjs-utils-overview.md +219 -219
- package/lib/bmad-cache/tea/src/agents/bmad-tea/resources/knowledge/pactjs-utils-provider-verifier.md +397 -397
- package/lib/bmad-cache/tea/src/agents/bmad-tea/resources/knowledge/pactjs-utils-request-filter.md +224 -224
- package/lib/bmad-cache/tea/src/agents/bmad-tea/resources/knowledge/pactjs-utils-zod-to-pact.md +262 -262
- package/lib/bmad-cache/tea/src/agents/bmad-tea/resources/knowledge/playwright-cli.md +280 -280
- package/lib/bmad-cache/tea/src/agents/bmad-tea/resources/knowledge/playwright-config.md +734 -734
- package/lib/bmad-cache/tea/src/agents/bmad-tea/resources/knowledge/probability-impact.md +601 -601
- package/lib/bmad-cache/tea/src/agents/bmad-tea/resources/knowledge/recurse.md +421 -421
- package/lib/bmad-cache/tea/src/agents/bmad-tea/resources/knowledge/risk-governance.md +615 -615
- package/lib/bmad-cache/tea/src/agents/bmad-tea/resources/knowledge/selective-testing.md +732 -732
- package/lib/bmad-cache/tea/src/agents/bmad-tea/resources/knowledge/selector-resilience.md +527 -527
- package/lib/bmad-cache/tea/src/agents/bmad-tea/resources/knowledge/test-healing-patterns.md +644 -644
- package/lib/bmad-cache/tea/src/agents/bmad-tea/resources/knowledge/test-levels-framework.md +473 -473
- package/lib/bmad-cache/tea/src/agents/bmad-tea/resources/knowledge/test-priorities-matrix.md +373 -373
- package/lib/bmad-cache/tea/src/agents/bmad-tea/resources/knowledge/test-quality.md +664 -664
- package/lib/bmad-cache/tea/src/agents/bmad-tea/resources/knowledge/timing-debugging.md +372 -372
- package/lib/bmad-cache/tea/src/agents/bmad-tea/resources/knowledge/visual-debugging.md +527 -527
- package/lib/bmad-cache/tea/src/agents/bmad-tea/resources/knowledge/webhook-module-setup.md +122 -122
- package/lib/bmad-cache/tea/src/agents/bmad-tea/resources/knowledge/webhook-providers.md +155 -155
- package/lib/bmad-cache/tea/src/agents/bmad-tea/resources/knowledge/webhook-risk-guidance.md +114 -114
- package/lib/bmad-cache/tea/src/agents/bmad-tea/resources/knowledge/webhook-template-matchers.md +160 -160
- package/lib/bmad-cache/tea/src/agents/bmad-tea/resources/knowledge/webhook-testing-fundamentals.md +42 -42
- package/lib/bmad-cache/tea/src/agents/bmad-tea/resources/knowledge/webhook-timeout-error.md +130 -130
- package/lib/bmad-cache/tea/src/agents/bmad-tea/resources/knowledge/webhook-waiting-querying.md +167 -167
- package/lib/bmad-cache/tea/src/agents/bmad-tea/resources/tea-index.csv +52 -52
- package/lib/bmad-cache/tea/src/module-help.csv +11 -11
- package/lib/bmad-cache/tea/src/module.yaml +307 -307
- package/lib/bmad-cache/tea/src/workflows/testarch/README.md +76 -76
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-teach-me-testing/SKILL.md +129 -129
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-teach-me-testing/checklist.md +198 -198
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-teach-me-testing/customize.toml +40 -40
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-teach-me-testing/data/curriculum.yaml +129 -129
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-teach-me-testing/data/quiz-questions.yaml +206 -206
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-teach-me-testing/data/role-paths.yaml +136 -136
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-teach-me-testing/data/session-content-map.yaml +219 -219
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-teach-me-testing/data/tea-resources-index.yaml +394 -394
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-teach-me-testing/instructions.md +137 -137
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-teach-me-testing/steps-c/step-01-init.md +235 -235
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-teach-me-testing/steps-c/step-01b-continue.md +147 -147
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-teach-me-testing/steps-c/step-02-assess.md +258 -258
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-teach-me-testing/steps-c/step-03-session-menu.md +219 -219
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-teach-me-testing/steps-c/step-04-session-01.md +460 -460
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-teach-me-testing/steps-c/step-04-session-02.md +465 -465
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-teach-me-testing/steps-c/step-04-session-03.md +301 -301
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-teach-me-testing/steps-c/step-04-session-04.md +234 -234
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-teach-me-testing/steps-c/step-04-session-05.md +234 -234
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-teach-me-testing/steps-c/step-04-session-06.md +209 -209
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-teach-me-testing/steps-c/step-04-session-07.md +220 -220
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-teach-me-testing/steps-c/step-05-completion.md +347 -347
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-teach-me-testing/steps-e/step-e-01-assess-workflow.md +141 -141
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-teach-me-testing/steps-e/step-e-02-apply-edits.md +130 -130
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-teach-me-testing/steps-v/step-v-01-validate.md +272 -272
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-teach-me-testing/templates/certificate-template.md +86 -86
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-teach-me-testing/templates/progress-template.yaml +95 -95
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-teach-me-testing/templates/session-notes-template.md +83 -83
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-teach-me-testing/workflow-plan-teach-me-testing.md +950 -950
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-atdd/SKILL.md +85 -85
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-atdd/atdd-checklist-template.md +394 -394
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-atdd/checklist.md +375 -375
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-atdd/customize.toml +40 -40
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-atdd/instructions.md +44 -44
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-atdd/resources/knowledge/adr-quality-readiness-checklist.md +377 -377
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-atdd/resources/knowledge/api-request.md +563 -563
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-atdd/resources/knowledge/api-testing-patterns.md +915 -915
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-atdd/resources/knowledge/auth-session.md +548 -548
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-atdd/resources/knowledge/burn-in.md +273 -273
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-atdd/resources/knowledge/ci-burn-in.md +717 -717
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-atdd/resources/knowledge/component-tdd.md +486 -486
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-atdd/resources/knowledge/contract-testing.md +1067 -1067
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-atdd/resources/knowledge/data-factories.md +500 -500
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-atdd/resources/knowledge/email-auth.md +721 -721
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-atdd/resources/knowledge/error-handling.md +725 -725
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-atdd/resources/knowledge/feature-flags.md +750 -750
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-atdd/resources/knowledge/file-utils.md +456 -456
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-atdd/resources/knowledge/fixture-architecture.md +401 -401
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-atdd/resources/knowledge/fixtures-composition.md +382 -382
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-atdd/resources/knowledge/intercept-network-call.md +426 -426
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-atdd/resources/knowledge/log.md +426 -426
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-atdd/resources/knowledge/network-error-monitor.md +401 -401
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-atdd/resources/knowledge/network-first.md +486 -486
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-atdd/resources/knowledge/network-recorder.md +527 -527
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-atdd/resources/knowledge/nfr-criteria.md +670 -670
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-atdd/resources/knowledge/overview.md +286 -286
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-atdd/resources/knowledge/pact-broker-webhooks.md +237 -237
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-atdd/resources/knowledge/pact-consumer-di.md +310 -310
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-atdd/resources/knowledge/pact-consumer-framework-setup.md +757 -757
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-atdd/resources/knowledge/pact-mcp.md +205 -205
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-atdd/resources/knowledge/pactjs-utils-consumer-helpers.md +380 -380
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-atdd/resources/knowledge/pactjs-utils-overview.md +219 -219
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-atdd/resources/knowledge/pactjs-utils-provider-verifier.md +397 -397
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-atdd/resources/knowledge/pactjs-utils-request-filter.md +224 -224
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-atdd/resources/knowledge/pactjs-utils-zod-to-pact.md +262 -262
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-atdd/resources/knowledge/playwright-cli.md +280 -280
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-atdd/resources/knowledge/playwright-config.md +734 -734
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-atdd/resources/knowledge/probability-impact.md +601 -601
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-atdd/resources/knowledge/recurse.md +421 -421
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-atdd/resources/knowledge/risk-governance.md +615 -615
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-atdd/resources/knowledge/selective-testing.md +732 -732
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-atdd/resources/knowledge/selector-resilience.md +527 -527
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-atdd/resources/knowledge/test-healing-patterns.md +644 -644
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-atdd/resources/knowledge/test-levels-framework.md +473 -473
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-atdd/resources/knowledge/test-priorities-matrix.md +373 -373
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-atdd/resources/knowledge/test-quality.md +664 -664
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-atdd/resources/knowledge/timing-debugging.md +372 -372
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-atdd/resources/knowledge/visual-debugging.md +527 -527
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-atdd/resources/knowledge/webhook-module-setup.md +122 -122
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-atdd/resources/knowledge/webhook-providers.md +155 -155
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-atdd/resources/knowledge/webhook-risk-guidance.md +114 -114
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-atdd/resources/knowledge/webhook-template-matchers.md +160 -160
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-atdd/resources/knowledge/webhook-testing-fundamentals.md +42 -42
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-atdd/resources/knowledge/webhook-timeout-error.md +130 -130
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-atdd/resources/knowledge/webhook-waiting-querying.md +167 -167
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-atdd/resources/tea-index.csv +52 -52
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-atdd/steps-c/step-01-preflight-and-context.md +244 -244
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-atdd/steps-c/step-01b-resume.md +96 -96
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-atdd/steps-c/step-02-generation-mode.md +125 -125
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-atdd/steps-c/step-03-test-strategy.md +110 -110
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-atdd/steps-c/step-04-generate-tests.md +335 -335
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-atdd/steps-c/step-04a-subagent-api-failing.md +294 -294
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-atdd/steps-c/step-04b-subagent-e2e-failing.md +244 -244
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-atdd/steps-c/step-04c-aggregate.md +394 -394
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-atdd/steps-c/step-05-validate-and-complete.md +123 -123
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-atdd/steps-e/step-01-assess.md +65 -65
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-atdd/steps-e/step-02-apply-edit.md +68 -68
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-atdd/steps-v/step-01-validate.md +75 -75
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-atdd/validation-report-20260127-095021.md +73 -73
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-atdd/validation-report-20260127-102401.md +116 -116
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-atdd/workflow-plan.md +21 -21
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-atdd/workflow.yaml +46 -46
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-automate/SKILL.md +85 -85
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-automate/checklist.md +611 -611
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-automate/customize.toml +40 -40
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-automate/instructions.md +49 -49
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-automate/resources/knowledge/adr-quality-readiness-checklist.md +377 -377
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-automate/resources/knowledge/api-request.md +563 -563
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-automate/resources/knowledge/api-testing-patterns.md +915 -915
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-automate/resources/knowledge/auth-session.md +548 -548
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-automate/resources/knowledge/burn-in.md +273 -273
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-automate/resources/knowledge/ci-burn-in.md +717 -717
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-automate/resources/knowledge/component-tdd.md +486 -486
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-automate/resources/knowledge/contract-testing.md +1066 -1066
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-automate/resources/knowledge/data-factories.md +500 -500
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-automate/resources/knowledge/email-auth.md +721 -721
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-automate/resources/knowledge/error-handling.md +725 -725
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-automate/resources/knowledge/feature-flags.md +750 -750
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-automate/resources/knowledge/file-utils.md +456 -456
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-automate/resources/knowledge/fixture-architecture.md +401 -401
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-automate/resources/knowledge/fixtures-composition.md +382 -382
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-automate/resources/knowledge/intercept-network-call.md +426 -426
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-automate/resources/knowledge/log.md +426 -426
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-automate/resources/knowledge/network-error-monitor.md +401 -401
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-automate/resources/knowledge/network-first.md +486 -486
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-automate/resources/knowledge/network-recorder.md +527 -527
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-automate/resources/knowledge/nfr-criteria.md +670 -670
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-automate/resources/knowledge/overview.md +286 -286
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-automate/resources/knowledge/pact-broker-webhooks.md +237 -237
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-automate/resources/knowledge/pact-consumer-di.md +310 -310
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-automate/resources/knowledge/pact-consumer-framework-setup.md +757 -757
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-automate/resources/knowledge/pact-mcp.md +205 -205
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-automate/resources/knowledge/pactjs-utils-consumer-helpers.md +380 -380
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-automate/resources/knowledge/pactjs-utils-overview.md +216 -216
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-automate/resources/knowledge/pactjs-utils-provider-verifier.md +397 -397
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-automate/resources/knowledge/pactjs-utils-request-filter.md +224 -224
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-automate/resources/knowledge/playwright-cli.md +280 -280
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-automate/resources/knowledge/playwright-config.md +734 -734
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-automate/resources/knowledge/probability-impact.md +601 -601
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-automate/resources/knowledge/recurse.md +421 -421
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-automate/resources/knowledge/risk-governance.md +615 -615
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-automate/resources/knowledge/selective-testing.md +732 -732
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-automate/resources/knowledge/selector-resilience.md +527 -527
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-automate/resources/knowledge/test-healing-patterns.md +644 -644
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-automate/resources/knowledge/test-levels-framework.md +473 -473
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-automate/resources/knowledge/test-priorities-matrix.md +373 -373
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-automate/resources/knowledge/test-quality.md +664 -664
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-automate/resources/knowledge/timing-debugging.md +372 -372
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-automate/resources/knowledge/visual-debugging.md +527 -527
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-automate/resources/knowledge/webhook-module-setup.md +122 -122
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-automate/resources/knowledge/webhook-providers.md +155 -155
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-automate/resources/knowledge/webhook-risk-guidance.md +114 -114
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-automate/resources/knowledge/webhook-template-matchers.md +160 -160
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-automate/resources/knowledge/webhook-testing-fundamentals.md +42 -42
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-automate/resources/knowledge/webhook-timeout-error.md +130 -130
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-automate/resources/knowledge/webhook-waiting-querying.md +167 -167
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-automate/resources/tea-index.csv +51 -51
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-automate/steps-c/step-01-preflight-and-context.md +237 -237
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-automate/steps-c/step-01b-resume.md +94 -94
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-automate/steps-c/step-02-identify-targets.md +169 -169
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-automate/steps-c/step-03-generate-tests.md +394 -394
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-automate/steps-c/step-03a-subagent-api.md +271 -271
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-automate/steps-c/step-03b-subagent-backend.md +246 -246
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-automate/steps-c/step-03b-subagent-e2e.md +213 -213
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-automate/steps-c/step-03c-aggregate.md +398 -398
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-automate/steps-c/step-04-validate-and-summarize.md +114 -114
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-automate/steps-e/step-01-assess.md +65 -65
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-automate/steps-e/step-02-apply-edit.md +68 -68
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-automate/steps-v/step-01-validate.md +75 -75
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-automate/validation-report-20260127-095021.md +72 -72
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-automate/validation-report-20260127-102401.md +114 -114
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-automate/workflow-plan.md +20 -20
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-automate/workflow.yaml +53 -53
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-ci/SKILL.md +85 -85
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-ci/azure-pipelines-template.yaml +155 -155
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-ci/checklist.md +289 -289
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-ci/customize.toml +40 -40
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-ci/github-actions-template.yaml +328 -328
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-ci/gitlab-ci-template.yaml +158 -158
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-ci/harness-pipeline-template.yaml +160 -160
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-ci/instructions.md +44 -44
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-ci/jenkins-pipeline-template.groovy +129 -129
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-ci/resources/knowledge/adr-quality-readiness-checklist.md +377 -377
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-ci/resources/knowledge/api-request.md +563 -563
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-ci/resources/knowledge/api-testing-patterns.md +915 -915
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-ci/resources/knowledge/auth-session.md +548 -548
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-ci/resources/knowledge/burn-in.md +273 -273
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-ci/resources/knowledge/ci-burn-in.md +717 -717
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-ci/resources/knowledge/component-tdd.md +486 -486
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-ci/resources/knowledge/contract-testing.md +1066 -1066
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-ci/resources/knowledge/data-factories.md +500 -500
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-ci/resources/knowledge/email-auth.md +721 -721
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-ci/resources/knowledge/error-handling.md +725 -725
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-ci/resources/knowledge/feature-flags.md +750 -750
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-ci/resources/knowledge/file-utils.md +456 -456
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-ci/resources/knowledge/fixture-architecture.md +401 -401
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-ci/resources/knowledge/fixtures-composition.md +382 -382
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-ci/resources/knowledge/intercept-network-call.md +426 -426
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-ci/resources/knowledge/log.md +426 -426
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-ci/resources/knowledge/network-error-monitor.md +401 -401
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-ci/resources/knowledge/network-first.md +486 -486
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-ci/resources/knowledge/network-recorder.md +527 -527
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-ci/resources/knowledge/nfr-criteria.md +670 -670
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-ci/resources/knowledge/overview.md +286 -286
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-ci/resources/knowledge/pact-broker-webhooks.md +237 -237
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-ci/resources/knowledge/pact-consumer-di.md +310 -310
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-ci/resources/knowledge/pact-consumer-framework-setup.md +757 -757
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-ci/resources/knowledge/pact-mcp.md +205 -205
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-ci/resources/knowledge/pactjs-utils-consumer-helpers.md +380 -380
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-ci/resources/knowledge/pactjs-utils-overview.md +216 -216
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-ci/resources/knowledge/pactjs-utils-provider-verifier.md +397 -397
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-ci/resources/knowledge/pactjs-utils-request-filter.md +224 -224
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-ci/resources/knowledge/playwright-cli.md +280 -280
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-ci/resources/knowledge/playwright-config.md +734 -734
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-ci/resources/knowledge/probability-impact.md +601 -601
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-ci/resources/knowledge/recurse.md +421 -421
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-ci/resources/knowledge/risk-governance.md +615 -615
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-ci/resources/knowledge/selective-testing.md +732 -732
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-ci/resources/knowledge/selector-resilience.md +527 -527
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-ci/resources/knowledge/test-healing-patterns.md +644 -644
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-ci/resources/knowledge/test-levels-framework.md +473 -473
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-ci/resources/knowledge/test-priorities-matrix.md +373 -373
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-ci/resources/knowledge/test-quality.md +664 -664
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-ci/resources/knowledge/timing-debugging.md +372 -372
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-ci/resources/knowledge/visual-debugging.md +527 -527
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-ci/resources/knowledge/webhook-module-setup.md +122 -122
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-ci/resources/knowledge/webhook-providers.md +155 -155
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-ci/resources/knowledge/webhook-risk-guidance.md +114 -114
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-ci/resources/knowledge/webhook-template-matchers.md +160 -160
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-ci/resources/knowledge/webhook-testing-fundamentals.md +42 -42
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-ci/resources/knowledge/webhook-timeout-error.md +130 -130
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-ci/resources/knowledge/webhook-waiting-querying.md +167 -167
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-ci/resources/tea-index.csv +51 -51
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-ci/steps-c/step-01-preflight.md +158 -158
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-ci/steps-c/step-01b-resume.md +110 -110
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-ci/steps-c/step-02-generate-pipeline.md +293 -293
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-ci/steps-c/step-03-configure-quality-gates.md +145 -145
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-ci/steps-c/step-04-validate-and-summary.md +100 -100
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-ci/steps-e/step-01-assess.md +65 -65
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-ci/steps-e/step-02-apply-edit.md +68 -68
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-ci/steps-v/step-01-validate.md +89 -89
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-ci/validation-report-20260127-095021.md +72 -72
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-ci/validation-report-20260127-102401.md +114 -114
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-ci/workflow-plan.md +20 -20
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-ci/workflow.yaml +48 -48
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-framework/SKILL.md +85 -85
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-framework/checklist.md +345 -345
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-framework/customize.toml +40 -40
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-framework/instructions.md +44 -44
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-framework/resources/knowledge/adr-quality-readiness-checklist.md +377 -377
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-framework/resources/knowledge/api-request.md +563 -563
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-framework/resources/knowledge/api-testing-patterns.md +915 -915
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-framework/resources/knowledge/auth-session.md +548 -548
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-framework/resources/knowledge/burn-in.md +273 -273
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-framework/resources/knowledge/ci-burn-in.md +717 -717
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-framework/resources/knowledge/component-tdd.md +486 -486
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-framework/resources/knowledge/contract-testing.md +1066 -1066
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-framework/resources/knowledge/data-factories.md +500 -500
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-framework/resources/knowledge/email-auth.md +721 -721
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-framework/resources/knowledge/error-handling.md +725 -725
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-framework/resources/knowledge/feature-flags.md +750 -750
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-framework/resources/knowledge/file-utils.md +456 -456
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-framework/resources/knowledge/fixture-architecture.md +401 -401
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-framework/resources/knowledge/fixtures-composition.md +382 -382
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-framework/resources/knowledge/intercept-network-call.md +426 -426
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-framework/resources/knowledge/log.md +426 -426
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-framework/resources/knowledge/network-error-monitor.md +401 -401
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-framework/resources/knowledge/network-first.md +486 -486
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-framework/resources/knowledge/network-recorder.md +527 -527
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-framework/resources/knowledge/nfr-criteria.md +670 -670
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-framework/resources/knowledge/overview.md +286 -286
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-framework/resources/knowledge/pact-broker-webhooks.md +237 -237
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-framework/resources/knowledge/pact-consumer-di.md +310 -310
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-framework/resources/knowledge/pact-consumer-framework-setup.md +757 -757
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-framework/resources/knowledge/pact-mcp.md +205 -205
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-framework/resources/knowledge/pactjs-utils-consumer-helpers.md +380 -380
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-framework/resources/knowledge/pactjs-utils-overview.md +216 -216
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-framework/resources/knowledge/pactjs-utils-provider-verifier.md +397 -397
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-framework/resources/knowledge/pactjs-utils-request-filter.md +224 -224
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-framework/resources/knowledge/playwright-cli.md +280 -280
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-framework/resources/knowledge/playwright-config.md +734 -734
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-framework/resources/knowledge/probability-impact.md +601 -601
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-framework/resources/knowledge/recurse.md +421 -421
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-framework/resources/knowledge/risk-governance.md +615 -615
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-framework/resources/knowledge/selective-testing.md +732 -732
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-framework/resources/knowledge/selector-resilience.md +527 -527
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-framework/resources/knowledge/test-healing-patterns.md +644 -644
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-framework/resources/knowledge/test-levels-framework.md +473 -473
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-framework/resources/knowledge/test-priorities-matrix.md +373 -373
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-framework/resources/knowledge/test-quality.md +664 -664
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-framework/resources/knowledge/timing-debugging.md +372 -372
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-framework/resources/knowledge/visual-debugging.md +527 -527
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-framework/resources/knowledge/webhook-module-setup.md +122 -122
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-framework/resources/knowledge/webhook-providers.md +155 -155
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-framework/resources/knowledge/webhook-risk-guidance.md +114 -114
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-framework/resources/knowledge/webhook-template-matchers.md +160 -160
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-framework/resources/knowledge/webhook-testing-fundamentals.md +42 -42
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-framework/resources/knowledge/webhook-timeout-error.md +130 -130
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-framework/resources/knowledge/webhook-waiting-querying.md +167 -167
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-framework/resources/tea-index.csv +51 -51
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-framework/steps-c/step-01-preflight.md +132 -132
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-framework/steps-c/step-01b-resume.md +116 -116
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-framework/steps-c/step-02-select-framework.md +117 -117
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-framework/steps-c/step-03-scaffold-framework.md +328 -328
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-framework/steps-c/step-04-docs-and-scripts.md +105 -105
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-framework/steps-c/step-05-validate-and-summary.md +101 -101
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-framework/steps-e/step-01-assess.md +65 -65
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-framework/steps-e/step-02-apply-edit.md +68 -68
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-framework/steps-v/step-01-validate.md +75 -75
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-framework/validation-report-20260127-095021.md +73 -73
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-framework/validation-report-20260127-102401.md +116 -116
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-framework/workflow-plan.md +22 -22
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-framework/workflow.yaml +48 -48
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-nfr/SKILL.md +85 -85
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-nfr/checklist.md +407 -407
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-nfr/customize.toml +40 -40
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-nfr/instructions.md +43 -43
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-nfr/nfr-report-template.md +470 -470
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-nfr/resources/knowledge/adr-quality-readiness-checklist.md +377 -377
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-nfr/resources/knowledge/api-request.md +563 -563
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-nfr/resources/knowledge/api-testing-patterns.md +915 -915
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-nfr/resources/knowledge/auth-session.md +548 -548
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-nfr/resources/knowledge/burn-in.md +273 -273
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-nfr/resources/knowledge/ci-burn-in.md +717 -717
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-nfr/resources/knowledge/component-tdd.md +486 -486
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-nfr/resources/knowledge/contract-testing.md +1066 -1066
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-nfr/resources/knowledge/data-factories.md +500 -500
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-nfr/resources/knowledge/email-auth.md +721 -721
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-nfr/resources/knowledge/error-handling.md +725 -725
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-nfr/resources/knowledge/feature-flags.md +750 -750
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-nfr/resources/knowledge/file-utils.md +456 -456
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-nfr/resources/knowledge/fixture-architecture.md +401 -401
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-nfr/resources/knowledge/fixtures-composition.md +382 -382
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-nfr/resources/knowledge/intercept-network-call.md +426 -426
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-nfr/resources/knowledge/log.md +426 -426
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-nfr/resources/knowledge/network-error-monitor.md +401 -401
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-nfr/resources/knowledge/network-first.md +486 -486
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-nfr/resources/knowledge/network-recorder.md +527 -527
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-nfr/resources/knowledge/nfr-criteria.md +670 -670
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-nfr/resources/knowledge/overview.md +286 -286
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-nfr/resources/knowledge/pact-broker-webhooks.md +237 -237
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-nfr/resources/knowledge/pact-consumer-di.md +310 -310
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-nfr/resources/knowledge/pact-consumer-framework-setup.md +757 -757
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-nfr/resources/knowledge/pact-mcp.md +205 -205
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-nfr/resources/knowledge/pactjs-utils-consumer-helpers.md +380 -380
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-nfr/resources/knowledge/pactjs-utils-overview.md +216 -216
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-nfr/resources/knowledge/pactjs-utils-provider-verifier.md +397 -397
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-nfr/resources/knowledge/pactjs-utils-request-filter.md +224 -224
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-nfr/resources/knowledge/playwright-cli.md +280 -280
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-nfr/resources/knowledge/playwright-config.md +734 -734
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-nfr/resources/knowledge/probability-impact.md +601 -601
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-nfr/resources/knowledge/recurse.md +421 -421
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-nfr/resources/knowledge/risk-governance.md +615 -615
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-nfr/resources/knowledge/selective-testing.md +732 -732
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-nfr/resources/knowledge/selector-resilience.md +527 -527
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-nfr/resources/knowledge/test-healing-patterns.md +644 -644
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-nfr/resources/knowledge/test-levels-framework.md +473 -473
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-nfr/resources/knowledge/test-priorities-matrix.md +373 -373
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-nfr/resources/knowledge/test-quality.md +664 -664
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-nfr/resources/knowledge/timing-debugging.md +372 -372
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-nfr/resources/knowledge/visual-debugging.md +527 -527
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-nfr/resources/knowledge/webhook-module-setup.md +122 -122
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-nfr/resources/knowledge/webhook-providers.md +155 -155
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-nfr/resources/knowledge/webhook-risk-guidance.md +114 -114
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-nfr/resources/knowledge/webhook-template-matchers.md +160 -160
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-nfr/resources/knowledge/webhook-testing-fundamentals.md +42 -42
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-nfr/resources/knowledge/webhook-timeout-error.md +130 -130
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-nfr/resources/knowledge/webhook-waiting-querying.md +167 -167
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-nfr/resources/tea-index.csv +51 -51
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-nfr/steps-c/step-01-load-context.md +138 -138
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-nfr/steps-c/step-01b-resume.md +106 -106
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-nfr/steps-c/step-02-define-thresholds.md +107 -107
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-nfr/steps-c/step-03-gather-evidence.md +108 -108
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-nfr/steps-c/step-04-evaluate-and-score.md +254 -254
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-nfr/steps-c/step-04a-subagent-security.md +138 -138
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-nfr/steps-c/step-04b-subagent-performance.md +84 -84
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-nfr/steps-c/step-04c-subagent-reliability.md +85 -85
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-nfr/steps-c/step-04d-subagent-scalability.md +88 -88
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-nfr/steps-c/step-04e-aggregate-nfr.md +264 -264
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-nfr/steps-c/step-05-generate-report.md +116 -116
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-nfr/steps-e/step-01-assess.md +65 -65
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-nfr/steps-e/step-02-apply-edit.md +68 -68
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-nfr/steps-v/step-01-validate.md +75 -75
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-nfr/validation-report-20260127-095021.md +73 -73
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-nfr/validation-report-20260127-102401.md +116 -116
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-nfr/workflow-plan.md +19 -19
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-nfr/workflow.yaml +48 -48
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-design/SKILL.md +87 -87
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-design/checklist.md +464 -464
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-design/customize.toml +40 -40
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-design/instructions.md +104 -104
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-design/resources/knowledge/adr-quality-readiness-checklist.md +377 -377
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-design/resources/knowledge/api-request.md +563 -563
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-design/resources/knowledge/api-testing-patterns.md +915 -915
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-design/resources/knowledge/auth-session.md +548 -548
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-design/resources/knowledge/burn-in.md +273 -273
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-design/resources/knowledge/ci-burn-in.md +717 -717
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-design/resources/knowledge/component-tdd.md +486 -486
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-design/resources/knowledge/contract-testing.md +1066 -1066
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-design/resources/knowledge/data-factories.md +500 -500
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-design/resources/knowledge/email-auth.md +721 -721
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-design/resources/knowledge/error-handling.md +725 -725
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-design/resources/knowledge/feature-flags.md +750 -750
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-design/resources/knowledge/file-utils.md +456 -456
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-design/resources/knowledge/fixture-architecture.md +401 -401
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-design/resources/knowledge/fixtures-composition.md +382 -382
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-design/resources/knowledge/intercept-network-call.md +426 -426
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-design/resources/knowledge/log.md +426 -426
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-design/resources/knowledge/network-error-monitor.md +401 -401
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-design/resources/knowledge/network-first.md +486 -486
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-design/resources/knowledge/network-recorder.md +527 -527
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-design/resources/knowledge/nfr-criteria.md +670 -670
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-design/resources/knowledge/overview.md +286 -286
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-design/resources/knowledge/pact-broker-webhooks.md +237 -237
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-design/resources/knowledge/pact-consumer-di.md +310 -310
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-design/resources/knowledge/pact-consumer-framework-setup.md +757 -757
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-design/resources/knowledge/pact-mcp.md +205 -205
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-design/resources/knowledge/pactjs-utils-consumer-helpers.md +380 -380
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-design/resources/knowledge/pactjs-utils-overview.md +216 -216
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-design/resources/knowledge/pactjs-utils-provider-verifier.md +397 -397
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-design/resources/knowledge/pactjs-utils-request-filter.md +224 -224
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-design/resources/knowledge/playwright-cli.md +280 -280
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-design/resources/knowledge/playwright-config.md +734 -734
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-design/resources/knowledge/probability-impact.md +601 -601
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-design/resources/knowledge/recurse.md +421 -421
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-design/resources/knowledge/risk-governance.md +615 -615
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-design/resources/knowledge/selective-testing.md +732 -732
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-design/resources/knowledge/selector-resilience.md +527 -527
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-design/resources/knowledge/test-healing-patterns.md +644 -644
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-design/resources/knowledge/test-levels-framework.md +473 -473
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-design/resources/knowledge/test-priorities-matrix.md +373 -373
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-design/resources/knowledge/test-quality.md +664 -664
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-design/resources/knowledge/timing-debugging.md +372 -372
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-design/resources/knowledge/visual-debugging.md +527 -527
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-design/resources/knowledge/webhook-module-setup.md +122 -122
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-design/resources/knowledge/webhook-providers.md +155 -155
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-design/resources/knowledge/webhook-risk-guidance.md +114 -114
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-design/resources/knowledge/webhook-template-matchers.md +160 -160
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-design/resources/knowledge/webhook-testing-fundamentals.md +42 -42
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-design/resources/knowledge/webhook-timeout-error.md +130 -130
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-design/resources/knowledge/webhook-waiting-querying.md +167 -167
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-design/resources/tea-index.csv +51 -51
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-design/steps-c/step-01-detect-mode.md +140 -140
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-design/steps-c/step-01b-resume.md +116 -116
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-design/steps-c/step-02-load-context.md +248 -248
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-design/steps-c/step-03-risk-and-testability.md +116 -116
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-design/steps-c/step-04-coverage-plan.md +129 -129
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-design/steps-c/step-05-generate-output.md +236 -236
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-design/steps-e/step-01-assess.md +65 -65
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-design/steps-e/step-02-apply-edit.md +68 -68
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-design/steps-v/step-01-validate.md +75 -75
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-design/test-design-architecture-template.md +233 -233
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-design/test-design-handoff-template.md +70 -70
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-design/test-design-qa-template.md +399 -399
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-design/test-design-template.md +347 -347
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-design/validation-report-20260127-095021.md +73 -73
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-design/validation-report-20260127-102401.md +116 -116
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-design/workflow-plan.md +22 -22
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-design/workflow.yaml +77 -77
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-review/SKILL.md +85 -85
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-review/checklist.md +475 -475
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-review/customize.toml +40 -40
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-review/instructions.md +45 -45
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-review/resources/knowledge/adr-quality-readiness-checklist.md +377 -377
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-review/resources/knowledge/api-request.md +563 -563
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-review/resources/knowledge/api-testing-patterns.md +915 -915
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-review/resources/knowledge/auth-session.md +548 -548
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-review/resources/knowledge/burn-in.md +273 -273
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-review/resources/knowledge/ci-burn-in.md +717 -717
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-review/resources/knowledge/component-tdd.md +486 -486
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-review/resources/knowledge/contract-testing.md +1066 -1066
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-review/resources/knowledge/data-factories.md +500 -500
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-review/resources/knowledge/email-auth.md +721 -721
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-review/resources/knowledge/error-handling.md +725 -725
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-review/resources/knowledge/feature-flags.md +750 -750
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-review/resources/knowledge/file-utils.md +456 -456
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-review/resources/knowledge/fixture-architecture.md +401 -401
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-review/resources/knowledge/fixtures-composition.md +382 -382
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-review/resources/knowledge/intercept-network-call.md +426 -426
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-review/resources/knowledge/log.md +426 -426
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-review/resources/knowledge/network-error-monitor.md +401 -401
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-review/resources/knowledge/network-first.md +486 -486
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-review/resources/knowledge/network-recorder.md +527 -527
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-review/resources/knowledge/nfr-criteria.md +670 -670
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-review/resources/knowledge/overview.md +286 -286
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-review/resources/knowledge/pact-broker-webhooks.md +237 -237
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-review/resources/knowledge/pact-consumer-di.md +310 -310
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-review/resources/knowledge/pact-consumer-framework-setup.md +757 -757
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-review/resources/knowledge/pact-mcp.md +205 -205
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-review/resources/knowledge/pactjs-utils-consumer-helpers.md +380 -380
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-review/resources/knowledge/pactjs-utils-overview.md +216 -216
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-review/resources/knowledge/pactjs-utils-provider-verifier.md +397 -397
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-review/resources/knowledge/pactjs-utils-request-filter.md +224 -224
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-review/resources/knowledge/playwright-cli.md +280 -280
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-review/resources/knowledge/playwright-config.md +734 -734
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-review/resources/knowledge/probability-impact.md +601 -601
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-review/resources/knowledge/recurse.md +421 -421
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-review/resources/knowledge/risk-governance.md +615 -615
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-review/resources/knowledge/selective-testing.md +732 -732
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-review/resources/knowledge/selector-resilience.md +527 -527
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-review/resources/knowledge/test-healing-patterns.md +644 -644
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-review/resources/knowledge/test-levels-framework.md +473 -473
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-review/resources/knowledge/test-priorities-matrix.md +373 -373
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-review/resources/knowledge/test-quality.md +664 -664
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-review/resources/knowledge/timing-debugging.md +372 -372
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-review/resources/knowledge/visual-debugging.md +527 -527
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-review/resources/knowledge/webhook-module-setup.md +122 -122
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-review/resources/knowledge/webhook-providers.md +155 -155
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-review/resources/knowledge/webhook-risk-guidance.md +114 -114
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-review/resources/knowledge/webhook-template-matchers.md +160 -160
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-review/resources/knowledge/webhook-testing-fundamentals.md +42 -42
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-review/resources/knowledge/webhook-timeout-error.md +130 -130
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-review/resources/knowledge/webhook-waiting-querying.md +167 -167
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-review/resources/tea-index.csv +51 -51
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-review/steps-c/step-01-load-context.md +197 -197
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-review/steps-c/step-01b-resume.md +104 -104
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-review/steps-c/step-02-discover-tests.md +120 -120
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-review/steps-c/step-03-quality-evaluation.md +274 -274
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-review/steps-c/step-03a-subagent-determinism.md +257 -257
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-review/steps-c/step-03b-subagent-isolation.md +125 -125
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-review/steps-c/step-03c-subagent-maintainability.md +102 -102
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-review/steps-c/step-03e-subagent-performance.md +117 -117
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-review/steps-c/step-03f-aggregate-scores.md +277 -277
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-review/steps-c/step-04-generate-report.md +119 -119
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-review/steps-e/step-01-assess.md +65 -65
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-review/steps-e/step-02-apply-edit.md +68 -68
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-review/steps-v/step-01-validate.md +75 -75
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-review/test-review-template.md +387 -387
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-review/validation-report-20260127-095021.md +72 -72
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-review/validation-report-20260127-102401.md +114 -114
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-review/workflow-plan.md +18 -18
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-review/workflow.yaml +48 -48
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-trace/SKILL.md +87 -87
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-trace/checklist.md +671 -671
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-trace/customize.toml +40 -40
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-trace/instructions.md +45 -45
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-trace/resources/knowledge/adr-quality-readiness-checklist.md +377 -377
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-trace/resources/knowledge/api-request.md +563 -563
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-trace/resources/knowledge/api-testing-patterns.md +915 -915
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-trace/resources/knowledge/auth-session.md +548 -548
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-trace/resources/knowledge/burn-in.md +273 -273
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-trace/resources/knowledge/ci-burn-in.md +717 -717
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-trace/resources/knowledge/component-tdd.md +486 -486
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-trace/resources/knowledge/contract-testing.md +1066 -1066
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-trace/resources/knowledge/data-factories.md +500 -500
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-trace/resources/knowledge/email-auth.md +721 -721
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-trace/resources/knowledge/error-handling.md +725 -725
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-trace/resources/knowledge/feature-flags.md +750 -750
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-trace/resources/knowledge/file-utils.md +456 -456
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-trace/resources/knowledge/fixture-architecture.md +401 -401
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-trace/resources/knowledge/fixtures-composition.md +382 -382
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-trace/resources/knowledge/intercept-network-call.md +426 -426
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-trace/resources/knowledge/log.md +426 -426
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-trace/resources/knowledge/network-error-monitor.md +401 -401
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-trace/resources/knowledge/network-first.md +486 -486
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-trace/resources/knowledge/network-recorder.md +527 -527
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-trace/resources/knowledge/nfr-criteria.md +670 -670
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-trace/resources/knowledge/overview.md +286 -286
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-trace/resources/knowledge/pact-broker-webhooks.md +237 -237
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-trace/resources/knowledge/pact-consumer-di.md +310 -310
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-trace/resources/knowledge/pact-consumer-framework-setup.md +757 -757
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-trace/resources/knowledge/pact-mcp.md +205 -205
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-trace/resources/knowledge/pactjs-utils-consumer-helpers.md +380 -380
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-trace/resources/knowledge/pactjs-utils-overview.md +216 -216
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-trace/resources/knowledge/pactjs-utils-provider-verifier.md +397 -397
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-trace/resources/knowledge/pactjs-utils-request-filter.md +224 -224
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-trace/resources/knowledge/playwright-cli.md +280 -280
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-trace/resources/knowledge/playwright-config.md +734 -734
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-trace/resources/knowledge/probability-impact.md +601 -601
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-trace/resources/knowledge/recurse.md +421 -421
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-trace/resources/knowledge/risk-governance.md +615 -615
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-trace/resources/knowledge/selective-testing.md +732 -732
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-trace/resources/knowledge/selector-resilience.md +527 -527
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-trace/resources/knowledge/test-healing-patterns.md +644 -644
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-trace/resources/knowledge/test-levels-framework.md +473 -473
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-trace/resources/knowledge/test-priorities-matrix.md +373 -373
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-trace/resources/knowledge/test-quality.md +664 -664
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-trace/resources/knowledge/timing-debugging.md +372 -372
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-trace/resources/knowledge/visual-debugging.md +527 -527
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-trace/resources/knowledge/webhook-module-setup.md +122 -122
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-trace/resources/knowledge/webhook-providers.md +155 -155
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-trace/resources/knowledge/webhook-risk-guidance.md +114 -114
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-trace/resources/knowledge/webhook-template-matchers.md +160 -160
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-trace/resources/knowledge/webhook-testing-fundamentals.md +42 -42
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-trace/resources/knowledge/webhook-timeout-error.md +130 -130
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-trace/resources/knowledge/webhook-waiting-querying.md +167 -167
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-trace/resources/tea-index.csv +51 -51
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-trace/steps-c/step-01-load-context.md +166 -166
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-trace/steps-c/step-01b-resume.md +102 -102
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-trace/steps-c/step-02-discover-tests.md +132 -132
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-trace/steps-c/step-03-map-criteria.md +101 -101
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-trace/steps-c/step-04-analyze-gaps.md +628 -628
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-trace/steps-c/step-05-gate-decision.md +681 -681
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-trace/steps-e/step-01-assess.md +65 -65
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-trace/steps-e/step-02-apply-edit.md +68 -68
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-trace/steps-v/step-01-validate.md +75 -75
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-trace/trace-template.md +716 -716
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-trace/validation-report-20260127-095021.md +73 -73
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-trace/validation-report-20260127-102401.md +116 -116
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-trace/workflow-plan.md +24 -24
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-trace/workflow.yaml +80 -80
- package/lib/bmad-cache/tea/test/README.md +23 -23
- package/lib/bmad-cache/tea/test/fixtures/agent-schema/invalid/critical-actions/actions-as-string.agent.yaml +27 -27
- package/lib/bmad-cache/tea/test/fixtures/agent-schema/invalid/critical-actions/empty-string-in-actions.agent.yaml +30 -30
- package/lib/bmad-cache/tea/test/fixtures/agent-schema/invalid/menu/empty-menu.agent.yaml +22 -22
- package/lib/bmad-cache/tea/test/fixtures/agent-schema/invalid/menu/missing-menu.agent.yaml +20 -20
- package/lib/bmad-cache/tea/test/fixtures/agent-schema/invalid/menu-commands/empty-command-target.agent.yaml +25 -25
- package/lib/bmad-cache/tea/test/fixtures/agent-schema/invalid/menu-commands/no-command-target.agent.yaml +24 -24
- package/lib/bmad-cache/tea/test/fixtures/agent-schema/invalid/menu-triggers/camel-case.agent.yaml +25 -25
- package/lib/bmad-cache/tea/test/fixtures/agent-schema/invalid/menu-triggers/compound-invalid-format.agent.yaml +25 -25
- package/lib/bmad-cache/tea/test/fixtures/agent-schema/invalid/menu-triggers/compound-mismatched-kebab.agent.yaml +25 -25
- package/lib/bmad-cache/tea/test/fixtures/agent-schema/invalid/menu-triggers/duplicate-triggers.agent.yaml +31 -31
- package/lib/bmad-cache/tea/test/fixtures/agent-schema/invalid/menu-triggers/empty-trigger.agent.yaml +25 -25
- package/lib/bmad-cache/tea/test/fixtures/agent-schema/invalid/menu-triggers/leading-asterisk.agent.yaml +25 -25
- package/lib/bmad-cache/tea/test/fixtures/agent-schema/invalid/menu-triggers/snake-case.agent.yaml +25 -25
- package/lib/bmad-cache/tea/test/fixtures/agent-schema/invalid/menu-triggers/trigger-with-spaces.agent.yaml +25 -25
- package/lib/bmad-cache/tea/test/fixtures/agent-schema/invalid/metadata/empty-module-string.agent.yaml +26 -26
- package/lib/bmad-cache/tea/test/fixtures/agent-schema/invalid/metadata/empty-name.agent.yaml +24 -24
- package/lib/bmad-cache/tea/test/fixtures/agent-schema/invalid/metadata/extra-metadata-fields.agent.yaml +27 -27
- package/lib/bmad-cache/tea/test/fixtures/agent-schema/invalid/metadata/missing-id.agent.yaml +23 -23
- package/lib/bmad-cache/tea/test/fixtures/agent-schema/invalid/persona/empty-principles-array.agent.yaml +24 -24
- package/lib/bmad-cache/tea/test/fixtures/agent-schema/invalid/persona/empty-string-in-principles.agent.yaml +27 -27
- package/lib/bmad-cache/tea/test/fixtures/agent-schema/invalid/persona/extra-persona-fields.agent.yaml +27 -27
- package/lib/bmad-cache/tea/test/fixtures/agent-schema/invalid/persona/missing-role.agent.yaml +24 -24
- package/lib/bmad-cache/tea/test/fixtures/agent-schema/invalid/prompts/empty-content.agent.yaml +29 -29
- package/lib/bmad-cache/tea/test/fixtures/agent-schema/invalid/prompts/extra-prompt-fields.agent.yaml +31 -31
- package/lib/bmad-cache/tea/test/fixtures/agent-schema/invalid/prompts/missing-content.agent.yaml +28 -28
- package/lib/bmad-cache/tea/test/fixtures/agent-schema/invalid/prompts/missing-id.agent.yaml +28 -28
- package/lib/bmad-cache/tea/test/fixtures/agent-schema/invalid/top-level/empty-file.agent.yaml +5 -5
- package/lib/bmad-cache/tea/test/fixtures/agent-schema/invalid/top-level/extra-top-level-keys.agent.yaml +28 -28
- package/lib/bmad-cache/tea/test/fixtures/agent-schema/invalid/top-level/missing-agent-key.agent.yaml +11 -11
- package/lib/bmad-cache/tea/test/fixtures/agent-schema/invalid/yaml-errors/invalid-indentation.agent.yaml +19 -19
- package/lib/bmad-cache/tea/test/fixtures/agent-schema/invalid/yaml-errors/malformed-yaml.agent.yaml +18 -18
- package/lib/bmad-cache/tea/test/fixtures/agent-schema/valid/critical-actions/empty-critical-actions.agent.yaml +24 -24
- package/lib/bmad-cache/tea/test/fixtures/agent-schema/valid/critical-actions/no-critical-actions.agent.yaml +22 -22
- package/lib/bmad-cache/tea/test/fixtures/agent-schema/valid/critical-actions/valid-critical-actions.agent.yaml +27 -27
- package/lib/bmad-cache/tea/test/fixtures/agent-schema/valid/menu/multiple-menu-items.agent.yaml +31 -31
- package/lib/bmad-cache/tea/test/fixtures/agent-schema/valid/menu/single-menu-item.agent.yaml +22 -22
- package/lib/bmad-cache/tea/test/fixtures/agent-schema/valid/menu-commands/all-command-types.agent.yaml +37 -37
- package/lib/bmad-cache/tea/test/fixtures/agent-schema/valid/menu-commands/multiple-commands.agent.yaml +24 -24
- package/lib/bmad-cache/tea/test/fixtures/agent-schema/valid/menu-triggers/compound-triggers.agent.yaml +31 -31
- package/lib/bmad-cache/tea/test/fixtures/agent-schema/valid/menu-triggers/kebab-case-triggers.agent.yaml +34 -34
- package/lib/bmad-cache/tea/test/fixtures/agent-schema/valid/metadata/core-agent-with-module.agent.yaml +24 -24
- package/lib/bmad-cache/tea/test/fixtures/agent-schema/valid/metadata/empty-module-name-in-path.agent.yaml +24 -24
- package/lib/bmad-cache/tea/test/fixtures/agent-schema/valid/metadata/malformed-path-treated-as-core.agent.yaml +24 -24
- package/lib/bmad-cache/tea/test/fixtures/agent-schema/valid/metadata/module-agent-correct.agent.yaml +24 -24
- package/lib/bmad-cache/tea/test/fixtures/agent-schema/valid/metadata/module-agent-missing-module.agent.yaml +23 -23
- package/lib/bmad-cache/tea/test/fixtures/agent-schema/valid/metadata/wrong-module-value.agent.yaml +24 -24
- package/lib/bmad-cache/tea/test/fixtures/agent-schema/valid/persona/complete-persona.agent.yaml +24 -24
- package/lib/bmad-cache/tea/test/fixtures/agent-schema/valid/prompts/empty-prompts.agent.yaml +24 -24
- package/lib/bmad-cache/tea/test/fixtures/agent-schema/valid/prompts/no-prompts.agent.yaml +22 -22
- package/lib/bmad-cache/tea/test/fixtures/agent-schema/valid/prompts/valid-prompts-minimal.agent.yaml +28 -28
- package/lib/bmad-cache/tea/test/fixtures/agent-schema/valid/prompts/valid-prompts-with-description.agent.yaml +30 -30
- package/lib/bmad-cache/tea/test/fixtures/agent-schema/valid/top-level/minimal-core-agent.agent.yaml +24 -24
- package/lib/bmad-cache/tea/test/schema/agent.js +491 -491
- package/lib/bmad-cache/tea/test/test-agent-schema.js +387 -387
- package/lib/bmad-cache/tea/test/test-installation-components.js +422 -422
- package/lib/bmad-cache/tea/test/test-knowledge-base.js +213 -213
- package/lib/bmad-cache/tea/test/test-release-metadata.js +71 -71
- package/lib/bmad-cache/tea/test/unit-test-schema.js +133 -133
- package/lib/bmad-cache/tea/test/validate-agent-schema.js +110 -110
- package/lib/bmad-cache/tea/tools/build-docs.js +575 -575
- package/lib/bmad-cache/tea/tools/fix-doc-links.js +288 -288
- package/lib/bmad-cache/tea/tools/schema/agent.js +491 -491
- package/lib/bmad-cache/tea/tools/validate-agent-schema.js +284 -284
- package/lib/bmad-cache/tea/tools/validate-doc-links.js +371 -371
- package/lib/bmad-cache/tea/tools/validate-tea-workflow-descriptions.js +122 -122
- package/lib/bmad-cache/tea/tools/verify-paths.js +100 -100
- package/lib/bmad-cache/tea/website/README.md +137 -137
- package/lib/bmad-cache/tea/website/astro.config.mjs +183 -183
- package/lib/bmad-cache/tea/website/package-lock.json +6856 -6856
- package/lib/bmad-cache/tea/website/package.json +24 -24
- package/lib/bmad-cache/tea/website/public/img/tea-logo.svg +7 -7
- package/lib/bmad-cache/tea/website/public/robots.txt +37 -37
- package/lib/bmad-cache/tea/website/src/components/Banner.astro +74 -74
- package/lib/bmad-cache/tea/website/src/components/Header.astro +121 -121
- package/lib/bmad-cache/tea/website/src/components/MobileMenuFooter.astro +53 -53
- package/lib/bmad-cache/tea/website/src/content/config.ts +6 -6
- package/lib/bmad-cache/tea/website/src/lib/site-url.js +25 -25
- package/lib/bmad-cache/tea/website/src/pages/404.astro +11 -11
- package/lib/bmad-cache/tea/website/src/rehype-base-paths.js +89 -89
- package/lib/bmad-cache/tea/website/src/rehype-markdown-links.js +117 -117
- package/lib/bmad-cache/tea/website/src/styles/custom.css +518 -518
- package/lib/bmad-cache/tea/website/tsconfig.json +9 -9
- package/lib/bmad-cache/wds/.claude-plugin/marketplace.json +35 -35
- package/lib/bmad-cache/wds/.markdownlint-cli2.yaml +38 -38
- package/lib/bmad-cache/wds/.prettierignore +9 -9
- package/lib/bmad-cache/wds/LICENSE +27 -27
- package/lib/bmad-cache/wds/README.md +139 -139
- package/lib/bmad-cache/wds/_git_preserved/HEAD +1 -1
- package/lib/bmad-cache/wds/_git_preserved/config +13 -13
- package/lib/bmad-cache/wds/_git_preserved/description +1 -1
- package/lib/bmad-cache/wds/_git_preserved/hooks/applypatch-msg.sample +15 -15
- package/lib/bmad-cache/wds/_git_preserved/hooks/commit-msg.sample +24 -24
- package/lib/bmad-cache/wds/_git_preserved/hooks/fsmonitor-watchman.sample +174 -174
- package/lib/bmad-cache/wds/_git_preserved/hooks/post-update.sample +8 -8
- package/lib/bmad-cache/wds/_git_preserved/hooks/pre-applypatch.sample +14 -14
- package/lib/bmad-cache/wds/_git_preserved/hooks/pre-commit.sample +49 -49
- package/lib/bmad-cache/wds/_git_preserved/hooks/pre-merge-commit.sample +13 -13
- package/lib/bmad-cache/wds/_git_preserved/hooks/pre-push.sample +53 -53
- package/lib/bmad-cache/wds/_git_preserved/hooks/pre-rebase.sample +169 -169
- package/lib/bmad-cache/wds/_git_preserved/hooks/pre-receive.sample +24 -24
- package/lib/bmad-cache/wds/_git_preserved/hooks/prepare-commit-msg.sample +42 -42
- package/lib/bmad-cache/wds/_git_preserved/hooks/push-to-checkout.sample +78 -78
- package/lib/bmad-cache/wds/_git_preserved/hooks/sendemail-validate.sample +77 -77
- package/lib/bmad-cache/wds/_git_preserved/hooks/update.sample +128 -128
- package/lib/bmad-cache/wds/_git_preserved/info/exclude +6 -6
- package/lib/bmad-cache/wds/_git_preserved/packed-refs +2 -2
- package/lib/bmad-cache/wds/_git_preserved/refs/heads/main +1 -1
- package/lib/bmad-cache/wds/_git_preserved/refs/remotes/origin/HEAD +1 -1
- package/lib/bmad-cache/wds/_git_preserved/shallow +1 -1
- package/lib/bmad-cache/wds/eslint.config.mjs +152 -152
- package/lib/bmad-cache/wds/package.json +82 -82
- package/lib/bmad-cache/wds/prettier.config.mjs +32 -32
- package/lib/bmad-cache/wds/src/agents/wds-agent-freya-ux/bmad-skill-manifest.yaml +12 -12
- package/lib/bmad-cache/wds/src/agents/wds-agent-saga-analyst/bmad-skill-manifest.yaml +12 -12
- package/lib/bmad-cache/wds/src/module-help.csv +19 -19
- package/lib/bmad-cache/wds/src/module.yaml +145 -145
- package/lib/bmad-cache/wds/src/workflows/wds-0-alignment-signoff/bmad-skill-manifest.yaml +1 -1
- package/lib/bmad-cache/wds/src/workflows/wds-0-project-setup/bmad-skill-manifest.yaml +1 -1
- package/lib/bmad-cache/wds/src/workflows/wds-0-project-setup/resources/wds-1-project-brief/templates/platform-requirements.template.yaml +69 -69
- package/lib/bmad-cache/wds/src/workflows/wds-0-project-setup/resources/wds-7-design-system/templates/catalog.template.html +363 -363
- package/lib/bmad-cache/wds/src/workflows/wds-1-project-brief/bmad-skill-manifest.yaml +1 -1
- package/lib/bmad-cache/wds/src/workflows/wds-1-project-brief/templates/platform-requirements.template.yaml +69 -69
- package/lib/bmad-cache/wds/src/workflows/wds-2-trigger-mapping/bmad-skill-manifest.yaml +1 -1
- package/lib/bmad-cache/wds/src/workflows/wds-3-scenarios/bmad-skill-manifest.yaml +1 -1
- package/lib/bmad-cache/wds/src/workflows/wds-4-ux-design/bmad-skill-manifest.yaml +1 -1
- package/lib/bmad-cache/wds/src/workflows/wds-4-ux-design/templates/design-delivery.template.yaml +104 -104
- package/lib/bmad-cache/wds/src/workflows/wds-4-ux-design/templates/test-scenario.template.yaml +192 -192
- package/lib/bmad-cache/wds/src/workflows/wds-5-agentic-development/bmad-skill-manifest.yaml +1 -1
- package/lib/bmad-cache/wds/src/workflows/wds-5-agentic-development/templates/components/dev-mode.css +164 -164
- package/lib/bmad-cache/wds/src/workflows/wds-5-agentic-development/templates/components/dev-mode.html +18 -18
- package/lib/bmad-cache/wds/src/workflows/wds-5-agentic-development/templates/components/dev-mode.js +430 -430
- package/lib/bmad-cache/wds/src/workflows/wds-5-agentic-development/templates/demo-data-template.json +63 -63
- package/lib/bmad-cache/wds/src/workflows/wds-5-agentic-development/templates/page-template.html +465 -465
- package/lib/bmad-cache/wds/src/workflows/wds-5-agentic-development/templates/work-file-template.yaml +264 -264
- package/lib/bmad-cache/wds/src/workflows/wds-6-asset-generation/bmad-skill-manifest.yaml +1 -1
- package/lib/bmad-cache/wds/src/workflows/wds-7-design-system/bmad-skill-manifest.yaml +1 -1
- package/lib/bmad-cache/wds/src/workflows/wds-7-design-system/templates/catalog.template.html +363 -363
- package/lib/bmad-cache/wds/src/workflows/wds-8-product-evolution/bmad-skill-manifest.yaml +1 -1
- package/lib/bmad-customize/bmm-analyst.customize.yaml +8 -8
- package/lib/bmad-customize/bmm-architect.customize.yaml +8 -8
- package/lib/bmad-customize/bmm-bmad-master.customize.yaml +6 -6
- package/lib/bmad-customize/bmm-dev.customize.yaml +8 -8
- package/lib/bmad-customize/bmm-pm.customize.yaml +8 -8
- package/lib/bmad-customize/bmm-qa.customize.yaml +26 -26
- package/lib/bmad-customize/bmm-sm.customize.yaml +8 -8
- package/lib/bmad-customize/bmm-tech-writer.customize.yaml +8 -8
- package/lib/bmad-customize/bmm-ux-designer.customize.yaml +8 -8
- package/lib/bmad-extension-plugin/.claude-plugin/marketplace.json +1 -1
- package/lib/bmad.js +191 -1
- package/lib/installer.js +2024 -2024
- package/lib/merge/roomodes.js +125 -125
- package/lib/methodology/version.json +7 -7
- package/lib/mil498-templates/OCD.md +169 -169
- package/lib/mil498-templates/README.md +4 -4
- package/lib/mil498-templates/SDD.md +163 -163
- package/lib/mil498-templates/SDP.md +307 -307
- package/lib/mil498-templates/SRS.md +219 -219
- package/lib/mil498-templates/SSDD.md +154 -154
- package/lib/mil498-templates/SSS.md +225 -225
- package/lib/mil498-templates/STD.md +188 -188
- package/lib/profile.js +130 -130
- package/lib/reconfigure.js +334 -334
- package/lib/skill-authoring.js +732 -732
- package/lib/templates/agents-md.template.md +67 -67
- package/lib/templates/clinerules.template.md +13 -13
- package/lib/templates/instruction-block-onprem.template.md +86 -86
- package/lib/templates/instruction-block-universal.template.md +29 -29
- package/lib/templates/project-context.template.md +47 -47
- package/lib/templates/roomodes.template.yaml +96 -96
- package/lib/uninstall.js +314 -314
- package/lib/warning-filter.js +245 -245
- package/mil498/OCD.md +169 -169
- package/mil498/README.md +4 -4
- package/mil498/SDP.md +307 -307
- package/mil498/SRS.md +219 -219
- package/mil498/SSDD.md +154 -154
- package/mil498/SSS.md +225 -225
- package/mil498/STD.md +188 -188
- package/package.json +57 -57
- package/scripts/build-bmad-cache.js +494 -494
- package/skills/README.md +473 -473
- package/skills/add-sprint/SKILL.md +204 -204
- package/skills/add-sprint/skill.json +7 -7
- package/skills/add-to-sprint/SKILL.md +270 -270
- package/skills/add-to-sprint/skill.json +7 -7
- package/skills/ai-audit-trail/SKILL.md +19 -19
- package/skills/ai-audit-trail/skill.json +20 -20
- package/skills/auto-bug-detection/SKILL.md +165 -165
- package/skills/auto-bug-detection/skill.json +8 -8
- package/skills/bmad-sprint-planning/SKILL.md +362 -362
- package/skills/bmad-sprint-planning/skill.json +7 -7
- package/skills/bmad-sprint-status/SKILL.md +312 -312
- package/skills/bmad-sprint-status/skill.json +7 -7
- package/skills/cleanup-done/SKILL.md +242 -242
- package/skills/cleanup-done/skill.json +7 -7
- package/skills/close-sprint/SKILL.md +409 -409
- package/skills/close-sprint/skill.json +7 -7
- package/skills/code-review/SKILL.md +79 -79
- package/skills/code-review/claude-code.md +64 -64
- package/skills/code-review/cline.md +55 -55
- package/skills/code-review/generic.md +39 -39
- package/skills/code-review/skill.json +7 -7
- package/skills/commit-message/SKILL.md +75 -75
- package/skills/commit-message/generic.md +75 -75
- package/skills/commit-message/skill.json +7 -7
- package/skills/cpp-best-practices/SKILL.md +230 -230
- package/skills/cpp-best-practices/examples/modern-idioms.md +189 -189
- package/skills/cpp-best-practices/examples/naming-and-organization.md +102 -102
- package/skills/cpp-best-practices/skill.json +25 -25
- package/skills/create-hardened-docker-skill/README.md +85 -85
- package/skills/create-hardened-docker-skill/SKILL.md +633 -633
- package/skills/create-hardened-docker-skill/scripts/create-all.sh +489 -489
- package/skills/create-hardened-docker-skill/skill.json +7 -7
- package/skills/csharp-best-practices/SKILL.md +274 -274
- package/skills/csharp-best-practices/skill.json +23 -23
- package/skills/docker-hardening-verification/scripts/verify-hardening.sh +39 -39
- package/skills/docker-image-signing/scripts/sign-image.sh +33 -33
- package/skills/document-revision-history/SKILL.md +100 -100
- package/skills/document-revision-history/skill.json +18 -18
- package/skills/generate-backlog/SKILL.md +219 -219
- package/skills/generate-backlog/skill.json +7 -7
- package/skills/git-workflow-skill/README.md +135 -135
- package/skills/git-workflow-skill/SKILL.md +190 -190
- package/skills/git-workflow-skill/hooks/commit-msg +61 -61
- package/skills/git-workflow-skill/hooks/pre-commit +38 -38
- package/skills/git-workflow-skill/hooks/prepare-commit-msg +56 -56
- package/skills/git-workflow-skill/scripts/finish-feature.sh +192 -192
- package/skills/git-workflow-skill/scripts/install-hooks.sh +55 -55
- package/skills/git-workflow-skill/scripts/start-feature.sh +110 -110
- package/skills/git-workflow-skill/scripts/validate-workflow.sh +229 -229
- package/skills/git-workflow-skill/skill.json +21 -21
- package/skills/js-ts-security-skill/scripts/verify-security.sh +136 -136
- package/skills/js-ts-security-skill/skill.json +17 -17
- package/skills/modify-sprint/SKILL.md +341 -341
- package/skills/modify-sprint/skill.json +7 -7
- package/skills/open-presentation/SKILL.md +31 -31
- package/skills/open-presentation/skill.json +11 -11
- package/skills/prioritize-backlog/SKILL.md +242 -242
- package/skills/prioritize-backlog/skill.json +7 -7
- package/skills/python-best-practices/SKILL.md +381 -381
- package/skills/python-best-practices/skill.json +26 -26
- package/skills/remove-from-sprint/SKILL.md +213 -213
- package/skills/remove-from-sprint/skill.json +7 -7
- package/skills/self-signed-cert/scripts/generate-cert.sh +43 -43
- package/skills/skill-creator/SKILL.md +211 -211
- package/skills/skill-creator/claude-code.md +64 -64
- package/skills/skill-creator/generic.md +192 -192
- package/skills/skill-creator/references/output-patterns.md +82 -82
- package/skills/skill-creator/references/workflows.md +28 -28
- package/skills/skill-creator/scripts/init_skill.py +208 -208
- package/skills/skill-creator/scripts/package_skill.py +99 -99
- package/skills/skill-creator/scripts/quick_validate.py +113 -113
- package/skills/skill-creator/skill.json +8 -8
- package/skills/sprint-status-view/SKILL.md +212 -212
- package/skills/sprint-status-view/skill.json +7 -7
- package/skills/story-status-lookup/SKILL.md +106 -106
- package/skills/story-status-lookup/skill.json +8 -8
- package/skills/test-generator/SKILL.md +74 -74
- package/skills/test-generator/claude-code.md +103 -103
- package/skills/test-generator/cline.md +69 -69
- package/skills/test-generator/generic.md +61 -61
- package/skills/test-generator/skill.json +18 -18
- package/skills/vercel-react-best-practices/SKILL.md +105 -105
- package/skills/vercel-react-best-practices/claude-code.md +80 -80
- package/skills/vercel-react-best-practices/generic.md +105 -105
- package/skills/vercel-react-best-practices/skill.json +19 -19
- package/skills/verify-hardened-docker-skill/README.md +85 -85
- package/skills/verify-hardened-docker-skill/SKILL.md +438 -438
- package/skills/verify-hardened-docker-skill/scripts/verify-docker-hardening.sh +439 -439
- package/skills/verify-hardened-docker-skill/skill.json +7 -7
- package/lib/.bmad-extension-plugin.build-1264-1777348888201/.claude-plugin/marketplace.json +0 -109
- package/lib/.bmad-extension-plugin.build-1264-1777348888201/skills/module-help.csv +0 -62
- package/lib/.bmad-extension-plugin.build-1264-1777348888201/skills/module.yaml +0 -20
- package/lib/.bmad-extension-plugin.build-24696-1777348768444/.claude-plugin/marketplace.json +0 -109
- package/lib/.bmad-extension-plugin.build-24696-1777348768444/skills/module-help.csv +0 -62
- package/lib/.bmad-extension-plugin.build-24696-1777348768444/skills/module.yaml +0 -20
- package/lib/.bmad-extension-plugin.build-25428-1777348694953/.claude-plugin/marketplace.json +0 -109
- package/lib/.bmad-extension-plugin.build-25428-1777348694953/skills/module-help.csv +0 -62
- package/lib/.bmad-extension-plugin.build-25428-1777348694953/skills/module.yaml +0 -20
- package/lib/bmad-cache/bmb/_git_preserved/logs/HEAD +0 -1
- package/lib/bmad-cache/bmb/_git_preserved/logs/refs/heads/main +0 -1
- package/lib/bmad-cache/bmb/_git_preserved/logs/refs/remotes/origin/HEAD +0 -1
- package/lib/bmad-cache/cis/_git_preserved/logs/HEAD +0 -1
- package/lib/bmad-cache/cis/_git_preserved/logs/refs/heads/main +0 -1
- package/lib/bmad-cache/cis/_git_preserved/logs/refs/remotes/origin/HEAD +0 -1
- package/lib/bmad-cache/gds/_git_preserved/logs/HEAD +0 -1
- package/lib/bmad-cache/gds/_git_preserved/logs/refs/heads/main +0 -1
- package/lib/bmad-cache/gds/_git_preserved/logs/refs/remotes/origin/HEAD +0 -1
- package/lib/bmad-cache/tea/.github/workflows/publish.yaml +0 -168
- package/lib/bmad-cache/tea/.vscode/settings.json +0 -47
- package/lib/bmad-cache/wds/_git_preserved/logs/HEAD +0 -1
- package/lib/bmad-cache/wds/_git_preserved/logs/refs/heads/main +0 -1
- package/lib/bmad-cache/wds/_git_preserved/logs/refs/remotes/origin/HEAD +0 -1
|
@@ -1,757 +1,757 @@
|
|
|
1
|
-
# Pact Consumer CDC — Framework Setup
|
|
2
|
-
|
|
3
|
-
## Principle
|
|
4
|
-
|
|
5
|
-
When scaffolding a Pact.js consumer contract testing framework, align every artifact — directory layout, vitest config, package.json scripts, shell scripts, CI workflow, and test files — with the canonical `@seontechnologies/pactjs-utils` conventions. Consistency across repositories eliminates onboarding friction and ensures CI pipelines are copy-paste portable.
|
|
6
|
-
|
|
7
|
-
## Rationale
|
|
8
|
-
|
|
9
|
-
The TEA framework workflow generates scaffolding for consumer-driven contract (CDC) testing. Without opinionated, battle-tested conventions, each project invents its own structure — different script names, different env var patterns, different CI step ordering — making cross-repo maintenance expensive. This fragment codifies the production-proven patterns from the pactjs-utils reference implementation so that every new project starts correctly.
|
|
10
|
-
|
|
11
|
-
## Pattern Examples
|
|
12
|
-
|
|
13
|
-
### Example 1: Directory Structure & File Naming
|
|
14
|
-
|
|
15
|
-
**Context**: Consumer contract test project layout using pactjs-utils conventions.
|
|
16
|
-
|
|
17
|
-
**Implementation**:
|
|
18
|
-
|
|
19
|
-
```
|
|
20
|
-
tests/contract/
|
|
21
|
-
├── consumer/
|
|
22
|
-
│ ├── get-filter-fields.pacttest.ts # Consumer test (one per endpoint group)
|
|
23
|
-
│ ├── filter-transactions.pacttest.ts
|
|
24
|
-
│ └── get-transaction-stats.pacttest.ts
|
|
25
|
-
└── support/
|
|
26
|
-
├── pact-config.ts # PactV4 factory (consumer/provider names, output dir)
|
|
27
|
-
├── provider-states.ts # Provider state factory functions
|
|
28
|
-
└── consumer-helpers.ts # Local shim (until pactjs-utils is published)
|
|
29
|
-
|
|
30
|
-
scripts/
|
|
31
|
-
├── env-setup.sh # Shared env loader (sourced by all broker scripts)
|
|
32
|
-
├── publish-pact.sh # Publish pact files to broker
|
|
33
|
-
├── can-i-deploy.sh # Deployment safety check
|
|
34
|
-
└── record-deployment.sh # Record deployment after merge
|
|
35
|
-
|
|
36
|
-
.github/
|
|
37
|
-
├── actions/
|
|
38
|
-
│ └── detect-breaking-change/
|
|
39
|
-
│ └── action.yml # PR checkbox-driven breaking change detection
|
|
40
|
-
└── workflows/
|
|
41
|
-
└── contract-test-consumer.yml # Consumer CDC CI workflow
|
|
42
|
-
```
|
|
43
|
-
|
|
44
|
-
**Key Points**:
|
|
45
|
-
|
|
46
|
-
- Consumer tests use `.pacttest.ts` extension (not `.pact.spec.ts` or `.contract.ts`)
|
|
47
|
-
- Support files live in `tests/contract/support/`, not mixed with consumer tests
|
|
48
|
-
- Shell scripts live in `scripts/` at project root, not nested inside test directories
|
|
49
|
-
- CI workflow named `contract-test-consumer.yml` (not `pact-consumer.yml` or other variants)
|
|
50
|
-
|
|
51
|
-
---
|
|
52
|
-
|
|
53
|
-
### Example 2: Vitest Configuration for Pact
|
|
54
|
-
|
|
55
|
-
**Context**: Minimal vitest config dedicated to contract tests — do NOT copy settings from the project's main `vitest.config.ts`.
|
|
56
|
-
|
|
57
|
-
**Implementation**:
|
|
58
|
-
|
|
59
|
-
```typescript
|
|
60
|
-
// vitest.config.pact.ts
|
|
61
|
-
// See pact-consumer-framework-setup.md Example 2 "Key Points" for rationale on
|
|
62
|
-
// fileParallelism + pool:forks + singleFork. Do not remove those three settings.
|
|
63
|
-
import { defineConfig } from 'vitest/config';
|
|
64
|
-
|
|
65
|
-
export default defineConfig({
|
|
66
|
-
test: {
|
|
67
|
-
environment: 'node',
|
|
68
|
-
include: ['tests/contract/**/*.pacttest.ts'],
|
|
69
|
-
testTimeout: 30000,
|
|
70
|
-
fileParallelism: false,
|
|
71
|
-
pool: 'forks',
|
|
72
|
-
poolOptions: { forks: { singleFork: true } },
|
|
73
|
-
},
|
|
74
|
-
});
|
|
75
|
-
```
|
|
76
|
-
|
|
77
|
-
**Key Points**:
|
|
78
|
-
|
|
79
|
-
- **`fileParallelism: false` is required** — primary defense against non-deterministic pact generation. Without it, parallel workers race on the shared pact JSON file and corrupt interactions. Symptom: local runs pass, CI randomly fails with `Cannot change pact content for already published pact`. See Example 10 for the determinism gate that enforces byte-stability across re-runs.
|
|
80
|
-
- **`pool: 'forks'` + `singleFork: true` is required for multi-file consumer suites** — same config the provider side uses (`pactjs-utils-provider-verifier.md` Example 7). Best current understanding: the `@pact-foundation/pact` napi-rs binding is not robust across Vitest worker threads sharing a process; with the default threads pool (Vitest v1) and multiple `.pacttest.ts` files on the same consumer+provider pair, we observed reproducible "request was expected but not received" flakes on Linux CI only. `singleFork: true` serializes every pact file into one forked subprocess and eliminated the flake on two repos (`pactjs-utils`, `seon-mcp-server`). Vitest v2+ defaults to `forks`, but set the pool explicitly so the contract does not drift with Vitest version bumps.
|
|
81
|
-
- **Single-file consumer suites** (one `.pacttest.ts` per consumer+provider pair) have not been observed to flake under default threads pool, because FFI state is not shared across files when there is only one file. Adding `pool: 'forks'` is still recommended — it future-proofs you the moment a second file is added — but a suite passing today with only `fileParallelism: false` is not broken.
|
|
82
|
-
- **Interacting settings**: leave `isolate` at its default (`true`). Do NOT set `sequence.concurrent: true`, `maxConcurrency > 1`, or `maxWorkers > 1` in this config — they defeat the serialization this rule relies on. `hookTimeout` may be raised if mock-server startup is slow, but keep `testTimeout` ≥ `hookTimeout`.
|
|
83
|
-
- Do NOT add `setupFiles`, `coverage`, or other settings from the unit test config
|
|
84
|
-
- Keep it minimal — Pact tests run in Node environment with extended timeout
|
|
85
|
-
- 30 second timeout accommodates Pact mock server startup and interaction verification
|
|
86
|
-
- Use a dedicated config file (`vitest.config.pact.ts`), not the main vitest config
|
|
87
|
-
|
|
88
|
-
---
|
|
89
|
-
|
|
90
|
-
### Example 3: Package.json Script Naming
|
|
91
|
-
|
|
92
|
-
**Context**: Colon-separated naming matching pactjs-utils exactly. Scripts source `env-setup.sh` inline.
|
|
93
|
-
|
|
94
|
-
**Implementation**:
|
|
95
|
-
|
|
96
|
-
```json
|
|
97
|
-
{
|
|
98
|
-
"scripts": {
|
|
99
|
-
"test:pact:consumer": "./scripts/check-pact-determinism.sh 'npm run test:pact:consumer:run' 3 ./pacts",
|
|
100
|
-
"test:pact:consumer:run": "vitest run --config vitest.config.pact.ts",
|
|
101
|
-
"publish:pact": ". ./scripts/env-setup.sh && ./scripts/publish-pact.sh",
|
|
102
|
-
"can:i:deploy:consumer": ". ./scripts/env-setup.sh && PACTICIPANT=<service-name> ./scripts/can-i-deploy.sh",
|
|
103
|
-
"record:consumer:deployment": ". ./scripts/env-setup.sh && PACTICIPANT=<service-name> ./scripts/record-deployment.sh"
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
```
|
|
107
|
-
|
|
108
|
-
Replace `<service-name>` with the consumer's pacticipant name (e.g., `my-frontend-app`).
|
|
109
|
-
|
|
110
|
-
**Key Points**:
|
|
111
|
-
|
|
112
|
-
- **`test:pact:consumer` IS the determinism gate** — it runs the inner command 3× and fails if pact output is not byte-stable. This is the command CI and developers run before pushing. See Example 10 for the `check-pact-determinism.sh` script itself.
|
|
113
|
-
- **`test:pact:consumer:run` is the fast inner command** for TDD loops (a single pass of the suite, no gate). Developers can iterate with this; CI always goes through the outer gated script.
|
|
114
|
-
- Use colon-separated naming: `test:pact:consumer`, NOT `test:contract` or `test:contract:consumer`
|
|
115
|
-
- Broker scripts source `env-setup.sh` inline in package.json (`. ./scripts/env-setup.sh && ...`)
|
|
116
|
-
- `PACTICIPANT` is set per-script invocation, not globally
|
|
117
|
-
- Do NOT use `npx pact-broker` — use `pact-broker` directly (installed as a dependency)
|
|
118
|
-
|
|
119
|
-
---
|
|
120
|
-
|
|
121
|
-
### Example 4: Shell Scripts
|
|
122
|
-
|
|
123
|
-
**Context**: Reusable bash scripts aligned with pactjs-utils conventions.
|
|
124
|
-
|
|
125
|
-
#### `scripts/env-setup.sh` — Shared Environment Loader
|
|
126
|
-
|
|
127
|
-
```bash
|
|
128
|
-
#!/bin/bash
|
|
129
|
-
# -e: exit on error -u: error on undefined vars (catches typos/missing env vars in CI)
|
|
130
|
-
set -eu
|
|
131
|
-
|
|
132
|
-
if [ -f .env ]; then
|
|
133
|
-
set -a
|
|
134
|
-
source .env
|
|
135
|
-
set +a
|
|
136
|
-
fi
|
|
137
|
-
|
|
138
|
-
export GITHUB_SHA="${GITHUB_SHA:-$(git rev-parse --short HEAD)}"
|
|
139
|
-
export GITHUB_BRANCH="${GITHUB_BRANCH:-$(git rev-parse --abbrev-ref HEAD)}"
|
|
140
|
-
```
|
|
141
|
-
|
|
142
|
-
#### `scripts/publish-pact.sh` — Publish Pacts to Broker (with defense-in-depth normalization)
|
|
143
|
-
|
|
144
|
-
```bash
|
|
145
|
-
#!/bin/bash
|
|
146
|
-
# Publish generated pact files to PactFlow/Pact Broker.
|
|
147
|
-
#
|
|
148
|
-
# Before publish, normalize each pact JSON: sort interactions by (description, provider state name,
|
|
149
|
-
# method, path) and sort object keys via `jq -S`. This gives byte-stable output to the broker even
|
|
150
|
-
# if the PactV4 generator produces ordering drift between runs. Paired with scripts/check-pact-determinism.sh
|
|
151
|
-
# as defense-in-depth — the gate catches drift pre-publish; normalization ensures "Cannot change pact
|
|
152
|
-
# content" from PactFlow never fires on ordering-only changes that slip past the gate.
|
|
153
|
-
#
|
|
154
|
-
# Requires: PACT_BROKER_BASE_URL, PACT_BROKER_TOKEN, GITHUB_SHA, GITHUB_BRANCH, jq
|
|
155
|
-
# -e: exit on error -u: error on undefined vars -o pipefail: fail if any pipe segment fails
|
|
156
|
-
set -euo pipefail
|
|
157
|
-
|
|
158
|
-
. ./scripts/env-setup.sh
|
|
159
|
-
|
|
160
|
-
PACT_DIR="./pacts"
|
|
161
|
-
|
|
162
|
-
# Defense-in-depth: normalize interaction order for byte-stable publishes.
|
|
163
|
-
for f in "$PACT_DIR"/*.json; do
|
|
164
|
-
tmp="$(mktemp)"
|
|
165
|
-
jq -S '.interactions |= sort_by(.description, (.providerStates[0].name // ""), .request.method, .request.path)' \
|
|
166
|
-
"$f" > "$tmp"
|
|
167
|
-
mv "$tmp" "$f"
|
|
168
|
-
done
|
|
169
|
-
|
|
170
|
-
pact-broker publish "$PACT_DIR" \
|
|
171
|
-
--consumer-app-version="$GITHUB_SHA" \
|
|
172
|
-
--branch="$GITHUB_BRANCH" \
|
|
173
|
-
--broker-base-url="$PACT_BROKER_BASE_URL" \
|
|
174
|
-
--broker-token="$PACT_BROKER_TOKEN"
|
|
175
|
-
```
|
|
176
|
-
|
|
177
|
-
#### `scripts/can-i-deploy.sh` — Deployment Safety Check
|
|
178
|
-
|
|
179
|
-
```bash
|
|
180
|
-
#!/bin/bash
|
|
181
|
-
# Check if a pacticipant version can be safely deployed
|
|
182
|
-
#
|
|
183
|
-
# Requires: PACTICIPANT (set by caller), PACT_BROKER_BASE_URL, PACT_BROKER_TOKEN, GITHUB_SHA
|
|
184
|
-
# -e: exit on error -u: error on undefined vars -o pipefail: fail if any pipe segment fails
|
|
185
|
-
set -euo pipefail
|
|
186
|
-
|
|
187
|
-
. ./scripts/env-setup.sh
|
|
188
|
-
|
|
189
|
-
PACTICIPANT="${PACTICIPANT:?PACTICIPANT env var is required}"
|
|
190
|
-
ENVIRONMENT="${ENVIRONMENT:-dev}"
|
|
191
|
-
|
|
192
|
-
pact-broker can-i-deploy \
|
|
193
|
-
--pacticipant "$PACTICIPANT" \
|
|
194
|
-
--version="$GITHUB_SHA" \
|
|
195
|
-
--to-environment "$ENVIRONMENT" \
|
|
196
|
-
--retry-while-unknown=10 \
|
|
197
|
-
--retry-interval=30
|
|
198
|
-
```
|
|
199
|
-
|
|
200
|
-
#### `scripts/record-deployment.sh` — Record Deployment
|
|
201
|
-
|
|
202
|
-
```bash
|
|
203
|
-
#!/bin/bash
|
|
204
|
-
# Record a deployment to an environment in Pact Broker
|
|
205
|
-
# Only records on main/master branch (skips feature branches)
|
|
206
|
-
#
|
|
207
|
-
# Requires: PACTICIPANT, PACT_BROKER_BASE_URL, PACT_BROKER_TOKEN, GITHUB_SHA, GITHUB_BRANCH
|
|
208
|
-
# -e: exit on error -u: error on undefined vars -o pipefail: fail if any pipe segment fails
|
|
209
|
-
set -euo pipefail
|
|
210
|
-
|
|
211
|
-
. ./scripts/env-setup.sh
|
|
212
|
-
|
|
213
|
-
PACTICIPANT="${PACTICIPANT:?PACTICIPANT env var is required}"
|
|
214
|
-
|
|
215
|
-
if [ "$GITHUB_BRANCH" = "main" ] || [ "$GITHUB_BRANCH" = "master" ]; then
|
|
216
|
-
pact-broker record-deployment \
|
|
217
|
-
--pacticipant "$PACTICIPANT" \
|
|
218
|
-
--version "$GITHUB_SHA" \
|
|
219
|
-
--environment "${npm_config_env:-dev}"
|
|
220
|
-
else
|
|
221
|
-
echo "Skipping record-deployment: not on main branch (current: $GITHUB_BRANCH)"
|
|
222
|
-
fi
|
|
223
|
-
```
|
|
224
|
-
|
|
225
|
-
**Key Points**:
|
|
226
|
-
|
|
227
|
-
- `env-setup.sh` uses `set -eu` (no pipefail — it only sources `.env`, no pipes); broker scripts use `set -euo pipefail`
|
|
228
|
-
- Use `pact-broker` directly, NOT `npx pact-broker`
|
|
229
|
-
- Use `PACTICIPANT` env var (required via `${PACTICIPANT:?...}`), not hardcoded service names
|
|
230
|
-
- `can-i-deploy` includes `--retry-while-unknown=10 --retry-interval=30` (waits for provider verification)
|
|
231
|
-
- `record-deployment` has branch guard (only records on main/master)
|
|
232
|
-
- **`publish-pact.sh` normalizes interactions with `jq -S` + `sort_by(...)` before publishing** — defense-in-depth alongside the determinism gate (Example 10). The gate catches drift; normalization ensures byte-stable payload to the broker regardless of generator quirks. Keep both; they protect against different failure modes.
|
|
233
|
-
- Do NOT invent custom env vars like `PACT_CONSUMER_VERSION` or `PACT_BREAKING_CHANGE` in scripts — those are handled by `env-setup.sh` and the CI detect-breaking-change action respectively
|
|
234
|
-
|
|
235
|
-
---
|
|
236
|
-
|
|
237
|
-
### Example 5: CI Workflow (`contract-test-consumer.yml`)
|
|
238
|
-
|
|
239
|
-
**Context**: GitHub Actions workflow for consumer CDC, matching pactjs-utils structure exactly.
|
|
240
|
-
|
|
241
|
-
**Implementation**:
|
|
242
|
-
|
|
243
|
-
```yaml
|
|
244
|
-
name: Contract Test - Consumer
|
|
245
|
-
on:
|
|
246
|
-
pull_request:
|
|
247
|
-
types: [opened, synchronize, reopened, edited]
|
|
248
|
-
push:
|
|
249
|
-
branches: [main]
|
|
250
|
-
|
|
251
|
-
env:
|
|
252
|
-
PACT_BROKER_BASE_URL: ${{ secrets.PACT_BROKER_BASE_URL }}
|
|
253
|
-
PACT_BROKER_TOKEN: ${{ secrets.PACT_BROKER_TOKEN }}
|
|
254
|
-
GITHUB_SHA: ${{ github.sha }}
|
|
255
|
-
GITHUB_BRANCH: ${{ github.head_ref || github.ref_name }}
|
|
256
|
-
|
|
257
|
-
concurrency:
|
|
258
|
-
group: ${{ github.workflow }}-${{ github.head_ref || github.ref }}
|
|
259
|
-
cancel-in-progress: true
|
|
260
|
-
|
|
261
|
-
jobs:
|
|
262
|
-
consumer-contract-test:
|
|
263
|
-
if: github.actor != 'dependabot[bot]'
|
|
264
|
-
runs-on: ubuntu-latest
|
|
265
|
-
steps:
|
|
266
|
-
- uses: actions/checkout@v6
|
|
267
|
-
|
|
268
|
-
- uses: actions/setup-node@v6
|
|
269
|
-
with:
|
|
270
|
-
node-version-file: '.nvmrc'
|
|
271
|
-
cache: 'npm'
|
|
272
|
-
|
|
273
|
-
- name: Detect Pact breaking change
|
|
274
|
-
uses: ./.github/actions/detect-breaking-change
|
|
275
|
-
|
|
276
|
-
- name: Install dependencies
|
|
277
|
-
run: npm ci
|
|
278
|
-
|
|
279
|
-
# (1) Generate pact files — runs the determinism gate (3 runs + byte-stable check via jq)
|
|
280
|
-
- name: Consumer pact tests (determinism gate)
|
|
281
|
-
run: npm run test:pact:consumer
|
|
282
|
-
|
|
283
|
-
# (2) Publish pacts to broker (publish-pact.sh also normalizes interaction order as defense-in-depth)
|
|
284
|
-
- name: Publish pacts to PactFlow
|
|
285
|
-
run: npm run publish:pact
|
|
286
|
-
|
|
287
|
-
# After publish, PactFlow fires a webhook that triggers
|
|
288
|
-
# the provider's contract-test-provider.yml workflow.
|
|
289
|
-
# can-i-deploy retries while waiting for provider verification.
|
|
290
|
-
|
|
291
|
-
# (4) Check deployment safety (main only — on PRs, local verification is the gate)
|
|
292
|
-
- name: Can I deploy consumer? (main only)
|
|
293
|
-
if: github.ref == 'refs/heads/main' && env.PACT_BREAKING_CHANGE != 'true'
|
|
294
|
-
run: npm run can:i:deploy:consumer
|
|
295
|
-
|
|
296
|
-
# (5) Record deployment (main only)
|
|
297
|
-
- name: Record consumer deployment (main only)
|
|
298
|
-
if: github.ref == 'refs/heads/main'
|
|
299
|
-
run: npm run record:consumer:deployment --env=dev
|
|
300
|
-
```
|
|
301
|
-
|
|
302
|
-
**Key Points**:
|
|
303
|
-
|
|
304
|
-
- **1:1 local/CI parity is a hard rule**: every CI step is `npm run <same-name-a-dev-uses>`. Never let CI invoke `vitest` or `pact-broker` directly — that divergence is how "works on my machine" slips in. The determinism gate, publish, can-i-deploy, and record-deployment are all the same commands a developer runs locally.
|
|
305
|
-
- **The determinism gate is its own visible step, not a side-effect of publish.** A failing gate must be debuggable from the CI log without re-running. Do not fold it into a `prepublish:pact` hook — folding hides the failure inside a publish log and makes attribution harder.
|
|
306
|
-
- **Workflow-level `env` block** for broker secrets and git vars — not per-step
|
|
307
|
-
- **`detect-breaking-change` step** runs before install to set `PACT_BREAKING_CHANGE` env var
|
|
308
|
-
- **Step numbering skips (3)** — step 3 is the webhook-triggered provider verification (happens externally)
|
|
309
|
-
- **can-i-deploy condition**: `github.ref == 'refs/heads/main' && env.PACT_BREAKING_CHANGE != 'true'`
|
|
310
|
-
- **Comment on (4)**: "on PRs, local verification is the gate"
|
|
311
|
-
- **No upload-artifact step** — the broker is the source of truth for pact files
|
|
312
|
-
- **`dependabot[bot]` skip** on the job (contract tests don't run for dependency updates)
|
|
313
|
-
- **PR types include `edited`** — needed for breaking change checkbox detection in PR body
|
|
314
|
-
- **`GITHUB_BRANCH`** uses `${{ github.head_ref || github.ref_name }}` — `head_ref` for PRs, `ref_name` for pushes
|
|
315
|
-
|
|
316
|
-
---
|
|
317
|
-
|
|
318
|
-
### Example 6: Detect Breaking Change Composite Action
|
|
319
|
-
|
|
320
|
-
**Context**: GitHub composite action that reads a `[x] Pact breaking change` checkbox from the PR body.
|
|
321
|
-
|
|
322
|
-
**Implementation**:
|
|
323
|
-
|
|
324
|
-
Create `.github/actions/detect-breaking-change/action.yml`:
|
|
325
|
-
|
|
326
|
-
```yaml
|
|
327
|
-
name: 'Detect Pact Breaking Change'
|
|
328
|
-
description: 'Reads the PR template checkbox to determine if this change is a Pact breaking change. Sets PACT_BREAKING_CHANGE env var.'
|
|
329
|
-
|
|
330
|
-
outputs:
|
|
331
|
-
is_breaking_change:
|
|
332
|
-
description: 'Whether the change is a breaking change (true/false)'
|
|
333
|
-
value: ${{ steps.result.outputs.is_breaking_change }}
|
|
334
|
-
|
|
335
|
-
runs:
|
|
336
|
-
using: 'composite'
|
|
337
|
-
steps:
|
|
338
|
-
# PR event path: read checkbox directly from current PR body.
|
|
339
|
-
- name: Set PACT_BREAKING_CHANGE from PR description (PR only)
|
|
340
|
-
if: github.event_name == 'pull_request'
|
|
341
|
-
uses: actions/github-script@v7
|
|
342
|
-
with:
|
|
343
|
-
script: |
|
|
344
|
-
const prBody = context.payload.pull_request.body || '';
|
|
345
|
-
const breakingChangePattern = /\[\s*[xX]\s*\]\s*Pact breaking change/i;
|
|
346
|
-
const isBreakingChange = breakingChangePattern.test(prBody);
|
|
347
|
-
core.exportVariable('PACT_BREAKING_CHANGE', isBreakingChange ? 'true' : 'false');
|
|
348
|
-
console.log(`PACT_BREAKING_CHANGE=${isBreakingChange ? 'true' : 'false'} (from PR description checkbox).`);
|
|
349
|
-
|
|
350
|
-
# Push-to-main path: resolve the merged PR and read the same checkbox.
|
|
351
|
-
- name: Set PACT_BREAKING_CHANGE from merged PR (push to main)
|
|
352
|
-
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
|
|
353
|
-
uses: actions/github-script@v7
|
|
354
|
-
with:
|
|
355
|
-
script: |
|
|
356
|
-
const { data: prs } = await github.rest.repos.listPullRequestsAssociatedWithCommit({
|
|
357
|
-
owner: context.repo.owner,
|
|
358
|
-
repo: context.repo.repo,
|
|
359
|
-
commit_sha: context.sha,
|
|
360
|
-
});
|
|
361
|
-
const merged = prs.find(pr => pr.merged_at);
|
|
362
|
-
const mergedBody = merged?.body || '';
|
|
363
|
-
const breakingChangePattern = /\[\s*[xX]\s*\]\s*Pact breaking change/i;
|
|
364
|
-
const isBreakingChange = breakingChangePattern.test(mergedBody);
|
|
365
|
-
core.exportVariable('PACT_BREAKING_CHANGE', isBreakingChange ? 'true' : 'false');
|
|
366
|
-
console.log(`PACT_BREAKING_CHANGE=${isBreakingChange ? 'true' : 'false'} (from merged PR lookup).`);
|
|
367
|
-
|
|
368
|
-
- name: Export result
|
|
369
|
-
id: result
|
|
370
|
-
shell: bash
|
|
371
|
-
run: echo "is_breaking_change=${PACT_BREAKING_CHANGE:-false}" >> "$GITHUB_OUTPUT"
|
|
372
|
-
```
|
|
373
|
-
|
|
374
|
-
**Key Points**:
|
|
375
|
-
|
|
376
|
-
- Two separate conditional steps (better CI log readability than single if/else)
|
|
377
|
-
- PR path: reads checkbox directly from PR body
|
|
378
|
-
- Push-to-main path: resolves merged PR via GitHub API, reads same checkbox
|
|
379
|
-
- Exports `PACT_BREAKING_CHANGE` env var for downstream steps
|
|
380
|
-
- `outputs.is_breaking_change` available for consuming workflows
|
|
381
|
-
- Uses a case-insensitive checkbox regex (`/\[\s*[xX]\s*\]\s*Pact breaking change/i`) to detect checked states robustly
|
|
382
|
-
|
|
383
|
-
---
|
|
384
|
-
|
|
385
|
-
### Example 7: Consumer Test Using PactV4 Builder
|
|
386
|
-
|
|
387
|
-
**Context**: Consumer pact test using PactV4 `addInteraction()` builder pattern. The test MUST call **real consumer code** (your actual API client/service functions) against the mock server — not raw `fetch()`. Using `fetch()` directly defeats the purpose of CDC testing because it doesn't verify your actual consumer code works with the contract.
|
|
388
|
-
|
|
389
|
-
**Implementation**:
|
|
390
|
-
|
|
391
|
-
The consumer code must expose a way to inject the base URL (e.g., `setApiUrl()`, constructor parameter, or environment variable). This is a prerequisite for contract testing.
|
|
392
|
-
|
|
393
|
-
```typescript
|
|
394
|
-
// src/api/movie-client.ts — The REAL consumer code (already exists in your project)
|
|
395
|
-
import axios from 'axios';
|
|
396
|
-
|
|
397
|
-
const axiosInstance = axios.create({
|
|
398
|
-
baseURL: process.env.API_URL || 'http://localhost:3001',
|
|
399
|
-
});
|
|
400
|
-
|
|
401
|
-
// Expose a way to override the base URL for Pact testing
|
|
402
|
-
export const setApiUrl = (url: string) => {
|
|
403
|
-
axiosInstance.defaults.baseURL = url;
|
|
404
|
-
};
|
|
405
|
-
|
|
406
|
-
export const getMovies = async () => {
|
|
407
|
-
const res = await axiosInstance.get('/movies');
|
|
408
|
-
return res.data;
|
|
409
|
-
};
|
|
410
|
-
|
|
411
|
-
export const getMovieById = async (id: number) => {
|
|
412
|
-
const res = await axiosInstance.get(`/movies/${id}`);
|
|
413
|
-
return res.data;
|
|
414
|
-
};
|
|
415
|
-
```
|
|
416
|
-
|
|
417
|
-
```typescript
|
|
418
|
-
// tests/contract/consumer/get-movies.pacttest.ts
|
|
419
|
-
import { MatchersV3 } from '@pact-foundation/pact';
|
|
420
|
-
import type { V3MockServer } from '@pact-foundation/pact';
|
|
421
|
-
import { createProviderState, setJsonBody, setJsonContent } from '../support/consumer-helpers';
|
|
422
|
-
import { movieExists } from '../support/provider-states';
|
|
423
|
-
import { createPact } from '../support/pact-config';
|
|
424
|
-
// Import REAL consumer code — this is what we're actually testing
|
|
425
|
-
import { getMovies, getMovieById, setApiUrl } from '../../../src/api/movie-client';
|
|
426
|
-
|
|
427
|
-
const { like, integer, string } = MatchersV3;
|
|
428
|
-
|
|
429
|
-
const pact = createPact();
|
|
430
|
-
|
|
431
|
-
describe('Movies API Consumer Contract', () => {
|
|
432
|
-
const movieWithId = { id: 1, name: 'The Matrix', year: 1999, rating: 8.7, director: 'Wachowskis' };
|
|
433
|
-
|
|
434
|
-
it('should get a movie by ID', async () => {
|
|
435
|
-
const [stateName, stateParams] = createProviderState(movieExists(movieWithId));
|
|
436
|
-
|
|
437
|
-
await pact
|
|
438
|
-
.addInteraction()
|
|
439
|
-
.given(stateName, stateParams)
|
|
440
|
-
.uponReceiving('a request to get movie by ID')
|
|
441
|
-
.withRequest(
|
|
442
|
-
'GET',
|
|
443
|
-
'/movies/1',
|
|
444
|
-
setJsonContent({
|
|
445
|
-
headers: { Accept: 'application/json' },
|
|
446
|
-
}),
|
|
447
|
-
)
|
|
448
|
-
.willRespondWith(
|
|
449
|
-
200,
|
|
450
|
-
setJsonBody(
|
|
451
|
-
like({
|
|
452
|
-
id: integer(1),
|
|
453
|
-
name: string('The Matrix'),
|
|
454
|
-
year: integer(1999),
|
|
455
|
-
rating: like(8.7),
|
|
456
|
-
director: string('Wachowskis'),
|
|
457
|
-
}),
|
|
458
|
-
),
|
|
459
|
-
)
|
|
460
|
-
.executeTest(async (mockServer: V3MockServer) => {
|
|
461
|
-
// Inject mock server URL into the REAL consumer code
|
|
462
|
-
setApiUrl(mockServer.url);
|
|
463
|
-
|
|
464
|
-
// Call the REAL consumer function — this is what CDC testing validates
|
|
465
|
-
const movie = await getMovieById(1);
|
|
466
|
-
|
|
467
|
-
expect(movie.id).toBe(1);
|
|
468
|
-
expect(movie.name).toBe('The Matrix');
|
|
469
|
-
});
|
|
470
|
-
});
|
|
471
|
-
|
|
472
|
-
it('should handle movie not found', async () => {
|
|
473
|
-
await pact
|
|
474
|
-
.addInteraction()
|
|
475
|
-
.given('No movies exist')
|
|
476
|
-
.uponReceiving('a request for a non-existent movie')
|
|
477
|
-
.withRequest('GET', '/movies/999')
|
|
478
|
-
.willRespondWith(404, setJsonBody({ error: 'Movie not found' }))
|
|
479
|
-
.executeTest(async (mockServer: V3MockServer) => {
|
|
480
|
-
setApiUrl(mockServer.url);
|
|
481
|
-
|
|
482
|
-
await expect(getMovieById(999)).rejects.toThrow();
|
|
483
|
-
});
|
|
484
|
-
});
|
|
485
|
-
});
|
|
486
|
-
```
|
|
487
|
-
|
|
488
|
-
**Key Points**:
|
|
489
|
-
|
|
490
|
-
- **CRITICAL**: Always test your REAL consumer code — import and call actual API client functions, never raw `fetch()`
|
|
491
|
-
- Using `fetch()` directly only tests that Pact's mock server works, which is meaningless
|
|
492
|
-
- Consumer code MUST expose a URL injection mechanism: `setApiUrl()`, env var override, or constructor parameter
|
|
493
|
-
- If the consumer code doesn't support URL injection, add it — this is a design prerequisite for CDC testing
|
|
494
|
-
- Use PactV4 `addInteraction()` builder (not PactV3 fluent API with `withRequest({...})` object)
|
|
495
|
-
- **Interaction naming convention**: Use the pattern `"a request to <action> <resource> [<condition>]"` for `uponReceiving()`. Examples: `"a request to get a movie by ID"`, `"a request to delete a non-existing movie"`, `"a request to create a movie that already exists"`. These names appear in Pact Broker UI and verification logs — keep them descriptive and unique within the consumer-provider pair.
|
|
496
|
-
- Use `setJsonContent` for request/response builder callbacks with query/header/body concerns; use `setJsonBody` for body-only response callbacks
|
|
497
|
-
- Provider state factory functions (`movieExists`) return `ProviderStateInput` objects
|
|
498
|
-
- `createProviderState` converts to `[stateName, stateParams]` tuple for `.given()`
|
|
499
|
-
|
|
500
|
-
**Common URL injection patterns** (pick whichever fits your consumer architecture):
|
|
501
|
-
|
|
502
|
-
| Pattern | Example | Best For |
|
|
503
|
-
| -------------------- | -------------------------------------------- | --------------------- |
|
|
504
|
-
| `setApiUrl(url)` | Mutates axios instance `baseURL` | Singleton HTTP client |
|
|
505
|
-
| Constructor param | `new ApiClient({ baseUrl: mockServer.url })` | Class-based clients |
|
|
506
|
-
| Environment variable | `process.env.API_URL = mockServer.url` | Config-driven apps |
|
|
507
|
-
| Factory function | `createApi({ baseUrl: mockServer.url })` | Functional patterns |
|
|
508
|
-
|
|
509
|
-
---
|
|
510
|
-
|
|
511
|
-
### Example 8: Support Files
|
|
512
|
-
|
|
513
|
-
#### Pact Config Factory
|
|
514
|
-
|
|
515
|
-
```typescript
|
|
516
|
-
// tests/contract/support/pact-config.ts
|
|
517
|
-
import path from 'node:path';
|
|
518
|
-
import { PactV4 } from '@pact-foundation/pact';
|
|
519
|
-
|
|
520
|
-
export const createPact = (overrides?: { consumer?: string; provider?: string }) =>
|
|
521
|
-
new PactV4({
|
|
522
|
-
dir: path.resolve(process.cwd(), 'pacts'),
|
|
523
|
-
consumer: overrides?.consumer ?? 'MyConsumerApp',
|
|
524
|
-
provider: overrides?.provider ?? 'MyProviderAPI',
|
|
525
|
-
logLevel: 'warn',
|
|
526
|
-
});
|
|
527
|
-
```
|
|
528
|
-
|
|
529
|
-
#### Provider State Factories
|
|
530
|
-
|
|
531
|
-
```typescript
|
|
532
|
-
// tests/contract/support/provider-states.ts
|
|
533
|
-
import type { ProviderStateInput } from './consumer-helpers';
|
|
534
|
-
|
|
535
|
-
export const movieExists = (movie: { id: number; name: string; year: number; rating: number; director: string }): ProviderStateInput => ({
|
|
536
|
-
name: 'An existing movie exists',
|
|
537
|
-
params: movie,
|
|
538
|
-
});
|
|
539
|
-
|
|
540
|
-
export const hasMovieWithId = (id: number): ProviderStateInput => ({
|
|
541
|
-
name: 'Has a movie with a specific ID',
|
|
542
|
-
params: { id },
|
|
543
|
-
});
|
|
544
|
-
```
|
|
545
|
-
|
|
546
|
-
#### Local Consumer Helpers Shim
|
|
547
|
-
|
|
548
|
-
```typescript
|
|
549
|
-
// tests/contract/support/consumer-helpers.ts
|
|
550
|
-
// TODO(temporary scaffolding): Replace local TemplateHeaders/TemplateQuery types
|
|
551
|
-
// with '@seontechnologies/pactjs-utils' exports when available.
|
|
552
|
-
|
|
553
|
-
type TemplateHeaders = Record<string, string | number | boolean>;
|
|
554
|
-
type TemplateQueryValue = string | number | boolean | Array<string | number | boolean>;
|
|
555
|
-
type TemplateQuery = Record<string, TemplateQueryValue>;
|
|
556
|
-
|
|
557
|
-
export type ProviderStateInput = {
|
|
558
|
-
name: string;
|
|
559
|
-
params: Record<string, unknown>;
|
|
560
|
-
};
|
|
561
|
-
|
|
562
|
-
type JsonMap = { [key: string]: boolean | number | string | null | JsonMap | Array<unknown> };
|
|
563
|
-
type JsonContentBuilder = {
|
|
564
|
-
headers: (headers: TemplateHeaders) => unknown;
|
|
565
|
-
jsonBody: (body: unknown) => unknown;
|
|
566
|
-
query?: (query: TemplateQuery) => unknown;
|
|
567
|
-
};
|
|
568
|
-
|
|
569
|
-
export type JsonContentInput = {
|
|
570
|
-
body?: unknown;
|
|
571
|
-
headers?: TemplateHeaders;
|
|
572
|
-
query?: TemplateQuery;
|
|
573
|
-
};
|
|
574
|
-
|
|
575
|
-
export const toJsonMap = (obj: Record<string, unknown>): JsonMap =>
|
|
576
|
-
Object.fromEntries(
|
|
577
|
-
Object.entries(obj).map(([key, value]) => {
|
|
578
|
-
if (value === null || value === undefined) return [key, 'null'];
|
|
579
|
-
if (typeof value === 'object' && !(value instanceof Date) && !Array.isArray(value)) return [key, JSON.stringify(value)];
|
|
580
|
-
if (typeof value === 'number' || typeof value === 'boolean') return [key, value];
|
|
581
|
-
if (value instanceof Date) return [key, value.toISOString()];
|
|
582
|
-
return [key, String(value)];
|
|
583
|
-
}),
|
|
584
|
-
);
|
|
585
|
-
|
|
586
|
-
export const createProviderState = ({ name, params }: ProviderStateInput): [string, JsonMap] => [name, toJsonMap(params)];
|
|
587
|
-
|
|
588
|
-
export const setJsonContent =
|
|
589
|
-
({ body, headers, query }: JsonContentInput) =>
|
|
590
|
-
(builder: JsonContentBuilder): void => {
|
|
591
|
-
if (query && builder.query) {
|
|
592
|
-
builder.query(query);
|
|
593
|
-
}
|
|
594
|
-
|
|
595
|
-
if (headers) {
|
|
596
|
-
builder.headers(headers);
|
|
597
|
-
}
|
|
598
|
-
|
|
599
|
-
if (body !== undefined) {
|
|
600
|
-
builder.jsonBody(body);
|
|
601
|
-
}
|
|
602
|
-
};
|
|
603
|
-
|
|
604
|
-
export const setJsonBody = (body: unknown) => setJsonContent({ body });
|
|
605
|
-
```
|
|
606
|
-
|
|
607
|
-
**Key Points**:
|
|
608
|
-
|
|
609
|
-
- If `@seontechnologies/pactjs-utils` is not yet installed, create a local shim that mirrors the API
|
|
610
|
-
- Add a TODO comment noting to swap for the published package when available
|
|
611
|
-
- The shim exports `createProviderState`, `toJsonMap`, `setJsonContent`, `setJsonBody`, and helper input types
|
|
612
|
-
- Keep shim types local (or sourced from public exports only); do not import from internal Pact paths like `@pact-foundation/pact/src/*`
|
|
613
|
-
|
|
614
|
-
---
|
|
615
|
-
|
|
616
|
-
### Example 9: .gitignore Entries
|
|
617
|
-
|
|
618
|
-
**Context**: Pact-specific entries to add to `.gitignore`.
|
|
619
|
-
|
|
620
|
-
```
|
|
621
|
-
# Pact contract testing artifacts
|
|
622
|
-
/pacts/
|
|
623
|
-
pact-logs/
|
|
624
|
-
```
|
|
625
|
-
|
|
626
|
-
---
|
|
627
|
-
|
|
628
|
-
### Example 10: Determinism Gate Script (Primary Defense)
|
|
629
|
-
|
|
630
|
-
**Context**: Even with `fileParallelism: false` (Example 2) and one-interaction-per-`it()` (see `pactjs-utils-consumer-helpers.md`), the PactV4 Rust FFI layer can occasionally produce byte-different pact JSON between runs — interaction ordering drift, nested matcher serialization quirks, or `Date` / random-value matchers that weren't locked down. This causes PactFlow to reject re-publishes of the same consumer SHA with `Cannot change pact content for already published pact`. The determinism gate runs the consumer suite N times locally and in CI, hashes the normalized pact files, and fails fast if drift is detected — before any publish is attempted.
|
|
631
|
-
|
|
632
|
-
**Implementation**:
|
|
633
|
-
|
|
634
|
-
#### `scripts/check-pact-determinism.sh`
|
|
635
|
-
|
|
636
|
-
```bash
|
|
637
|
-
#!/bin/bash
|
|
638
|
-
# Run a pact consumer command N times and fail if the generated pact files are not byte-stable.
|
|
639
|
-
# Primary defense against PactV4 non-deterministic output.
|
|
640
|
-
#
|
|
641
|
-
# Usage: ./scripts/check-pact-determinism.sh "<cmd>" [runs] [pact-dir]
|
|
642
|
-
# Example: ./scripts/check-pact-determinism.sh 'npm run test:pact:consumer:run' 3 ./pacts
|
|
643
|
-
#
|
|
644
|
-
# Requires: jq installed on the runner (ubuntu-latest has it; macOS users need `brew install jq`).
|
|
645
|
-
set -euo pipefail
|
|
646
|
-
|
|
647
|
-
CMD="${1:?usage: ./scripts/check-pact-determinism.sh \"<cmd>\" [runs] [pact-dir]}"
|
|
648
|
-
RUNS="${PACT_DETERMINISM_RUNS:-${2:-3}}"
|
|
649
|
-
PACT_DIR="${3:-./pacts}"
|
|
650
|
-
|
|
651
|
-
TMP_DIR="$(mktemp -d)"
|
|
652
|
-
trap 'rm -rf "$TMP_DIR"' EXIT
|
|
653
|
-
|
|
654
|
-
hash_pact_file() {
|
|
655
|
-
# Sort interactions by (description, first provider state name, method, path), sort keys with -S.
|
|
656
|
-
# The sorted output is what we hash — so ordering-only drift does NOT count as non-determinism here.
|
|
657
|
-
# (The gate catches deeper drift; ordering drift is handled by publish-pact.sh normalization.)
|
|
658
|
-
jq -S '.interactions |= sort_by(.description, (.providerStates[0].name // ""), .request.method, .request.path)' "$1" \
|
|
659
|
-
| shasum -a 256 | awk '{print $1}'
|
|
660
|
-
}
|
|
661
|
-
|
|
662
|
-
for run in $(seq 1 "$RUNS"); do
|
|
663
|
-
echo "→ determinism run $run/$RUNS"
|
|
664
|
-
rm -f "$PACT_DIR"/*.json 2>/dev/null || true
|
|
665
|
-
eval "$CMD" >"$TMP_DIR/run-$run.log" 2>&1 || {
|
|
666
|
-
echo "❌ run $run failed — dumping log:"
|
|
667
|
-
cat "$TMP_DIR/run-$run.log"
|
|
668
|
-
exit 1
|
|
669
|
-
}
|
|
670
|
-
: > "$TMP_DIR/run-$run.hashes"
|
|
671
|
-
for f in "$PACT_DIR"/*.json; do
|
|
672
|
-
[ -f "$f" ] || continue
|
|
673
|
-
printf '%s %s\n' "$(hash_pact_file "$f")" "$(basename "$f")" >> "$TMP_DIR/run-$run.hashes"
|
|
674
|
-
done
|
|
675
|
-
sort -o "$TMP_DIR/run-$run.hashes" "$TMP_DIR/run-$run.hashes"
|
|
676
|
-
done
|
|
677
|
-
|
|
678
|
-
# Compare every subsequent run against run 1.
|
|
679
|
-
FAIL=0
|
|
680
|
-
for run in $(seq 2 "$RUNS"); do
|
|
681
|
-
if ! diff -q "$TMP_DIR/run-1.hashes" "$TMP_DIR/run-$run.hashes" >/dev/null; then
|
|
682
|
-
FAIL=1
|
|
683
|
-
echo ""
|
|
684
|
-
echo "❌ Pact output differs between run 1 and run $run:"
|
|
685
|
-
diff "$TMP_DIR/run-1.hashes" "$TMP_DIR/run-$run.hashes" || true
|
|
686
|
-
fi
|
|
687
|
-
done
|
|
688
|
-
|
|
689
|
-
if [ "$FAIL" -ne 0 ]; then
|
|
690
|
-
echo ""
|
|
691
|
-
echo "Pact output is non-deterministic across $RUNS runs. Likely causes:"
|
|
692
|
-
echo " • multiple .addInteraction() chained in a single it() block (PactV4 FFI drops one non-deterministically)"
|
|
693
|
-
echo " • fileParallelism: true in vitest.config.pact.ts (workers race on shared pact JSON)"
|
|
694
|
-
echo " • missing pool: 'forks' + singleFork: true (threads pool shares FFI state across files on Linux CI)"
|
|
695
|
-
echo " • Date / random matchers that don't lock a stable example value"
|
|
696
|
-
echo " • provider state params mutating between runs (e.g. Date.now())"
|
|
697
|
-
exit 1
|
|
698
|
-
fi
|
|
699
|
-
|
|
700
|
-
echo "✅ Pact output is byte-stable across $RUNS runs."
|
|
701
|
-
```
|
|
702
|
-
|
|
703
|
-
**Key Points**:
|
|
704
|
-
|
|
705
|
-
- **Wire this script into `test:pact:consumer`** (see Example 3). The outer script IS the gate; the inner `test:pact:consumer:run` is the single-pass command for TDD loops.
|
|
706
|
-
- **Default 3 runs** is the sweet spot — 2 runs miss intermittent drops, >3 slows CI without catching more. Override with an env var or the positional arg if you're actively debugging a flake.
|
|
707
|
-
- **Treat gate failures as a P0 bug, not a "retry until green" condition.** Find the source of non-determinism (chained `addInteraction`, unsorted interactions, Date-dependent matchers). Do not raise `RUNS` to 10 to mask the symptom.
|
|
708
|
-
- **Requires `jq`** — installed by default on `ubuntu-latest`. For macOS local dev, document `brew install jq` in the project README.
|
|
709
|
-
- **In CI, make this its own visible step** (see Example 5 step (1) naming). Do not fold into a `prepublish:pact` hook — that hides the failure inside a publish log.
|
|
710
|
-
- **Defense-in-depth with `publish-pact.sh` normalization** (Example 4): the gate catches pre-publish drift; the publish-time `jq` sort ensures any ordering-only drift that slipped past the gate still produces a byte-stable payload to PactFlow.
|
|
711
|
-
|
|
712
|
-
---
|
|
713
|
-
|
|
714
|
-
## Validation Checklist
|
|
715
|
-
|
|
716
|
-
Before presenting the consumer CDC framework to the user, verify:
|
|
717
|
-
|
|
718
|
-
- [ ] `vitest.config.pact.ts` is minimal **and sets `fileParallelism: false` AND `pool: 'forks'` with `poolOptions.forks.singleFork: true`** (`fileParallelism: false` prevents shared pact JSON corruption from parallel workers; forks + `singleFork: true` eliminates the Linux-CI "request was expected but not received" flake observed once a second `.pacttest.ts` is added — see Example 2 Key Points for evidence, mechanism qualifier, and single-file exception)
|
|
719
|
-
- [ ] `vitest.config.pact.ts` does NOT set `sequence.concurrent: true`, `maxConcurrency > 1`, `maxWorkers > 1`, or `isolate: false` — all four defeat the serialization the rule relies on
|
|
720
|
-
- [ ] `package.json` splits `test:pact:consumer` (gated determinism runner) and `test:pact:consumer:run` (inner single-pass command)
|
|
721
|
-
- [ ] `scripts/check-pact-determinism.sh` is present, hashes via `jq -S` + `sort_by`, defaults to 3 runs, and is the body of the `test:pact:consumer` script
|
|
722
|
-
- [ ] `scripts/publish-pact.sh` normalizes interactions with `jq -S '.interactions |= sort_by(.description, (.providerStates[0].name // ""), .request.method, .request.path)'` before the `pact-broker publish` call (defense-in-depth alongside the gate)
|
|
723
|
-
- [ ] Script names match pactjs-utils (`test:pact:consumer`, `test:pact:consumer:run`, `publish:pact`, `can:i:deploy:consumer`, `record:consumer:deployment`)
|
|
724
|
-
- [ ] Scripts source `env-setup.sh` inline in package.json
|
|
725
|
-
- [ ] Shell scripts use `pact-broker` not `npx pact-broker`
|
|
726
|
-
- [ ] Shell scripts use `PACTICIPANT` env var pattern
|
|
727
|
-
- [ ] `can-i-deploy.sh` has `--retry-while-unknown=10 --retry-interval=30`
|
|
728
|
-
- [ ] `record-deployment.sh` has branch guard
|
|
729
|
-
- [ ] `env-setup.sh` uses `set -eu`; broker scripts use `set -euo pipefail` — each with explanatory comment
|
|
730
|
-
- [ ] CI workflow named `contract-test-consumer.yml`
|
|
731
|
-
- [ ] CI has workflow-level env block (not per-step)
|
|
732
|
-
- [ ] CI has `detect-breaking-change` step before install
|
|
733
|
-
- [ ] CI step (1) is the determinism gate (calls `npm run test:pact:consumer`) — its own visible step, not folded into publish
|
|
734
|
-
- [ ] CI steps are 1:1 with developer commands — every CI step calls `npm run <same-name>` a dev would run locally (no direct `vitest` or `pact-broker` invocation)
|
|
735
|
-
- [ ] CI step numbering skips (3) — webhook-triggered provider verification
|
|
736
|
-
- [ ] CI can-i-deploy has `PACT_BREAKING_CHANGE != 'true'` condition
|
|
737
|
-
- [ ] CI has NO upload-artifact step
|
|
738
|
-
- [ ] `.github/actions/detect-breaking-change/action.yml` exists
|
|
739
|
-
- [ ] Consumer tests use `.pacttest.ts` extension
|
|
740
|
-
- [ ] Consumer tests use PactV4 `addInteraction()` builder
|
|
741
|
-
- [ ] `uponReceiving()` names follow `"a request to <action> <resource> [<condition>]"` pattern and are unique within the consumer-provider pair
|
|
742
|
-
- [ ] Interaction callbacks use `setJsonContent` for query/header/body and `setJsonBody` for body-only responses
|
|
743
|
-
- [ ] Request bodies use exact values (no `like()` wrapper) — Postel's Law: be strict in what you send
|
|
744
|
-
- [ ] `like()`, `eachLike()`, `string()`, `integer()` matchers are only used in `willRespondWith` (responses), not in `withRequest` (requests) — matchers check type/shape, not exact values
|
|
745
|
-
- [ ] Consumer tests call REAL consumer code (actual API client functions), NOT raw `fetch()`
|
|
746
|
-
- [ ] Consumer code exposes URL injection mechanism (`setApiUrl()`, env var, or constructor param)
|
|
747
|
-
- [ ] Local consumer-helpers shim present if pactjs-utils not installed
|
|
748
|
-
- [ ] `.gitignore` includes `/pacts/` and `pact-logs/`
|
|
749
|
-
|
|
750
|
-
## Related Fragments
|
|
751
|
-
|
|
752
|
-
- `pactjs-utils-overview.md` — Library decision tree and installation
|
|
753
|
-
- `pactjs-utils-consumer-helpers.md` — `createProviderState`, `toJsonMap`, `setJsonContent`, `setJsonBody`, **one-interaction-per-`it()` rule**
|
|
754
|
-
- `pactjs-utils-provider-verifier.md` — Provider-side verification patterns; consumer and provider BOTH require `pool: 'forks'` + `singleFork: true` — same FFI-safety rule applies on both sides
|
|
755
|
-
- `pactjs-utils-request-filter.md` — Auth injection for provider verification
|
|
756
|
-
- `pact-broker-webhooks.md` — PactFlow → GitHub webhook auth pattern (dedicated user, classic PAT, PactFlow secret) and staleness monitoring
|
|
757
|
-
- `contract-testing.md` — Foundational CDC patterns and resilience coverage
|
|
1
|
+
# Pact Consumer CDC — Framework Setup
|
|
2
|
+
|
|
3
|
+
## Principle
|
|
4
|
+
|
|
5
|
+
When scaffolding a Pact.js consumer contract testing framework, align every artifact — directory layout, vitest config, package.json scripts, shell scripts, CI workflow, and test files — with the canonical `@seontechnologies/pactjs-utils` conventions. Consistency across repositories eliminates onboarding friction and ensures CI pipelines are copy-paste portable.
|
|
6
|
+
|
|
7
|
+
## Rationale
|
|
8
|
+
|
|
9
|
+
The TEA framework workflow generates scaffolding for consumer-driven contract (CDC) testing. Without opinionated, battle-tested conventions, each project invents its own structure — different script names, different env var patterns, different CI step ordering — making cross-repo maintenance expensive. This fragment codifies the production-proven patterns from the pactjs-utils reference implementation so that every new project starts correctly.
|
|
10
|
+
|
|
11
|
+
## Pattern Examples
|
|
12
|
+
|
|
13
|
+
### Example 1: Directory Structure & File Naming
|
|
14
|
+
|
|
15
|
+
**Context**: Consumer contract test project layout using pactjs-utils conventions.
|
|
16
|
+
|
|
17
|
+
**Implementation**:
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
tests/contract/
|
|
21
|
+
├── consumer/
|
|
22
|
+
│ ├── get-filter-fields.pacttest.ts # Consumer test (one per endpoint group)
|
|
23
|
+
│ ├── filter-transactions.pacttest.ts
|
|
24
|
+
│ └── get-transaction-stats.pacttest.ts
|
|
25
|
+
└── support/
|
|
26
|
+
├── pact-config.ts # PactV4 factory (consumer/provider names, output dir)
|
|
27
|
+
├── provider-states.ts # Provider state factory functions
|
|
28
|
+
└── consumer-helpers.ts # Local shim (until pactjs-utils is published)
|
|
29
|
+
|
|
30
|
+
scripts/
|
|
31
|
+
├── env-setup.sh # Shared env loader (sourced by all broker scripts)
|
|
32
|
+
├── publish-pact.sh # Publish pact files to broker
|
|
33
|
+
├── can-i-deploy.sh # Deployment safety check
|
|
34
|
+
└── record-deployment.sh # Record deployment after merge
|
|
35
|
+
|
|
36
|
+
.github/
|
|
37
|
+
├── actions/
|
|
38
|
+
│ └── detect-breaking-change/
|
|
39
|
+
│ └── action.yml # PR checkbox-driven breaking change detection
|
|
40
|
+
└── workflows/
|
|
41
|
+
└── contract-test-consumer.yml # Consumer CDC CI workflow
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
**Key Points**:
|
|
45
|
+
|
|
46
|
+
- Consumer tests use `.pacttest.ts` extension (not `.pact.spec.ts` or `.contract.ts`)
|
|
47
|
+
- Support files live in `tests/contract/support/`, not mixed with consumer tests
|
|
48
|
+
- Shell scripts live in `scripts/` at project root, not nested inside test directories
|
|
49
|
+
- CI workflow named `contract-test-consumer.yml` (not `pact-consumer.yml` or other variants)
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
### Example 2: Vitest Configuration for Pact
|
|
54
|
+
|
|
55
|
+
**Context**: Minimal vitest config dedicated to contract tests — do NOT copy settings from the project's main `vitest.config.ts`.
|
|
56
|
+
|
|
57
|
+
**Implementation**:
|
|
58
|
+
|
|
59
|
+
```typescript
|
|
60
|
+
// vitest.config.pact.ts
|
|
61
|
+
// See pact-consumer-framework-setup.md Example 2 "Key Points" for rationale on
|
|
62
|
+
// fileParallelism + pool:forks + singleFork. Do not remove those three settings.
|
|
63
|
+
import { defineConfig } from 'vitest/config';
|
|
64
|
+
|
|
65
|
+
export default defineConfig({
|
|
66
|
+
test: {
|
|
67
|
+
environment: 'node',
|
|
68
|
+
include: ['tests/contract/**/*.pacttest.ts'],
|
|
69
|
+
testTimeout: 30000,
|
|
70
|
+
fileParallelism: false,
|
|
71
|
+
pool: 'forks',
|
|
72
|
+
poolOptions: { forks: { singleFork: true } },
|
|
73
|
+
},
|
|
74
|
+
});
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
**Key Points**:
|
|
78
|
+
|
|
79
|
+
- **`fileParallelism: false` is required** — primary defense against non-deterministic pact generation. Without it, parallel workers race on the shared pact JSON file and corrupt interactions. Symptom: local runs pass, CI randomly fails with `Cannot change pact content for already published pact`. See Example 10 for the determinism gate that enforces byte-stability across re-runs.
|
|
80
|
+
- **`pool: 'forks'` + `singleFork: true` is required for multi-file consumer suites** — same config the provider side uses (`pactjs-utils-provider-verifier.md` Example 7). Best current understanding: the `@pact-foundation/pact` napi-rs binding is not robust across Vitest worker threads sharing a process; with the default threads pool (Vitest v1) and multiple `.pacttest.ts` files on the same consumer+provider pair, we observed reproducible "request was expected but not received" flakes on Linux CI only. `singleFork: true` serializes every pact file into one forked subprocess and eliminated the flake on two repos (`pactjs-utils`, `seon-mcp-server`). Vitest v2+ defaults to `forks`, but set the pool explicitly so the contract does not drift with Vitest version bumps.
|
|
81
|
+
- **Single-file consumer suites** (one `.pacttest.ts` per consumer+provider pair) have not been observed to flake under default threads pool, because FFI state is not shared across files when there is only one file. Adding `pool: 'forks'` is still recommended — it future-proofs you the moment a second file is added — but a suite passing today with only `fileParallelism: false` is not broken.
|
|
82
|
+
- **Interacting settings**: leave `isolate` at its default (`true`). Do NOT set `sequence.concurrent: true`, `maxConcurrency > 1`, or `maxWorkers > 1` in this config — they defeat the serialization this rule relies on. `hookTimeout` may be raised if mock-server startup is slow, but keep `testTimeout` ≥ `hookTimeout`.
|
|
83
|
+
- Do NOT add `setupFiles`, `coverage`, or other settings from the unit test config
|
|
84
|
+
- Keep it minimal — Pact tests run in Node environment with extended timeout
|
|
85
|
+
- 30 second timeout accommodates Pact mock server startup and interaction verification
|
|
86
|
+
- Use a dedicated config file (`vitest.config.pact.ts`), not the main vitest config
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
### Example 3: Package.json Script Naming
|
|
91
|
+
|
|
92
|
+
**Context**: Colon-separated naming matching pactjs-utils exactly. Scripts source `env-setup.sh` inline.
|
|
93
|
+
|
|
94
|
+
**Implementation**:
|
|
95
|
+
|
|
96
|
+
```json
|
|
97
|
+
{
|
|
98
|
+
"scripts": {
|
|
99
|
+
"test:pact:consumer": "./scripts/check-pact-determinism.sh 'npm run test:pact:consumer:run' 3 ./pacts",
|
|
100
|
+
"test:pact:consumer:run": "vitest run --config vitest.config.pact.ts",
|
|
101
|
+
"publish:pact": ". ./scripts/env-setup.sh && ./scripts/publish-pact.sh",
|
|
102
|
+
"can:i:deploy:consumer": ". ./scripts/env-setup.sh && PACTICIPANT=<service-name> ./scripts/can-i-deploy.sh",
|
|
103
|
+
"record:consumer:deployment": ". ./scripts/env-setup.sh && PACTICIPANT=<service-name> ./scripts/record-deployment.sh"
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Replace `<service-name>` with the consumer's pacticipant name (e.g., `my-frontend-app`).
|
|
109
|
+
|
|
110
|
+
**Key Points**:
|
|
111
|
+
|
|
112
|
+
- **`test:pact:consumer` IS the determinism gate** — it runs the inner command 3× and fails if pact output is not byte-stable. This is the command CI and developers run before pushing. See Example 10 for the `check-pact-determinism.sh` script itself.
|
|
113
|
+
- **`test:pact:consumer:run` is the fast inner command** for TDD loops (a single pass of the suite, no gate). Developers can iterate with this; CI always goes through the outer gated script.
|
|
114
|
+
- Use colon-separated naming: `test:pact:consumer`, NOT `test:contract` or `test:contract:consumer`
|
|
115
|
+
- Broker scripts source `env-setup.sh` inline in package.json (`. ./scripts/env-setup.sh && ...`)
|
|
116
|
+
- `PACTICIPANT` is set per-script invocation, not globally
|
|
117
|
+
- Do NOT use `npx pact-broker` — use `pact-broker` directly (installed as a dependency)
|
|
118
|
+
|
|
119
|
+
---
|
|
120
|
+
|
|
121
|
+
### Example 4: Shell Scripts
|
|
122
|
+
|
|
123
|
+
**Context**: Reusable bash scripts aligned with pactjs-utils conventions.
|
|
124
|
+
|
|
125
|
+
#### `scripts/env-setup.sh` — Shared Environment Loader
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
#!/bin/bash
|
|
129
|
+
# -e: exit on error -u: error on undefined vars (catches typos/missing env vars in CI)
|
|
130
|
+
set -eu
|
|
131
|
+
|
|
132
|
+
if [ -f .env ]; then
|
|
133
|
+
set -a
|
|
134
|
+
source .env
|
|
135
|
+
set +a
|
|
136
|
+
fi
|
|
137
|
+
|
|
138
|
+
export GITHUB_SHA="${GITHUB_SHA:-$(git rev-parse --short HEAD)}"
|
|
139
|
+
export GITHUB_BRANCH="${GITHUB_BRANCH:-$(git rev-parse --abbrev-ref HEAD)}"
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
#### `scripts/publish-pact.sh` — Publish Pacts to Broker (with defense-in-depth normalization)
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
#!/bin/bash
|
|
146
|
+
# Publish generated pact files to PactFlow/Pact Broker.
|
|
147
|
+
#
|
|
148
|
+
# Before publish, normalize each pact JSON: sort interactions by (description, provider state name,
|
|
149
|
+
# method, path) and sort object keys via `jq -S`. This gives byte-stable output to the broker even
|
|
150
|
+
# if the PactV4 generator produces ordering drift between runs. Paired with scripts/check-pact-determinism.sh
|
|
151
|
+
# as defense-in-depth — the gate catches drift pre-publish; normalization ensures "Cannot change pact
|
|
152
|
+
# content" from PactFlow never fires on ordering-only changes that slip past the gate.
|
|
153
|
+
#
|
|
154
|
+
# Requires: PACT_BROKER_BASE_URL, PACT_BROKER_TOKEN, GITHUB_SHA, GITHUB_BRANCH, jq
|
|
155
|
+
# -e: exit on error -u: error on undefined vars -o pipefail: fail if any pipe segment fails
|
|
156
|
+
set -euo pipefail
|
|
157
|
+
|
|
158
|
+
. ./scripts/env-setup.sh
|
|
159
|
+
|
|
160
|
+
PACT_DIR="./pacts"
|
|
161
|
+
|
|
162
|
+
# Defense-in-depth: normalize interaction order for byte-stable publishes.
|
|
163
|
+
for f in "$PACT_DIR"/*.json; do
|
|
164
|
+
tmp="$(mktemp)"
|
|
165
|
+
jq -S '.interactions |= sort_by(.description, (.providerStates[0].name // ""), .request.method, .request.path)' \
|
|
166
|
+
"$f" > "$tmp"
|
|
167
|
+
mv "$tmp" "$f"
|
|
168
|
+
done
|
|
169
|
+
|
|
170
|
+
pact-broker publish "$PACT_DIR" \
|
|
171
|
+
--consumer-app-version="$GITHUB_SHA" \
|
|
172
|
+
--branch="$GITHUB_BRANCH" \
|
|
173
|
+
--broker-base-url="$PACT_BROKER_BASE_URL" \
|
|
174
|
+
--broker-token="$PACT_BROKER_TOKEN"
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
#### `scripts/can-i-deploy.sh` — Deployment Safety Check
|
|
178
|
+
|
|
179
|
+
```bash
|
|
180
|
+
#!/bin/bash
|
|
181
|
+
# Check if a pacticipant version can be safely deployed
|
|
182
|
+
#
|
|
183
|
+
# Requires: PACTICIPANT (set by caller), PACT_BROKER_BASE_URL, PACT_BROKER_TOKEN, GITHUB_SHA
|
|
184
|
+
# -e: exit on error -u: error on undefined vars -o pipefail: fail if any pipe segment fails
|
|
185
|
+
set -euo pipefail
|
|
186
|
+
|
|
187
|
+
. ./scripts/env-setup.sh
|
|
188
|
+
|
|
189
|
+
PACTICIPANT="${PACTICIPANT:?PACTICIPANT env var is required}"
|
|
190
|
+
ENVIRONMENT="${ENVIRONMENT:-dev}"
|
|
191
|
+
|
|
192
|
+
pact-broker can-i-deploy \
|
|
193
|
+
--pacticipant "$PACTICIPANT" \
|
|
194
|
+
--version="$GITHUB_SHA" \
|
|
195
|
+
--to-environment "$ENVIRONMENT" \
|
|
196
|
+
--retry-while-unknown=10 \
|
|
197
|
+
--retry-interval=30
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
#### `scripts/record-deployment.sh` — Record Deployment
|
|
201
|
+
|
|
202
|
+
```bash
|
|
203
|
+
#!/bin/bash
|
|
204
|
+
# Record a deployment to an environment in Pact Broker
|
|
205
|
+
# Only records on main/master branch (skips feature branches)
|
|
206
|
+
#
|
|
207
|
+
# Requires: PACTICIPANT, PACT_BROKER_BASE_URL, PACT_BROKER_TOKEN, GITHUB_SHA, GITHUB_BRANCH
|
|
208
|
+
# -e: exit on error -u: error on undefined vars -o pipefail: fail if any pipe segment fails
|
|
209
|
+
set -euo pipefail
|
|
210
|
+
|
|
211
|
+
. ./scripts/env-setup.sh
|
|
212
|
+
|
|
213
|
+
PACTICIPANT="${PACTICIPANT:?PACTICIPANT env var is required}"
|
|
214
|
+
|
|
215
|
+
if [ "$GITHUB_BRANCH" = "main" ] || [ "$GITHUB_BRANCH" = "master" ]; then
|
|
216
|
+
pact-broker record-deployment \
|
|
217
|
+
--pacticipant "$PACTICIPANT" \
|
|
218
|
+
--version "$GITHUB_SHA" \
|
|
219
|
+
--environment "${npm_config_env:-dev}"
|
|
220
|
+
else
|
|
221
|
+
echo "Skipping record-deployment: not on main branch (current: $GITHUB_BRANCH)"
|
|
222
|
+
fi
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
**Key Points**:
|
|
226
|
+
|
|
227
|
+
- `env-setup.sh` uses `set -eu` (no pipefail — it only sources `.env`, no pipes); broker scripts use `set -euo pipefail`
|
|
228
|
+
- Use `pact-broker` directly, NOT `npx pact-broker`
|
|
229
|
+
- Use `PACTICIPANT` env var (required via `${PACTICIPANT:?...}`), not hardcoded service names
|
|
230
|
+
- `can-i-deploy` includes `--retry-while-unknown=10 --retry-interval=30` (waits for provider verification)
|
|
231
|
+
- `record-deployment` has branch guard (only records on main/master)
|
|
232
|
+
- **`publish-pact.sh` normalizes interactions with `jq -S` + `sort_by(...)` before publishing** — defense-in-depth alongside the determinism gate (Example 10). The gate catches drift; normalization ensures byte-stable payload to the broker regardless of generator quirks. Keep both; they protect against different failure modes.
|
|
233
|
+
- Do NOT invent custom env vars like `PACT_CONSUMER_VERSION` or `PACT_BREAKING_CHANGE` in scripts — those are handled by `env-setup.sh` and the CI detect-breaking-change action respectively
|
|
234
|
+
|
|
235
|
+
---
|
|
236
|
+
|
|
237
|
+
### Example 5: CI Workflow (`contract-test-consumer.yml`)
|
|
238
|
+
|
|
239
|
+
**Context**: GitHub Actions workflow for consumer CDC, matching pactjs-utils structure exactly.
|
|
240
|
+
|
|
241
|
+
**Implementation**:
|
|
242
|
+
|
|
243
|
+
```yaml
|
|
244
|
+
name: Contract Test - Consumer
|
|
245
|
+
on:
|
|
246
|
+
pull_request:
|
|
247
|
+
types: [opened, synchronize, reopened, edited]
|
|
248
|
+
push:
|
|
249
|
+
branches: [main]
|
|
250
|
+
|
|
251
|
+
env:
|
|
252
|
+
PACT_BROKER_BASE_URL: ${{ secrets.PACT_BROKER_BASE_URL }}
|
|
253
|
+
PACT_BROKER_TOKEN: ${{ secrets.PACT_BROKER_TOKEN }}
|
|
254
|
+
GITHUB_SHA: ${{ github.sha }}
|
|
255
|
+
GITHUB_BRANCH: ${{ github.head_ref || github.ref_name }}
|
|
256
|
+
|
|
257
|
+
concurrency:
|
|
258
|
+
group: ${{ github.workflow }}-${{ github.head_ref || github.ref }}
|
|
259
|
+
cancel-in-progress: true
|
|
260
|
+
|
|
261
|
+
jobs:
|
|
262
|
+
consumer-contract-test:
|
|
263
|
+
if: github.actor != 'dependabot[bot]'
|
|
264
|
+
runs-on: ubuntu-latest
|
|
265
|
+
steps:
|
|
266
|
+
- uses: actions/checkout@v6
|
|
267
|
+
|
|
268
|
+
- uses: actions/setup-node@v6
|
|
269
|
+
with:
|
|
270
|
+
node-version-file: '.nvmrc'
|
|
271
|
+
cache: 'npm'
|
|
272
|
+
|
|
273
|
+
- name: Detect Pact breaking change
|
|
274
|
+
uses: ./.github/actions/detect-breaking-change
|
|
275
|
+
|
|
276
|
+
- name: Install dependencies
|
|
277
|
+
run: npm ci
|
|
278
|
+
|
|
279
|
+
# (1) Generate pact files — runs the determinism gate (3 runs + byte-stable check via jq)
|
|
280
|
+
- name: Consumer pact tests (determinism gate)
|
|
281
|
+
run: npm run test:pact:consumer
|
|
282
|
+
|
|
283
|
+
# (2) Publish pacts to broker (publish-pact.sh also normalizes interaction order as defense-in-depth)
|
|
284
|
+
- name: Publish pacts to PactFlow
|
|
285
|
+
run: npm run publish:pact
|
|
286
|
+
|
|
287
|
+
# After publish, PactFlow fires a webhook that triggers
|
|
288
|
+
# the provider's contract-test-provider.yml workflow.
|
|
289
|
+
# can-i-deploy retries while waiting for provider verification.
|
|
290
|
+
|
|
291
|
+
# (4) Check deployment safety (main only — on PRs, local verification is the gate)
|
|
292
|
+
- name: Can I deploy consumer? (main only)
|
|
293
|
+
if: github.ref == 'refs/heads/main' && env.PACT_BREAKING_CHANGE != 'true'
|
|
294
|
+
run: npm run can:i:deploy:consumer
|
|
295
|
+
|
|
296
|
+
# (5) Record deployment (main only)
|
|
297
|
+
- name: Record consumer deployment (main only)
|
|
298
|
+
if: github.ref == 'refs/heads/main'
|
|
299
|
+
run: npm run record:consumer:deployment --env=dev
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
**Key Points**:
|
|
303
|
+
|
|
304
|
+
- **1:1 local/CI parity is a hard rule**: every CI step is `npm run <same-name-a-dev-uses>`. Never let CI invoke `vitest` or `pact-broker` directly — that divergence is how "works on my machine" slips in. The determinism gate, publish, can-i-deploy, and record-deployment are all the same commands a developer runs locally.
|
|
305
|
+
- **The determinism gate is its own visible step, not a side-effect of publish.** A failing gate must be debuggable from the CI log without re-running. Do not fold it into a `prepublish:pact` hook — folding hides the failure inside a publish log and makes attribution harder.
|
|
306
|
+
- **Workflow-level `env` block** for broker secrets and git vars — not per-step
|
|
307
|
+
- **`detect-breaking-change` step** runs before install to set `PACT_BREAKING_CHANGE` env var
|
|
308
|
+
- **Step numbering skips (3)** — step 3 is the webhook-triggered provider verification (happens externally)
|
|
309
|
+
- **can-i-deploy condition**: `github.ref == 'refs/heads/main' && env.PACT_BREAKING_CHANGE != 'true'`
|
|
310
|
+
- **Comment on (4)**: "on PRs, local verification is the gate"
|
|
311
|
+
- **No upload-artifact step** — the broker is the source of truth for pact files
|
|
312
|
+
- **`dependabot[bot]` skip** on the job (contract tests don't run for dependency updates)
|
|
313
|
+
- **PR types include `edited`** — needed for breaking change checkbox detection in PR body
|
|
314
|
+
- **`GITHUB_BRANCH`** uses `${{ github.head_ref || github.ref_name }}` — `head_ref` for PRs, `ref_name` for pushes
|
|
315
|
+
|
|
316
|
+
---
|
|
317
|
+
|
|
318
|
+
### Example 6: Detect Breaking Change Composite Action
|
|
319
|
+
|
|
320
|
+
**Context**: GitHub composite action that reads a `[x] Pact breaking change` checkbox from the PR body.
|
|
321
|
+
|
|
322
|
+
**Implementation**:
|
|
323
|
+
|
|
324
|
+
Create `.github/actions/detect-breaking-change/action.yml`:
|
|
325
|
+
|
|
326
|
+
```yaml
|
|
327
|
+
name: 'Detect Pact Breaking Change'
|
|
328
|
+
description: 'Reads the PR template checkbox to determine if this change is a Pact breaking change. Sets PACT_BREAKING_CHANGE env var.'
|
|
329
|
+
|
|
330
|
+
outputs:
|
|
331
|
+
is_breaking_change:
|
|
332
|
+
description: 'Whether the change is a breaking change (true/false)'
|
|
333
|
+
value: ${{ steps.result.outputs.is_breaking_change }}
|
|
334
|
+
|
|
335
|
+
runs:
|
|
336
|
+
using: 'composite'
|
|
337
|
+
steps:
|
|
338
|
+
# PR event path: read checkbox directly from current PR body.
|
|
339
|
+
- name: Set PACT_BREAKING_CHANGE from PR description (PR only)
|
|
340
|
+
if: github.event_name == 'pull_request'
|
|
341
|
+
uses: actions/github-script@v7
|
|
342
|
+
with:
|
|
343
|
+
script: |
|
|
344
|
+
const prBody = context.payload.pull_request.body || '';
|
|
345
|
+
const breakingChangePattern = /\[\s*[xX]\s*\]\s*Pact breaking change/i;
|
|
346
|
+
const isBreakingChange = breakingChangePattern.test(prBody);
|
|
347
|
+
core.exportVariable('PACT_BREAKING_CHANGE', isBreakingChange ? 'true' : 'false');
|
|
348
|
+
console.log(`PACT_BREAKING_CHANGE=${isBreakingChange ? 'true' : 'false'} (from PR description checkbox).`);
|
|
349
|
+
|
|
350
|
+
# Push-to-main path: resolve the merged PR and read the same checkbox.
|
|
351
|
+
- name: Set PACT_BREAKING_CHANGE from merged PR (push to main)
|
|
352
|
+
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
|
|
353
|
+
uses: actions/github-script@v7
|
|
354
|
+
with:
|
|
355
|
+
script: |
|
|
356
|
+
const { data: prs } = await github.rest.repos.listPullRequestsAssociatedWithCommit({
|
|
357
|
+
owner: context.repo.owner,
|
|
358
|
+
repo: context.repo.repo,
|
|
359
|
+
commit_sha: context.sha,
|
|
360
|
+
});
|
|
361
|
+
const merged = prs.find(pr => pr.merged_at);
|
|
362
|
+
const mergedBody = merged?.body || '';
|
|
363
|
+
const breakingChangePattern = /\[\s*[xX]\s*\]\s*Pact breaking change/i;
|
|
364
|
+
const isBreakingChange = breakingChangePattern.test(mergedBody);
|
|
365
|
+
core.exportVariable('PACT_BREAKING_CHANGE', isBreakingChange ? 'true' : 'false');
|
|
366
|
+
console.log(`PACT_BREAKING_CHANGE=${isBreakingChange ? 'true' : 'false'} (from merged PR lookup).`);
|
|
367
|
+
|
|
368
|
+
- name: Export result
|
|
369
|
+
id: result
|
|
370
|
+
shell: bash
|
|
371
|
+
run: echo "is_breaking_change=${PACT_BREAKING_CHANGE:-false}" >> "$GITHUB_OUTPUT"
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
**Key Points**:
|
|
375
|
+
|
|
376
|
+
- Two separate conditional steps (better CI log readability than single if/else)
|
|
377
|
+
- PR path: reads checkbox directly from PR body
|
|
378
|
+
- Push-to-main path: resolves merged PR via GitHub API, reads same checkbox
|
|
379
|
+
- Exports `PACT_BREAKING_CHANGE` env var for downstream steps
|
|
380
|
+
- `outputs.is_breaking_change` available for consuming workflows
|
|
381
|
+
- Uses a case-insensitive checkbox regex (`/\[\s*[xX]\s*\]\s*Pact breaking change/i`) to detect checked states robustly
|
|
382
|
+
|
|
383
|
+
---
|
|
384
|
+
|
|
385
|
+
### Example 7: Consumer Test Using PactV4 Builder
|
|
386
|
+
|
|
387
|
+
**Context**: Consumer pact test using PactV4 `addInteraction()` builder pattern. The test MUST call **real consumer code** (your actual API client/service functions) against the mock server — not raw `fetch()`. Using `fetch()` directly defeats the purpose of CDC testing because it doesn't verify your actual consumer code works with the contract.
|
|
388
|
+
|
|
389
|
+
**Implementation**:
|
|
390
|
+
|
|
391
|
+
The consumer code must expose a way to inject the base URL (e.g., `setApiUrl()`, constructor parameter, or environment variable). This is a prerequisite for contract testing.
|
|
392
|
+
|
|
393
|
+
```typescript
|
|
394
|
+
// src/api/movie-client.ts — The REAL consumer code (already exists in your project)
|
|
395
|
+
import axios from 'axios';
|
|
396
|
+
|
|
397
|
+
const axiosInstance = axios.create({
|
|
398
|
+
baseURL: process.env.API_URL || 'http://localhost:3001',
|
|
399
|
+
});
|
|
400
|
+
|
|
401
|
+
// Expose a way to override the base URL for Pact testing
|
|
402
|
+
export const setApiUrl = (url: string) => {
|
|
403
|
+
axiosInstance.defaults.baseURL = url;
|
|
404
|
+
};
|
|
405
|
+
|
|
406
|
+
export const getMovies = async () => {
|
|
407
|
+
const res = await axiosInstance.get('/movies');
|
|
408
|
+
return res.data;
|
|
409
|
+
};
|
|
410
|
+
|
|
411
|
+
export const getMovieById = async (id: number) => {
|
|
412
|
+
const res = await axiosInstance.get(`/movies/${id}`);
|
|
413
|
+
return res.data;
|
|
414
|
+
};
|
|
415
|
+
```
|
|
416
|
+
|
|
417
|
+
```typescript
|
|
418
|
+
// tests/contract/consumer/get-movies.pacttest.ts
|
|
419
|
+
import { MatchersV3 } from '@pact-foundation/pact';
|
|
420
|
+
import type { V3MockServer } from '@pact-foundation/pact';
|
|
421
|
+
import { createProviderState, setJsonBody, setJsonContent } from '../support/consumer-helpers';
|
|
422
|
+
import { movieExists } from '../support/provider-states';
|
|
423
|
+
import { createPact } from '../support/pact-config';
|
|
424
|
+
// Import REAL consumer code — this is what we're actually testing
|
|
425
|
+
import { getMovies, getMovieById, setApiUrl } from '../../../src/api/movie-client';
|
|
426
|
+
|
|
427
|
+
const { like, integer, string } = MatchersV3;
|
|
428
|
+
|
|
429
|
+
const pact = createPact();
|
|
430
|
+
|
|
431
|
+
describe('Movies API Consumer Contract', () => {
|
|
432
|
+
const movieWithId = { id: 1, name: 'The Matrix', year: 1999, rating: 8.7, director: 'Wachowskis' };
|
|
433
|
+
|
|
434
|
+
it('should get a movie by ID', async () => {
|
|
435
|
+
const [stateName, stateParams] = createProviderState(movieExists(movieWithId));
|
|
436
|
+
|
|
437
|
+
await pact
|
|
438
|
+
.addInteraction()
|
|
439
|
+
.given(stateName, stateParams)
|
|
440
|
+
.uponReceiving('a request to get movie by ID')
|
|
441
|
+
.withRequest(
|
|
442
|
+
'GET',
|
|
443
|
+
'/movies/1',
|
|
444
|
+
setJsonContent({
|
|
445
|
+
headers: { Accept: 'application/json' },
|
|
446
|
+
}),
|
|
447
|
+
)
|
|
448
|
+
.willRespondWith(
|
|
449
|
+
200,
|
|
450
|
+
setJsonBody(
|
|
451
|
+
like({
|
|
452
|
+
id: integer(1),
|
|
453
|
+
name: string('The Matrix'),
|
|
454
|
+
year: integer(1999),
|
|
455
|
+
rating: like(8.7),
|
|
456
|
+
director: string('Wachowskis'),
|
|
457
|
+
}),
|
|
458
|
+
),
|
|
459
|
+
)
|
|
460
|
+
.executeTest(async (mockServer: V3MockServer) => {
|
|
461
|
+
// Inject mock server URL into the REAL consumer code
|
|
462
|
+
setApiUrl(mockServer.url);
|
|
463
|
+
|
|
464
|
+
// Call the REAL consumer function — this is what CDC testing validates
|
|
465
|
+
const movie = await getMovieById(1);
|
|
466
|
+
|
|
467
|
+
expect(movie.id).toBe(1);
|
|
468
|
+
expect(movie.name).toBe('The Matrix');
|
|
469
|
+
});
|
|
470
|
+
});
|
|
471
|
+
|
|
472
|
+
it('should handle movie not found', async () => {
|
|
473
|
+
await pact
|
|
474
|
+
.addInteraction()
|
|
475
|
+
.given('No movies exist')
|
|
476
|
+
.uponReceiving('a request for a non-existent movie')
|
|
477
|
+
.withRequest('GET', '/movies/999')
|
|
478
|
+
.willRespondWith(404, setJsonBody({ error: 'Movie not found' }))
|
|
479
|
+
.executeTest(async (mockServer: V3MockServer) => {
|
|
480
|
+
setApiUrl(mockServer.url);
|
|
481
|
+
|
|
482
|
+
await expect(getMovieById(999)).rejects.toThrow();
|
|
483
|
+
});
|
|
484
|
+
});
|
|
485
|
+
});
|
|
486
|
+
```
|
|
487
|
+
|
|
488
|
+
**Key Points**:
|
|
489
|
+
|
|
490
|
+
- **CRITICAL**: Always test your REAL consumer code — import and call actual API client functions, never raw `fetch()`
|
|
491
|
+
- Using `fetch()` directly only tests that Pact's mock server works, which is meaningless
|
|
492
|
+
- Consumer code MUST expose a URL injection mechanism: `setApiUrl()`, env var override, or constructor parameter
|
|
493
|
+
- If the consumer code doesn't support URL injection, add it — this is a design prerequisite for CDC testing
|
|
494
|
+
- Use PactV4 `addInteraction()` builder (not PactV3 fluent API with `withRequest({...})` object)
|
|
495
|
+
- **Interaction naming convention**: Use the pattern `"a request to <action> <resource> [<condition>]"` for `uponReceiving()`. Examples: `"a request to get a movie by ID"`, `"a request to delete a non-existing movie"`, `"a request to create a movie that already exists"`. These names appear in Pact Broker UI and verification logs — keep them descriptive and unique within the consumer-provider pair.
|
|
496
|
+
- Use `setJsonContent` for request/response builder callbacks with query/header/body concerns; use `setJsonBody` for body-only response callbacks
|
|
497
|
+
- Provider state factory functions (`movieExists`) return `ProviderStateInput` objects
|
|
498
|
+
- `createProviderState` converts to `[stateName, stateParams]` tuple for `.given()`
|
|
499
|
+
|
|
500
|
+
**Common URL injection patterns** (pick whichever fits your consumer architecture):
|
|
501
|
+
|
|
502
|
+
| Pattern | Example | Best For |
|
|
503
|
+
| -------------------- | -------------------------------------------- | --------------------- |
|
|
504
|
+
| `setApiUrl(url)` | Mutates axios instance `baseURL` | Singleton HTTP client |
|
|
505
|
+
| Constructor param | `new ApiClient({ baseUrl: mockServer.url })` | Class-based clients |
|
|
506
|
+
| Environment variable | `process.env.API_URL = mockServer.url` | Config-driven apps |
|
|
507
|
+
| Factory function | `createApi({ baseUrl: mockServer.url })` | Functional patterns |
|
|
508
|
+
|
|
509
|
+
---
|
|
510
|
+
|
|
511
|
+
### Example 8: Support Files
|
|
512
|
+
|
|
513
|
+
#### Pact Config Factory
|
|
514
|
+
|
|
515
|
+
```typescript
|
|
516
|
+
// tests/contract/support/pact-config.ts
|
|
517
|
+
import path from 'node:path';
|
|
518
|
+
import { PactV4 } from '@pact-foundation/pact';
|
|
519
|
+
|
|
520
|
+
export const createPact = (overrides?: { consumer?: string; provider?: string }) =>
|
|
521
|
+
new PactV4({
|
|
522
|
+
dir: path.resolve(process.cwd(), 'pacts'),
|
|
523
|
+
consumer: overrides?.consumer ?? 'MyConsumerApp',
|
|
524
|
+
provider: overrides?.provider ?? 'MyProviderAPI',
|
|
525
|
+
logLevel: 'warn',
|
|
526
|
+
});
|
|
527
|
+
```
|
|
528
|
+
|
|
529
|
+
#### Provider State Factories
|
|
530
|
+
|
|
531
|
+
```typescript
|
|
532
|
+
// tests/contract/support/provider-states.ts
|
|
533
|
+
import type { ProviderStateInput } from './consumer-helpers';
|
|
534
|
+
|
|
535
|
+
export const movieExists = (movie: { id: number; name: string; year: number; rating: number; director: string }): ProviderStateInput => ({
|
|
536
|
+
name: 'An existing movie exists',
|
|
537
|
+
params: movie,
|
|
538
|
+
});
|
|
539
|
+
|
|
540
|
+
export const hasMovieWithId = (id: number): ProviderStateInput => ({
|
|
541
|
+
name: 'Has a movie with a specific ID',
|
|
542
|
+
params: { id },
|
|
543
|
+
});
|
|
544
|
+
```
|
|
545
|
+
|
|
546
|
+
#### Local Consumer Helpers Shim
|
|
547
|
+
|
|
548
|
+
```typescript
|
|
549
|
+
// tests/contract/support/consumer-helpers.ts
|
|
550
|
+
// TODO(temporary scaffolding): Replace local TemplateHeaders/TemplateQuery types
|
|
551
|
+
// with '@seontechnologies/pactjs-utils' exports when available.
|
|
552
|
+
|
|
553
|
+
type TemplateHeaders = Record<string, string | number | boolean>;
|
|
554
|
+
type TemplateQueryValue = string | number | boolean | Array<string | number | boolean>;
|
|
555
|
+
type TemplateQuery = Record<string, TemplateQueryValue>;
|
|
556
|
+
|
|
557
|
+
export type ProviderStateInput = {
|
|
558
|
+
name: string;
|
|
559
|
+
params: Record<string, unknown>;
|
|
560
|
+
};
|
|
561
|
+
|
|
562
|
+
type JsonMap = { [key: string]: boolean | number | string | null | JsonMap | Array<unknown> };
|
|
563
|
+
type JsonContentBuilder = {
|
|
564
|
+
headers: (headers: TemplateHeaders) => unknown;
|
|
565
|
+
jsonBody: (body: unknown) => unknown;
|
|
566
|
+
query?: (query: TemplateQuery) => unknown;
|
|
567
|
+
};
|
|
568
|
+
|
|
569
|
+
export type JsonContentInput = {
|
|
570
|
+
body?: unknown;
|
|
571
|
+
headers?: TemplateHeaders;
|
|
572
|
+
query?: TemplateQuery;
|
|
573
|
+
};
|
|
574
|
+
|
|
575
|
+
export const toJsonMap = (obj: Record<string, unknown>): JsonMap =>
|
|
576
|
+
Object.fromEntries(
|
|
577
|
+
Object.entries(obj).map(([key, value]) => {
|
|
578
|
+
if (value === null || value === undefined) return [key, 'null'];
|
|
579
|
+
if (typeof value === 'object' && !(value instanceof Date) && !Array.isArray(value)) return [key, JSON.stringify(value)];
|
|
580
|
+
if (typeof value === 'number' || typeof value === 'boolean') return [key, value];
|
|
581
|
+
if (value instanceof Date) return [key, value.toISOString()];
|
|
582
|
+
return [key, String(value)];
|
|
583
|
+
}),
|
|
584
|
+
);
|
|
585
|
+
|
|
586
|
+
export const createProviderState = ({ name, params }: ProviderStateInput): [string, JsonMap] => [name, toJsonMap(params)];
|
|
587
|
+
|
|
588
|
+
export const setJsonContent =
|
|
589
|
+
({ body, headers, query }: JsonContentInput) =>
|
|
590
|
+
(builder: JsonContentBuilder): void => {
|
|
591
|
+
if (query && builder.query) {
|
|
592
|
+
builder.query(query);
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
if (headers) {
|
|
596
|
+
builder.headers(headers);
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
if (body !== undefined) {
|
|
600
|
+
builder.jsonBody(body);
|
|
601
|
+
}
|
|
602
|
+
};
|
|
603
|
+
|
|
604
|
+
export const setJsonBody = (body: unknown) => setJsonContent({ body });
|
|
605
|
+
```
|
|
606
|
+
|
|
607
|
+
**Key Points**:
|
|
608
|
+
|
|
609
|
+
- If `@seontechnologies/pactjs-utils` is not yet installed, create a local shim that mirrors the API
|
|
610
|
+
- Add a TODO comment noting to swap for the published package when available
|
|
611
|
+
- The shim exports `createProviderState`, `toJsonMap`, `setJsonContent`, `setJsonBody`, and helper input types
|
|
612
|
+
- Keep shim types local (or sourced from public exports only); do not import from internal Pact paths like `@pact-foundation/pact/src/*`
|
|
613
|
+
|
|
614
|
+
---
|
|
615
|
+
|
|
616
|
+
### Example 9: .gitignore Entries
|
|
617
|
+
|
|
618
|
+
**Context**: Pact-specific entries to add to `.gitignore`.
|
|
619
|
+
|
|
620
|
+
```
|
|
621
|
+
# Pact contract testing artifacts
|
|
622
|
+
/pacts/
|
|
623
|
+
pact-logs/
|
|
624
|
+
```
|
|
625
|
+
|
|
626
|
+
---
|
|
627
|
+
|
|
628
|
+
### Example 10: Determinism Gate Script (Primary Defense)
|
|
629
|
+
|
|
630
|
+
**Context**: Even with `fileParallelism: false` (Example 2) and one-interaction-per-`it()` (see `pactjs-utils-consumer-helpers.md`), the PactV4 Rust FFI layer can occasionally produce byte-different pact JSON between runs — interaction ordering drift, nested matcher serialization quirks, or `Date` / random-value matchers that weren't locked down. This causes PactFlow to reject re-publishes of the same consumer SHA with `Cannot change pact content for already published pact`. The determinism gate runs the consumer suite N times locally and in CI, hashes the normalized pact files, and fails fast if drift is detected — before any publish is attempted.
|
|
631
|
+
|
|
632
|
+
**Implementation**:
|
|
633
|
+
|
|
634
|
+
#### `scripts/check-pact-determinism.sh`
|
|
635
|
+
|
|
636
|
+
```bash
|
|
637
|
+
#!/bin/bash
|
|
638
|
+
# Run a pact consumer command N times and fail if the generated pact files are not byte-stable.
|
|
639
|
+
# Primary defense against PactV4 non-deterministic output.
|
|
640
|
+
#
|
|
641
|
+
# Usage: ./scripts/check-pact-determinism.sh "<cmd>" [runs] [pact-dir]
|
|
642
|
+
# Example: ./scripts/check-pact-determinism.sh 'npm run test:pact:consumer:run' 3 ./pacts
|
|
643
|
+
#
|
|
644
|
+
# Requires: jq installed on the runner (ubuntu-latest has it; macOS users need `brew install jq`).
|
|
645
|
+
set -euo pipefail
|
|
646
|
+
|
|
647
|
+
CMD="${1:?usage: ./scripts/check-pact-determinism.sh \"<cmd>\" [runs] [pact-dir]}"
|
|
648
|
+
RUNS="${PACT_DETERMINISM_RUNS:-${2:-3}}"
|
|
649
|
+
PACT_DIR="${3:-./pacts}"
|
|
650
|
+
|
|
651
|
+
TMP_DIR="$(mktemp -d)"
|
|
652
|
+
trap 'rm -rf "$TMP_DIR"' EXIT
|
|
653
|
+
|
|
654
|
+
hash_pact_file() {
|
|
655
|
+
# Sort interactions by (description, first provider state name, method, path), sort keys with -S.
|
|
656
|
+
# The sorted output is what we hash — so ordering-only drift does NOT count as non-determinism here.
|
|
657
|
+
# (The gate catches deeper drift; ordering drift is handled by publish-pact.sh normalization.)
|
|
658
|
+
jq -S '.interactions |= sort_by(.description, (.providerStates[0].name // ""), .request.method, .request.path)' "$1" \
|
|
659
|
+
| shasum -a 256 | awk '{print $1}'
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
for run in $(seq 1 "$RUNS"); do
|
|
663
|
+
echo "→ determinism run $run/$RUNS"
|
|
664
|
+
rm -f "$PACT_DIR"/*.json 2>/dev/null || true
|
|
665
|
+
eval "$CMD" >"$TMP_DIR/run-$run.log" 2>&1 || {
|
|
666
|
+
echo "❌ run $run failed — dumping log:"
|
|
667
|
+
cat "$TMP_DIR/run-$run.log"
|
|
668
|
+
exit 1
|
|
669
|
+
}
|
|
670
|
+
: > "$TMP_DIR/run-$run.hashes"
|
|
671
|
+
for f in "$PACT_DIR"/*.json; do
|
|
672
|
+
[ -f "$f" ] || continue
|
|
673
|
+
printf '%s %s\n' "$(hash_pact_file "$f")" "$(basename "$f")" >> "$TMP_DIR/run-$run.hashes"
|
|
674
|
+
done
|
|
675
|
+
sort -o "$TMP_DIR/run-$run.hashes" "$TMP_DIR/run-$run.hashes"
|
|
676
|
+
done
|
|
677
|
+
|
|
678
|
+
# Compare every subsequent run against run 1.
|
|
679
|
+
FAIL=0
|
|
680
|
+
for run in $(seq 2 "$RUNS"); do
|
|
681
|
+
if ! diff -q "$TMP_DIR/run-1.hashes" "$TMP_DIR/run-$run.hashes" >/dev/null; then
|
|
682
|
+
FAIL=1
|
|
683
|
+
echo ""
|
|
684
|
+
echo "❌ Pact output differs between run 1 and run $run:"
|
|
685
|
+
diff "$TMP_DIR/run-1.hashes" "$TMP_DIR/run-$run.hashes" || true
|
|
686
|
+
fi
|
|
687
|
+
done
|
|
688
|
+
|
|
689
|
+
if [ "$FAIL" -ne 0 ]; then
|
|
690
|
+
echo ""
|
|
691
|
+
echo "Pact output is non-deterministic across $RUNS runs. Likely causes:"
|
|
692
|
+
echo " • multiple .addInteraction() chained in a single it() block (PactV4 FFI drops one non-deterministically)"
|
|
693
|
+
echo " • fileParallelism: true in vitest.config.pact.ts (workers race on shared pact JSON)"
|
|
694
|
+
echo " • missing pool: 'forks' + singleFork: true (threads pool shares FFI state across files on Linux CI)"
|
|
695
|
+
echo " • Date / random matchers that don't lock a stable example value"
|
|
696
|
+
echo " • provider state params mutating between runs (e.g. Date.now())"
|
|
697
|
+
exit 1
|
|
698
|
+
fi
|
|
699
|
+
|
|
700
|
+
echo "✅ Pact output is byte-stable across $RUNS runs."
|
|
701
|
+
```
|
|
702
|
+
|
|
703
|
+
**Key Points**:
|
|
704
|
+
|
|
705
|
+
- **Wire this script into `test:pact:consumer`** (see Example 3). The outer script IS the gate; the inner `test:pact:consumer:run` is the single-pass command for TDD loops.
|
|
706
|
+
- **Default 3 runs** is the sweet spot — 2 runs miss intermittent drops, >3 slows CI without catching more. Override with an env var or the positional arg if you're actively debugging a flake.
|
|
707
|
+
- **Treat gate failures as a P0 bug, not a "retry until green" condition.** Find the source of non-determinism (chained `addInteraction`, unsorted interactions, Date-dependent matchers). Do not raise `RUNS` to 10 to mask the symptom.
|
|
708
|
+
- **Requires `jq`** — installed by default on `ubuntu-latest`. For macOS local dev, document `brew install jq` in the project README.
|
|
709
|
+
- **In CI, make this its own visible step** (see Example 5 step (1) naming). Do not fold into a `prepublish:pact` hook — that hides the failure inside a publish log.
|
|
710
|
+
- **Defense-in-depth with `publish-pact.sh` normalization** (Example 4): the gate catches pre-publish drift; the publish-time `jq` sort ensures any ordering-only drift that slipped past the gate still produces a byte-stable payload to PactFlow.
|
|
711
|
+
|
|
712
|
+
---
|
|
713
|
+
|
|
714
|
+
## Validation Checklist
|
|
715
|
+
|
|
716
|
+
Before presenting the consumer CDC framework to the user, verify:
|
|
717
|
+
|
|
718
|
+
- [ ] `vitest.config.pact.ts` is minimal **and sets `fileParallelism: false` AND `pool: 'forks'` with `poolOptions.forks.singleFork: true`** (`fileParallelism: false` prevents shared pact JSON corruption from parallel workers; forks + `singleFork: true` eliminates the Linux-CI "request was expected but not received" flake observed once a second `.pacttest.ts` is added — see Example 2 Key Points for evidence, mechanism qualifier, and single-file exception)
|
|
719
|
+
- [ ] `vitest.config.pact.ts` does NOT set `sequence.concurrent: true`, `maxConcurrency > 1`, `maxWorkers > 1`, or `isolate: false` — all four defeat the serialization the rule relies on
|
|
720
|
+
- [ ] `package.json` splits `test:pact:consumer` (gated determinism runner) and `test:pact:consumer:run` (inner single-pass command)
|
|
721
|
+
- [ ] `scripts/check-pact-determinism.sh` is present, hashes via `jq -S` + `sort_by`, defaults to 3 runs, and is the body of the `test:pact:consumer` script
|
|
722
|
+
- [ ] `scripts/publish-pact.sh` normalizes interactions with `jq -S '.interactions |= sort_by(.description, (.providerStates[0].name // ""), .request.method, .request.path)'` before the `pact-broker publish` call (defense-in-depth alongside the gate)
|
|
723
|
+
- [ ] Script names match pactjs-utils (`test:pact:consumer`, `test:pact:consumer:run`, `publish:pact`, `can:i:deploy:consumer`, `record:consumer:deployment`)
|
|
724
|
+
- [ ] Scripts source `env-setup.sh` inline in package.json
|
|
725
|
+
- [ ] Shell scripts use `pact-broker` not `npx pact-broker`
|
|
726
|
+
- [ ] Shell scripts use `PACTICIPANT` env var pattern
|
|
727
|
+
- [ ] `can-i-deploy.sh` has `--retry-while-unknown=10 --retry-interval=30`
|
|
728
|
+
- [ ] `record-deployment.sh` has branch guard
|
|
729
|
+
- [ ] `env-setup.sh` uses `set -eu`; broker scripts use `set -euo pipefail` — each with explanatory comment
|
|
730
|
+
- [ ] CI workflow named `contract-test-consumer.yml`
|
|
731
|
+
- [ ] CI has workflow-level env block (not per-step)
|
|
732
|
+
- [ ] CI has `detect-breaking-change` step before install
|
|
733
|
+
- [ ] CI step (1) is the determinism gate (calls `npm run test:pact:consumer`) — its own visible step, not folded into publish
|
|
734
|
+
- [ ] CI steps are 1:1 with developer commands — every CI step calls `npm run <same-name>` a dev would run locally (no direct `vitest` or `pact-broker` invocation)
|
|
735
|
+
- [ ] CI step numbering skips (3) — webhook-triggered provider verification
|
|
736
|
+
- [ ] CI can-i-deploy has `PACT_BREAKING_CHANGE != 'true'` condition
|
|
737
|
+
- [ ] CI has NO upload-artifact step
|
|
738
|
+
- [ ] `.github/actions/detect-breaking-change/action.yml` exists
|
|
739
|
+
- [ ] Consumer tests use `.pacttest.ts` extension
|
|
740
|
+
- [ ] Consumer tests use PactV4 `addInteraction()` builder
|
|
741
|
+
- [ ] `uponReceiving()` names follow `"a request to <action> <resource> [<condition>]"` pattern and are unique within the consumer-provider pair
|
|
742
|
+
- [ ] Interaction callbacks use `setJsonContent` for query/header/body and `setJsonBody` for body-only responses
|
|
743
|
+
- [ ] Request bodies use exact values (no `like()` wrapper) — Postel's Law: be strict in what you send
|
|
744
|
+
- [ ] `like()`, `eachLike()`, `string()`, `integer()` matchers are only used in `willRespondWith` (responses), not in `withRequest` (requests) — matchers check type/shape, not exact values
|
|
745
|
+
- [ ] Consumer tests call REAL consumer code (actual API client functions), NOT raw `fetch()`
|
|
746
|
+
- [ ] Consumer code exposes URL injection mechanism (`setApiUrl()`, env var, or constructor param)
|
|
747
|
+
- [ ] Local consumer-helpers shim present if pactjs-utils not installed
|
|
748
|
+
- [ ] `.gitignore` includes `/pacts/` and `pact-logs/`
|
|
749
|
+
|
|
750
|
+
## Related Fragments
|
|
751
|
+
|
|
752
|
+
- `pactjs-utils-overview.md` — Library decision tree and installation
|
|
753
|
+
- `pactjs-utils-consumer-helpers.md` — `createProviderState`, `toJsonMap`, `setJsonContent`, `setJsonBody`, **one-interaction-per-`it()` rule**
|
|
754
|
+
- `pactjs-utils-provider-verifier.md` — Provider-side verification patterns; consumer and provider BOTH require `pool: 'forks'` + `singleFork: true` — same FFI-safety rule applies on both sides
|
|
755
|
+
- `pactjs-utils-request-filter.md` — Auth injection for provider verification
|
|
756
|
+
- `pact-broker-webhooks.md` — PactFlow → GitHub webhook auth pattern (dedicated user, classic PAT, PactFlow secret) and staleness monitoring
|
|
757
|
+
- `contract-testing.md` — Foundational CDC patterns and resilience coverage
|