For AI agents: the complete documentation index is available at https://mfdoctor.kevinbeier.com/1.0.0/llms.txt, the full documentation bundle is available at https://mfdoctor.kevinbeier.com/1.0.0/llms-full.txt, and this page is available as Markdown at https://mfdoctor.kevinbeier.com/1.0.0/custom-rules.md.

Custom rules

Custom rules use defineRule and receive frozen normalized facts only. A rule may be async. It reports findings through context.report and cannot mutate facts. Facts come from public MF options, manifests, stats, and recorded capabilities — not private plugin state (limitations).

import { defineRule } from "@tonoizer/mfdoctor/rules";

export const requireManifest = defineRule({
  meta: {
    id: "team/require-manifest",
    defaultSeverity: "error",
    supportedBundlers: ["vite", "rspack", "rsbuild", "webpack", "modern"],
    documentation: "/rules/team/require-manifest",
  },
  check(context) {
    if (!context.facts.artifacts.manifest) {
      context.report({
        message: "Manifest missing.",
        evidence: {},
        // Optional (#136): detailsSchema + details — never put schema version in evidence
        // detailsSchema: "custom.team.topic.v1",
        // details: { path: "mf-manifest.json" },
      });
    }
  },
});

Register custom rules through extends (alone or inside a policy pack):

import { requireManifest } from "./rules/require-manifest";

export default {
  extends: ["recommended", requireManifest],
};