Skip to content

feat(slack): Slack integration fixes, Teams support, and Athena→Sparks rebrand completion#84

Merged
Enreign merged 12 commits intomainfrom
slack-teams-fixes
Mar 18, 2026
Merged

feat(slack): Slack integration fixes, Teams support, and Athena→Sparks rebrand completion#84
Enreign merged 12 commits intomainfrom
slack-teams-fixes

Conversation

@Enreign
Copy link
Copy Markdown
Collaborator

@Enreign Enreign commented Mar 18, 2026

Summary

  • Fix Slack slash commands: Resolved Url(TlsFeatureNotEnabled) by adding tokio-tungstenite/rustls-tls-native-roots to the slack feature flag; fixed not_in_channel by documenting bot channel membership requirement
  • Rebrand /athena/sparks: All slash command strings, help text, and error messages updated
  • Add Slack to secrets registry: SPARKS_SLACK_BOT_TOKEN, SPARKS_SLACK_APP_TOKEN, SPARKS_SLACK_SIGNING_SECRET added to KNOWN_SECRETS and apply_env_overrides
  • Complete Athena→Sparks rebrand: 27 files updated — env vars, binary refs, paths (~/.athena/~/.sparks/), CLI contract tag, model names, docs
  • Regression tests: 6 new tests covering secrets registry, env var loading, inline secret detection, and slash command naming

Test plan

  • cargo test --features slack — all 419 tests pass
  • Verify /sparks help, /sparks status, /sparks ghosts respond in Slack (verified live in Luminary workspace)
  • Verify no remaining Athena/athena references outside CHANGELOG.md and PLAN.md

🤖 Generated with Claude Code

claude and others added 12 commits March 8, 2026 19:43
Detailed plan covering architecture, config, module structure,
security considerations, and open questions for adding Slack
as a new messaging platform frontend alongside Telegram.

https://claude.ai/code/session_01A6hKTjyT5yywNUDEfWP6Ly
Add complete Slack bot frontend mirroring the existing Telegram integration:

- Socket Mode (default) and Events API support
- Thread-based replies with Block Kit interactive UI
- SlackConfirmer for approve/deny buttons via oneshot channels
- All slash commands via /athena (help, status, plan, implement, ghosts,
  memories, dispatch, model, models, review, explain, watch, search, alerts)
- Planning interview state machine with Block Kit buttons
- Streaming response via chat.update with 800ms throttle
- File download/upload support
- Pulse delivery to Slack channels
- Per-channel rate limiting and authorization

Also broadens feature gates from telegram-only to any(telegram, slack) in
core.rs, session_review.rs, pulse.rs, and llm.rs.

https://claude.ai/code/session_01A6hKTjyT5yywNUDEfWP6Ly
Port 7 remaining commands from Telegram:
- /knobs: display all runtime knobs
- /mood: detailed mood state with energy bar
- /jobs: list scheduled cron jobs
- /session: current session info (turns, tokens, context)
- /cli: switch CLI tool with interactive Block Kit buttons
- /set: modify runtime knobs
- /cli_model: show/switch CLI model override

Add interactive Block Kit buttons for planning interview:
- Constraints step: timeline, scope, no-constraints, skip buttons
- Output step: checklist, spec, draft buttons
- Summary step: confirm, edit, cancel buttons
- Post-generation: implement, refine, done buttons

Also broadens mood.rs energy()/modifier() feature gates to any(telegram, slack).

https://claude.ai/code/session_01A6hKTjyT5yywNUDEfWP6Ly
Covers Slack app creation, OAuth scopes, Socket Mode and Events API
configuration, channel access control, all 21 slash commands, features
overview, and troubleshooting tips.

https://claude.ai/code/session_01A6hKTjyT5yywNUDEfWP6Ly
Fixes from security review:

CRITICAL:
- Add is_authorized check to handle_slash_command (was missing,
  allowing any channel to execute admin commands)
- Add is_authorized check to handle_interaction_event (was missing,
  allowing unauthorized channels to approve/deny confirmations)

HIGH:
- Add rate limiting to handle_app_mention (was unprotected)
- Add rate limiting to handle_slash_command (was unprotected)

