Findings name the file they concern but not where in it. An editor integration, or anyone reading a failure on a large schema, has to search for the offending key by hand.
Requested in review: "ideally we also return line + column numbers if available, also for ui editors error message placements" and "line numbers of the checked source file would help in debugging".
Where things stand
Check in src/oold/validation/report.py carries id, target, status, message, detail, meta_version, rule. There is no position.
Some checks already know structurally where the problem is, just not textually. src/oold/validation/schema_checks.py:65 builds a location from a jsonschema error:
location = "/".join(str(part) for part in error.absolute_path)
pattern_lint.py and several pipeline.py paths sort by absolute_path too. So a JSON pointer is available or cheap for the meta-schema family; it is the pointer-to-line-and-column step that is missing everywhere.
Why it is not a small change
json.loads discards positions (resolve.py:170, :186, :205, :234, :381). Recovering them needs a position-preserving parse of the raw text, kept alongside the parsed document.
Suggested shape
- Parse once into a position index mapping JSON pointer to (line, column), from the raw text rather than the parsed object
- Have checks report a JSON pointer, which several already can, and resolve pointer to position centrally at report time. This avoids threading line numbers through every check
Check gains an optional position; to_dict includes it; the CLI prints file:line:col; the MCP result models expose it as typed fields
Cases that need an answer
- Generated instances have no source file at all, so
roundtrip.generated and generate.satisfiable findings can carry a pointer but never a position
- Inline JSON via MCP is materialised into a temp file, so positions would refer to that copy; they are still correct relative to the text the caller sent
- Dereferenced schemas: after
$ref resolution a node may originate in a different file from the one being validated, so a position needs to name its own file rather than assume the target
- Multi-version runs report the same target once per meta-schema version; positions must not be duplicated inconsistently
Acceptance
- A failing fixture reports a position that points at the right key, asserted in a test rather than eyeballed
- Checks with no meaningful position omit it rather than reporting 0 or 1
- Parity is unaffected:
OOLD_SCHEMA_DIR=../oold-schema uv run pytest -m parity compares verdicts, and positions are additive
Raised from review of #114 (#114 (comment), #114 (comment)).
Findings name the file they concern but not where in it. An editor integration, or anyone reading a failure on a large schema, has to search for the offending key by hand.
Requested in review: "ideally we also return line + column numbers if available, also for ui editors error message placements" and "line numbers of the checked source file would help in debugging".
Where things stand
Checkinsrc/oold/validation/report.pycarriesid,target,status,message,detail,meta_version,rule. There is no position.Some checks already know structurally where the problem is, just not textually.
src/oold/validation/schema_checks.py:65builds a location from ajsonschemaerror:pattern_lint.pyand severalpipeline.pypaths sort byabsolute_pathtoo. So a JSON pointer is available or cheap for the meta-schema family; it is the pointer-to-line-and-column step that is missing everywhere.Why it is not a small change
json.loadsdiscards positions (resolve.py:170,:186,:205,:234,:381). Recovering them needs a position-preserving parse of the raw text, kept alongside the parsed document.Suggested shape
Checkgains an optional position;to_dictincludes it; the CLI printsfile:line:col; the MCP result models expose it as typed fieldsCases that need an answer
roundtrip.generatedandgenerate.satisfiablefindings can carry a pointer but never a position$refresolution a node may originate in a different file from the one being validated, so a position needs to name its own file rather than assume the targetAcceptance
OOLD_SCHEMA_DIR=../oold-schema uv run pytest -m paritycompares verdicts, and positions are additiveRaised from review of #114 (#114 (comment), #114 (comment)).