Stateful Voice-Flow Shift-Left Framework
Decision
RIFF validates multi-call, multi-object workflows with declarative stateful scenarios before OTA. Scenarios run production tool functions and deterministic choice resolution against a stateful backend implementing the production client interface.
This bridge catches missing objects, incorrect spoken lists, ambiguous selection, cross-object mutation, and weak audit evidence locally. Telephony and external integration remain OTA concerns.
Contract and Artifacts
riff_stateful_scenario_v1 files declare an adapter, synthetic
identity, ordered actions, captured references, and exact/contains/excludes
assertions. The generic runner writes:
trace.jsonlfor replayable steps and checks;events.jsonlfor ordered backend audit operations;quality.jsonfor CI;quality.mdandquality.htmlfor operators.
Fixtures use synthetic data only and never contain credentials, real caller identity, raw card data, or raw passwords.
Property-Management Proof
- Create separate sink and heater requests.
- List both and verify both are spoken.
- Select, read, and update the first request.
- List again, then select, read, and update the second request.
- Read both and prove updates did not cross ticket boundaries.
- List both at the end and retain ordered audit evidence.
The adapter calls the production create, list, get, and update tools. Selection uses the compiled flow's locked-choice contract and production resolver.
Shift-Left Gate
The CI test discovers every YAML file in tests/scenarios, so adding
a scenario automatically adds a gate.
.venv/bin/python scripts/run-stateful-scenario.py \
tests/scenarios/property_management_two_tickets.yaml \
--out runs/stateful-scenarios/property_management_two_tickets
This command is local and places no phone call. A real OTA call still requires
explicit human GO.
Extension Rules
- Implement the production client surface in a stateful simulator.
- Map scenario actions to production tools and resolvers in a small adapter.
- Add a synthetic scenario with observable assertions.
- Log object, call, and operation IDs in ordered events.
- Block promotion on scenario failure before OTA.
Business behavior stays out of the generic runner. Production limitations are fixed in production code, and the revealing scenario remains as the regression gate.