Deterministic routing ladders

Forge recipe routing is a ordered pipeline, not one monolithic decision tree. Each stage has a narrow job; later stages run only when earlier ones abstain.

Updated

Runtime ladder (request)

Human utterance + trusted scope (server-owned)
  → Normalize ask
  → Rules match (anchored regex, token_all, exact phrase)
  → Margin gate (min_score, min_margin)
  → Optional phrase FTS (catalog recipes with allow_phrase_fts)
  → Optional LLM tiebreak (flag + recipe allow_llm_tiebreak; closed top-2 list)
  → Recipe match + param binders (trusted deck_ids, scope)
  → Precompiled AF v4 OR Python handler OR slow copilot_ask fallback
  → Canonical response + route trace

Active fast path skips copilot_ask when a wired recipe returns an accepted envelope. Draft recipes and stub handlers fall back to the slow path deliberately.

Authoring ladder (maintainer)

GoalSpec / IntentProgram
  → PlanIR → BoundPlan
  → AutomationFlow v4 JSON
  → validate + parity tests + hash pins

Change placement (C0–C6)

Rung Change New executable?
C0 Alias / normalize No
C1 Slot / schema Rarely
C2 GoalSpec specialization Maybe
C3 Compose recipes Reuse
C4 New consumer capability Yes, registered
C5 New v5 construct Only from proven v4
C6 Native AF v5 runtime RFC + hold gate

Learning (offline only)

Observed asks → cluster → propose inactive patch
  → compile to v4 → tests → human Git/CI → shadow → activate

Promotion never mutates production catalogs from live chat.