Skip to content

Add galvanotaxis with source-bounded flagellar motility evidence - #1642

Merged
realmarcin merged 2 commits into
mainfrom
add-galvanotaxis-trait
Oct 4, 2026
Merged

realmarcin merged 2 commits into
mainfrom
add-galvanotaxis-trait

Conversation

@realmarcin

@realmarcin realmarcin commented Oct 3, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Add traitmech:000581 galvanotaxis (PHYSIOLOGY, CLASS, PROPOSED) beneath
METPO:1000702 motile, with two strain-qualified examples and a five-node,
four-edge flagellar-motility graph. Reserve METPO:1053500 in proposal v458.

The definition requires active movement in response to an electric field.
It does not treat fixed-cell electrophoresis as galvanotaxis or prescribe a
universal anode/cathode direction. The graph does not claim a proven electrical
sensor or infer individual FliC necessity from a fliC/fljB double mutant.

Evidence And Authorities

  • Definition: DOI:10.1101/sqb.1988.053.01.006, free publisher Excerpt at
    https://symposium.cshlp.org/content/53/23.short; paywalled full text not accessed.
  • K-12 behavior: DOI:10.1128/jb.178.4.1113-1119.1996, PMID:8576046;
    primary abstract inspected, not full text.
  • Mechanism and IR715 behavior: DOI:10.1038/s41564-024-01778-8,
    https://www.nature.com/articles/s41564-024-01778-8, Version of Record dated
    August 20, 2024. Publisher full text, Figure 5, Methods, Extended Data,
    Supplementary Table 1 and source workbook inspected. No video was viewed.
  • Structural family: https://www.ebi.ac.uk/interpro/entry/InterPro/IPR001492/;
    the issuing API resolves IPR001492 as the Flagellin family, not a terminal domain.
  • NCBI resolves NCBITaxon:83333 to E. coli K-12 and NCBITaxon:588858 to
    Salmonella enterica subsp. enterica serovar Typhimurium str. 14028S.
    Green ST is IR715 plus pGFT/RalFc, not the SW473 flagellar mutant or LT2.
  • UniProtKB:A0A0F6B2U2 is unreviewed 14028S FliC, entry 42, sequence 1,
    resolved via https://www.ebi.ac.uk/proteins/api/proteins/A0A0F6B2U2.
    https://rest.uniprot.org/proteomes/UP000002695.json confirms its reference
    proteome. UniProtKB REST protein requests failed during source retrieval.
  • GO:0071973 grounds the flagellar process, not the organismal trait.
    QuickGO galvanotaxis/electrotaxis searches returned no exact term; broader
    MeSH Taxis Response was rejected as an exact xref. Existing predicates are
    RO:0002211, RO:0002326 and METPO:2007700.

All seven evidence items have directly source-matched contiguous snippets;
aggregate quotations stay within 25 words per source. Europe PMC's abstract-only
checker returned 1 VERIFIED, 3 NOT_IN_ABSTRACT and 2 UNRESOLVED; the latter five
are not proof of paraphrase and were checked directly against publisher sources.

Boundaries And Provenance

  • Novelty and allocation searches included ignored and hidden files. Fresh
    seeding returned 399 IDs (344 present, 55 absent); both frozen release-review
    tables were read. A cable-bacteria research mention is not an exact trait.
  • Open discussions retain charge/orientation-model uncertainty and the
    differing directedness signs in the source workbook versus published text.
    Direction labels agree; no numeric cosine values or correction are imported.
  • The writer defaults to dry run, validates before writes, refuses drift and
    records a MINTED_TRAITMECH_ID event. Repository history:
    history/records/galvanotaxis/2026-10-03T232431Z-codex-3a5ed2.yaml.
  • Corpus count is 976. All 975 existing trait pages have footer-only changes
    except motile, which additionally gains the new child link. Reports,
    discussions, priority and QC dashboards were regenerated through maintained
    recipes; shared generator source matched reviewed claw 6d0a6fb (139 files).
  • After fixing PR #1642: preserve failed UniProt REST audit result for galvanotaxis FliC #1643, the tracked UniProt report adds the actual HTTP 503 row
    from the maintained REST audit, not an alternate-authority pass. The EBI
    cross-check remains only in the trait's source provenance. All 142 historical rows remain
    byte-identical, including 110 pre-existing findings; they are not claimed as
    freshly revalidated. The full live REST audit exited 1: 143 uses, 112 unique
    accessions, 134 transport failures (114 HTTP 503, 20 timeouts), five older
    entry-version mismatches and four clean uses. The FliC request returned 503.
    Failed lookups also produce empty-metadata comparison flags; those are not
    evidence of biological identity mismatches. This separate temporary report
    did not overwrite the tracked historical observations. No full REST pass is claimed.
  • Exact configured embedding inputs and alias path are unavailable. Existing
    embedding artifacts are preserved; rendered coverage is 477/976 (48.9%).
  • Protected spore_germination YAML and all older trait YAMLs are unchanged.

