orthonym.assembly.offer_pool#

Note

Internal API. Names and behaviour may change between releases.

a phase Task L2.1: whole-molecule Offer + rank_offers/select_offer.

A NEW, small, PURE module – deliberately NOT built on assembly.candidate_pool or wired through assembly.inner_dispatch. The L2 a trace (task-L2-brief.md, a project rule) proved those are the wrong vehicle: candidate_pool.best ranks parent SKELETONS by the seniority criteria and CandidateName carries no is_pin/tier/coverage field at all, and restructuring dispatch_inner would hit tier_a_ring.py:540-542, which scrubs its own rejected candidates from the shared pool.

This module instead ranks WHOLE finished NAMES (one per naming strategy that offered a result), consumed additively at namer.py::_finish. With exactly one offer (today, L2) selection is a pure identity; L3 adds a second (systematic floor) offer and L4 adds RT-gated retry offers – neither of those layers changes this module, only what gets appended to the pool before select_offer runs.

Pure by design: imports only dataclasses/typing. No OPSIN, no rdkit, no namer import – keeping it import-cycle-free and trivially unit-testable.

orthonym.assembly.offer_pool.PIN_VERIFIED = 'pin_verified'#

Confidence-band names for the result tier field (renamed from the T1.. codes; single source of truth for the spelling – namer.py imports these rather than re-spelling the literals).

class orthonym.assembly.offer_pool.Offer(name, result_obj, is_pin, tier, source, complete)#

Bases: object

One candidate finished name a naming strategy is offering as the result for the whole molecule.

result_obj is the GeneralEngineResult backing name when one exists (None for a bare-str PIN-path winner) – carried through so a later gate (L4) can re-run OPSIN/E1 checks against the SAME bindings that produced name, rather than re-deriving them from the string.

name: str#
result_obj: Any#
is_pin: bool#
tier: str#
source: str#
complete: bool#
orthonym.assembly.offer_pool.rank_offers(offers)#

Sort offers ascending by _rank_key – the most-preferred offer (complete, PIN, lowest tier, then alphabetically-first source/name) is first; an incomplete offer always sorts after every complete one.

orthonym.assembly.offer_pool.select_offer(offers)#

The single most-preferred offer, or None for an empty pool.

orthonym.assembly.offer_pool.select_rt_passing(offers, rt_ok)#

a phase L4-core: the RT/PIN-gate-over-offers SELECTION PRIMITIVE.

Walks rank_offers(offers) in order and returns the FIRST offer that is both .complete and passes the caller-injected rt_ok(offer) -> bool predicate; None if no offer qualifies (including an empty pool).

This is the SAFETY NET every later offer (a systematic floor, a capability producer) relies on: an added offer can never win purely on rank – it must also pass whichever OPSIN round-trip / self-consistency check rt_ok encodes. With today’s single-offer pool this is a proven IDENTITY whenever that offer’s own rt_ok is True (the common case, since the primary winner was already gated upstream); the caller’s contract (not this function’s) is to fall back to the name already shipping when this returns None, rather than newly abstaining.

rt_ok is injected (never imported) so this module stays pure – no OPSIN, no rdkit, no namer import, matching the rest of the module.