Suppose a review spreadsheet has every required column and no missing action fields. Can a workflow now call the manuscript “verified”? No. Completing a record and resolving the scientific problem described by that record are different events.
A small Python teaching example can preserve that distinction. It reports whether a deliberately narrow CSV matrix is complete, and separately carries forward the identifiers of claims whose entered labels still describe gaps. The program does not read a manuscript, evaluate a causal argument, or decide whether evidence is true.
We are the RigorMed team. All inputs below are self-written synthetic metadata. This code was actually run locally with Python's standard library; it did not call a model, install a research Skill, or start a production research task.
Define what your labels mean before checking them
For this example only, the columns are claim_id, support, evidence_id, issue, and action. An evidence identifier is just a reference entered by the person preparing the matrix. Its presence does not establish that the corresponding file exists, was read, or supports the claim.
The three invented claims behind the IDs are: C1, an abstract/table population mismatch; C2, causal wording in a cross-sectional statement; and C3, a no-risk statement with no mapped evidence. We designed and classified them by hand. The program did not discover them.
Two structural rules are useful for this declared format. A row marked supported needs an evidence ID. A row marked partly_supported needs a recorded issue rather than none. Every row not marked supported should retain a next action; a missing action is reported separately. These are modest rules for our example, not a complete review rubric or a universal evidence schema.
Keep the gap list separate from the completeness flag
import csv
import io
import json
FIELDS = ["claim_id", "support", "evidence_id", "issue", "action"]
SUPPORT = {"supported", "partly_supported", "unsupported", "not_assessed"}
def inspect_matrix(text):
reader = csv.DictReader(io.StringIO(text))
if reader.fieldnames != FIELDS:
raise ValueError("Unexpected matrix columns")
rows = list(reader)
seen, errors, warnings, unresolved = set(), [], [], []
for row in rows:
claim = row["claim_id"]
if not claim or claim in seen:
raise ValueError("Missing or duplicate claim_id")
seen.add(claim)
if row["support"] not in SUPPORT:
raise ValueError("Unknown support label")
if row["support"] == "supported" and not row["evidence_id"]:
errors.append(f"{claim}: supported_without_evidence_id")
if row["support"] == "partly_supported" and row["issue"] == "none":
errors.append(f"{claim}: partial_without_issue")
if row["support"] != "supported":
unresolved.append(claim)
if not row["action"]:
warnings.append(f"{claim}: missing_next_action")
return {
"matrix_complete": not errors and not warnings,
"errors": errors,
"warnings": warnings,
"claims_with_declared_gaps": unresolved,
}
bad = """claim_id,support,evidence_id,issue,action
C1,supported,,none,check analysis set
C2,partly_supported,E2,none,check causal identification
C3,not_assessed,,none,
"""
filled = """claim_id,support,evidence_id,issue,action
C1,unsupported,,population,check analysis set and exclusions
C2,partly_supported,E2,causal_language,check causal identification
C3,not_assessed,,none,locate outcome denominator period and uncertainty
"""
reports = {"incomplete": inspect_matrix(bad), "filled": inspect_matrix(filled)}
if len(reports["incomplete"]["errors"]) != 2 or len(reports["incomplete"]["warnings"]) != 1:
raise RuntimeError("Unexpected teaching output")
if not reports["filled"]["matrix_complete"] or reports["filled"]["claims_with_declared_gaps"] != ["C1", "C2", "C3"]:
raise RuntimeError("A declared scientific gap was lost")
print(json.dumps(reports, indent=2))
Actual local output:
{
"incomplete": {
"matrix_complete": false,
"errors": [
"C1: supported_without_evidence_id",
"C2: partial_without_issue"
],
"warnings": [
"C3: missing_next_action"
],
"claims_with_declared_gaps": [
"C2",
"C3"
]
},
"filled": {
"matrix_complete": true,
"errors": [],
"warnings": [],
"claims_with_declared_gaps": [
"C1",
"C2",
"C3"
]
}
}
The incomplete input has two errors and one missing-action warning. In the second input, C1 is explicitly marked unsupported, C2 retains partial support with a causal-language issue, and C3 remains unassessed. Their actions have been recorded, so the matrix is complete under the tiny format rules. All three IDs remain in claims_with_declared_gaps.
Nothing was scientifically resolved by filling those fields. The population still needs its analysis set and exclusions checked. The causal statement still needs an appropriate identification argument. The no-risk statement still needs a defined outcome, denominator, observation period, and uncertainty. Those are researcher tasks, not results of a CSV parser.
Watch the boundary of this example
The function rejects an unexpected header, missing or duplicate identifiers, and unknown support labels. It is not a hardened CSV ingestion library: it does not handle every malformed row, normalize arbitrary whitespace, define a complete issue taxonomy, or resolve evidence files. Do not deploy it unchanged as a professional review gate.
There is also no model confidence score and no statistical inference. A person could enter a completely wrong support label and still produce a structurally complete matrix. Another person could fill an evidence ID with a nonexistent identifier. Resolving those possibilities requires the authorized source material, source-location checks, and appropriate human scientific review.
For a larger workflow, the important output distinction remains simple: “the record is complete” and “the evidence supports this claim” need separate facts and separate responsibility. Do not let a generic success branch silently convert one into the other. If you have not checked the original material, retain that state explicitly.
A useful material handoff
Give the reviewer authorized manuscript text, tables, figures, references, the original comments, and the current claim matrix. Request locations, evidence references, limitations, and next actions. Keep proposed analyses distinct from completed analyses, and confirm materials and execution authorization before any new research computation.
For text-source location and research-draft handoff, RigorMed's browser research entry can take a concrete task and authorized material. Actual model use follows the displayed credit terms. This article does not claim that the teaching function is a shipped RigorMed validator, that a third-party Skill is integrated, or that a manuscript is ready for submission.
Sources checked on 2026-11-04: Python's official CSV module documentation, including the limited semantics of DictReader, and JSON module documentation. The example, labels, inputs, and output interpretation here are our own teaching material.
Top comments (0)