Validation

Passed: ten focused tests; direct LinkML and strict record validation; history
schema/links and committed-diff provenance; proposal verification, cross-cohort
coverage and ROBOT/ELK reasoning; graph structure, predicate domains and
protein/taxon coverage; source and research-artifact checks; Ruff; whitespace
check excluding only the required trailing ROBOT TSV header cells.

Live NCBI: 698 examples resolved, zero errors and 24 older-record label warnings.
Playwright: 1440px and 390px, five nodes/four edges, protein tooltip, no page
errors, no horizontal overflow or evidence overlap; screenshots inspected.

Committed-tree just qc and identifier-label validation passed on the initial
head. Full local pytest passed there: 1,831 tests, two dependency deprecation
warnings, 938.24 seconds. The #1643 fix changes only the report, one regression
test and skill guidance: all 19 focused tests pass, Ruff and committed history
pass. Final-head local just qc passed. All eight final-head PR checks passed;
CI pytest run 37163196269 reports 1,832 passed, two warnings in 388.34 seconds.
Use the native merge queue; delete branches only after actual MERGED state.

Review Receipts

  • Author-side review initially missed the REST-report provenance defect.
    Independent review found it; issue PR #1642: preserve failed UniProt REST audit result for galvanotaxis FliC #1643 and commit d2bb48f address it.
  • Copilot review request was accepted; no submitted Copilot review observed yet.
  • Independent Claude review: run 37162537461 completed successfully and
    submitted CHANGES_REQUESTED (review 5403506805) on the initial head.
    Re-review run 37163219590 completed successfully and submitted APPROVED
    (review 5403529808) on d2bb48f.
    No new defect or inline finding remained. The reviewer was offline;
    live-source and verbatim checks were performed by the author, not independently
    confirmed through network access by either review round.
  • The uncertain InterPro snippet concern was checked again against a fresh
    issuing API response: exact contiguous match in metadata.description text.
  • Targeted PR Shepherd: run 37162538898 completed successfully, found the PR
    unstuck and intentionally posted nothing; it did not perform a code review.
  • The approving review's optional future generator suggestion is retained in
    the review: suppress empty-metadata mismatch flags after transport errors.
    This PR preserves the actual maintained output and documents its limitation;
    it does not change the resolver's comparison semantics.

Fixes #1643.

Merge And Cleanup

  • Enqueued normally at 2026-10-04T00:01:57Z, with an exact-head guard and no
    admin bypass or early branch deletion.
  • All eight merge-group checks passed on
    586532f48d5b74c230c125b09411bef5df66c1fb. Queue pytest run 37163659769
    reports 1,832 passed, two warnings in 385.41 seconds.
  • Actual MERGED state confirmed at 2026-10-04T00:09:42Z with that commit.
    Its tree 5d33dfd10f4587f272f1112022778c49b1d78c26 matches the approved head.
  • Issue PR #1642: preserve failed UniProt REST audit result for galvanotaxis FliC #1643 closed as completed at 2026-10-04T00:09:44Z.
  • Remote feature branch deleted with an exact-head lease; remote absence and
    absence of local/tracking refs verified. Local main is clean and 0/0 against
    origin/main. No review-source or service-availability limitation was hidden.

@realmarcin

Copy link
Copy Markdown
Contributor Author

Local adversarial review: checked trait novelty (including ignored/hidden files), motile parent scope, K-12 versus IR715/14028S strain identities, double-mutant versus individual-FliC claims, family versus domain grounding, all seven verbatim snippets, proposal/header/allocation parity, and generated artifact scope. No actionable new curation defect found. Explicit limits remain: the graph is not a complete electrical-orientation mechanism; workbook/paper coordinate signs are not reconciled or imported; 1988 and 1996 access is excerpt/abstract only; full UniProt REST audit failed mostly on transport while the new EBI/proteome snapshot passed. All 975 older trait pages are footer-only except the expected motile child link; no older trait YAML changed. This author-side review is not independent approval.

@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.

