verae-mcp-timestamping-serv.../docs/cutover.md
George Lambert 30b5df6757 docs: cutover checklist and tsnats usage
Add docs/cutover.md (shadow :8001, embedded NATS :4223, REQUIRE_BEARER
host-token default, cutover/rollback; no JetStream for job-complete).
Expand README Usage with env table and pkg/tsnats snippet; add
examples/tsnats-bulk.
2026-09-29 12:14:46 -04:00

3.2 KiB

Shadow deploy and cutover (Go MCP)

Python stays on 127.0.0.1:8000. Go shadows on 127.0.0.1:8001 with embedded NATS on 127.0.0.1:4223. Do not install or enable the Go unit on ns1 until an explicit publish/deploy order.

Shadow layout

Role Bind Notes
Python MCP (live) 127.0.0.1:8000 Caddy → public /mcp
Go MCP (shadow) 127.0.0.1:8001 Internal smoke only until cutover
Go embedded NATS 127.0.0.1:4223 pkg/tsnats / bulk workers

Install tree (when deploying): /opt/verae/verae-mcp-timestamping-server-go/ (does not overwrite the Python venv). Unit file in-repo: deploy/verae-mcp-timestamping-go.service.

Bearer / host-token (shadow default)

VERAE_MCP_REQUIRE_BEARER Behavior
0 or unset (default) Caller Authorization: Bearer wins when present. Otherwise the process keeps a host token from ~/.verae/auth.properties (or VERAE_AUTH_PROPERTIES / VERAE_GLOBAL_TOKEN) and refreshes before expiry.
1 Caller bearer required for global VeraeTime paths; no host-token fallback.

Shadow unit ships VERAE_MCP_REQUIRE_BEARER=0 so operators can smoke without every client supplying a JWT.

Embedded NATS / job-complete

  • Listen: VERAE_NATS_LISTEN=127.0.0.1:4223 (set empty to disable embed).
  • Request/reply: verae.ts.request, verae.ts.verify, verae.hash.report.
  • Job-complete / jobId notify: core NATS only on verae.ts.completed (and receipt notify if used). No JetStream (or other persistent stream) for job-complete. Publishers fire-and-forget; listeners subscribe.

Env cheat sheet (shadow)

VERAE_MCP_TRANSPORT=streamable-http
VERAE_MCP_HOST=127.0.0.1
VERAE_MCP_PORT=8001
VERAE_NATS_LISTEN=127.0.0.1:4223
VERAE_MCP_REQUIRE_BEARER=0
# optional: VERAE_AUTH_PROPERTIES, VERAE_LEDGER_PATH, VERAE_GLOBAL_URL, VERAE_GLOBAL_TOKEN, VERAE_MCP_CORS

Service user on ns1 is verae-mcp with HOME=/var/lib/verae-mcp (share or isolate auth.properties vs Python as chosen for the soak).

Local parity before soak

With Python on :8000 and Go on :8001:

./scripts/parity_smoke.sh

Compares tools/list name sets. Optionally stamp/verify/hash_report the same digests against both ports during soak.

Cutover checklist

  1. Shadow green for the agreed soak (tools/list parity, global stamp/verify/hash_report, local ledger, NATS stamp + verae.ts.completed observe).
  2. Stop Python unit or switch Caddy upstream away from :8000 Python.
  3. Point Go at public port: set VERAE_MCP_PORT=8000 (or leave Go on 8001 and point Caddy at Go).
  4. Confirm https://mcp.verae.ai/mcp tools/list and a known digest hash_report.
  5. Keep the Python tree on disk for one release cycle.
  6. Do not enable JetStream for job-complete as part of cutover.

Rollback checklist

  1. Restore Python ExecStart / Caddy upstream to 127.0.0.1:8000 Python.
  2. Stop or disable verae-mcp-timestamping-go.service (or move Go back to :8001 only).
  3. Restart Python; confirm public tools/list and a known hash_report.
  4. Leave Go binary under /opt/verae/verae-mcp-timestamping-server-go/ for a later retry; do not delete until soak of the rollback is confirmed.