
Write a semantic review packet for a harness to judge
Source:R/semantic-review-packet.R
write_semantic_review_packet.RdModel judgement runs outside metasalmon (ruled 2026-09-25, hub Q67). This
writes the deterministic file a harness reads: every semantic slot that
still needs a decision, each slot's ranked candidate shortlist with the
evidence the package's own validators read (label, IRI, source, ontology,
native type, role hints, term type, resource kind, type IRIs, definition
and scores), the measurement bundles with their current slots, the scored
excerpts from your context documents, the review instructions, the
decision vocabulary and the 30-column assessment schema. The harness
answers in a CSV next to the packet, and
ingest_semantic_assessments() reads it back.
Usage
write_semantic_review_packet(
x,
context_files = NULL,
context_text = NULL,
top_n = 5L,
sources = NULL,
search_fn = find_terms,
code_scope = c("factor", "all", "none"),
review_dir = NULL,
overwrite = FALSE,
quiet = FALSE
)Arguments
- x
A package directory written by
create_sdp(), or a dictionary carrying thesemantic_targetsandsemantic_suggestionsattributes thatsuggest_semantics()attaches (an artifact list in theinfer_salmon_datapackage_artifacts()shape is read through itsdict).- context_files
Optional character vector of local file paths whose text is chunked and scored against each unit, under the same path-only contract as
llm_context_files: a parsed object is refused.- context_text
Optional character vector of inline context text.
- top_n
Integer. The shortlist shown per slot and, for a package path, the retrieval depth. Default 5.
- sources
Optional character vector of vocabulary sources. When omitted, each role searches its default sources (
sources_for_role()); when supplied, it is a strict allowlist.- search_fn
The search function, used only for a package path. Defaults to
find_terms().- code_scope
Which
codes.csvvalues get a slot when a blank slot is recovered by discovery for a package path: the same choice ascreate_sdp(semantic_code_scope = ), whose default this shares. Nothing in a package records the scope it was created with, so the packet records the one used here, and a blank code-level slot outside it is reported asnot_coveredrather than silently dropped.- review_dir
Where to write the packet. Defaults to
review/under the package directory; required for in-memory input.- overwrite
Logical. A review session that already holds answers or a record refuses to be overwritten unless this is
TRUE, in which case the session's files are deleted first.- quiet
Logical. Suppress the summary message.
Value
Invisibly, a list with path (the packet file), packet_id
(the SHA-256 the ingester checks), pass (always 1 here), units and
targets (counts), and not_covered: the blank code-level slots the
chosen code_scope left out, one row each (empty for in-memory input).
Details
This never calls a model. For a package path it retrieves each slot's
shortlist again through search_fn, which is the only way it reaches the
network; for in-memory input it makes no network call at all.
For a package path the packet holds exactly the queue review_semantics()
would show – slots in column_dictionary.csv, codes.csv or tables.csv
whose IRI field is blank or REVIEW:-marked and that carry no recorded
decision – and never a fresh discovery. For an in-memory dictionary it
holds every target in the semantic_targets attribute, including targets
with no candidates, with the first top_n candidates of each from the
semantic_suggestions attribute.
The packet holds excerpts from your own context documents. It is written
under review/, which no publication path reads, and it is never
published.
For a package path, recovering blank slots re-runs discovery over the
package's own metadata and data. A data resource is opened only when
tables.csv names it with a plain relative path inside the package (no
.., no absolute path, no symbolic link in the path); any other row is
skipped with a warning.
Examples
dict <- tibble::tibble(
dataset_id = "demo-1", table_id = "spawners", column_name = "spawner_count",
column_role = "measurement", column_label = "Spawner count",
column_description = "Number of spawners counted.", unit_label = "count",
term_iri = NA_character_
)
target <- tibble::tibble(
dataset_id = "demo-1", table_id = "spawners", column_name = "spawner_count",
code_value = NA_character_, dictionary_role = "variable", search_role = "variable",
target_scope = "column", target_sdp_file = "column_dictionary.csv",
target_sdp_field = "term_iri", target_row_key = "demo-1/spawners/spawner_count",
target_label = "Spawner count", target_description = "Number of spawners counted.",
search_query = "spawner count", target_query_basis = "label",
target_query_context = "Spawner count", column_label = "Spawner count",
column_description = "Number of spawners counted.",
code_label = NA_character_, code_description = NA_character_
)
attr(dict, "semantic_targets") <- target
attr(dict, "semantic_suggestions") <- dplyr::bind_cols(
target,
tibble::tibble(
label = "Spawner Abundance", iri = "https://w3id.org/smn/SpawnerAbundance",
source = "smn", ontology = "smn", role = "variable", match_type = "label",
definition = "Mature salmon returning to spawn.", score = 4.9
)
)
review_dir <- file.path(tempdir(), "review-packet-example")
packet <- write_semantic_review_packet(dict, review_dir = review_dir, quiet = TRUE)
packet$packet_id
#> [1] "c39b7fc0df2632fb3767fa06e484d2bf2ab3c7d9ebff9d1b6a56c7601ba8b0f6"