Skip to content

Latest commit

 

History

History
46 lines (36 loc) · 2.25 KB

File metadata and controls

46 lines (36 loc) · 2.25 KB

ADR 0013: Declarative hard-filter DSL

  • Status: Accepted (2026-08-23)
  • Implements: roadmap M1.3; consumes hard_filters + targeting from ADR-0006 documents

Context

The prototype embedded one person's filter semantics in code: clearance stance prose, a defaulted current-employer slug, seniority vocabulary, and role-archetype exclusions. None of it was configurable, none of it explained itself, and the default employer name was literally a constant (common/config.py). Purge items A5/A6/A7 close by construction here.

Decision

openjobradar.policy.evaluate_hard_filters(posting, profile) folds independent findings into one verdict:

Rule Source Severity
current_employer hard_filters.current_employers deny
seniority_excluded targeting.excluded_seniority deny
archetype_excluded hard_filters.excluded_archetypes deny
clearance_required / clearance_preferred hard_filters.clearance_stance (any/plus_digest_only/never) deny / demote_digest
comp_below_floor hard_filters.comp_floor_usd vs parsed low end deny

Semantics worth pinning:

  • All findings are collected, not short-circuited — a posting can be denied for two reasons and the UI shows both.
  • Statuses are portfolio-wide: allow / deny / demote_digest (demote = digest-only, never alerted).
  • Executive acronyms match their expansions bidirectionally (CTOchief technology officer); phrase matching is word-boundary padded so SVP never hits inside another token.
  • Clearance phrasing resolves per sentence: preferred markers (preferred, a plus, not required) downgrade to preferred; anything else mentioning clearance is required. Under never, even preferred-clearance roles demote to digest.
  • Compensation parsing takes the low end of a range, skips hourly rates, and never blocks when pay is absent or unparseable (no evidence is not negative evidence).

Consequences

  • Zero person-specific filter facts in code; every knob is validated config surfaced later by the settings hub (roadmap M5.2).
  • Rule names are stable API surface for explainability UI and metrics.
  • The acronym table is deliberately small and explicit; growing it is a reviewed code change, not silent drift.