Skip to content

P-022 step 5a: port diagnostic messages and ordered Evidence with Python parity #255

Description

@PhysShell

Parent: #250
Recommended tier: strong
Depends on: #251

Goal

Extend rust/crates/own-diagnostics from data-only verdict types to the full normalized diagnostic contract needed before report/SARIF and bridge cutover:

  • canonical message;
  • severity;
  • subject;
  • resource kind;
  • primary source location;
  • ordered Evidence records;
  • stable diagnostic identity and ordering.

Python remains the source of truth. A divergence is a Rust bug unless changed separately Python-first.

Sources of truth

Deliverable

Rust model

Add or complete data structures for:

  • diagnostic code and severity;
  • primary span/path/line;
  • subject and resource kind;
  • message arguments or another representation that reproduces Python exactly;
  • ordered Evidence steps;
  • evidence labels/roles and related source locations;
  • deterministic normalized comparison keys.

Diagnostics remain data, not Result/errors.

Rendering

Implement the normalized human-message contract used by the current Python core:

  • canonical message text;
  • deterministic formatting;
  • stable ordering for equal-location findings;
  • path normalization matching Python;
  • Unicode-safe identifiers and paths;
  • no presentation dependency on the parser or solver.

Python-authored fixture

Add an explicit generator producing a frozen fixture containing, at minimum:

{
"path": "...",
"line": 42,
"code": "OWN001",
"severity": "warning",
"message": "...",
"subject": "...",
"resource_kind": "...",
"evidence": [
{"path": "...", "line": 10, "kind": "...", "label": "..."}
]
}

Rust steady-state replay must run with zero Python.

Required controls

Architecture guardrails

  • own-diagnostics may depend only on the agreed location/span leaf, never own-syntax, own-cfg or own-analysis.
  • own-analysis may construct diagnostics but owns no presentation logic.
  • No SARIF or report JSON in this issue.
  • No OwnIR bridge.
  • No new diagnostic codes, severity changes or analyzer heuristics.
  • Do not change Python output merely to simplify Rust.

Fixture discipline

The PR must document:

Python source of truth:
Fixture path:
Regeneration command:
Rust replay command:
Python-only count:
Rust-only count:
Changed count:
Ordering-only count:
Unexplained count:

Unexplained count must be zero.

Acceptance

  • Exact normalized parity for path, line, code, severity, message, subject, resource kind and ordered Evidence.
  • Rust replay runs without Python.
  • Fixture regeneration is explicit and reviewed as a semantic diff.
  • Existing verdict fixtures remain unchanged unless the new fixture references them without modifying acceptance.
  • Cargo DAG fitness tests remain green.
  • cargo fmt --check, workspace clippy and tests pass.
  • Python test/lint gates pass.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions