week_1-2: Module C — eval harness skeleton + TRACT hub-firewall + scoring#3
Open
PRAteek-singHWY wants to merge 2 commits into
Open
week_1-2: Module C — eval harness skeleton + TRACT hub-firewall + scoring#3PRAteek-singHWY wants to merge 2 commits into
PRAteek-singHWY wants to merge 2 commits into
Conversation
Adds the three internal modules the eval harness composes: - hub_firewall.py: TRACT-style strip of test-row text from the CRE hub representations before scoring (W1's correctness deliverable — without it the locked +33%/+29% pre-code numbers may be leakage-inflated). Whitespace and case insensitive. The CRE vector hub itself arrives W3; W1 models the hub as (cre_id, text) reps so the methodology and its test exist now. - scoring.py: Q-D default multi-link rule (Jaccard >= 0.5 of expected CRE set AND top-1 in set). Isolated in one function and TODO-flagged so a rule change touches one place. Provisional pending mentor confirmation at the Friday call. - knowledge_source.py: abstract KnowledgeSource interface + a FixtureKnowledgeSource stub reading JSONL rows in the KnowledgeQueueItem shape (master guide §1.2). The real DB-backed source lands W8 and yields the same shape. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds scripts/evaluate_librarian.py with the RFC-spec'd CLI args (--dataset, --slice, --limit, --threshold, --top_k_retrieval, --top_k_rerank, --dry_run, --no_hub_firewall) and the hub-firewall ON by default. predict() is a stub (real retriever/ranker arrive W3-W4); the harness exercises the dataset, scorer, and firewall end-to-end so the ruler is ready before any pipeline code. Adds the 10-row seed golden_dataset.json (5 slices: explicit, positive, hard_negative, update, ambiguous) so the harness has something to run against. The real 277-row DB-derived set replaces this in week_1-3. Adds hub_firewall_test.py (asserts the row's text is absent from the hub after firewalling — the W1 correctness assertion) and scoring_test.py (Jaccard boundary, top-1-in-set, empty prediction, exact match). 40/40 librarian tests green. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this PR is
This is the second of three PRs for Module C, Week 1. PR 1 (
week_1-1) landed the RFC-aligned Pydantic contracts and config. This PR lands the regression scaffolding — the eval harness, the TRACT hub-firewall (W1's correctness deliverable), the provisional Q-D scoring rule, the abstract knowledge-source interface with a fixture stub, and a small seed golden dataset so the harness actually runs end-to-end. PR 3 (week_1-3) will replace the seed with the real 277-row dataset derived from the OpenCRE DB.This is a stacked PR — its base is
gsocmodule_C_week_1_1(notmain), so reviewers see only the W1-2 changes. Onceweek_1-1merges, GitHub will re-target this tomainautomatically and the diff stays clean.Why this PR exists
The W1 contract was contracts + tests before any pipeline code. PR 1 nailed the contracts. This PR nails the ruler — the thing every future C PR (W4 cross-encoder, W6 decision engine, W8 live integration) will be measured against in CI. Without it, accuracy claims can drift silently. The hub-firewall part is the specific deliverable our internal notes call out as W1-critical (see
module-c-weekly-deliverables.md,tract-analysis-module-c.md§3.4, master guide §5.7 + §9.3).What's in this PR, step by step
1. The TRACT hub-firewall (
hub_firewall.py+hub_firewall_test.py)The problem: the OpenCRE graph already links most ASVS/WSTG content to CREs. If we evaluate retrieval on those same standards, the "CRE hub" representation contains the exact text under test → retrieval echoes the text back → reported accuracy is inflated.
The fix: before scoring any golden-set row, strip that row's text from the hub. Whitespace and case insensitive. The CRE vector hub arrives W3 — for now the hub is modeled as a list of
(cre_id, text)reps so the methodology and the test exist before any number is claimed.The harness has the firewall ON by default;
--no_hub_firewallis an explicit escape hatch for ablation. The test asserts the row's text is absent from the hub after firewalling — the W1 correctness assertion.2. The Q-D scoring rule (
scoring.py+scoring_test.py)A chunk can map to several CREs. What counts as "correct" in CI? The provisional rule, isolated in one function and marked
# TODO(Q-D):Strict enough to penalise broad over-linking, lenient enough to not punish near-miss ordering. Tests cover the Jaccard boundary, top-1 outside the expected set, empty predictions, exact match. Confirmation needed at the Friday call before this PR merges — see the "Open question" section.
3. The abstract knowledge source (
knowledge_source.py)Defines the
KnowledgeSourceinterface + aFixtureKnowledgeSourcestub that reads JSONL rows in theKnowledgeQueueItemshape (master guide §1.2) — the same shape the real DB-backed source at W8 will yield. Future weeks swap the implementation; the interface stays.4. The eval harness skeleton (
scripts/evaluate_librarian.py)CLI:
--dataset --slice --limit --threshold --top_k_retrieval --top_k_rerank --dry_run --no_hub_firewall. Wires together the dataset loader, the scorer, the firewall, and apredict()stub. Output:The
correct 2/10baseline is right: the 2review-decision rows expect no CRE ids, so empty predictions match; the 8linked-decision rows correctly show as not-yet-predicted. Once a real retriever lands, the same harness measures it.5. Seed golden dataset (
fixtures/golden_dataset.json)10 rows, 2 per slice (explicit, positive, hard_negative, update, ambiguous), schema-valid (round-trips against
GoldenDatasetRowfromweek_1-1). CRE ids are placeholders;provenance.ground_truth_sourcehonestly records that. The full 277-row DB-derived dataset replaces this inweek_1-3.What is deliberately NOT in this PR
golden_dataset.json— lands inweek_1-3.cre.py— W3 per master-guide §8.2.How to verify locally
Black-clean. No existing repo file touched beyond what
week_1-1already pinned (pydantic).Open question for mentors — blocks this PR's merge
Q-D — multi-link scoring rule. Default proposed: Jaccard ≥ 0.5 of expected CRE set AND top-1 in set. Other reasonable defaults exist (exact-set match — too harsh; top-1 only — ignores multi-link reality). Confirmation appreciated at the Friday call. Until then, the default is in place and TODO-flagged in
scoring.pyso a rule change touches one function.Stacked on
gsocmodule_C_week_1_1. Next:week_1-3(real 277-row golden dataset derived fromstandards_cache.sqlite'scre_node_links).