Skip to contents

Overview

A Betwixt review begins with a candidate dataset. The candidate dataset brings together evidence made available to a reviewer, human-readable descriptions of the objects under review, and candidate semantic assertions that the reviewer is asked to evaluate. It defines the input to review rather than the resulting review state.

This vignette constructs a small candidate dataset from three museum records in MuIS, the Estonian museum information system. The example includes:

  • thumbnails presented directly as evidence;
  • links to the corresponding museum records;
  • primary and alternative descriptive information;
  • candidate semantic assertions linked to Getty AAT concepts;
  • row-level contextual information; and
  • dataset-level provenance describing preparation of the candidate state.

The example uses a wide review representation, in which each row groups the review material for one object and candidate assertions are exposed through columns.

Source data

We begin with an ordinary tibble. There is nothing Betwixt-specific about this input representation.

review_input <- tibble::tribble(
  ~page_id, ~label_en, ~description_en, ~label_hu, ~description_hu,
  ~page_url, ~thumbnail_url,
  ~subject, ~predicate, ~value, ~value_definition,
  "635780",
  "sweater, women's",
  "MuIS museum record 635780.",
  "női kardigán",
  "A MuIS 635780 számú múzeumi rekordja.",
  "https://www.muis.ee/museaalview/635780",
  paste0(
    "https://www.muis.ee/digitaalhoidla/api/meedia/pisipilt?",
    "id=ebc07930-f719-44f2-a108-6698bcecc20b"
  ),
  paste0(
    "https://www.muis.ee/digitaalhoidla/api/meedia/pisipilt?",
    "id=ebc07930-f719-44f2-a108-6698bcecc20b"
  ),
  "depicts",
  "300209900",
  "http://vocab.getty.edu/page/aat/300209900",
  "633053",
  "gloves",
  "MuIS museum record 633053.",
  "kesztyű",
  "A MuIS 633053 számú múzeumi rekordja.",
  "https://www.muis.ee/museaalview/633053",
  paste0(
    "https://www.muis.ee/digitaalhoidla/api/meedia/pisipilt?",
    "id=6440f24f-eaad-4cd4-84d7-1ae7a9d44d5a"
  ),
  paste0(
    "https://www.muis.ee/digitaalhoidla/api/meedia/pisipilt?",
    "id=6440f24f-eaad-4cd4-84d7-1ae7a9d44d5a"
  ),
  "depicts",
  "300148821",
  "http://vocab.getty.edu/page/aat/300148821",
  "635778",
  "shirt, women's",
  "MuIS museum record 635778.",
  "női ing",
  "A MuIS 635778 számú múzeumi rekordja.",
  "https://www.muis.ee/museaalview/635778",
  paste0(
    "https://www.muis.ee/digitaalhoidla/api/meedia/pisipilt?",
    "id=826c402e-c130-4860-b11e-9538bd403ecf"
  ),
  paste0(
    "https://www.muis.ee/digitaalhoidla/api/meedia/pisipilt?",
    "id=826c402e-c130-4860-b11e-9538bd403ecf"
  ),
  "depicts",
  "300212499",
  "http://vocab.getty.edu/page/aat/300212499"
)

The input separates evidence, human-readable descriptive information, and values that will become candidate assertions. Keeping these roles distinct is important because their presence in the same review representation does not give them the same semantic or review role.

In this particular example, we will change the translation női kardigán to női pulóver.

Evidence

Betwixt distinguishes between evidence that is presented directly in the review interface and evidence resources that a reviewer may open.

In this example, the MuIS thumbnail is presented directly:

evidence_media_url = review_input$thumbnail_url

while the museum record itself is retained as an evidence resource:

evidence_url = review_input$page_url

A short human-readable identification of the evidence is supplied separately:

evidence_text = review_input$label_en

This distinction allows a review to present convenient visual evidence while separately retaining links to evidence resources that the reviewer may inspect. Evidence is also distinct from provenance: it supports the assertions under review, whereas provenance records how the candidate and review states were produced.

Describing the object under review

The primary label and description provide human-readable descriptive information to the reviewer:

