Skip to main content

Onboarding Engine — Operator Pulse integration

Last updated: 2026-07-20 The Onboarding Engine is an autonomous runtime (Hermes, ~/.hermes on the mini — not in this repo) that tracks operator health on GHL pipeline cards. This app supplies its two health signals over a read-only HTTP endpoint. This doc records the contract, the GHL surface the engine writes to, and the go-live state.

Signals served by this app

Response 200: { "locationId": string, "lastLoginAt": number|null, "lastCreditPullAt": number|null } (401 on missing/wrong token or when AGENT_PULSE_TOKEN is unset — fail closed; 400 on missing locationId.)
  • lastLoginAtghlInstallations.lastSeenAt, stamped fire-and-forget on every operator app open by the login bootstrap routes (app/api/auth/validate-sso, app/api/auth/location-session) via lib/operatorLastSeen.tsinternal.ghlInstallations.touchInstallationLastSeen.
  • lastCreditPullAt — newest creditReportRequests.createdAt per location (by_location_createdAt index, bounded take(1)).
Implementation: convex/agentPulse.ts + route registration in convex/http.ts. Tests: tests/agentOperatorPulse.test.ts (auth matrix, payload shape), tests/operatorLastSeenStamp.test.ts (login-route wiring). AGENT_PULSE_TOKEN was generated and set on the prod Convex deployment (brainy-crocodile-746) on 2026-07-14. Never commit it, and never print it to a terminal or agent transcript (AGENTS.md Safety: printing/exposing secrets is prohibited). To provision the engine, pipe it straight into ~/.hermes/.env without echoing the value (prod deploy key):
Verify presence without exposing it: grep -c '^ENGINE_PULSE_TOKEN=' ~/.hermes/.env.

GHL surface the engine writes to

Funding Machine agency, location ReoQmuh4ooNuHeE5stlj (this is a separate agency from the Leadbuilt admin location, GHL_ADMIN_LOCATION_ID — don’t confuse the two).
  • Pipelines: Onboarding (Pfnl7aNXOFvQxzjYvrjj) and Retention (M1qJVId6EtPGaXq0FGeG).
  • Opportunity custom fields (per-card):
    • Last App Login (Vk5td7RYmFDis48mabBQ, DATE) ← pulse lastLoginAt
    • Last Credit Pull (7DtlDwTpCbIleN8FODEs, DATE) ← pulse lastCreditPullAt
    • Product Location ID (cokiropDHpj8atwrDrqF, TEXT) — mapping field: the operator’s app locationId the engine polls the pulse for. A card without it gets no login/credit data even in live mode.
    • Slack Channel ID (ACD1FcIE6IfXaje1wnkH, TEXT) — activates Slack-kick per card.

Engine-side configuration (mini, ~/.hermes/.env)

  • ENGINE_PULSE_URL=https://brainy-crocodile-746.convex.site
  • ENGINE_PULSE_TOKEN=<AGENT_PULSE_TOKEN> — set via the no-echo command above.
  • ENGINE_MODE=live + ENGINE_LIVE_ACTIONS=<allowlist> — actions not on the allowlist stay dry-run. Internal-only go-live is ENGINE_LIVE_ACTIONS=set_field (GHL field writes live; engine-initiated emails / client-facing notifications stay suppressed until explicitly added). The allowlist only gates what the engine itself sends — it cannot suppress GHL’s own automations. Keep move_stage off the allowlist until the stage-change workflows/automations on the Onboarding and Retention pipelines are audited: a stage move can trigger GHL workflows that send client-facing emails/SMS regardless of engine mode.
  • GHL auth: a dedicated location-scoped Private Integration Token for ReoQmuh4ooNuHeE5stlj (confirmed in place 2026-07-20).

Go-live checklist state (2026-07-20)

  • Convex functions + login stamping deployed and verified in prod (PR #1205; the post-merge deploy race was recovered manually on 2026-07-14).
  • AGENT_PULSE_TOKEN set on prod; endpoint verified fail-closed and serving data.
  • Login stamping confirmed at scale (125/155 installs stamped within the first week).
  • 5 engine dry-run TEST cards deleted from Onboarding/Retention pipelines.
  • Dedicated location-scoped PIT confirmed for the engine.
  • Flip ENGINE_MODE=live + ENGINE_LIVE_ACTIONS=set_field on the mini.
  • Audit the stage-change workflows/automations on the Onboarding and Retention pipelines (confirm none send client-facing messages, or explicitly gate them), then add move_stage to ENGINE_LIVE_ACTIONS.
  • Fill Product Location ID (and Slack Channel ID where wanted) on the real cards.
Known data caveat: the Kevin Hill card (test account, opportunity TZHO5gDZuvsYZSkzo8EH) carries a synthetic Last App Login = 2026-07-20 written manually while testing the pipe end-to-end; the location’s lastSeenAt was stamped via ghlInstallations:touchInstallationLastSeen rather than a real app open.