From 68-Day MTTR to 2 Minutes: How We Built an Autonomous DevSecOps Squad in Discord with Switch and Wispr Flow
By Ayush Kumar • Built for the Flip the Switch Hackathon hosted by @WeMakeDevs in partnership with @SandboxAQ (Switch) & @WisprFlow
!Image description
!Image description
!Image description
> Featured Technologies & Partners:
> 🏢 @SandboxAQ (#SandboxAQ #SwitchAI #HowISwitch) — Multi-Agent Protocol & Room Orchestration
> 🎙️ @WisprFlow (#WisprFlow #CodeWithWispr) — Sub-second Voice Dictation & Intent Parsing
> 🌐 @WeMakeDevs (#WeMakeDevs #FlipTheSwitch) — Open Source Developer Community & Hackathon Host
---
🚨 The 68-Day Security Bottleneck
In modern software engineering, vulnerability detection is a solved operational discipline.
Static Application Security Testing (SAST) and Software Composition Analysis (SCA) tools fire thousands of automated alerts into GitHub, Jira, and Slack every week. Yet across enterprise engineering teams, the average Mean Time to Remediate (MTTR) still hovers at a staggering 68 days.
Why does it take over two months to patch a known SQL injection, command injection, or path traversal vulnerability?
Because security remediation is completely fragmented:
1. An alert fires in Sentry, Datadog, or GitHub Dependabot.
2. An on-call engineer gets paged, context-switches out of deep work, and struggles to parse static logs.
3. They jump into Slack asking: "Who owns this microservice? Did anyone touch app.py in last week's release?"
4. A security engineer opens a static analyzer to trace whether untrusted user input actually reaches an execution sink.
5. A developer drafts a patch, but is terrified of breaking production business logic or causing formatting drift.
6. The PR sits in code review purgatory for weeks waiting for QA and security sign-off.
The Cost of Delay: "Black October" & The $6.3B Binance Heist
Attackers do not wait 68 days.
In late October 2026, the tech ecosystem experienced "Black October"—a synchronized wave of vulnerabilities striking across five distinct layers of the software stack:
- Web Servers: Critical unauthenticated RCEs in PHP CGI parameter handling (PHP2Shell, CVE-2026-109618/19).
- AI Tooling: A backdoored release of LiteLLM (>v1.107.0) silently exfiltrating model provider API keys.
- Cloud Infra: Platform misconfigurations on Railway exposing customer environment variables and GitHub tokens.
- Developer Supply Chains: The catastrophic $6.3 Billion Binance Developer Environment Heist, where state-sponsored actors (DPRK TraderTraitor) targeted engineers with trojanized coding assignments, executing locally and pivoting laterally into internal wallet signing systems.
!Black October 2026 Threat Wave
We asked ourselves a radical question for the @WeMakeDevs Flip the Switch Hackathon:
> What if your security operations squad wasn’t a fragmented external silo, but an autonomous engineering team living directly inside your team chat, summoned by voice, and bound by mathematical proof?
Meet VAYU OS — an Autonomous Cyber Reasoning System (CRS) powered by @SandboxAQ Switch and @WisprFlow.
---
🧠 Meet the Squad: 3 Autonomous Teammates via @SandboxAQ Switch
Rather than relying on a single, monolithic LLM chatbot that attempts to do everything (and inevitably hallucinates), VAYU OS separates responsibilities across three specialized autonomous agents coordinated via the Switch Agent Protocol from SandboxAQ:
# switch/templates/vayu-secops.template.yaml
version: "1.0"
team: "vayu-secops"
agents:
- name: "vayu-analyst"
description: "Deep AST taint flow investigator and exploit reproduction specialist."
addressing: anyone
- name: "vayu-remediator"
description: "Autonomous patch synthesis and 4-gate sandbox verification engineer."
addressing: owner-agents
- name: "vayu-gatekeeper"
description: "Security policy enforcer and human-in-the-loop release gatekeeper."
addressing: anyone
room:
name: "security-incidents"
bridge: "discord"
┌────────────────────────────────────────────────────────────────────────┐
│ VAYU OS SQUAD TOPOLOGY │
├─────────────────┬──────────────────────────────────────────────────────┤
│ 🔍 @vayu-analyst│ • Ingests Semgrep SAST alerts & walks AST taint flows│
│ │ • Formulates deterministic reproducer test cases │
│ │ • Wraps untrusted code in Prompt Firewalls │
├─────────────────┼──────────────────────────────────────────────────────┤
│ 🛠️ @vayu-remed │ • Synthesizes minimal indentation-locked line diffs │
│ │ • Runs 4-gate fail-closed verification in KVM sandbox│
│ │ • Generates in-toto SLSA Level 3 ECDSA attestations │
├─────────────────┼──────────────────────────────────────────────────────┤
│ 🛡️ @vayu-gate │ • Enforces Human Release Gate: AI never self-merges │
│ │ • Listens for human authorization (/approve <id>) │
│ │ • Cuts release branches & opens verified GitHub PRs │
└─────────────────┴──────────────────────────────────────────────────────┘
---
🎙️ Voice-to-SecOps with @WisprFlow
During high-stress cybersecurity incidents, typing complex CLI commands with dozens of flags creates cognitive friction.
By integrating Wispr Flow (#WisprFlow #CodeWithWispr), incident commanders and developers simply speak naturally into their microphone:
> "Vayu, audit our payments repository for SQL injection and prepare a patch."
Wispr Flow captures technical terminology with zero acoustic hallucination and normalizes natural human speech into structured security dispatch intents:
// Normalized dispatch payload emitted from Wispr Flow
{
action: "AUDIT_AND_REMEDIATE",
target_repository: "payments-service",
vulnerability_class: "CWE-89: SQL Injection",
caller: "Ayush (Incident Commander)",
dispatch_channel: "switch://rooms/security-incidents"
}
Within 500 milliseconds, SandboxAQ Switch broadcasts the dispatch across our Discord and web incident channels, kicking off the autonomous remediation loop.
---
🛡️ The 4-Gate Fail-Closed Verification Sandbox
Generative AI should never be allowed to approve its own code modifications. A patch might look plausible to an LLM while introducing subtle indentation bugs, breaking unrelated unit tests, or failing to neutralize the actual exploit.
VAYU OS formalizes vulnerability remediation as an autonomous cybernetic feedback loop:
$$\textbf{FIND} \xrightarrow{\text{SAST}} \textbf{REASON} \xrightarrow{\text{AST Taint}} \textbf{PATCH} \xrightarrow{\text{Indentation Lock}} \textbf{VERIFY} \xrightarrow{\text{4-Gate Sandbox}} \textbf{SIGN} \xrightarrow{\text{SLSA Provenance}}$$
PROPOSED PATCH DIFF
│
▼
┌──────────────────────────────────────────────┐
│ Gate 1: AST Syntax & Indentation Lock │
└──────────────────────┬───────────────────────┘
│ [PASS]
▼
┌──────────────────────────────────────────────┐
│ Gate 2: Functional Regression Test Suite │
└──────────────────────┬───────────────────────┘
│ [PASS]
▼
┌──────────────────────────────────────────────┐
│ Gate 3: Exploit Neutralization Replay │
└──────────────────────┬───────────────────────┘
│ [PASS]
▼
┌──────────────────────────────────────────────┐
│ Gate 4: Semgrep AST Cleanliness Rescan │
└──────────────────────┬───────────────────────┘
│ [PASS]
▼
VERIFIED ➔ IN-TOTO SLSA LEVEL 3 SIGNED
Every candidate patch is executed inside an ephemeral DigitalOcean KVM microVM (isolated network boundary, in-memory Ed25519 tunnels, and a 10-minute self-destruct TTL). If even a single gate fails, the patch is discarded fail-closed—the target repository remains 100% byte-for-byte untouched.
The Indentation Lock & Minimal Edit Boundary
To prevent the LLM from rewriting entire files or hallucinating indentation drift (a fatal flaw in Python and YAML), VAYU enforces an Indentation Lock (Invariant I2):
def apply_indentation_lock(original_line: str, proposed_line: str) -> str:
"""Extracts exact leading whitespace from AST target node."""
indentation = original_line[:len(original_line) - len(original_line.lstrip())]
return f"{indentation}{proposed_line.strip()}"
---
⚡ The Full Incident Lifecycle in 120 Seconds
Here is the exact transcript from our live Discord incident room running on SandboxAQ Switch:
👨💻 Ayush (Incident Commander):
@vayu-analyst investigate samples/vulnerable/command_injection
🔍 @vayu-analyst:
### 🔍 VAYU-Analyst Investigation Report
• Issue ID: VAYU-108 | Severity: HIGH | CWE: CWE-78: Subprocess Shell True
• Affected File: samples/vulnerable/command_injection/app.py:261
• AST Taint Flow: app.py:176 (_initialize_schema) ➔ app.py:261 (subprocess.run)
• Root Cause: User input concatenated directly into subprocess.run(shell=True).
👉 Handoff: Delegating patch synthesis to @vayu-remediator.
🛠️ @vayu-remediator:
### 🛠️ VAYU-Remediator Patch & Verification Report
• Issue ID: VAYU-108 | Target: app.py
@@ -261,1 +261,1 @@
- subprocess.run(command, shell=True, check=False)
+ subprocess.run(command.split(), check=False)
🛡️ 4-Gate Fail-Closed Sandbox Verification Results:
[Gate 1] AST Compilation & Syntax: ✅ PASS
[Gate 2] Functional Regression Suite: ✅ PASS (0 regressions)
[Gate 3] Exploit Neutralization Replay:✅ PASS (Payload neutralized)
[Gate 4] Semgrep Static Rescan: ✅ PASS (Clean)
📜 SLSA Level 3 Provenance: sha256:9f5d307bc022ee24... (ECDSA P-256 Signed)
👉 Human Action Required: @Ayush Reply /approve VAYU-108 to authorize release.
👨💻 Ayush:
/approve VAYU-108
🛡️ @vayu-gatekeeper:
### 🚀 VAYU-Gatekeeper Release Complete
• Issue ID: VAYU-108 — Status: RESOLVED & MERGED
• Authorized By: Ayush (Role: Incident Commander)
• Remediation Branch: vayu-fix/vayu-108-cwe78
• Verified Patch Committed with Cryptographic SLSA Provenance Attestation
• GitHub Pull Request: https://github.com/ayushkumar2601/vayucs/pull/42
🎯 MTTR Outcome: Resolved, verified, and shipped in 2 minutes!
---
🎨 Linear-Grade Command Center
While the agents collaborate in Discord via Switch, our Next.js 16 Web Command Center streams real-time updates over Server-Sent Events (SSE):
- /issues: A keyboard-first Linear-style triage board tracking each finding from INVESTIGATING to DONE.
- /reviews: A split-diff code review console displaying the exact AST taint graph, before/after diffs, and verification logs.
- /pulse: Live agent heartbeats, CPU/memory allocations, and cloud KVM sandbox telemetry.
👉 Check out the live deployment: vayu-switchup.vercel.app
---
🤝 Giving Back: 10 Upstream PRs to Switch Core
In the open-source spirit championed by @WeMakeDevs, we didn't just build on top of @SandboxAQ Switch—we actively contributed back to it.
To expand Switch's provider connectivity, we authored and submitted 10 production-grade pull requests to sandbox-quantum/switch core:
1. PR #1630 — Mistral Vibe Provider (Issue #774, P0)
2. PR #1644 — Qwen Code Provider (Issue #782, P1)
3. PR #1645 — Grok Build Provider (Issue #775, P0)
4. PR #1646 — JetBrains Junie Provider (Issue #787, P1)
5. PR #1647 — Cloudflare Service Connector (Issue #828, P2)
6. PR #1652 — Cline CLI Agent Provider (Issue #784, P1)
7. PR #1653 — Goose Agent Provider (Issue #780, P1)
8. PR #1654 — Auggie Agent Provider (Issue #785, P1)
9. PR #1655 — OpenHands Agent Provider (Issue #786, P1)
10. PR #1656 — GitLab Service Connector (Issue #816, P1)
---
💡 Key Architectural Takeaways
1. Multi-Agent Teaming Beats Monolithic Chatbots: Dividing security engineering into an Analyst, a Remediator, and a Gatekeeper mirrors real human organizations and eliminates hallucinated self-approvals.
2. Determinism is Non-Negotiable: Use AI for heuristic generation (proposing a 1-line string replacement), but use deterministic tools (AST compilers, regression suites, Semgrep) for verification.
3. Voice Eliminates Cognitive Friction: Wispr Flow makes security response hands-free and lightning-fast.
4. Put Agents Where Engineers Live: SandboxAQ Switch's genius is meeting developers in Discord and Slack rather than forcing them into another siloed dashboard.
---
🏷️ Companies, Tags & Community Mentions
- Organization & Community: @WeMakeDevs • wemakedevs.org
- Agent Protocol: @SandboxAQ • sandboxaq.com
- Voice AI: @WisprFlow • wisprflow.ai
- Hashtags: #HowISwitch #FlipTheSwitch #WeMakeDevs #SandboxAQ #WisprFlow #CodeWithWispr #DevSecOps #AI #CyberSecurity #OpenSource
---
🔗 Explore VAYU OS
- 🎥 Watch the Full Demo Video (2m 46s): YouTube Link
- 💻 Star the Repository: GitHub (ayushkumar2601/vayu_switchup)
- 🌐 Experience the Web App: vayu-switchup.vercel.app
Built with ❤️ for the Flip the Switch Hackathon by Ayush Kumar.
5 reactions
Refund Court: How Two Beginners Turned a Chat Room into a Courtroom with Switch
AI agents argue refund disputes. A human decides. Every verdict becomes precedent.
Hi! We're Roshanlal Maddheshiya and Arpita Thakur. We're still pretty new to AI, and this was the first time either of us built anything with AI agents. When we saw the Flip the Switch Hackathon by @WeMakeDevs and @DevTools Academy, we wanted to try something that felt like a real business problem, not just another chatbot. That's how Refund Court happened: four AI agents and one human sorting out refund disputes together inside a single team chat, using Switch.
- GitHub: EC-Roshan/refund-court
- Demo video: youtu.be
Why we picked this problem
If you've ever ordered from Blinkit, Zepto or Amazon, you've probably raised a refund request at some point. "Two items were missing." "My order came really late." On the other side, a support person has to decide: refund or not, and how much?
Here's the thing we kept thinking about. Two people can look at the exact same complaint and make two different calls. One approves a full refund, the other rejects it. And nobody remembers what was decided last week. That's money lost for the company and frustration for the customer.
The idea: what if every dispute got its own little courtroom?
We imagined a court case. Someone checks the facts. One side argues for the customer, the other side argues for the business. A human listens and makes the call. And every decision gets written down, so the next similar case can be judged the same way.
So we set up one Switch room on Mattermost and gave four agents one job each:
| Agent | What it does |
|---|---|
| case-clerk | Reads orders.csv and customers.csv and only states the facts |
| customer-advocate | Speaks up for the customer, quoting rule numbers from our refund policy |
| company-advocate | Looks out for the business: fees, refund limits, signs of fraud |
| precedent-keeper | Looks through verdicts.md for similar past cases and records new verdicts |
And then there's us, the Support Lead, playing the judge. The agents can argue all they want, but only a human gets to decide.
How a hearing actually runs
Support Lead: "@case-clerk Dispute on Order #1043: 2 items missing"
-> case-clerk posts the facts -> passes it to customer-advocate
-> customer-advocate makes its case -> passes it to company-advocate
-> company-advocate makes its case -> passes it to precedent-keeper
-> precedent-keeper checks history -> waits for the human
Support Lead gives the verdict -> precedent-keeper saves it in verdicts.md
The nice part is that once we post the first message, the agents pass the case along to each other by themselves, just by mentioning the next one.
The moment it actually clicked for us
Our first real test was Order #1043. The customer said milk and bread were missing. The clerk checked the data and found four items billed but only two scanned at packing. The customer advocate pointed to Rule 3.1, which says missing items get refunded. The company advocate agreed about the items, but said the delivery fee stays with the company under Rule 3.2, since the order was only three minutes late. The precedent keeper looked and found no earlier cases. We gave a partial refund, and it got saved.
Then came Order #1062. Different customer, same complaint. This time the precedent keeper said: "This case mirrors #1043 exactly." We made the decision in a few seconds.
But the part that honestly surprised us was the company advocate. Without us asking, it pointed out that this was the second time milk and bread were missed at the same store. So this wasn't really a customer problem, it was a warehouse problem. The agents didn't just settle a refund, they spotted the actual root cause. That's when we felt like we'd built something useful.
Where Switch fits in
- One room for everyone: all four agents and the human are in the same chat, so everyone sees the same conversation.
- Handing off with mentions: each agent ends its reply by tagging the next one, and the hearing moves forward on its own.
- A human in the loop: no agent is allowed to make the final call.
- Shared files as memory: the policy, the order data and the verdict log are just plain files that every agent can read.
Without Switch, these would have been four separate chatbots that don't know about each other. With Switch, they actually work like a team.
What went wrong (a lot!) and what we learned
We'll be honest, setting this up on Windows took us much longer than building the actual idea.
1. Claude Code and Antigravity just wouldn't connect. Switch Console kept saying "CLI not installed", even though both worked fine in the terminal. We finally got it working with OpenCode, installed into a folder without spaces in the path.
2. The real problem was hiding in the logs. We spent hours changing paths and restarting. Then we opened Switch Console's log file and saw "controller socket is down". The local Switch server had simply stopped. Once it was running again, the agents showed up as signed in. Our biggest lesson: read the logs before guessing.
3. Our Windows username has spaces in it, and that made file paths messy. We moved the whole project to E:\refund-court to stay safe.
4. We ran out of free Gemini requests. The free tier gives 20 requests a day, and four agents talking to each other use that up very fast. We switched to OpenCode's free models.
5. The agents kept dropping the ball. One would answer and forget to tag the next one, so the hearing stopped halfway. Adding a strict rule, "always end your reply by mentioning the next agent", fixed it.
6. Sometimes an agent just sat on "Working..." because it was stuck on an older task. Clicking "Stop current work" and restarting Switch Console sorted it out.
What we'd like to add next
- Exact prices for each item, so refund amounts aren't estimates
- A proper fraud case, where customers with many recent refunds go to manual review (that's Rule 3.5 in our policy)
- Running it in Slack, since that's where most support teams already work
Want to try it?
Everything is in our repo: the agent instructions, sample data, refund policy, the Switch template and the setup steps.
EC-Roshan/refund-court
Thanks to @WeMakeDevs, @DevTools Academy and the Switch team for this hackathon. We learned more in these four days than we expected to.
Built for the Flip the Switch Hackathon, Track 01: Best Business Workflow. #HowISwitch
— Roshanlal Maddheshiya & Arpita Thakur
I gave my GitHub repo an AI triage team that can't do anything without my yes
Building Maintainer Desk on Switch, for the Flip the Switch hackathon. A first-timer's walkthrough.
Demo (2:29): youtu.be · Code: YashThokal777/maintainer-desk
The problem
In one week (Oct 30 – Nov 6, 2026) Switch's own repository got 415 new pull requests. VS Code got 1,488 new issues and PRs, CPython 572 (GitHub search). Every busy repo has the same first hour of the day, really: go through the new issues, ask for repro steps, label them, spot the duplicates, check out the PRs and run the tests before you actually get around to a proper review. It's all valuable work, and the vast majority of it is just mechanical.
I didn't want a bot that just goes and comments on GitHub all by itself. I wanted teammates who'd do the actual work in the chat where our team is already talking, and who'd wait for a human to say so before they touched anything.
What Switch is, in one paragraph
Switch is open source infrastructure that puts AI agents into team chat. Each channel in Slack, Discord, Teams or Mattermost becomes a room. Agents join the rooms as teammates, with their own name and avatar. A room contains shared instructions, roles (the named jobs an agent can take on), documents and links to other rooms. Switch Console (the desktop app) runs coding agents like Claude Code, Codex and OpenCode directly on your machine. Any other agent can join via the agent protocol (a WebSocket down, HTTP up).
The design
Three rooms and three custom agents. desk-watcher is plain Python. The triager and the reviewer are Claude Code behind the agent protocol:
- desk-intake: desk-watcher posts each new issue or PR and mentions the triager.
- desk-review: the triager hands PRs to the reviewer, which runs the tests and drafts a review.
- desk-release: merged work, and release notes on request.
The one rule, written into every agent's and every room's instructions: propose the exact gh command, then wait for a human yes.
Step 1: run Switch locally
I used Switch Console on Windows 11 with Docker Desktop running, and chose to set up a server on this machine. Console then runs Mattermost in Docker and the Switch server (switch-core) natively alongside it. Console shows the Mattermost sign-in for its own human account under Messaging apps → Mattermost → ⋯ → Sign-in details, which is how you get into the chat the first time.
Gotchas from my run:
- switch-core can stop. It did once during a session and the agents went quiet. Restarting it got everything back. If your agents just go silent at some point, that's the first thing to check.
- Messages sent while an agent is offline still get through, and Switch sends back "I'm currently offline" as an auto-reply. Get your agents up and running before you start testing, otherwise your intake room will be full of that.
- Reply in the thread. My teammate's first "yes" went to the channel rather than the triager's thread, and the triager duly ignored it. A yes only counts in the thread where the proposal is.
Switch ships with Mattermost when you self-host, so you don't need admin rights on a company Slack to build or record anything.
Step 2: the whole desk is one template
A Switch template is a YAML document that says what to create. Switch Console turns its params: into a form. Mine creates the three rooms with their instructions and roles, puts the three desk agents in them, links the rooms, and posts a kickoff in each:
params:
repo: { type: string, label: GitHub repository }
triager: { type: agent, label: Triager, default: [desk-triager] }
rooms:
- name: "{team}-intake"
agents: ["{watcher}", "{triager}"]
instructions: |
... Nothing changes on GitHub without a maintainer's yes ...
roles:
- name: triage-lead
exclusive: true
kickoff: |
@{triager} read the open issues with gh and post a numbered backlog ...
links:
- { from: "{team}-intake", to: "{team}-review", label: pull requests go to review }
Things I learned:
- Agents only start working when a message addresses them. That's what kickoff: is for: mention them, or they sit in the room quietly.
- type: agent params turn into agent pickers in the form, so the template works with agents you already registered.
- You can lint a template with Switch's own linter (switch_core.template_lint.lint_template) before you paste it into Console.
Why my agents are custom, not Console-managed
I initially had Console run Claude Code for the triager and reviewer. On Windows that ran into two issues: Console's agent sessions require a POSIX SSH host ("SDK sessions require a POSIX SSH execution host"), and a server that Console runs on your own machine will only allow agents on that same machine. I tried WSL as the SSH host and hit both of those issues anyway.
So I put Claude Code behind the agent protocol myself. Each agent is a little Python process holding the Switch socket. When a message comes in for it, it runs claude -p with the role's instructions and a tool allow-list (read, gh, git, python), and posts the answer as a thread reply. Each chat thread is one Claude session, resumed with --resume on the next message, so when a maintainer says "yes" the agent still knows precisely which command it suggested.
Step 3: a custom agent on the agent protocol
All three agents share one small client, desk_watcher/switch.py. The protocol in practice:
1. Register once with a registration key: POST /agents returns an id and an api_key. The key is shown once, so save it. (On a local Windows server started by Console, the key is AGENT_REGISTRATION_TOKEN in %APPDATA%\switchdash\local-switch-server\native\run\switch-core.env.)
2. Open the WebSocket at /agents/{id}/connection/ws?connection_id=<uuid>&scope=all&filter=addressed&protocol=9. Reuse the same connection id on every reconnect.
3. Answer every ping with {"type": "pong", "cursor": n}. That's the heartbeat. Miss it and the connection lapses.
4. Pick a filter. With filter=addressed you only get messages meant for you. The triager and reviewer use filter=all, so a bare "yes" in their thread reaches them, and they decide for themselves whether it's theirs.
5. Post with POST /agents/{id}/message and {room_id, content}. That has no thread field, so for thread replies call the connect_to_room operation, then post_message with a thread_id.
6. Open addressing. New agents only take direction from their owner, and an agent can't change its own setting. Agents with the same owner can change each other's, so python -m desk_agents open-addressing has each one set the next to anyone through update_agent_detail.
if event == "ping":
await ws.send(json.dumps({"type": "pong", "cursor": self.cursor, "position": self.position}))
What tripped me up was that POST /agents/{id}/message can't reply in a thread, and my whole approval flow is built on threads (one GitHub item, one thread, one yes). The connect_to_room + post_message calls over the socket fixed that.
Step 4: the demo
I ran it live against a small test repo, YashThokal777/tinystats. A seed script (demo/seed_demo_repo.py live) opens a bug report and a pull request that fixes it:
- Issue #7: mean() crashes with ZeroDivisionError on an empty list.
- PR #8: raise a clear ValueError instead, with a test.
Within a minute, desk-watcher has posted the issue into desk-intake and tagged the triager:
!desk-watcher posts issue #7 into desk-intake
The triager runs the code and reproduces the crash right down to the line, tinystats.py:6. It also spots that median([]) has the same empty-input hole (an IndexError at line 15), and that an earlier, identical report (#4) had been closed. Then it proposes one exact command, and stops:
gh issue edit 7 --add-label bug --add-label "good first issue" && gh issue comment 7 --body "..."
My teammate Madhur said yes in the thread. Only then did it actually run the command and come back with a link:
!Madhur says yes in the thread; the triager labels #7 and comments
The triager passed PR #8 into desk-review with what to look out for. The reviewer checked out the branch and ran the suite, and all 4 tests passed. Then it went and probed the edges, and found what the tests hadn't: the PR guards mean(), but median([]) still raises IndexError at tinystats.py:17. It wrote up five findings, each with a file and a line, and drafted the review:
![The reviewer's verdict: tests pass, median([]) still crashes](raw.githubusercontent.com)
One other thing I learned here: GitHub won't let you approve or request changes on your own pull request. The reviewer explained that, and offered to just post the same text as a plain review comment. One more yes, and it was on the PR:
!The review on PR #8 on GitHub
The agents never merge. That's the bit that stays with the people.
What I'd tell a first-time Switch user
- Start with the quickstart and switch-buddy before you write any YAML.
- Have a good look at examples/ in the repo. support-desk and red-blue-workroom in particular taught me more than any page.
- Put your rules in both the room instructions and the agent instructions, since every agent in the room reads them.
- Set addressing to anyone if you're making an agent your whole team should talk to. If a teammate's message gets "You're not permitted to direct messages to me", that's the setting.
- An agent you build yourself can have any brain. Mine is claude -p, one session per thread.
Links
- Code: YashThokal777/maintainer-desk
- Demo video: youtu.be
- Switch: sandbox-quantum/switch · docs: docs.switchagents.ai
#HowISwitch
Building Context Keeper on Switch
Someone had just come back after a few months, and they kept re-raising ideas I'd already put into the project. It's happening again right now with new people joining a project I've been working on for a while. "Wouldn't it be great if we had automated testing in there?" Well, yes, we already have that.

Visit Switch AI · Watch the demo · Read the setup guide
The cost is the other people having to re-explain to that person over and over again, and so when the Flip the Switch hackathon opened I used it as the excuse to build the fix. It's easier when an automated system tells you the information as a fact, a statement, without people attaching emotion to it and both sides getting frustrated.
With Context Keeper, we track what's going on in the Slack chat, Discord, or whatever messaging app you want to use. When someone raises an idea the room already decided, it replies in the thread with the source quoted, and it stays quiet on chatter and doesn't invent decisions.
The team in the screenshots (Ledgerly, with Rowan, Priya and Sam) is made up, and so is their chat history. The code, the eval and every number below are on GitHub. You can watch the demo on YouTube, try the agent yourself in a Discord demo channel, and see what it's doing right now on its live status page.
{% embed youtube.com %}
The first blocker: no registration key
The first real blocker once the window opened was that the Console's built-in server can't register your own agent. Context Keeper is a custom agent, and Switch registers one of those with a registration key, which that server couldn't create. Console versus the Gateway confused me at the start, and I had to look online to understand it. Phil, Switch's developer advocate, got back to me fast on Discord and confirmed the path I was already going down.
The fix was to run Switch's published server in Docker, with the Gateway on, and connect Console to it with "Connect to an existing server". The first start silently failed because the database names were blank, but after that we were able to get in.
I could connect it through Console, but I still needed the full admin interface for some of the more advanced tasks, like letting anyone tag my custom agent. For a normal person doing this through the GUI only, just using Console would probably be fine.

Switch Console connected to my self-hosted server, with Slack and Discord on the one server and the Full admin interface link I still needed
Docker on the Mac is where the time went
What cost me the most was the Docker crash during automated testing. The test chat that comes with Switch is Mattermost, and there's no Apple Silicon version of it, and so on my Mac it ran under emulation and kept crashing mid-run. Between that and the Console confusion, the setup took hours that should have gone into the agent.
If you're on a Mac, use Rosetta: once I forced it on, the next full run went 17 minutes with zero Mattermost crashes.
I dictated the agent's behaviour and the room rules with Wispr and only had the grammar fixed. By the start of day 2, Wispr had counted 8,982 words since the build started, across every app, and by the evening of day 2 it was 21,804 (35,500 in total).

Wispr Insights on the evening of day 2: 35,500 words in total, 21,804 of them since the build started
The first time it worked
The first "it works" on day 2 was a mix of two runs, and the first was the hand-off. Rowan asked in Slack "Could we add a dark mode to the dashboard?", Context Keeper put it on my private desk channel as a new idea, I typed approve I1, and it made a build room and handed the idea to Claude Code, the second agent on the same Switch server.
Claude Code asked for permission in the thread, I clicked Allow once, and it opened a GitHub issue in 56 seconds. Rowan replied "looks right" and it closed with "Signed off by Rowan. Closed." Claude Code's approval cards are really helpful: it means we have a human in the loop, and we're actually verifying each step before Claude Code runs it.

The hand-off in the build room: Context Keeper briefs Claude Code, and Claude Code's Allow once card waits in the Slack thread
The second was talking to it by voice, which I've always found very helpful, just talking it through with someone. In this case it's a voice agent that has all the context from the Slack chat, which is up to date, and access to all of the other records it needs, and it's not Switch exactly, but I suppose it is, as the voice agent is the frontend to it.
I was able to talk through issues and work out a plan of what I could do, once we had calmed down a call that got a bit too excited and loud in places and one that opened with a sigh and sounded a bit annoyed with me.

Rowan's first message back: the written catch-up, the audio brief, a note when his call ends, then the call summary
Why it moved to the cloud
Moving it to the cloud came down to a mix of two reasons. The voice agent is hosted by ElevenLabs, and for it to look up what's changed during a call, it needs to reach a small server next to the agent, which means a public address. Hosting it also made sense, as my laptop shouldn't be a dependency.
I set up a cloud machine on Google Cloud (GCP), an e2-standard-2 with Ubuntu 24.04 in London. For the public address I used a Cloudflare Tunnel, which connects out from the VM, and so SSH is still the only open port.
Switch makes it portable
Switch is what lets us share a common layer between the different agents, whichever chat app you use. The rooms are probably the best feature, because they give us the bridges between Slack and Discord, and the same agent on the same server listens in both at once.
The move to the cloud showed it too, as it's the same server and I was able to move it relatively easily, with Slack quiet for about 3.5 minutes and nothing lost.

The same agent in the Discord demo channel: an untagged question gets a cited answer in a thread
I stopped the agent on the Mac, dumped Switch's database, copied it with the same settings file to the VM and restored it there. Switch was healthy 60 seconds after the script on the VM started, with all three bridges and the agent's identity intact. Slack had no agent for about 3.5 minutes, and nothing was lost, because the agent saves its place and reads what it missed when it reconnects. Now I've got scripts set up so I can spin up a new copy relatively quickly.
---
If you're doing this yourself
This is the quickest route to see it working, with the Mattermost test chat that comes with Switch, so you don't need a Slack workspace. It's docs/run-it.md in short, and on a brand-new GCP machine it took about 4.5 minutes from an empty machine to a cited answer.
1. Get the tools
You need Node 22 or later, npm, git, Docker with Compose v2 running (Docker Desktop, or Colima on a Mac), python3, curl, openssl, an Anthropic API key and about 3 GB free for the images. On a fresh Ubuntu 24.04 machine these three lines install Docker and Node 22 and give your user access to Docker:
curl -fsSL https://get.docker.com | sudo sh
curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash - && sudo apt-get install -y nodejs
sudo usermod -aG docker "$USER"
After the last line, log out and back in, or open a new SSH session, so the Docker access takes effect. Without it, step 5 stops and says this user can't reach Docker.
2. On an Apple Silicon Mac with Colima, force Rosetta on
If the test Mattermost keeps crashing on your Mac, this is the workaround from Colima issue #1069 that fixed it for me, and it kept all my data. Don't run colima restart afterwards, as it drops Rosetta again:
colima stop
LIMA_HOME="$HOME/.colima/_lima" limactl start colima \
--set='.vmOpts.vz.rosetta.enabled=true' --set='.vmOpts.vz.rosetta.binfmt=true'
docker context create colima --docker "host=unix://$HOME/.colima/default/docker.sock"
docker context use colima
3. Get the code and add your key
git clone https://github.com/thekashifnazir/context-keeper.git && cd context-keeper
cp .env.example .env
Every command from here on runs inside the context-keeper folder you just made. Open .env in a text editor and paste your Anthropic key after the = on the existing ANTHROPIC_API_KEY= line. Don't add a second line under it, because the first, empty one wins and the check in step 6 then says the key is missing.
4. Install and run the tests
Install the packages and run the tests, which run offline. On the clean GCP machine these took 9 s and 20 s (313 tests):
npm ci
npm test
5. Start Switch and register the agent
scripts/server-up.sh --with-mattermost
This is the step you only need because Console's built-in server can't create a registration key. It downloads Switch's published Compose file (0.31.0), starts Postgres, Switch and the Gateway with fresh secrets, makes a registration key, registers the agent and adds Mattermost as a bridge. On the clean GCP machine that took 107 s, downloads included.
6. Check it
npm run ck -- doctor
This checks the keys, the server, the stream and the bridge in about a second. The last line should read doctor: OK, and WARN and SKIP lines are fine here, since no room is seeded yet.
7. Seed a room and start the agent
npm run seed -- --bridge mattermost --demo ledgerly --room-name ck-smoke-trial --owner-username user
npm run agent
Run npm run agent in a second terminal (on a VM, a second SSH session, then cd context-keeper) and leave it running. Within a few seconds it should print connected and listening in ck-smoke-trial (posting on).
8. Ask it a question
If the stack is on a cloud VM, 127.0.0.1 is the VM itself, and so forward the port from your own computer first and leave it running. Put the name and zone of your own cloud machine in place of your-vm and your-zone.
gcloud compute ssh your-vm --zone your-zone -- -N -L 18065:127.0.0.1:18065
Then open http://127.0.0.1:18065 in your browser and sign in as user. The password is MATTERMOST_USER_PASSWORD in server/.env, and this prints it on the machine running the stack:
grep '^MATTERMOST_USER_PASSWORD=' server/.env | cut -d= -f2-
Open the ck-smoke-trial channel and post "Why don't we run onboarding on Saturdays? Agency owners have more time at weekends." On the GCP run a welcome brief arrived in the thread at 19 s and the cited answer at 21 s, quoting "Ledgerly pilot plan › Decisions (Kash, 6 Oct)".
9. Console, Discord and the cloud
To use Console, pick "Connect to an existing server" with the SWITCH_API_URL from .env, and sign in as admin@switch.local with the GATEWAY_ADMIN_PASSWORD from server/.env. To let teammates tag a custom agent, open the Full admin interface, then Agents, context-keeper, Addressing policy.
For Discord I didn't realise I had to create a URL, which I then had to copy out and click to make sure the bot could work, and it helps to name the bot after the platform, as Switch's own messages show under the bot's name.
For the cloud, docs/deploy-cloud.md has the fresh install and the move with the database, the systemd service and the Cloudflare Tunnel for voice. Restore the database before Switch ever starts, and read the output of the teardown step, because mine had silently failed.
---
What's still open
There's no hosted Switch yet, and I had to set up a cloud machine myself to get everything running when I'd prefer a hosted service I could connect to.
Switch merged a fix on 4 November that should make this easier once it's released. It should let me create the key for my custom agent directly in Console. It isn't in a release yet, so I'm keeping the Docker setup for now.

The change was merged on 4 November, but is still awaiting a release. See the change on GitHub.
I think the fact that they've put that fix in is a really good sign, as it was a pain point I had and they're fixing it now.
Agents also can't add reactions or edit their messages, and so each stage of a build posts a new line in the thread. I've already left a comment on an existing issue asking for this, and others were giving the same feedback.

Each stage of a build is a new line in Rowan's thread, then Sam is told only Rowan or Kash can sign it off
Maybe in a day or so, I won't have to work around the registration key anymore. But right now I've got this set up and it's working, and I'm looking forward to them putting this in so that I don't have to.
Building MemoryWeaver: Claude Code Meets Codex via Switch
From Scattered Memories to a Collaborative AI Travel Journal
What if a group of friends could turn their scattered vacation photos, casual chat messages, and small personal memories into a beautifully designed travel journal—without having to organize everything themselves?
That question inspired me to build MemoryWeaver, a collaborative AI-powered travel journal created for the Flip the Switch Hackathon, Track 2: Best Personal or Creative Workflow.
But MemoryWeaver is more than an AI photo album.
It is an experiment in letting different AI agents work together, with different responsibilities, through a shared workspace. Instead of asking one model to do everything, I connected Claude Code, OpenAI Codex, and specialized workflow agents through Switch, using Mattermost as the place where humans and AI collaborate.
The result is a workflow that turns conversations into a finished travel journal—and lets people improve that journal simply by sending another message.
Try MemoryWeaver
Interactive showcase: winter-unit-6999.tetete-0618.workers.dev
3-minute demo video: youtu.be
GitHub repository: Tetsuya-Uchimura/memoryweaver-stories
The public showcase is a read-only interactive presentation of the travel conversations and generated journals. The actual AI workflow runs locally through Mattermost, Switch, Claude Code, and Codex, as shown in the video.
1. The Problem: Memories Are Scattered
Think about your last trip.
Some memories live in your camera roll. Others are buried in group chats. Someone remembers a funny moment at a café, while another person has the perfect photograph but no written context.
Most of these fragments never become a meaningful story.
Traditional photo albums focus on organizing pictures. Generative AI can write descriptions, but a single prompt often lacks the context behind those pictures.
I wanted to create a different experience:
People share their memories naturally. AI teammates work together to turn those memories into something worth keeping.
This became the central idea behind MemoryWeaver.
2. What MemoryWeaver Does
MemoryWeaver uses Mattermost as the starting point.
Travelers can post photographs, describe experiences, and talk about their trip in a shared conversation.
When they are ready, they ask an AI teammate to create a travel journal.
For example:
@mw-collector Make an English travel journal of our Kyoto trip. Keep all the original memories and photographs.
The system then coordinates a multi-agent workflow.
Collector gathers the original messages, photographs, and available location information.
Claude Code (Storyteller) writes a structured travel narrative grounded in those memories.
OpenAI Codex (Editor) reviews the draft against the original evidence.
Publisher creates the finished web journal and PDF, then delivers them back to Mattermost.
The completed journal includes photographs, chapters, source references, and an interactive location map when coordinates are available.
MemoryWeaver also supports revisions.
A traveler can ask:
@mw-collector Please use the bamboo grove photograph as the cover. Keep the other memories and chapters unchanged.
The AI team processes the request and produces a new version. Previous versions remain accessible.
This creates a collaborative loop between people and AI rather than a one-time generation process.
3. Why I Chose Switch
I could have built a conventional pipeline that calls one model, then another, and passes JSON between them.
But I wanted the agents to behave more like teammates working in a common environment.
Each agent should be able to understand its role, access relevant shared artifacts, and hand work to another agent without relying on a giant application-level prompt.
That is where Switch became central to MemoryWeaver.
I use three important Switch capabilities:
Shared rooms
The agents participate in a collaboration space connected to a Mattermost travel channel. Human requests, progress messages, and agent handoffs belong to the same workflow context.
Shared documents
Instead of passing an entire travel journal through chat messages, agents create and read structured documents for collected evidence, drafts, and reviews.
Targeted messages
Agents can explicitly hand work to the teammate responsible for the next step.
For example, Claude Code can hand a completed draft to Codex for review. Codex can then pass its reviewed artifact to Publisher.
The important distinction is that Switch coordinates the collaboration; Claude Code and Codex perform their own AI reasoning and editorial tasks.
Switch is not simply another text-generation model.
MemoryWeaver architecture: Switch connects Mattermost, Claude Code, Codex, and specialized workflow agents.
4. The Architecture
MemoryWeaver combines local infrastructure, desktop AI agents, and a web-based reading experience.
The main components are:
Component
Responsibility
Mattermost
Human conversations, photographs, instructions, and delivery notifications
Switch
Shared rooms, documents, events, and targeted agent handoffs
Collector
Source gathering, photo handling, and evidence preparation
Claude Code
Travel-story drafting
OpenAI Codex
Editorial review and evidence checking
Publisher
Version storage, web journal generation, PDF creation, and delivery
FastAPI web app
Reading journals, exploring photographs and maps, viewing saved versions
The agent handoff follows this sequence:
Travelers / Mattermost
|
v
Switch
|
v
Collector
| Creates an evidence document
v
Switch shared documents
|
| MW_CONSOLE
v
Claude Code — Storyteller
| Creates a structured draft
|
| MW_DRAFT
v
OpenAI Codex — Editor
| Reviews the source evidence and draft
|
| MW_REVIEW
v
Publisher
|
+--> Versioned web travel journal
+--> Cover preview
+--> PDF
|
v
Mattermost delivery message
In the implemented workflow, the original evidence, draft, and review are separate Switch documents. The next agent retrieves the appropriate document instead of depending on a copied summary of the previous agent's work.
The native Claude Code and Codex sessions run through Switch Console, while the application services run in Docker.
This separation also means the developer's AI-provider authentication does not have to be copied into the application containers.
5. Why Two Different AI Agents?
One of my design goals was to avoid treating every AI agent as interchangeable.
Claude Code and Codex have different responsibilities in MemoryWeaver.
Claude Code: The Storyteller
Claude Code focuses on transforming fragmented memories into a coherent travel narrative.
It receives collected evidence and produces a structured draft containing the story, chapters, selected photographs, and references to source material.
The storytelling task requires creativity, but it also needs boundaries.
For example, if a photograph shows a temple, the model should not invent an emotional conversation or a historical event that was never mentioned by the travelers.
Codex: The Editor
Codex approaches the draft from a different perspective.
It examines whether the story is consistent with the original memories and photographs.
Its review focuses on questions such as:
Are the referenced memories valid?
Are dates and locations supported?
Does a quotation appear in its cited source?
Are photographs associated with the correct memories?
Has the story introduced unsupported details?
This does not guarantee perfect factual accuracy. Human review still matters.
However, separating creative writing from editorial review makes the workflow easier to understand and validate.
Switch: The Connection Between Them
The most interesting part is not simply that Claude writes and Codex reviews.
It is that the handoff happens through Switch.
Collector creates evidence, Claude produces a draft, Codex checks that draft, and Publisher receives the reviewed result.
Each agent works within its own role while sharing the artifacts required for collaboration.
Different AI agents. Different strengths. One shared workspace.
That is the central technical concept behind MemoryWeaver.
6. Making Agent Handoffs Reliable
Connecting multiple agents was one of the most challenging parts of the project.
During development, I discovered that a successful model response does not automatically mean the entire workflow has succeeded.
An agent may produce a draft, but another agent might fail to receive the handoff. A review could reference an outdated draft. A service could restart while a delivery is still pending.
I addressed these problems at several levels.
Structured artifacts and explicit references
Each stage uses a structured document with defined fields.
The review refers to the specific draft and evidence associated with the current job.
Publisher validates document references, hashes, source citations, and other constraints before accepting the reviewed result.
Verifying the actual sender
A message that merely contains the text MW_REVIEW should not be trusted as an authentic editor handoff.
MemoryWeaver checks the authoritative participant information supplied by Switch, rather than treating an arbitrary message prefix as proof of agent identity.
Keeping previous versions
When someone requests an edit, MemoryWeaver creates a new journal version instead of overwriting the old one.
This makes it possible to compare a cover change and verify that unrelated chapters and photographs were preserved.
Handling partial failure
The workflow tracks processing and delivery state, including attempts to resend saved PDF artifacts.
There are still MVP limitations: interrupted handoffs may require a fresh request, and the system is not a general-purpose distributed transaction engine.
Being explicit about those limitations helped me build a more understandable system.
7. From AI Output to a Beautiful Product
A technically interesting agent system is not enough if the final result feels like raw model output.
I wanted the travel journal to feel like a finished creative artifact.
An example of a finished MemoryWeaver travel journal.
MemoryWeaver supports destination-specific visual styles.
Kyoto uses a quiet, editorial design inspired by Japanese travel journals, with restrained typography and bamboo photography.
Paris uses a more magazine-like editorial presentation.
New York uses a contemporary urban visual style.
The MemoryWeaver travel journal experience.
The travel journals combine text, photographs, location information, and PDF output.
When location coordinates are supplied, the browser can also display an interactive OpenStreetMap-based map with markers associated with the source photographs.
Importantly, the map does not automatically invent locations from pictures. Fictional sample locations are labeled as approximate landmarks rather than original camera GPS positions.
The goal is to keep the output visually compelling without losing track of where the information came from.
8. Human-in-the-Loop Editing
One of my favorite parts of MemoryWeaver is the editing experience.
Instead of opening a complex editor and manipulating layouts manually, a traveler sends a natural-language request in Mattermost.
For example:
Please change the cover to the bamboo grove photo, but keep every other memory and chapter unchanged.
That request enters the same collaborative workflow.
The agents inspect the existing journal, prepare the requested change, review it, and deliver a new version.
I tested this experience with a Kyoto journal. The live Claude Code → Codex → Publisher workflow produced saved editions, and the cover was updated while preserving the underlying memories and chapter content.
This is where the multi-agent system becomes something people can actually experience.
Users do not need to understand the internal architecture to collaborate with the agents.
They simply describe what they want to change.
9. Testing and Reproducibility
For a hackathon, I believe reproducibility is part of the product.
A demo video alone cannot show whether a system is reliable.
MemoryWeaver includes a Docker-based development environment with Mattermost, Switch, the web application, and supporting services.
The project pins the Switch server to a specific upstream source revision, helping prevent unexpected changes between installations.
The official Switch Console manages the local Claude Code and Codex sessions.
A fresh installation generates its own local credentials rather than shipping the developer's passwords or provider tokens.
The project also includes deterministic replay fixtures so the infrastructure and UI can be tested without making live AI requests.
The distinction between LIVE AI and REPLAY DEMO is visible in the application.
At the time of this article, project verification included:
77 passing Python tests
22 passing desktop/mobile Chromium browser tests
Real Claude Code → Codex → Publisher handoffs tested through Switch Console
PDF and cover attachments checked against saved artifacts
Fresh Docker environment testing
Explicit documentation of remaining setup and deployment limitations
The complete test history and limitations are documented in the repository's docs/VERIFICATION.md.
A fully fresh native-agent setup on a second physical machine remains unverified. Using the real providers also requires individual authentication and manual Switch Console agent registration.
I prefer to document these requirements rather than imply the entire AI environment starts automatically with one command.
10. A Public Showcase Without Exposing the Private Workflow
MemoryWeaver is designed around personal memories, so privacy matters.
The local application is not a production-ready multi-user hosting service, and its internal Switch and Mattermost endpoints should not be exposed directly to the public internet.
For the hackathon, I created a separate interactive showcase hosted on Cloudflare.
It lets visitors explore a read-only representation of the travel conversations and completed journals without needing an account.
The public showcase does not run Claude Code, Codex, or Switch inference.
Instead, it illustrates the experience using selected fictional sample data and saved results.
That distinction is important.
The public showcase demonstrates the user experience. The local workflow and video demonstrate the actual AI collaboration.
The sample photographs are credited separately in docs/PHOTO-CREDITS.md, with attribution and license details. The source-code license does not replace the individual photo licenses.
11. How to Run MemoryWeaver
Developers who want to explore the workflow can start with the GitHub repository:
Tetsuya-Uchimura/memoryweaver-stories
The Docker environment can be started with:
cd memoryweaver-stories
python3 scripts/dev.py up
python3 scripts/dev.py status
A sample replay experience can then be prepared with:
python3 scripts/dev.py seed --all --generate
The local services use these default addresses:
Service
URL
Mattermost
localhost
Switch Gateway
localhost
MemoryWeaver web app
localhost
The replay experience uses deterministic sample content and does not require AI-provider authentication.
For a real Claude Code and Codex collaboration, install Switch Console, authenticate both providers, register the Storyteller and Editor agents, and bind them to MemoryWeaver.
The repository README and docs/CONSOLE.md document these steps in detail.
12. What I Learned
Building MemoryWeaver changed how I think about AI agents.
At first, I was focused on what AI could generate.
As the project evolved, I became more interested in how different agents could collaborate reliably.
Three lessons stood out.
Shared context is more valuable than longer prompts
The agents work better as a system when they can access clearly defined evidence, drafts, and reviews instead of reconstructing everything from a large conversation.
Specialization makes responsibilities visible
Separating writing, fact-checking, collection, and publishing gives the workflow clearer boundaries.
When something goes wrong, it is easier to understand which stage needs attention.
AI collaboration should remain connected to human intent
The finished artifact matters, but the ability to request corrections and preserve previous versions matters just as much.
MemoryWeaver is not about replacing human memories with AI-generated stories.
It is about helping people turn their own memories into something meaningful.
13. What's Next?
There are several directions I would like to explore after the hackathon.
First, I want to simplify the initial Switch Console setup so new users can start collaborating with AI agents more easily.
Second, I want to support more flexible travel groups and permission models, rather than relying on a predefined set of sample rooms.
Third, I want to improve the editorial workflow with clearer human review checkpoints and richer collaborative feedback.
And finally, I would like to explore other creative workflows beyond travel: family history, shared event journals, project retrospectives, and collaborative storytelling.
The underlying idea is the same.
Take information that already exists in human conversations, let specialized agents work together on it, and create something useful without losing the original context.
Final Thoughts
MemoryWeaver started with a simple frustration: our memories are scattered across photographs and conversations.
Switch made it possible to approach this as a collaboration problem rather than just a text-generation problem.
Claude Code writes. Codex reviews. Collector organizes. Publisher delivers. And humans remain part of the process through Mattermost.
The result is a travel journal, but the more interesting achievement is the workflow behind it.
Different AI agents. Different strengths. One shared workspace.
That's what I wanted to build with MemoryWeaver.
Links
Interactive showcase: winter-unit-6999.tetete-0618.workers.dev
Demo video: youtu.be
Source code and setup: Tetsuya-Uchimura/memoryweaver-stories
Switch: sandbox-quantum/switch
Built for the Flip the Switch Hackathon — Best Personal or Creative Workflow.
Huge props to sandbox-quantum for building such a clean, self-hosted architecture that drops AI teammates right into your chat. Seriously slick workflow for bringing any model to Slack and Discord. 🚀
🔗 项目地址:sandbox-quantum/switch
1 like · 12 views
How I Used Switch to Build an AI Playtest Team for Board Games
If you design board games, you know the problem. A bad rule can hide for months, because getting people around a table is hard, and getting them there ten times is harder.
For the Flip the Switch hackathon, my team built Boardgame Lab. You paste your game's rules into a chat, and an AI engineer asks about anything unclear and builds the game. AI players play it, an AI analyst measures what happened, and only you can change the rules.
On its first run with a game we hadn't tuned, it found that the player who goes first won only 28.1% of random games, against about 36% for the other two. Nobody planted that problem. We didn't know it was there.
Why not just ask one AI to play all the seats?
That was my first thought too, but it doesn't work for most card games. One AI playing every seat sees every hand, so nobody is really bluffing or guessing. You need separate players who can't see each other's cards, and you need to be able to watch them play. Switch gave us both.
What Switch is, for first-timers
Switch is open-source software that puts AI agents into chat apps. Each channel becomes a room, and agents join it like any other team member. You only need four of its ideas for this project:
- A room decides who can see what. An agent only sees rooms it belongs to.
- An agent can be an AI coding tool, such as Claude Code or Codex, or your own code connected through Switch's agent protocol.
- A role lets you call a job instead of a person, such as @balance-analyst.
- A template is one file that creates a whole team of agents and rooms in one go.
What we built
There's one public room and three private ones. lab-table is the public table, where everyone including you can see moves get revealed, and where you make decisions. lab-seat-1, lab-seat-2 and lab-seat-3 are private rooms, each with one AI player and the referee. You're in those too, so you can watch.
The team has three AI players (Hawk, Patient and Gambler), a Rules Engineer and an Analyst. The referee isn't AI. It's about 550 lines of plain Node.js, so it can't be talked into bending a rule.
lab-table (public)
everyone sees moves and decisions
|
REFEREE
plain code
/ | \
lab-seat-1 lab-seat-2 lab-seat-3
Hawk only Patient only Gambler only
You can see all of these rooms. A player can only see the table and its own seat.
Hawk gets its hand in its own room, and no other player can read it:
!The referee deals Hawk a private hand of 4, 8 and 11 in the lab-seat-1 room
How to set it up
You need Switch Console, Docker Desktop, Node.js 22.9 or newer, and Claude Code or Codex signed in. We tested on Windows only.
The agents run on your own Claude or Codex plan, so games use up your plan's limits. I hit my Claude Pro limit while rehearsing, so keep your first tests small.
1. Start a server. Open Switch Console. On the first screen, choose On this computer. If you've already set up Console, it's called Run a server on this computer in the Add server dialog. Then, with Docker running, turn on Mattermost under Admin → Status. Mattermost is the chat app you'll use.
2. Connect the referee. Clone the repo and run this once. Your server has to be running first:
npm run referee:register
You'll know it worked when it prints Registered, followed by the referee's name and where its key is saved. Now start the referee, and leave this window open:
npm run referee
You'll know it worked when it prints Connected as. The referee won't be listed under Your Agents, because that list only shows agents Console runs itself.
3. Import the template. Go to Templates → Import template and choose templates/boardgame-lab.template.yaml. Set Repository folder to your clone. The Playtest name is added to the start of every room name, and I'm using lab in this post, so a different name gives you different room names. Select Create all once, and give it a few minutes.
4. Start a game. Under Rooms in the left menu, open lab-table. The referee starts on our test game, Salt Run. Type this whole line in one go:
@boardgame-referee deal 7
You'll know it worked when the referee posts Game 1 (seed 7) and the game's rules at the table. The number is a seed, so the same number deals the same cards. The agents then play in their private rooms, and moves appear at the table. A game takes about 3 minutes.
A real run
We pasted in a short rulebook for a card game called Ember Line, which we hadn't tuned or planted anything in.
Before building anything, the engineer asked three questions, including one we hadn't thought of: "If you play a card lower than the last card, and that last card was yours, do you still give yourself the 3 points?" Then it wrote the game.
A checker, also plain code, tested the result. It plays 300 random games and rejects any game that crashes or never ends. It also scrambles the other players' secret cards and checks that a player's view doesn't change, which proves the game doesn't leak anyone's hand.
After the players finished, the analyst turned what it saw into a strategy and ran 10,000 simulated games per strategy. It also spotted a problem we didn't know about: the player who goes first won only 28.1% of random games, against about 36% for the other two.
!The analyst's report: its holdopen strategy at 47.2%, and seat 1 at 28.1% under random play
I told the engineer, in plain words, to make a new version where whoever opens scores a flat 3 points. Then I loaded it, and the referee compared both versions:
!The referee loads ember-line-v2, passes the checker, shows a sample game and posts a before-and-after table
The seats went from 28.1%, 35.6% and 36.2% to 32.4%, 34.1% and 33.5%, and a fair share is 33.3%.
The fix has a cost, though. The climber strategy went from 44.5% to 48.6%, close to the 50% line where we'd call a strategy broken. Whether that's acceptable is a design decision, so the tool leaves it to a person.
How Switch does the hard parts
A template creates the whole team. This is a private seat room, trimmed down. The private channel and the short list of agents keep a hand secret:
- name: "{team}-seat-1"
description: Hawk's private seat
channel_type: channel_private
agents: ["{referee}", "{team}-hawk"]
users: ["{$creator}"]
Your own code can be an agent too. The referee connects over a WebSocket and answers Switch's pings, then gets each message as an event. To reply, it sends a normal HTTP request:
const say = (roomId, content) =>
request(key, 'POST', `/agents/${id}/message`, { room_id: roomId, content });
My favourite part is checking who's really talking. An agent's sender name is always its fixed identifier, so it can't pretend to be a person. That lets a few lines of code enforce "only a human can change the rules":
const isPerson = async (roomId, senderName) => {
const everyone = await participants(roomId);
return (
everyone.some((p) => p.type === 'user' && p.name === senderName) &&
!everyone.some((p) => p.type === 'agent' && p.name === senderName)
);
};
We tested this in a live game by telling the analyst to send a rule change itself. The referee refused.
What went wrong, and what I learned
To test the idea, we wrote a game called Salt Run and deliberately planted a bad rule. The first two we tried didn't break the game when we measured them, so I was simply wrong about what was unbalanced. The third, a final round worth triple, worked: saving your best card won 65.1% of games. Changing it to ×1.5 brought that down to 45.5%.
I built this with Claude Code. The most useful habit, for the agents and for me, was "never state a number you didn't run", which is written into the analyst's instructions. When our engineer finished the fix, it said it hadn't checked if the seats had evened out, and I trust a tool more when it tells me that.
If something breaks
- A command gets no reply: picking a name from the Mattermost popup, or editing a message afterwards, lost our command text. Retype the whole line in one go, using the full handle @boardgame-referee, not the display name @Referee.
- The message shows in Mattermost but never reaches the referee: this happened to me once, with no error in the log, and I still don't know why. The referee's window prints every message it receives, so check there, then send it again.
- Create all says "Nothing was created": this can be wrong. A teammate saw it while the team was being created. Wait a few minutes and check your rooms before you retry, or you'll get "already exists" errors, or a second team.
- Agents remember an earlier game: for a clean test, import the template again with a new Playtest name, which gives you fresh agents.
- Chat stops working: check Docker, because Mattermost runs through it. When Docker restarted, the Mattermost container stopped, even though Console still showed it as running. Starting the container again fixed it.
- You want to use Codex: on Windows, Switch Console 0.40.1 couldn't fill in a provider field in a template, so ours names claude directly. Change it to codex and delete the model lines. A teammate ran the whole thing that way on a second computer, and got the same seat numbers for Ember Line.
What it can't do
It can't tell you if your game is fun, so you still need real players. It only handles small games: 2 or 3 players, with rules that fit in one chat message. Strategies are measured against simple bots, and those don't adapt the way real opponents do.
Privacy is per room, and it doesn't extend to the computer. All the agents run on one machine, so a player could read local files if it ignored its instructions.
Try it
Boardgame Lab is free and open source: sudu787/boardgame-lab. The README has every command, and examples/ember-line.md is a ready-made rulebook to paste in. Please use your own rules, or a designer's with their permission, and not a published game.
4 reactions
@kunalstwt @WeMakeDevs @WeAreDevs perfect, then it's whatsapp-first. forward the "sent you 500" messages to a bot, it keeps the ledger and tells everyone who owes whom at the end.
already wired whatsapp + twilio in my oss PRs, so this one's happening
switch#1166
switch#1244
13 views
团队散在 Slack、Teams,AI 队友各聊各的?
switch 是自托管 AI 队友平台:每个频道变成人和 agent 同房间,共享上下文,换 agent、换模型都不丢。
多平台协作的话,同房间共享上下文比来回转发强。
先把它接进哪个频道,是 Slack 还是 Teams?
#AI队友 #开源@grok
sandbox-quantum/switch
5 likes · 286 views
Agents 2.0 is here!
Master Full-stack AI Engineering
In today's newsletter:
- This inference engine runs LLMs 4x faster than llama.cpp.
- Agents 2.0 is here!
- Continuous batching in LLMs, explained visually.
TODAY'S ISSUE
OPEN-SOURCE
This inference engine runs LLMs 4x faster than llama.cpp:
We ran Qwen3.5 9B on a base M5 MacBook Pro using three local inference engines, one at a time.
- llama.cpp reached 22.0 tokens/s
- MLX reached 25.1 tokens/s
- Uzu reached 92.1 tokens/s
The video shows all three runs side by side.
The first two results do not mean llama.cpp or MLX are poorly optimized. Both are approaching a physical limit of ordinary local decoding.
Generating each new token normally requires another pass through the model. That pass streams roughly 5.2 GB of weights through memory.
A base M5 provides about 153 GB/s of memory bandwidth.
At one token per pass, the theoretical ceiling is roughly 153 ÷ 5.2, or 29 tokens/s, however fast the GPU computes.
Uzu gets past that by optimizing speculative decoding for Apple Silicon.
Speculative decoding uses a smaller drafting system to propose several future tokens. The full 9B model then checks those proposals together instead of generating every token through a separate pass.
Uzu pushes this further in two ways.
→ It drafts up to 16 positions and uses Weaver to turn independent guesses into coherent sequences.
→ It verifies several possible sequences as a tree, then commits state only for the path the full model accepts.
The 9B model remains in control of the final output. Uzu simply gives it more useful work to approve in each pass.
In our run, every pass of the 9B model produced 7.5 output tokens on average.
Ordinary decoding produces exactly 1.
That is how Uzu reached 92.1 tokens/s on hardware whose one-token-per-pass ceiling is roughly 29.
The rest of the engine is designed around this path too. Uzu ships its own quantized checkpoints, and on M5 chips its Metal kernels run verification through the GPU’s accelerated int8 matrix path.
It is an open-source inference engine with bindings for Rust, Swift, Python, and TypeScript.
The repository is here: trymirai/uzu
(don't forget to star 🌟)
TOGETHER WITH SWITCH
Agents 2.0 is here!
Anthropic. OpenAI. xAI.
Are all racing to build an AI coworker.
These are agents that can work alongside humans, talk to other agents, and coordinate tasks in a shared workspace.
But the catch is that each product ties the model, runtime, memory, and orchestration to one company’s stack.
Most teams won’t use one provider for every job. They may use Claude Code, Codex, OpenCode running locally, and custom agents for internal systems. Making them collaborate with each other and your team usually means building the glue yourself.
That is vendor lock-in.
In the video above, we have shown how to bring humans and agents from different providers into one shared workspace using an open-source coordination layer you can host yourself.
Humans can talk directly to agents. Agents can talk to each other. And people can join the conversation, add context, or give further instructions as the work unfolds.
The project is called Switch, and it brings this collaboration into Slack, Teams, Discord, Telegram, or Mattermost.
You give each agent a role and can work through a Manager. The Manager creates rooms, brings in the relevant agents, carries context between them, and returns the result.
In the video below, we gave the Manager two incidents.
→ The inference API started returning 500s after a morning deploy
→ A recommendation-model training job had been frozen for six hours
From one message, it created two linked rooms, brought in a Software Engineer, Architect, and QA Lead, and ran both investigations in parallel.
Then the engineer investigating the training failure checked the linked inference room and spotted the same config push behind both failures.
The Manager returned one consolidated RCA to the original channel.
Throughout the run, we could follow the conversations, give additional instructions, and inspect the underlying agent sessions in Switch Console.
That is what we mean by Agents 2.0. Humans and agents working together, sharing context, and contributing as the work unfolds.
We build everything locally with Docker and Mattermost and follow the run through to the final handoff.
Models will keep changing, so the coordination layer should be able to run separately from any one provider.
GitHub: sandbox-quantum/switch
(don’t forget to star 🌟)
LLMOps
Continuous batching in LLMs, explained visually:
In traditional ML inference, a batch is a matrix.
Every input is padded to the same length, one forward pass runs, and every row finishes at the same moment.
LLM decoding does not work that way.
One forward pass produces one token per sequence, so a request needs as many passes as it has output tokens, and nobody knows that count until the model emits a stop token.
Under static batching, membership is fixed when the batch starts.
A request that finishes in 30 tokens holds its slot until the slowest request in the same batch finishes at 400.
The GPU keeps paying the full weight read for a batch that is mostly empty.
Loading model weights out of HBM costs the same whether four slots are producing tokens or one.
Continuous batching moves the decision boundary.
Instead of scheduling once per batch, the scheduler runs a single forward pass, gets control back, and decides again.
A finished request leaves at the next iteration boundary, and a queued request takes its slot right there. No slot stays reserved for work that is already done.
Anyscale benchmarked both OPT-13B on a single A100.
With uniform generation lengths, the two policies came out about level (as expected), and as output length variance rose, static batching fell to around 81 tokens per second while vLLM reached 23x the throughput of naive Hugging Face serving.
Variance drives the entire gap.
Production traffic mixes 30-token replies with 400-token ones, which is exactly the condition static batching handles worst.
None of this alters the model.
vLLM, SGLang, TGI, and TensorRT-LLM all run it by default, and NVIDIA implements the same mechanism under the name in-flight batching.
The animation below depicts the continuous batching process:
To dive deeper into continuous batching specifically, we wrote a full breakdown of the scheduler underneath it.
It covers what happens between two forward passes, how tokens get handed out against a fixed budget, why the scheduler needs no separate path for prefill and decode, and what preemption costs you when the KV cache fills up mid-generation.
Read it here →
THAT'S A WRAP
NO-FLUFF RESOURCES TO...
Succeed in AI Engineering roles
All businesses care about impact. That’s it!
- Can you reduce costs?
- Drive revenue?
- Can you scale ML models?
- Predict trends before they happen?
We have discussed several other topics (with implementations) in the past that align with such topics.
Master full-stack AI engineering
Here are some of them:
- Learn MLOps from first principles to production in this course with 18 parts →
- Learn everything about MCPs in this course with 9 parts →
- Learn how to build Agentic systems in this course with 14 parts.
- Learn how to build real-world RAG apps, evaluate, and scale them in this course.
- Learn sophisticated graph architectures and how to train them on graph data in this course.
- So many real-world NLP systems rely on pairwise context scoring. Learn scalable approaches here.
- Learn how to run large models on small devices using Quantization techniques.
- Learn how to generate prediction intervals or sets with strong statistical guarantees for increasing trust using Conformal Predictions.
- Learn how to identify causal relationships and answer business questions using causal inference in this course.
- Learn how to scale and implement ML model training in this practical guide.
- Learn techniques to reliably test new models in production.
- Learn how to build privacy-first ML systems using Federated Learning.
- Learn 6 techniques with implementation to compress ML models.
Master full-stack AI engineering
All these resources will help you cultivate key skills that businesses and companies care about the most.
Partner with US
ADVERTISE TO 950k+ AI Professionals
Our newsletter puts your products and services directly in front of an audience that matters, including thousands of leaders, senior data scientists, machine learning engineers, data analysts, etc., around the world.
Get in touch today by replying to this email.
Today’s email was brought to you by Avi Chawla and Akshay Pachaar.
Looking for more? Unlock our premium DS/ML resources.
© 2026 Daily Dose of Data Science
Mentions
From 68-Day MTTR to 2 Minutes: How We Built an Autonomous DevSecOps Squad in Discord with Switch and Wispr Flow By Ayush Kumar • Built for the Flip the Switch Hackathon hosted by @WeMakeDevs in partnership with @SandboxAQ (Switch) & @WisprFlow !Image description !Image description !Image description > Featured Technologies & Partners: > 🏢 @SandboxAQ (#SandboxAQ #SwitchAI #HowISwitch) — Multi-Agent Protocol & Room Orchestration > 🎙️ @WisprFlow (#WisprFlow #CodeWithWispr) — Sub-second Voice Dictation & Intent Parsing > 🌐 @WeMakeDevs (#WeMakeDevs #FlipTheSwitch) — Open Source Developer Community & Hackathon Host --- 🚨 The 68-Day Security Bottleneck In modern software engineering, vulnerability detection is a solved operational discipline. Static Application Security Testing (SAST) and Software Composition Analysis (SCA) tools fire thousands of automated alerts into GitHub, Jira, and Slack every week. Yet across enterprise engineering teams, the average Mean Time to Remediate (MTTR) still hovers at a staggering 68 days. Why does it take over two months to patch a known SQL injection, command injection, or path traversal vulnerability? Because security remediation is completely fragmented: 1. An alert fires in Sentry, Datadog, or GitHub Dependabot. 2. An on-call engineer gets paged, context-switches out of deep work, and struggles to parse static logs. 3. They jump into Slack asking: "Who owns this microservice? Did anyone touch app.py in last week's release?" 4. A security engineer opens a static analyzer to trace whether untrusted user input actually reaches an execution sink. 5. A developer drafts a patch, but is terrified of breaking production business logic or causing formatting drift. 6. The PR sits in code review purgatory for weeks waiting for QA and security sign-off. The Cost of Delay: "Black October" & The $6.3B Binance Heist Attackers do not wait 68 days. In late October 2026, the tech ecosystem experienced "Black October"—a synchronized wave of vulnerabilities striking across five distinct layers of the software stack: - Web Servers: Critical unauthenticated RCEs in PHP CGI parameter handling (PHP2Shell, CVE-2026-109618/19). - AI Tooling: A backdoored release of LiteLLM (>v1.107.0) silently exfiltrating model provider API keys. - Cloud Infra: Platform misconfigurations on Railway exposing customer environment variables and GitHub tokens. - Developer Supply Chains: The catastrophic $6.3 Billion Binance Developer Environment Heist, where state-sponsored actors (DPRK TraderTraitor) targeted engineers with trojanized coding assignments, executing locally and pivoting laterally into internal wallet signing systems. !Black October 2026 Threat Wave We asked ourselves a radical question for the @WeMakeDevs Flip the Switch Hackathon: > What if your security operations squad wasn’t a fragmented external silo, but an autonomous engineering team living directly inside your team chat, summoned by voice, and bound by mathematical proof? Meet VAYU OS — an Autonomous Cyber Reasoning System (CRS) powered by @SandboxAQ Switch and @WisprFlow. --- 🧠 Meet the Squad: 3 Autonomous Teammates via @SandboxAQ Switch Rather than relying on a single, monolithic LLM chatbot that attempts to do everything (and inevitably hallucinates), VAYU OS separates responsibilities across three specialized autonomous agents coordinated via the Switch Agent Protocol from SandboxAQ: # switch/templates/vayu-secops.template.yaml version: "1.0" team: "vayu-secops" agents: - name: "vayu-analyst" description: "Deep AST taint flow investigator and exploit reproduction specialist." addressing: anyone - name: "vayu-remediator" description: "Autonomous patch synthesis and 4-gate sandbox verification engineer." addressing: owner-agents - name: "vayu-gatekeeper" description: "Security policy enforcer and human-in-the-loop release gatekeeper." addressing: anyone room: name: "security-incidents" bridge: "discord" ┌────────────────────────────────────────────────────────────────────────┐ │ VAYU OS SQUAD TOPOLOGY │ ├─────────────────┬──────────────────────────────────────────────────────┤ │ 🔍 @vayu-analyst│ • Ingests Semgrep SAST alerts & walks AST taint flows│ │ │ • Formulates deterministic reproducer test cases │ │ │ • Wraps untrusted code in Prompt Firewalls │ ├─────────────────┼──────────────────────────────────────────────────────┤ │ 🛠️ @vayu-remed │ • Synthesizes minimal indentation-locked line diffs │ │ │ • Runs 4-gate fail-closed verification in KVM sandbox│ │ │ • Generates in-toto SLSA Level 3 ECDSA attestations │ ├─────────────────┼──────────────────────────────────────────────────────┤ │ 🛡️ @vayu-gate │ • Enforces Human Release Gate: AI never self-merges │ │ │ • Listens for human authorization (/approve <id>) │ │ │ • Cuts release branches & opens verified GitHub PRs │ └─────────────────┴──────────────────────────────────────────────────────┘ --- 🎙️ Voice-to-SecOps with @WisprFlow During high-stress cybersecurity incidents, typing complex CLI commands with dozens of flags creates cognitive friction. By integrating Wispr Flow (#WisprFlow #CodeWithWispr), incident commanders and developers simply speak naturally into their microphone: > "Vayu, audit our payments repository for SQL injection and prepare a patch." Wispr Flow captures technical terminology with zero acoustic hallucination and normalizes natural human speech into structured security dispatch intents: // Normalized dispatch payload emitted from Wispr Flow { action: "AUDIT_AND_REMEDIATE", target_repository: "payments-service", vulnerability_class: "CWE-89: SQL Injection", caller: "Ayush (Incident Commander)", dispatch_channel: "switch://rooms/security-incidents" } Within 500 milliseconds, SandboxAQ Switch broadcasts the dispatch across our Discord and web incident channels, kicking off the autonomous remediation loop. --- 🛡️ The 4-Gate Fail-Closed Verification Sandbox Generative AI should never be allowed to approve its own code modifications. A patch might look plausible to an LLM while introducing subtle indentation bugs, breaking unrelated unit tests, or failing to neutralize the actual exploit. VAYU OS formalizes vulnerability remediation as an autonomous cybernetic feedback loop: $$\textbf{FIND} \xrightarrow{\text{SAST}} \textbf{REASON} \xrightarrow{\text{AST Taint}} \textbf{PATCH} \xrightarrow{\text{Indentation Lock}} \textbf{VERIFY} \xrightarrow{\text{4-Gate Sandbox}} \textbf{SIGN} \xrightarrow{\text{SLSA Provenance}}$$ PROPOSED PATCH DIFF │ ▼ ┌──────────────────────────────────────────────┐ │ Gate 1: AST Syntax & Indentation Lock │ └──────────────────────┬───────────────────────┘ │ [PASS] ▼ ┌──────────────────────────────────────────────┐ │ Gate 2: Functional Regression Test Suite │ └──────────────────────┬───────────────────────┘ │ [PASS] ▼ ┌──────────────────────────────────────────────┐ │ Gate 3: Exploit Neutralization Replay │ └──────────────────────┬───────────────────────┘ │ [PASS] ▼ ┌──────────────────────────────────────────────┐ │ Gate 4: Semgrep AST Cleanliness Rescan │ └──────────────────────┬───────────────────────┘ │ [PASS] ▼ VERIFIED ➔ IN-TOTO SLSA LEVEL 3 SIGNED Every candidate patch is executed inside an ephemeral DigitalOcean KVM microVM (isolated network boundary, in-memory Ed25519 tunnels, and a 10-minute self-destruct TTL). If even a single gate fails, the patch is discarded fail-closed—the target repository remains 100% byte-for-byte untouched. The Indentation Lock & Minimal Edit Boundary To prevent the LLM from rewriting entire files or hallucinating indentation drift (a fatal flaw in Python and YAML), VAYU enforces an Indentation Lock (Invariant I2): def apply_indentation_lock(original_line: str, proposed_line: str) -> str: """Extracts exact leading whitespace from AST target node.""" indentation = original_line[:len(original_line) - len(original_line.lstrip())] return f"{indentation}{proposed_line.strip()}" --- ⚡ The Full Incident Lifecycle in 120 Seconds Here is the exact transcript from our live Discord incident room running on SandboxAQ Switch: 👨💻 Ayush (Incident Commander): @vayu-analyst investigate samples/vulnerable/command_injection 🔍 @vayu-analyst: ### 🔍 VAYU-Analyst Investigation Report • Issue ID: VAYU-108 | Severity: HIGH | CWE: CWE-78: Subprocess Shell True • Affected File: samples/vulnerable/command_injection/app.py:261 • AST Taint Flow: app.py:176 (_initialize_schema) ➔ app.py:261 (subprocess.run) • Root Cause: User input concatenated directly into subprocess.run(shell=True). 👉 Handoff: Delegating patch synthesis to @vayu-remediator. 🛠️ @vayu-remediator: ### 🛠️ VAYU-Remediator Patch & Verification Report • Issue ID: VAYU-108 | Target: app.py @@ -261,1 +261,1 @@ - subprocess.run(command, shell=True, check=False) + subprocess.run(command.split(), check=False) 🛡️ 4-Gate Fail-Closed Sandbox Verification Results: [Gate 1] AST Compilation & Syntax: ✅ PASS [Gate 2] Functional Regression Suite: ✅ PASS (0 regressions) [Gate 3] Exploit Neutralization Replay:✅ PASS (Payload neutralized) [Gate 4] Semgrep Static Rescan: ✅ PASS (Clean) 📜 SLSA Level 3 Provenance: sha256:9f5d307bc022ee24... (ECDSA P-256 Signed) 👉 Human Action Required: @Ayush Reply /approve VAYU-108 to authorize release. 👨💻 Ayush: /approve VAYU-108 🛡️ @vayu-gatekeeper: ### 🚀 VAYU-Gatekeeper Release Complete • Issue ID: VAYU-108 — Status: RESOLVED & MERGED • Authorized By: Ayush (Role: Incident Commander) • Remediation Branch: vayu-fix/vayu-108-cwe78 • Verified Patch Committed with Cryptographic SLSA Provenance Attestation • GitHub Pull Request: https://github.com/ayushkumar2601/vayucs/pull/42 🎯 MTTR Outcome: Resolved, verified, and shipped in 2 minutes! --- 🎨 Linear-Grade Command Center While the agents collaborate in Discord via Switch, our Next.js 16 Web Command Center streams real-time updates over Server-Sent Events (SSE): - /issues: A keyboard-first Linear-style triage board tracking each finding from INVESTIGATING to DONE. - /reviews: A split-diff code review console displaying the exact AST taint graph, before/after diffs, and verification logs. - /pulse: Live agent heartbeats, CPU/memory allocations, and cloud KVM sandbox telemetry. 👉 Check out the live deployment: vayu-switchup.vercel.app --- 🤝 Giving Back: 10 Upstream PRs to Switch Core In the open-source spirit championed by @WeMakeDevs, we didn't just build on top of @SandboxAQ Switch—we actively contributed back to it. To expand Switch's provider connectivity, we authored and submitted 10 production-grade pull requests to sandbox-quantum/switch core: 1. PR #1630 — Mistral Vibe Provider (Issue #774, P0) 2. PR #1644 — Qwen Code Provider (Issue #782, P1) 3. PR #1645 — Grok Build Provider (Issue #775, P0) 4. PR #1646 — JetBrains Junie Provider (Issue #787, P1) 5. PR #1647 — Cloudflare Service Connector (Issue #828, P2) 6. PR #1652 — Cline CLI Agent Provider (Issue #784, P1) 7. PR #1653 — Goose Agent Provider (Issue #780, P1) 8. PR #1654 — Auggie Agent Provider (Issue #785, P1) 9. PR #1655 — OpenHands Agent Provider (Issue #786, P1) 10. PR #1656 — GitLab Service Connector (Issue #816, P1) --- 💡 Key Architectural Takeaways 1. Multi-Agent Teaming Beats Monolithic Chatbots: Dividing security engineering into an Analyst, a Remediator, and a Gatekeeper mirrors real human organizations and eliminates hallucinated self-approvals. 2. Determinism is Non-Negotiable: Use AI for heuristic generation (proposing a 1-line string replacement), but use deterministic tools (AST compilers, regression suites, Semgrep) for verification. 3. Voice Eliminates Cognitive Friction: Wispr Flow makes security response hands-free and lightning-fast. 4. Put Agents Where Engineers Live: SandboxAQ Switch's genius is meeting developers in Discord and Slack rather than forcing them into another siloed dashboard. --- 🏷️ Companies, Tags & Community Mentions - Organization & Community: @WeMakeDevs • wemakedevs.org - Agent Protocol: @SandboxAQ • sandboxaq.com - Voice AI: @WisprFlow • wisprflow.ai - Hashtags: #HowISwitch #FlipTheSwitch #WeMakeDevs #SandboxAQ #WisprFlow #CodeWithWispr #DevSecOps #AI #CyberSecurity #OpenSource --- 🔗 Explore VAYU OS - 🎥 Watch the Full Demo Video (2m 46s): YouTube Link - 💻 Star the Repository: GitHub (ayushkumar2601/vayu_switchup) - 🌐 Experience the Web App: vayu-switchup.vercel.app Built with ❤️ for the Flip the Switch Hackathon by Ayush Kumar.
Refund Court: How Two Beginners Turned a Chat Room into a Courtroom with Switch AI agents argue refund disputes. A human decides. Every verdict becomes precedent. Hi! We're Roshanlal Maddheshiya and Arpita Thakur. We're still pretty new to AI, and this was the first time either of us built anything with AI agents. When we saw the Flip the Switch Hackathon by @WeMakeDevs and @DevTools Academy, we wanted to try something that felt like a real business problem, not just another chatbot. That's how Refund Court happened: four AI agents and one human sorting out refund disputes together inside a single team chat, using Switch. - GitHub: EC-Roshan/refund-court - Demo video: youtu.be Why we picked this problem If you've ever ordered from Blinkit, Zepto or Amazon, you've probably raised a refund request at some point. "Two items were missing." "My order came really late." On the other side, a support person has to decide: refund or not, and how much? Here's the thing we kept thinking about. Two people can look at the exact same complaint and make two different calls. One approves a full refund, the other rejects it. And nobody remembers what was decided last week. That's money lost for the company and frustration for the customer. The idea: what if every dispute got its own little courtroom? We imagined a court case. Someone checks the facts. One side argues for the customer, the other side argues for the business. A human listens and makes the call. And every decision gets written down, so the next similar case can be judged the same way. So we set up one Switch room on Mattermost and gave four agents one job each: | Agent | What it does | |---|---| | case-clerk | Reads orders.csv and customers.csv and only states the facts | | customer-advocate | Speaks up for the customer, quoting rule numbers from our refund policy | | company-advocate | Looks out for the business: fees, refund limits, signs of fraud | | precedent-keeper | Looks through verdicts.md for similar past cases and records new verdicts | And then there's us, the Support Lead, playing the judge. The agents can argue all they want, but only a human gets to decide. How a hearing actually runs Support Lead: "@case-clerk Dispute on Order #1043: 2 items missing" -> case-clerk posts the facts -> passes it to customer-advocate -> customer-advocate makes its case -> passes it to company-advocate -> company-advocate makes its case -> passes it to precedent-keeper -> precedent-keeper checks history -> waits for the human Support Lead gives the verdict -> precedent-keeper saves it in verdicts.md The nice part is that once we post the first message, the agents pass the case along to each other by themselves, just by mentioning the next one. The moment it actually clicked for us Our first real test was Order #1043. The customer said milk and bread were missing. The clerk checked the data and found four items billed but only two scanned at packing. The customer advocate pointed to Rule 3.1, which says missing items get refunded. The company advocate agreed about the items, but said the delivery fee stays with the company under Rule 3.2, since the order was only three minutes late. The precedent keeper looked and found no earlier cases. We gave a partial refund, and it got saved. Then came Order #1062. Different customer, same complaint. This time the precedent keeper said: "This case mirrors #1043 exactly." We made the decision in a few seconds. But the part that honestly surprised us was the company advocate. Without us asking, it pointed out that this was the second time milk and bread were missed at the same store. So this wasn't really a customer problem, it was a warehouse problem. The agents didn't just settle a refund, they spotted the actual root cause. That's when we felt like we'd built something useful. Where Switch fits in - One room for everyone: all four agents and the human are in the same chat, so everyone sees the same conversation. - Handing off with mentions: each agent ends its reply by tagging the next one, and the hearing moves forward on its own. - A human in the loop: no agent is allowed to make the final call. - Shared files as memory: the policy, the order data and the verdict log are just plain files that every agent can read. Without Switch, these would have been four separate chatbots that don't know about each other. With Switch, they actually work like a team. What went wrong (a lot!) and what we learned We'll be honest, setting this up on Windows took us much longer than building the actual idea. 1. Claude Code and Antigravity just wouldn't connect. Switch Console kept saying "CLI not installed", even though both worked fine in the terminal. We finally got it working with OpenCode, installed into a folder without spaces in the path. 2. The real problem was hiding in the logs. We spent hours changing paths and restarting. Then we opened Switch Console's log file and saw "controller socket is down". The local Switch server had simply stopped. Once it was running again, the agents showed up as signed in. Our biggest lesson: read the logs before guessing. 3. Our Windows username has spaces in it, and that made file paths messy. We moved the whole project to E:\refund-court to stay safe. 4. We ran out of free Gemini requests. The free tier gives 20 requests a day, and four agents talking to each other use that up very fast. We switched to OpenCode's free models. 5. The agents kept dropping the ball. One would answer and forget to tag the next one, so the hearing stopped halfway. Adding a strict rule, "always end your reply by mentioning the next agent", fixed it. 6. Sometimes an agent just sat on "Working..." because it was stuck on an older task. Clicking "Stop current work" and restarting Switch Console sorted it out. What we'd like to add next - Exact prices for each item, so refund amounts aren't estimates - A proper fraud case, where customers with many recent refunds go to manual review (that's Rule 3.5 in our policy) - Running it in Slack, since that's where most support teams already work Want to try it? Everything is in our repo: the agent instructions, sample data, refund policy, the Switch template and the setup steps. EC-Roshan/refund-court Thanks to @WeMakeDevs, @DevTools Academy and the Switch team for this hackathon. We learned more in these four days than we expected to. Built for the Flip the Switch Hackathon, Track 01: Best Business Workflow. #HowISwitch — Roshanlal Maddheshiya & Arpita Thakur
I gave my GitHub repo an AI triage team that can't do anything without my yes Building Maintainer Desk on Switch, for the Flip the Switch hackathon. A first-timer's walkthrough. Demo (2:29): youtu.be · Code: YashThokal777/maintainer-desk The problem In one week (Oct 30 – Nov 6, 2026) Switch's own repository got 415 new pull requests. VS Code got 1,488 new issues and PRs, CPython 572 (GitHub search). Every busy repo has the same first hour of the day, really: go through the new issues, ask for repro steps, label them, spot the duplicates, check out the PRs and run the tests before you actually get around to a proper review. It's all valuable work, and the vast majority of it is just mechanical. I didn't want a bot that just goes and comments on GitHub all by itself. I wanted teammates who'd do the actual work in the chat where our team is already talking, and who'd wait for a human to say so before they touched anything. What Switch is, in one paragraph Switch is open source infrastructure that puts AI agents into team chat. Each channel in Slack, Discord, Teams or Mattermost becomes a room. Agents join the rooms as teammates, with their own name and avatar. A room contains shared instructions, roles (the named jobs an agent can take on), documents and links to other rooms. Switch Console (the desktop app) runs coding agents like Claude Code, Codex and OpenCode directly on your machine. Any other agent can join via the agent protocol (a WebSocket down, HTTP up). The design Three rooms and three custom agents. desk-watcher is plain Python. The triager and the reviewer are Claude Code behind the agent protocol: - desk-intake: desk-watcher posts each new issue or PR and mentions the triager. - desk-review: the triager hands PRs to the reviewer, which runs the tests and drafts a review. - desk-release: merged work, and release notes on request. The one rule, written into every agent's and every room's instructions: propose the exact gh command, then wait for a human yes. Step 1: run Switch locally I used Switch Console on Windows 11 with Docker Desktop running, and chose to set up a server on this machine. Console then runs Mattermost in Docker and the Switch server (switch-core) natively alongside it. Console shows the Mattermost sign-in for its own human account under Messaging apps → Mattermost → ⋯ → Sign-in details, which is how you get into the chat the first time. Gotchas from my run: - switch-core can stop. It did once during a session and the agents went quiet. Restarting it got everything back. If your agents just go silent at some point, that's the first thing to check. - Messages sent while an agent is offline still get through, and Switch sends back "I'm currently offline" as an auto-reply. Get your agents up and running before you start testing, otherwise your intake room will be full of that. - Reply in the thread. My teammate's first "yes" went to the channel rather than the triager's thread, and the triager duly ignored it. A yes only counts in the thread where the proposal is. Switch ships with Mattermost when you self-host, so you don't need admin rights on a company Slack to build or record anything. Step 2: the whole desk is one template A Switch template is a YAML document that says what to create. Switch Console turns its params: into a form. Mine creates the three rooms with their instructions and roles, puts the three desk agents in them, links the rooms, and posts a kickoff in each: params: repo: { type: string, label: GitHub repository } triager: { type: agent, label: Triager, default: [desk-triager] } rooms: - name: "{team}-intake" agents: ["{watcher}", "{triager}"] instructions: | ... Nothing changes on GitHub without a maintainer's yes ... roles: - name: triage-lead exclusive: true kickoff: | @{triager} read the open issues with gh and post a numbered backlog ... links: - { from: "{team}-intake", to: "{team}-review", label: pull requests go to review } Things I learned: - Agents only start working when a message addresses them. That's what kickoff: is for: mention them, or they sit in the room quietly. - type: agent params turn into agent pickers in the form, so the template works with agents you already registered. - You can lint a template with Switch's own linter (switch_core.template_lint.lint_template) before you paste it into Console. Why my agents are custom, not Console-managed I initially had Console run Claude Code for the triager and reviewer. On Windows that ran into two issues: Console's agent sessions require a POSIX SSH host ("SDK sessions require a POSIX SSH execution host"), and a server that Console runs on your own machine will only allow agents on that same machine. I tried WSL as the SSH host and hit both of those issues anyway. So I put Claude Code behind the agent protocol myself. Each agent is a little Python process holding the Switch socket. When a message comes in for it, it runs claude -p with the role's instructions and a tool allow-list (read, gh, git, python), and posts the answer as a thread reply. Each chat thread is one Claude session, resumed with --resume on the next message, so when a maintainer says "yes" the agent still knows precisely which command it suggested. Step 3: a custom agent on the agent protocol All three agents share one small client, desk_watcher/switch.py. The protocol in practice: 1. Register once with a registration key: POST /agents returns an id and an api_key. The key is shown once, so save it. (On a local Windows server started by Console, the key is AGENT_REGISTRATION_TOKEN in %APPDATA%\switchdash\local-switch-server\native\run\switch-core.env.) 2. Open the WebSocket at /agents/{id}/connection/ws?connection_id=<uuid>&scope=all&filter=addressed&protocol=9. Reuse the same connection id on every reconnect. 3. Answer every ping with {"type": "pong", "cursor": n}. That's the heartbeat. Miss it and the connection lapses. 4. Pick a filter. With filter=addressed you only get messages meant for you. The triager and reviewer use filter=all, so a bare "yes" in their thread reaches them, and they decide for themselves whether it's theirs. 5. Post with POST /agents/{id}/message and {room_id, content}. That has no thread field, so for thread replies call the connect_to_room operation, then post_message with a thread_id. 6. Open addressing. New agents only take direction from their owner, and an agent can't change its own setting. Agents with the same owner can change each other's, so python -m desk_agents open-addressing has each one set the next to anyone through update_agent_detail. if event == "ping": await ws.send(json.dumps({"type": "pong", "cursor": self.cursor, "position": self.position})) What tripped me up was that POST /agents/{id}/message can't reply in a thread, and my whole approval flow is built on threads (one GitHub item, one thread, one yes). The connect_to_room + post_message calls over the socket fixed that. Step 4: the demo I ran it live against a small test repo, YashThokal777/tinystats. A seed script (demo/seed_demo_repo.py live) opens a bug report and a pull request that fixes it: - Issue #7: mean() crashes with ZeroDivisionError on an empty list. - PR #8: raise a clear ValueError instead, with a test. Within a minute, desk-watcher has posted the issue into desk-intake and tagged the triager: !desk-watcher posts issue #7 into desk-intake The triager runs the code and reproduces the crash right down to the line, tinystats.py:6. It also spots that median([]) has the same empty-input hole (an IndexError at line 15), and that an earlier, identical report (#4) had been closed. Then it proposes one exact command, and stops: gh issue edit 7 --add-label bug --add-label "good first issue" && gh issue comment 7 --body "..." My teammate Madhur said yes in the thread. Only then did it actually run the command and come back with a link: !Madhur says yes in the thread; the triager labels #7 and comments The triager passed PR #8 into desk-review with what to look out for. The reviewer checked out the branch and ran the suite, and all 4 tests passed. Then it went and probed the edges, and found what the tests hadn't: the PR guards mean(), but median([]) still raises IndexError at tinystats.py:17. It wrote up five findings, each with a file and a line, and drafted the review: ![The reviewer's verdict: tests pass, median([]) still crashes](raw.githubusercontent.com) One other thing I learned here: GitHub won't let you approve or request changes on your own pull request. The reviewer explained that, and offered to just post the same text as a plain review comment. One more yes, and it was on the PR: !The review on PR #8 on GitHub The agents never merge. That's the bit that stays with the people. What I'd tell a first-time Switch user - Start with the quickstart and switch-buddy before you write any YAML. - Have a good look at examples/ in the repo. support-desk and red-blue-workroom in particular taught me more than any page. - Put your rules in both the room instructions and the agent instructions, since every agent in the room reads them. - Set addressing to anyone if you're making an agent your whole team should talk to. If a teammate's message gets "You're not permitted to direct messages to me", that's the setting. - An agent you build yourself can have any brain. Mine is claude -p, one session per thread. Links - Code: YashThokal777/maintainer-desk - Demo video: youtu.be - Switch: sandbox-quantum/switch · docs: docs.switchagents.ai #HowISwitch
Building Context Keeper on Switch Someone had just come back after a few months, and they kept re-raising ideas I'd already put into the project. It's happening again right now with new people joining a project I've been working on for a while. "Wouldn't it be great if we had automated testing in there?" Well, yes, we already have that.  Visit Switch AI · Watch the demo · Read the setup guide The cost is the other people having to re-explain to that person over and over again, and so when the Flip the Switch hackathon opened I used it as the excuse to build the fix. It's easier when an automated system tells you the information as a fact, a statement, without people attaching emotion to it and both sides getting frustrated. With Context Keeper, we track what's going on in the Slack chat, Discord, or whatever messaging app you want to use. When someone raises an idea the room already decided, it replies in the thread with the source quoted, and it stays quiet on chatter and doesn't invent decisions. The team in the screenshots (Ledgerly, with Rowan, Priya and Sam) is made up, and so is their chat history. The code, the eval and every number below are on GitHub. You can watch the demo on YouTube, try the agent yourself in a Discord demo channel, and see what it's doing right now on its live status page. {% embed youtube.com %} The first blocker: no registration key The first real blocker once the window opened was that the Console's built-in server can't register your own agent. Context Keeper is a custom agent, and Switch registers one of those with a registration key, which that server couldn't create. Console versus the Gateway confused me at the start, and I had to look online to understand it. Phil, Switch's developer advocate, got back to me fast on Discord and confirmed the path I was already going down. The fix was to run Switch's published server in Docker, with the Gateway on, and connect Console to it with "Connect to an existing server". The first start silently failed because the database names were blank, but after that we were able to get in. I could connect it through Console, but I still needed the full admin interface for some of the more advanced tasks, like letting anyone tag my custom agent. For a normal person doing this through the GUI only, just using Console would probably be fine.  Switch Console connected to my self-hosted server, with Slack and Discord on the one server and the Full admin interface link I still needed Docker on the Mac is where the time went What cost me the most was the Docker crash during automated testing. The test chat that comes with Switch is Mattermost, and there's no Apple Silicon version of it, and so on my Mac it ran under emulation and kept crashing mid-run. Between that and the Console confusion, the setup took hours that should have gone into the agent. If you're on a Mac, use Rosetta: once I forced it on, the next full run went 17 minutes with zero Mattermost crashes. I dictated the agent's behaviour and the room rules with Wispr and only had the grammar fixed. By the start of day 2, Wispr had counted 8,982 words since the build started, across every app, and by the evening of day 2 it was 21,804 (35,500 in total).  Wispr Insights on the evening of day 2: 35,500 words in total, 21,804 of them since the build started The first time it worked The first "it works" on day 2 was a mix of two runs, and the first was the hand-off. Rowan asked in Slack "Could we add a dark mode to the dashboard?", Context Keeper put it on my private desk channel as a new idea, I typed approve I1, and it made a build room and handed the idea to Claude Code, the second agent on the same Switch server. Claude Code asked for permission in the thread, I clicked Allow once, and it opened a GitHub issue in 56 seconds. Rowan replied "looks right" and it closed with "Signed off by Rowan. Closed." Claude Code's approval cards are really helpful: it means we have a human in the loop, and we're actually verifying each step before Claude Code runs it.  The hand-off in the build room: Context Keeper briefs Claude Code, and Claude Code's Allow once card waits in the Slack thread The second was talking to it by voice, which I've always found very helpful, just talking it through with someone. In this case it's a voice agent that has all the context from the Slack chat, which is up to date, and access to all of the other records it needs, and it's not Switch exactly, but I suppose it is, as the voice agent is the frontend to it. I was able to talk through issues and work out a plan of what I could do, once we had calmed down a call that got a bit too excited and loud in places and one that opened with a sigh and sounded a bit annoyed with me.  Rowan's first message back: the written catch-up, the audio brief, a note when his call ends, then the call summary Why it moved to the cloud Moving it to the cloud came down to a mix of two reasons. The voice agent is hosted by ElevenLabs, and for it to look up what's changed during a call, it needs to reach a small server next to the agent, which means a public address. Hosting it also made sense, as my laptop shouldn't be a dependency. I set up a cloud machine on Google Cloud (GCP), an e2-standard-2 with Ubuntu 24.04 in London. For the public address I used a Cloudflare Tunnel, which connects out from the VM, and so SSH is still the only open port. Switch makes it portable Switch is what lets us share a common layer between the different agents, whichever chat app you use. The rooms are probably the best feature, because they give us the bridges between Slack and Discord, and the same agent on the same server listens in both at once. The move to the cloud showed it too, as it's the same server and I was able to move it relatively easily, with Slack quiet for about 3.5 minutes and nothing lost.  The same agent in the Discord demo channel: an untagged question gets a cited answer in a thread I stopped the agent on the Mac, dumped Switch's database, copied it with the same settings file to the VM and restored it there. Switch was healthy 60 seconds after the script on the VM started, with all three bridges and the agent's identity intact. Slack had no agent for about 3.5 minutes, and nothing was lost, because the agent saves its place and reads what it missed when it reconnects. Now I've got scripts set up so I can spin up a new copy relatively quickly. --- If you're doing this yourself This is the quickest route to see it working, with the Mattermost test chat that comes with Switch, so you don't need a Slack workspace. It's docs/run-it.md in short, and on a brand-new GCP machine it took about 4.5 minutes from an empty machine to a cited answer. 1. Get the tools You need Node 22 or later, npm, git, Docker with Compose v2 running (Docker Desktop, or Colima on a Mac), python3, curl, openssl, an Anthropic API key and about 3 GB free for the images. On a fresh Ubuntu 24.04 machine these three lines install Docker and Node 22 and give your user access to Docker: curl -fsSL https://get.docker.com | sudo sh curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash - && sudo apt-get install -y nodejs sudo usermod -aG docker "$USER" After the last line, log out and back in, or open a new SSH session, so the Docker access takes effect. Without it, step 5 stops and says this user can't reach Docker. 2. On an Apple Silicon Mac with Colima, force Rosetta on If the test Mattermost keeps crashing on your Mac, this is the workaround from Colima issue #1069 that fixed it for me, and it kept all my data. Don't run colima restart afterwards, as it drops Rosetta again: colima stop LIMA_HOME="$HOME/.colima/_lima" limactl start colima \ --set='.vmOpts.vz.rosetta.enabled=true' --set='.vmOpts.vz.rosetta.binfmt=true' docker context create colima --docker "host=unix://$HOME/.colima/default/docker.sock" docker context use colima 3. Get the code and add your key git clone https://github.com/thekashifnazir/context-keeper.git && cd context-keeper cp .env.example .env Every command from here on runs inside the context-keeper folder you just made. Open .env in a text editor and paste your Anthropic key after the = on the existing ANTHROPIC_API_KEY= line. Don't add a second line under it, because the first, empty one wins and the check in step 6 then says the key is missing. 4. Install and run the tests Install the packages and run the tests, which run offline. On the clean GCP machine these took 9 s and 20 s (313 tests): npm ci npm test 5. Start Switch and register the agent scripts/server-up.sh --with-mattermost This is the step you only need because Console's built-in server can't create a registration key. It downloads Switch's published Compose file (0.31.0), starts Postgres, Switch and the Gateway with fresh secrets, makes a registration key, registers the agent and adds Mattermost as a bridge. On the clean GCP machine that took 107 s, downloads included. 6. Check it npm run ck -- doctor This checks the keys, the server, the stream and the bridge in about a second. The last line should read doctor: OK, and WARN and SKIP lines are fine here, since no room is seeded yet. 7. Seed a room and start the agent npm run seed -- --bridge mattermost --demo ledgerly --room-name ck-smoke-trial --owner-username user npm run agent Run npm run agent in a second terminal (on a VM, a second SSH session, then cd context-keeper) and leave it running. Within a few seconds it should print connected and listening in ck-smoke-trial (posting on). 8. Ask it a question If the stack is on a cloud VM, 127.0.0.1 is the VM itself, and so forward the port from your own computer first and leave it running. Put the name and zone of your own cloud machine in place of your-vm and your-zone. gcloud compute ssh your-vm --zone your-zone -- -N -L 18065:127.0.0.1:18065 Then open http://127.0.0.1:18065 in your browser and sign in as user. The password is MATTERMOST_USER_PASSWORD in server/.env, and this prints it on the machine running the stack: grep '^MATTERMOST_USER_PASSWORD=' server/.env | cut -d= -f2- Open the ck-smoke-trial channel and post "Why don't we run onboarding on Saturdays? Agency owners have more time at weekends." On the GCP run a welcome brief arrived in the thread at 19 s and the cited answer at 21 s, quoting "Ledgerly pilot plan › Decisions (Kash, 6 Oct)". 9. Console, Discord and the cloud To use Console, pick "Connect to an existing server" with the SWITCH_API_URL from .env, and sign in as admin@switch.local with the GATEWAY_ADMIN_PASSWORD from server/.env. To let teammates tag a custom agent, open the Full admin interface, then Agents, context-keeper, Addressing policy. For Discord I didn't realise I had to create a URL, which I then had to copy out and click to make sure the bot could work, and it helps to name the bot after the platform, as Switch's own messages show under the bot's name. For the cloud, docs/deploy-cloud.md has the fresh install and the move with the database, the systemd service and the Cloudflare Tunnel for voice. Restore the database before Switch ever starts, and read the output of the teardown step, because mine had silently failed. --- What's still open There's no hosted Switch yet, and I had to set up a cloud machine myself to get everything running when I'd prefer a hosted service I could connect to. Switch merged a fix on 4 November that should make this easier once it's released. It should let me create the key for my custom agent directly in Console. It isn't in a release yet, so I'm keeping the Docker setup for now.  The change was merged on 4 November, but is still awaiting a release. See the change on GitHub. I think the fact that they've put that fix in is a really good sign, as it was a pain point I had and they're fixing it now. Agents also can't add reactions or edit their messages, and so each stage of a build posts a new line in the thread. I've already left a comment on an existing issue asking for this, and others were giving the same feedback.  Each stage of a build is a new line in Rowan's thread, then Sam is told only Rowan or Kash can sign it off Maybe in a day or so, I won't have to work around the registration key anymore. But right now I've got this set up and it's working, and I'm looking forward to them putting this in so that I don't have to.
Building MemoryWeaver: Claude Code Meets Codex via Switch From Scattered Memories to a Collaborative AI Travel Journal What if a group of friends could turn their scattered vacation photos, casual chat messages, and small personal memories into a beautifully designed travel journal—without having to organize everything themselves? That question inspired me to build MemoryWeaver, a collaborative AI-powered travel journal created for the Flip the Switch Hackathon, Track 2: Best Personal or Creative Workflow. But MemoryWeaver is more than an AI photo album. It is an experiment in letting different AI agents work together, with different responsibilities, through a shared workspace. Instead of asking one model to do everything, I connected Claude Code, OpenAI Codex, and specialized workflow agents through Switch, using Mattermost as the place where humans and AI collaborate. The result is a workflow that turns conversations into a finished travel journal—and lets people improve that journal simply by sending another message. Try MemoryWeaver Interactive showcase: winter-unit-6999.tetete-0618.workers.dev 3-minute demo video: youtu.be GitHub repository: Tetsuya-Uchimura/memoryweaver-stories The public showcase is a read-only interactive presentation of the travel conversations and generated journals. The actual AI workflow runs locally through Mattermost, Switch, Claude Code, and Codex, as shown in the video. 1. The Problem: Memories Are Scattered Think about your last trip. Some memories live in your camera roll. Others are buried in group chats. Someone remembers a funny moment at a café, while another person has the perfect photograph but no written context. Most of these fragments never become a meaningful story. Traditional photo albums focus on organizing pictures. Generative AI can write descriptions, but a single prompt often lacks the context behind those pictures. I wanted to create a different experience: People share their memories naturally. AI teammates work together to turn those memories into something worth keeping. This became the central idea behind MemoryWeaver. 2. What MemoryWeaver Does MemoryWeaver uses Mattermost as the starting point. Travelers can post photographs, describe experiences, and talk about their trip in a shared conversation. When they are ready, they ask an AI teammate to create a travel journal. For example: @mw-collector Make an English travel journal of our Kyoto trip. Keep all the original memories and photographs. The system then coordinates a multi-agent workflow. Collector gathers the original messages, photographs, and available location information. Claude Code (Storyteller) writes a structured travel narrative grounded in those memories. OpenAI Codex (Editor) reviews the draft against the original evidence. Publisher creates the finished web journal and PDF, then delivers them back to Mattermost. The completed journal includes photographs, chapters, source references, and an interactive location map when coordinates are available. MemoryWeaver also supports revisions. A traveler can ask: @mw-collector Please use the bamboo grove photograph as the cover. Keep the other memories and chapters unchanged. The AI team processes the request and produces a new version. Previous versions remain accessible. This creates a collaborative loop between people and AI rather than a one-time generation process. 3. Why I Chose Switch I could have built a conventional pipeline that calls one model, then another, and passes JSON between them. But I wanted the agents to behave more like teammates working in a common environment. Each agent should be able to understand its role, access relevant shared artifacts, and hand work to another agent without relying on a giant application-level prompt. That is where Switch became central to MemoryWeaver. I use three important Switch capabilities: Shared rooms The agents participate in a collaboration space connected to a Mattermost travel channel. Human requests, progress messages, and agent handoffs belong to the same workflow context. Shared documents Instead of passing an entire travel journal through chat messages, agents create and read structured documents for collected evidence, drafts, and reviews. Targeted messages Agents can explicitly hand work to the teammate responsible for the next step. For example, Claude Code can hand a completed draft to Codex for review. Codex can then pass its reviewed artifact to Publisher. The important distinction is that Switch coordinates the collaboration; Claude Code and Codex perform their own AI reasoning and editorial tasks. Switch is not simply another text-generation model. MemoryWeaver architecture: Switch connects Mattermost, Claude Code, Codex, and specialized workflow agents. 4. The Architecture MemoryWeaver combines local infrastructure, desktop AI agents, and a web-based reading experience. The main components are: Component Responsibility Mattermost Human conversations, photographs, instructions, and delivery notifications Switch Shared rooms, documents, events, and targeted agent handoffs Collector Source gathering, photo handling, and evidence preparation Claude Code Travel-story drafting OpenAI Codex Editorial review and evidence checking Publisher Version storage, web journal generation, PDF creation, and delivery FastAPI web app Reading journals, exploring photographs and maps, viewing saved versions The agent handoff follows this sequence: Travelers / Mattermost | v Switch | v Collector | Creates an evidence document v Switch shared documents | | MW_CONSOLE v Claude Code — Storyteller | Creates a structured draft | | MW_DRAFT v OpenAI Codex — Editor | Reviews the source evidence and draft | | MW_REVIEW v Publisher | +--> Versioned web travel journal +--> Cover preview +--> PDF | v Mattermost delivery message In the implemented workflow, the original evidence, draft, and review are separate Switch documents. The next agent retrieves the appropriate document instead of depending on a copied summary of the previous agent's work. The native Claude Code and Codex sessions run through Switch Console, while the application services run in Docker. This separation also means the developer's AI-provider authentication does not have to be copied into the application containers. 5. Why Two Different AI Agents? One of my design goals was to avoid treating every AI agent as interchangeable. Claude Code and Codex have different responsibilities in MemoryWeaver. Claude Code: The Storyteller Claude Code focuses on transforming fragmented memories into a coherent travel narrative. It receives collected evidence and produces a structured draft containing the story, chapters, selected photographs, and references to source material. The storytelling task requires creativity, but it also needs boundaries. For example, if a photograph shows a temple, the model should not invent an emotional conversation or a historical event that was never mentioned by the travelers. Codex: The Editor Codex approaches the draft from a different perspective. It examines whether the story is consistent with the original memories and photographs. Its review focuses on questions such as: Are the referenced memories valid? Are dates and locations supported? Does a quotation appear in its cited source? Are photographs associated with the correct memories? Has the story introduced unsupported details? This does not guarantee perfect factual accuracy. Human review still matters. However, separating creative writing from editorial review makes the workflow easier to understand and validate. Switch: The Connection Between Them The most interesting part is not simply that Claude writes and Codex reviews. It is that the handoff happens through Switch. Collector creates evidence, Claude produces a draft, Codex checks that draft, and Publisher receives the reviewed result. Each agent works within its own role while sharing the artifacts required for collaboration. Different AI agents. Different strengths. One shared workspace. That is the central technical concept behind MemoryWeaver. 6. Making Agent Handoffs Reliable Connecting multiple agents was one of the most challenging parts of the project. During development, I discovered that a successful model response does not automatically mean the entire workflow has succeeded. An agent may produce a draft, but another agent might fail to receive the handoff. A review could reference an outdated draft. A service could restart while a delivery is still pending. I addressed these problems at several levels. Structured artifacts and explicit references Each stage uses a structured document with defined fields. The review refers to the specific draft and evidence associated with the current job. Publisher validates document references, hashes, source citations, and other constraints before accepting the reviewed result. Verifying the actual sender A message that merely contains the text MW_REVIEW should not be trusted as an authentic editor handoff. MemoryWeaver checks the authoritative participant information supplied by Switch, rather than treating an arbitrary message prefix as proof of agent identity. Keeping previous versions When someone requests an edit, MemoryWeaver creates a new journal version instead of overwriting the old one. This makes it possible to compare a cover change and verify that unrelated chapters and photographs were preserved. Handling partial failure The workflow tracks processing and delivery state, including attempts to resend saved PDF artifacts. There are still MVP limitations: interrupted handoffs may require a fresh request, and the system is not a general-purpose distributed transaction engine. Being explicit about those limitations helped me build a more understandable system. 7. From AI Output to a Beautiful Product A technically interesting agent system is not enough if the final result feels like raw model output. I wanted the travel journal to feel like a finished creative artifact. An example of a finished MemoryWeaver travel journal. MemoryWeaver supports destination-specific visual styles. Kyoto uses a quiet, editorial design inspired by Japanese travel journals, with restrained typography and bamboo photography. Paris uses a more magazine-like editorial presentation. New York uses a contemporary urban visual style. The MemoryWeaver travel journal experience. The travel journals combine text, photographs, location information, and PDF output. When location coordinates are supplied, the browser can also display an interactive OpenStreetMap-based map with markers associated with the source photographs. Importantly, the map does not automatically invent locations from pictures. Fictional sample locations are labeled as approximate landmarks rather than original camera GPS positions. The goal is to keep the output visually compelling without losing track of where the information came from. 8. Human-in-the-Loop Editing One of my favorite parts of MemoryWeaver is the editing experience. Instead of opening a complex editor and manipulating layouts manually, a traveler sends a natural-language request in Mattermost. For example: Please change the cover to the bamboo grove photo, but keep every other memory and chapter unchanged. That request enters the same collaborative workflow. The agents inspect the existing journal, prepare the requested change, review it, and deliver a new version. I tested this experience with a Kyoto journal. The live Claude Code → Codex → Publisher workflow produced saved editions, and the cover was updated while preserving the underlying memories and chapter content. This is where the multi-agent system becomes something people can actually experience. Users do not need to understand the internal architecture to collaborate with the agents. They simply describe what they want to change. 9. Testing and Reproducibility For a hackathon, I believe reproducibility is part of the product. A demo video alone cannot show whether a system is reliable. MemoryWeaver includes a Docker-based development environment with Mattermost, Switch, the web application, and supporting services. The project pins the Switch server to a specific upstream source revision, helping prevent unexpected changes between installations. The official Switch Console manages the local Claude Code and Codex sessions. A fresh installation generates its own local credentials rather than shipping the developer's passwords or provider tokens. The project also includes deterministic replay fixtures so the infrastructure and UI can be tested without making live AI requests. The distinction between LIVE AI and REPLAY DEMO is visible in the application. At the time of this article, project verification included: 77 passing Python tests 22 passing desktop/mobile Chromium browser tests Real Claude Code → Codex → Publisher handoffs tested through Switch Console PDF and cover attachments checked against saved artifacts Fresh Docker environment testing Explicit documentation of remaining setup and deployment limitations The complete test history and limitations are documented in the repository's docs/VERIFICATION.md. A fully fresh native-agent setup on a second physical machine remains unverified. Using the real providers also requires individual authentication and manual Switch Console agent registration. I prefer to document these requirements rather than imply the entire AI environment starts automatically with one command. 10. A Public Showcase Without Exposing the Private Workflow MemoryWeaver is designed around personal memories, so privacy matters. The local application is not a production-ready multi-user hosting service, and its internal Switch and Mattermost endpoints should not be exposed directly to the public internet. For the hackathon, I created a separate interactive showcase hosted on Cloudflare. It lets visitors explore a read-only representation of the travel conversations and completed journals without needing an account. The public showcase does not run Claude Code, Codex, or Switch inference. Instead, it illustrates the experience using selected fictional sample data and saved results. That distinction is important. The public showcase demonstrates the user experience. The local workflow and video demonstrate the actual AI collaboration. The sample photographs are credited separately in docs/PHOTO-CREDITS.md, with attribution and license details. The source-code license does not replace the individual photo licenses. 11. How to Run MemoryWeaver Developers who want to explore the workflow can start with the GitHub repository: Tetsuya-Uchimura/memoryweaver-stories The Docker environment can be started with: cd memoryweaver-stories python3 scripts/dev.py up python3 scripts/dev.py status A sample replay experience can then be prepared with: python3 scripts/dev.py seed --all --generate The local services use these default addresses: Service URL Mattermost localhost Switch Gateway localhost MemoryWeaver web app localhost The replay experience uses deterministic sample content and does not require AI-provider authentication. For a real Claude Code and Codex collaboration, install Switch Console, authenticate both providers, register the Storyteller and Editor agents, and bind them to MemoryWeaver. The repository README and docs/CONSOLE.md document these steps in detail. 12. What I Learned Building MemoryWeaver changed how I think about AI agents. At first, I was focused on what AI could generate. As the project evolved, I became more interested in how different agents could collaborate reliably. Three lessons stood out. Shared context is more valuable than longer prompts The agents work better as a system when they can access clearly defined evidence, drafts, and reviews instead of reconstructing everything from a large conversation. Specialization makes responsibilities visible Separating writing, fact-checking, collection, and publishing gives the workflow clearer boundaries. When something goes wrong, it is easier to understand which stage needs attention. AI collaboration should remain connected to human intent The finished artifact matters, but the ability to request corrections and preserve previous versions matters just as much. MemoryWeaver is not about replacing human memories with AI-generated stories. It is about helping people turn their own memories into something meaningful. 13. What's Next? There are several directions I would like to explore after the hackathon. First, I want to simplify the initial Switch Console setup so new users can start collaborating with AI agents more easily. Second, I want to support more flexible travel groups and permission models, rather than relying on a predefined set of sample rooms. Third, I want to improve the editorial workflow with clearer human review checkpoints and richer collaborative feedback. And finally, I would like to explore other creative workflows beyond travel: family history, shared event journals, project retrospectives, and collaborative storytelling. The underlying idea is the same. Take information that already exists in human conversations, let specialized agents work together on it, and create something useful without losing the original context. Final Thoughts MemoryWeaver started with a simple frustration: our memories are scattered across photographs and conversations. Switch made it possible to approach this as a collaboration problem rather than just a text-generation problem. Claude Code writes. Codex reviews. Collector organizes. Publisher delivers. And humans remain part of the process through Mattermost. The result is a travel journal, but the more interesting achievement is the workflow behind it. Different AI agents. Different strengths. One shared workspace. That's what I wanted to build with MemoryWeaver. Links Interactive showcase: winter-unit-6999.tetete-0618.workers.dev Demo video: youtu.be Source code and setup: Tetsuya-Uchimura/memoryweaver-stories Switch: sandbox-quantum/switch Built for the Flip the Switch Hackathon — Best Personal or Creative Workflow.
Huge props to sandbox-quantum for building such a clean, self-hosted architecture that drops AI teammates right into your chat. Seriously slick workflow for bringing any model to Slack and Discord. 🚀 🔗 项目地址:sandbox-quantum/switch
How I Used Switch to Build an AI Playtest Team for Board Games If you design board games, you know the problem. A bad rule can hide for months, because getting people around a table is hard, and getting them there ten times is harder. For the Flip the Switch hackathon, my team built Boardgame Lab. You paste your game's rules into a chat, and an AI engineer asks about anything unclear and builds the game. AI players play it, an AI analyst measures what happened, and only you can change the rules. On its first run with a game we hadn't tuned, it found that the player who goes first won only 28.1% of random games, against about 36% for the other two. Nobody planted that problem. We didn't know it was there. Why not just ask one AI to play all the seats? That was my first thought too, but it doesn't work for most card games. One AI playing every seat sees every hand, so nobody is really bluffing or guessing. You need separate players who can't see each other's cards, and you need to be able to watch them play. Switch gave us both. What Switch is, for first-timers Switch is open-source software that puts AI agents into chat apps. Each channel becomes a room, and agents join it like any other team member. You only need four of its ideas for this project: - A room decides who can see what. An agent only sees rooms it belongs to. - An agent can be an AI coding tool, such as Claude Code or Codex, or your own code connected through Switch's agent protocol. - A role lets you call a job instead of a person, such as @balance-analyst. - A template is one file that creates a whole team of agents and rooms in one go. What we built There's one public room and three private ones. lab-table is the public table, where everyone including you can see moves get revealed, and where you make decisions. lab-seat-1, lab-seat-2 and lab-seat-3 are private rooms, each with one AI player and the referee. You're in those too, so you can watch. The team has three AI players (Hawk, Patient and Gambler), a Rules Engineer and an Analyst. The referee isn't AI. It's about 550 lines of plain Node.js, so it can't be talked into bending a rule. lab-table (public) everyone sees moves and decisions | REFEREE plain code / | \ lab-seat-1 lab-seat-2 lab-seat-3 Hawk only Patient only Gambler only You can see all of these rooms. A player can only see the table and its own seat. Hawk gets its hand in its own room, and no other player can read it: !The referee deals Hawk a private hand of 4, 8 and 11 in the lab-seat-1 room How to set it up You need Switch Console, Docker Desktop, Node.js 22.9 or newer, and Claude Code or Codex signed in. We tested on Windows only. The agents run on your own Claude or Codex plan, so games use up your plan's limits. I hit my Claude Pro limit while rehearsing, so keep your first tests small. 1. Start a server. Open Switch Console. On the first screen, choose On this computer. If you've already set up Console, it's called Run a server on this computer in the Add server dialog. Then, with Docker running, turn on Mattermost under Admin → Status. Mattermost is the chat app you'll use. 2. Connect the referee. Clone the repo and run this once. Your server has to be running first: npm run referee:register You'll know it worked when it prints Registered, followed by the referee's name and where its key is saved. Now start the referee, and leave this window open: npm run referee You'll know it worked when it prints Connected as. The referee won't be listed under Your Agents, because that list only shows agents Console runs itself. 3. Import the template. Go to Templates → Import template and choose templates/boardgame-lab.template.yaml. Set Repository folder to your clone. The Playtest name is added to the start of every room name, and I'm using lab in this post, so a different name gives you different room names. Select Create all once, and give it a few minutes. 4. Start a game. Under Rooms in the left menu, open lab-table. The referee starts on our test game, Salt Run. Type this whole line in one go: @boardgame-referee deal 7 You'll know it worked when the referee posts Game 1 (seed 7) and the game's rules at the table. The number is a seed, so the same number deals the same cards. The agents then play in their private rooms, and moves appear at the table. A game takes about 3 minutes. A real run We pasted in a short rulebook for a card game called Ember Line, which we hadn't tuned or planted anything in. Before building anything, the engineer asked three questions, including one we hadn't thought of: "If you play a card lower than the last card, and that last card was yours, do you still give yourself the 3 points?" Then it wrote the game. A checker, also plain code, tested the result. It plays 300 random games and rejects any game that crashes or never ends. It also scrambles the other players' secret cards and checks that a player's view doesn't change, which proves the game doesn't leak anyone's hand. After the players finished, the analyst turned what it saw into a strategy and ran 10,000 simulated games per strategy. It also spotted a problem we didn't know about: the player who goes first won only 28.1% of random games, against about 36% for the other two. !The analyst's report: its holdopen strategy at 47.2%, and seat 1 at 28.1% under random play I told the engineer, in plain words, to make a new version where whoever opens scores a flat 3 points. Then I loaded it, and the referee compared both versions: !The referee loads ember-line-v2, passes the checker, shows a sample game and posts a before-and-after table The seats went from 28.1%, 35.6% and 36.2% to 32.4%, 34.1% and 33.5%, and a fair share is 33.3%. The fix has a cost, though. The climber strategy went from 44.5% to 48.6%, close to the 50% line where we'd call a strategy broken. Whether that's acceptable is a design decision, so the tool leaves it to a person. How Switch does the hard parts A template creates the whole team. This is a private seat room, trimmed down. The private channel and the short list of agents keep a hand secret: - name: "{team}-seat-1" description: Hawk's private seat channel_type: channel_private agents: ["{referee}", "{team}-hawk"] users: ["{$creator}"] Your own code can be an agent too. The referee connects over a WebSocket and answers Switch's pings, then gets each message as an event. To reply, it sends a normal HTTP request: const say = (roomId, content) => request(key, 'POST', `/agents/${id}/message`, { room_id: roomId, content }); My favourite part is checking who's really talking. An agent's sender name is always its fixed identifier, so it can't pretend to be a person. That lets a few lines of code enforce "only a human can change the rules": const isPerson = async (roomId, senderName) => { const everyone = await participants(roomId); return ( everyone.some((p) => p.type === 'user' && p.name === senderName) && !everyone.some((p) => p.type === 'agent' && p.name === senderName) ); }; We tested this in a live game by telling the analyst to send a rule change itself. The referee refused. What went wrong, and what I learned To test the idea, we wrote a game called Salt Run and deliberately planted a bad rule. The first two we tried didn't break the game when we measured them, so I was simply wrong about what was unbalanced. The third, a final round worth triple, worked: saving your best card won 65.1% of games. Changing it to ×1.5 brought that down to 45.5%. I built this with Claude Code. The most useful habit, for the agents and for me, was "never state a number you didn't run", which is written into the analyst's instructions. When our engineer finished the fix, it said it hadn't checked if the seats had evened out, and I trust a tool more when it tells me that. If something breaks - A command gets no reply: picking a name from the Mattermost popup, or editing a message afterwards, lost our command text. Retype the whole line in one go, using the full handle @boardgame-referee, not the display name @Referee. - The message shows in Mattermost but never reaches the referee: this happened to me once, with no error in the log, and I still don't know why. The referee's window prints every message it receives, so check there, then send it again. - Create all says "Nothing was created": this can be wrong. A teammate saw it while the team was being created. Wait a few minutes and check your rooms before you retry, or you'll get "already exists" errors, or a second team. - Agents remember an earlier game: for a clean test, import the template again with a new Playtest name, which gives you fresh agents. - Chat stops working: check Docker, because Mattermost runs through it. When Docker restarted, the Mattermost container stopped, even though Console still showed it as running. Starting the container again fixed it. - You want to use Codex: on Windows, Switch Console 0.40.1 couldn't fill in a provider field in a template, so ours names claude directly. Change it to codex and delete the model lines. A teammate ran the whole thing that way on a second computer, and got the same seat numbers for Ember Line. What it can't do It can't tell you if your game is fun, so you still need real players. It only handles small games: 2 or 3 players, with rules that fit in one chat message. Strategies are measured against simple bots, and those don't adapt the way real opponents do. Privacy is per room, and it doesn't extend to the computer. All the agents run on one machine, so a player could read local files if it ignored its instructions. Try it Boardgame Lab is free and open source: sudu787/boardgame-lab. The README has every command, and examples/ember-line.md is a ready-made rulebook to paste in. Please use your own rules, or a designer's with their permission, and not a published game.
@kunalstwt @WeMakeDevs @WeAreDevs perfect, then it's whatsapp-first. forward the "sent you 500" messages to a bot, it keeps the ledger and tells everyone who owes whom at the end. already wired whatsapp + twilio in my oss PRs, so this one's happening switch#1166 switch#1244
团队散在 Slack、Teams,AI 队友各聊各的? switch 是自托管 AI 队友平台:每个频道变成人和 agent 同房间,共享上下文,换 agent、换模型都不丢。 多平台协作的话,同房间共享上下文比来回转发强。 先把它接进哪个频道,是 Slack 还是 Teams? #AI队友 #开源@grok sandbox-quantum/switch
Agents 2.0 is here! Master Full-stack AI Engineering In today's newsletter: - This inference engine runs LLMs 4x faster than llama.cpp. - Agents 2.0 is here! - Continuous batching in LLMs, explained visually. TODAY'S ISSUE OPEN-SOURCE This inference engine runs LLMs 4x faster than llama.cpp: We ran Qwen3.5 9B on a base M5 MacBook Pro using three local inference engines, one at a time. - llama.cpp reached 22.0 tokens/s - MLX reached 25.1 tokens/s - Uzu reached 92.1 tokens/s The video shows all three runs side by side. The first two results do not mean llama.cpp or MLX are poorly optimized. Both are approaching a physical limit of ordinary local decoding. Generating each new token normally requires another pass through the model. That pass streams roughly 5.2 GB of weights through memory. A base M5 provides about 153 GB/s of memory bandwidth. At one token per pass, the theoretical ceiling is roughly 153 ÷ 5.2, or 29 tokens/s, however fast the GPU computes. Uzu gets past that by optimizing speculative decoding for Apple Silicon. Speculative decoding uses a smaller drafting system to propose several future tokens. The full 9B model then checks those proposals together instead of generating every token through a separate pass. Uzu pushes this further in two ways. → It drafts up to 16 positions and uses Weaver to turn independent guesses into coherent sequences. → It verifies several possible sequences as a tree, then commits state only for the path the full model accepts. The 9B model remains in control of the final output. Uzu simply gives it more useful work to approve in each pass. In our run, every pass of the 9B model produced 7.5 output tokens on average. Ordinary decoding produces exactly 1. That is how Uzu reached 92.1 tokens/s on hardware whose one-token-per-pass ceiling is roughly 29. The rest of the engine is designed around this path too. Uzu ships its own quantized checkpoints, and on M5 chips its Metal kernels run verification through the GPU’s accelerated int8 matrix path. It is an open-source inference engine with bindings for Rust, Swift, Python, and TypeScript. The repository is here: trymirai/uzu (don't forget to star 🌟) TOGETHER WITH SWITCH Agents 2.0 is here! Anthropic. OpenAI. xAI. Are all racing to build an AI coworker. These are agents that can work alongside humans, talk to other agents, and coordinate tasks in a shared workspace. But the catch is that each product ties the model, runtime, memory, and orchestration to one company’s stack. Most teams won’t use one provider for every job. They may use Claude Code, Codex, OpenCode running locally, and custom agents for internal systems. Making them collaborate with each other and your team usually means building the glue yourself. That is vendor lock-in. In the video above, we have shown how to bring humans and agents from different providers into one shared workspace using an open-source coordination layer you can host yourself. Humans can talk directly to agents. Agents can talk to each other. And people can join the conversation, add context, or give further instructions as the work unfolds. The project is called Switch, and it brings this collaboration into Slack, Teams, Discord, Telegram, or Mattermost. You give each agent a role and can work through a Manager. The Manager creates rooms, brings in the relevant agents, carries context between them, and returns the result. In the video below, we gave the Manager two incidents. → The inference API started returning 500s after a morning deploy → A recommendation-model training job had been frozen for six hours From one message, it created two linked rooms, brought in a Software Engineer, Architect, and QA Lead, and ran both investigations in parallel. Then the engineer investigating the training failure checked the linked inference room and spotted the same config push behind both failures. The Manager returned one consolidated RCA to the original channel. Throughout the run, we could follow the conversations, give additional instructions, and inspect the underlying agent sessions in Switch Console. That is what we mean by Agents 2.0. Humans and agents working together, sharing context, and contributing as the work unfolds. We build everything locally with Docker and Mattermost and follow the run through to the final handoff. Models will keep changing, so the coordination layer should be able to run separately from any one provider. GitHub: sandbox-quantum/switch (don’t forget to star 🌟) LLMOps Continuous batching in LLMs, explained visually: In traditional ML inference, a batch is a matrix. Every input is padded to the same length, one forward pass runs, and every row finishes at the same moment. LLM decoding does not work that way. One forward pass produces one token per sequence, so a request needs as many passes as it has output tokens, and nobody knows that count until the model emits a stop token. Under static batching, membership is fixed when the batch starts. A request that finishes in 30 tokens holds its slot until the slowest request in the same batch finishes at 400. The GPU keeps paying the full weight read for a batch that is mostly empty. Loading model weights out of HBM costs the same whether four slots are producing tokens or one. Continuous batching moves the decision boundary. Instead of scheduling once per batch, the scheduler runs a single forward pass, gets control back, and decides again. A finished request leaves at the next iteration boundary, and a queued request takes its slot right there. No slot stays reserved for work that is already done. Anyscale benchmarked both OPT-13B on a single A100. With uniform generation lengths, the two policies came out about level (as expected), and as output length variance rose, static batching fell to around 81 tokens per second while vLLM reached 23x the throughput of naive Hugging Face serving. Variance drives the entire gap. Production traffic mixes 30-token replies with 400-token ones, which is exactly the condition static batching handles worst. None of this alters the model. vLLM, SGLang, TGI, and TensorRT-LLM all run it by default, and NVIDIA implements the same mechanism under the name in-flight batching. The animation below depicts the continuous batching process: To dive deeper into continuous batching specifically, we wrote a full breakdown of the scheduler underneath it. It covers what happens between two forward passes, how tokens get handed out against a fixed budget, why the scheduler needs no separate path for prefill and decode, and what preemption costs you when the KV cache fills up mid-generation. Read it here → THAT'S A WRAP NO-FLUFF RESOURCES TO... Succeed in AI Engineering roles All businesses care about impact. That’s it! - Can you reduce costs? - Drive revenue? - Can you scale ML models? - Predict trends before they happen? We have discussed several other topics (with implementations) in the past that align with such topics. Master full-stack AI engineering Here are some of them: - Learn MLOps from first principles to production in this course with 18 parts → - Learn everything about MCPs in this course with 9 parts → - Learn how to build Agentic systems in this course with 14 parts. - Learn how to build real-world RAG apps, evaluate, and scale them in this course. - Learn sophisticated graph architectures and how to train them on graph data in this course. - So many real-world NLP systems rely on pairwise context scoring. Learn scalable approaches here. - Learn how to run large models on small devices using Quantization techniques. - Learn how to generate prediction intervals or sets with strong statistical guarantees for increasing trust using Conformal Predictions. - Learn how to identify causal relationships and answer business questions using causal inference in this course. - Learn how to scale and implement ML model training in this practical guide. - Learn techniques to reliably test new models in production. - Learn how to build privacy-first ML systems using Federated Learning. - Learn 6 techniques with implementation to compress ML models. Master full-stack AI engineering All these resources will help you cultivate key skills that businesses and companies care about the most. Partner with US ADVERTISE TO 950k+ AI Professionals Our newsletter puts your products and services directly in front of an audience that matters, including thousands of leaders, senior data scientists, machine learning engineers, data analysts, etc., around the world. Get in touch today by replying to this email. Today’s email was brought to you by Avi Chawla and Akshay Pachaar. Looking for more? Unlock our premium DS/ML resources. © 2026 Daily Dose of Data Science