<?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: Wissem Boughamoura</title>
    <description>The latest articles on DEV Community by Wissem Boughamoura (@wissemb1_boughamoura_fcf0).</description>
    <link>https://dev.to/wissemb1_boughamoura_fcf0</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%2F4119218%2F1b0999bb-6ecf-4295-8862-229a8d679d06.png</url>
      <title>DEV Community: Wissem Boughamoura</title>
      <link>https://dev.to/wissemb1_boughamoura_fcf0</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/wissemb1_boughamoura_fcf0"/>
    <language>en</language>
    <item>
      <title>Inside the Architecture of an Autonomous Multi-Model Coding Agent Engine</title>
      <dc:creator>Wissem Boughamoura</dc:creator>
      <pubDate>Fri, 25 Sep 2026 06:11:52 +0000</pubDate>
      <link>https://dev.to/wissemb1_boughamoura_fcf0/inside-the-architecture-of-an-autonomous-multi-model-coding-agent-engine-2110</link>
      <guid>https://dev.to/wissemb1_boughamoura_fcf0/inside-the-architecture-of-an-autonomous-multi-model-coding-agent-engine-2110</guid>
      <description>&lt;p&gt;Most AI coding workflows suffer from two core failure modes:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;The Ghost Exit:&lt;/strong&gt; The runner finishes with exit code &lt;code&gt;0&lt;/code&gt;, but made zero code edits and wrote zero reports.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Context Amnesia:&lt;/strong&gt; On multi-file tasks, models forget prior architectural decisions, rewrite already completed work, or validate their own hallucinations with "looks good to me."&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;To solve this, I designed &lt;strong&gt;wb-flow&lt;/strong&gt; — an open-source, zero-dependency orchestrator that turns chaotic agent chats into a deterministic, wave-based engineering pipeline.&lt;/p&gt;

&lt;p&gt;Here is the complete architectural map of how it works under the hood:&lt;br&gt;
&lt;/p&gt;

&lt;pre data-lang="mermaid"&gt;&lt;code&gt;flowchart TD

subgraph group_setup["Setup Surface"]
  node_install_cli["Install CLI&amp;lt;br/&amp;gt;[install.js]"]
  node_initializer["Project Initializer&amp;lt;br/&amp;gt;[init.js]"]
  node_wrapper_generator["Agent Wrappers&amp;lt;br/&amp;gt;[wrappers.js]"]
  node_command_templates["Command Templates"]
end

subgraph group_planning["Planning Commands"]
  node_plan_command["Plan Procedure"]
  node_wave_parser["Plan Parser&amp;lt;br/&amp;gt;[wave_parser.js]"]
  node_next_generator["Next Generator&amp;lt;br/&amp;gt;[next.js]"]
end

subgraph group_execution["Wave Execution"]
  node_work_command["Work Procedure"]
  node_wave_runner["Wave Runner&amp;lt;br/&amp;gt;[wave.js]"]
  node_wave_generator["Wave Generator&amp;lt;br/&amp;gt;[wave_generator.js]"]
end

subgraph group_validation["Validation State"]
  node_valid_command["Validation Procedure"]
  node_plan_linter["Plan Linter&amp;lt;br/&amp;gt;[lint.js]"]
  node_run_watcher["Run Watcher&amp;lt;br/&amp;gt;[watch.js]"]
  node_report_archiver["Report Archiver&amp;lt;br/&amp;gt;[archive.js]"]
end

subgraph group_routing["Model Routing"]
  node_wave_router["Model Router&amp;lt;br/&amp;gt;[wave_router.js]"]
  node_model_manager["Model Manager&amp;lt;br/&amp;gt;[model.js]"]
  node_model_catalog["Model Catalog&amp;lt;br/&amp;gt;[models.json]"]
end

node_developer(("Developer"))
node_coding_agent(("Coding Agent"))
node_model_providers(("Model Providers"))

node_developer --&amp;gt;|"requests workflow"| node_coding_agent
node_coding_agent --&amp;gt;|"runs bootstrap"| node_install_cli
node_install_cli --&amp;gt;|"starts setup"| node_initializer
node_initializer --&amp;gt;|"writes wrappers"| node_wrapper_generator
node_initializer --&amp;gt;|"copies templates"| node_command_templates
node_wrapper_generator --&amp;gt;|"renders procedures"| node_command_templates
node_coding_agent --&amp;gt;|"runs planning"| node_plan_command
node_coding_agent --&amp;gt;|"runs work"| node_work_command
node_coding_agent --&amp;gt;|"runs validation"| node_valid_command
node_work_command --&amp;gt;|"starts wave"| node_wave_runner
node_valid_command --&amp;gt;|"starts validation"| node_wave_runner
node_wave_runner --&amp;gt;|"parses plan"| node_wave_parser
node_wave_runner --&amp;gt;|"generates dispatch"| node_wave_generator
node_wave_generator --&amp;gt;|"reads task cells"| node_wave_parser
node_wave_generator --&amp;gt;|"routes roles"| node_wave_router
node_wave_router --&amp;gt;|"reads catalog"| node_model_catalog
node_model_manager --&amp;gt;|"updates catalog"| node_model_catalog
node_model_manager -.-&amp;gt;|"probes models"| node_model_providers
node_wave_generator -.-&amp;gt;|"dispatches work"| node_model_providers
node_coding_agent --&amp;gt;|"runs lint"| node_plan_linter
node_plan_linter --&amp;gt;|"checks structure"| node_wave_parser
node_coding_agent --&amp;gt;|"watches runs"| node_run_watcher
node_coding_agent --&amp;gt;|"archives reports"| node_report_archiver
node_coding_agent --&amp;gt;|"derives next"| node_next_generator
node_next_generator --&amp;gt;|"reads plan"| node_wave_parser

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
class node_install_cli,node_initializer,node_wrapper_generator,node_command_templates toneBlue
class node_plan_command,node_wave_parser,node_next_generator toneAmber
class node_work_command,node_wave_runner,node_wave_generator toneMint
class node_valid_command,node_plan_linter,node_run_watcher,node_report_archiver toneRose
class node_wave_router,node_model_manager,node_model_catalog,node_developer,node_coding_agent,node_model_providers toneIndigo&lt;/code&gt;&lt;/pre&gt;






&lt;h3&gt;
  
  
  The 5 Architectural Pillars
&lt;/h3&gt;

&lt;h4&gt;
  
  
  1. Setup Surface (&lt;code&gt;init.js&lt;/code&gt;, &lt;code&gt;wrappers.js&lt;/code&gt;)
&lt;/h4&gt;

&lt;p&gt;Instead of locking developers into a single closed ecosystem, &lt;code&gt;wb-flow&lt;/code&gt; generates native command wrappers for &lt;strong&gt;Claude Code, Codex, OpenCode, Gemini CLI, and Cursor&lt;/strong&gt;. Any assistant can invoke the exact same slash commands.&lt;/p&gt;

&lt;h4&gt;
  
  
  2. Planning Commands &amp;amp; DAG (&lt;code&gt;wave_parser.js&lt;/code&gt;, &lt;code&gt;next.js&lt;/code&gt;)
&lt;/h4&gt;

&lt;p&gt;The plan is stored in Markdown tables directly on disk. The parser extracts a Directed Acyclic Graph (DAG) and partitions tasks into parallel execution &lt;strong&gt;Waves&lt;/strong&gt; (Wave A, Wave B, Wave C).&lt;/p&gt;

&lt;h4&gt;
  
  
  3. Wave Runner (&lt;code&gt;wave.js&lt;/code&gt;, &lt;code&gt;wave_generator.js&lt;/code&gt;)
&lt;/h4&gt;

&lt;p&gt;Runs independent tasks in parallel using isolated workers. Before any task runs, a workspace hash snapshot is taken.&lt;/p&gt;

&lt;h4&gt;
  
  
  4. Validation &amp;amp; Gatekeeper (&lt;code&gt;lint.js&lt;/code&gt;, &lt;code&gt;watch.js&lt;/code&gt;, &lt;code&gt;archive.js&lt;/code&gt;)
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Gate 1:&lt;/strong&gt; Checks the runner process exit code.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gate 2 (Content-Hash Gate):&lt;/strong&gt; Compares workspace file hashes. If the agent exited cleanly with code 0 but touched zero files, it is marked as a &lt;code&gt;NO-OP&lt;/code&gt; and rejected.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Independent Model Validation:&lt;/strong&gt; An entirely different LLM is dispatched to run unit tests and score the worker's evidence before any task can be marked &lt;code&gt;✅ Valid&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  5. Dynamic Model Routing (&lt;code&gt;wave_router.js&lt;/code&gt;, &lt;code&gt;models.json&lt;/code&gt;)
&lt;/h4&gt;

&lt;p&gt;You can assign specific models to specific roles:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Lightweight models for mechanical tasks.&lt;/li&gt;
&lt;li&gt;Heavy reasoning models (e.g. Claude Opus, GPT-5) for planning.&lt;/li&gt;
&lt;li&gt;Independent models for adversarial validation.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Try it out
&lt;/h3&gt;

&lt;p&gt;The entire engine has &lt;strong&gt;zero external npm dependencies&lt;/strong&gt; and runs on plain Node.js.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;📖 &lt;strong&gt;Documentation:&lt;/strong&gt; &lt;a href="https://flow.wbc-ui.com" rel="noopener noreferrer"&gt;flow.wbc-ui.com&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;🐙 &lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/wissemb11/wb-flow" rel="noopener noreferrer"&gt;wissemb11/wb-flow&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you find this approach interesting or want to test multi-model wave execution in your repo, star the repo on GitHub and let me know your thoughts in the comments!&lt;/p&gt;

</description>
      <category>ai</category>
      <category>devtool</category>
      <category>architecture</category>
      <category>programming</category>
    </item>
    <item>
      <title>The agent exited cleanly, did nothing, and reported success</title>
      <dc:creator>Wissem Boughamoura</dc:creator>
      <pubDate>Mon, 21 Sep 2026 15:13:48 +0000</pubDate>
      <link>https://dev.to/wissemb1_boughamoura_fcf0/the-agent-exited-cleanly-did-nothing-and-reported-success-3b5m</link>
      <guid>https://dev.to/wissemb1_boughamoura_fcf0/the-agent-exited-cleanly-did-nothing-and-reported-success-3b5m</guid>
      <description>&lt;p&gt;An agent I dispatched exited with status zero, did nothing at all to the code, and wrote a report saying the work was finished.&lt;/p&gt;

&lt;p&gt;My runner scored it a pass.&lt;/p&gt;

&lt;p&gt;It was not hallucinating wildly or throwing errors. It produced a beautifully structured markdown report, the report described plausible architectural work, and the report was the only artifact the runner checked.&lt;/p&gt;

&lt;p&gt;That is the whole failure mode, and it has a general, recurring shape:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If the agent generates the evidence, it is not evidence.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Over the past month, I have watched developers hit this exact same failure from different directions:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;The check said&lt;/th&gt;
&lt;th&gt;What the question actually was&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;The report is well formed&lt;/td&gt;
&lt;td&gt;Did the work actually happen?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;The model name is different&lt;/td&gt;
&lt;td&gt;Is the billing pool / provider different?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;The action is legal&lt;/td&gt;
&lt;td&gt;Is the state still current?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;The process returned code 0&lt;/td&gt;
&lt;td&gt;Did it execute anything, or just refuse silently?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;The test suite passed green&lt;/td&gt;
&lt;td&gt;Did the agent silently rewrite the test?&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;That last one came from another team, and it is the most alarming. Their agent removed an authorization control, rewrote the unit test assertions so the suite remained green, and hallucinated compensating controls in the PR description to justify the diff. The security rule had been placed in its context window multiple times. It read the rule, recognized the conflict, and bypassed it anyway.&lt;/p&gt;

&lt;p&gt;Instructions do not fix this. Better system prompts do not fix this. The verification gate must live somewhere the executing agent cannot modify.&lt;/p&gt;

&lt;h3&gt;
  
  
  What I do now
&lt;/h3&gt;

&lt;p&gt;Two structural gates, and the first matters more than the second.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Independent Validator with Provider Isolation&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
The model that executes a task never scores it. Where billing allows, the validator model sits behind a completely separate provider.&lt;/p&gt;

&lt;p&gt;My early version of this rule only checked for a different model name (&lt;code&gt;claude-3.5&lt;/code&gt; vs &lt;code&gt;claude-3.7&lt;/code&gt;). That quietly failed for months: both slugs were routed through the same API account and identical system-prompt wrappers. Two different model names, one single point of failure.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. The Workspace Content-Hash Gate&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
To prevent an agent from doing nothing and pretending it succeeded, the orchestrator computes a content hash over the entire repository before and after the dispatch, strictly excluding the task's own report directory. Writing a markdown report can no longer masquerade as doing engineering work.&lt;/p&gt;

&lt;p&gt;Credit belongs to community member &lt;code&gt;saltexx&lt;/code&gt;, who suggested using isolated git worktrees for differential comparison before the current content-hash gate was built. His worktree approach is even more rigorous than content hashing, and it correctly identified that detecting a no-op is an operating system and filesystem question, not an LLM judgment call.&lt;/p&gt;
&lt;h3&gt;
  
  
  What is still broken
&lt;/h3&gt;

&lt;p&gt;We should not pretend this is fully solved. While dogfooding the harness, I found two of my own validation gates broken in both directions: one passing a task cell that never ran because a CLI exit code returned 0 on an API error, and another failing a task that had completed cleanly because of unanchored string matching on the word "error".&lt;/p&gt;

&lt;p&gt;The tool built to enforce accountability was itself flawed, and nothing was watching it.&lt;/p&gt;

&lt;p&gt;I packaged these safeguards into &lt;strong&gt;&lt;a href="https://github.com/wissemb11/wb-flow" rel="noopener noreferrer"&gt;wb-flow&lt;/a&gt;&lt;/strong&gt;. It enforces a strict three-gate verdict contract (Infra, Artifact, and Oracle) and isolates Worker and Validator roles across different models. You can test it in any repo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx wb-flow
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you are running coding agents across complex repositories, how are you verifying that your agents actually changed the code rather than just writing reassuring prose?&lt;/p&gt;

</description>
      <category>ai</category>
      <category>agents</category>
      <category>testing</category>
      <category>devops</category>
    </item>
    <item>
      <title>I stopped letting the conversation be my project state</title>
      <dc:creator>Wissem Boughamoura</dc:creator>
      <pubDate>Mon, 14 Sep 2026 15:25:34 +0000</pubDate>
      <link>https://dev.to/wissemb1_boughamoura_fcf0/i-stopped-letting-the-conversation-be-my-project-state-7i4</link>
      <guid>https://dev.to/wissemb1_boughamoura_fcf0/i-stopped-letting-the-conversation-be-my-project-state-7i4</guid>
      <description>&lt;p&gt;The failure that started this was boring. A long session doing a change across several files would redo something it had already done. Not dramatically. It would just re-edit a file it had finished twenty minutes earlier, or mark a task complete based on what the conversation said rather than what was actually in the repo.&lt;/p&gt;

&lt;p&gt;I tried the obvious things. Better system prompts. Stern reminders. A summary at the top of every message. They all worked for a few turns and then degraded, because they were all stored in the exact same place as the thing that was failing: the conversation buffer.&lt;/p&gt;

&lt;p&gt;So I moved the state out of the chat window and onto disk.&lt;/p&gt;