label = review_input$label_en
description = review_input$description_en

A review may also contain alternative descriptive information. Here the optional fields provide Hungarian descriptions:

alternative_label = review_input$label_hu
alternative_description = review_input$description_hu

Alternative descriptions are deliberately not restricted to translations. They may contain terminology intended for another user group, a more detailed description, or another useful description of the same object.

Constructing the candidate dataset

We can now bring these elements together.

candidates <- create_candidate_dataset(
  evidence_media_url = review_input$thumbnail_url,
  evidence_url = review_input$page_url,
  evidence_text = review_input$label_en,
  label = review_input$label_en,
  description = review_input$description_en,
  alternative_label = review_input$label_hu,
  alternative_description = review_input$description_hu,
  subject = review_input$subject,
  data_manager_name = "Daniel Antal",
  data_manager_iri = "https://orcid.org/0000-0001-7513-6760",
  data_manager_email = "daniel@example.org",
  project_id = "muis-garments"
)

The subject column identifies the subject of each candidate assertion. In this example it is the URL of the digital image presented as evidence.

candidates
#> # A tibble: 3 × 11
#>   row_number evidence_url     evidence_media_url evidence_text label description
#>        <int> <chr>            <chr>              <chr>         <chr> <chr>      
#> 1          1 https://www.mui… https://www.muis.… sweater, wom… swea… MuIS museu…
#> 2          2 https://www.mui… https://www.muis.… gloves        glov… MuIS museu…
#> 3          3 https://www.mui… https://www.muis.… shirt, women… shir… MuIS museu…
#> # ℹ 5 more variables: alternative_label <chr>, alternative_description <chr>,
#> #   subject <chr>, subject_range <chr>, subject_definition <chr>

The candidate dataset also carries dataset-level provenance. The data manager identifies the person responsible for preparing the candidate state. Betwixt records the generation time and software version automatically.

attr(candidates, "provenance")
#> $data_manager
#> [1] "Daniel Antal"
#> 
#> $data_manager_iri
#> [1] "https://orcid.org/0000-0001-7513-6760"
#> 
#> $data_manager_email
#> [1] "daniel@example.org"
#> 
#> $project_id
#> [1] "muis-garments"
#> 
#> $generated_at
#> [1] "2026-09-11T08:41:48Z"
#> 
#> $software_agent
#> [1] "Betwixt"
#> 
#> $software_version
#> [1] "0.0.7"

This provenance describes the preparation of the candidate dataset. It is distinct from the provenance of the subsequent review, including the identity of the reviewer and the review lifecycle.

Adding candidate assertions

Additional reviewable assertions can be added incrementally with add_candidate_column().

Here each image is associated with a proposed concept from the Getty Art & Architecture Thesaurus:

candidates <- candidates |>
  add_candidate_column(
    name = "depicts",
    value = review_input$value,
    definition = review_input$value_definition
  )

The resulting wide representation contains subject and depicts as reviewable semantic columns. The accompanying depicts_definition records the semantic identity of each proposed value using its Getty AAT URI.

candidates
#> # A tibble: 3 × 14
#>   row_number evidence_url     evidence_media_url evidence_text label description
#>        <int> <chr>            <chr>              <chr>         <chr> <chr>      
#> 1          1 https://www.mui… https://www.muis.… sweater, wom… swea… MuIS museu…
#> 2          2 https://www.mui… https://www.muis.… gloves        glov… MuIS museu…
#> 3          3 https://www.mui… https://www.muis.… shirt, women… shir… MuIS museu…
#> # ℹ 8 more variables: alternative_label <chr>, alternative_description <chr>,
#> #   subject <chr>, subject_range <chr>, subject_definition <chr>,
#> #   depicts <chr>, depicts_range <chr>, depicts_definition <chr>

The _definition column is metadata about the candidate value. It is not itself presented as a separate assertion for review.

The wide tabular structure arranges candidate semantic material for human review without making that table structure the underlying semantic model.

Adding row context

Some information is useful for interpreting a review row without itself being something that the reviewer is asked to evaluate.

