Skip to content

Hardened Escalation Path for ACP-attached Mayor#2700

Open
roder wants to merge 7 commits intosteveyegge:mainfrom
roder:main
Open

Hardened Escalation Path for ACP-attached Mayor#2700
roder wants to merge 7 commits intosteveyegge:mainfrom
roder:main

Conversation

@roder
Copy link
Contributor

@roder roder commented Mar 12, 2026

Summary

This PR hardens the ACP-attached Mayor escalation path from end to end, per the request for item 6.

It makes escalation delivery metadata-driven instead of text-driven, preserves escalation urgency through the mail-to-nudge pipeline, prevents ACP from silently losing escalation notifications during startup/degraded states, surfaces delivery failures in structured output, and adds targeted end-to-end coverage for the attached Mayor path.

Why

Before this series, escalation handling had several reliability gaps:

  • escalation mail copies did not preserve strong structured escalation identity
  • urgency could degrade when mail notifications fell back to queued nudges
  • ACP Propeller could drain nudges before ACP was actually ready to present them
  • escalation-aware behavior in ACP was too close to generic notification handling
  • delivery failures were often only visible as warnings rather than structured status
  • the full attached-Mayor path did not have focused regression coverage

This change set closes those gaps for the ACP delivery mechanics path.

Included changes

1. Preserve structured escalation metadata on Mayor mail copies

Commit: 1be2098feat: preserve escalation metadata in mayor mail copies

This establishes a durable structured contract for escalation mail copies.

Changes include:

  • introducing a first-class escalation mail type
  • sending escalation mail as TypeEscalation rather than generic task mail
  • adding escalation-specific mail labels such as:
    • gt:escalation
    • msg-type:escalation
  • preserving thread linkage to the escalation bead
  • extending parsing/round-trip behavior so escalation mail remains structurally identifiable after persistence
  • adding tests proving escalation mail type and labels survive conversion/parsing

Impact:

  • downstream mail, nudge, and ACP code can detect escalations from structured metadata rather than relying on subject/body wording

2. Preserve escalation urgency in mail nudges

Commit: 1a77fd5feat: preserve escalation urgency in mail nudges

This ensures escalation urgency survives the mail notification fallback path.

Changes include:

  • mapping escalation mail priority into queued nudge priority
  • ensuring critical/high escalation notifications are not reduced to generic normal mail nudges
  • replacing generic “you have new mail” fallback text with escalation-specific notification content
  • including actionable escalation context in fallback messages:
    • escalation sender
    • escalation ID
    • severity
    • gt mail read <id>
    • gt escalate ack <id>
  • adding tests for:
    • escalation priority preservation
    • escalation notification formatting
    • normal mail remaining normal

Impact:

  • the attached Mayor sees urgency and actionable escalation context even when delivery happens through queued ACP nudges rather than direct mail UI handling

3. Requeue undeliverable ACP escalation nudges

Commit: 33b4e42fix: requeue undeliverable ACP escalation nudges

This removes a loss mode in ACP Propeller.

Before:

  • Propeller could drain queued nudges
  • if ACP had no usable sessionID or delivery failed, those nudges could be consumed without presentation

After:

  • drained nudges are requeued when session readiness is incomplete
  • drained nudges are requeued when delivery fails
  • the no-session path returns explicit errors instead of failing silently
  • degraded delivery paths emit observable ACP warning/error signals
  • tests cover:
    • requeue when session is unavailable
    • explicit failure when notifying without a session ID

Impact:

  • escalation nudges are no longer silently lost during ACP startup/degraded conditions

4. Add metadata-driven ACP escalation handling

Commit: 008b74ffeat: add metadata-driven ACP escalation handling

This makes ACP escalation handling explicitly metadata-driven.

Changes include:

  • extending queued nudges with structured escalation fields:
    • Kind
    • ThreadID
    • Severity
  • tagging escalation nudges as escalation-specific rather than generic mail
  • deriving ACP session/update metadata from structured nudge fields
  • injecting escalation-specific _meta into ACP UI notifications, including:
    • gt/escalation
    • gt/threadID
    • gt/severity
    • gt/kind
  • adding tests proving:
    • escalation classification is driven by metadata
    • generic mail containing words like “urgent” or “helpful” does not falsely classify as escalation
    • escalation metadata is propagated into ACP session/update

Impact:

  • the ACP-attached Mayor path no longer depends on heuristic wording to recognize escalation behavior

5. Report escalation delivery failures structurally

Commit: 71e6147fix: report escalation delivery failures

This improves observability for high/critical escalation routing and notification outcomes.

Changes include:

  • adding structured per-channel/per-target delivery reporting in gt escalate
  • distinguishing delivery stages such as:
    • escalation bead creation
    • mail persistence/runtime notification
    • external action execution
  • adding delivery details to JSON output
  • adding top-level command status such as ok vs partial_failure
  • preserving warnings/errors for:
    • failed mail sends
    • annotation failures
    • external action failures
  • surfacing operator-visible delivery issue summaries in non-JSON mode
  • adding tests for:
    • partial-failure JSON shape
    • successful delivery status shape
    • external action warning/failure reporting

Impact:

  • operators and automation can now tell whether escalation creation succeeded but delivery partially failed, instead of relying on stderr warnings alone

6. Add ACP escalation delivery path coverage

Commit: cf208a4test: cover ACP escalation delivery path

This adds targeted regression coverage across the attached-Mayor delivery path.

Coverage includes:

  • attached Mayor ACP session/update delivery with structured escalation metadata
  • preservation of escalation ID/severity into ACP UI payloads
  • urgent escalation delivery behavior
  • no-session requeue behavior
  • metadata-driven classification behavior
  • delivery-status JSON behavior for success and partial failure cases

Impact:

  • the core ACP escalation mechanics now have focused regression coverage that protects against future heuristic drift, urgency loss, or silent delivery failures

Resulting behavior

After this series:

  • escalation mail copies are structurally identifiable
  • urgency is preserved from escalation creation through queued ACP delivery
  • ACP does not silently consume undeliverable escalation nudges
  • ACP escalation handling is driven by structured metadata, not by subject/body wording
  • delivery failures are visible to both humans and machines
  • the attached-Mayor escalation path has targeted regression coverage

Scope note

This PR focuses specifically on ACP delivery mechanics for the attached Mayor path.

It does not include adjacent policy work such as:

  • broader mute/DND notification policy
  • escalation durability/auditability policy changes

Testing

Targeted verification performed across the affected packages includes:

  • internal/mail
    • escalation label preservation
    • escalation nudge priority/formatting
  • internal/acp
    • metadata-driven escalation detection
    • no-session requeue behavior
    • ACP _meta injection
    • attached-Mayor escalation session/update path
  • internal/cmd
    • escalation mail body formatting
    • structured delivery-status output
    • partial-failure JSON reporting

Representative targeted test coverage now verifies:

  • structured escalation classification
  • false-positive resistance for heuristic wording
  • urgency preservation
  • delayed/unavailable ACP session handling
  • structured delivery failure reporting

Testing

  • Unit tests pass (go test ./...)
  • Manual testing performed

Checklist

  • Code follows project style
  • Documentation updated (if applicable)
  • No breaking changes (or documented in summary)

@github-actions github-actions bot added the status/needs-triage Inbox — we haven't looked at it yet label Mar 12, 2026
Replace Signal(0)-based process probing with platform-specific
liveness checks, using OpenProcess on Windows and a shared helper in
mayor cleanup logic.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

status/needs-triage Inbox — we haven't looked at it yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant