<?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: Leon</title>
    <description>The latest articles on DEV Community by Leon (@b2a48b).</description>
    <link>https://dev.to/b2a48b</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%2F2763971%2F9ca8020e-1ea4-43cb-b367-5d38db8d6055.png</url>
      <title>DEV Community: Leon</title>
      <link>https://dev.to/b2a48b</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/b2a48b"/>
    <language>en</language>
    <item>
      <title>IDE-Style Code Navigation and Refactoring Don’t Automatically Improve Your Coding Agent</title>
      <dc:creator>Leon</dc:creator>
      <pubDate>Tue, 06 Oct 2026 14:36:13 +0000</pubDate>
      <link>https://dev.to/b2a48b/ide-style-code-navigation-and-refactoring-dont-automatically-improve-your-coding-agent-28n</link>
      <guid>https://dev.to/b2a48b/ide-style-code-navigation-and-refactoring-dont-automatically-improve-your-coding-agent-28n</guid>
      <description>&lt;p&gt;The appeal of a drop-in upgrade for a coding agent is easy to understand: install a tool, give the agent IDE-style code navigation and refactoring, and expect better results. I wanted to know whether that actually helped the same agent finish tasks faster, with fewer mistakes or less token usage.&lt;/p&gt;

&lt;p&gt;I tested one recommendation on ten refactorings in HTTPX. Each task had two attempts with the agent's ordinary tools and two with added navigation and refactoring tools: 40 completed runs.&lt;/p&gt;

&lt;p&gt;Both workflows passed every acceptance check. With the added tools and explicit usage guidance, average agent time increased from &lt;strong&gt;89.8 seconds to 111.4 seconds&lt;/strong&gt;—about &lt;strong&gt;24% longer&lt;/strong&gt;. Average total reported tokens increased by about &lt;strong&gt;40%&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;For this prescribed workflow in fresh sessions, the added tools increased time and token usage without improving acceptance. That is why I want reproducible evidence and tested best practices before treating an extra tool as a drop-in improvement.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Idea Behind the Recommendation
&lt;/h2&gt;

&lt;p&gt;The idea made sense: “go to definition” and “find references” help when working with unfamiliar code. Searching for a method name can return unrelated methods with the same name; finding references to a specific symbol can give a more precise answer.&lt;/p&gt;

&lt;p&gt;The recommended tool was &lt;a href="https://github.com/oraios/serena" rel="noopener noreferrer"&gt;Serena&lt;/a&gt;, which exposes these capabilities to agents through MCP, a protocol for connecting tools to AI clients. An agent can retrieve a function, inspect its references, or edit a particular symbol.&lt;/p&gt;

&lt;p&gt;One route is a language server, which supplies code analysis for editor features through the &lt;a href="https://microsoft.github.io/language-server-protocol/" rel="noopener noreferrer"&gt;Language Server Protocol (LSP)&lt;/a&gt;. A native IDE integration is another: the &lt;a href="https://github.com/oraios/serena#the-serena-jetbrains-plugin" rel="noopener noreferrer"&gt;JetBrains backend&lt;/a&gt; uses an IDE's own analysis and refactoring capabilities.&lt;/p&gt;

&lt;p&gt;This experiment used the language-server backend with Pyright, a Python analysis tool.&lt;/p&gt;

&lt;p&gt;The practical question was whether adding those capabilities improved the same agent's finished work after accounting for the effort of using them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why I Tested the Whole Workflow
&lt;/h2&gt;

&lt;p&gt;Successful navigation and refactoring show capabilities. A productivity claim also needs evidence about completed work. For example, Serena's &lt;a href="https://oraios.github.io/serena/04-evaluation/030_results/000_evaluation-results.html" rel="noopener noreferrer"&gt;agent-written evaluations&lt;/a&gt; compare operation chains, call counts, and payload sizes on its JetBrains backend. Those reports do not establish gains across repeated development tasks with independent acceptance checks.&lt;/p&gt;

&lt;p&gt;Its &lt;a href="https://oraios.github.io/serena/04-evaluation/010_methodology.html#prompt-fairness" rel="noopener noreferrer"&gt;methodology&lt;/a&gt; raises a confirmation-bias concern. The agent chooses examples and judges its own work. Negative findings are requested, yet the prompt used to review the methodology assumes capable agents use the tools correctly, excludes misuse and failure modes, and explicitly says: “Do not question the validity of this assumption.”&lt;/p&gt;

&lt;p&gt;I would not treat reports built on that protected assumption as proof of a drop-in improvement. For any tool, I want repeated complete-task comparisons, independent checks, and tested guidance for real workflows.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ten Refactorings in HTTPX
&lt;/h2&gt;

&lt;p&gt;I was looking for an existing, medium-sized Python project on GitHub: real code spread across files, enough variety for ten distinct refactorings, and a substantial test suite to check that behavior stayed intact. It also needed to be manageable for repeated runs.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/encode/httpx/tree/b5addb64f0161ff6bfe94c124ef76f6a1fba5254" rel="noopener noreferrer"&gt;HTTPX&lt;/a&gt;, a Python HTTP client, was an arbitrary choice that fit that brief. The selected snapshot had about 8,800 lines of production Python. Every attempt used the same fixed commit.&lt;/p&gt;

&lt;p&gt;The ten tasks included renaming classes and methods, moving functions while preserving old imports, extracting shared implementations and modules, inlining a private helper, and simplifying control flow.&lt;/p&gt;

&lt;p&gt;One task renamed &lt;code&gt;Headers.get_list&lt;/code&gt; while leaving &lt;code&gt;QueryParams.get_list&lt;/code&gt; unchanged. It also required preserving the old method as a compatibility alias. Another moved a file-length helper into a new module while preserving stream position and keeping the old import bound to the same function. These gave the checks something more specific to verify than whether the code still ran.&lt;/p&gt;

&lt;p&gt;Every task had two attempts per condition, starting from fresh Docker copies of the same source. Runs were sequential, with the order reversed for the second repetition. The configuration was:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Component&lt;/th&gt;
&lt;th&gt;Tested configuration&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Agent&lt;/td&gt;
&lt;td&gt;Codex CLI 0.160.0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Model&lt;/td&gt;
&lt;td&gt;GPT-6.1 Sol, Medium reasoning&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Evaluation runner&lt;/td&gt;
&lt;td&gt;Harbor 0.23.0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Serena&lt;/td&gt;
&lt;td&gt;1.7.0, LSP backend&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Python analysis&lt;/td&gt;
&lt;td&gt;Pyright 1.1.403&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Per-run resources&lt;/td&gt;
&lt;td&gt;2 CPUs, 4 GiB memory, Linux ARM64 Docker on a Mac&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The ordinary workflow used shell commands, text search, file reads, and edits. The guided workflow kept those tools and added the tool server with explicit instructions: read its guidance, locate the target symbol, inspect references before editing, and use at least one applicable symbol-editing operation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This compares a prescribed workflow using the added tools with the agent's ordinary workflow.&lt;/strong&gt; The guidance is part of the intervention. It does not isolate the effect of LSP itself or measure how an agent chooses among optional tools.&lt;/p&gt;

&lt;p&gt;Acceptance came from a separate offline verifier that checked change scope, requested structure, behavior, tests, type checking, and linting. Before the runs, it accepted ten known-good patches and rejected ten deliberately flawed ones. No human repaired the measured patches.&lt;/p&gt;

&lt;p&gt;The full reproduction bundle is not public yet, so independent reproduction remains a limitation of this report.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the 40 Runs Showed
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Measurement&lt;/th&gt;
&lt;th&gt;Ordinary tools&lt;/th&gt;
&lt;th&gt;Guided tools&lt;/th&gt;
&lt;th&gt;Change&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Accepted attempts&lt;/td&gt;
&lt;td&gt;20/20&lt;/td&gt;
&lt;td&gt;20/20&lt;/td&gt;
&lt;td&gt;Equal&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mean agent time&lt;/td&gt;
&lt;td&gt;89.8 s&lt;/td&gt;
&lt;td&gt;111.4 s&lt;/td&gt;
&lt;td&gt;+24%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mean total reported tokens&lt;/td&gt;
&lt;td&gt;147,247&lt;/td&gt;
&lt;td&gt;205,444&lt;/td&gt;
&lt;td&gt;+40%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mean uncached input tokens&lt;/td&gt;
&lt;td&gt;20,508&lt;/td&gt;
&lt;td&gt;30,047&lt;/td&gt;
&lt;td&gt;+47%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mean completed tool actions&lt;/td&gt;
&lt;td&gt;9.6&lt;/td&gt;
&lt;td&gt;20.4&lt;/td&gt;
&lt;td&gt;+112%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;For someone expecting a drop-in upgrade, this is a worse result on the measured efficiency criteria: the same accepted work took more time and tokens, despite explicit instructions to use the new tools.&lt;/p&gt;

&lt;p&gt;All twenty attempts with the added tools followed the required workflow. Five of the 239 server calls failed.&lt;/p&gt;

&lt;p&gt;Token figures are cumulative usage across model calls and include cached context. Billing was not measured.&lt;/p&gt;

&lt;p&gt;Agent time includes MCP startup, tool use, and tests run by the agent. It excludes container and agent setup, and the independent verifier. Each attempt started a fresh tool server and language-server process, so these are results for fresh sessions rather than a server kept running throughout a working day.&lt;/p&gt;

&lt;p&gt;When I compared matching attempts at the same task, the guided workflow was faster in &lt;strong&gt;5 of 20 comparisons&lt;/strong&gt;. The table below averages each task's two attempts per workflow:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Refactoring&lt;/th&gt;
&lt;th&gt;Ordinary tools&lt;/th&gt;
&lt;th&gt;Guided tools&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Class rename across files&lt;/td&gt;
&lt;td&gt;80.4 s&lt;/td&gt;
&lt;td&gt;92.3 s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rename one of two same-named methods&lt;/td&gt;
&lt;td&gt;76.9 s&lt;/td&gt;
&lt;td&gt;82.5 s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Function move with compatibility&lt;/td&gt;
&lt;td&gt;104.4 s&lt;/td&gt;
&lt;td&gt;133.6 s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Extract two classes into a module&lt;/td&gt;
&lt;td&gt;80.8 s&lt;/td&gt;
&lt;td&gt;122.1 s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Extract related helpers into a module&lt;/td&gt;
&lt;td&gt;109.9 s&lt;/td&gt;
&lt;td&gt;173.0 s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Extract a duplicate implementation&lt;/td&gt;
&lt;td&gt;73.2 s&lt;/td&gt;
&lt;td&gt;107.0 s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Extract a shared encoder&lt;/td&gt;
&lt;td&gt;77.9 s&lt;/td&gt;
&lt;td&gt;88.2 s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Extract a branch with edge cases&lt;/td&gt;
&lt;td&gt;104.8 s&lt;/td&gt;
&lt;td&gt;100.2 s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Inline a private helper&lt;/td&gt;
&lt;td&gt;94.7 s&lt;/td&gt;
&lt;td&gt;121.7 s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Simplify local control flow&lt;/td&gt;
&lt;td&gt;95.2 s&lt;/td&gt;
&lt;td&gt;93.7 s&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The predeclared target was at least a 15% speed improvement without lower acceptance. It was not met.&lt;/p&gt;

&lt;p&gt;Two repetitions per task give a limited view of run-to-run variation. These are descriptive results for one agent and model on ten curated tasks. Other coding agents, models, and Python projects may behave differently.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Would Convince Me?
&lt;/h2&gt;

&lt;p&gt;For any tool presented as a coding-agent upgrade, I want the authors to define "better," measure it, and turn the findings into tested guidance. People looking for a drop-in solution should not have to discover every trade-off themselves.&lt;/p&gt;

&lt;p&gt;For a claim about speed, reliability, or token efficiency, I would look for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The same tasks and starting code with and without the tool, with agent, model, backend, and versions recorded.&lt;/li&gt;
&lt;li&gt;Repeated attempts, independent checks of the resulting code, and clear treatment of failures.&lt;/li&gt;
&lt;li&gt;Complete-task time and token usage, including the work of using the tool.&lt;/li&gt;
&lt;li&gt;Per-run records and runnable scripts, so someone else can repeat the comparison and inspect where the gains came from.&lt;/li&gt;
&lt;li&gt;Tested best practices: which tasks benefit, when ordinary tools work better, and which agent instructions, backend, and setup produced the measured gains.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A tool may help on one task and add overhead on another. Publish both outcomes and the conditions behind them: repository size, model, backend, server lifetime, and instructions. If selective use is recommended, test that policy too.&lt;/p&gt;

&lt;p&gt;Until that evidence is inspectable and reproducible, I do not find broad productivity claims trustworthy enough to base my workflow on.&lt;/p&gt;

&lt;h2&gt;
  
  
  Can They Actually Show an Improvement?
&lt;/h2&gt;

&lt;p&gt;This experiment measured guided use on ten tasks with fresh tool servers. A larger repository, another language, a server that stays running, or a native IDE backend might produce a different result; those possibilities remain untested here. With both workflows passing every check, this comparison also cannot establish differences in maintainability or defects outside the tested cases.&lt;/p&gt;

&lt;p&gt;For this workflow, the extra capabilities produced a slower result with more token usage. That is the risk of treating new tooling as an automatic upgrade: without reproducible evidence and tested best practices, you can make the same agent's workflow worse.&lt;/p&gt;

&lt;p&gt;My question for the authors of coding-agent tools is straightforward: &lt;strong&gt;can you demonstrate an improvement in complete tasks, publish enough of the experiment for someone else to verify it, and show users when and how to get that benefit?&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>devtools</category>
      <category>lsp</category>
      <category>serena</category>
      <category>agents</category>
    </item>
    <item>
      <title>How has AI actually made your life better?</title>
      <dc:creator>Leon</dc:creator>
      <pubDate>Sat, 03 Oct 2026 21:16:16 +0000</pubDate>
      <link>https://dev.to/b2a48b/how-has-ai-actually-made-your-life-better-o44</link>
      <guid>https://dev.to/b2a48b/how-has-ai-actually-made-your-life-better-o44</guid>
      <description>&lt;p&gt;We spend a lot of time discussing new AI tools, comparing models, building things, and exploring what’s possible. I do this too.&lt;/p&gt;

&lt;p&gt;But I want to hear more about what happens after the experimentation. What problem has AI helped you solve, and what difference did that make in your life?&lt;/p&gt;

&lt;p&gt;I’ll start with some examples from my own experience.&lt;/p&gt;

&lt;h2&gt;
  
  
  Meals and Cooking
&lt;/h2&gt;

&lt;p&gt;I use AI to plan meals around the ingredients I have, track what’s been used, and work out preparation instructions. It also orders groceries for the following week. It helps me organize batch cooking sessions that can cover multiple meals across several days.&lt;/p&gt;

&lt;p&gt;Having the meal plan, grocery order, and preparation instructions fit together means I can focus on making the food, with much less figuring out what to eat, what to buy, and how to prepare it.&lt;/p&gt;

&lt;p&gt;I also display the recipes on an e-reader that I can refer to while cooking.&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%2Frg61141mgb4207xh6n51.png" 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%2Frg61141mgb4207xh6n51.png" alt="A white BOOX e-reader displaying a pea soup recipe behind the glass door of a light wood kitchen cupboard." width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The e-reader I use to follow recipes while cooking. Image edited with AI.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Keeping Up with the News
&lt;/h2&gt;

&lt;p&gt;AI collects news from sources I’m interested in and filters out content I consider toxic, polarizing, or irrelevant. It can also turn that selection into a short morning audio briefing.&lt;/p&gt;

&lt;p&gt;I used to finish reading the news pissed off. Being able to stay informed without carrying that frustration into the rest of my day has made a real difference.&lt;/p&gt;

&lt;h2&gt;
  
  
  Shopping
&lt;/h2&gt;

&lt;p&gt;I use AI to find products, check prices and availability, look for discounts at checkout, place orders, and track deliveries.&lt;/p&gt;

&lt;p&gt;Buying something takes much less of my attention. I can explain what I’m looking for, review the options, and have AI help handle the purchase and follow-up. I spend less time searching across stores, trying discount codes, and checking shipping updates myself.&lt;/p&gt;

&lt;h2&gt;
  
  
  Communications
&lt;/h2&gt;

&lt;p&gt;I use AI to help manage conversations across email and messaging apps: contacting service providers, arranging appointments, understanding replies, drafting and sending messages, and following up. It brings together previous exchanges and relevant documents so we can continue a conversation with the right context.&lt;/p&gt;

&lt;p&gt;I can ask where things stand and review a proposed response without having to reread old messages to reconstruct the situation. Much less of the correspondence and follow-through depends on me remembering who I was waiting for and keeping track of everything myself.&lt;/p&gt;

&lt;h2&gt;
  
  
  Work Management
&lt;/h2&gt;

&lt;p&gt;I work with agents to organize and prioritize tasks, work out the next steps, and carry them out.&lt;/p&gt;

&lt;p&gt;With agents helping plan and execute the work, more of my attention can go toward setting the direction, making decisions, and reviewing progress. The organizing, prioritizing, and follow-through no longer depend so much on me personally managing each step.&lt;/p&gt;

&lt;h2&gt;
  
  
  Monthly Finances and Paperwork
&lt;/h2&gt;

&lt;p&gt;AI helps me work through my monthly financial routine: checking records, preparing transfers, distributing money across expense accounts and savings, and organizing invoices and documents. It also handles my tax reporting. I still review and approve the financial actions.&lt;/p&gt;

&lt;p&gt;This used to take a few hours of my time every month. My part is now down to minutes—reviewing the results and approving the financial actions.&lt;/p&gt;

&lt;h2&gt;
  
  
  What About You?
&lt;/h2&gt;

&lt;p&gt;Tell me about one problem AI has helped you solve. What was it like before, what do you do now, and what difference has it made?&lt;/p&gt;

&lt;p&gt;It could be a recurring chore, a one-time problem, or something you couldn’t do before. Small improvements count too.&lt;/p&gt;

&lt;p&gt;If you built something, I’d love to hear what it actually does for you now that you’re using it.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This post was written with AI assistance. The cover illustration was generated with AI.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>discuss</category>
      <category>productivity</category>
      <category>watercooler</category>
    </item>
    <item>
      <title>How I Stopped Codex Agents from Hammering 1Password</title>
      <dc:creator>Leon</dc:creator>
      <pubDate>Sat, 29 Aug 2026 17:11:00 +0000</pubDate>
      <link>https://dev.to/b2a48b/secrets-agents-and-too-many-approval-buttons-2jk1</link>
      <guid>https://dev.to/b2a48b/secrets-agents-and-too-many-approval-buttons-2jk1</guid>
      <description>&lt;p&gt;One afternoon, every Codex task that needed a secret stopped at once. Not one agent. All of them. A tiny distributed-systems incident, staged entirely inside my laptop.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;op service-account ratelimit&lt;/code&gt; delivered the diagnosis with admirable bureaucratic calm: the shared daily allowance was exhausted, and roughly 13 hours remained before reset. The agents were ready to work; 1Password had clocked out for the day.&lt;/p&gt;

&lt;p&gt;The agents already had unattended access through a service-account token limited to the vault they needed—the behavior I wanted. There was no approval loop. The problem was that every agent contacted 1Password independently, and together they exhausted a shared limit none of them could see. They had achieved impressive teamwork, just in the least useful direction possible.&lt;/p&gt;

&lt;p&gt;That changed the question from “how should each agent retrieve a secret?” to “why should each agent retrieve it at all?”&lt;/p&gt;

&lt;p&gt;The replacement had to support:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;several concurrent local agents;&lt;/li&gt;
&lt;li&gt;unattended work after application startup;&lt;/li&gt;
&lt;li&gt;project and non-project tasks, including dynamically created working directories;&lt;/li&gt;
&lt;li&gt;an explicit environment-variable allowlist;&lt;/li&gt;
&lt;li&gt;preferably no plaintext copy of the credentials on disk.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The answer that finally worked was almost disappointingly architectural:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Resolve secrets once at the application boundary. Let Codex forward only an explicit application-wide allowlist to agent commands.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I then took a surprisingly comprehensive tour of ways to move one secret from A to B before settling on two practical choices:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Put the actual values in &lt;code&gt;~/.codex/.env&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Keep the values in 1Password and start ChatGPT with &lt;code&gt;op run&lt;/code&gt;, using an env file that contains only 1Password references.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;These are alternatives, not layers. The first is wonderfully boring but stores credentials on disk. The second keeps 1Password as the only durable secret store and concentrates the unusual part at startup. I chose the second.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I tested this on macOS on 2026-08-27 with ChatGPT desktop/Codex app &lt;code&gt;26.820.71523&lt;/code&gt;, Codex CLI &lt;code&gt;0.150.1&lt;/code&gt;, and 1Password CLI &lt;code&gt;2.39.0&lt;/code&gt;. The undocumented behavior described below may change in later builds.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Why Per-Agent Vault Reads Failed
&lt;/h2&gt;

&lt;p&gt;The original setup gave agents a service-account token limited to the vault they needed. That was unattended, easy to automate, and initially looked like exactly the right solution.&lt;/p&gt;

&lt;p&gt;It also made every agent responsible for talking to 1Password. An agent could avoid repeating its own reads, but it could not share that work with the others. Every agent was responsibly optimized in private. Collectively, they were still eating the same allowance.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.1password.dev/service-accounts/rate-limits" rel="noopener noreferrer"&gt;1Password documents&lt;/a&gt; a daily limit shared by all service accounts in an account. On individual and Families accounts, that allowance is 1,000 requests per 24 hours, and some CLI commands use more than one request.&lt;/p&gt;

&lt;p&gt;That is why creating another token would not have rescued the day: the daily limit belonged to the account, not the token. It would have been a new tap connected to the same empty tank.&lt;/p&gt;

&lt;p&gt;The incident was useful in one respect: it made the hidden dependency visible. My agents did not merely &lt;em&gt;receive&lt;/em&gt; secrets from 1Password. They depended on 1Password being available and below quota throughout their work.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Suspiciously Easy Option: &lt;code&gt;~/.codex/.env&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;On the ChatGPT/Codex desktop build I tested, ChatGPT loads this file when it starts:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;~/.codex/.env
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It is an ordinary dotenv file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;EXAMPLE_API_TOKEN=&amp;lt;actual value&amp;gt;
EXAMPLE_WEBHOOK_SECRET=&amp;lt;actual value&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is it. No sidecar. No broker. No daemon with a YAML file and opinions.&lt;/p&gt;

&lt;p&gt;I verified the behavior with both a fresh ChatGPT launch and a fresh &lt;code&gt;codex exec&lt;/code&gt; process, the non-interactive entry point to the same local Codex tooling. OpenAI's documentation lists the &lt;a href="https://learn.chatgpt.com/docs/config-file/environment-variables" rel="noopener noreferrer"&gt;environment variables that Codex supports directly&lt;/a&gt;, but it does not document automatic loading of this file. I therefore treat &lt;code&gt;~/.codex/.env&lt;/code&gt; as observed behavior of the tested setup, not a permanent cross-platform contract.&lt;/p&gt;

&lt;p&gt;Protect the file and never commit it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;chmod &lt;/span&gt;600 ~/.codex/.env
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Changes take effect only on the next full launch. Closing a ChatGPT window does not quit the application, however final the disappearing window may look.&lt;/p&gt;

&lt;p&gt;This is the smallest setup and the easiest one to debug. Its price is equally simple: the credentials remain on disk in plaintext. File permissions reduce exposure, but the file is still a durable copy that must be protected, rotated, and kept in sync.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Option I Use: Resolve References Once
&lt;/h2&gt;

&lt;p&gt;I wanted 1Password to remain the source of truth without inviting it into every agent operation. The order matters: &lt;code&gt;op run&lt;/code&gt; starts first, authenticates through 1Password desktop if needed, resolves the references, and then launches ChatGPT.&lt;/p&gt;

&lt;p&gt;The runtime sequence has three stages:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Start &lt;code&gt;op run&lt;/code&gt; with &lt;code&gt;~/.codex/.env-run&lt;/code&gt;, which maps environment-variable names to 1Password references.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;op run&lt;/code&gt; contacts 1Password desktop. The desktop app unlocks or asks for startup approval if needed; &lt;code&gt;op run&lt;/code&gt; resolves the references and launches ChatGPT with the resulting environment.&lt;/li&gt;
&lt;li&gt;After ChatGPT starts, &lt;code&gt;~/.codex/config.toml&lt;/code&gt; decides exactly which variables Codex may forward to agent commands.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;.env-run&lt;/code&gt; Is the Map, Not the Treasure
&lt;/h3&gt;

&lt;p&gt;The file looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;EXAMPLE_API_TOKEN=op://&amp;lt;vault&amp;gt;/&amp;lt;item&amp;gt;/&amp;lt;field&amp;gt;
EXAMPLE_WEBHOOK_SECRET=op://&amp;lt;vault&amp;gt;/&amp;lt;item&amp;gt;/&amp;lt;field&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The right-hand sides are references, not copied credential values. I still keep the file local, uncommitted, and mode &lt;code&gt;0600&lt;/code&gt;, because vault and item names can reveal useful metadata. A treasure map may not contain the treasure, but there is no reason to hand it out at the train station.&lt;/p&gt;

&lt;h3&gt;
  
  
  One Command, One Boundary
&lt;/h3&gt;

&lt;p&gt;Quit ChatGPT completely, then run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;op run &lt;span class="nt"&gt;--env-file&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="s2"&gt;/.codex/.env-run"&lt;/span&gt; &lt;span class="nt"&gt;--&lt;/span&gt; /usr/bin/open &lt;span class="nt"&gt;-a&lt;/span&gt; ChatGPT
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is the whole launch mechanism. &lt;code&gt;op run&lt;/code&gt; asks 1Password desktop to unlock or approve the startup request if necessary, replaces the references with their values, and starts ChatGPT inside the resolved environment. There is no second launcher or background service. The command does the interesting work once and then gets out of the way.&lt;/p&gt;

&lt;p&gt;This assumes that the 1Password CLI's desktop-app integration is enabled and that the shell is not forcing a different authentication method. The &lt;a href="https://www.1password.dev/cli/secrets-scripts" rel="noopener noreferrer"&gt;&lt;code&gt;op run&lt;/code&gt; documentation&lt;/a&gt; describes how secret references are resolved and passed to a child process as environment variables.&lt;/p&gt;

&lt;p&gt;Once ChatGPT starts, its agents inherit the resolved environment through the policy below. They do not return to 1Password individually, so parallel work no longer multiplies vault reads.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Other Half: &lt;code&gt;shell_environment_policy&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Getting values into the ChatGPT process is only half the job. &lt;code&gt;config.toml&lt;/code&gt; still decides which variables Codex may forward to commands.&lt;/p&gt;

&lt;p&gt;An &lt;code&gt;include&lt;/code&gt; entry creates an allowlist. Once any include filter exists, variables that do not match one are removed. This is excellent for limiting the environment and slightly less excellent if you include two API tokens but forget that programs also enjoy having a &lt;code&gt;PATH&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;A practical baseline looks like this:&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="nn"&gt;[shell_environment_policy]&lt;/span&gt;
&lt;span class="py"&gt;inherit&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"all"&lt;/span&gt;
&lt;span class="py"&gt;ignore_default_excludes&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;

