Skip to content

Audit foundation: finding identity v2 (pattern, occurrence, lineage) with provenance #266

Description

@PhysShell

Classification

  • Change type: enhancement / foundational contract
  • Priority: P0
  • Expected value: very high — prerequisite for lifecycle tracking, evidence aggregation and honest calibration
  • Implementation risk: medium — schema compatibility and identity drift
  • Canonical owner: Own.NET/audit/ while the audit pipeline remains canonical there

Problem

The current FP-judge finding_id is intentionally line-independent and pattern-level:

sha1(path + rule + message)[:16]

That is correct for deduplicating repeated instances before an expensive judge call, but it is not enough for lifecycle tracking. One pattern ID can represent several physical findings in the same file. If one occurrence is fixed and another remains, a single identity cannot represent both outcomes honestly.

The audit pipeline needs three distinct identities:

  1. pattern_id — the existing line-independent logical pattern; backward-compatible with today's finding_id.
  2. occurrence_id — one concrete physical finding emitted by one producer run.
  3. lineage_id — the best-supported cross-commit identity for following an occurrence through line drift, rename or movement.

Required contract

pattern_id

  • Preserve the current FP-judge recipe and semantics.
  • Keep accepting legacy overlays keyed by finding_id during a documented compatibility window.
  • Make the intentional many-occurrences-to-one-pattern relationship explicit.

occurrence_id

Derive from stable run-local inputs, including at minimum:

producer_run_id
producer/tool identity
rule
path
physical anchor

Requirements:

  • two identical findings at different physical sites receive distinct IDs;
  • rerendering the same normalized run is deterministic;
  • presentation-only ordering does not change the ID;
  • occurrence identity never pretends to survive an unrelated producer run.

lineage_id

  • Link occurrences across commits only when supported by explicit mapping evidence.
  • Prefer symbol/context/AST fingerprints plus Git diff/rename mapping over raw line numbers.
  • Represent ambiguity as unresolved or one-to-many evidence; never guess a single lineage merely to keep dashboards tidy.
  • Store the mapping evidence and confidence class separately from the ID.

Provenance fields

Each occurrence must carry enough provenance to reproduce or reject it:

producer_run_id
producer_name
producer_version
input_digest
config_digest
source_commit
schema_version

Unknown/missing provenance must remain visible as a coverage limitation, not silently synthesized.

Compatibility and migration

  • Version the normalized finding schema.
  • Existing findings.json and fp-verdicts.json fixtures remain readable.
  • Existing finding_id consumers either map it to pattern_id or fail with an actionable version error.
  • No existing diagnostic code, severity, message or analyzer verdict changes in this issue.

Required controls

  1. Two identical messages/rules in one file on different lines:
    • same pattern_id;
    • different occurrence_id.
  2. Pure line drift between commits:
    • new occurrence;
    • same supported lineage.
  3. One repeated occurrence fixed, another retained:
    • lineage outcomes remain independent.
  4. File rename with unchanged symbol/context:
    • lineage may continue with rename evidence.
  5. Ambiguous copy/move:
    • lineage remains unresolved or explicitly branched, never guessed.
  6. Producer/config/input digest changes:
    • provenance changes are observable.
  7. Legacy FP overlay:
    • still expands one pattern verdict to all matching current occurrences only when the input digest contract is valid.

Acceptance

  • Versioned identity contract is documented and implemented.
  • pattern_id, occurrence_id and lineage_id have distinct tested semantics.
  • Repeated physical findings no longer share one lifecycle state.
  • Legacy finding_id compatibility is explicit and tested.
  • Every emitted occurrence carries producer/input/config provenance or an explicit unknown marker.
  • Ambiguous lineage fails honestly rather than producing a convenient false match.
  • Existing analyzer outputs remain semantically unchanged.

Non-goals

  • No Evidence Ledger implementation beyond the identity/provenance seam.
  • No ranking, probability or calibration model.
  • No auto-suppression or merge blocking.
  • No analyzer precision/soundness changes.
  • No forced lift-out from Own.NET/audit/ to OwnAudit.

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