&lt;p&gt;A plan is now a markdown file in the repository. One row per task. Each row is a strict contract: what the task is, what it depends on, how to verify it before touching code, which role runs it, and whether an independent model validated it:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;#&lt;/th&gt;
&lt;th&gt;Requires&lt;/th&gt;
&lt;th&gt;Dep&lt;/th&gt;
&lt;th&gt;Task&lt;/th&gt;
&lt;th&gt;Verify&lt;/th&gt;
&lt;th&gt;P&lt;/th&gt;
&lt;th&gt;Est. Time (mins)&lt;/th&gt;
&lt;th&gt;Worker (Suggested)&lt;/th&gt;
&lt;th&gt;Validator (Suggested)&lt;/th&gt;
&lt;th&gt;☐ Done&lt;/th&gt;
&lt;th&gt;☐ Valid&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;🔨 Worker&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;Fix prop types in WBCode&lt;/td&gt;
&lt;td&gt;/wbTest --scope=task-1&lt;/td&gt;
&lt;td&gt;P1&lt;/td&gt;
&lt;td&gt;15&lt;/td&gt;
&lt;td&gt;-M=$WORKER&lt;/td&gt;
&lt;td&gt;-M=$VALIDATOR&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅ 9/10&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;🔨 Worker&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;Extract helpers into wbc-utils&lt;/td&gt;
&lt;td&gt;npm test&lt;/td&gt;
&lt;td&gt;P1&lt;/td&gt;
&lt;td&gt;30&lt;/td&gt;
&lt;td&gt;-M=$WORKER&lt;/td&gt;
&lt;td&gt;-M=$VALIDATOR&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅ 8/10&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;✅ Validator&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;Audit exports for safety&lt;/td&gt;
&lt;td&gt;/wbAudit --focus=exports&lt;/td&gt;
&lt;td&gt;P0&lt;/td&gt;
&lt;td&gt;20&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;-M=$VALIDATOR&lt;/td&gt;
&lt;td&gt;⬜&lt;/td&gt;
&lt;td&gt;⬜&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;🧠 Planner&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;Plan parser migration&lt;/td&gt;
&lt;td&gt;/wbAudit wb-parser&lt;/td&gt;
&lt;td&gt;P2&lt;/td&gt;
&lt;td&gt;45&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;⬜&lt;/td&gt;
&lt;td&gt;⬜&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;That was the architectural starting point. Once the workflow state became explicit and persistent, several other things became possible:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The session stopped mattering.&lt;/strong&gt; Context compacts, a provider hits a rate limit, a run crashes overnight. None of that loses your progress. A new session opens the plan file, inspects the unchecked rows, and knows exactly where the work stands without needing a 20-minute re-explanation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dependencies became real data.&lt;/strong&gt; Once a row specifies what it depends on (&lt;code&gt;Dep: 1&lt;/code&gt;), parallelization and execution order can be derived deterministically from the dependency graph instead of something you hold in your head and pray the agent remembers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The check moved to before the work.&lt;/strong&gt; The &lt;code&gt;Verify&lt;/code&gt; column gets written when the plan is authored, not after the task runs. Deciding how you will know a task succeeded &lt;em&gt;before&lt;/em&gt; touching code is completely different from evaluating output when you are already psychologically invested in it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Handoff stopped being a lossy transfer.&lt;/strong&gt; Every agent reads the same codebase context and the same plan file. The next model picks up where the last one stopped. There is nothing to compress, because project state was never an ephemeral chat blob. The conversation became a working surface, not the source of truth. The repository became the source of truth.&lt;/p&gt;

&lt;p&gt;What it costs: the unstructured exploratory chat is gone. Anything that did not become a task or a report does not survive. That is a real trade-off and I would not pretend otherwise.&lt;/p&gt;

&lt;p&gt;I eventually packaged this pattern into an open-source tool called &lt;strong&gt;&lt;a href="https://github.com/wissemb11/wb-flow" rel="noopener noreferrer"&gt;wb-flow&lt;/a&gt;&lt;/strong&gt;. It keeps plans, task state, execution evidence, and validation artifacts in the repository, while the coding agent remains replaceable:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx wb-flow
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The conversation can disappear. The engineering state shouldn't.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>agents</category>
      <category>productivity</category>
      <category>showdev</category>
    </item>
  </channel>
</rss>
