CLI command
funnel
Funnel drop-offs: each step's conversion to the next compared between two windows, hypotheses that cite both rates for a step that fell, those hypotheses queued in the growth hypothesis queue, and runs made on a schedule with an alert for a fallen step.
Invocation#
echo-cli funnel list --product <id>
echo-cli funnel add --product <id> --name <text> --app <web or mobile source> --step <event name>... --by <name>
echo-cli funnel remove --id <funnel-id>
echo-cli funnel dropoffs --funnel <funnel-id> --days <n> --drop <fraction> --by <name>
echo-cli funnel runs --funnel <funnel-id>
echo-cli funnel queue --run <run-id> --from <step event> --place <n> --impact <n> --confidence <n> --ease <n> --by <name>
echo-cli funnel schedule --funnel <funnel-id> --days <n> --drop <fraction> --every-days <n> --notify-user <user-id> --by <name>
echo-cli funnel schedules
echo-cli funnel unschedule --funnel <funnel-id>
echo-cli funnel dueInputs and output#
list writes the product's funnels by name: id, product_id, name, app_id, steps (the event names in order), created_by and created_at; add and remove write the funnel they made or removed. dropoffs writes the run it stored: id, funnel_id, window_days, drop_points, previous_from and current_from (where each window starts), steps, hypothesis_route, computed_by and computed_at. Each step has from and to (the two events), previous and current (each with entered, converted and rate, null when no one entered), dropped, and hypotheses (empty unless dropped). runs writes a funnel's stored runs, newest first. queue writes the hypothesis it queued, as echo-cli hypotheses list prints one, with dropoff_run_id and dropoff_step (from → to).
State effect#
Every verb calls Echo Web's authenticated /api/analytics/funnels or /api/analytics/funnels/dropoffs with ECHO_INTERNAL_BEARER at ECHO_WEB_BASE_URL; the Funnel drop-offs section of the tracking screen and of Echo Desktop's GEO screen call the same operations (each hypothesis with its own Queue), and echo-mcp lists funnels (echo_list_funnels), reads runs (echo_funnel_dropoff_runs) and queues a hypothesis (echo_funnel_queue_hypothesis) but runs nothing. --step repeats once per step, in order, at least twice. dropoffs reads the source's stored events over twice --days ending now — a web source's web events or a mobile app's mobile events — and joins every identifier the identity edges link into one person. In each window, a person entered a step when they sent its event there and converted when they sent the next step's event after it in the same window; a step is flagged when both windows had people enter it and its rate fell by at least --drop (a fraction above 0 and at most 1, so 0.1 is ten points). For each flagged step, the model route the deployment declares in ECHO_FUNNEL_HYPOTHESIS_ROUTE is asked through Brama for hypotheses; only those quoting both rates exactly as Echo wrote them, one decimal of a percent, are kept. queue takes the hypothesis at --place (counted from one) of the step from --from in the run, unchanged, and queues it in the funnel's product's growth hypothesis queue with the ICE scores given (see hypotheses), keeping the run and step it came from; a hypothesis is queued from a step once. schedule writes the schedule it stored: funnel_id, window_days, drop_points, every_days, notify_user, declared_by, declared_at, attempted_at, run_id, alert_id and error; schedules writes { schedules }, oldest declared first; unschedule writes the schedule it removed (its runs stay); due writes { schedules }, the ones it attempted. Schedules call /api/analytics/funnels/schedules, and the daily /api/cron/funnel-dropoffs runs every schedule never tried or last tried at least every_days ago: it makes the run as dropoffs does (computed_by "schedule declared by <name>"), and when a step is flagged raises one pending action of type funnel_dropoff for notify_user naming every flagged step with both rates and the run (metadata funnel_id, run_id, window_days, drop_points, steps). echo-mcp lists them as echo_funnel_dropoff_schedules; the tracking screen's Funnel drop-offs panel shows each funnel's schedule and Echo Desktop's Scheduled drop-off runs section the same, each with schedule, unschedule and run due now.
Refusals#
- A wrong invocation is refused before anything is sent: "funnel takes <every usage, separated by semicolons>; got <word>", "funnel <verb> does not take <flag>; it takes …", "<flag> needs a value", "--step needs a value" and "funnel <verb> needs <flag>" for each flag the verb needs.
- queue is refused before anything is sent with "--place must be a number; got <text>" (and --impact, --confidence, --ease), and by Echo Web with "place must be a positive whole number: …; got <value>", "the step <from> → <to> of run <id> did not fall, so it proposed no hypothesis", "the step <from> → <to> of run <id> proposed <n> hypotheses; got place <n>" and the hypotheses refusals for a score that is not positive; not found with "no drop-off run has id <id>" or "run <id> has no step from <event>; its steps start at <events>"; and a conflict with "that hypothesis of <from> → <to> in run <id> is already queued as <hypothesis id>".
- schedule is refused before anything is sent with "--days must be a number; got <text>" (and --drop, --every-days), and by Echo Web with "every_days must be a positive whole number: how many days pass between runs; got <value>", "window_days must be a positive whole number of days; got <value>", "drop_points must be above 0 and at most 1: …; got <value>", "notify_user is required: the id of the user whose pending actions receive the alert; got <value>" or "declared_by is required: an internal caller has no signed-in user, so it names who is acting"; not found with "no funnel has id <id>; echo-cli funnel list --product <id> lists them"; unschedule answers not found with "funnel <id> has no drop-off schedule; echo-cli funnel schedules lists them". A scheduled run that fails (an undeclared route, a route citing neither rate) does not stop the others: its schedule keeps attempted_at and the error, and its previous run and alert.
- Echo Web answers a bad request with "product_id is required: …", "name is required: …", "app_id is required: …", "steps is required: at least two stored event names, in the order a person takes them", "steps[<n>] is required: …", "steps names <event> twice; each step is a different event", "funnel_id is required: …", "window_days is required: …", "window_days must be a positive whole number of days; got <n>", "drop_points is required: …", "drop_points must be above 0 and at most 1: the fall in conversion that flags a step; got <n>" or "computed_by is required: …"; not found with "no product has id <id>; echo-cli products lists the ones that exist" or "no funnel has id <id>; echo-cli funnel list --product <id> lists them"; and a conflict with "product <id> already has the funnel <name> as <id>". A run without the route answers "ECHO_FUNNEL_HYPOTHESIS_ROUTE is required", and a route that cites neither rate answers "the route <route> proposed no hypothesis for <from> → <to> citing both <rate> and <rate>: <what it said>"; nothing is stored then. The command prints Echo Web's sentence and exits 1.