{
  "schemaVersion": 1,
  "generatedAt": "2026-09-24T15:55:49.921Z",
  "site": "https://noctcore.github.io/eslint-plugins/",
  "rulesPage": "https://noctcore.github.io/eslint-plugins/rules/",
  "count": 113,
  "packages": [
    {
      "name": "@noctcore/eslint-plugin-react",
      "short": "react",
      "version": "0.4.2",
      "description": "React architecture and correctness ESLint rules: prop drilling, state colocation, memoized context, effect safety and guarded web storage.",
      "kind": "eslint-plugin",
      "namespace": "noctcore-react",
      "url": "https://noctcore.github.io/eslint-plugins/packages/react/"
    },
    {
      "name": "@noctcore/eslint-plugin-architecture",
      "short": "architecture",
      "version": "0.3.4",
      "description": "Framework-agnostic ESLint rules for module and folder shape: folder-per-component, barrels, feature boundaries, import depth and colocated tests.",
      "kind": "eslint-plugin",
      "namespace": "noctcore-architecture",
      "url": "https://noctcore.github.io/eslint-plugins/packages/architecture/"
    },
    {
      "name": "@noctcore/eslint-plugin-monorepo",
      "short": "monorepo",
      "version": "0.2.4",
      "description": "ESLint rules for enforcing workspace / monorepo package boundaries.",
      "kind": "eslint-plugin",
      "namespace": "noctcore-monorepo",
      "url": "https://noctcore.github.io/eslint-plugins/packages/monorepo/"
    },
    {
      "name": "@noctcore/eslint-plugin-contracts",
      "short": "contracts",
      "version": "0.7.2",
      "description": "ESLint rules for IO contracts and config: checked fetch responses, parsed boundary data, error cause and taxonomy, zod schema and wire naming, env access, decimal money and translation keys.",
      "kind": "eslint-plugin",
      "namespace": "noctcore-contracts",
      "url": "https://noctcore.github.io/eslint-plugins/packages/contracts/"
    },
    {
      "name": "@noctcore/eslint-plugin-code-quality",
      "short": "code-quality",
      "version": "0.3.2",
      "description": "Portable code-quality, comment-hygiene and test-discipline ESLint rules: guard clauses, deterministic time, no stray process.exit, and tests that cannot pass vacuously.",
      "kind": "eslint-plugin",
      "namespace": "noctcore-code-quality",
      "url": "https://noctcore.github.io/eslint-plugins/packages/code-quality/"
    },
    {
      "name": "@noctcore/eslint-plugin-async-safety",
      "short": "async-safety",
      "version": "0.4.2",
      "description": "ESLint rules for async correctness: fetch timeouts, AbortSignal forwarding, and shared-state / concurrency races.",
      "kind": "eslint-plugin",
      "namespace": "noctcore-async-safety",
      "url": "https://noctcore.github.io/eslint-plugins/packages/async-safety/"
    },
    {
      "name": "@noctcore/eslint-plugin-observability",
      "short": "observability",
      "version": "0.3.4",
      "description": "Structured-logging ESLint rules: context objects over interpolated messages, no sensitive fields in logs, no lost error detail, and declared PII in audit payloads.",
      "kind": "eslint-plugin",
      "namespace": "noctcore-observability",
      "url": "https://noctcore.github.io/eslint-plugins/packages/observability/"
    },
    {
      "name": "@noctcore/eslint-plugin-security",
      "short": "security",
      "version": "0.4.2",
      "description": "Security ESLint rules: shell injection, path traversal, SSRF, open redirects, unsanitized HTML (XSS), timing-unsafe comparisons and server actions that bypass their action client.",
      "kind": "eslint-plugin",
      "namespace": "noctcore-security",
      "url": "https://noctcore.github.io/eslint-plugins/packages/security/"
    },
    {
      "name": "@noctcore/eslint-plugin-prisma",
      "short": "prisma",
      "version": "0.5.2",
      "description": "Prisma tenancy, data-integrity and transaction guardrails: unscoped-client and raw-SQL fences, client-supplied tenant ids and request bodies, tenant and soft-delete filters, single-writer models, multi-write transactions and audit placement.",
      "kind": "eslint-plugin",
      "namespace": "noctcore-prisma",
      "url": "https://noctcore.github.io/eslint-plugins/packages/prisma/"
    },
    {
      "name": "@noctcore/eslint-plugin-rsc",
      "short": "rsc",
      "version": "0.1.2",
      "description": "React Server Components and App Router correctness rules: control-flow errors that must not be swallowed.",
      "kind": "eslint-plugin",
      "namespace": "noctcore-rsc",
      "url": "https://noctcore.github.io/eslint-plugins/packages/rsc/"
    },
    {
      "name": "@noctcore/eslint-plugin-llm",
      "short": "llm",
      "version": "0.1.2",
      "description": "ESLint rules for code that calls LLM SDKs: model output treated as untrusted input before it reaches a dangerous sink.",
      "kind": "eslint-plugin",
      "namespace": "noctcore-llm",
      "url": "https://noctcore.github.io/eslint-plugins/packages/llm/"
    },
    {
      "name": "@noctcore/lint-meta-rules",
      "short": "lint-meta-rules",
      "version": "0.6.2",
      "description": "Portable, parameterized lint-meta rules — whole-repo / cross-file invariants ESLint cannot reach — for the @noctcore/harness lint-meta runner.",
      "kind": "lint-meta",
      "namespace": null,
      "url": "https://noctcore.github.io/eslint-plugins/packages/lint-meta-rules/"
    }
  ],
  "rules": [
    {
      "id": "noctcore-react/component-props-naming",
      "name": "component-props-naming",
      "package": "@noctcore/eslint-plugin-react",
      "runner": "eslint",
      "description": "A function component's first-param props type must be named `<Component>Props`. Autofixes by renaming the in-file type declaration and its references when that is safe.",
      "url": "https://noctcore.github.io/eslint-plugins/rules/react/component-props-naming/",
      "recommended": "error",
      "fixable": true,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null
    },
    {
      "id": "noctcore-react/context-value-must-be-memoized",
      "name": "context-value-must-be-memoized",
      "package": "@noctcore/eslint-plugin-react",
      "runner": "eslint",
      "description": "A context Provider `value` must not be an inline object literal — a fresh reference each render re-renders every consumer. Memoize it with `useMemo` and pass the stable reference.",
      "url": "https://noctcore.github.io/eslint-plugins/rules/react/context-value-must-be-memoized/",
      "recommended": "error",
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null
    },
    {
      "id": "noctcore-react/max-hook-return-surface",
      "name": "max-hook-return-surface",
      "package": "@noctcore/eslint-plugin-react",
      "runner": "eslint",
      "description": "An exported `use*` hook in a hook file may return object literals (top-level or nested one level) of at most `max` (default 20) members. Wider returns are god-controllers in the making.",
      "url": "https://noctcore.github.io/eslint-plugins/rules/react/max-hook-return-surface/",
      "recommended": "error",
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null
    },
    {
      "id": "noctcore-react/max-hooks-per-file",
      "name": "max-hooks-per-file",
      "package": "@noctcore/eslint-plugin-react",
      "runner": "eslint",
      "description": "A hook/query/mutation file (default `*.hooks.ts` / `*.queries.ts` / `*.mutations.ts`) may export at most `max` (default 4) `use*` hooks. Split larger files.",
      "url": "https://noctcore.github.io/eslint-plugins/rules/react/max-hooks-per-file/",
      "recommended": "error",
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null
    },
    {
      "id": "noctcore-react/max-props-per-component",
      "name": "max-props-per-component",
      "package": "@noctcore/eslint-plugin-react",
      "runner": "eslint",
      "description": "A `*Props` interface/type-literal may declare at most `max` (default 12) local members. `extends` clauses are not counted.",
      "url": "https://noctcore.github.io/eslint-plugins/rules/react/max-props-per-component/",
      "recommended": "error",
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null
    },
    {
      "id": "noctcore-react/no-effect-derived-state",
      "name": "no-effect-derived-state",
      "package": "@noctcore/eslint-plugin-react",
      "runner": "eslint",
      "description": "An effect whose entire body is `setState` calls with values derived purely from its dependencies is the \"you might not need an effect\" anti-pattern — compute the value during render (or with `useMemo`) instead.",
      "url": "https://noctcore.github.io/eslint-plugins/rules/react/no-effect-derived-state/",
      "recommended": "error",
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null
    },
    {
      "id": "noctcore-react/no-jsx-computation",
      "name": "no-jsx-computation",
      "package": "@noctcore/eslint-plugin-react",
      "runner": "eslint",
      "description": "Disallow array methods, arithmetic, and chained logical expressions directly inside JSX `{...}`. Lift them to a const above the return or into the hook.",
      "url": "https://noctcore.github.io/eslint-plugins/rules/react/no-jsx-computation/",
      "recommended": "error",
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null
    },
    {
      "id": "noctcore-react/no-jsx-in-hooks",
      "name": "no-jsx-in-hooks",
      "package": "@noctcore/eslint-plugin-react",
      "runner": "eslint",
      "description": "A `use*`-named function must not return JSX — that is a component wearing a hook costume. Rename it to a PascalCase component, or return values instead of elements.",
      "url": "https://noctcore.github.io/eslint-plugins/rules/react/no-jsx-in-hooks/",
      "recommended": "error",
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null
    },
    {
      "id": "noctcore-react/no-prop-drilling",
      "name": "no-prop-drilling",
      "package": "@noctcore/eslint-plugin-react",
      "runner": "eslint",
      "description": "A bundle of `maxForwarded`+ (default 4) props each forwarded unchanged (`name={name}`) from the `*Props` param to the same child component is prop drilling. Compose instead.",
      "url": "https://noctcore.github.io/eslint-plugins/rules/react/no-prop-drilling/",
      "recommended": "error",
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null
    },
    {
      "id": "noctcore-react/no-state-in-component-body",
      "name": "no-state-in-component-body",
      "package": "@noctcore/eslint-plugin-react",
      "runner": "eslint",
      "description": "State/effect/query hooks must live in the colocated hook file (`<Name>.hooks.ts`), not in the component `.tsx` body. The component is a thin shell.",
      "url": "https://noctcore.github.io/eslint-plugins/rules/react/no-state-in-component-body/",
      "recommended": "error",
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null
    },
    {
      "id": "noctcore-react/no-unguarded-web-storage",
      "name": "no-unguarded-web-storage",
      "package": "@noctcore/eslint-plugin-react",
      "runner": "eslint",
      "description": "A `localStorage` / `sessionStorage` call must sit inside a `try` block: the access itself throws when storage is disabled, partitioned or full.",
      "url": "https://noctcore.github.io/eslint-plugins/rules/react/no-unguarded-web-storage/",
      "recommended": "error",
      "fixable": false,
      "hasSuggestions": true,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null
    },
    {
      "id": "noctcore-react/prefer-lazy-state-init",
      "name": "prefer-lazy-state-init",
      "package": "@noctcore/eslint-plugin-react",
      "runner": "eslint",
      "description": "A `useState` initializer that is an expensive call (default `JSON.parse` / `localStorage.getItem` / `sessionStorage.getItem`, or a configured builder) must be wrapped in a function so it runs once on mount, not every render.",
      "url": "https://noctcore.github.io/eslint-plugins/rules/react/prefer-lazy-state-init/",
      "recommended": "error",
      "fixable": true,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null
    },
    {
      "id": "noctcore-react/props-must-be-visual",
      "name": "props-must-be-visual",
      "package": "@noctcore/eslint-plugin-react",
      "runner": "eslint",
      "description": "Component props must be visual. Auth/business-identity and credential prop names (`userId`, `currentUser`, `*token*`, `*jwt*`, `*secret*`, `apiKey`, ...) are disallowed. A live `password` input is a legitimate visual concern and is intentionally allowed.",
      "url": "https://noctcore.github.io/eslint-plugins/rules/react/props-must-be-visual/",
      "recommended": "error",
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null
    },
    {
      "id": "noctcore-react/require-effect-cancellation",
      "name": "require-effect-cancellation",
      "package": "@noctcore/eslint-plugin-react",
      "runner": "eslint",
      "description": "A `setState`/`dispatch` that runs after an `await` or `.then()` inside a `useEffect` must be guarded against a unmounted/re-run effect (AbortController, a cancelled flag, or a cleanup return).",
      "url": "https://noctcore.github.io/eslint-plugins/rules/react/require-effect-cancellation/",
      "recommended": "error",
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null
    },
    {
      "id": "noctcore-architecture/barrel-purity",
      "name": "barrel-purity",
      "package": "@noctcore/eslint-plugin-architecture",
      "runner": "eslint",
      "description": "A barrel (`index.ts` / `index.tsx`) must contain only re-exports — never local declarations, side effects, or default-exported values.",
      "url": "https://noctcore.github.io/eslint-plugins/rules/architecture/barrel-purity/",
      "recommended": "error",
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null
    },
    {
      "id": "noctcore-architecture/colocated-test-required",
      "name": "colocated-test-required",
      "package": "@noctcore/eslint-plugin-architecture",
      "runner": "eslint",
      "description": "A source file matching an `include` glob must have a colocated `*.test.*` / `*.spec.*` sibling on disk.",
      "url": "https://noctcore.github.io/eslint-plugins/rules/architecture/colocated-test-required/",
      "recommended": "off",
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null
    },
    {
      "id": "noctcore-architecture/component-folder-structure",
      "name": "component-folder-structure",
      "package": "@noctcore/eslint-plugin-architecture",
      "runner": "eslint",
      "description": "A component `<Name>/<Name>.tsx` under `<componentRoot>/<feature>/...` must have its sibling set (`.hooks.ts`, `.types.ts`, `.stories.tsx`, `.test.tsx`, `index.ts`) present on disk.",
      "url": "https://noctcore.github.io/eslint-plugins/rules/architecture/component-folder-structure/",
      "recommended": "error",
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null
    },
    {
      "id": "noctcore-architecture/filename-matches-export",
      "name": "filename-matches-export",
      "package": "@noctcore/eslint-plugin-architecture",
      "runner": "eslint",
      "description": "A file's basename must match its primary export (a default export, or the sole named export).",
      "url": "https://noctcore.github.io/eslint-plugins/rules/architecture/filename-matches-export/",
      "recommended": "error",
      "fixable": false,
      "hasSuggestions": true,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null
    },
    {
      "id": "noctcore-architecture/index-must-reexport-default",
      "name": "index-must-reexport-default",
      "package": "@noctcore/eslint-plugin-architecture",
      "runner": "eslint",
      "description": "A component folder's `index.ts` must re-export the component default (`export { default as <Name> } from './<Name>'`).",
      "url": "https://noctcore.github.io/eslint-plugins/rules/architecture/index-must-reexport-default/",
      "recommended": "error",
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null
    },
    {
      "id": "noctcore-architecture/max-import-depth",
      "name": "max-import-depth",
      "package": "@noctcore/eslint-plugin-architecture",
      "runner": "eslint",
      "description": "A relative import may not climb more than `max` parent levels (default 3). Autofixed to a path alias when one is configured.",
      "url": "https://noctcore.github.io/eslint-plugins/rules/architecture/max-import-depth/",
      "recommended": "error",
      "fixable": true,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null
    },
    {
      "id": "noctcore-architecture/no-cross-feature-imports",
      "name": "no-cross-feature-imports",
      "package": "@noctcore/eslint-plugin-architecture",
      "runner": "eslint",
      "description": "A file in one feature may not import runtime code from another feature. Move shared code to a shared module or a shared feature.",
      "url": "https://noctcore.github.io/eslint-plugins/rules/architecture/no-cross-feature-imports/",
      "recommended": "error",
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null
    },
    {
      "id": "noctcore-architecture/single-semantic-module",
      "name": "single-semantic-module",
      "package": "@noctcore/eslint-plugin-architecture",
      "runner": "eslint",
      "description": "Require each module to export only one semantic concern (types, constants, functions, classes, components, hooks, schemas or enums).",
      "url": "https://noctcore.github.io/eslint-plugins/rules/architecture/single-semantic-module/",
      "recommended": "off",
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null
    },
    {
      "id": "noctcore-monorepo/no-deep-package-imports",
      "name": "no-deep-package-imports",
      "package": "@noctcore/eslint-plugin-monorepo",
      "runner": "eslint",
      "description": "Workspace packages in the configured `scopes` must be consumed through their package barrel only — never via a deep subpath into package internals.",
      "url": "https://noctcore.github.io/eslint-plugins/rules/monorepo/no-deep-package-imports/",
      "recommended": "off",
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null
    },
    {
      "id": "noctcore-monorepo/no-unexported-subpath-import",
      "name": "no-unexported-subpath-import",
      "package": "@noctcore/eslint-plugin-monorepo",
      "runner": "eslint",
      "description": "Importing a `@scope/pkg/<subpath>` that the target workspace package's `exports` map does not expose. Reads the target `package.json` from disk.",
      "url": "https://noctcore.github.io/eslint-plugins/rules/monorepo/no-unexported-subpath-import/",
      "recommended": "off",
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null
    },
    {
      "id": "noctcore-contracts/env-var-schema-parity",
      "name": "env-var-schema-parity",
      "package": "@noctcore/eslint-plugin-contracts",
      "runner": "eslint",
      "description": "Require every `process.env.FOO` / `import.meta.env.FOO` key to be declared in a schema file (`.env.example` or a zod-env module), so config access and config declaration cannot drift apart.",
      "url": "https://noctcore.github.io/eslint-plugins/rules/contracts/env-var-schema-parity/",
      "recommended": "off",
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null
    },
    {
      "id": "noctcore-contracts/fetch-must-check-ok",
      "name": "fetch-must-check-ok",
      "package": "@noctcore/eslint-plugin-contracts",
      "runner": "eslint",
      "description": "Require a fetch response to be checked with `.ok` or a status comparison before `.json()` parses its body.",
      "url": "https://noctcore.github.io/eslint-plugins/rules/contracts/fetch-must-check-ok/",
      "recommended": "error",
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null
    },
    {
      "id": "noctcore-contracts/money-must-be-decimal",
      "name": "money-must-be-decimal",
      "package": "@noctcore/eslint-plugin-contracts",
      "runner": "eslint",
      "description": "Disallow monetary values typed as the JS primitive `number`. Money-named fields explicitly typed `: number` lose precision to float rounding; use a Decimal money type instead.",
      "url": "https://noctcore.github.io/eslint-plugins/rules/contracts/money-must-be-decimal/",
      "recommended": "error",
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null
    },
    {
      "id": "noctcore-contracts/no-direct-process-env",
      "name": "no-direct-process-env",
      "package": "@noctcore/eslint-plugin-contracts",
      "runner": "eslint",
      "description": "Disallow direct `process.env` access. Force every consumer through a typed, validated config accessor so a missing variable fails at boot, not at use.",
      "url": "https://noctcore.github.io/eslint-plugins/rules/contracts/no-direct-process-env/",
      "recommended": "error",
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null
    },
    {
      "id": "noctcore-contracts/no-error-stringify",
      "name": "no-error-stringify",
      "package": "@noctcore/eslint-plugin-contracts",
      "runner": "eslint",
      "description": "Disallow stringifying an error with bare `${error}` interpolation, `error.toString()`, or `error + \"\"`. These drop the cause chain. Use `error instanceof Error ? error.message : String(error)` instead.",
      "url": "https://noctcore.github.io/eslint-plugins/rules/contracts/no-error-stringify/",
      "recommended": "error",
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null
    },
    {
      "id": "noctcore-contracts/require-error-cause",
      "name": "require-error-cause",
      "package": "@noctcore/eslint-plugin-contracts",
      "runner": "eslint",
      "description": "Require re-thrown errors inside a `catch` to forward the caught error as `{ cause }`. A `throw new SomeError(...)` that omits the cause severs the chain to the original failure.",
      "url": "https://noctcore.github.io/eslint-plugins/rules/contracts/require-error-cause/",
      "recommended": "error",
      "fixable": true,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null
    },
    {
      "id": "noctcore-contracts/require-registered-keys",
      "name": "require-registered-keys",
      "package": "@noctcore/eslint-plugin-contracts",
      "runner": "eslint",
      "description": "Require the key/name argument of configured sink APIs (storage, event channels, cache keys) to be an imported constant from a registry module, not a raw string literal.",
      "url": "https://noctcore.github.io/eslint-plugins/rules/contracts/require-registered-keys/",
      "recommended": "off",
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null
    },
    {
      "id": "noctcore-contracts/require-schema-parse-at-boundary",
      "name": "require-schema-parse-at-boundary",
      "package": "@noctcore/eslint-plugin-contracts",
      "runner": "eslint",
      "description": "Disallow asserting external boundary data with `as T` instead of parsing it at runtime. Flags casts of `JSON.parse`, `res.json()`, web storage, URL search params, message-event data and LLM tool input, directly or through a `const`; use a zod/valibot parse.",
      "url": "https://noctcore.github.io/eslint-plugins/rules/contracts/require-schema-parse-at-boundary/",
      "recommended": "off",
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null
    },
    {
      "id": "noctcore-contracts/restrict-throw-to-taxonomy",
      "name": "restrict-throw-to-taxonomy",
      "package": "@noctcore/eslint-plugin-contracts",
      "runner": "eslint",
      "description": "Restrict `throw` to an approved error taxonomy. Flags throwing a non-allowlisted error class and throwing a non-Error value (string, object, number, ...).",
      "url": "https://noctcore.github.io/eslint-plugins/rules/contracts/restrict-throw-to-taxonomy/",
      "recommended": "error",
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null
    },
    {
      "id": "noctcore-contracts/schema-enum-field-consistency",
      "name": "schema-enum-field-consistency",
      "package": "@noctcore/eslint-plugin-contracts",
      "runner": "eslint",
      "description": "Disallow a zod field that is an enum in one object schema of a module from being `z.string()` in another, which widens the wire type every consumer then narrows by hand.",
      "url": "https://noctcore.github.io/eslint-plugins/rules/contracts/schema-enum-field-consistency/",
      "recommended": "error",
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null
    },
    {
      "id": "noctcore-contracts/translation-key-exists",
      "name": "translation-key-exists",
      "package": "@noctcore/eslint-plugin-contracts",
      "runner": "eslint",
      "description": "Require every static i18next / react-i18next translation key (`t(...)`, `i18n.t(...)`, `<Trans i18nKey>`) to exist in the catalog of the namespace in scope.",
      "url": "https://noctcore.github.io/eslint-plugins/rules/contracts/translation-key-exists/",
      "recommended": "off",
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "optional",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null
    },
    {
      "id": "noctcore-contracts/wire-message-naming",
      "name": "wire-message-naming",
      "package": "@noctcore/eslint-plugin-contracts",
      "runner": "eslint",
      "description": "A message-schema const ending in a role suffix (default Event/Command/Query) whose zod object declares `type: z.literal(...)` must set that literal to kebab-case(const name minus its role suffix).",
      "url": "https://noctcore.github.io/eslint-plugins/rules/contracts/wire-message-naming/",
      "recommended": "error",
      "fixable": true,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null
    },
    {
      "id": "noctcore-contracts/zod-schema-naming",
      "name": "zod-schema-naming",
      "package": "@noctcore/eslint-plugin-contracts",
      "runner": "eslint",
      "description": "Every exported zod schema is a PascalCase const suffixed `Schema`, paired with a same-named inferred type (`export type Foo = z.infer<typeof FooSchema>`).",
      "url": "https://noctcore.github.io/eslint-plugins/rules/contracts/zod-schema-naming/",
      "recommended": "error",
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null
    },
    {
      "id": "noctcore-code-quality/fake-timers-must-be-restored",
      "name": "fake-timers-must-be-restored",
      "package": "@noctcore/eslint-plugin-code-quality",
      "runner": "eslint",
      "description": "A test file that calls `useFakeTimers()` must also call `useRealTimers()`, so fake timers do not leak into later tests.",
      "url": "https://noctcore.github.io/eslint-plugins/rules/code-quality/fake-timers-must-be-restored/",
      "recommended": "error",
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null
    },
    {
      "id": "noctcore-code-quality/interface-prefix-i",
      "name": "interface-prefix-i",
      "package": "@noctcore/eslint-plugin-code-quality",
      "runner": "eslint",
      "description": "Interface names must be prefixed with `I` followed by an uppercase letter. Module/global augmentations are exempt.",
      "url": "https://noctcore.github.io/eslint-plugins/rules/code-quality/interface-prefix-i/",
      "recommended": null,
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null
    },
    {
      "id": "noctcore-code-quality/no-bare-date-now",
      "name": "no-bare-date-now",
      "package": "@noctcore/eslint-plugin-code-quality",
      "runner": "eslint",
      "description": "Disallow bare `Date.now()` / `new Date()` in business logic. Read wall-clock time through a shared `clock` util (`nowMs()` / `now()`) so time is mockable.",
      "url": "https://noctcore.github.io/eslint-plugins/rules/code-quality/no-bare-date-now/",
      "recommended": "error",
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null
    },
    {
      "id": "noctcore-code-quality/no-conditional-expect",
      "name": "no-conditional-expect",
      "package": "@noctcore/eslint-plugin-code-quality",
      "runner": "eslint",
      "description": "Disallow `expect()` inside a branch, `catch` or loop that may not run: a skipped assertion lets a broken test pass.",
      "url": "https://noctcore.github.io/eslint-plugins/rules/code-quality/no-conditional-expect/",
      "recommended": "error",
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null
    },
    {
      "id": "noctcore-code-quality/no-elided-code-comments",
      "name": "no-elided-code-comments",
      "package": "@noctcore/eslint-plugin-code-quality",
      "runner": "eslint",
      "description": "Disallow comments that stand in for elided code ('// ... existing code ...', '// rest of the function unchanged', '// your code here'). They are what an agent leaves when it rewrites a file from an abbreviated draft, and the code they replaced has usually been deleted.",
      "url": "https://noctcore.github.io/eslint-plugins/rules/code-quality/no-elided-code-comments/",
      "recommended": "error",
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null
    },
    {
      "id": "noctcore-code-quality/no-focused-tests",
      "name": "no-focused-tests",
      "package": "@noctcore/eslint-plugin-code-quality",
      "runner": "eslint",
      "description": "Ban focused tests (it.only / describe.only / test.only, fdescribe / fit / ddescribe) so a focused test never silently lands in CI.",
      "url": "https://noctcore.github.io/eslint-plugins/rules/code-quality/no-focused-tests/",
      "recommended": "error",
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null
    },
    {
      "id": "noctcore-code-quality/no-historical-comments",
      "name": "no-historical-comments",
      "package": "@noctcore/eslint-plugin-code-quality",
      "runner": "eslint",
      "description": "Disallow comments that frame code relative to what it used to do or to a past incident ('before the fix', 'after the refactor', 'we used to', 'no longer'). Source comments describe the current invariant; history belongs in the commit message or PR description, where it does not rot when the code changes again.",
      "url": "https://noctcore.github.io/eslint-plugins/rules/code-quality/no-historical-comments/",
      "recommended": "error",
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null
    },
    {
      "id": "noctcore-code-quality/no-narration-comments",
      "name": "no-narration-comments",
      "package": "@noctcore/eslint-plugin-code-quality",
      "runner": "eslint",
      "description": "Disallow narrative comments like 'Here we...', 'Now we...', 'First, we...'. These read as step-by-step prose and add no information a future reader cannot get from the code itself. Often a tell that the comment was generated by an agent describing its own changes.",
      "url": "https://noctcore.github.io/eslint-plugins/rules/code-quality/no-narration-comments/",
      "recommended": "error",
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null
    },
    {
      "id": "noctcore-code-quality/no-pr-reference-comments",
      "name": "no-pr-reference-comments",
      "package": "@noctcore/eslint-plugin-code-quality",
      "runner": "eslint",
      "description": "Disallow PR/issue references in comments. They belong in commit messages and PR descriptions, where they do not rot when the repo moves, the issue tracker migrates, or the numbering changes.",
      "url": "https://noctcore.github.io/eslint-plugins/rules/code-quality/no-pr-reference-comments/",
      "recommended": "error",
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null
    },
    {
      "id": "noctcore-code-quality/no-process-exit",
      "name": "no-process-exit",
      "package": "@noctcore/eslint-plugin-code-quality",
      "runner": "eslint",
      "description": "Disallow `process.exit()` outside bootstrap/shutdown paths and standalone CLIs. Application and service code must throw or reject so the lifecycle can shut down gracefully.",
      "url": "https://noctcore.github.io/eslint-plugins/rules/code-quality/no-process-exit/",
      "recommended": "error",
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null
    },
    {
      "id": "noctcore-code-quality/no-real-network-in-unit-tests",
      "name": "no-real-network-in-unit-tests",
      "package": "@noctcore/eslint-plugin-code-quality",
      "runner": "eslint",
      "description": "Unit tests must not perform real network I/O: mock the HTTP client, or move the test to an integration suite.",
      "url": "https://noctcore.github.io/eslint-plugins/rules/code-quality/no-real-network-in-unit-tests/",
      "recommended": "error",
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null
    },
    {
      "id": "noctcore-code-quality/no-swallowed-assertion",
      "name": "no-swallowed-assertion",
      "package": "@noctcore/eslint-plugin-code-quality",
      "runner": "eslint",
      "description": "Disallow assertions inside a `try` whose `catch` neither rethrows nor asserts, and `.catch()` handlers that swallow an `expect(...).rejects`/`.resolves` failure: the assertion fails, the error is dropped, and the test passes.",
      "url": "https://noctcore.github.io/eslint-plugins/rules/code-quality/no-swallowed-assertion/",
      "recommended": "error",
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null
    },
    {
      "id": "noctcore-code-quality/no-template-trim-empty-ternary",
      "name": "no-template-trim-empty-ternary",
      "package": "@noctcore/eslint-plugin-code-quality",
      "runner": "eslint",
      "description": "Disallow inline `<template>.trim() === '' ? fallback : <template>.trim()` patterns. Extract to a named utility so the expression is built once and is unit-testable in one place.",
      "url": "https://noctcore.github.io/eslint-plugins/rules/code-quality/no-template-trim-empty-ternary/",
      "recommended": null,
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null
    },
    {
      "id": "noctcore-code-quality/no-vacuous-expect",
      "name": "no-vacuous-expect",
      "package": "@noctcore/eslint-plugin-code-quality",
      "runner": "eslint",
      "description": "Disallow vacuous expects (`typeof` checks, literal tautologies, a sole `toBeDefined`/`toBeTruthy`): a test must assert behaviour that a real regression would break.",
      "url": "https://noctcore.github.io/eslint-plugins/rules/code-quality/no-vacuous-expect/",
      "recommended": "error",
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null
    },
    {
      "id": "noctcore-code-quality/prefer-early-return",
      "name": "prefer-early-return",
      "package": "@noctcore/eslint-plugin-code-quality",
      "runner": "eslint",
      "description": "Prefer guard clauses (early return) over wrapping the whole function body in a multi-statement `if` without an `else`.",
      "url": "https://noctcore.github.io/eslint-plugins/rules/code-quality/prefer-early-return/",
      "recommended": "error",
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null
    },
    {
      "id": "noctcore-code-quality/skipped-tests-need-tracking",
      "name": "skipped-tests-need-tracking",
      "package": "@noctcore/eslint-plugin-code-quality",
      "runner": "eslint",
      "description": "Skipped tests (`.skip` / `.fixme` / `xit` / `xdescribe`) must carry a tracking marker (an issue URL or `TODO(@owner)`) on or above the line, so the debt has an owner instead of rotting silently.",
      "url": "https://noctcore.github.io/eslint-plugins/rules/code-quality/skipped-tests-need-tracking/",
      "recommended": "error",
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null
    },
    {
      "id": "noctcore-async-safety/forward-abort-signal",
      "name": "forward-abort-signal",
      "package": "@noctcore/eslint-plugin-async-safety",
      "runner": "eslint",
      "description": "A function that accepts an `AbortSignal` (param named `signal` or typed `AbortSignal`) but awaits a call without ever forwarding it leaves that work uncancellable.",
      "url": "https://noctcore.github.io/eslint-plugins/rules/async-safety/forward-abort-signal/",
      "recommended": "error",
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null
    },
    {
      "id": "noctcore-async-safety/no-concurrent-shared-mutation",
      "name": "no-concurrent-shared-mutation",
      "package": "@noctcore/eslint-plugin-async-safety",
      "runner": "eslint",
      "description": "A read-modify-write of an outer-scope binding inside a concurrent `Promise.all(arr.map(async …))` callback can lose updates.",
      "url": "https://noctcore.github.io/eslint-plugins/rules/async-safety/no-concurrent-shared-mutation/",
      "recommended": "error",
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null
    },
    {
      "id": "noctcore-async-safety/no-leaky-race-timeout",
      "name": "no-leaky-race-timeout",
      "package": "@noctcore/eslint-plugin-async-safety",
      "runner": "eslint",
      "description": "A `setTimeout` timeout raced with `Promise.race` must be cleared — otherwise the timer outlives the race whenever the other promise wins.",
      "url": "https://noctcore.github.io/eslint-plugins/rules/async-safety/no-leaky-race-timeout/",
      "recommended": "error",
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null
    },
    {
      "id": "noctcore-async-safety/no-shared-mutable-module-state",
      "name": "no-shared-mutable-module-state",
      "package": "@noctcore/eslint-plugin-async-safety",
      "runner": "eslint",
      "description": "A module-scoped mutable binding written inside an exported async/handler function is shared across concurrent requests. Opt in per file via `include`.",
      "url": "https://noctcore.github.io/eslint-plugins/rules/async-safety/no-shared-mutable-module-state/",
      "recommended": "error",
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null
    },
    {
      "id": "noctcore-async-safety/prefer-parallel-awaits",
      "name": "prefer-parallel-awaits",
      "package": "@noctcore/eslint-plugin-async-safety",
      "runner": "eslint",
      "description": "Consecutive independent `const x = await read()` statements can run concurrently via `await Promise.all([...])`.",
      "url": "https://noctcore.github.io/eslint-plugins/rules/async-safety/prefer-parallel-awaits/",
      "recommended": "off",
      "fixable": false,
      "hasSuggestions": true,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null
    },
    {
      "id": "noctcore-async-safety/require-client-timeout",
      "name": "require-client-timeout",
      "package": "@noctcore/eslint-plugin-async-safety",
      "runner": "eslint",
      "description": "A configured network client must be constructed with a timeout option; an unbounded client can hang forever.",
      "url": "https://noctcore.github.io/eslint-plugins/rules/async-safety/require-client-timeout/",
      "recommended": "error",
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null
    },
    {
      "id": "noctcore-async-safety/require-fetch-timeout",
      "name": "require-fetch-timeout",
      "package": "@noctcore/eslint-plugin-async-safety",
      "runner": "eslint",
      "description": "A `fetch` (or configured wrapper) call must carry a `signal`/`timeout` in its options — an unbounded request can hang forever.",
      "url": "https://noctcore.github.io/eslint-plugins/rules/async-safety/require-fetch-timeout/",
      "recommended": "error",
      "fixable": false,
      "hasSuggestions": true,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null
    },
    {
      "id": "noctcore-observability/audit-pii-declared",
      "name": "audit-pii-declared",
      "package": "@noctcore/eslint-plugin-observability",
      "runner": "eslint",
      "description": "A PII-shaped key written into an audit payload must be declared, either registered for scrubbing on purge or declared non-PII.",
      "url": "https://noctcore.github.io/eslint-plugins/rules/observability/audit-pii-declared/",
      "recommended": "error",
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null
    },
    {
      "id": "noctcore-observability/no-error-detail-loss",
      "name": "no-error-detail-loss",
      "package": "@noctcore/eslint-plugin-observability",
      "runner": "eslint",
      "description": "A catch block that reports a failure must not reduce the error to only `e.message` / `String(e)` / `${e}` — log the error itself so its stack and cause survive.",
      "url": "https://noctcore.github.io/eslint-plugins/rules/observability/no-error-detail-loss/",
      "recommended": "error",
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null
    },
    {
      "id": "noctcore-observability/no-sensitive-fields-in-logs",
      "name": "no-sensitive-fields-in-logs",
      "package": "@noctcore/eslint-plugin-observability",
      "runner": "eslint",
      "description": "A logger call must not reference an identifier, property, or object key whose name matches a sensitive-field denylist (password, token, secret, ...). Redact it before logging.",
      "url": "https://noctcore.github.io/eslint-plugins/rules/observability/no-sensitive-fields-in-logs/",
      "recommended": "error",
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null
    },
    {
      "id": "noctcore-observability/structured-log-arguments",
      "name": "structured-log-arguments",
      "package": "@noctcore/eslint-plugin-observability",
      "runner": "eslint",
      "description": "A logger call must not interpolate dynamic values into the message string (a template literal with expressions). Pass a static message and a structured context object instead.",
      "url": "https://noctcore.github.io/eslint-plugins/rules/observability/structured-log-arguments/",
      "recommended": "error",
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null
    },
    {
      "id": "noctcore-security/no-shell-interpolation",
      "name": "no-shell-interpolation",
      "package": "@noctcore/eslint-plugin-security",
      "runner": "eslint",
      "description": "A dynamically-interpolated command string must not flow into a shell runner (`exec`/`execSync`, or `spawn`/`execFile` with `shell: true`). Pass the program and arguments separately.",
      "url": "https://noctcore.github.io/eslint-plugins/rules/security/no-shell-interpolation/",
      "recommended": "error",
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null
    },
    {
      "id": "noctcore-security/no-timing-unsafe-compare",
      "name": "no-timing-unsafe-compare",
      "package": "@noctcore/eslint-plugin-security",
      "runner": "eslint",
      "description": "An HMAC digest or signature must not be compared with `===` / `!==` / `==` / `!=` or `Buffer#equals`; use `crypto.timingSafeEqual`.",
      "url": "https://noctcore.github.io/eslint-plugins/rules/security/no-timing-unsafe-compare/",
      "recommended": "error",
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null
    },
    {
      "id": "noctcore-security/no-user-controlled-fetch-url",
      "name": "no-user-controlled-fetch-url",
      "package": "@noctcore/eslint-plugin-security",
      "runner": "eslint",
      "description": "Disallow HTTP requests whose origin is not fixed at authoring time: a runtime-controlled host enables SSRF.",
      "url": "https://noctcore.github.io/eslint-plugins/rules/security/no-user-controlled-fetch-url/",
      "recommended": "error",
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null
    },
    {
      "id": "noctcore-security/no-user-controlled-redirect",
      "name": "no-user-controlled-redirect",
      "package": "@noctcore/eslint-plugin-security",
      "runner": "eslint",
      "description": "Disallow redirects whose target origin is not fixed at authoring time: a user-controlled target is an open redirect.",
      "url": "https://noctcore.github.io/eslint-plugins/rules/security/no-user-controlled-redirect/",
      "recommended": "error",
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null
    },
    {
      "id": "noctcore-security/require-path-containment",
      "name": "require-path-containment",
      "package": "@noctcore/eslint-plugin-security",
      "runner": "eslint",
      "description": "Request-shaped input (`req.*`) passed directly into `path.join` / `path.resolve` without a containment guard is a path-traversal sink.",
      "url": "https://noctcore.github.io/eslint-plugins/rules/security/require-path-containment/",
      "recommended": null,
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null
    },
    {
      "id": "noctcore-security/require-sanitized-html",
      "name": "require-sanitized-html",
      "package": "@noctcore/eslint-plugin-security",
      "runner": "eslint",
      "description": "HTML reaching `dangerouslySetInnerHTML`, `innerHTML`, `outerHTML` or `insertAdjacentHTML` must be static markup or pass through a configured sanitizer.",
      "url": "https://noctcore.github.io/eslint-plugins/rules/security/require-sanitized-html/",
      "recommended": null,
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null
    },
    {
      "id": "noctcore-security/server-action-through-client",
      "name": "server-action-through-client",
      "package": "@noctcore/eslint-plugin-security",
      "runner": "eslint",
      "description": "In a `'use server'` module every exported action must be built from a configured action client; a raw exported function bypasses input validation, error shaping and middleware.",
      "url": "https://noctcore.github.io/eslint-plugins/rules/security/server-action-through-client/",
      "recommended": null,
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null
    },
    {
      "id": "noctcore-prisma/mutation-entry-must-reach-audit",
      "name": "mutation-entry-must-reach-audit",
      "package": "@noctcore/eslint-plugin-prisma",
      "runner": "eslint",
      "description": "Require a mutation entry point whose type-resolved call graph reaches a Prisma write to also reach an audit write. Reports only when the whole graph was read.",
      "url": "https://noctcore.github.io/eslint-plugins/rules/prisma/mutation-entry-must-reach-audit/",
      "recommended": null,
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "required",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null
    },
    {
      "id": "noctcore-prisma/no-audit-write-in-transaction",
      "name": "no-audit-write-in-transaction",
      "package": "@noctcore/eslint-plugin-prisma",
      "runner": "eslint",
      "description": "Disallow an audit-log write inside a `$transaction` callback, where it rolls back with the business work. It does not check that mutations are audited at all.",
      "url": "https://noctcore.github.io/eslint-plugins/rules/prisma/no-audit-write-in-transaction/",
      "recommended": "error",
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null
    },
    {
      "id": "noctcore-prisma/no-cross-tenant-id-in-where",
      "name": "no-cross-tenant-id-in-where",
      "package": "@noctcore/eslint-plugin-prisma",
      "runner": "eslint",
      "description": "Disallow a Prisma query or write whose tenant id in `where` or `data` is read from client input. Without row-level security, a client-supplied tenant id is a cross-tenant access (IDOR).",
      "url": "https://noctcore.github.io/eslint-plugins/rules/prisma/no-cross-tenant-id-in-where/",
      "recommended": "error",
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null
    },
    {
      "id": "noctcore-prisma/no-raw-sql-outside-allowlist",
      "name": "no-raw-sql-outside-allowlist",
      "package": "@noctcore/eslint-plugin-prisma",
      "runner": "eslint",
      "description": "Disallow raw Prisma SQL ($queryRaw, $executeRaw, $queryRawTyped, *Unsafe) that can touch a table outside an allowlist. A raw query has no model, so a tenant-scope extension passes it through unscoped.",
      "url": "https://noctcore.github.io/eslint-plugins/rules/prisma/no-raw-sql-outside-allowlist/",
      "recommended": "error",
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null
    },
    {
      "id": "noctcore-prisma/no-request-body-in-write",
      "name": "no-request-body-in-write",
      "package": "@noctcore/eslint-plugin-prisma",
      "runner": "eslint",
      "description": "Disallow a Prisma write whose `data` (or `where`) is the raw request body. Passing client input straight through lets a caller set any column (mass assignment) or widen the filter.",
      "url": "https://noctcore.github.io/eslint-plugins/rules/prisma/no-request-body-in-write/",
      "recommended": "error",
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null
    },
    {
      "id": "noctcore-prisma/no-unscoped-prisma-outside-allowlist",
      "name": "no-unscoped-prisma-outside-allowlist",
      "package": "@noctcore/eslint-plugin-prisma",
      "runner": "eslint",
      "description": "Disallow the unscoped Prisma client and tenant-scope escape-hatch functions outside an allowlist of seeds, migrations, isolation tests, and designated system files.",
      "url": "https://noctcore.github.io/eslint-plugins/rules/prisma/no-unscoped-prisma-outside-allowlist/",
      "recommended": "error",
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null
    },
    {
      "id": "noctcore-prisma/prisma-tx-uses-tx-not-client",
      "name": "prisma-tx-uses-tx-not-client",
      "package": "@noctcore/eslint-plugin-prisma",
      "runner": "eslint",
      "description": "Inside a `$transaction(async (tx) => ...)` callback, writes must go through the `tx` parameter, not the outer client, so they participate in the transaction and roll back together.",
      "url": "https://noctcore.github.io/eslint-plugins/rules/prisma/prisma-tx-uses-tx-not-client/",
      "recommended": "error",
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null
    },
    {
      "id": "noctcore-prisma/prisma-write-in-transaction",
      "name": "prisma-write-in-transaction",
      "package": "@noctcore/eslint-plugin-prisma",
      "runner": "eslint",
      "description": "Disallow two or more Prisma writes in a single function/method body that are not wrapped in a `$transaction`. A partial failure between writes leaves half-written state.",
      "url": "https://noctcore.github.io/eslint-plugins/rules/prisma/prisma-write-in-transaction/",
      "recommended": "error",
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null
    },
    {
      "id": "noctcore-prisma/restrict-model-writes",
      "name": "restrict-model-writes",
      "package": "@noctcore/eslint-plugin-prisma",
      "runner": "eslint",
      "description": "Restrict Prisma writes to configured models (or to configured columns of them) to the files that own those writes, including nested relation writes. It fences who writes; it does not validate which values or state transitions are legal.",
      "url": "https://noctcore.github.io/eslint-plugins/rules/prisma/restrict-model-writes/",
      "recommended": null,
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null
    },
    {
      "id": "noctcore-prisma/soft-deletable-tables-require-deleted-at",
      "name": "soft-deletable-tables-require-deleted-at",
      "package": "@noctcore/eslint-plugin-prisma",
      "runner": "eslint",
      "description": "Require a filtered read or bulk write on a soft-deletable Prisma model to exclude soft-deleted rows in its `where`. Soft delete is convention only, with no Prisma extension injecting the filter, so a query that omits it reads and mutates deleted rows.",
      "url": "https://noctcore.github.io/eslint-plugins/rules/prisma/soft-deletable-tables-require-deleted-at/",
      "recommended": null,
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null
    },
    {
      "id": "noctcore-prisma/tenant-scoped-tables-require-where",
      "name": "tenant-scoped-tables-require-where",
      "package": "@noctcore/eslint-plugin-prisma",
      "runner": "eslint",
      "description": "Require every tenant field in the `where` of a read or bulk write on a tenant-scoped model through the unscoped client, and a scope column in the `where` of any query on a hand-scoped model.",
      "url": "https://noctcore.github.io/eslint-plugins/rules/prisma/tenant-scoped-tables-require-where/",
      "recommended": null,
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null
    },
    {
      "id": "noctcore-prisma/tenant-write-must-carry-tenant-id",
      "name": "tenant-write-must-carry-tenant-id",
      "package": "@noctcore/eslint-plugin-prisma",
      "runner": "eslint",
      "description": "Require every tenant field in the `data` of a create on a tenant-scoped Prisma model through the unscoped client, which does not inject the tenant scope.",
      "url": "https://noctcore.github.io/eslint-plugins/rules/prisma/tenant-write-must-carry-tenant-id/",
      "recommended": null,
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null
    },
    {
      "id": "noctcore-rsc/no-navigation-throw-in-try",
      "name": "no-navigation-throw-in-try",
      "package": "@noctcore/eslint-plugin-rsc",
      "runner": "eslint",
      "description": "Disallow `redirect()`, `notFound()` and the other throwing `next/navigation` calls inside a `try` whose `catch` swallows the error instead of rethrowing it.",
      "url": "https://noctcore.github.io/eslint-plugins/rules/rsc/no-navigation-throw-in-try/",
      "recommended": "error",
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null
    },
    {
      "id": "noctcore-llm/no-llm-output-to-sink",
      "name": "no-llm-output-to-sink",
      "package": "@noctcore/eslint-plugin-llm",
      "runner": "eslint",
      "description": "Text an LLM SDK call returned must not reach `eval`, a shell, raw SQL, HTML injection, a `fetch` origin or an `fs` path in the same function without being validated or sanitized first.",
      "url": "https://noctcore.github.io/eslint-plugins/rules/llm/no-llm-output-to-sink/",
      "recommended": "error",
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null
    },
    {
      "id": "agents-doc-presence",
      "name": "agents-doc-presence",
      "package": "@noctcore/lint-meta-rules",
      "runner": "harness",
      "description": "AGENTS.md must exist at the repo root, every surface, and every non-opted-out package.",
      "url": "https://noctcore.github.io/eslint-plugins/rules/lint-meta-rules/agents-doc-presence/",
      "recommended": null,
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null,
      "category": "source-text",
      "ciCritical": true,
      "factory": "createAgentsDocPresenceRule",
      "entry": "@noctcore/lint-meta-rules"
    },
    {
      "id": "canonical-helpers-single-home",
      "name": "canonical-helpers-single-home",
      "package": "@noctcore/lint-meta-rules",
      "runner": "harness",
      "description": "Pure helpers must live in one canonical home (flag the same exported symbol appearing in multiple homes).",
      "url": "https://noctcore.github.io/eslint-plugins/rules/lint-meta-rules/canonical-helpers-single-home/",
      "recommended": null,
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null,
      "category": "source-text",
      "ciCritical": true,
      "factory": "createCanonicalHelpersSingleHomeRule",
      "entry": "@noctcore/lint-meta-rules"
    },
    {
      "id": "dockerfile-base-image-digest-pin",
      "name": "dockerfile-base-image-digest-pin",
      "package": "@noctcore/lint-meta-rules",
      "runner": "harness",
      "description": "Dockerfile FROM base images must be pinned by `@sha256:` digest (scratch and earlier build stages exempt).",
      "url": "https://noctcore.github.io/eslint-plugins/rules/lint-meta-rules/dockerfile-base-image-digest-pin/",
      "recommended": null,
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null,
      "category": "ci",
      "ciCritical": true,
      "factory": "createDockerfileBaseImageDigestPinRule",
      "entry": "@noctcore/lint-meta-rules"
    },
    {
      "id": "eslint-config-no-warn",
      "name": "eslint-config-no-warn",
      "package": "@noctcore/lint-meta-rules",
      "runner": "harness",
      "description": "Every rule in the RESOLVED ESLint config is \"error\" or \"off\", never \"warn\", including severities a spread preset injects.",
      "url": "https://noctcore.github.io/eslint-plugins/rules/lint-meta-rules/eslint-config-no-warn/",
      "recommended": null,
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null,
      "category": "config",
      "ciCritical": true,
      "factory": "createEslintConfigNoWarnRule",
      "entry": "@noctcore/lint-meta-rules/resolved-config"
    },
    {
      "id": "file-size-ratchet",
      "name": "file-size-ratchet",
      "package": "@noctcore/lint-meta-rules",
      "runner": "harness",
      "description": "Source files stay at or under 400 raw lines. Today's offenders are grandfathered by .nightcore/lint-meta/baselines/file-size-ratchet.json; a new/grown offender fails, and a stale/shrunk baseline entry demands tightening.",
      "url": "https://noctcore.github.io/eslint-plugins/rules/lint-meta-rules/file-size-ratchet/",
      "recommended": null,
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null,
      "category": "source-text",
      "ciCritical": true,
      "factory": "createFileSizeRatchetRule",
      "entry": "@noctcore/lint-meta-rules"
    },
    {
      "id": "github-actions-least-privilege-permissions",
      "name": "github-actions-least-privilege-permissions",
      "package": "@noctcore/lint-meta-rules",
      "runner": "harness",
      "description": "GitHub Actions workflows declare a read-only top-level `permissions:` (no `write-all`/`read-all`, no `<scope>: write`); writes go on the job that needs them.",
      "url": "https://noctcore.github.io/eslint-plugins/rules/lint-meta-rules/github-actions-least-privilege-permissions/",
      "recommended": null,
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null,
      "category": "ci",
      "ciCritical": true,
      "factory": "createGithubActionsLeastPrivilegePermissionsRule",
      "entry": "@noctcore/lint-meta-rules"
    },
    {
      "id": "github-actions-no-template-injection",
      "name": "github-actions-no-template-injection",
      "package": "@noctcore/lint-meta-rules",
      "runner": "harness",
      "description": "GitHub Actions `run:` and github-script bodies never expand attacker-controllable `${{ }}` context (issue/PR titles, comments, branch names); pass it through `env:` instead.",
      "url": "https://noctcore.github.io/eslint-plugins/rules/lint-meta-rules/github-actions-no-template-injection/",
      "recommended": null,
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null,
      "category": "ci",
      "ciCritical": true,
      "factory": "createGithubActionsNoTemplateInjectionRule",
      "entry": "@noctcore/lint-meta-rules"
    },
    {
      "id": "github-actions-runner-pinned",
      "name": "github-actions-runner-pinned",
      "package": "@noctcore/lint-meta-rules",
      "runner": "harness",
      "description": "GitHub Actions jobs must run on a pinned runner image (for example ubuntu-24.04), never a *-latest label.",
      "url": "https://noctcore.github.io/eslint-plugins/rules/lint-meta-rules/github-actions-runner-pinned/",
      "recommended": null,
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null,
      "category": "ci",
      "ciCritical": true,
      "factory": "createGithubActionsRunnerPinnedRule",
      "entry": "@noctcore/lint-meta-rules"
    },
    {
      "id": "github-actions-sha-pinned",
      "name": "github-actions-sha-pinned",
      "package": "@noctcore/lint-meta-rules",
      "runner": "harness",
      "description": "GitHub Actions `uses:` refs must be pinned to a 40-character commit SHA with a `# vN` comment (local ./ actions exempt).",
      "url": "https://noctcore.github.io/eslint-plugins/rules/lint-meta-rules/github-actions-sha-pinned/",
      "recommended": null,
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null,
      "category": "ci",
      "ciCritical": true,
      "factory": "createGithubActionsShaPinnedRule",
      "entry": "@noctcore/lint-meta-rules"
    },
    {
      "id": "idempotency-key-parity",
      "name": "idempotency-key-parity",
      "package": "@noctcore/lint-meta-rules",
      "runner": "harness",
      "description": "Procedures carrying the idempotency middleware must have a client caller that sends an idempotency key, or no client caller at all.",
      "url": "https://noctcore.github.io/eslint-plugins/rules/lint-meta-rules/idempotency-key-parity/",
      "recommended": null,
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null,
      "category": "source-text",
      "ciCritical": true,
      "factory": "createIdempotencyKeyParityRule",
      "entry": "@noctcore/lint-meta-rules/trpc"
    },
    {
      "id": "layer-rank",
      "name": "layer-rank",
      "package": "@noctcore/lint-meta-rules",
      "runner": "harness",
      "description": "Fixed dependency direction by rank: a module imports only strictly-lower-ranked <scope> packages (equal/upward forbidden).",
      "url": "https://noctcore.github.io/eslint-plugins/rules/lint-meta-rules/layer-rank/",
      "recommended": null,
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null,
      "category": "source-text",
      "ciCritical": true,
      "factory": "createLayerRankRule",
      "entry": "@noctcore/lint-meta-rules"
    },
    {
      "id": "no-cloned-component-folders",
      "name": "no-cloned-component-folders",
      "package": "@noctcore/lint-meta-rules",
      "runner": "harness",
      "description": "A component folder name may exist under only ONE feature. Shared surfaces are hoisted; divergent ones get a divergent name. Today’s clones are frozen in a shrinking allowlist.",
      "url": "https://noctcore.github.io/eslint-plugins/rules/lint-meta-rules/no-cloned-component-folders/",
      "recommended": null,
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null,
      "category": "source-text",
      "ciCritical": true,
      "factory": "createNoClonedComponentFoldersRule",
      "entry": "@noctcore/lint-meta-rules"
    },
    {
      "id": "no-warn-severity",
      "name": "no-warn-severity",
      "package": "@noctcore/lint-meta-rules",
      "runner": "harness",
      "description": "ESLint severity is 'error' or 'off', never 'warn'. A rule that matters is an error; a failure is fixed, not silenced.",
      "url": "https://noctcore.github.io/eslint-plugins/rules/lint-meta-rules/no-warn-severity/",
      "recommended": null,
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null,
      "category": "config",
      "ciCritical": true,
      "factory": "createNoWarnSeverityRule",
      "entry": "@noctcore/lint-meta-rules"
    },
    {
      "id": "package-shape",
      "name": "package-shape",
      "package": "@noctcore/lint-meta-rules",
      "runner": "harness",
      "description": "Every workspace is named <scope>/<dir>; library packages expose a barrel and point main/module/types/exports at the built output.",
      "url": "https://noctcore.github.io/eslint-plugins/rules/lint-meta-rules/package-shape/",
      "recommended": null,
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null,
      "category": "config",
      "ciCritical": true,
      "factory": "createPackageShapeRule",
      "entry": "@noctcore/lint-meta-rules"
    },
    {
      "id": "prisma-method-surface",
      "name": "prisma-method-surface",
      "package": "@noctcore/lint-meta-rules",
      "runner": "harness",
      "description": "The Prisma reads and writes the rules police partition the generated client's <Model>Delegate method surface exactly, so a Prisma upgrade cannot add an unguarded method.",
      "url": "https://noctcore.github.io/eslint-plugins/rules/lint-meta-rules/prisma-method-surface/",
      "recommended": null,
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null,
      "category": "config",
      "ciCritical": true,
      "factory": "createPrismaMethodSurfaceRule",
      "entry": "@noctcore/lint-meta-rules/prisma"
    },
    {
      "id": "security-scanner-version-parity",
      "name": "security-scanner-version-parity",
      "package": "@noctcore/lint-meta-rules",
      "runner": "harness",
      "description": "The gitleaks version pinned in the workflows must equal the one in scripts/ci/pre-push.sh, and the hook must compare a native gitleaks against it at run time.",
      "url": "https://noctcore.github.io/eslint-plugins/rules/lint-meta-rules/security-scanner-version-parity/",
      "recommended": null,
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null,
      "category": "ci",
      "ciCritical": true,
      "factory": "createSecurityScannerVersionParityRule",
      "entry": "@noctcore/lint-meta-rules"
    },
    {
      "id": "service-image-digest-pin",
      "name": "service-image-digest-pin",
      "package": "@noctcore/lint-meta-rules",
      "runner": "harness",
      "description": "Workflow service and container images, and docker-compose images, must be pinned by `@sha256:` digest (a service that builds locally is exempt).",
      "url": "https://noctcore.github.io/eslint-plugins/rules/lint-meta-rules/service-image-digest-pin/",
      "recommended": null,
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null,
      "category": "ci",
      "ciCritical": true,
      "factory": "createServiceImageDigestPinRule",
      "entry": "@noctcore/lint-meta-rules"
    },
    {
      "id": "session-epoch-captured",
      "name": "session-epoch-captured",
      "package": "@noctcore/lint-meta-rules",
      "runner": "harness",
      "description": "Every call into the sign-in seam must pass the session epoch captured before the credential was read, or a revocation landing during the credential check loses the race.",
      "url": "https://noctcore.github.io/eslint-plugins/rules/lint-meta-rules/session-epoch-captured/",
      "recommended": null,
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null,
      "category": "source-text",
      "ciCritical": true,
      "factory": "createSessionEpochCapturedRule",
      "entry": "@noctcore/lint-meta-rules/session"
    },
    {
      "id": "session-kind-stamped",
      "name": "session-kind-stamped",
      "package": "@noctcore/lint-meta-rules",
      "runner": "harness",
      "description": "Every call that mints a session must stamp the principal kind onto it, or sit in an allowlisted, provably single-kind flow; a session read without the kind falls back to a default and can silently promote one kind of account into another.",
      "url": "https://noctcore.github.io/eslint-plugins/rules/lint-meta-rules/session-kind-stamped/",
      "recommended": null,
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null,
      "category": "source-text",
      "ciCritical": true,
      "factory": "createSessionKindStampedRule",
      "entry": "@noctcore/lint-meta-rules/session"
    },
    {
      "id": "session-landing-declared",
      "name": "session-landing-declared",
      "package": "@noctcore/lint-meta-rules",
      "runner": "harness",
      "description": "Every file that opens a door into a session must declare where it leaves the caller, and a door whose landing demands a return shape (the one that carries the principal kind to the client) must have it.",
      "url": "https://noctcore.github.io/eslint-plugins/rules/lint-meta-rules/session-landing-declared/",
      "recommended": null,
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null,
      "category": "source-text",
      "ciCritical": true,
      "factory": "createSessionLandingDeclaredRule",
      "entry": "@noctcore/lint-meta-rules/session"
    },
    {
      "id": "session-mint-callers",
      "name": "session-mint-callers",
      "package": "@noctcore/lint-meta-rules",
      "runner": "harness",
      "description": "The method that mints a session may only be called from allowlisted files; a new sign-in entry point must route through the gate in front of it so the gate cannot be bypassed.",
      "url": "https://noctcore.github.io/eslint-plugins/rules/lint-meta-rules/session-mint-callers/",
      "recommended": null,
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null,
      "category": "source-text",
      "ciCritical": true,
      "factory": "createSessionMintCallersRule",
      "entry": "@noctcore/lint-meta-rules/session"
    },
    {
      "id": "tenant-model-registry-parity",
      "name": "tenant-model-registry-parity",
      "package": "@noctcore/lint-meta-rules",
      "runner": "harness",
      "description": "Every tenant-bearing Prisma model is scoped by the runtime extension or exempt with a reason, and the tenant lint rules resolve with exactly that registry.",
      "url": "https://noctcore.github.io/eslint-plugins/rules/lint-meta-rules/tenant-model-registry-parity/",
      "recommended": null,
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null,
      "category": "config",
      "ciCritical": true,
      "factory": "createTenantModelRegistryParityRule",
      "entry": "@noctcore/lint-meta-rules/prisma"
    },
    {
      "id": "test-runner-segregation",
      "name": "test-runner-segregation",
      "package": "@noctcore/lint-meta-rules",
      "runner": "harness",
      "description": "Bun-side packages use 'bun:test'; foreign-side packages use 'vitest'. Never mix runners.",
      "url": "https://noctcore.github.io/eslint-plugins/rules/lint-meta-rules/test-runner-segregation/",
      "recommended": null,
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null,
      "category": "testing",
      "ciCritical": true,
      "factory": "createTestRunnerSegregationRule",
      "entry": "@noctcore/lint-meta-rules"
    },
    {
      "id": "test-sibling-enforcement",
      "name": "test-sibling-enforcement",
      "package": "@noctcore/lint-meta-rules",
      "runner": "harness",
      "description": "Every source file matched by `include` must have a colocated sibling test. Pure helpers must ship a test.",
      "url": "https://noctcore.github.io/eslint-plugins/rules/lint-meta-rules/test-sibling-enforcement/",
      "recommended": null,
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null,
      "category": "source-text",
      "ciCritical": true,
      "factory": "createTestSiblingEnforcementRule",
      "entry": "@noctcore/lint-meta-rules"
    },
    {
      "id": "test-workspace-enrollment",
      "name": "test-workspace-enrollment",
      "package": "@noctcore/lint-meta-rules",
      "runner": "harness",
      "description": "Every candidate package with test files must be enumerated in the root 'test:node' script.",
      "url": "https://noctcore.github.io/eslint-plugins/rules/lint-meta-rules/test-workspace-enrollment/",
      "recommended": null,
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null,
      "category": "testing",
      "ciCritical": true,
      "factory": "createTestWorkspaceEnrollmentRule",
      "entry": "@noctcore/lint-meta-rules"
    },
    {
      "id": "translation-dead-keys",
      "name": "translation-dead-keys",
      "package": "@noctcore/lint-meta-rules",
      "runner": "harness",
      "description": "Every translation catalog key must be reachable from the source: named by a translation call, or spelled by some string in the code.",
      "url": "https://noctcore.github.io/eslint-plugins/rules/lint-meta-rules/translation-dead-keys/",
      "recommended": null,
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null,
      "category": "source-text",
      "ciCritical": true,
      "factory": "createTranslationDeadKeysRule",
      "entry": "@noctcore/lint-meta-rules/i18n"
    },
    {
      "id": "ui-primitive-shape",
      "name": "ui-primitive-shape",
      "package": "@noctcore/lint-meta-rules",
      "runner": "harness",
      "description": "A folder primitive under the ui root must ship its proof siblings (test, stories); a flat primitive must not carry sibling proof files at the root.",
      "url": "https://noctcore.github.io/eslint-plugins/rules/lint-meta-rules/ui-primitive-shape/",
      "recommended": null,
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null,
      "category": "source-text",
      "ciCritical": true,
      "factory": "createUiPrimitiveShapeRule",
      "entry": "@noctcore/lint-meta-rules"
    },
    {
      "id": "workspace-graph-parity",
      "name": "workspace-graph-parity",
      "package": "@noctcore/lint-meta-rules",
      "runner": "harness",
      "description": "Imported <scope>/* specifiers must be declared workspace:* deps, and tsconfig references must mirror those deps.",
      "url": "https://noctcore.github.io/eslint-plugins/rules/lint-meta-rules/workspace-graph-parity/",
      "recommended": null,
      "fixable": false,
      "hasSuggestions": false,
      "typeInfo": "none",
      "deprecated": false,
      "replacedBy": [],
      "deprecatedSince": null,
      "category": "config",
      "ciCritical": true,
      "factory": "createWorkspaceGraphParityRule",
      "entry": "@noctcore/lint-meta-rules"
    }
  ]
}
