<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: YASH THOKAL</title>
    <description>The latest articles on DEV Community by YASH THOKAL (@yash_thokal_a1899d36b0351).</description>
    <link>https://dev.to/yash_thokal_a1899d36b0351</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3335141%2F1f21ab4b-c02f-4608-9814-04ac2369d2ae.jpg</url>
      <title>DEV Community: YASH THOKAL</title>
      <link>https://dev.to/yash_thokal_a1899d36b0351</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/yash_thokal_a1899d36b0351"/>
    <language>en</language>
    <item>
      <title>I gave my GitHub repo an AI triage team that can't do anything without my yes</title>
      <dc:creator>YASH THOKAL</dc:creator>
      <pubDate>Fri, 06 Nov 2026 19:27:01 +0000</pubDate>
      <link>https://dev.to/yash_thokal_a1899d36b0351/i-gave-my-github-repo-an-ai-triage-team-that-cant-do-anything-without-my-yes-1h6n</link>
      <guid>https://dev.to/yash_thokal_a1899d36b0351/i-gave-my-github-repo-an-ai-triage-team-that-cant-do-anything-without-my-yes-1h6n</guid>
      <description>&lt;p&gt;&lt;em&gt;Building Maintainer Desk on Switch, for the Flip the Switch hackathon. A first-timer's walkthrough.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Demo (2:29): &lt;a href="https://youtu.be/9JXPkAAXD48" rel="noopener noreferrer"&gt;https://youtu.be/9JXPkAAXD48&lt;/a&gt; · Code: &lt;a href="https://github.com/YashThokal777/maintainer-desk" rel="noopener noreferrer"&gt;https://github.com/YashThokal777/maintainer-desk&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem
&lt;/h2&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Switch is, in one paragraph
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/sandbox-quantum/switch" rel="noopener noreferrer"&gt;Switch&lt;/a&gt; is open source infrastructure that puts AI agents into team chat. Each channel in Slack, Discord, Teams or Mattermost becomes a &lt;strong&gt;room&lt;/strong&gt;. Agents join the rooms as teammates, with their own name and avatar. A room contains shared &lt;strong&gt;instructions&lt;/strong&gt;, &lt;strong&gt;roles&lt;/strong&gt; (the named jobs an agent can take on), documents and &lt;strong&gt;links&lt;/strong&gt; 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 &lt;strong&gt;agent protocol&lt;/strong&gt; (a WebSocket down, HTTP up).&lt;/p&gt;

&lt;h2&gt;
  
  
  The design
&lt;/h2&gt;

&lt;p&gt;Three rooms and three custom agents. desk-watcher is plain Python. The triager and the reviewer are Claude Code behind the agent protocol:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;desk-intake&lt;/code&gt;: desk-watcher posts each new issue or PR and mentions the triager.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;desk-review&lt;/code&gt;: the triager hands PRs to the reviewer, which runs the tests and drafts a review.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;desk-release&lt;/code&gt;: merged work, and release notes on request.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The one rule, written into every agent's and every room's instructions: &lt;strong&gt;propose the exact &lt;code&gt;gh&lt;/code&gt; command, then wait for a human yes.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: run Switch locally
&lt;/h2&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;Gotchas from my run:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;switch-core can stop.&lt;/strong&gt; 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.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Messages sent while an agent is offline still get through&lt;/strong&gt;, 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.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reply in the thread.&lt;/strong&gt; 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.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Switch ships with Mattermost when you self-host, so you don't need admin rights on a company Slack to build or record anything.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: the whole desk is one template
&lt;/h2&gt;

&lt;p&gt;A Switch template is a YAML document that says what to create. Switch Console turns its &lt;code&gt;params:&lt;/code&gt; 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:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;params&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;repo&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;    &lt;span class="pi"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;string&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;label&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;GitHub repository&lt;/span&gt; &lt;span class="pi"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;triager&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;agent&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;label&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;Triager&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;default&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;desk-triager&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt; &lt;span class="pi"&gt;}&lt;/span&gt;
&lt;span class="na"&gt;rooms&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;{team}-intake"&lt;/span&gt;
    &lt;span class="na"&gt;agents&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;{watcher}"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;{triager}"&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
    &lt;span class="na"&gt;instructions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
      &lt;span class="s"&gt;... Nothing changes on GitHub without a maintainer's yes ...&lt;/span&gt;
    &lt;span class="na"&gt;roles&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;triage-lead&lt;/span&gt;
        &lt;span class="na"&gt;exclusive&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
    &lt;span class="na"&gt;kickoff&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
      &lt;span class="s"&gt;@{triager} read the open issues with gh and post a numbered backlog ...&lt;/span&gt;
&lt;span class="na"&gt;links&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;from&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;{team}-intake"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;to&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;{team}-review"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;label&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;pull requests go to review&lt;/span&gt; &lt;span class="pi"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Things I learned:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Agents only start working when a message addresses them.&lt;/strong&gt; That's what &lt;code&gt;kickoff:&lt;/code&gt; is for: mention them, or they sit in the room quietly.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;type: agent&lt;/code&gt; params turn into agent pickers in the form, so the template works with agents you already registered.&lt;/li&gt;
&lt;li&gt;You can lint a template with Switch's own linter (&lt;code&gt;switch_core.template_lint.lint_template&lt;/code&gt;) before you paste it into Console.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why my agents are custom, not Console-managed
&lt;/h2&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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 &lt;code&gt;claude -p&lt;/code&gt; with the role's instructions and a tool allow-list (read, &lt;code&gt;gh&lt;/code&gt;, &lt;code&gt;git&lt;/code&gt;, &lt;code&gt;python&lt;/code&gt;), and posts the answer as a thread reply. Each chat thread is one Claude session, resumed with &lt;code&gt;--resume&lt;/code&gt; on the next message, so when a maintainer says "yes" the agent still knows precisely which command it suggested.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: a custom agent on the agent protocol
&lt;/h2&gt;

&lt;p&gt;All three agents share one small client, &lt;code&gt;desk_watcher/switch.py&lt;/code&gt;. The protocol in practice:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Register once&lt;/strong&gt; with a registration key: &lt;code&gt;POST /agents&lt;/code&gt; returns an &lt;code&gt;id&lt;/code&gt; and an &lt;code&gt;api_key&lt;/code&gt;. The key is shown once, so save it. (On a local Windows server started by Console, the key is &lt;code&gt;AGENT_REGISTRATION_TOKEN&lt;/code&gt; in &lt;code&gt;%APPDATA%\switchdash\local-switch-server\native\run\switch-core.env&lt;/code&gt;.)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Open the WebSocket&lt;/strong&gt; at &lt;code&gt;/agents/{id}/connection/ws?connection_id=&amp;lt;uuid&amp;gt;&amp;amp;scope=all&amp;amp;filter=addressed&amp;amp;protocol=9&lt;/code&gt;. Reuse the same connection id on every reconnect.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Answer every &lt;code&gt;ping&lt;/code&gt;&lt;/strong&gt; with &lt;code&gt;{"type": "pong", "cursor": n}&lt;/code&gt;. That's the heartbeat. Miss it and the connection lapses.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pick a filter.&lt;/strong&gt; With &lt;code&gt;filter=addressed&lt;/code&gt; you only get messages meant for you. The triager and reviewer use &lt;code&gt;filter=all&lt;/code&gt;, so a bare "yes" in their thread reaches them, and they decide for themselves whether it's theirs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Post&lt;/strong&gt; with &lt;code&gt;POST /agents/{id}/message&lt;/code&gt; and &lt;code&gt;{room_id, content}&lt;/code&gt;. That has no thread field, so for thread replies call the &lt;code&gt;connect_to_room&lt;/code&gt; operation, then &lt;code&gt;post_message&lt;/code&gt; with a &lt;code&gt;thread_id&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Open addressing.&lt;/strong&gt; 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 &lt;code&gt;python -m desk_agents open-addressing&lt;/code&gt; has each one set the next to &lt;code&gt;anyone&lt;/code&gt; through &lt;code&gt;update_agent_detail&lt;/code&gt;.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ping&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;ws&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dumps&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;pong&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;cursor&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;position&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;position&lt;/span&gt;&lt;span class="p"&gt;}))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What tripped me up was that &lt;code&gt;POST /agents/{id}/message&lt;/code&gt; can't reply in a thread, and my whole approval flow is built on threads (one GitHub item, one thread, one yes). The &lt;code&gt;connect_to_room&lt;/code&gt; + &lt;code&gt;post_message&lt;/code&gt; calls over the socket fixed that.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: the demo
&lt;/h2&gt;

&lt;p&gt;I ran it live against a small test repo, &lt;code&gt;YashThokal777/tinystats&lt;/code&gt;. A seed script (&lt;code&gt;demo/seed_demo_repo.py live&lt;/code&gt;) opens a bug report and a pull request that fixes it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Issue #7:&lt;/strong&gt; &lt;code&gt;mean()&lt;/code&gt; crashes with &lt;code&gt;ZeroDivisionError&lt;/code&gt; on an empty list.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PR #8:&lt;/strong&gt; raise a clear &lt;code&gt;ValueError&lt;/code&gt; instead, with a test.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Within a minute, desk-watcher has posted the issue into &lt;code&gt;desk-intake&lt;/code&gt; and tagged the triager:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkwa0y8wyv6qmnvh1jcyc.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkwa0y8wyv6qmnvh1jcyc.jpg" alt="desk-watcher posts issue #7 into desk-intake" width="800" height="394"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The triager runs the code and reproduces the crash right down to the line, &lt;code&gt;tinystats.py:6&lt;/code&gt;. It also spots that &lt;code&gt;median([])&lt;/code&gt; has the same empty-input hole (an &lt;code&gt;IndexError&lt;/code&gt; at line 15), and that an earlier, identical report (#4) had been closed. Then it proposes one exact command, and stops:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gh issue edit 7 --add-label bug --add-label "good first issue" &amp;amp;&amp;amp; gh issue comment 7 --body "..."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;My teammate Madhur said &lt;strong&gt;yes&lt;/strong&gt; in the thread. Only then did it actually run the command and come back with a link:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fr6x07ny8vjd4b2mdvx6c.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fr6x07ny8vjd4b2mdvx6c.jpg" alt="Madhur says yes in the thread; the triager labels #7 and comments" width="800" height="394"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The triager passed PR #8 into &lt;code&gt;desk-review&lt;/code&gt; with what to look out for. The reviewer checked out the branch and ran the suite, and all &lt;strong&gt;4 tests passed&lt;/strong&gt;. Then it went and probed the edges, and found what the tests hadn't: the PR guards &lt;code&gt;mean()&lt;/code&gt;, but &lt;code&gt;median([])&lt;/code&gt; still raises &lt;code&gt;IndexError&lt;/code&gt; at &lt;code&gt;tinystats.py:17&lt;/code&gt;. It wrote up five findings, each with a file and a line, and drafted the review:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fie7wthkid63csjq57jjs.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fie7wthkid63csjq57jjs.jpg" alt="The reviewer's verdict: tests pass, median([]) still crashes" width="800" height="394"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;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:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3qjuq8ptjpcu00konwwq.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3qjuq8ptjpcu00konwwq.jpg" alt="The review on PR #8 on GitHub" width="800" height="394"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The agents never merge. That's the bit that stays with the people.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I'd tell a first-time Switch user
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Start with the quickstart and switch-buddy before you write any YAML.&lt;/li&gt;
&lt;li&gt;Have a good look at &lt;code&gt;examples/&lt;/code&gt; in the repo. &lt;code&gt;support-desk&lt;/code&gt; and &lt;code&gt;red-blue-workroom&lt;/code&gt; in particular taught me more than any page.&lt;/li&gt;
&lt;li&gt;Put your rules in both the room instructions and the agent instructions, since every agent in the room reads them.&lt;/li&gt;
&lt;li&gt;Set addressing to &lt;code&gt;anyone&lt;/code&gt; 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.&lt;/li&gt;
&lt;li&gt;An agent you build yourself can have any brain. Mine is &lt;code&gt;claude -p&lt;/code&gt;, one session per thread.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Code: &lt;a href="https://github.com/YashThokal777/maintainer-desk" rel="noopener noreferrer"&gt;https://github.com/YashThokal777/maintainer-desk&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Demo video: &lt;a href="https://youtu.be/9JXPkAAXD48" rel="noopener noreferrer"&gt;https://youtu.be/9JXPkAAXD48&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Switch: &lt;a href="https://github.com/sandbox-quantum/switch" rel="noopener noreferrer"&gt;https://github.com/sandbox-quantum/switch&lt;/a&gt; · docs: &lt;a href="https://docs.switchagents.ai" rel="noopener noreferrer"&gt;https://docs.switchagents.ai&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  HowISwitch
&lt;/h1&gt;

</description>
      <category>ai</category>
      <category>opensource</category>
      <category>github</category>
      <category>productivity</category>
    </item>
  </channel>
</rss>
