orthonym.metrics.provenance#

Note

Internal API. Names and behaviour may change between releases.

: per-call naming provenance (tier derivation inputs).

Observation-only contextvars — the default naming path’s BEHAVIOR is untouched; sites merely record where the shipped name came from.

orthonym.metrics.provenance.GATE_OUTCOME_NOT_RUN = 'not_run'#

no gate call was recorded for this naming session (the default).

orthonym.metrics.provenance.GATE_OUTCOME_BYPASSED = 'bypassed'#

an outcome WAS recorded, but for a different string than the one shipped (e.g. _apply_trivial_fallback ships a retained name the gate never saw).

orthonym.metrics.provenance.GATE_OUTCOME_DISABLED = 'gate_disabled'#

_DISABLE_VALIDITY_GATE (env) or _disable_opsin_validity_gate (instance).

orthonym.metrics.provenance.GATE_OUTCOME_UNAVAILABLE = 'unavailable'#

jar absent / transient OPSIN failure — the gate failed OPEN.

orthonym.metrics.provenance.GATE_OUTCOME_DESCRIPTIVE_FALLBACK = 'descriptive_fallback'#

the name handed to the gate was already a descriptive-fallback sentinel, so the gate skipped it (nothing was verified).

orthonym.metrics.provenance.GATE_OUTCOME_SUPPRESSED = 'suppressed'#

the gate suppressed a candidate to the descriptive fallback.

orthonym.metrics.provenance.GATE_OUTCOME_SELF01 = 'self_consistency_verified'#

OPSIN parsed the FULL name and returned verdict “ok”. The ONE state that may claim a bare.

orthonym.metrics.provenance.GATE_OUTCOME_SELF01_CONSTITUTION_ONLY = 'self_consistency_constitution_only'#

judged the stereo-STRIPPED parse, so the CONSTITUTION is verified and the stereo layer is NOT.

Type:

the OPSIN-validity stereo carve-out

orthonym.metrics.provenance.GATE_OUTCOME_SELF01_INCONCLUSIVE = 'self_consistency_inconclusive'#

ran and could not compare (fail-OPEN) — nothing was proven.

orthonym.metrics.provenance.GATE_OUTCOME_SELF01_SKIPPED = 'self_consistency_skipped'#

was a no-op (_SC_MODE == “off”, or no input SMILES to compare to).

orthonym.metrics.provenance.GATE_OUTCOME_SELF01_WARN_MISMATCH = 'self_consistency_warn_mismatch'#

PROVED a different molecule but _SC_MODE == “warn” shipped it.

orthonym.metrics.provenance.GATE_OUTCOME_STEREO_RECOMPOSED = 'stereo_omission_full_key_recomposed'#

the general-fallback stereo-OMISSION reclaim COMPOSED the input’s dropped stereo back onto a constitution-verified flat name and re-verified that the composed name recomputes to the input’s FULL InChIKey. That check is strictly STRONGER than (it compares the full stereo layer, not just the skeleton), so this is a genuine VERIFIED state — not a by-design carve-out that ships unproven. (It used to be recorded as carveout:stereo_omission_reanchor, which mislabels a full-key-verified name as unverified — a review -P2 F3.)

orthonym.metrics.provenance.GATE_OUTCOME_CARVEOUT_PREFIX = 'carveout:'#

prefix for the ten by-design return name carve-outs: carveout:<slug>.

orthonym.metrics.provenance.GATE_OUTCOME_FULL_KEY_VERIFIED = 'full_key_round_trip_verified'#

at a general tier, name_tiered checked the shipped string itself because no verified outcome was recorded for it (an offer the pool picked after the gate had seen another string, or an outcome recorded for a different string): OPSIN read the name and the FULL InChIKey of what it read equals the input’s. That is the round trip the paper claims for every shown name, and stronger than, so it claims the plain “verified” label.

Type:

claims conformance (2026-09-27)

orthonym.metrics.provenance.note_touched(*names)#

Public: record that names were written by a path that bypasses the setter functions (a replay-memo HIT writes the ContextVars directly). Lets an enclosing touched-log still capture them.

orthonym.metrics.provenance.push_touched_log()#

Arm a fresh touched-var log for the current nested call and return it. Pair with:func:pop_touched_log in a try/finally (LIFO).

orthonym.metrics.provenance.pop_touched_log()#

Disarm the innermost touched-var log and return it (LIFO).

orthonym.metrics.provenance.push_non_pin_log()#

Arm a fresh record-call log; pair with:func:pop_non_pin_log (LIFO).

orthonym.metrics.provenance.pop_non_pin_log()#

Disarm the innermost record-call log and return it (LIFO).

orthonym.metrics.provenance.clear_provenance()#
orthonym.metrics.provenance.restore_provenance(snapshot)#

Re-set every provenance ContextVar from a get_provenance dict.

The inverse of:func:get_provenance. A caller that speculatively runs a producer which records provenance (record_source et al.) and then REJECTS its candidate must restore the pre-attempt provenance, otherwise the kept emission carries the rejected producer’s label. Used by the Engine-3 NP→von-Baeyer downgrade, whose _try_general_engine_recovery probe stamps source="general_engine" before the RT gate can decline it.

The name-scoped non-PIN record (record_non_pin_fragment) is the one exception: it only grows within a naming call (clear_provenance resets it at a call boundary), so a restore keeps the fragments recorded since the snapshot. A rejected attempt leaves cache entries behind – the scope memo (assembly.memo.cache_or_compute) and the fragment cache return a stored string without the record its computation made – so dropping the record let a later cache hit ship a recorded non-PIN spelling as if none had been recorded, and the result then depended on ORTHONYM_MEMO (branch review, 2026-09-28: ‘C[C@@H](CN(C[C@@H]1CCC=CC1)C)O’ was named at the PIN tier with the memo on and abstained with it off, through the ‘(R)-(cyclohex-3-en-1-yl)meth’ record that rules.pin_vocabulary.promote_at_pin_tier rolled back). A kept record only demotes a name that CONTAINS the recorded spelling.

orthonym.metrics.provenance.record_source(source, opsin=None)#
orthonym.metrics.provenance.record_stereo_unexpressed(flag)#

T6.4: mark the current emission as constitution-only (stereo defined on the input but not expressed in the name). Set at the flagged best-effort ship site; read by name_tiered.

orthonym.metrics.provenance.record_suffix_free_prefix_name(flag)#

: mark the current emission as citing the principal characteristic group as a PREFIX with no suffix – ill-formed per (see the ContextVar comment). Set only at the PG-suppressed assembly site; read by name_tiered and surfaced per row so can enumerate the debt.

orthonym.metrics.provenance.record_gate_outcome(outcome, name)#

T1: record what _final_opsin_validity_gate DID, and for WHICH string. Called at every return of the gate (and of _self_consistency_decision, which owns the gate’s exits).

name must be the string the gate is about to RETURN, not the one it was handed — on a suppression those differ, and the outcome belongs to what actually ships.

orthonym.metrics.provenance.carveout_outcome(slug)#

carveout:<slug> — a by-design return name carve-out. The name is shipped deliberately despite an OPSIN coverage gap; it is NOT verified.

orthonym.metrics.provenance.resolve_gate_outcome(outcome, outcome_name, shipped_name)#

The outcome that applies to shipped_name — deny-by-default.

A recorded outcome only counts for the exact string it was recorded for. Paths that ship a name the gate never saw (_apply_trivial_fallback returns a retained name only AFTER the gate has suppressed the systematic candidate, so the recorded outcome then belongs to a DIFFERENT string) get bypassed, never the previous name’s verdict.

orthonym.metrics.provenance.opsin_label_for_gate_outcome(outcome)#

verified / verified_constitution_only / unverified.

Allowlist, so it fails closed: any outcome not explicitly listed — including a state that does not exist yet — reports unverified.

orthonym.metrics.provenance.gate_token_for_gate_outcome(outcome)#

The gates_passed token this outcome earns, or None if it earns none.

orthonym.metrics.provenance.record_general_ring_prefix()#

-T1c: mark that a PIN-path (composer) name contains a ring substituent prefix that only the GENERAL tier could produce.

Tier and is_pin are decided from source alone (namer.py:2728), and every composer emission reports source='pin_path' -> T1, is_pin=True. A systematic replacement / von Baeyer substituent form is a VALID name but not the PREFERRED one, so shipping it under that label would assert PIN status for a non-PIN name – measured on OC(=O)CC12CC3CC(O)(CC(C3)C1)C2, whose ring PIN is the retained name adamantane, not tricyclo[3.3.1.1^3,7]decane.

This flag lets name_tiered demote exactly those emissions to the general tier while leaving every other composer emission untouched. It is deliberately one-way (never cleared) for the duration of a naming call.

orthonym.metrics.provenance.record_pin_promotion_rerun()#

Mark the name about to ship as built by the PIN tier’s promotion re-run (see _PIN_PROMOTION_RERUN): labelled pin_unverified, never pin_verified.

orthonym.metrics.provenance.record_non_pin_fragment(fragment)#

Record a name fragment that a producer built and that is valid (the whole name is still round-trip verified) but is never part of a PIN – e.g. a carbon-substituted N+ cited as ‘trimethylazaniumyl’, whose PIN form ‘…methanaminiumyl’ cannot be verified.

Unlike record_general_ring_prefix this is NAME-SCOPED: name_tiered demotes the shipped name only if it CONTAINS a recorded fragment. A producer that runs speculatively (a // sort key naming a prefix) or whose candidate is discarded (a later gate rejects it and another path names the molecule) therefore cannot demote a name that does not carry its fragment.

orthonym.metrics.provenance.record_non_pin_label(fragment)#

Record fragment as a LABEL-ONLY non-PIN part (see _NON_PIN_LABELS): a shipped name that contains it is labelled below the PIN; the PIN tier’s promotion re-run still ships it.

orthonym.metrics.provenance.record_uncertified_pin_name(name)#

Record name as a PIN-form name whose preferred status the Blue Book leaves open (see _UNCERTIFIED_PIN_NAMES): a shipped name that contains it is labelled pin_unverified, is_pin False.

orthonym.metrics.provenance.record_derived_non_pin_fragment(source, derived)#

Record derived as a non-PIN fragment when source contains a recorded one: a form built from a non-PIN name by a string conversion (an acid name turned into its acyl prefix) keeps the source’s status, since the recorded substring does not survive the conversion.

orthonym.metrics.provenance.name_carries_non_pin_part(prov, name, *, label_forms=True)#

True when name must not be labelled a PIN: the whole-call general_ring_prefix flag, the whole-call pin_promotion_rerun flag (the PIN tier’s promotion re-run built the name), or a recorded non-PIN fragment it contains. label_forms is passed to rules.pin_vocabulary. non_pin_vocabulary.

orthonym.metrics.provenance.get_provenance()#