mirror of
https://github.com/harvard-edge/cs249r_book.git
synced 2026-05-06 17:49:07 -05:00
v2.3 \u2192 v2.4. ARCHITECTURE.md header + Appendix reflect the completed
migration.
WHAT CLOSED (\u00a711.1 contract):
1. `vault build --legacy-json` regenerates the site's
interviews/staffml/src/data/corpus.json from YAML. 9,199 published
questions, site-compatible shape (chain_positions back to 0-indexed
dict form, bloom_level derived from zone, competency_area aliased
from topic, scope aliased from track). Deterministic via sort_keys +
id-sort.
2. Pre-commit hook INSTALLED via worktree-aware Makefile target
(`make -C interviews/vault-cli hooks`). Symlink points at
pre_commit_corpus_guard.py. Tested end-to-end: direct edit to
vault/corpus.json triggers exit-1 with §11.1 reference.
3. CI equivalence check added to .github/workflows/vault-ci.yml:
regenerates corpus.json from YAML, diffs against committed. Fails
PR on drift with actionable error message.
4. Legacy generators demoted with DEPRECATED headers:
- interviews/paper/scripts/analyze_corpus.py \u2192 vault export-paper
- interviews/staffml/scripts/sync-vault.py \u2192 vault build --legacy-json
- interviews/staffml/scripts/generate-manifest.py \u2192 vault publish
- interviews/vault/scripts/export_to_staffml.py \u2192 vault build --legacy-json
5. New DEPRECATED.md files at interviews/vault/scripts/ and
interviews/staffml/scripts/ map every legacy script to its
replacement. Both directories keep the old scripts for git-history
legibility and archaeology; new contributors see the vault CLI first.
6. ARCHITECTURE.md \u00a7Appendix rewritten as current-state table instead
of aspirational "gone. replaced by..." entries.
NEW TESTS (interviews/vault-cli/tests/test_legacy_export.py \u2014 +4):
- test_legacy_shape_matches_site_interface: every field corpus.ts
declares is present in regenerated JSON.
- test_chain_positions_legacy_shape: 1-indexed new schema \u2192
0-indexed legacy dict form.
- test_emitter_deterministic: byte-stable across reversed input order
(required for CI diff-check).
- test_competency_area_aliases_topic: legacy alias fields populated
correctly.
FULL MATRIX GREEN:
pytest: 38/38 passed in 0.19s (34 + 4 legacy-export)
ruff: All checks passed
hook: exit 0 on clean diff / exit 1 on corpus.json direct edit
e2e: vault build --legacy-json regenerates a bit-identical corpus.json
vs the committed one; CI check wired to catch drift
WHAT'S LEFT (deploy-gated, \u00a720.5 #1, #5, #6 partial, #8, #9):
- Production serves from D1: requires Phase-3 wrangler d1 create + deploy
- Manual QA per CUTOVER_QA.md: requires live staging
- Zero data loss D1-side verification: requires live D1
- 48h monitoring: requires production traffic
These are intrinsically user-action; the YAML-side migration is done.
50 lines
1.5 KiB
Makefile
50 lines
1.5 KiB
Makefile
# Makefile for vault-cli — convenience wrappers over CLI and tests (B.2).
|
|
|
|
PKG_DIR := $(shell pwd)
|
|
# `git rev-parse --git-path hooks` works correctly in both regular clones
|
|
# and worktrees (where .git is a file pointing at the main repo's hooks dir).
|
|
HOOKS_DIR := $(shell git rev-parse --git-path hooks 2>/dev/null)
|
|
HOOK_SRC := $(PKG_DIR)/scripts/pre_commit_corpus_guard.py
|
|
HOOK_DST := $(HOOKS_DIR)/pre-commit
|
|
|
|
.PHONY: install test lint hooks hooks-uninstall help
|
|
|
|
help:
|
|
@echo "Targets:"
|
|
@echo " install pip install -e with dev extras"
|
|
@echo " test run pytest"
|
|
@echo " lint ruff check (mypy is non-blocking at Phase 0)"
|
|
@echo " hooks symlink pre-commit-corpus-guard into .git/hooks/"
|
|
@echo " hooks-uninstall remove the hook symlink"
|
|
|
|
install:
|
|
pip install -e ".[dev]"
|
|
|
|
test:
|
|
pytest tests/ -v
|
|
|
|
lint:
|
|
ruff check src tests
|
|
@mypy src || echo "[mypy] strict is non-blocking at Phase 0"
|
|
|
|
hooks:
|
|
@if [ -z "$(HOOKS_DIR)" ]; then \
|
|
echo "could not resolve git hooks dir; run make from a git checkout"; exit 1; \
|
|
fi
|
|
@mkdir -p "$(HOOKS_DIR)"
|
|
@if [ -e "$(HOOK_DST)" ] && [ ! -L "$(HOOK_DST)" ]; then \
|
|
echo "refusing to overwrite non-symlink at $(HOOK_DST); remove it first"; \
|
|
exit 1; \
|
|
fi
|
|
@ln -sf "$(HOOK_SRC)" "$(HOOK_DST)"
|
|
@chmod +x "$(HOOK_SRC)"
|
|
@echo "installed hook: $(HOOK_DST) -> $(HOOK_SRC)"
|
|
|
|
hooks-uninstall:
|
|
@if [ -L "$(HOOK_DST)" ]; then \
|
|
rm "$(HOOK_DST)"; \
|
|
echo "removed $(HOOK_DST)"; \
|
|
else \
|
|
echo "no symlink at $(HOOK_DST)"; \
|
|
fi
|