Config Schema (.yaml)
Each rule lives in <rulesDir>/<RuleName>/ and ships with a config.yaml (always named config.yaml — the directory name is what carries the rule identity). This page is the authoritative schema reference for that file.
Top-level structure
Section titled “Top-level structure”version: 1 # required, must be 1
extends: ../base.yaml # optional, path relative to this file
output: language: cpp # required for non-default; see table below autoDeduceIncludes: true # default: true outputDirectory: "" # optional, override default output directory outputNameTemplate: "" # optional, override output filename pattern
permissions: # optional http: allowlist: - "schema-registry.example.com" env: os_allowlist: - "BUILD_CHANNEL"
params: # optional, free-form, exposed to scripts as `params` apiVersion: "v1" emitDocs: true
node_kinds: # optional, defaults to ["Struct"] - Struct - Class - Enum
shared: # optional, controls which shared/*.luau scripts load include: ["json_*"] # absent = include all; [] = include none exclude: ["legacy_*"] # subtracted from includeversion
Section titled “version”Must be the integer 1. Any other value emits E002 and aborts.
extends
Section titled “extends”Optional path (relative to this config file) to a base config. The base is loaded first, then values in this file override matching keys. Chains deeper than 8 levels emit E001. A missing target emits E001.
output.language
Section titled “output.language”Selects the default file extension and the C++-specific assembly path (banner, self-include, project-include rebasing). Must be one of:
| Value | Default extension |
|---|---|
cpp | .g.cpp |
csharp | .cs |
kotlin | .kt |
swift | .swift |
typescript | .ts |
plain | .txt |
markdown | .md |
html | .html |
mdx | .mdx |
Any other value emits E001. Defaults to cpp when omitted.
Only cpp triggers the C++ assembly path: // Generated with Codegen - DO NOT EDIT!!! banner, #pragma once for header outputs, automatic self-include of the input header, and project-include rebasing when outputDirectory relocates the output.
output.autoDeduceIncludes
Section titled “output.autoDeduceIncludes”Default true. When enabled, the engine takes the rule’s emitted includes list and removes any entries already covered by the input header’s transitive include graph (per the analyzer). Set to false to emit every requested include verbatim.
This is not a stdlib auto-detector — it filters explicit includes against the include graph; it does not synthesize includes from generated source text.
output.outputDirectory
Section titled “output.outputDirectory”Overrides the default output directory (which is the input header’s parent directory). Path is taken as-is — relative paths are resolved against the process working directory.
output.outputNameTemplate
Section titled “output.outputNameTemplate”Overrides the default output filename. Tokens (Go-template style):
| Token | Substitution |
|---|---|
{{.InputFile}} | Input header filename without extension |
{{.InputDir}} | Input header’s parent directory (generic-form path) |
{{.RuleName}} | The rule (attribute) name |
Default filename when this is unset:
cpp→<stem>.g.cpp- everything else →
<stem>.<ruleName><ext>
The full path is <outputDirectory or inputDir>/<filename>.
permissions.http.allowlist
Section titled “permissions.http.allowlist”A list of host patterns. Each entry is matched against the host component of the URL passed to http.get(...) (NOT a substring of the full URL). Supported forms:
| Entry | Meaning |
|---|---|
example.com | Exact host match. evil.example.com is not matched. |
*.example.com | Wildcard: any subdomain (api.example.com, a.b.example.com). Does not match the apex example.com. |
* | Match any host (escape hatch). |
An empty or absent allowlist disables HTTP entirely; calls to http.get raise http.get: url not in allowlist: and emit E010.
The CLI flag --allow-http <pattern> appends entries to the allowlist at run time.
permissions.env.os_allowlist
Section titled “permissions.env.os_allowlist”A list of OS environment variable names the rule’s scripts may read. When non-empty, the engine activates the env capability and exposes the named vars to the LuaU env module.
The CLI flag --allow-env <NAME> appends entries to this list at run time.
Dotenv files (<rulesDir>/<RuleName>/.env and <rulesDir>/../shared/.env) are loaded automatically when present and exposed via the same env module; they do not require an allowlist entry. The CLI flag --env KEY=VALUE overrides individual dotenv entries.
params
Section titled “params”Free-form YAML, converted to JSON and exposed to every script as params:
- Preamble script:
paramsis a key on the JSON context object passed in. - Handler (transform) script:
paramsis added under theparamskey on the entity payload. - Grouping script:
paramsis a sibling ofentitieson the input object.
The CLI flag -P key=value (repeatable) overrides params per invocation. The value is parsed as JSON when possible, otherwise stored as a string.
node_kinds
Section titled “node_kinds”A list of NodeKind enum names. Defaults to ["Struct"] when omitted. Controls which AST node kinds the rule’s attribute matcher will fire on. Valid entries are listed in engine/node_introspection.cpp (a few common ones: Struct, Class, Union, Function, Variable, Constructor, Destructor, Operator, EnumSpecifier).
Unknown entries emit a warning: unknown node_kind '<name>' line on stderr but do not fail the load.
shared
Section titled “shared”Controls which <rulesDir>/../shared/*.luau scripts get prepended to this rule’s transform. Both keys take a list of fnmatch-style globs (*, ?, [abc]) matched against the script’s filename stem (i.e. json_helpers.luau matches as json_helpers).
| Key | Behaviour |
|---|---|
shared.include absent | Include every shared/*.luau (default). |
shared.include: [] | Include none — no shared prelude for this rule. |
shared.include: ["a", "b_*"] | Include only the matching stems. |
shared.exclude: [...] | Subtract matching stems from whatever the include step yielded. |
Independence assumption: shared scripts are concatenated in alphabetical filename order with no require-style dependency tracking. If your shared scripts depend on each other, name them so dependencies sort before dependents.
Companion files (not part of the YAML)
Section titled “Companion files (not part of the YAML)”transform.luau— handler script, required.preamble.luau— preamble script, required (an emptyreturn function() return "" endis fine).grouping.luau— grouping script, optional..env— per-rule dotenv, optional.
Plus the workspace-shared directory:
<rulesDir>/../shared/*.luau— auto-loaded in alphabetical filename order, filtered through each rule’sshared.include/shared.exclude, and prepended to that rule’s transform. Team-tier feature; today the directory is loaded unconditionally and the licence gate ships later.<rulesDir>/../shared/.env— baseline dotenv; per-rule entries override.
Full annotated example
Section titled “Full annotated example”version: 1
extends: ../base.yaml
output: language: cpp autoDeduceIncludes: false outputDirectory: generated/advanced outputNameTemplate: "{{.InputFile}}.{{.RuleName}}.g.cpp"
permissions: http: allowlist: - "https://schema-registry.internal.example.com/" env: os_allowlist: - "BUILD_CHANNEL"
params: apiVersion: "v1" emitDocs: true
node_kinds: - Struct - Class