# ResearchOwl — developer tasks. # # SEO engine vendoring: src/seo/rules.py is a byte-for-byte copy of the canonical # seo_rules.py (repo git.chemavx.xyz/chemavx/chemavx-seo-tools; local working copy # ~/seo-tools). These targets keep the vendored copy in sync; CI enforces it too. SEO_TOOLS_DIR ?= $(HOME)/seo-tools CANON := $(SEO_TOOLS_DIR)/seo_rules.py VENDORED := src/seo/rules.py HEADER := src/seo/_vendor_header.py MARKER := BEGIN VENDORED seo_rules.py .PHONY: sync-seo check-seo-sync sync-seo: ## Re-copy canonical seo_rules.py into the vendored file + record hash @test -f "$(CANON)" || { echo "canonical not found at $(CANON)"; exit 1; } @cat "$(HEADER)" "$(CANON)" > "$(VENDORED)" @sha256sum "$(CANON)" | cut -d' ' -f1 > src/seo/.rules.sha256 @echo "synced $(VENDORED) from $(CANON) (sha $$(cat src/seo/.rules.sha256))" check-seo-sync: ## Fail if the vendored copy diverges from the local canonical @test -f "$(CANON)" || { echo "canonical not found at $(CANON) — skipping (run on a machine with seo-tools)"; exit 0; } @N=$$(grep -n "$(MARKER)" "$(VENDORED)" | head -1 | cut -d: -f1); \ tail -n +$$((N+1)) "$(VENDORED)" > /tmp/_vendored_body.py; \ if cmp -s /tmp/_vendored_body.py "$(CANON)"; then \ echo "seo engine in sync ($(VENDORED) == $(CANON))"; \ else \ echo "SEO ENGINE DRIFT: $(VENDORED) != $(CANON). Run 'make sync-seo' and commit."; \ diff -u "$(CANON)" /tmp/_vendored_body.py | head -40; exit 1; \ fi