diff --git a/Makefile b/Makefile index 25e9ba1..dfbd47b 100644 --- a/Makefile +++ b/Makefile @@ -12,10 +12,18 @@ VALIDATOR := $(PYTHON) tools/validate_content.py GO ?= go TEMPL ?= templ +# The runtime image is distroless/static (deploy/Dockerfile): no libc, no +# dynamic loader. Everything the server needs is pure Go (modernc.org/sqlite), +# so a static binary is buildable and is what the container can actually exec. +# Without this the build host's cgo links the nix glibc loader and the container +# fails with "exec /usr/bin/resume-server: no such file or directory". +CGO_ENABLED ?= 0 + BIN := bin DIST := dist -.PHONY: build dist generate dev test validate validate-self-test fmt vet clean help +.PHONY: build dist generate dev test validate validate-self-test fmt vet clean help \ + corpus corpus-sync corpus-rebuild corpus-audit corpus-verify corpus-demo corpus-test help: @echo "make build templ generate, compile bin/, no dist" @@ -26,11 +34,19 @@ help: @echo "make validate validate content/** front-matter against the frozen schema" @echo "make fmt vet gofmt / go vet over cmd and internal" @echo "make clean remove bin/ and dist/" + @echo "" + @echo "corpus (Phase 4, python3 -m corpus.cli):" + @echo "make corpus rebuild the corpus from content/ (drops the collection)" + @echo "make corpus-sync incremental update; only changed documents are re-embedded" + @echo "make corpus-audit freshness + drift audit (exit 1 on findings)" + @echo "make corpus-verify check the index against content/ and Qdrant" + @echo "make corpus-demo same query with and without an area filter" + @echo "make corpus-test corpus unit tests (no container, no network)" build: generate @mkdir -p $(BIN) - $(GO) build -trimpath -buildvcs=false -o $(BIN)/resume-build ./cmd/build - $(GO) build -trimpath -buildvcs=false -o $(BIN)/resume-server ./cmd/server + CGO_ENABLED=$(CGO_ENABLED) $(GO) build -trimpath -buildvcs=false -o $(BIN)/resume-build ./cmd/build + CGO_ENABLED=$(CGO_ENABLED) $(GO) build -trimpath -buildvcs=false -o $(BIN)/resume-server ./cmd/server dist: build @$(BIN)/resume-build --dist $(DIST) @@ -57,5 +73,34 @@ fmt: vet: @$(GO) vet ./... +# -- corpus (Phase 4, docs/phase-4-corpus.md) -------------------------------- +# +# The corpus is data, not a build artefact: it lives in data/corpus/ (gitignored) +# and in Qdrant. RESUME_QDRANT_URL defaults to http://127.0.0.1:6333 and +# RESUME_EMBED_PROVIDER defaults to local-hashing; production sets both in the +# environment, never in this file. + +CORPUS := $(PYTHON) -m corpus.cli + +corpus: corpus-rebuild + +corpus-rebuild: + @$(CORPUS) rebuild + +corpus-sync: + @$(CORPUS) sync + +corpus-audit: + @$(CORPUS) audit --fail-on-findings + +corpus-verify: + @$(CORPUS) verify + +corpus-demo: + @$(CORPUS) demo-filter --query "distributed audio endpoints" --area edge + +corpus-test: + @$(PYTHON) -m unittest discover -s corpus/tests -t . + clean: @rm -rf $(BIN) $(DIST) diff --git a/deploy/compose.yml b/deploy/compose.yml index d59b037..53bdc65 100644 --- a/deploy/compose.yml +++ b/deploy/compose.yml @@ -12,7 +12,14 @@ # # `curl http://127.0.0.1:8096/healthz` must answer with static ready. -name: ai-resume +# The compose project name is deliberately not `ai-resume`: /home/sam/deployment/ +# ai-resume on .13 already runs a compose project by that name (backend + db on +# the ai-mesh network). Sharing the name would make this site's containers show +# up as orphans in that project and vice versa, so anything running `compose +# down --remove-orphans` under either project could stop the other. The image +# tag stays ai-resume:local (Phase 3 fixes it); only the project namespace is +# distinct. +name: ai-resume-site services: resume: diff --git a/deploy/deploy.sh b/deploy/deploy.sh index 60f75c4..e1939c9 100755 --- a/deploy/deploy.sh +++ b/deploy/deploy.sh @@ -38,7 +38,9 @@ set -Eeuo pipefail -APP=ai-resume +APP=ai-resume # image tag (fixed by Phase 3 ยง3.2) +PROJECT=ai-resume-site # compose project; distinct from the older + # /home/sam/deployment/ai-resume project on .13 PORT=8096 HEALTH_PATH=/healthz @@ -92,7 +94,7 @@ done # ---------------------------------------------------------------- helpers --- -compose() { docker compose -f "$COMPOSE" -p "$APP" "$@"; } +compose() { docker compose -f "$COMPOSE" -p "$PROJECT" "$@"; } current_target() { readlink -- "$CURRENT" 2>/dev/null || true; } previous_target() { readlink -- "$PREVIOUS" 2>/dev/null || true; }