Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ jobs:
id: drafts
uses: ./
with:
files: examples/drafts/*.yaml
files: examples/drafts/*claim.yaml
profile: literature-claim
format: draft
fail-on: rejected
Expand Down
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

## Unreleased

- Add admitted and rejected `dataset-label` draft examples, covered by draft and
installed-wheel checks.

## 0.7.0 — Expert review, quality checks, community and documentation site

- Add `bioevidence review` (`check`, `agreement`, `adjudication-sheet`, `score`, `freeze`)
Expand Down
35 changes: 35 additions & 0 deletions examples/drafts/dataset_label_reference.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Synthetic dataset-label draft admitted for reference annotation.
# Build: bioevidence build examples/drafts/dataset_label_reference.yaml --output record.json
# Validate: bioevidence validate record.json --profile dataset-label (exit 0: admitted)
profile: dataset-label
uses: [reference_annotation]

statement:
subject: {id: "SYN:SAMPLE_A", label: Synthetic sample A, type: sample}
predicate: has_label
object: {id: "SYN:LABEL_A", label: Synthetic class A, type: class_label}
scope: ["cohort:synthetic"]

sources:
- id: labels
title: Synthetic label table; not real biological evidence
type: dataset_snapshot
uri: https://example.org/synthetic-labels
version: synthetic-v1
retrieved_at: "2026-09-25T00:00:00Z"
sha256: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

evidence:
- source: labels
locator: row-1-label
text: Synthetic sample A has synthetic class A.
type: curated_label
method: manual_curation
scope: ["cohort:synthetic"]

- source: labels
locator: row-1-link
text: Synthetic sample A is linked to row 1 of the label table.
type: sample_link
method: deterministic_parser
scope: ["cohort:synthetic"]
35 changes: 35 additions & 0 deletions examples/drafts/dataset_label_training_unreviewed.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Synthetic dataset-label draft rejected for training use without human acceptance.
# Build: bioevidence build examples/drafts/dataset_label_training_unreviewed.yaml --output record.json
# Validate: bioevidence validate record.json --profile dataset-label (exit 1: rejected)
profile: dataset-label
uses: [training_data]

statement:
subject: {id: "SYN:SAMPLE_A", label: Synthetic sample A, type: sample}
predicate: has_label
object: {id: "SYN:LABEL_A", label: Synthetic class A, type: class_label}
scope: ["cohort:synthetic"]

sources:
- id: labels
title: Synthetic label table; not real biological evidence
type: dataset_snapshot
uri: https://example.org/synthetic-labels
version: synthetic-v1
retrieved_at: "2026-09-25T00:00:00Z"
sha256: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

evidence:
- source: labels
locator: row-1-label
text: Synthetic sample A has synthetic class A.
type: curated_label
method: manual_curation
scope: ["cohort:synthetic"]

- source: labels
locator: row-1-link
text: Synthetic sample A is linked to row 1 of the label table.
type: sample_link
method: deterministic_parser
scope: ["cohort:synthetic"]
27 changes: 24 additions & 3 deletions tests/test_draft.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,19 @@ def test_reviewed_draft_is_admitted_for_both_uses():
assert overall == "admitted" and uses == {"research_summary": "admitted", "knowledge_base": "admitted"}


def test_dataset_label_reference_draft_is_admitted():
overall, uses, _ = statuses(draft("dataset_label_reference.yaml"))
assert overall == "admitted"
assert uses == {"reference_annotation": "admitted"}


def test_dataset_label_training_draft_requires_human_acceptance():
overall, uses, report = statuses(draft("dataset_label_training_unreviewed.yaml"))
assert overall == "rejected"
assert uses == {"training_data": "rejected"}
assert {f["rule_id"] for f in report["findings"]} == {"BEV010"}


def test_build_expands_structure_and_hashes_local_file():
record = build(draft())
source, = record["source_artifacts"]
Expand Down Expand Up @@ -138,9 +151,17 @@ def test_draft_schema_is_valid_json_schema(profile):
assert schema["properties"]["profile"] == {"const": profile}


@pytest.mark.parametrize("name", ["llm_claim.yaml", "reviewed_claim.yaml"])
def test_example_drafts_match_their_profile_schema(name):
Draft202012Validator(draft_json_schema("literature-claim")).validate(draft(name))
@pytest.mark.parametrize(
"name,profile",
[
("llm_claim.yaml", "literature-claim"),
("reviewed_claim.yaml", "literature-claim"),
("dataset_label_reference.yaml", "dataset-label"),
("dataset_label_training_unreviewed.yaml", "dataset-label"),
],
)
def test_example_drafts_match_their_profile_schema(name, profile):
Draft202012Validator(draft_json_schema(profile)).validate(draft(name))


def test_draft_schema_turns_profile_allowlists_into_enums():
Expand Down
2 changes: 1 addition & 1 deletion tests/test_github_action.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ def run(monkeypatch, tmp_path, *args):

@pytest.mark.parametrize("fail_on,expected", [("review", 1), ("rejected", 0)])
def test_drafts_fail_on_review_only_when_asked(monkeypatch, tmp_path, fail_on, expected):
code, summary, counts = run(monkeypatch, tmp_path, "--files", "examples/drafts/*.yaml",
code, summary, counts = run(monkeypatch, tmp_path, "--files", "examples/drafts/*claim.yaml",
"--profile", "literature-claim", "--format", "draft", "--fail-on", fail_on)
assert code == expected
assert counts == {"admitted": 1, "review_required": 1, "rejected": 0, "error": 0}
Expand Down
9 changes: 7 additions & 2 deletions tools/check_distribution.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,15 @@ def run(*args, expected=0):
run("generate-schema", "--output", output)
assert "BioEvidenceRecord" in json.loads(output.read_text(encoding="utf-8"))["$defs"]
with tempfile.TemporaryDirectory() as directory:
for draft, expected in [("llm_claim.yaml", 2), ("reviewed_claim.yaml", 0)]:
for draft, profile, expected in [
("llm_claim.yaml", "literature-claim", 2),
("reviewed_claim.yaml", "literature-claim", 0),
("dataset_label_reference.yaml", "dataset-label", 0),
("dataset_label_training_unreviewed.yaml", "dataset-label", 1),
]:
output = Path(directory) / (draft + ".json")
run("build", root / "examples/drafts" / draft, "--output", output)
run("validate", output, "--profile", "literature-claim", expected=expected)
run("validate", output, "--profile", profile, expected=expected)
schema = json.loads(run("draft-schema", "--profile", "literature-claim").stdout)
assert schema["properties"]["profile"] == {"const": "literature-claim"}
record = json.loads((root / "examples/general/curated_assertion.json").read_text(encoding="utf-8"))
Expand Down
Loading