MODULE 13 · 7 HOUR BUILD
Temporal dependency evidence explorer
Build a reproducible evidence explorer that answers which teams were connected to a deprecated dependency at a specified time, then evaluates passage and graph retrieval on labeled questions.
Build evidence Record your actual checks, results, and limitations.
Build it in stages
- Run the seed to compare the same ownership query at two valid times.
- Create a versioned corpus and typed graph with source passage IDs for dependencies and ownership.
- Add valid-time and recording-time filters plus explicit source-conflict handling.
- Implement bounded relation-aware retrieval with a cited path and an insufficient-evidence response.
- Build a held-out evaluation report covering retrieval metrics, grounded answers, latency, and index cost.
Your acceptance criteria
Use these as your project review. Record commands, outputs, and failure cases in your repository.
- At least 24 questions include local facts, multi-hop joins, temporal boundaries, late facts, and unanswerable cases.
- Every returned relation has a stable source revision and passage reference.
- No answer combines edges whose validity intervals are incompatible with the query.
- The report compares passage-only and graph-assisted retrieval on the same corpus and budget, using actual measured results.
A working starting point
The seed runs as supplied. Extend it to satisfy the full brief. It is a teaching starting point, not a finished portfolio submission.
main.py
python
import json
from collections import defaultdict, deque
EDGES = [
("lib-Q", "checkout", 1, None, "dependency-v1-p2"),
("checkout", "team-red", 1, 5, "ownership-v1-p1"),
("checkout", "team-blue", 5, None, "ownership-v2-p1"),
]
def retrieve(start, at, max_hops=2):
adjacency = defaultdict(list)
for source, target, begin, end, evidence in EDGES:
if begin <= at and (end is None or at < end):
adjacency[source].append((target, evidence))
queue = deque([(start, [])])
seen = {start}
answers = []
while queue:
node, path = queue.popleft()
if node.startswith("team-"):
answers.append({"team": node, "evidence": path})
continue
if len(path) >= max_hops:
continue
for target, evidence in sorted(adjacency[node]):
if target not in seen:
seen.add(target)
queue.append((target, path + [evidence]))
return answers
for at in [4, 5]:
result = {"valid_at": at, "dependency": "lib-Q", "answers": retrieve("lib-Q", at)}
print(json.dumps(result, sort_keys=True))
print("seed graph edges:", len(EDGES))
Push it further
Add community summaries with provenance dependencies, then measure whether global-query quality improves enough to justify summary build and refresh costs.