Retype six mis-typed dispositions, and route six real states (#334) - #351
Conversation
The recommendation going in was to check node TYPES before touching predicates, because that has been the actual defect three times running (#328's assay_measurement, #331's unmodelled acetate kinase step, #330's negated node name). It holds again: half of the STATE/CAPACITY objects here are not states at all. Their own descriptions give them away -- "Capacity of an organism to grow and survive under high hydrostatic pressure", "Ability to grow when external phosphate is unavailable", "Detoxification-mediated tolerance of arsenic oxyanions". Those describe what an organism CAN do, which is what a TRAIT is. Five nodes retyped (one carries two in-edges), six edges then take METPO:2007700 confers unchanged, because with the object correctly a TRAIT the existing relation already fits. The other six objects ARE genuine states -- a proton gradient, a community composition, an internal microoxic environment -- so retyping them would be wrong. They take RO:0002326 (contributes to), which fits because the subject genuinely contributes to the OCCURRENCE OR GENERATION of the object. That is biolink's actual wording, and it is the same test the motive-force edges FAILED in #341, where the subject powers a machine it does not generate. Getting the same relation right here and wrong there is the distinction, not an inconsistency. ENABLES_RANGE_VIOLATION: 28 -> 16. Retyping to TRAIT adds reachability anchors, so audit-graphs improved: 1535 -> 1521 findings, none new. Also widened the confers gate for ORGANELLE, which appeared once buoyancy became a TRAIT (gas_vesicle confers buoyancy) -- listed rather than left open so each new subject kind stays an explicit decision. The #322 round-trip guard caught the hand-built curation events again; 11 records re-emitted through the helper. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Claude finished @realmarcin's task in 6m 33s —— View job ReviewI ran what this environment allowed: The grounding checks pass. Two things to fix. 🟡 Two retyped TRAIT nodes duplicate traits that already exist, and are left ungrounded
This matters beyond hygiene, because it is where the audit number comes from. All 14 of the 1535→1521 drop is the anchor effect:
🟡 The playbook still says this case is unsettled
That row is exactly what this PR settles, and it is the PR that should close it: retype the disposition to 🔵 The same-kind CAPACITY nodes elsewhere are untouched: 🔵 Four edge descriptions still say "enables" under the new predicate: Advisory, not a defect: 11 files under Verdict: requesting changes on the two 🟡 items. |
There was a problem hiding this comment.
Two 🟡 items — see the detailed review comment.
-
Two retyped TRAIT nodes duplicate traits that already exist and are left ungrounded:
hhp_tolerance(pressure_optimum.yaml:56) ispiezotolerant/traitmech:000003, already in the corpus;growth_external_ph_5_5_9(ph_delta_high.yaml:78) is the same concept as that record's ownph_delta_high_trait(METPO:1000478). The playbook (docs/CURATION_PLAYBOOK.md:316-317) gives both TRAIT rows a grounding. This is also where the audit number comes from: all 14 of the 1535→1521 drop is the anchor effect — pressure_optimum's 5-node island and ploidy's 4-node island stopped being reported UNREACHABLE_FROM_TRAIT without a single edge changing, and FRAGMENTED_GRAPH still says components=2 of 9 for both.arsenic_toleranceis the one done right: it already carriedis a metal_tolerant_trait, so its anchor changed nothing. -
docs/CURATION_PLAYBOOK.md:169 still says the STATE/CAPACITY tolerance case is 'not settled — see #334', which is exactly what this PR settles, and :159 still says 33 baselined edges when it is 16.
The disposition-vs-state split itself is correct — CAPACITY is defined in traitmech.yaml:520-525 as a reservoir-of-X notion, which these nodes are not — and RO:0002326 checks out against data/raw/biolink-model.yaml:3853-3866.
…iew) The sharpest point is one I should have caught: "audit-graphs improved 1535 -> 1521" was ANCHOR ACCOUNTING, not connectivity. pressure_optimum's 5-node island and ploidy's 4-node island stopped being reported UNREACHABLE_FROM_TRAIT without a single edge changing -- they just acquired an ungrounded anchor inside them. FRAGMENTED_GRAPH still says components=2 for both, and is still 218 overall. The islands are intact. Making a metric fall without improving the graph is exactly what I should be catching rather than causing, and the PR body said the opposite. Two of the retyped nodes duplicated traits that already exist and were left ungrounded, which the playbook requires of every TRAIT row (462 of 482 TRAIT nodes carry one, so ungrounded is the exception here): - hhp_tolerance IS piezotolerant, already traitmech:000003 -> grounded to it - growth_external_ph_5_5_9 is the same concept as its own record's ph_delta_high_trait -> grounded to METPO:1000478, which makes the duplication explicit rather than leaving two unrelated-looking anchors The playbook still told curators this case was unsettled. It now gives the rule the retyping followed -- a node described as a capacity to, an ability to, or a tolerance of is a disposition, so retype and use confers, and ground it -- plus the separate row for genuine states, with the occurrence-or-generation test that distinguishes them from #341's motive-force edges. Four edge descriptions still said "enables" under the new predicate; reworded. Filed #352 for the 🔵: salt tolerance, low-pH tolerance, oxygen tolerance and growth at 4C are the same concept still typed CAPACITY, surviving only because their in-edges did not happen to violate the range -- an unrelated fact. That wants the typing rule as its trigger, not a range-violation sweep. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
The anchor-accounting point is the one that matters, and you're right — I claimed an improvement that didn't happen. 🟡 Ungrounded anchors, and the audit number" Making a metric fall without improving the graph is precisely what I should be catching rather than causing. The PR body is corrected to say so plainly. On the two duplicates — both grounded, and grounding was owed anyway: 462 of 482 TRAIT nodes carry one, so ungrounded is very much the exception, not the norm I'd implicitly assumed.
🟡 The playbookFixed. It now gives the rule this PR actually followed — a node described as a "capacity to", an "ability to", or a "tolerance of" is a disposition, so retype it and use 🔵 Same-kind CAPACITY nodes elsewhereFiled as #352. Your framing is the important part: 🔵 Four descriptionsReworded.
|
|
Claude finished @realmarcin's task in 4m 12s —— View job ReviewRe-checked The corrected audit claim reproduces. The new playbook rows are the rule this PR actually followed, including the occurrence-or-generation carve-out against #341. Two things still to fix, one of them new in this commit. 🟡 The
🟡 The two table rows were rewritten, but the sentence above them still reads:
It is 16 — that is what both 🔵 🔵 The grounding change added no Verdict: requesting changes on the two 🟡 items. The typo is the one that matters — it is corrupted data on a live page. |
There was a problem hiding this comment.
Two 🟡 items — see the detailed review comment.
-
NEW in 9994ee7: the
enables→contributes toreword mangled the description at data/traits/morphology/branched_shaped.yaml:195 — "contributes to proper powth and normal branch spacing". It ate "polar gro", so the description no longer names its own object node (proper polar growth and normal branch spacing, :93), and it shipped to pages/traits/morphology/branched_shaped.html:234. Free-text descriptions are not validated, so qc will not catch it. The other three rewords are clean. -
docs/CURATION_PLAYBOOK.md:159 still says "33 pre-existing edges are baselined". It is 16 — in reports/predicate_domain_audit.tsv, in conf/predicate_domain_audit_baseline.tsv, and in the PR body. Only the table rows were rewritten.
Everything else checks out. traitmech:000003 is piezotolerant and METPO:1000478 is pH delta high; both labels match the nodes they now ground. just audit-graphs reproduces 1521 baselined / 0 new with a clean tree, UNREACHABLE_FROM_TRAIT 1303 vs 1317 baselined and FRAGMENTED_GRAPH unchanged at 218 — the corrected anchor-accounting wording in the body is accurate. The new playbook rows are the right rule, including the occurrence-or-generation carve-out against #341.
The reword script matched on a 60-character prefix and substituted into it, which turned "proper polar growth and normal branch spacing" into "proper powth and normal branch spacing" in branched_shaped.yaml. Repaired, and swept every edge this PR touched for the same signature -- that is the only one. A regex that edits prose it does not parse was the wrong tool for four descriptions; doing them by hand would have been faster and safer. CURATION_PLAYBOOK.md still said "33 pre-existing edges" for ENABLES_RANGE_VIOLATION. It is 16 after this PR -- and the page is where a curator learns whether their edge shape is allowed, so a stale count there misstates how settled the area is. Third stale-prose spot in this PR, which is the same pattern #350 ended on. Added GROUND_CAUSAL_NODES events for the two groundings, per the 🔵. They were a real change to the records, not just metadata: an ungrounded TRAIT node still counts as a reachability anchor, which is how the audit number moved without the graph changing. Folded the other 🔵 into #352: nothing detects two nodes sharing a grounding within one graph, which is the machine-readable signature of exactly the duplication that issue is about, and would have found the ph_delta_high case without anyone reading descriptions. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Both fixed. 🟡 The mangled descriptionMy reword script matched on a 60-character prefix and substituted into it, turning "proper polar growth and normal branch spacing" into "proper powth and normal branch spacing". Repaired, and I swept every edge this PR touched for the same signature — that's the only one. The honest lesson: a regex that edits prose it doesn't parse was the wrong tool for four descriptions. Doing them by hand would have been faster and safer, and I'd have seen the damage immediately. 🟡
|
|
Claude finished @realmarcin's task in 2m 2s —— View job ReviewBoth 🟡 items from the last round are fixed, and the repair introduced nothing new. The mangled description. The stale count. Re-verified. The two 🔵 The duplicate Verdict: approve. The disposition-vs-state split was correct on the first pass and the three rounds since have been about grounding the anchors and unwinding the prose damage; both are done. |
There was a problem hiding this comment.
Both remaining items are fixed. branched_shaped.yaml:195 now reads 'contributes to proper polar growth and normal branch spacing', matching its object node label at :93, and it propagated to pages/traits/morphology/branched_shaped.html:234 and the embedded graph JSON. I swept all five descriptions this PR adds under data/traits/** — the other four (pressure_optimum.yaml:96,115,135, ploidy.yaml:107) are clean, so the claim that this was the only instance holds. CURATION_PLAYBOOK.md:159 now says 16, matching both reports/predicate_domain_audit.tsv and conf/predicate_domain_audit_baseline.tsv.
just audit-graphs reproduces 1521 findings / 1521 baselined / 0 new with a clean tree; both groundings hold on the generated pages and neither node remains in reports/node_grounding_residual.tsv. validate-strict and qc were blocked by this runner's bash permissions again.
The GROUND_CAUSAL_NODES entries usefully record that an ungrounded TRAIT node still counts as a reachability anchor. The duplicate METPO:1000478 within ph_delta_high, and the absent detector for it, are tracked in #352.
…352) (#353) * Detect the typing inconsistency instead of guessing at seven records (#352) #352 asks for a sweep. Doing it by hand first showed why a sweep is the wrong deliverable: each candidate CAPACITY node turned out to duplicate its OWN record's trait -- salt_tolerance beside METPO:1000625, low_ph_tolerance beside METPO:1000232, growth_at_4c beside METPO:1000618 -- so retyping them to TRAIT without merging would recreate exactly the ungrounded-duplicate-anchor problem #351's review caught. That is seven modelling decisions, not a mechanical pass. So this adds the two checks that make the class visible and non-growing, in the audit that already has the ratchet machinery: DUPLICATE_GROUNDING two nodes in one graph with the same grounding -- the machine-readable signature of one concept modelled twice DISPOSITION_MISTYPED a CAPACITY or STATE node whose own DESCRIPTION reads as a disposition ("capacity to", "ability to", "tolerance of"), which is a TRAIT Both found more than my hand sweep did, which is the argument for building them rather than doing one pass: - DUPLICATE_GROUNDING found catalase/catalase_function sharing GO:0004096 and urease/urease_function sharing GO:0009039. Neither was known; both are a protein node and a function node modelling one thing. Only the ph_delta_high case from #351 was on anyone's list. - DISPOSITION_MISTYPED found 8 where I had found 6, including oxygen_tolerance -- my pattern wanted "capacity to" and the record says "Capacity OF A CELL to" -- and elongation_capacity in sphere_shaped. Anchored on the DESCRIPTION rather than the label on purpose: the label is usually just the concept name ("buoyancy"), while the description is where the disposition shows. All 11 baselined, since each needs a per-record decision. Canaried: a new CAPACITY node described as a disposition exits 1. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Make the heuristic principled, and let DUPLICATE_GROUNDING ratchet (PR #353 review) Four findings, all correct. The docstring said the check reads the description "rather than the label", and the code read both. Now description-only, which is what the rationale actually argues for -- a label is usually just the concept name. DUPLICATE_GROUNDING did not ratchet on growth. _key takes the leading whitespace-delimited token of detail as the baseline discriminator, and the detail led with the CURIE, so a THIRD node joining the same grounding kept the key stable and baselining two would have silently forgiven three. Now leads with the node count, which is exactly the reasoning FRAGMENTED_GRAPH records a few lines below and which I had read without applying. A test pins that two and three nodes key differently. The pattern's precision was accidental. ph_optimum.yaml's "Capacity of cytoplasmic buffers (e.g. ...) to absorb pH fluctuations" is a genuine reservoir CAPACITY and escaped only because the dots in "e.g." stopped the character class -- a right answer for a reason an unrelated cleanup would erase, and under --fail-on new that is CI failing with a wrong diagnosis. The capacity/ability arms now require the capacity to be ORGANISM-scoped: bare, or of a cell/organism/bacterium/microbe. Verified it still excludes the reservoir case WITH THE PARENTHETICAL REMOVED, and still catches all eight real ones. Documented why QUALITY is out of scope: carboxydotrophic's oxygen_tolerance is "Ability of an ENZYME to function in the presence of O2", a property of a protein rather than something an organism can do, while the same node_id typed CAPACITY in oxygen_preference IS organism-scoped and is flagged. Widening would need a distinction this heuristic does not make. Both blocks moved above the FRAGMENTED_GRAPH rationale comment, which they had been inserted into the middle of. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Key DUPLICATE_GROUNDING on the count AND the CURIE (PR #353 review round 2) Leading the detail with the count closed one fail-open and opened its mirror. _key takes the leading whitespace-delimited token, so with `nodes=2` in front, two DIFFERENT groundings each duplicated across 2 nodes in the same graph collapse onto one key -- freezing one silently forgives the other. The previous round had the same bug pointing the other way. Only one part varying is not enough; both are now in the token: `nodes=2;grounding=METPO:1000478`. A test writes two 2-node groundings in one graph and asserts two distinct keys. Confirmed it fails (1 == 2) against the count-only form and passes here, so it pins the fix rather than restating it. Widened the disposition scope nouns with strain|species|isolate|archae*, which the review offered as cheap and are ordinary in this corpus. Findings unchanged at 8 + 3. Baseline and report regenerated: the discriminator changed, so the three DUPLICATE_GROUNDING keys are rewritten. Same 1532 findings. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
#334) (#355) * Repair the last 16 enables edges whose object cannot satisfy the range (#334) biolink gives enables (RO:0002327) the range 'biological process or activity', which of CausalNodeTypeEnum only BIOLOGICAL_PROCESS, PATHWAY and MOLECULAR_FUNCTION satisfy. #315 widened the audit from its original TRAIT-only test to that full range and surfaced 33 edges; #351 took 17. These are the remaining 16, and ENABLES_RANGE_VIOLATION is now 0. THERE WAS NO SINGLE SWEEP. Six idioms are mixed together and the object type does not classify them - the same lesson `reduces` recorded when its two senses turned out not to be separable that way. Every decision is in DECISIONS in the migration script with the sentence from the record that justifies it: - 4 needed only REPOINTING, because the process the subject actually feeds was already in the graph. cytoplasmic_na was pointed at the Mrp complex while the record said "the substrate that sustains alkaliphile ANTIPORT activity", and that antiport node sits three lines above. - 1 was simply BACKWARDS, and its own description said so: "high-affinity terminal oxidase ENABLING oxygen respiration at low O2 tensions" had been written as oxygen enables the oxidase. Reversed onto the graph's existing aerobic_respiration node, which is both domain- and range-correct. - 3 had the wrong NODE TYPE rather than the wrong predicate. An object labelled "even peptidoglycan distribution" is described as "evenly distributed INSERTION of peptidoglycan" - a process. "Treatment resistance and persistence" is a disposition, not a quality. And buoyancy was typed QUALITY here while intracellular_inclusion.yaml already typed the same concept TRAIT - a typing inconsistency of exactly #352's shape, resolved toward TRAIT. - 3 moved onto existing relations that fit better than enables ever did: `produces` for an operon making a chemical, `has output` for a PATHWAY subject (the documented activity/non-activity split), and `transports` for FtsW, which FLIPS lipid II rather than enabling it. - 2 were never causal: Scy is "a COMPONENT of the tip-organizing centre" (part of), and Hfq increases RpoS (promotes). - 5 needed a term that does not exist upstream. MINTED METPO:2007900 `powers` for those 5, proposed in proposals/metpo_traitmech_v10. An ion motive force, a proton motive force, or torque generation, operating a molecular machine. RO has no relation for it because RO models energetics at the PROCESS level while all five objects are protein complexes - the same gap `exports`/`imports` were minted for. The label is not a coinage: all five edge descriptions already used the verb "power". object_types is gated to GENE_OR_PROTEIN because an energetic driver feeding a process satisfies enables' range already and must stay there; leaving it open would let the term absorb edges that are not broken. Two gates widened deliberately and recorded in the table: GENE_OR_PROTEIN added to `transports` subject_types (a flippase is a protein, not a pathway), TRAIT added to `confers` (a structural trait conferring a functional disposition, which the corpus already carried and lacked a subject type for). EDITS ARE STRUCTURAL, NOT TEXTUAL. All 15 files round-trip byte-identical through emit_trait_yaml, verified before touching them, so they are parsed, modified and re-emitted. Earlier migrations spliced raw lines and broke YAML three times and once turned "proper polar growth" into "proper powth". I made two mistakes editing predicate_grounding.tsv and caught both by reading the diff rather than the exit code. csv.writer with escapechar='\\' rewrote the "" quote-doubling in FOUR UNRELATED rows into \", corrupting data it had no business touching. And I filled the new row's columns 4-6 from their names instead of from a real row: they are the SSSOM mapping predicate, source ontology and match confidence, not the causal predicate. Redone with QUOTE_MINIMAL and the columns copied off an existing row; the diff is now exactly 2 changed rows and 1 added. MEASURED, not predicted: ENABLES_RANGE_VIOLATION 16 -> 0, MICROBE_DOMAIN_ON_NONORGANISM stays 0, audit-graphs unchanged at 1533 findings (218 FRAGMENTED_GRAPH, 1303 UNREACHABLE_FROM_TRAIT) - the repairs repointed edges without stranding a node. The only baseline churn is key moves: two evidence-snippet findings and ten gas_vesicle UNREACHABLE details that now name both TRAIT anchors because buoyancy became one. Same node set, same counts, verified by diffing them. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Cite what the edge now claims, and count the edges the gate really grounds (#355 review) Four findings, all correct. THE REVERSED CYTOCHROME BD EDGE. This was the one place in the PR where a CLAIM changed rather than a predicate, and I rewrote it to "high-affinity terminal oxidase, sustaining aerobic respiration at the low O2 tensions where low-affinity oxidases cannot operate" while leaving the evidence untouched. The retained quote is about WHICH oxidase is active given the available acceptor and says nothing about affinity or low O2, so the new assertion was uncited; the high-affinity reading came from the node's own description, which is not itself sourced. Rewritten to what the quote actually supports rather than attaching a citation I do not have, and the evidence note's trailing clause, which still described the deleted edge, now describes this one. POWERS GROUNDS SEVEN EDGES, NOT FIVE. Verified rather than taken on faith: the gate also matches ph_optimum_mid2.yaml and carboxydotrophic.yaml, whose proton_motive_force -> ATP synthase edges predate #334 and read correctly under the definition. My own reports showed it and I did not read them. Nothing needs regrounding, but three statements understated it and the round-trip plan is the one that would have cost someone: it said the placeholder lives in "the five edges' predicate_id", so whoever swaps in the minted ID would have missed two that a grounding pass had stamped. Counts corrected in the mapping note, the ROBOT template and the proposal, with both records named. While counting I also confirmed the gate behaves as designed: of the four `powers` edges left blocked_by_node_type, THREE are blocked correctly - their objects are processes, which satisfy enables' range and belong on RO:0002327. The fourth is blocked only because phototrophic.yaml types proton_motive_force as CAPACITY where carboxydotrophic.yaml types the byte-identical assertion's subject STATE. That concept carries four different node types across the corpus and this PR is what turned the inconsistency into something that decides groundings, so it is filed as #356 and referenced from the proposal rather than left to be rediscovered. HFQ. The migration argued this edge does not assert anything about translation - the object is the sigma factor - and then left the description reading "Hfq enables sRNA-dependent translation of RpoS". True sentence, wrong edge. Now states what `promotes` asserts. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Record the provenance of this migration (#325) #325 landed as "enforce it", and I said in this PR's review response that if it did, this change is one of the ones that should get a retrospective record. Following through rather than leaving main with a grandfathered gap on the first day the gate exists. ONE record for the whole change, per the granularity #325 settled, and targeting the migration script rather than any of the 15 records it edited: the script IS the artifact that says what drove the change, and it is reviewable in a way that 15 copies of the same sentence are not. The per-file curation_history: blocks stay as they are. They record what changed in each file; this records which model, which tool, which issue and which PR - none of which CurationEvent has a slot for. Scaffolded with `just new-history` and validated with `just validate-history` (no issues found). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Take history/README.md back out of this PR The previous commit staged it by accident: I switched branches with #325's working-tree changes still present, and `git add history/` picked up the README edit along with the record I meant to add. That edit is #325's policy change and belongs in #325's PR, not here. Restored to main's content, forward-only. The commit that introduced it is already pushed, and rewriting a pushed branch to hide a mistake is worse than a two-commit trail that shows it. The history record itself, which IS this PR's business, stays. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Make the idiom tally add up to 16 (#355 re-review) The record said "Six idioms: 4 repointed ... 5 powers", which sums to 18, two lines below "Repaired 16 edges". Two errors that nearly cancelled: the repoint count was 1 rather than 4, and the manifests as edge (intracellular_inclusion) was missing from the enumeration entirely. Recounted from DECISIONS, which is the source of truth: 1 repoint, keep enables ph_range_high 1 reversed facultative_oxygen_preference 3 retyped human_pathogen, gas_vesicle, cell_width_large 3 produces / has output / transports 2 part of / promotes 1 manifests as intracellular_inclusion 5 powers =16 Fixed in the record NOW rather than after merge, because history/README.md says a record is written once and never edited - a correction afterwards costs a whole second record, and the reviewer was right that this is the one artifact here where that is true. The same two errors were in the PR body table and, worse, in docs/CURATION_PLAYBOOK.md, which asserted "four of #334's sixteen needed only repointing" as guidance for future curators. Corrected: one needed only that, and a second was fixed by reversing it onto a node already present. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Correct two more #334 counts in the playbook (#355 re-review) Both wrong, both added by this PR, both in the paragraph the last commit had just edited without checking the rest of it. "five of the sixteen edges had the right predicate and the wrong node type" - three had the wrong node type, and of those exactly ONE also had the right predicate (cell_width_large, which keeps enables). The other two moved to confers as well. The reviewer's sharpest point is that the sentence's own second example undercut it: "tolerance to antimicrobial treatment" is treatment_resistance_persistence, whose predicate DID change, so it was never an instance of the thing the sentence claimed. Rewritten so the number supports the heading it sits under - check the node type first, because rewriting the predicate around a mistyped node preserves the error and hides it. "Twice in #334 the edge was simply backwards" - once. Only facultative_oxygen_preference rewrites a subject, and it is the one the sentence then quotes. Line 194, which I had just corrected, already said as much from the other side. This is the third round of counting errors in the same file, so I stopped counting by hand and re-derived every #334 claim the playbook now makes straight from DECISIONS: three of the sixteen had wrong node type True one of those needed only a retype True once backwards True one needed only repointing True The playbook is the artifact where a wrong number misdirects a future curator rather than merely misrecording history, which is why it deserved that check before the first correction rather than after the second. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
The recommendation going in was check node types before touching predicates, because
that has been the actual defect three times running — #328's
assay_measurementtypedEXPERIMENTAL_FACTORwhile its description said "Investigation process", #331's acetatekinase step that existed only in prose, #330's negated node name.
It holds again: half of these STATE/CAPACITY objects aren't states at all.
Six were mis-typed dispositions
Their own descriptions give them away:
Those describe what an organism can do, which is what a
TRAITis. Five nodes retyped(one carries two in-edges), and the six edges then take
METPO:2007700confersunchanged — with the object correctly a TRAIT, the existing relation already fits. No new
terms.
Six are genuine states
A proton gradient, a community composition, an internal microoxic environment — retyping
those would be wrong. They take
RO:0002326contributes to, which fits because thesubject genuinely contributes to the occurrence or generation of the object. That's
biolink's actual wording.
That's the same test the motive-force edges failed in #341, where the subject powers a
machine it does not generate. Getting the relation right here and rejecting it there is the
distinction, not an inconsistency — and it's why these needed reading rather than sweeping.
Result
ENABLES_RANGE_VIOLATION: 28 → 16.What was checked
audit-graphs: 1535 → 1521, and that drop is ANCHOR ACCOUNTING, not connectivity.pressure_optimum's 5-node island andploidy's 4-node island stopped being reportedUNREACHABLE_FROM_TRAITwithout a single edge changing — they acquired an anchor insidethem.
FRAGMENTED_GRAPHis unchanged at 218 and still sayscomponents=2for both.The islands are intact. Corrected after review; the original wording claimed an
improvement that did not happen.
confersgate forORGANELLE, which appeared oncebuoyancybecame aTRAIT (
gas_vesicle confers buoyancy) — listed rather than left open, so each new subjectkind stays an explicit decision.
just validate-strict477 / 0 errors ·just qcgreen · 472 tests pass.re-emitted through the helper.
Partial burn-down of #334 (16 remain: GENE_OR_PROTEIN 8, QUALITY 4, CHEMICAL 3,
CELLULAR_LOCALIZATION 1).
🤖 Generated with Claude Code