Such information can be represented using context_* columns:

candidates <- candidates |>
  dplyr::mutate(
    context_held_by = "Estonian National Museum"
  )

Here context_held_by records the institution holding the objects represented by the MuIS records.

candidates
#> # A tibble: 3 × 15
#>   row_number evidence_url     evidence_media_url evidence_text label description
#>        <int> <chr>            <chr>              <chr>         <chr> <chr>      
#> 1          1 https://www.mui… https://www.muis.… sweater, wom… swea… MuIS museu…
#> 2          2 https://www.mui… https://www.muis.… gloves        glov… MuIS museu…
#> 3          3 https://www.mui… https://www.muis.… shirt, women… shir… MuIS museu…
#> # ℹ 9 more variables: alternative_label <chr>, alternative_description <chr>,
#> #   subject <chr>, subject_range <chr>, subject_definition <chr>,
#> #   depicts <chr>, depicts_range <chr>, depicts_definition <chr>,
#> #   context_held_by <chr>

Betwixt preserves row context throughout the review and subsequent projections, but does not treat it as a candidate assertion and does not assign it a review status.

Rendering the review

We can now turn the candidate dataset into a standalone Betwixt review.

render_review(
  candidates,
  cols = c(
    subject = "Digital image",
    depicts = "AAT concept"
  ),
  title = "MuIS garment terminology review",
  description = paste(
    "Review the proposed Hungarian labels and verify that the",
    "Getty AAT concepts correctly identify the depicted garments."
  ),
  row_comment = TRUE,
  reviewer_name = "Daniel Antal",
  reviewer_iri = "https://orcid.org/0000-0001-7513-6760",
  review_comment = TRUE,
  project_id = "muis-garments",
  filename_stem = "muis-garments-review",
  sequence = 0L,
  path = "."
)

Candidate provenance and review provenance remain distinct. The data manager recorded in the candidate dataset is responsible for preparing the candidate state. The reviewer recorded by render_review() is responsible for evaluating it. The same person may perform both roles, as in this example, without collapsing the distinction between the two activities.

Here row_comment = TRUE gives the reviewer an optional comment field for each object. review_comment = TRUE adds a separate comment field for observations concerning the review as a whole.

Initial candidate review
Initial candidate review

The resulting review separates several kinds of reviewer intervention:

  • editing descriptive information or candidate values;
  • qualifying individual candidate assertions;
  • finalising individual review rows;
  • commenting on an individual row; and
  • commenting on the review as a whole.

Candidate data and review output

The candidate dataset defines the input to review. Reviewer decisions and comments are not added to create_candidate_dataset() because they belong to the resulting review state rather than to the candidate state.

Instead, the standalone review records those interventions as review proceeds. The initial review generated above is sequence 0: it contains the candidate state but no reviewer decisions.

Open the initial candidate review

Saving a review

Once reviewer interventions are recorded, the review has a state distinct from its original candidate input. The first browser save therefore starts review sequence 1.

Saving a draft preserves the current review state without finalising the review. The standalone HTML retains the original candidate values while also persisting current descriptive and assertion values, assertion qualifications, row finalisation, row comments, review-level comments, reviewer information, candidate provenance, and review lifecycle metadata.

Open the saved draft

The reviewer can reopen the saved HTML and continue working with the preserved state.

Finalising the review

Finalising the review preserves the same information but marks the review activity as completed and records its completion time. It does not by itself promote reviewed assertions into a subsequent stabilised semantic state or apply them to an external knowledge system. A draft and a finalised review from the same review cycle therefore belong to the same sequence.

Open the finalised review

The three files make the review lifecycle directly inspectable:

  1. candidate review — sequence 0
  2. saved draft — sequence 1
  3. finalised review — sequence 1

This separation is fundamental to Betwixt. The candidate dataset defines what is proposed for review and records the provenance of that candidate state. The saved review preserves that state while recording what the reviewer did with those proposals and the provenance of the review activity.

The resulting review artefact therefore preserves a chain from candidate preparation through human review, from which the candidate and reviewed states can subsequently be reconstructed and projected.