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
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.)
lastLoginAt—ghlInstallations.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) vialib/operatorLastSeen.ts→internal.ghlInstallations.touchInstallationLastSeen.lastCreditPullAt— newestcreditReportRequests.createdAtper location (by_location_createdAtindex, boundedtake(1)).
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):
grep -c '^ENGINE_PULSE_TOKEN=' ~/.hermes/.env.
GHL surface the engine writes to
Funding Machine agency, locationReoQmuh4ooNuHeE5stlj (this is a separate agency
from the Leadbuilt admin location, GHL_ADMIN_LOCATION_ID — don’t confuse the two).
- Pipelines:
Onboarding(Pfnl7aNXOFvQxzjYvrjj) andRetention(M1qJVId6EtPGaXq0FGeG). - Opportunity custom fields (per-card):
Last App Login(Vk5td7RYmFDis48mabBQ, DATE) ← pulselastLoginAtLast Credit Pull(7DtlDwTpCbIleN8FODEs, DATE) ← pulselastCreditPullAtProduct 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.siteENGINE_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 isENGINE_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. Keepmove_stageoff 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_TOKENset 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_fieldon 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_stagetoENGINE_LIVE_ACTIONS. - Fill
Product Location ID(andSlack Channel IDwhere wanted) on the real cards.
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.
