From 9bad9b9db44b52bc5b842c3e1041a043839df7b4 Mon Sep 17 00:00:00 2001 From: Adam Wright Date: Mon, 21 Sep 2026 23:23:59 -0400 Subject: [PATCH] Align attributions with the deltasignal paraphrases; remove home paths The two repos had drifted apart. deltasignal #63 paraphrased two requirement sentences out of verbatim quotation, and this repo still carried the same two sentences quoted verbatim -- so the record said different things about the same requirement in two places, which is what makes a record untrustworthy later. Paraphrased here to match: src/diagram_connectivity.py (the two-glyphs-same- compartment requirement) and src/resolution_validation.py (the both-directions mapping requirement), plus three name attributions in specs/001-validator-fidelity/spec.md, src/logic_network_generator.py and tests/test_provenance_exports.py. Technical content unchanged; only the quoting and the attribution-by-name went. The pyproject.toml authorship line stays. Home paths gone: both bin/ scripts hardcoded /home/awright/gitroot/mp-biopath-pathways, now MPBIO_ROOT with a ~/gitroot default, matching the convention the deltasignal bench scripts use. NOT changed, deliberately: docker-compose.yml publishes Neo4j on all interfaces with image-default auth. I had flagged that as an exposure and it is not one -- the image is public.ecr.aws/reactome/graphdb, i.e. Reactome own publicly distributed database, so there is no confidentiality impact, and publishing the ports is the point of the file. The credential literals in three tests authenticate against that same public database. 1036 passed, 1 pre-existing MHC failure; ruff and mypy clean. --- bin/check-no-path-cases-in-neo4j.py | 5 ++++- bin/validate-against-mpbiopath.py | 5 ++++- specs/001-validator-fidelity/spec.md | 8 ++++---- src/diagram_connectivity.py | 6 +++--- src/logic_network_generator.py | 2 +- src/resolution_validation.py | 6 +++--- tests/test_provenance_exports.py | 6 +++--- 7 files changed, 22 insertions(+), 16 deletions(-) diff --git a/bin/check-no-path-cases-in-neo4j.py b/bin/check-no-path-cases-in-neo4j.py index de1f36f..23ed3eb 100644 --- a/bin/check-no-path-cases-in-neo4j.py +++ b/bin/check-no-path-cases-in-neo4j.py @@ -32,7 +32,10 @@ from src.neo4j_connector import get_graph # noqa: E402 -MP_BIOPATH_DIR = Path("/home/awright/gitroot/mp-biopath-pathways") +# Overridable so the path is not tied to one machine; the default follows the +# same ~/gitroot layout the rest of the tooling assumes. +MP_BIOPATH_DIR = Path(os.environ.get("MPBIO_ROOT", + str(Path.home() / "gitroot" / "mp-biopath-pathways"))) def load_pathway_lookup() -> dict[str, str]: diff --git a/bin/validate-against-mpbiopath.py b/bin/validate-against-mpbiopath.py index 9b2d207..b29de9f 100644 --- a/bin/validate-against-mpbiopath.py +++ b/bin/validate-against-mpbiopath.py @@ -41,7 +41,10 @@ from src.argument_parser import logger # noqa: E402 from src.neo4j_connector import get_graph # noqa: E402 -MP_BIOPATH_DIR = Path("/home/awright/gitroot/mp-biopath-pathways") +# Overridable so the path is not tied to one machine; the default follows the +# same ~/gitroot layout the rest of the tooling assumes. +MP_BIOPATH_DIR = Path(os.environ.get("MPBIO_ROOT", + str(Path.home() / "gitroot" / "mp-biopath-pathways"))) DOWN, NORMAL, UP = 0, 1, 2 MAX_ITERATIONS = 50 diff --git a/specs/001-validator-fidelity/spec.md b/specs/001-validator-fidelity/spec.md index ab9a9a2..f72301c 100644 --- a/specs/001-validator-fidelity/spec.md +++ b/specs/001-validator-fidelity/spec.md @@ -32,11 +32,11 @@ generator deliberately re-represents Reactome: A validator that fails on correct output is worse than no validator: it trains the reader to ignore it, and it masks the real defects underneath. -## Architecture principle (Adam, 2026-09) +## Architecture principle (stated 2026-09) -> We want to make the LNGs in a way that represents them based on how curators -> intended to design them. And DeltaSignal would figure out how best to -> process them. +The logic networks should represent pathways as the curators intended them to +be designed; it is DeltaSignal's job to work out how best to process that +representation. Validation follows from this: the validator must check **faithfulness to curator intent under the generator's chosen representation**, not diff --git a/src/diagram_connectivity.py b/src/diagram_connectivity.py index 5b51bf4..0fa7ff2 100644 --- a/src/diagram_connectivity.py +++ b/src/diagram_connectivity.py @@ -242,9 +242,9 @@ def augment_reaction_connections(pathway_id: str, def diagram_glyph_positions(pathway_id: str) -> Dict[Tuple[str, str, str], List[int]]: """``(reaction_stId, entity_stId, role) -> [glyph_id]`` for one pathway. - Adam: *"two nodes in the reactome pathway diagram that are in the same - compartment could be the same thing but in two different places. We need - to be able to know which one the uuid was from."* + Requirement: two glyphs in the same compartment of a Reactome pathway + diagram can draw the same entity in two different places, and it must be + possible to tell which of them a uuid came from. That identity exists and this module already read it — ``x["id"]`` on each input/output/catalyst entry is the DiagramObject id, which is what the diff --git a/src/logic_network_generator.py b/src/logic_network_generator.py index 5015893..f5ddae4 100755 --- a/src/logic_network_generator.py +++ b/src/logic_network_generator.py @@ -1422,7 +1422,7 @@ def _emit_precedingevent_handoff_edges( complex on the other — so bundling makes them different nodes and the link is lost. This is NOT a heuristic: the ``precedingEvent`` edge is in Neo4j. - Rule (per Adam): for each precedingEvent pair, do nothing if the reactions are + The rule: for each precedingEvent pair, do nothing if the reactions are ALREADY connected by a shared whole entity (the curator's asserted entity is represented). Only when they share no whole entity — yet the curator says they're connected — add ONE bridge, between the output/input nodes that share diff --git a/src/resolution_validation.py b/src/resolution_validation.py index b133d89..b88497f 100644 --- a/src/resolution_validation.py +++ b/src/resolution_validation.py @@ -1,8 +1,8 @@ """Completeness checks for node_resolution.csv, in both directions. -Adam's requirement: "we need to be able to map every node in the database to -the LNG node perfectly. and same with the other way around." "Perfectly" is -not checkable, so it is expressed here as: no absence goes undeclared. +Requirement: every node in the database must map to an LNG node, and back +again. "Perfectly" is not checkable, so it is expressed here as: no absence +goes undeclared. Pure functions over already-loaded rows, deliberately free of the filesystem and Neo4j, so the negative control in diff --git a/tests/test_provenance_exports.py b/tests/test_provenance_exports.py index 17f533b..7d7e149 100644 --- a/tests/test_provenance_exports.py +++ b/tests/test_provenance_exports.py @@ -153,9 +153,9 @@ def test_glyph_id_and_diagram_are_written_together(tmp_path, monkeypatch): Glyph ids are unique only WITHIN a diagram — the same integer identifies a different drawing in another one — so a row carrying one without the other - cannot be resolved back to anything. This is the invariant behind Adam's - question: knowing a uuid came from glyph 535 is only useful if you also - know which diagram 535 belongs to. + cannot be resolved back to anything. This is the invariant behind the + original question: knowing a uuid came from glyph 535 is only useful if you + also know which diagram 535 belongs to. """ monkeypatch.setattr(m, "get_labels", lambda e: ["EntityWithAccessionedSequence"], raising=False)