Skip to content

bug: email phase never assembles — requires: email but the connector is enabled/detected as gmail #172

Description

@jordanrburger

Summary

The email connector phase (phases/connectors/email.md) is silently dropped from every assembled SKILL.md on any vault whose mail connector is enabled under the key gmail (the value detection naturally produces). The phase gate requires the key email, but the enabled-connectors list contains gmail, so the keys never match and select_sections drops the whole phase.

Mechanism — three connector namespaces, two disagree

Namespace Where Value for the mail connector
Phase gate phases/connectors/email.md frontmatter requires: email
Enabled list vault scout-config.yamlconnectors.enabled gmail
Health registry engine/scout/connectors.yaml mcp:claude_ai_Gmail

Assembly (engine/scout/scripts/phase_assembly.py:select_sections) keeps a connector section only when requires ∈ enabled_connectors:

"email"  ∈  {calendar, claude_sessions, drive, github, gmail, granola, linear, slack}   →  False

→ all three sections of email.md are excluded from the assembled SKILL.

Reproduction

Assemble SKILL with a standard enabled set (the mail connector keyed as gmail, as detection emits it):

from scout.scripts.bootstrap import BootstrapConfig, _assemble
cfg = BootstrapConfig(..., enabled_connectors={
    "calendar","claude_sessions","drive","github","gmail","granola","linear","slack"})
sk = _assemble(cfg, "SKILL")
assert "gmail_search_messages" in sk   # FAILS — email phase absent
assert "Slack Notification"   in sk    # passes — slack phase present (control)

Observed on a live vault: the deployed SKILL.md has 0 occurrences of every email-phase marker (gmail_search_messages, Cold outreach, Inbound email, Mass email), while the Slack-phase control is present.

Impact

  • Scheduled briefing/consolidation runs carry no email/Gmail discipline in their assembled prompt — no cold-outreach skip, no automated-alert triage, no thread-drill rule. (Gmail MCP tools remain available, so Gmail may still be touched opportunistically, but none of the phase's guidance is in-prompt.)
  • Anything added to email.md is inert until the keys reconcile — including the rules just landed in feat(email): automated-alert triage + thread-drill rules #157 (automated-alert triage, snippet-vs-thread drill). We've been adding rules to a phase that doesn't assemble.

Why only this connector

Every other connector's requires: key equals the token detection writes into the config — slackslack, granolagranola, githubgithub, claude-sessions.mdclaude_sessions. The mail connector detects from mcp:claude_ai_Gmailgmail, but email.md alone chose the provider-neutral logical name email and never reconciled. One-connector naming inconsistency.

Fix options

  1. Rename the phase gate email → gmail (requires: + name:, optionally the filename). One line; matches the existing "key = detected token" convention. Cost: couples the phase to one provider.
  2. Alias/normalization layer — map gmail (and a future outlook, …) → the logical email key where requires is matched. Keeps phase keys provider-neutral; best for distributability; slightly more code.
  3. Change detection + migrate existing configs to write email. Most disruptive (touches existing vaults).

This likely belongs in the connector-catalog work (#152), which is already reworking the connector key model — folding the reconciliation in there may be cleaner than a standalone hotfix. Flagging now so it isn't lost.

🤖 Generated with Claude Code

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions