metadata:
version: "1.0.0"
author: "Sovereign AI Stack"
description: "Tokenization contract for document chunking and BM25 term extraction"
crate: "trueno-rag"
references:
- "Robertson & Zaragoza (2009) The Probabilistic Relevance Framework: BM25 and Beyond"
- "Manning, Raghavan & Schuetze (2008) Introduction to Information Retrieval, Ch. 2"
equations:
tokenize_invariant:
formula: "tokenize(doc) = [t_1, ..., t_n] where t_i = lowercase(strip_punct(split_whitespace(doc)[i]))"
domain: "doc in String, doc.len() > 0"
invariants:
- "Output tokens are non-empty strings"
- "Token count <= word count of input"
- "All tokens are lowercase"
token_frequency:
formula: "tf(t, d) = count(t in tokenize(d)) / |tokenize(d)|"
domain: "t in String, d in String, |tokenize(d)| > 0"
invariants:
- "0 < tf(t, d) <= 1.0 for t in tokenize(d)"
- "Sum of tf over unique tokens <= 1.0 per token (each tf individually bounded)"
idf_weight:
formula: "idf(t) = log((N - df(t) + 0.5) / (df(t) + 0.5) + 1)"
domain: "N >= 1, 0 <= df(t) <= N"
invariants:
- "idf(t) >= 0 for all terms t"
- "Rare terms have higher idf than common terms"
proof_obligations:
- type: invariant
property: "Non-empty tokens"
formal: "forall t in tokenize(doc): t.len() > 0"
applies_to: all
- type: bound
property: "Token count bounded by input length"
formal: "|tokenize(doc)| <= doc.split_whitespace().count()"
applies_to: all
- type: monotonicity
property: "IDF monotonically decreasing with document frequency"
formal: "df1 < df2 implies idf(df1, N) > idf(df2, N)"
applies_to: all
falsification_tests:
- id: FALSIFY-TOK-001
rule: "Non-empty output tokens"
test: "test_bm25_tokenize"
prediction: "verified"
if_fails: "Tokenizer produces empty strings from consecutive delimiters"
- id: FALSIFY-TOK-002
rule: "Lowercase normalization"
test: "test_bm25_tokenize_lowercase"
prediction: "verified"
if_fails: "Case normalization not applied"
- id: FALSIFY-TOK-003
rule: "IDF monotonicity"
test: "test_bm25_idf_calculation"
prediction: "verified"
if_fails: "BM25 IDF formula incorrect"
kani_harnesses:
- id: KANI-TOK-001
obligation: PO-TOK-001
property: "Non-empty tokens invariant"
bound: 8
strategy: bounded_int
harness: verify_tokenize_non_empty
- id: KANI-TOK-002
obligation: PO-TOK-002
property: "Token count bounded"
bound: 16
strategy: bounded_int
harness: verify_token_count_bound
qa_gate:
id: QA-TOKENIZE
name: "tokenize contract"
min_coverage: 0.90
max_complexity: 20
required_tests:
- test_bm25_tokenize
- test_bm25_tokenize_lowercase
- test_bm25_idf_calculation