You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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.yaml → connectors.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:
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 — slack→slack, granola→granola, github→github, claude-sessions.md→claude_sessions. The mail connector detects from mcp:claude_ai_Gmail → gmail, but email.md alone chose the provider-neutral logical name email and never reconciled. One-connector naming inconsistency.
Fix options
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.
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.
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.
Summary
The
emailconnector phase (phases/connectors/email.md) is silently dropped from every assembledSKILL.mdon any vault whose mail connector is enabled under the keygmail(the value detection naturally produces). The phase gate requires the keyemail, but the enabled-connectors list containsgmail, so the keys never match andselect_sectionsdrops the whole phase.Mechanism — three connector namespaces, two disagree
phases/connectors/email.mdfrontmatterrequires: emailscout-config.yaml→connectors.enabledgmailengine/scout/connectors.yamlmcp:claude_ai_GmailAssembly (
engine/scout/scripts/phase_assembly.py:select_sections) keeps a connector section only whenrequires ∈ enabled_connectors:→ all three sections of
email.mdare excluded from the assembled SKILL.Reproduction
Assemble
SKILLwith a standard enabled set (the mail connector keyed asgmail, as detection emits it):Observed on a live vault: the deployed
SKILL.mdhas 0 occurrences of every email-phase marker (gmail_search_messages,Cold outreach,Inbound email,Mass email), while the Slack-phase control is present.Impact
email.mdis 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 —slack→slack,granola→granola,github→github,claude-sessions.md→claude_sessions. The mail connector detects frommcp:claude_ai_Gmail→gmail, butemail.mdalone chose the provider-neutral logical nameemailand never reconciled. One-connector naming inconsistency.Fix options
email → gmail(requires:+name:, optionally the filename). One line; matches the existing "key = detected token" convention. Cost: couples the phase to one provider.gmail(and a futureoutlook, …) → the logicalemailkey whererequiresis matched. Keeps phase keys provider-neutral; best for distributability; slightly more code.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