Skip to content

Report line and column positions in findings #124

Description

@LukasOro

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)).

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions