/ LAB NOTES / ENGLISH
Coding Agents Are Changing How I Build Open Source and Why I Do It

After more than twenty years of developing and publishing software through CyberGarage, I am finding that coding agents change more than how quickly I can write code. They have helped me restart stalled development, bring existing libraries to new hardware, respond to contributors, and work through security flaws and years of maintenance debt. Work that I could not fit into my own time is moving again. I used to work through projects one at a time; delegating to agents has made working on several in parallel my normal way of developing.
I now use Codex as my primary tool, with Claude in a supporting role. I rarely use GitHub Copilot these days. The examples here come from that personal workflow, not a comparison of the tools or a claim about every developer's experience.
The change is welcome, but not uncomplicated. I spend more time setting direction, preparing tests, and judging results, while agents carry more of the implementation. That makes maintaining my projects more practical without replacing my responsibility for them. It also changes the satisfaction I used to find in solving a difficult problem myself. The implementation burden is lighter, but keeping up with the decisions can be tiring.
This is an account of both sides: what has started moving in my projects, and what that progress has made me reconsider about learning, building, and participating in open source. If making an alternative becomes easier, what still draws me to a shared project, and what will I want to build for the pleasure of building it?
On this page11 sections
1. Coding agents got stalled maintenance moving again
The benefits have appeared in several kinds of work: developing something I had struggled to finish, responding to new reports and contributions, investigating security weaknesses, and returning to old maintenance debt.
New development: accelerating work and reaching new platforms
Agents gave me room both to restart an unfinished implementation and to take established libraries into a new environment. The first meant working through Matter's specifications and security requirements; the second meant adapting existing protocol code to ESP32 hardware. Neither was just a request to generate code. I still had to prepare useful logs, test tools, and equipment, but the agent could carry more of the investigation, implementation, and testing between my decisions. The following examples show those two kinds of progress.
Matter: restarting go-matter
go-matter is a Go implementation of Matter, the smart-home interoperability standard, with a commissioner that pairs devices and then reads, writes, and invokes their functions. I started it in 2024, but the volume of specifications and the effort of turning them into a working implementation had slowed my progress.
Preparing the underlying communication libraries also took time: go-mdns provides multicast DNS and DNS-based service discovery, while go-ble provides Bluetooth Low Energy scanning and GATT communication. Before I could concentrate on Matter itself, I had to build and check these foundations as well.
Even once those underlying protocols were ready, progress on Matter itself remained slow. Compared with the UPnP and ECHONET Lite implementations I had worked on, Matter required me to absorb much more background on security and cryptography alongside a large body of specifications. Getting discovery or a transport working was only the beginning; understanding how to establish trust and exchange protected messages was another substantial task.
After leaving the project largely stalled for a long time, I recently returned to it when I could fit it in between other work with agents. Coding agents helped me work through those specifications, compare the code with the reference implementation, and turn failures into specific corrections. The Git history shows what that meant in practice, beyond simply adding more code:
| Date (UTC) | Progress recorded in the history |
|---|---|
| 2026-09-28–30 | Added end-to-end commissioning over mDNS and UDP, then commissioning tests against the Matter SDK's chip-tool and On/Off Light operation and subscription tests. |
| 2026-10-09–11 | Built a full-screen matterctl controller (PR #10), then added observed device inventory (PR #15) and bounded configuration writes with fresh readback (PR #16). |
| 2026-10-14 | Added device-attestation verification (PR #20), attribute subscriptions (PR #22), event reads and subscriptions (PR #23), session resumption (PR #24), and a private-key store (PR #25). |
| 2026-10-15 | Corrected operational discovery (PR #31) and session acknowledgements (PR #36) based on device behavior, then prepared v0.9.0 (PR #37). |
That progress depended on preparing an environment the agent could investigate, not simply asking it to implement a standard. I built observability around go-logger, including hexadecimal dumps of protocol messages, so the agent had concrete bytes and logs to examine. I also made specification-related utility programs and real Matter devices available for communication tests. Together, these gave it a way to compare expected behavior with actual exchanges and continue investigating without my interpreting every packet.
At a later stage, my part often became resetting and configuring the physical devices for the next attempt. The agent would then communicate with them, analyze the resulting traces, revise the implementation, and test again. I was preparing the equipment and deciding what to try, while it carried much of the analysis-and-implementation loop.
ESP32: bringing existing libraries to a new platform
I already had provisional implementation code and a rough idea of where changes were needed for ESP32. But I had left the work sitting for a long time without completing the final tests. The remaining step was to carry that tentative work through verification, not to begin from nothing.
mUPnP for C is a UPnP library I have maintained for more than twenty years. Its adoption history includes Nokia tablets and, more recently, REGZA and TCL televisions.
uEcho for C is my C library for discovering and controlling devices through ECHONET Lite. ECHONET Lite is a home-appliance and energy-management communication standard developed in Japan, used to connect equipment such as lighting, air conditioners, and smart meters.
With help from coding agents, I brought both libraries to ESP32 through ESP-IDF. These were new uses for existing code: discovery and control from a small Wi-Fi board, and an ECHONET Lite lighting-device example. The work progressed from porting and build checks to specific hardware tests:
| Library | Development and validation history |
|---|---|
| mUPnP for C | The initial ESP-IDF port (PR #27) established cross-build and host-test coverage. Follow-up hardware checks (PR #30) on an ESP32 DevKitC-VE covered discovery, rediscovery, SOAP control, and GENA notifications over Wi-Fi and IPv4. These were recorded against the 3.1.0-era implementation, not every later change. |
| uEcho for C | The ESP-IDF component and lighting example (PR #8) began with ESP32/S3/C3 builds and emulator tests. Real ESP32 Wi-Fi checks (PR #11) then covered discovery, Get responses, and SetC on/off responses. Build coverage for other variants was not equivalent to hardware validation. |
These were specific hardware configurations and examples, not verification of every feature or ESP32 variant. The mUPnP guide and uEcho for C guide distinguish hardware results from build coverage. For me, the useful change was being able to extend existing libraries into another environment without carrying every porting and test step myself.
New reports and PRs: responding promptly with less burden
When I publish software as open source, reports and contributions can arrive from users on platforms I do not normally use. Agents have made it easier to give those contributions prompt attention rather than let them become another backlog. I can give instructions and have the agent investigate, check the change, and handle the reply, while the reporter's diagnosis or patch provides the starting point. These three cases illustrate that lighter response cycle:
| Date (UTC) | New work | Result |
|---|---|---|
| 2026-10-08 | mUPnP Issue #49, reported by Brecht Sanders | Four defects addressed in PR #50. About 2 h 28 min from the report to the reporter's successful rebuild. |
| 2026-10-30 | uEcho for C PR #22, contributed by alosafuzz | The allocation-failure fix was reviewed and merged in about 68 minutes, with local sanitizer and test results recorded in my reply (PR #22). |
| 2026-11-11 | Net::UPnP RT #182942/#182943, reported by Slaven Rezic | About 81 minutes from the reports to the 1.4.10 release, following PR #12. Target-environment retests remained unconfirmed. |
These are elapsed times between events, not measurements of working time; the endpoints differ between cases. My practical involvement was largely limited to giving instructions, while the agent handled the investigation, checks, and replies.
In mUPnP Issue #49, Brecht Sanders reported four Windows / MinGW build and link problems involving integer types, logging names, a function declaration, and a thread function. His diagnosis and successful rebuild were essential to the result.
In uEcho for C PR #22, alosafuzz contributed the allocation-failure check that prevented a NULL dereference; the patch and credit belong to its contributor.
Net::UPnP is my Perl library for UPnP discovery and control. Its first release was in December 2005, and Debian distributes it as libnet-upnp-perl. Just after 1.4.9, CPAN smoke tester Slaven Rezic reported older-Perl and long-double failures in the security checks introduced with 1.4.7. The agent helped fix the compatibility issue and test assumption.
Security review: turning findings into checked fixes
Vulnerabilities in open-source dependencies, including those documented in Apache's security advisories, are a reminder that widely used software still needs scrutiny. I wanted to examine my own OSS with OpenAI's Codex Security. It uses a repository-specific threat model to investigate potential vulnerabilities, attempts to validate them in an isolated environment, and proposes patches for review rather than automatically changing the code.
Security research can also be misused to develop attacks. OpenAI’s Daybreak Access provides approved users with reduced refusals for supported, authorized security work while retaining safeguards against abuse.
Daybreak Access can be useful for deeper security investigations, but obtaining it requires an application and identity verification, as well as preparation of a physical security key. Even without that access, I used Codex Security to find vulnerabilities in my own OSS projects. These investigations led to the following findings and fixes:
| Project | Findings and follow-through |
|---|---|
| mUPnP for C | PR #28 addressed 13 findings across HTTP and XML resource limits, TLS verification, SSDP handling, and object lifetimes. Follow-up PR #29 corrected shared-data lifetime and server-deletion races. |
| uEcho for C | PR #10 addressed five security boundaries involving buffers, concurrency, permissions, spoofed responses, and cached data. |
| CyberGarage UPnP for Java | PR #48 addressed nine findings, including XML external entities, HTTP limits, GENA event handling, and SSDP processing. Three other candidates remained deferred rather than being counted as fixed. |
| Perl Net::UPnP | PR #4 recorded seven validated findings but changed no implementation. PR #5 and PR #6 supplied the repairs, including HTTP deadlines and limits, SSDP destination constraints, bounded traversal, and XML escaping. |
In my own experience, Codex Security sometimes warned and stopped during deeper investigations without Daybreak Access. I have now obtained the hardware security key needed for the individual access process and plan to repeat those detailed reviews once the remaining setup and approval are complete.
Existing debt: resolving work that had waited for years
For an individual maintainer, the limiting factor is often the time and effort available for reproducing reports, implementing changes, and checking compatibility alongside other work. Even when I knew what needed attention, I could not always make room for it. Agents made more of that work practical to take on.
mUPnP for C: resolving long-standing discovery and compatibility issues
The mUPnP 3.1.1 release brought together fixes for discovery that could stall, missing access to device-description information, and resource and object-lifetime problems. It also added opt-in IPv6 support requested years earlier.
| Long-standing problem | Work included in 3.1.1 |
|---|---|
| Discovery could hang on a dropped TCP connection (Issue #10, 2014). | PR #40 applied pre-connect socket timeouts and bounded connection establishment. |
| Missing access to declared state-variable information (Issue #9, 2014). | PR #41 and PR #46 exposed SCPD default values and data types. |
| IPv6 support requested in 2016 (Issue #17). | PR #42 and PR #43 added opt-in link-local support and corrected discovery address handling. Still experimental, without real-network IPv6 validation. |
| Resource and lifecycle defects. | PR #39 grew HTTP buffers as data arrived; PR #44 fixed subscription URL leaks and a device-deletion use-after-free; PR #47 stopped endless startup retries without a usable interface. |
These were different kinds of maintenance work, from making existing behavior reliable to exposing information applications needed and extending protocol support.
Net::UPnP: working through a long-standing CPAN backlog
Before this maintenance effort, Net::UPnP had not had a release since 2018. After the October security review described above, I returned to a CPAN RT queue containing 17 reports from 2006–2018, some nearly twenty years old.
The releases combined security hardening, compatibility corrections, and the long-requested protocol addition:
| Release | Main changes |
|---|---|
| 1.4.7 · PR #7 | Shipped the security hardening, corrected documentation and example errors, and added the correctly spelled gettotalbytesreceived() while retaining the old name as an alias. |
| 1.4.8 · PR #9 | Fixed empty service-list handling, respected caller-supplied control URLs and joined relative URLs correctly, switched requests to HTTP/1.1 for devices rejecting HTTP/1.0, and declared the BSD license in package metadata. |
| 1.4.9 · PR #11 | Added WANPPPConnection support for routers without WANIPConnection, addressing a request from 2010. |
Across 1.4.7–1.4.9, the regression suite grew from 193 to 236 tests, without retesting every historical device. The 17 ticket closures were not 17 new fixes: six were already addressed, and three involved guidance or retest requests.
2. The developer's work and enjoyment have changed
I used to write code at the speed of my own thinking. Working out a design and making it run felt like solving a puzzle. The process satisfied my intellectual curiosity, and completing it brought a sense of achievement.
PuzzleDB: a changing sense of technical challenge
PuzzleDB is my Go-based, multi-protocol database project, inspired by the idea of a Cosmos DB-style system with multiple database interfaces over shared services. It includes PostgreSQL- and MySQL-compatible protocol frontends, with compatibility still being developed rather than complete. I had been working on it energetically in recent years and wrote about its design in Building a Multi-Protocol NewSQL Database in Go.
Building a compatible implementation also meant understanding the protocol specifications in detail, rather than simply translating them into code. That work sometimes exposed errors or inconsistencies in the documentation itself. I submitted MySQL PR #568 to correct the payload length in a COM_QUERY example, and PR #593 to correct COM_STMT_PREPARE examples and the documented condition for reading warning_count. The corresponding MySQL bug records document these fixes in 9.2.0 and 9.3.0, respectively.
It was a difficult, absorbing way to learn by building. Understanding the specifications, checking them against actual packets, and contributing what I found were part of the challenge. But established implementations, protocols, and tests also make this field especially accessible to coding agents. I have lost much of the motivation that came from treating it as a personal challenge.
| Project | What changed my sense of the challenge |
|---|---|
| PuzzleDB | The pleasure lay in learning to make a complex system work myself, not only in obtaining a working database. |
| pgrust | Michael Malis describes using Codex to reimplement PostgreSQL in Rust from existing code and regression tests. |
| rusql | Its author describes an agent-written Rust implementation targeting MySQL 8.0 compatibility using Claude Code and Cursor. It remains a developer preview, not a production replacement. |
The latter two are independent projects and their authors' accounts, not replacements of upstream PostgreSQL or MySQL or proof of full compatibility.
Even with those limits, seeing such work changes my sense of the challenge. An agent may make implementation easier while taking away the particular satisfaction that made me want to implement it myself. Getting more done does not automatically replace that motivation.
Retro computing: rethinking a retirement hobby
The same change has reached a hobby I had been saving for retirement: hacking retro computers. I had collected many arcade circuit boards and old computers, expecting years of enjoyment from understanding them and making them do something new. Yet my interest in that work has faded surprisingly quickly as well.
| Retro-computing example | Agent-assisted work and its limits |
|---|---|
| Game Boy emulator | Sanjeet describes ten days with Claude Code and other models, getting Tetris running and improving graphics and audio. Incorrect simplification of pixel processing and register/joypad problems still required expert help. |
| Marbles² game port | Remy Sharp brought his 2002 Palm game to a 32 KB Game Boy cartridge in about a week, with Claude Code writing the code. He directed design iterations and proposed a one-bit font saving about 3 KB; the same approach failed on another game. |
| ZX-Reaper | The project reports annotated, rebuildable assembly and a Python port of Hungry Horace, checked against gameplay and Z80 memory/state traces. Jet Set Willy had reached assembly reconstruction. |
These examples do not reproduce my collection or settle every hardware problem. They do change my anticipation of the work. What I had imagined as a long, hands-on journey of discovery now looks increasingly like something I could direct an agent through. Even when the result is impressive, that is not necessarily the retirement hobby I had been looking forward to.
3. How I develop now
My work now often resembles leading a project with capable staff. I describe the objective, inspect the result, point out what is missing, and make the next decision. Instead of working through one project at a time, I now routinely delegate work across several projects in parallel. That creates a different kind of busyness: I need to keep making decisions so that I do not become their bottleneck.
In my professional work, I have developed substantial systems with human teams, including FractalDB. In that setting, making a design real involved more than solving technical problems. Aligning priorities and carrying a direction through a team could take as much care as the implementation itself. I also put considerable effort into making sure I did not become the person holding everyone else up. I find myself worrying about the same thing with agents, and that sense of needing to keep their work moving can itself be exhausting.
Working with agents feels lighter. Even a large project carries less coordination overhead, and I can pursue my own design intentions more directly. Commissioning designers and securing people used to be essential to moving a project forward. Whether or not I have those skills myself, I can now readily ask an agent to take on such work. I still have to judge the result, but trying another approach no longer requires the same effort to arrange.
When I wrote the code by hand, the work could move at the speed of my own thinking. With agents, the next question, result, or decision can arrive before I have finished processing the last one. Across parallel projects, that pace sometimes exceeds what I can comfortably take in. I can feel as though there is no time to pause, even though the agents are doing more of the implementation. For me, less manual coding has not necessarily meant a less tiring working day.
Capable does not mean infallible. An agent may start implementing before clarifying a requirement, overlook an existing design policy, or produce code that works but does not fit the project's conventions. People also deliver imperfect work. The difference is partly in how I can respond.
With a human team, each iteration costs time and attention and can affect morale. Even a valid architectural refinement or coding-style correction has to be weighed against other priorities. Good collaboration includes deciding which changes justify asking people to revisit their work.
With an agent, asking for another revision feels lighter. I can revisit details I might previously have accepted as a practical compromise, while still having to make the requirements clear and judge whether the result actually meets them. If agents had feelings, though, mine might have quite a grudge against me by now.
There is satisfaction in directing work across several projects and seeing neglected software improve. It is a different satisfaction from solving each puzzle with my own hands. I do not think I need to pretend that nothing has been lost in order to acknowledge what I have gained.
4. If rebuilding becomes easier, what happens to OSS?
These experiences bring me back to the larger question. A substantial reason to reuse software has been the human effort required to build it. Agents are lowering that barrier enough that starting again can feel feasible even for fairly substantial software.
Previously, disagreeing with an open-source project's policies might lead me to accept the difference, propose a change, or maintain a fork. Now I also consider asking an agent to build an implementation around my own requirements. Adopting existing OSS no longer feels like the automatic first choice in every case for me. That is a change in my own decisions, not evidence that everyone will make the same choice.
That does not make the work free. Computation has substantial costs even when my marginal cost feels low within a subscription. Verification, security work, compatibility, and maintenance continue to consume resources. And non-commercial open source has never been motivated by economics alone. Curiosity and the desire to solve a problem are reasons to build something even when a reusable implementation exists.
Companies may make similar choices. An in-house implementation tailored to a business could become more attractive than a general package or SaaS product in some cases. Having source code locally also gives an agent something concrete to inspect and adapt. Whether that choice is economical over the whole lifecycle will depend on the organization and the software.
Shared knowledge and reusable implementations still have value, whether shared by individuals, within a company, across a specialist domain, publicly, or privately. I am consolidating what I learn into libraries and tools such as asciidoc-pubkit for publishing and git-history-cleaner for Git workflows. Reusing that knowledge helps me avoid solving the same operational problem repeatedly.
Libraries and tools also let me put repeatable operations into deterministic code instead of asking a model to interpret a skill and recreate the procedure each time. With fixed inputs, versions, and relevant environmental conditions, that code can provide behavior I can test and reproduce. A model-guided skill is useful for choosing and adapting a workflow, but its interpretation can vary between runs. Skills can call deterministic tools; I see value in combining that flexibility with a stable implementation underneath, rather than replacing every tool with instructions.
This also raises a question about collaboration. When building an alternative takes less effort, I may have less reason to accept upstream decisions or spend time negotiating a change with committers. Shared maintenance and knowledge still give me reasons to participate, but the balance may shift. Projects in which a small group holds decision-making authority may have to reconsider how they involve contributors if those contributors find it easier to leave and build something else. I do not know whether that will change governance, encourage more private implementations, or lead us back to shared foundations.
5. More progress, a different reason to build
Coding agents have made it more practical for me to develop new features, investigate security problems, and keep long-lived projects useful. My role has shifted toward choosing the work, giving it direction, and checking the result. The progress is real, but so is the responsibility that remains with me.
What surprised me was how much of the reward had come from the process itself. I was looking forward not only to finished software or working hardware, but to becoming the person who could understand and build it. Getting the result more easily does not necessarily give me that same satisfaction.
I have not settled what this means for my own motivation, or how easier alternatives will change my reasons to work with others on shared software. For now, I intend to keep developing and publishing what I make. I can value the work that coding agents have made possible while continuing to ask what I want from the act of building it.
