Skip to content

Add Slack → Colibri Bridge proposal#20

Draft
tomlarkworthy wants to merge 6 commits into
feelingofcomputing:mainfrom
tomlarkworthy:slack-colibri-bridge-proposal
Draft

Add Slack → Colibri Bridge proposal#20
tomlarkworthy wants to merge 6 commits into
feelingofcomputing:mainfrom
tomlarkworthy:slack-colibri-bridge-proposal

Conversation

@tomlarkworthy
Copy link
Copy Markdown

Summary

Adds pages/slack-colibri-bridge.md — a draft proposal for mirroring FoC Slack messages into the Colibri atproto network so the community's conversation data ends up public and consumable via the atproto firehose.

One-way (Slack → atproto), public-by-default, no self-hosting. Slack stays canonical. The intent is to let us playtest Colibri as a Slack replacement without designing a new lexicon.

Highlights

  • Reuses social.colibri.message as the wire format — no new chat lexicon.
  • Stack: Cloudflare Worker (Slack Events API receiver) → CF Queue → consumer Worker → bsky.social PDS. D1 (SQLite) is a dumb cache of atproto records keyed by (repo, collection, rkey); OAuth tokens live in a separate private D1 table (v2).
  • Three sidecar lexicons under com.feelingof.bridge.*:
    • slackOrigin — provenance + dedupe authority via deterministic rkey
    • slackChannel — Slack ↔ Colibri channel mapping
    • slackUser — identity, with optional claimedDid
  • Identity: one bot DID on bsky.social for v0/v1, with attribution rendered as **@user:** ... in message text. v1 self-claim flow: post I am did:plc:... in any bridged Slack channel. v2 introduces OAuth-delegated posting from the user's own DID (medium-lived tokens, periodic re-auth).
  • Upstream ask of Colibri: extend social.colibri.message with optional displayAuthor: { name, avatar } for render-time author overrides — useful for any bridge.
  • Credential-free alternative: user-driven backfill — claimed users republish their own messages from their own DID using a small CLI we'd ship.

Status

Draft proposal, looking for feedback before any code is written. Particularly interested in input from people who've poked at the Slack → other-protocol bridging problem.

Test plan

  • Read the proposal and leave feedback / objections on the architecture, lexicon shape, or identity model.

tomlarkworthy and others added 6 commits May 22, 2026 22:47
A draft proposal for mirroring FoC Slack messages onto the Colibri atproto
network as a Slack-shaped replacement playtest. One-way (Slack → atproto),
public by default, CF Worker + Queue + D1 cache, bot identity on bsky.social.

Includes three sidecar lexicons under com.feelingof.bridge (slackOrigin,
slackChannel, slackUser), an identity claim flow via "I am did:plc:..." in
Slack, an upstream ask for a displayAuthor extension on social.colibri.message,
and a credential-free user-driven backfill path.

Looking for feedback.
…ed inverse pattern

The appview's channel handler scopes channel ownership to the channel record's
author DID, so a bot can only create channels in a community it also owns. The
inverse — community owner pre-creates channels, bot publishes via membership —
was validated against the FoC Colibri instance with a 9-message backfill into
#present-company.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The consumer now writes a `com.feelingof.bridge.slackRaw` record before any
derivation, capturing the full Slack payload (reactions, edits, file
references, blocks). The Colibri message can be regenerated from atproto alone
if the derivation logic changes. Also expands the prior-art note on Mariano's
existing FoC dump pipeline (Node puller + LanceDB + axum / systemd / nginx)
which plays the same archival role for a search use case.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…bri-bridge.ts)

Bun/TS implementation of the bridge backfill described in the proposal: reads
Mariano's history/YYYY/MM/DD{,.replies}.json dumps and publishes each Slack
message as a social.colibri.message on the bot's atproto repo, two-pass thread
handling with deterministic parent rkeys.

Notable: walks Slack's rich_text blocks (port of fromData logic from
marianoguerra/Feeling-of-Computing conversations/src/components.js) into
Colibri text+facets, covering mentions, channels, links, bold/italic/
strikethrough/code, code blocks, quotes, lists, and emoji (via
conversations/src/emoji-data.js). Falls back to the legacy text+regex
extraction for messages without blocks.

Validated against the FoC Colibri instance with a 29-message week-long
backfill (10 top-level + 19 thread replies across 6 channels). Wiki build
skips this file (no frontmatter) so it ships only as a PR-readable artifact.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Third pass after top-level + replies publishes social.colibri.reaction records
on the bot's repo for each (target_message, emoji_name) pair found in the
Slack dump. Deterministic rkey from (message_ts, emoji_name) keeps upsert
idempotent. Multi-reactor counts are not preserved at the reaction-record
level (one record per emoji per target; all author from the bot) — the per-
user data is retained losslessly in slackRaw and is recoverable once an
upstream per-record author override lands.

Emoji shortcode → unicode via the same emoji-data.js map used by the message
text walker; unknown / custom workspace emojis fall through as `:name:`.

Validated: 20 reactions across last week's backfill, 0 failures.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…-churn insurance + consolidate upstream asks

The slackRaw lexicon already lived under com.feelingof.*; this commit makes
the namespace boundary explicit and explains the three things it buys us:
de-risks Colibri's active lexicon rework (feat/rework branch deletes v1's
lexicons.ts wholesale and is staging a new shape), de-risks Colibri being
abandoned, and avoids polluting social.colibri.* with bridge-specific concepts.

Also pulls the scattered upstream-Colibri asks into a dedicated "Asks of
Colibri" section. New entry: collapsed/nested thread rendering — Colibri is
Discourse-flat in v1 and feat/rework still renders parent_message as a jump-
link rather than a collapsed sub-thread, so the bridged Slack threads lose
their visual grouping. Existing asks (displayAuthor, cross-repo channel
ownership, quote facet, TID monotonicity, attachment shape) consolidated and
sharpened. Reactions / attachments lines in Open questions updated to reflect
the implementation that actually shipped.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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.

1 participant