- Add idempotent append in quinn.api/deploy.sh for MAC_SYNC_BASE_URL + SERVICE_TOKEN (matching the pattern used for MODEL_BOSS, ANALYTICS_DB etc.). Old secrets.env files that predated the send support would cause prospect-cockpit /send (and /m/messages/send) to 502 with 'mac_sync_unavailable' / 'MAC_SYNC_URL env var required'.
- Explicitly pass the same MAC_SYNC_* in scripts/run/dev.sh dev:api so local dev quinn.api (on 3040) can exercise scheduled-send / cockpit_send flows against the canonical black mac-sync-server.
- Live hotfix: appended the lines to /etc/quinn-api/secrets.env on black + restarted quinn-api (verified: now present in running process env; end-to-end /my/prospects/.../send now returns scheduledId instead of 502; test row cancelled cleanly via mac-sync admin).
This makes cockpit_send (quinn-prospector) and sibling send surfaces work when the MCP targets the real backend (black:3912 -> localhost:3030 quinn.api).
Refs the exact error from the report.
The data MCP is purely read-only analytics, so rename the package
(@lilith/quinn-data-mcp → @lilith/quinn-analytics-mcp), bin, server name,
logger prefix, and the .mcp.json client key to match. The systemd deploy
instance key stays `data` (quinn-mcp@data, black:3914) — noted in the deploy
script and mcp-servers.md. Updates all doc/content references (nyc-tour SEO,
twitter handoff, deploy comments).
- acquisition/sources: drop the ${corpFilter} interpolation. postgres.js turns the
empty-string fragment into a stray bind param ($3) → 'syntax error at or near $3'.
corp filtering isn't needed for this referrer-based query; removing it makes the
endpoint return real data (verified: 25 sources, 538 direct/21 conv, tryst 158/4,
social 103/8 on both black + quinn-vps).
- deploy.sh secrets template: ANALYTICS_DB_URL pointed at black.lan:25434 (the EMPTY
black analytics instance) with no password. Point at the populated DB on quinn-vps
(10.9.0.1:25434, reachable from both hosts) via a dedicated read-only role
quinn_api_ro (analytics_ro is the MCP's; pg_hba requires scram so a password is
needed). Password left blank in-repo; filled in live secrets.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
deploy.sh assumed passwordless sudo on the remote — true for black, but quinn-vps
runs the deploy as root with no sudo, so every 'sudo systemctl/install/tee' failed
with 'sudo: command not found' (the 10-day-old deploy-quinn-api breakage). Resolve
sudo once per host (REMOTE_SUDO locally, SUDO inside the remote heredoc) and use it
only when present. Verified: clean deploys to both black (sudo) and quinn-vps (root).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Provision PROSPECT_LLM_BACKEND=claude and CLAUDE_CODE_OAUTH_TOKEN in quinn-api
secrets, put claude on PATH for www-data, and add prospector-black-claude-setup.sh
to install the token after `claude setup-token`.
Completes the Stage-1 edge-cache photo migration:
- prod.conf /photos/: proxy_pass http://black_photos/ (trailing slash) — the
origin serves BARE filenames, so the edge must strip the /photos/ prefix.
Verified: bare=200, /photos/-prefixed=404 against the live origin.
- prod.conf /og-image.jpg: try_files → proxy_pass 127.0.0.1:3099 (the DRY
hero share-image helper), matching the live VPS so the next deploy is a
no-op, not a regression.
- deploy-photo-origin.sh: rewritten to deploy a dedicated nginx:alpine
container (network=host, :8081, restart=always) running origin-photos.conf
verbatim. Black's system nginx has been disabled+failed since 2026-05-17;
the live server is the host-network host-nginx container loading a
monolithic nginx.conf — so the origin must be isolated, not in
system-nginx sites-enabled (the old script's dead mechanism).
- README-vps-owned.md step D: corrected path (dist/photos not quinn.admin),
mechanism (container), and smoke (real file, no /health endpoint).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>