topos.evaluation.policies.base

Shared types for the policy translators Φᵢ : ℝ → Ω.

Following the math spec (§3 “Policy Translation”), each quality generator gᵢ G_qual has an associated policy translator Φᵢ that maps probe outputs into a ScoredDecision. The characteristic morphism (topos.evaluation.characteristic_morphism) reads each decision’s achieved flag and assembles the 8-element verdict in Ω via topos.core.omega.verdict_from_generators().

This module defines the shared types; all numeric calibration lives in topos.evaluation.policies.calibration:

  • ScoredDecision — output of one Φᵢ (score + achieved + text).

  • Priority — legacy single-generator emphasis (signature

    compatibility only; Φᵢ do not use it today).

  • WeightProfile — legacy intra-Φᵢ metric weights (same).

  • THRESHOLDS — re-export of score-floor helpers from

    SCORE_FLOORS for tools that aggregate normalized scores without re-running a full Φᵢ.

There is exactly one Φᵢ per generator:

Φ_SIMPLE      ↦ simple.py::score_simple
Φ_COMPOSABLE  ↦ composable.py::score_coupling
Φ_SECURE      ↦ secure.py::score_secure

Auxiliary policies (outside G_qual / Ω) live alongside these:

clone detection   ↦ clones.py::are_clones
test coverage     ↦ coverage.py::score_declaration_coverage

Decisive semantics: AND-of-raw-metric thresholds

Each Φᵢ owns per-metric raw thresholds (cyclomatic ≤ 15, zero taint flows, fan-in ≤ 15, …). achieved is the independent AND of those checks — not score THRESHOLDS[g]:

achieved_simple     = score_simple(...).achieved
achieved_composable = score_coupling(...).achieved
achieved_secure     = score_secure(...).achieved

The normalized score on ScoredDecision is min(per-metric qualities) for reporting and multi-file meets; it does not gate achieved.

The 8-element verdict in Ω is the independent AND of the three achieved flags — lattice meets fall out for free:

SIMPLE_COMPOSABLE  ⟺  achieved_simple ∧ achieved_composable
IDEAL              ⟺  all three achieved
SLOP               ⟺  none achieved
…

Generator checks are orthogonal: fixes for SIMPLE (split branches, lift guards) do not substitute for SECURE (eliminate taint) or COMPOSABLE (rebalance coupling). Agents walk the relaxation tree in topos.evaluation.preferences when IDEAL is unreachable.

Score-floor helpers (THRESHOLDS, meet_satisfied())

THRESHOLDS and is_satisfied() / meet_satisfied() implement an alternate score-floor gate (score THRESHOLDS[g]) for callers that already hold normalized scores. The live CharacteristicMorphism path does not use them — it trusts ScoredDecision.achieved from each Φᵢ.

Preferences

Full strict orderings on generators live in topos.evaluation.preferences.UserPreferences (relaxation walk, aspirational IDEAL vs pragmatic pairwise meet). Priority is the lower-resolution CLI shorthand for the top-ranked generator only.

topos.evaluation.policies.base.threshold(generator)[source]

Normalized score floor for one generator (score-floor path only).

topos.evaluation.policies.base.is_satisfied(generator, score)[source]

Whether a normalized score clears the score-floor for one generator.

topos.evaluation.policies.base.meet_satisfied(scores)[source]

Score-floor AND across generators, for pre-aggregated normalized scores.

Returns {g: score[g] THRESHOLDS[g]}. Feed into topos.core.omega.verdict_from_generators() for the Ω element.

Prefer each Φᵢ’s ScoredDecision.achieved when probe metrics are available — that path applies raw-metric gates from topos.evaluation.policies.calibration.

class topos.evaluation.policies.base.Priority(*values)[source]

Bases: StrEnum

Single-generator emphasis.

A Priority is the lower-resolution shadow of a full UserPreferences: it captures only the top-ranked generator of the ordering. New code should pass a UserPreferences ranking; Priority is the simpler CLI / single-knob shorthand when the caller does not want to articulate a full strict order.

Members:

SIMPLE: The user’s top-ranked generator is SIMPLE. COMPOSABLE: The user’s top-ranked generator is COMPOSABLE. SECURE: The user’s top-ranked generator is SECURE.

Passed through the classify API for compatibility; current Φᵢ implementations do not change achieved based on priority.

SIMPLE = 'simple'
COMPOSABLE = 'composable'
SECURE = 'secure'
top_generator()[source]

The generator this priority emphasizes.

class topos.evaluation.policies.base.WeightProfile(w_complexity, w_coupling, w_taint)[source]

Bases: object

Legacy per-generator metric weights for a priority/ranking.

Retained for from_ranking() / WEIGHT_PROFILES and API stability. Current Φᵢ implementations use fixed AND-of-raw-thresholds and do not read these weights.

w_complexity

Weight on cyclomatic_quality within Φ_SIMPLE. Entropy gets 1 - w_complexity.

Type:

float

w_coupling

Weight on coupling_quality within Φ_COMPOSABLE. Instability gets 1 - w_coupling.

Type:

float

w_taint

Weight on taint_quality within Φ_SECURE. Dangerous-API reachability gets 1 - w_taint.

Type:

float

w_complexity
w_coupling
w_taint
classmethod from_ranking(ranking)[source]

Derive intra-policy weights from a full preference ordering.

Top-ranked generator’s Φᵢ is biased toward its primary metric (so it is more decisive); the bottom-ranked one’s stays conservative. Concretely we use weights 0.7 / 0.5 / 0.3 in ranking order:

ranking[0] (top)    → primary-metric weight 0.7  (decisive)
ranking[1] (middle) → primary-metric weight 0.5  (neutral)
ranking[2] (bottom) → primary-metric weight 0.3  (conservative)

This is the canonical path from a UserPreferences ranking to scoring weights.

classmethod from_priority(priority)[source]

Look up the legacy Priority-keyed weight profile.

class topos.evaluation.policies.base.ScoredDecision(score, achieved, interpretation=<factory>)[source]

Bases: object

Result of applying one policy translator Φᵢ.

score

Conservative min(per-metric qualities) in [0.0, 1.0] for display and multi-file aggregation. Does not gate achieved.

Type:

float

achieved

True when every supplied raw metric passes that Φᵢ’s policy thresholds (AND semantics). This is what CharacteristicMorphism feeds into verdict_from_generators.

Type:

bool

interpretation

Per-metric human-readable strings keyed by metric name (e.g. cfg.cyclomatic).

Type:

dict[str, str]

score
achieved
interpretation