Skip to main content
alfiz-verify reads its configuration from alfiz-verify.config.json in the current working directory, or from the path passed via --config <path>. The file is plain JSON, with no JavaScript and no comments.

Config fields

string
required
Path to the emitted catalog JSON file, the output of catalog.toDocument(). Resolved relative to the current working directory.
string[]
default:"[\"src\"]"
Directories (or individual files) to scan. Resolved relative to the current working directory. alfiz-verify walks each directory recursively and scans every .ts, .tsx, .mts, and .cts file it finds (.d.ts files are skipped).
string[]
Path substrings to skip. A file is excluded when its path contains any of these strings. The built-in excludes ["node_modules", "dist", ".next", ".git"] are always applied; this field adds to them.
string[]
Additional function names to treat as concrete-permission gates, added to the built-in defaults (can, fresh, require, requirePermission, gateAction, apiRequirePermission). Gate calls are checked for typed key validity, mark the enclosing function as gated, and count toward coverage.
This field is additive, so it extends the defaults. You do not need to restate can or require. If you want full replacement of the defaults (dropping the built-ins), use the programmatic verifyProject API directly.
string[]
Additional function names to treat as visibility affordances, added to the built-in defaults (canAny, requireAny, holds). Visibility affordances count toward key coverage but produce an error when used as a gate in a server file.
Like gateNames, this is additive. The built-in visibility names are always included.
string[]
Additional RegExp source strings matched against file paths to identify server enforcement points, added to the built-in patterns (app/.*route.(t|j)sx?, pages/api/). Files matching these patterns are treated as server files even without a "use server" directive, so exported async functions in them must contain a gate.
Each string is compiled into a RegExp. If any entry is not a valid regular expression, alfiz-verify exits with code 2.
This is additive. The built-in patterns (app/.*route.(t|j)sx? and pages/api/) are always applied.
string[]
Identifiers that must not appear in any "use client" module. Use this to ensure service-key material (environment variable names, key shim imports) can never reach the browser. When a listed identifier is found in a client-reachable file, alfiz-verify reports an error with the client-reachable-secret rule.
This is the build-time half of the service-principal security posture: createServiceKeyShim validates keys server-side; this guard ensures the key material can never be bundled into client JavaScript.
string
Path to the emitted import manifest, the output of catalog.toImportManifest(). Required if your catalog declares imports: a catalog document carries owned vocabulary only, so without the manifest the verifier treats every imported key as foreign.
Record<string, string>
The namespace owners’ published documents, keyed by namespace. Optional enrichment on top of importManifest: the manifest already names every imported key, so these only add display copy and sharpen did-you-mean suggestions.
"registry" | "none"
Declares that a registry or Alfiz Cloud dashboard is wired up, which makes implicit-import a warning rather than an error. Defaults to "registry" when your catalog already declares imports.This is declared, never detected. alfiz-verify is offline and deterministic by construction: no network call decides whether your build passes.
"error" | "warn" | "off"
Overrides the implicit-import severity outright. Use "off" when foreign keys are an accepted, reviewed part of this codebase.
string[]
Namespaces exempt from implicit-import entirely, which is narrower than turning the rule off.

Complete example

Additive vs. replacement

The three name lists (gateNames, visibilityNames, serverFilePatterns) are always additive through the CLI. This is intentional: the CLI is the batteries-included path, and forgetting to restate can in gateNames should not silently un-gate your whole codebase. If you need full replacement of the built-in defaults, for example a codebase that uses entirely custom gate wrappers and wants to treat the built-in names as errors, use the programmatic verifyProject API from @alfiz/verify directly:
files is a list of paths; the source text comes from read, which defaults to the filesystem. Pass your own to verify an in-memory tree. verifyProject is synchronous and performs no network I/O, by construction. It returns a VerifyReport:
referencedPatterns is kept separately from referencedKeys because an imported wildcard expands to no keys. Pattern-wise reach is the only way to tell a live import from a stale one.