Decision break-in (lmeta v4)

A decision break-in is a bounded, auditable LLM judgment invoked only when deterministic rules are exhausted — a long UI flip-flop, a stall, or a repeated failure where deterministic situation awareness no longer helps.…

Updated

Guarantee: the flow never breaks

Every break-in construct is fallback-safe. On any transport Err, non-JSON output, low-confidence, ambiguous, out-of-set action, or explicit escalate, the decision collapses to the caller's deterministic default_action with fallback: true. The worst case is a deterministic action, never a crash.

The lmeta expression engine also fails closed: an unresolved path makes a comparison False, routing to defaultTransition. This is the backbone of fallback safety.

When to break in

Gate the LLM behind a deterministic alarm so it runs rarely:

  • a guard state watching a signal window (flip_count_gte, no_progress_gte, repeat_count_gte), and
  • a budget block capping LLM calls per situation signature.
{ "name": "WatchFlicker", "type": "guard", "signal": "${ .last_output.view_mode }",
  "window": 30, "trigger": { "flip_count_gte": 3 }, "onTrigger": "BreakIn", "else": "Probe" }

The forgeDecide action

{ "functionRef": { "refName": "forgeDecide", "arguments": {
  "task_id": "automation_situation_arbitrate",
  "input": { "facts": "${ .outputs.WatchFlicker.series }" },
  "allowed_actions": ["force_search_results_surface", "retry_repair", "escalate_operator"],
  "min_confidence": 0.75,
  "default_action": "escalate_operator"
}}}

Output: {status, action, confidence, reason, fallback}. The action is guaranteed to be a member of allowed_actions (or the default_action). Map it to an existing atom in a downstream switch.

forgeConsensus (quality)

Run the task samples times and majority-vote on agree_field; the agreement ratio becomes the effective confidence, and no quorum falls back. Failures dilute agreement because the denominator is the configured samples. This is the biggest quality lever for genuinely ambiguous arbitration.

The governed task: automation_situation_arbitrate

Tri-state output decided | ambiguous | escalate, mirroring game_move_parse:

  • decidedaction (in allowed_actions), confidence in [0,1], optional reason, optional stable.
  • ambiguouscandidate_actions (non-empty, duplicate-free subset of allowed_actions).
  • escalate — optional reason.

Post-validation is deterministic: an out-of-set action is a SchemaFailure. facts is a bounded situation summary (capped at 20 KB) — never DOM/HTML dumps (see Extraction convergence). An optional self_check: true runs one bounded revision pass when the first answer is weak (ambiguous / low-confidence / invalid).

Identity safety carve-out

Identity/People surfaces must only ever escalate. Do not add person-disambiguation actions to allowed_actions — the LLM must never guess a person.

The decision-break-in unit

decision_break_in_unit() (shipped mirror flows/units/decision-break-in.lmeta) wraps forgeDecide — or forgeConsensus when samples > 1 — so a flow can break in with a single forgeSubflow call. No forgeTryCatch boilerplate is needed because the default is built in.

{ "functionRef": { "refName": "forgeSubflow", "arguments": {
  "unit": "decision-break-in", "as": "brk",
  "input": {
    "facts": { "flow_id": "mail-stall-remediate", "series": "${ .outputs.WatchFlicker.series }" },
    "allowed_actions": ["force_search_results_surface", "retry_repair", "escalate_operator"],
    "default_action": "escalate_operator", "min_confidence": 0.75
  }
}}}

See the standalone demo flows/examples/decision-break-in-demo.lmeta (guard + budget + subflow) for the full composition.

Incremental quality loops

  1. Self-check — one bounded revision inside the task (self_check: true).
  2. Signature cachesituation_signature() + DecisionCache cap one LLM call per distinct situation and grow a deterministic decision table over time (consumer-owned, like SQLite persistence).
  3. Offline benchmark — the arbitrate_quality suite scores decisions against labeled fixtures with a fake chat; run it in CI without a live model.

Rollout

  • Env gate FORGE_LCDL_INGEST_LLM_BREAKIN=1 (default off) for consumer adoption.
  • Full trace of facts + decision + chosen action + fallback flag lands in flow outputs.
  • Reference: AutomationFlow v4 spec.