Checks reference
opensip-cli ships 158 built-in checks across seven packs. Each check is a single source file that returns violations when the rule is broken. Below: every check by pack, grouped by primary tag, with the one-line description from defineCheck.
This page is auto-generated from the source by
scripts/build-checks-index.mjs. Do not edit it by hand — edit the check's source file (the link in each row), then re-run the generator.
Universal (96 checks)
Language-agnostic; runs against every project.
Architecture (16)
| Slug | Description |
|---|---|
| docker-ignore-validation | Validate .dockerignore files exist alongside Dockerfiles with required patterns |
| docker-version-sync | Validate Docker Node/pnpm versions match package.json |
| empty-package-detection | Detects packages with empty or commented-out exports |
| env-var-validation | Detects environment variable access without proper validation |
| heavy-import-detection | Detects heavy/deprecated library imports and excessive named imports that bloat bundle size |
| interface-implementation-consistency | Verifies interfaces match their implementations |
| no-custom-event-emitter | Detects direct EventEmitter usage that should use infrastructure/events |
| no-duplicate-packages | Detects packages that serve the same purpose |
| no-kebab-option-indexing | Command handlers must not index parsed options by a kebab-case key — Commander camelCases long flags, so the kebab key is always undefined (silent no-op flag) |
| node-version-consistency | Validate Node.js version consistency across configs |
| project-readme-existence | Ensures every package has a README.md file |
| stale-build-artifacts | Detects compiled .js/.d.ts/.js.map files in source directories that should only exist in dist/ |
| tool-has-manifest | Every first-party tool package must declare a conformant opensipTools manifest (kind/id/apiVersion/commands) the host can read before import |
| tool-identity-single-source | Tool packages declare opensipTools.identity once; manifest id, primary command, aliases, and pluginLayout.domain must match the normalized runtime surface |
| vitest-config-extends-base | Per-package vitest configs must extend the shared .config/vitest.base (when one exists) |
| vitest-config-required-with-tests | Ensures packages with tests have a vitest.config at the package root |
Security (18)
| Slug | Description |
|---|---|
| api-key-rotation | Validate API key handling supports rotation |
| auth-middleware-coverage | Validate routes have authentication middleware |
| auth-route-guard | Verify (auth) group _layout files include authentication checks (useAuth/useSession hooks) |
| cors-configuration | Validate CORS configuration follows security best practices |
| csp-headers | Validate Content Security Policy headers configuration |
| dependency-vulnerability-audit | Dependency vulnerability scanning via package manager audit |
| docker-best-practices | Validate Dockerfiles follow security and efficiency best practices |
| env-secret-exposure | Detect secrets exposed through environment variables in logs or errors |
| hasura-production-config | Verify Hasura production docker-compose has required security settings |
| jwt-validation | Validate JWT handling follows security best practices |
| no-eval | Detect dangerous eval and dynamic code execution |
| no-hardcoded-secrets | Detect hardcoded secrets, API keys, and credentials in source code |
| package-supply-chain-policy | Validate npm/pnpm/Bun supply-chain guardrails |
| rate-limit-coverage | Validate routes have rate limiting configured |
| semgrep-scan | Run Semgrep static analysis to detect security vulnerabilities |
| sentry-pii-scrubbing | Detects missing PII scrubbing in Sentry — personal data may leak to third party |
| use-centralized-crypto | Enforce use of centralized crypto module instead of direct crypto operations |
| webhook-signature-verification | Detect webhook endpoints without signature verification |
Quality (28)
| Slug | Description |
|---|---|
| async-state-pattern | Ensure data-driven screens use AsyncState pattern |
| dead-code | Detect unused files, exports, types, and dependencies using Knip |
| dependency-version-consistency | Ensures consistent dependency versions across all packages |
| expo-vector-icons | Ensure consistent icon library usage with @expo/vector-icons |
| file-length-limit | (no description; see source) |
| fitness-ignore-hygiene | Validates that @fitness-ignore directives have valid check slugs and reason comments |
| graph-ignore-hygiene | Validates that @graph-ignore directives have valid graph rule ids and reason comments |
| graphql-offset-pagination | Detect $offset variables in GraphQL queries that indicate offset-based pagination |
| image-optimization | Detect unoptimized image usage and recommend best practices |
| navigation-typing | Verify navigation params are properly typed for type-safe routing |
| no-ai-attribution | Detects AI-attribution metadata in comments |
| no-compatibility-layer-names | Detects compatibility-layer, legacy-wrapper, and backward-compat declarations |
| no-console-log | Disallow console.log in production code - use a structured logger |
| no-deprecated-tags | Detects @deprecated JSDoc tags in production code |
| no-non-null-assertions | Detects TypeScript non-null assertion operator (!) usage in production code — prefer proper null handling |
| no-process-artifacts | Detects process/planning artifacts (Phase X, Sprint X, version stamps) in comments |
| no-raw-regex-on-code | Detect regex checks that should use contentFilter: strip-strings |
| no-skipped-tests | Tests must never ship skipped, focused (.only), or placeholder |
| no-temporary-workarounds | Detects HACK/FIXME comments that describe themselves as temporary |
| no-todo-comments | TODO/FIXME/XXX/OPTIMIZE markers should not ship to production |
| no-unimplemented-markers | (no description; see source) |
| no-window-alert | Disallows window.alert(), window.confirm(), and window.prompt() — use proper UI components |
| performance-anti-patterns | Detects common performance anti-patterns (sequential await, spread in loops) |
| pino-serializer-coverage | Validates that complex objects logged have proper Pino serializers |
| sentry-release-set | Detects Sentry.init() without release — cannot track regressions across deploys |
| sentry-source-maps | Detects missing Sentry source map upload — stack traces will be unreadable |
| yagni-ignore-hygiene | Validates that @yagni-ignore directives have valid detector slugs and reason comments |
| zod-openapi-sync | Ensures Zod schemas use .satisfies z.ZodType<> pattern |
Resilience (26)
| Slug | Description |
|---|---|
| batch-operation-limits | Detect batch operations that may process unbounded data |
| cache-ttl-validation | Validate cache TTL values for appropriate caching behavior |
| catch-clause-safety | Detects unsafe catch clause patterns: as Error casts without instanceof, catch(e: any) |
| dangerous-config-defaults | Detect dangerous default configurations |
| error-code-registration | Validates that error codes used in code are registered in an error registry file |
| event-architecture | Validate event handling follows architectural patterns |
| event-handler-idempotency | Validate event handlers implement idempotency |
| exit-code-correctness | Detect error branches that mask failures with silent success exit |
| graceful-shutdown | Validate services implement graceful shutdown handling |
| no-custom-cache | Enforce use of a shared cache abstraction instead of custom Map-based caches |
| no-custom-rate-limiter | Enforce use of a shared rate limiter instead of custom rate limiting implementations |
| no-hardcoded-timeouts | Detect hardcoded timeout values that should be configurable |
| no-process-exit-in-finally | Detect process.exit() that bypasses finally cleanup |
| rate-limiting-coverage | Validate API endpoints have rate limiting |
| readline-cleanup | Detect readline usage without proper cleanup (close/finally) |
| recovery-patterns | Enforce use of shared recovery/retry utilities instead of hand-rolled retry loops |
| reentrancy-guard | Detect boolean reentrancy guards that need counter/mutex semantics |
| retry-config-validation | Validate retry configs: flag excessive maxRetries (>10) and aggressive baseDelay (<100ms) |
| sentry-dsn-configured | Detects Sentry.init() without a DSN — monitoring silently disabled |
| sentry-environment-set | Detects Sentry.init() without environment — errors from all environments mixed |
| sentry-error-boundary | Detects React + Sentry without ErrorBoundary — render crashes go unreported |
| sentry-sample-rate | Detects missing or 1.0 tracesSampleRate — tracing disabled or too expensive |
| timer-lifecycle | Detects setInterval() calls without corresponding clearInterval() cleanup — prevents timer leaks |
| transaction-boundary-validation | Validate transaction boundaries are properly managed |
| transaction-timeout | Validate transactions have timeout configurations |
| unbounded-memory | Detect unbounded collections and file reads that may cause OOM |
Documentation (4)
| Slug | Description |
|---|---|
| directive-audit | Audit suppression directives for periodic review |
| eslint-justifications | Ensures all ESLint suppressions have proper justifications |
| no-markdown-references | Detect markdown file references in code comments that may become stale |
| public-api-jsdoc | Requires JSDoc documentation on all public API exports in shared packages |
Testing (4)
| Slug | Description |
|---|---|
| no-stub-tests | Detects stub tests with empty bodies, TODO-only bodies, or trivial always-passing assertions |
| test-convention-consistency | Detects mixed .test and .spec naming conventions across the codebase |
| test-file-naming | Validates test file naming conventions follow .test.ts or .spec.ts patterns |
| test-file-pairing | Ensures every source file has a corresponding test file |
TypeScript (56 checks)
TypeScript/JavaScript projects; uses TS-AST analysis.
Architecture (15)
| Slug | Description |
|---|---|
| architecture-no-run-done-result | Run commands render via the single RunPresentation variant; the contracts surface must not re-introduce a per-tool *DoneResult run type |
| callback-invocation-safe | Class-field callbacks invoked from producer code paths (subscribers.forEach, for-of over listeners, etc.) must be wrapped in a safe<Name>(...) helper or try/catch. A throw from one subscriber must not crash the producer or skip subsequent subscribers. |
| circular-import-detection | Detects file-level circular import dependencies |
| command-handler-host-owned-output | A tool command handler must let the host own rendering and exit — no direct stdout/console/process.exit inside a non-raw-stream defineCommand handler |
| contracts-schema-consistency | Validates that contracts use Zod schemas consistently: types derived from schemas via z.infer |
| drizzle-orm-migration-guardrails | Detects dangerous patterns in Drizzle ORM migrations (raw SQL, DROP, TRUNCATE, type changes) |
| host-tool-runtime-import-boundary | External tool runtimes never import in the host: importToolRuntime stays in the admission/discovery boundary, host imports are bundled-only, and the external worker policy is confined to the worker plane (ADR-0054 M4-G capstone) |
| live-view-through-cli-live | Tool engine live views route through cli-live (no direct ink render imports) |
| missing-type-exports | Detects types imported via deep internal paths not declared in the package exports map or barrel |
| module-coupling-fan-out | Flags files with high outbound import fan-out (god-files) |
| no-bootstrap-tool-import | The CLI host must not statically import a tool runtime — bundled tools load via the dynamic plugin path (§1 install-source independence) |
| package-json-exports-field | (no description; see source) |
| phantom-dependency-detection | Detect phantom dependencies (used but not declared in package.json) |
| subprocess-correlation-required | CLI subprocess spawn/fork sites must forward the RunCorrelation bag (runId via env, other fields via env+spec) so child failures are attributable |
| tsconfig-extends-validation | Ensures all tsconfig.json files extend a shared base and the base file exists |
Security (4)
| Slug | Description |
|---|---|
| input-sanitization | Detect unsanitized user input usage |
| pii-exposure-in-logs | Detects potential PII exposure in log statements |
| sql-injection | Detect potential SQL injection vulnerabilities |
| unsafe-secret-comparison | Detect timing-unsafe equality comparisons on secret/token values |
Quality (31)
| Slug | Description |
|---|---|
| a11y-form-labels | Verify form inputs have associated labels for accessibility |
| a11y-semantic-html | Detect View components with press handlers missing accessibilityRole |
| api-contract-validation | Validate API handlers have proper validation, typed responses, and error handling |
| api-response-validation | Ensure API responses are validated with Zod schemas |
| array-validation | Detect array parameters without proper validation |
| async-waterfall-detection | Detect sequential await statements that could be parallelized |
| database-index-coverage | Validate database queries have appropriate indexes |
| database-schema-validation | Validate database schema definitions follow best practices |
| dispose-pattern-completeness | Validate IDisposable implementations clean up all resources |
| duplicate-utility-functions | Detect duplicate and similar utility functions |
| error-handling-quality | Detect silent error handling in try/catch and Result patterns |
| fastify-route-validation | Ensure all Fastify POST/PATCH/PUT routes validate request bodies with Zod schemas |
| fastify-schema-coverage | Validate that Fastify routes have proper request/response schema validation |
| in-memory-repository-detection | Detect repository classes using Map or in-memory storage instead of proper persistence |
| incomplete-regex-escaping | Detect incomplete regex character escaping that can lead to security vulnerabilities |
| lifecycle-cleanup-enforcement | Detect resources with lifecycle methods (destroy/close/shutdown) created without cleanup |
| logger-event-name-format | Validate logger evt fields have 3+ dot-separated segments |
| missing-input-validation | Detect API handlers accepting external input without validation (Zod, Joi, etc.) |
| no-any-types | Detect usage of any type - use unknown with type narrowing instead |
| no-hardcoded-correlation-id | Detect hardcoded correlation ID string literals |
| null-safety | Detect unsafe property and method access without null checks |
| numeric-validation | Detect numeric parameters without NaN/Infinity/range validation |
| result-pattern-consistency | Ensures consistent use of Result<T,E> for expected failures and throw for unexpected failures |
| silent-early-returns | Detect single-line early returns without logging |
| stream-buffer-size-limits | Detects Buffer.concat() and stream buffering without size limit guards |
| stubbed-implementation-detection | Detects incomplete/placeholder implementations |
| test-only-frontend-modules | Detects frontend code only imported by test files |
| throws-documentation | Detects functions with throw statements but no @throws JSDoc |
| toctou-race-condition | Detects read-then-update patterns without atomic guarantees |
| typescript-frontend | Validates TypeScript compilation for frontend apps |
| unused-config-options | Detects configuration properties defined but never accessed |
Resilience (5)
| Slug | Description |
|---|---|
| context-leakage | Detect potential request context leakage |
| context-mutation | Detect unsafe mutations of request/execution context |
| detached-promises | Detect promises that may not be awaited (potential silent failures) |
| no-raw-fetch | Detect direct fetch() calls that should use wrapped HTTP clients |
| no-unbounded-concurrency | Detect Promise.all with unbounded concurrency |
Testing (1)
| Slug | Description |
|---|---|
| mock-implementations-in-production | Detects mock, stub, or fake implementations in production code |
Python (2 checks)
Python projects.
Quality (2)
| Slug | Description |
|---|---|
| python-function-too-long | Python functions should stay under a line budget for readability and testability |
| python-no-bare-except | Bare except clauses catch system-exiting exceptions like KeyboardInterrupt |
Go (1 check)
Go projects.
Quality (1)
| Slug | Description |
|---|---|
| go-no-fmt-print | (no description; see source) |
Java (1 check)
Java projects.
Quality (1)
| Slug | Description |
|---|---|
| java-no-print-stack-trace | e.printStackTrace() bypasses the logging framework — use a logger instead |
C / C++ (1 check)
C/C++ projects.
Quality (1)
| Slug | Description |
|---|---|
| cpp-clang-tidy | Run clang-tidy and surface its diagnostics as opensip-cli violations |
Rust (1 check)
Rust projects.
Quality (1)
| Slug | Description |
|---|---|
| rust-no-dbg-macro | (no description; see source) |
How to use a check
Every check above is loaded automatically when its pack is in your project's node_modules/. To target one explicitly:
opensip fit --check <slug> # run one check
opensip fit --tags security # run all checks tagged security
opensip fit --recipe quick-smoke # run a named lineup
Per-check parameter overrides go in your recipe under config: — see recipes and checks.
To write your own check, see plugin authoring.