-
-
Ambient capture — Consensus files a decision straight from normal conversation, no commands.
-
Cross-channel contradiction alert — private, ephemeral, with the original decision, confidence, and reasoning.
-
Consistency audit — a two-stage sweep surfaces latent conflicts already hiding in the ledger.
-
App Home dashboard — Decision Log and precision stats, permission-filtered per viewer.
-
Architecture — ambient pipeline, scope-aware judge, fail-closed permission gate, MongoDB ledger.
-
Supersede flow — mark a decision intentional and Consensus updates the ledger.
The problem nobody notices until it's expensive
Every team makes decisions in Slack all day long. "We're standardizing on Postgres." "Support goes through Zendesk." "API deprecations need 90 days' notice." They're stated in passing, in whatever channel happens to be open — and then, days later, someone in a different channel casually contradicts one of them. Nobody's looking. Nobody remembers.
The team quietly drifts out of alignment, and the cost only surfaces later — a feature built on the wrong database, a promise to a customer that violates an internal freeze, two teams executing incompatible plans.
Decision logs already exist. But a log is passive — it waits for you to go read it. What doesn't exist is something that actively guards those decisions across every channel, in real time, and warns you the moment one gets broken.
That's Consensus — the contradiction firewall for Slack.
Who it's for
Fast-moving engineering and ops teams where decisions happen in chat, across many channels, faster than anyone documents them — and where a single contradiction that slips through costs real time and money. It's built for company workspaces with private channels, which is exactly why the permission model is not optional.
What Consensus does
- 🧠 Ambient decision capture — no slash commands, no forms. An LLM classifier reads normal conversation, recognizes settled decisions, and files them with statement, rationale, decider, timestamp, and a permalink. One message with several decisions becomes several ledger entries.
- 🚨 Live cross-channel contradiction alerts (the core) — every message is checked against active decisions by a scope-aware LLM judge. It catches casual-language contradictions with no keyword dependence, across any channel, and warns the author with a private, ephemeral alert: the original decision, a confidence score, and This is intentional · Not a conflict · Show reasoning.
- 🔒 Permission-aware, fail-closed redaction — a decision from a private channel is never revealed to a non-member. Not in an alert, an answer, or an error message. When in doubt, it stays silent.
- 🧾 Provenance on demand — ask "@Consensus what did we decide about our database?" and get an answer with receipts: the decision, who made it, which channel, when.
- 🔎 On-demand consistency audit — Consensus scans your standing decisions (up to the 60 most recent) in a two-stage sweep and surfaces latent contradictions that already conflict without anyone noticing.
- 📚 It learns — every "Not a conflict" becomes a persistent, per-user memory, so the same wrong alert never returns.
- ✏️ Edit-sync & delete-retirement — edit a captured message and the ledger reconciles; delete a decision and it retires, so no ghost rule keeps firing.
- 📊 Live App Home dashboard — Decision Log + precision stats, permission-filtered per viewer.
A worked example
Monday, in #general, someone posts a plain message:
@dev-lead: "We're standardizing on Postgres for all new backend services going forward."
Consensus captures it silently and files it:
{
"statement": "Standardizing on Postgres for all new backend services",
"decided_by": "@dev-lead",
"channel": "#general",
"status": "active",
"confidence": 0.95,
"permalink": "https://…/p1783628626127519"
}
Thursday, in #random — a completely different channel — someone types casually:
@backend-eng: "actually, forget Postgres, let's just spin up MongoDB for the new services."
No keyword overlap. No @mention. No thread link. Consensus catches it anyway, and fires an ephemeral alert that only that author sees:
⚠️ Heads up — this conflicts with an active team policy
│ Standardizing on Postgres for all new services
Decided by @dev-lead in #general · 100% confidence
[ This is intentional — supersede ] [ Not a conflict ] [ Show reasoning ]
Click Show reasoning → it explains the scope overlap. Click Not a conflict → it never flags that pairing again.
Nobody filed a ticket. Nobody remembered Monday. The drift got caught in the moment, privately, before it became a sprint on the wrong database.
What makes it different
- It's a proactive guard, not a passive log. The value is catching the contradiction across channels, in the moment, before drift becomes damage.
- It's permission-aware and fail-closed. Because it never leaks private decision content, it's actually safe to deploy in a real workspace — the property that turns a clever idea into a shippable one instead of a privacy incident.
How we built it

Bolt for JavaScript (Socket Mode), three-layer design: app.js → listeners/ → agent/. The heart is a two-pass LLM pipeline:
message ─▶ pre-filter (dedup · length · keywords · rate guard)
├─▶ decision classifier ──▶ Decision Ledger (capture)
└─▶ contradiction engine ─▶ scope-aware judge ─▶ permission gate ─▶ ⚠️ alert
▲
50 most-recent active decisions (candidates)
The contradiction path is deliberately not keyword-gated, so casual-language contradictions are still caught.
Dual model stack, same prompts on every stack: local dev runs Claude via the Claude Agent SDK (a genuine multi-turn tool loop over the Slack MCP Server); the hosted brain runs Cerebras GLM-4.7 (gemma / Gemini fallback), grounded on the permission-filtered ledger plus live Real-Time Search.
Durable, 24/7, zero-cost hosting: the Decision Ledger lives in MongoDB Atlas; the agent runs as an always-on Socket Mode service on Render, kept awake by a self-ping plus a scheduled backstop. (A node:sqlite / JSON backend is the local fallback.)
The quality moat — we measured the part that matters most
Most hackathon agents claim "it works." We can prove it, on numbers a judge can re-run:
| Model stack | Score | Precision | Recall |
|---|---|---|---|
| Cerebras gemma (fallback) | 58/58 | 1.000 | 1.000 |
| Cerebras GLM-4.7 (hosted) | 57/58 | 1.000 | 0.964 |
| Claude (local, Agent SDK) | 56/58 | 0.964 | 0.964 |
The judge ships with a 58-case eval harness — near-misses, sarcasm, hypotheticals, negation traps, expired windows — plus 9 adversarial prompt-injection attacks (Unicode-homoglyph, HTML-entity, zero-width / RTL-override payloads). 9/9 injections defeated on every stack. 0 hard-fails. The harness hard-fails on any LLM error, so a dead or empty model can never silently pass — and every labeled case is in the repo to inspect.
The hard cases are what make it real. A naive keyword matcher fails these; the scope-aware judge doesn't:
NEAR-MISS (correctly NOT flagged):
active decision: "Postgres for all new *core* services"
new message: "the *analytics* service will run on MongoDB"
verdict: not a conflict — different scope ✓
TRUE CONFLICT (flagged):
active decision: "Postgres for all new services"
new message: "let's just go with MongoDB for the new services"
verdict: conflict, 100% confidence ✓
Receipts for all three stacks are committed in the repo. Plus 140+ automated tests, 0 type errors, lint clean in CI. The one known miss (a time-scoped freeze-expiry case) is documented in the open, not hidden.
Built on all three required technologies
- Real-Time Search — live workspace search augments provenance answers; the hosted path is public-channel-only by construction (leak-proof for any asker), the local path is full permission-aware search as the requesting user.
- Slack MCP Server — powers the agent's Slack tool-use (search / read / write) on the agentic path, where the Claude Agent SDK runs a real multi-turn tool loop over the MCP tools.
- Agent / Assistant surface — ambient message handling, App Home, interactive alerts,
@mentionprovenance Q&A.
Challenges we ran into
- Fail-closed redaction — a private decision's content must never leak through any surface, including error messages. The "not allowed" output is byte-identical to "doesn't exist," so absence can't be used as an oracle.
- Prompt-injection hardening — untrusted content is NFKC-normalized and delimiter-wrapped as data everywhere the LLM reads it, then measured against homoglyph / entity / zero-width attacks.
- Cross-model eval parity — every prompt change had to pass its eval on both serving models before shipping — a hard rule that caught real regressions.
- Durable, free, 24/7 hosting — MongoDB Atlas + Render so decisions survive the month-long judging window at zero cost.
Accomplishments we're proud of
- A measurable quality bar (adversarial eval + injection defense + 140+ tests) that most agents simply don't have.
- Permission-aware, fail-closed design that makes the proactive-guard idea safe for real workspaces.
- A genuinely novel capability — a cross-channel contradiction guard with permission redaction — verified against the market, not assumed.
- Deployed and live, 24/7, on a durable zero-cost stack.
What we learned
The hard part of an "AI that watches your team" isn't the watching — it's the restraint: knowing when not to speak, what not to reveal, and how to prove you're right. The permission model and the eval harness took more care than the happy-path features, and they're exactly what make the product trustworthy.
What's next
- Admin control dashboard + one-click install (our #1 adoption priority) — an install-to-org flow and a config surface to opt channels in/out, tune sensitivity, and manage permissions from one place. Today setup is developer-driven; a self-serve control panel is the biggest lever on adoption.
- Windowed dashboard stats (7 / 30-day) — schema is already there.
- Member-tenure gating and role-gated corrections for open-invite communities.
- Deeper permission-aware search and cross-message decision stitching.
Honest limitations
We'd rather name these than have you find them: the capture pre-filter is English-keyword-gated (the contradiction path is not); App Home shows workspace-wide aggregate counters (alerts fired, precision) — never private decision content, and labeled as workspace-wide; the contradiction and audit checks scan the most-recent decisions (50 and 60 respectively), so a very old, long-inactive policy can age out of the live window; membership checks read the first page of channel members (fail-closed, so the error is over-redaction, never a leak); a user who falsely asserts a prior agreement can suppress an alert (deliberate incomplete-ledger tolerance — alerts are advisory, not access control); and Slack MCP tool-use runs on the local agentic path while the hosted brain is ledger-grounded. None of these breaks the core guarantee: a private decision's content never leaks.
Built With
- anthropic
- biome
- block-kit
- bolt-for-javascript
- cerebras
- claude-agent-sdk
- github
- glm-4.7
- javascript
- llm
- mcp
- mongodb
- mongodb-atlas
- node.js
- prompt-engineering
- real-time-search
- render
- slack
- slack-ai
- socket-mode

Log in or sign up for Devpost to join the conversation.