🟡 IMPORTANT — reports/uniprot_grounding_audit.tsv:110 records a UniProt resolution that did not happen

The added row for A0A0F6B2U2 is a clean success across the board: status=unreviewed, primary_accession_match=YES, taxon_match=YES, entry_status_match=YES, entry_version_match=YES, sequence_version_match=YES, proteome_ids=UP000002695, and an empty finding.

That report has exactly one generator, scripts/audit_uniprot_grounding.py, and exactly one authority: API on line 33, pinned to rest.uniprot.org/uniprotkb/<acc>.json. On a 503, fetch() returns status error with uniprot_name set to HTTP 503, every _same() comparison collapses to NO, and result_row() emits UNIPROT_ERROR plus the mismatch findings.

By the account given in this PR, that is what happened: "The FliC request returned 503", and the evidence note in the record itself says "UniProtKB REST protein requests failed during retrieval; the EBI Proteins API supplied the metadata." So the committed row cannot have come from the generator — the generator has no EBI code path. It was assembled from a different authority and written into a generated artifact, which is what the repository contract forbids.

This matters beyond bookkeeping: the tracked report currently contains zero failure rows — grepping it for UNIPROT_ERROR or HTTP 5 returns 0. It reads as a table of verified resolutions, so a clean row there is a positive assertion that this accession was checked against UniProt REST and passed. It was not.

Either drop the row and leave the accession unaudited until a REST pass succeeds, or commit the row the generator actually produces. Do not hand-place a pass verdict the gate never returned. The EBI cross-check is fine as provenance — it already lives in the evidence notes of the record, which is the right place for it.

What I could not verify, and am not scoring

This environment has no network, so I could not check the seven snippets verbatim, resolve the three DOIs, or confirm that NCBITaxon:588858 is the 14028S strain. That is a gap in my review, not a defect in yours.

One snippet is worth a character-for-character re-read before merge: Flagellin is the subunit protein that polymerises to form the flagella (the contributes to edge). The British polymerises and the InterPro register are right, but the clause reads smoothed — that where entry abstracts of this kind usually run which, and an ending that stops short of the usual the filaments of bacterial flagella. If it is a trimmed near-quote rather than a contiguous substring, it fails the snippet policy. I could not establish either way.

What checks out

  • just audit-graphs: 0 new findings, 0 blocking; connectivity 129/129 components, 1567/1567 nodes attached. The five nodes are all wired, every edge subject and object resolves to a declared node_id, and the trait node is reachable.
  • just validate-history: 1003 records, 0 invalid. History record present under history/records/galvanotaxis/.
  • Groundings corroborated against the reviewed mappings already in the repository rather than taken on faith: GO:0071973 = bacterial-type flagellum-dependent cell motility and InterPro:IPR001492 = Flagellin both match mappings/node_grounding.tsv:176 and :62. The flagellar motility node label is an exact match to the mapped label. modulates to RO:0002211, contributes to to RO:0002326, and confers to METPO:2007700 all match mappings/predicate_grounding.tsv, and BIOLOGICAL_PROCESS -> TRAIT is within the declared domain and range for confers.
  • Every README count is live-accurate: 976 trait files, 97 physiology, and 461 PROPOSED / 427 REVIEWED / 50 DEPRECATED / 38 SEEDED corpus-wide.
  • traitmech:000581 is unused elsewhere; METPO:1053500 does not collide in data/raw/metpo.owl, which also contains no galvanotax or electrotax class, so the novelty claim holds. The block follows 1053400 from v457.
  • METPO:1000702 motile is a defensible and notably tighter parent than the one chemotaxis uses (METPO:1000059 phenotype), and METPO has no taxis class to prefer.
  • scripts/add_galvanotaxis_trait.py honours the mutation contract: dry run by default, write_validated_trait, record_curation_event, and a refuse-on-drift comparison before --apply.
  • The scope discipline is the strongest part of this change. Bounding the graph to the flagellar-motility branch, declining to infer individual FliC necessity from a fliC/fljB double mutant, keeping host CFTR out, and parking the source-workbook cosine-sign disagreement in an open CURATION_TODO instead of importing or silently correcting the numbers — that is the right call on all four, and the kind of restraint that is easy to skip.

@realmarcin

Copy link
Copy Markdown
Contributor Author

Addressed review 5403506805 in d2bb48f (issue #1643). The tracked A0A0F6B2U2 row now exactly matches the completed maintained REST audit: status=error, HTTP 503, and its emitted findings. The 142 pre-existing rows are byte-identical; the EBI cross-check remains in evidence notes only. Added a regression test exercising the actual fetch() HTTP 503 path through audit_uses() and write_report(), plus an add-trait skill rule preventing alternate-authority success substitution. All 19 focused tests, Ruff and committed-history checks pass; full QC/CI are rerunning.

The InterPro snippet concern is not a defect: I re-fetched https://www.ebi.ac.uk/interpro/api/entry/interpro/IPR001492/ and verified the stored snippet is a literal contiguous substring of metadata.description[0].text, including the word that and the stated ending. No snippet rewrite is needed. This is the InterPro family description, not the differently worded UniProt annotation.

Requesting a fresh independent review of the corrected head; no merge while the changes-requested verdict remains outstanding.

@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.

Approving. I found no defect.

What I checked, and how

Ontology grounding — all six CURIEs resolve correctly and the labels match:

  • METPO:1000702 resolves in data/raw/metpo.owl to motile ("A motility in which an organism has the ability to move independently using metabolic energy"). This is the right parent, and notably a tighter one than chemotaxis/magnetotaxis, which are still parented to the generic METPO:1000059 phenotype.
  • GO:0071973 → bacterial-type flagellum-dependent cell motility, RO:0002326 → contributes to, RO:0002211 → regulates (the documented closeMatch target for modulates in mappings/predicate_grounding.tsv:66), METPO:2007700 → confers with BIOLOGICAL_PROCESS in subject_types and TRAIT as the gated object. All already in the mapping tables and therefore covered by the blocking label-correspondence gate, which passes.
  • InterPro:IPR001492 is ignored_prefixes in conf/id_label_targets.yaml so it is not machine-resolved, but Flagellin matches the reviewed entry in mappings/node_grounding.tsv:62 and the existing use in spirochete_shaped.yaml.

Causal-graph structure — 5 nodes, 4 edges, every edge endpoint declared, the trait node reachable from all four others. just audit-graphs reports 74 findings, 74 baselined, 0 new, 0 blocking, and 1567/1567 nodes attached. The new connectivity row (5/1/5/5) is consistent.

Numbers — every README edit is exactly right against the live corpus: 97 physiology records, 53 carrying graphs, 51 PROPOSED / 45 REVIEWED / 1 SEEDED, 976 total, 718 graphs corpus-wide.

Identifiers — traitmech:000581 is unique and the next free ID after 000580; METPO:1053500 follows v457's 1053400; proposal v458 follows v457. No pre-existing galvanotaxis or electrotaxis record exists; the only other mention in the repo is the cable-bacteria research lead the proposal already discloses.

Provenance — history record present under history/records/galvanotaxis/, writer defaults to dry run and refuses drift against an existing target, and both record_curation_event and write_validated_trait are used. The file shape matches the thermotaxis PR merged immediately before this one, path for path.

CI: qc, validate-strict, label-correspondence, canonical-example-taxonomy, history, pr-sanity, vendored-sync all pass.

One disclosure about the scope of my review

Network access was unavailable to me in this environment, so I could not independently confirm that the seven snippets are verbatim, nor re-resolve IPR001492, A0A0F6B2U2, or the two NCBITaxon ids against their issuing APIs. The snippet-length budget, contiguity, and the confinement of interpretation to notes all look right, and audit-snippets passes, but verbatim-ness itself rests on the prior review round rather than on anything I did. I am not raising it as a finding — just naming what my approval does and does not cover.

One optional observation, not blocking

The preserved REST-audit row is the right call under the playbook, and hand-editing it would have been wrong. Worth noting for a future generator change rather than this PR: galvanotaxis is now the only status=error row in reports/uniprot_grounding_audit.tsv, and it carries TAXON_MISMATCH|ENTRY_STATUS_MISMATCH|ENTRY_VERSION_MISMATCH|SEQUENCE_VERSION_MISMATCH|PROTEOME_MISMATCH alongside UNIPROT_ERROR. Those five come from comparing against empty metadata after the 503, not from any biological disagreement. A reader scanning the finding column has no way to tell that apart from five real identity mismatches. Suppressing the comparison flags when status=error would make the report say only what it actually observed. That is a change to the resolver, not to this record.

@realmarcin
realmarcin added this pull request to the merge queue Oct 4, 2026
Merged via the queue into main with commit 586532f Oct 4, 2026
8 checks passed
@realmarcin
realmarcin deleted the add-galvanotaxis-trait branch October 4, 2026 00:10
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.

PR #1642: preserve failed UniProt REST audit result for galvanotaxis FliC

1 participant