Skip to content

manual_escalation.yaml

Source: config/manual_escalation.yaml

# Manual escalation / over-budget decision tree configuration.
# Realizes docs/superpowers/specs/manual-escalation.md §6.1 (the slice
# 17 subset; budget_extension and prompt_delivery blocks land in slices
# 18 and 20). Dashboard runtime overrides resolve through the
# `dashboard_setting` table — slice 23 will add the write path.

enabled: true                          # global kill switch

# Escalation-gate posture (manual-escalation.md §4).
#   shadow  — log every call that WOULD escalate, but never prompt, create
#             rows, or block. Used to calibrate estimate accuracy before the
#             interactive decision tree starts interrupting the user.
#   enforce — run the full Approve/Manual/Pause/Cancel decision tree.
# The daily/monthly budget *caps* are enforced regardless of this setting
# (see BudgetGuard); this only governs the per-task interactive gate.
gate:
  mode: shadow

modes:
  chat:
    enabled: true
  claude_code:
    enabled: true
    # Slice 21: where the user's worktrees live. Sibling-of-workspace,
    # NOT inside the host repo, so accidental `git status` in the wrong
    # cwd doesn't surface stray escalation files.
    worktree_root: "${DONNA_WORKSPACE_PATH}/worktrees"
    # Env var name for the read-only host repo mount the poller diffs
    # against. Spec §5.3 / §10.3 row 5.
    host_repo_path_env: "DONNA_HOST_REPO_PATH"
    base_ref: "main"
    # Discord failure feedback: at most this many failing case names
    # surface in the message. Full output goes to validation_result JSON.
    feedback_max_failing_cases: 3
    poll_tick_seconds: 60

budget_extension:
  enabled: true
  max_daily_extension_usd: 10.0
  hard_monthly_ceiling_usd: 150.0      # absolute cap, dashboard cannot exceed

triggers:
  task_approval_threshold_usd: 5.0     # estimate above this always offers escalation
  escalation_timeout_minutes: 60       # auto-pause after this many minutes if no click
  manual_iteration_limit: 3            # used by slices 20/21

# Slice 20 — chat mode delivery (canonical spec §6.1). The full prompt
# always lives on disk + DB; Discord only carries summary + optional
# attachment, which removes the 2000-char Discord problem entirely.
prompt_delivery:
  attach_full_prompt_to_discord: true   # post the full prompt as <correlation_id>.md
  discord_summary_max_chars: 1500       # safety margin under Discord's 2000-char limit
  attachment_size_limit_mb: 25          # Discord free-tier ceiling; MD never approaches this
  workspace_subdir: escalations         # under ${DONNA_WORKSPACE_PATH}
  slash_command_max_chars: 3000         # /donna submit hard cap; longer → "use dashboard"
  chat_min_answer_chars: 50             # mirror schemas/escalation_submission.json minLength

# Slice 22 — tool-gap surfacing (canonical spec §7, §10.5).
# High-blocking gaps post a [File request] [Snooze 24h] view to the
# `realtime_channel`; speculative gaps file silently and surface via
# the morning digest. Tool builds use the same claude_code protocol as
# §5.3 with the extra lint gates declared here.
tool_gap:
  realtime_channel: agents              # Discord channel for high-severity pings
  snooze_seconds: 86400                 # 24h (matches button label)
  reping_cooldown_seconds: 14400        # 4h floor between dedup-hit re-pings
  lint:
    requires_rebuild_default: false     # default rendered into tool_build.md
    default_timeout_seconds: 5          # default rendered into tool_build.md
    detect_secrets_enabled: false       # opt-in shim — false = curated regex only