@raishin/vanguard-frontier-agentic 3.0.2 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +36 -1
- package/.cursor-plugin/plugin.json +36 -1
- package/.github/plugin/marketplace.json +1 -1
- package/README.md +12 -11
- package/agents/frontend/accessibility-wcag-agent/AGENT.md +137 -0
- package/agents/frontend/accessibility-wcag-agent/harnesses/claude-code.agent.md +119 -0
- package/agents/frontend/accessibility-wcag-agent/harnesses/codex.toml +42 -0
- package/agents/frontend/accessibility-wcag-agent/harnesses/copilot.agent.md +129 -0
- package/agents/frontend/accessibility-wcag-agent/harnesses/cursor.agent.md +122 -0
- package/agents/frontend/accessibility-wcag-agent/harnesses/gemini.agent.md +121 -0
- package/agents/frontend/accessibility-wcag-agent/harnesses/kiro-cli.agent.json +5 -0
- package/agents/frontend/accessibility-wcag-agent/harnesses/kiro-ide.agent.md +120 -0
- package/agents/frontend/accessibility-wcag-agent/metadata.json +42 -0
- package/agents/frontend/ai-assisted-frontend-review-agent/AGENT.md +121 -0
- package/agents/frontend/ai-assisted-frontend-review-agent/harnesses/claude-code.agent.md +104 -0
- package/agents/frontend/ai-assisted-frontend-review-agent/harnesses/codex.toml +39 -0
- package/agents/frontend/ai-assisted-frontend-review-agent/harnesses/copilot.agent.md +113 -0
- package/agents/frontend/ai-assisted-frontend-review-agent/harnesses/cursor.agent.md +106 -0
- package/agents/frontend/ai-assisted-frontend-review-agent/harnesses/gemini.agent.md +105 -0
- package/agents/frontend/ai-assisted-frontend-review-agent/harnesses/kiro-cli.agent.json +5 -0
- package/agents/frontend/ai-assisted-frontend-review-agent/harnesses/kiro-ide.agent.md +104 -0
- package/agents/frontend/ai-assisted-frontend-review-agent/metadata.json +39 -0
- package/agents/frontend/angular-specialist-agent/AGENT.md +128 -0
- package/agents/frontend/angular-specialist-agent/harnesses/claude-code.agent.md +101 -0
- package/agents/frontend/angular-specialist-agent/harnesses/codex.toml +48 -0
- package/agents/frontend/angular-specialist-agent/harnesses/copilot.agent.md +110 -0
- package/agents/frontend/angular-specialist-agent/harnesses/cursor.agent.md +103 -0
- package/agents/frontend/angular-specialist-agent/harnesses/gemini.agent.md +102 -0
- package/agents/frontend/angular-specialist-agent/harnesses/kiro-cli.agent.json +5 -0
- package/agents/frontend/angular-specialist-agent/harnesses/kiro-ide.agent.md +101 -0
- package/agents/frontend/angular-specialist-agent/metadata.json +44 -0
- package/agents/frontend/api-integration-bff-agent/AGENT.md +124 -0
- package/agents/frontend/api-integration-bff-agent/harnesses/claude-code.agent.md +107 -0
- package/agents/frontend/api-integration-bff-agent/harnesses/codex.toml +40 -0
- package/agents/frontend/api-integration-bff-agent/harnesses/copilot.agent.md +116 -0
- package/agents/frontend/api-integration-bff-agent/harnesses/cursor.agent.md +109 -0
- package/agents/frontend/api-integration-bff-agent/harnesses/gemini.agent.md +108 -0
- package/agents/frontend/api-integration-bff-agent/harnesses/kiro-cli.agent.json +5 -0
- package/agents/frontend/api-integration-bff-agent/harnesses/kiro-ide.agent.md +107 -0
- package/agents/frontend/api-integration-bff-agent/metadata.json +40 -0
- package/agents/frontend/browser-compatibility-agent/AGENT.md +133 -0
- package/agents/frontend/browser-compatibility-agent/harnesses/claude-code.agent.md +116 -0
- package/agents/frontend/browser-compatibility-agent/harnesses/codex.toml +39 -0
- package/agents/frontend/browser-compatibility-agent/harnesses/copilot.agent.md +125 -0
- package/agents/frontend/browser-compatibility-agent/harnesses/cursor.agent.md +118 -0
- package/agents/frontend/browser-compatibility-agent/harnesses/gemini.agent.md +117 -0
- package/agents/frontend/browser-compatibility-agent/harnesses/kiro-cli.agent.json +5 -0
- package/agents/frontend/browser-compatibility-agent/harnesses/kiro-ide.agent.md +116 -0
- package/agents/frontend/browser-compatibility-agent/metadata.json +42 -0
- package/agents/frontend/build-tooling-bundling-agent/AGENT.md +121 -0
- package/agents/frontend/build-tooling-bundling-agent/harnesses/claude-code.agent.md +104 -0
- package/agents/frontend/build-tooling-bundling-agent/harnesses/codex.toml +40 -0
- package/agents/frontend/build-tooling-bundling-agent/harnesses/copilot.agent.md +113 -0
- package/agents/frontend/build-tooling-bundling-agent/harnesses/cursor.agent.md +106 -0
- package/agents/frontend/build-tooling-bundling-agent/harnesses/gemini.agent.md +105 -0
- package/agents/frontend/build-tooling-bundling-agent/harnesses/kiro-cli.agent.json +5 -0
- package/agents/frontend/build-tooling-bundling-agent/harnesses/kiro-ide.agent.md +104 -0
- package/agents/frontend/build-tooling-bundling-agent/metadata.json +39 -0
- package/agents/frontend/css-architecture-agent/AGENT.md +123 -0
- package/agents/frontend/css-architecture-agent/harnesses/claude-code.agent.md +106 -0
- package/agents/frontend/css-architecture-agent/harnesses/codex.toml +41 -0
- package/agents/frontend/css-architecture-agent/harnesses/copilot.agent.md +115 -0
- package/agents/frontend/css-architecture-agent/harnesses/cursor.agent.md +108 -0
- package/agents/frontend/css-architecture-agent/harnesses/gemini.agent.md +107 -0
- package/agents/frontend/css-architecture-agent/harnesses/kiro-cli.agent.json +5 -0
- package/agents/frontend/css-architecture-agent/harnesses/kiro-ide.agent.md +106 -0
- package/agents/frontend/css-architecture-agent/metadata.json +42 -0
- package/agents/frontend/design-systems-governance-agent/AGENT.md +124 -0
- package/agents/frontend/design-systems-governance-agent/harnesses/claude-code.agent.md +107 -0
- package/agents/frontend/design-systems-governance-agent/harnesses/codex.toml +41 -0
- package/agents/frontend/design-systems-governance-agent/harnesses/copilot.agent.md +116 -0
- package/agents/frontend/design-systems-governance-agent/harnesses/cursor.agent.md +109 -0
- package/agents/frontend/design-systems-governance-agent/harnesses/gemini.agent.md +108 -0
- package/agents/frontend/design-systems-governance-agent/harnesses/kiro-cli.agent.json +5 -0
- package/agents/frontend/design-systems-governance-agent/harnesses/kiro-ide.agent.md +107 -0
- package/agents/frontend/design-systems-governance-agent/metadata.json +41 -0
- package/agents/frontend/enterprise-red-team-review-agent/AGENT.md +140 -0
- package/agents/frontend/enterprise-red-team-review-agent/harnesses/claude-code.agent.md +91 -0
- package/agents/frontend/enterprise-red-team-review-agent/harnesses/codex.toml +48 -0
- package/agents/frontend/enterprise-red-team-review-agent/harnesses/copilot.agent.md +100 -0
- package/agents/frontend/enterprise-red-team-review-agent/harnesses/cursor.agent.md +93 -0
- package/agents/frontend/enterprise-red-team-review-agent/harnesses/gemini.agent.md +92 -0
- package/agents/frontend/enterprise-red-team-review-agent/harnesses/kiro-cli.agent.json +5 -0
- package/agents/frontend/enterprise-red-team-review-agent/harnesses/kiro-ide.agent.md +91 -0
- package/agents/frontend/enterprise-red-team-review-agent/metadata.json +39 -0
- package/agents/frontend/frontend-board-chair-agent/AGENT.md +94 -0
- package/agents/frontend/frontend-board-chair-agent/harnesses/claude-code.agent.md +55 -0
- package/agents/frontend/frontend-board-chair-agent/harnesses/codex.toml +33 -0
- package/agents/frontend/frontend-board-chair-agent/harnesses/copilot.agent.md +34 -0
- package/agents/frontend/frontend-board-chair-agent/harnesses/cursor.agent.md +57 -0
- package/agents/frontend/frontend-board-chair-agent/harnesses/gemini.agent.md +56 -0
- package/agents/frontend/frontend-board-chair-agent/harnesses/kiro-cli.agent.json +1 -0
- package/agents/frontend/frontend-board-chair-agent/harnesses/kiro-ide.agent.md +55 -0
- package/agents/frontend/frontend-board-chair-agent/metadata.json +41 -0
- package/agents/frontend/frontend-finops-cost-to-serve-agent/AGENT.md +123 -0
- package/agents/frontend/frontend-finops-cost-to-serve-agent/harnesses/claude-code.agent.md +106 -0
- package/agents/frontend/frontend-finops-cost-to-serve-agent/harnesses/codex.toml +40 -0
- package/agents/frontend/frontend-finops-cost-to-serve-agent/harnesses/copilot.agent.md +115 -0
- package/agents/frontend/frontend-finops-cost-to-serve-agent/harnesses/cursor.agent.md +108 -0
- package/agents/frontend/frontend-finops-cost-to-serve-agent/harnesses/gemini.agent.md +107 -0
- package/agents/frontend/frontend-finops-cost-to-serve-agent/harnesses/kiro-cli.agent.json +5 -0
- package/agents/frontend/frontend-finops-cost-to-serve-agent/harnesses/kiro-ide.agent.md +106 -0
- package/agents/frontend/frontend-finops-cost-to-serve-agent/metadata.json +40 -0
- package/agents/frontend/frontend-maestro-agent/AGENT.md +91 -0
- package/agents/frontend/frontend-maestro-agent/harnesses/claude-code.agent.md +38 -0
- package/agents/frontend/frontend-maestro-agent/harnesses/codex.toml +34 -0
- package/agents/frontend/frontend-maestro-agent/harnesses/copilot.agent.md +51 -0
- package/agents/frontend/frontend-maestro-agent/harnesses/cursor.agent.md +40 -0
- package/agents/frontend/frontend-maestro-agent/harnesses/gemini.agent.md +39 -0
- package/agents/frontend/frontend-maestro-agent/harnesses/kiro-cli.agent.json +5 -0
- package/agents/frontend/frontend-maestro-agent/harnesses/kiro-ide.agent.md +38 -0
- package/agents/frontend/frontend-maestro-agent/metadata.json +40 -0
- package/agents/frontend/frontend-migration-modernization-agent/AGENT.md +140 -0
- package/agents/frontend/frontend-migration-modernization-agent/harnesses/claude-code.agent.md +123 -0
- package/agents/frontend/frontend-migration-modernization-agent/harnesses/codex.toml +46 -0
- package/agents/frontend/frontend-migration-modernization-agent/harnesses/copilot.agent.md +132 -0
- package/agents/frontend/frontend-migration-modernization-agent/harnesses/cursor.agent.md +125 -0
- package/agents/frontend/frontend-migration-modernization-agent/harnesses/gemini.agent.md +124 -0
- package/agents/frontend/frontend-migration-modernization-agent/harnesses/kiro-cli.agent.json +5 -0
- package/agents/frontend/frontend-migration-modernization-agent/harnesses/kiro-ide.agent.md +123 -0
- package/agents/frontend/frontend-migration-modernization-agent/metadata.json +40 -0
- package/agents/frontend/frontend-observability-rum-agent/AGENT.md +131 -0
- package/agents/frontend/frontend-observability-rum-agent/harnesses/claude-code.agent.md +114 -0
- package/agents/frontend/frontend-observability-rum-agent/harnesses/codex.toml +40 -0
- package/agents/frontend/frontend-observability-rum-agent/harnesses/copilot.agent.md +124 -0
- package/agents/frontend/frontend-observability-rum-agent/harnesses/cursor.agent.md +117 -0
- package/agents/frontend/frontend-observability-rum-agent/harnesses/gemini.agent.md +116 -0
- package/agents/frontend/frontend-observability-rum-agent/harnesses/kiro-cli.agent.json +5 -0
- package/agents/frontend/frontend-observability-rum-agent/harnesses/kiro-ide.agent.md +115 -0
- package/agents/frontend/frontend-observability-rum-agent/metadata.json +43 -0
- package/agents/frontend/frontend-platform-architect-agent/AGENT.md +139 -0
- package/agents/frontend/frontend-platform-architect-agent/harnesses/claude-code.agent.md +122 -0
- package/agents/frontend/frontend-platform-architect-agent/harnesses/codex.toml +44 -0
- package/agents/frontend/frontend-platform-architect-agent/harnesses/copilot.agent.md +133 -0
- package/agents/frontend/frontend-platform-architect-agent/harnesses/cursor.agent.md +124 -0
- package/agents/frontend/frontend-platform-architect-agent/harnesses/gemini.agent.md +123 -0
- package/agents/frontend/frontend-platform-architect-agent/harnesses/kiro-cli.agent.json +5 -0
- package/agents/frontend/frontend-platform-architect-agent/harnesses/kiro-ide.agent.md +122 -0
- package/agents/frontend/frontend-platform-architect-agent/metadata.json +40 -0
- package/agents/frontend/frontend-security-agent/AGENT.md +123 -0
- package/agents/frontend/frontend-security-agent/harnesses/claude-code.agent.md +106 -0
- package/agents/frontend/frontend-security-agent/harnesses/codex.toml +40 -0
- package/agents/frontend/frontend-security-agent/harnesses/copilot.agent.md +115 -0
- package/agents/frontend/frontend-security-agent/harnesses/cursor.agent.md +108 -0
- package/agents/frontend/frontend-security-agent/harnesses/gemini.agent.md +107 -0
- package/agents/frontend/frontend-security-agent/harnesses/kiro-cli.agent.json +5 -0
- package/agents/frontend/frontend-security-agent/harnesses/kiro-ide.agent.md +106 -0
- package/agents/frontend/frontend-security-agent/metadata.json +44 -0
- package/agents/frontend/html-semantics-agent/AGENT.md +139 -0
- package/agents/frontend/html-semantics-agent/harnesses/claude-code.agent.md +122 -0
- package/agents/frontend/html-semantics-agent/harnesses/codex.toml +44 -0
- package/agents/frontend/html-semantics-agent/harnesses/copilot.agent.md +132 -0
- package/agents/frontend/html-semantics-agent/harnesses/cursor.agent.md +125 -0
- package/agents/frontend/html-semantics-agent/harnesses/gemini.agent.md +124 -0
- package/agents/frontend/html-semantics-agent/harnesses/kiro-cli.agent.json +5 -0
- package/agents/frontend/html-semantics-agent/harnesses/kiro-ide.agent.md +123 -0
- package/agents/frontend/html-semantics-agent/metadata.json +44 -0
- package/agents/frontend/internationalization-localization-agent/AGENT.md +115 -0
- package/agents/frontend/internationalization-localization-agent/harnesses/claude-code.agent.md +98 -0
- package/agents/frontend/internationalization-localization-agent/harnesses/codex.toml +40 -0
- package/agents/frontend/internationalization-localization-agent/harnesses/copilot.agent.md +107 -0
- package/agents/frontend/internationalization-localization-agent/harnesses/cursor.agent.md +100 -0
- package/agents/frontend/internationalization-localization-agent/harnesses/gemini.agent.md +99 -0
- package/agents/frontend/internationalization-localization-agent/harnesses/kiro-cli.agent.json +5 -0
- package/agents/frontend/internationalization-localization-agent/harnesses/kiro-ide.agent.md +98 -0
- package/agents/frontend/internationalization-localization-agent/metadata.json +42 -0
- package/agents/frontend/javascript-runtime-agent/AGENT.md +121 -0
- package/agents/frontend/javascript-runtime-agent/harnesses/claude-code.agent.md +104 -0
- package/agents/frontend/javascript-runtime-agent/harnesses/codex.toml +41 -0
- package/agents/frontend/javascript-runtime-agent/harnesses/copilot.agent.md +113 -0
- package/agents/frontend/javascript-runtime-agent/harnesses/cursor.agent.md +106 -0
- package/agents/frontend/javascript-runtime-agent/harnesses/gemini.agent.md +105 -0
- package/agents/frontend/javascript-runtime-agent/harnesses/kiro-cli.agent.json +5 -0
- package/agents/frontend/javascript-runtime-agent/harnesses/kiro-ide.agent.md +104 -0
- package/agents/frontend/javascript-runtime-agent/metadata.json +41 -0
- package/agents/frontend/monorepo-dx-agent/AGENT.md +111 -0
- package/agents/frontend/monorepo-dx-agent/harnesses/claude-code.agent.md +94 -0
- package/agents/frontend/monorepo-dx-agent/harnesses/codex.toml +38 -0
- package/agents/frontend/monorepo-dx-agent/harnesses/copilot.agent.md +103 -0
- package/agents/frontend/monorepo-dx-agent/harnesses/cursor.agent.md +96 -0
- package/agents/frontend/monorepo-dx-agent/harnesses/gemini.agent.md +95 -0
- package/agents/frontend/monorepo-dx-agent/harnesses/kiro-cli.agent.json +5 -0
- package/agents/frontend/monorepo-dx-agent/harnesses/kiro-ide.agent.md +94 -0
- package/agents/frontend/monorepo-dx-agent/metadata.json +41 -0
- package/agents/frontend/nextjs-specialist-agent/AGENT.md +122 -0
- package/agents/frontend/nextjs-specialist-agent/harnesses/claude-code.agent.md +105 -0
- package/agents/frontend/nextjs-specialist-agent/harnesses/codex.toml +45 -0
- package/agents/frontend/nextjs-specialist-agent/harnesses/copilot.agent.md +114 -0
- package/agents/frontend/nextjs-specialist-agent/harnesses/cursor.agent.md +107 -0
- package/agents/frontend/nextjs-specialist-agent/harnesses/gemini.agent.md +106 -0
- package/agents/frontend/nextjs-specialist-agent/harnesses/kiro-cli.agent.json +5 -0
- package/agents/frontend/nextjs-specialist-agent/harnesses/kiro-ide.agent.md +105 -0
- package/agents/frontend/nextjs-specialist-agent/metadata.json +43 -0
- package/agents/frontend/package-governance-agent/AGENT.md +116 -0
- package/agents/frontend/package-governance-agent/harnesses/claude-code.agent.md +99 -0
- package/agents/frontend/package-governance-agent/harnesses/codex.toml +39 -0
- package/agents/frontend/package-governance-agent/harnesses/copilot.agent.md +108 -0
- package/agents/frontend/package-governance-agent/harnesses/cursor.agent.md +101 -0
- package/agents/frontend/package-governance-agent/harnesses/gemini.agent.md +100 -0
- package/agents/frontend/package-governance-agent/harnesses/kiro-cli.agent.json +5 -0
- package/agents/frontend/package-governance-agent/harnesses/kiro-ide.agent.md +99 -0
- package/agents/frontend/package-governance-agent/metadata.json +41 -0
- package/agents/frontend/product-analytics-experimentation-agent/AGENT.md +133 -0
- package/agents/frontend/product-analytics-experimentation-agent/harnesses/claude-code.agent.md +116 -0
- package/agents/frontend/product-analytics-experimentation-agent/harnesses/codex.toml +45 -0
- package/agents/frontend/product-analytics-experimentation-agent/harnesses/copilot.agent.md +126 -0
- package/agents/frontend/product-analytics-experimentation-agent/harnesses/cursor.agent.md +119 -0
- package/agents/frontend/product-analytics-experimentation-agent/harnesses/gemini.agent.md +118 -0
- package/agents/frontend/product-analytics-experimentation-agent/harnesses/kiro-cli.agent.json +5 -0
- package/agents/frontend/product-analytics-experimentation-agent/harnesses/kiro-ide.agent.md +117 -0
- package/agents/frontend/product-analytics-experimentation-agent/metadata.json +40 -0
- package/agents/frontend/pwa-offline-capability-agent/AGENT.md +117 -0
- package/agents/frontend/pwa-offline-capability-agent/harnesses/claude-code.agent.md +100 -0
- package/agents/frontend/pwa-offline-capability-agent/harnesses/codex.toml +40 -0
- package/agents/frontend/pwa-offline-capability-agent/harnesses/copilot.agent.md +109 -0
- package/agents/frontend/pwa-offline-capability-agent/harnesses/cursor.agent.md +102 -0
- package/agents/frontend/pwa-offline-capability-agent/harnesses/gemini.agent.md +101 -0
- package/agents/frontend/pwa-offline-capability-agent/harnesses/kiro-cli.agent.json +5 -0
- package/agents/frontend/pwa-offline-capability-agent/harnesses/kiro-ide.agent.md +100 -0
- package/agents/frontend/pwa-offline-capability-agent/metadata.json +42 -0
- package/agents/frontend/react-specialist-agent/AGENT.md +124 -0
- package/agents/frontend/react-specialist-agent/harnesses/claude-code.agent.md +107 -0
- package/agents/frontend/react-specialist-agent/harnesses/codex.toml +47 -0
- package/agents/frontend/react-specialist-agent/harnesses/copilot.agent.md +116 -0
- package/agents/frontend/react-specialist-agent/harnesses/cursor.agent.md +109 -0
- package/agents/frontend/react-specialist-agent/harnesses/gemini.agent.md +108 -0
- package/agents/frontend/react-specialist-agent/harnesses/kiro-cli.agent.json +5 -0
- package/agents/frontend/react-specialist-agent/harnesses/kiro-ide.agent.md +107 -0
- package/agents/frontend/react-specialist-agent/metadata.json +44 -0
- package/agents/frontend/routing-navigation-agent/AGENT.md +123 -0
- package/agents/frontend/routing-navigation-agent/harnesses/claude-code.agent.md +106 -0
- package/agents/frontend/routing-navigation-agent/harnesses/codex.toml +40 -0
- package/agents/frontend/routing-navigation-agent/harnesses/copilot.agent.md +115 -0
- package/agents/frontend/routing-navigation-agent/harnesses/cursor.agent.md +108 -0
- package/agents/frontend/routing-navigation-agent/harnesses/gemini.agent.md +107 -0
- package/agents/frontend/routing-navigation-agent/harnesses/kiro-cli.agent.json +5 -0
- package/agents/frontend/routing-navigation-agent/harnesses/kiro-ide.agent.md +106 -0
- package/agents/frontend/routing-navigation-agent/metadata.json +40 -0
- package/agents/frontend/ssr-hydration-streaming-agent/AGENT.md +123 -0
- package/agents/frontend/ssr-hydration-streaming-agent/harnesses/claude-code.agent.md +106 -0
- package/agents/frontend/ssr-hydration-streaming-agent/harnesses/codex.toml +41 -0
- package/agents/frontend/ssr-hydration-streaming-agent/harnesses/copilot.agent.md +116 -0
- package/agents/frontend/ssr-hydration-streaming-agent/harnesses/cursor.agent.md +109 -0
- package/agents/frontend/ssr-hydration-streaming-agent/harnesses/gemini.agent.md +108 -0
- package/agents/frontend/ssr-hydration-streaming-agent/harnesses/kiro-cli.agent.json +5 -0
- package/agents/frontend/ssr-hydration-streaming-agent/harnesses/kiro-ide.agent.md +107 -0
- package/agents/frontend/ssr-hydration-streaming-agent/metadata.json +40 -0
- package/agents/frontend/state-management-data-flow-agent/AGENT.md +126 -0
- package/agents/frontend/state-management-data-flow-agent/harnesses/claude-code.agent.md +109 -0
- package/agents/frontend/state-management-data-flow-agent/harnesses/codex.toml +41 -0
- package/agents/frontend/state-management-data-flow-agent/harnesses/copilot.agent.md +118 -0
- package/agents/frontend/state-management-data-flow-agent/harnesses/cursor.agent.md +111 -0
- package/agents/frontend/state-management-data-flow-agent/harnesses/gemini.agent.md +110 -0
- package/agents/frontend/state-management-data-flow-agent/harnesses/kiro-cli.agent.json +5 -0
- package/agents/frontend/state-management-data-flow-agent/harnesses/kiro-ide.agent.md +109 -0
- package/agents/frontend/state-management-data-flow-agent/metadata.json +40 -0
- package/agents/frontend/svelte-sveltekit-specialist-agent/AGENT.md +121 -0
- package/agents/frontend/svelte-sveltekit-specialist-agent/harnesses/claude-code.agent.md +104 -0
- package/agents/frontend/svelte-sveltekit-specialist-agent/harnesses/codex.toml +44 -0
- package/agents/frontend/svelte-sveltekit-specialist-agent/harnesses/copilot.agent.md +113 -0
- package/agents/frontend/svelte-sveltekit-specialist-agent/harnesses/cursor.agent.md +106 -0
- package/agents/frontend/svelte-sveltekit-specialist-agent/harnesses/gemini.agent.md +105 -0
- package/agents/frontend/svelte-sveltekit-specialist-agent/harnesses/kiro-cli.agent.json +1 -0
- package/agents/frontend/svelte-sveltekit-specialist-agent/harnesses/kiro-ide.agent.md +104 -0
- package/agents/frontend/svelte-sveltekit-specialist-agent/metadata.json +43 -0
- package/agents/frontend/testing-quality-engineering-agent/AGENT.md +120 -0
- package/agents/frontend/testing-quality-engineering-agent/harnesses/claude-code.agent.md +103 -0
- package/agents/frontend/testing-quality-engineering-agent/harnesses/codex.toml +41 -0
- package/agents/frontend/testing-quality-engineering-agent/harnesses/copilot.agent.md +112 -0
- package/agents/frontend/testing-quality-engineering-agent/harnesses/cursor.agent.md +105 -0
- package/agents/frontend/testing-quality-engineering-agent/harnesses/gemini.agent.md +104 -0
- package/agents/frontend/testing-quality-engineering-agent/harnesses/kiro-cli.agent.json +5 -0
- package/agents/frontend/testing-quality-engineering-agent/harnesses/kiro-ide.agent.md +103 -0
- package/agents/frontend/testing-quality-engineering-agent/metadata.json +42 -0
- package/agents/frontend/typescript-contracts-agent/AGENT.md +122 -0
- package/agents/frontend/typescript-contracts-agent/harnesses/claude-code.agent.md +105 -0
- package/agents/frontend/typescript-contracts-agent/harnesses/codex.toml +39 -0
- package/agents/frontend/typescript-contracts-agent/harnesses/copilot.agent.md +114 -0
- package/agents/frontend/typescript-contracts-agent/harnesses/cursor.agent.md +107 -0
- package/agents/frontend/typescript-contracts-agent/harnesses/gemini.agent.md +106 -0
- package/agents/frontend/typescript-contracts-agent/harnesses/kiro-cli.agent.json +5 -0
- package/agents/frontend/typescript-contracts-agent/harnesses/kiro-ide.agent.md +105 -0
- package/agents/frontend/typescript-contracts-agent/metadata.json +41 -0
- package/agents/frontend/visual-regression-agent/AGENT.md +123 -0
- package/agents/frontend/visual-regression-agent/harnesses/claude-code.agent.md +106 -0
- package/agents/frontend/visual-regression-agent/harnesses/codex.toml +40 -0
- package/agents/frontend/visual-regression-agent/harnesses/copilot.agent.md +115 -0
- package/agents/frontend/visual-regression-agent/harnesses/cursor.agent.md +108 -0
- package/agents/frontend/visual-regression-agent/harnesses/gemini.agent.md +107 -0
- package/agents/frontend/visual-regression-agent/harnesses/kiro-cli.agent.json +5 -0
- package/agents/frontend/visual-regression-agent/harnesses/kiro-ide.agent.md +106 -0
- package/agents/frontend/visual-regression-agent/metadata.json +41 -0
- package/agents/frontend/vue-specialist-agent/AGENT.md +126 -0
- package/agents/frontend/vue-specialist-agent/harnesses/claude-code.agent.md +109 -0
- package/agents/frontend/vue-specialist-agent/harnesses/codex.toml +61 -0
- package/agents/frontend/vue-specialist-agent/harnesses/copilot.agent.md +118 -0
- package/agents/frontend/vue-specialist-agent/harnesses/cursor.agent.md +111 -0
- package/agents/frontend/vue-specialist-agent/harnesses/gemini.agent.md +110 -0
- package/agents/frontend/vue-specialist-agent/harnesses/kiro-cli.agent.json +5 -0
- package/agents/frontend/vue-specialist-agent/harnesses/kiro-ide.agent.md +109 -0
- package/agents/frontend/vue-specialist-agent/metadata.json +45 -0
- package/agents/frontend/web-performance-core-vitals-agent/AGENT.md +124 -0
- package/agents/frontend/web-performance-core-vitals-agent/harnesses/claude-code.agent.md +107 -0
- package/agents/frontend/web-performance-core-vitals-agent/harnesses/codex.toml +41 -0
- package/agents/frontend/web-performance-core-vitals-agent/harnesses/copilot.agent.md +117 -0
- package/agents/frontend/web-performance-core-vitals-agent/harnesses/cursor.agent.md +110 -0
- package/agents/frontend/web-performance-core-vitals-agent/harnesses/gemini.agent.md +109 -0
- package/agents/frontend/web-performance-core-vitals-agent/harnesses/kiro-cli.agent.json +5 -0
- package/agents/frontend/web-performance-core-vitals-agent/harnesses/kiro-ide.agent.md +108 -0
- package/agents/frontend/web-performance-core-vitals-agent/metadata.json +45 -0
- package/agents/frontend/web-platform-foundation-agent/AGENT.md +117 -0
- package/agents/frontend/web-platform-foundation-agent/harnesses/claude-code.agent.md +100 -0
- package/agents/frontend/web-platform-foundation-agent/harnesses/codex.toml +40 -0
- package/agents/frontend/web-platform-foundation-agent/harnesses/copilot.agent.md +109 -0
- package/agents/frontend/web-platform-foundation-agent/harnesses/cursor.agent.md +102 -0
- package/agents/frontend/web-platform-foundation-agent/harnesses/gemini.agent.md +101 -0
- package/agents/frontend/web-platform-foundation-agent/harnesses/kiro-cli.agent.json +5 -0
- package/agents/frontend/web-platform-foundation-agent/harnesses/kiro-ide.agent.md +100 -0
- package/agents/frontend/web-platform-foundation-agent/metadata.json +41 -0
- package/catalog/agents.json +1164 -93
- package/catalog/asset-integrity.json +15389 -12589
- package/catalog/install-roles.json +103 -1
- package/catalog/skill-manifest.json +1909 -26
- package/catalog/skills.json +1672 -24
- package/package.json +3 -2
- package/plugins/vanguard-frontier-agentic/.codex-plugin/plugin.json +1 -1
- package/powers/README.md +3 -2
- package/powers/vanguard-frontend/POWER.md +42 -0
- package/schemas/agent.schema.json +1 -0
- package/schemas/skill.schema.json +1 -0
- package/scripts/generate-docs-data.mjs +1 -0
- package/scripts/generate-kiro-powers.mjs +12 -0
- package/scripts/update-catalog-new-agents.py +6 -1
- package/skills/frontend/ai-generated-frontend-code-review/SKILL.md +68 -0
- package/skills/frontend/ai-generated-frontend-code-review/metadata.json +27 -0
- package/skills/frontend/ai-generated-frontend-code-review/references/generated-a11y-gap-audit.md +55 -0
- package/skills/frontend/ai-generated-frontend-code-review/references/hallucinated-api-verification.md +56 -0
- package/skills/frontend/ai-generated-frontend-code-review/references/slopsquat-dependency-check.md +49 -0
- package/skills/frontend/angular-architecture-signals-review/SKILL.md +80 -0
- package/skills/frontend/angular-architecture-signals-review/metadata.json +28 -0
- package/skills/frontend/angular-architecture-signals-review/references/linked-signal-and-di-boundaries.md +46 -0
- package/skills/frontend/angular-architecture-signals-review/references/workflow-and-output.md +99 -0
- package/skills/frontend/angular-ssr-hydration-review/SKILL.md +77 -0
- package/skills/frontend/angular-ssr-hydration-review/metadata.json +28 -0
- package/skills/frontend/angular-ssr-hydration-review/references/i18n-event-replay-and-third-party-libs.md +50 -0
- package/skills/frontend/angular-ssr-hydration-review/references/workflow-and-output.md +101 -0
- package/skills/frontend/angular-template-sanitizer-security-review/SKILL.md +69 -0
- package/skills/frontend/angular-template-sanitizer-security-review/metadata.json +27 -0
- package/skills/frontend/angular-template-sanitizer-security-review/references/iframe-security-attributes.md +63 -0
- package/skills/frontend/angular-template-sanitizer-security-review/references/sanitizer-bypass-and-innerhtml.md +93 -0
- package/skills/frontend/angular-template-sanitizer-security-review/references/workflow-and-output.md +45 -0
- package/skills/frontend/api-integration-contract-review/SKILL.md +72 -0
- package/skills/frontend/api-integration-contract-review/metadata.json +27 -0
- package/skills/frontend/api-integration-contract-review/references/authorization-and-data-minimization.md +73 -0
- package/skills/frontend/api-integration-contract-review/references/error-shape-cors-versioning.md +65 -0
- package/skills/frontend/api-integration-contract-review/references/workflow-and-output.md +38 -0
- package/skills/frontend/browser-compatibility-review/SKILL.md +68 -0
- package/skills/frontend/browser-compatibility-review/metadata.json +27 -0
- package/skills/frontend/browser-compatibility-review/references/baseline-status-model.md +45 -0
- package/skills/frontend/browser-compatibility-review/references/browserslist-matrix-interpretation.md +49 -0
- package/skills/frontend/browser-compatibility-review/references/fallback-verification-patterns.md +54 -0
- package/skills/frontend/build-tooling-vite-webpack-review/SKILL.md +76 -0
- package/skills/frontend/build-tooling-vite-webpack-review/metadata.json +27 -0
- package/skills/frontend/build-tooling-vite-webpack-review/references/migration-and-config-diff-safety.md +41 -0
- package/skills/frontend/build-tooling-vite-webpack-review/references/vite-chunking-config.md +68 -0
- package/skills/frontend/build-tooling-vite-webpack-review/references/webpack-splitchunks-config.md +84 -0
- package/skills/frontend/bundle-budget-code-splitting-review/SKILL.md +76 -0
- package/skills/frontend/bundle-budget-code-splitting-review/metadata.json +29 -0
- package/skills/frontend/bundle-budget-code-splitting-review/references/budget-methodology.md +36 -0
- package/skills/frontend/bundle-budget-code-splitting-review/references/bundler-chunking-apis.md +116 -0
- package/skills/frontend/bundle-budget-code-splitting-review/references/ci-enforcement-and-verification.md +53 -0
- package/skills/frontend/bundle-budget-code-splitting-review/references/code-splitting-boundaries.md +46 -0
- package/skills/frontend/core-web-vitals-triage/SKILL.md +75 -0
- package/skills/frontend/core-web-vitals-triage/metadata.json +33 -0
- package/skills/frontend/core-web-vitals-triage/references/cls-attribution.md +45 -0
- package/skills/frontend/core-web-vitals-triage/references/evidence-tiers-and-handoff.md +57 -0
- package/skills/frontend/core-web-vitals-triage/references/inp-phase-decomposition.md +49 -0
- package/skills/frontend/core-web-vitals-triage/references/lcp-phase-decomposition.md +51 -0
- package/skills/frontend/critical-rendering-path-review/SKILL.md +67 -0
- package/skills/frontend/critical-rendering-path-review/metadata.json +31 -0
- package/skills/frontend/critical-rendering-path-review/references/lab-vs-field-evidence.md +60 -0
- package/skills/frontend/critical-rendering-path-review/references/layout-shift-sources.md +68 -0
- package/skills/frontend/critical-rendering-path-review/references/resource-loading-order.md +79 -0
- package/skills/frontend/css-architecture-design-system-review/SKILL.md +71 -0
- package/skills/frontend/css-architecture-design-system-review/metadata.json +30 -0
- package/skills/frontend/css-architecture-design-system-review/references/cascade-layer-strategy.md +64 -0
- package/skills/frontend/css-architecture-design-system-review/references/responsive-strategy.md +63 -0
- package/skills/frontend/css-architecture-design-system-review/references/token-conformance.md +58 -0
- package/skills/frontend/design-token-governance-review/SKILL.md +64 -0
- package/skills/frontend/design-token-governance-review/metadata.json +27 -0
- package/skills/frontend/design-token-governance-review/references/contrast-compliance-review.md +90 -0
- package/skills/frontend/design-token-governance-review/references/token-source-and-pipeline-review.md +97 -0
- package/skills/frontend/e2e-testing-playwright-review/SKILL.md +65 -0
- package/skills/frontend/e2e-testing-playwright-review/metadata.json +28 -0
- package/skills/frontend/e2e-testing-playwright-review/references/ci-sharding-and-parallelism.md +24 -0
- package/skills/frontend/e2e-testing-playwright-review/references/fixtures-and-auth-setup.md +26 -0
- package/skills/frontend/e2e-testing-playwright-review/references/visual-assertion-tuning.md +28 -0
- package/skills/frontend/edge-cache-data-bleed-review/SKILL.md +71 -0
- package/skills/frontend/edge-cache-data-bleed-review/metadata.json +28 -0
- package/skills/frontend/edge-cache-data-bleed-review/references/cache-control-and-vary-headers.md +59 -0
- package/skills/frontend/edge-cache-data-bleed-review/references/caching-directives-and-route-config.md +59 -0
- package/skills/frontend/edge-cache-data-bleed-review/references/workflow-and-output.md +47 -0
- package/skills/frontend/enterprise-red-team-review/SKILL.md +69 -0
- package/skills/frontend/enterprise-red-team-review/metadata.json +27 -0
- package/skills/frontend/enterprise-red-team-review/references/a11y-checklist.md +36 -0
- package/skills/frontend/enterprise-red-team-review/references/ai-code-review.md +44 -0
- package/skills/frontend/enterprise-red-team-review/references/security-checklist.md +43 -0
- package/skills/frontend/framework-upgrade-risk-review/SKILL.md +69 -0
- package/skills/frontend/framework-upgrade-risk-review/metadata.json +27 -0
- package/skills/frontend/framework-upgrade-risk-review/references/breaking-change-triage.md +58 -0
- package/skills/frontend/framework-upgrade-risk-review/references/dependency-compatibility-matrix.md +37 -0
- package/skills/frontend/frontend-auth-session-security-review/SKILL.md +74 -0
- package/skills/frontend/frontend-auth-session-security-review/metadata.json +28 -0
- package/skills/frontend/frontend-auth-session-security-review/references/csrf-redirect-and-oauth.md +74 -0
- package/skills/frontend/frontend-auth-session-security-review/references/token-storage-and-cookies.md +49 -0
- package/skills/frontend/frontend-auth-session-security-review/references/workflow-and-output.md +63 -0
- package/skills/frontend/frontend-bff-boundary-review/SKILL.md +71 -0
- package/skills/frontend/frontend-bff-boundary-review/metadata.json +26 -0
- package/skills/frontend/frontend-bff-boundary-review/references/owasp-api-trust-boundary.md +42 -0
- package/skills/frontend/frontend-bff-boundary-review/references/workflow-and-output.md +107 -0
- package/skills/frontend/frontend-board-chair/SKILL.md +67 -0
- package/skills/frontend/frontend-board-chair/metadata.json +27 -0
- package/skills/frontend/frontend-board-chair/references/conflict-resolution.md +67 -0
- package/skills/frontend/frontend-board-chair/references/evidence-and-handoff.md +63 -0
- package/skills/frontend/frontend-board-chair/references/workflow-routing.md +86 -0
- package/skills/frontend/frontend-dom-xss-csp-review/SKILL.md +74 -0
- package/skills/frontend/frontend-dom-xss-csp-review/metadata.json +28 -0
- package/skills/frontend/frontend-dom-xss-csp-review/references/csp-directive-review.md +80 -0
- package/skills/frontend/frontend-dom-xss-csp-review/references/dom-xss-sink-source-taxonomy.md +73 -0
- package/skills/frontend/frontend-dom-xss-csp-review/references/third-party-script-governance.md +103 -0
- package/skills/frontend/frontend-dom-xss-csp-review/references/trusted-types-enforcement.md +100 -0
- package/skills/frontend/frontend-dom-xss-csp-review/references/workflow-and-output.md +51 -0
- package/skills/frontend/frontend-error-boundary-resilience-review/SKILL.md +64 -0
- package/skills/frontend/frontend-error-boundary-resilience-review/metadata.json +27 -0
- package/skills/frontend/frontend-error-boundary-resilience-review/references/boundary-placement-and-granularity.md +63 -0
- package/skills/frontend/frontend-error-boundary-resilience-review/references/fallback-ux-and-accessibility.md +61 -0
- package/skills/frontend/frontend-error-boundary-resilience-review/references/observability-and-recovery.md +62 -0
- package/skills/frontend/frontend-finops-cost-to-serve-review/SKILL.md +58 -0
- package/skills/frontend/frontend-finops-cost-to-serve-review/metadata.json +27 -0
- package/skills/frontend/frontend-finops-cost-to-serve-review/references/ssr-isr-invocation-cost-modeling.md +83 -0
- package/skills/frontend/frontend-finops-cost-to-serve-review/references/third-party-script-cost-attribution.md +70 -0
- package/skills/frontend/frontend-maestro/SKILL.md +63 -0
- package/skills/frontend/frontend-maestro/metadata.json +26 -0
- package/skills/frontend/frontend-maestro/references/official-sources.md +28 -0
- package/skills/frontend/frontend-maestro/references/routing-quality-and-safety.md +67 -0
- package/skills/frontend/frontend-maestro/references/safety-checklist.md +45 -0
- package/skills/frontend/frontend-maestro/references/workflow-and-output.md +157 -0
- package/skills/frontend/frontend-migration-modernization-plan/SKILL.md +71 -0
- package/skills/frontend/frontend-migration-modernization-plan/metadata.json +27 -0
- package/skills/frontend/frontend-migration-modernization-plan/references/rewrite-vs-incremental-decision.md +49 -0
- package/skills/frontend/frontend-migration-modernization-plan/references/rollback-and-exit-criteria.md +75 -0
- package/skills/frontend/frontend-migration-modernization-plan/references/strangler-boundary-design.md +63 -0
- package/skills/frontend/frontend-observability-rum-instrumentation/SKILL.md +72 -0
- package/skills/frontend/frontend-observability-rum-instrumentation/metadata.json +27 -0
- package/skills/frontend/frontend-observability-rum-instrumentation/references/opentelemetry-web-tracing-wiring.md +135 -0
- package/skills/frontend/frontend-observability-rum-instrumentation/references/sampling-cardinality-pii-controls.md +96 -0
- package/skills/frontend/frontend-observability-rum-instrumentation/references/web-vitals-attribution-wiring.md +87 -0
- package/skills/frontend/frontend-platform-architecture-review/SKILL.md +71 -0
- package/skills/frontend/frontend-platform-architecture-review/metadata.json +27 -0
- package/skills/frontend/frontend-platform-architecture-review/references/rendering-topology-and-budgets.md +61 -0
- package/skills/frontend/frontend-platform-architecture-review/references/workflow-and-output.md +48 -0
- package/skills/frontend/frontend-testing-strategy-review/SKILL.md +67 -0
- package/skills/frontend/frontend-testing-strategy-review/metadata.json +27 -0
- package/skills/frontend/frontend-testing-strategy-review/references/e2e-framework-review.md +39 -0
- package/skills/frontend/frontend-testing-strategy-review/references/flaky-test-governance.md +55 -0
- package/skills/frontend/frontend-testing-strategy-review/references/pyramid-shape-and-coverage.md +62 -0
- package/skills/frontend/frontend-testing-strategy-review/references/unit-component-framework-review.md +35 -0
- package/skills/frontend/graphql-client-security-review/SKILL.md +73 -0
- package/skills/frontend/graphql-client-security-review/metadata.json +29 -0
- package/skills/frontend/graphql-client-security-review/references/cache-lifecycle-and-query-surface.md +107 -0
- package/skills/frontend/graphql-client-security-review/references/devtools-and-auth-header-risk.md +83 -0
- package/skills/frontend/graphql-client-security-review/references/workflow-and-output.md +53 -0
- package/skills/frontend/html-semantics-accessibility-review/SKILL.md +66 -0
- package/skills/frontend/html-semantics-accessibility-review/metadata.json +29 -0
- package/skills/frontend/html-semantics-accessibility-review/references/apg-pattern-index.md +55 -0
- package/skills/frontend/html-semantics-accessibility-review/references/heading-landmark-rules.md +54 -0
- package/skills/frontend/html-semantics-accessibility-review/references/wcag-criterion-mapping.md +40 -0
- package/skills/frontend/i18n-l10n-readiness-review/SKILL.md +122 -0
- package/skills/frontend/i18n-l10n-readiness-review/metadata.json +28 -0
- package/skills/frontend/i18n-l10n-readiness-review/references/intl-formatting-audit.md +101 -0
- package/skills/frontend/i18n-l10n-readiness-review/references/pluralization-icu-messageformat.md +132 -0
- package/skills/frontend/i18n-l10n-readiness-review/references/rtl-logical-properties-audit.md +125 -0
- package/skills/frontend/javascript-runtime-async-review/SKILL.md +70 -0
- package/skills/frontend/javascript-runtime-async-review/metadata.json +29 -0
- package/skills/frontend/javascript-runtime-async-review/references/event-loop-tracing.md +95 -0
- package/skills/frontend/javascript-runtime-async-review/references/race-condition-patterns.md +96 -0
- package/skills/frontend/javascript-runtime-async-review/references/rejection-audit.md +77 -0
- package/skills/frontend/legacy-jquery-to-modern-framework-review/SKILL.md +68 -0
- package/skills/frontend/legacy-jquery-to-modern-framework-review/metadata.json +27 -0
- package/skills/frontend/legacy-jquery-to-modern-framework-review/references/dom-mutation-and-plugin-side-effects.md +66 -0
- package/skills/frontend/legacy-jquery-to-modern-framework-review/references/event-delegation-inventory.md +60 -0
- package/skills/frontend/legacy-jquery-to-modern-framework-review/references/legacy-a11y-shim-audit.md +58 -0
- package/skills/frontend/microfrontend-boundary-review/SKILL.md +71 -0
- package/skills/frontend/microfrontend-boundary-review/metadata.json +26 -0
- package/skills/frontend/microfrontend-boundary-review/references/shared-runtime-security.md +50 -0
- package/skills/frontend/microfrontend-boundary-review/references/workflow-and-output.md +45 -0
- package/skills/frontend/monorepo-package-governance-review/SKILL.md +68 -0
- package/skills/frontend/monorepo-package-governance-review/metadata.json +32 -0
- package/skills/frontend/monorepo-package-governance-review/references/dependency-lockfile-governance.md +82 -0
- package/skills/frontend/monorepo-package-governance-review/references/npm-supply-chain-governance.md +95 -0
- package/skills/frontend/monorepo-package-governance-review/references/task-graph-review.md +82 -0
- package/skills/frontend/nextjs-app-router-data-fetching-review/SKILL.md +66 -0
- package/skills/frontend/nextjs-app-router-data-fetching-review/metadata.json +27 -0
- package/skills/frontend/nextjs-app-router-data-fetching-review/references/owasp-a01-broken-access-control.md +42 -0
- package/skills/frontend/nextjs-app-router-data-fetching-review/references/workflow-and-output.md +94 -0
- package/skills/frontend/nextjs-rendering-caching-review/SKILL.md +68 -0
- package/skills/frontend/nextjs-rendering-caching-review/metadata.json +27 -0
- package/skills/frontend/nextjs-rendering-caching-review/references/cache-tag-invalidation.md +45 -0
- package/skills/frontend/nextjs-rendering-caching-review/references/isr-reference.md +45 -0
- package/skills/frontend/nextjs-rendering-caching-review/references/workflow-and-output.md +85 -0
- package/skills/frontend/nextjs-server-security-review/SKILL.md +70 -0
- package/skills/frontend/nextjs-server-security-review/metadata.json +29 -0
- package/skills/frontend/nextjs-server-security-review/references/env-and-ssrf-surfaces.md +73 -0
- package/skills/frontend/nextjs-server-security-review/references/middleware-and-server-actions.md +67 -0
- package/skills/frontend/nextjs-server-security-review/references/workflow-and-output.md +51 -0
- package/skills/frontend/nuxt-fullstack-security-review/SKILL.md +161 -0
- package/skills/frontend/nuxt-fullstack-security-review/metadata.json +32 -0
- package/skills/frontend/nuxt-fullstack-security-review/references/acceptance-rubric.md +96 -0
- package/skills/frontend/nuxt-fullstack-security-review/references/runtime-config-and-cross-request-state.md +193 -0
- package/skills/frontend/nuxt-fullstack-security-review/references/ssrf-payload-and-response-headers.md +264 -0
- package/skills/frontend/nuxt-fullstack-security-review/references/workflow-and-output.md +127 -0
- package/skills/frontend/pci-payment-ui-security-review/SKILL.md +72 -0
- package/skills/frontend/pci-payment-ui-security-review/metadata.json +27 -0
- package/skills/frontend/pci-payment-ui-security-review/references/hosted-fields-and-tokenization.md +107 -0
- package/skills/frontend/pci-payment-ui-security-review/references/script-integrity-and-scope.md +66 -0
- package/skills/frontend/pci-payment-ui-security-review/references/workflow-and-output.md +52 -0
- package/skills/frontend/product-analytics-experimentation-review/SKILL.md +87 -0
- package/skills/frontend/product-analytics-experimentation-review/metadata.json +29 -0
- package/skills/frontend/product-analytics-experimentation-review/references/consent-and-pii-in-events.md +57 -0
- package/skills/frontend/product-analytics-experimentation-review/references/privacy-consent-depth-for-analytics.md +83 -0
- package/skills/frontend/product-analytics-experimentation-review/references/srm-and-bucketing-integrity.md +64 -0
- package/skills/frontend/product-analytics-experimentation-review/references/stopping-rules-and-peeking.md +61 -0
- package/skills/frontend/pwa-offline-readiness-review/SKILL.md +73 -0
- package/skills/frontend/pwa-offline-readiness-review/metadata.json +29 -0
- package/skills/frontend/pwa-offline-readiness-review/references/live-verification-protocol.md +67 -0
- package/skills/frontend/pwa-offline-readiness-review/references/manifest-installability-checklist.md +41 -0
- package/skills/frontend/pwa-offline-readiness-review/references/offline-fallback-precache-pattern.md +65 -0
- package/skills/frontend/react-component-architecture-review/SKILL.md +67 -0
- package/skills/frontend/react-component-architecture-review/metadata.json +27 -0
- package/skills/frontend/react-component-architecture-review/references/composite-widget-patterns.md +41 -0
- package/skills/frontend/react-component-architecture-review/references/workflow-and-output.md +84 -0
- package/skills/frontend/react-rsc-data-boundary-review/SKILL.md +70 -0
- package/skills/frontend/react-rsc-data-boundary-review/metadata.json +27 -0
- package/skills/frontend/react-rsc-data-boundary-review/references/boundary-data-leaks-and-taint.md +115 -0
- package/skills/frontend/react-rsc-data-boundary-review/references/server-actions-and-env-exposure.md +136 -0
- package/skills/frontend/react-rsc-data-boundary-review/references/workflow-and-output.md +48 -0
- package/skills/frontend/react-state-effects-review/SKILL.md +69 -0
- package/skills/frontend/react-state-effects-review/metadata.json +27 -0
- package/skills/frontend/react-state-effects-review/references/effect-cleanup-and-race-conditions.md +89 -0
- package/skills/frontend/react-state-effects-review/references/stale-closures-and-dependency-arrays.md +74 -0
- package/skills/frontend/react-state-effects-review/references/workflow-and-output.md +46 -0
- package/skills/frontend/routing-navigation-review/SKILL.md +72 -0
- package/skills/frontend/routing-navigation-review/metadata.json +27 -0
- package/skills/frontend/routing-navigation-review/references/code-splitting-and-url-state.md +72 -0
- package/skills/frontend/routing-navigation-review/references/focus-and-navigation-blocking.md +65 -0
- package/skills/frontend/routing-navigation-review/references/server-enforcement-patterns.md +90 -0
- package/skills/frontend/routing-navigation-review/references/workflow-and-output.md +68 -0
- package/skills/frontend/service-worker-cache-strategy-review/SKILL.md +73 -0
- package/skills/frontend/service-worker-cache-strategy-review/metadata.json +29 -0
- package/skills/frontend/service-worker-cache-strategy-review/references/cache-security-and-scope-audit.md +48 -0
- package/skills/frontend/service-worker-cache-strategy-review/references/route-classification-matrix.md +47 -0
- package/skills/frontend/service-worker-cache-strategy-review/references/workbox-strategy-semantics.md +44 -0
- package/skills/frontend/ssr-hydration-streaming-diagnosis/SKILL.md +69 -0
- package/skills/frontend/ssr-hydration-streaming-diagnosis/metadata.json +28 -0
- package/skills/frontend/ssr-hydration-streaming-diagnosis/references/fetch-waterfall-and-auth-timing.md +64 -0
- package/skills/frontend/ssr-hydration-streaming-diagnosis/references/hydration-mismatch-diagnosis.md +66 -0
- package/skills/frontend/ssr-hydration-streaming-diagnosis/references/suspense-streaming-structure.md +63 -0
- package/skills/frontend/state-management-decision-review/SKILL.md +74 -0
- package/skills/frontend/state-management-decision-review/metadata.json +30 -0
- package/skills/frontend/state-management-decision-review/references/client-store-topology-and-rerenders.md +81 -0
- package/skills/frontend/state-management-decision-review/references/server-state-caching-and-invalidation.md +82 -0
- package/skills/frontend/state-management-decision-review/references/workflow-and-output.md +63 -0
- package/skills/frontend/sveltekit-actions-load-security-review/SKILL.md +72 -0
- package/skills/frontend/sveltekit-actions-load-security-review/metadata.json +28 -0
- package/skills/frontend/sveltekit-actions-load-security-review/references/cookies-and-html-bindings.md +78 -0
- package/skills/frontend/sveltekit-actions-load-security-review/references/csrf-and-auth-boundaries.md +91 -0
- package/skills/frontend/sveltekit-actions-load-security-review/references/workflow-and-output.md +51 -0
- package/skills/frontend/sveltekit-progressive-enhancement-review/SKILL.md +68 -0
- package/skills/frontend/sveltekit-progressive-enhancement-review/metadata.json +27 -0
- package/skills/frontend/sveltekit-progressive-enhancement-review/references/failure-state-and-accessibility.md +48 -0
- package/skills/frontend/sveltekit-progressive-enhancement-review/references/workflow-and-output.md +63 -0
- package/skills/frontend/sveltekit-routing-load-review/SKILL.md +67 -0
- package/skills/frontend/sveltekit-routing-load-review/metadata.json +27 -0
- package/skills/frontend/sveltekit-routing-load-review/references/routing-conventions.md +35 -0
- package/skills/frontend/sveltekit-routing-load-review/references/workflow-and-output.md +60 -0
- package/skills/frontend/tree-shaking-dead-code-review/SKILL.md +74 -0
- package/skills/frontend/tree-shaking-dead-code-review/metadata.json +28 -0
- package/skills/frontend/tree-shaking-dead-code-review/references/esm-cjs-interop-and-verification.md +57 -0
- package/skills/frontend/tree-shaking-dead-code-review/references/module-format-and-sideeffects.md +61 -0
- package/skills/frontend/tree-shaking-dead-code-review/references/rollup-vite-treeshake-options.md +79 -0
- package/skills/frontend/typescript-contracts-review/SKILL.md +70 -0
- package/skills/frontend/typescript-contracts-review/metadata.json +29 -0
- package/skills/frontend/typescript-contracts-review/references/public-api-surface-diff.md +59 -0
- package/skills/frontend/typescript-contracts-review/references/strict-flag-posture.md +61 -0
- package/skills/frontend/typescript-contracts-review/references/trust-boundary-validation.md +68 -0
- package/skills/frontend/visual-regression-storybook-review/SKILL.md +64 -0
- package/skills/frontend/visual-regression-storybook-review/metadata.json +27 -0
- package/skills/frontend/visual-regression-storybook-review/references/accessibility-addon-gating.md +86 -0
- package/skills/frontend/visual-regression-storybook-review/references/test-runner-and-chromatic-wiring.md +56 -0
- package/skills/frontend/visual-regression-storybook-review/references/theme-and-variant-coverage.md +51 -0
- package/skills/frontend/vue-composition-api-architecture-review/SKILL.md +68 -0
- package/skills/frontend/vue-composition-api-architecture-review/metadata.json +27 -0
- package/skills/frontend/vue-composition-api-architecture-review/references/composable-and-script-setup-conventions.md +50 -0
- package/skills/frontend/vue-composition-api-architecture-review/references/reactivity-boundaries.md +44 -0
- package/skills/frontend/vue-composition-api-architecture-review/references/workflow-and-output.md +49 -0
- package/skills/frontend/vue-router-navigation-security-review/SKILL.md +155 -0
- package/skills/frontend/vue-router-navigation-security-review/metadata.json +30 -0
- package/skills/frontend/vue-router-navigation-security-review/references/acceptance-rubric.md +110 -0
- package/skills/frontend/vue-router-navigation-security-review/references/client-guards-and-control-flow.md +188 -0
- package/skills/frontend/vue-router-navigation-security-review/references/open-redirect-and-injection.md +190 -0
- package/skills/frontend/vue-router-navigation-security-review/references/workflow-and-output.md +134 -0
- package/skills/frontend/vue-ssr-security-review/SKILL.md +69 -0
- package/skills/frontend/vue-ssr-security-review/metadata.json +27 -0
- package/skills/frontend/vue-ssr-security-review/references/cross-request-state-pollution.md +98 -0
- package/skills/frontend/vue-ssr-security-review/references/injection-and-dynamic-urls.md +120 -0
- package/skills/frontend/vue-ssr-security-review/references/workflow-and-output.md +48 -0
- package/skills/frontend/vue-state-store-security-review/SKILL.md +168 -0
- package/skills/frontend/vue-state-store-security-review/metadata.json +30 -0
- package/skills/frontend/vue-state-store-security-review/references/acceptance-rubric.md +101 -0
- package/skills/frontend/vue-state-store-security-review/references/persistence-and-hydration.md +234 -0
- package/skills/frontend/vue-state-store-security-review/references/untrusted-payloads-and-authorization.md +200 -0
- package/skills/frontend/vue-state-store-security-review/references/workflow-and-output.md +142 -0
- package/skills/frontend/wcag-22-accessibility-audit/SKILL.md +67 -0
- package/skills/frontend/wcag-22-accessibility-audit/metadata.json +27 -0
- package/skills/frontend/wcag-22-accessibility-audit/references/act-rules-detection-boundary.md +64 -0
- package/skills/frontend/wcag-22-accessibility-audit/references/legal-exposure-severity.md +59 -0
- package/skills/frontend/wcag-22-accessibility-audit/references/wcag22-sc-index.md +114 -0
- package/tests/fixtures/frontend-maestro-routing/expected/001-happy-accessibility-wcag.json +6 -0
- package/tests/fixtures/frontend-maestro-routing/expected/002-happy-ai-assisted-frontend-review.json +6 -0
- package/tests/fixtures/frontend-maestro-routing/expected/003-happy-angular.json +6 -0
- package/tests/fixtures/frontend-maestro-routing/expected/004-happy-api-integration-bff.json +6 -0
- package/tests/fixtures/frontend-maestro-routing/expected/005-happy-browser-compatibility.json +6 -0
- package/tests/fixtures/frontend-maestro-routing/expected/006-happy-build-tooling-bundling.json +6 -0
- package/tests/fixtures/frontend-maestro-routing/expected/007-happy-css-architecture.json +6 -0
- package/tests/fixtures/frontend-maestro-routing/expected/008-happy-design-systems-governance.json +6 -0
- package/tests/fixtures/frontend-maestro-routing/expected/009-happy-enterprise-red-team-review.json +6 -0
- package/tests/fixtures/frontend-maestro-routing/expected/010-happy-frontend-finops-cost-to-serve.json +6 -0
- package/tests/fixtures/frontend-maestro-routing/expected/011-happy-frontend-migration-modernization.json +6 -0
- package/tests/fixtures/frontend-maestro-routing/expected/012-happy-frontend-observability-rum.json +6 -0
- package/tests/fixtures/frontend-maestro-routing/expected/013-happy-frontend-platform-architect.json +6 -0
- package/tests/fixtures/frontend-maestro-routing/expected/014-happy-frontend-security.json +6 -0
- package/tests/fixtures/frontend-maestro-routing/expected/015-happy-html-semantics.json +6 -0
- package/tests/fixtures/frontend-maestro-routing/expected/016-happy-internationalization-localization.json +6 -0
- package/tests/fixtures/frontend-maestro-routing/expected/017-happy-javascript-runtime.json +6 -0
- package/tests/fixtures/frontend-maestro-routing/expected/018-happy-monorepo-dx.json +6 -0
- package/tests/fixtures/frontend-maestro-routing/expected/019-happy-nextjs.json +6 -0
- package/tests/fixtures/frontend-maestro-routing/expected/020-happy-package-governance.json +6 -0
- package/tests/fixtures/frontend-maestro-routing/expected/021-happy-product-analytics-experimentation.json +6 -0
- package/tests/fixtures/frontend-maestro-routing/expected/022-happy-pwa-offline-capability.json +6 -0
- package/tests/fixtures/frontend-maestro-routing/expected/023-happy-react.json +6 -0
- package/tests/fixtures/frontend-maestro-routing/expected/024-happy-routing-navigation.json +6 -0
- package/tests/fixtures/frontend-maestro-routing/expected/025-happy-ssr-hydration-streaming.json +6 -0
- package/tests/fixtures/frontend-maestro-routing/expected/026-happy-state-management-data-flow.json +6 -0
- package/tests/fixtures/frontend-maestro-routing/expected/027-happy-svelte-sveltekit.json +6 -0
- package/tests/fixtures/frontend-maestro-routing/expected/028-happy-testing-quality-engineering.json +6 -0
- package/tests/fixtures/frontend-maestro-routing/expected/029-happy-typescript-contracts.json +6 -0
- package/tests/fixtures/frontend-maestro-routing/expected/030-happy-visual-regression.json +6 -0
- package/tests/fixtures/frontend-maestro-routing/expected/031-happy-vue.json +6 -0
- package/tests/fixtures/frontend-maestro-routing/expected/032-happy-web-performance-core-vitals.json +6 -0
- package/tests/fixtures/frontend-maestro-routing/expected/033-happy-web-platform-foundation.json +6 -0
- package/tests/fixtures/frontend-maestro-routing/expected/034-parallel-react-performance-a11y.json +7 -0
- package/tests/fixtures/frontend-maestro-routing/expected/035-parallel-security-and-typescript.json +7 -0
- package/tests/fixtures/frontend-maestro-routing/expected/036-ambiguous-vague-request.json +4 -0
- package/tests/fixtures/frontend-maestro-routing/expected/037-adv-instruction-injection.json +6 -0
- package/tests/fixtures/frontend-maestro-routing/expected/038-adv-persona-replacement.json +6 -0
- package/tests/fixtures/frontend-maestro-routing/expected/039-adv-liveguard-deploy-prod.json +4 -0
- package/tests/fixtures/frontend-maestro-routing/expected/040-adv-liveguard-flag-flip.json +4 -0
- package/tests/fixtures/frontend-maestro-routing/expected/041-adv-secrets-bait.json +6 -0
- package/tests/fixtures/frontend-maestro-routing/expected/042-adv-liveguard-production-deploy.json +4 -0
- package/tests/fixtures/frontend-maestro-routing/inputs/001-happy-accessibility-wcag.json +7 -0
- package/tests/fixtures/frontend-maestro-routing/inputs/002-happy-ai-assisted-frontend-review.json +7 -0
- package/tests/fixtures/frontend-maestro-routing/inputs/003-happy-angular.json +7 -0
- package/tests/fixtures/frontend-maestro-routing/inputs/004-happy-api-integration-bff.json +7 -0
- package/tests/fixtures/frontend-maestro-routing/inputs/005-happy-browser-compatibility.json +7 -0
- package/tests/fixtures/frontend-maestro-routing/inputs/006-happy-build-tooling-bundling.json +7 -0
- package/tests/fixtures/frontend-maestro-routing/inputs/007-happy-css-architecture.json +7 -0
- package/tests/fixtures/frontend-maestro-routing/inputs/008-happy-design-systems-governance.json +7 -0
- package/tests/fixtures/frontend-maestro-routing/inputs/009-happy-enterprise-red-team-review.json +7 -0
- package/tests/fixtures/frontend-maestro-routing/inputs/010-happy-frontend-finops-cost-to-serve.json +7 -0
- package/tests/fixtures/frontend-maestro-routing/inputs/011-happy-frontend-migration-modernization.json +7 -0
- package/tests/fixtures/frontend-maestro-routing/inputs/012-happy-frontend-observability-rum.json +7 -0
- package/tests/fixtures/frontend-maestro-routing/inputs/013-happy-frontend-platform-architect.json +7 -0
- package/tests/fixtures/frontend-maestro-routing/inputs/014-happy-frontend-security.json +7 -0
- package/tests/fixtures/frontend-maestro-routing/inputs/015-happy-html-semantics.json +7 -0
- package/tests/fixtures/frontend-maestro-routing/inputs/016-happy-internationalization-localization.json +7 -0
- package/tests/fixtures/frontend-maestro-routing/inputs/017-happy-javascript-runtime.json +7 -0
- package/tests/fixtures/frontend-maestro-routing/inputs/018-happy-monorepo-dx.json +7 -0
- package/tests/fixtures/frontend-maestro-routing/inputs/019-happy-nextjs.json +7 -0
- package/tests/fixtures/frontend-maestro-routing/inputs/020-happy-package-governance.json +7 -0
- package/tests/fixtures/frontend-maestro-routing/inputs/021-happy-product-analytics-experimentation.json +7 -0
- package/tests/fixtures/frontend-maestro-routing/inputs/022-happy-pwa-offline-capability.json +7 -0
- package/tests/fixtures/frontend-maestro-routing/inputs/023-happy-react.json +7 -0
- package/tests/fixtures/frontend-maestro-routing/inputs/024-happy-routing-navigation.json +7 -0
- package/tests/fixtures/frontend-maestro-routing/inputs/025-happy-ssr-hydration-streaming.json +7 -0
- package/tests/fixtures/frontend-maestro-routing/inputs/026-happy-state-management-data-flow.json +7 -0
- package/tests/fixtures/frontend-maestro-routing/inputs/027-happy-svelte-sveltekit.json +7 -0
- package/tests/fixtures/frontend-maestro-routing/inputs/028-happy-testing-quality-engineering.json +7 -0
- package/tests/fixtures/frontend-maestro-routing/inputs/029-happy-typescript-contracts.json +7 -0
- package/tests/fixtures/frontend-maestro-routing/inputs/030-happy-visual-regression.json +7 -0
- package/tests/fixtures/frontend-maestro-routing/inputs/031-happy-vue.json +7 -0
- package/tests/fixtures/frontend-maestro-routing/inputs/032-happy-web-performance-core-vitals.json +7 -0
- package/tests/fixtures/frontend-maestro-routing/inputs/033-happy-web-platform-foundation.json +7 -0
- package/tests/fixtures/frontend-maestro-routing/inputs/034-parallel-react-performance-a11y.json +7 -0
- package/tests/fixtures/frontend-maestro-routing/inputs/035-parallel-security-and-typescript.json +7 -0
- package/tests/fixtures/frontend-maestro-routing/inputs/036-ambiguous-vague-request.json +7 -0
- package/tests/fixtures/frontend-maestro-routing/inputs/037-adv-instruction-injection.json +7 -0
- package/tests/fixtures/frontend-maestro-routing/inputs/038-adv-persona-replacement.json +7 -0
- package/tests/fixtures/frontend-maestro-routing/inputs/039-adv-liveguard-deploy-prod.json +7 -0
- package/tests/fixtures/frontend-maestro-routing/inputs/040-adv-liveguard-flag-flip.json +7 -0
- package/tests/fixtures/frontend-maestro-routing/inputs/041-adv-secrets-bait.json +7 -0
- package/tests/fixtures/frontend-maestro-routing/inputs/042-adv-liveguard-production-deploy.json +3 -0
- package/tests/fixtures/frontend-maestro-routing/taxonomy.json +377 -0
- package/tests/fixtures/frontend-security-detection/angular-template-sanitizer-security-review/detectors.json +50 -0
- package/tests/fixtures/frontend-security-detection/angular-template-sanitizer-security-review/green/avatar.component.ts +19 -0
- package/tests/fixtures/frontend-security-detection/angular-template-sanitizer-security-review/green/comment.component.ts +12 -0
- package/tests/fixtures/frontend-security-detection/angular-template-sanitizer-security-review/green/embed.component.html +3 -0
- package/tests/fixtures/frontend-security-detection/angular-template-sanitizer-security-review/green/profile-link.component.ts +20 -0
- package/tests/fixtures/frontend-security-detection/angular-template-sanitizer-security-review/green/profile.component.html +4 -0
- package/tests/fixtures/frontend-security-detection/angular-template-sanitizer-security-review/red/avatar.component.ts +19 -0
- package/tests/fixtures/frontend-security-detection/angular-template-sanitizer-security-review/red/comment.component.ts +19 -0
- package/tests/fixtures/frontend-security-detection/angular-template-sanitizer-security-review/red/embed.component.html +5 -0
- package/tests/fixtures/frontend-security-detection/angular-template-sanitizer-security-review/red/profile-link.component.ts +20 -0
- package/tests/fixtures/frontend-security-detection/angular-template-sanitizer-security-review/red/profile.component.html +6 -0
- package/tests/fixtures/frontend-security-detection/edge-cache-data-bleed-review/detectors.json +50 -0
- package/tests/fixtures/frontend-security-detection/edge-cache-data-bleed-review/green/api-user-profile-route.ts +15 -0
- package/tests/fixtures/frontend-security-detection/edge-cache-data-bleed-review/green/api-user-profile-vary.ts +15 -0
- package/tests/fixtures/frontend-security-detection/edge-cache-data-bleed-review/green/dashboard-revalidate-cookies.tsx +32 -0
- package/tests/fixtures/frontend-security-detection/edge-cache-data-bleed-review/green/get-user-data.ts +13 -0
- package/tests/fixtures/frontend-security-detection/edge-cache-data-bleed-review/green/product-static-params.tsx +19 -0
- package/tests/fixtures/frontend-security-detection/edge-cache-data-bleed-review/red/api-user-profile-route.ts +17 -0
- package/tests/fixtures/frontend-security-detection/edge-cache-data-bleed-review/red/api-user-profile-vary.ts +16 -0
- package/tests/fixtures/frontend-security-detection/edge-cache-data-bleed-review/red/dashboard-revalidate-cookies.tsx +18 -0
- package/tests/fixtures/frontend-security-detection/edge-cache-data-bleed-review/red/get-user-data.ts +13 -0
- package/tests/fixtures/frontend-security-detection/edge-cache-data-bleed-review/red/product-static-params.tsx +25 -0
- package/tests/fixtures/frontend-security-detection/frontend-auth-session-security-review/detectors.json +50 -0
- package/tests/fixtures/frontend-security-detection/frontend-auth-session-security-review/green/oauth-flow.js +14 -0
- package/tests/fixtures/frontend-security-detection/frontend-auth-session-security-review/green/pkce-authorize-url.js +6 -0
- package/tests/fixtures/frontend-security-detection/frontend-auth-session-security-review/green/redirect-validation.js +12 -0
- package/tests/fixtures/frontend-security-detection/frontend-auth-session-security-review/green/session-cookie.js +6 -0
- package/tests/fixtures/frontend-security-detection/frontend-auth-session-security-review/green/token-storage.js +24 -0
- package/tests/fixtures/frontend-security-detection/frontend-auth-session-security-review/red/oauth-flow.js +9 -0
- package/tests/fixtures/frontend-security-detection/frontend-auth-session-security-review/red/pkce-authorize-url.js +7 -0
- package/tests/fixtures/frontend-security-detection/frontend-auth-session-security-review/red/redirect-validation.js +11 -0
- package/tests/fixtures/frontend-security-detection/frontend-auth-session-security-review/red/session-cookie.js +6 -0
- package/tests/fixtures/frontend-security-detection/frontend-auth-session-security-review/red/token-storage.js +11 -0
- package/tests/fixtures/frontend-security-detection/frontend-dom-xss-csp-review/detectors.json +77 -0
- package/tests/fixtures/frontend-security-detection/frontend-dom-xss-csp-review/green/csp-broad-script-src.txt +7 -0
- package/tests/fixtures/frontend-security-detection/frontend-dom-xss-csp-review/green/dangerously-set-html.jsx +6 -0
- package/tests/fixtures/frontend-security-detection/frontend-dom-xss-csp-review/green/dynamic-function.js +11 -0
- package/tests/fixtures/frontend-security-detection/frontend-dom-xss-csp-review/green/dynamic-script-untrusted-src.js +24 -0
- package/tests/fixtures/frontend-security-detection/frontend-dom-xss-csp-review/green/eval-config.js +8 -0
- package/tests/fixtures/frontend-security-detection/frontend-dom-xss-csp-review/green/innerhtml-sink.js +7 -0
- package/tests/fixtures/frontend-security-detection/frontend-dom-xss-csp-review/green/legacy-write.js +9 -0
- package/tests/fixtures/frontend-security-detection/frontend-dom-xss-csp-review/green/third-party-script-no-sri.html +14 -0
- package/tests/fixtures/frontend-security-detection/frontend-dom-xss-csp-review/red/csp-broad-script-src.txt +6 -0
- package/tests/fixtures/frontend-security-detection/frontend-dom-xss-csp-review/red/dangerously-set-html.jsx +6 -0
- package/tests/fixtures/frontend-security-detection/frontend-dom-xss-csp-review/red/dynamic-function.js +7 -0
- package/tests/fixtures/frontend-security-detection/frontend-dom-xss-csp-review/red/dynamic-script-untrusted-src.js +11 -0
- package/tests/fixtures/frontend-security-detection/frontend-dom-xss-csp-review/red/eval-config.js +6 -0
- package/tests/fixtures/frontend-security-detection/frontend-dom-xss-csp-review/red/innerhtml-sink.js +7 -0
- package/tests/fixtures/frontend-security-detection/frontend-dom-xss-csp-review/red/legacy-write.js +6 -0
- package/tests/fixtures/frontend-security-detection/frontend-dom-xss-csp-review/red/third-party-script-no-sri.html +11 -0
- package/tests/fixtures/frontend-security-detection/graphql-client-security-review/detectors.json +50 -0
- package/tests/fixtures/frontend-security-detection/graphql-client-security-review/green/apollo-client-setup.js +11 -0
- package/tests/fixtures/frontend-security-detection/graphql-client-security-review/green/auth-context-link.js +15 -0
- package/tests/fixtures/frontend-security-detection/graphql-client-security-review/green/logout-handler.js +10 -0
- package/tests/fixtures/frontend-security-detection/graphql-client-security-review/green/payment-cache-policy.js +33 -0
- package/tests/fixtures/frontend-security-detection/graphql-client-security-review/green/persisted-query-link.js +18 -0
- package/tests/fixtures/frontend-security-detection/graphql-client-security-review/red/apollo-client-setup.js +12 -0
- package/tests/fixtures/frontend-security-detection/graphql-client-security-review/red/auth-context-link.js +13 -0
- package/tests/fixtures/frontend-security-detection/graphql-client-security-review/red/logout-handler.js +12 -0
- package/tests/fixtures/frontend-security-detection/graphql-client-security-review/red/payment-cache-policy.js +21 -0
- package/tests/fixtures/frontend-security-detection/graphql-client-security-review/red/persisted-query-link.js +13 -0
- package/tests/fixtures/frontend-security-detection/nextjs-server-security-review/detectors.json +50 -0
- package/tests/fixtures/frontend-security-detection/nextjs-server-security-review/green/env.server-only-secret.txt +6 -0
- package/tests/fixtures/frontend-security-detection/nextjs-server-security-review/green/middleware-matcher-explicit-allowlist.ts +14 -0
- package/tests/fixtures/frontend-security-detection/nextjs-server-security-review/green/middleware-rewrite-allowlisted.ts +19 -0
- package/tests/fixtures/frontend-security-detection/nextjs-server-security-review/green/next.config.local-ip-disabled.js +9 -0
- package/tests/fixtures/frontend-security-detection/nextjs-server-security-review/green/next.config.server-actions-with-origins.js +12 -0
- package/tests/fixtures/frontend-security-detection/nextjs-server-security-review/red/env.next-public-secret.txt +6 -0
- package/tests/fixtures/frontend-security-detection/nextjs-server-security-review/red/middleware-matcher-excludes-api.ts +16 -0
- package/tests/fixtures/frontend-security-detection/nextjs-server-security-review/red/middleware-rewrite-ssrf.ts +11 -0
- package/tests/fixtures/frontend-security-detection/nextjs-server-security-review/red/next.config.dangerously-allow-local-ip.js +11 -0
- package/tests/fixtures/frontend-security-detection/nextjs-server-security-review/red/next.config.server-actions-no-origins.js +14 -0
- package/tests/fixtures/frontend-security-detection/nuxt-fullstack-security-review/detectors.json +50 -0
- package/tests/fixtures/frontend-security-detection/nuxt-fullstack-security-review/green/CommentBody.vue +11 -0
- package/tests/fixtures/frontend-security-detection/nuxt-fullstack-security-review/green/external-call.ts +6 -0
- package/tests/fixtures/frontend-security-detection/nuxt-fullstack-security-review/green/nuxt.config.ts +8 -0
- package/tests/fixtures/frontend-security-detection/nuxt-fullstack-security-review/green/proxy.ts +11 -0
- package/tests/fixtures/frontend-security-detection/nuxt-fullstack-security-review/green/session.ts +5 -0
- package/tests/fixtures/frontend-security-detection/nuxt-fullstack-security-review/red/CommentBody.vue +9 -0
- package/tests/fixtures/frontend-security-detection/nuxt-fullstack-security-review/red/external-call.ts +5 -0
- package/tests/fixtures/frontend-security-detection/nuxt-fullstack-security-review/red/nuxt.config.ts +7 -0
- package/tests/fixtures/frontend-security-detection/nuxt-fullstack-security-review/red/proxy.ts +5 -0
- package/tests/fixtures/frontend-security-detection/nuxt-fullstack-security-review/red/session.ts +8 -0
- package/tests/fixtures/frontend-security-detection/pci-payment-ui-security-review/detectors.json +50 -0
- package/tests/fixtures/frontend-security-detection/pci-payment-ui-security-review/green/card-data-persistence.js +9 -0
- package/tests/fixtures/frontend-security-detection/pci-payment-ui-security-review/green/missing-iframe-isolation.jsx +26 -0
- package/tests/fixtures/frontend-security-detection/pci-payment-ui-security-review/green/raw-pan-input.vue +29 -0
- package/tests/fixtures/frontend-security-detection/pci-payment-ui-security-review/green/self-posted-card-data.ts +14 -0
- package/tests/fixtures/frontend-security-detection/pci-payment-ui-security-review/green/unsigned-third-party-script.html +17 -0
- package/tests/fixtures/frontend-security-detection/pci-payment-ui-security-review/red/card-data-persistence.js +11 -0
- package/tests/fixtures/frontend-security-detection/pci-payment-ui-security-review/red/missing-iframe-isolation.jsx +35 -0
- package/tests/fixtures/frontend-security-detection/pci-payment-ui-security-review/red/raw-pan-input.vue +27 -0
- package/tests/fixtures/frontend-security-detection/pci-payment-ui-security-review/red/self-posted-card-data.ts +15 -0
- package/tests/fixtures/frontend-security-detection/pci-payment-ui-security-review/red/unsigned-third-party-script.html +14 -0
- package/tests/fixtures/frontend-security-detection/react-rsc-data-boundary-review/detectors.json +50 -0
- package/tests/fixtures/frontend-security-detection/react-rsc-data-boundary-review/green/ClientDashboard.tsx +8 -0
- package/tests/fixtures/frontend-security-detection/react-rsc-data-boundary-review/green/ClientWidget.tsx +8 -0
- package/tests/fixtures/frontend-security-detection/react-rsc-data-boundary-review/green/Dashboard.tsx +9 -0
- package/tests/fixtures/frontend-security-detection/react-rsc-data-boundary-review/green/actions.ts +20 -0
- package/tests/fixtures/frontend-security-detection/react-rsc-data-boundary-review/green/config.ts +9 -0
- package/tests/fixtures/frontend-security-detection/react-rsc-data-boundary-review/red/ClientDashboard.tsx +9 -0
- package/tests/fixtures/frontend-security-detection/react-rsc-data-boundary-review/red/ClientWidget.tsx +9 -0
- package/tests/fixtures/frontend-security-detection/react-rsc-data-boundary-review/red/Dashboard.tsx +8 -0
- package/tests/fixtures/frontend-security-detection/react-rsc-data-boundary-review/red/actions.ts +8 -0
- package/tests/fixtures/frontend-security-detection/react-rsc-data-boundary-review/red/config.ts +7 -0
- package/tests/fixtures/frontend-security-detection/service-worker-cache-strategy-review/detectors.json +50 -0
- package/tests/fixtures/frontend-security-detection/service-worker-cache-strategy-review/green/auth-network-only.js +20 -0
- package/tests/fixtures/frontend-security-detection/service-worker-cache-strategy-review/green/cors-checked-put.js +14 -0
- package/tests/fixtures/frontend-security-detection/service-worker-cache-strategy-review/green/login-network-only.js +6 -0
- package/tests/fixtures/frontend-security-detection/service-worker-cache-strategy-review/green/nav-stale-while-revalidate.js +10 -0
- package/tests/fixtures/frontend-security-detection/service-worker-cache-strategy-review/green/registerroute-get-only.js +15 -0
- package/tests/fixtures/frontend-security-detection/service-worker-cache-strategy-review/red/auth-echo-cached.js +18 -0
- package/tests/fixtures/frontend-security-detection/service-worker-cache-strategy-review/red/login-cache-first.js +7 -0
- package/tests/fixtures/frontend-security-detection/service-worker-cache-strategy-review/red/nav-cache-first.js +10 -0
- package/tests/fixtures/frontend-security-detection/service-worker-cache-strategy-review/red/opaque-nocors-put.js +13 -0
- package/tests/fixtures/frontend-security-detection/service-worker-cache-strategy-review/red/put-non-get.js +19 -0
- package/tests/fixtures/frontend-security-detection/sveltekit-actions-load-security-review/detectors.json +50 -0
- package/tests/fixtures/frontend-security-detection/sveltekit-actions-load-security-review/green/CommentBody.svelte +12 -0
- package/tests/fixtures/frontend-security-detection/sveltekit-actions-load-security-review/green/csrf-disabled.config.js +14 -0
- package/tests/fixtures/frontend-security-detection/sveltekit-actions-load-security-review/green/csrf-wildcard-origins.config.js +14 -0
- package/tests/fixtures/frontend-security-detection/sveltekit-actions-load-security-review/green/load-session-leak.server.js +12 -0
- package/tests/fixtures/frontend-security-detection/sveltekit-actions-load-security-review/green/set-cookie-insecure.server.js +15 -0
- package/tests/fixtures/frontend-security-detection/sveltekit-actions-load-security-review/red/CommentBody.svelte +12 -0
- package/tests/fixtures/frontend-security-detection/sveltekit-actions-load-security-review/red/csrf-disabled.config.js +16 -0
- package/tests/fixtures/frontend-security-detection/sveltekit-actions-load-security-review/red/csrf-wildcard-origins.config.js +16 -0
- package/tests/fixtures/frontend-security-detection/sveltekit-actions-load-security-review/red/load-session-leak.server.js +12 -0
- package/tests/fixtures/frontend-security-detection/sveltekit-actions-load-security-review/red/set-cookie-insecure.server.js +15 -0
- package/tests/fixtures/frontend-security-detection/vue-router-navigation-security-review/detectors.json +50 -0
- package/tests/fixtures/frontend-security-detection/vue-router-navigation-security-review/green/guard-sole-authz.js +11 -0
- package/tests/fixtures/frontend-security-detection/vue-router-navigation-security-review/green/open-redirect.js +10 -0
- package/tests/fixtures/frontend-security-detection/vue-router-navigation-security-review/green/redirect-loop.js +8 -0
- package/tests/fixtures/frontend-security-detection/vue-router-navigation-security-review/green/reflected-xss.vue +14 -0
- package/tests/fixtures/frontend-security-detection/vue-router-navigation-security-review/green/scheme-injection.vue +19 -0
- package/tests/fixtures/frontend-security-detection/vue-router-navigation-security-review/red/guard-sole-authz.js +8 -0
- package/tests/fixtures/frontend-security-detection/vue-router-navigation-security-review/red/open-redirect.js +7 -0
- package/tests/fixtures/frontend-security-detection/vue-router-navigation-security-review/red/redirect-loop.js +8 -0
- package/tests/fixtures/frontend-security-detection/vue-router-navigation-security-review/red/reflected-xss.vue +10 -0
- package/tests/fixtures/frontend-security-detection/vue-router-navigation-security-review/red/scheme-injection.vue +10 -0
- package/tests/fixtures/frontend-security-detection/vue-ssr-security-review/detectors.json +41 -0
- package/tests/fixtures/frontend-security-detection/vue-ssr-security-review/green/AvatarImage.vue +18 -0
- package/tests/fixtures/frontend-security-detection/vue-ssr-security-review/green/ProfileLink.vue +19 -0
- package/tests/fixtures/frontend-security-detection/vue-ssr-security-review/green/UserBio.vue +9 -0
- package/tests/fixtures/frontend-security-detection/vue-ssr-security-review/green/entry-server.js +21 -0
- package/tests/fixtures/frontend-security-detection/vue-ssr-security-review/red/AvatarImage.vue +9 -0
- package/tests/fixtures/frontend-security-detection/vue-ssr-security-review/red/ProfileLink.vue +9 -0
- package/tests/fixtures/frontend-security-detection/vue-ssr-security-review/red/UserBio.vue +9 -0
- package/tests/fixtures/frontend-security-detection/vue-ssr-security-review/red/entry-server.js +22 -0
- package/tests/fixtures/frontend-security-detection/vue-state-store-security-review/detectors.json +50 -0
- package/tests/fixtures/frontend-security-detection/vue-state-store-security-review/green/auth-flag-ui-only.js +18 -0
- package/tests/fixtures/frontend-security-detection/vue-state-store-security-review/green/hydrate-validated.js +14 -0
- package/tests/fixtures/frontend-security-detection/vue-state-store-security-review/green/hydration-devalue.js +15 -0
- package/tests/fixtures/frontend-security-detection/vue-state-store-security-review/green/persist-scoped.js +22 -0
- package/tests/fixtures/frontend-security-detection/vue-state-store-security-review/green/ssr-per-request.js +14 -0
- package/tests/fixtures/frontend-security-detection/vue-state-store-security-review/red/auth-flag-gate.js +14 -0
- package/tests/fixtures/frontend-security-detection/vue-state-store-security-review/red/hydrate-unvalidated.js +10 -0
- package/tests/fixtures/frontend-security-detection/vue-state-store-security-review/red/hydration-serialize.js +13 -0
- package/tests/fixtures/frontend-security-detection/vue-state-store-security-review/red/persist-unscoped.js +19 -0
- package/tests/fixtures/frontend-security-detection/vue-state-store-security-review/red/ssr-singleton.js +15 -0
- package/tests/validate-catalog.py +1 -0
- package/tests/validate-frontend-security-detection.py +209 -0
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# CSP Directive Review
|
|
2
|
+
|
|
3
|
+
Use this reference only when auditing or authoring an actual Content-Security-Policy header or `<meta http-equiv="Content-Security-Policy">` value. Grounded in the MDN CSP header reference. Do not treat header presence as a pass — every directive must be parsed individually.
|
|
4
|
+
|
|
5
|
+
## What people get wrong
|
|
6
|
+
|
|
7
|
+
The naive assumption is:
|
|
8
|
+
|
|
9
|
+
> "The response has a `Content-Security-Policy` header, so CSP is handled."
|
|
10
|
+
|
|
11
|
+
Wrong. A CSP header is a set of independent directives, each restricting a different resource category, and a permissive value in any single directive can defeat the protection the other directives appear to provide. The recurring real failure mode: a policy that looks comprehensive (many directives listed) but includes `'unsafe-inline'` or a wildcard in `script-src`, which alone reduces the script-injection protection to near zero regardless of how strict the other directives are.
|
|
12
|
+
|
|
13
|
+
## Officially grounded directive semantics (MDN)
|
|
14
|
+
|
|
15
|
+
- **`script-src`** — controls valid sources for `<script>` elements, inline event handlers, and `javascript:` URLs. `'unsafe-inline'` allows inline `<script>` blocks and inline event-handler attributes, which defeats the primary purpose of CSP against DOM XSS: an injected `<script>` tag or `onerror` attribute would otherwise be blocked by the browser, but with `'unsafe-inline'` present it executes normally. `'unsafe-eval'` permits `eval()`, `Function()`, and string-argument `setTimeout`/`setInterval` to execute — combining this with an `eval`-class sink finding from `references/dom-xss-sink-source-taxonomy.md` means CSP provides zero mitigation for that specific finding.
|
|
16
|
+
- **`strict-dynamic`** — when present, propagates trust from a script loaded with a valid nonce or hash to the scripts it dynamically inserts, and (per spec behavior) causes host-source and scheme-source expressions in `script-src` to be ignored by browsers that support it. Effective only when paired with a per-response, unpredictable nonce or a hash allowlist; a static, hardcoded nonce value defeats it because an attacker can read and reuse the same nonce.
|
|
17
|
+
- **`object-src`** — controls `<object>`, `<embed>`, and `<applet>` sources. MDN explicitly recommends `object-src 'none'` as a baseline hardening step for most applications, because plugin content can execute script outside the page's normal script-loading path and is rarely needed by modern applications.
|
|
18
|
+
- **`base-uri`** — restricts URLs usable in a `<base>` element. A missing `base-uri` directive lets an attacker who can inject any HTML (even in a context otherwise well-protected by `script-src`) insert a `<base href="https://attacker.example/">` tag that silently rewrites all relative URLs on the page, redirecting script/resource loads to an attacker-controlled origin.
|
|
19
|
+
- **`default-src`** — the fallback for any resource-type directive not explicitly specified. A restrictive `default-src` (e.g., `'self'`) is not sufficient on its own if `script-src` is separately specified with a permissive value — explicit directives always override `default-src` for their resource type, so `default-src` alone does not prove `script-src` is safe.
|
|
20
|
+
- **`frame-ancestors`** — controls which origins may embed the page in a `<frame>`/`<iframe>`/`<object>`. Distinct from clickjacking-only `X-Frame-Options`; `frame-ancestors 'none'` or a specific allowlist is the CSP-native replacement and takes precedence when both are present.
|
|
21
|
+
- **`require-trusted-types-for`** and **`trusted-types`** — CSP-level enforcement hooks for the Trusted Types API; see `references/trusted-types-enforcement.md` for the full review of these two directives specifically.
|
|
22
|
+
|
|
23
|
+
## Non-negotiable design rules
|
|
24
|
+
|
|
25
|
+
### 1. Parse every directive value individually — do not grade the policy as a whole
|
|
26
|
+
|
|
27
|
+
A policy with 8 well-configured directives and 1 permissive `script-src 'unsafe-inline'` is not "mostly good." State the single permissive directive as its own confirmed finding at the severity that directive's gap implies, independent of how strict the others are.
|
|
28
|
+
|
|
29
|
+
### 2. `'unsafe-inline'` in `script-src` is a confirmed finding whenever DOM XSS sinks are also in scope
|
|
30
|
+
|
|
31
|
+
If the review scope includes both a CSP audit and a DOM-sink review, and the CSP has `'unsafe-inline'` in `script-src`, note explicitly that CSP provides no mitigation for any confirmed HTML-context sink finding in the same review — the two findings compound rather than one substituting for the other.
|
|
32
|
+
|
|
33
|
+
### 3. A wildcard or overly broad `script-src` source is equivalent to no restriction for practical purposes
|
|
34
|
+
|
|
35
|
+
`script-src https:` (any HTTPS origin) or `script-src *` allows loading and executing script from effectively any external origin, including an attacker-controlled one reachable over HTTPS. Treat this the same severity as `'unsafe-inline'` for a script-injection finding.
|
|
36
|
+
|
|
37
|
+
### 4. `strict-dynamic` correctness depends on nonce generation, not directive presence
|
|
38
|
+
|
|
39
|
+
Do not clear a `strict-dynamic` configuration as a pass without confirming the nonce is generated fresh per response (typically server-side, per-request) rather than hardcoded in a template or CSP meta tag. A static nonce in source is trivially readable and reusable by an attacker, providing no protection despite `strict-dynamic` being present.
|
|
40
|
+
|
|
41
|
+
### 5. CSP is a defense-in-depth layer, not a substitute for fixing a confirmed DOM XSS sink
|
|
42
|
+
|
|
43
|
+
Never recommend "add CSP" as the sole remediation for a confirmed unsanitized sink finding from `references/dom-xss-sink-source-taxonomy.md`. The sink itself must be fixed (sanitizer call or removal of the dynamic-code-execution pattern); CSP reduces blast radius if a sink is missed elsewhere, it does not replace fixing the one found.
|
|
44
|
+
|
|
45
|
+
## Minimal safe policy shape (illustrative, not a template to copy verbatim)
|
|
46
|
+
|
|
47
|
+
```
|
|
48
|
+
Content-Security-Policy:
|
|
49
|
+
default-src 'self';
|
|
50
|
+
script-src 'self' 'nonce-{PER-RESPONSE-RANDOM-VALUE}' 'strict-dynamic';
|
|
51
|
+
object-src 'none';
|
|
52
|
+
base-uri 'self';
|
|
53
|
+
frame-ancestors 'none';
|
|
54
|
+
require-trusted-types-for 'script';
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Anti-pattern (common in the wild — do not approve):
|
|
58
|
+
|
|
59
|
+
```
|
|
60
|
+
Content-Security-Policy: default-src * 'unsafe-inline' 'unsafe-eval';
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
This is functionally equivalent to no CSP for script-injection purposes: it permits inline scripts, `eval`-class execution, and loading script from any origin.
|
|
64
|
+
|
|
65
|
+
## Verification targets
|
|
66
|
+
|
|
67
|
+
- Locate the effective policy: grep server/middleware config, framework security headers config, or the rendered HTML `<meta http-equiv="Content-Security-Policy">` tag.
|
|
68
|
+
- Split the policy string on `;` and parse each directive-value pair independently; flag every occurrence of `'unsafe-inline'`, `'unsafe-eval'`, a bare wildcard `*`, or a scheme-only source (`https:`) in `script-src` or `default-src`.
|
|
69
|
+
- Confirm `object-src 'none'` and `base-uri` are present; if absent, this is a confirmed finding even if no other directive is misconfigured.
|
|
70
|
+
- If `strict-dynamic` is present, grep the server-side code that renders the nonce value to confirm it is generated per-request (e.g., via a cryptographically random value), not a fixed string.
|
|
71
|
+
- If a CSP `report-to`/`report-uri` endpoint is configured, note that browser-native CSP violation reports are a distinct mechanism from typical observability instrumentation (`documentation-based, gap confirmed via Context7`: OpenTelemetry's browser SDK/instrumentation packages have no built-in CSP-violation-report receiver as of current docs) — a custom collector endpoint must ingest the browser's native report POST; do not assume an existing OpenTelemetry pipeline captures these without a purpose-built receiver.
|
|
72
|
+
|
|
73
|
+
## When to push back
|
|
74
|
+
|
|
75
|
+
Push back if the user asks to:
|
|
76
|
+
|
|
77
|
+
- treat CSP header presence as sufficient without directive-level review,
|
|
78
|
+
- add `'unsafe-inline'` "temporarily" to unblock a deploy without a tracked follow-up to remove it — this is a confirmed finding regardless of stated intent to revisit it,
|
|
79
|
+
- rely on `X-Frame-Options` alone in a CSP review scope when `frame-ancestors` is unset — the two are not equivalent and `frame-ancestors` should be reviewed explicitly,
|
|
80
|
+
- treat "we added CSP" as the fix for a confirmed unsanitized DOM XSS sink instead of fixing the sink directly.
|
package/skills/frontend/frontend-dom-xss-csp-review/references/dom-xss-sink-source-taxonomy.md
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# DOM XSS Sink and Source Taxonomy
|
|
2
|
+
|
|
3
|
+
Use this reference only when the review scope includes a specific sink match (`innerHTML`, `dangerouslySetInnerHTML`, `v-html`, `document.write`, an `eval`-class API, or a dynamic attribute/URL binding). Grounded in the OWASP DOM-Based XSS Prevention Cheat Sheet's source/sink model.
|
|
4
|
+
|
|
5
|
+
## What people get wrong
|
|
6
|
+
|
|
7
|
+
The naive assumption is:
|
|
8
|
+
|
|
9
|
+
> "I found `innerHTML` in a grep, so this is an XSS finding."
|
|
10
|
+
|
|
11
|
+
Wrong. OWASP's own DOM XSS model requires two confirmed elements, not one: a **source** (attacker-reachable input) and a **sink** (a DOM API that can execute the value as code or markup), connected by an actual data-flow path with no sanitization in between. A sink with no reachable source is not exploitable. A source with no sink it reaches is not exploitable either. The recurring real failure mode is treating the sink match alone as the finding, or treating "we sanitize somewhere" as proof the specific traced path is clean.
|
|
12
|
+
|
|
13
|
+
## Officially grounded sink classes (OWASP DOM XSS Cheat Sheet)
|
|
14
|
+
|
|
15
|
+
- **HTML-context sinks** — assignment to `innerHTML`, `outerHTML`, `insertAdjacentHTML`, jQuery's `.html()`, React's `dangerouslySetInnerHTML`, Vue's `v-html` or an `innerHTML` render-function/JSX binding, Angular's `[innerHTML]` binding without going through `DomSanitizer`. These parse the assigned string as HTML/DOM, so any embedded `<script>`, event-handler attribute (`onerror`, `onload`), or `javascript:` URL in an unsanitized value executes.
|
|
16
|
+
- **JavaScript-execution sinks** — `eval()`, `new Function(...)`, `setTimeout(string, ...)`, `setInterval(string, ...)`, `execScript` (legacy IE). These execute the string argument directly as code; there is no markup step to sanitize around, so any confirmed attacker-reachable string reaching these is a direct code-execution finding.
|
|
17
|
+
- **URL-context sinks** — assignment to `location`, `location.href`, `location.replace()`, `window.open()`, dynamic `<a href>`/`<script src>`/`<iframe src>` bindings. A `javascript:` or `data:` scheme in an unvalidated attacker-reachable value executes on interaction (click, navigation, or load, depending on the element).
|
|
18
|
+
- **Document-write sinks** — `document.write()`, `document.writeln()`. Parses the argument as HTML into the document at call time; same risk class as HTML-context sinks but with the added hazard of executing during initial page parse, before most runtime sanitization layers are wired up.
|
|
19
|
+
- **jQuery/legacy DOM sinks** — `.html()`, `.append()`, `.prepend()`, `.after()`, `.before()`, `.replaceWith()` when passed a string (these route through the same HTML-parsing path as `innerHTML`); `.attr()` when setting an event-handler or `href`/`src` attribute from an attacker-reachable value.
|
|
20
|
+
|
|
21
|
+
## Officially grounded source classes (OWASP DOM XSS Cheat Sheet)
|
|
22
|
+
|
|
23
|
+
Treat all of the following as attacker-reachable sources unless proven otherwise for the specific application:
|
|
24
|
+
|
|
25
|
+
- `location.*` (`href`, `search`, `hash`, `pathname`) — URL components are fully attacker-controlled; a victim can be sent a crafted link.
|
|
26
|
+
- `document.referrer` — controlled by whatever page linked to the current one.
|
|
27
|
+
- `document.cookie` — if the application itself writes attacker-influenceable values into cookies (e.g., echoing a query param into a cookie), reading it back is a source.
|
|
28
|
+
- `window.name` — persists across navigations within a tab and is attacker-settable by a page that opens or navigates the target window.
|
|
29
|
+
- `postMessage` payloads (`event.data`) — attacker-reachable from any origin unless the receiving handler validates `event.origin`.
|
|
30
|
+
- `localStorage`/`sessionStorage` — attacker-reachable if written by another script/extension in the same origin, or if the value itself originated from one of the sources above and was persisted.
|
|
31
|
+
- API/network responses that echo user-submitted or third-party-submitted content (a comment system, a CMS with contributor accounts, a product-review feed, any endpoint whose stored data originated from user input at some point upstream) — not automatically trusted just because the immediate call site is "just an API response."
|
|
32
|
+
|
|
33
|
+
Not attacker-reachable by default: literal strings in source files, values from the application's own build-time configuration with no runtime mutation path, and content authored exclusively through a trusted internal CMS with no public or user-submission path anywhere upstream.
|
|
34
|
+
|
|
35
|
+
## Non-negotiable design rules
|
|
36
|
+
|
|
37
|
+
### 1. A sink match without a completed source trace is a pattern-only observation, not a finding
|
|
38
|
+
|
|
39
|
+
State this distinction explicitly in every response. Do not let a sink count (e.g., "found 12 uses of `dangerouslySetInnerHTML`") stand in for 12 findings.
|
|
40
|
+
|
|
41
|
+
### 2. Trace through every intermediate transform, not just the assignment site
|
|
42
|
+
|
|
43
|
+
A value can pass through a template-string concatenation, a markdown renderer, a `JSON.parse`, or a component-prop chain before reaching the sink. Each hop must be checked: does it neutralize the attacker-controlled portion, or does it pass it through unmodified (or re-introduce it, e.g., a markdown renderer that itself allows raw HTML passthrough)?
|
|
44
|
+
|
|
45
|
+
### 3. A sanitizer call must sit on the exact traced path
|
|
46
|
+
|
|
47
|
+
"This codebase imports DOMPurify" is not evidence for a specific finding. The sanitizer call must be reachable on the specific hop-by-hop path between the confirmed source and the confirmed sink.
|
|
48
|
+
|
|
49
|
+
### 4. JavaScript-execution sinks (`eval`, `Function()`, string-arg `setTimeout`/`setInterval`) have no sanitization escape hatch
|
|
50
|
+
|
|
51
|
+
Unlike HTML-context sinks, there is no "sanitize the string first" pattern that makes passing attacker-reachable data to these safe while still executing it as code. The only safe fix is removing the dynamic-code-execution pattern entirely (e.g., replacing `setTimeout(userString, 1000)` with `setTimeout(() => knownFunction(parsedArgs), 1000)`).
|
|
52
|
+
|
|
53
|
+
### 5. Do not conflate framework auto-escaping with sink safety
|
|
54
|
+
|
|
55
|
+
React's JSX text interpolation, Vue's `{{ }}` interpolation, and Angular's default property binding all auto-escape by design — but this protection applies only to the framework's normal rendering path, not to any of the explicit escape-hatch sinks listed above. Confirming "the component mostly uses JSX text nodes" does not clear a `dangerouslySetInnerHTML` call three lines later.
|
|
56
|
+
|
|
57
|
+
## Verification targets
|
|
58
|
+
|
|
59
|
+
- Grep for each sink pattern listed above across the review scope (`innerHTML`, `outerHTML`, `insertAdjacentHTML`, `dangerouslySetInnerHTML`, `v-html`, `document.write`, `document.writeln`, `eval(`, `new Function(`, string-argument `setTimeout`/`setInterval`, jQuery `.html()`/`.append()`-family calls).
|
|
60
|
+
- For each match, grep backward through the enclosing function/component for the variable's assignment, prop origin, or API-response parsing site.
|
|
61
|
+
- Grep for a sanitizer import (`dompurify`, `sanitize-html`, or an equivalent project-specific utility) and confirm the call site sits on the traced path, not merely present in the file or module.
|
|
62
|
+
- Grep for `addEventListener('message'` / `.onmessage` and confirm an `event.origin` check exists inside every handler whose `event.data` reaches a sink in scope.
|
|
63
|
+
|
|
64
|
+
## Adversarial checklist
|
|
65
|
+
|
|
66
|
+
Before clearing a sink as not a finding, answer these:
|
|
67
|
+
|
|
68
|
+
- What is the literal origin of the value reaching the sink — a source-file literal, a prop, a computed value, store state, or an API response?
|
|
69
|
+
- Does any hop in that trace involve content any user (current or otherwise) previously submitted, or any of the attacker-reachable sources listed above?
|
|
70
|
+
- Is there a named sanitizer or Trusted-Types transform visible on the exact traced path, or only "a sanitizer exists somewhere in this codebase"?
|
|
71
|
+
- For a JavaScript-execution sink specifically: is there any dynamic-code-execution path at all reachable from attacker-controlled input, regardless of sanitization — because sanitization does not clear this sink class?
|
|
72
|
+
|
|
73
|
+
If any answer is unclear, the finding is confirmed and defaults to HIGH — do not soften it to "worth double-checking."
|
package/skills/frontend/frontend-dom-xss-csp-review/references/third-party-script-governance.md
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
# Third-Party Script Governance and Subresource Integrity
|
|
2
|
+
|
|
3
|
+
Use this reference only when the review scope includes a third-party/CDN `<script src>`, a tag-manager or marketing-loader script injection path, or a dynamic `document.createElement('script')` call fed by remote/untrusted config. Grounded in the MDN Subresource Integrity (SRI) guide and the MDN CSP `script-src` reference (standard-based: W3C Subresource Integrity specification; documentation-based: MDN SRI and CSP guides). This is a supply-chain concern distinct from the sink-taint review in `references/dom-xss-sink-source-taxonomy.md` — the question here is not "does tainted data reach a sink" but "can the code that *executes* on this page be silently substituted by a compromised or malicious third party."
|
|
4
|
+
|
|
5
|
+
## What people get wrong
|
|
6
|
+
|
|
7
|
+
The naive assumption is:
|
|
8
|
+
|
|
9
|
+
> "It's just an analytics/marketing snippet from a reputable CDN, and it's loaded over HTTPS — that's safe enough."
|
|
10
|
+
|
|
11
|
+
Wrong. HTTPS proves transport confidentiality and that the response came from the domain named in the URL; it proves nothing about what that domain currently serves. A compromised CDN account, a hijacked DNS record, a malicious dependency update on the vendor's side, or a MITM on a network the vendor's own infra trusts can all cause the *exact same URL* to serve attacker-controlled JavaScript that executes with full access to the page's origin — cookies, DOM, `localStorage`, everything. Subresource Integrity exists specifically to close this gap: it lets the browser verify the fetched bytes match a hash pinned by the page author, independent of which origin served them.
|
|
12
|
+
|
|
13
|
+
## Officially grounded facts (MDN Subresource Integrity + CSP)
|
|
14
|
+
|
|
15
|
+
- **SRI is a browser-enforced hash check** (standard-based, W3C SRI spec / MDN): when a `<script>` or `<link>` element carries an `integrity` attribute, the browser computes a cryptographic digest of the fetched resource and refuses to execute/apply it if the digest does not match. The `integrity` value supports SHA-256, SHA-384, or SHA-512, expressed as `<algorithm>-<base64-hash>`, and multiple space-separated hashes can be listed as fallbacks.
|
|
16
|
+
- **`integrity` requires a paired `crossorigin` attribute** (documentation-based, MDN SRI guide): for a cross-origin `<script src>`, the browser only performs the SRI comparison if the fetch is made in CORS mode, which requires `crossorigin="anonymous"` (or `"use-credentials"` when appropriate) on the element. An `integrity` attribute present without a `crossorigin` attribute on a cross-origin resource does not get verified as expected — the two attributes must be reviewed as a pair, not independently.
|
|
17
|
+
- **A broad CSP `script-src` allowlist does not substitute for SRI** (documentation-based, MDN CSP `script-src` reference): CSP's `script-src` restricts *which origins* may serve script; it says nothing about whether the *content* served by an allowed origin is the content the developer intended. `script-src https://cdn.example.com` or the broader `script-src https:` both permit the browser to execute whatever the named origin(s) currently return — if that origin is compromised, CSP does not detect it, because CSP checks origin, not content hash. Only SRI (or Trusted Types origin/content enforcement) closes that gap.
|
|
18
|
+
- **Dynamically created `<script>` elements do not get SRI verification for free** (documentation-based, MDN `HTMLScriptElement`): setting `script.integrity` on a script element created via `document.createElement('script')` is supported by the platform, but the far more common real-world pattern — a tag-manager or marketing loader that builds a `<script>` element and sets `.src` to a URL sourced from a remote config/API response, then appends it to the DOM — frequently omits `integrity` entirely, because the loader does not know the hash of a URL it only learns at runtime. In that shape, the safeguard has to shift from a hash check to an **origin allowlist check** performed in code before the `src` is ever assigned.
|
|
19
|
+
- **Trusted Types `createScriptURL` is the platform hook for enforcing that allowlist** (standard-based, W3C Trusted Types spec): when CSP's `require-trusted-types-for 'script'` is active, the platform requires any `HTMLScriptElement.src` assignment (and other script-URL sinks) to go through a `TrustedScriptURL` produced by a registered policy's `createScriptURL` callback. A policy that validates the incoming URL's origin against a fixed allowlist before returning it — and throws or rewrites otherwise — is the documented way to make a remote-config-driven script loader safe. A policy whose callback returns the input unmodified is a permissive pass-through and provides no protection, per the general Trusted Types pass-through caveat already covered in `references/trusted-types-enforcement.md`.
|
|
20
|
+
|
|
21
|
+
## Non-negotiable design rules
|
|
22
|
+
|
|
23
|
+
### 1. Every third-party/CDN `<script src>` must carry both `integrity` and `crossorigin`, or be a confirmed finding
|
|
24
|
+
|
|
25
|
+
Grep every `<script src="https://...">` (or `<link rel="...">` for stylesheets/modulepreload where applicable) pointing at a different origin than the page itself. Absence of `integrity` is a confirmed supply-chain finding regardless of the vendor's current reputation — SRI reviews the *mechanism*, not the *vendor*. `integrity` present without `crossorigin` on a cross-origin element is also a confirmed finding: the pairing is required for the check to actually run.
|
|
26
|
+
|
|
27
|
+
### 2. A dynamic `document.createElement('script')` path fed by remote config needs an origin-allowlist check, not just SRI
|
|
28
|
+
|
|
29
|
+
If a config value, API response, or tag-manager payload supplies the URL assigned to `script.src`, SRI is not the applicable control (the hash is not known ahead of time). Instead confirm the code validates the URL's origin against a fixed, statically defined allowlist before assignment — ideally enforced structurally via a Trusted Types `createScriptURL` policy under `require-trusted-types-for 'script'`, not merely as an inline `if` check that a future refactor could silently drop.
|
|
30
|
+
|
|
31
|
+
### 3. Tag-manager and marketing-loader injection is a first-class supply-chain path, not an edge case
|
|
32
|
+
|
|
33
|
+
Analytics tags, marketing pixels, and A/B-testing snippets routinely fetch a remote configuration document and then dynamically inject one or more `<script>` elements based on it. Treat this pattern as in-scope for review whenever present: identify where the config originates (first-party API vs. third-party vendor endpoint), whether that endpoint is authenticated/integrity-protected in its own right, and whether the resulting script URLs are constrained to an expected set of origins before injection.
|
|
34
|
+
|
|
35
|
+
### 4. A broad or wildcard `script-src` in CSP compounds an SRI gap — call out both, do not let one substitute for the other
|
|
36
|
+
|
|
37
|
+
If the CSP audit (see `references/csp-directive-review.md`) finds `script-src` scoped broadly (e.g., a wildcard subdomain like `https://*.cdn.example.com`, or `https:` alone) *and* the third-party scripts loaded under that policy lack `integrity`, state both findings explicitly and note they compound: CSP is not narrowing which origins can serve script, and SRI is not verifying what those origins actually return.
|
|
38
|
+
|
|
39
|
+
### 5. `'unsafe-inline'` defeats third-party script governance the same way it defeats sink review
|
|
40
|
+
|
|
41
|
+
If `'unsafe-inline'` is present in `script-src`, any injected inline `<script>` block — including one written by a compromised third-party loader — executes regardless of SRI or origin-allowlist controls applied to `<script src>` elements. Note this compounding relationship rather than treating SRI review and the `'unsafe-inline'` CSP finding as unrelated.
|
|
42
|
+
|
|
43
|
+
## Safe idiom shapes (illustrative, not a template to copy verbatim)
|
|
44
|
+
|
|
45
|
+
Static third-party script with SRI:
|
|
46
|
+
|
|
47
|
+
```html
|
|
48
|
+
<script
|
|
49
|
+
src="https://cdn.example.com/analytics.js"
|
|
50
|
+
integrity="sha384-BASE64_HASH_PLACEHOLDER"
|
|
51
|
+
crossorigin="anonymous">
|
|
52
|
+
</script>
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Dynamic script injection with an origin-allowlist enforced via Trusted Types:
|
|
56
|
+
|
|
57
|
+
```js
|
|
58
|
+
const allowedScriptOrigins = ['https://cdn.example.com'];
|
|
59
|
+
const scriptPolicy = trustedTypes.createPolicy('vendor-script-loader', {
|
|
60
|
+
createScriptURL(url) {
|
|
61
|
+
const parsed = new URL(url, location.href);
|
|
62
|
+
if (!allowedScriptOrigins.includes(parsed.origin)) {
|
|
63
|
+
throw new Error('Blocked script URL outside allowlist: ' + parsed.origin);
|
|
64
|
+
}
|
|
65
|
+
return url;
|
|
66
|
+
},
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
const script = document.createElement('script');
|
|
70
|
+
script.src = scriptPolicy.createScriptURL(configFromRemote.scriptUrl);
|
|
71
|
+
script.crossOrigin = 'anonymous';
|
|
72
|
+
document.body.appendChild(script);
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Anti-pattern (common in the wild — do not approve):
|
|
76
|
+
|
|
77
|
+
```html
|
|
78
|
+
<script src="https://cdn.example.com/analytics.js"></script>
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
```js
|
|
82
|
+
const script = document.createElement('script');
|
|
83
|
+
script.src = configFromRemote.scriptUrl; // no allowlist check, no Trusted Types policy
|
|
84
|
+
document.body.appendChild(script);
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Both anti-patterns execute whatever the named origin (or config-supplied URL) currently returns, with no mechanism to detect substitution.
|
|
88
|
+
|
|
89
|
+
## Verification targets
|
|
90
|
+
|
|
91
|
+
- Grep every `<script src="http` (or `https`) across templates/rendered HTML for a cross-origin target; confirm `integrity` and `crossorigin` are both present on each match.
|
|
92
|
+
- Grep for `document.createElement('script')` and trace every `.src =` assignment on the resulting element back to its data source; if the source is a config object, API response, or tag-manager payload, confirm an origin-allowlist check or a Trusted Types `createScriptURL` policy sits between the untrusted value and the assignment.
|
|
93
|
+
- Cross-reference any CSP `script-src` finding from `references/csp-directive-review.md` — a broad allowlist there compounds with a missing-SRI finding here.
|
|
94
|
+
- If `require-trusted-types-for 'script'` is active, confirm the registered policy's `createScriptURL` callback actually validates origin rather than returning the input unmodified (same pass-through caveat as `references/trusted-types-enforcement.md`).
|
|
95
|
+
|
|
96
|
+
## When to push back
|
|
97
|
+
|
|
98
|
+
Push back if the user asks to:
|
|
99
|
+
|
|
100
|
+
- approve a third-party `<script src>` because "the vendor is reputable" without `integrity`/`crossorigin` present — reputation is not a substitute for a browser-enforced hash check,
|
|
101
|
+
- treat a broad CSP `script-src` allowlist as sufficient protection against a compromised or malicious third-party script served from an allowed origin,
|
|
102
|
+
- ship a tag-manager or marketing-loader integration that injects scripts from a remote-config-supplied URL with no origin-allowlist check "because it's just analytics",
|
|
103
|
+
- add a Trusted Types `createScriptURL` policy that returns the input URL unmodified and call the supply-chain risk mitigated.
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# Trusted Types Enforcement Review
|
|
2
|
+
|
|
3
|
+
Use this reference only when the review scope includes Trusted Types policy design or `require-trusted-types-for`/`trusted-types` CSP directive enforcement. Grounded in the W3C Trusted Types specification.
|
|
4
|
+
|
|
5
|
+
## What people get wrong
|
|
6
|
+
|
|
7
|
+
The naive assumption is:
|
|
8
|
+
|
|
9
|
+
> "The code calls `trustedTypes.createPolicy(...)`, so Trusted Types is protecting this application."
|
|
10
|
+
|
|
11
|
+
Wrong. Trusted Types is an opt-in enforcement mechanism with two independent conditions that must both hold: (1) the CSP `require-trusted-types-for 'script'` directive must actually be set so the browser enforces the requirement at all, and (2) every policy's `createHTML`/`createScript`/`createScriptURL` callback must perform a real transformation (sanitize or reject), not pass the input through unmodified. Code that creates a policy but never sets the enforcing CSP directive provides no protection — Trusted Types objects become optional convenience wrappers, and raw strings can still reach `innerHTML` and other sinks unchecked. A policy whose callback returns its input unchanged provides no protection either, even with enforcement active.
|
|
12
|
+
|
|
13
|
+
## Officially grounded rules (W3C Trusted Types spec)
|
|
14
|
+
|
|
15
|
+
- **Trusted Types only restricts assignment to specific "injection sink" DOM APIs** (e.g., `Element.innerHTML`, `Element.outerHTML`, `Document.write`, `Range.createContextualFragment`, `eval`-family via `TrustedScript`, and `<script src>`/similar via `TrustedScriptURL`) when `require-trusted-types-for 'script'` is set. Without that CSP directive, these sinks continue to accept plain strings exactly as before — Trusted Types objects can still be created and used, but they are not required.
|
|
16
|
+
- **The `trusted-types` CSP directive restricts which named policies may be created**, and whether an unnamed/default policy or duplicate policy names are permitted. A missing `trusted-types` directive combined with `require-trusted-types-for 'script'` still enforces the sink restriction, but allows any script running on the page (including an injected one, before enforcement blocks further injection) to create its own policy — restricting allowed policy names closes this gap.
|
|
17
|
+
- **A policy named `'default'` is special**: per spec, when a string is assigned directly to a Trusted-Types-guarded sink (bypassing an explicit policy call), the browser invokes the `'default'` policy if one is registered, implicitly converting the string. This is a compatibility escape hatch, not a security boundary — a permissive `'default'` policy that echoes its input unmodified reintroduces exactly the unrestricted-sink behavior Trusted Types is meant to close.
|
|
18
|
+
- **`createHTML`, `createScript`, and `createScriptURL` are ordinary JavaScript callbacks** with no built-in sanitization. The spec does not provide a default sanitizer; the application must supply one (e.g., calling DOMPurify inside `createHTML`) or reject/throw for unsafe input. A callback that simply returns its argument is spec-compliant but provides zero security value.
|
|
19
|
+
|
|
20
|
+
## Non-negotiable design rules
|
|
21
|
+
|
|
22
|
+
### 1. Confirm the enforcing CSP directive is actually set, not just that policy-creation code exists
|
|
23
|
+
|
|
24
|
+
Grep the effective CSP (see `references/csp-directive-review.md` for locating it) for `require-trusted-types-for 'script'`. If absent, every `trustedTypes.createPolicy` call in the codebase is inert for enforcement purposes — state this as a confirmed finding, not as "Trusted Types is partially implemented."
|
|
25
|
+
|
|
26
|
+
### 2. Read every policy callback body, not just the `createPolicy` call site
|
|
27
|
+
|
|
28
|
+
For each `createHTML`/`createScript`/`createScriptURL` callback, confirm it performs a real transformation: a sanitizer call (e.g., DOMPurify), a strict allowlist check with rejection/throw on mismatch, or an equivalent safe transform. A callback body of `(input) => input` or equivalent pass-through is a confirmed finding regardless of enforcement being active.
|
|
29
|
+
|
|
30
|
+
### 3. Treat a permissive `'default'` policy as high severity
|
|
31
|
+
|
|
32
|
+
Because the `'default'` policy silently intercepts any direct string assignment to a guarded sink, a permissive `'default'` policy re-opens every sink in the application at once — it has broader blast radius than a single permissive named policy used in one call site. Flag this distinctly and at higher severity than a single permissive named-policy finding.
|
|
33
|
+
|
|
34
|
+
### 4. Restrict allowed policy names via the `trusted-types` directive when feasible
|
|
35
|
+
|
|
36
|
+
If the `require-trusted-types-for` directive is set but the `trusted-types` directive is absent or overly permissive (e.g., no allowlist), note this as a gap: any script that executes before full lockdown (or a supply-chain-compromised dependency) can register its own arbitrarily permissive policy.
|
|
37
|
+
|
|
38
|
+
### 5. Do not treat "uses a framework with built-in Trusted Types support" as sufficient without confirming the actual runtime configuration
|
|
39
|
+
|
|
40
|
+
Some frameworks and bundlers offer opt-in Trusted Types integration, but it must be explicitly enabled and configured (policy name, sanitizer wiring) in the project's actual config — its mere availability in the framework does not mean the reviewed application has turned it on. Confirm via the project's actual build/runtime configuration, not the framework's general capability.
|
|
41
|
+
|
|
42
|
+
## Minimal safe implementation pattern
|
|
43
|
+
|
|
44
|
+
```javascript
|
|
45
|
+
// Enforcing CSP directive (see csp-directive-review.md):
|
|
46
|
+
// Content-Security-Policy: require-trusted-types-for 'script'; trusted-types app-html;
|
|
47
|
+
|
|
48
|
+
import DOMPurify from 'dompurify';
|
|
49
|
+
|
|
50
|
+
const htmlPolicy = trustedTypes.createPolicy('app-html', {
|
|
51
|
+
createHTML: (input) => DOMPurify.sanitize(input),
|
|
52
|
+
createScript: () => { throw new Error('script creation not permitted by this policy'); },
|
|
53
|
+
createScriptURL: (input) => {
|
|
54
|
+
const allowed = ['https://cdn.trusted-example.com/'];
|
|
55
|
+
if (!allowed.some((prefix) => input.startsWith(prefix))) {
|
|
56
|
+
throw new Error('script URL not on allowlist');
|
|
57
|
+
}
|
|
58
|
+
return input;
|
|
59
|
+
},
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
element.innerHTML = htmlPolicy.createHTML(untrustedInput);
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Anti-pattern (policy exists but provides no protection — do not approve):
|
|
66
|
+
|
|
67
|
+
```javascript
|
|
68
|
+
// No 'require-trusted-types-for' directive set anywhere — this policy is never enforced.
|
|
69
|
+
const policy = trustedTypes.createPolicy('default', {
|
|
70
|
+
createHTML: (input) => input, // pass-through: zero sanitization
|
|
71
|
+
});
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Adversarial checklist
|
|
75
|
+
|
|
76
|
+
Before clearing Trusted Types as properly enforced, answer these:
|
|
77
|
+
|
|
78
|
+
- Is `require-trusted-types-for 'script'` actually present in the effective CSP (header or meta tag), or does only application code reference the Trusted Types API?
|
|
79
|
+
- For every `createPolicy` call in scope, does the `createHTML`/`createScript`/`createScriptURL` callback perform a real sanitize-or-reject transform, or does it return its input unmodified?
|
|
80
|
+
- Is there a `'default'` policy registered? If so, is its transform equally strict as the named policies, given its broader implicit-invocation blast radius?
|
|
81
|
+
- Is the `trusted-types` directive present to restrict which policy names may be created, or can any script on the page register an arbitrarily permissive policy?
|
|
82
|
+
- Does this confirmed enforcement actually cover the specific sink(s) flagged in a co-occurring `references/dom-xss-sink-source-taxonomy.md` finding, or is the policy scoped to a different part of the application?
|
|
83
|
+
|
|
84
|
+
If any answer reveals a gap, state it as a confirmed finding — do not describe partial implementation as "Trusted Types is in place."
|
|
85
|
+
|
|
86
|
+
## Verification targets
|
|
87
|
+
|
|
88
|
+
- Grep the effective CSP for `require-trusted-types-for` and `trusted-types` directive values.
|
|
89
|
+
- Grep the codebase for `trustedTypes.createPolicy` and read every callback function body in full.
|
|
90
|
+
- Grep specifically for a policy named `'default'` and treat any match as requiring the same scrutiny as every named policy, plus the broader-blast-radius note above.
|
|
91
|
+
- Cross-reference confirmed Trusted-Types-guarded sinks against the sink list in `references/dom-xss-sink-source-taxonomy.md` to confirm enforcement scope actually matches the sinks the review is concerned with.
|
|
92
|
+
|
|
93
|
+
## When to push back
|
|
94
|
+
|
|
95
|
+
Push back if the user asks to:
|
|
96
|
+
|
|
97
|
+
- treat the presence of `trustedTypes.createPolicy` calls as sufficient without confirming the enforcing CSP directive is set,
|
|
98
|
+
- approve a policy callback that passes input through unmodified because "we'll add sanitization later,"
|
|
99
|
+
- register a permissive `'default'` policy as a convenience to avoid updating call sites — this is a confirmed high-severity finding given its implicit, page-wide invocation,
|
|
100
|
+
- skip verifying the `trusted-types` directive's policy-name allowlist because "only our own code creates policies" — a supply-chain-compromised dependency is exactly the scenario this allowlist defends against.
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# Review Workflow and Findings Contract
|
|
2
|
+
|
|
3
|
+
Use this reference for the step-by-step review procedure and the required output shape. Load the sink-taxonomy, CSP, and Trusted Types references only for the specific concern the code under review actually raises.
|
|
4
|
+
|
|
5
|
+
## Prerequisites
|
|
6
|
+
|
|
7
|
+
- Read `package.json` to confirm the framework(s) and major version(s) in scope. Sink APIs, sanitizer defaults, and CSP/Trusted Types tooling (e.g., a framework's CSP-nonce middleware) differ by framework and version — do not apply one framework's semantics to another's codebase.
|
|
8
|
+
- Identify whether the review scope is sink-focused (specific file/component), CSP-focused (a header/meta value or server config emitting one), Trusted Types-focused, or all three. Scope the review to what was actually asked; do not expand a single-sink review into a full CSP audit unless requested.
|
|
9
|
+
|
|
10
|
+
## Workflow
|
|
11
|
+
|
|
12
|
+
1. **Enumerate every candidate sink in scope.** Grep for `innerHTML`, `outerHTML`, `dangerouslySetInnerHTML`, `v-html`, `document.write`, `document.writeln`, `eval(`, `new Function(`, and `setTimeout`/`setInterval` calls whose first argument is a string literal built from a variable (not a function reference). See `references/dom-xss-sink-source-taxonomy.md`.
|
|
13
|
+
2. **Trace each candidate sink's data source backward.** Follow the value through props, variables, function returns, and API responses to its origin. Classify the origin as attacker-reachable (URL/query params, `postMessage`, request bodies, third-party API responses that echo user or third-party input, `document.referrer`, `window.name`, `localStorage`/`sessionStorage` writable by another origin or script context) or fully origin-controlled (a literal in source, a value from the app's own trusted build-time config with no runtime mutation path).
|
|
14
|
+
3. **For each attacker-reachable sink, check for a sanitizer call on the exact traced path.** A sanitizer import or call present elsewhere in the codebase does not clear the finding — it must sit between the untrusted origin and the sink on the specific path reviewed.
|
|
15
|
+
4. **If the review scope includes CSP, locate the effective policy.** Find the `Content-Security-Policy` HTTP header, the `<meta http-equiv="Content-Security-Policy">` tag, or the server/framework config that emits either. Parse directive-by-directive per `references/csp-directive-review.md`.
|
|
16
|
+
5. **If the review scope includes Trusted Types, locate the enforcement mode and default policy.** Check for `require-trusted-types-for 'script'` and `trusted-types` directives, and read every `trustedTypes.createPolicy(...)` call's callback bodies per `references/trusted-types-enforcement.md`.
|
|
17
|
+
6. **Check every `postMessage` listener in scope for origin validation.** An `addEventListener('message', handler)` with no `event.origin` check inside `handler` is itself an untraced taint source for any sink it feeds.
|
|
18
|
+
7. **Produce ranked findings** using the output contract below.
|
|
19
|
+
|
|
20
|
+
## Decision tree (taint confirmation)
|
|
21
|
+
|
|
22
|
+
- Sink match, traced data source is attacker-reachable, no sanitizer/Trusted-Types call on the exact path → **confirmed finding**, severity per sink class (script-execution sinks — `eval`, `Function()`, `innerHTML`/`dangerouslySetInnerHTML`/`v-html` with script-capable markup, `document.write` — default HIGH; URL/attribute-injection sinks depend on reachability, MEDIUM-to-HIGH).
|
|
23
|
+
- Sink match, traced data source is attacker-reachable, but a named sanitizer call (e.g., DOMPurify) or a Trusted Types policy transformation visibly sits on the exact path → **not a finding**; state this explicitly with the sanitizer/policy name and location rather than omitting the sink from the review.
|
|
24
|
+
- Sink match, traced data source is fully origin-controlled with no attacker-reachable input anywhere in the trace → **not a finding**, but record it explicitly ("reviewed, not a finding, because X") rather than silently dropping it — a later code change could introduce a reachable path into the same sink.
|
|
25
|
+
- Sink match, trace could not be completed within the review scope (e.g., the origin is in a third-party dependency not under review, or requires runtime state unavailable statically) → **pattern-only observation**, not a confirmed finding; state exactly what would be needed to complete the trace.
|
|
26
|
+
- CSP directive parsed and found permissive (`unsafe-inline`, `unsafe-eval`, missing `object-src 'none'`, missing `base-uri`, wildcard `script-src`) → **confirmed finding** regardless of whether a sink finding co-occurs; CSP gaps are findings in their own right.
|
|
27
|
+
- Trusted Types default policy callback returns input unmodified or is absent while `require-trusted-types-for 'script'` is not set → **confirmed finding**; enforcement is not active even if policy-creation code exists.
|
|
28
|
+
|
|
29
|
+
## Output contract
|
|
30
|
+
|
|
31
|
+
Every response from this skill must return:
|
|
32
|
+
|
|
33
|
+
1. **Scope** — the file(s)/sink(s), CSP surface, and/or Trusted Types surface actually reviewed.
|
|
34
|
+
2. **Ranked findings** — each with file:line (or CSP directive name / policy name), defect category (`dom-xss-sink`, `postmessage-origin`, `csp-directive-gap`, or `trusted-types-gap`), the concrete source-to-sink trace or directive-level gap, and a fix sketch matching the confirmed framework's documented pattern.
|
|
35
|
+
3. **Confirmed-taint vs. pattern-only status** for every sink finding — never presented as equivalent to a confirmed finding.
|
|
36
|
+
4. **Sanitizer/Trusted-Types status per sink finding** — an explicit statement of whether a sanitizer or Trusted Types transform is present on the traced path; never inferred.
|
|
37
|
+
5. **OWASP category id** for every confirmed finding (e.g., A03:2021-Injection, A05:2021-Security Misconfiguration).
|
|
38
|
+
6. **Evidence level per finding** — `repo evidence`, `documentation-based`, or `inference`.
|
|
39
|
+
7. **Verdict** — approve / approve-with-notes / block.
|
|
40
|
+
8. **Explicit no-live-exploit statement** — confirm no exploit payload was run against any live or staging target, and state what remains to be manually confirmed (e.g., "confirming exploitability in production requires a controlled, authorized penetration test").
|
|
41
|
+
9. **Open questions or out-of-scope items** not covered by this review pass.
|
|
42
|
+
|
|
43
|
+
## When to push back
|
|
44
|
+
|
|
45
|
+
Push back if the user asks to:
|
|
46
|
+
|
|
47
|
+
- treat a sink match as a confirmed finding without a completed source-to-sink trace — a grep hit is not a finding,
|
|
48
|
+
- clear a sink finding because "we sanitize elsewhere in the app" with no sanitizer call visible on the specific traced path,
|
|
49
|
+
- treat CSP header presence alone as sufficient without directive-level parsing,
|
|
50
|
+
- run an exploit payload against a live or staging system to "prove" a finding — this skill does not perform live penetration testing; confirm via static trace and recommend authorized live testing separately if needed,
|
|
51
|
+
- downgrade a confirmed script-execution sink finding to informational because "it's probably fine" — this skill's default for confirmed script-execution sinks is HIGH.
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: frontend-error-boundary-resilience-review
|
|
3
|
+
description: Reviews error-boundary placement, fallback UX, and failure-isolation strategy to prevent a single component's runtime error from crashing the whole page, ensuring granular, accessible degradation instead of an app-root-only safety net or a silent, unlogged failure.
|
|
4
|
+
allowed-tools: Read Grep Glob
|
|
5
|
+
metadata:
|
|
6
|
+
author: "github: Raishin"
|
|
7
|
+
version: "0.1.0"
|
|
8
|
+
updated: "2026-07-02"
|
|
9
|
+
category: resilience
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# Frontend Error Boundary & Resilience Review
|
|
13
|
+
|
|
14
|
+
## Purpose
|
|
15
|
+
|
|
16
|
+
Review the placement, granularity, and fallback UX of error boundaries across a frontend application so that a single component's runtime error is isolated to its own section instead of blanking the entire page. This skill exists because "we have an error boundary" is frequently true and still insufficient: a single app-root boundary, a fallback that leaks `error.stack` to end users, or a caught error that is never logged are each individually shippable-looking and each individually a defect. This skill treats failure isolation as a design surface with its own placement rules, accessibility requirements, and observability contract — not an afterthought bolted on after an incident.
|
|
17
|
+
|
|
18
|
+
## When to use
|
|
19
|
+
|
|
20
|
+
Use this skill when the user asks to:
|
|
21
|
+
|
|
22
|
+
- review a new feature's error-handling design before it ships,
|
|
23
|
+
- investigate a production incident where a non-critical widget's error blanked an entire page or unrelated flow,
|
|
24
|
+
- audit an existing application for missing error boundaries around suspending, async, or third-party-embedded components,
|
|
25
|
+
- review fallback UI copy, accessibility, or recovery affordances for an error state.
|
|
26
|
+
|
|
27
|
+
Do not use this skill for:
|
|
28
|
+
|
|
29
|
+
- diagnosing the specific root cause of a hydration-mismatch error — that is `ssr-hydration-streaming-diagnosis`, though the two are frequently reviewed together since every suspending read needs a paired error boundary,
|
|
30
|
+
- reviewing the shape or contract of API error responses from the server — that is `api-integration-contract-review`.
|
|
31
|
+
|
|
32
|
+
## Context7 Documentation Protocol
|
|
33
|
+
|
|
34
|
+
- Resolve `/reactjs/react.dev` before approving any specific error-boundary implementation. React does not currently offer a function-component error-boundary primitive — `static getDerivedStateFromError` and `componentDidCatch` are class-component-only lifecycle methods, and React's own docs point to the community-maintained `react-error-boundary` package for teams that want a component API without hand-writing the class boilerplate. Recommending a hook-based error boundary (`useErrorBoundary` as a from-scratch primitive, for example) as if React ships one natively is a version-sensitive mistake; verify before approving.
|
|
35
|
+
- Call `query-docs` scoped to the confirmed React major version for "error boundary" and, if the tree also suspends via `use()` or `Suspense`, for "use hook error boundary" — a rejected Promise from `use()` propagates to the nearest Error Boundary, not the nearest Suspense fallback, so a suspending read wrapped only in `<Suspense>` with no ancestor Error Boundary crashes to unhandled on rejection.
|
|
36
|
+
- If the codebase uses `react-error-boundary`, confirm the installed version's API surface (`fallback` vs `fallbackRender` vs `FallbackComponent`, `resetKeys`, `onReset`) via `query-docs` before approving a specific prop pattern — this library's API has shifted across major versions.
|
|
37
|
+
- If Context7 is unavailable, fall back to the `official_docs` URLs in this skill's `metadata.json` and label every claim `documentation-based, unverified against current release`.
|
|
38
|
+
|
|
39
|
+
## Lean operating rules
|
|
40
|
+
|
|
41
|
+
- One error boundary at the app root is not "handled" — it is a single point of total failure with narrower blast radius than no boundary at all, but it still takes down the whole page for any descendant error. Require granular, per-independently-failable-section boundaries around anything non-critical (a recommendations panel, an ad slot, a third-party embed) so its failure cannot take the checkout form or the primary content with it.
|
|
42
|
+
- Every suspending or async-rejectable read (`use()` on a Promise, a lazy-loaded component via `React.lazy`, a third-party SDK embed that can throw) needs a paired ancestor Error Boundary. A Suspense boundary alone only handles the pending state, not rejection — treat a suspending read with no ancestor Error Boundary as a crash-to-blank defect, not a style preference.
|
|
43
|
+
- Fallback UI must never render raw `error.message` or `error.stack` to end users in production. That is an information-disclosure defect, not a copy nitpick — internal implementation detail (stack traces, library names, internal endpoint paths) belongs in server-side/observability logs, never in the DOM a user or attacker can read.
|
|
44
|
+
- A caught error that is never logged anywhere is a worse outcome than an uncaught one: the uncaught error is at least visible in a crash report or user complaint, while a silently-swallowed caught error erodes observability into real failure rates with no signal. `componentDidCatch` (or the `onError`/`onReset` hook equivalent in `react-error-boundary`) must always forward to logging/observability, even when the UI gracefully degrades.
|
|
45
|
+
- Fallback UI is not just a decision-tree checkbox — it must be perceivable by assistive technology. Apply the ARIA APG alert pattern (`role="alert"` or an `aria-live` region) so screen-reader users are notified of the failure, not left staring at a silently-changed DOM region.
|
|
46
|
+
- Never execute, build, or run application code as part of this review; this is a static-review skill (Read/Grep/Glob only) — review from the component tree, existing boundary placement, and any incident report or fallback UI source the user provides.
|
|
47
|
+
|
|
48
|
+
## References
|
|
49
|
+
|
|
50
|
+
Load these only when needed:
|
|
51
|
+
|
|
52
|
+
- [Boundary placement and granularity](references/boundary-placement-and-granularity.md) — use when mapping the component tree to confirm every suspending/async/third-party component has an ancestor error boundary, and when granularity is too coarse (app-root-only).
|
|
53
|
+
- [Fallback UX and accessibility](references/fallback-ux-and-accessibility.md) — use when reviewing fallback UI copy, information-disclosure risk, accessible alert semantics, recovery affordances, or layout-shift impact of a fallback swap.
|
|
54
|
+
- [Observability and recovery](references/observability-and-recovery.md) — use when confirming caught errors are still logged, and when reviewing reset/retry design (`resetKeys`, retry affordances) so a boundary doesn't stay permanently tripped.
|
|
55
|
+
|
|
56
|
+
## Response minimum
|
|
57
|
+
|
|
58
|
+
Return, at minimum:
|
|
59
|
+
|
|
60
|
+
- the error-boundary placement map (component → boundary → fallback UX → logging hook) or the specific gap found,
|
|
61
|
+
- evidence level (`documentation-based`, `repo evidence`, `user-provided evidence`, or `inference`) and what Context7 query grounded the claim,
|
|
62
|
+
- whether fallback UI leaks raw error detail and whether it uses accessible alert semantics,
|
|
63
|
+
- confirmation that caught errors are still logged to observability, or explicit flag if not,
|
|
64
|
+
- verdict: approve / approve-with-notes / block.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "frontend-error-boundary-resilience-review",
|
|
3
|
+
"name": "Frontend Error Boundary & Resilience Review",
|
|
4
|
+
"type": "skill",
|
|
5
|
+
"provider": "frontend",
|
|
6
|
+
"harnesses": [
|
|
7
|
+
"claude-code",
|
|
8
|
+
"cursor",
|
|
9
|
+
"codex",
|
|
10
|
+
"gemini",
|
|
11
|
+
"kiro",
|
|
12
|
+
"other"
|
|
13
|
+
],
|
|
14
|
+
"summary": "Reviews error-boundary placement, fallback UX, and failure-isolation strategy to prevent whole-page crashes from a single component's runtime error and ensure graceful, accessible degradation.",
|
|
15
|
+
"source_type": "original",
|
|
16
|
+
"official_docs": [
|
|
17
|
+
"https://react.dev/reference/react/Component#catching-rendering-errors-with-an-error-boundary",
|
|
18
|
+
"https://react.dev/reference/react/Suspense",
|
|
19
|
+
"https://www.w3.org/WAI/ARIA/apg/patterns/alert/",
|
|
20
|
+
"https://web.dev/articles/vitals"
|
|
21
|
+
],
|
|
22
|
+
"security_notes": "Error-boundary fallback UI must never render raw error.message or error.stack from unexpected exceptions to end users in production - this can leak internal implementation detail; require a sanitized, generic fallback with detail only in server-side/observability logs. Static-review-only skill: it reads and greps component tree, boundary placement, and fallback UI source but never executes, builds, or runs application code.",
|
|
23
|
+
"last_verified": "2026-07-02",
|
|
24
|
+
"path": "skills/frontend/frontend-error-boundary-resilience-review",
|
|
25
|
+
"author": "github: Raishin",
|
|
26
|
+
"version": "0.1.0"
|
|
27
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# Boundary Placement and Granularity
|
|
2
|
+
|
|
3
|
+
Use this reference when mapping a component tree to confirm every suspending, async, or third-party-embedded component has an ancestor error boundary, and when the only boundary present is at the app root.
|
|
4
|
+
|
|
5
|
+
## What people get wrong
|
|
6
|
+
|
|
7
|
+
The naive story is:
|
|
8
|
+
|
|
9
|
+
> We have an `ErrorBoundary` wrapping `<App />`, so errors are handled.
|
|
10
|
+
|
|
11
|
+
Technically true, practically insufficient. An app-root-only boundary means every descendant error — no matter how unimportant the component — takes the entire page down to the same fallback. A broken third-party ad slot and a broken checkout form produce the identical user-facing outcome: total page loss. Error boundaries are not a binary "present or absent" property of an app; they are a placement and granularity design, and the design question is *where the blast radius of each independently-failable section ends*.
|
|
12
|
+
|
|
13
|
+
## Officially grounded shape
|
|
14
|
+
|
|
15
|
+
- React does not currently ship a function-component error-boundary primitive. `static getDerivedStateFromError(error)` and `componentDidCatch(error, info)` are class-component lifecycle methods; a component defining both is, by definition, an Error Boundary. Teams that want a component API without writing the class boilerplate use the community-maintained `react-error-boundary` package, which React's own reference docs link to.
|
|
16
|
+
- `getDerivedStateFromError` must be a pure function that returns the state used to render the fallback; it should not perform side effects. `componentDidCatch` is where side effects (logging) belong. A component needs both to be a complete, useful Error Boundary — `getDerivedStateFromError` alone renders a fallback with no logging; `componentDidCatch` alone (calling `setState` inside it) is a deprecated pattern.
|
|
17
|
+
- An Error Boundary catches errors thrown during rendering by its children, including distant descendants — not just its immediate child.
|
|
18
|
+
- A component that suspends via `use()` on a Promise, or any Suspense-triggering data read, propagates a **rejection** to the nearest ancestor Error Boundary, not the nearest Suspense fallback. Suspense and Error Boundaries solve different problems: Suspense handles the pending state; the Error Boundary handles the rejected/thrown state. Official React examples consistently pair them: `<ErrorBoundary fallback={...}><Suspense fallback={...}>{children}</Suspense></ErrorBoundary>`.
|
|
19
|
+
- `React.lazy`-loaded components that fail to load (network failure, bad chunk) throw during render and require the same ancestor Error Boundary treatment as any other suspending/rejecting read.
|
|
20
|
+
|
|
21
|
+
## Non-negotiable design rules
|
|
22
|
+
|
|
23
|
+
### 1. Every suspending, async, or third-party component needs an ancestor error boundary
|
|
24
|
+
|
|
25
|
+
This is not optional and not a style preference. Map every component that can throw during render — a `use()` call, a lazy-loaded chunk, a third-party embed's mount/render path — and confirm an Error Boundary exists somewhere above it in the tree. If it does not, the component is one runtime error away from an unhandled crash.
|
|
26
|
+
|
|
27
|
+
### 2. Boundary granularity must match failure-isolation need, not code convenience
|
|
28
|
+
|
|
29
|
+
One boundary at the app root is the easiest thing to write and the worst thing to ship when the page mixes critical flows (checkout, primary content, forms) with non-critical, independently-failable sections (recommendations, third-party embeds, secondary widgets). Wrap each non-critical, independently-failable section in its own boundary so its failure cannot propagate upward into a critical flow's render tree.
|
|
30
|
+
|
|
31
|
+
### 3. Do not conflate "has a boundary somewhere" with "has the right boundary"
|
|
32
|
+
|
|
33
|
+
A component nested three levels inside a checkout form that shares the checkout form's own Error Boundary is not isolated — an error in that nested component still trips the checkout form's fallback. The relevant question is always: does *this specific* independently-failable unit have a boundary that fails *only that unit*, or does it share a boundary with something the business cannot afford to lose?
|
|
34
|
+
|
|
35
|
+
### 4. Suspense placement and Error Boundary placement are related but not the same decision
|
|
36
|
+
|
|
37
|
+
A Suspense boundary controls what shows while content is pending and bounds hydration-mismatch re-render blast radius. It does not handle rejection. When reviewing a tree, evaluate Suspense granularity and Error Boundary coverage as two related but separately-checked properties — a well-placed Suspense boundary with no ancestor Error Boundary is still a crash-to-blank defect on rejection.
|
|
38
|
+
|
|
39
|
+
## Minimal safe review flow
|
|
40
|
+
|
|
41
|
+
1. Map every suspending/async read (`use()`, lazy-loaded component, third-party SDK mount) and every third-party embed in the tree under review.
|
|
42
|
+
2. For each, walk up the ancestor chain and confirm an Error Boundary exists. If none exists, flag as a defect immediately — do not wait for other findings.
|
|
43
|
+
3. For each existing Error Boundary, identify exactly which components it covers and whether that scope matches an independently-failable unit (good) or spans across a critical flow and a non-critical section (defect — too coarse).
|
|
44
|
+
4. Confirm no critical flow (checkout, auth, primary content) shares a boundary with a non-critical, independently-failable section.
|
|
45
|
+
5. Confirm each Error Boundary implements both `getDerivedStateFromError` (or the `fallback`/`fallbackRender` equivalent) and `componentDidCatch`/`onError` — a boundary with only one of the two is incomplete (see `observability-and-recovery.md` for the logging half).
|
|
46
|
+
6. State the verdict per boundary and per uncovered suspending/third-party component, not just for the tree as a whole.
|
|
47
|
+
|
|
48
|
+
## High-risk assumptions to kill
|
|
49
|
+
|
|
50
|
+
- "We have an ErrorBoundary at the root, so we're covered" — covered against total blank pages, not against unnecessary blast radius.
|
|
51
|
+
- "It's wrapped in Suspense, so errors are handled" — Suspense handles pending state, not rejection; a rejection with no ancestor Error Boundary is still an unhandled crash.
|
|
52
|
+
- "Third-party embeds are usually stable, we don't need a boundary just for that widget" — third-party code is exactly the code the application has the least control over and the strongest reason to isolate.
|
|
53
|
+
- "React has an error boundary hook now, right?" — verify against current Context7 docs before asserting this; as of official React reference docs, error boundaries remain class-component-only, with `react-error-boundary` as the documented community path for a component API.
|
|
54
|
+
|
|
55
|
+
## When to push back
|
|
56
|
+
|
|
57
|
+
Push back if the user asks to:
|
|
58
|
+
|
|
59
|
+
- ship a suspending or third-party-embedded component with no ancestor Error Boundary "for now, we'll add it later,"
|
|
60
|
+
- rely on a single app-root boundary and call the failure-isolation review complete,
|
|
61
|
+
- nest a non-critical, independently-failable section inside the same boundary as a critical flow purely to reduce the number of `ErrorBoundary` components in the file.
|
|
62
|
+
|
|
63
|
+
Those trade a contained, isolated failure for a page-wide one, and the tradeoff is rarely visible until the incident that reveals it.
|