Skip to content

Harden apply_retractions: name-level granularity, index cleanup, orphan assertion #599

Description

@realmarcin

Follow-up from PR #597 (chemical-mapping retraction pass). The pass is safe today, but two design limitations are worth hardening before the retraction list grows.

1. Object-granular retraction depends on a frozen external analysis

apply_retractions drops at the object level (del self.chemicals[oid]), but the underlying data is name→object groundings. If a listed stale object is also the correct grounding for some name that is not in the retraction list — now or as the synced upstream (UNIFIED_INGREDIENT_MAPPING.tsv, the MIM SSSOM) evolves — that name is silently orphaned. The sole-source guard can't prevent this (the legitimate name would also be sole-sourced from culturebotai_reviewed).

Mitigations already in place (PR #597 review round): a non-fatal orphan guard warns if any now_asserted target is absent after the pass. Verified 0 orphans on the current 161-row list.

Possible further hardening:

  • Move to name-level retraction (drop the specific (name, object) grounding, keep the object if other names still point to it), or
  • Make the orphan guard fatal in CI once we trust it, or
  • Regenerate/re-verify the retraction list from a diff of consecutive culturebotai_reviewed inputs rather than a frozen file.

2. del self.chemicals[oid] leaves dangling name_index / formula_index entries

The drop removes only the self.chemicals record; name_index[norm_name] / formula_index[formula] still point at the deleted CURIE. Harmless today (export_unified_sssom and propagate_synonyms_via_xrefs both iterate/snapshot self.chemicals and don't consult name_index afterward), but a latent trap for any future code that resolves a name via name_index after this pass. Cheap fix: prune those indices in the drop loop.

3. Test coverage

Added in review: idempotency, curator-qualified sole-source, empty-source-not-dropped. Still worth adding: an explicit orphan-detection test (a listed object that is also the sole-source correct target of a second unlisted name).

Context: root cause of 3 of the 16 stale objects is upstream and filed at CultureBotAI/MediaIngredientMech#138.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions