Skip to content

Duplicate-edge dedup + opt-in catalyst bundling#46

Merged
adamjohnwright merged 3 commits into
mainfrom
fix/dedup-and-catalyst-toggle
Jul 15, 2026
Merged

Duplicate-edge dedup + opt-in catalyst bundling#46
adamjohnwright merged 3 commits into
mainfrom
fix/dedup-and-catalyst-toggle

Conversation

@adamjohnwright

Copy link
Copy Markdown
Contributor

Follow-up to #45 (which merged the set-expansion fix). These commits were made after #45 merged and never reached main.

Ships by default

Drop fully-identical duplicate edges — distinct virtual reactions of one curated reaction can canonicalize to the same target node; a catalyst/regulator attached to each then produces exact-duplicate rows that the solver double-weights in its activator aggregation. Final dedup keyed by (source, target, sign, type, reaction). 39/92 catalog pathways affected; Pre-NOTCH 40,548→27,552 edges (−32%), FGFR2 −7,806, ERBB2 −3,345. Benchmarked neutral (experimental 66.43%, curator 81.18%).

Behind a toggle, OFF by default (LNG_CATALYST_BUNDLE=1)

Catalyst/regulator bundling — the faithful complex-as-node representation (no subunit shatter). Kept opt-in because it exposes a pre-existing UUID-silo defect (a complex produced by one reaction and catalysing/regulating another is stored as separate un-unified nodes, compounded by set-variant mismatch + non-deterministic set-member selection) that breaks the curated produce→catalyse chain. Subunit decomposition accidentally masks this via spurious hub paths and scores ~1.2pp higher on experimental — luck, not correctness. Default stays subunit until the canonical entity-node unification is redesigned (documented ceiling; full-merge was −204pp).

Net effect at default settings: dedup only; bundle inert unless toggled.

Full non-DB suite (139) green, ruff + mypy clean, coverage 46%.

🤖 Generated with Claude Code

adamjohnwright and others added 3 commits July 15, 2026 16:59
Distinct virtual reactions of one curated reaction can canonicalize (union-find)
to the same target node; a catalyst/regulator attached to each then produces
exact-duplicate rows (same source, target, sign, type, reaction). The solver has
no dedup — create_reaction_from_edges pushes each edge's parent into `activators`
— so a duplicated catalyst is double-weighted in the activator aggregation
(geomean/hill), skewing the reaction toward that parent.

Add a final dedup pass on the edge list keyed by
(source, target, pos_neg, and_or, edge_type, edge_reaction_id). Distinct
reactions keep distinct edge_reaction_id, so only truly-redundant rows collapse.

Scale: 39 of 92 catalog pathways affected; Pre-NOTCH 40,548 -> 27,552 edges
(32% were duplicates), FGFR2 -7,806, ERBB2 -3,345, RAF -2,191.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…nit shatter)

Catalysts and positive regulators were decomposed to their individual subunit
proteins, making each protein a SHARED node wired directly to every reaction its
complexes catalyse — a super-hub that lets signal flood unrelated reactions and
is inconsistent with the complex-as-node treatment of reaction inputs.

Now they use bundle_complex mode in _decompose_regulator_entity: a complex is
ONE node regardless of internal sets (no subunit shatter, and no cartesian
set-variant expansion either — variant expansion blew TP53 up to 156k edges).
Only genuine top-level "one-of" EntitySets still expand into OR alternatives.
Negative regulators keep variant decomposition as before. Env toggle
LNG_CATALYST_SUBUNITS=1 restores the old subunit shatter for A/B.

Effect (TP53): 18,082 -> 5,631 edges (69% fewer) — its transcription catalysts
were heavily shattered. (Does NOT by itself fix DAXX over-reach, which is
network-wide shared-node coupling + undamped propagation, a separate issue.)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…_CATALYST_BUNDLE

Catalyst/positive-regulator bundling (the faithful complex-as-node representation)
is more correct but OFF BY DEFAULT: it exposes a pre-existing UUID-silo defect
(a complex produced by one reaction and catalysing/regulating another is stored
as separate, un-unified nodes — compounded by set-variant mismatches and
non-deterministic set-member selection), so the curated produce→catalyse chain
doesn't carry signal. Subunit decomposition accidentally masks this via spurious
shared-protein hub paths and scores ~1.2pp higher on the experimental set — not
because it's more correct, but because the hubs reconnect what the silo severs.

Until the silo × set-variant entity-identity problem is redesigned, subunit
decomposition remains the default; bundling is opt-in via LNG_CATALYST_BUNDLE=1
for when that work happens.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@adamjohnwright
adamjohnwright merged commit b2cef91 into main Jul 15, 2026
4 checks passed
@adamjohnwright
adamjohnwright deleted the fix/dedup-and-catalyst-toggle branch July 15, 2026 23:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant