hyf

Context-aware query service for Radroots
git clone https://radroots.dev/git/hyf.git
Log | Files | Refs | README | LICENSE

commit 7b576ca84ff92bd65df1434ff5b3fc8912478985
parent dfc2a7accded8cb1e59242a9f3d03ef5815fb3e6
Author: triesap <tyson@radroots.org>
Date:   Mon, 21 Sep 2026 12:54:12 +0000

core: add evidence reference types

Diffstat:
Asrc/hyf_core/domain/evidence.mojo | 80+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mtests/test_domain.mojo | 37+++++++++++++++++++++++++++++++++++++
2 files changed, 117 insertions(+), 0 deletions(-)

diff --git a/src/hyf_core/domain/evidence.mojo b/src/hyf_core/domain/evidence.mojo @@ -0,0 +1,80 @@ +from std.collections import Optional + + +@fieldwise_init +struct EvidenceRef(Copyable, Movable): + var source_id: String + var revision: String + var kind: String + var start: Int + var end: Int + var record_id: Optional[String] + var field: Optional[String] + var method: String + + +def span_evidence( + source_id: String, revision: String, start: Int, end: Int, method: String +) raises -> EvidenceRef: + if source_id.strip() == "": + raise Error("evidence source_id must not be empty") + if revision.strip() == "": + raise Error("evidence revision must not be empty") + if method.strip() == "": + raise Error("evidence method must not be empty") + if start < 0: + raise Error("evidence span start must be non-negative") + if end < start: + raise Error("evidence span end must not precede start") + return EvidenceRef( + source_id=String(source_id), + revision=String(revision), + kind="span", + start=start, + end=end, + record_id=None, + field=None, + method=String(method), + ) + + +def record_field_evidence( + source_id: String, revision: String, record_id: String, field: String +) raises -> EvidenceRef: + if source_id.strip() == "" or revision.strip() == "": + raise Error("evidence source_id and revision must not be empty") + if record_id.strip() == "" or field.strip() == "": + raise Error("record_field evidence requires record_id and field") + return EvidenceRef( + source_id=String(source_id), + revision=String(revision), + kind="record_field", + start=0, + end=0, + record_id=Optional[String](String(record_id)), + field=Optional[String](String(field)), + method="trusted_record", + ) + + +def span_is_valid(text: String, evidence: EvidenceRef) raises -> Bool: + if evidence.kind != "span": + raise Error("span_is_valid requires span evidence") + return evidence.end <= text.byte_length() + + +def validate_span_against_revision( + text: String, source_revision: String, evidence: EvidenceRef +) raises: + if evidence.kind != "span": + raise Error("span evidence required") + if evidence.revision != source_revision: + raise Error("evidence revision does not match source revision") + if not span_is_valid(text, evidence): + raise Error("evidence span exceeds source byte length") + + +def selected_text(text: String, evidence: EvidenceRef) raises -> String: + if evidence.kind != "span": + raise Error("selected_text requires span evidence") + return String(text[byte=evidence.start:evidence.end]) diff --git a/tests/test_domain.mojo b/tests/test_domain.mojo @@ -1,5 +1,6 @@ from std.testing import TestSuite, assert_equal, assert_raises, assert_true +from hyf_core.domain.evidence import EvidenceRef from hyf_core.domain.source import ( actor_id, farm_id, @@ -36,3 +37,39 @@ def test_trusted_source_preserves_revision() raises: def main() raises: TestSuite.discover_tests[__functions_in_module()]().run() + + +from hyf_core.domain.evidence import ( + record_field_evidence, + selected_text, + span_evidence, + span_is_valid, + validate_span_against_revision, +) + + +def test_evidence_span_byte_offsets_and_revision() raises: + var text = "caf\u00e9: 80 lb" + var evidence = span_evidence("s1", "r1", 7, 12, "span") + assert_equal(evidence.kind, "span") + assert_equal(selected_text(text, evidence), "80 lb") + validate_span_against_revision(text, "r1", evidence) + assert_true(span_is_valid(text, evidence)) + + with assert_raises(): + _ = span_evidence("s1", "r1", 5, 4, "span") + + +def test_evidence_rejects_out_of_range_and_revision_mismatch() raises: + var text = "short" + with assert_raises(): + _ = span_evidence("s1", "r1", -1, 2, "span") + var beyond = span_evidence("s1", "r1", 0, 99, "span") + with assert_raises(): + validate_span_against_revision(text, "r1", beyond) + var good = span_evidence("s1", "r1", 0, 3, "span") + with assert_raises(): + validate_span_against_revision(text, "r2", good) + var field = record_field_evidence("s1", "r1", "lot-1", "unreserved_quantity") + assert_equal(field.kind, "record_field") + assert_equal(field.record_id.value(), "lot-1")