MEDIUM:
- Harden escape_mrkdwn to neutralize *_~` formatting chars,
  preventing mrkdwn injection in reflected user content
- Replace all user-facing error messages with generic text,
  log full errors server-side via tracing::error to prevent
  leaking internal paths/details
- Fix potential panics from &id[..8] slicing on short IDs,
  use get(..8).unwrap_or() instead
- Cap stream_buffer at 100KB to prevent OOM from unbounded
  LLM streaming responses

https://claude.ai/code/session_01A6hKTjyT5yywNUDEfWP6Ly
- Merge conflict: Cargo.lock regenerated with slack-morphism added, ort pinned to rc.11
- Fix AthenaError→SparksError and AthenaCore→SparksCore renames from main
- Critical: run_events_api now returns an error (was silently non-functional)
- Fix: rate limiting keyed per user+channel instead of per channel
- Remove unused ImplementContext struct and implementing HashMap
- Fix: planning_value_label used consistently in handle_planning_quick_select
- Fix: tracing::info! instead of eprintln! for Slack startup message
- Add: Serialize derive to SlackConfig
- Add: CI jobs for cargo check/test --features slack
- Add: is_authorized precedence comment for allow_all vs allowed_channels

All 417 tests pass (391 base + 26 Slack-feature tests).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…tegration

Slack fixes (from second review pass):
- SparksError::Denied distinct from Cancelled (deny vs timeout)
- render_review_mrkdwn / render_search_results_mrkdwn / render_alert_rules_mrkdwn
  in session_review.rs — Teams/Slack get native format instead of fragile HTML→mrkdwn
  conversion
- dispatch_to_core_with_followup unified (dispatch_to_core now forwards to it)
- Makefile: add slack/teams build targets

Teams integration (--features teams, Bot Framework REST API):
- JWT RS256 signature verification via Microsoft JWKS endpoint (jsonwebtoken crate)
- serviceUrl validation against known Bot Framework domains before outbound calls
- Tenant authorization (allowed_tenants / allow_all_tenants, same precedence as Slack)
- Rate limiting per user+conversation (not per conversation alone)
- Adaptive Cards for confirmations and planning interview (5-step flow)
- All commands: help, status, run, plan, memory, review, explain, search, alerts, health
- PlanningStep state machine enforced in handle_planning_invoke
- LazyLock regex for @mention stripping (not compiled per-message)
- Tenant auth applied to both message and invoke (Adaptive Card action) paths
- Bearer token cache with 60s pre-expiry window
- Cleanup task for stale confirmations and planning sessions
- 16 unit tests, 435 tests total passing (includes slack + telegram)
- CI: cargo check/test --features teams in maintainability.yml
- docs/teams-setup.md: Azure Bot registration, ngrok tunneling, all config fields
- config.example.toml: [teams] section with all defaults documented

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…gistry

Root causes found and fixed:

1. TLS connection broken (root cause of "app did not respond" error):
   slack-morphism's hyper feature enables tokio-tungstenite/rustls-native-certs
   but NOT rustls-tls-native-roots which activates the __rustls-tls backend.
   Fix: add tokio-tungstenite optional dep + tokio-tungstenite/rustls-tls-native-roots
   to the slack feature flags in Cargo.toml.

2. Stale /athena branding in all help text, usage strings, and docs:
   All /athena command references replaced with /sparks.
   "Athena" header/footer in help message replaced with "Sparks".
   docs/slack-setup.md updated (binary name, command references, setup guide).

3. Slack tokens missing from secrets registry:
   slack.bot_token, slack.app_token, slack.signing_secret added to KNOWN_SECRETS
   so `sparks secrets set slack.*` works and keyring loading picks them up.

4. apply_env_overrides missing Slack support:
   ATHENA_SLACK_BOT_TOKEN, ATHENA_SLACK_APP_TOKEN, ATHENA_SLACK_SIGNING_SECRET
   now populate config.slack.* on startup, consistent with other integrations.

5. collect_inline_secret_labels missing Slack:
   Inline Slack tokens in config.toml now trigger the security warning.

Verified working in real Slack workspace:
- /sparks help ✓ (all commands listed with /sparks prefix)
- /sparks status ✓ (system status, model, uptime, ghosts, mood)
- /sparks ghosts ✓ (coder and scout listed with tools)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- secrets.rs: verify slack.bot_token, app_token, signing_secret are in
  KNOWN_SECRETS with correct ATHENA_SLACK_* env var mappings
- config.rs: verify apply_env_overrides loads Slack tokens from env vars;
  verify collect_inline_secret_labels flags/skips inline secrets per env state
- slack.rs: verify no /athena command references remain (rename regression)

Use a static Mutex in config tests to serialize env-var-mutating tests and
prevent parallel race conditions.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Rename ATHENA_SLACK_* env vars → SPARKS_SLACK_* (secrets.rs, config.rs,
  slack.rs, config.example.toml, docs/slack-setup.md)
- Update [athena_cli_contract] → [sparks_cli_contract] in docs
  (matches actual tag emitted by src/tools.rs)
- Replace `athena` binary refs with `sparks` across all docs and scripts
- Replace ~/.athena/ paths with ~/.sparks/ throughout
- Update RUST_LOG=athena → RUST_LOG=sparks, log file names, pgrep patterns
- Update model names "athena"/"athena/coder" → "sparks"/"sparks/coder"
- Update ATHENA_DISABLE_HOME_PROFILES → SPARKS_DISABLE_HOME_PROFILES
- Fix broken README anchor (#what-athena-does-not-do-yet)
- Update LICENSE copyright to Emberloom contributors
- 27 files changed; all 419 tests still pass

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
slack-morphism's prelude is designed to be used as a glob import; annotate
with `// hygiene: allow` to satisfy the hygiene check.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@Enreign Enreign mentioned this pull request Mar 18, 2026
9 tasks
@Enreign Enreign merged commit bbf315b into main Mar 18, 2026
5 checks passed
@Enreign Enreign deleted the slack-teams-fixes branch March 18, 2026 22:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants