<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Vibe Coding on scripting.pro</title><link>https://scripting.pro/tags/vibe-coding/</link><description>Recent content in Vibe Coding on scripting.pro</description><image><title>scripting.pro</title><url>https://scripting.pro/images/og-featured.png</url><link>https://scripting.pro/images/og-featured.png</link></image><generator>Hugo</generator><language>en-us</language><lastBuildDate>Mon, 02 Nov 2026 12:00:00 -0500</lastBuildDate><atom:link href="https://scripting.pro/tags/vibe-coding/index.xml" rel="self" type="application/rss+xml"/><item><title>Keeping Control of Code You No Longer Write</title><link>https://scripting.pro/posts/keeping-control-of-code-you-no-longer-write/</link><pubDate>Mon, 02 Nov 2026 12:00:00 -0500</pubDate><guid>https://scripting.pro/posts/keeping-control-of-code-you-no-longer-write/</guid><description>When a model writes most of the code, the first thing to degrade is knowing what the system already contains. Generated maps, checked by tests that fail as messages to the model, keep that knowledge executable: a structural counterpart to executable specifications.</description><content:encoded><![CDATA[<h2 id="the-problem-is-knowing-what-already-exists">The problem is knowing what already exists</h2>
<p>In my experience, when a model writes most of your code, the first thing to degrade is not code quality. It is your knowledge of what the system already contains.</p>
<p>I discovered this in a surprisingly ordinary question: <em>How friendly must a character be to count as a friend?</em></p>
<p>My project had five answers. <code>FriendThreshold = 10</code> appeared as a private constant in three files. Two more files used <code>BestFriendThreshold = 20</code> and <code>FriendRelationThreshold = 20</code> for a neighbouring question. Each class was clean. Nothing was obviously broken. Yet the same area of the domain had quietly acquired five separate decisions.</p>
<p>The project is a mod for a strategy game, in production since June 2026, with more than 5,300 unique downloads. I built it entirely with an AI model and have not written a line of its code. I do not review that code either: with my experience as a developer, reviewing every line would cost about as much as writing it, and speed is the reason I work this way. I have never played the mod.</p>
<p>That unusual arrangement changed my relationship with the software. The model begins each session without the knowledge carried through earlier conversations; unless something directs it to an existing concept, it has no reason to look for one it does not know exists. Meanwhile, as I moved from writing code to describing what I wanted, I lost the small design moments that used to happen while typing: pausing over a name, noticing a familiar rule, questioning where something belonged.</p>
<p>I had stopped being the coder of the system and become its customer, while remaining responsible for its architecture.</p>
<p>I needed a way to keep making architectural decisions without relying on having read every implementation.</p>
<h2 id="why-better-instructions-do-not-fix-it">Why better instructions do not fix it</h2>
<p>My first answer was the obvious one: tell the model what good code should look like.</p>
<p>From the beginning, I had detailed instructions about layering, SOLID and Tell, Don&rsquo;t Ask, alongside specifications and other guardrails. The five thresholds appeared anyway. Each class could follow the rules perfectly while the duplication emerged <em>between</em> classes.</p>
<p>An instruction to a model is advice, not a constraint. It helps only if the model considers it at the right moment, among thousands of other tokens. There is no automatic alarm when it does not. My instructions file eventually described 16 sections of a prompt that had grown to 108.</p>
<p>Generated documentation was not enough either. One file listed every rule guaranteed by a test, with a header telling readers to regenerate it when the tests changed. Ten days passed without regeneration. The document fell about 600 rules behind, but looked as authoritative as ever.</p>
<p>That was the problem with both approaches: nothing forced the description to remain aligned with reality.</p>
<p>A document stays trustworthy only if something compares it with the system whenever the system changes, and refuses to let a difference go unnoticed.</p>
<p>Others have approached the same problem from another direction. In a <a href="https://youtu.be/EkH_uoybj8k">recent video</a>, Dave Farley describes a growing consensus that prompts and Markdown specifications cannot reliably steer an agent on their own. Specifications need to be executable. His acceptance tests establish <em>what</em> the system must do while leaving the agent freedom over <em>how</em> it does it.</p>
<p>But that freedom is exactly where my five thresholds came from. All five implementations could satisfy the behavioural tests. The behaviour was correct; the structure was drifting. Acceptance tests deliberately avoid prescribing implementation structure, so I needed their counterpart: executable checks on the parts of the <em>how</em> that matter architecturally.</p>
<h2 id="a-map-a-generated-view-held-true-by-a-test">A map: a generated view, held true by a test</h2>
<p>The first mechanism was simple: generate a map of the code, commit it, and make a test fail whenever the code and the committed map disagree.</p>
<p>This is approval testing applied to structure rather than output. A small generator reads the source as text, using a syntax parser rather than requiring a build, and produces Markdown.</p>
<p>For example, the top of a real constants map groups names declared in multiple places:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt" id="hl-0-1"><a class="lnlinks" href="#hl-0-1">1</a>
</span><span class="lnt" id="hl-0-2"><a class="lnlinks" href="#hl-0-2">2</a>
</span><span class="lnt" id="hl-0-3"><a class="lnlinks" href="#hl-0-3">3</a>
</span><span class="lnt" id="hl-0-4"><a class="lnlinks" href="#hl-0-4">4</a>
</span><span class="lnt" id="hl-0-5"><a class="lnlinks" href="#hl-0-5">5</a>
</span><span class="lnt" id="hl-0-6"><a class="lnlinks" href="#hl-0-6">6</a>
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">## One name, several homes
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">| Name            | Where, and what it is worth there                           |
</span></span><span class="line"><span class="cl">|-----------------|-------------------------------------------------------------|
</span></span><span class="line"><span class="cl">| ArrivalDistance | AmbushBehavior = 2.5; MissionBehavior = 2.0; PatrolBehavior = 2.0 |
</span></span><span class="line"><span class="cl">| CooldownDays    | EncounterService = 1; AmbitionPolicy = 30; DuelPolicy = 7   |
</span></span></code></pre></td></tr></table>
</div>
</div><p>Not every repeated name is a defect. Sometimes two declarations represent one concept that should have one home; sometimes they are different concepts with similar names. The map does not decide. It brings the question into view so someone can.</p>
<p>From then on, each change produces two kinds of diff. The code diff shows what was edited. The map diff shows what changed about the system&rsquo;s structure: perhaps a new dependency between modules, or another declaration of an existing name. Even an unchanged map tells me something about the scope of a change.</p>
<p>Of course, a test helps only if it runs. A pre-commit hook or a pipeline can provide the trigger. My mod needs the game&rsquo;s libraries and cannot be built on a server, so I run the checks locally. In a team, the checks and their baselines belong in protected continuous integration, beyond the agent&rsquo;s ability to approve its own exceptions.</p>
<p>The underlying idea is not new. Neal Ford, Rebecca Parsons and Patrick Kua describe architectural fitness functions; ArchUnit, NDepend and PublicApiAnalyzers cover important parts of this territory. My maps address questions specific to the system, including cases where the code cannot be compiled in the test environment.</p>
<p>The closest recent practice is what OpenAI calls <a href="https://openai.com/index/harness-engineering/">harness engineering</a>, described in February 2026: architecture documentation kept consistent through linters and CI, structural tests that enforce layering, and repository maps that help agents navigate the code. That work focuses on the environment in which agents produce a coherent system. I am interested in the other side of the loop: <strong>how the person responsible for the architecture continues to judge it without reading all the code.</strong></p>
<h2 id="a-failing-test-is-a-message-to-the-model">A failing test is a message to the model</h2>
<p>The maps became useful for a reason I had not initially appreciated: <em>when</em> their information appeared.</p>
<p>An instruction says, &ldquo;Remember this rule.&rdquo; A failing test says, &ldquo;Something you just changed affects this rule. Look at it now.&rdquo;</p>
<p>The second message arrives while the model is still working on the change. The suite remains red until the discrepancy is addressed. A red map test does not necessarily mean the software is broken; it means a structural change requires attention.</p>
<p>That only works if the failure explains itself. My tests show the moved lines and, where a contract blocks a change, the reason it is blocked and how to handle an intentional exception.</p>
<p>Here is a real failure, triggered deliberately by deleting a public API member that had shipped in the previous release:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt" id="hl-1-1"><a class="lnlinks" href="#hl-1-1">1</a>
</span><span class="lnt" id="hl-1-2"><a class="lnlinks" href="#hl-1-2">2</a>
</span><span class="lnt" id="hl-1-3"><a class="lnlinks" href="#hl-1-3">3</a>
</span><span class="lnt" id="hl-1-4"><a class="lnlinks" href="#hl-1-4">4</a>
</span><span class="lnt" id="hl-1-5"><a class="lnlinks" href="#hl-1-5">5</a>
</span><span class="lnt" id="hl-1-6"><a class="lnlinks" href="#hl-1-6">6</a>
</span><span class="lnt" id="hl-1-7"><a class="lnlinks" href="#hl-1-7">7</a>
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">Failed GIVEN_a_released_modder_api_member_WHEN_the_code_no_longer_has_it_THEN_the_suite_refuses_it
</span></span><span class="line"><span class="cl">  These public members shipped in v2.8.1 and are no longer there:
</span></span><span class="line"><span class="cl">  CrLetters: static bool Deliver(Hero sender, string body, string sourceMod)
</span></span><span class="line"><span class="cl">  A bridge built on them breaks on a player&#39;s machine. Put the member back (mark it
</span></span><span class="line"><span class="cl">  [Obsolete] and keep it working if it must go), or, if removing it is truly intended,
</span></span><span class="line"><span class="cl">  set CR_ALLOW_API_REMOVAL=1, name it under &#34;For modders&#34; in the release notes,
</span></span><span class="line"><span class="cl">  and say why in the commit.
</span></span></code></pre></td></tr></table>
</div>
</div><p>The failure identifies the missing promise, explains whom the change would affect, and offers two legitimate responses: preserve compatibility or explicitly acknowledge a breaking change.</p>
<p>The timing is not perfect. The test fires <em>after</em> code has been written, so reading a map before editing is still preferable. The test catches what that habit missed, sometimes at the cost of rework.</p>
<p>Still, this is the insight I find most transferable. Farley uses a red test to show that a specification can reject a wrong answer. Here, the failure is also a communication channel. <strong>Designing tests around what they tell the agent when they fail matters as much as deciding what they check.</strong></p>
<h2 id="what-makes-a-map-worth-reading">What makes a map worth reading</h2>
<p>A map only earns its place if reading it is cheaper than reading the code.</p>
<p>In practice, I aim for one fact per line, with enough context (owner, name and value) for that line to make sense when an agent retrieves it through search rather than reading the document from top to bottom.</p>
<p>There is a limit to what such a map can claim. It gathers what the source declares, and its reliability depends on the names and comments it finds. Missing documentation leaves a visible gap. A misleading name is worse: it can make an incorrect description look complete.</p>
<blockquote>
<p>A map cannot be more honest than the names it reads.</p>
</blockquote>
<p>I learned this through a detector for hard-coded relationship thresholds. The first version searched for relevant names, and its count appeared stable for months. Then I added a detector for comparisons between relationship values and numeric literals. It found 33 cases the original had missed.</p>
<p>The map now records which detector produced each line, so a reader can distinguish directly extracted facts from inferred matches. Generation makes the output reproducible. It does not make the interpretation true.</p>
<h2 id="when-informative-maps-stop-informing">When informative maps stop informing</h2>
<p>Most maps inform: the test fails, someone inspects the diff, regenerates the approved snapshot, and commits it.</p>
<p>That process can lose its purpose without anyone noticing.</p>
<p>The model had started regenerating maps <em>before</em> checking them. Each test then compared the new map with itself and passed. This went on for weeks. Once I corrected the order (<strong>compare first, inspect the changes, then regenerate to approve</strong>), the first honest review exposed a blind spot in my dependency detection.</p>
<p>Even with the right order, attention is fragile. A review can slowly become a ritual of &ldquo;regenerate and commit.&rdquo; That is why I now treat informative maps as the fallback, not the goal.</p>
<p>For every map, I ask: can a rule decide whether a change is acceptable? If the question is &ldquo;Did this measure get worse?&rdquo;, often it can. If the question is &ldquo;Do these two declarations mean the same thing?&rdquo;, the answer still needs human judgment.</p>
<p>That distinction led me to two stronger mechanisms: ratchets and contracts.</p>
<h3 id="ratchets-make-yesterdays-debt-the-ceiling">Ratchets: make yesterday&rsquo;s debt the ceiling</h3>
<p>A ratchet preserves a measure that is allowed to improve but not worsen. The current value becomes a ceiling. If the measure rises, the test fails. If it falls, the ceiling must be lowered in the same commit.</p>
<p>That last step matters. Without it, a cleanup does not protect its own gains: the old ceiling would permit the debt to return.</p>
<blockquote>
<p>Today&rsquo;s mess becomes tomorrow&rsquo;s ceiling.</p>
</blockquote>
<p>This makes ratchets practical on legacy code. I do not have to eliminate every existing problem before I can prevent new ones.</p>
<p>The measure must also reflect the problem. For dependency cycles, I compare the <em>set of namespaces involved</em>, not just the number of cycles. Splitting one namespace can increase the number of counted cycles without actually worsening the architecture.</p>
<p>A ratchet gives an agent a direction it can test. &ldquo;Improve the architecture&rdquo; is vague. A ceiling of 46 is concrete: reduce it, confirm the test, and update the baseline. When one of my ratchets reached zero, it became a wall. The debt it measured had turned into a rule prohibiting its return.</p>
<p>That does not mean maps or ratchets improve architecture by themselves. They expose relations and prevent certain regressions. Someone still has to decide what should change and why.</p>
<p>And a guard protects only what it can detect. My first dependency map read <code>using</code> directives, but missed references expressed through fully qualified names. Real cycles escaped detection while the ratchet stayed green.</p>
<p>A good way to test a guard is to make it fail on purpose. Remove a public member. Introduce a cycle through a qualified name. If the suite stays green, the apparent protection is an illusion.</p>
<p>Farley also warns about agents removing tests to make a suite pass. The same applies to baselines: lowering a ceiling as debt improves can be automatic, but raising one, or editing a released contract reference, changes the specification itself and should require a person&rsquo;s approval.</p>
<h3 id="contracts-protect-promises-made-outside-the-codebase">Contracts: protect promises made outside the codebase</h3>
<p>Some structural changes are not merely worth reviewing. They break promises to consumers: a key stored in a player&rsquo;s save file, for example, or a public member that another mod compiles against.</p>
<p>For these, I use blocking contract maps. If a released member disappears, the suite fails even when someone tries to regenerate the map. The baseline is the last released state, stored separately and updated only at release. Otherwise, accepting a new snapshot could quietly erase the very promise the guard exists to protect.</p>
<p>Sometimes additions break compatibility too. In a second project, each new feature added required fields to an export format. A file written an hour earlier could no longer be imported. The map displayed ten apparently harmless added lines; the model recognized the consequence during review. The guard now rejects new required fields relative to the last release, and an original exported file remains as a regression check.</p>
<p>A useful contract must identify the <em>consumer&rsquo;s promise</em>, not the implementation detail behind it. During a retrospective replay of Jellyfin, a contract whose identity included the handler method generated 112 alarms on a single commit that only moved files. Keyed on the promise alone, verb and route, the same contract raised two alarms in thirteen and a half years, both on real losses.</p>
<p>A gate&rsquo;s usefulness depends on its false-alarm rate. If it cries wolf often enough, people switch it off, however sound its underlying logic. The stable identity is the one the consumer actually depends on.</p>
<p>Contract maps have another benefit: they let me review design decisions without opening the code.</p>
<p>After a bug report from another mod author, the model proposed a new public API member: <code>PlayerIsActor</code>, a boolean. I saw the addition in the API map and asked whether other mods should have to understand <em>my</em> mod&rsquo;s notion of a player&rsquo;s deed.</p>
<p>They should not. The model replaced the flag with a list of the heroes who acted, leaving my mod to draw its own conclusion. The member had not shipped, so this took one commit rather than a breaking release.</p>
<p>I did not need to read the implementation to make that decision. The contract showed me the shape of the promise at the level where I could judge it. Farley argues that executable specifications can make code reading a choice based on risk. A structural contract can do the same for architecture.</p>
<h3 id="decision-tables-check-the-behaviour-of-a-refactor">Decision tables: check the behaviour of a refactor</h3>
<p>One kind of map goes beyond reading source code. It runs rules.</p>
<p>A decision table sweeps a value across its range, records the output of every rule that depends on that value alone, and commits the result. When a refactor is meant to preserve behaviour, the expected diff is empty. &ldquo;I only moved code&rdquo; becomes something that can be checked.</p>
<p>The limitation is equally important: a rule combining the swept value with other inputs remains outside that table&rsquo;s view.</p>
<h2 id="what-maps-cannot-see">What maps cannot see</h2>
<p>My first maps largely catalogued names. But two rules can represent the same concept without sharing a name.</p>
<p>When the model added a rule based on a clan&rsquo;s rank, it searched the constants map and found one existing rule. A direct source search found two more, neither represented by a named constant.</p>
<p>So we changed the question. Instead of asking <em>what are the rules called?</em>, we asked <em>what game facts do they read?</em></p>
<p>The resulting map follows values from the game into pure rules and groups those rules by the facts they consume. Under clan rank, it revealed 28 entries covering roughly fifteen distinct features, where the manual search had found three.</p>
<p>This gave us enough visibility for a refactor: rank became a single type accessed through one gateway, and the map confirmed that rules no longer read the raw value directly.</p>
<p>Then the model reached a harder question: <em>What counts as a ruler?</em> Eighteen rules gave answers that were not equivalent. The map could collect every reader of the concept. It could not decide what the concept was supposed to mean.</p>
<p>Static maps have other boundaries. Because they read source, they cannot tell me what the game engine actually does at runtime. Each feature that interacts with the engine therefore has a self-test, launched through the game console against a real save and the production code path, with game state restored afterwards. One such test revealed that the engine reuses identifiers of destroyed entities, something tests outside the engine had not exposed.</p>
<p>The mod also uses a language model internally. Putting a fact into a prompt does not ensure the model will behave as expected. Where a rule can be checked literally, I check it literally: a secret name never included in the prompt must not appear in the reply. I reserve model-as-judge tests for cases that cannot be verified that way, and run them on demand because they cost money.</p>
<p>These checks complement the maps; they do not make the maps comprehensive.</p>
<h2 id="where-intent-comes-from">Where intent comes from</h2>
<p>There is an objection worth confronting. If a test is generated from existing code, does it do anything more than confirm the code&rsquo;s current behaviour? Where does the intended design come from?</p>
<p>Informative maps do not claim to verify intent. They describe what the source currently contains and make changes to that description visible. Intent enters when someone decides which changes are acceptable, which measures must not worsen, and which promises must remain stable.</p>
<p>Behavioural intent needs a home as well. In my project, it lives in tests. Each test file begins by describing how the rule could go wrong, recorded when the rule was decided. For example, the policy allowing a player&rsquo;s spouse to request a divorce names two opposite failures: a happy marriage disturbed by unsolicited letters, and a miserable one in which nobody ever speaks up. Some tests even cite the question I asked that led to the rule.</p>
<p>Intent is easiest to capture when it is formed. Later, we can only reconstruct it.</p>
<p>One problem remains unsolved. When the same model writes both implementation and tests, the tests can end up confirming whatever the implementation already does. Evidence from outside the loop helps: reports from real users, translated into regression tests, and a human reviewing the structural diffs.</p>
<h2 id="testing-the-idea-beyond-my-own-project">Testing the idea beyond my own project</h2>
<p>I wanted to know whether the structural patterns I was seeing were peculiar to AI-generated code. So I turned to software developed in the more traditional way: Jellyfin, an open-source media server with thirteen and a half years of history, about thirty maintainers and mandatory code review.</p>
<p>I replayed the generators over all 11,221 commits. If ordinary review eliminated this kind of structural drift, the maps should have found little worth surfacing. They found considerably more, but what they found needs to be interpreted carefully.</p>
<table>
	<thead>
			<tr>
					<th>Question</th>
					<th>What the replay showed</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td>Does review catch scattered concepts?</td>
					<td>Constant names declared in several modules: 119 episodes, median survival 390 days. Type names: 176 episodes, 535 days. These are candidates, not confirmed duplicates.</td>
			</tr>
			<tr>
					<td>Does a contract identity matter?</td>
					<td>Keyed on verb, route and handler: 112 alarms on one commit that only moved files. Keyed on the promise alone: 2 alarms in 13.5 years, both real.</td>
			</tr>
			<tr>
					<td>Is a ratchet quiet?</td>
					<td>Namespaces in cycles held at 41 for seven years, then jumped to 54. A ratchet set in 2018 fires about four times a year.</td>
			</tr>
			<tr>
					<td>What does reading maps cost?</td>
					<td>About one commit in three moves an informing map; the median diff is two or three lines.</td>
			</tr>
			<tr>
					<td>What do maps miss?</td>
					<td>65% of bug fixes and 42% of refactors move no map line at all.</td>
			</tr>
	</tbody>
</table>
<p>The last row matters as much as the others. Many meaningful changes do not appear in these maps. That is why they need behavioural and runtime checks alongside them.</p>
<p>The replay also has clear limits. It shows what the maps <em>would have displayed</em>, not what a reviewer <em>would have done</em>. And the cycle figures may undercount real dependencies if the replayed generator shared the blind spot I found in my own project.</p>
<p>My forward evidence comes from the mod itself. It has been in production since June 2026, carries more than 6,600 unit tests and over 200 in-game self-tests, and ships updates frequently: a player recently remarked that a new one appears roughly every three days. One project developed by one person demonstrates that the approach can be used, not that it improves outcomes for every team.</p>
<p>I also tried the method on a smaller project in another language. I asked a model to create a Postman-like HTTP client in JavaScript, with maps present from the first commit, and later asked it to evaluate its own architecture. I wrote no code.</p>
<p>In roughly an hour and a half and twelve commits, similar drift appeared: small rules were rewritten beside their originals, and a main file grew from 237 to 353 lines through individually reasonable additions. A subsequent split brought it down to 25 lines. On a fresh project, ratchets can start at zero and act as walls from day one, rather than freezing an existing level of debt.</p>
<p>This was still a short experiment with the same author, model and skill, not an independent team trial. The <a href="https://github.com/LogRaam/A-Postman-Alternative">repository</a> preserves the commit history for inspection.</p>
<h2 id="where-to-start-and-why-this-matters-now">Where to start, and why this matters now</h2>
<p>I would not begin by mapping everything.</p>
<p>Start with one generated map and a test that compares it against the committed version. Protect any contracts with external consumers. Then add maps and guards in response to problems you have actually encountered more than once. Each map should earn its place by making a recurring architectural decision visible when it arises.</p>
<p>I packaged this approach as an agent skill. Its <a href="https://github.com/LogRaam/My-Claude-Skills/blob/main/generated-maps/README.md">README</a> covers generators, test patterns and a suggested adoption order.</p>
<p>Why do this now? Because the economics of change have shifted. With an AI model, writing or rewriting an implementation has become cheap enough that I often prototype and correct rather than specify everything in advance, but finding out <em>what deserves correction</em> has not become cheaper. Verification matters as much as before; it now lives less in specifications written before implementation and more in checks that run whenever implementation changes.</p>
<p>We used to write code so our colleagues could understand it. Now we also need to preserve <em>why</em> it was written for a reader who has no memory of the conversation that produced it. More and more often, that reader is the model itself.</p>
<p>The developer&rsquo;s role changes with it. Someone who delegates implementation becomes responsible for an architecture they can no longer keep in their head by reading each line as it is written.</p>
<p>Maps do not restore that lost familiarity. They provide something different: a view of the system that cannot quietly drift without a test noticing, and that arrives when a change makes it relevant. Combined with explicit constraints and human judgment, that can be enough to keep making sound architectural decisions about code we no longer remember writing.</p>
<hr>
<p><em>Gabriel Mailhot is a Senior Subject Matter Expert at Desjardins, where he works on development practices, architecture, and complex organizational problems spanning technology, process, and governance. He publishes at scripting.pro.</em></p>
]]></content:encoded></item></channel></rss>