Two consecutive PeerCortex deploys today (2026-07-16) broke in the same
way: server.js requires local files (src/backend/config.js,
src/backend/services/smtp.js) that were never actually uploaded to Erik,
because the deploy process was ad-hoc 'cat file | ssh' per-file uploads
with no systematic check that every require() target actually exists on
the target machine. A missing npm dependency (pg) caused the same class
of problem separately.
- .github/workflows/build-verify.yml: runs on every push/PR (Gitea Actions
already has a working runner for this repo, confirmed via the existing
.github/workflows/security-scan.yml on the github-import/main branch).
npm ci, syntax-checks server.js + the other top-level .js files, verifies
every local require() target resolves to an actual file, typechecks
(informational for now -- see the step comment for why), builds dist/,
runs the existing vitest suite. Catches both of today's failures before
they'd ever reach Erik.
- deploy-from-git.sh: replaces the per-file upload process with a single
git pull + npm ci + require()-check + syntax-check + build + backup +
pm2 restart sequence, run manually on Erik. Deliberately NOT wired to a
Gitea Action with SSH secrets -- Erik hosts many unrelated production
services and main can contain code that hasn't been live-verified yet,
so the actual deploy trigger stays a human decision. CI catches
what's broken; this makes running the fix a single repeatable command
instead of a manually-assembled file list.