Ontology term requests

Turn unresolved semantic targets into curator-reviewed request drafts.

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; and
  • candidate_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.

Back to top