Milestone 4 of 9

Score and rank both systems with complete traces

Reproduce the integer baseline, calculate tf-idf cosine contributions and norms, apply exact rounding and ties, and retain complete positive rankings.

Now score the same query/document candidates two ways. Keep the arithmetic visible so a rank is reproducible rather than an unexplained number.

Goal

Reproduce the exact integer term-count baseline and supplied tf–idf cosine score, record complete contributions and norms, and apply deterministic ranking ties to the complete positive-score results.

Inputs

Use the positional index, term and document weights, document norms, analyzed query vectors, query norms, validated configuration, and query/document order. Both systems use the same candidate documents: documents containing at least one in-index query term.

For the baseline, calculate over distinct in-index query terms:

term_contribution = query_term_count * document_term_count
baseline_score = sum(term_contribution)

Save one row per distinct query term, including zero contribution when that term is absent from a candidate document. For cosine, calculate:

numerator_contribution(t) = query_weight(t, q) * document_weight(t, d)
dot_product = sum(numerator_contribution(t) for t in in-index query terms)
raw_cosine_score = dot_product / (query_norm * document_norm)

Only positive dot products and non-zero norms enter cosine rankings. The raw score must be finite and within [0, 1] under the configured tolerance. Round the raw value to exactly twelve decimal places to form ranking_score, while retaining the raw value separately. The baseline's exact integer score is its ranking_score.

Deliverables

Implement src/score.py. Produce output/score_contributions.csv with both systems' term-level contributions, sums, norms, raw scores, and ranking scores; produce complete output/ranked_results.jsonl records for both systems. Each ranked record contains query ID, system identity, rank ordinal, document ID, score fields, matched-distinct-query-term count, and the contribution evidence.

Rank each system independently by decreasing ranking_score, decreasing matched-distinct-query-term count, then lexicographically increasing document_id. Rank starts at one. Return every positive-score result; do not insert zero-score documents or truncate before evaluation.

Checks

Hand-check exact baseline contributions, cosine numerator contributions, dot products, norms, raw-versus-rounded identity, finite bounds, candidate sets, and all three tie stages. Check repeated query terms are counted as specified, missing terms contribute zero, zero-norm queries produce empty rankings, and zero-term documents remain in accounting but not positive rankings.

Check every positive-score document appears once, every contribution sum agrees with its score, query and document identities remain stable, and the two systems use identical candidates. Do not call the baseline a probability or a semantic score, and do not treat display tie keys as additional relevance evidence.

Workspace

Keep scoring and ranking in src/score.py. Read prior sparse artifacts and write contributions and complete rankings in deterministic CSV and JSONL. Do not align judgments or calculate cutoffs yet.

Hints

HintMake the candidate set explicit
Start from documents that contain at least one in-index query term. The candidate set is shared; only the scoring rule changes.
HintRound after the raw score
Retain the raw cosine value, round it to twelve places, and sort by the rounded ranking_score. Never sort by an unstated tolerance.
HintTrace a zero
A zero contribution row explains why a candidate's term was absent. Keep it instead of dropping the row and making the score look less complete.

Review

Choose one query/document pair and reproduce both scores from the contribution rows. Then inspect a tie resolved by each secondary key. What evidence belongs to the score, and what merely makes the display deterministic?

How to check your work

Checks compare contributions, norms, raw and rounded scores, candidate sets, and rank order with the hand-check fixtures. The supplied fixture returns complete positive rankings and does not add top_k or a relevance interpretation.

LLM PrimerScore and rank both systems with complete traceshttps://llmprimer.com/python/projects/build-a-ranked-retrieval-and-evaluation-workbench/score-and-rank-both-systems-with-complete-traces© 2026 LLM Primer