Files
Vijay Janapa Reddi f1ffe5b6fa Rename interviews/ to staffml/ and drop the repeated prefix inside it
interviews/ held StaffML and nothing else, so the directory now carries the
product's name. Three names inside it repeated that prefix, and now line up
with vault/, vault-cli/, and paper/:

  interviews/staffml/               -> staffml/app/
  interviews/staffml-vault-worker/  -> staffml/vault-worker/
  interviews/staffml-vault-types/   -> staffml/vault-types/

Every repository path moved with it: workflow paths: triggers and variable
fallbacks, pre-commit hooks, .gitignore, contributor tooling, vault-cli path
joins, the app's tsconfig mapping to the shared types, and the docs.

Left alone on purpose:
- the published /interviews/ redirect to /staffml/ and the gh-pages subsite
  lists that protect it; those are URLs, not repository paths
- package and worker names (staffml-vault-worker, @staffml/vault-types) and
  the vitest job name, which branch protection may key on
- question YAMLs and generated track JSON, which are content-addressed.
  Three questions carry an older corruption, "recall @interviews/vault/
  questions/...", that predates this change
- the applied D1 migration 0001 and the vault CHANGELOG, which are history

codegen-hashes.txt is re-recorded; the three pinned artifacts changed only in
path strings. vault-cli: 97 passed, codegen --check clean.

interviewer.py's __main__ loader was one parent short and pointed at a
corpus.json that never existed; it now resolves staffml/app/src/data/
corpus.json. tools/validate_playbook.py and generate_interview_flashcard.py
still expect per-track directories that no longer exist; they point at the
new root but remain dead.

The GitHub repository variables STAFFML_ROOT, VAULT_DIR, and VAULT_CLI_DIR
still name the old paths and must change when this reaches origin.
2026-09-10 14:48:04 +02:00

70 lines
2.2 KiB
Python

#!/usr/bin/env python3
"""Validate bibliography entries in paper.bbl against CrossRef.
Reads paper.bbl from the paper directory, extracts each \\bibitem's rough
title, queries CrossRef, and reports whether a match was found. Useful as a
spot-check after large bibliography edits to catch typos, wrong years, or
silently-renamed works.
Run: python3 staffml/paper/scripts/validate_refs.py
Reads: ../paper.bbl (generated by LaTeX from references.bib)
Writes: stdout — [OK] / [WARN] / [ERR] per citation key
"""
import json
import re
import time
import urllib.parse
import urllib.request
from pathlib import Path
SCRIPTS_DIR = Path(__file__).parent
PAPER_DIR = SCRIPTS_DIR.parent
BBL_FILE = PAPER_DIR / "paper.bbl"
with open(BBL_FILE, "r") as f:
bbl = f.read()
# Extract bibitems
entries = re.split(r"\\bibitem\[.*?\]\{(.*?)\}", bbl)[1:]
keys = entries[0::2]
blocks = entries[1::2]
print(f"Checking {len(keys)} cited references...")
results = []
for i, (key, block) in enumerate(zip(keys, blocks)):
# Very rough extraction: grab text after \newblock up to a period
m = re.search(r"\\newblock (.*?)\.", block.replace("\n", " "))
title = m.group(1) if m else key
title = re.sub(r"\\[a-zA-Z]+", "", title)
title = re.sub(r"[\{\}\[\]\$\^~]", "", title)
title = title.strip()
if len(title) < 5:
title = key
try:
url = (
"https://api.crossref.org/works?query.title="
+ urllib.parse.quote(title)
+ "&select=title,author,URL&rows=1"
)
req = urllib.request.Request(
url, headers={"User-Agent": "mailto:vj@eecs.harvard.edu"}
)
with urllib.request.urlopen(req) as response:
data = json.loads(response.read().decode())
if data["message"]["items"]:
top_hit = data["message"]["items"][0]
crossref_title = top_hit.get("title", [""])[0]
results.append(f"[OK] {key}: Found '{crossref_title}'")
else:
results.append(f"[WARN] {key}: No CrossRef hit for '{title}'")
except Exception as e:
results.append(f"[ERR] {key}: {str(e)} for '{title}'")
time.sleep(0.1)
for r in results:
print(r)