Skip to content

Escalation modes

A Work Unit can carry an escalation: escalation_triggers such as sensitive_data, budget or cross_lane_arch, or an explicit requires_human_escalation flag. wu:done refuses to land an unresolved escalation. Who may resolve it is a consumer choice, made once in workspace.yaml under software_delivery.escalation.

escalation.modeWho resolveswu:done gate
human (default)A human, through approval:request and approval:reviewRefuses until a human resolution is recorded
delegatedAn independent agent seat, under escalation.delegated_resolutionRefuses until a valid human or delegated resolution
offNobody: triggers are detected and recorded, agents decideNever gates; records the escalation as advisory

The block is part of the trusted policy: it is read from the upstream policy snapshot, never from a lane-editable checkout, and it is covered by the claim policy digest. Enabling or changing it is a governed, audited policy change (pnpm config:set), never a per-WU flag. An unknown or invalid value fails closed with a message naming the key, and an unreadable policy is treated as human.

Under mode: human, a human resolves the escalation. The agent asks for the approval and never resolves its own escalation.

# The agent records a request for the WU. It does not resolve the escalation.
pnpm approval:request --type human-escalation --wu <wu-id> --triggers sensitive_data --summary "<what changed>"

# A human, in a shell with no agent session, approves the request.
pnpm approval:review --approve <approval_id>

The review command runs wu:escalate --resolve for the approval, records the approval as approved, and then runs wu:done. wu:done refuses while an approval is pending.

The interim checks in the local route:

  • wu:escalate --resolve refuses when any agent-session signal is set in the reviewing process: LUMENFLOW_AGENT_SESSION, LUMENFLOW_AGENT_SESSION_PROOF, LUMENFLOW_SESSION_OWNER_PID, CLAUDECODE, CLAUDE_CODE or AI_AGENT, with any non-empty value.
  • approval:request records the requester from the checkout’s git user.email and the requester’s agent-session evidence. A review is refused when the reviewing process shows an agent signal, or when the reviewing process is the requester’s own agent session. When the requester had no agent-session evidence, a reviewer who uses the same git email is also refused.
  • The resolver is always the checkout’s git user.email. --resolver is only a cross-check.

The route leaves an audit trail and raises the cost of self-resolution.

# workspace.yaml
software_delivery:
  escalation:
    mode: delegated # human (default) | delegated | off
    delegated_resolution:
      triggers: [sensitive_data, budget, cross_lane_arch] # default; security_p0 is not delegable unless listed
      require_independent_review: true # zero-findings verdict on the exact tip (default)
      require_green_gates: true # gate-set checkpoint on the exact tip (default)
      resolver: different-seat # different-seat (default) | named-roles
      allowed_resolver_roles: [] # used with resolver: named-roles

Set it with the governed command, which validates the whole workspace and commits it:

pnpm config:set --key software_delivery.escalation.mode --value delegated

Every field, its type, default and description is in the configuration reference.

Under mode: delegated, an agent seat resolves a human escalation in place of a person:

pnpm wu:escalate --id <wu-id> --resolve --delegated

It succeeds from an agent session only when every condition holds, each checked against trusted or committed evidence rather than a lane-editable claim. Any unmet condition refuses and names it:

  1. Policy. The trusted escalation.mode is delegated, and every trigger on the WU is listed in delegated_resolution.triggers. A WU with several triggers is delegable only if all are listed; a flag-only escalation (no trigger name) always stays on the human route.
  2. Separation of duties (the floor). The resolving session is an authenticated agent session that is not the WU’s claim holder (and not the requester of a named approval). The session is either a WU session or a live role session (for example a reviewer registered with pnpm agent:session), named by LUMENFLOW_AGENT_SESSION; a role session must be unrevoked, hold its lease and not be stale, and a refused one is named in the refusal. A named --approval-id may be a local approval record or a control-plane approval (a request file for this WU with route control-plane). This has no setting: nothing in the policy can turn it off. Under resolver: named-roles the seat must also hold one of allowed_resolver_roles.
  3. Independent review. A review verdict with zero findings is recorded for the exact current tip through the existing independent-review contract (pnpm wu:review --record, by a reviewer session under an externally signed grant). It is bound to that commit and the contract digest.
  4. Green gates. The gate-set checkpoint from pnpm wu:prep covers every gate wu:prep can run, with the same configuration digest, for that same tip. Done-only gates (gates wu:done requires that wu:prep never runs, such as delivery_review) are not judged here: the evidence lists them as deferred_done_gates, and wu:done still runs each of them after the resolution and refuses if one fails. The resolution never marks a done-only gate as satisfied.

The resolution is recorded in the WU as resolver_type: delegated-agent, never as a human: escalation_resolved_by is delegated-agent:<session>, and escalation_resolution_evidence carries the resolving session, the claim holder’s session, the trusted policy digest and the digest of the escalation block, which conditions the policy required (so the audit shows the policy in force), the tip SHA, the review verdict reference and the gate checkpoint reference.

wu:done re-verifies it rather than trusting the YAML: the review reference must match the journalled verdict, the policy block must be unchanged, and the landing candidate must be the evidence tip with only the resolution commit and lifecycle journal appends past it. A new commit after the review invalidates the resolution; re-run wu:prep, get a fresh review and resolve again.

A consumer may relax review or gates only by writing it out, and the evidence records the relaxation:

software_delivery:
  escalation:
    mode: delegated
    delegated_resolution:
      require_independent_review: false # no reviewer seat available
      require_green_gates: true

Separation of duties is never configurable.

Host prerequisite for require_independent_review: true

Section titled “Host prerequisite for require_independent_review: true”

The default (require_independent_review: true) needs a recorded review verdict, and pnpm wu:review --record only accepts one under an externally signed reviewer grant verified against a system-owned reviewer-grant trust anchor (grant-trust.json, see reviewer grant trust). On a host with no such anchor the record is refused with grant_missing_trust_anchor, so the default delegated route can never succeed there. In that case wu:escalate --resolve --delegated refuses by naming the missing anchor and the two routes that work without one (and does not send you to wu:review --record), and wu:review --record appends the same two routes to its anchor refusal when the trusted mode is delegated. Both are agent-runnable with pnpm config:set, and neither weakens a check:

  • delegated_resolution.require_independent_review: false. Separation of duties (the resolver is a different session from the claim holder and any requester) and the green-gate checkpoint on the exact tip still hold, and the evidence records that the review was not required. Pick this when you want a recorded, gated resolution.
  • mode: off. Triggers are recorded as advisory and never gate wu:done; agents decide.

Either change moves the policy digest, so in-flight claims take one governed policy refresh.

For a repository where agents choose the best option themselves while developing:

software_delivery:
  escalation:
    mode: off

Triggers are still detected and recorded (escalation_triggers, the claim log, and the brief shows them as advisory), and wu:edit --add-escalation-trigger still works and stays raise-only. They simply never block wu:done. The landed WU carries an escalation_advisory record (mode: off, the trusted policy digest, the triggers) so the audit shows why a detected trigger did not gate the landing.

Example: a consumer that wants fully autonomous operation

Section titled “Example: a consumer that wants fully autonomous operation”

Pick the weakest control that still satisfies you, and set it once:

# Agents resolve escalations themselves, with separation of duties, an independent
# zero-findings review and green gates on the exact tip, all recorded in the WU.
software_delivery:
  escalation:
    mode: delegated
# Agents decide; escalations are recorded as advisory and never block a landing.
software_delivery:
  escalation:
    mode: 'off'

Quote "off" in YAML so it stays a string. Either way a human is never a blocker and is never expected to run a command; switching back to human is the same one-line governed change.

wu:brief and the spawn prompts follow the mode. Under delegated the agent is told to run the delegated route and not to ask a person or expect a human to run a command; under off it is told the escalation is advisory; under human it requests an approval as before.