Summary
Validation currently answers a yes/no question. BIDSValidator.is_bids() returns a
boolean, and the CLI prints one line per non-compliant file:
/sub-01/anat/oops.nii.gz is not a valid bids filename
That output carries no severity, no stable code, and no structure a program can consume.
It cannot be counted, filtered, serialised, or shown in a UI, and it cannot say why a
name is wrong.
context.py already anticipates this: ValidationError is a stub whose entire body is
"""TODO: Add issue structure.""".
Proposal
Two small pieces.
1. An issue model (bids_validator/issues.py). Pure data, no I/O, attrs to match
the convention already used by context.py, bidsignore.py and types/files.py:
Severity (error, warning)
Issue with code, severity, location, message, sub_code, rule
DatasetIssues, an ordered collection with add, extend, by_severity,
has_errors, __len__, __iter__
Field names mirror the reference validator so output stays interchangeable.
2. Emit findings from filename validation. Rather than one blanket answer, report the
specific reason using the reference validator's codes: NOT_INCLUDED,
MISSING_REQUIRED_ENTITY, ENTITY_NOT_IN_RULE, ENTITY_WITH_NO_LABEL,
INVALID_ENTITY_LABEL, EXTENSION_MISMATCH, DATATYPE_MISMATCH, INVALID_LOCATION,
FILENAME_MISMATCH, ALL_FILENAME_RULES_HAVE_ISSUES.
Scope is names and paths only. No file contents are read.
BIDSValidator.is_bids() stays untouched, since pybids and mne-bids depend on it.
Why this first
Every later check needs somewhere to report to. Content validation (sidecar fields, NIfTI
headers, tabular columns) produces the same Issue type into the same DatasetIssues,
so the output contract is defined once and does not change as coverage grows.
Questions for maintainers
- Is the minimal field set above right, or do you want the reference validator's richer
fields (rule provenance, machine-actionable fixes, an ignore severity, line spans)
from the start? I kept them out to keep the first PR small.
- The CLI currently prints
<path> is not a valid bids filename for each bad file.
When these findings are wired into it, should that output change to show the
specific code and reason, or should the current text stay the default with the
structured output behind a flag? Changing it would be more useful but would break
anyone parsing the current output.
- Any preference on module naming (
issues.py / filename_checks.py)?
I have a working implementation with tests and am happy to open a PR, or to adjust the
shape first if you would prefer a different design.
Summary
Validation currently answers a yes/no question.
BIDSValidator.is_bids()returns aboolean, and the CLI prints one line per non-compliant file:
That output carries no severity, no stable code, and no structure a program can consume.
It cannot be counted, filtered, serialised, or shown in a UI, and it cannot say why a
name is wrong.
context.pyalready anticipates this:ValidationErroris a stub whose entire body is"""TODO: Add issue structure.""".Proposal
Two small pieces.
1. An issue model (
bids_validator/issues.py). Pure data, no I/O,attrsto matchthe convention already used by
context.py,bidsignore.pyandtypes/files.py:Severity(error,warning)Issuewithcode,severity,location,message,sub_code,ruleDatasetIssues, an ordered collection withadd,extend,by_severity,has_errors,__len__,__iter__Field names mirror the reference validator so output stays interchangeable.
2. Emit findings from filename validation. Rather than one blanket answer, report the
specific reason using the reference validator's codes:
NOT_INCLUDED,MISSING_REQUIRED_ENTITY,ENTITY_NOT_IN_RULE,ENTITY_WITH_NO_LABEL,INVALID_ENTITY_LABEL,EXTENSION_MISMATCH,DATATYPE_MISMATCH,INVALID_LOCATION,FILENAME_MISMATCH,ALL_FILENAME_RULES_HAVE_ISSUES.Scope is names and paths only. No file contents are read.
BIDSValidator.is_bids()stays untouched, since pybids and mne-bids depend on it.Why this first
Every later check needs somewhere to report to. Content validation (sidecar fields, NIfTI
headers, tabular columns) produces the same
Issuetype into the sameDatasetIssues,so the output contract is defined once and does not change as coverage grows.
Questions for maintainers
fields (rule provenance, machine-actionable fixes, an
ignoreseverity, line spans)from the start? I kept them out to keep the first PR small.
<path> is not a valid bids filenamefor each bad file.When these findings are wired into it, should that output change to show the
specific code and reason, or should the current text stay the default with the
structured output behind a flag? Changing it would be more useful but would break
anyone parsing the current output.
issues.py/filename_checks.py)?I have a working implementation with tests and am happy to open a PR, or to adjust the
shape first if you would prefer a different design.