exlab_wizard.validator.rules#
Validator rule functions. Backend Spec §8.1.
This module is a pure-function library: one function per §8.1 rule. Each
function takes the rule-specific inputs and returns a list of finding-shaped
dictionaries (the §11.8 wire shape, partially populated – the engine layer
fills in run_path, synced_under_prior_policy and override_active
once it knows the run context).
The rule functions are intentionally stateless and side-effect free so they
can be exercised in isolation by the unit-test suite and re-used by both
creation-time mode (single proposed path) and audit mode (whole subtree
walk). The engine layer (validator/engine.py) orchestrates which rules
fire on which inputs.
Each finding dict has the shape:
{
"rule": "<rule_name>",
"tier": "hard" | "soft",
"matched_token": "<token>" | None,
"rule_detail": "<human description>",
"offending_kind": "directory_segment" | "file_name" | "file_content",
"offending_path": "<path or filename>",
}
Functions
§8.1.2: detect Windows-illegal characters in any segment / file name. |
|
|
§8.1: detect malformed YAML front matter at the head of a Markdown file. |
|
§8.1.5: detect required README fields that are absent or empty. |
|
§8.1.3: detect three-way disagreement between |
|
§8.1.4: detect missing |
|
§8.1.2: detect Windows reserved names ( |
|
§8.1.1: detect angle-bracket and Jinja placeholder tokens. |
- exlab_wizard.validator.rules.check_illegal_filesystem_character(*, path_segments, file_names)[source]#
§8.1.2: detect Windows-illegal characters in any segment / file name.
Illegal set: NUL,
<,>,:,",/,\,|,?,*, ASCII 0-31, trailing dot or trailing space.The spec’s POSIX exception allows
</>in non-token positions on POSIX – but our app composes paths cross-platform, so we ALWAYS reject. Returns ruleillegal_filesystem_characterfindings.
- exlab_wizard.validator.rules.check_malformed_yaml_front_matter(*, content)[source]#
§8.1: detect malformed YAML front matter at the head of a Markdown file.
Soft-tier. Returns rule
malformed_yaml_front_matterfinding when the first---opens a block but no second---closes it within the first 200 lines, OR whenyaml.safe_loadfails on the block.
- exlab_wizard.validator.rules.check_missing_required_field(*, readme_fields, required_field_ids)[source]#
§8.1.5: detect required README fields that are absent or empty.
Soft-tier. Walks the
readme_fields_jsonlayer dicts (core_fields,template_fields,config_fields) for each id inrequired_field_ids. Returns rulemissing_required_fieldfindings.
- exlab_wizard.validator.rules.check_mode_prefix_mismatch(*, leaf_dir_name, parent_dir_name, creation_run_kind)[source]#
§8.1.3: detect three-way disagreement between
run_kind, leaf prefix, and parent folder.Hard-tier. Triple-agreement contract:
run_kind="experimental"<=> leaf prefixRun_<=> parent !=TestRuns/run_kind="test"<=> leaf prefixTestRun_<=> parent ==TestRuns/
Returns rule
mode_prefix_mismatchfindings naming the conflict.
- exlab_wizard.validator.rules.check_orphan(*, level, has_creation_json)[source]#
§8.1.4: detect missing
creation.jsonat project / run level (NOT equipment).Soft-tier. Returns one rule
orphanfinding whenlevelisDirectoryLevel.PROJECTorDirectoryLevel.RUNandhas_creation_jsonisFalse.
- exlab_wizard.validator.rules.check_reserved_filesystem_name(*, file_names)[source]#
§8.1.2: detect Windows reserved names (
CON,PRN,AUX,NUL,COM1..COM9,LPT1..LPT9).Case-insensitive; with or without extension. Uses
WINDOWS_RESERVED_NAMESfrom constants. Returns rulereserved_filesystem_namefindings.
- exlab_wizard.validator.rules.check_unresolved_placeholder(*, path_segments, file_names, file_contents)[source]#
§8.1.1: detect angle-bracket and Jinja placeholder tokens.
Hard-tier. Uses
PLACEHOLDER_ANGLE_BRACKET_PATTERNand the two Jinja patterns from constants. Returns one finding per match with ruleunresolved_placeholder_token(angle-bracket) orleftover_jinja_marker(Jinja).file_contentsmay be empty for path-only checks. Files larger than_CONTENT_SCAN_MAX_BYTESare skipped per §8.1.1.