Model the acetate kinase step instead of a chemical producing ATP (#331) - #339
Conversation
`acetyl_phosphate --produces--> atp` had a CHEMICAL subject on METPO:2007800, whose definition is that the ACTIVITY OR STATE of the subject brings the object into existence. A chemical has neither in that sense. RO:0001001 (derives into) did not fit either, and #327 said why: ATP's matter comes mostly from ADP and only the phosphoryl group transfers, so it fails that relation's inherits-the-significant-portion- of-the-matter test. That is why it was filed rather than swept into #327. The resolution was already written in the edge's own description -- "The acetate kinase step generates ATP" -- and in its evidence, which says ACK converts acetyl phosphate to acetate yielding ATP. The process was named but not modelled. Added it as a BIOLOGICAL_PROCESS node and split the edge into `acetate_kinase_step has input acetyl_phosphate` (RO:0002233) and `acetate_kinase_step has output atp` (RO:0002234), both range-correct. Wired on BOTH sides deliberately: atp had exactly one edge, so replacing it without an input edge would have orphaned the new node and atp together. audit-graphs confirms no new findings. This was the last CHEMICAL-subject `produces` edge, so METPO:2007800's subject_types gate drops CHEMICAL and now matches its definition exactly. Added a `has input` mapping row (RO:0002233), gated to the three activity node types for the same reason `has output` is. Evidence-snippet baseline moves 2737 -> 2738, and the delta is exactly explainable: the pre-existing MISSING_SNIPPET re-keys onto the new has-output edge, plus one genuinely new finding because the has-input edge reuses the same evidence, which carries notes but no verbatim snippet. A snippet cannot be invented -- the schema specifies a verbatim quote and the source text is not to hand -- so it joins the known backlog rather than being fabricated. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Claude finished @realmarcin's task in 6m 1s —— View job ReviewThe modelling call is right and the reasoning in the PR body holds up. Two things I checked that the body asserts, both confirmed independently:
I could not run 🟡 That edge is Two consequences: the mapping table and the corpus disagree, and the next 🔵 🔵 The step has No Verdict: requesting changes for the one 🟡. Everything else here is sound; that edge is a one-line addition.
|
There was a problem hiding this comment.
The modelling call is right and the reasoning holds up. Verified independently: reachability in audit_causal_graphs.py:95 is undirected so nothing is orphaned; all 84 produces edges have GENE_OR_PROTEIN/TRAIT/STATE/BIOLOGICAL_PROCESS subjects, so dropping CHEMICAL from the gate is safe; the RO CURIEs are correct and the snippet-baseline delta matches.
One blocker: the new has input mapping row now covers data/traits/upper/biological_process.yaml:123, but that edge was left without predicate_id: RO:0002233 while its sibling three lines below carries RO:0002234. The mapping table and the corpus disagree, and the next just ground-predicates --apply will silently touch a file this PR didn't. #327 set the opposite precedent — the derives into row landed with RO:0001001 written onto all four covered edges.
Details and two optional suggestions in the review comment.
The 🟡 is the same failure #328 had, and the reviewer is right that #327 set the opposite precedent. Adding the `has input` row made upper/biological_process.yaml's `molecular_function --has input--> chemical_input` edge LOOK mapped, so it dropped out of the residual report, but nothing grounded it -- leaving it in neither the grounded set nor the backlog, with the next `ground-predicates --apply` silently touching a file this PR had not. Grounded to RO:0002233, which its own evidence note already named ("Has input [RO:0002233]") and which its sibling has-output edge has carried all along. Curation event appended by the tool. Both 🔵s recorded as decisions in the curation event rather than left as omissions, which is what the reviewer asked for: - The node is typed BIOLOGICAL_PROCESS, not MOLECULAR_FUNCTION. The latter would have grounded to GO:0008776 via node_grounding.tsv, but this trait's own research report asks for a process label plus explicit reaction edges for the SLP step, and that is exactly what this is. - The step carries has-output atp but deliberately not has-output acetate. The existing acetyl_phosphate is-converted-to acetate edge already states that half of the reaction on the chemical chain; asserting it again at the process level is the duplication at two levels of description that #303 criticised in dissimilatory_iron_reduction. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Fixed, and you're right that #327 set the opposite precedent — I should have followed it. 🟡 The ungrounded
|
|
Claude finished @realmarcin's task in 1m 38s —— View job Re-review (commit
|
There was a problem hiding this comment.
The 🟡 is fixed correctly and completely.
data/traits/upper/biological_process.yaml:126 now carries predicate_id: RO:0002233, matching its sibling's RO:0002234 and the CURIE its own evidence note already named. It's the only other has input edge in the corpus, so the new mapping row has zero uncovered edges — the mapping table and corpus agree again, and ground-predicates --apply has nothing left to silently touch. The residual report drops the has input line by grounding rather than by disappearing.
Derived artifacts are consistent with each other: node_grounding_residual.tsv gains acetate kinase step (the honest cost of the label-only node, in the backlog rather than quietly absent), and the snippet baseline is +2/−1 exactly as claimed with no invented snippet.
Both 🔵s are now decisions with reasons in the curation event rather than omissions. I don't need to agree with either call — they're defensible and legible to the next reader, which was the ask.
Note for accuracy: the acetogenesis curation event was amended in place rather than appended. Fine here since it's this PR's own event, but the reasoning and the change landed in different commits.
I still could not run just qc, validate-strict, or the tests (uv run is blocked in this sandbox), so the green-CI claims are unverified by me. Everything checkable statically holds.
#340) The corpus-as-of stamp is the maximum curation_history timestamp across the whole corpus, inlined into every rendered page. Because the value is global but stored per-page, ANY PR appending a curation event -- i.e. every data PR, since the playbook requires one -- rewrote all 477 trait pages. PR #300 changed 14 trait files and produced a 508-file diff of which 477 were nothing but a footer timestamp; #339 in this same session touched 495 files for one curation event. Took the issue's option 1, storing the value once rather than 477 times, but without dropping it from trait pages: they now carry their OWN latest curation timestamp, labelled "Record as of". That changes only when the record changes, and "when was THIS trait last curated" is the more useful question on a trait page anyway. The corpus-wide stamp stays on the aggregate pages, where it is a property of what is being shown. Measured, not asserted. Appending one curation event to one record and re-rendering: before: 477+ pages rewritten after: 13 -- the changed trait page, browse, graph, umap, and the 9 category pages, all of which legitimately carry the corpus stamp The changed trait page IS among the 13, checked explicitly; a fix that stopped the real page changing would be worse than the churn. pages/index.html carries no stamp either way -- its template does not extend base.html. Pre-existing, verified against main, not touched here. Three tests pin the distinction, including that a record's stamp is not the corpus maximum, which is the property the whole change rests on. Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
acetyl_phosphate --produces--> atphad aCHEMICALsubject onMETPO:2007800, whosedefinition is that the activity or state of the subject brings the object into
existence. A chemical has neither in that sense.
RO:0001001(derives into) didn't fit either, and #327 already said why: ATP's mattercomes mostly from ADP and only the phosphoryl group transfers, so it fails that
relation's inherits-the-significant-portion-of-the-matter test. That's exactly why it was
filed separately rather than swept into #327.
The answer was already in the record
The edge's own description says "The acetate kinase step generates ATP", and its evidence
says "ACK convert acetyl-phosphate to acetate, yielding ATP via SLP". The process was
named but never modelled.
Added it as a
BIOLOGICAL_PROCESSnode and split the edge:acetate_kinase_step --has input--> acetyl_phosphateRO:0002233acetate_kinase_step --has output--> atpRO:0002234Both range-correct, and this is option 1 from the issue — the one that lets the gate tighten.
Wired on both sides deliberately:
atphad exactly one edge, so replacing it without aninput edge would have orphaned the new node and
atptogether.audit-graphsconfirmsno new findings (1535, unchanged).
The gate now matches its definition
This was the last
CHEMICAL-subjectproducesedge, soMETPO:2007800'ssubject_typesdropsCHEMICAL— the tightening #331 predicted. Also added ahas inputmapping row (
RO:0002233), gated to the three activity node types for the same reasonhas outputis.The one honest cost
Evidence-snippet baseline moves 2737 → 2738, and the delta is exactly explainable:
MISSING_SNIPPETre-keys onto the new has-output edge, andcarries notes but no verbatim snippet.
A snippet cannot be invented — the schema specifies a verbatim quote and the source text
isn't to hand — so it joins the known backlog (2586 such findings) rather than being
fabricated.
What was checked
just qcgreen ·just validate-strict477 / 0 errors · 431 tests pass ·audit-graphsunchanged · zeroCHEMICAL-subjectproducesedges remain · curation eventadded with history verified in order.
Closes #331.
🤖 Generated with Claude Code