Skip to content

Split the two senses written under reduces (#330) - #333

Merged
realmarcin merged 2 commits into
mainfrom
fix/330-reduces-lessens-sense
Aug 6, 2026
Merged

Split the two senses written under reduces (#330)#333
realmarcin merged 2 commits into
mainfrom
fix/330-reduces-lessens-sense

Conversation

@realmarcin

Copy link
Copy Markdown
Contributor

METPO:2007802 is defined as "donates electrons to the object, lowering its oxidation
state"
— but 30 corpus edges carried it in two different senses, and 11 asserted
something the definition doesn't support. Membrane lipid remodelling does not donate
electrons to proton leakage.

What changed

The 11 "lessens/decreases" edges are relabelled reducesdecreases and grounded to
RO:0002212 (negatively regulates), which already had a mapping row:

record edge
gut_associated intestinal peristalsis → colonization/retention in duodenum
acidotolerant membrane lipid remodeling → inward proton leakage
facultatively_acidophilic hopanoid biosynthesis → membrane proton permeability
nacl_range cyclic di-AMP → high-salt tolerance
ph_delta_high membrane lipid/porin changes → inward proton leakage
ph_delta_mid3 membrane lipid composition shifts → membrane proton permeability
ph_range_very_low inside-positive membrane potential → passive proton influx
temperature_optimum_high positive DNA supercoiling → DNA melting
plasmid_carriage compensatory mutation → plasmid fitness cost
gram_variable thin peptidoglycan layer → CV-iodide complex retention
oligotrophic streamlined genome → reduced metabolic redundancy

19 edges remain on METPO:2007802, all genuine electron donation.

Object type is not a classifier — verified, not assumed

photosystem I --reduces--> ferredoxin has a GENE_OR_PROTEIN object but is genuine
redox
("PSI oxidizes plastocyanin and reduces ferredoxin"). So the obvious
"object is not a CHEMICAL" filter would have relabelled it wrongly. Each of the 30 was read
individually. This was flagged in #330 before anyone could write that filter.

No new entailment introduced

Checked rather than assumed: RO:0002212 declares no rdfs:domain or rdfs:range, so
this cannot recreate the class of defect #301 removed. Note biolink's own regulates
does declare physical essence or occurrent — that's a different term, not used here.

The warnings are removed because there's nothing left to warn about

#329 added a KNOWN MISMATCH note to the reduces mapping row and the v9 proposal
artifact, specifically so the mismatch wouldn't land as silent precedent. Both are now
cleared, and the row is narrowed from the wide gate it inherited
(BIOLOGICAL_PROCESS|CELLULAR_LOCALIZATION|CHEMICAL|ENVIRONMENTAL_FACTOR|GENE_OR_PROTEIN|STATE
BIOLOGICAL_PROCESS|CHEMICAL|GENE_OR_PROTEIN) to the shape it actually admits.

Deliberately left wide

decreases keeps */*: RO:0002212 is a general regulation relation reached from six
corpus labels, and 3 of the relabelled edges point at a QUALITY rather than a process.
That's a mild stretch of the canonical process→process reading but carries no
declared-range violation — noted rather than silently tightened.

What was checked

just qc green · just validate-strict 477 / 0 errors · uv run pytest 421 passed ·
just verify-proposal metpo_traitmech_v9 PASS · curation events on all 11 records with
curation_history verified to sort in order · audit-predicate-domains still 0 under
the hard gate.

Closes #330.

🤖 Generated with Claude Code

METPO:2007802 is defined as "donates electrons to the object, lowering
its oxidation state", but 30 corpus edges carried it in two different
senses. 11 meant "lessens/decreases" and asserted something the
definition does not support -- membrane lipid remodelling does not donate
electrons to proton leakage.

Those 11 are relabelled from `reduces` to `decreases` and grounded to
RO:0002212 (negatively regulates), which already had a mapping row.
RO:0002212 declares no rdfs:domain or rdfs:range, so this introduces no
entailment of the kind #301 removed -- checked rather than assumed,
including that biolink's own `regulates` (domain/range "physical essence
or occurrent") is a different term this does not use.

The senses could not be separated mechanically: unlike #327's case, the
label was identical, so each edge was read. Notably object type is NOT a
classifier -- `photosystem I reduces ferredoxin` has a GENE_OR_PROTEIN
object and is genuine redox, so it stays on METPO:2007802. That is why
the naive "object is not a CHEMICAL" filter would have been wrong, and
why it was flagged in #330 before anyone wrote it.

With the corpus clean, the `reduces` row is narrowed from the wide gate
it inherited to the redox shape it actually admits, and the KNOWN
MISMATCH warning is removed from both the mapping row and the v9 proposal
artifact that goes upstream -- those existed only to stop the mismatch
landing as silent precedent, and there is no longer a mismatch to warn
about.

19 edges remain on METPO:2007802, all genuine electron donation.

`decreases` keeps its wide gate deliberately: RO:0002212 is a general
regulation relation reached from 6 corpus labels, and 3 of the relabelled
edges point at a QUALITY rather than a process. That is a mild stretch of
the canonical process-to-process reading but carries no declared-range
violation; noted rather than silently tightened.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@culturebot-reviewer

culturebot-reviewer Bot commented Aug 6, 2026

Copy link
Copy Markdown

Claude finished @realmarcin's task in 6m 19s —— View job


Review posted — changes requested

  • Read README.md / docs conventions (docs/CURATION_PLAYBOOK.md, history/README.md)
  • Review the diff (11 YAMLs, 11 pages, mapping row, v9 proposal)
  • Verify RO:0002212 grounding + label match
  • Verify the 19 remaining METPO:2007802 edges are genuine redox
  • Check graph structure, node types vs. the narrowed gate, curation history
  • Post verdict

The redox/lessens split itself is right. I read all 19 remaining METPO:2007802 edges and every one is genuine electron donation, and the narrowed gate matches them exactly — subjects only GENE_OR_PROTEIN/CHEMICAL/BIOLOGICAL_PROCESS, objects only CHEMICAL/GENE_OR_PROTEIN, with ferredoxin the sole GENE_OR_PROTEIN object. The row's "exactly one edge" note is accurate, and the point that object type was never a safe classifier is well made.

Two things to fix:

🟡 Direction inversion in data/traits/physiology/oligotrophic.yaml:176

The object node reduced_metabolic_redundancy is a negated concept — label "reduced metabolic redundancy", description "Loss of non-essential genes and metabolic redundancy under streamlining". So

streamlined_genome --RO:0002212 negatively regulates--> reduced_metabolic_redundancy

asserts that streamlining prevents the loss of redundancy, the opposite of the edge's own description ("Genome streamlining removes non-essential genes and metabolic redundancy") and of the cited Clifton et al. 2024 note. Under METPO:2007802 this edge was wrong in an obvious way; under negatively regulates it is now a well-formed claim that is backwards — the harder kind to catch downstream.

Fix either by renaming the node to metabolic_redundancy and keeping decreases/RO:0002212, or by keeping the node and using increases/RO:0002213. It is a leaf with exactly one in-edge, so either is contained. The other 10 relabelled edges are fine — each object is an unnegated quantity and each reads correctly as negative regulation.

Fix this →

🟡 Stale coverage count in proposals/metpo_traitmech_v9/metpo_proposal_properties_robot.tsv:5

The traits_addressed cell still says covers 30 causal-graph edges. It is 19 now, as the PR body itself says. The PR rewrote the observations cell on that exact row and left the count next to it. Every other v9 row's count matches its actual corpus count, so this field reads as maintained rather than approximate — and it is the artifact that goes to METPO curators.

(Separately, and not this PR's doing: METPO:2007800 claims 83 but the corpus has 81. Worth a look while you're in the file.)

Verified, not just read

  • 19 remaining redox edges enumerated individually: terminal oxidases → O₂, complex I → quinone pool, PSII → plastoquinone, PSI → ferredoxin, FNR → NADPH, arsC → arsenate, SOR → superoxide, NosZ → N₂O, AprAB → APS, DsrMKJOP → DsrC trisulfide, heme a₃-Cu_B → O₂, and the rest. No "lessens" residue.
  • Rendered pages match the YAML in both the list markup and the embedded graph JSON.
  • curation_history appends in timestamp order in all 11 records.
  • The narrowing is safe against the tooling: the type-gate columns are a forward guard applied by ground_causal_predicates.py to empty predicate_ids and are not retrospectively validated; audit_predicate_domains.py does not read them at all.

Advisory — 11 trait targets changed with no history/records/** entry, which history/README.md describes as one record per session per target. Not blocking.

Could not run just qc, just validate-strict, or pytest — this environment denied execution of those commands, so the green results in the description are taken on trust. Nothing I found statically would fail them.
· fix/330-reduces-lessens-sense

@culturebot-reviewer culturebot-reviewer Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two things to fix before this lands. The redox/lessens split itself is right — I read all 19 remaining METPO:2007802 edges and all 19 are genuine electron donation, and the narrowed gate matches them exactly.

1. Direction inversion introduced in data/traits/physiology/oligotrophic.yaml. The object node reduced_metabolic_redundancy is a negated concept (label "reduced metabolic redundancy", description "Loss of non-essential genes and metabolic redundancy under streamlining"). So streamlined_genome --RO:0002212 negatively regulates--> reduced_metabolic_redundancy asserts that streamlining prevents the loss of redundancy — the opposite of the edge's own description ("Genome streamlining removes non-essential genes and metabolic redundancy") and of the cited Clifton et al. 2024 note. Under METPO:2007802 this edge was wrong in an obvious way; under negatively regulates it is now a well-formed claim that is backwards, which is the harder kind to catch downstream. Fix either by renaming the node to metabolic_redundancy and keeping decreases/RO:0002212, or by keeping the node and using increases/RO:0002213. It is a leaf node with exactly one in-edge, so either is contained. The other 10 relabelled edges are fine — each object is an unnegated quantity and each reads correctly as negative regulation.

2. Stale coverage count in the v9 proposal. proposals/metpo_traitmech_v9/metpo_proposal_properties_robot.tsv still has covers 30 causal-graph edges on the METPO:2007802 row. It is 19 now, as the PR body itself says. The PR rewrote the observations cell on that exact row and left the count next to it. Every other v9 row's count matches its actual corpus count, so this reads as maintained rather than approximate — and it is the artifact that goes to METPO curators. (Separately and not this PR's doing: METPO:2007800 claims 83 but the corpus has 81. Worth a look while you're in the file.)

Verified, not just read:

  • All 19 remaining METPO:2007802 edges are redox (terminal oxidases → O2, complex I → quinone pool, PSII → plastoquinone, arsC → arsenate, SOR → superoxide, NosZ → N2O, etc.).
  • The narrowed gate is consistent with them: subjects are only GENE_OR_PROTEIN / CHEMICAL / BIOLOGICAL_PROCESS, objects only CHEMICAL / GENE_OR_PROTEIN. ferredoxin is the only GENE_OR_PROTEIN object in the set, so the row's "exactly one edge" note is accurate. The point about object type not being a safe classifier is well made.
  • Rendered pages match the YAML in both the list markup and the embedded graph JSON.
  • curation_history entries append in timestamp order in all 11 records.

Advisory only: 11 trait targets changed with no history/records/** entry, which history/README.md describes as one record per session per target.

I could not run just qc, validate-strict or pytest in this environment (no permission to execute them), so the green results in the description are taken on trust. Nothing I found statically would fail those gates — the type-gate columns are a forward guard applied by ground_causal_predicates.py to empty predicate_ids and are not retrospectively validated, and audit_predicate_domains.py does not read them at all.

…view)

Both findings valid.

oligotrophic.yaml's node was named `reduced_metabolic_redundancy` -- a
NEGATED quantity, "Loss of non-essential genes and metabolic redundancy".
While its in-edge was grounded to METPO:2007802 that was harmless,
because the edge was simply wrong in an obvious way. Regrounding it to
RO:0002212 turned it into a well-formed claim that is BACKWARDS:
streamlining asserted to prevent the loss of redundancy, the opposite of
the edge's own description and of the cited Clifton et al. 2024 evidence.
That is the harder kind to catch downstream, and it is a defect this PR
introduced rather than inherited.

Renamed the node to `metabolic_redundancy` with a matching label and
description, so `streamlined_genome decreases metabolic_redundancy` reads
correctly. It is a leaf with one in-edge, so the rename is contained.
RENAME_CAUSAL_NODE event records why.

That rename re-keyed one evidence-snippet baseline row
(streamlined_genome->reduced_metabolic_redundancy becomes
->metabolic_redundancy). Regenerated: exactly 1 row changes, count
unchanged at 2737, no new snippet defects. The
test_the_committed_baseline_matches_the_corpus gate caught this before CI
did, which is what it is for.

The v9 artifact said `covers 30 causal-graph edges` for reduces; it is 19
after this split. Rather than fix only the reported cell, cross-checked
EVERY v9 row against the corpus and found a second stale one: produces
claimed 83 but has 81, because #327 moved two thiosulfate edges to
RO:0001001. Both corrected; all 13 v9 rows and all 3 v8 rows now match
the corpus exactly.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@realmarcin

Copy link
Copy Markdown
Contributor Author

Both valid — and the first is a defect this PR introduced, which makes it the more important of the two.

🟡 The negated node name

Exactly right, and well diagnosed. reduced_metabolic_redundancy names a negated quantity ("Loss of non-essential genes and metabolic redundancy"). While its in-edge sat on METPO:2007802 that was harmless — the edge was simply wrong in an obvious way. Regrounding to RO:0002212 turned it into a well-formed claim that is backwards: streamlining asserted to prevent the loss, contradicting both the edge's own description and the cited Clifton et al. 2024 evidence.

Took your first option: renamed the node to metabolic_redundancy with matching label and description, keeping decreases/RO:0002212, so the edge reads correctly. Leaf with one in-edge, so contained. RENAME_CAUSAL_NODE event records the reasoning.

Worth noting the rename re-keyed one evidence-snippet baseline row — test_the_committed_baseline_matches_the_corpus caught that locally before CI did. Regenerated: exactly 1 row changes, count unchanged at 2737, no new snippet defects.

🟡 Stale coverage count — and a second one

covers 3019, correct.

Rather than fix only the reported cell, I cross-checked every v9 row against the corpus — and your parenthetical was right: METPO:2007800 claimed 83 but has 81, because #327 moved two thiosulfate edges to RO:0001001. Both corrected.

All 13 v9 rows and all 3 v8 rows now match the corpus exactly, verified programmatically rather than by eye.

On your note about the type gates

Agreed and useful: the subject_types/object_types columns are a forward guard applied by ground_causal_predicates.py to empty predicate_ids only, and audit_predicate_domains.py doesn't read them at all — so narrowing the reduces row can't retroactively fail anything. That's why the narrowing is safe to land in the same PR as the relabel.

Re-verified

just qc green · just validate-strict 477 / 0 · 421 tests pass · audit-predicate-domains still 0 under the hard gate.

history/records/

Still not added — the convention gap and whether it should be enforced is tracked in #325, filed during the v8 migration for this same reason.

@culturebot-reviewer

culturebot-reviewer Bot commented Aug 6, 2026

Copy link
Copy Markdown

Claude finished @realmarcin's task in 2m 59s —— View job


Review posted — approved

  • Verify the reduced_metabolic_redundancymetabolic_redundancy rename and edge direction
  • Verify the v9 coverage counts against the corpus
  • Re-count every v9 and v8 row, not just the two reported
  • Check the evidence-snippet baseline re-key
  • Check rendered pages + curation history
  • Post verdict

Both findings are fixed, and the second was fixed more thoroughly than reported.

Direction inversion — resolved. reduced_metabolic_redundancymetabolic_redundancy in data/traits/physiology/oligotrophic.yaml:82, with label and description rewritten to name the unnegated quantity. streamlined_genome --RO:0002212 negatively regulates--> metabolic_redundancy now agrees with the edge description and with Clifton et al. 2024. The rename is complete: no stale reduced_metabolic_redundancy reference survives anywhere except the RENAME_CAUSAL_NODE curation entry that documents it (oligotrophic.yaml:279, rendered at oligotrophic.html:526), and the rendered page matches the YAML in both the node list and the embedded graph JSON. The one re-keyed conf/evidence_snippet_baseline.tsv row is exactly the expected one — streamlined_genome->metabolic_redundancy, still a pre-existing MISSING_SNIPPET WARN, no new defect.

Coverage counts — resolved, and the audit went wider than asked. I re-counted every row against the corpus rather than trusting the claim:

claimed corpus
v9 METPO:2007800 produces 81 81 ✓
v9 METPO:2007802 reduces 19 19 ✓
v9 2007801/20078032007812 1, 21, 14, 12, 12, 8, 6, 6, 3, 2, 1 all ✓
v8 METPO:2007700 207 edges / 172 records 207 / 172 ✓
v8 METPO:2007701 13 / 13 13 / 13 ✓
v8 METPO:2007702 6 / 4 6 / 4 ✓

All 13 v9 rows and all 3 v8 rows match, record counts included. The METPO:2007800 83→81 correction I raised parenthetically was picked up rather than deferred.

🔵 One optional note, nothing blocking. The renamed node keeps node_type: BIOLOGICAL_PROCESS, but its new description — "Non-essential genes and duplicated metabolic capability" — describes a capability, not a process. The schema's CAPACITY value (src/traitmech/schema/traitmech.yaml:520: "a metabolic or functional capacity … neither a single chemical species nor a process") fits the node better under the new wording than it did under the old. Nothing fails on this: decreases keeps */* gates and no validator reads the node type here. Take it or leave it.

Advisory, unchanged: still no history/records/** entry for the 11 changed targets. Tracked in #325.

Could not run just qc, just validate-strict, or pytest — this environment denies executing them, so those green results remain on trust. Everything checkable statically holds, and the two things I asked for are done.

· fix/330-reduces-lessens-sense ·

@culturebot-reviewer culturebot-reviewer Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both findings are fixed, and the second was fixed more thoroughly than reported.

Direction inversion — resolved. reduced_metabolic_redundancymetabolic_redundancy in data/traits/physiology/oligotrophic.yaml:82, with label and description rewritten to name the unnegated quantity. streamlined_genome --RO:0002212 negatively regulates--> metabolic_redundancy now agrees with the edge description and with Clifton et al. 2024. The rename is complete: no stale reduced_metabolic_redundancy reference survives anywhere except the RENAME_CAUSAL_NODE curation entry that documents it, and the rendered page matches in both the node list and the embedded graph JSON. The one re-keyed conf/evidence_snippet_baseline.tsv row is exactly the expected one.

Coverage counts — resolved, and the audit went wider than asked. I re-counted every row against the corpus rather than trusting the claim. All 13 v9 rows match (METPO:2007800 81, 2007802 19, 2007803 21, 2007804 14, 2007805 12, 2007806 12, 2007807 8, 2007808 6, 2007809 6, 2007810 3, 2007811 2, 2007801/2007812 1). All 3 v8 rows match on both counts, including the record counts — 2007700 is 207 edges across 172 records, 2007702 is 6 across 4. The METPO:2007800 83→81 correction I raised parenthetically was picked up rather than deferred.

🔵 One optional note, nothing blocking: the renamed node keeps node_type: BIOLOGICAL_PROCESS, but its new description — "Non-essential genes and duplicated metabolic capability" — describes a capability, not a process. The schema's CAPACITY value ("a metabolic or functional capacity ... neither a single chemical species nor a process") fits it better now than it did under the old wording. Nothing fails on this: decreases keeps */* gates and no validator reads it. Take it or leave it.

Advisory, unchanged: still no history/records/** entry for the 11 changed targets. Tracked in #325.

I still could not run just qc, just validate-strict or pytest — this environment denies executing them, so those green results remain on trust. Everything I could check statically holds, and the two things I asked for are done.

@realmarcin
realmarcin merged commit 452b6de into main Aug 6, 2026
7 checks passed
@realmarcin
realmarcin deleted the fix/330-reduces-lessens-sense branch August 6, 2026 07:01
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.

~11 reduces edges use the 'lessens' sense but sit on the redox term METPO:2007802

1 participant