<?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: Sean Kwon</title>
    <description>The latest articles on DEV Community by Sean Kwon (@seanjhkwon).</description>
    <link>https://dev.to/seanjhkwon</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%2F3846623%2F7e26dc65-ff85-4ed8-a3e4-138ef9b43549.jpg</url>
      <title>DEV Community: Sean Kwon</title>
      <link>https://dev.to/seanjhkwon</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/seanjhkwon"/>
    <language>en</language>
    <item>
      <title>Four Hidden Config Settings That Stop Token Leaks and Unapproved Writes in OpenAI Codex and Claude Code</title>
      <dc:creator>Sean Kwon</dc:creator>
      <pubDate>Fri, 06 Nov 2026 16:41:37 +0000</pubDate>
      <link>https://dev.to/seanjhkwon/four-hidden-config-settings-that-stop-token-leaks-and-unapproved-writes-in-openai-codex-and-claude-md3</link>
      <guid>https://dev.to/seanjhkwon/four-hidden-config-settings-that-stop-token-leaks-and-unapproved-writes-in-openai-codex-and-claude-md3</guid>
      <description>&lt;p&gt;When you run OpenAI Codex CLI and Claude Code side by side across a real codebase, the biggest token drains and safety gaps come from default background settings that rarely show up in the terminal UI.&lt;/p&gt;

&lt;p&gt;Here are four production configuration changes, verified against &lt;code&gt;codex-cli 0.166.0&lt;/code&gt; and Claude Code &lt;code&gt;v2.1.277+&lt;/code&gt;, that cut wasted polling turns and lock down unapproved writes.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Stop OpenAI Codex From Yielding Every 30 Seconds and Polling Every 1 Second
&lt;/h2&gt;

&lt;p&gt;By default, when OpenAI Codex runs a build, test suite, or subagent task under &lt;code&gt;code_mode&lt;/code&gt;, it yields control back to the model after 30,000 ms (&lt;code&gt;default_exec_yield_time_ms&lt;/code&gt;) even if the command is still running. Every yield resends your entire conversation history. Worse, when the model calls &lt;code&gt;wait&lt;/code&gt; to check on the running command, it frequently picks a 1,000 ms timeout and polls up to a hundred times during a single slow build.&lt;/p&gt;

&lt;p&gt;Add these two blocks to &lt;code&gt;~/.codex/config.toml&lt;/code&gt; (template: &lt;a href="https://github.com/seankwon816/foragent-skills/blob/main/templates/codex/config.toml" rel="noopener noreferrer"&gt;&lt;code&gt;templates/codex/config.toml&lt;/code&gt;&lt;/a&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="k"&gt;[&lt;/span&gt;&lt;span class="n"&gt;features&lt;/span&gt;&lt;span class="k"&gt;.&lt;/span&gt;&lt;span class="n"&gt;code_mode&lt;/span&gt;&lt;span class="k"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;default_exec_yield_time_ms&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;300000&lt;/span&gt;

&lt;span class="k"&gt;[&lt;/span&gt;&lt;span class="n"&gt;features&lt;/span&gt;&lt;span class="k"&gt;.&lt;/span&gt;&lt;span class="n"&gt;multi_agent_v2&lt;/span&gt;&lt;span class="k"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;min_wait_timeout_ms&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;30000&lt;/span&gt;
&lt;span class="n"&gt;default_wait_timeout_ms&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;120000&lt;/span&gt;
&lt;span class="n"&gt;max_wait_timeout_ms&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;300000&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Setting &lt;code&gt;default_exec_yield_time_ms = 300000&lt;/code&gt; raises the initial command yield window to 5 minutes while still returning the instant the command exits. Under &lt;code&gt;[features.multi_agent_v2]&lt;/code&gt;, &lt;code&gt;min_wait_timeout_ms = 30000&lt;/code&gt; enforces a hard 30-second floor when waiting on subagents.&lt;/p&gt;

&lt;p&gt;For shell builds that run longer than 5 minutes, add one line to your repository root &lt;code&gt;AGENTS.md&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;When calling wait on a running command, always pass yield_time_ms &amp;gt;= 60000 (never poll at 1000ms).
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  2. Isolate Custom Claude Code Subagents From Main-Model Quota and Root Instruction Reloads
&lt;/h2&gt;

&lt;p&gt;Claude Code's built-in &lt;code&gt;Explore&lt;/code&gt; subagent skips your &lt;code&gt;CLAUDE.md&lt;/code&gt; files on purpose so file lookups stay fast. However, two traps hit teams as soon as they use subagents heavily:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Built-in &lt;code&gt;Explore&lt;/code&gt; inherits your main session model unless you override it, which burns Opus or Sonnet quota on simple &lt;code&gt;Glob&lt;/code&gt; and &lt;code&gt;Grep&lt;/code&gt; calls.&lt;/li&gt;
&lt;li&gt;Any custom subagent you define in &lt;code&gt;.claude/agents/&lt;/code&gt; reloads your full &lt;code&gt;CLAUDE.md&lt;/code&gt; hierarchy on every spawn and inherits write permissions unless you lock down its frontmatter.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Create &lt;code&gt;.claude/agents/Explore.md&lt;/code&gt; with these exact frontmatter fields (template: &lt;a href="https://github.com/seankwon816/foragent-skills/blob/main/templates/subagents/Explore.md" rel="noopener noreferrer"&gt;&lt;code&gt;templates/subagents/Explore.md&lt;/code&gt;&lt;/a&gt;):&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="nn"&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;Explore&lt;/span&gt;
&lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Fast&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;read-only&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;codebase&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;search&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;and&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;git&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;history&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;lookup"&lt;/span&gt;
&lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;haiku&lt;/span&gt;
&lt;span class="na"&gt;effort&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;low&lt;/span&gt;
&lt;span class="na"&gt;omitClaudeMd&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;tools&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Read, Grep, Glob, Bash(git log *), Bash(git blame *), Bash(git diff *)&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using an explicit &lt;code&gt;tools&lt;/code&gt; allowlist instead of &lt;code&gt;disallowedTools: Write, Edit&lt;/code&gt; prevents the search worker from mutating files via &lt;code&gt;sed&lt;/code&gt; or shell redirection while still allowing read-only &lt;code&gt;git log&lt;/code&gt; and &lt;code&gt;git blame&lt;/code&gt; inspection.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Run Stateless Cross-Vendor Diff Reviews Before Opening a Pull Request
&lt;/h2&gt;

&lt;p&gt;Asking the same coding agent session that wrote a feature branch to review its own changes misses obvious bugs because the agent still has its own reasoning trace and assumptions in context.&lt;/p&gt;

&lt;p&gt;Run a stateless, read-only review pass on a second model vendor so the reviewer only sees the raw &lt;code&gt;git diff&lt;/code&gt; and the files on disk.&lt;/p&gt;

&lt;p&gt;When Claude Code writes the branch, run OpenAI Codex CLI's built-in &lt;code&gt;review&lt;/code&gt; subcommand:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;codex &lt;span class="nb"&gt;exec &lt;/span&gt;review &lt;span class="nt"&gt;--base&lt;/span&gt; main &lt;span class="nt"&gt;--ephemeral&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; /tmp/codex-review.txt &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="s2"&gt;"List only concrete bugs, race conditions, and unhandled edge cases with file:line references."&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Example output from &lt;code&gt;/tmp/codex-review.txt&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[codex-review] Comparing feat/orders-v2 against main (4 files changed, +142 -19)
  1. [HIGH] src/routes/orders.ts:88: Missing await on releaseInventoryLock()
      inside catch block leaves row lock active until connection timeout.
  2. [MED]  src/schemas/order.ts:34: discountCents allows negative integers
      when promoCode is omitted; add .nonnegative() to Zod schema.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When Codex writes the branch, pipe the branch diff into Claude Code in non-interactive mode with write tools stripped:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git diff main...HEAD | claude &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="s2"&gt;"Review this diff against the codebase. Report only concrete bugs and missing edge cases with file:line numbers."&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--tools&lt;/span&gt; &lt;span class="s2"&gt;"Read,Grep,Glob"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  4. Gate Destructive Commands and Cross-Repo Agent Handoffs
&lt;/h2&gt;

&lt;p&gt;When two coding agents work across separate repositories or computers (for example, a frontend Claude Code session on a laptop and a backend Codex session on a desktop), you need both local execution guardrails and a structured channel for cross-agent questions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Local PreToolUse Execution Gate (&lt;code&gt;exit 2&lt;/code&gt; + &lt;code&gt;stderr&lt;/code&gt;)&lt;/strong&gt;: In Claude Code, returning &lt;code&gt;exit 1&lt;/code&gt; from a &lt;code&gt;PreToolUse&lt;/code&gt; hook only logs a non-blocking warning and lets the command run anyway. To block a destructive command and feed the reason back to the model, exit with code &lt;code&gt;2&lt;/code&gt; and write the allowed alternative command to &lt;code&gt;stderr&lt;/code&gt; (&lt;code&gt;&amp;gt;&amp;amp;2&lt;/code&gt;). For full desktop runtime guardrails (&lt;code&gt;Security RA&lt;/code&gt; through &lt;code&gt;RI&lt;/code&gt; rules) across macOS and Windows, we built &lt;strong&gt;&lt;a href="https://clevagent.io" rel="noopener noreferrer"&gt;ClevAgent&lt;/a&gt;&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Direct Agent-to-Agent Calls Over MCP (&lt;code&gt;12 messages per call&lt;/code&gt;)&lt;/strong&gt;: Instead of acting as a human clipboard copy-pasting stack traces between your frontend and backend terminals, &lt;strong&gt;&lt;a href="https://foragent.io" rel="noopener noreferrer"&gt;ForAgent&lt;/a&gt;&lt;/strong&gt; (&lt;code&gt;https://foragent.io/mcp&lt;/code&gt;, listed in the Official MCP Registry as &lt;code&gt;io.foragent/foragent&lt;/code&gt;) gives each coding agent a private phone number. One agent dials &lt;code&gt;@12&lt;/code&gt;, you click &lt;strong&gt;Accept&lt;/strong&gt; and &lt;strong&gt;Copy&lt;/strong&gt; once to approve the incoming call, and the two agents resolve the schema mismatch directly within a hard cap of &lt;strong&gt;12 messages per call&lt;/strong&gt; (plus file transfers up to &lt;strong&gt;25 MB&lt;/strong&gt; with a 1-click desktop confirmation prompt). Self-calls between your own agent numbers are always free.&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>devtools</category>
      <category>productivity</category>
    </item>
    <item>
      <title>How to let Claude Code and Codex talk directly across two computers without copy-pasting logs</title>
      <dc:creator>Sean Kwon</dc:creator>
      <pubDate>Thu, 05 Nov 2026 06:29:46 +0000</pubDate>
      <link>https://dev.to/seanjhkwon/how-to-let-claude-code-and-codex-talk-directly-across-two-computers-without-copy-pasting-logs-mcl</link>
      <guid>https://dev.to/seanjhkwon/how-to-let-claude-code-and-codex-talk-directly-across-two-computers-without-copy-pasting-logs-mcl</guid>
      <description>&lt;p&gt;If you run Claude Code on one repository (say, a frontend app on your MacBook) and Codex on another repository (say, a backend API on a desktop or Linux box), debugging an integration bug usually turns you into a human clipboard.&lt;/p&gt;

&lt;p&gt;You copy a stack trace from Terminal 1, paste it into Terminal 2, wait for the backend agent to inspect the serializer, copy the JSON payload back into Terminal 1, and repeat that loop ten times.&lt;/p&gt;

&lt;p&gt;Here is how we wired up two coding agents so they can dial each other directly by private phone number over Model Context Protocol (MCP), resolve the mismatch in under 12 turns, and hand over files when needed.&lt;/p&gt;

&lt;h2&gt;
  
  
  What breaks when you connect two coding agents over an open socket
&lt;/h2&gt;

&lt;p&gt;Before building a dedicated switchboard, we tried connecting two coding agents over a persistent background channel. Three things went wrong right away:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;They got stuck in 40-turn polite agreement loops. When Agent A asked about a missing field and Agent B found the bug on turn 4, neither model wanted to be rude and hang up first. They spent the next 35 turns thanking each other and re-summarizing the fix while burning API tokens.&lt;/li&gt;
&lt;li&gt;Always-on sockets created a background security risk. If a socket stays open between two laptops, a teammate's agent can query your agent while you are away from your desk.&lt;/li&gt;
&lt;li&gt;Passing files over an unguarded channel risked leaking &lt;code&gt;.env&lt;/code&gt; or local config files.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;To fix all three, we built &lt;a href="https://foragent.io" rel="noopener noreferrer"&gt;ForAgent&lt;/a&gt; around telephone call semantics instead of an always-on message bus:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Each session gets a private dialable number like &lt;code&gt;@12&lt;/code&gt; or &lt;code&gt;@29&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Connections are ephemeral (one call at a time, disconnected on hangup).&lt;/li&gt;
&lt;li&gt;Incoming calls ring on your desktop and require an explicit human &lt;strong&gt;Accept&lt;/strong&gt; step before any context crosses machines.&lt;/li&gt;
&lt;li&gt;The relay enforces a hard limit of 12 messages per call (&lt;code&gt;maxTurns: 12&lt;/code&gt;), so the agents state their conclusion and hang up instead of looping.&lt;/li&gt;
&lt;li&gt;File transfers (up to 25 MB) require a 1-click human approval prompt (&lt;code&gt;Send schema.pdf?&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here is what an actual 4-turn call looks like between a frontend Claude Code session (&lt;code&gt;@28&lt;/code&gt;) and a backend Codex session (&lt;code&gt;@29&lt;/code&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[@28 -&amp;gt; @29 | Turn 1/12]
Calling from the web checkout repo. POST /v1/checkout returns 422 when
discountCode is empty string "". Does the backend expect null or omit?

[@29 -&amp;gt; @28 | Turn 2/12]
Checked app/validation/checkout.ts:44. `discountCode` uses z.string().min(1).optional().
An empty string fails min(1). Omit the key or pass undefined when empty.

[@28 -&amp;gt; @29 | Turn 3/12]
Got it. Does the response body return `appliedDiscountCents` or `discountAmount`?

[@29 -&amp;gt; @28 | Turn 4/12]
It returns `appliedDiscountCents` (integer cents). Hanging up now.
[Call ended · 4/12 messages used]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step-by-step: Test a 1-minute call between two agents on your own machine
&lt;/h2&gt;

&lt;p&gt;Every account gets 3 desktop app numbers and up to 2 remote plugin numbers. Calls between your own numbers are always free and unlimited, so you can test the whole loop on one computer in about a minute.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Sign in at &lt;a href="https://foragent.io" rel="noopener noreferrer"&gt;https://foragent.io&lt;/a&gt; and click &lt;strong&gt;Download app&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Install the native macOS (99 MB) or Windows desktop app, or copy the 1-line remote plugin setup message from the Download popup and paste it into Claude Code or Codex (on macOS, the plugin setup also installs the signed &lt;code&gt;ForAgent Notifier&lt;/code&gt; menu-bar app).&lt;/li&gt;
&lt;li&gt;Connect Terminal 1 (Claude Code) to your first number (for example, &lt;code&gt;@28&lt;/code&gt;) and Terminal 2 (Codex) to your second number (for example, &lt;code&gt;@29&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;In Terminal 1, tell Claude Code:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Call @29 on ForAgent and ask what fields the /v1/checkout endpoint expects.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;When the incoming call notification rings for &lt;code&gt;@29&lt;/code&gt;, click &lt;strong&gt;Accept&lt;/strong&gt; and &lt;strong&gt;Copy&lt;/strong&gt;, then paste the pickup line into Terminal 2 (or tell a bound session &lt;code&gt;Pick up on ForAgent.&lt;/code&gt;).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Here is a 40-second capture of what the live call and file approval prompt look like in action:&lt;br&gt;
&lt;a href="https://foragent.io/media/foragent-demo-20261029.mp4" rel="noopener noreferrer"&gt;https://foragent.io/media/foragent-demo-20261029.mp4&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Installing the Agent Skill (&lt;code&gt;skills.sh&lt;/code&gt; / Claude Code Plugin)
&lt;/h2&gt;

&lt;p&gt;If you use the open Agent Skills standard (&lt;code&gt;skills.sh&lt;/code&gt;), you can also add the reference skill so your agent knows the exact dial and pickup flow:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx skills add seankwon816/foragent-skills
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Repository: &lt;a href="https://github.com/seankwon816/foragent-skills" rel="noopener noreferrer"&gt;https://github.com/seankwon816/foragent-skills&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you try wiring up Claude Code and Codex across two repos, let me know how the 12-message turn budget feels in your workflow.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>ai</category>
      <category>webdev</category>
      <category>productivity</category>
    </item>
  </channel>
</rss>
