Skip to content

[Refactor] _SIGNAL_CATEGORY is dead for category lookup — all 24 entries are shadowed by hardcoded generator categories #757

Description

@mick-gsk

Problem

negative_context/core.py defines _SIGNAL_CATEGORY, a SignalType -> NegativeContextCategory map. It reads as the authoritative place where a signal's negative-context category is declared. It is not.

The map has exactly two readers:

  • core.py:103_policy_uncovered_signal_types(), which uses only .keys() as a signal inventory, never the values
  • generators.py:1236_gen_fallback(), the generic generator for signals without a dedicated generator:
category = _SIGNAL_CATEGORY.get(signal_type, NegativeContextCategory.ARCHITECTURE)

Every one of the 24 dedicated generators hardcodes its own category instead:

@_register(SignalType.PHANTOM_REFERENCE)
def _gen_phr(finding: Finding) -> list[NegativeContext]:
    return [NegativeContext(
        category=NegativeContextCategory.AI_QUALITY,   # <- the value that actually ships
        ...

The measurable consequence

entries in _SIGNAL_CATEGORY : 24
of those, with own generator: 24   -> dead for output
reachable via _gen_fallback :  0

@_register(...) count is 24 and category=NegativeContextCategory. count in generators.py is also 24 — one per generator. So the map's values never reach the output at all. A signal only reaches _gen_fallback if it has no registered generator, and all 24 mapped signals have one. The .get() on line 1236 can therefore only ever return its default, ARCHITECTURE.

Why it matters

Two sources of truth, one of which is silently inert:

  1. Changing a category in _SIGNAL_CATEGORY alone has no effect on output — a plausible and undetectable mistake.
  2. Tests that assert on the map look behavioural but are not. fix: classify phantom references under AI quality #754 added test_phantom_reference_uses_ai_quality_category, which asserts _SIGNAL_CATEGORY[PHANTOM_REFERENCE] == AI_QUALITY. It passes whether or not the generator agrees. The real guard in that PR is test_phr_finding_generates_ai_quality_item.
  3. The two can drift apart with nothing failing. Before fix: classify phantom references under AI quality #754 they already had: the map said COMPLETENESS while signal_registry.py filed PHR under ai_quality.

Options

  • A — Make the map authoritative: drop the hardcoded category= from all 24 generators and have the NegativeContext construction read _SIGNAL_CATEGORY. Removes the duplication; one place to change.
  • B — Make the generators authoritative: rename the map to something honest about its only real use (a signal inventory for the policy-coverage check) and drop its values entirely.
  • C — Keep both, add a consistency guard asserting every registered generator's emitted category equals _SIGNAL_CATEGORY[signal]. Cheapest, keeps the redundancy but makes drift impossible.

A is the smallest surface long-term; C is the smallest change now.

Notes

Found while reviewing #754. No user-visible bug today — the two sources currently agree for every signal. This is about preventing a silent divergence, and about tests that assert on something inert.

  • drift version: 2.51.1

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions