Ontology term requests
Detect structured gaps
detect_semantic_term_gaps() combines deterministic candidate gaps with final LLM request_new_term assessments.
from metasalmonpy import detect_semantic_term_gaps
gaps = detect_semantic_term_gaps(reviewed)When suggestions is omitted, the function reads both semantic_suggestions and semantic_llm_assessments from the dictionary attributes. When suggestions are supplied explicitly, only their embedded LLM fields are used.
The gap_detection_basis field distinguishes:
candidate_gap;llm_request_new_term; andcandidate_gap_and_llm_request_new_term.
An explicit final LLM gap remains visible even when SMN candidates exist. Duplicate assessments with conflicting proposed-term fields are rejected rather than silently collapsed.
Review gaps recorded in the Salmon Knowledge Commons
The commons publishes its concept gap register as JSON through scripts/okf-check.py . --gaps. Pass the resulting export file path to the same detector; a compiled gaps.json with build metadata is a different envelope. This input is exclusive with a dictionary, suggestions, and SDP-only filters.
from metasalmonpy import (
detect_semantic_term_gaps,
render_ontology_term_request,
submit_term_request_issues,
)
commons_gaps = detect_semantic_term_gaps(commons_gaps="commons-gaps.json")
commons_requests = render_ontology_term_request(commons_gaps, ask=False)
preview = submit_term_request_issues(commons_requests, dry_run=True)Every source row remains visible in source order, including repeated concepts and rows held for review. The result keeps the existing SDP gap columns and adds commons_ source fields, including lifecycle, proposed mint target, verification state, and commons_hold_reason. The SDP dataset and column fields remain missing because a commons concept is not a dataset column.
Only open, unheld gaps explicitly targeted to SMN or GCDFO reach the dry-run preview. Proposed or rejected gaps, blocked or contested gaps, gaps needing evidence, do-not-mint declarations, and unsupported targets remain held. scope, scope_overrides, and ask cannot reopen them or redirect a commons declaration. Request bodies cite the concept card and retain its draft note; they leave the definition and term type to a curator. No term IRI is chosen. The issue_labels argument retains the same handling as ordinary Python request rendering.
Route and render requests
from metasalmonpy import render_ontology_term_request
requests = render_ontology_term_request(gaps, scope="auto")First-class scopes are:
| Scope | Destination |
|---|---|
smn |
Shared Salmon Domain Ontology |
gcdfo |
DFO-specific GCDFO Salmon Ontology |
profile |
A local, program, or organization profile |
uncertain |
Requires explicit routing |
skip |
Do not prepare a request |
Automatic routing uses explicit row overrides first, then a forced function scope, a recognized namespace suggestion, and finally the deterministic placement heuristic. llm_new_term_namespace is evidence, not authority.
Profile requests require profile_name in non-interactive use:
profile_requests = render_ontology_term_request(
gaps,
scope="profile",
profile_name="coho-monitoring-profile",
)The resulting DataFrame contains repository-specific titles and issue bodies matching the active SMN or GCDFO template.
Preview before submission
from metasalmonpy import submit_term_request_issues
preview = submit_term_request_issues(requests, dry_run=True)Live submission is deliberately difficult to trigger accidentally. It requires dry_run=False, confirm=True, a GitHub token, and a separate interactive confirmation for every issue.
submitted = submit_term_request_issues(
requests,
dry_run=False,
confirm=True,
)Generated requests are drafts for ontology curators. metasalmonpy never approves a new ontology term or submits one as a side effect of semantic review.