&lt;span class="nn"&gt;[shell_environment_policy.filters]&lt;/span&gt;
&lt;span class="py"&gt;"PATH"&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"include"&lt;/span&gt;
&lt;span class="py"&gt;"HOME"&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"include"&lt;/span&gt;
&lt;span class="py"&gt;"USER"&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"include"&lt;/span&gt;
&lt;span class="py"&gt;"SHELL"&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"include"&lt;/span&gt;
&lt;span class="py"&gt;"PWD"&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"include"&lt;/span&gt;
&lt;span class="py"&gt;"TMPDIR"&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"include"&lt;/span&gt;
&lt;span class="py"&gt;"LANG"&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"include"&lt;/span&gt;
&lt;span class="py"&gt;"LC_*"&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"include"&lt;/span&gt;
&lt;span class="py"&gt;"TERM"&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"include"&lt;/span&gt;
&lt;span class="py"&gt;"CODEX_HOME"&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"include"&lt;/span&gt;
&lt;span class="py"&gt;"EXAMPLE_API_TOKEN"&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"include"&lt;/span&gt;
&lt;span class="py"&gt;"EXAMPLE_WEBHOOK_SECRET"&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"include"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The exact non-secret baseline depends on the commands you run. The goal is not to recreate your entire login shell inside Codex. Preserve the ordinary process context your tools need, then add credentials by exact name.&lt;/p&gt;

&lt;p&gt;The current OpenAI &lt;a href="https://learn.chatgpt.com/docs/config-file/config-reference" rel="noopener noreferrer"&gt;configuration reference&lt;/a&gt; documents &lt;code&gt;filters&lt;/code&gt; as the canonical mechanism and the older &lt;code&gt;include_only&lt;/code&gt; array as legacy. It also documents &lt;code&gt;ignore_default_excludes = true&lt;/code&gt; as the default; I keep it explicit because the example names contain &lt;code&gt;TOKEN&lt;/code&gt; and &lt;code&gt;SECRET&lt;/code&gt;, and I prefer the intent to be visible beside the allowlist.&lt;/p&gt;

&lt;p&gt;Adding a value to &lt;code&gt;.env&lt;/code&gt; or &lt;code&gt;.env-run&lt;/code&gt; is therefore only half a configuration change. You must also include its name in &lt;code&gt;shell_environment_policy&lt;/code&gt;. The secret source and the allowlist must agree on the name; computers remain stubbornly literal about spelling.&lt;/p&gt;

&lt;p&gt;Because the environment belongs to the ChatGPT process rather than a project directory, this works for project and non-project tasks, including tasks whose working directories are created dynamically.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Tried Before Settling on This
&lt;/h2&gt;

&lt;p&gt;1Password has many relevant features. Each made sense on its own. The awkwardness appeared when I asked for concurrent local agents, unattended work, a clear allowlist, and no plaintext credential copy at the same time.&lt;/p&gt;

&lt;h3&gt;
  
  
  Service-Account Token
&lt;/h3&gt;

&lt;p&gt;This was the original design, not a rejected theoretical option. It worked until parallel agents exhausted the shared daily allowance. Making each agent more careful about its own requests did not coordinate the group.&lt;/p&gt;

&lt;h3&gt;
  
  
  Desktop CLI Calls from Agents
&lt;/h3&gt;

&lt;p&gt;This avoided the service-account quota, but put a human back into the per-agent path. In my testing, approval appeared in a separate 1Password window without clearly identifying the requesting Codex task or downstream operation. I rejected that as a steady-state design; I was not operating that way before the quota incident.&lt;/p&gt;

&lt;h3&gt;
  
  
  1Password Environments
&lt;/h3&gt;

&lt;p&gt;In my test, values in an Environment were separate stored values; putting an &lt;code&gt;op://&lt;/code&gt; reference inside one did not resolve it dynamically. The local dotenv destination used a named pipe rather than plaintext, prompted on first read, and relocked with 1Password. In concurrent tests, fresh Codex processes alternated between receiving all variables and receiving none. Excellent suspense; poor configuration delivery.&lt;/p&gt;

&lt;h3&gt;
  
  
  1Password Connect
&lt;/h3&gt;

&lt;p&gt;Connect can centralize and cache vault access, which directly addresses repeated reads. It also meant deploying and maintaining an API container, a sync container, a credentials JSON file, an access token, a cache volume, ports, and lifecycle management. The &lt;a href="https://www.1password.dev/connect/api-reference" rel="noopener noreferrer"&gt;Connect API&lt;/a&gt; includes create, replace, update, and delete operations, so I would also need to verify and enforce the token's effective permissions rather than assume a read-only boundary.&lt;/p&gt;

