@wazir-dev/cli 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +111 -0
- package/CHANGELOG.md +14 -0
- package/CONTRIBUTING.md +101 -0
- package/LICENSE +21 -0
- package/README.md +314 -0
- package/assets/composition-engine.mmd +34 -0
- package/assets/demo-script.sh +17 -0
- package/assets/logo-dark.svg +14 -0
- package/assets/logo.svg +14 -0
- package/assets/pipeline.mmd +39 -0
- package/assets/record-demo.sh +51 -0
- package/docs/README.md +51 -0
- package/docs/adapters/context-mode.md +60 -0
- package/docs/concepts/architecture.md +87 -0
- package/docs/concepts/artifact-model.md +60 -0
- package/docs/concepts/composition-engine.md +36 -0
- package/docs/concepts/indexing-and-recall.md +160 -0
- package/docs/concepts/observability.md +41 -0
- package/docs/concepts/roles-and-workflows.md +59 -0
- package/docs/concepts/terminology-policy.md +27 -0
- package/docs/getting-started/01-installation.md +78 -0
- package/docs/getting-started/02-first-run.md +102 -0
- package/docs/getting-started/03-adding-to-project.md +15 -0
- package/docs/getting-started/04-host-setup.md +15 -0
- package/docs/guides/ci-integration.md +15 -0
- package/docs/guides/creating-skills.md +15 -0
- package/docs/guides/expertise-module-authoring.md +15 -0
- package/docs/guides/hook-development.md +15 -0
- package/docs/guides/memory-and-learnings.md +34 -0
- package/docs/guides/multi-host-export.md +15 -0
- package/docs/guides/troubleshooting.md +101 -0
- package/docs/guides/writing-custom-roles.md +15 -0
- package/docs/plans/2026-03-15-cli-pipeline-integration-design.md +592 -0
- package/docs/plans/2026-03-15-cli-pipeline-integration-plan.md +598 -0
- package/docs/plans/2026-03-15-docs-enforcement-plan.md +238 -0
- package/docs/readmes/INDEX.md +99 -0
- package/docs/readmes/features/expertise/README.md +171 -0
- package/docs/readmes/features/exports/README.md +222 -0
- package/docs/readmes/features/hooks/README.md +103 -0
- package/docs/readmes/features/hooks/loop-cap-guard.md +133 -0
- package/docs/readmes/features/hooks/post-tool-capture.md +121 -0
- package/docs/readmes/features/hooks/post-tool-lint.md +130 -0
- package/docs/readmes/features/hooks/pre-compact-summary.md +122 -0
- package/docs/readmes/features/hooks/pre-tool-capture-route.md +100 -0
- package/docs/readmes/features/hooks/protected-path-write-guard.md +128 -0
- package/docs/readmes/features/hooks/session-start.md +119 -0
- package/docs/readmes/features/hooks/stop-handoff-harvest.md +125 -0
- package/docs/readmes/features/roles/README.md +157 -0
- package/docs/readmes/features/roles/clarifier.md +152 -0
- package/docs/readmes/features/roles/content-author.md +190 -0
- package/docs/readmes/features/roles/designer.md +193 -0
- package/docs/readmes/features/roles/executor.md +184 -0
- package/docs/readmes/features/roles/learner.md +210 -0
- package/docs/readmes/features/roles/planner.md +182 -0
- package/docs/readmes/features/roles/researcher.md +164 -0
- package/docs/readmes/features/roles/reviewer.md +184 -0
- package/docs/readmes/features/roles/specifier.md +162 -0
- package/docs/readmes/features/roles/verifier.md +215 -0
- package/docs/readmes/features/schemas/README.md +178 -0
- package/docs/readmes/features/skills/README.md +63 -0
- package/docs/readmes/features/skills/brainstorming.md +96 -0
- package/docs/readmes/features/skills/debugging.md +148 -0
- package/docs/readmes/features/skills/design.md +120 -0
- package/docs/readmes/features/skills/prepare-next.md +109 -0
- package/docs/readmes/features/skills/run-audit.md +159 -0
- package/docs/readmes/features/skills/scan-project.md +109 -0
- package/docs/readmes/features/skills/self-audit.md +176 -0
- package/docs/readmes/features/skills/tdd.md +137 -0
- package/docs/readmes/features/skills/using-skills.md +92 -0
- package/docs/readmes/features/skills/verification.md +120 -0
- package/docs/readmes/features/skills/writing-plans.md +104 -0
- package/docs/readmes/features/tooling/README.md +320 -0
- package/docs/readmes/features/workflows/README.md +186 -0
- package/docs/readmes/features/workflows/author.md +181 -0
- package/docs/readmes/features/workflows/clarify.md +154 -0
- package/docs/readmes/features/workflows/design-review.md +171 -0
- package/docs/readmes/features/workflows/design.md +169 -0
- package/docs/readmes/features/workflows/discover.md +162 -0
- package/docs/readmes/features/workflows/execute.md +173 -0
- package/docs/readmes/features/workflows/learn.md +167 -0
- package/docs/readmes/features/workflows/plan-review.md +165 -0
- package/docs/readmes/features/workflows/plan.md +170 -0
- package/docs/readmes/features/workflows/prepare-next.md +167 -0
- package/docs/readmes/features/workflows/review.md +169 -0
- package/docs/readmes/features/workflows/run-audit.md +191 -0
- package/docs/readmes/features/workflows/spec-challenge.md +159 -0
- package/docs/readmes/features/workflows/specify.md +160 -0
- package/docs/readmes/features/workflows/verify.md +177 -0
- package/docs/readmes/packages/README.md +50 -0
- package/docs/readmes/packages/ajv.md +117 -0
- package/docs/readmes/packages/context-mode.md +118 -0
- package/docs/readmes/packages/gray-matter.md +116 -0
- package/docs/readmes/packages/node-test.md +137 -0
- package/docs/readmes/packages/yaml.md +112 -0
- package/docs/reference/configuration-reference.md +159 -0
- package/docs/reference/expertise-index.md +52 -0
- package/docs/reference/git-flow.md +43 -0
- package/docs/reference/hooks.md +87 -0
- package/docs/reference/host-exports.md +50 -0
- package/docs/reference/launch-checklist.md +172 -0
- package/docs/reference/marketplace-listings.md +76 -0
- package/docs/reference/release-process.md +34 -0
- package/docs/reference/roles-reference.md +77 -0
- package/docs/reference/skills.md +33 -0
- package/docs/reference/templates.md +29 -0
- package/docs/reference/tooling-cli.md +94 -0
- package/docs/truth-claims.yaml +222 -0
- package/expertise/PROGRESS.md +63 -0
- package/expertise/README.md +18 -0
- package/expertise/antipatterns/PROGRESS.md +56 -0
- package/expertise/antipatterns/backend/api-design-antipatterns.md +1271 -0
- package/expertise/antipatterns/backend/auth-antipatterns.md +1195 -0
- package/expertise/antipatterns/backend/caching-antipatterns.md +622 -0
- package/expertise/antipatterns/backend/database-antipatterns.md +1038 -0
- package/expertise/antipatterns/backend/index.md +24 -0
- package/expertise/antipatterns/backend/microservices-antipatterns.md +850 -0
- package/expertise/antipatterns/code/architecture-antipatterns.md +919 -0
- package/expertise/antipatterns/code/async-antipatterns.md +622 -0
- package/expertise/antipatterns/code/code-smells.md +1186 -0
- package/expertise/antipatterns/code/dependency-antipatterns.md +1209 -0
- package/expertise/antipatterns/code/error-handling-antipatterns.md +1360 -0
- package/expertise/antipatterns/code/index.md +27 -0
- package/expertise/antipatterns/code/naming-and-abstraction.md +1118 -0
- package/expertise/antipatterns/code/state-management-antipatterns.md +1076 -0
- package/expertise/antipatterns/code/testing-antipatterns.md +1053 -0
- package/expertise/antipatterns/design/accessibility-antipatterns.md +1136 -0
- package/expertise/antipatterns/design/dark-patterns.md +1121 -0
- package/expertise/antipatterns/design/index.md +22 -0
- package/expertise/antipatterns/design/ui-antipatterns.md +1202 -0
- package/expertise/antipatterns/design/ux-antipatterns.md +680 -0
- package/expertise/antipatterns/frontend/css-layout-antipatterns.md +691 -0
- package/expertise/antipatterns/frontend/flutter-antipatterns.md +1827 -0
- package/expertise/antipatterns/frontend/index.md +23 -0
- package/expertise/antipatterns/frontend/mobile-antipatterns.md +573 -0
- package/expertise/antipatterns/frontend/react-antipatterns.md +1128 -0
- package/expertise/antipatterns/frontend/spa-antipatterns.md +1235 -0
- package/expertise/antipatterns/index.md +31 -0
- package/expertise/antipatterns/performance/index.md +20 -0
- package/expertise/antipatterns/performance/performance-antipatterns.md +1013 -0
- package/expertise/antipatterns/performance/premature-optimization.md +623 -0
- package/expertise/antipatterns/performance/scaling-antipatterns.md +785 -0
- package/expertise/antipatterns/process/ai-coding-antipatterns.md +853 -0
- package/expertise/antipatterns/process/code-review-antipatterns.md +656 -0
- package/expertise/antipatterns/process/deployment-antipatterns.md +920 -0
- package/expertise/antipatterns/process/index.md +23 -0
- package/expertise/antipatterns/process/technical-debt-antipatterns.md +647 -0
- package/expertise/antipatterns/security/index.md +20 -0
- package/expertise/antipatterns/security/secrets-antipatterns.md +849 -0
- package/expertise/antipatterns/security/security-theater.md +843 -0
- package/expertise/antipatterns/security/vulnerability-patterns.md +801 -0
- package/expertise/architecture/PROGRESS.md +70 -0
- package/expertise/architecture/data/caching-architecture.md +671 -0
- package/expertise/architecture/data/data-consistency.md +574 -0
- package/expertise/architecture/data/data-modeling.md +536 -0
- package/expertise/architecture/data/event-streams-and-queues.md +634 -0
- package/expertise/architecture/data/index.md +25 -0
- package/expertise/architecture/data/search-architecture.md +663 -0
- package/expertise/architecture/data/sql-vs-nosql.md +708 -0
- package/expertise/architecture/decisions/architecture-decision-records.md +640 -0
- package/expertise/architecture/decisions/build-vs-buy.md +616 -0
- package/expertise/architecture/decisions/index.md +23 -0
- package/expertise/architecture/decisions/monolith-to-microservices.md +790 -0
- package/expertise/architecture/decisions/technology-selection.md +616 -0
- package/expertise/architecture/distributed/cap-theorem-and-tradeoffs.md +800 -0
- package/expertise/architecture/distributed/circuit-breaker-bulkhead.md +741 -0
- package/expertise/architecture/distributed/consensus-and-coordination.md +796 -0
- package/expertise/architecture/distributed/distributed-systems-fundamentals.md +564 -0
- package/expertise/architecture/distributed/idempotency-and-retry.md +796 -0
- package/expertise/architecture/distributed/index.md +25 -0
- package/expertise/architecture/distributed/saga-pattern.md +797 -0
- package/expertise/architecture/foundations/architectural-thinking.md +460 -0
- package/expertise/architecture/foundations/coupling-and-cohesion.md +770 -0
- package/expertise/architecture/foundations/design-principles-solid.md +649 -0
- package/expertise/architecture/foundations/domain-driven-design.md +719 -0
- package/expertise/architecture/foundations/index.md +25 -0
- package/expertise/architecture/foundations/separation-of-concerns.md +472 -0
- package/expertise/architecture/foundations/twelve-factor-app.md +797 -0
- package/expertise/architecture/index.md +34 -0
- package/expertise/architecture/integration/api-design-graphql.md +638 -0
- package/expertise/architecture/integration/api-design-grpc.md +804 -0
- package/expertise/architecture/integration/api-design-rest.md +892 -0
- package/expertise/architecture/integration/index.md +25 -0
- package/expertise/architecture/integration/third-party-integration.md +795 -0
- package/expertise/architecture/integration/webhooks-and-callbacks.md +1152 -0
- package/expertise/architecture/integration/websockets-realtime.md +791 -0
- package/expertise/architecture/mobile-architecture/index.md +22 -0
- package/expertise/architecture/mobile-architecture/mobile-app-architecture.md +780 -0
- package/expertise/architecture/mobile-architecture/mobile-backend-for-frontend.md +670 -0
- package/expertise/architecture/mobile-architecture/offline-first.md +719 -0
- package/expertise/architecture/mobile-architecture/push-and-sync.md +782 -0
- package/expertise/architecture/patterns/cqrs-event-sourcing.md +717 -0
- package/expertise/architecture/patterns/event-driven.md +797 -0
- package/expertise/architecture/patterns/hexagonal-clean-architecture.md +870 -0
- package/expertise/architecture/patterns/index.md +27 -0
- package/expertise/architecture/patterns/layered-architecture.md +736 -0
- package/expertise/architecture/patterns/microservices.md +753 -0
- package/expertise/architecture/patterns/modular-monolith.md +692 -0
- package/expertise/architecture/patterns/monolith.md +626 -0
- package/expertise/architecture/patterns/plugin-architecture.md +735 -0
- package/expertise/architecture/patterns/serverless.md +780 -0
- package/expertise/architecture/scaling/database-scaling.md +615 -0
- package/expertise/architecture/scaling/feature-flags-and-rollouts.md +757 -0
- package/expertise/architecture/scaling/horizontal-vs-vertical.md +606 -0
- package/expertise/architecture/scaling/index.md +24 -0
- package/expertise/architecture/scaling/multi-tenancy.md +800 -0
- package/expertise/architecture/scaling/stateless-design.md +787 -0
- package/expertise/backend/embedded-firmware.md +625 -0
- package/expertise/backend/go.md +853 -0
- package/expertise/backend/index.md +24 -0
- package/expertise/backend/java-spring.md +448 -0
- package/expertise/backend/node-typescript.md +625 -0
- package/expertise/backend/python-fastapi.md +724 -0
- package/expertise/backend/rust.md +458 -0
- package/expertise/backend/solidity.md +711 -0
- package/expertise/composition-map.yaml +443 -0
- package/expertise/content/foundations/content-modeling.md +395 -0
- package/expertise/content/foundations/editorial-standards.md +449 -0
- package/expertise/content/foundations/index.md +24 -0
- package/expertise/content/foundations/microcopy.md +455 -0
- package/expertise/content/foundations/terminology-governance.md +509 -0
- package/expertise/content/index.md +34 -0
- package/expertise/content/patterns/accessibility-copy.md +518 -0
- package/expertise/content/patterns/index.md +24 -0
- package/expertise/content/patterns/notification-content.md +433 -0
- package/expertise/content/patterns/sample-content.md +486 -0
- package/expertise/content/patterns/state-copy.md +439 -0
- package/expertise/design/PROGRESS.md +58 -0
- package/expertise/design/disciplines/dark-mode-theming.md +577 -0
- package/expertise/design/disciplines/design-systems.md +595 -0
- package/expertise/design/disciplines/index.md +25 -0
- package/expertise/design/disciplines/information-architecture.md +800 -0
- package/expertise/design/disciplines/interaction-design.md +788 -0
- package/expertise/design/disciplines/responsive-design.md +552 -0
- package/expertise/design/disciplines/usability-testing.md +516 -0
- package/expertise/design/disciplines/user-research.md +792 -0
- package/expertise/design/foundations/accessibility-design.md +796 -0
- package/expertise/design/foundations/color-theory.md +797 -0
- package/expertise/design/foundations/iconography.md +795 -0
- package/expertise/design/foundations/index.md +26 -0
- package/expertise/design/foundations/motion-and-animation.md +653 -0
- package/expertise/design/foundations/rtl-design.md +585 -0
- package/expertise/design/foundations/spacing-and-layout.md +607 -0
- package/expertise/design/foundations/typography.md +800 -0
- package/expertise/design/foundations/visual-hierarchy.md +761 -0
- package/expertise/design/index.md +32 -0
- package/expertise/design/patterns/authentication-flows.md +474 -0
- package/expertise/design/patterns/content-consumption.md +789 -0
- package/expertise/design/patterns/data-display.md +618 -0
- package/expertise/design/patterns/e-commerce.md +1494 -0
- package/expertise/design/patterns/feedback-and-states.md +642 -0
- package/expertise/design/patterns/forms-and-input.md +819 -0
- package/expertise/design/patterns/gamification.md +801 -0
- package/expertise/design/patterns/index.md +31 -0
- package/expertise/design/patterns/microinteractions.md +449 -0
- package/expertise/design/patterns/navigation.md +800 -0
- package/expertise/design/patterns/notifications.md +705 -0
- package/expertise/design/patterns/onboarding.md +700 -0
- package/expertise/design/patterns/search-and-filter.md +601 -0
- package/expertise/design/patterns/settings-and-preferences.md +768 -0
- package/expertise/design/patterns/social-and-community.md +748 -0
- package/expertise/design/platforms/desktop-native.md +612 -0
- package/expertise/design/platforms/index.md +25 -0
- package/expertise/design/platforms/mobile-android.md +825 -0
- package/expertise/design/platforms/mobile-cross-platform.md +983 -0
- package/expertise/design/platforms/mobile-ios.md +699 -0
- package/expertise/design/platforms/tablet.md +794 -0
- package/expertise/design/platforms/web-dashboard.md +790 -0
- package/expertise/design/platforms/web-responsive.md +550 -0
- package/expertise/design/psychology/behavioral-nudges.md +449 -0
- package/expertise/design/psychology/cognitive-load.md +1191 -0
- package/expertise/design/psychology/error-psychology.md +778 -0
- package/expertise/design/psychology/index.md +22 -0
- package/expertise/design/psychology/persuasive-design.md +736 -0
- package/expertise/design/psychology/user-mental-models.md +623 -0
- package/expertise/design/tooling/open-pencil.md +266 -0
- package/expertise/frontend/angular.md +1073 -0
- package/expertise/frontend/desktop-electron.md +546 -0
- package/expertise/frontend/flutter.md +782 -0
- package/expertise/frontend/index.md +27 -0
- package/expertise/frontend/native-android.md +409 -0
- package/expertise/frontend/native-ios.md +490 -0
- package/expertise/frontend/react-native.md +1160 -0
- package/expertise/frontend/react.md +808 -0
- package/expertise/frontend/vue.md +1089 -0
- package/expertise/humanize/domain-rules-code.md +79 -0
- package/expertise/humanize/domain-rules-content.md +67 -0
- package/expertise/humanize/domain-rules-technical-docs.md +56 -0
- package/expertise/humanize/index.md +35 -0
- package/expertise/humanize/self-audit-checklist.md +87 -0
- package/expertise/humanize/sentence-patterns.md +218 -0
- package/expertise/humanize/vocabulary-blacklist.md +105 -0
- package/expertise/i18n/PROGRESS.md +65 -0
- package/expertise/i18n/advanced/accessibility-and-i18n.md +28 -0
- package/expertise/i18n/advanced/bidirectional-text-algorithm.md +38 -0
- package/expertise/i18n/advanced/complex-scripts.md +30 -0
- package/expertise/i18n/advanced/performance-and-i18n.md +27 -0
- package/expertise/i18n/advanced/testing-i18n.md +28 -0
- package/expertise/i18n/content/content-adaptation.md +23 -0
- package/expertise/i18n/content/locale-specific-formatting.md +23 -0
- package/expertise/i18n/content/machine-translation-integration.md +28 -0
- package/expertise/i18n/content/translation-management.md +29 -0
- package/expertise/i18n/foundations/date-time-calendars.md +67 -0
- package/expertise/i18n/foundations/i18n-architecture.md +272 -0
- package/expertise/i18n/foundations/locale-and-language-tags.md +79 -0
- package/expertise/i18n/foundations/numbers-currency-units.md +61 -0
- package/expertise/i18n/foundations/pluralization-and-gender.md +109 -0
- package/expertise/i18n/foundations/string-externalization.md +236 -0
- package/expertise/i18n/foundations/text-direction-bidi.md +241 -0
- package/expertise/i18n/foundations/unicode-and-encoding.md +86 -0
- package/expertise/i18n/index.md +38 -0
- package/expertise/i18n/platform/backend-i18n.md +31 -0
- package/expertise/i18n/platform/flutter-i18n.md +148 -0
- package/expertise/i18n/platform/native-android-i18n.md +36 -0
- package/expertise/i18n/platform/native-ios-i18n.md +36 -0
- package/expertise/i18n/platform/react-i18n.md +103 -0
- package/expertise/i18n/platform/web-css-i18n.md +81 -0
- package/expertise/i18n/rtl/arabic-specific.md +175 -0
- package/expertise/i18n/rtl/hebrew-specific.md +149 -0
- package/expertise/i18n/rtl/rtl-animations-and-transitions.md +111 -0
- package/expertise/i18n/rtl/rtl-forms-and-input.md +161 -0
- package/expertise/i18n/rtl/rtl-fundamentals.md +211 -0
- package/expertise/i18n/rtl/rtl-icons-and-images.md +181 -0
- package/expertise/i18n/rtl/rtl-layout-mirroring.md +252 -0
- package/expertise/i18n/rtl/rtl-navigation-and-gestures.md +107 -0
- package/expertise/i18n/rtl/rtl-testing-and-qa.md +147 -0
- package/expertise/i18n/rtl/rtl-typography.md +160 -0
- package/expertise/index.md +113 -0
- package/expertise/index.yaml +216 -0
- package/expertise/infrastructure/cloud-aws.md +597 -0
- package/expertise/infrastructure/cloud-gcp.md +599 -0
- package/expertise/infrastructure/cybersecurity.md +816 -0
- package/expertise/infrastructure/database-mongodb.md +447 -0
- package/expertise/infrastructure/database-postgres.md +400 -0
- package/expertise/infrastructure/devops-cicd.md +787 -0
- package/expertise/infrastructure/index.md +27 -0
- package/expertise/performance/PROGRESS.md +50 -0
- package/expertise/performance/backend/api-latency.md +1204 -0
- package/expertise/performance/backend/background-jobs.md +506 -0
- package/expertise/performance/backend/connection-pooling.md +1209 -0
- package/expertise/performance/backend/database-query-optimization.md +515 -0
- package/expertise/performance/backend/index.md +23 -0
- package/expertise/performance/backend/rate-limiting-and-throttling.md +971 -0
- package/expertise/performance/foundations/algorithmic-complexity.md +954 -0
- package/expertise/performance/foundations/caching-strategies.md +489 -0
- package/expertise/performance/foundations/concurrency-and-parallelism.md +847 -0
- package/expertise/performance/foundations/index.md +24 -0
- package/expertise/performance/foundations/measuring-and-profiling.md +440 -0
- package/expertise/performance/foundations/memory-management.md +964 -0
- package/expertise/performance/foundations/performance-budgets.md +1314 -0
- package/expertise/performance/index.md +31 -0
- package/expertise/performance/infrastructure/auto-scaling.md +1059 -0
- package/expertise/performance/infrastructure/cdn-and-edge.md +1081 -0
- package/expertise/performance/infrastructure/index.md +22 -0
- package/expertise/performance/infrastructure/load-balancing.md +1081 -0
- package/expertise/performance/infrastructure/observability.md +1079 -0
- package/expertise/performance/mobile/index.md +23 -0
- package/expertise/performance/mobile/mobile-animations.md +544 -0
- package/expertise/performance/mobile/mobile-memory-battery.md +416 -0
- package/expertise/performance/mobile/mobile-network.md +452 -0
- package/expertise/performance/mobile/mobile-rendering.md +599 -0
- package/expertise/performance/mobile/mobile-startup-time.md +505 -0
- package/expertise/performance/platform-specific/flutter-performance.md +647 -0
- package/expertise/performance/platform-specific/index.md +22 -0
- package/expertise/performance/platform-specific/node-performance.md +1307 -0
- package/expertise/performance/platform-specific/postgres-performance.md +1366 -0
- package/expertise/performance/platform-specific/react-performance.md +1403 -0
- package/expertise/performance/web/bundle-optimization.md +1239 -0
- package/expertise/performance/web/image-and-media.md +636 -0
- package/expertise/performance/web/index.md +24 -0
- package/expertise/performance/web/network-optimization.md +1133 -0
- package/expertise/performance/web/rendering-performance.md +1098 -0
- package/expertise/performance/web/ssr-and-hydration.md +918 -0
- package/expertise/performance/web/web-vitals.md +1374 -0
- package/expertise/quality/accessibility.md +985 -0
- package/expertise/quality/evidence-based-verification.md +499 -0
- package/expertise/quality/index.md +24 -0
- package/expertise/quality/ml-model-audit.md +614 -0
- package/expertise/quality/performance.md +600 -0
- package/expertise/quality/testing-api.md +891 -0
- package/expertise/quality/testing-mobile.md +496 -0
- package/expertise/quality/testing-web.md +849 -0
- package/expertise/security/PROGRESS.md +54 -0
- package/expertise/security/agentic-identity.md +540 -0
- package/expertise/security/compliance-frameworks.md +601 -0
- package/expertise/security/data/data-encryption.md +364 -0
- package/expertise/security/data/data-privacy-gdpr.md +692 -0
- package/expertise/security/data/database-security.md +1171 -0
- package/expertise/security/data/index.md +22 -0
- package/expertise/security/data/pii-handling.md +531 -0
- package/expertise/security/foundations/authentication.md +1041 -0
- package/expertise/security/foundations/authorization.md +603 -0
- package/expertise/security/foundations/cryptography.md +1001 -0
- package/expertise/security/foundations/index.md +25 -0
- package/expertise/security/foundations/owasp-top-10.md +1354 -0
- package/expertise/security/foundations/secrets-management.md +1217 -0
- package/expertise/security/foundations/secure-sdlc.md +700 -0
- package/expertise/security/foundations/supply-chain-security.md +698 -0
- package/expertise/security/index.md +31 -0
- package/expertise/security/infrastructure/cloud-security-aws.md +1296 -0
- package/expertise/security/infrastructure/cloud-security-gcp.md +1376 -0
- package/expertise/security/infrastructure/container-security.md +721 -0
- package/expertise/security/infrastructure/incident-response.md +1295 -0
- package/expertise/security/infrastructure/index.md +24 -0
- package/expertise/security/infrastructure/logging-and-monitoring.md +1618 -0
- package/expertise/security/infrastructure/network-security.md +1337 -0
- package/expertise/security/mobile/index.md +23 -0
- package/expertise/security/mobile/mobile-android-security.md +1218 -0
- package/expertise/security/mobile/mobile-binary-protection.md +1229 -0
- package/expertise/security/mobile/mobile-data-storage.md +1265 -0
- package/expertise/security/mobile/mobile-ios-security.md +1401 -0
- package/expertise/security/mobile/mobile-network-security.md +1520 -0
- package/expertise/security/smart-contract-security.md +594 -0
- package/expertise/security/testing/index.md +22 -0
- package/expertise/security/testing/penetration-testing.md +1258 -0
- package/expertise/security/testing/security-code-review.md +1765 -0
- package/expertise/security/testing/threat-modeling.md +1074 -0
- package/expertise/security/testing/vulnerability-scanning.md +1062 -0
- package/expertise/security/web/api-security.md +586 -0
- package/expertise/security/web/cors-and-headers.md +433 -0
- package/expertise/security/web/csrf.md +562 -0
- package/expertise/security/web/file-upload.md +1477 -0
- package/expertise/security/web/index.md +25 -0
- package/expertise/security/web/injection.md +1375 -0
- package/expertise/security/web/session-management.md +1101 -0
- package/expertise/security/web/xss.md +1158 -0
- package/exports/README.md +17 -0
- package/exports/hosts/claude/.claude/agents/clarifier.md +42 -0
- package/exports/hosts/claude/.claude/agents/content-author.md +63 -0
- package/exports/hosts/claude/.claude/agents/designer.md +55 -0
- package/exports/hosts/claude/.claude/agents/executor.md +55 -0
- package/exports/hosts/claude/.claude/agents/learner.md +51 -0
- package/exports/hosts/claude/.claude/agents/planner.md +53 -0
- package/exports/hosts/claude/.claude/agents/researcher.md +43 -0
- package/exports/hosts/claude/.claude/agents/reviewer.md +54 -0
- package/exports/hosts/claude/.claude/agents/specifier.md +47 -0
- package/exports/hosts/claude/.claude/agents/verifier.md +71 -0
- package/exports/hosts/claude/.claude/commands/author.md +42 -0
- package/exports/hosts/claude/.claude/commands/clarify.md +38 -0
- package/exports/hosts/claude/.claude/commands/design-review.md +46 -0
- package/exports/hosts/claude/.claude/commands/design.md +44 -0
- package/exports/hosts/claude/.claude/commands/discover.md +37 -0
- package/exports/hosts/claude/.claude/commands/execute.md +48 -0
- package/exports/hosts/claude/.claude/commands/learn.md +38 -0
- package/exports/hosts/claude/.claude/commands/plan-review.md +42 -0
- package/exports/hosts/claude/.claude/commands/plan.md +39 -0
- package/exports/hosts/claude/.claude/commands/prepare-next.md +37 -0
- package/exports/hosts/claude/.claude/commands/review.md +40 -0
- package/exports/hosts/claude/.claude/commands/run-audit.md +41 -0
- package/exports/hosts/claude/.claude/commands/spec-challenge.md +41 -0
- package/exports/hosts/claude/.claude/commands/specify.md +38 -0
- package/exports/hosts/claude/.claude/commands/verify.md +37 -0
- package/exports/hosts/claude/.claude/settings.json +34 -0
- package/exports/hosts/claude/CLAUDE.md +19 -0
- package/exports/hosts/claude/export.manifest.json +38 -0
- package/exports/hosts/claude/host-package.json +67 -0
- package/exports/hosts/codex/AGENTS.md +19 -0
- package/exports/hosts/codex/export.manifest.json +38 -0
- package/exports/hosts/codex/host-package.json +41 -0
- package/exports/hosts/cursor/.cursor/hooks.json +16 -0
- package/exports/hosts/cursor/.cursor/rules/wazir-core.mdc +19 -0
- package/exports/hosts/cursor/export.manifest.json +38 -0
- package/exports/hosts/cursor/host-package.json +42 -0
- package/exports/hosts/gemini/GEMINI.md +19 -0
- package/exports/hosts/gemini/export.manifest.json +38 -0
- package/exports/hosts/gemini/host-package.json +41 -0
- package/hooks/README.md +18 -0
- package/hooks/definitions/loop_cap_guard.yaml +21 -0
- package/hooks/definitions/post_tool_capture.yaml +24 -0
- package/hooks/definitions/pre_compact_summary.yaml +19 -0
- package/hooks/definitions/pre_tool_capture_route.yaml +19 -0
- package/hooks/definitions/protected_path_write_guard.yaml +19 -0
- package/hooks/definitions/session_start.yaml +19 -0
- package/hooks/definitions/stop_handoff_harvest.yaml +20 -0
- package/hooks/loop-cap-guard +17 -0
- package/hooks/post-tool-lint +36 -0
- package/hooks/protected-path-write-guard +17 -0
- package/hooks/session-start +41 -0
- package/llms-full.txt +2355 -0
- package/llms.txt +43 -0
- package/package.json +79 -0
- package/roles/README.md +20 -0
- package/roles/clarifier.md +42 -0
- package/roles/content-author.md +63 -0
- package/roles/designer.md +55 -0
- package/roles/executor.md +55 -0
- package/roles/learner.md +51 -0
- package/roles/planner.md +53 -0
- package/roles/researcher.md +43 -0
- package/roles/reviewer.md +54 -0
- package/roles/specifier.md +47 -0
- package/roles/verifier.md +71 -0
- package/schemas/README.md +24 -0
- package/schemas/accepted-learning.schema.json +20 -0
- package/schemas/author-artifact.schema.json +156 -0
- package/schemas/clarification.schema.json +19 -0
- package/schemas/design-artifact.schema.json +80 -0
- package/schemas/docs-claim.schema.json +18 -0
- package/schemas/export-manifest.schema.json +20 -0
- package/schemas/hook.schema.json +67 -0
- package/schemas/host-export-package.schema.json +18 -0
- package/schemas/implementation-plan.schema.json +19 -0
- package/schemas/proposed-learning.schema.json +19 -0
- package/schemas/research.schema.json +18 -0
- package/schemas/review.schema.json +29 -0
- package/schemas/run-manifest.schema.json +18 -0
- package/schemas/spec-challenge.schema.json +18 -0
- package/schemas/spec.schema.json +20 -0
- package/schemas/usage.schema.json +102 -0
- package/schemas/verification-proof.schema.json +29 -0
- package/schemas/wazir-manifest.schema.json +173 -0
- package/skills/README.md +40 -0
- package/skills/brainstorming/SKILL.md +77 -0
- package/skills/debugging/SKILL.md +50 -0
- package/skills/design/SKILL.md +61 -0
- package/skills/dispatching-parallel-agents/SKILL.md +128 -0
- package/skills/executing-plans/SKILL.md +70 -0
- package/skills/finishing-a-development-branch/SKILL.md +169 -0
- package/skills/humanize/SKILL.md +123 -0
- package/skills/init-pipeline/SKILL.md +124 -0
- package/skills/prepare-next/SKILL.md +20 -0
- package/skills/receiving-code-review/SKILL.md +123 -0
- package/skills/requesting-code-review/SKILL.md +105 -0
- package/skills/requesting-code-review/code-reviewer.md +108 -0
- package/skills/run-audit/SKILL.md +197 -0
- package/skills/scan-project/SKILL.md +41 -0
- package/skills/self-audit/SKILL.md +153 -0
- package/skills/subagent-driven-development/SKILL.md +154 -0
- package/skills/subagent-driven-development/code-quality-reviewer-prompt.md +26 -0
- package/skills/subagent-driven-development/implementer-prompt.md +102 -0
- package/skills/subagent-driven-development/spec-reviewer-prompt.md +61 -0
- package/skills/tdd/SKILL.md +23 -0
- package/skills/using-git-worktrees/SKILL.md +163 -0
- package/skills/using-skills/SKILL.md +95 -0
- package/skills/verification/SKILL.md +22 -0
- package/skills/wazir/SKILL.md +463 -0
- package/skills/writing-plans/SKILL.md +30 -0
- package/skills/writing-skills/SKILL.md +157 -0
- package/skills/writing-skills/anthropic-best-practices.md +122 -0
- package/skills/writing-skills/persuasion-principles.md +50 -0
- package/templates/README.md +20 -0
- package/templates/artifacts/README.md +10 -0
- package/templates/artifacts/accepted-learning.md +19 -0
- package/templates/artifacts/accepted-learning.template.json +12 -0
- package/templates/artifacts/author.md +74 -0
- package/templates/artifacts/author.template.json +19 -0
- package/templates/artifacts/clarification.md +21 -0
- package/templates/artifacts/clarification.template.json +12 -0
- package/templates/artifacts/execute-notes.md +19 -0
- package/templates/artifacts/implementation-plan.md +21 -0
- package/templates/artifacts/implementation-plan.template.json +11 -0
- package/templates/artifacts/learning-proposal.md +19 -0
- package/templates/artifacts/next-run-handoff.md +21 -0
- package/templates/artifacts/plan-review.md +19 -0
- package/templates/artifacts/proposed-learning.template.json +12 -0
- package/templates/artifacts/research.md +21 -0
- package/templates/artifacts/research.template.json +12 -0
- package/templates/artifacts/review-findings.md +19 -0
- package/templates/artifacts/review.template.json +11 -0
- package/templates/artifacts/run-manifest.template.json +8 -0
- package/templates/artifacts/spec-challenge.md +19 -0
- package/templates/artifacts/spec-challenge.template.json +11 -0
- package/templates/artifacts/spec.md +21 -0
- package/templates/artifacts/spec.template.json +12 -0
- package/templates/artifacts/verification-proof.md +19 -0
- package/templates/artifacts/verification-proof.template.json +11 -0
- package/templates/examples/accepted-learning.example.json +14 -0
- package/templates/examples/author.example.json +152 -0
- package/templates/examples/clarification.example.json +15 -0
- package/templates/examples/docs-claim.example.json +8 -0
- package/templates/examples/export-manifest.example.json +7 -0
- package/templates/examples/host-export-package.example.json +11 -0
- package/templates/examples/implementation-plan.example.json +17 -0
- package/templates/examples/proposed-learning.example.json +13 -0
- package/templates/examples/research.example.json +15 -0
- package/templates/examples/research.example.md +6 -0
- package/templates/examples/review.example.json +17 -0
- package/templates/examples/run-manifest.example.json +9 -0
- package/templates/examples/spec-challenge.example.json +14 -0
- package/templates/examples/spec.example.json +21 -0
- package/templates/examples/verification-proof.example.json +21 -0
- package/templates/examples/wazir-manifest.example.yaml +65 -0
- package/templates/task-definition-schema.md +99 -0
- package/tooling/README.md +20 -0
- package/tooling/src/adapters/context-mode.js +50 -0
- package/tooling/src/capture/command.js +376 -0
- package/tooling/src/capture/store.js +99 -0
- package/tooling/src/capture/usage.js +270 -0
- package/tooling/src/checks/branches.js +50 -0
- package/tooling/src/checks/brand-truth.js +110 -0
- package/tooling/src/checks/changelog.js +231 -0
- package/tooling/src/checks/command-registry.js +36 -0
- package/tooling/src/checks/commits.js +102 -0
- package/tooling/src/checks/docs-drift.js +103 -0
- package/tooling/src/checks/docs-truth.js +201 -0
- package/tooling/src/checks/runtime-surface.js +156 -0
- package/tooling/src/cli.js +116 -0
- package/tooling/src/command-options.js +56 -0
- package/tooling/src/commands/validate.js +320 -0
- package/tooling/src/doctor/command.js +91 -0
- package/tooling/src/export/command.js +77 -0
- package/tooling/src/export/compiler.js +498 -0
- package/tooling/src/guards/loop-cap-guard.js +52 -0
- package/tooling/src/guards/protected-path-write-guard.js +67 -0
- package/tooling/src/index/command.js +152 -0
- package/tooling/src/index/storage.js +1061 -0
- package/tooling/src/index/summarizers.js +261 -0
- package/tooling/src/loaders.js +18 -0
- package/tooling/src/project-root.js +22 -0
- package/tooling/src/recall/command.js +225 -0
- package/tooling/src/schema-validator.js +30 -0
- package/tooling/src/state-root.js +40 -0
- package/tooling/src/status/command.js +71 -0
- package/wazir.manifest.yaml +135 -0
- package/workflows/README.md +19 -0
- package/workflows/author.md +42 -0
- package/workflows/clarify.md +38 -0
- package/workflows/design-review.md +46 -0
- package/workflows/design.md +44 -0
- package/workflows/discover.md +37 -0
- package/workflows/execute.md +48 -0
- package/workflows/learn.md +38 -0
- package/workflows/plan-review.md +42 -0
- package/workflows/plan.md +39 -0
- package/workflows/prepare-next.md +37 -0
- package/workflows/review.md +40 -0
- package/workflows/run-audit.md +41 -0
- package/workflows/spec-challenge.md +41 -0
- package/workflows/specify.md +38 -0
- package/workflows/verify.md +37 -0
|
@@ -0,0 +1,594 @@
|
|
|
1
|
+
# Smart Contract Security — Expertise Module
|
|
2
|
+
|
|
3
|
+
> Expertise module for AI agents building or auditing smart contracts on EVM-compatible
|
|
4
|
+
> blockchains. Covers reentrancy, flash loans, oracle manipulation, access control, MEV,
|
|
5
|
+
> integer safety, formal verification, and audit methodology — the vulnerability classes
|
|
6
|
+
> responsible for billions in on-chain losses.
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## 1. Threat Landscape
|
|
11
|
+
|
|
12
|
+
Chainalysis reported $3.8 billion stolen in crypto hacks in 2022 alone. Smart contracts
|
|
13
|
+
are immutable, permissionless, and custody real value — a single exploitable line drains
|
|
14
|
+
entire protocols with no rollback.
|
|
15
|
+
|
|
16
|
+
### Landmark Exploits
|
|
17
|
+
|
|
18
|
+
| Year | Protocol | Loss | Root Cause |
|
|
19
|
+
|------|----------|------|------------|
|
|
20
|
+
| 2016 | The DAO | $60M | Reentrancy in split function |
|
|
21
|
+
| 2017 | Parity Wallet | $300M frozen | Library self-destruct via unprotected init |
|
|
22
|
+
| 2021 | Poly Network | $611M | Unprotected cross-chain message handler |
|
|
23
|
+
| 2022 | Wormhole | $320M | Missing signature verification on guardian set |
|
|
24
|
+
| 2022 | Ronin Bridge | $624M | Compromised validator keys (5 of 9) |
|
|
25
|
+
| 2023 | Euler Finance | $197M | Unchecked donate-to-self in flash loan flow |
|
|
26
|
+
| 2023 | Curve Finance | $70M | Vyper compiler reentrancy lock bug |
|
|
27
|
+
|
|
28
|
+
**References:** SWC Registry, Trail of Bits, OpenZeppelin, Consensys Diligence.
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## 2. Reentrancy Attacks
|
|
33
|
+
|
|
34
|
+
Reentrancy occurs when an external call lets the callee re-enter the caller before state
|
|
35
|
+
updates complete. Defense: **Checks-Effects-Interactions (CEI)** + `ReentrancyGuard`.
|
|
36
|
+
|
|
37
|
+
### 2.1 Single-Function Reentrancy
|
|
38
|
+
|
|
39
|
+
```solidity
|
|
40
|
+
// VULNERABLE: state update after external call
|
|
41
|
+
function withdraw(uint256 amount) external {
|
|
42
|
+
require(balances[msg.sender] >= amount);
|
|
43
|
+
(bool success, ) = msg.sender.call{value: amount}("");
|
|
44
|
+
require(success);
|
|
45
|
+
balances[msg.sender] -= amount; // State update AFTER external call
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// FIXED: Checks-Effects-Interactions + ReentrancyGuard
|
|
49
|
+
function withdraw(uint256 amount) external nonReentrant {
|
|
50
|
+
require(balances[msg.sender] >= amount);
|
|
51
|
+
balances[msg.sender] -= amount; // Effect BEFORE interaction
|
|
52
|
+
(bool success, ) = msg.sender.call{value: amount}("");
|
|
53
|
+
require(success);
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Attacker contract exploits the vulnerable version by re-entering `withdraw()` from its
|
|
58
|
+
`receive()` callback before the balance is decremented.
|
|
59
|
+
|
|
60
|
+
### 2.2 Cross-Function Reentrancy
|
|
61
|
+
|
|
62
|
+
Two functions share state. Attacker re-enters through a different function that reads
|
|
63
|
+
stale state.
|
|
64
|
+
|
|
65
|
+
```solidity
|
|
66
|
+
// VULNERABLE: transfer reads stale balance during withdraw callback
|
|
67
|
+
function withdraw(uint256 amount) external {
|
|
68
|
+
require(balances[msg.sender] >= amount);
|
|
69
|
+
(bool success, ) = msg.sender.call{value: amount}("");
|
|
70
|
+
require(success);
|
|
71
|
+
balances[msg.sender] -= amount;
|
|
72
|
+
}
|
|
73
|
+
function transfer(address to, uint256 amount) external {
|
|
74
|
+
require(balances[msg.sender] >= amount); // Still inflated mid-callback
|
|
75
|
+
balances[msg.sender] -= amount;
|
|
76
|
+
balances[to] += amount;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// FIXED: shared nonReentrant on both functions + CEI in withdraw
|
|
80
|
+
function withdraw(uint256 amount) external nonReentrant {
|
|
81
|
+
require(balances[msg.sender] >= amount);
|
|
82
|
+
balances[msg.sender] -= amount;
|
|
83
|
+
(bool success, ) = msg.sender.call{value: amount}("");
|
|
84
|
+
require(success);
|
|
85
|
+
}
|
|
86
|
+
function transfer(address to, uint256 amount) external nonReentrant {
|
|
87
|
+
require(balances[msg.sender] >= amount);
|
|
88
|
+
balances[msg.sender] -= amount;
|
|
89
|
+
balances[to] += amount;
|
|
90
|
+
}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### 2.3 Cross-Contract Reentrancy
|
|
94
|
+
|
|
95
|
+
Contract A depends on state in Contract B. Callback during B's external call re-enters A,
|
|
96
|
+
which reads B's stale state.
|
|
97
|
+
|
|
98
|
+
```solidity
|
|
99
|
+
// VULNERABLE: ERC-777 token triggers callback before vault state updates
|
|
100
|
+
contract VulnerableTokenVault {
|
|
101
|
+
IERC20 public token;
|
|
102
|
+
mapping(address => uint256) public shares;
|
|
103
|
+
|
|
104
|
+
function withdraw() external {
|
|
105
|
+
uint256 userShares = shares[msg.sender];
|
|
106
|
+
uint256 tokenAmount = calculateTokens(userShares);
|
|
107
|
+
shares[msg.sender] = 0;
|
|
108
|
+
token.transfer(msg.sender, tokenAmount); // ERC-777 callback re-enters
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// FIXED: nonReentrant + SafeERC20
|
|
113
|
+
contract SecureTokenVault is ReentrancyGuard {
|
|
114
|
+
function withdraw() external nonReentrant {
|
|
115
|
+
uint256 userShares = shares[msg.sender];
|
|
116
|
+
require(userShares > 0, "No shares");
|
|
117
|
+
shares[msg.sender] = 0;
|
|
118
|
+
SafeERC20.safeTransfer(token, msg.sender, calculateTokens(userShares));
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### 2.4 Read-Only Reentrancy
|
|
124
|
+
|
|
125
|
+
A `view` function returns stale state during a callback. A third contract reads the
|
|
126
|
+
inconsistent view and makes decisions on it. This bypasses reentrancy guards because the
|
|
127
|
+
re-entered function is read-only.
|
|
128
|
+
|
|
129
|
+
```solidity
|
|
130
|
+
// VULNERABLE: getPricePerShare() returns stale ratio mid-withdraw
|
|
131
|
+
function withdraw(uint256 shares) external {
|
|
132
|
+
uint256 assets = shares * totalAssets / totalShares;
|
|
133
|
+
totalShares -= shares;
|
|
134
|
+
(bool s, ) = msg.sender.call{value: assets}(""); // Callback here
|
|
135
|
+
require(s);
|
|
136
|
+
totalAssets -= assets; // Stale during callback — getPricePerShare() lies
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// FIXED: update ALL state before external call
|
|
140
|
+
function withdraw(uint256 shares) external nonReentrant {
|
|
141
|
+
uint256 assets = shares * totalAssets / totalShares;
|
|
142
|
+
totalShares -= shares;
|
|
143
|
+
totalAssets -= assets; // Both updated before interaction
|
|
144
|
+
(bool s, ) = msg.sender.call{value: assets}("");
|
|
145
|
+
require(s);
|
|
146
|
+
}
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
---
|
|
150
|
+
|
|
151
|
+
## 3. Flash Loan Attacks
|
|
152
|
+
|
|
153
|
+
Flash loans provide unlimited zero-collateral capital within a single transaction, repaid
|
|
154
|
+
atomically or the entire transaction reverts.
|
|
155
|
+
|
|
156
|
+
### Attack Mechanism
|
|
157
|
+
|
|
158
|
+
1. Borrow massive capital via flash loan (e.g., 100M USDC)
|
|
159
|
+
2. Swap into target token on a DEX, moving the spot price dramatically
|
|
160
|
+
3. Use the distorted price as input to a vulnerable protocol's oracle
|
|
161
|
+
4. Execute the exploit (borrow at manipulated price, liquidate positions)
|
|
162
|
+
5. Reverse the swap, repay the flash loan, keep the profit
|
|
163
|
+
|
|
164
|
+
```solidity
|
|
165
|
+
// VULNERABLE: spot price from AMM reserves
|
|
166
|
+
function getPrice() public view returns (uint256) {
|
|
167
|
+
(uint112 r0, uint112 r1, ) = pair.getReserves();
|
|
168
|
+
return uint256(r0) * 1e18 / uint256(r1); // Manipulable via flash loan
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// FIXED: TWAP oracle (time-weighted average price)
|
|
172
|
+
function getTWAP() public view returns (uint256 price) {
|
|
173
|
+
(int24 arithmeticMeanTick, ) = OracleLibrary.consult(pool, TWAP_PERIOD);
|
|
174
|
+
price = OracleLibrary.getQuoteAtTick(arithmeticMeanTick, 1e18, token0, token1);
|
|
175
|
+
}
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
**Defense checklist:**
|
|
179
|
+
- Never use single-block spot prices for financial decisions
|
|
180
|
+
- TWAP with minimum 15-30 minute window
|
|
181
|
+
- Chainlink feeds as primary or fallback oracle
|
|
182
|
+
- Borrow/repay delays (minimum 1 block separation)
|
|
183
|
+
- Circuit breakers: halt if price moves >N% in one block
|
|
184
|
+
|
|
185
|
+
---
|
|
186
|
+
|
|
187
|
+
## 4. Oracle Manipulation
|
|
188
|
+
|
|
189
|
+
| Property | Spot Price | TWAP |
|
|
190
|
+
|----------|-----------|------|
|
|
191
|
+
| Manipulation cost | One transaction | Sustained over window |
|
|
192
|
+
| Latency | Real-time | Delayed by window |
|
|
193
|
+
| Use case | UI display only | Financial decisions |
|
|
194
|
+
|
|
195
|
+
**Rule: never use spot prices for on-chain financial calculations.**
|
|
196
|
+
|
|
197
|
+
### Chainlink Best Practices
|
|
198
|
+
|
|
199
|
+
```solidity
|
|
200
|
+
function getPrice() public view returns (uint256) {
|
|
201
|
+
(uint80 roundId, int256 price, , uint256 updatedAt, uint80 answeredInRound)
|
|
202
|
+
= priceFeed.latestRoundData();
|
|
203
|
+
require(price > 0, "Oracle: invalid price"); // Positive
|
|
204
|
+
require(answeredInRound >= roundId, "Oracle: stale round"); // Complete
|
|
205
|
+
require(block.timestamp - updatedAt <= STALENESS, "Oracle: stale price"); // Fresh
|
|
206
|
+
return uint256(price);
|
|
207
|
+
}
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
### L2 Sequencer Uptime Check
|
|
211
|
+
|
|
212
|
+
On Arbitrum/Optimism, always verify the sequencer is live and a grace period has passed
|
|
213
|
+
since it recovered — stale prices may appear fresh after an outage.
|
|
214
|
+
|
|
215
|
+
```solidity
|
|
216
|
+
function _checkSequencer() internal view {
|
|
217
|
+
(, int256 answer, uint256 startedAt, , ) = sequencerFeed.latestRoundData();
|
|
218
|
+
require(answer == 0, "Sequencer down");
|
|
219
|
+
require(block.timestamp - startedAt > GRACE_PERIOD, "Grace period");
|
|
220
|
+
}
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
### Fallback Oracle Pattern
|
|
224
|
+
|
|
225
|
+
Use dual oracles (Chainlink + TWAP). Cross-validate and fall back gracefully.
|
|
226
|
+
|
|
227
|
+
```solidity
|
|
228
|
+
contract DualOracle {
|
|
229
|
+
AggregatorV3Interface public primaryOracle; // Chainlink
|
|
230
|
+
address public twapOracle; // Uniswap V3 TWAP
|
|
231
|
+
uint256 public constant MAX_DEVIATION = 500; // 5%
|
|
232
|
+
|
|
233
|
+
function getPrice() public view returns (uint256) {
|
|
234
|
+
(bool primaryOk, uint256 primaryPrice) = _tryPrimary();
|
|
235
|
+
(bool twapOk, uint256 twapPrice) = _tryTWAP();
|
|
236
|
+
|
|
237
|
+
if (primaryOk && twapOk) {
|
|
238
|
+
uint256 deviation = _percentDiff(primaryPrice, twapPrice);
|
|
239
|
+
require(deviation <= MAX_DEVIATION, "Oracle: price deviation");
|
|
240
|
+
return primaryPrice;
|
|
241
|
+
}
|
|
242
|
+
if (primaryOk) return primaryPrice;
|
|
243
|
+
if (twapOk) return twapPrice;
|
|
244
|
+
revert("Oracle: no valid price source");
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
---
|
|
250
|
+
|
|
251
|
+
## 5. Access Control
|
|
252
|
+
|
|
253
|
+
Any unprotected function is callable by anyone, forever. The Parity Wallet ($300M frozen)
|
|
254
|
+
and Poly Network ($611M) were both access control failures.
|
|
255
|
+
|
|
256
|
+
```solidity
|
|
257
|
+
// VULNERABLE: anyone can mint
|
|
258
|
+
function mint(address to, uint256 amount) external {
|
|
259
|
+
balances[to] += amount;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
// FIXED: role-based access control
|
|
263
|
+
import "@openzeppelin/contracts/access/AccessControl.sol";
|
|
264
|
+
contract SecureToken is AccessControl {
|
|
265
|
+
bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
|
|
266
|
+
function mint(address to, uint256 amount) external onlyRole(MINTER_ROLE) {
|
|
267
|
+
balances[to] += amount;
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
### Centralization Mitigations
|
|
273
|
+
|
|
274
|
+
- **Multi-sig** (Gnosis Safe) for admin ops — M-of-N signatures required
|
|
275
|
+
- **Timelocks** (TimelockController) — 24-48 hour delay on admin actions
|
|
276
|
+
- **Role separation** — separate minter, pauser, upgrader, admin roles
|
|
277
|
+
- **Two-step transfer** (Ownable2Step) — prevents accidental ownership loss
|
|
278
|
+
- **Role renunciation** — renounce admin once governance is established
|
|
279
|
+
|
|
280
|
+
### Timelock for Governance
|
|
281
|
+
|
|
282
|
+
```solidity
|
|
283
|
+
TimelockController timelock = new TimelockController(
|
|
284
|
+
48 hours, proposers, executors, address(0) // Self-governed
|
|
285
|
+
);
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
---
|
|
289
|
+
|
|
290
|
+
## 6. Front-Running and MEV
|
|
291
|
+
|
|
292
|
+
MEV (Maximal Extractable Value) — profit a block producer extracts by reordering,
|
|
293
|
+
inserting, or censoring transactions within a block.
|
|
294
|
+
|
|
295
|
+
### Mempool Sniping
|
|
296
|
+
|
|
297
|
+
All pending transactions are visible in the public mempool before block inclusion. An
|
|
298
|
+
attacker monitors the mempool, detects a profitable transaction, and submits their own
|
|
299
|
+
with a higher gas price to execute first. Targets: DEX swaps, NFT mints, governance
|
|
300
|
+
votes, token listings.
|
|
301
|
+
|
|
302
|
+
### Sandwich Attacks
|
|
303
|
+
|
|
304
|
+
1. Attacker sees a large pending swap (e.g., buy 1M USDC of TOKEN)
|
|
305
|
+
2. Front-runs: buys TOKEN, pushing the price up
|
|
306
|
+
3. Victim's swap executes at the inflated price
|
|
307
|
+
4. Back-runs: sells TOKEN at the higher price
|
|
308
|
+
5. Victim receives fewer tokens; attacker profits from the spread
|
|
309
|
+
|
|
310
|
+
### Commit-Reveal Defense
|
|
311
|
+
|
|
312
|
+
```solidity
|
|
313
|
+
function commit(bytes32 hash) external {
|
|
314
|
+
commitments[msg.sender] = Commitment(hash, block.number);
|
|
315
|
+
}
|
|
316
|
+
function reveal(uint256 amount, bytes32 secret) external {
|
|
317
|
+
Commitment memory c = commitments[msg.sender];
|
|
318
|
+
require(block.number >= c.block + REVEAL_DELAY, "Too early");
|
|
319
|
+
require(c.hash == keccak256(abi.encodePacked(msg.sender, amount, secret)));
|
|
320
|
+
delete commitments[msg.sender];
|
|
321
|
+
_executeAction(msg.sender, amount);
|
|
322
|
+
}
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
### MEV Protection Strategies
|
|
326
|
+
|
|
327
|
+
| Strategy | Mechanism | Trade-off |
|
|
328
|
+
|----------|-----------|-----------|
|
|
329
|
+
| Flashbots Protect | Private mempool | Requires RPC change |
|
|
330
|
+
| MEV Blocker | Backrun auction | Adds latency |
|
|
331
|
+
| Slippage limits | Max acceptable price impact | Too tight = reverts |
|
|
332
|
+
| Batch auctions | Uniform clearing price | Higher latency |
|
|
333
|
+
| Encrypted mempools | Threshold encryption until inclusion | Experimental |
|
|
334
|
+
|
|
335
|
+
### Slippage Protection
|
|
336
|
+
|
|
337
|
+
```solidity
|
|
338
|
+
// VULNERABLE: amountOutMin = 0 accepts ANY output
|
|
339
|
+
router.swapExactTokensForTokens(amountIn, 0, path, msg.sender, block.timestamp);
|
|
340
|
+
|
|
341
|
+
// FIXED: enforce minimum output + deadline
|
|
342
|
+
uint256 minOut = getExpectedOutput(amountIn) * 995 / 1000; // 0.5% tolerance
|
|
343
|
+
router.swapExactTokensForTokens(amountIn, minOut, path, msg.sender, block.timestamp + 300);
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
---
|
|
347
|
+
|
|
348
|
+
## 7. Integer Overflow/Underflow
|
|
349
|
+
|
|
350
|
+
### Pre-0.8: Silent Wrapping
|
|
351
|
+
|
|
352
|
+
```solidity
|
|
353
|
+
// VULNERABLE (Solidity < 0.8): 0 - 1 underflows to 2^256 - 1
|
|
354
|
+
pragma solidity ^0.7.6;
|
|
355
|
+
function transfer(address to, uint256 amount) external {
|
|
356
|
+
require(balances[msg.sender] - amount >= 0); // Always true — underflow wraps
|
|
357
|
+
balances[msg.sender] -= amount;
|
|
358
|
+
balances[to] += amount;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
// FIXED: SafeMath
|
|
362
|
+
using SafeMath for uint256;
|
|
363
|
+
balances[msg.sender] = balances[msg.sender].sub(amount); // Reverts on underflow
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
### 0.8+ Built-in Checks
|
|
367
|
+
|
|
368
|
+
Solidity 0.8 reverts automatically on overflow/underflow. The `unchecked` block disables
|
|
369
|
+
this for gas optimization — safe only when overflow is mathematically impossible.
|
|
370
|
+
|
|
371
|
+
```solidity
|
|
372
|
+
// SAFE: loop counter
|
|
373
|
+
for (uint256 i = 0; i < array.length;) {
|
|
374
|
+
unchecked { ++i; } // i bounded by array.length
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
// DANGEROUS: user-controlled values
|
|
378
|
+
unchecked { balances[msg.sender] -= amount; } // Can underflow
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
**Rule:** never place user-controlled arithmetic inside `unchecked` blocks.
|
|
382
|
+
|
|
383
|
+
---
|
|
384
|
+
|
|
385
|
+
## 8. Formal Verification Tools
|
|
386
|
+
|
|
387
|
+
| Tool | Approach | Best For | Speed |
|
|
388
|
+
|------|----------|----------|-------|
|
|
389
|
+
| Slither | Static analysis | Quick vulnerability scan | Seconds |
|
|
390
|
+
| Mythril | Symbolic execution | Deep path analysis | Minutes |
|
|
391
|
+
| Echidna | Property-based fuzzing | Invariant testing | Minutes-hours |
|
|
392
|
+
| Certora | Formal verification | Mathematical proofs | Hours |
|
|
393
|
+
| Halmos | Symbolic testing | Foundry-compatible | Minutes |
|
|
394
|
+
|
|
395
|
+
### Slither
|
|
396
|
+
|
|
397
|
+
```bash
|
|
398
|
+
slither . --detect reentrancy-eth,reentrancy-no-eth,suicidal,uninitialized-state
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
Key detectors: `reentrancy-eth`, `suicidal`, `arbitrary-send-eth`,
|
|
402
|
+
`controlled-delegatecall`, `uninitialized-state`.
|
|
403
|
+
|
|
404
|
+
### Echidna Property Tests
|
|
405
|
+
|
|
406
|
+
Echidna generates random transaction sequences trying to violate invariant properties.
|
|
407
|
+
Functions prefixed `echidna_` must return `true` — if Echidna finds a sequence that
|
|
408
|
+
returns `false`, the invariant is broken.
|
|
409
|
+
|
|
410
|
+
```solidity
|
|
411
|
+
contract VaultTest is Vault {
|
|
412
|
+
function echidna_balance_invariant() public view returns (bool) {
|
|
413
|
+
return address(this).balance >= totalDeposits;
|
|
414
|
+
}
|
|
415
|
+
function echidna_supply_conservation() public view returns (bool) {
|
|
416
|
+
return totalMinted == totalBurned + totalSupply();
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
```
|
|
420
|
+
|
|
421
|
+
```yaml
|
|
422
|
+
# echidna.yaml
|
|
423
|
+
testMode: assertion
|
|
424
|
+
testLimit: 100000
|
|
425
|
+
seqLen: 100
|
|
426
|
+
deployer: "0x10000"
|
|
427
|
+
sender: ["0x20000", "0x30000"]
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
### Foundry Fuzz Testing
|
|
431
|
+
|
|
432
|
+
```solidity
|
|
433
|
+
function testFuzz_withdrawNeverExceedsBalance(uint256 dep, uint256 wd) public {
|
|
434
|
+
dep = bound(dep, 1, 100 ether);
|
|
435
|
+
wd = bound(wd, 0, dep);
|
|
436
|
+
vault.deposit{value: dep}();
|
|
437
|
+
vault.withdraw(wd);
|
|
438
|
+
assertGe(address(vault).balance, dep - wd);
|
|
439
|
+
}
|
|
440
|
+
```
|
|
441
|
+
|
|
442
|
+
---
|
|
443
|
+
|
|
444
|
+
## 9. Audit Checklist
|
|
445
|
+
|
|
446
|
+
### Critical — Immediate Exploitation Risk
|
|
447
|
+
|
|
448
|
+
| # | Check | SWC |
|
|
449
|
+
|---|-------|-----|
|
|
450
|
+
| C1 | Reentrancy — state modified after external call | SWC-107 |
|
|
451
|
+
| C2 | Access control — admin functions callable by anyone | SWC-105 |
|
|
452
|
+
| C3 | Unchecked external call return value | SWC-104 |
|
|
453
|
+
| C4 | Delegatecall to user-controlled address | SWC-112 |
|
|
454
|
+
| C5 | Unprotected selfdestruct in proxy | SWC-106 |
|
|
455
|
+
| C6 | Signature replay — missing nonce or chain ID | — |
|
|
456
|
+
| C7 | Flash loan oracle manipulation | — |
|
|
457
|
+
| C8 | Uninitialized proxy implementation | — |
|
|
458
|
+
|
|
459
|
+
### High — Significant Financial Risk
|
|
460
|
+
|
|
461
|
+
| # | Check | SWC |
|
|
462
|
+
|---|-------|-----|
|
|
463
|
+
| H1 | Single-source spot price oracle | — |
|
|
464
|
+
| H2 | Flash loan attack vectors | — |
|
|
465
|
+
| H3 | Front-running sensitive operations | SWC-114 |
|
|
466
|
+
| H4 | Storage collision in proxy patterns | SWC-124 |
|
|
467
|
+
| H5 | Token approval race condition | — |
|
|
468
|
+
| H6 | Precision loss — division before multiplication | — |
|
|
469
|
+
| H7 | Missing slippage protection on swaps | — |
|
|
470
|
+
|
|
471
|
+
### Medium — Conditional Exploitation
|
|
472
|
+
|
|
473
|
+
| # | Check | SWC |
|
|
474
|
+
|---|-------|-----|
|
|
475
|
+
| M1 | Gas griefing — unbounded loops | SWC-128 |
|
|
476
|
+
| M2 | DoS via revert in push pattern | SWC-113 |
|
|
477
|
+
| M3 | Centralization risk — single admin key | — |
|
|
478
|
+
| M4 | Missing events for state changes | — |
|
|
479
|
+
| M5 | Block timestamp dependence | SWC-116 |
|
|
480
|
+
| M6 | ERC-20 return value not checked | — |
|
|
481
|
+
|
|
482
|
+
### Low — Best Practice Violations
|
|
483
|
+
|
|
484
|
+
| # | Check | SWC |
|
|
485
|
+
|---|-------|-----|
|
|
486
|
+
| L1 | Floating pragma | SWC-103 |
|
|
487
|
+
| L2 | Missing NatSpec documentation | — |
|
|
488
|
+
| L3 | Unused variables or imports | — |
|
|
489
|
+
| L4 | Missing zero-address checks | — |
|
|
490
|
+
| L5 | Magic numbers without named constants | — |
|
|
491
|
+
|
|
492
|
+
---
|
|
493
|
+
|
|
494
|
+
## 10. Anti-Patterns
|
|
495
|
+
|
|
496
|
+
### 10.1 tx.origin for Authentication
|
|
497
|
+
|
|
498
|
+
`tx.origin` returns the original EOA, not the immediate caller. A phishing contract
|
|
499
|
+
forwards calls with the victim's `tx.origin`.
|
|
500
|
+
|
|
501
|
+
```solidity
|
|
502
|
+
// VULNERABLE // FIXED
|
|
503
|
+
require(tx.origin == owner); require(msg.sender == owner);
|
|
504
|
+
```
|
|
505
|
+
|
|
506
|
+
### 10.2 Block Timestamp for Randomness
|
|
507
|
+
|
|
508
|
+
Validators manipulate `block.timestamp` within ~15 seconds. Use Chainlink VRF instead.
|
|
509
|
+
|
|
510
|
+
```solidity
|
|
511
|
+
// VULNERABLE: predictable
|
|
512
|
+
uint256(keccak256(abi.encodePacked(block.timestamp, block.difficulty, msg.sender)));
|
|
513
|
+
// FIXED: Chainlink VRF — request/callback pattern with cryptographic proof
|
|
514
|
+
```
|
|
515
|
+
|
|
516
|
+
### 10.3 Missing Slippage Protection
|
|
517
|
+
|
|
518
|
+
Setting `amountOutMin = 0` makes every swap a sandwich target. Always calculate minimum
|
|
519
|
+
acceptable output from an oracle price and enforce a transaction deadline.
|
|
520
|
+
|
|
521
|
+
### 10.4 msg.value Reuse in Loops
|
|
522
|
+
|
|
523
|
+
`msg.value` is constant across loop iterations. An attacker deposits once but claims
|
|
524
|
+
credit per iteration.
|
|
525
|
+
|
|
526
|
+
```solidity
|
|
527
|
+
// VULNERABLE: msg.value checked per iteration
|
|
528
|
+
for (uint256 i = 0; i < amounts.length; i++) {
|
|
529
|
+
require(msg.value >= amounts[i]); // Same msg.value every time
|
|
530
|
+
deposits[msg.sender] += amounts[i];
|
|
531
|
+
}
|
|
532
|
+
// FIXED: sum total required, check once
|
|
533
|
+
uint256 total = 0;
|
|
534
|
+
for (uint256 i = 0; i < amounts.length; i++) {
|
|
535
|
+
total += amounts[i];
|
|
536
|
+
deposits[msg.sender] += amounts[i];
|
|
537
|
+
}
|
|
538
|
+
require(msg.value >= total, "Insufficient ETH");
|
|
539
|
+
```
|
|
540
|
+
|
|
541
|
+
### 10.5 Trusting External Return Values
|
|
542
|
+
|
|
543
|
+
Malicious tokens can return `true` without transferring. Always verify balance changes.
|
|
544
|
+
|
|
545
|
+
```solidity
|
|
546
|
+
// VULNERABLE: trusting return value
|
|
547
|
+
bool success = IERC20(token).transfer(recipient, amount);
|
|
548
|
+
if (success) credits[msg.sender] += amount; // Credit without real transfer
|
|
549
|
+
|
|
550
|
+
// FIXED: verify actual balance change
|
|
551
|
+
uint256 before = IERC20(token).balanceOf(address(this));
|
|
552
|
+
SafeERC20.safeTransferFrom(IERC20(token), msg.sender, address(this), amount);
|
|
553
|
+
uint256 received = IERC20(token).balanceOf(address(this)) - before;
|
|
554
|
+
credits[msg.sender] += received; // Credit actual amount received
|
|
555
|
+
```
|
|
556
|
+
|
|
557
|
+
### 10.6 Unprotected Initialize Functions
|
|
558
|
+
|
|
559
|
+
Proxy implementations must use OpenZeppelin's `initializer` modifier. An unprotected
|
|
560
|
+
`initialize()` lets anyone take ownership of the implementation contract.
|
|
561
|
+
|
|
562
|
+
```solidity
|
|
563
|
+
// VULNERABLE // FIXED
|
|
564
|
+
function initialize(address o) external { function initialize(address o) external initializer {
|
|
565
|
+
owner = o; __Ownable_init(o);
|
|
566
|
+
} }
|
|
567
|
+
```
|
|
568
|
+
|
|
569
|
+
---
|
|
570
|
+
|
|
571
|
+
## 11. Development Workflow
|
|
572
|
+
|
|
573
|
+
### Pre-Deployment Checklist
|
|
574
|
+
|
|
575
|
+
1. **Static analysis** — Slither with all critical detectors on every commit
|
|
576
|
+
2. **Fuzz testing** — Echidna or Foundry fuzz, 100k+ runs minimum
|
|
577
|
+
3. **Unit tests** — 100% branch coverage on state-changing functions
|
|
578
|
+
4. **Formal verification** — Certora for contracts with >$10M TVL
|
|
579
|
+
5. **Peer review** — minimum two Solidity-experienced reviewers
|
|
580
|
+
6. **External audit** — mandatory for any contract handling user funds
|
|
581
|
+
7. **Bug bounty** — Immunefi program before mainnet launch
|
|
582
|
+
8. **Testnet deployment** — full integration testing on Sepolia
|
|
583
|
+
9. **Timelock admin** — all admin functions behind timelock
|
|
584
|
+
10. **Monitoring** — Forta or OpenZeppelin Defender for anomaly detection
|
|
585
|
+
|
|
586
|
+
### Gas Optimization Safety
|
|
587
|
+
|
|
588
|
+
Never sacrifice security for gas savings:
|
|
589
|
+
- Removing `nonReentrant` (~2600 gas) reintroduces reentrancy
|
|
590
|
+
- `unchecked` on user-controlled arithmetic reintroduces overflow
|
|
591
|
+
- Removing zero-address checks (~200 gas) enables permanent burns
|
|
592
|
+
- Inline assembly bypasses Solidity safety checks
|
|
593
|
+
|
|
594
|
+
**Rule:** optimize after the contract is correct and audited. Use `forge test --gas-report`.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Directory Purpose
|
|
2
|
+
|
|
3
|
+
The `testing` security directory outlines methodologies for identifying and validating vulnerabilities before and after deployment.
|
|
4
|
+
|
|
5
|
+
# Key Concepts
|
|
6
|
+
|
|
7
|
+
- Identifying architectural flaws early
|
|
8
|
+
- Automating vulnerability detection
|
|
9
|
+
- Conducting manual security audits
|
|
10
|
+
|
|
11
|
+
# File Map
|
|
12
|
+
|
|
13
|
+
- `penetration-testing.md` — red teaming, bug bounties, and external audits
|
|
14
|
+
- `security-code-review.md` — SAST, identifying logic flaws, and taint analysis
|
|
15
|
+
- `threat-modeling.md` — STRIDE, DREAD, and attack surface mapping
|
|
16
|
+
- `vulnerability-scanning.md` — DAST, dependency checks, and continuous scanning
|
|
17
|
+
|
|
18
|
+
# Reading Guide
|
|
19
|
+
|
|
20
|
+
If starting a new major feature → read `threat-modeling.md`
|
|
21
|
+
If reviewing a pull request → read `security-code-review.md`
|
|
22
|
+
If configuring a CI pipeline → read `vulnerability-scanning.md`
|