@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,622 @@
|
|
|
1
|
+
# Async & Concurrency Anti-Patterns
|
|
2
|
+
|
|
3
|
+
**Module:** Code Anti-Patterns / Async & Concurrency
|
|
4
|
+
**Severity range:** Medium to Critical
|
|
5
|
+
**Applies to:** JavaScript/TypeScript, Python, C#, Go, Java, Rust
|
|
6
|
+
**Prerequisites:** Basic understanding of async/await, promises/futures, threads, event loops
|
|
7
|
+
|
|
8
|
+
Concurrency bugs hide behind microsecond timing windows, pass single-threaded test suites, and
|
|
9
|
+
detonate under production load. Node.js v15 changed to crash-on-unhandled-rejection after years
|
|
10
|
+
of silently swallowed errors. CVE-2024-30088 showed a single TOCTOU race in the Windows kernel
|
|
11
|
+
enabled full privilege escalation. This module catalogs 18 async and concurrency anti-patterns
|
|
12
|
+
with detection heuristics, real incident data, and concrete fixes.
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Anti-Pattern Catalog
|
|
17
|
+
|
|
18
|
+
### AP-01: Callback Hell
|
|
19
|
+
|
|
20
|
+
**Also known as:** Pyramid of Doom, Hadouken Code
|
|
21
|
+
**Frequency:** Common (legacy) | **Severity:** Medium | **Detection difficulty:** Easy
|
|
22
|
+
|
|
23
|
+
**What it looks like:**
|
|
24
|
+
```javascript
|
|
25
|
+
getUser(id, function(err, user) {
|
|
26
|
+
getOrders(user.id, function(err, orders) {
|
|
27
|
+
getDetails(orders[0].id, function(err, details) {
|
|
28
|
+
getShipping(details.trackingId, function(err, status) {
|
|
29
|
+
render(user, orders, details, status);
|
|
30
|
+
});
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
**Why developers do it:** Only pattern available in pre-Promise Node.js. Each requirement adds a nesting level.
|
|
37
|
+
|
|
38
|
+
**What goes wrong:** Error handling duplicated at every level. Missing one `if (err)` silently drops errors. Variable scoping spans closures -- renaming in an outer callback silently breaks inner ones. The callbackhell.com project documented this as the most complained-about pattern in early Node.js.
|
|
39
|
+
|
|
40
|
+
**The fix:**
|
|
41
|
+
```javascript
|
|
42
|
+
// After: flat async/await
|
|
43
|
+
async function loadDashboard(id) {
|
|
44
|
+
const user = await getUser(id);
|
|
45
|
+
const orders = await getOrders(user.id);
|
|
46
|
+
const details = await getDetails(orders[0].id);
|
|
47
|
+
const status = await getShipping(details.trackingId);
|
|
48
|
+
render(user, orders, details, status);
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
**Detection rule:** ESLint `max-nested-callbacks` set to 3.
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
### AP-02: Fire and Forget
|
|
57
|
+
|
|
58
|
+
**Also known as:** Detached Promise, Unawaited Async, Orphan Task
|
|
59
|
+
**Frequency:** Very Common | **Severity:** High | **Detection difficulty:** Medium
|
|
60
|
+
|
|
61
|
+
**What it looks like:**
|
|
62
|
+
```javascript
|
|
63
|
+
app.post("/api/orders", (req, res) => {
|
|
64
|
+
sendConfirmationEmail(order); // Promise never awaited
|
|
65
|
+
updateAnalytics(order); // Promise never awaited
|
|
66
|
+
res.json({ success: true });
|
|
67
|
+
});
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
**Why developers do it:** Fast response times -- "the email can send in the background." Works in dev because the process lives long enough.
|
|
71
|
+
|
|
72
|
+
**What goes wrong:** Exceptions are swallowed (pre-Node 15) or crash the process (Node 15+). During deployments, in-flight tasks die mid-execution. ASP.NET Core disposes scoped services (DbContext) when requests complete, so fire-and-forget tasks throw `ObjectDisposedException`. Microsoft's `IHostedService` docs explicitly warn against this.
|
|
73
|
+
|
|
74
|
+
**The fix:**
|
|
75
|
+
```javascript
|
|
76
|
+
// Before // After
|
|
77
|
+
sendConfirmationEmail(order); await queue.enqueue("email", { orderId: order.id });
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
**Detection rule:** ESLint `@typescript-eslint/no-floating-promises`. C#: `CA2012`.
|
|
81
|
+
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
### AP-03: Sequential Awaits in Loops
|
|
85
|
+
|
|
86
|
+
**Also known as:** Async Waterfall, One-at-a-Time Trap
|
|
87
|
+
**Frequency:** Very Common | **Severity:** Medium | **Detection difficulty:** Medium
|
|
88
|
+
|
|
89
|
+
**What it looks like:**
|
|
90
|
+
```javascript
|
|
91
|
+
for (const id of userIds) {
|
|
92
|
+
const user = await fetchUser(id); // each waits for previous
|
|
93
|
+
users.push(user);
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
**Why developers do it:** `async/await` makes async code look synchronous -- its strength and its trap. A `for` loop with `await` reads naturally.
|
|
98
|
+
|
|
99
|
+
**What goes wrong:** 50 users at 200ms each = 10 seconds instead of ~200ms parallel. One case had a dashboard calling 30 microservices sequentially, producing 15-second page loads discovered only at full rollout.
|
|
100
|
+
|
|
101
|
+
**The fix:**
|
|
102
|
+
```javascript
|
|
103
|
+
// Before: 10 seconds // After: ~200ms
|
|
104
|
+
for (const id of ids) { const users = await Promise.all(
|
|
105
|
+
users.push(await fetchUser(id)); ids.map(id => fetchUser(id))
|
|
106
|
+
} );
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
**Detection rule:** ESLint `no-await-in-loop`.
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
### AP-04: Race Conditions
|
|
114
|
+
|
|
115
|
+
**Also known as:** Data Race, Check-Then-Act, Read-Modify-Write
|
|
116
|
+
**Frequency:** Common | **Severity:** Critical | **Detection difficulty:** Hard
|
|
117
|
+
|
|
118
|
+
**What it looks like:**
|
|
119
|
+
```python
|
|
120
|
+
async def purchase(item_id, user_id):
|
|
121
|
+
item = await db.get(item_id)
|
|
122
|
+
if item.quantity > 0: # two requests both read quantity=1
|
|
123
|
+
item.quantity -= 1 # both decrement to 0
|
|
124
|
+
await db.save(item) # oversold, quantity should be -1
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
**Why developers do it:** Single-threaded mental model. Works with one user in dev.
|
|
128
|
+
|
|
129
|
+
**What goes wrong:** Cloudflare's June 2024 outage: a race in their rate limiter let requests enter an infinite loop, causing 114 minutes of degraded service. AWS October 2025: a race in DNS management for DynamoDB caused a major disruption. Financial systems get double-charges, oversold inventory, and balances requiring manual reconciliation.
|
|
130
|
+
|
|
131
|
+
**The fix:**
|
|
132
|
+
```python
|
|
133
|
+
# Before: read-modify-write race # After: atomic operation
|
|
134
|
+
item = await db.get(item_id) result = await db.update_one(
|
|
135
|
+
if item.quantity > 0: {"_id": item_id, "quantity": {"$gt": 0}},
|
|
136
|
+
item.quantity -= 1 {"$inc": {"quantity": -1}},
|
|
137
|
+
await db.save(item) )
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
**Detection rule:** Go: `-race` flag. Flag any read-then-write on shared state without lock/atomic.
|
|
141
|
+
|
|
142
|
+
---
|
|
143
|
+
|
|
144
|
+
### AP-05: Deadlocks
|
|
145
|
+
|
|
146
|
+
**Also known as:** Deadly Embrace, Circular Wait, Lock Ordering Violation
|
|
147
|
+
**Frequency:** Uncommon | **Severity:** Critical | **Detection difficulty:** Hard
|
|
148
|
+
|
|
149
|
+
**What it looks like:**
|
|
150
|
+
```python
|
|
151
|
+
# Thread A # Thread B
|
|
152
|
+
lock_accounts.acquire() lock_ledger.acquire()
|
|
153
|
+
lock_ledger.acquire() # BLOCKED lock_accounts.acquire() # BLOCKED
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
**Why developers do it:** Locks added to fix races without a global lock ordering policy. Each module acquires locks in locally logical order.
|
|
157
|
+
|
|
158
|
+
**What goes wrong:** A PostgreSQL production incident: product deletion acquired EXCLUSIVE lock before DELETE while concurrent INSERTs needed the same lock in reverse order, crashing checkout. Another: a job scheduler and maintenance script shared advisory lock IDs, blocking each other indefinitely. System appeared "hung" -- zero CPU, no crash, no error, silence.
|
|
159
|
+
|
|
160
|
+
**The fix:**
|
|
161
|
+
```python
|
|
162
|
+
# Before: arbitrary ordering # After: consistent ordering by ID
|
|
163
|
+
def transfer(a, b, amount): def transfer(a, b, amount):
|
|
164
|
+
a.lock.acquire() first, second = sorted([a, b], key=lambda x: x.id)
|
|
165
|
+
b.lock.acquire() with first.lock, second.lock:
|
|
166
|
+
a.balance -= amount; b.balance += amount
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
**Detection rule:** PostgreSQL: `log_lock_waits = on`. Java: `jstack` thread dump. Flag nested lock acquisitions.
|
|
170
|
+
|
|
171
|
+
---
|
|
172
|
+
|
|
173
|
+
### AP-06: Promise Constructor Anti-Pattern
|
|
174
|
+
|
|
175
|
+
**Also known as:** Deferred Anti-Pattern, Unnecessary Promise Wrapping
|
|
176
|
+
**Frequency:** Common | **Severity:** Low-Medium | **Detection difficulty:** Easy
|
|
177
|
+
|
|
178
|
+
**What it looks like:**
|
|
179
|
+
```javascript
|
|
180
|
+
function getUser(id) {
|
|
181
|
+
return new Promise((resolve, reject) => {
|
|
182
|
+
fetchFromDb(id).then(resolve).catch(reject); // pointless wrapping
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
**Why developers do it:** Misunderstanding that `.then()` already returns a Promise. Overapplying callback-to-promise conversion patterns.
|
|
188
|
+
|
|
189
|
+
**What goes wrong:** The wrapper obscures errors. In the `async` executor variant (`new Promise(async (resolve, reject) => {})`), throwing does not reject -- it throws synchronously, bypassing Promise error handling. `reject()` does not stop execution, so code after it runs, potentially calling `resolve()`.
|
|
190
|
+
|
|
191
|
+
**The fix:**
|
|
192
|
+
```javascript
|
|
193
|
+
// Before // After
|
|
194
|
+
return new Promise((resolve, reject) => { return fetchFromDb(id);
|
|
195
|
+
fetchFromDb(id).then(resolve).catch(reject);
|
|
196
|
+
});
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
**Detection rule:** ESLint `no-async-promise-executor`. Flag `new Promise` wrapping a single `.then/.catch` chain.
|
|
200
|
+
|
|
201
|
+
---
|
|
202
|
+
|
|
203
|
+
### AP-07: Missing Error Handling on Promises
|
|
204
|
+
|
|
205
|
+
**Also known as:** Floating Promise, Unhandled Rejection, Silent Failure
|
|
206
|
+
**Frequency:** Very Common | **Severity:** Critical | **Detection difficulty:** Medium
|
|
207
|
+
|
|
208
|
+
**What it looks like:**
|
|
209
|
+
```javascript
|
|
210
|
+
fetch("/api/users").then(r => r.json()).then(renderUsers); // no .catch()
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
**Why developers do it:** Happy-path development. Plans to "add error handling later."
|
|
214
|
+
|
|
215
|
+
**What goes wrong:** Node.js 15+ crashes the process on unhandled rejections. Before that, operations silently failed. A DZone analysis documented a production API "randomly" crashing with no logs -- root cause was a missing `.catch()` on a database query in middleware. The unhandled rejection killed the process with no stack trace pointing to the failure.
|
|
216
|
+
|
|
217
|
+
**The fix:**
|
|
218
|
+
```javascript
|
|
219
|
+
fetch("/api/users")
|
|
220
|
+
.then(r => { if (!r.ok) throw new Error(`HTTP ${r.status}`); return r.json(); })
|
|
221
|
+
.then(renderUsers)
|
|
222
|
+
.catch(err => { logger.error("User load failed", err); renderError(); });
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
**Detection rule:** ESLint `@typescript-eslint/no-floating-promises`. Node.js: `--unhandled-rejections=throw` in CI.
|
|
226
|
+
|
|
227
|
+
---
|
|
228
|
+
|
|
229
|
+
### AP-08: Mixing Callbacks and Promises
|
|
230
|
+
|
|
231
|
+
**Also known as:** Async Frankenstein, Dual-Mode API
|
|
232
|
+
**Frequency:** Common | **Severity:** Medium | **Detection difficulty:** Medium
|
|
233
|
+
|
|
234
|
+
**What it looks like:**
|
|
235
|
+
```javascript
|
|
236
|
+
function getUser(id, callback) {
|
|
237
|
+
fetchFromCache(id).then(cached => {
|
|
238
|
+
if (cached) { callback(null, cached); return; }
|
|
239
|
+
return fetchFromDb(id);
|
|
240
|
+
}).then(user => {
|
|
241
|
+
callback(null, user); // called TWICE if cache hit
|
|
242
|
+
}).catch(err => callback(err));
|
|
243
|
+
}
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
**Why developers do it:** Gradual migration from callbacks to promises. Library authors supporting both styles.
|
|
247
|
+
|
|
248
|
+
**What goes wrong:** Callback invoked multiple times. Error handling splits across two mechanisms. In Express, calling `next()` from both a callback and `.catch()` sends the response twice -- "headers already sent" crash.
|
|
249
|
+
|
|
250
|
+
**The fix:**
|
|
251
|
+
```javascript
|
|
252
|
+
// Pure async; wrap at boundary only
|
|
253
|
+
async function getUser(id) {
|
|
254
|
+
const cached = await fetchFromCache(id);
|
|
255
|
+
return cached || await fetchFromDb(id);
|
|
256
|
+
}
|
|
257
|
+
function getUserCb(id, cb) { getUser(id).then(u => cb(null, u), cb); } // single adapter
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
**Detection rule:** `eslint-plugin-promise`: `no-callback-in-promise`, `no-promise-in-callback`.
|
|
261
|
+
|
|
262
|
+
---
|
|
263
|
+
|
|
264
|
+
### AP-09: Async Void
|
|
265
|
+
|
|
266
|
+
**Also known as:** Async Fire-and-Crash, Unobserved Task
|
|
267
|
+
**Frequency:** Common (C#, Dart) | **Severity:** Critical | **Detection difficulty:** Easy
|
|
268
|
+
|
|
269
|
+
**What it looks like:**
|
|
270
|
+
```csharp
|
|
271
|
+
public async void LogActivity(string msg) {
|
|
272
|
+
await store.WriteAsync(msg); // if this throws, process crashes
|
|
273
|
+
}
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
**Why developers do it:** Event handler delegates require `void`. Developers apply the pattern to non-event-handler methods by habit.
|
|
277
|
+
|
|
278
|
+
**What goes wrong:** A production ASP.NET Core app (documented by Josh the Coder, 2023) crashed periodically. An anonymous `async void` lambda inside a controller threw, bypassing all middleware and killing `w3wp.exe`. The `async void` was buried in a LINQ `.ForEach()` -- invisible in code review. GitHub issue dotnet/aspnetcore#13867 confirmed this as known process-crashing behavior.
|
|
279
|
+
|
|
280
|
+
**The fix:**
|
|
281
|
+
```csharp
|
|
282
|
+
// Before: async void (crasher) // After: async Task (catchable)
|
|
283
|
+
public async void Log(string m) { ... } public async Task LogAsync(string m) { ... }
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
**Detection rule:** C# Roslyn analyzer `VSTHRD100`. Dart: `avoid_void_async` lint rule.
|
|
287
|
+
|
|
288
|
+
---
|
|
289
|
+
|
|
290
|
+
### AP-10: Thread-Unsafe Singletons
|
|
291
|
+
|
|
292
|
+
**Also known as:** Lazy Init Race, Double-Checked Locking Bug
|
|
293
|
+
**Frequency:** Common | **Severity:** High | **Detection difficulty:** Hard
|
|
294
|
+
|
|
295
|
+
**What it looks like:**
|
|
296
|
+
```java
|
|
297
|
+
private static ConnectionPool instance;
|
|
298
|
+
public static ConnectionPool getInstance() {
|
|
299
|
+
if (instance == null) instance = new ConnectionPool(); // two threads, two pools
|
|
300
|
+
return instance;
|
|
301
|
+
}
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
**Why developers do it:** Lazy init avoids startup cost. Check-then-create is correct single-threaded.
|
|
305
|
+
|
|
306
|
+
**What goes wrong:** Two threads create separate instances; one gets GC'd while threads hold stale references. Connection pools leak connections. Config singletons diverge. Swift 6 now emits compiler warnings for non-Sendable shared static properties.
|
|
307
|
+
|
|
308
|
+
**The fix:**
|
|
309
|
+
```java
|
|
310
|
+
// After: holder pattern (JVM guarantees thread-safe class loading)
|
|
311
|
+
private static class Holder { static final ConnectionPool INSTANCE = new ConnectionPool(); }
|
|
312
|
+
public static ConnectionPool getInstance() { return Holder.INSTANCE; }
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
**Detection rule:** SpotBugs `LI_LAZY_INIT_STATIC`. PMD `SingletonClassReturningNewInstance`.
|
|
316
|
+
|
|
317
|
+
---
|
|
318
|
+
|
|
319
|
+
### AP-11: Busy Waiting
|
|
320
|
+
|
|
321
|
+
**Also known as:** Spin Loop, Poll Loop, CPU Burner
|
|
322
|
+
**Frequency:** Common | **Severity:** Medium-High | **Detection difficulty:** Easy
|
|
323
|
+
|
|
324
|
+
**What it looks like:**
|
|
325
|
+
```python
|
|
326
|
+
while not os.path.exists(path):
|
|
327
|
+
pass # 100% CPU on one core, doing nothing useful
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
**Why developers do it:** Simplest "wait for something" implementation. Works in dev where the wait is milliseconds.
|
|
331
|
+
|
|
332
|
+
**What goes wrong:** Burns a full CPU core. In containers with CPU limits, steals budget from real work. Causes priority inversion: low-priority thread spinning prevents higher-priority threads from releasing the lock it's waiting on.
|
|
333
|
+
|
|
334
|
+
**The fix:**
|
|
335
|
+
```python
|
|
336
|
+
# After: exponential backoff
|
|
337
|
+
async def wait_for_file(path, timeout=30.0):
|
|
338
|
+
deadline, interval = time.monotonic() + timeout, 0.1
|
|
339
|
+
while not os.path.exists(path):
|
|
340
|
+
if time.monotonic() > deadline: raise TimeoutError(f"{path} not ready")
|
|
341
|
+
await asyncio.sleep(interval)
|
|
342
|
+
interval = min(interval * 2, 5.0)
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
**Detection rule:** Flag `while` loops without `sleep`/`await`/`yield`/blocking calls in the body.
|
|
346
|
+
|
|
347
|
+
---
|
|
348
|
+
|
|
349
|
+
### AP-12: Over-Synchronization
|
|
350
|
+
|
|
351
|
+
**Also known as:** Lock Contention, Giant Lock, Synchronized Everything
|
|
352
|
+
**Frequency:** Common | **Severity:** Medium | **Detection difficulty:** Medium
|
|
353
|
+
|
|
354
|
+
**What it looks like:**
|
|
355
|
+
```java
|
|
356
|
+
public synchronized User getUser(String id) { return cache.get(id); }
|
|
357
|
+
public synchronized List<User> search(String q) { /* blocks while getUser runs */ }
|
|
358
|
+
public synchronized void clearCache() { /* blocks everything */ }
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
**Why developers do it:** After a race condition, `synchronized` on every method is the "safe" fix.
|
|
362
|
+
|
|
363
|
+
**What goes wrong:** Application becomes effectively single-threaded. Under load, threads queue on the lock: latency spikes, throughput collapses. Profiling shows low CPU but high response times. 64-core servers perform worse than single-core from lock contention overhead.
|
|
364
|
+
|
|
365
|
+
**The fix:**
|
|
366
|
+
```java
|
|
367
|
+
// After: ConcurrentHashMap handles per-segment locking
|
|
368
|
+
private final ConcurrentHashMap<String, User> cache = new ConcurrentHashMap<>();
|
|
369
|
+
public User getUser(String id) { return cache.computeIfAbsent(id, this::fetch); }
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
**Detection rule:** PMD `AvoidSynchronizedAtMethodLevel`. Flag classes where >50% methods are `synchronized`.
|
|
373
|
+
|
|
374
|
+
---
|
|
375
|
+
|
|
376
|
+
### AP-13: TOCTOU (Time-of-Check to Time-of-Use)
|
|
377
|
+
|
|
378
|
+
**Also known as:** Check-Then-Act, Symlink Race
|
|
379
|
+
**Frequency:** Common | **Severity:** Critical | **Detection difficulty:** Hard
|
|
380
|
+
|
|
381
|
+
**What it looks like:**
|
|
382
|
+
```python
|
|
383
|
+
if os.access(filepath, os.W_OK): # CHECK
|
|
384
|
+
with open(filepath, "w") as f: # USE -- attacker swapped symlink between lines
|
|
385
|
+
f.write(data)
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
**Why developers do it:** Check-then-act is how humans reason sequentially. Security checks feel like they should precede the action.
|
|
389
|
+
|
|
390
|
+
**What goes wrong:** CVE-2024-30088: TOCTOU in Windows kernel allowed privilege escalation to SYSTEM. CVE-2018-15664: Docker symlink race yielded root access on host from within container. 2023 Pwn2Own: team compromised Tesla Model 3 gateway via TOCTOU. CWE-367 lists 400+ CVEs -- one of the most exploited vulnerability classes.
|
|
391
|
+
|
|
392
|
+
**The fix:**
|
|
393
|
+
```python
|
|
394
|
+
# After: atomic write-then-rename
|
|
395
|
+
fd, tmp = tempfile.mkstemp(dir=os.path.dirname(filepath))
|
|
396
|
+
os.write(fd, data); os.fsync(fd); os.close(fd)
|
|
397
|
+
os.rename(tmp, filepath) # atomic on same filesystem
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
**Detection rule:** Semgrep/CodeQL TOCTOU rules. Flag `os.access()` or `os.path.exists()` followed by `open()`.
|
|
401
|
+
|
|
402
|
+
---
|
|
403
|
+
|
|
404
|
+
### AP-14: Thundering Herd
|
|
405
|
+
|
|
406
|
+
**Also known as:** Cache Stampede, Dog-Pile Effect
|
|
407
|
+
**Frequency:** Common (at scale) | **Severity:** High | **Detection difficulty:** Medium
|
|
408
|
+
|
|
409
|
+
**What it looks like:**
|
|
410
|
+
```python
|
|
411
|
+
async def get_catalog():
|
|
412
|
+
cached = await redis.get("catalog")
|
|
413
|
+
if cached: return json.loads(cached)
|
|
414
|
+
catalog = await db.query("SELECT * FROM products") # every request hits DB
|
|
415
|
+
await redis.set("catalog", json.dumps(catalog), ex=300)
|
|
416
|
+
return catalog
|
|
417
|
+
```
|
|
418
|
+
|
|
419
|
+
**Why developers do it:** Standard cache-aside pattern. Correct at low concurrency.
|
|
420
|
+
|
|
421
|
+
**What goes wrong:** Twitter, Reddit, and Instagram have all publicly documented stampede incidents. When a popular key expires, the database goes from 500 queries/sec to 15,000 identical queries in one second. Database saturates, cache stays empty longer, more requests pile up -- positive feedback loop that can take down the data tier.
|
|
422
|
+
|
|
423
|
+
**The fix:**
|
|
424
|
+
```python
|
|
425
|
+
# After: single-flight with distributed lock
|
|
426
|
+
lock_key = f"lock:{key}"
|
|
427
|
+
if await redis.set(lock_key, "1", nx=True, ex=10): # one winner fetches
|
|
428
|
+
data = await fetch_fn()
|
|
429
|
+
await redis.set(key, json.dumps(data), ex=ttl)
|
|
430
|
+
await redis.delete(lock_key)
|
|
431
|
+
else:
|
|
432
|
+
await asyncio.sleep(0.1) # losers retry from cache
|
|
433
|
+
return await get_with_singleflight(key, fetch_fn)
|
|
434
|
+
```
|
|
435
|
+
|
|
436
|
+
**Detection rule:** Alert on cache miss rate spikes correlated with DB query spikes. Track concurrent identical cache misses.
|
|
437
|
+
|
|
438
|
+
---
|
|
439
|
+
|
|
440
|
+
### AP-15: Async Constructors
|
|
441
|
+
|
|
442
|
+
**Also known as:** Constructor Side-Effect, Async Init Trap
|
|
443
|
+
**Frequency:** Common | **Severity:** Medium | **Detection difficulty:** Easy
|
|
444
|
+
|
|
445
|
+
**What it looks like:**
|
|
446
|
+
```javascript
|
|
447
|
+
class DbClient {
|
|
448
|
+
constructor(connStr) {
|
|
449
|
+
this.conn = this.connect(connStr); // this.conn is a Promise, not a connection
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
```
|
|
453
|
+
|
|
454
|
+
**Why developers do it:** Constructors are "where setup goes." Natural instinct to put initialization there.
|
|
455
|
+
|
|
456
|
+
**What goes wrong:** Constructor returns a half-initialized object. Every method must `await this.conn`. In Python, `asyncio.run()` in `__init__` crashes if an event loop is already running. The object violates the constructor's contract that the returned instance is ready to use.
|
|
457
|
+
|
|
458
|
+
**The fix:**
|
|
459
|
+
```javascript
|
|
460
|
+
class DbClient {
|
|
461
|
+
constructor(conn) { this.conn = conn; } // already resolved
|
|
462
|
+
static async create(connStr) {
|
|
463
|
+
return new DbClient(await pg.connect(connStr));
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
const client = await DbClient.create(connStr);
|
|
467
|
+
```
|
|
468
|
+
|
|
469
|
+
**Detection rule:** Flag constructors containing `await`, `asyncio.run`, or Promise assignment.
|
|
470
|
+
|
|
471
|
+
---
|
|
472
|
+
|
|
473
|
+
### AP-16: Not Canceling Obsolete Operations
|
|
474
|
+
|
|
475
|
+
**Also known as:** Stale Closure, Zombie Request, Use-After-Unmount
|
|
476
|
+
**Frequency:** Very Common (frontend) | **Severity:** Medium | **Detection difficulty:** Medium
|
|
477
|
+
|
|
478
|
+
**What it looks like:**
|
|
479
|
+
```javascript
|
|
480
|
+
useEffect(() => {
|
|
481
|
+
fetch(`/api/users/${userId}`).then(r => r.json()).then(setUser);
|
|
482
|
+
// no cleanup -- stale fetch overwrites current data
|
|
483
|
+
}, [userId]);
|
|
484
|
+
```
|
|
485
|
+
|
|
486
|
+
**Why developers do it:** Cancellation is not part of the happy path. AbortController feels like boilerplate.
|
|
487
|
+
|
|
488
|
+
**What goes wrong:** If a user navigates Alice -> Bob -> Charlie quickly, three fetches race. The last to complete wins -- which may be Alice's data on Charlie's profile. React team documented this in GitHub issue #15006. Memory leaks accumulate as unmounted components retain promise callbacks.
|
|
489
|
+
|
|
490
|
+
**The fix:**
|
|
491
|
+
```javascript
|
|
492
|
+
useEffect(() => {
|
|
493
|
+
const ctrl = new AbortController();
|
|
494
|
+
fetch(`/api/users/${userId}`, { signal: ctrl.signal })
|
|
495
|
+
.then(r => r.json()).then(setUser)
|
|
496
|
+
.catch(e => { if (e.name !== "AbortError") setError(e); });
|
|
497
|
+
return () => ctrl.abort();
|
|
498
|
+
}, [userId]);
|
|
499
|
+
```
|
|
500
|
+
|
|
501
|
+
**Detection rule:** Flag `useEffect` with `fetch`/async calls but no cleanup returning `abort()`.
|
|
502
|
+
|
|
503
|
+
---
|
|
504
|
+
|
|
505
|
+
### AP-17: Shared Mutable State Across Threads
|
|
506
|
+
|
|
507
|
+
**Also known as:** Unprotected Global, Thread-Hostile Singleton
|
|
508
|
+
**Frequency:** Common | **Severity:** Critical | **Detection difficulty:** Hard
|
|
509
|
+
|
|
510
|
+
**What it looks like:**
|
|
511
|
+
```kotlin
|
|
512
|
+
var counter = 0
|
|
513
|
+
suspend fun main() {
|
|
514
|
+
val jobs = List(1000) { GlobalScope.launch { repeat(1000) { counter++ } } }
|
|
515
|
+
jobs.forEach { it.join() }
|
|
516
|
+
println(counter) // prints ~578_923, not 1_000_000
|
|
517
|
+
}
|
|
518
|
+
```
|
|
519
|
+
|
|
520
|
+
**Why developers do it:** Global state is simplest. Python's GIL gives false safety (it protects bytecodes, not multi-step sequences). JS developers moving to Kotlin don't realize coroutines may run on different threads.
|
|
521
|
+
|
|
522
|
+
**What goes wrong:** Kotlin docs explicitly show the counter example producing 30-50% fewer increments than expected. In production: negative inventory, user sessions showing another user's data, analytics that never add up. Bugs depend on exact thread scheduling -- notoriously unreproducible.
|
|
523
|
+
|
|
524
|
+
**The fix:**
|
|
525
|
+
```kotlin
|
|
526
|
+
// Before: data race // After: atomic
|
|
527
|
+
var counter = 0 val counter = AtomicInteger(0)
|
|
528
|
+
massiveRun { counter++ } massiveRun { counter.incrementAndGet() }
|
|
529
|
+
```
|
|
530
|
+
|
|
531
|
+
**Detection rule:** Go: `-race` flag. Rust: compiler prevents at compile time. Flag `global`/`var` mutated from async contexts.
|
|
532
|
+
|
|
533
|
+
---
|
|
534
|
+
|
|
535
|
+
### AP-18: Zombie Processes
|
|
536
|
+
|
|
537
|
+
**Also known as:** Defunct Process, Orphan Worker, Leaked Subprocess
|
|
538
|
+
**Frequency:** Common (containers) | **Severity:** High | **Detection difficulty:** Medium
|
|
539
|
+
|
|
540
|
+
**What it looks like:**
|
|
541
|
+
```python
|
|
542
|
+
def health_check():
|
|
543
|
+
proc = subprocess.Popen(["curl", "-s", "http://localhost:8080/health"])
|
|
544
|
+
# never calls proc.wait() -- zombie accumulates every 10 seconds
|
|
545
|
+
```
|
|
546
|
+
|
|
547
|
+
**Why developers do it:** `Popen`/`spawn` are fire-and-forget by default. Parent doesn't need the result.
|
|
548
|
+
|
|
549
|
+
**What goes wrong:** Kubernetes #81042: containers with exec probes accumulated zombies because pause container v3.0 didn't reap children. Zombies consumed PID table entries until the system hit PID limit, freezing the node. containerd #3781: zombie processes made pods fail readiness checks, causing cascading cluster restarts. Kubernetes #66892: pods stuck in "Terminating" because zombie children ignored SIGTERM.
|
|
550
|
+
|
|
551
|
+
**The fix:**
|
|
552
|
+
```python
|
|
553
|
+
# Before: zombie leak # After: managed lifecycle
|
|
554
|
+
proc = subprocess.Popen(cmd) result = subprocess.run(cmd, timeout=5, capture_output=True)
|
|
555
|
+
# Container: ENTRYPOINT ["tini", "--"]
|
|
556
|
+
```
|
|
557
|
+
|
|
558
|
+
**Detection rule:** Flag `Popen` without `.wait()`/`.communicate()`. Kubernetes: flag pods without `tini`/`dumb-init`.
|
|
559
|
+
|
|
560
|
+
---
|
|
561
|
+
|
|
562
|
+
## Root Cause Analysis
|
|
563
|
+
|
|
564
|
+
| Root Cause | Anti-Patterns | Prevention |
|
|
565
|
+
|---|---|---|
|
|
566
|
+
| Single-threaded mental model | AP-04, 10, 13, 17 | Concurrency training; race condition testing |
|
|
567
|
+
| Happy-path-only development | AP-02, 07, 16 | Chaos engineering; failure injection in CI |
|
|
568
|
+
| Copy-paste from outdated tutorials | AP-01, 06, 08 | Style guide with lint rules enforced in CI |
|
|
569
|
+
| "Works in dev" false confidence | AP-03, 11, 14 | Load testing before merge; production-like staging |
|
|
570
|
+
| Misunderstanding language semantics | AP-06, 09, 15 | Language-specific async guidelines; typed linting |
|
|
571
|
+
| Missing lifecycle management | AP-02, 16, 18 | RAII pattern; cleanup in finally/defer/using |
|
|
572
|
+
| Lock-based thinking without ordering | AP-05, 12 | Lock hierarchy docs; prefer lock-free structures |
|
|
573
|
+
| Ignoring cancellation as "edge case" | AP-16, 18 | AbortController/CancellationToken as mandatory API |
|
|
574
|
+
|
|
575
|
+
---
|
|
576
|
+
|
|
577
|
+
## Self-Check Questions
|
|
578
|
+
|
|
579
|
+
1. Is every Promise/Task/Future either awaited, returned, or handled with `.catch()`?
|
|
580
|
+
2. Are independent async operations in a loop running sequentially when `Promise.all` would work?
|
|
581
|
+
3. If this async operation throws, where does the exception go? Handler, crash, or void?
|
|
582
|
+
4. If the user navigates away or the server shuts down, does this operation clean up or become a zombie?
|
|
583
|
+
5. If this code acquires multiple locks, is the ordering consistent across all code paths?
|
|
584
|
+
6. Is there a gap between checking a condition and acting on it that another thread could exploit?
|
|
585
|
+
7. If 1000 requests hit this cache miss simultaneously, does the system survive?
|
|
586
|
+
8. Is any mutable variable accessed from multiple threads/coroutines without synchronization?
|
|
587
|
+
9. Does every `Popen`/`spawn`/`exec` have lifecycle management (wait, timeout, cleanup)?
|
|
588
|
+
10. Does any constructor perform async I/O, returning a half-initialized object?
|
|
589
|
+
11. Does this code mix callbacks and promises, or use `async void` where `async Task` is needed?
|
|
590
|
+
12. Does every external call have a bounded timeout, or can it hang forever?
|
|
591
|
+
13. If N clients retry this failed operation simultaneously, does the system stampede?
|
|
592
|
+
14. Is this lazy-initialized singleton safe under concurrent first access?
|
|
593
|
+
15. Is there a polling loop without sleep/backoff that will burn CPU?
|
|
594
|
+
|
|
595
|
+
---
|
|
596
|
+
|
|
597
|
+
## Code Smell Quick Reference
|
|
598
|
+
|
|
599
|
+
| Smell | Anti-Pattern | First Check |
|
|
600
|
+
|---|---|---|
|
|
601
|
+
| `>3` levels of callback nesting | AP-01 Callback Hell | Refactor to async/await |
|
|
602
|
+
| Promise returned but not awaited | AP-02 Fire and Forget | Add `await` or `.catch()` |
|
|
603
|
+
| `await` inside `for`/`for...of` | AP-03 Sequential Awaits | Use `Promise.all` if independent |
|
|
604
|
+
| Read-then-write without lock/atomic | AP-04 Race Condition | Use atomic op or transaction |
|
|
605
|
+
| Nested lock acquisitions | AP-05 Deadlock | Verify consistent lock ordering |
|
|
606
|
+
| `new Promise` wrapping `.then/.catch` | AP-06 Promise Constructor | Return inner promise directly |
|
|
607
|
+
| `.then()` chain with no `.catch()` | AP-07 Missing Error Handling | Add `.catch()` or try/catch |
|
|
608
|
+
| Function accepts callback AND returns Promise | AP-08 Mixed Models | Pick one; adapter at boundary |
|
|
609
|
+
| `async void` (C#) / `void...async` (Dart) | AP-09 Async Void | Change to `async Task`/`Future` |
|
|
610
|
+
| `if (instance == null) instance = new` | AP-10 Unsafe Singleton | Use language-safe lazy init |
|
|
611
|
+
| `while(true)` without sleep/yield | AP-11 Busy Waiting | Add backoff or event-driven wait |
|
|
612
|
+
| `synchronized` on every method | AP-12 Over-Synchronization | Use concurrent data structures |
|
|
613
|
+
| `os.access()` then `open()` | AP-13 TOCTOU | Atomic operation, handle error |
|
|
614
|
+
| Cache get-miss-fetch without lock | AP-14 Thundering Herd | Add single-flight/distributed lock |
|
|
615
|
+
| `await`/`asyncio.run` in constructor | AP-15 Async Constructor | Use static factory method |
|
|
616
|
+
| `useEffect` + fetch, no cleanup | AP-16 Not Canceling | Add AbortController cleanup |
|
|
617
|
+
| `global`/`var` mutated from async code | AP-17 Shared Mutable State | Atomic types or confinement |
|
|
618
|
+
| `Popen()`/`spawn()` without `.wait()` | AP-18 Zombie Processes | Use `subprocess.run` or add handler |
|
|
619
|
+
|
|
620
|
+
---
|
|
621
|
+
|
|
622
|
+
*Researched: 2026-03-08 | Sources: [Cloudflare Incident June 2024](https://blog.cloudflare.com/cloudflare-incident-on-june-20-2024/), [Node.js Unhandled Rejections (DZone)](https://dzone.com/articles/unhandled-promise-rejections-nodejs-crash), [Node.js Issue #20392](https://github.com/nodejs/node/issues/20392), [ASP.NET async void crash](https://joshthecoder.com/2023/12/01/sneaky-async-void-leads-to-aspnetcore-crash.html), [dotnet/aspnetcore #13867](https://github.com/dotnet/aspnetcore/issues/13867), [CVE-2024-30088 Windows TOCTOU](https://www.broadcom.com/support/security-center/protection-bulletin/microsoft-windows-kernel-toctou-race-condition-vulnerability-cve-2024-30088), [CWE-367](https://cwe.mitre.org/data/definitions/367.html), [CVE-2018-15664 Docker race](https://en.wikipedia.org/wiki/Time-of-check_to_time-of-use), [Kubernetes #81042 zombies](https://github.com/kubernetes/kubernetes/issues/81042), [containerd #3781](https://github.com/containerd/containerd/issues/3781), [Kubernetes #66892](https://github.com/kubernetes/kubernetes/issues/66892), [Thundering Herd (Encore)](https://encore.dev/blog/thundering-herd-problem), [PostgreSQL Deadlocks (Netdata)](https://www.netdata.cloud/academy/10-real-world-postgresql-deadlock/), [Kotlin shared mutable state](https://kotlinlang.org/docs/shared-mutable-state-and-concurrency.html), [React #15006](https://github.com/facebook/react/issues/15006), [Promise anti-patterns](https://medium.com/datafire-io/es6-promises-patterns-and-anti-patterns-bbb21a5d0918), [callbackhell.com](https://callbackhell.com/), [Async constructors](https://dev.to/somedood/the-proper-way-to-write-async-constructors-in-javascript-1o8c)*
|