&lt;p&gt;That can be the right architecture for an organization. For one desktop application, it was more infrastructure than I wanted to own. I wanted credentials, not a new on-call rotation.&lt;/p&gt;

&lt;h3&gt;
  
  
  1Password MCP or Agent Tool Calls
&lt;/h3&gt;

&lt;p&gt;These are useful when the task is “operate on 1Password.” They do not transparently inject environment variables into arbitrary programs, and they keep password-manager calls inside the agent workflow—the dependency I was trying to remove. Useful tool, different plumbing.&lt;/p&gt;

&lt;p&gt;The common problem was not that any one feature was bad. It was that “can this process receive the credential it needs?” kept acquiring quota state, concurrency behavior, human intervention, or a local server.&lt;/p&gt;

&lt;h2&gt;
  
  
  What This Solves—and What It Does Not
&lt;/h2&gt;

&lt;p&gt;None of this turns environment variables into an enchanted security boundary.&lt;/p&gt;

&lt;p&gt;The plaintext option keeps credentials on disk. The &lt;code&gt;op run&lt;/code&gt; option avoids that extra durable copy, but depends on desktop authentication, requires starting ChatGPT from a terminal command, and concentrates trust in that launch step.&lt;/p&gt;

&lt;p&gt;Both options place secrets in the ChatGPT process environment. &lt;code&gt;shell_environment_policy&lt;/code&gt; does not authorize commands; it only filters the variables inherited by commands that Codex launches. A command that inherits an allowlisted credential can use it, so the configuration and the code being run still need to be trusted. Environment variables improve delivery and separation of concerns; they do not make an untrusted process trustworthy.&lt;/p&gt;

&lt;p&gt;The allowlist is application-wide, not task-specific. Every task and subagent running inside that ChatGPT process should be treated as capable of launching a command that inherits every listed secret. It limits what can leave the application environment; it does not decide which agent gets which credential. True per-agent isolation would require separate processes or a credential broker, and neither preserves the simplicity of this setup.&lt;/p&gt;

&lt;p&gt;In the build I tested, Codex added the names exposed to its command environment to the initial prompt, not their values. Instructions can therefore say, “To access the API, use the environment variable &lt;code&gt;SOME_API_KEY&lt;/code&gt;.” The model can refer to that name in a command, and the program reads the value from its environment without the value appearing in the command itself.&lt;/p&gt;

&lt;p&gt;That distinction is useful, but it is not a force field. An agent can still dump its environment or make a program log a credential. Avoiding those operations remains part of the model's and tool's responsibility.&lt;/p&gt;

&lt;p&gt;Resolved values remain in the application's runtime environment until the app exits. Locking 1Password, changing a vault value, or removing vault access does not rewrite the copy already injected into a running ChatGPT process. Fully quit and relaunch through the chosen route to discard the old environment and receive current values.&lt;/p&gt;

&lt;p&gt;Finally, &lt;code&gt;~/.codex/.env&lt;/code&gt; loading is observed rather than documented, and the 1Password-backed route depends on several products behaving as tested. A small non-secret startup check is worthwhile. It is nicer to discover a broken environment before an agent begins real work and develops opinions about the error message.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Least-Worst Setup Wins
&lt;/h2&gt;

&lt;p&gt;The important change was not a better retry policy. It was removing 1Password from the per-agent hot path.&lt;/p&gt;

&lt;p&gt;Use &lt;code&gt;~/.codex/.env&lt;/code&gt; when the smallest possible setup matters most and a protected plaintext file is acceptable. Use launch-time injection when the secret store should remain the only durable source and one authentication step at startup is acceptable. In my case, that means &lt;code&gt;op run&lt;/code&gt; with &lt;code&gt;~/.codex/.env-run&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This arrangement is not perfect. It trades per-agent vault access for an application-wide runtime environment, and it does not provide a distinct, least-privilege identity to each agent. It is simply the least cumbersome setup I have found that survives concurrent work without turning secret retrieval into a distributed-systems hobby.&lt;/p&gt;

&lt;p&gt;Disclosure: I used ChatGPT Codex to help draft and edit this article. The experience, conclusions, and final publication decision are mine.&lt;/p&gt;

&lt;p&gt;The unresolved question is how desktop agents and subagents should receive a well-attributed, least-privilege identity without persistent tokens, plaintext files, context-free approval windows, or a local platform team.&lt;/p&gt;

&lt;p&gt;If you have a cleaner pattern—especially one that works for general-purpose desktop agents with dynamically created working directories—I genuinely want to hear how you handle it.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>security</category>
      <category>productivity</category>
      <category>openai</category>
    </item>
  </channel>
</rss>
