Skip to content

whats a valid variable vs event payload (detect_machine) #333

@Len-PGH

Description

@Len-PGH

Reference: issues/18972#issuecomment-4478791375

detect_machine casing — investigation

Headline finding

The code matches the hosted documentation. What initially looked like Inconsistency A (lowercase finished among uppercase event values) is documented behavior. What initially looked like Inconsistency B (event channel vs. SWML variable) is two separate documented contracts on two different surfaces.

The reporter's pain is real, but the diagnosis in the GitHub issue was based on a different doc URL (/docs/swml/reference/detect-machine.md) that does not match the hosted page (/docs/swml/reference/calling/detect-machine). On the hosted page the casings line up with the implementation.

The two surfaces and their contracts

Surface Docs say (hosted) Code emits Source
calling.call.detect event payload params.detect.params.event HUMAN, MACHINE, READY, NOT_READY, UNKNOWN, finished same relay_detect.c:291, 298, 384, 443, 514-526, 541; relay.c:10644
${detect_result} SWML variable conditional example uses 'machine', 'human', 'fax' (lowercase) machine, human, fax, unknown, detecting, error

Both surfaces are internally self-consistent and consistent with the docs. The trap is that they use different conventions, and a reader doing switch.case on event payloads while expecting them to behave like the variable will be confused.

Where the real problems live (all docs, no code)

1. READY is in the wrong bullet list

The hosted page lists READY and NOT_READY alongside HUMAN, MACHINE, UNKNOWN, and finished as if they're all the same kind of value. They aren't:

  • HUMAN, MACHINE, UNKNOWN are detection outcomes — final results of an AMD attempt. They also (lowercased) populate ${detect_result}.
  • READY, NOT_READY are lifecycle markers for the voice-activity layer — they fire as the call transitions between voice and silence and never appear in ${detect_result}. detect_result_to_str has no READY case.
  • finished is a terminal lifecycle marker — fires once when the detector stops. Also never in ${detect_result}.

Lumping these into one list makes readers think detect_result == 'READY' could match. It can't.

Fix: split the docs list by surface — outcomes vs. lifecycle markers — and make it explicit that READY/NOT_READY/finished only appear in event payloads.

2. The finished casing in docs looks like a typo but isn't

finished is lowercase in a list of otherwise uppercase tokens. Reader instinct is "this is a doc typo, the code probably emits FINISHED." It's not — the code really does emit finished . The docs match.

But it remains weird-looking. Two options if we ever revisit it:

  • Tighten the docs to call out that lifecycle markers (finished) follow a different casing than outcomes (MACHINE). Cheapest.
  • Uppercase the code (FINISHED) for visual consistency. One-line change, but a wire-format break.

Not worth the second option unless we're already touching the wire format for other reasons.

3. The conditional example contradicts the bullet list above it

Same page:

  • Bullet list of valid event values: HUMAN, MACHINE, READY, NOT_READY, UNKNOWN, finished (mostly uppercase)
  • Conditional example: detect_result == 'machine' (lowercase)

These are two different surfaces, but a reader scanning quickly comes away thinking the docs contradict themselves. The fix is to make the surface boundary explicit: "Event payload uses these uppercase values… ${detect_result} carries these lowercase values…"

On the original issue's three asks

  1. "Reconcile the runtime validator with the published schema for detect_machine timing parameters." — Addressed by the validator fixes.

  2. "Normalize detect_result casing across calling.call.detect, SWML variables, trigger/final events." — No code change recommended. The two surfaces have documented contracts that the code matches. Aligning them would be a wire-format break for marginal benefit; documenting them more clearly costs nothing and solves the reporter's underlying confusion.

  3. "Clarify whether READY is a valid detect_result value." — No, it isn't. READY is an event payload lifecycle marker only. ${detect_result} only ever holds machine, human, fax, unknown, detecting, or error. Pure docs clarification.

Recommendation

  • Code on this branch: leave casing alone. Ship the validator fixes only.
  • Follow-up docs ticket against the hosted reference page covering: split the value list by surface, clarify READY/NOT_READY/finished are lifecycle-only, align the conditional example with the bullet list (or call out the surface difference explicitly).
  • Optional, low-priority code follow-up: if the docs ever standardize on UPPER for the event channel, uppercase finishedFINISHED to match. Requires a coordinated rollout (Hagrid → Prime → SDKs → docs → customer notice) and is probably not worth doing in isolation.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions