RIFF Business Pack Import Architecture Brief

A design brief for shifting new business onboarding left: flexible importers, strict canonical packs, deterministic compiled runtime.

Status: design briefDate: 2026-07-03Source: ~/src/riff

Short Answer

RIFF should not let each company's JSON directly drive the live phone runtime. Add an intermediate canonical layer:

Company JSON / website / CRM export / AI-generated brief
        -> importer / normalizer
        -> RIFF Business Pack, versioned canonical schema
        -> riffc compiler
        -> deterministic call artifact
        -> runtime
Working position: flexible importers -> strict Business Pack -> deterministic compiler -> boring runtime.

The Principle

The core source of truth should not be "a menu." The source of truth should be business capabilities. A menu is only one projection of capabilities. The same capability can appear in a voice menu, a companion page button, a dynamic returning-caller menu, an intake form, a scheduler action, or a post-call receipt.

Recommended Architecture

External source
  - company JSON
  - website
  - CRM export
  - NOC feed
  - AI-generated business profile
        |
        v
Importer / Adapter
        |
        v
RIFF Business Pack
        |
        v
riffc
        |
        v
CallPlan Artifact
        |
        v
Runtime

Do not rearchitect the live runtime. Keep the deterministic FSM, riffc, typed slots, locked choices, companion surfaces, scheduler offer_ids, preflow audio, and RunRecord gate. Rearchitect the authoring/import layer.

Business Pack Shape

schema_version: riff_business_pack_v0

business:
  id: smith_legal
  name: Smith Legal Group
  timezone: America/Chicago
  phone: "+15125550100"
  industry: legal

capabilities:
  - id: schedule_consultation
    kind: calendar_booking
    label: Schedule a consultation
    aliases: ["book", "appointment", "talk to lawyer"]

  - id: start_intake
    kind: intake_form
    label: Start a new intake

menus:
  main_new_caller:
    when: "caller.known == false"
    items:
      - capability: schedule_consultation
        dtmf: "1"
      - capability: start_intake
        dtmf: "2"

slots:
  matter_type:
    type: enum
    options: [family, criminal, injury, housing, estate, business, other]
    label: Legal issue
    reask: What kind of legal issue is this about?

scheduler:
  services:
    consultation:
      duration_minutes: 30
      slot_increment_minutes: 15
      min_advance_minutes: 120

What riffc Should Reject

  • Menu item points to a missing capability.
  • Capability has no voice path.
  • Collect slot has no type.
  • Required collect slot has no reask.
  • Companion form has no voice fallback.
  • Booking capability has no scheduler policy.
  • Scheduler action does not use offer_id.
  • Legal flow lacks disclaimer.
  • Emergency route has no handoff.
  • Caller-memory menu has no safe fallback.
  • PII field is exposed on the companion page without permission.
  • Tool action has no timeout/failure path.
  • No generated L1 scenario for a menu item.

Vertical Examples

Plumber

Book service visit, emergency leak routing, issue description, existing request, address, urgency, shutoff status, callback number.

Electrician

Outage triage, inspection booking, emergency handoff, breaker status, sparks/smell/shock risk, panel access.

Lawyer

Schedule consultation, start intake, continue matter, leave message, conflict data, deadlines, disclaimers, no legal advice.

Space Channel

Map NOC feed categories into capabilities and content topics, then pre-render audio and companion surfaces.

Fable 5 Ask

RIFF Business Pack v0:
A canonical intermediate schema for importing businesses into RIFF.

It should support plumbers, electricians, lawyers, and content brands.
It must compile into deterministic FSM artifacts, companion surfaces,
scheduler policies, intake forms, pre-rendered audio, and tests.

Core question:
What is the smallest schema that is flexible enough for many businesses
but strict enough that riffc can reject unsafe or incomplete flows before runtime?

Recommended Build Order

  1. Write the Business Pack schema draft.
  2. Build a validator that only validates packs, not flows.
  3. Build a Space Channel importer: NOC JSON -> Business Pack.
  4. Build a lawyer intake sample pack by hand.
  5. Build a plumber/electrician sample pack by hand.
  6. Build pack-to-flow compiler for a small subset: menu, collect, message, schedule.
  7. Generate companion surfaces from pack output.
  8. Generate L1 scenarios from every menu item and required slot path.
  9. Run comparison: hand-authored flow vs pack-generated flow.
  10. Only then expand the schema.