fix(connectors): reconcile mail connector key — probe gmail → canonical email (#172) - #189
Merged
Merged
Conversation
…al email (#172) The probe/config key for the mail connector was `gmail`, but the email phase gates on `requires: email`, so select_sections silently dropped every email section from assembled SKILL.md whenever Gmail was enabled. The mismatch was masked in tests because dummy-mixed.md used `requires: gmail` instead of the real phase key. Per the connector-catalog spec §7 resolution (PR #152, confirmed in the 2026-06-30 design review): standardize on the provider-neutral `email`. - Rename the probe registry key `gmail` → `email` (same Gmail probe tool). - Add CONNECTOR_KEY_ALIASES + normalize_connector_keys(); BootstrapConfig normalizes enabled_connectors at construction, so every entrypoint (install / upgrade / migrate-legacy / backport) accepts the legacy key and /scout-update idempotently persists the canonical one. - Fix the masking fixture to use the canonical `email` key. - Add test_connector_key_invariant.py: every phase `requires:` must resolve to a shipped probe key, phases must not use alias keys, and the legacy-config end-to-end path selects the real email phase. - Add the missing `fathom` probe entry — same silently-un-enableable class: phases/connectors/fathom.md gates on `requires: fathom` but no probe could ever write that key to connectors.enabled. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Standalone fix for the connector key-namespace bug identified in the connector-catalog spec §7 (#152) and confirmed in the 2026-06-30 design review — split out as recommended there, independent of the catalog work. Fixes #172.
The bug
The mail connector was named by two different keys across the namespaces that must agree:
templates/connector-probes.yaml,scout-config.yamlconnectors.enabled):gmailphases/connectors/email.md):requires: emailselect_sectionskeeps a section only when itsrequires:key is inenabled_connectors, so with Gmail enabled the assembler silently dropped every email section from assembledSKILL.md— no error, just missing behavior. Tests never caught it because the fixture (dummy-mixed.md) usedrequires: gmail, matching the probe key instead of the real phase key.The fix (spec §7's recommended resolution)
Standardize on the provider-neutral
email, keepgmailas a legacy alias:templates/connector-probes.yaml— probe key renamedgmail→email(same Gmail probe tool). A future Outlook/IMAP probe maps to the same capability key: one phase, many providers.connector_probes.py— newCONNECTOR_KEY_ALIASES = {"gmail": "email"}+normalize_connector_keys().bootstrap.py—BootstrapConfig.__post_init__normalizesenabled_connectors. Every entrypoint (install / upgrade / migrate-legacy / phases backport) constructsBootstrapConfig, so a pre-rename vault'sgmailkeeps working immediately, and the next/scout-updateidempotently rewritesconnectors.enabledto the canonical key — no manual migration.dummy-mixed.mdnow uses the canonicalemailkey.Regression guard
New
engine/tests/unit/test_connector_key_invariant.py:requires:key in shippedphases/resolves to a shipped probe-registry key (a key with no probe entry is silently un-enableable — this is the CI check spec §7 calls for);requires: emailbut the connector is enabled/detected asgmail#172 reproduction: a legacy{"gmail"}config selects zero sections of the real email phase raw, and all sections once normalized;BootstrapConfignormalization itself.Also fixed in passing
The new invariant test immediately flagged a second instance of the same class:
phases/connectors/fathom.mdgates onrequires: fathom, but no probe entry existed, so nothing could ever writefathomintoconnectors.enabledvia setup. Added the missing probe (mcp__fathom__list_meetings, the same tool the phase itself uses). Happy to split this into its own PR if preferred.Verification
ruff format/ruff checkcleanSCOUT_DATA_DIRset)🤖 Generated with Claude Code