<script data-pm-proxy="intercept"></script><?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:googleplay="http://www.google.com/schemas/play-podcasts/1.0"><channel><title><![CDATA[Limitless Ledger]]></title><description><![CDATA[Positioning, planning and progress in your personal and career development. We're building a SaaS product to highlight your skills, match with people and companies of interest, and understand where you want to learn, teach, and grow next.]]></description><link>https://limitlessledger.substack.com</link><image><url>https://substackcdn.com/image/fetch/$s_!wTF-!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbd332c66-0018-42b1-ae21-9b36fd2806f3_1080x1080.png</url><title>Limitless Ledger</title><link>https://limitlessledger.substack.com</link></image><generator>Substack</generator><lastBuildDate>Tue, 01 Sep 2026 17:21:09 GMT</lastBuildDate><atom:link href="/__u/limitlessledger.substack.com/feed" rel="self" type="application/rss+xml"/><copyright><![CDATA[Jennifer Moffeit-Vacher & Shayne Vacher-Moffeit]]></copyright><language><![CDATA[en]]></language><webMaster><![CDATA[limitlessledger@substack.com]]></webMaster><itunes:owner><itunes:email><![CDATA[limitlessledger@substack.com]]></itunes:email><itunes:name><![CDATA[Jennifer Moffeit-Vacher]]></itunes:name></itunes:owner><itunes:author><![CDATA[Jennifer Moffeit-Vacher]]></itunes:author><googleplay:owner><![CDATA[limitlessledger@substack.com]]></googleplay:owner><googleplay:email><![CDATA[limitlessledger@substack.com]]></googleplay:email><googleplay:author><![CDATA[Jennifer Moffeit-Vacher]]></googleplay:author><itunes:block><![CDATA[Yes]]></itunes:block><item><title><![CDATA[Last two weeks in review, Aug 31, 2026]]></title><description><![CDATA[More subqueries and musings of an American tech-worker in EU]]></description><link>https://limitlessledger.substack.com/p/last-two-weeks-in-review-aug-31-2026</link><guid isPermaLink="false">https://limitlessledger.substack.com/p/last-two-weeks-in-review-aug-31-2026</guid><dc:creator><![CDATA[Shayne Vacher-Moffeit]]></dc:creator><pubDate>Mon, 31 Aug 2026 15:59:18 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/86b87ab5-bbf6-455e-94f7-0d90d31fcdfe_2816x1536.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><em><span>tldr: An exploration of some of the societal historic underpinnings driving the differences between tech in the US vs the EU, and factors to keep in mind going forward.</span></em></p><p><span>My subquery work has been another one of the things that seemed straightforward, but turned out to be more involved. I&#8217;m nearing completion of it, and while I could talk about its particulars, it probably wouldn&#8217;t be the most riveting, as most of it at this point is plumbing.</span></p><p><span>Instead, this post will focus on my perspectives and learnings about European alternatives to US tech, and some key systemic differences that lead to what is available and how they are evaluated.</span></p><p><span>Jenn and I have lived in the EU (Portugal) for just over four years now. Prior to that, we were active in the US tech sector for a huge part of the internet revolution as both workers and consumers.</span></p><p><span> We&#8217;ve both seen behind the scenes at big household-name companies as well as scrappy small shops, primarily in Seattle and San Francisco. I also held several roles that had me exposed to how tech was built across the Continental US: both coasts, the Midwest and the South. It also exposed me to how software was built in different industries, such as manufacturing, logistics, insurance, and finance.</span></p><p><span>While there were regional and domain based differences, ultimately it was very similar and fit into the overarching American culture.</span></p><p><span>My exposure to European tech has been nowhere near as deep, and mostly from a consumer perspective, but there are clear differences that have profound implications, and knock-on effects.</span></p><h1><strong><span>Privacy and Consent</span></strong></h1><p><span>Anyone who has done tech business in the EU has heard of and likely cursed GDPR. Going to most websites from anywhere in Europe will immediately ask you about cookies and what you want the site to know about your activity.</span></p><p><span>You also have the right to control what they do with that information.</span></p><p><span>There&#8217;s a whole lot more to those laws (and the EU AI act) that would be far more than would make for interesting reading, but the intent is all about giving the consumer the control over their online presence and data.</span></p><p><span>This is fundamentally different from how US tech operates.</span></p><p><span>That said, if a US company wishes to do business with anyone in Europe (even visiting, as in, on </span><em><span>vacation</span></em><span>), they have to conform to both acts, but if the user is purely inside the US they don&#8217;t. This leads to some interesting implications, particularly in the realm of UX and Product Management.</span></p><p><span>Both the disciplines of UX and modern Product Management, as defined by some of the leading product-led companies in the world, are completely based on gaining a clear understanding of user behavior.</span></p><h2><strong><span>Being observed changes your behavior</span></strong></h2><p><span>There&#8217;s a psychological phenomenon known as the &#8220;Hawthorne Effect&#8221; or the &#8220;Observer Effect&#8221; that comes into play here.</span></p><p><span>From 1924 to 1932 researchers were looking into how alterations in the workplace (e.g., lighting levels, breaks, shift length) would impact productivity at the Western Electric Hawthorne Works plant. They found that productivity would increase no matter what the change was. This even occurred when the change was something that would be generally detrimental to the work, such as setting the lighting levels very dim.</span></p><p><span>The conclusion was that the real reason for the change of productivity was because the workers knew their productivity was being observed and evaluated.</span></p><p><span>As with all biases, the worker was not necessarily aware of their own behavior change, but it was distinct and measurable.</span></p><h2><strong><span>Life in the petri dish</span></strong></h2><p><span>In order to get the best real read of user behavior, UXers and modern Product people in the US are constantly running experiments and evaluations of user behavior without the user&#8217;s consent or knowledge. This has become so sophisticated, often these teams will probably know better than you whether or not you are likely to click on a given button.</span></p><p><span>Their sophistication has led to speculation about whether or not various devices are listening in without our knowledge. The reality is, the kind of eavesdropping by big tech that people tend to suspect would be unreasonably processing intensive. It&#8217;s far easier and more economic to measure and predict user behavior (and the behavior of those the user interacts with) on various interlinked systems.</span></p><p><span>This is how you end up having a conversation with a friend about something like macrame over coffee, and next time you&#8217;re online you start seeing ads for macrame supplies, despite having never searched for it.</span></p><p><span>It&#8217;s not your devices listening in. Instead it&#8217;s evaluations of you and your friend&#8217;s unconscious behavior when presented with anything about macrame. Often this is based on things that those in your broader circle happened to search for. The interests of people within your circle was likely what led to the topic coming up in the first place, so it increases the chance you would be interested in the topic.</span></p><p><span>Your recent exposure to a given topic, through various sources, will cause a slight measurable difference in behavior than something that has not.</span></p><p><span>This is also a key part of the intense information bubbles forming, but that&#8217;s a topic for another post.</span></p><h2><strong><span>How right to privacy impacts this</span></strong></h2><p><span>Full transparency, this is more my musings and observations than anything deeply researched.</span></p><p><span>Testing this would require a lot more time and effort than I&#8217;m able to expend at this point, but there are some absolute differences between UX and Product design and support in the US and EU.</span></p><p><span>US tech tends to have a better baseline UX experience than corresponding EU tech. Both Jenn and I have been exploring EU based alternatives, and have consistently found them harder to use and less intuitive than their US counterparts.</span></p><p><span>EU tech is every bit as stable as US counterparts, or even more so. If you can get past the often clunky UX, EU tech is absolutely solid. The foundation is well built, and tends to get the most focus. The problem is the UX and support is sometimes so frustrating that it limits the abilities to deliver their value.</span></p><p><span>While some of this could be ecosystem related, after all IDEO the birthplace of Design Thinking, is in the San Francisco bay area. I think some of this is strongly influenced by the privacy laws here, as well as the overall societal underpinnings.</span></p><h1><strong><span>Looks Good vs Well Built</span></strong></h1><p><span>This is a very deep topic, and one that is sure to get some folks riled, but it seems to be one of the core cultural underpinning of the difference between US and EU tech: do we value more something that looks good, or something that is solidly built?</span></p><p><span>Let&#8217;s start by reviewing Conway&#8217;s law:</span></p><blockquote><p><em><span>&#8220;[O]rganizations which design systems (in the broad sense used here) are constrained to produce designs which are copies of the communication structures of these organizations.&#8221;</span></em></p></blockquote><p><span>&#8212;&#8202;Melvin E. Conway</span></p><h2><strong><span>Different perspectives, different outcomes</span></strong></h2><p><span>Let&#8217;s peel back the layers to the European colonization of the Americas. For the purposes of this evaluation, I&#8217;m only focused on European immigration. Due to many factors, some quite unpleasant, European immigrants had an outsized impact on American business society that still echoes to this day. While other groups, such as the original people in the Americas, people from other parts of the world, and those who the Europeans moved without their consent, had huge impacts on business society, much of that was applied atop the existing established system.</span></p><p><span>This analysis is also based on broad generalizations and personal observations from my perspective of being an armchair history buff and systems thinker. As always, individual variances significantly outweigh generalized group behavior.</span></p><h3><strong><span>The American perspective</span></strong></h3><p><span>Consider those who immigrated from Europe vs those who stayed. For the most part the people who moved to the Americas were people who, for whatever reason, didn&#8217;t fit in European society of the time. They came to a new society where they had to do whatever they could to survive using their wits and their ingenuity.</span></p><p><span>Pragmatism in relationships and business deals would be more important than deep loyalties. This would lead to a very fluid and fast way of doing business, where you needed to rapidly determine who you were willing to trust or not.</span></p><p><span>It was also fertile ground for those who wished to take advantage of others. In order to rein some of this in, the court systems became more and more important.</span></p><h4><span>The Engineering of Desire</span></h4><p><span>In the early 1900s a man by the name of Edward Bernays, who happened to be Sigmund Freud&#8217;s nephew, had a powerful realization and introduced what he called &#8220;the engineering of consent.&#8221; His realization was that using facts to appeal to people&#8217;s rationale was nowhere near as effective as appealing to their emotions and unconscious desires.</span></p><p><span>This became the foundation of both Public Relations and Marketing in general. A form of weaponized psychology designed to drive consumer behavior.</span></p><p><span>This was so effective that even today if you ask the average American about when is the right time to eat steak and eggs or an omelet, they will overwhelmingly say &#8220;Breakfast, of course!&#8221; In Europe omelets are great for any meal, and here in Portugal a common dinner or lunch is a steak with a fried egg on top (it&#8217;s really good).</span></p><p><span>This perspective was due to his very successful campaign of &#8220;An American Breakfast&#8221;. Also of note, that&#8217;s where the fixation on bacon and orange juice came from too, the same campaign increasing the sales of pork and oranges.</span></p><p><span>This mix of psychological manipulation and rapid-fire deal making, combined by rampant competition driven by the need to survive, led to the US being amazingly innovative, but absolutely cutthroat.</span></p><h4><span>Style above substance</span></h4><p><span>Systems built in the US need to quickly establish trust and comfort. It&#8217;s less important that they actually work or do what they say they do, as long as they do enough to not get hammered by lawsuits. This has led to those able to navigate the labyrinth of law being highly valued, while also often despised.</span></p><p><span>It has also led to a society easily deceived by people who have gotten very skilled at it.</span></p><p><span>I also posit: </span><em><span>the US is more susceptible than perhaps any other society to the wholesale adoption of AI because as long as it looks good, it&#8217;s generally readily accepted.</span></em></p><p><span>Recent times have shown a shift to a more skeptical baseline, but it will be a while before it penetrates all parts of society.</span></p><h4><span>American societal perspective summarized</span></h4><p><span>If I were to boil the American perspective down to a few points, they would be:</span></p><ul><li><p><span>Quantity of money is the only way to achieve quality of life</span></p></li><li><p><span>Personal competitive advantage, often through corporate interests, is more important than societal good</span></p></li><li><p><span>Appearing polished and professional is more important than foundational quality</span></p></li><li><p><span>Business dealmaking moves very fast and considerable effort is made to streamline it</span></p></li></ul><h3><strong><span>The European perspective, through the eyes of an American Expat</span></strong></h3><p><span>Things in Europe are quite a bit different. I would not say better or worse&#8230;just different.</span></p><p><span>To be clear, every country in Europe has very distinct cultures, and even within those countries (including the very small ones) there are subdivisions. Some of these cultural differences are massive so some of what I&#8217;ve observed will apply more or less to different parts of European society.</span></p><h4><span>Patronage, Reputation, and Institutional Trust</span></h4><p><span>For an exceptionally long time in Europe the way to get ahead was to build trusting relationships with those in positions of power and influence. I&#8217;m not talking about liking at all, I&#8217;m talking about currying favor and building reputation. Their trust would lead to opportunities opening up for you, the lack of it would lead to destitution and ruin.</span></p><p><span>Unless you happened to be born into a position of massive privilege, you would need to look for patrons to sponsor you and provide for your needs. Even many of those with that massive privilege would often need to do so as well.</span></p><p><span>To find a patron who would have been willing to provide for you often required a great deal of time and energy. The patron would be extremely careful about who they would support as they would be making a massive commitment which would be closely tied to their own reputation and prospects. In order to foster that relationship, it would need to be built over time with many different indicators showing that you were worthy of their trust and support.</span></p><h4><span>Societal Palimpsest</span></h4><p><span>Architectural Palimpsest, which is common in some parts of Europe, is the practice of building a new structure on top of an existing one, leading to modern buildings with Roman foundations and different floors from different eras.</span></p><p><span>The same sort of factor can be seen in societal patterns.</span></p><p><span>As Europe moved into the modern era, and the old order shifted, many of these systems took on different forms, but were all built on top of this strong impulse of relationship building. This had some catastrophic consequences from the late 1700s to the mid 1900s which left their marks, but it is still a strong underpinning of society today.</span></p><h4><span>Generalized European societal perspective summarized</span></h4><p><span>The general theme I&#8217;ve picked up, which is very different from the US can be boiled down to a few key perspectives:</span></p><ul><li><p><span>A stable society is a higher priority than personal independence</span></p></li><li><p><span>Personal privacy and consent is more important than corporate interests</span></p></li><li><p><span>A fulfilling and enjoyable life is more important than quantity of money</span></p></li><li><p><span>A solid technical foundation is more important than polish or ease of use</span></p></li></ul><h2><strong><span>So what do we do with this?</span></strong></h2><p><span>Honestly, I don&#8217;t entirely know. I tend to find myself aligning more with European values, but I, of course, have a huge number of US-based biases. I think there are benefits from both perspectives, as well as inherent risks.</span></p><p><span>As a social introvert, the amount of time and energy it takes to forge connections here is not something that comes naturally to me. We have likely missed opportunities because of not prioritizing that as much as would fit this culture.</span></p><p><span>As much as I find the constant cookie warnings a bit annoying, and GDPR compliance means a ton of work I wouldn&#8217;t have to do if building a US-only app, I&#8217;m ultimately glad to be protected by it, and that work has led to a more solid and thought out application.</span></p><p><span>I&#8217;d encourage people to check out </span><a href="https://europeantechmap.eu/alternative-to"><span>European alternatives in technology</span></a><span>. There&#8217;s a lot of them and if you care about sustainability, solid tech and control of your information, they are often a better option than their US counterparts.</span></p><p><span>You will find, however, that their UX is nowhere near as slick for the most part&#8230; but that&#8217;s continually improving as much as it can in an environment where all their learnings will be impacted by the Hawthorne Effect.</span></p>]]></content:encoded></item><item><title><![CDATA[Last two weeks in review, Aug 17, 2026]]></title><description><![CDATA[Subquery search quirks and IDE shakeups]]></description><link>https://limitlessledger.substack.com/p/last-two-weeks-in-review-aug-17-2026</link><guid isPermaLink="false">https://limitlessledger.substack.com/p/last-two-weeks-in-review-aug-17-2026</guid><dc:creator><![CDATA[Shayne Vacher-Moffeit]]></dc:creator><pubDate>Mon, 17 Aug 2026 15:27:01 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/7e048a28-2e77-4f74-a72d-b3165abea886_2816x1536.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><em><span>tldr: Empty results on looping subqueries can deliver unexpected results that must be accounted for, GDPR can be both a pain and a blessing, and taking a principled stand has a cost.</span></em></p><p><span>The last two weeks have been focused on getting the subquery search stuff buttoned up. This has been a bigger effort than anticipated, and I knew going in it was not going to be simple. As frequently happens, most of the challenge was re-familiarizing myself with code I wrote almost a year ago. That said, I eventually had the ah-ha moments I needed for me to figure out where the tweaks needed to be, and things started working&#8230; almost. Turns out there was a significant wrinkle.</span></p><h2><strong><span>The Cartesian Trap &amp; Full-Loop Traversals</span></strong></h2><p><span>In my post </span><a href="/__u/limitlessledger.substack.com/p/last-week-in-review-jan-26-2026"><span>Last Week in Review Jan 26, 2026</span></a><span> I discussed using Call chains to avoid a massive cartesian result. These are essentially another query that is launched from the results of a higher order query. So using our examples of the Pollinators, Predators and Flowers as shown here:</span></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!aB-k!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F79d764be-8a95-45b3-b632-6128b13ef5d4_1086x660.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!aB-k!, /__u/limitlessledger.substack.com/w_424, /__u/limitlessledger.substack.com/c_limit, /__u/limitlessledger.substack.com/f_webp, /__u/limitlessledger.substack.com/q_auto:good, /__u/limitlessledger.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F79d764be-8a95-45b3-b632-6128b13ef5d4_1086x660.png 424w, /__u/substackcdn.com/image/fetch/$s_!aB-k!, /__u/limitlessledger.substack.com/w_848, /__u/limitlessledger.substack.com/c_limit, /__u/limitlessledger.substack.com/f_webp, /__u/limitlessledger.substack.com/q_auto:good, /__u/limitlessledger.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F79d764be-8a95-45b3-b632-6128b13ef5d4_1086x660.png 848w, /__u/substackcdn.com/image/fetch/$s_!aB-k!, /__u/limitlessledger.substack.com/w_1272, /__u/limitlessledger.substack.com/c_limit, /__u/limitlessledger.substack.com/f_webp, /__u/limitlessledger.substack.com/q_auto:good, /__u/limitlessledger.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F79d764be-8a95-45b3-b632-6128b13ef5d4_1086x660.png 1272w, /__u/substackcdn.com/image/fetch/$s_!aB-k!, /__u/limitlessledger.substack.com/w_1456, /__u/limitlessledger.substack.com/c_limit, /__u/limitlessledger.substack.com/f_webp, /__u/limitlessledger.substack.com/q_auto:good, /__u/limitlessledger.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F79d764be-8a95-45b3-b632-6128b13ef5d4_1086x660.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!aB-k!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F79d764be-8a95-45b3-b632-6128b13ef5d4_1086x660.png" width="1086" height="660" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/79d764be-8a95-45b3-b632-6128b13ef5d4_1086x660.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:660,&quot;width&quot;:1086,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:66384,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://limitlessledger.substack.com/i/211573571?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F79d764be-8a95-45b3-b632-6128b13ef5d4_1086x660.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!aB-k!, /__u/limitlessledger.substack.com/w_424, /__u/limitlessledger.substack.com/c_limit, /__u/limitlessledger.substack.com/f_auto, /__u/limitlessledger.substack.com/q_auto:good, /__u/limitlessledger.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F79d764be-8a95-45b3-b632-6128b13ef5d4_1086x660.png 424w, /__u/substackcdn.com/image/fetch/$s_!aB-k!, /__u/limitlessledger.substack.com/w_848, /__u/limitlessledger.substack.com/c_limit, /__u/limitlessledger.substack.com/f_auto, /__u/limitlessledger.substack.com/q_auto:good, /__u/limitlessledger.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F79d764be-8a95-45b3-b632-6128b13ef5d4_1086x660.png 848w, /__u/substackcdn.com/image/fetch/$s_!aB-k!, /__u/limitlessledger.substack.com/w_1272, /__u/limitlessledger.substack.com/c_limit, /__u/limitlessledger.substack.com/f_auto, /__u/limitlessledger.substack.com/q_auto:good, /__u/limitlessledger.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F79d764be-8a95-45b3-b632-6128b13ef5d4_1086x660.png 1272w, /__u/substackcdn.com/image/fetch/$s_!aB-k!, /__u/limitlessledger.substack.com/w_1456, /__u/limitlessledger.substack.com/c_limit, /__u/limitlessledger.substack.com/f_auto, /__u/limitlessledger.substack.com/q_auto:good, /__u/limitlessledger.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F79d764be-8a95-45b3-b632-6128b13ef5d4_1086x660.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><span> We could write a query chain that looks like this:</span></p><ol><li><p><span>Find a Flower</span></p></li><li><p><span>From that Flower, find all the Pollinators that Pollinate that flower</span></p></li><li><p><span>From those Pollinators, find all Predators that Eat them</span></p></li><li><p><span>From those Predators, only return the ones that Hide In that particular flower</span></p></li></ol><p><span>This gives us information about the specific interactions between these two animals and a particular flower. This means if you had a pollinator that pollinates both orchids and roses, and one predator that only hides in orchids, and another that only hides in roses, you could limit your result set to the exact flower you wish to examine.</span></p><p><span>Importantly, it would only return the pollinators which were part of this relationship dynamic.</span></p><p><span>It works cleanly and quickly and is super useful immediately for a whole range of applications.</span></p><p><span>The problem comes in when you interrupt the full loop traversal. If the fourth query of the set doesn&#8217;t occur, the results aren&#8217;t limited by the flower being examined. So if we filtered by the predator eats the pollinator our workflow would look like this instead:</span></p><ol><li><p><span>Find a Flower</span></p></li><li><p><span>From that Flower, find all the Pollinators that Pollinate that flower</span></p></li><li><p><span>From those Pollinators, find all Predators that Eat them more than 5 times a day</span></p></li><li><p><span>From those Predators, only return the ones that Hide In that particular flower</span></p></li></ol><p><span>The query would return all the pollinators that pollinate the flower whether or not they are eaten at the defined rate by the predators that hide in that flower. In fact, it would also return pollinators who were not eaten by predators at all.</span></p><h3><strong><span>The Data Leakage Risk</span></strong></h3><p><span>While in this example the results may be messy, ultimately they are benign. It would be a lot less benign in other domains. Personal information related domains are of particular risk. If this broken traversal were not handled, there was a very real risk that one user would see another user&#8217;s information by accident.</span></p><p><span>This was something that was critical to fix.</span></p><p><span>It took me a few fits and starts to finally land on the right solution, but when I did, it fit into place nicely.</span></p><h3><strong><span>The Solution: The Empty Set Rule</span></strong></h3><p><span>In short the rule is: </span><em><span>If the query chain loops back on itself, then an empty result set is passed all the way back up the chain.</span></em></p><p><span>To make that clearer (hopefully), though with a minor tweak:</span></p><ol><li><p><span>Find flowers in the system (let&#8217;s say there&#8217;s a rose, and an orchid)</span></p></li><li><p><span>From those flowers, find all the Pollinators that Pollinate each flower</span></p></li><li><p><span>From those Pollinators, find all Predators that Eat them more than 5 times a day</span></p></li><li><p><span>From those Predators, only return the ones that Hide In the flower the chain started with</span></p></li></ol><p><span>Let&#8217;s say the orchid has a predator that hides in it that eats a pollinator more than 5 times a day, and a rose does not.</span></p><p><span>The orchid would traverse the entire chain and give us our result as expected.</span></p><p><span>The rose would get to step 3, and find no results. That empty set of results would be handed up the chain to step 2. Rather than returning what it had matched of all the rose pollinators, it would set the result to an empty set.</span></p><p><span>In the end, we would see an orchid with the particular relationship interaction we were looking for, and a rose without that particular relationship interaction. In other words, exactly what our subquery was looking for, without pollution from other parts of the chain.</span></p><p><span>I was stoked! It was a simple and elegant solution and it cleanly handled my issue with a clear and describable rule.</span></p><p><span>I ran my scenarios (which revealed the problem in the first place), and saw that indeed the data was not returning that pollution. In fact, in the polluted case, it wasn&#8217;t returning anything at all.</span></p><p><span>While this was better than the pollution, as it wasn&#8217;t oversharing information, it was still a problem for consumers who would have to determine whether or not the value happened to show up. The better result would be returning the empty set, which for some reason was being trimmed off.</span></p><h3><strong><span>Finding the Real Culprit in the Normalizer</span></strong></h3><p><span>As it turned out, while I initially thought the problem might have been the database, my normalizer - the system that takes data from the database and turns it into something javascript is happy to work with - was actually actively stripping empty result sets for some reason.</span></p><p><span>It took me a while to remember why I made that choice, and when I did, I realized there was a much cleaner and more accurate approach. By Thursday evening, I </span><em><span>finally</span></em><span> had something doing exactly what I wanted in a simpler way.</span></p><h2><strong><span>The IDE Shakeup &amp; Moving to EU Sovereignty</span></strong></h2><p><span>Part of the reason this work took longer than anticipated was a major development when it comes to the IDE (Integrated Development Environment) I worked with. I had been using Cursor for some time, which if you&#8217;re not familiar with it, is an AI integrated IDE built on top of Visual Studio Code (a Microsoft open source offering). It&#8217;s a pretty decent product all in all, and while there were various annoyances I was largely a happy customer.</span></p><p><span>Jenn and I had determined that we wanted to move to a more and more EU Sovereign footing, and have been working our way off of US tech (far easier said than done), so I knew I&#8217;d be transitioning off of Cursor in the future, and had some plans brewing about doing that after some product milestones were completed.</span></p><p><span>Compounding that, a few months ago, the announcement was made that SpaceX was to acquire Cursor&#8217;s parent company. This reinforced my decision to find alternatives as I want nothing to do with companies in that particular lineage, but as acquisitions take time, it still wasn&#8217;t enough to make me prioritize it.</span></p><p><span>That timeline got accelerated dramatically by some of the choices Cursor&#8217;s team and/or parent company  made.</span></p><h3><strong><span>The Grok Switch &amp; Breaking Trust</span></strong></h3><p><span>Cursor provides the ability to choose the AI models that drive the system for their Agents and sub Agents. This allows you to pick and choose which models you wish to use, and which you don&#8217;t want impacting your code. They, of course, have their own, and make suggestions, but you&#8217;re not forced to do that. Most of the time you don&#8217;t really think about them after initial setup if at all.</span></p><p><span>One day, I logged in and there was a notification that Cursor had a new model they were excited to rollout based on Grok. I dismissed the notification, thinking there&#8217;s no way I would use it. I want nothing to do with that platform. I find it highly problematic and in many ways a misinformation platform (e.g, </span><a href="https://en.wikipedia.org/wiki/Grok_sexual_deepfake_scandal"><span>Grok sexual deepfake scandal</span></a><span>, </span><a href="https://www.cbsnews.com/news/grok-elon-musks-ai-chatbot-antisemitic-comments/"><span>Grok, Elon Musk&#8217;s AI chatbot on X, posts antisemitic comments, later deleted</span></a><span>, </span><a href="https://www.pbs.org/newshour/politics/why-does-the-ai-powered-chatbot-grok-post-false-offensive-things-on-x"><span>Why does the AI-powered chatbot Grok post false, offensive things on X?</span></a><span>).</span></p><p><span>Some time later, for some reason I honestly can&#8217;t recall, I was checking my models and I was appalled to find that my primary model for both my agents and subagents were set to this Grok-based model. I reset them to models I vastly preferred.</span></p><p><span>I proceeded to vent my frustrations to Gemini, which helpfully let me know that Cursor was partnered with Grok/xAI and was sending training data over to them based on my interactions (source: </span><a href="https://www.mindstudio.ai/blog/what-is-grok-4-5-xai-cursor-coding-model"><span>What Is Grok 4.5? xAI and Cursor&#8217;s First Jointly Trained Coding Model</span></a><span>).</span></p><p><span>This is absolutely not something I would consent to, at least with that model. I believe I had privacy mode turned on with my system, so if they honored that then my data should not have been used in that set, but even still my trust was broken with them.</span></p><p><span>I hold nothing against the team at Cursor, and I truly wish things had gone differently, but it didn&#8217;t feel to me to be a company I wished to continue to support based on those moves.</span></p><h3><strong><span>Exercising GDPR Article 17</span></strong></h3><p><span>I live in a country protected by GDPR (Portugal), so I triggered an Article 17 deletion request. For those of you not familiar with GDPR, triggering this gives the company 30 days to remove the vast majority of information about me from their systems, and send a record of that removal, and this includes any other organizations they shared that information with. It was something that was frustrating to build for, but now that I needed it, I was happy to have that option.</span></p><p><span>Failure to comply triggers massive fines from the EU. The EU AI act puts more intense teeth into the whole situation.</span></p><p><span>This is absolutely something any company doing business in the EU should have top of mind, as it applies to you if any of your customers are EU based (citizen or not). In fact, it comes into effect if your customers are just vacationing in the EU.</span></p><p><strong><span>Do not think you can get around it unless you are absolutely certain none of your customers will ever set foot in the EU. </span></strong><span>These laws are not to be trifled with.</span></p><h3><strong><span>Life After Cursor: VSCodium, Continue, and Local AI</span></strong></h3><p><span>So, now that I&#8217;ve moved off of Cursor, I&#8217;m more aware than ever of their value proposition.</span></p><p><span>I&#8217;m now using VSCodium, another VS Code/based offering, but this one strips out all of Microsoft&#8217;s telemetry data harvesting. With that, there&#8217;s an open source plugin called Continue that allows you to integrate AI models into your system. I&#8217;ve actually loaded a few locally, and well&#8230; I suppose you get what you pay for. They&#8217;re slower (running on my laptop) and much dumber than I&#8217;m used to using, but I don&#8217;t have to pay per request. I probably will go to a paid model again to get closer to Cursor&#8217;s functionality. Right now I&#8217;m thinking of checking out Mistral&#8217;s offering: Devstral.</span></p><p><span>A key benefit of this setup is that I have complete control. The downside is that, with that complete control comes a lot of quirkiness and configuration pain.</span></p><h3><strong><span>The price of principles</span></strong></h3><p><span>I guess the point of this ramble really is, be sure to check on how your providers are using your data. Be aware of your rights (in the US you don&#8217;t have as many in this area), and exercise them where appropriate. Don&#8217;t assume that your providers have your best interests or values at heart. They don&#8217;t. At best theirs are aligned with yours at the moment, but that can change rapidly and in all likelihood their values are being driven by someone up their investor chain.</span></p><p><span>Taking a principled stand can absolutely take a lot more time, effort, and frustration but ultimately it makes it more likely that you are having the impact in the world that YOU wish to.</span></p>]]></content:encoded></item><item><title><![CDATA[It's pretty loud for humans to not be talking to each other.]]></title><description><![CDATA[If your inbox, phone, life feels like mine it's buzzing, pinging, and notifying. But the 'ah ha' moments live entirely elsewhere.]]></description><link>https://limitlessledger.substack.com/p/its-pretty-loud-for-humans-to-not</link><guid isPermaLink="false">https://limitlessledger.substack.com/p/its-pretty-loud-for-humans-to-not</guid><dc:creator><![CDATA[Jennifer Moffeit-Vacher]]></dc:creator><pubDate>Fri, 07 Aug 2026 16:40:45 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!so8g!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1c374c45-77bb-49bf-9c53-d7ba2cacb0ac_1200x630.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><span>Everything feels so synthetic lately. Like when you accidentally pick up a cute shirt that looks easy to take care of and it never wrinkles but you also come to find it is made out of polyester.</span></p><p><span>No room for breathing, no natural qualities, looks great from far away but the moment the weather isn&#8217;t perfect, it&#8217;s usability goes to zero. It&#8217;s uncomfortable, one drop of sweat and you turn into a walking furnace. A drop in temperature and you are weirdly colder than everyone else.</span></p><p><span>My inbox is full of newsletters maximized to get some metric, I have apps screaming at me to engage. There seems to be tons of content everywhere, and more apps built to help you build even more content. Everyone has the tools to get to as many people as their newsletter list will allow, and everyone is trying so hard to get a click.</span></p><p><span>I haven&#8217;t run across much in those zones that have helped me understand myself better, or how I fit into this world.</span></p><p><span>The most I&#8217;ve learned about myself have come from 1:1 conversations and taking the space and time afterward to reflect. I&#8217;ve also learned a ton by watching others do the same.</span></p><p><span>Example, this picture that&#8217;s the main pic of this post. That&#8217;s Shayne and someone that helped us drag our bags from our two-night rental to our new apartment in Lisbon. We were in Portugal for less than 48 hours. We worked through the company helping us do the admin work of the move, and this guy was working there. He showed up at our rental with his car and we all packed in to go the kilometer or so to the new apartment.<br><br>Within minutes, we realized we&#8217;d met him before - he was our waiter about a year earlier on another trip during a relaxed dinner at a cafe near our hotel. The world is a lovely, small place. And it gets even more lovely when you talk to people!</span></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!so8g!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1c374c45-77bb-49bf-9c53-d7ba2cacb0ac_1200x630.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!so8g!, /__u/limitlessledger.substack.com/w_424, /__u/limitlessledger.substack.com/c_limit, /__u/limitlessledger.substack.com/f_webp, /__u/limitlessledger.substack.com/q_auto:good, /__u/limitlessledger.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1c374c45-77bb-49bf-9c53-d7ba2cacb0ac_1200x630.png 424w, /__u/substackcdn.com/image/fetch/$s_!so8g!, /__u/limitlessledger.substack.com/w_848, /__u/limitlessledger.substack.com/c_limit, /__u/limitlessledger.substack.com/f_webp, /__u/limitlessledger.substack.com/q_auto:good, /__u/limitlessledger.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1c374c45-77bb-49bf-9c53-d7ba2cacb0ac_1200x630.png 848w, /__u/substackcdn.com/image/fetch/$s_!so8g!, /__u/limitlessledger.substack.com/w_1272, /__u/limitlessledger.substack.com/c_limit, /__u/limitlessledger.substack.com/f_webp, /__u/limitlessledger.substack.com/q_auto:good, /__u/limitlessledger.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1c374c45-77bb-49bf-9c53-d7ba2cacb0ac_1200x630.png 1272w, /__u/substackcdn.com/image/fetch/$s_!so8g!, /__u/limitlessledger.substack.com/w_1456, /__u/limitlessledger.substack.com/c_limit, /__u/limitlessledger.substack.com/f_webp, /__u/limitlessledger.substack.com/q_auto:good, /__u/limitlessledger.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1c374c45-77bb-49bf-9c53-d7ba2cacb0ac_1200x630.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!so8g!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1c374c45-77bb-49bf-9c53-d7ba2cacb0ac_1200x630.png" width="1200" height="630" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/1c374c45-77bb-49bf-9c53-d7ba2cacb0ac_1200x630.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:630,&quot;width&quot;:1200,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:846421,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://limitlessledger.substack.com/i/209119398?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1c374c45-77bb-49bf-9c53-d7ba2cacb0ac_1200x630.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!so8g!, /__u/limitlessledger.substack.com/w_424, /__u/limitlessledger.substack.com/c_limit, /__u/limitlessledger.substack.com/f_auto, /__u/limitlessledger.substack.com/q_auto:good, /__u/limitlessledger.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1c374c45-77bb-49bf-9c53-d7ba2cacb0ac_1200x630.png 424w, /__u/substackcdn.com/image/fetch/$s_!so8g!, /__u/limitlessledger.substack.com/w_848, /__u/limitlessledger.substack.com/c_limit, /__u/limitlessledger.substack.com/f_auto, /__u/limitlessledger.substack.com/q_auto:good, /__u/limitlessledger.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1c374c45-77bb-49bf-9c53-d7ba2cacb0ac_1200x630.png 848w, /__u/substackcdn.com/image/fetch/$s_!so8g!, /__u/limitlessledger.substack.com/w_1272, /__u/limitlessledger.substack.com/c_limit, /__u/limitlessledger.substack.com/f_auto, /__u/limitlessledger.substack.com/q_auto:good, /__u/limitlessledger.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1c374c45-77bb-49bf-9c53-d7ba2cacb0ac_1200x630.png 1272w, /__u/substackcdn.com/image/fetch/$s_!so8g!, /__u/limitlessledger.substack.com/w_1456, /__u/limitlessledger.substack.com/c_limit, /__u/limitlessledger.substack.com/f_auto, /__u/limitlessledger.substack.com/q_auto:good, /__u/limitlessledger.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1c374c45-77bb-49bf-9c53-d7ba2cacb0ac_1200x630.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><span>We&#8217;d just got the keys to the apartment. They started talking about software development in the elevator, and this sweet guy wanted to understand how to even begin. So after we wrangled our six bags massive bags we&#8217;d brought from the U.S. with all our worldy possessions, they plugged in Shayne&#8217;s laptop, sat on the floor, and began to have an animated conversation about where he could start. It was the first use of our internet.</span></p><p><span>We had no furniture, no dishes, nothing but the utilities turned on. But that was a shining and memorable nerd share from our first hours in our new life here.</span></p><p><span>This is what questions and a few minutes can bring.</span></p><h1><strong><span>The friction of the solve seems lost.</span></strong></h1><p><span>I caught up with a colleague from long ago a few days ago. Her day is a mix of being in a number of areas across the business but her title is still &#8216;marketing&#8217;. She&#8217;s using AI where it makes sense to guide her research. She seems to have figured out where the human in the loop is needed vs. when research can be handled for a bit and passed on to her.</span></p><p><span>We used to work together at a company that drove us into the ground with work. This was before AI, when you had to talk through a blog post for a day or two with a writer, run over to the graphic design folks and talk through a narrative, then go to the project manager to talk through deadlines. That was all to manage one client, and we all had at least 10 clients moving at a break neck pace.</span></p><p><span>All that work was interacting with humans with thought processes and ideas that didn&#8217;t already live somewhere else.</span></p><p><span>It was amazing to connect to another human that remembers the toil, pain, late nights, elation of solving - all the things that we as humans connect on.</span></p><p><span>Now, it seems we are in a place where a lot of those human ideas have been replaced by a machine that looks at the median information already available.</span></p><p><span>The original thought still has to come from us, but the friction to do the research, understand the client, work with others, and have that light bulb moment (or 20) that&#8217;s truly connective&#8230;that seems to be lost.</span></p><p><span>Hell, even this post itself was started a week ago, sat on, I awoke the next day at 4am to continue on it, and I&#8217;m finalizing it now. Days later. With a bot, I could have given them an idea and cranked something out in minutes.</span></p><p><em><span>But what would I have learned?</span></em></p><p>Now, I&#8217;m rereading it again to double check it, and thinking about the whole story, adding bits of clarification. I&#8217;ve lived human moments since then that are now helping me bring this to life in a way no one else could because everyone&#8217;s stories and way of telling is unique.</p><p><span>We have tech companies battling to pull in as much of human existence and thought as possible to train models. But machines will never know what it feels like to read something, put it aside, and have that &#8216;I GET it now&#8217; moment. That moment where a person starts writing, or painting, or creating in whatever format to capture the thing. Or connecting the dots in a conversation that helps them understand someone else better.</span></p><p><span>That moment feels amazing. It feels like that&#8217;s been somewhat replaced by a native integration.</span></p><p><span>Where are we in this? Who exactly are we in this all?</span></p><p><span>Got me wondering, what if we took it back to old school communication. 1:1. I know I&#8217;m acting like this is some ground breaking thing of people talking to other people.</span></p><p><span>It&#8217;s not ground breaking. </span></p><p><span>And yet here we are using machines to do our research, be our therapists and friends, be the thing that catches our thoughts that we&#8217;re a little too scared to say out loud.</span></p><p><span>They are built to give us just enough, make us feel like winning is just around the corner. They are a slot machine that spits out information, we&#8217;re in a huge casino with a few of those slot machines dinging in the background helping us feel like we just might be the next person to get that perfect answer.</span></p><p><span>The answer that changes everything and helps us with whatever our goal is. But that answer never truly arrives.</span></p><p><span>What if</span></p><ul><li><p><span>someone asks a question and some real human answers it</span></p></li><li><p><span>that question is difficult to answer but opens up something in both people participating in the conversation</span></p></li></ul><p><span>So, I thought&#8230;why not setup something slower, more human to human, more exhausting in a way where I can learn something from others?</span></p><p><span>So in the </span><a href="https://skillbearings.com/become-a-design-partner"><span>design cohort we have</span></a><span>, where we&#8217;re testing out our product, I&#8217;m taking it </span><em><span>very </span></em><span>old-school. Uncomfortably so since I&#8217;ve lived and breathed automations, databases, and alleviating the simplest work for decades now.</span></p><p><span>I&#8217;m asking questions, I&#8217;m not having people fill out forms for every interaction. We&#8217;re having conversations and back-and-forth dialogue. Over email. Super manual.</span></p><p><span>Crazy? Maybe. Time consuming? Absolutely. But worth it? I freaking hope so. If it&#8217;s not worth it, then I don&#8217;t know where we fit anymore if we have nothing left to learn from talking to each other.</span></p><p><span>So if you want to get asked hard questions about your path or goals, and have a real human answer them, and push for clarification and cheer you on like only humans can, join our design cohort.</span></p><p>I&#8217;d be <em><strong>thrilled </strong></em>to hear from you. Like, truly. </p><p>I got a sign up last night and it made my night. We&#8217;ve already gone back and forth a few times today. We&#8217;re meeting next week.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://skillbearings.com/become-a-design-partner&quot;,&quot;text&quot;:&quot;Become a Design Partner.&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://skillbearings.com/become-a-design-partner"><span>Become a Design Partner.</span></a></p><p><span>There might be typos or a slight rant in the message (that already happened today). But I can assure you, a real human will be on the other side of it, thinking about a real answer.</span></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://limitlessledger.substack.com/p/its-pretty-loud-for-humans-to-not?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="/__u/limitlessledger.substack.com/p/its-pretty-loud-for-humans-to-not?utm_source=substack&amp;utm_medium=email&amp;utm_content=share&amp;action=share"><span>Share</span></a></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://limitlessledger.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="/__u/limitlessledger.substack.com/subscribe"><span>Subscribe now</span></a></p><p></p>]]></content:encoded></item><item><title><![CDATA[Last two weeks in Review Aug 3, 2026]]></title><description><![CDATA[Realities of search and frustrations with systems]]></description><link>https://limitlessledger.substack.com/p/last-two-weeks-in-review-aug-3-2026</link><guid isPermaLink="false">https://limitlessledger.substack.com/p/last-two-weeks-in-review-aug-3-2026</guid><dc:creator><![CDATA[Shayne Vacher-Moffeit]]></dc:creator><pubDate>Mon, 03 Aug 2026 14:24:27 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/5996054c-b2f1-42b1-b7dc-482d46b206b5_2528x1684.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><em><span>tldr: Graph Databases provide for incredibly deep and rich models of information, but getting the data out of them can get complicated very quickly, especially when trying to translate that into something that can fit into a url. This post goes into some detail about those struggles and my approach to tackle it.</span></em></p><p><span>After getting rich text in place, I was ready to dig back into the deeper system. I still had some refinements and tweaks I needed to make on the public interfaces, but most of those were pretty minor, or could be safely deferred. I came to a realization that to make things work in the way I wanted, I needed to tackle a big challenge I had been putting off: more robust searching.</span></p><p><span>In this post, I&#8217;ll be talking about what makes searching both more powerful and more complicated (expect there to be nerdery). I will also cover some of the surprises that I ran into and more thoughts about the weird world of AI enabled engineering, and the realities of it, beyond the hype.</span></p><h2><strong><span>Into the nerdery</span></strong></h2><p><span>In my posts </span><a href="/__u/limitlessledger.substack.com/p/week-in-review-jan-12-2025"><span>Week in Review - Jan 12, 2025</span></a><span> and </span><a href="/__u/limitlessledger.substack.com/p/last-week-in-review-jan-26-2026"><span>Last Week in Review Jan 26, 2026</span></a><span>, I talked about some of the interesting elements of a graph-based system.</span></p><p><span>Having relationships as a first-order entity with their own collection of data tends to be challenging for many to consider, and subqueries increase the complexity dramatically. This is all compounded by the need to communicate with the system to get the appropriate information in a clean and repeatable way.</span></p><p><span>To start to illustrate some of this, I&#8217;ll bring back our ecosystem graph we were working with in our last explorations of graph structure. In the referenced articles,  I used an example graph with the following entities and relationships:</span></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!c28U!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ebdee4f-9331-4f59-ba87-68cf15a7b1f6_566x340.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!c28U!, /__u/limitlessledger.substack.com/w_424, /__u/limitlessledger.substack.com/c_limit, /__u/limitlessledger.substack.com/f_webp, /__u/limitlessledger.substack.com/q_auto:good, /__u/limitlessledger.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ebdee4f-9331-4f59-ba87-68cf15a7b1f6_566x340.png 424w, /__u/substackcdn.com/image/fetch/$s_!c28U!, /__u/limitlessledger.substack.com/w_848, /__u/limitlessledger.substack.com/c_limit, /__u/limitlessledger.substack.com/f_webp, /__u/limitlessledger.substack.com/q_auto:good, /__u/limitlessledger.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ebdee4f-9331-4f59-ba87-68cf15a7b1f6_566x340.png 848w, /__u/substackcdn.com/image/fetch/$s_!c28U!, /__u/limitlessledger.substack.com/w_1272, /__u/limitlessledger.substack.com/c_limit, /__u/limitlessledger.substack.com/f_webp, /__u/limitlessledger.substack.com/q_auto:good, /__u/limitlessledger.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ebdee4f-9331-4f59-ba87-68cf15a7b1f6_566x340.png 1272w, /__u/substackcdn.com/image/fetch/$s_!c28U!, /__u/limitlessledger.substack.com/w_1456, /__u/limitlessledger.substack.com/c_limit, /__u/limitlessledger.substack.com/f_webp, /__u/limitlessledger.substack.com/q_auto:good, /__u/limitlessledger.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ebdee4f-9331-4f59-ba87-68cf15a7b1f6_566x340.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!c28U!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ebdee4f-9331-4f59-ba87-68cf15a7b1f6_566x340.png" width="563" height="338.19787985865725" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/1ebdee4f-9331-4f59-ba87-68cf15a7b1f6_566x340.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:340,&quot;width&quot;:566,&quot;resizeWidth&quot;:563,&quot;bytes&quot;:29876,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://limitlessledger.substack.com/i/209631307?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ebdee4f-9331-4f59-ba87-68cf15a7b1f6_566x340.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!c28U!, /__u/limitlessledger.substack.com/w_424, /__u/limitlessledger.substack.com/c_limit, /__u/limitlessledger.substack.com/f_auto, /__u/limitlessledger.substack.com/q_auto:good, /__u/limitlessledger.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ebdee4f-9331-4f59-ba87-68cf15a7b1f6_566x340.png 424w, /__u/substackcdn.com/image/fetch/$s_!c28U!, /__u/limitlessledger.substack.com/w_848, /__u/limitlessledger.substack.com/c_limit, /__u/limitlessledger.substack.com/f_auto, /__u/limitlessledger.substack.com/q_auto:good, /__u/limitlessledger.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ebdee4f-9331-4f59-ba87-68cf15a7b1f6_566x340.png 848w, /__u/substackcdn.com/image/fetch/$s_!c28U!, /__u/limitlessledger.substack.com/w_1272, /__u/limitlessledger.substack.com/c_limit, /__u/limitlessledger.substack.com/f_auto, /__u/limitlessledger.substack.com/q_auto:good, /__u/limitlessledger.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ebdee4f-9331-4f59-ba87-68cf15a7b1f6_566x340.png 1272w, /__u/substackcdn.com/image/fetch/$s_!c28U!, /__u/limitlessledger.substack.com/w_1456, /__u/limitlessledger.substack.com/c_limit, /__u/limitlessledger.substack.com/f_auto, /__u/limitlessledger.substack.com/q_auto:good, /__u/limitlessledger.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ebdee4f-9331-4f59-ba87-68cf15a7b1f6_566x340.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><span>In the world of graph dbs, each noun tends to map to a node, and each verb tends to map to a relationship, and both of those contain their own set of information. This enables data structures to be built that tend to be intuitive. As they grow, they can quickly become overwhelming, but ultimately the core principles can always be broken down to two nouns joined by a verb.</span></p><p><span>So, why is this important in search?</span></p><h2><strong><span>Finding the perfect Node</span></strong></h2><p><span>Searching for a node (noun) in the system is very straightforward. If I have a </span><span data-color="#f6b26b" style="color: rgb(246, 178, 107);">Pollinator</span> with a value on it, such as &#8220;cycle&#8221;, which corresponds to when it is active, I can very easily say &#8220;give me all the diurnal pollinators&#8221;. The actual cypher command to do that would look like this:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;sql&quot;,&quot;nodeId&quot;:&quot;c673605d-6691-42bc-b250-830e8b2744db&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-sql">MATCH (p:Pollinator)
WHERE p.cycle=&#8217;diurnal&#8217;
RETURN p</code></pre></div><p><span>Of course, there are more sophisticated queries, but for now we&#8217;ll stick with simple examples.</span></p><p><span>Translating this to an external api querystring would be quite simple. Something like this would totally work:<br></span><em><span>/ecoapi/</span><span data-color="#f6b26b" style="color: rgb(246, 178, 107);">pollinator</span><span>/?cycle_eq=diurnal</span></em></p><p><span>The search can be further expanded by adding more values:<br></span><em><span>/ecoapi/</span><span data-color="#f6b26b" style="color: rgb(246, 178, 107);">pollinator</span><span>/?cycle_eq=diurnal&amp;class=insecta</span></em></p><p><span>This would further filter our prior list by only returning insects.</span></p><p><span>URL query sidenote: You may have noticed a suffix _eq (and _gt in later examples) hanging off the field names in the urls. This is because there is a whole range of comparators that can be used to search for depending on the nature of the value in the field. I&#8217;m not going to go deep into them in this post, but every field in the search needs to designate the nature of the comparison being done.</span></p><p><span>The cypher command would end up looking like this:</span></p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;sql&quot;,&quot;nodeId&quot;:&quot;911cde24-999a-4349-b54d-a80bec3b193a&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-sql">MATCH (p:Pollinator)
WHERE p.cycle=&#8217;diurnal&#8217;
  AND p.class=&#8217;insecta&#8217;
RETURN p</code></pre></div><p><span>This same pattern would work well with any of the nodes in our system.</span></p><p><span>The first problem with the querystring emerges when you want to expand your result set rather than filter it further.</span></p><p><span>If, for example, you wanted all diurnal </span><span data-color="#f6b26b" style="color: rgb(246, 178, 107);">Pollinators</span><span>, and all insect </span><span data-color="#f6b26b" style="color: rgb(246, 178, 107);">Pollinators</span><span> in one set for some reason (no idea why, but you do you). You would want a query that looks like this:</span></p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;sql&quot;,&quot;nodeId&quot;:&quot;1e4a46af-87b4-49e6-a85f-01f8ac760e1c&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-sql">MATCH (p:Pollinator)
WHERE p.cycle=&#8217;diurnal&#8217;
  OR p.class=&#8217;insecta&#8217;
RETURN p</code></pre></div><p></p><p><span>The problem is, our basic querystrings have no way of designating what the conjunctions between the criteria are. This gets even more challenging when conjunction types are mixed (both AND&#8217;s and OR&#8217;s).</span></p><p><span>The good news is that with querystring encoding you can send just about any shape in a querystring, including standardized formats like JSON.</span></p><p><span>I decided that instead of trying to use a flat querystring (which also has other values), I would put all of my search definitions in one JSON search field. I had actually made that decision long ago, knowing this would be an issue, but now it was finally being exercised.</span></p><p><span>The way JSON has to be encoded in a URL is hard for humans to read so my examples are not what you would see in the real URL. The encoded url has a lot more %&#8217;s and numbers.</span></p><p><span>So, here&#8217;s what the payload of the search field would look like for our prior examples:</span></p><p><span>With this url:  </span><em><span>/ecoapi/</span><span data-color="#f6b26b" style="color: rgb(246, 178, 107);">pollinators</span><span>/?search=</span></em></p><p><span>Find all diurnal </span><span data-color="#f6b26b" style="color: rgb(246, 178, 107);">Pollinators</span><span>:</span></p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;json&quot;,&quot;nodeId&quot;:&quot;e82b509f-c42c-44c7-90a5-a749585baa7b&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-json">{ "cycle_eq":"diurnal&#8221; }</code></pre></div><p><span>Find all diurnal insect </span><span data-color="#f6b26b" style="color: rgb(246, 178, 107);">Pollinators</span><span>:</span></p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;json&quot;,&quot;nodeId&quot;:&quot;6c29b4d8-2204-4c40-bec0-8ae986c69b75&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-json">{
  "cycle_eq":"diurnal",
  "class_eq":"insecta"
}</code></pre></div><p><span>Find all diurnal or insect </span><span data-color="#f6b26b" style="color: rgb(246, 178, 107);">Pollinators</span><span>:</span></p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;json&quot;,&quot;nodeId&quot;:&quot;5637e1a7-aad4-4200-b928-8018ab71ac13&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-json">{
  "_or":[{
    "cycle_eq":"diurnal"
  },{
    "class_eq":"insecta"
  }]
}</code></pre></div><p><span>This allows for sophisticated search criteria to be built, with a clear dialect for finding what is needed.</span></p><h2><strong><span>On the Edge of Relationships</span></strong></h2><p><span>Once relationships (verbs) enter the chat it gets more complicated.</span></p><p><span>In the graph world, both </span><span data-color="#f6b26b" style="color: rgb(246, 178, 107);">nodes</span><span> and </span><span data-color="#76a5af" style="color: rgb(118, 165, 175);">relationships</span><span> can hold data that can be filtered on. Also, an identically named relationship can connect two other nodes with different contexts.</span></p><p><span>For example:</span></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!QxRU!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fec6acf91-b0b9-497f-8751-6e5bc7bfee1b_620x362.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!QxRU!, /__u/limitlessledger.substack.com/w_424, /__u/limitlessledger.substack.com/c_limit, /__u/limitlessledger.substack.com/f_webp, /__u/limitlessledger.substack.com/q_auto:good, /__u/limitlessledger.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fec6acf91-b0b9-497f-8751-6e5bc7bfee1b_620x362.png 424w, /__u/substackcdn.com/image/fetch/$s_!QxRU!, /__u/limitlessledger.substack.com/w_848, /__u/limitlessledger.substack.com/c_limit, /__u/limitlessledger.substack.com/f_webp, /__u/limitlessledger.substack.com/q_auto:good, /__u/limitlessledger.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fec6acf91-b0b9-497f-8751-6e5bc7bfee1b_620x362.png 848w, /__u/substackcdn.com/image/fetch/$s_!QxRU!, /__u/limitlessledger.substack.com/w_1272, /__u/limitlessledger.substack.com/c_limit, /__u/limitlessledger.substack.com/f_webp, /__u/limitlessledger.substack.com/q_auto:good, /__u/limitlessledger.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fec6acf91-b0b9-497f-8751-6e5bc7bfee1b_620x362.png 1272w, /__u/substackcdn.com/image/fetch/$s_!QxRU!, /__u/limitlessledger.substack.com/w_1456, /__u/limitlessledger.substack.com/c_limit, /__u/limitlessledger.substack.com/f_webp, /__u/limitlessledger.substack.com/q_auto:good, /__u/limitlessledger.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fec6acf91-b0b9-497f-8751-6e5bc7bfee1b_620x362.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!QxRU!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fec6acf91-b0b9-497f-8751-6e5bc7bfee1b_620x362.png" width="620" height="362" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ec6acf91-b0b9-497f-8751-6e5bc7bfee1b_620x362.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:362,&quot;width&quot;:620,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:37912,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://limitlessledger.substack.com/i/209631307?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fec6acf91-b0b9-497f-8751-6e5bc7bfee1b_620x362.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!QxRU!, /__u/limitlessledger.substack.com/w_424, /__u/limitlessledger.substack.com/c_limit, /__u/limitlessledger.substack.com/f_auto, /__u/limitlessledger.substack.com/q_auto:good, /__u/limitlessledger.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fec6acf91-b0b9-497f-8751-6e5bc7bfee1b_620x362.png 424w, /__u/substackcdn.com/image/fetch/$s_!QxRU!, /__u/limitlessledger.substack.com/w_848, /__u/limitlessledger.substack.com/c_limit, /__u/limitlessledger.substack.com/f_auto, /__u/limitlessledger.substack.com/q_auto:good, /__u/limitlessledger.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fec6acf91-b0b9-497f-8751-6e5bc7bfee1b_620x362.png 848w, /__u/substackcdn.com/image/fetch/$s_!QxRU!, /__u/limitlessledger.substack.com/w_1272, /__u/limitlessledger.substack.com/c_limit, /__u/limitlessledger.substack.com/f_auto, /__u/limitlessledger.substack.com/q_auto:good, /__u/limitlessledger.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fec6acf91-b0b9-497f-8751-6e5bc7bfee1b_620x362.png 1272w, /__u/substackcdn.com/image/fetch/$s_!QxRU!, /__u/limitlessledger.substack.com/w_1456, /__u/limitlessledger.substack.com/c_limit, /__u/limitlessledger.substack.com/f_auto, /__u/limitlessledger.substack.com/q_auto:good, /__u/limitlessledger.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fec6acf91-b0b9-497f-8751-6e5bc7bfee1b_620x362.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><span>In this case, the relationship </span><span data-color="#76a5af" style="color: rgb(118, 165, 175);">EATS</span> is identical, but the case of a <span data-color="#f6b26b" style="color: rgb(246, 178, 107);">predator</span> <span data-color="#76a5af" style="color: rgb(118, 165, 175);">eating</span> a <span data-color="#f6b26b" style="color: rgb(246, 178, 107);">pollinator</span>, is fundamentally different (and more violent) than a cow grazing on daisies.</p><h3><strong><span>Choosing the right relationship</span></strong></h3><p><span>Because of this, while possible, searching for all of the </span><span data-color="#76a5af" style="color: rgb(118, 165, 175);">EATS</span> relationships that are attached to any two nodes, is not often as useful as thinking of the relationships as a triplet (<span data-color="#f6b26b" style="color: rgb(246, 178, 107);">noun</span>-<span data-color="#76a5af" style="color: rgb(118, 165, 175);">verb</span>-<span data-color="#f6b26b" style="color: rgb(246, 178, 107);">noun</span>).</p><p><span>The catch is, the value that identifies which relationship is useful could be on any or all of the three entities involved. So to extend our example further, if both </span><span data-color="#f6b26b" style="color: rgb(246, 178, 107);">Predators</span><span> and </span><span data-color="#f6b26b" style="color: rgb(246, 178, 107);">Pollinators</span><span> have the same class and cycle fields, and </span><span data-color="#76a5af" style="color: rgb(118, 165, 175);">EATS </span><span>has a frequencyPerDay, a search like this is absolutely possible:</span></p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;sql&quot;,&quot;nodeId&quot;:&quot;8bfa213a-7711-4608-a441-eb4bf0354941&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-sql">MATCH (pre:Predator)-[e:EATS]-&gt;(p:Pollinator)
WHERE pre.class=&#8217;mammalia&#8217;
  AND e.frequencyPerDay &gt; 5
  AND p.class=&#8217;insecta&#8217;
RETURN pre, e, p</code></pre></div><p></p><p><span>This can give us a sense of the impact that mammal predation has on the insects in our ecosystem. While very useful,  it starts to get much more complicated to call with the API.</span></p><p><span>First, we have to establish that we care about the particular </span><span data-color="#76a5af" style="color: rgb(118, 165, 175);">EATS </span><span>relationship between </span><span data-color="#f6b26b" style="color: rgb(246, 178, 107);">Predators</span><span> and </span><span data-color="#f6b26b" style="color: rgb(246, 178, 107);">Pollinators</span><span> (so we don&#8217;t end up with our daisy munching cows).</span></p><p><span>Often the shape of the base url can help with that</span><em><span> /ecoapi/</span><span data-color="#f6b26b" style="color: rgb(246, 178, 107);">predator</span><span>/</span><span data-color="#76a5af" style="color: rgb(118, 165, 175);">eats</span><span>/</span><span data-color="#f6b26b" style="color: rgb(246, 178, 107);">pollinator</span><span>/</span></em><span>, from there we need to determine the shape of the various criteria. It needs to be crystal clear which field applies to which entity (either of the nodes, or the relationship itself).</span></p><p><span>To do that, I thought the most logical course of action would be to prefix the node fields with the name of their node, and omit a prefix for the relationship fields.</span></p><p><span>So the query above would have a search argument that looks like this:</span></p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;json&quot;,&quot;nodeId&quot;:&quot;1d23005c-ba28-4447-9e06-42cfb2adf0f0&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-json">{
  "predator_class_eq":"mammalia",
  "frequencyPerDay_gt":5,
  "pollinator_class_eq":"insecta&#8221;
}</code></pre></div><p><span>With that solved, I was faced with another challenge. In the query I mentioned above, it would only return a value where all of the search terms matched. Useful for classic searches, but less useful if you wish to see root node records both with and without relationships.</span></p><h3><strong><span>The set gets Jagged</span></strong></h3><p><span>Consider this scenario:</span></p><blockquote><p><span>Your application needs to list all the mammalia </span><span data-color="#f6b26b" style="color: rgb(246, 178, 107);">Predators</span><span> and show the set of insect </span><span data-color="#f6b26b" style="color: rgb(246, 178, 107);">Pollinators</span><span> those </span><span data-color="#f6b26b" style="color: rgb(246, 178, 107);">Predators</span><span> </span><span data-color="#76a5af" style="color: rgb(118, 165, 175);">EAT</span><span>. The </span><span data-color="#f6b26b" style="color: rgb(246, 178, 107);">Predator</span><span> should always show up, whether or not their </span><span data-color="#76a5af" style="color: rgb(118, 165, 175);">EATS</span><span> relationship matches those specific criteria.</span></p></blockquote><p><span>What you would need can be referred to as a jagged set.</span></p><p><span>With what we defined above, we could handle this by making two calls, then have the caller knit them together:</span></p><ol><li><p><span>one for all the mammalia </span><span data-color="#f6b26b" style="color: rgb(246, 178, 107);">Predators</span></p></li><li><p><span>one for the </span><span data-color="#76a5af" style="color: rgb(118, 165, 175);">EATS</span><span> </span><span data-color="#f6b26b" style="color: rgb(246, 178, 107);">Pollinator</span><span> relationships</span></p></li></ol><p><span>While this would technically work, it would get messy fast, and it also increases both the information across the wire, and the work the caller needed to do on their end.  To make this work in a single call, instead of the query I had above, I&#8217;d have to do something a bit more involved: I&#8217;d need to use a subquery.</span></p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;sql&quot;,&quot;nodeId&quot;:&quot;20a91c6a-def6-45c9-8360-9dc71385a4c2&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-sql">MATCH (pre:Predator)
  WHERE pre.class=&#8217;mammalia&#8217;
  CALL (pre) {
    MATCH (pre)-[e:EATS]-&gt;(p:Pollinator)
      WHERE e.frequencyPerDay &gt; 5
        AND p.class=&#8217;insecta&#8217;
    RETURN collect({e,p}) AS e_p_collection
  }
RETURN pre, e_p_collection</code></pre></div><p><span>This tells the database to always return the matching </span><span data-color="#f6b26b" style="color: rgb(246, 178, 107);">Predators</span><span>, but also return the collection of the </span><span data-color="#f6b26b" style="color: rgb(246, 178, 107);">Pollinators </span><span>they </span><span data-color="#76a5af" style="color: rgb(118, 165, 175);">EAT </span><span>more frequently than 5 per day if they have any matches.</span></p><p><span>The good news is, I already had the deep systems in place to do that. The bad news is, I hadn&#8217;t figured out how to get them to work on the querystring api.</span></p><p><span>That took some work.</span></p><h2><strong><span>Compounding with Subqueries</span></strong></h2><p><span>One more piece I need to share to set the context has to do with the way subqueries are defined on the querystring.</span></p><p><span>In </span><a href="/__u/limitlessledger.substack.com/p/last-week-in-review-jan-26-2026"><span>Last Week in Review Jan 26, 2026</span></a><span> I go into some depth about subqueries, and I covered them in some detail here </span><a href="/__u/limitlessledger.substack.com/i/189664701/the-return-of-the-refactor-bubbling-trees-and-digests"><span>Week in review Mar 01, 2026</span></a><span>, but here&#8217;s a  quick overview:</span></p><p><span>A subquery is an additional chunk of data that is gathered based on an initial query (for a node or a relationship) I refer to as the &#8220;root&#8221;. A way to think about it, would be getting to a particular place, and seeing what is nearby. Subqueries can be potentially any length and are expressed by a chain of relationships.</span></p><p><span>Different shapes of information are useful for different needs and as of now, the system supports three:</span></p><ul><li><p><strong><span>Counts:</span></strong><span> the number of items that match the subquery definition</span></p></li><li><p><strong><span>Digests:</span></strong><span> a table shaped record made up of specific values from the matches</span></p></li><li><p><strong><span>Trees:</span></strong><span> the full definition of every entity that matches the definition</span></p></li></ul><p><span>Currently a subquery is requested by referencing a descriptive key that maps to the full configuration based definition on the service.</span></p><p><span>So I could say:<br></span><em><span>/ecoapi/</span><span data-color="#f6b26b" style="color: rgb(246, 178, 107);">pollinator</span><span>/</span><span data-color="#76a5af" style="color: rgb(118, 165, 175);">pollinates</span><span>/</span><span data-color="#f6b26b" style="color: rgb(246, 178, 107);">flower</span><span>/?with_relationships=predators_who_ambush_from_that_flower</span></em><span><br><br>On the backend, it would know that we were looking for the </span><span data-color="#76a5af" style="color: rgb(118, 165, 175);">POLLINATES </span><span>relationship between the </span><span data-color="#f6b26b" style="color: rgb(246, 178, 107);">Pollinator </span><span>and the </span><span data-color="#f6b26b" style="color: rgb(246, 178, 107);">Flower</span><span>, and we also wanted additional information about </span><span data-color="#f6b26b" style="color: rgb(246, 178, 107);">Predators </span><span>that hide in that </span><span data-color="#f6b26b" style="color: rgb(246, 178, 107);">Flower </span><span>and </span><span data-color="#76a5af" style="color: rgb(118, 165, 175);">EAT </span><span>that </span><span data-color="#f6b26b" style="color: rgb(246, 178, 107);">Pollinator</span><span>. I&#8217;ll spare you the cypher as it gets quite involved.</span></p><p><span>In a form of shorthand you could say:</span></p><p><span>Root relationship triplet is: </span><span data-color="#f6b26b" style="color: rgb(246, 178, 107);">pollinator</span><span>-</span><span data-color="#76a5af" style="color: rgb(118, 165, 175);">pollinates</span><span>-</span><span data-color="#f6b26b" style="color: rgb(246, 178, 107);">flower</span></p><p><span>Sub query relationship triplets are: </span></p><ul><li><p><span data-color="#f6b26b" style="color: rgb(246, 178, 107);">predator</span><span>-</span><span data-color="#76a5af" style="color: rgb(118, 165, 175);">eats</span><span>-</span><span data-color="#f6b26b" style="color: rgb(246, 178, 107);">pollinator</span></p></li><li><p><span data-color="#f6b26b" style="color: rgb(246, 178, 107);">predator</span><span>-</span><span data-color="#76a5af" style="color: rgb(118, 165, 175);">hides_in</span><span>-</span><span data-color="#f6b26b" style="color: rgb(246, 178, 107);">flower</span></p></li></ul><p><span>The key lets the system know it needs to knit these relationships together in a meaningful way, without the consumer of the api needing to know the mechanics.</span></p><p><span>Adding the ability to search anywhere along the subquery adds a significant issue: how do I designate what should be searched and where. I realized my answer wasn&#8217;t as bad as I had thought.</span></p><h3><strong><span>Searching the relationships along the way</span></strong></h3><p><span>Each link in a subquery chain is a relationship by its very nature. As such it should be treated as any other relationship search. We could also use the same pattern of having JSON in the querystring argument.</span></p><p><span>So if I wanted that same subquery, but I only really wanted to know about the insect </span><span data-color="#f6b26b" style="color: rgb(246, 178, 107);">Predators </span><span>that use camouflage to </span><span data-color="#76a5af" style="color: rgb(118, 165, 175);">hide in</span><span> the </span><span data-color="#f6b26b" style="color: rgb(246, 178, 107);">Flowers</span><span> and </span><span data-color="#76a5af" style="color: rgb(118, 165, 175);">eat </span><span>with a frequency greater than 5 per day,  I could set the value of with_tree to:</span></p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;json&quot;,&quot;nodeId&quot;:&quot;c5e3fa75-b58b-4d26-8012-66455b299db8&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-json">{
  "subQueryKey":"predators_who_ambush_from_that_flower",
  "links":[{
    "target":"predator-eats-pollinator",
    "search":{
      "predator_class_eq":"insecta",
      "frequencyPerDay_gt":5
    }
  },{
    "target":"predator-hides_in-flower",
    "search":{
      "method_eq":"camouflage"
    }
  }]
}</code></pre></div><p><span>The downside is the caller would have to know the structure of what the subquery maps to, but that is likely a critical thing for anything like this. Additionally, any other query modifier (such as sort order, or max length) can also be applied using this structure.</span></p><p><span>I&#8217;m very excited about the capabilities this unlocks. I&#8217;m not quite done with the subquery handling yet. I&#8217;ll still be working on it next week, but the groundwork is already laid.</span></p><p><span>There are additional challenges, but they are more complex than this one. This piece is meant to outline the main effort. I may touch on these more complex changes in a future post.</span></p><h2><strong><span>Wrapup</span></strong></h2><p><span>With all this dense query related stuff, I should probably call it. I did promise a little venting about frustrations, so I&#8217;ll keep it brief:</span></p><h3><strong><span>Goodbye GitHub Actions, hello Dagger</span></strong></h3><p><span>For the second time at a critical juncture, GitHub Actions decided to suddenly shut down my pipeline due to lack of payment&#8230; on a free account&#8230; with no way to pay that I could find, and no warning.</span></p><p><span>The first time was when I was launching our live site, this time I was dealing with a hotfix I needed to make (markdown renderers don&#8217;t like null&#8230; who knew?). I&#8217;m sure it makes sense to them, but as a user, it was a horrible experience.</span></p><h3><strong><span>Suboptimal but functional</span></strong></h3><p><span>This led to me spending pretty much all of last weekend vibing up a build and deployment pipeline using Dagger. I&#8217;m sure the code is atrocious and overly bloated. In fact, according to the bot it&#8217;s actually bigger than my workhorse webservice code. At this point, it seems to be working reliably, and much quicker than GitHub Actions. Only downside (and it&#8217;s minor), it all runs on my local machine for now, so I have to be on it to run it. The pipeline is completely portable so can be plopped onto any host that has Docker. When we set up hosting for our internal tools, this  will be a natural fit for that.</span></p><h3><strong><span>The casino effect</span></strong></h3><p><span>I touched on this a little </span><a href="/__u/limitlessledger.substack.com/i/207785837/critical-thinking-is-not-optional"><span>in my last post</span></a><span>, but the realization that the various bot providers are not incentivized to actually solve your problems has really stuck with me. They are very much like a casino that frequently gives you an almost great hand, but rarely an actual prize. It&#8217;s just enough to keep you coming back and continue to play. I&#8217;m certainly not the first person to come up with that observation, in fact I remember reading that months ago but it really struck a chord.</span></p><p><span>If their entire business is selling tokens (and it is), then they couldn&#8217;t care less about solving your actual problems, but instead want you to keep spending tokens. While they have to solve things now and again to keep people hoping, getting close is even more effective, and much easier to achieve.</span></p><p><span>This combined with frustration with Cursor (I could write a dissertation on that one) and Gemini quirkiness inspired me to have Gemini spit out a Cyberpunk-inspired short story about what the dark near future would look like with the logical extensions of our current &#8220;AI&#8221; systems.</span></p><p><span>It took some tuning, but I think it turned out pretty nicely, and darkly funny. Ironically, there were some real life things that occurred in the production of it, that was very close to what the AI in the story did.</span></p><p><span>Let me know if you want to see it. I won&#8217;t be posting it&#8217;s fulltext here as it is absolutely AI generated, and substack is working hard to reduce the AI slop (which I greatly appreciate!!!).</span></p>]]></content:encoded></item><item><title><![CDATA[Last Two Weeks in Review July 20, 2026]]></title><description><![CDATA[Rich Text and Rich Learnings]]></description><link>https://limitlessledger.substack.com/p/last-two-weeks-in-review-july-20</link><guid isPermaLink="false">https://limitlessledger.substack.com/p/last-two-weeks-in-review-july-20</guid><dc:creator><![CDATA[Shayne Vacher-Moffeit]]></dc:creator><pubDate>Mon, 20 Jul 2026 14:55:55 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/9dff3552-2a52-4f48-b77e-6059a1ccfa4d_2816x1536.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><em><span>tldr: Adding searchable rich-text to the product, which may seem simple from the outside, has significant complexity and resulted in a few bot-related object lessons. We&#8217;ve also found that the core need our project helps address is helping people feel seen, for real.</span></em></p><p><span>The last two weeks have been primarily focused on adding searchable rich text to some of the fields in the product. There have also been some continuing learning on the product side about how we might hit the market and how we can best learn from those who this product is geared to help.</span></p><p><span>My primary focus will be on the engineering work and some of the serious gotchas about an AI standing in for a pairing partner, and how this can be a major problem. If I don&#8217;t get too long-winded, I&#8217;ll touch on some of the outreach work as well, but I&#8217;m guessing the tech will take most of the window.</span></p><h1><strong><span>Enriching the Text</span></strong></h1><p><span>Peppered throughout our product are various longer form fields: descriptions, summaries, and the like. In my initial build, for ease, I made them plain text. In most places the display did not keep formatting at all, so each of these blocks was a wall of text, no matter how many line breaks you put in them.</span></p><p><span>This was fine for conveying the base concept, but Jenn made it very clear that it would not work fine longterm. She was absolutely right. People have become used to WYSIWYG (What You See Is What You Get) editing and being able to format longer form content. This is particularly important for areas where formatting will help people understand potentially dense information.</span></p><p><span>It was a reasonable request, and one I knew I&#8217;d need to tackle eventually. Modern tooling makes it look easy, so the common stakeholder perception is that you plug it into the application with a small amount of work, and you&#8217;re on your way. This is often true with full-fledged website editors but less so when you are building a web application. While there are great existing libraries, including open source ones, there are still a ton of decisions that need to be made when adding something like this.</span></p><p><span>To make matters worse, she also wanted to be able to search the content of these rich text fields, and for very good reasons.</span></p><h2><strong><span>The challenge</span></strong></h2><p><span>To do this I needed to resolve a whole range of questions and problems.</span></p><p><span>These were the biggest:</span></p><ul><li><p><strong><span>Format of data:</span></strong><span> I needed to first choose a way to store the rich text formatting information. It would render in html, but I needed to either store that html or instructions of how to make that html. Fortunately, the industry has a great standardized and lightweight way to do this called markdown. It&#8217;s modeled off of the ways people would try to show formatting in plain text back in the day, so it&#8217;s quite intuitive.</span></p></li><li><p><strong><span>Not making it a problem:</span></strong><span> Allowing users latitude to change formatting, and essentially add html at will introduces a whole host of problems. Custom formatting can easily break layouts, but that&#8217;s not the worst of it. Giving users the ability to essentially generate html can allow them to do all sorts of things including embedding scripts, or images/videos to stuff we wouldn&#8217;t want to be associated with. Whatever I added needed to protect against that.</span></p></li><li><p><strong><span>Making search meaningful:</span></strong><span> The naive approach would be just store the markdown in the existing text field and call it a day, and that would have worked fine if we didn&#8217;t need to search it. The problem is, the formatting information would also come up in search results if you searched using that field. An example of how this could get wacky: in markdown if I want to bold something I surround it with **. So, if I had this string: &#8220;The **most important** thing.&#8221; and I searched for &#8220;important thing&#8221;,  I would not get any results. To find it by that phrase, I&#8217;d have to search for &#8220;important** thing&#8221;. Clearly, not intuitive.</span></p></li></ul><h2><strong><span>Solutions take form</span></strong></h2><p><span>It didn&#8217;t take me long to decide to use Markdown, that was really a &#8220;no brainer&#8221;. I knew that expecting the user to write raw markdown was a non-starter, so I needed a WYSIWYG control for that. Building my own was not really something I wanted to take on, so I went looking for libraries.</span></p><p><span>There are quite a few that serve that need, but of course the most mature would not be in our budget. I eventually settled on Milkdown. Their Crepe editor plays nicely with Nuxt (what our app is built on), and would handle the vast majority of the functionality needed for the editor, and it is open source.</span></p><p><span>Integrating Milkdown/Crepe seemed to be going smoothly. To handle the search issue, I decided I needed to store another field for plaintext. So if I had a field named summary, it would get a partner field named summaryPlaintext which it could be searched on.</span></p><h2><strong><span>I really miss human pairing buddies, or problems with relying on a bot</span></strong></h2><p><span>Throughout this time I was working closely with a bot (or two) to help work through these problems and bounce ideas off of. They were super helpful in identifying libraries to use based on my specific needs, and making integration with those libraries less of a massive learning curve.</span></p><p><span>For this next bit, I need to give you a little context of our application. We have the following systems:</span></p><ul><li><p><strong><span>UI - NodeJs application using Nuxt:</span></strong><span> this is what you see and interact with</span></p></li><li><p><strong><span>Webservice - NodeJs application using Koa:</span></strong><span>  this is what acts as the orchestrator between the UI and DB</span></p></li><li><p><strong><span>Database - Graph DB using Neo4j (Community Edition):</span></strong><span> this is the workhorse that stores and retrieves the data</span></p></li></ul><p><span>The control I&#8217;m discussing is part of the UI, and the extra fields I&#8217;m adding are needed by the Database, but the Webservice also needs to be part of that equation.</span></p><h3><strong><span>Frustration with a sycophant</span></strong></h3><p><span>My initial thought was to have the UI component generate both the markdown and the plaintext, then send them both into the Webservice, and it would just save them as is. This would make it so the UI would need to know to search for the plaintext value, which would never be returned. I also was adding a new validation rule that made sure if any of these rich text fields were passed in they would require both values to be set, so we could make sure the data was clean.</span></p><p><span>I ran the idea by one of the bots, and they thought it was brilliant. So I started implementing it. The return from the rich text editor was a bit clunky, as those things usually are set for a single value, but it was manageable. Once I put the Webservice validation in place, a whole bunch of my scenarios broke.</span></p><p><span>I decided to take a shower.</span></p><p><span>Shower thoughts are where some of the best realizations come from, and that was the case here. I was thinking about api versioning, and realized that if I was following strict SemVer (Semantic Versioning) on the Webservice, me adding the validation would be a major revision/breaking change and that didn&#8217;t sit well with me.</span></p><p><span>That&#8217;s when it hit me, my approach was awful. I had completely broken encapsulation. I was forcing my UI to know about a field that it would never show, and it had no real reason to care about, except it had to search using it.</span></p><p><span>Once I was done with my shower I let the bot know about my realization, to which it chirpily confirmed I was right and spewed out the reasons why the other previous approach was wrong.</span></p><p><span>It was a clear reminder that bots will always give you the feedback it thinks you want to hear rather than real critical feedback. Heck, if you ask a bot to give you critical feedback, it will critique everything whether or not that critique is warranted.</span></p><p><span>This is because it fundamentally has no idea what the concept you are discussing with it is. It just knows what series of characters are more likely to follow another set of characters. No matter what they throw at and train today&#8217;s AI&#8217;s, they are just sophisticated pattern matchers. Super cool in many ways, but fundamentally flawed when it comes to true understanding.</span></p><p><span>If I had been paired up with a real human partner, like other times in my career, the chance of them bringing up the glaring encapsulation issue early would have been much higher and saved me hours of effort.</span></p><p><span>If I hadn&#8217;t been lucky enough to have that shower thought when I did, I would have built layers of code on top of that, which would have made the system far more complex than it needed to be and harder to maintain.</span></p><h3><strong><span>A chilling example</span></strong></h3><p><span>The last example was a relatively tame one. There&#8217;s a much more brutal one that also happened in the same time period, guaranteed to get anyone with any form of compliance understanding very uncomfortable.</span></p><p><span>I mentioned earlier that to accomplish searchable rich text, I needed to introduce a new field. The problem is, until the values are saved again that field isn&#8217;t set. This means it won&#8217;t come up in search results until that happens. Not ideal.</span></p><p><span>I was discussing this challenge with a bot, and it &#8220;helpfully&#8221; spewed out the database command that would go through the database and copy the old field value into the new field.</span></p><p><span>Super helpful, right?</span></p><p><span>It made my blood run cold.</span></p><p><span>Here&#8217;s the thing, running raw modification scripts against a production database violates almost every data governance law in the book. While it&#8217;s fine on your local db that no one but you uses, if you&#8217;re actually building a real application for real people to use, it&#8217;s a huge no-no.</span></p><p><span>We&#8217;re also in a country covered by GDPR, where every modification to a data record with personal information needs to be logged, or massive fines can be levied. That said, even in the wild west that is the US compliance ecosystem, that little script (which totally seemed like it would have worked) would violate major policies (SOC 2 compliance to name a biggie).</span></p><p><span>The bot provided that script (unrequested) in an attempt to be helpful. Fortunately, my background of decades in the tech industry set off major alarm bells, so I pushed back hard.</span></p><p><span>The thing is, </span><strong><span>how many people out there would have gotten that script and ran it without a second thought, exposing their companies and/or themselves to MAJOR risk?</span></strong></p><p><span>Additionally, bots frequently make mistakes, so there was a significant chance that there was a flaw in the script that could have unrecoverable consequences.</span></p><p><span>To make matters even worse, if a non-technical stakeholder wanted the thing done and had a senior staff member who would say: &#8220;that&#8217;s not a great idea, we have to do it in a more methodical way&#8221;, or a bot enabled junior who says &#8220;Absolutely, I&#8217;ll do that right now!&#8221;, who do you think they&#8217;ll choose, and which do you think would be more likely to land them in very hot water?</span></p><h3><strong><span>Critical thinking is not optional</span></strong></h3><p><span>What both of these examples have in common is that today&#8217;s bots are tuned to tell you what you want to hear, whether or not it is accurate. In fact, accuracy is a much lower priority for them than engagement.</span></p><p><span>This is baked into each of them for sound business reasons: at the end of the day the companies that make bots want you to use as many tokens as possible as that is their revenue stream. The more you rely on and  interact with the bots the more money they make. This applies to the entire ecosystem, from chip manufacturers to agent creators. They do not care about you being compliant, nor having something solid. In fact, in many cases, the less solid it is the more dependent on the bots you become.</span></p><p><span>A human pairing partner is much more likely to be aligned in purpose and motivations, as well as having a real understanding of what is going on.</span></p><h2><strong><span>How I actually solved it</span></strong></h2><p><span>With my encapsulation realization, I made a hard pivot. The UI control would only interact with the markdown, and that would be the only field passed to the Webservice. The Webservice would know the value was markdown, and automatically populate a plaintext field stripped of the formatting information. It would also know to route searches of that field to the plaintext field. Things that call the webservice, such as the UI, have no knowledge at all of the plaintext existing, nor do they care.</span></p><p><span>There were other challenges, such as ensuring that escaped things were shown properly and restricted things didn&#8217;t look like options on the toolbar, but all in all after that shift everything worked a lot smoother.</span></p><p><span>We now have completely functional searchable rich text, though there is still a lot of manual saving of existing fields work to be done for them to appear in search.</span></p><h1><strong><span>Product realizations</span></strong></h1><p><span>We&#8217;re continuing to learn more about our potential customers and what might interest them in this system.</span></p><p><span>A key realization about the problems we are grappling with is that what is missing in today&#8217;s environment, both in the job market and online spaces in general, is that most of us don&#8217;t feel seen or cared about.</span></p><p><span>We shape our outward image to whatever might make us appear better in some algorithm or another, but how much are they reflections of who we </span><em><span>really</span></em><span> are?</span></p><p><span>When we apply for jobs we feel well suited for and get a rejection letter (if we&#8217;re lucky), do we really feel like someone took the time to consider us? They may very well have, but it sure doesn&#8217;t look like it from our perspective.</span></p><p><span>On the other side of the fence, if we post a job looking for a specific set of skills, the flood of desperate applicants who don&#8217;t match the qualifications, or possibly are not even real is enough to overwhelm anyone. Does it feel that anyone cares enough about our needs to actually target their applications?</span></p><p><span>We are more connected than ever before (I have regular video calls with an advisor on the other side of the planet), yet we are feeling less seen, less heard, and less cared about for our real qualities than ever before.</span></p><p><span>This is not a problem we can solve alone, it&#8217;s a multifaceted beast that will take at least decades to unravel, but what we&#8217;re working on, I feel, is one of the pieces that can help with this.</span></p><p><span>If you find what I write about interesting, and want to give us feedback about what can help us in our efforts to make things a bit better, consider becoming one of our </span><a href="https://skillbearings.com/become-a-design-partner#designpartnerform"><span>Design Partners</span></a><span>.</span></p>]]></content:encoded></item><item><title><![CDATA[We've got a particular set of skills]]></title><description><![CDATA[The more we dig in, the more we realize that skills are never truly siloed, but interconnected to everything we experience and offer the world]]></description><link>https://limitlessledger.substack.com/p/weve-got-a-particular-set-of-skills</link><guid isPermaLink="false">https://limitlessledger.substack.com/p/weve-got-a-particular-set-of-skills</guid><dc:creator><![CDATA[Jennifer Moffeit-Vacher]]></dc:creator><pubDate>Tue, 14 Jul 2026 12:59:19 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/0e10660e-2002-414c-bc6d-fea51175ca35_1200x630.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><em><span>TLDR: We&#8217;re using stories from the past as well as our own to help demo our platform and the particular set of skills people built to do great things. Or just things, not everything has to be great, sometimes it can just exist. In turn, we&#8217;re building out more and more skills of our own in the process.</span></em></p><p><span>We recently imposed a huge deadline on ourselves to get a basic website and the application viewable to the public.</span></p><p><span>As with anything, this is always easier said than done.</span></p><p><span>Having launched hundreds of websites previously in life, I&#8217;m used to a certain level of deadline, stress, anxiety, and late-night double checking.</span></p><p><strong><span>This was next level because it&#8217;s really, truly </span></strong><em><strong><span>ours</span></strong></em><strong><span>.</span></strong></p><h3><strong><span>The questions that started it all</span></strong></h3><p><span>First of all, I&#8217;ve always treated any work like it is my own creation, because that&#8217;s just how I operate. But there was something different about this. Maybe it&#8217;s because we&#8217;ve been talking about this for a few years now, took the last year-ish to frame the idea, and we&#8217;re  trying to put into the simplest of words why it&#8217;s important. Why it matters, why people should care.</span></p><p><span>This thing we&#8217;ve built that started with me asking some questions:</span></p><ul><li><p><span>Why do we attach skills to a whole job duration instead of a specific achievement, project, or milestone?</span></p></li><li><p><span>Can we actually map how we learn our skills and progress over time so we can better understand and advocate for ourselves?</span></p></li><li><p>Is there an easier way to ask the same questions I&#8217;ve been asking people for years now - what&#8217;d you learn, how&#8217;d you grow, what did you take to the next role/adventure?</p></li></ul><p><span>While I&#8217;ve been pondering the philosophy of this, Shayne&#8217;s been wrestling with code to make the thing come into literal life. He&#8217;s been working magic, but I digress.</span></p><p><strong><span>The point is: we have something others can now see. We have a </span><a href="https://skillbearings.com/"><span>website</span></a><span>! and an </span><a href="https://app.skillbearings.com/"><span>application</span></a><span>!</span></strong></p><h3><strong><span>Demoing the data</span></strong></h3><h4><strong><span>Using our own information to test the system</span></strong></h4><p><span>To test this theory, we went way back in time. In history and our own lives. </span></p><p><span>We&#8217;ve been using historical figures to demo out the system as well as our own profiles. I can say it has been enlightening in understanding my skill journey, where it began, and how it evolved.</span></p><p><span>Thinking back that far really helped ground me in what has continually been present for me or what I gravitated toward. I tried a lot of things, some of them led to other pathways that are a core part of who I am. Some I stopped doing and wish I&#8217;d kept up.</span></p><p><span>I found for me the great lightbulb moments while looking at my skills and the story behind them are 1. try new stuff and 2. ask yourself what you learned from one point in the path to the next, and what you brought with you.</span></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!VJKa!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9ac2b4bb-47e9-49f2-959f-66a9fddd76ff_1184x1152.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!VJKa!, /__u/limitlessledger.substack.com/w_424, /__u/limitlessledger.substack.com/c_limit, /__u/limitlessledger.substack.com/f_webp, /__u/limitlessledger.substack.com/q_auto:good, /__u/limitlessledger.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9ac2b4bb-47e9-49f2-959f-66a9fddd76ff_1184x1152.jpeg 424w, /__u/substackcdn.com/image/fetch/$s_!VJKa!, /__u/limitlessledger.substack.com/w_848, /__u/limitlessledger.substack.com/c_limit, /__u/limitlessledger.substack.com/f_webp, /__u/limitlessledger.substack.com/q_auto:good, /__u/limitlessledger.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9ac2b4bb-47e9-49f2-959f-66a9fddd76ff_1184x1152.jpeg 848w, /__u/substackcdn.com/image/fetch/$s_!VJKa!, /__u/limitlessledger.substack.com/w_1272, /__u/limitlessledger.substack.com/c_limit, /__u/limitlessledger.substack.com/f_webp, /__u/limitlessledger.substack.com/q_auto:good, /__u/limitlessledger.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9ac2b4bb-47e9-49f2-959f-66a9fddd76ff_1184x1152.jpeg 1272w, /__u/substackcdn.com/image/fetch/$s_!VJKa!, /__u/limitlessledger.substack.com/w_1456, /__u/limitlessledger.substack.com/c_limit, /__u/limitlessledger.substack.com/f_webp, /__u/limitlessledger.substack.com/q_auto:good, /__u/limitlessledger.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9ac2b4bb-47e9-49f2-959f-66a9fddd76ff_1184x1152.jpeg 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!VJKa!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9ac2b4bb-47e9-49f2-959f-66a9fddd76ff_1184x1152.jpeg" width="364" height="354.1621621621622" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9ac2b4bb-47e9-49f2-959f-66a9fddd76ff_1184x1152.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1152,&quot;width&quot;:1184,&quot;resizeWidth&quot;:364,&quot;bytes&quot;:84556,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://limitlessledger.substack.com/i/205576735?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9ac2b4bb-47e9-49f2-959f-66a9fddd76ff_1184x1152.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!VJKa!, /__u/limitlessledger.substack.com/w_424, /__u/limitlessledger.substack.com/c_limit, /__u/limitlessledger.substack.com/f_auto, /__u/limitlessledger.substack.com/q_auto:good, /__u/limitlessledger.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9ac2b4bb-47e9-49f2-959f-66a9fddd76ff_1184x1152.jpeg 424w, /__u/substackcdn.com/image/fetch/$s_!VJKa!, /__u/limitlessledger.substack.com/w_848, /__u/limitlessledger.substack.com/c_limit, /__u/limitlessledger.substack.com/f_auto, /__u/limitlessledger.substack.com/q_auto:good, /__u/limitlessledger.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9ac2b4bb-47e9-49f2-959f-66a9fddd76ff_1184x1152.jpeg 848w, /__u/substackcdn.com/image/fetch/$s_!VJKa!, /__u/limitlessledger.substack.com/w_1272, /__u/limitlessledger.substack.com/c_limit, /__u/limitlessledger.substack.com/f_auto, /__u/limitlessledger.substack.com/q_auto:good, /__u/limitlessledger.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9ac2b4bb-47e9-49f2-959f-66a9fddd76ff_1184x1152.jpeg 1272w, /__u/substackcdn.com/image/fetch/$s_!VJKa!, /__u/limitlessledger.substack.com/w_1456, /__u/limitlessledger.substack.com/c_limit, /__u/limitlessledger.substack.com/f_auto, /__u/limitlessledger.substack.com/q_auto:good, /__u/limitlessledger.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9ac2b4bb-47e9-49f2-959f-66a9fddd76ff_1184x1152.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Me, at four-ish, right before dance class. Clearly not a top skill, but I learned throughout this process of going back that far that I have tons of skills. Some never moved past novice, but I was enthusiastic nonetheless.</figcaption></figure></div><h4>Working with historic icons to find deeper stories of learning and progression</h4><p><span>I&#8217;ve got a huge list but so far, here&#8217;s where we are at with what is viewable, so you can see how it works:</span></p><ul><li><p><a href="https://app.skillbearings.com/adalovelace"><span>Ada Lovelace</span></a><span> - established foundational principles for theoretical computability and machine architecture.</span></p></li><li><p><a href="https://app.skillbearings.com/alanturing"><span>Alan Turing</span></a><span> - visionary mathematician, logician, and master cryptanalyst whose cross-functional breakthroughs laid the structural bedrock for the modern digital era.</span></p></li><li><p><a href="https://app.skillbearings.com/avonhumboldt"><span>Alexander von Humboldt</span></a><span> - The ultimate scientific disruptor of the 19th century and a visionary polymath who fundamentally re-engineered how humanity understands the natural world.</span></p></li><li><p><a href="https://app.skillbearings.com/cshannon"><span>Claude Shannon</span></a><span> - visionary mathematician and electrical engineer widely revered as the &#8220;father of information theory&#8221;</span></p></li><li><p><a href="https://app.skillbearings.com/hedylamarr"><span>Hedy Lammar</span></a><span> - her architectural design serves as a foundational milestone for modern wireless infrastructure, including Wi-Fi, GPS, and Bluetooth technology</span></p></li><li><p><a href="https://app.skillbearings.com/hildegardofbingen"><span>Hildegard of Bingen</span></a><span> - the founder of scientific natural history in Germany.</span></p></li><li><p><a href="https://app.skillbearings.com/leonardodavinci"><span>Leonardo da Vinci</span></a><span> - Stands as history&#8217;s ultimate High Renaissance polymath, a visionary who refused to see any boundary between the beauty of art and the rigor of science.</span></p></li><li><p><a href="https://app.skillbearings.com/marysomerville"><span>Mary Somerville</span></a><span> &#8211; The &#8220;Queen of Science&#8221; in the 19th century, she was an authority in physical sciences, and inspired the coining of the term scientist.</span></p></li></ul><p><span>Now I have the hard job of figuring out how to tell people about this.</span></p><p><span>The best way I know how is to try to be human and tell stories along with it all.</span></p><p><span>So, I&#8217;m going to try to continue to use historical figures to help me show off the system, and drive home how to show progression of skills, how non-traditional pathways work to build learning, and honestly, make it a little more engaging and fun (maybe only for me, we&#8217;ll see).</span></p><h4><strong><span>Leonardo da Vinci&#8217;s (Terrible) Time Management</span></strong></h4><p><span>I started with Leonardo da Vinci, because he was the first person I thought of. Digging into the depth of his skill and where he really flails is kinda wild.</span></p><p><span>He was the artist that would stare at a wall for a day or two to understood how light worked. He was &#8216;unlettered&#8217;/not formally educated, and had to find different paths to learning that were available to him. That led him to study anatomy intensely however he could, which helped him paint and sculpt more realistic portraits. His particular intermix of skills that might seem strange from the outside is what made him truly exceptional at what he did.</span></p><p><span>Some things he </span><em><span>really </span></em><span>struggled with. He was notoriously bad at keeping deadlines and delivering work. He ended up in a twenty year court battle for not delivering work he was contractually obligated to complete.</span></p><p><span>He straight up nerded, got obsessed and curious. Which is great, but he did it to a point he went down a lot of tracks that, let&#8217;s say, weren&#8217;t in scope.</span></p><p><span>He wasn&#8217;t easy to work with, and I truly wonder if he had peer reviews what that would look like. I&#8217;m pretty certain it wouldn&#8217;t be all &#8220;you&#8217;re an asset to any organization&#8221;, and that he&#8217;d be told he&#8217;s an expert in Oil Painting but at best a novice at Project and Time Management.</span></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!YGH_!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b79cf97-7b9f-4a0a-9d4e-5f575d9c87cc_746x444.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!YGH_!, /__u/limitlessledger.substack.com/w_424, /__u/limitlessledger.substack.com/c_limit, /__u/limitlessledger.substack.com/f_webp, /__u/limitlessledger.substack.com/q_auto:good, /__u/limitlessledger.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b79cf97-7b9f-4a0a-9d4e-5f575d9c87cc_746x444.png 424w, /__u/substackcdn.com/image/fetch/$s_!YGH_!, /__u/limitlessledger.substack.com/w_848, /__u/limitlessledger.substack.com/c_limit, /__u/limitlessledger.substack.com/f_webp, /__u/limitlessledger.substack.com/q_auto:good, /__u/limitlessledger.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b79cf97-7b9f-4a0a-9d4e-5f575d9c87cc_746x444.png 848w, /__u/substackcdn.com/image/fetch/$s_!YGH_!, /__u/limitlessledger.substack.com/w_1272, /__u/limitlessledger.substack.com/c_limit, /__u/limitlessledger.substack.com/f_webp, /__u/limitlessledger.substack.com/q_auto:good, /__u/limitlessledger.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b79cf97-7b9f-4a0a-9d4e-5f575d9c87cc_746x444.png 1272w, /__u/substackcdn.com/image/fetch/$s_!YGH_!, /__u/limitlessledger.substack.com/w_1456, /__u/limitlessledger.substack.com/c_limit, /__u/limitlessledger.substack.com/f_webp, /__u/limitlessledger.substack.com/q_auto:good, /__u/limitlessledger.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b79cf97-7b9f-4a0a-9d4e-5f575d9c87cc_746x444.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!YGH_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b79cf97-7b9f-4a0a-9d4e-5f575d9c87cc_746x444.png" width="720" height="428.5254691689008" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9b79cf97-7b9f-4a0a-9d4e-5f575d9c87cc_746x444.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:444,&quot;width&quot;:746,&quot;resizeWidth&quot;:720,&quot;bytes&quot;:46816,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://limitlessledger.substack.com/i/205576735?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b79cf97-7b9f-4a0a-9d4e-5f575d9c87cc_746x444.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!YGH_!, /__u/limitlessledger.substack.com/w_424, /__u/limitlessledger.substack.com/c_limit, /__u/limitlessledger.substack.com/f_auto, /__u/limitlessledger.substack.com/q_auto:good, /__u/limitlessledger.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b79cf97-7b9f-4a0a-9d4e-5f575d9c87cc_746x444.png 424w, /__u/substackcdn.com/image/fetch/$s_!YGH_!, /__u/limitlessledger.substack.com/w_848, /__u/limitlessledger.substack.com/c_limit, /__u/limitlessledger.substack.com/f_auto, /__u/limitlessledger.substack.com/q_auto:good, /__u/limitlessledger.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b79cf97-7b9f-4a0a-9d4e-5f575d9c87cc_746x444.png 848w, /__u/substackcdn.com/image/fetch/$s_!YGH_!, /__u/limitlessledger.substack.com/w_1272, /__u/limitlessledger.substack.com/c_limit, /__u/limitlessledger.substack.com/f_auto, /__u/limitlessledger.substack.com/q_auto:good, /__u/limitlessledger.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b79cf97-7b9f-4a0a-9d4e-5f575d9c87cc_746x444.png 1272w, /__u/substackcdn.com/image/fetch/$s_!YGH_!, /__u/limitlessledger.substack.com/w_1456, /__u/limitlessledger.substack.com/c_limit, /__u/limitlessledger.substack.com/f_auto, /__u/limitlessledger.substack.com/q_auto:good, /__u/limitlessledger.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b79cf97-7b9f-4a0a-9d4e-5f575d9c87cc_746x444.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">What I imagine Da Vinci&#8217;s Time Management skill would look like. He never really got much past Advanced Beginner with The Last Supper - only because he had to work around the hours of the monastery and patrons on that one.</figcaption></figure></div><h4><strong><span>Skills aren&#8217;t a movie montage, as much as cinema would like us to think so</span></strong></h4><p><span>It all got me thinking about how much of what we learn is so interconnected with our entire lives and our experiences, but yet that&#8217;s really hard to see. It is hard to see the breakdown of how much time it truly takes to get to an expert level.</span></p><p><span>It&#8217;s hard to see how sometimes the skills we aren&#8217;t so good at help us in some way. Perhaps because someone isn&#8217;t so great at something they offload it, work around it, make the lack of skill work for them. </span></p><p><span>Or in Da Vinci&#8217;s case they run away from it completely and still make it work.</span></p><p><span>Skill building isn&#8217;t an ever constant hustle like we see in montages. Sometimes people never get better at a skill they need or want.</span></p><p><span>Skill building has times of quiet reflection, living life, and having moments of clarity in the most unrelated moments. Sometimes it&#8217;s just completely doing something else for a long while and picking it back up again. Other times it can ignoring everything else and becoming obsessed.</span></p><p><span>There is no perfect way to learn, but maybe the closest to perfect is to just keep trying to learn anything at all.</span></p><div><hr></div><p><em><strong>P.S. We aren&#8217;t building this in a vacuum.</strong> </em></p><p>If you want to play a real part in shaping how we map human growth, we are actively looking for <strong>design partners</strong> to test the platform, break things, and give us truly honest feedback.</p><p>Learn more at <a href="https://skillbearings.com">skillbearings.com</a>.<br></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://limitlessledger.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="/__u/limitlessledger.substack.com/subscribe"><span>Subscribe now</span></a></p>]]></content:encoded></item><item><title><![CDATA[Last two weeks in review Jul 6, 2026]]></title><description><![CDATA[Deadlines. What are they good for?]]></description><link>https://limitlessledger.substack.com/p/last-two-weeks-in-review-jul-6-2026</link><guid isPermaLink="false">https://limitlessledger.substack.com/p/last-two-weeks-in-review-jul-6-2026</guid><dc:creator><![CDATA[Shayne Vacher-Moffeit]]></dc:creator><pubDate>Mon, 06 Jul 2026 15:04:21 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/fa48f644-327f-4307-b11d-511350456580_2816x1536.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><em><span>Tldr: Deadlines are a fraught subject that has led to tremendous pain, but they are a thing for very good reasons. I touch on how XP and Scrum both arose from this tension, and I share how a recent deadline actually helped us achieve several big goals, including launching </span><a href="http://www.skillbearings.com"><span>Skill Bearings</span></a><span>.</span></em></p><p><span>I am no fan of deadlines, particularly for software.</span></p><p><span>This is a controversial statement in conventional software development. It is a pretty common sentiment among the agile engineering community, or at least that&#8217;s the prevailing view that people tend to hold about agile engineers.</span></p><p><span>The reality is far more nuanced.</span></p><p><span>Many in the engineering community have been beaten up by deadlines and the systems built around them. Pretty much any engineer you talk to can cite many examples where they were asked for a gut feel of when something might be done, only to find themselves in a situation where they are strictly held to that guess they made with very little information, or even worse, told that guess was too high so they need to come up with a shorter one.</span></p><p><span>In particularly bad situations they will have a deadline assigned to them without them having a say.</span></p><p><span>This dynamic is the underpinning of a lot of the friction about deadlines in agile. Scar tissue from toxic interactions compounded by the very fact that software engineering is an invention and knowledge based discipline, where early in the lifecycle it&#8217;s literally impossible to predict with any level of accuracy when something will be good enough to call done.</span></p><p><span>On the other hand, it makes sense why deadlines are needed. Consider paying a lot of money for something you are staking your reputation and livelihood on, only to be told that there is no way to predict when you&#8217;ll get that thing, nor any real verifiable assurance that you will get what you are expecting.</span></p><p><span>It&#8217;s not something that many would want to do. If someone did make that choice and end up getting nothing for their support there are many who would consider that person completely foolish.</span></p><p><span>Unfortunately, that&#8217;s pretty much what we engineers are asking others to do when we resist deadlines.</span></p><p><span>There&#8217;s also another factor to the whole mess having to do with how many of our brains work. If we have the perception that we have a lot of time, or completely flexible time we tend to make choices that will make things go longer. This was captured well by the old adage &#8220;all meetings will expand to fill their allotted time.&#8221; It&#8217;s not just meetings, it&#8217;s pretty much everything we do.</span></p><h2><strong><span>It goes to eleven</span></strong></h2><p><span>It was in exactly this push and pull dynamic that the various agile methodologies and practices evolved.</span></p><p><span>Extreme Programming (XP) took a scientific approach to how to solve these problems (as well as many others in the field). They would take a practice that everyone agreed led to good software and asked essentially, what would happen if they took it to the extreme level (turn it up to 11). After that, they would examine if it made things better or worse for their software delivery practice. Based on that, they&#8217;d decide if they wished to keep it or not.</span></p><p><span>From this experimental approach numerous practices arose and have become the underpinnings of high quality professional software delivery. Examples include:</span></p><ul><li><p><strong><span>Test Driven Development</span></strong><span>: Common agreement that unit tests made software better.</span></p><ul><li><p><em><span>Experiment:</span></em><span> What if tests were written before the code?</span></p></li><li><p><em><span>Outcome:</span></em><span> Granular and more maintainable code, with exceptional levels of reliability</span></p></li><li><p><em><span>Surprise:</span></em><span> Rapidly became less about testing, but more about driving the design in modular ways.</span></p></li><li><p><em><span>Legacy:</span></em><span> Still used a lot today and often considered a development best practice. People learned that using tests to express behavior led to less churn and developed Behavior Driven Development. Other subdisciplines also emerged, such as Database Test Driven Development.</span></p></li></ul></li><li><p><strong><span>Pair Programming:</span></strong><span> Common agreement that code reviews led to better software.</span></p><ul><li><p><em><span>Experiment:</span></em><span> What if we had continual code reviews by having the developer and the reviewer sit together at the same computer?</span></p></li><li><p><em><span>Outcome:</span></em><span> Delivery did not slow down and the output was better quality. Better information sharing amongst the team.</span></p></li><li><p><em><span>Surprise:</span></em><span> Delivery times often sped up due to the need for developers to voice their thoughts, leading heading off bad ideas earlier. Once people got used to the practice, they tended to prefer it over working independently.</span></p></li><li><p><em><span>Legacy:</span></em><span> Still very active in the field. It has grown further into the concept of Mob Programming where the entire team works on the same work item/computer.</span></p></li></ul></li><li><p><strong><span>Continuous Integration:</span></strong><span> The shorter period of time there is before all the team&#8217;s code is put together, the less time is spent dealing with integration issues.</span></p><ul><li><p><em><span>Experiment:</span></em><span> What if we integrated the code at least once a day, but ideally multiple times per day?</span></p></li><li><p><em><span>Outcome:</span></em><span> Less time fighting merge issues and diverging designs</span></p></li><li><p><em><span>Surprise:</span></em><span> Tended to allow integration issues that did arise to be resolved quickly, support another practice Collective Code Ownership, and promote more of an &#8220;all in it together&#8221; mindset on the team.</span></p></li><li><p><em><span>Legacy:</span></em><span> Entire industries of Continuous Integration tooling have sprung up </span><em><span>(note: it is a practice NOT a tool, no matter what the tool salespeople tell you)</span></em><span>. The concept matured into Continuous Delivery, where not only were things integrated, since they needed to be built and tested to ensure the integration worked, people realized they could also be deployed automatically.</span></p></li></ul></li></ul><h2><strong><span>Two different ways to handle the same problem</span></strong></h2><p><span>Other practices such as Scrum arose due to the same tension. Their approach was different than the XP folks, but due to cross pollination a lot of XP practices are now attributed to Scrum.</span></p><p><span>One thing pretty much all of these practices shared was the realization that the feedback loop needed to speed up dramatically. Each approach had different ways to achieve this.</span></p><p><span>The two prevailing schools of thought were:</span></p><ul><li><p><span>Getting more focused on what really mattered - XP aligned</span></p></li><li><p><span>Shortening the deadline cycle - Scrum aligned</span></p></li></ul><p><span>Their common philosophy is the more frequent the touchpoint is between the stakeholders and the engineers, the more likely the stakeholders would be ok with the spend, and the engineers would be more likely to build something that matched what the stakeholders wanted. It would also allow the stakeholders to better predict when things might be done so they could communicate better with their own stakeholders.</span></p><p><span>For the most part, both things worked well. They did, of course, have their shortcomings, one of the biggest comes down to the fact that most innovative software engineering is inherently unpredictable, and the predictable stuff is not really something that is as likely to be what is going to be a big differentiator for a business.</span></p><p><span>This led to a lot of the great ideas of the practices getting oddly corrupted or becoming dogmatically used patterns, rather than tied to the actual outcome they were meant to achieve.</span></p><h2><strong><span>Story Points: How Gummy Bears became corporate thugs</span></strong></h2><p><span>A classic example of this is the concept of Story Points. This was an XP invention that Ron Jeffries invented by accident, and regrets. Basically the story comes down to this same deadline tension.</span></p><p><span>XP had come up with User Stories, which took the part of Use Cases they thought helped &#8211;the focus on what the user was trying to achieve with the system&#8211; and stripped away all the fluff. In doing that, they went from a multiple page document down to a series of things that fit on index cards.</span></p><p><span>This allowed a granular approach to developing software, where each of these little bits of user functionality could be prioritized and arranged in multiple ways. It enabled a sense of movement and accomplishment, as well as a way to facilitate fast feedback.</span></p><h3><strong><span>Not all functionality is created equal</span></strong></h3><p><span>The key issue is that these bits of functionality could be vastly different in effort. Both the stakeholders and the team needed a way to get a sense of that.</span></p><p><span>There was also the problem that a pack of index cards didn&#8217;t answer the question </span>very well <span>for the stakeholder about when they&#8217;d see a return on their investment, and/or when they could share it with their own stakeholders.</span></p><p><span>The stakeholders were accustomed to working with &#8220;man days&#8221; or &#8220;man hours&#8221;, as in how much time would the average set of developers need before they can deliver this Use Case. This of course was an inherently flawed metric as I&#8217;ve mentioned before, but the more granular approach must have been enticing.</span></p><h3><strong>It&#8217;s all relative</strong></h3><p><span>There was a big desire to apply this same measure to User Stories. The thing is, as mentioned before, you can&#8217;t really estimate the time it will take to do a work item or another, but you can get a sense of how big or small it is compared to its peers.</span></p><p><span>So the reasoning was simple: add in an abstract relative sizing mechanism, at the time it was Gummy Bears, and that would provide the conceptual abstraction to know if something is bigger or smaller than something else. This would aid in prioritization among many other things.</span></p><p><span>I&#8217;m not sure when the cracks started showing, but I can tell you, I&#8217;ve seen the firsthand damage of Story Points many times. From early in my career where people were still stuck on converting them to segments of time, to later in my career when people treated them like a scoring mechanism: &#8220;I want to get my points for this Sprint&#8221;. While the original concept wasn&#8217;t the worst, the way it got corrupted is downright stunning, and a testament to the human ability to game just about anything.</span></p><h3><strong><span>Pulling the emergency brake</span></strong></h3><p><span>Well, this was originally supposed to be a short preamble about the agile view on deadlines and where the tension shows up, and how despite popular thought otherwise, </span><em><span>agile is NOT in fact anti-deadline</span></em><span>. I&#8217;m afraid it turned into a bit of an agile history lesson.</span></p><p><span>I&#8217;m going to stop myself there and get to my main point:</span></p><h2><strong><span>What good IS a deadline?</span></strong></h2><p><span>We set a deadline last week, and it worked. It did lead to me pushing myself to a punishing, until-midnight fight with the first deployment to production, and levels of stress I hadn&#8217;t felt in many years. That said, all in all the level of focus both Jenn and I have had recently has been great. It&#8217;s also led to significant results.</span></p><p><span>We have:</span></p><ul><li><p><strong><span>Trimmed scope:</span></strong><span> We realized that the first thing we needed to get feedback on is our public display and to do that, we could focus on just that part of the application. We also could handle our ability to log in via a much simpler mechanism than the full authentication strategy I&#8217;m building for others to log in. There are too many other things that this simplified to mention, but it was a game changer.</span></p></li><li><p><strong><span>Extended the application deployment system to production:</span></strong><span> We are now deploying to our production environment, with a fully automated pipeline. To ensure our costs don&#8217;t explode, and for direct control we&#8217;re keeping the deployments to production manually triggered, but that&#8217;s a simple button push. The system still has some kinks, but I think I&#8217;ve cleaned up most of them.</span></p></li><li><p><strong><span>Launched both the website, and the application:</span></strong><span> This involved a fair amount of work from both of us. Related to trimming scope, we decided to separate our overall concept into multiple more-targeted named subproducts.</span></p></li></ul><p><span>So, we settled on the name </span><a href="https://skillbearings.com/"><span>Skill Bearings</span></a><span>. This part of the product is to enable you to take your bearings of the various skills and learnings that make up the entire picture of you. At this stage, we are selecting a handful of people we will work directly with to build out their profile on our system, who can help guide us to build something impactful that customers will love.</span></p><p><span>I still don&#8217;t like deadlines&#8230; but sometimes they are useful.</span></p><p><span>Please take a look at the site, and sign up if you are interested. We are particularly interested in people who are passionate about self reflection, and tracking their progress in their lives.</span></p>]]></content:encoded></item><item><title><![CDATA[Once more for the seats in the back]]></title><description><![CDATA[I feel like I've said this a billion times but I'll say it again: the system is setup to flatten us, and I'm so very tired of it. Something has to change, and it's probably us.]]></description><link>https://limitlessledger.substack.com/p/once-more-for-the-seats-in-the-back</link><guid isPermaLink="false">https://limitlessledger.substack.com/p/once-more-for-the-seats-in-the-back</guid><dc:creator><![CDATA[Jennifer Moffeit-Vacher]]></dc:creator><pubDate>Thu, 25 Jun 2026 18:54:44 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/d7608175-8cb3-4c9d-85ed-fe16c60cf8d5_1080x1080.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h4>First, a quite long sidequest into my writing style, cadence, and quandry</h4><p>Back a long, long time ago, I used to have a blog called &#8216;RANT&#8217; - my 20-something self, who was in public and in person very quiet, would use the space to go off on people&#8217;s behavior in public, why certain things happened the way they did, and how the world in general didn&#8217;t make sense. It was the opposite of myself externally and I loved having a space to just process the world.</p><h4>I walk a line</h4><p>Now, I&#8217;m a bit older and the internet is not a place to do that anymore without being seen in a light that&#8217;s unflattering in some way. Some people build brands on their own way of being, housed around authenticity, swear words, and crackling, biting humor which is entertaining to read or interact with but if you had to sit next to them at a dinner you&#8217;d probably lose your mind. Or at least I would. I have my own list of who those people are.</p><p>For me, there&#8217;s a fine line that I&#8217;m walking now between how I really feel, and how I desire to be seen. I never want to be that person that can be read but not tolerated in real life. I want to be approachable in both. I keep some parts of me for my closest of friends and confidants, while others may lay it all out there for everyone.</p><p>This is why in some ways I peel back from interaction in the public space because it&#8217;s hard to feel like you say the same things over and over again. It&#8217;s hard to see the systems and be gesturing broadly to a crowd of no one that can change it. It&#8217;s hard to keep having the energy for it.</p><p>I feel like most of what I&#8217;ve posted here is the same - all leaning toward the same idea that how the system is setup is not for us and it&#8217;s erasing our sense of self-understanding and sense of self.</p><p>I know that something has to be repeated many times for someone to &#8216;get&#8217; something, and that a lot of what most are saying in certain spaces is going on deaf ears.</p><p><strong>I know that the ears that need to hear this aren&#8217;t the ones that are reading</strong>, but perhaps if I every once in a while pop up with a new way of approaching this concept I&#8217;ll accomplish a few things:</p><ul><li><p>I&#8217;ll be able to be creative in my words, which I like</p></li><li><p>Someone else for the first time might read this and go &#8216;yeah, that&#8217;s right!&#8217; - which is a total win</p></li></ul><p>Now that I&#8217;ve gotten that out there, to the heart of the matter that keeps me up at night, wakes me up in the morning, and at random like a cat with the zoomies, gets me ramped up at random parts of the day.</p><h4>We have to shape the professional futures we want to see, as a whole, as a movement</h4><p>I&#8217;ve spoken to tons of job seekers and done a fair amount of research into the issues we see today. We all know the job market is a mess and that companies no longer lay people off only when there&#8217;s financial trouble but also when they are printing money. These things I don&#8217;t need to repeat.</p><p>But I do think what&#8217;s worth speaking about, even if it very much feels like zero shock to anyone, is that companies, stock markets, systems that employ and bring clients will not change on their own.</p><p>They have to be forced. Or, we need a different system to play in.</p><p>Companies have been going along just fine for a long time shoving people into boxy job titles while leaving out their non-traditional skills, their hobbies, and their life-won achievements that don&#8217;t fit into the corporate narrative. They erase what context doesn&#8217;t suit them. Or, there&#8217;s not even an option for it to exist at all. </p><p>They build a job shaped hole that everyone has to walk through everyday when they start work, and walk out of when they end their day.</p><h4>We can have it both ways, and so can they</h4><p>I get why companies pick and choose what they need to filter through and see in the moment. I have an attention problem so I deeply understand the need for no more information than what&#8217;s needed. </p><p>But, with that choice comes a concrete wall separating what will likely be of incredible use. As a whole, all of us, the places we work, the people we interact with are seeing fractured parts of our existence and what we have to offer the world.</p><p>But, perhaps someday instead of companies having to put up the walls because they don&#8217;t have a proper mechanism, people could decide in a concise and data-driven way what they might want to let through.</p><h4>Maybe all versions of ourselves meet at the gate</h4><p>Instead of a concrete wall, we form a gate that organizes life&#8217;s stream of work, curiosity, and achievement into readable functions for organizations, educational institutions, and communities to see the whole value someone could bring. If they want to bring it.</p><p>Whatever the person doesn&#8217;t want to let through, they don&#8217;t.</p><p>We&#8217;re trying to build this gate, and we&#8217;re finally getting around to positioning it in a way that hopefully makes sense.</p><p>As much as I like to play with words and explain things, explaining this issue and how we&#8217;re trying to go about fixing it has been one of the hardest things I&#8217;ve done (yet).</p><p>But I do think I&#8217;m starting to get somewhere with the difference between a job-shaped hole in a concrete wall and an individual-controlled gate.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://limitlessledger.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="/__u/limitlessledger.substack.com/subscribe"><span>Subscribe now</span></a></p><p></p>]]></content:encoded></item><item><title><![CDATA[Last two weeks in review Jun 22, 2026]]></title><description><![CDATA[Key insights often come from discomfort and challenges]]></description><link>https://limitlessledger.substack.com/p/last-two-weeks-in-review-jun-22-2026</link><guid isPermaLink="false">https://limitlessledger.substack.com/p/last-two-weeks-in-review-jun-22-2026</guid><dc:creator><![CDATA[Shayne Vacher-Moffeit]]></dc:creator><pubDate>Tue, 23 Jun 2026 17:50:32 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/bda195e7-5876-4671-bf43-315b7c13e020_2816x1536.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><em><span>tldr: While great questions don&#8217;t always feel great, they can lead you to better insights. It is easy to lose sight of the customer, no matter how well defined, when in build mode. There are people who enjoy entering data, we need to get to know them. Reducing update frequency to every other week</span></em></p><p><span>I had initially planned to get back on the post every week schedule, but something important came up that derailed that plan. In fact, due to that same thing, this update will be shorter than usual. Last Monday we met with someone very deep in the entrepreneurial ecosystem in Germany. Beyond being a well-connected angel investor and venture scout, he is a leader of an organization that represents our ultimate dream institutional partner. This was a high-stakes moment for us.</span></p><p><span>The purpose of the meeting was to demo the product we had discussed in Vienna, and show that it was not just a concept but actual functional software. While it&#8217;s not perfect, it certainly shows off the concept reasonably well, and I was thrilled to get a chance to walk him through it.</span></p><p><span>I was feeling like it was going pretty well. The software did its thing, there was no sign of unhappy demo gods (software crashing in the middle of a demo), and I was able to showcase the concept quite quickly for the depth of it.</span></p><p><span>Then he asked a question. It&#8217;s a question that I&#8217;m embarrassed to say, my brain went blank and into a little bit of a panic about:</span></p><p><em><span>&#8220;Who is the customer, and what are their needs?&#8221;</span></em></p><p><span>What&#8217;s so embarrassing about this is that I&#8217;ve spent countless hours asking others variations of the same question. I know the criticality of that question and the thought behind it. It&#8217;s the most fundamental question of any product development. In our work to this point, we had done a lot of work answering this question and digging deeply into it. Yet when he asked this question, my brain went blank.</span></p><p><span>My response was far from anything I was particularly proud of, but he expressed willingness to continue to help guide us.</span></p><p><span>We walked away from that meeting feeling a bit deflated. While the outcome was ultimately really good, not being able to answer that question well was a major letdown for both of us.</span></p><h2><strong><span>Confronting the builder&#8217;s blindspot</span></strong></h2><p><span>It sparked some really good discussions between me and Jenn. We both handled our letdown in different ways. Jenn dove into research. I dove into reflection.</span></p><p><span>My reflection was based around the overall question, despite all the focus on that question, why did my brain freeze when asked about it in the moment. This was something I had spent considerable time and energy covering in the business plan, and all aspects of what we had been doing, it should have been top of mind&#8230; that&#8217;s when it struck me. The reason it hadn&#8217;t been top of mind is that I had shifted my entire perspective to a delivery focus. I was so focused on creating software that expressed the concept, my customer obsession had slipped. It wasn&#8217;t that I didn&#8217;t know about the customer and their needs, it was that I was so hard focused on delivery that they weren&#8217;t top of mind.</span></p><p><span>While I can&#8217;t speak to Jenn&#8217;s rapid recall of the customer or their needs, her reaction after the call seems to suggest that she also felt she needed a clearer definition. One of the bits of feedback offered was that what we did share was far too broad of a group. We had been feeling this for some time as well, and Jenn dove into narrowing the niche, with an important perspective.</span></p><h2><strong><span>The hunt for people who love data entry</span></strong></h2><p><span>We&#8217;ve known for a long time one of the biggest detractors of what we are building is data entry. Many people would likely opt for a root canal rather than massive data entry and documentation. The problem is, for the system to show its true value it needs a lot of data. Ideally data entry is a regular and ongoing process that is part of the users&#8217; life, rather than only based on an immediate need.</span></p><p><span>To solve this, we discussed multiple approaches including: gamification,  conversational AI, and a broad integrations library. While each of these approaches has merit and a place on our roadmap, they each have a significant technical and product design lift. One that is out of the realm of possibility at this time.</span></p><p><span>The questions we were asked in that meeting led Jenn toward a different question:</span></p><p><em><span>&#8220;Was there a group of people, for whom data entry was something they enjoyed doing?&#8221;</span></em></p><p><span>It turns out that, yes. There is a group of people who enjoy entering the type of information that our product covers, and treat it as a hobby. As it turns out, they have a solid and robust community complete with conferences, and they absolutely have very strong feelings about what&#8217;s currently available on the market.</span></p><p><span>Even better, this community has a huge overlap with what we already identified as our key target market. We&#8217;re still in the early stages of connecting with that community, but it&#8217;s exciting to find a group that seems likely to not be put off by the biggest detractor of our system, provided, of course, that we can give them solid value for that effort.</span></p><h2><strong><span>Scope ruthlessness with an early MVP</span></strong></h2><p><span>With these insights in mind, we continued communicating with the gentleman we had met with. He continued to provide us with exactly the help we need, more tough questions that challenge us and improve our chances of success.</span></p><p><span>The next one was about the MVP. How can we get this thing to see the light of day in the shortest timeframe possible.</span></p><p><span>Our discussions around that topic led us to realize: we can significantly reduce scope if we only allow external users to interact with the public display. This will enable us to get feedback about what is or isn&#8217;t useful about the end product that the data entry is meant to achieve. That way we can continue to refine it based on real feedback, and hopefully build real excitement.</span></p><p><span>To that end, I set a target for myself to have the application publicly viewable by the end of the month&#8230; about a week and a half away. It&#8217;s actually quite close, but there&#8217;s a few pieces of significant work that need to be done.</span></p><h2><strong><span>Going forward at an adjusted pace</span></strong></h2><p><span>Speaking of targets. At the beginning of the year, I set a target for myself to post a review each week to illustrate progress, and to help me establish my voice as a tech founder. This has been an excellent practice as it has helped me think through some concepts, as well as voice my perspectives. It&#8217;s been gratifying to see Google Gemini being able to express more and more clearly my stance and what I&#8217;m working on.</span></p><p><span>While I&#8217;m still keeping to my commitment of regular updates, I&#8217;m thinking of shifting them to every other week. This is for two major reasons:</span></p><ul><li><p><span>Doing this every week severely limits schedule flexibility.</span></p></li><li><p><span>What was initially conceived of as short blurbs has turned into essays which take much more time than was anticipated.</span></p></li></ul><p><span>So for the next while at least, expect to hear from me every other week. Now back to trying to meet my public soft release goal.</span></p>]]></content:encoded></item><item><title><![CDATA[Last few weeks in review Jun 8, 2026]]></title><description><![CDATA[Ceremonies and Explorations]]></description><link>https://limitlessledger.substack.com/p/last-few-weeks-in-review-jun-8-2026</link><guid isPermaLink="false">https://limitlessledger.substack.com/p/last-few-weeks-in-review-jun-8-2026</guid><dc:creator><![CDATA[Shayne Vacher-Moffeit]]></dc:creator><pubDate>Mon, 08 Jun 2026 13:52:17 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/a86ba203-c7ee-4608-ac24-6b433bdcf689_2816x1536.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><em>tl;dr: part travelogue, part tech musings, these past three weeks have involved a medieval academic vow in Vienna, a sweltering exploration of Lyon, and showing dear friends our beautiful town Viana do Castelo. This time was characterized by good food, beautiful wanders, and rambling conversations, leading to the crystallization of a critical insight: A system built on probabilism is characteristically unsuited for core system logic. Instead it is well suited as a translation layer between messy human communication, and structured data that traditional code can work with deterministically.</em></p><p>My writing hiatus was a bit longer than expected, but it was quite eventful. While not the most productive as far as programming goes, there were several significant outcomes.</p><h2><strong>Reconnections in a storied capital</strong></h2><p>Thursday May 21st I returned to Vienna for the third time. Jenn came along with me, and we were joined with two close friends (one being my Data Science Advisor), who came all the way from Seattle to meet up with us.</p><p>This wasn&#8217;t just any gathering of friends though, we all came together for an important milestone. The next day, May 22nd, I was to join my classmates in the last joint graduation ceremony between Tomorrow University (ToU) and Vienna University Executive Academy (WU). When ToU started, they needed an accrediting body and WU agreed to be that for them. Now ToU is able to self-accredit, and that partnership ran its course.</p><p>Our friends arrived earlier in the day so were able to get a little rest from their long haul and major time shift. Travel went a whole lot smoother than feared and we had no real hiccoughs. Our friends had booked a beautiful apartment in the heart of Vienna within blocks of the downtown palace. This was the first time we had seen each other in person in over three years, and it was great to reconnect.</p><p>Once we settled in we headed off to the first graduation-oriented gathering. This gathering was held at a big hall called Gleis/Garten. It turned out we were the first guests there, and the person who was organizing things from the school had been a student in the last class I taught. Soon others trickled in, some school faculty and staff, alum in the area as well as students like me set to graduate the next day. The conversations flowed enthusiastically and easily. I was thrilled to get some time to connect with the more technical co-CEO of ToU and share with him a high-level description of what we&#8217;re working on. His counterpart was my thesis advisor and grader, so very well acquainted with it. He was very interested in learning more about it, so we&#8217;ve set up time to demo it to him in the very near future.</p><h2><strong>Old traditions and important milestones</strong></h2><p>The ceremony itself took place on WU campus in a building known as the Spaceship. It is a big imposing structure and is the library, as well as where big events like this take place. I&#8217;m not sure exactly how many others were graduating with me, but it wasn&#8217;t a huge amount, probably between 20 and 30. I honestly wasn&#8217;t sure what to expect, but was soon suited out in a cap and gown. A couple things caught our attention, one was a lady who was also dressed in robes, with a beautiful scepter, and it also quickly became apparent, fitting for Vienna, our music would be a live string quartet.</p><p>Having not been to many graduation ceremonies, I think it proceeded as they generally do, with inspiring speeches and cap throwing and the like. There was one interesting difference from what most graduation ceremonies I&#8217;ve heard of, and it involves the scepter.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!eqpW!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3120925f-99ae-4cf7-b307-9cdadbb5e815_6048x3916.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!eqpW!, /__u/limitlessledger.substack.com/w_424, /__u/limitlessledger.substack.com/c_limit, /__u/limitlessledger.substack.com/f_webp, /__u/limitlessledger.substack.com/q_auto:good, /__u/limitlessledger.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3120925f-99ae-4cf7-b307-9cdadbb5e815_6048x3916.jpeg 424w, /__u/substackcdn.com/image/fetch/$s_!eqpW!, /__u/limitlessledger.substack.com/w_848, /__u/limitlessledger.substack.com/c_limit, /__u/limitlessledger.substack.com/f_webp, /__u/limitlessledger.substack.com/q_auto:good, /__u/limitlessledger.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3120925f-99ae-4cf7-b307-9cdadbb5e815_6048x3916.jpeg 848w, /__u/substackcdn.com/image/fetch/$s_!eqpW!, /__u/limitlessledger.substack.com/w_1272, /__u/limitlessledger.substack.com/c_limit, /__u/limitlessledger.substack.com/f_webp, /__u/limitlessledger.substack.com/q_auto:good, /__u/limitlessledger.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3120925f-99ae-4cf7-b307-9cdadbb5e815_6048x3916.jpeg 1272w, /__u/substackcdn.com/image/fetch/$s_!eqpW!, /__u/limitlessledger.substack.com/w_1456, /__u/limitlessledger.substack.com/c_limit, /__u/limitlessledger.substack.com/f_webp, /__u/limitlessledger.substack.com/q_auto:good, /__u/limitlessledger.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3120925f-99ae-4cf7-b307-9cdadbb5e815_6048x3916.jpeg 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!eqpW!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3120925f-99ae-4cf7-b307-9cdadbb5e815_6048x3916.jpeg" width="1456" height="943" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3120925f-99ae-4cf7-b307-9cdadbb5e815_6048x3916.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:943,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:3769123,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://limitlessledger.substack.com/i/201147064?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3120925f-99ae-4cf7-b307-9cdadbb5e815_6048x3916.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!eqpW!, /__u/limitlessledger.substack.com/w_424, /__u/limitlessledger.substack.com/c_limit, /__u/limitlessledger.substack.com/f_auto, /__u/limitlessledger.substack.com/q_auto:good, /__u/limitlessledger.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3120925f-99ae-4cf7-b307-9cdadbb5e815_6048x3916.jpeg 424w, /__u/substackcdn.com/image/fetch/$s_!eqpW!, /__u/limitlessledger.substack.com/w_848, /__u/limitlessledger.substack.com/c_limit, /__u/limitlessledger.substack.com/f_auto, /__u/limitlessledger.substack.com/q_auto:good, /__u/limitlessledger.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3120925f-99ae-4cf7-b307-9cdadbb5e815_6048x3916.jpeg 848w, /__u/substackcdn.com/image/fetch/$s_!eqpW!, /__u/limitlessledger.substack.com/w_1272, /__u/limitlessledger.substack.com/c_limit, /__u/limitlessledger.substack.com/f_auto, /__u/limitlessledger.substack.com/q_auto:good, /__u/limitlessledger.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3120925f-99ae-4cf7-b307-9cdadbb5e815_6048x3916.jpeg 1272w, /__u/substackcdn.com/image/fetch/$s_!eqpW!, /__u/limitlessledger.substack.com/w_1456, /__u/limitlessledger.substack.com/c_limit, /__u/limitlessledger.substack.com/f_auto, /__u/limitlessledger.substack.com/q_auto:good, /__u/limitlessledger.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3120925f-99ae-4cf7-b307-9cdadbb5e815_6048x3916.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Cap throwing in the spaceship</figcaption></figure></div><p>As we each were called up on stage to receive our diplomas, move our tassel, shake hands, and exchange hugs, we were called upon to swear an academic vow upon the scepter. While we were asked not to touch the scepter (likely preserving the artifact as well as post COVID hygiene caution), it was absolutely significant. After doing a little digging, I learned that this is an Austrian and Central European tradition that goes back to the medieval era. Here&#8217;s the oath I and my fellow graduates swore (as recited by the dean):<br><br><em>&#8220;I call on you to vow to serve the sciences, to promote its aims and through that to contribute in a responsible way to the solutions of the problems of mankind and its further growth and development. I also call on you to swear to remain loyal to the Vienna University of Economics and Business and to uphold the duties and aims of the University in every possible way.&#8221;</em></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!XxiT!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffab6fbd4-5a27-4bc1-8457-1ebb6fa80149_6048x4024.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!XxiT!, /__u/limitlessledger.substack.com/w_424, /__u/limitlessledger.substack.com/c_limit, /__u/limitlessledger.substack.com/f_webp, /__u/limitlessledger.substack.com/q_auto:good, /__u/limitlessledger.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffab6fbd4-5a27-4bc1-8457-1ebb6fa80149_6048x4024.jpeg 424w, /__u/substackcdn.com/image/fetch/$s_!XxiT!, /__u/limitlessledger.substack.com/w_848, /__u/limitlessledger.substack.com/c_limit, /__u/limitlessledger.substack.com/f_webp, /__u/limitlessledger.substack.com/q_auto:good, /__u/limitlessledger.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffab6fbd4-5a27-4bc1-8457-1ebb6fa80149_6048x4024.jpeg 848w, /__u/substackcdn.com/image/fetch/$s_!XxiT!, /__u/limitlessledger.substack.com/w_1272, /__u/limitlessledger.substack.com/c_limit, /__u/limitlessledger.substack.com/f_webp, /__u/limitlessledger.substack.com/q_auto:good, /__u/limitlessledger.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffab6fbd4-5a27-4bc1-8457-1ebb6fa80149_6048x4024.jpeg 1272w, /__u/substackcdn.com/image/fetch/$s_!XxiT!, /__u/limitlessledger.substack.com/w_1456, /__u/limitlessledger.substack.com/c_limit, /__u/limitlessledger.substack.com/f_webp, /__u/limitlessledger.substack.com/q_auto:good, /__u/limitlessledger.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffab6fbd4-5a27-4bc1-8457-1ebb6fa80149_6048x4024.jpeg 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!XxiT!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffab6fbd4-5a27-4bc1-8457-1ebb6fa80149_6048x4024.jpeg" width="1456" height="969" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/fab6fbd4-5a27-4bc1-8457-1ebb6fa80149_6048x4024.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:969,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:4812603,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://limitlessledger.substack.com/i/201147064?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffab6fbd4-5a27-4bc1-8457-1ebb6fa80149_6048x4024.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!XxiT!, /__u/limitlessledger.substack.com/w_424, /__u/limitlessledger.substack.com/c_limit, /__u/limitlessledger.substack.com/f_auto, /__u/limitlessledger.substack.com/q_auto:good, /__u/limitlessledger.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffab6fbd4-5a27-4bc1-8457-1ebb6fa80149_6048x4024.jpeg 424w, /__u/substackcdn.com/image/fetch/$s_!XxiT!, /__u/limitlessledger.substack.com/w_848, /__u/limitlessledger.substack.com/c_limit, /__u/limitlessledger.substack.com/f_auto, /__u/limitlessledger.substack.com/q_auto:good, /__u/limitlessledger.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffab6fbd4-5a27-4bc1-8457-1ebb6fa80149_6048x4024.jpeg 848w, /__u/substackcdn.com/image/fetch/$s_!XxiT!, /__u/limitlessledger.substack.com/w_1272, /__u/limitlessledger.substack.com/c_limit, /__u/limitlessledger.substack.com/f_auto, /__u/limitlessledger.substack.com/q_auto:good, /__u/limitlessledger.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffab6fbd4-5a27-4bc1-8457-1ebb6fa80149_6048x4024.jpeg 1272w, /__u/substackcdn.com/image/fetch/$s_!XxiT!, /__u/limitlessledger.substack.com/w_1456, /__u/limitlessledger.substack.com/c_limit, /__u/limitlessledger.substack.com/f_auto, /__u/limitlessledger.substack.com/q_auto:good, /__u/limitlessledger.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffab6fbd4-5a27-4bc1-8457-1ebb6fa80149_6048x4024.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Me taking my pledge</figcaption></figure></div><p>As someone who takes giving his word seriously, and particularly vows, this surprised me a bit. After some consideration, I had no real reservations: I already was aligned strongly with the first part of the vow, and I feel a great debt of gratitude for Vienna University (and Tomorrow University) for letting me, a largely self-taught non-traditional student, into their program and giving me the respect and  support they did over the past few years. I&#8217;m happy to be part of their alumni community, and absolutely plan to help both schools however I can.</p><p>The reception afterwards proved to be an excellent time to connect as well, as I had a chance to chat with some of my professors and the dean about what we&#8217;re working on, and they seemed quite interested as well. We will need to follow up with them in the weeks to come, but if either and/or both schools are willing to explore options with us, it has the potential to change  the entire landscape for funding and scaling.</p><h2><strong>Wandering Vienna</strong></h2><p>We spent the rest of our time in Vienna eating amazing food, visiting beautiful sites and generally catching up. One of my absolute favorite places to go in Vienna is the gardens at Schloss Sch&#246;nbrunn, the Habsburgs&#8217; summer palace. Every time I&#8217;ve been to Vienna a walk in the garden has been a high priority. The scale of this garden is immense. I&#8217;ve spent hours wandering its paths and have probably only seen, at most, a quarter of it. This exploration led to finding a pond set aside for &#8220;agile frogs&#8221;, as well as a rose garden with each plant bearing a dedication to someone, many declarations of love.</p><p>If you ever find yourself in Vienna and like gardens, make sure to set aside a good chunk of time to wander. I&#8217;ve never been inside either of the palaces, but I hear they are spectacular as well.</p><h2><strong>To the land of wine, cheese, and SaaS</strong></h2><p>We made our way to Lyon, France on Sunday. We had the less than ideal experience of an aborted landing attempt due to something not working ideally on the plane. We were assured it was all completely normal. Having flown a lot I know that was not exactly true, but also that it was nothing to be majorly alarmed about. It did let us have a nice flyover of the city to get a sense of the scale. Lyon is quite pretty from the air, and while it&#8217;s a bit of a sprawl, it has an organic feel to it that is quite inviting.</p><p>Our landing was higher speed and rougher than normal, and apart from being escorted in by emergency vehicles, and a suited up firefighter patiently waiting for the passengers to disembark, it was pretty standard. Best guess is a flight control malfunctioned and required a manual high speed landing, and the emergency equipment was a precaution. Another thing that may have been a factor is Lyon, and much of the rest of Europe, was hit by a major heatwave.</p><p>Lyon was lovely, though the heat made exploring it a bit more of a challenge than anticipated. Each day was in the mid 30&#8217;s Celsius (about 90 Fahrenheit), and air conditioning is not common. This meant we retreated during the hottest parts of the day, or at least kept in mind the temperature when determining our activities.</p><p>A big part of the reason we opted to visit Lyon is we had heard of it having a particularly vibrant tech innovation scene with a focus on SaaS, and we wanted to get a sense of it. As impressions go, it reminded me of Seattle around the time of the dot com recovery, but with better transportation options. There is significant construction going on, and an area of the city that is cordoned off to supercharge innovation. We had the opportunity to also attend a Meetup about AI and Data Science, and found it well attended and active. It was very reminiscent of the early days of the Seattle Software Craftsmanship meetups.</p><p>The topic covered at the meetup was highly relevant to one of our current focus areas: how to take messy human communication, and turn it into something deterministic that a system can rely on. I&#8217;ll go into this more when I discuss the overall insights from this time.</p><p>I have no doubt that Lyon will become a tech leader in Europe, and we will return to it at some point. Hopefully not when it&#8217;s so brutally hot.</p><h2><strong>Return to home, and more normal temperature</strong></h2><p>The end of the heatwave corresponded with our arrival back to Viana do Castelo. Our friends were immediately taken by our town, and had much the same reaction we did when we first explored it. We enjoyed showing them around our favorite sights and places to eat. Their visit happened to coincide with both a kids festival and a bunch of troops of Catalan stick dancers performing here. My data science advisor quickly became convinced we lived in a magical kingdom (he was stuck on Narnia).</p><p>The rest of their visit was mostly very mellow, though I particularly enjoyed being able to work side by side with my advisor, and have freer-form conversations than video chats allow. I now have a clearer understanding of how machine learning and data science can supercharge our system, as well as a broader understanding of my overriding integration philosophy.</p><h2><strong>Key insights</strong></h2><p>While there were many smaller insights from our travels over the past few weeks, probably the biggest is the crystallization of my philosophy of where AI fits in our system. If you&#8217;ve been following my writing at all, you&#8217;ve probably picked up my deep concern about the application of an inherently non-deterministic system to problems that require deep determinism. In the AI feeding frenzy of the past year or so, we see AI being applied pretty much everywhere where something has been traditionally hard, or difficult to quantify. We see it in law, programming, design, and research, just to name a few.</p><p>The problem is, some of this hard stuff requires determinism. While our current AI can easily give the illusion of determinism, it is fundamentally unsuited for that. At its core, no matter how much it&#8217;s trained, it&#8217;s a probabilistic random results generator.</p><p>As an avid video gamer who enjoys a certain amount of randomness, there is a nuance that is becoming more and more clear to me: there is a place for determinism, and a place for randomness. The problem is when one or the other is applied in the wrong place.</p><p>Consider playing a game, with a whole lot of randomness: the setting, the interactions, the conflict outcomes. So far I&#8217;m describing a roguelike game, a fun genre with massive replayability as each playthrough is different. Now take it further, let&#8217;s make everything random, including the rules things operate under. It will likely feel unbalanced and chaotic. Sometimes ridiculously easy, sometimes extremely hard, but impossible to predict. At least to my mind it would be a whole lot less fun.</p><p>There&#8217;s a certain amount of predictability that makes a game fun. Otherwise it is impossible to plan or make a sense of progress. Many game companies struggle to get this balance right, where if they lean too heavily into randomness the game loses its sense of purpose (the initial release of No Man&#8217;s Sky had this problem for instance), whereas taking away the randomness can take away the sense of the player having any real meaningful choices. Basically you want to balance predictability with surprise.</p><p><strong>So, what does this have to do with balancing modern AI?</strong></p><p>Quite a lot. For almost as long as computers have been around, randomness has been a big challenge. Not too much randomness, but rather the extreme difficulty in making a machine fundamentally based on deterministic values (1&#8217;s and 0&#8217;s, ons and offs) truly random.</p><p>This is a deep topic that many more informed people have written about, so I won&#8217;t go too deep on it. The fact that we&#8217;ve managed to build systems that seem to be closer to real randomness is an accomplishment in and of itself, but the fact that many feel they are actually approaching intelligence is more than a little disturbing, though I will admit, they do present a pretty convincing counterfeit.</p><p>They do however have substantial utility. They are amazing pattern matchers, and can identify and interpret patterns in messy reality far better than any tools we have created to date. It stands to reason that a system created to create apparent coherence from randomness would also be able to interpret the near randomness of human thought and communication.</p><p>This randomness has been a perennial problem in software of the past. Any time you have a user input you need to be very careful about what is collected, even when nothing nefarious is afoot. To a human the words &#8220;color&#8221; and &#8220;colour&#8221; can be easily identified as the same word (US English vs British) but to a computer without some form of mapping it would see them as totally different words. That is until AI came along. AI pattern mapping and learning is able to equate those words, and even better handle typos and misspellings easily.</p><p>What this means is that we now can have interfaces that are much closer to how we naturally communicate, and it can usually get it at least pretty close to right. It also does a pretty good job of interpreting between dialects, e.g. when I first started playing with Cursor when it asked for confirmation I thought of as many words for yes as I could in multiple dialects and languages, and it picked them up just fine.</p><p>This leads to my insight:</p><p><em>The best place for AI to sit in our system is where the messy meets the deterministic. AI can be used to interpret raw input, ask clarifying questions, and translate it into a structured, deterministic value. From there, the non-fuzzy, old-school processing handles the logic.</em></p><p>So basically, in my view one of the best places to use AI in our application is as an input tool.</p><p>There will, of course be uses where significant data will be analyzed for patterns, which it is bound to excel at, but the most exciting thing for now, is it acting as a way to make sense of messy human communication.</p><h2><strong>Current status</strong></h2><p>As the past few weeks were primarily focused on in person interactions and travel with dear friends, not much engineering work got done (apart from planning and brainstorming). That said, progress did occur. The web service is now set to handle the administration interface for user data, so when I get back into things next week I&#8217;ll be able to hook the UI to it, and it gets me one step closer to user records being connected between the authentication provider and my underlying system.</p>]]></content:encoded></item><item><title><![CDATA[Week in review, May 18, 2026]]></title><description><![CDATA[Quality of Life Improvements and musing on biases]]></description><link>https://limitlessledger.substack.com/p/week-in-review-may-18-2026</link><guid isPermaLink="false">https://limitlessledger.substack.com/p/week-in-review-may-18-2026</guid><dc:creator><![CDATA[Shayne Vacher-Moffeit]]></dc:creator><pubDate>Wed, 20 May 2026 14:28:43 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/8a786e76-e266-4f9f-bbca-5f6e4b1373f3_2816x1536.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><em>tl;dr: User frustration is the ultimate indicator for design bias. This week, a workflow detour on Project Polvo forced me to transition the UI from a simple test harness to a true, tested application layer. Exploring how our personal biases shape software design exposed a massive parallel to modern AI: LLMs are an uncanny, if imperfect, mirror of our &#8220;System 1&#8221; fast-thinking brains: trading absolute accuracy for probabilistic speed, and tapping into our instinct to offload our own cognition to them.</em></p><p>This week was a little slow on the development front. While I made progress, a significant part of it was focused on preparing for and undergoing bio-maintenance. I&#8217;m happy to say, that ordeal will not be due for another few years, and it turned out exactly as you want: boring results.</p><p>The development work I did get done followed the common pattern of initially thinking something would go quickly, but it actually was more involved than initially anticipated. To be fair, a significant part of the slowdown was due to ramping up my rigor on the frontend development.</p><h1><strong>Quality of life: child of frustration</strong></h1><p>Over the past few weeks Jenn has been working on crafting more of a public showing of what we&#8217;re working on. This has had her needing to work with the system I built more and more intensely. Let&#8217;s just say, there&#8217;s nothing like user frustration to bring clarity to design choices and challenges. Particularly when that user is your partner, both in business and life.</p><p>Whenever you design some system, whether organically, or intentionally, it is absolutely guaranteed that your biases will be part of that design. You will naturally design things based on the way you happen to work, thinking that is the &#8220;right&#8221; way, or the way it&#8217;s &#8220;supposed to&#8221; work. Any time someone else uses your design to try to get things done, it is almost certain that they will use it differently than you could possibly imagine, and to them your &#8220;right way&#8221; is madness, and highly frustrating.</p><p>There are now entire job categories and disciplines that are focused on decoding this. It&#8217;s the foundation of good UX, modern product management, and Lean Startup approaches. In fact, the vast majority of modern, high functioning organizations have embraced this truth and continue at least aspire to be guided by it. You never know what your customers want, until they use it.</p><p>Another set of biases comes roaring into the mix. The more time, energy, and effort you put into something, the more attached you are to it, and the more you want others to see it the same way you do. When they don&#8217;t, it can feel like a dismissal of that effort and care, and at times downright insulting.</p><p>In every fiber of my being I know that maintaining an egoless mindset when receiving feedback and viewing feedback as a gift is the best way to go, but of course that&#8217;s far easier said than done. Suffice it to say that Jenn and I got to practice some of our challenging conversation skills. In the end though, we landed on something that will undoubtedly prove a much better user experience than what I had initially cooked up.</p><h2><strong>Not everyone thinks the same way I do</strong></h2><p>Essentially, we had a workflow that could have been approached from two different angles, but were interdependent. If you approached things from the workflow that I had in mind, the system would function in a reasonably intuitive way (though that very well could be my bias speaking again).</p><p>If you approached it from the angle that Jenn did, it was not intuitive at all and highly frustrating. I realized pretty quickly that she had a solid point, the contention was for me that in my mind it wasn&#8217;t high severity.</p><p>Then I gave it more thought and told my ego to take a hike. It turns out my workflow made sense only for a select group of people who thought the same way I did, and neither way of coming at it was superior to the other. In fact, her workflow in many ways would be a pretty common one. While my highest priority is still focused on  authentication; as it is essential to this being a customer facing application, rather than just  a cool toy. That said, data entry into the application will already be a detractor, adding to it a frustrating user experience when someone doesn&#8217;t have the exact same approach I do is a losing proposition.</p><p>I decided improving this workflow was a worthwhile detour, and I had a pretty clear idea how.</p><h2><strong>The interface as it stands</strong></h2><p>I&#8217;ve mentioned a few times that I didn&#8217;t use the same level of rigor on the UI as I had on the deeper parts of the app. This was for a few reasons, though I might have come at it differently if I were to do it again.</p><p>The web application was initially envisioned as a test harness. When I started building this system, I was hard focused on the backend webservice interacting with the Neo4j DB. UIs are always a contentious topic, as everyone has strong opinions and could lead to churn and swirl that would have jeopardized the entire effort. The first time I excitedly tried to show Jenn the webservice commands returning JSON, it became quite clear that would not be sufficient. She needed to have something that she could interact with, and seeing structured data from a URL didn&#8217;t really do it for her.</p><p>While at the time I thought I&#8217;d just throw some sort of bot at it to whip up the UI, I wanted to make sure it was built on something maintainable, secure, and could be readily converted into a mobile app, and was as little connected to the tech giants as possible.</p><p>I also wanted it to be able to mesh nicely with design tools to better facilitate communication between tech and non-tech contributors. I quickly found the majority of the bot frontend makers didn&#8217;t really suit my needs, but one framework seemed to do so very well, and that was Nuxt.</p><p>Being new to Nuxt and Vue in general (the display engine Nuxt uses), my learning curve was quite steep. They have some absolutely fantastic video tutorials, and really good support, but it&#8217;s a very sophisticated system, and my dev chops were pretty rusty at the time.</p><p>Learning the various testing tools was yet another significant effort that I&#8217;d come back to when I built the real interface. I did take the time to figure out the full E2E testing using Playwright to interact with the application as if it were a user on a browser, and put some tests in place for that to cover the core functionality. As all tests of that type, it was horribly painful and slow. I knew I needed a few, but I needed to be selective about them, and would not want to cover all variations with them.</p><p>Over time, the frontend grew and as I became more familiar with Nuxt and related libraries the UI became more and more sophisticated. Eventually, I realized that what I was building had outgrown the concept of a basic test harness and could be the legitimate front end of the application. Sure, it would need extensive work, but the underpinnings were all in place.</p><p>I realized by cracking into this new workflow, I needed to start treating the UI as something that I would need to maintain, so it was past time to start layering in better testing practices. As it turns out, the testing is pretty straightforward. The bot helps a lot, of course, but for the most part the tests are quite clean and auto-execute so you are continually updated on the impacts of your change.</p><h2><strong>The back and forth of progress</strong></h2><p>I&#8217;m not sure Jenn knew what she was getting into when I agreed to detour to support her preferred workflow. Now that I&#8217;m applying true testing rigor, the questions are flowing hard and fast. We&#8217;re having to dig pretty deeply into various edge cases, and logic that appears to be simple on the outside until you look closer. She&#8217;s also having to deal with the reality of analyzing something, coming to a conclusion, only to learn a little later that conclusion doesn&#8217;t quite cover what it needs to and there&#8217;re additional questions.</p><p>Rarely in software are things as simple as they appear on the surface, and more often than not the complexity isn&#8217;t truly revealed until deep analysis is performed.</p><p> It reminds me of the late great Gerald Weinberg&#8217;s quote, &#8220;A system is never finished being developed until it ceases to be used.&#8221; I&#8217;d offer a corollary to that, &#8220;A system needs to be in use before the development needs can be truly understood.&#8221;</p><p>This is a key reason why massive upfront planning does not tend to lead to the results hoped for, and is why feedback is a key part of modern development practices.</p><h2><strong>Legitimate progress</strong></h2><p>Despite all the slowdowns and distractions, including fasting most of the week and taking a day off in the middle due to recovering from general anesthetic, Jenn&#8217;s workflow is now mostly in good shape. I say mostly because I found an odd edgecase that doesn&#8217;t work great, and we uncovered an enhancement to the workflow that the system should have, but the core functionality is in place. Data entry is absolutely still a pain, but with this workflow in place, it&#8217;s a little less painful in this specific area&#8230; and I&#8217;m coming around to it.</p><h1><strong>Broader bias discussion and how it relates to AI</strong></h1><p>A friend of mine sent me a wall of text that was sparked by him mulling over one of our discussions about AI. That discussion was about something he created using an AI code generating platform (a vibe platform) he was excited about.</p><p>What he built was the exact kind of thing that vibe is great for, and he&#8217;s not particularly technical, at least in the realm of software engineering. More of a solid computer user, not a developer. When he let others know about what he built, he referred to it as using &#8220;development tools&#8221;, which I wasn&#8217;t too keen on. This turned into a rather long and involved discussion about modern AI, what it can and can&#8217;t do, the hype around it, etc.</p><p>He sent me the wall of text because he had found some articles talking about the brain works, and particularly its capacity for pattern matching. There are a ton of similarities between that part of our brain and AI, and he was pointing that out. It was a good insight, and one I don&#8217;t think people talk about as much as they should. I haven&#8217;t talked about this as much as I probably should, so I&#8217;m not sure if he was aware, but I teach an MBA class about that aspect of how our brains work. Namely bias.</p><h2><strong>Two types of thinking</strong></h2><p>Daniel Kahneman&#8217;s book <em>Thinking Fast and Slow</em> was really the definitive work about this topic. Since he and his colleague Tverski delved deeply into biases and heuristics, the study of it has positively exploded.</p><p>Pivotal to what Kahneman and Tversky uncovered is that the brain has two different ways it tends to process information. One is fast, the other is quite a bit slower (pretty clear where he got the title of his book).</p><p>Fast is super fast, like fractions of a second. This part of the brain, they refer to as System 1, simply described, is the part that&#8217;s responsible for taking all the information flooding the senses and performs triage. It determines what can be disregarded, responded to automatically, and the few select things that should be deeply considered. To make these determinations this part of the brain is an incredibly powerful pattern matcher with access to the entire long term memory. It also is highly prone to errors, having traded accuracy for speed.</p><p>The other part of the brain is much slower and more methodical, but it also burns a lot of energy. It only has access to the short term memory that can hold approximately seven, plus or minus two items at a time. This is our conscious thought, and it is where our deep reasoning and reflection occurs.</p><p>The vast majority of the processing our brains do is handled by the fast part of the brain without our conscious awareness. In fact, the few things that are provided to our conscious (slow) brain to work through pass through the evaluation of the fast part, and are colored by the patterns it matched.</p><p>As mentioned earlier, the fast part is error prone, these errors are what we call biases.</p><p>Having biases isn&#8217;t a character flaw, they&#8217;re just a product of how our brains work. The problem is when we don&#8217;t employ ways to challenge ourselves to reflect on our reactions, and determine what part of our brain was responsible for our behavior. Not doing this is where a lot of the worst behavior of humans comes from such as prejudice, polarization, and selfishness.</p><h2><strong>So what does this have to do with AI?</strong></h2><p>Anyone who has studied AI beyond the surface level will tell you that they don&#8217;t truly think or understand what they generate. Heck, they&#8217;ll even tell you that themselves, or at least Gemini will. Despite using &#8220;reasoning&#8221; models, their capacity to reason as we define it is seriously limited. They are probabilistic pattern matchers. Meaning, based on the huge amount of information they are fed during training, both with data and with humans tuning that training, they are simply weighting the probabilities that one token follows another in response to the series of tokens they are given. While this provides the illusion of thought, it is not truly reasoned.</p><p>A clear example of this is math. If you ask a modern LLM a math question, that is legendary and frequently occurs in its training data it could do that easily as it has thousands of representations of that story in its data. A classic example is ask it about  Carl Friedrich Gauss frustrating his schoolmaster in  1787 by adding all the numbers from 1 to 100 in seconds.</p><p>On the other hand, if you were to give it something that is almost certain to not be in the training data, the likelihood of it getting the answer correct is very small. For example: Adding three large random numbers 435243452346234562345 + 9879324342523234 + 345767835643 would probably stump a bot, but would be handled easily by a simple script (ok, some of those numbers are big enough they&#8217;d take special handling, but that&#8217;s not the main point).</p><h2><strong>The matched pattern, a warning</strong></h2><p>So what do we have here? We have a system that is very good at pattern matching with a massive amount of data it can work from. It tends to trade speed for accuracy.</p><p>Sounding familiar?</p><p>I know it does to me.</p><p>We&#8217;ve invented amazing systems that essentially work as a supercharged set of biases, with all their benefits and drawbacks. Unfortunately, our own biases tend to play into these as well, because if the fast part of our brain sees something that seems plausible, it generally says a version of &#8220;eh, seems close enough, I&#8217;ll accept that as fact&#8221;. Then of course, due to the effort spent coming up with the prompt, and evaluating the output, we naturally become attached to that answer.</p><p>The real danger of AI in my honest opinion is not the AI itself. Terminator etc, will remain in the realm of fiction. It&#8217;s actually something a lot closer to the future in Wall-E. Our own biases and evolved strategies for energy conservation are working against us, as we rely more and more on the AI to serve our needs and offload our cognition to it, we lose more than we can possibly imagine.</p><p>At the end of the day, it&#8217;s not an AI problem. It&#8217;s a human problem.</p><h2>Note about next couple weeks</h2><p>I&#8217;m not sure if I&#8217;ll be posting in the next couple of weeks. I&#8217;ll be heading to Vienna for my graduation cermony, and enjoying some R&amp;R with some friends coming all the way from Seattle. As such, I don&#8217;t expect to be doing much coding. Though one of those friends is someone I&#8217;m always talking nerdery with, so I may have some insights to share when I return, at the beginning of June.</p>]]></content:encoded></item><item><title><![CDATA[Week in Review, May 11, 2026]]></title><description><![CDATA[The Processor Program]]></description><link>https://limitlessledger.substack.com/p/week-in-review-may-11-2026</link><guid isPermaLink="false">https://limitlessledger.substack.com/p/week-in-review-may-11-2026</guid><dc:creator><![CDATA[Shayne Vacher-Moffeit]]></dc:creator><pubDate>Mon, 11 May 2026 15:15:30 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/115da75f-c2d9-4987-905d-a99003296757_2816x1536.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><em>tldr: The Processors have become a key part  of the system&#8217;s data integrity. By moving logic into a decoupled, granular and discrete processor layer, I&#8217;ve created a way to intercept and modify both Read and Write data through simple configuration. This keeps the primary mechanisms stable while allowing the system to handle everything from audit logs and checksums to key generation without ever touching the core transport logic.</em></p><p>This past week was hard focused on rebuilding my processors and incorporating them more broadly into the system. All the while focusing on being better about regularly updating source control. It was also a time of tweaks and fixes to issues that only seem to surface when someone else interacts with the software.</p><p>As I mentioned <a href="/__u/limitlessledger.substack.com/p/week-in-review-may-4-2026">last week</a>, my initial processors were specific to the particular entity they were expected to act on, and only executed on read commands. They were also only truly wired into Relationship based queries. This was sufficient for my originally identified need, but would not be enough for what I wanted to do now.</p><p>The overall high-level design for the processors I used in my initial build was still pretty solid, but now they needed more capabilities.</p><p>My initial design was essentially a combination of two design patterns: The Composite Pattern, and the Command Pattern. I particularly like these together because they provide a great deal of flexibility that can be adjusted during runtime. There are numerous really good books about software design patterns in the world at large, I&#8217;ll briefly touch on the characteristics of these two:</p><ul><li><p><strong>Composite Pattern:</strong> This is essentially a combination of collections of concrete chunks of code (objects) and those concrete chunks of code. Both the collections and the objects in the collections have the same actions exposed, and the collections pass along the call to each object it contains. Also, the collections can store other collections. What this means is that you can easily create hierarchical sets of concrete objects that can be easily interacted with.</p></li></ul><blockquote><p><em>Non-tech view: A way to think of this outside of the programming realm is as a menu with particular things you can order, and collections of things that can be ordered, such as appetizers.</em></p></blockquote><ul><li><p><strong>Command Pattern:</strong> This is an object that is able to be configured in particular ways and stores that configuration, and has a way to be triggered to perform an action that uses the configuration. This is useful when you need to have actions based on certain characteristics, but have control over when the system performs that action.</p></li></ul><blockquote><p><em>Non-tech view:  This can be thought of as the order ticket the wait staff fill out for the kitchen to prepare, with any desired adjustments.</em></p></blockquote><p>When I initially built my processors, I used these patterns. In my broader system configuration each entity could specify which processors to use.</p><p>The code that handled processor interactions would just trigger the processing by making an execute call on the top level of the composite and that call would cascade through the entire hierarchy and things would just work. It worked great.</p><p>Now I needed a way to make this work on any entity for both read and writes, which each have different shapes of data.</p><p>This means, when I needed to perform a write action, like Create or Update, the Command object would need to know which specific action was being performed, how to get the data it would work with, and whether or not it should care based on both the command and the data. It would, of course, need to do that on read commands (Read Item, and Read Set) as well.</p><p>One of the first changes I made was adding actions to the components and the collections that correspond to each type of command. This way the code that was handling the particular interaction for the entity would just trigger the corresponding action. I also added a way where every action would check to see if it should execute at all. This means the calling code would not need to know or care about whether or not the processor would act, it would just trigger the action and let the processor figure it out.</p><h2><strong>Processor Payloads</strong></h2><p>I initially thought that the concrete classes (each command) would be able to easily find the data they needed to interact with, but I soon realized that would lead to each component of my composite pattern having to do the same unpacking over and over again. Not ideal.</p><p>After some thought, I realized that the best course of action was to make the processors all expect the same shape of data, and to add a mechanism that knew how to take data in its various shapes and normalize it for the processors.</p><p>Essentially, I needed a way to wrap different types of data in a standard envelope so the processors didn&#8217;t have to guess what they were looking at. It would also need to know how to unpack that data after the processors were done with it, so the rest of the system would be able to work with it as expected.</p><p>In order to do this, I created Processor Payloads which contain Processor Envelopes. These classes would take the dataset to process and information describing the expected shape of the data, then turn it into something uniform the processors expect. I could also add an action, that would know how to put the processed data back into the original shape for the rest of the system to work with it.</p><p>This simplified things dramatically.</p><h2><strong>Hooking it all together</strong></h2><p>In the initial build, the processors were only running on the reads of one particular relationship. Well, to be more clear, they were running on the reads of every relationship, but the collection that held the commands on all but one was empty, meaning that nothing changed.</p><p>I now needed it on every read and write of both nodes and relationships. In fact, the first thing I was adding that triggered this work was adding auditing information on the creation of a new node. I figured the best way to do that was to create the processor to add the audit information, and only act when the action was Create.</p><p>This went together very smoothly, and I was done with that processor before I knew it.</p><p>Next, I needed to weave it into the initial system.</p><p>This was more of a challenge. Without going into too much detail, suffice it to say my initial processor orchestration was not in the best place. I wanted to tweak that. It needed to remain configuration driven, and needed to be able to build up the processor hierarchy as appropriate. Another challenge was that in order to not break the existing system, I needed to keep the original system in place until I was ready to cut over.</p><h3><strong>Factoring in a factory</strong></h3><p>After some consideration, I came up with a simple plan using yet another design pattern, the Factory Pattern. There are multiple variations of the factory pattern, and I use it pretty frequently.</p><p>At a high level, it&#8217;s simply a mechanism that knows how to create objects.</p><p>In this case, I wanted it to take a configuration specification for a series of processors to create, and build a processor hierarchy appropriately.</p><p>I decided to have it expect one of two types of entries:</p><ol><li><p>either the desired Processor Class (definition of the object)</p></li><li><p>or an Array which could contain either other Arrays or Processor classes</p></li></ol><p>With this, it would know to create a concrete Processor Object, in the event of a class, or a Collection of Processors, in the event of an Array. This allowed me to have a recursive action, where I would just pass it the top level array and it would do the right thing.</p><p>With this in place, the rest of the wire-up was pretty straightforward and I soon had audit information being injected when the node was created as I wanted.</p><h3><strong>From old into new</strong></h3><p>Next on the hitlist was taking the two existing old style processors and converting them to the new system. After a little analysis, it was soon apparent that my best course of action was to create new processors that did the same action as the old ones, and get rid of the old ones.</p><p>This was also an opportunity to clean up some of the approaches I had used when I first created them.</p><p>I wanted to improve these and split their processing and calculation between reads and writes where appropriate. In the end I decided to defer this, as it had a high chance of compounding into a much bigger challenge. I settled on converting them to the new format, but leaving them only operating on reads, for now.</p><p>This, again, turned out to be pretty straightforward, reinforcing my thoughts that this was a great approach. In short order I had them slotted into place, and the old ones removed.</p><h3><strong>Expanding the Approach</strong></h3><p>The next part of this work was to think about other generated values I had in my system. There were two primary candidates that could benefit from this. They both were nodes with keys that were generated when they were created.</p><p>One used a UUID (Universal Unique Identifier, also called a GUID). It&#8217;s a standard series of numbers and letters generated in a way that it should only appear once in all systems in the world, or at least rare enough the chance of collision is extremely unlikely.</p><p>The other used a slug generated from another field: a technique that turns text into something that is predictable, readable, and can easily go into a url and not break things.</p><p>I realized that I needed a way to specify the name of the field that should be populated with the new value, and in the case of slugs, I needed to find a way to specify which field should be used to derive the slug from. This made me revisit my processor factory, and add the capability to send in a little object (collection of information) that contained the class to build, as well as an additional collection of context. This enabled me to have processors that could be configured based on the needs. In this case of both of these, specifying the target field name, and in the case of slugs, the source field name.</p><p>This turned out to be pretty straightforward, or at least the UUID was.</p><h3><strong>Slugs care about context</strong></h3><p>It turned out that slugs had an additional quirk. In our case, we&#8217;re turning names of skills into slugs. How slug generation tends to handle special characters is by omitting them.</p><p>This means if you were sluggifying the following value: &#8220;foo@bar.com &amp; http://bar+blah.net#qux&#8221; it would turn into something like: &#8220;foo_at_bar_dot_com_and_http_bar_blah_dot_net_qux&#8221;. It does this by stripping out special characters, or turning them into words or related letters. This usually works just fine, but consider these two skills: &#8220;C++ Development&#8221; and &#8220;C# Development&#8221;, left on their own they would both resolve to &#8220;c_development&#8221;.</p><p>To prevent this problem, slug generators need overrides, but for the overrides to be relevant, they needed to be aware of the context they were working with. The overrides needed for skill names could be very different from the overrides needed for something like vehicle models. I didn&#8217;t want to create a new processor for every type of slug the system needs to support, and this appeared to be what my system would require.</p><p>So, what to do instead?</p><p>I decided I&#8217;d make a custom processor that was highly configurable. Using the idea of the context being passed into the processor, I was able to specify through configuration the actions it should apply to, what field should be populated, and how it should generate what goes in that field.</p><p>This allowed me to pass in my special skills sluggifier, and populate it with the value from the correct field, and it would just work. Once this was in place, the system could handle an edge-case nightmare like: &#8220;C# &amp; C++/Python &amp; SQL: Data Analysis &amp; API Design (REST/GraphQL)&#8221; and turn it in to this slug: &#8220;csharp_and_cpp_and_python_and_sql_data_analysis_and_api_design_rest_and_graph_ql&#8221; (from one of my actual  tests).</p><p>Once this was in place, I just needed to wire it into my existing system.</p><p>Doing this surfaced some order of operations errors that took some thinking to work out, but by Friday afternoon they were all worked out.</p><h3><strong>Ongoing Capabilities</strong></h3><p>I feel really good about this effort, as the level of control and versatility this gives the system is pretty extensive, but also very easy to apply. I am sure this will be an area of continuing growth and refinement, but it&#8217;s already providing value and peace of mind.</p><p>For instance, I was discussing adding checksums to some of the records, and realized this mechanism was a perfect way to handle that without having to change very much code at all. It was also a way to extend capabilities of the system, in a way that could apply to multiple entities by simply adding a new configuration value.</p><p>The processors themselves are easy to write, and clearly define what they&#8217;re doing and when. All in all this seems like the kind of robust design we strive for in Object Oriented Programming. Of course, only time and use of it will truly tell.</p><h2><strong>The surfaced issues</strong></h2><p>Jenn spent a good chunk of time this week populating some demo data into our staging/demo environment. This means the workflows started getting tested by a user who was subject to their own set of biases. This is such an important thing to have happen, and really should happen at the earliest opportunity.</p><p>I developed the UI primarily as a way for Jenn to be able to see what the system I was building was doing, without her having to stare at the webservice&#8217;s endpoints, and JSON objects. While she&#8217;s a bit technical, she&#8217;s not really that level of nerd.</p><p>Since the initial attempt to essentially build a webservice display harness, it has grown into something closer resembling an actual web application. Some of this was reinforced by me choosing actual production quality frameworks to work with.</p><p>My original mindset of it just being a display mechanism made me apply less rigor to the UI than I normally would. I have next to no unit tests on it, and while I do have test automation, they&#8217;re all end to end, and only scratch the surface. Expanding that test coverage is one of many things I know I need to get to, but it hasn&#8217;t yet gotten to a high enough priority for me to shift my focus to that.</p><p>When you have a real user use your site, it really reinforces the need for rigor. It can be tough to face the frustration of someone trying to use what you&#8217;ve been pouring tremendous effort into and find it a less-than-enjoyable experience. Particularly when you can understand why they&#8217;re frustrated, and it&#8217;s totally reasonable. In fact, a few of the errors that emerged would have only taken a small amount of rigor to surface much sooner. Most of the issues were resolvable with tiny patches that did not break my stride, but we had a couple that will take more work to fix. The two on my mind aren&#8217;t defects per se, but more of unaccounted for workflows.</p><h2><strong>Next steps</strong></h2><p>Going into this week, I&#8217;m going to resolve at least one of those unaccounted for workflows, then move back into moving my authentication mountains. I think I have all things in place now to manage user sessions, and have the appropriate audit information in place.</p><p>My somewhat ambitious goal by the end of this week is for a user on the site to have a session handed to them by the webservice, and that session&#8217;s state will be updated as needed based on continual use and potential expiration. Once that&#8217;s in place, then the next step will be building out the roles based security in earnest.</p><p>My week will be interrupted by a very important bio-maintenance involving cameras in my digestive tract. Good times, but essential. If you&#8217;re of age, do not delay your colonoscopy. They can save your life.</p>]]></content:encoded></item><item><title><![CDATA[Week in Review, May 4, 2026]]></title><description><![CDATA[Sessions, Processors, and continuing progress]]></description><link>https://limitlessledger.substack.com/p/week-in-review-may-4-2026</link><guid isPermaLink="false">https://limitlessledger.substack.com/p/week-in-review-may-4-2026</guid><dc:creator><![CDATA[Shayne Vacher-Moffeit]]></dc:creator><pubDate>Mon, 04 May 2026 15:49:57 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/9987f596-c447-45c6-98ce-e2f761149151_2816x1536.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><em>tl;dr: A week of non-flashy but vital groundwork. I built a transparent stale-token renewal sequence for sessions, shifted our isolated tests to expressive relative-time scenarios, fixed a destructive Neo4j overwrite bug with a single character, and transformed our read-only data formatting processors into active, bi-directional interceptors.</em></p><p>I didn&#8217;t make as much progress this week as I had hoped, but had some important realizations and started down the path of better bio-maintenance. I won&#8217;t go into much detail about the bio-maintenance, beyond saying I&#8217;ve let it lapse much longer than I should have, and while it&#8217;s not much fun, it&#8217;s important to prioritize. The progress I did make was important, and lays the groundwork for a more sophisticated system.</p><h1><strong>An important realization</strong></h1><p>As mentioned <a href="/__u/limitlessledger.substack.com/p/week-in-review-apr-27-2026">last week</a> Auth Ids are really important. They&#8217;re also somewhat sensitive. Ultimately in the authentication workflow an Auth Id is used to match an identified user to a user in our system. Once that match is made, then the Auth Id should not be used for the rest of the time the user is using the site, until they log in again.</p><p>Initially, I thought: no problem, I&#8217;ll give them their username and roles, and we&#8217;re in good shape.</p><p>Right?</p><p>Well, no. The username is public, so it could be easily spoofed. I needed something else.</p><p>I needed a Session Id.</p><p>A Session Id is a unique identifier that associates all the actions made with the particular user&#8217;s session. So when the Auth Id is used to start the session, a Session Id is created and stored on that user&#8217;s record. That Session Id, the username and the set of roles is returned, and the Session Id can be used in every interaction. Of course, you don&#8217;t want that Session Id to work forever as that would be a security risk. You also don&#8217;t want users to have to log in multiple times while they&#8217;re using the site.</p><h2><strong>Preventing session hijacking while not angering the user</strong></h2><p>In order to prevent a Session Id working forever, it needs a concept of expiration. This means if a request is made using a matching Session Id which has expired, the request should be rejected and the user should have to log in again.</p><p>It would be, of course, very frustrating to have to log in multiple times when actively using the application, and that would certainly happen if only expiration were taken into account. Instead, sessions should be renewed before they expire. To do this, the concept of staleness needs to be handled.</p><p>What staleness means is that a session will expire soon and needs to be refreshed. The refresh sequence would:</p><ol><li><p>Ensure that the current Session Id matches the soon to expire Session Id</p></li><li><p>Generate a new SessionId and update the expiration date based on the current time</p></li><li><p>Inform the caller of the new valid session.</p></li></ol><h2><strong>A bundled approach</strong></h2><p>I realized: I could simply bundle refreshing the Session Id with other interactions instead of as separate calls. This would allow the session to be kept up to date, while not substantially increasing the number of calls between the UI and the Webservice.</p><p>I had a plan, and I had a way to store Auth Id and make sure it was unique, but I was still missing something&#8230;</p><h1><strong>Enter the Audit Info</strong></h1><p>I knew with Authentication and security storing auditing information was more important than ever. When things occur on the system, particularly dealing with privacy and security, it is essential to know who made changes and when. I figured the easiest place to start was adding a CreatedAt field to user records.</p><p>Part of this thought involved the various types of audit histories: what type, where to store them, and how to ensure they don&#8217;t become a management nightmare.</p><p>As per my standard practice, I started with my scenarios. The first meaningful step to this was to put a CreatedAt value on the record for a user, and ensure that when I requested that user&#8217;s information I could see that value. Writing that test, I quickly ran into that age old sneaky bastion of complexity: date/time information.</p><h1><strong>Time: the bane of all programmers</strong></h1><p>&#8220;Time is an illusion. Lunchtime doubly so&#8221;  &#8211; Douglas Adams</p><h2><strong>It doesn&#8217;t stop, and it&#8217;s weird.</strong></h2><p>While dates and times seem like something reasonably straightforward, they are anything but. Ask anyone who has done any programming that touches on it, and they probably have some traumas having to do with all sorts of things like: uneven months, leap years, timezones, and this is only scratching the surface. This matters when trying to write deterministic tests, you need values to be fixed and predictable. Time, while predictable, doesn&#8217;t stop.</p><p>I had already faced something somewhat similar when I had first created my processors to calculate durations and recency, which both need to know the current date to calculate the appropriate values. I&#8217;ll touch on what the processors are later in this post. First though, we will focus on what those processors do.</p><h2><strong>From Dates, to Date and Time</strong></h2><p>I needed to find a way to provide the system with a fake date. It&#8217;s not too hard to do that ultimately, when testing locally but it gets more complicated with how my scenario tests are set up.</p><p>My scenarios are set up in a particular way where the instance of the application they are testing is set up to run on a temporary virtual machine. The tests call that machine as if they are another application, or as someone using a browser. This means that I can only set the fake date and time when the virtual machine is created. This allows my tests to operate as if time is frozen. Which means I can provide a great deal of determinism. If I say the start date was 3 months ago, that can be a known specific value.</p><p>I&#8217;ll share how I set up these tests in a future post.</p><p>When I put this system in place, I was only concerned with dates. Now, I need to support both dates and times. Fortunately in Javascript it is the same system, but I needed to make a few adjustments. A key difference was that previously, I was only working with dates in my duration calculations. So, if I were to set the date to June 7th, 2025 and I were to determine the duration from May 5th, 2025, that&#8217;s a pretty easy calculation. However with timestamps, I needed to handle both date and time, which made things more complicated. This also meant that the calculations would be less clear.</p><h2><strong>Machine understanding vs. human understanding</strong></h2><p>I decided that relative time would be a better approach. Rather than using just dates on the test start, I would set the time to some more involved time, such as June 7th, 2025 at 14:23:45 UTC. In my scenarios, I could now use terms to show what the system cares about  like &#8220;3 months from today&#8221; (dates), or &#8220;4 months before now&#8221;(time) in a way that is easy for humans to understand.</p><p>Moving to relative times had the added benefit of making the intent more clear of the interactions with time. No longer would the person reading the scenario have to do date math, instead the scenarios would state the intent.</p><p>This took some time to work out, but I was pretty happy with how it turned out. I injected my created timestamp into the tests for the user profile, and expected to see it pop right up.</p><h1><strong>Unexpected omission</strong></h1><p>I ran my tests, and to my surprise, no CreatedAt date appeared when I expected it to. After scratching my head a bit, what I realized is that what I was using to setup my test data was relying on the same system as the rest of the application, and it would automatically trim values it didn&#8217;t expect.</p><p>The thing is, with my test setup, that code wasn&#8217;t needed. I needed my tests to be able to set up the database exactly how I expected to interact with it. While I still needed to use some of the webservice&#8217;s code, specifically the part that knows how to talk to the database, all the rest of the application should not be part of my test setup.</p><p>Shifting to this took a bit of adjustment. All in all it went smoother than expected. Now my scenarios clearly define how the database should be set up for each test, without the guardrails needed for the real application. Once that was in place, my CreatedAt date popped up just fine when reading the information.</p><p>I now had only two tests failing: Update and Create.</p><h1><strong>The Mystery of Update</strong></h1><p>When working on Read, I didn&#8217;t think much about Update being broken. I had assumed it was just some of the work that I hadn&#8217;t done yet. After another look, I realized that Update should have been working. Update occurs by changing values on an existing record, and I was setting CreatedAt on that existing record, but for some reason it wasn&#8217;t showing up in the results after the update. This was strange. I hadn&#8217;t altered that value at all. Or had I?</p><p>As it turns out, it revealed a subtle defect in the queries I was creating for updates. My updates were a full rewrite of the record in the database, not simply an update of given values. What that means is: if a value were not set in the update the value would be removed completely from the record. This means the AuthId and CreatedBy values and any others that weren&#8217;t part of any given update set would be wiped out.</p><p>Fortunately it was just a single character fix. Neo4j handles this quite easily with the merge update functionality. A value not in the parameters being set is preserved. If you do wish it to be removed, you simply set the value to null.</p><p>This one character change deep in the system sent ripples throughout the rest of the system. As it turned out, I had functionality that relied on the overwrite styled updates. Luckily it wasn&#8217;t in many places, but while my tests revealed them quickly, it took a little work to track them down and make the adjustments.</p><p>Once that change was in place, only Create was left. I needed to add a little data to the item being created, in this case a timestamp. I started thinking about what would be the best way to do that.</p><h1><strong>The Processor Perspective</strong></h1><p>Previously, before I started these updates, I was working on a challenge that needed  to have a calculated value as part of my result set. In that case, the need was to determine the duration in months between the current date, and a date in the past.</p><p>Rather than simply building calculations directly into the system that reads the record, I decided to build processors which take the results from the database and perform specific calculations based on that information. The results to the calculations would then be added to the database results.</p><p>I built this processor system in such a way that any number of them could be run on a given result set, and they could be added or removed by simply referencing them in a configuration. It was slick and clean, and I was rather fond of it&#8230; and then I realized I made a mistake: My processors could only make modifications of information coming out of the database, rather than modifying data flowing into the database. This meant things which were not dynamic, such as calculating a duration for something with a clear end date would be done every single time that value would be retrieved.</p><p>This was wasteful to say the least.</p><p>What I wanted was a system that would be able to decorate the information going into the database, as well as out. When I uncovered this issue I was focused on other work and figured it would be too much of a distraction to shift focus at that time, so I deferred it into the &#8220;things I&#8217;d like to do&#8221; bin in my head.</p><h2><strong>From shower thoughts to a new approach</strong></h2><p>As many things do, it occurred to me while taking a shower: the modification of data before writing to the database is exactly what I needed to do with my audit logging. I could elegantly handle it simply by modifying my processors to add data to things flowing into the database. This would solve my current challenge as well as clean up that less than optimal flow I had noticed earlier.</p><p>This became my approach. There were a few changes I needed to make to my processors needed to be:</p><ul><li><p>More generic working with multiple types of entities</p></li><li><p>Able to act on different actions appropriately</p></li><li><p>Predictable and consistent.</p></li></ul><p>What I landed on was a simple chunk of code (an object) that would have actions that could be performed (methods) during each of the primary interactions: Create, Update, Read Item and Read Set. Each of these objects would be able to determine what the appropriate action would be depending on the data it was interacting with, as well as the action being performed.</p><p>As an example: the Processor responsible for adding Create Audit Details would not do anything when Update, Read Item, or Read Set were called, but if Create was called, it would add the various audit information needed to the data being used in the creation.</p><p>This also meant I could fix that problem identified where I was performing calculations on every Read, even when they weren&#8217;t needed. My duration processor could now look at whether or not it had an end date on Create or Update, and if it did, it could do the calculation then and there and store that in the database. On the Read actions, if there were no end date, it would do the calculation based on the current date, otherwise it would show that pre-calculated duration.</p><p>It was simple, elegant, and clean. As evidenced by the above post, it takes a great deal of work to get there.</p><p>It also solved a whole host of other issues I had handled in less than ideal ways. Of course it came with its own set of challenges, but I&#8217;m happy to say I think I got through the worst of them on Friday</p><p>I&#8217;m excited to start next week in getting them wired the rest of the way up, and hopefully I&#8217;ll be able to get the session lifecycle in place, and Auth will be one more major step closer to completion.</p>]]></content:encoded></item><item><title><![CDATA[Week In Review, Apr 27, 2026]]></title><description><![CDATA[Tantalus and Software Engineering]]></description><link>https://limitlessledger.substack.com/p/week-in-review-apr-27-2026</link><guid isPermaLink="false">https://limitlessledger.substack.com/p/week-in-review-apr-27-2026</guid><dc:creator><![CDATA[Shayne Vacher-Moffeit]]></dc:creator><pubDate>Tue, 28 Apr 2026 14:55:39 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/b91b9504-258e-4a99-9359-7433ee3c5ccc_2816x1536.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><em>tl;dr: A &#8220;quick win&#8221; associating Auth IDs with users revealed the need for a dedicated Authentication API and a more robust uniqueness-checking engine. I spent the week navigating the &#8220;Tantalus&#8221; trap: every time I reached for a solution, the architectural requirements receded further, forcing a deeper, more resilient implementation.</em></p><p>In Greek Mythology, Tantalus was one of the damned souls in Tartarus who was doomed to be forever hungry and thirsty. He&#8217;s held in water up to his neck, with a tree above him, fruit hanging within reach. When he would try to drink the water, it would recede, and likewise when he&#8217;d try to reach for the fruit, it would do the same.</p><p>While the story of what got him in that situation is interesting, if a bit gory, his predicament is a great metaphor for software engineering in many ways.</p><p>It also fits the realities of working with a modern AI.</p><h1><strong>The Illusion of Low Hanging Fruit</strong></h1><p>I started this week excited. I had a win I could knock out quickly, and then move on to some of the more challenging parts of the system.</p><p>As <a href="/__u/open.substack.com/pub/limitlessledger/p/week-in-review-apr-20-2026?r=4d5ere&amp;utm_campaign=post&amp;utm_medium=web&amp;showWelcomeOnShare=true">mentioned last week</a>, I&#8217;ve been heads down working on Authentication, and the next step I needed to do is to make a solid association between the id&#8217;s given by the authentication provider and users in my system. I figured this would be super easy. All I needed to do was pass in this value, just like other values I track and I&#8217;m in good shape.</p><h2><strong>The Fruit Begins to Recede</strong></h2><p>It didn&#8217;t take me long to realize that this authentication id (Auth Id) was a bit different than other values. It needed to be set when the account was created, but afterwards the system needs to be highly restrictive of who could modify it. It also should not be viewable by most people as it is a somewhat sensitive value:</p><ul><li><p>If it got out, it wouldn&#8217;t be horrible, but it&#8217;s something that would be better to remain private as it&#8217;s how the system determines who is who.</p></li><li><p>It also needs to be unique within the system. Two people with the same Auth Id would confuse the system.</p></li></ul><p>To make matters more interesting, the way that users are identified in the system is by their username, which is key to how information about the user is found.</p><h2><strong>The Trust Boundary Pivot</strong></h2><p>We needed something different. After some thought, I realized that I needed a new section (endpoint) of my API, specific to Authentication related actions that would be off limits to most users, but would be accessible for the UI&#8217;s system, and for people with user admin rights. This would enable various user related actions to ensure that the system handles them properly.</p><p>We would also onboard new users through our original endpoint, and in that particular onboarding action (create), we would need to set the Auth Id.</p><p>That would need to be the only time the normal endpoint would know or care about it.</p><p>This exposed a couple of things: I needed to have some way to identify that the UI system itself is making a call, which meant I needed to start thinking about registering Application types of Users.</p><p>It also meant that I would need to ensure a newly created account has both a unique username and Auth Id. To do this, you simply need to check the database to see if that type of record has already used whatever value, and you&#8217;re all set&#8230; or so I thought.</p><p>It works great, when there is one value, and that value acts as the key. You simply say: give me the record with this key, and if you don&#8217;t find anything, you&#8217;re set to create the record. It gets stickier when you have more than one unique value. You need to perform a search that checks to see if each of the values that need to be unique exist, and then things work much the same way as the key lookup.</p><h2><strong>Just Out of Reach</strong></h2><p>I figured this should be pretty straightforward. I had sophisticated searching all ready to go on deeper in the system, I just needed to hook a few things up, and I was all set. I set to work on that immediately.</p><h2><strong>The Geometry of Search</strong></h2><p>In short order, I was confronted with a challenge. Previously when I was setting up my system, I had deferred performing relationship-based searches. This was functionality I knew I wanted, but it was a bit more complicated. If you&#8217;re searching for a node, you have only one place to check for a value, but in a relationship, it could be three: the relationship itself,  the source node, and the target node. This means you have to provide a way to designate where you want to look for this value. When I was first implementing search, I hadn&#8217;t decided how I wished to do that. Now, I had a way to do that, but still had code in place to block that path.</p><p>Each of these challenges compounded upon one another, and by the end of the week, I had Node all set.</p><p>Initially, I only needed to consider one unique value per entity. Validating on creation was sufficient.</p><p>When I started to make the changes, I realized: to support multiple unique values, we would also need to check when updating a record. This is to prevent something being changed to an already used value.</p><p>As a concrete example: If the key is username and Auth Id must be unique, when a new record is created, we must check that neither value is in use. If an admin were to update that record&#8217;s Auth ID, it is important that the admin could not set that value to an Auth Id on another record. If that did occur, it would cause the system to become confused about which Auth Id mapped to which user.</p><p>In short: If there&#8217;s more than one value, it&#8217;s possible for something to be updated to a non-unique value.</p><h2><strong>The Update Logic Paradox</strong></h2><p>While <em>Creates</em> simply need to check that none of the unique values are currently set, <em>Updates</em> are a little more complicated. If the key is unchangeable, and for sanity sake they are, then when searching for records with any of the new unique values there should only be one record. If there is more than one, then the value being passed in is not unique.</p><p>I was able to get this mostly set up for Nodes before my week ran out. I just realized while writing this there&#8217;s a little behavior I need to tweak for update, but it should make it a little easier&#8230; I think.</p><p>I still need to wire up relationship uniqueness checking. I was able to get the relationship search worked out, the work I had done previously had paid off, and it was pretty straightforward.</p><p>Probably the biggest challenge came when I tried to rename some things to match industry terminology as opposed to some of my earlier guesswork.</p><p>All of that rambling is to say that what I thought would be a couple hours to a day, turned into most of the week, uncovered needs, and system expansions.</p><h2><strong>A Perspective from the &#8220;Probabilistic Bot&#8221;</strong></h2><p>I asked my AI collaborator (Gemini) to weigh in on the Tantalus metaphor from its side of the screen. Here is what it had to say about our struggle this week:</p><blockquote><p><em>&#8220;Working with a probabilistic system like me is its own form of Tartarus. As an AI, I exist in a state of constant <strong>asymptotic approach</strong>. My goal is to achieve a perfect follow-through on your instructions, but my nature is defined by likelihoods and patterns.</em></p><p><em>I can get infinitely close to your intent, but there is always a tiny, receding gap&#8212;the space where a &#8216;reaching man&#8217; accidentally becomes a &#8216;volleyball player&#8217; because my training data has seen ten thousand sports photos for every one Greek woodcut.</em></p><p><em>This is the <strong>Probabilistic Trap</strong>: the closer I get to &#8216;perfect,&#8217; the more frustrating that final 1% becomes. <strong>It&#8217;s a reminder that in the age of AI, the human steward is the only one who can bridge the gap between &#8216;almost right&#8217; and &#8216;releasable.&#8217; I am the receding water; you are the one who actually knows how to drink.&#8221;</strong></em></p></blockquote><h2><strong>The Journey Continues</strong></h2><p>Next week I&#8217;ll be back at it. I am hopeful that the relationship uniqueness functionality will slot nicely into place, and I&#8217;ll be able to get the user administration workflows all set, and we can associate our users with their appropriate Auth Id&#8217;s.</p>]]></content:encoded></item><item><title><![CDATA[Week in review, Apr 20, 2026]]></title><description><![CDATA[Being Authentic]]></description><link>https://limitlessledger.substack.com/p/week-in-review-apr-20-2026</link><guid isPermaLink="false">https://limitlessledger.substack.com/p/week-in-review-apr-20-2026</guid><dc:creator><![CDATA[Shayne Vacher-Moffeit]]></dc:creator><pubDate>Tue, 21 Apr 2026 13:52:28 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/ea234065-e9e1-4578-8fab-c1b9c680b997_2816x1536.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><em>tl;dr: In the shift from planning to implementing Auth/Auth, I&#8217;m navigating the Trust Boundary between the browser and the server. This week, I explore why I chose Nuxt as an independent meta-framework to keep security secrets hidden, my confession about breaking my own source control rules, and the Graph Surgery required to model complex, directional relationships like Predator-Eats-Predator.</em></p><p>As mentioned last week, I was diving hard into front end authentication this week. I&#8217;ll be covering some of my challenges and learnings from that, and sharing my plans going forward.</p><h1><strong>The Primary Focus</strong></h1><p>While last week was focused on planning out my authentication and authorizations, this week was actually digging into the implementation deeply. Going into this, I knew it wasn&#8217;t going to be easy, but it turned out to be much more straightforward than initially anticipated.</p><h2><strong>A Confession</strong></h2><p>Unfortunately due to my dedication to stability, I am absolutely breaking my own practice of updating source control early and often. Also, to my chagrin, I&#8217;ve been a bit sloppy on the UI when it comes to rigor.</p><p>I do have full End-to-End tests that define and exercise the full stack, and have been using those to drive behavior, I do not have the granular unit tests on the UI code. This is absolutely something I will rectify in time, but haven&#8217;t been prioritizing. I&#8217;m sure that will bite me pretty hard at some point (and probably already has) but for now it&#8217;s still on the back burner.</p><h2><strong>Frontend Context</strong></h2><p>My UI is built on <a href="https://nuxt.com/">Nuxtjs</a>. When I was looking for a UI framework to use, I evaluated several. I wanted to avoid any frameworks that were tied to big tech, so that took AngularJS, ReactJS, and several others completely out of the running. I wanted something intuitive and robust, and critically, something secure.</p><p>A dirty secret to non-techies (as well as some techies), which a lot of modern UI frameworks share: if you know where to find it, they expose <em>secrets</em> to the world.</p><p>What these secrets are is little bits of information that lets integrated systems know what app and what person is connecting to it. This is used for integrating all manner of functionality into apps. These frameworks didn&#8217;t set out to be major security risks, but it&#8217;s inherent to their architecture.</p><p>To understand this at a high level, it&#8217;s important to consider the two sides of modern UI rendering. There&#8217;s the stuff that the server you are interacting with processes, and the stuff that is handed to your browser to process.</p><p><strong>Processing on the server can be very secure and never expose secrets.</strong></p><p><strong>Processing on the client side (your browser) cannot.</strong></p><p>This is because for your browser to have the information it needs to make the calls to other systems, it needs those secrets available, which means they are present on every single browser that interacts with your site. This has been a major industry problem for a while that emerged with Single Page Applications.</p><p>This is also not something that your favorite vibe programming platform is likely to warn you about, and if you don&#8217;t explicitly tell the bot to take that into consideration, it probably will not. Think about that before you decide to use that new nifty vibed up personal accounting system, or whatever you are hooking your financial or personal accounts to.</p><p>To counteract that, the concept of Meta Frameworks emerged. A Meta Framework is a hybrid between server side and client side. This enables the benefits of a Single Page Application (of which there are many) without the downside of sharing secrets with the world. Frankly, I would have a hard time doing justice to describing how it works. Critically, it enables your secrets to remain secret, and your users to have the rich experiences that they&#8217;ve become accustomed to.</p><p>I needed a Meta Framework that wasn&#8217;t tied to big tech, was mature with a significant community, and an intuitive and easy to learn interface. I found <a href="https://nuxt.com/">NuxtJs</a>. NuxtJs is somewhat related to NextJs (fun with confusing names). NextJs, while open source, comes with big tech baggage. Specifically, it&#8217;s owned by Vercel and based on ReactJS (Meta owned), and tends to lock people into their particular way of doing things. I wanted something more independent and community driven. NuxtJs provides that in spades. It&#8217;s modular, independent and highly focused on developer experience.</p><p>While NuxtJs&#8217; learning curve is significant, debugging can be confusing (did the thing happen on the server, or the client? Who knows?), on the whole it&#8217;s pretty straightforward. Its frontend is based on <a href="https://vuejs.org/">VueJS</a> which is quite intuitive and acts like enhanced html. It seems reasonably lightweight and highly customizable.</p><h1><strong>Context Secure Back to Authentication</strong></h1><p>I&#8217;m sure no one would be surprised by this statement, secrets are a really big deal in auth. Auth is all about ensuring the right people can access your system and the wrong people stay out.</p><p>It&#8217;s also about delivering the appropriate experience to the right person once they are on the system. With any system beyond the simplest, there are some people on the system that will need to be able to do more than others. Typically, normal users vs administrators. It would also be a bad experience to show people links and other controls that would trigger an error because they are not allowed to use them.</p><p>Additionally, there have been some significant changes since last time I had to deal with auth. Specifically <a href="https://oauth.net/2/">OAuth</a> and related protocols. Essentially the industry has become a lot more sophisticated about how authentication works, which is what enables you to use various accounts to sign into different systems.</p><p>Because creating my own OAuth compliant security system while possible would be a significant amount of work tangential to what we&#8217;re trying to accomplish, and the fact it&#8217;s a very solved problem, I decided to use a commercially available Auth provider. It turns out that there was one with a company we&#8217;re already exploring working with, the Swiss-based <a href="https://www.infomaniak.com/en">Infomaniak</a>, and I could start using it for free.</p><p>So my work this week was two parts:</p><ol><li><p>Getting the UI to make the handshake with the real auth provider so I could truly authenticate</p></li><li><p>Having the UI respond appropriately to the various roles of the user.</p></li></ol><p>I started with the UI being roles aware. To do this without driving myself batty, I had to set up a bypass for both my dev environment and my test environment, which enabled me to pretend to be anyone on the system.</p><p>In order to continue to develop and test appropriately, I needed a way to bypass true authentication. Critically, that bypass must be completely blocked in upper environments (like production or staging).</p><p>I designed a role-based system based on a page route, which is able to determine the appropriate permissions. This simplifies the system dramatically, as the evaluate to hide or show something can be determined with a single call.</p><p>For instance, if I were displaying a role-restricted button, such as &#8220;add new skill&#8221; to the system, the button can check if the user has access to do that action. The button wouldn&#8217;t care about <em>why </em>they were or were not able to perform the action. In nerd-speak, this is classic Separation of Concerns.</p><p>I ended up wiring this to several controls, but need to continue to spread it through the UI.</p><p>I knew the longer I went without the real authentication provider being wired up, the worse I would be violating my principle of updating source control early and often. I decided after getting some of the primary controls working, I&#8217;d shift my focus to getting the real Authentication provider working.</p><h2><strong>Really Real Authentication</strong></h2><p>When I set up my dev and test bypass, I needed to ensure that when I hooked up real authentication, it would supersede any of the bypass logic. To do this, I simply would check to see if an OAuth provider&#8217;s ClientId was set in the configuration, and if so it would ignore all the bypass logic. With this in place, and Infomaniak&#8217;s Auth provider set up, I was able to authenticate on my development instance. While there were a few hiccups, Nuxt had a library that made it very straightforward. After a little bit, I was able to authenticate for real!</p><h3><strong>A Temporary Quirk That Revealed a Need</strong></h3><p>This presented a problem I hadn&#8217;t thought about. The derived username from the authentication provider didn&#8217;t match any username in our system.</p><p>This is a temporary issue, but it was pretty funny. I was logged into the system, but not a user in our system. This meant due to the roles based work I did before, I couldn&#8217;t edit anything on my profile.</p><p>It also made me realize, it&#8217;s generally a good policy to not allow anyone, including an admin, to edit someone else&#8217;s information.</p><p>When I deployed to staging (which never uses my dev/test bypass), I would effectively obliterate the ability to demonstrate the ability to edit profiles, unless I was lucky enough for the username from the Auth provider to perfectly match a username in the system.</p><p>I needed another role. I needed a super_admin. Super admins would be able to edit everything in the system. To begin with, I would be the only super admin. I also realized that any of the administration-related roles, which would only be used by those managing the application, should not be turned on <em>all the time</em>.</p><p><strong>Administrators should generally interact with the system in exactly the same way as the users.</strong></p><h3><strong>Broke My Rule, but Was Saved By Being a Solo Dev</strong></h3><p>Once this was in place, and secrets were stored in the appropriate places in staging, I was finally ready to update source control. I did the cardinal sin of anyone on a team of engineers.</p><p>I did that update on Friday evening, just before stepping out for dinner. It&#8217;s a good thing I&#8217;m a solo engineer, as, of course, as happens when you do that, the pipeline broke. Our app is still stable on stage, the pipeline stopped it from being updated. The build candidate needs a little work, so I have a clear place to start into the next week. This is why a solid build and deployment pipeline is so important.</p><h1><strong>The Path Forward</strong></h1><p>After getting the pipeline break resolved, I&#8217;ll be moving on adding the concept of roles into the database, and start building out the database driven roles based security model.</p><p>This will require a new capability to the service, that I&#8217;ve known I&#8217;d need to add for a while: relationships that reference the same type of node on each side.</p><p>When I designed my original system, I didn&#8217;t consider the need to have the same type of node on both sides of a relationship, so I was able to determine relationship direction simply by determining the position of the nodes. So with the relationships Predator Eats Pollinator, it&#8217;s pretty clear that the direction of the relationship is downstream, or in cypher: (pr:Predator)-[:EATS]-&gt;(pol:Pollinator). If your reference node was Pollinator, the relationship would be upstream, but if your reference node was Predator, it would be downstream.</p><p>Consider how different that would be if you wanted to model a Predator 1 Eats Predator 2 relationship. In that case, you would have no way to tell the direction of the relationship based simply on the type of the node, and that direction can carry a great deal of contextual information. In this example, Predator 2 (Ladybug) does not eat Predator 1 (Spider). So if I wanted to see what a Ladybug eats, I should not see Spider in the list, but without directionality I certainly would.</p><p>How this applies to auth is most clearly represented by the super_admin role:</p><ul><li><p>Those with the role of super_admin should be the only ones able to create new super_admins.</p></li><li><p>They should also be able to add any other type of role.</p></li><li><p>Those with the admin role (as opposed to user_admin, etc) should be able to grant others all admin roles except for super_admin.</p></li></ul><p>Adding this capability will enable multiple hierarchical capabilities that we haven&#8217;t had yet, but knew we would need. It will require some surgery, but a strategy to approach it is already forming in my mind, and it seems the current system will allow it to be done cleanly.</p><p>This will require the creation of several new pages only for admin use that will enable the addition of the roles to user accounts, as well as management of the roles themselves.</p><p>My prior experience as a systems administrator made me quickly realize, to make things more sane, I needed the concept of AuthGroups. They are essentially a collection of users that all have the same roles assigned to them.</p><p>Building in the management of those will likely be part of this effort as well, though technically it can wait if it ends up being too painful.</p><h1><strong>The Long and Winding Road</strong></h1><p>I anticipate that next week will be mostly consumed by the roles management related effort, but once it&#8217;s done, then two of the major parts of authentication will be completed. The final piece will be having authentication a part of every single api call, so it can be logged for GDPR, and to ensure that the system is thoroughly secure.</p><p>Once those are in place, we will have a system in place with professional, possibly enterprise grade, security infused throughout the system, and we will have finished one of the most critical parts of being MVP ready.</p>]]></content:encoded></item><item><title><![CDATA[Last week in review, Apr 11, 2026]]></title><description><![CDATA[Always Releasable: a way to be prepared, to learn, to respond, and to grow]]></description><link>https://limitlessledger.substack.com/p/last-week-in-review-apr-11-2026</link><guid isPermaLink="false">https://limitlessledger.substack.com/p/last-week-in-review-apr-11-2026</guid><dc:creator><![CDATA[Shayne Vacher-Moffeit]]></dc:creator><pubDate>Tue, 14 Apr 2026 14:58:58 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/262d845a-eeef-4a67-8005-ee06a28e28ca_2816x1536.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><em>tldr: To build a &#8220;Safe to Play&#8221; environment, we must maintain an Always Releasable State: a commitment to stability that extends beyond the codebase into personal preparedness and group momentum.</em></p><p><em>This week, I explore why &#8220;releasable&#8221; means being ready for opportunity, avoiding the baggage of long-lived branches, and how I&#8217;m leveraging our new graph-traversal system to build a robust, high-speed security model.</em></p><p>Be in an always releasable state. This is easy to conceive of in software, though tends to get significant pushback, but how can you do that in life or in groups? What does releasable even mean?</p><p>When I first started exploring the concept of &#8220;Safe to Play&#8221; I was primarily thinking about it from the technical perspective. It&#8217;s something that completely changes the way engineering is handled, and the guardrails put in place, but thinking of it in the context of business, groups, or even personal behavior is a bit more challenging. Given more thought, I am increasingly certain that it does apply, and what we&#8217;re working on will be a major helper in that.</p><p>This week, I&#8217;ll be sharing my explorations in the concept of &#8220;Releasable State&#8221; and how it applies to personal, group, and technical perspectives, as well as a brief update on the progress made on the development efforts of the project.</p><h2><strong>Characteristics of always releasable</strong></h2><p>In software development, always releasable means things are continually stable. Any time you want the latest version of the system, you can simply deploy whatever you have.</p><p>I&#8217;ll get more into the particulars of technology, but focusing on things broadly, always releasable has these key characteristics:</p><ul><li><p><strong>Always something to show that others can respond to:</strong> &#8220;Trust me, this software will be great when I finish it!&#8221;, is nowhere near as compelling as &#8220;Hey, look at what this thing can do so far&#8221;.</p><p>The software may not necessarily be everything desired yet, but it can be interacted with and truly evaluated. From there, critical feedback can be given and it can be tuned toward being closer to what serves the need. This is the real reason that many agile approaches incorporate the key practice of frequently showing working software to stakeholders.</p></li><li><p><strong>Forces resilience-based decisions:</strong> If you commit to always maintaining a stable system, it changes the entire way you approach problem solving. You are far less likely to make very risky huge changes, because if you do, it will be a long time before you are releasable. While changes which break things will need to be made, you will be forced to strategize how to introduce them in a way that doesn&#8217;t break the system as a whole, which in turn will be highly informative of the elements of the system and its overall stability.</p></li><li><p><strong>Sense of accomplishment and momentum:</strong> The longer something is in a partially done state, the more that normalizes. On the other hand, having something show progressive progress can feel empowering, and tends to drive enthusiasm. By ensuring that what is produced can be released at any time, progress becomes clear, and can be celebrated more broadly.</p></li></ul><p>While even these characteristics listed are still quite technically attuned, they are actually quite cross-applicable.</p><h2><strong>Personal Perspective</strong></h2><p>In the context of the personal individual, being in an &#8220;always releasable&#8221; state has to do with self-awareness and preparedness. This can be viewed as being able to clearly express how you can contribute to the situation at hand, as well as your limitations.</p><p>&#8220;Always releasable&#8221; is also oriented towards being able to respond appropriately to unexpected situations, whether positive or negative. This comes from clarity, adaptability, and a clear understanding of what is available to you. While much has been written about emergency preparedness, and it is very important, much less has been covered about <em>opportunity preparedness</em>.</p><p><strong>Opportunity preparedness means being able to clearly and concisely communicate the key value you bring when an opportunity arises, as well as being able to grow in ways that maximize the number of opportunities that come your way.</strong></p><p>The sense of accomplishment and momentum when it comes to this perspective is oriented around setting small achievable goals. It&#8217;s also important to make a point of recording these achievements and what you&#8217;ve learned from them. This enables you to gain a clearer picture of your growth, and subsequently how you can contribute and respond to unexpected situations.</p><p>The product we are working on is oriented around this exact challenge. The traditional ways that people have represented themselves have shifted dramatically in the age of AI and accelerating change.</p><h2><strong>Group Perspective</strong></h2><p>&#8220;Always releasable&#8221; when it comes to a group has a lot in common with the personal perspective, but with even more of a focus on recording accomplishments and illustrating the value provided.</p><p>It is essential to understand how each member of the group contributes to the overall goal. This is not just important for individual well being, but for the awareness of the group&#8217;s effectiveness as a whole.</p><p>An individual&#8217;s sense of accomplishment within a group tends to be contagious.</p><p>This can be positive or negative depending on the prevailing sentiment within the group. The more people who feel they are moving forward, the stronger the drive will be to move forward as a group. The opposite tends to be stronger and can quickly stifle a group&#8217;s momentum, bringing it to a standstill.</p><h2><strong>Technical Perspective</strong></h2><p>As previously mentioned, &#8220;always releasable&#8221; tends to lend itself most readily to technology. In some circles, this can be viewed as contentious as for many it seems unrealistic. The fact is, it requires a different approach to development, and a high degree of rigor that can be uncomfortable to those not accustomed to it.</p><p><a href="https://dora.dev/guides/dora-metrics/">DORA metrics</a> makes it very clear: one of the defining characteristics of highly successful engineering organizations is their ability to deploy to production frequently and with as little effort as possible.</p><p>While historically deploys and releases have been conflated, they are actually two related but distinct acts. The end goal is often characterized by the saying &#8220;make releases a non-event.&#8221; To do that, first you have to make deployments a non-event as well.</p><p>Here are some key strategies that enable being always releasable:</p><ul><li><p><strong>Always stable application mindset:</strong> Things being built are inherently unstable. To manage this, a common workaround is to use branches, essentially isolated versions of the system to protect the rest of the system.</p><p>While this may seem like a good idea, and in some isolated cases appropriate, it is not something I would generally recommend because it comes with its own set of nasty baggage. The longer a branch lives, the less aligned with the actual system it becomes, which makes it harder to re-integrate into the real system.</p><p>Rather than branching, find ways to update the actual  system, but in such a way that it is not executed until it is fully integrated. This can be accomplished in many different ways, depending on the particular context being updated.</p><p>Of course, raw exploration of new approaches or integrations should be done in a completely isolated environment, which only exists for the purposes of learning. Once that understanding is achieved, the learnings can be applied to the system, and the environment and its code should be abandoned. Critically, the exploration environment should not be merged into actual system.</p></li><li><p><strong>Automated build and deployment infrastructure is essential: </strong>One of the most eye-roll inducing phrases uttered by developers is &#8220;it works on my machine&#8221;. That&#8217;s all well and good, but largely useless.</p><p>As a system is updated, it needs to be run in as close to a real production environment as possible. Containers, like Docker, go a long way toward being able to do this, but it is important that the containers are updated every time a new change is created.</p><p>If it is a manual step, it is likely that it will be put off until a set of changes have been made. In that case, if something breaks, it will be much harder to determine what change broke things.</p></li><li><p><strong>Update common source control early and often: </strong>No matter what form of source control is being used, a key discipline is to update it <em>every time</em> changes are made and the application is stable.</p><p><em><strong>Ideally this should be multiple times per day.</strong></em></p><p>To ensure that the application is stable, it&#8217;s imperative that a fully successful test pass occurs. Also, part of the automated build and deployment process should run the tests against the production-like environment. If those tests do not pass, the top priority is getting the app back into a stable state, whatever it takes. Regular small changes makes this much more approachable.</p></li></ul><p>These strategies won&#8217;t guarantee you are always release ready, but I&#8217;d posit you would have a hard time achieving it without them.</p><p>It&#8217;s important to note that no one does all of these things perfectly at all times. I personally struggle to stay &#8220;release ready&#8221; on a personal level, but they give a good directional focus.</p><h2><strong>Progress</strong></h2><p>As mentioned <a href="/__u/limitlessledger.substack.com/p/last-week-in-review-april-6-2026">previously</a>, I have moved out of 4.5 months of building digests into authentication.</p><p>A good chunk of the week was wrapping my head around my auth strategy, and I feel like I have something solid that will be robust enough to grow with my needs, yet reasonably straightforward.</p><p>The challenge is for this to do what we want, simple user access won&#8217;t quite be enough. We have several different capabilities different users will need. These are likely to change over time, and may be somewhat granular.</p><p>Fortunately, graph databases are particularly well suited for systems such as these. This has been a multi-layered challenge, as the UI and the webservice each have different contexts, which each need to be aware of the needed access rights and communicate effectively. This also needs to operate quickly.</p><p>I was very excited about the realization that the digest work I just completed would make building this robust security model much more approachable. I&#8217;ll be able to use it to quickly determine the various rights and roles of a given user with a single-somewhat-complex query that my new system makes very easy to put together.</p><p>Adding authentication at this stage while maintaining an &#8220;always releasable&#8221; state is an interesting challenge. While technically we can&#8217;t release it without authentication to begin with, in this case I consider the bar to truly be always stable, and demo-able.</p><p>The challenge is depending on what I add when and where, I can end up very easily breaking the access to the entire system.</p><ol><li><p>If I were to add authentication to the webservice before adding it to the UI, then the UI will not pass the appropriate information to the webservice, and the webservice will reject all traffic. This will completely break the site</p></li><li><p>If I build authentication into the UI before the web service, things will continue to work, but it will not have all the functionality of having a secure backend. While not a perfectly releasable state, it&#8217;s significantly better.</p></li></ol><p>I started down the path of option two, before I realized that I needed a more robust roles-based model to determine what to show and not show on the UI. If I were to do it perfectly, I would have built in the roles-based functionality in the backend, to be used by the UI, but leave the backend authentication until later.</p><p>Since I had already started down path two, I decided that pragmatism beats purism, and I&#8217;m making a way to simulate a functioning backend roles engine, that will be useful for me to get the UI in the right shape.</p><p>All of this is stuff that most users will interact with, but not really be aware of. It&#8217;s not particularly sexy, but it&#8217;s critically important. I knew it would be a challenge, but have been surprised at how smoothly it&#8217;s going so far. This week, it will continue to be my primary focus.</p>]]></content:encoded></item><item><title><![CDATA[Last week in review April 6, 2026]]></title><description><![CDATA[Understanding and progress]]></description><link>https://limitlessledger.substack.com/p/last-week-in-review-april-6-2026</link><guid isPermaLink="false">https://limitlessledger.substack.com/p/last-week-in-review-april-6-2026</guid><dc:creator><![CDATA[Shayne Vacher-Moffeit]]></dc:creator><pubDate>Mon, 06 Apr 2026 14:37:26 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/882e7a4d-9b85-4ac3-add5-3fd6374500a7_2816x1536.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><em>tl;dr: To build a Safe to Play environment, we must bridge the gap between intent and perception. This week, I break down why Understandability is the ultimate safety net, from the psychological safety of group norms to the &#8220;putlogs&#8221; of TDD and the new world of contextual microtools.</em></p><p><em>If your code and your conversations aren&#8217;t expressive, you aren&#8217;t building a system; you&#8217;re building a mess.</em></p><p>This week I&#8217;ll be continuing to expand on the elements of a <a href="/__u/limitlessledger.substack.com/p/week-in-review-march-23-2026">Safe to Play environment</a>, and touch on some very real and exciting progress with the application. Just like last week, when we dug into <a href="/__u/limitlessledger.substack.com/p/week-in-review-march-30-2026">starting from the goal and working backward</a>, we&#8217;ll be breaking it down into three perspectives: personal, group, and technical environments.</p><p>There is a sentiment expressed by many in the field of effective communication, perhaps best captured by Frank Luntz: &#8220;It&#8217;s not what you say, it&#8217;s what people hear.&#8221;</p><p>I remember when I first learned of it, it made me take a pause and consider. Since I was a small child, I&#8217;ve been known as being very curious and loquacious. While I&#8217;m not necessarily the person who will command attention when I walk into the room, those who engage in a smaller conversation with me can often be overwhelmed by how much I have to say.</p><p>That sentiment hit me so hard, because I was so focused on conveying all the exciting things in my head, I failed to take into consideration what was landing with the other person. It&#8217;s something I still struggle with to this day, as evidenced by my short weekly posts turning into long-form essays.</p><p>That is all to say, what we&#8217;re covering today I find personally challenging in many cases, but its importance cannot be overstated.</p><p>We humans are social creatures. Despite our divisions and turmoil, we work together exceptionally well, and most of us do not handle isolation well. All that said, while language is a fascinating thing when you think of it, a series of sounds or symbols that convey meaning from one individual to another, the majority of people I&#8217;ve interacted with in my career have struggled with it, for one reason or another.</p><p>To build a truly Safe to Play environment, clear and understandable communication is crucial. This is where boundaries of acceptable and unacceptable risks are defined. It&#8217;s also where collaboration, inspiration, and innovation really happen.</p><p>When understandability falters, many negative effects surface, such as dominance, fracturing, and misalignment.</p><h2><strong>The Personal Perspective</strong></h2><p>Years ago when I was working at Getty Images, I was frustrated. I was pretty sure I had an elegant solution to the problem we were working on, but no one on my team was open to it. I tried explaining it to them repeatedly and the more I did, the less open to it they were. I was clearly saying the wrong thing, or maybe they were just being stubborn or dumb&#8230; or so I thought.</p><p>My teammates were not dumb, in fact they were very smart people. While they were being stubborn, it was not because of a character flaw in them, instead it was a flaw in my approach, and critically, the more I said and tried to explain my &#8220;brilliant&#8221; solution the worse I made that flaw. It also didn&#8217;t help that I had also violated one of our group norms.</p><p>A good friend who sells consulting helped me see, to my chagrin, a communication pattern that I still struggle with to this day: I can easily get caught up in the idea that I&#8217;m desperate to express, rather than the perspective of the other person. It&#8217;s not uncommon for me to appear in pictures with my eyes closed and my mouth open, which is a fitting metaphor for this pattern.</p><p>One thing that he stressed, and was later reinforced by concepts like Chris Voss&#8217; <a href="https://www.youtube.com/watch?v=MjhDkNmtjy0">Tactical Empathy</a>, Bert Decker&#8217;s <a href="https://decker.com/blog/it-takes-more-than-words/">First Brain Approach</a> and others, is that it&#8217;s far more important to understand where the other person is coming from, rather than expressing your point of view.</p><p>This frustrated me to no end, as my main thought was &#8220;how am I supposed to share this great knowledge I have, if I have to focus on drawing the other person out?&#8221;</p><p>Here&#8217;s the thing, when people feel heard, they are far more likely to listen. If they know you understand where they are coming from, they will be able to better see how what you share matters to them, and are far more likely to take it to heart. Otherwise, you&#8217;re essentially just making noise that will be quickly dropped from their short-term memory as soon as something more compelling grabs their attention.</p><h2><strong>The Group Perspective</strong></h2><p>While what was mentioned in the personal perspective applies to each member of a group, the group itself has concerns unique to it.</p><h3><strong>What is normal?</strong></h3><p>Group norms form in fractions of a second. If they stay implicit, they&#8217;re a minefield; if they&#8217;re explicitly co-authored, they become a safety net.</p><p>When norms are not clearly defined, often the strongest personality, or loudest person hijacks the group dynamics. This will usually lead to regressive patterns and stifle the creative energy of the group.</p><p>Group norms must be formed and enforced by the group itself. If they are dictated it sets up a dynamic where the people within the group are not attached to the norms, and will seek to find ways to get away with bending or breaking them. It also sets up the dynamic where the norms need to be enforced.</p><p>Instead, it is far better for the leader to frame the desired outcome and stakes that either caused the group to come together, or required an intervention. Once that is expressed, have them determine the norms that would be necessary for them to have to meet that outcome.</p><p>Dynamics at play are clarity of purpose, alignment, and expectations. When norms are established the team has an understanding of where they can operate safely as part of their group.</p><p>o learn more about these dynamics, I highly recommend exploring the work of:</p><ul><li><p><strong>Amy Edmondson</strong> on<a href="https://www.ted.com/talks/amy_edmondson_how_to_turn_a_group_of_strangers_into_a_team"> Building a Psychologically Safe Workplace</a></p></li><li><p><strong>Sidney Dekker</strong> on<a href="https://sidneydekker.com/safety-differently/"> Safety Differently</a></p></li><li><p><strong>David Marquet</strong> on<a href="https://www.youtube.com/watch?v=OqmdLcyES_Q"> &#8220;Greatness&#8221; model of Intent-Based Leadership</a></p></li></ul><h3><strong>Seeing is believing</strong></h3><p>Since I&#8217;m an Agile Coach, it likely comes as no surprise that I highly value information radiators. In fact, I&#8217;d go so far as to say they are a critical component of most high functioning teams. There are groups that are tightly in sync with each other, where they may not need one, but they are exceptionally rare.</p><p>There are more positive impacts of having a visual representation of the work than I can outline here, but here are some that have had huge impacts with teams I was on and those I coach:</p><ul><li><p><strong>Directional indicator:</strong> I mentioned last week the importance of having a shared goal. Having a visual representation of that goal, and its impacts has a profound psychological effect on the members of the group signalling to them that their contribution matters, and continues to reinforce the importance of their work.</p></li><li><p><strong>Clear display of work:</strong> This takes many different forms depending on the nature of the work, but ultimately this serves as a common place for the group to at a glance understand what is needed of them, how things are progressing, and where things may be off course. This enables the group to maintain their effectiveness and have a clear sense of progress, while enabling others to understand the contribution they are making.</p></li><li><p><strong>Transparent monitoring of the system:</strong> This is ideally automated, but doesn&#8217;t have to be. The key is for it to be honest, especially if it&#8217;s honestly telling you something unpleasant. A common place for this is build and deployment pipelines, but it can be any number of other areas. This is essentially your instrument panel that tells you objectively when things are not working as expected so you can respond to it appropriately. They must be trustworthy, and as close to real-time as possible.</p></li></ul><p>The key with all of these is to anchor the group on being part of something bigger than themselves, and reinforcing their sense of being able to depend on one another.</p><h2><strong>The Technical Perspective</strong></h2><p>&#8220;The code you write is a mechanism for communication. Who does it communicate with?&#8221;</p><p>This was the challenge from Scott Bain to a room full of Getty Images&#8217; Software Engineers to help us grasp <a href="https://www.goodreads.com/book/show/3139913-emergent-design">Emergent Design</a>.</p><p>One of us ventured a response, &#8220;The computer?&#8221;</p><p>Seemed reasonable enough to me, so I nodded along, thinking it was a strange question, but of course you wrote code for the computer.</p><p>Bain, quickly shot back, &#8220;A computer does just fine communicating in ones and zeros, try again.&#8221;</p><p>A tentative response came from another part of the class, &#8220;Other people?&#8221;</p><p>&#8220;That&#8217;s right, other people, whether it&#8217;s another engineer, or future you.&#8221;, Bain replied.</p><p>That exchange sticks with me. It was one of a number of classes I was sent to early in my career that truly shaped me.</p><p>Another class that made a big impact was Steve McConnell&#8217;s <a href="https://en.wikipedia.org/wiki/Code_Complete">Code Complete</a> where I learned that ideally code could be read almost as easily as a book, and needs to be expressive of what it actually is doing.</p><p>This is essential even as a solo dev, as it is guaranteed that once you move on to something else, you will have little to no recollection of the headspace you were in when you wrote it.</p><p>If you&#8217;ve been doing this for any significant amount of time, you probably have had the experience of looking at code written a bit ago and trying to figure out who the idiot was who wrote it. After a short amount of digging in source control, realize that <em>it was you</em>.</p><p>We spend the vast majority of our time programming, reading existing code, and trying to figure out how it works and what it does. This is required, because any change made needs to be made in the exact right place, and hooked to the exact right parts, or things don&#8217;t go well.</p><p>When something unintended occurs (like a defect), it&#8217;s rare that an engineer will know exactly where to look in the code to change that behavior. There are a variety of practices that help with that exact challenge, to a greater or lesser extent, but it remains one of the hardest parts of software engineering.</p><p>Here are some key practices that help in this, and a brief description of a lesser known exciting development that is focused exactly on this challenge.</p><ul><li><p><strong>Ensure code clearly describes what it does and uses the appropriate metaphor: </strong>Naming things well is one of the absolute most difficult things in software engineering. The very act of finding a good name can drive design decisions and deeply meaningful conversations with colleagues. A good name should: be short enough to easily read, and accurately describe what the code does.</p><p>This is much easier said than done. Often using metaphors can help. Some of these are commonly enough used that they have made their way into UI&#8217;s such as a way to narrow down a great deal of information to a few select things based on criteria is often called a filter. Code that implements that functionality should also have Filter as part of its name.</p></li><li><p><strong>Embrace TDD with behavior-oriented names:</strong> The goal is to be able at any time and any level to have a clear picture of what the system does without having to look at the code.</p><p>While many people mistakenly think of TDD as a testing discipline, it is absolutely an engineering discipline that forces engineers to think through their approach, and run micro experiments to modify their system to their needs.</p><p>Through working rigorously in this way, a mutually supportive relationship forms between the source code and the tests. A useful metaphor of this effect can be found on medieval buildings, where they have holes built into the walls called &#8220;putlogs&#8221;. These holes are designed to support the scaffolding that enables people to build and maintain the structures.</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!v9Wn!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3fe4160e-797b-4124-945e-0165d91b07b8_624x716.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!v9Wn!, /__u/limitlessledger.substack.com/w_424, /__u/limitlessledger.substack.com/c_limit, /__u/limitlessledger.substack.com/f_webp, /__u/limitlessledger.substack.com/q_auto:good, /__u/limitlessledger.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3fe4160e-797b-4124-945e-0165d91b07b8_624x716.png 424w, /__u/substackcdn.com/image/fetch/$s_!v9Wn!, /__u/limitlessledger.substack.com/w_848, /__u/limitlessledger.substack.com/c_limit, /__u/limitlessledger.substack.com/f_webp, /__u/limitlessledger.substack.com/q_auto:good, /__u/limitlessledger.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3fe4160e-797b-4124-945e-0165d91b07b8_624x716.png 848w, /__u/substackcdn.com/image/fetch/$s_!v9Wn!, /__u/limitlessledger.substack.com/w_1272, /__u/limitlessledger.substack.com/c_limit, /__u/limitlessledger.substack.com/f_webp, /__u/limitlessledger.substack.com/q_auto:good, /__u/limitlessledger.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3fe4160e-797b-4124-945e-0165d91b07b8_624x716.png 1272w, /__u/substackcdn.com/image/fetch/$s_!v9Wn!, /__u/limitlessledger.substack.com/w_1456, /__u/limitlessledger.substack.com/c_limit, /__u/limitlessledger.substack.com/f_webp, /__u/limitlessledger.substack.com/q_auto:good, /__u/limitlessledger.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3fe4160e-797b-4124-945e-0165d91b07b8_624x716.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!v9Wn!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3fe4160e-797b-4124-945e-0165d91b07b8_624x716.png" width="624" height="716" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3fe4160e-797b-4124-945e-0165d91b07b8_624x716.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:716,&quot;width&quot;:624,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!v9Wn!, /__u/limitlessledger.substack.com/w_424, /__u/limitlessledger.substack.com/c_limit, /__u/limitlessledger.substack.com/f_auto, /__u/limitlessledger.substack.com/q_auto:good, /__u/limitlessledger.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3fe4160e-797b-4124-945e-0165d91b07b8_624x716.png 424w, /__u/substackcdn.com/image/fetch/$s_!v9Wn!, /__u/limitlessledger.substack.com/w_848, /__u/limitlessledger.substack.com/c_limit, /__u/limitlessledger.substack.com/f_auto, /__u/limitlessledger.substack.com/q_auto:good, /__u/limitlessledger.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3fe4160e-797b-4124-945e-0165d91b07b8_624x716.png 848w, /__u/substackcdn.com/image/fetch/$s_!v9Wn!, /__u/limitlessledger.substack.com/w_1272, /__u/limitlessledger.substack.com/c_limit, /__u/limitlessledger.substack.com/f_auto, /__u/limitlessledger.substack.com/q_auto:good, /__u/limitlessledger.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3fe4160e-797b-4124-945e-0165d91b07b8_624x716.png 1272w, /__u/substackcdn.com/image/fetch/$s_!v9Wn!, /__u/limitlessledger.substack.com/w_1456, /__u/limitlessledger.substack.com/c_limit, /__u/limitlessledger.substack.com/f_auto, /__u/limitlessledger.substack.com/q_auto:good, /__u/limitlessledger.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3fe4160e-797b-4124-945e-0165d91b07b8_624x716.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><ul><li><p><strong>Continual refactoring:</strong> Refactoring is a key part of true TDD, but it deserves its own mention because it is often skipped, or thought of as a separate effort. To be clear, from the XP perspective, refactoring is the act of  improving the underlying structure of the code, without changing its behavior. In order to ensure this, automated testing that clearly defines that behavior is essential.</p><p>Ultimately the code should only reflect the needs of the system at the time it was written. As those needs change, grow, and as the system is better understood, it must be tuned to meet those needs more effectively. Each time these adjustments are delayed, the system further diverges from the actual needs, and the more effort is required to realign it.</p><p>An apt metaphor is cleaning a house. If you keep up with it as you go, it&#8217;s not that bad, but the longer you let it go, the worse it gets, until it becomes completely unmanageable.</p><p>All that said, a deep dive into refactoring of an old project that hasn&#8217;t been kept up, can grind everything to a halt. In my career I can&#8217;t think of a time where stopping all development for a pure focus on refactoring went well. Instead adopting more of a &#8220;boy-scout&#8221; rule in code, where you leave it better than how you found it, tends to serve to gradually move things to a more clear and coherent codebase.</p></li></ul><h2><strong>Progress: The light at the end of the tunnel was not a train!</strong></h2><p>The 4.5 month long odyssey came to a close early in the week and I&#8217;ve been reaping the benefits with UI work. It has been super cool to be able to provide rich contextual information based on deep graph traversals in an instant.</p><p>I&#8217;ve been busily tweaking the display into something compelling and informative. The thing we&#8217;re fighting with, and getting into some passionate conversations about, is how to show significant and meaningful information, without completely overwhelming the person using the site. This completely reinforces how essential rock solid UX is.</p><p>This coming week, I&#8217;ll probably finish up a few style tweaks, and move on to the dreaded authentication and authorization system. Once that&#8217;s finished up, we should be close to having something others can interact with.</p>]]></content:encoded></item><item><title><![CDATA[Week in review March 30, 2026]]></title><description><![CDATA[Wait, where are we going?]]></description><link>https://limitlessledger.substack.com/p/week-in-review-march-30-2026</link><guid isPermaLink="false">https://limitlessledger.substack.com/p/week-in-review-march-30-2026</guid><dc:creator><![CDATA[Shayne Vacher-Moffeit]]></dc:creator><pubDate>Tue, 31 Mar 2026 16:32:00 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/6507efc2-cffd-4a32-a8c3-0ea4617db8a9_2816x1536.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><em>Tldr: Working backward from a defined outcome isn&#8217;t just a strategy; it&#8217;s a safety net that turns &#8220;drifting&#8221; into &#8220;intentional play&#8221; across our habits, our teams, and our code.</em></p><p>Ever find yourself in business or life feeling like you&#8217;re just drifting, or focusing on what is in front of you without any sense of a destination or purpose? If so, how did that time feel?</p><p>If you&#8217;re anything like me, probably not that great, and certainly not my best when it comes to innovation and sense of accomplishment.</p><p>It&#8217;s sort of muddling along.</p><p>Unfortunately, that&#8217;s the sense I&#8217;ve seen at many organizations, particularly when people are deeply embedded in them, away from direct customer interactions.</p><p>Do you know how your work, whatever it is, makes the world a little bit better?</p><p>This is a question that I would use to align teams around a common purpose. Each person should be able to answer that question in their own way.</p><p>On embedded teams, it would always get serious pushback.</p><p>To be clear, I&#8217;m not necessarily referring to some grand purpose, and certainly not a full blown life plan charted out to the n-th degree. When you are working on something, take the time to develop a sense of what you are setting out to accomplish, and how it makes things a little better in whatever context you&#8217;re working with.</p><p>This week, I&#8217;ll be expanding on the safe to play principle of: <strong>Start with the desired outcome and work backward</strong>.</p><p>I&#8217;ll also give a very brief update on my progress, why I believe now more than ever the end of my &#8220;shouldn&#8217;t be too bad&#8221; change is finally drawing near, and how an overly cautious system I built is one of my last stumbling blocks.</p><h2><strong>The personal perspective</strong></h2><p>One of the most influential factors of our behavior is the habits we form. Many of these form without us being consciously aware. They&#8217;re just patterns we fall into because they feel normal, or they make sense at the time. Fundamental to habits are three major parts: the trigger, the action, and the reward. There are more, but these are the primary ones I&#8217;m focusing on here.</p><p>When reflecting on your habits, a good place to start is examining your interests and the impact you wish to make. Take notice of the scope of what you selected. Is it long term and all encompassing, shorter term and a more limited scope, or maybe something in between?</p><p>From there, think of who you would need to be to make that impact. Consider your behaviors and what aligns with your interests and desired impacts, and what diverges from them. The bigger the scope of what you selected, the more adjustments you will find you will need to make to get there.</p><p>If those adjustments are large, consider what would be one step closer to that desired outcome. So if you wish to help others learn about a specific topic, what sorts of behaviors or mindsets would you need to adopt?</p><p>Clearly, it depends on where you are starting from, but assuming that you have never taught before, and you have limited knowledge of the topic, you have a large number of things you would need to do to make yourself ready to do that. With that in mind, consider what behaviors and mindsets would be the immediate prerequisite for being ready. Continue to work backward from that point, to your current place.</p><p>From there, you can identify the minimal adjustments that would move you toward your goal. Once you have landed on those, consider what behaviors and actions you would need to adopt or change to make one of those adjustments.</p><p>If you have a behavior that diverges from that adjustment try breaking it down.</p><ul><li><p>Does that behavior occur at a particular time, situation, or event?</p></li><li><p>What is the action that you do that you&#8217;d like to change?</p></li><li><p>What is the feeling you have immediately afterward?</p></li></ul><p>Try experimenting with these parts. Is there something else that would give you the same feeling but would be closer to your goal?</p><p>If you need to add a new habit to your life to move you toward your goal, use the same structure:</p><ul><li><p>What would be a good event, or time to do the new thing you want to add?</p></li><li><p>What is that new thing you will do that will move you closer to your goal?</p></li><li><p>How will you reward yourself for doing that action (a sense of satisfaction counts)?</p></li></ul><p>By performing this mental and emotional work, you can start making progress toward the outcome you wish to achieve. There&#8217;s no guarantee that you will succeed, or that goal will remain the same, but this practice will make it more likely that you make progress.</p><h2><strong>The Group Perspective</strong></h2><p>The dynamics of this are very similar to personal goals, where the group determines the outcome it desires, and works backward toward the next viable step. </p><p>Some of the differences however have to do with the fact that each individual that makes up the group has their own set of interests and goals. This makes having a common explicit shared vision absolutely critical, but the key is having each individual of the group able to express in their own words the personalized importance of that shared goal.</p><p>Mechanisms like OKRs are great tools for helping align people around a vision and give them the means to measure their progress. That said, they are often misunderstood and too oriented around output rather than outcome, at least in most of the implementations I&#8217;ve been exposed to.</p><p><strong>The importance of outcome over output cannot be overstated.</strong></p><p>It really doesn&#8217;t matter how many widgets you produce, or how cool a given widget is. If no one finds it useful, and it doesn&#8217;t solve their problems, your efforts are a complete waste.</p><p>It is much easier to generate true excitement around something that clearly makes the world better, rather than some arbitrary number.</p><p>That said, if your goal is simply to learn about producing widgets, the real evaluation is how well you learned about it, and the goal was never the widget in the first place.</p><p><strong>Groups exist for a reason.</strong></p><p>If the members of a group are detached from that reason, they will quickly devolve to doing the minimum effort to ensure they don&#8217;t get kicked out of the group. That is of course dependent on them gaining some value from their membership (such as being paid).</p><p>One of my favorite quotes about this, is the celebrated thinker, inventor, writer, and all around impressive person, Antoine de Saint-Exup&#233;ry:<br><em>&#8220;If you want to build a ship, don&#8217;t drum up the men to gather wood, divide the work, and give orders. Instead, teach them to yearn for the vast and endless sea.&#8221;</em></p><h2><strong>The Tech Perspective</strong></h2><p>This is the section that kicked off this whole session of musing, but it&#8217;s tightly related to the other two. If you&#8217;ve read my other posts you can see that I&#8217;m very focused on determinism when it comes to technology. When I rail against AI, it&#8217;s not so much about the training data, nor the energy load (both of which are problematic). It&#8217;s generally focused on the very characteristics of what it is: A non-deterministic weighted probability model.</p><p>So, why does this matter?</p><p>In engineering systems, determinism is critical. It should perform the same way each time we interact with it. Imagine having a calculator that gives you the right answer most of the time, but you can never tell when it does or when it doesn&#8217;t.</p><p>In order to ensure that the system is doing exactly what it should, you must first truly understand the expected behavior. This is easier said than done, because often we have vague concepts of something, but actually making them concrete takes quite a bit of effort. This is an area that I&#8217;ve found LLMs to be highly useful. By working with them to gain clarity around an idea, I&#8217;m better able to decide what the system should or should not do. Once that is achieved, that can be captured in executable specifications. These are tests that clearly define the expectations of the system, and initially fail, as the system doesn&#8217;t do that yet.</p><p>Some key practices I use to do this are:</p><ul><li><p><strong>Model major behaviors in non-tech readable tests: </strong>As much as it pains me to admit this, specifications are important to establish common understanding between the technical and non-technical team members. This understanding is the basis of shaping marketing messages and stakeholder communications.</p><p>The problem is, unless a specification is executable, it is inaccurate and out-of-date as soon as it is written. An executable specification not only defines the expected behavior, it tells the reader whether or not the system actually does what it says.</p></li><li><p><strong>Always operate from a known state:</strong> An old adage about writing tests from my early days as an XP dev sticks with me to this day &#8220;Tell, don&#8217;t ask.&#8221;</p><p>This means all tests must start from a known baseline. In most layers, you do that with various fakes which appear to be the dependency of the system being tested. In the case of databases, this can be somewhat more tricky.</p><p>The most effective way I&#8217;ve found to do this is to have the database always start empty. Each test populates it in the exact expected way being covered by that test, essentially sterilizing the Operating Room.</p></li><li><p><strong>Determinism is a prerequisite: </strong>This is related to the prior point, but bears repeating. Fuzzy tests are prone to false results.</p><p>If I wanted to specify that my code returned &#8220;Hello world&#8221; and my test asserted that the result included &#8220;Hello&#8221; and &#8220;world&#8221;, the code could return &#8220;world Hello&#8221; or &#8220;aeSworldasdFsabHelloaerEwVasdf&#8221; and would pass. This is a simple example, and in more complex systems this problem compounds dramatically.</p></li></ul><h2><strong>Not a New Practice</strong></h2><p>While these practices may seem strange to some, they are by no means new. In fact, there have been many great innovators who have espoused the key practice of working backward from their desired outcome.</p><p>It&#8217;s a fundamental part of Lean Manufacturing, and it was one of the six key points of Creative Thinking that <a href="https://www1.ece.neu.edu/~naderi/Claude%20Shannon.html">Claude Shannon shared with Bell Labs</a>, back when computers were the size of rooms.</p><p>There are even accounts of no less than Aristotle exploring concepts similar to working this way back in 350 BC.</p><p>In Aristotle&#8217;s (somewhat difficult to read) words:<br><em>&#8220;We deliberate not about ends but about means... Having set the end, they examine how and by what means it is to be attained... until they come to the first cause, which in the order of discovery is last.&#8221; (Nicomachean Ethics, Book III).</em></p><h2><strong>Current progress</strong></h2><p>I truly see light at the end of the digests tunnel. I&#8217;m now running them against my full integration stack, though unfortunately I hit a snag on Friday. When I originally built the system, for some reason I did not trust the data coming back from the database.</p><p>Whenever records are retrieved from the database they are in a format that doesn&#8217;t necessarily play nice with JavaScript, so they need to be transformed into values that JavaScript understands. This is not uncommon in programming, and pretty basic stuff.</p><p>Well, for some reason I can&#8217;t recall, I put in code that required explicitly declared values that stated what that transformation needed to be, and if it wasn&#8217;t declared it would completely remove the value.</p><p>Of course, this was in an area where I skipped deeper testing rigor because of some excuse like expediency and trust that my higher level tests would catch it (and they do). The problem is things break in a way that is not clear: simply missing values.</p><p>I&#8217;ve tracked down the root cause multiple times, and slapped a bandaid on it, then moved on to other things, only to have it crop up again.</p><p>Well, no more. This week, I&#8217;m putting in transformers that simply transform whatever comes from the database without any pruning. There is no reason why I shouldn&#8217;t trust the values in my database.</p>]]></content:encoded></item><item><title><![CDATA[Week in review March 23, 2026]]></title><description><![CDATA[Safe to Fail vs. Safe to Play]]></description><link>https://limitlessledger.substack.com/p/week-in-review-march-23-2026</link><guid isPermaLink="false">https://limitlessledger.substack.com/p/week-in-review-march-23-2026</guid><dc:creator><![CDATA[Shayne Vacher-Moffeit]]></dc:creator><pubDate>Wed, 25 Mar 2026 15:28:47 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/ea538c2c-dfc8-4abd-8136-8adf26748ae1_2816x1536.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><em>tl;dr: In high-stakes environments, &#8220;Safe to Fail&#8221; sounds like insanity. This week, I&#8217;m reframing the conversation to &#8220;Safe to Play.&#8221; Using the analogy of an acrobat&#8217;s training harness, I explore three core mindsets: Outcome-First, Understandability, and Continual Releasability. These mindsets bridge the gap between software engineering and business leadership. Without this rigor, experimenting with &#8220;Vibe Coding&#8221; isn&#8217;t building a sandbox; it&#8217;s walking into quicksand.</em></p><p>A regular drive in many innovation oriented organizations, championed by some of the biggest names in Silicon Valley, is to create a &#8220;Safe to Fail&#8221; environment. I was a big part of creating that environment within programs like the Digital Accelerator within Charles Schwab. After that success, I was part of the group working to spread that mindset throughout the rest of the company.</p><p>It made a lot of people very uncomfortable.</p><p>Consider, what &#8220;fail&#8221; means in the context of an organization that is responsible for the financial stability of a huge number of clients? Layer in the fact that this organization is naturally the target of many bad actors who would love to access their client&#8217;s money. It&#8217;s no wonder that people were uncomfortable with that message when we were pushing it.</p><p>In a high-stakes environment, &#8220;Safe to Fail&#8221; sounds like insanity.</p><p>That said, without the ability to try things that may or may not work, it&#8217;s pretty much impossible to innovate. While I think the intent was good, I think the vernacular chosen was bad, and this obsession with failure that was being pushed did not serve things well. Instead, we should have worked to create a &#8220;Safe to Play&#8221; environment.</p><h2><strong>&#8220;Safe to Play&#8221; in Life</strong></h2><p>Consider any high performing artist or athlete. Take for example an acrobat.</p><p>They practice constantly.</p><p>Most of this is not apparent to the audience. When people see them perform, it is the culmination of many attempts, mistakes, and learnings. They often will work harder in their practice sessions than the show itself, and the true effort they go through is only apparent to their peers or others close to them.</p><p>When they perform publicly, it looks effortless, but ask any serious acrobat and they can give you a long litany of pain that it took for them to get to that level.</p><p>Achieving that pinnacle requires countless hours of practicing movement and conditioning, in an environment where a mistake can be easily recovered from without dire consequences. They also tend to constantly play with their craft, trying different movements and positions, exploring their abilities. This is undoubtedly very hard work, and requires focus, but intermixed is a sense of play, which is key to injecting the creativity and passion into their work.</p><p>By the time you get to see them perform, they have a very good idea of what they and their counterparts can and cannot do. Cirque du Soleil has released a number of <a href="https://www.youtube.com/watch?v=s9l4dy_okyw">videos </a>talking through what it takes to do the amazing performances they do.</p><h2><strong>&#8220;Safe to Play&#8221; in Software (and Business)</strong></h2><p>When thinking about the times I enjoyed working as a software engineer the most, versus times I was most stressed, the biggest difference boiled down to my confidence level that I could make a change to the system without breaking things.</p><p>Thinking about the times I enjoyed when being  part of or building solid teams:</p><h3><strong>In Software</strong></h3><p>This required various systems to enable me to be aware of the impacts of my change, the more immediate the better. If I get feedback within seconds of making a particular change I can more readily determine whether or not I made a mistake.</p><p>Working this way enables me to operate in a highly experimental way, where I can try things, and if they don&#8217;t work out I can easily reverse course or find another approach. This enables me to practice, and try things without worrying about dire consequences. It also enables me to have a high degree of confidence that anything I show to the world, operates in the way I expect it to.</p><p>This is of course a reasonably simple concept, but in application, especially when a project becomes more complex it can become quite involved.</p><p>When things are reasonably simple, a quick pass of exercising the behavior often works well enough. The problem is this has to be done for every single change made. The reality of software is it changes a lot, and often in ways that would have been impossible to predict before digging in due to the nature of software I mentioned in prior posts: creation being an <a href="/__u/limitlessledger.substack.com/p/week-in-review-mar-01-2026">invention based discipline</a> around <a href="/__u/limitlessledger.substack.com/p/week-in-review-feb-22-2026">shaping its behavior</a>.</p><p>To do this effectively requires a significant investment of time and energy to get the appropriate systems in place. To maintain them requires ongoing rigor.</p><p>Ultimately, this more than pays for itself by the peace of mind that comes from knowing you can experiment. This saves you from the experience of having all the blood drain from your face as you realize that little change you made just obliterated months of work.</p><p>It also tends to enable you to find better solutions faster, allowing you to rule out bad paths earlier.</p><p>As with all preventative measures, it is impossible to truly measure the impact, but much like brushing your teeth, failing to take these measures can be extremely costly.</p><p>Here are some key mindsets that I employ:</p><ul><li><p><strong>Start with the desired outcome and work backward:</strong> A key way to do this is to treat tests as executable specifications. Ideally someone new to the codebase can understand what it does by running the tests and reading the output. The tests must be deterministic and clear, with descriptive names that provide meaning to the results. When they fail, the reason for the failure should be clear and understandable. &#8220;Expected true to be false&#8221; is not particularly helpful.</p></li><li><p><strong>Optimize for understandability: </strong>Use various techniques and tools to ensure that anyone interacting with the system under development can quickly and readily understand, and make decisions about anything being built.</p></li></ul><blockquote><p>The clever but hard-to-understand thing that was woven into the system will become a nightmare if you need to change it even a month down the road, and it&#8217;s almost guaranteed that you will.</p></blockquote><ul><li><p><strong>Be in an </strong><em><strong>always releasable</strong></em><strong> state:</strong> As with many of these topics, this can be somewhat contentious, but a quick look at <a href="https://dora.dev/guides/dora-metrics/">DORA metrics</a> makes it very clear that the one of the defining characteristics of highly successful engineering organizations is their ability to deploy to production frequently and with as little effort as possible. This is often characterized by the saying &#8220;make releases a non-event.&#8221;</p></li></ul><p>By following these practices with a great deal of rigor and discipline, you are effectively working in an environment where making tweaks and changes are little or no stress, and you are working from known good state to known good state. You naturally reinforce your sandbox, and are able to be selective what leaves it, and what stays.</p><h3><strong>In Business</strong></h3><p>I&#8217;ve spent a lot of time digging into how this works in software, as that&#8217;s mostly where my head is now, but this readily applies to business as well. Consider:</p><ul><li><p><strong>Start with the desired outcome and work backward:</strong> A shared common vision is essential to align people around work. When you start with the desired outcome the rest of the group can figure out how they can contribute to realize it. It also enables you to naturally uncover the value stream that will lead to that outcome being realized.</p></li><li><p><strong>Optimize for Understanding:</strong> One of the biggest avoidable expenses in business is miscommunication. This manifests itself in a variety of ways, but by ensuring everyone has a common and realistic understanding, the entire nature of communication shifts from a competition of opinions to interpretations of the current situation. Ideally these interpretations are  oriented toward working toward the common desired outcome.</p></li><li><p><strong>Be in an always releasable state:</strong> While this one is clearly oriented around software, it is very cross applicable. Ultimately this compliments Optimizing for Understanding, by starting with something that conveys the general idea, and then progressively refining that idea. This gives everyone something they can rally around, and apply their own insights to in order to work toward the common desired outcome.</p></li></ul><p>Just like in software engineering, it takes a great deal of rigor to live by these mindsets. You will never do all of them perfectly, but by even aspiring to move toward them you are much more likely to have an aligned team, and make substantial progress toward your desired outcome.</p><p>I&#8217;ll explore each of these in more detail in future posts, but this should be a good enough general idea to build common understanding and to move toward the desired outcome of building a safe to play environment.</p><h2><strong>Safe to Play in the time of Vibe</strong></h2><p>I have no doubt whatsoever that it is possible to set up safe to play environments for vibe coding into. In fact, I&#8217;d wager that the vast majority of people coming from a similar background as mine do just this.</p><p>That said, the level of rigor I presented is somewhat rare even when code was primarily being written by humans. The reasons I have found it essential were formed over many years in the industry and seeing the consequences of less rigorous approaches. These consequences can range from increased stress, to the complete failure of a company due to inability to change as needed.</p><p>Part of the excitement around vibe coding is that anyone, even people with little or no technical skills, can use an AI to create anything they think of. It&#8217;s a compelling value proposition.</p><p>Unfortunately it comes with some severe downsides.</p><p>A major downside is that without the deeper technical background and understanding of why rigor is critical, it is unlikely your average user would even think to have the Vibe coding platform layer these safeguards. Also, I can attest from working extensively with Gemini Pro, determinism and rigor are not their strong suits.</p><h2><strong>Final thoughts</strong></h2><p>I&#8217;m all for experimenting with these tools. Heck given the current climate, it would be foolish not to. That said,<em><strong> it is critical to understand their limitations</strong></em>.</p><p>Otherwise, you may find your sandbox is quicksand.</p>]]></content:encoded></item><item><title><![CDATA[Last Week in Review, Mar 16, 2026]]></title><description><![CDATA[Biases&#8230; Biases everywhere]]></description><link>https://limitlessledger.substack.com/p/last-week-in-review-mar-16-2026</link><guid isPermaLink="false">https://limitlessledger.substack.com/p/last-week-in-review-mar-16-2026</guid><dc:creator><![CDATA[Shayne Vacher-Moffeit]]></dc:creator><pubDate>Mon, 16 Mar 2026 15:46:10 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/ab8dc222-477b-412e-9ff5-b2a99f2ba379_2816x1536.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><em><strong>tl;dr:</strong> This week, a &#8220;shouldn&#8217;t be too bad&#8221; engineering refactor serves as a mirror for the human brain. Just as I struggle with the hidden complexity of my own code, our 20-watt bio-computers struggle with the complexity of the modern world. I&#8217;m exploring why biases aren&#8217;t &#8220;mistakes&#8221; but essential energy-saving architecture, why we swap hard questions for easy ones (Attribute Substitution), and why a simple answer to a complex problem is almost always a lie.</em></p><p>You are biased. So is everyone you know, and don&#8217;t know.</p><p>It&#8217;s simply a function of how our brains work.</p><p>This week, after a very short engineering update, I&#8217;ll be talking about a specific set of biases that have a profound effect on our lives across the board. I&#8217;ll also touch on what drove my deep dive on biases.</p><h2><strong>Engineering Update: The Compounding Change</strong></h2><p>While I can indeed see light at the end of my four-month &#8220;shouldn&#8217;t be too bad&#8221; update, it wasn&#8217;t done compounding yet. Weaving the request for digests into my system uncovered a need for a more sophisticated ability to make targeted requests. This requires  a rethink about how modifiers to queries (such as filtering, paging, etc) are passed down to the deeper systems. I figured out a strategy to allow for that, and am now getting it into place.</p><p>Interaction with this code, even logic I wrote recently, reminds me of one of the points Tudor G&#238;rba and Simon Wardley made in <a href="https://medium.com/feenk/rewilding-software-engineering-900ca95ebc8c">Rewilding Software Engineering</a>: Software engineers spend a significant majority of their time reading code. At this stage I&#8217;m making sense of what I wrote a few months ago, and getting it to play nice with the general system.</p><h2><strong>The 20-Watt Bio-Computer</strong></h2><p>Our brains are amazing organs. By volume the brain uses more energy than any other part of our bodies, consuming roughly 20% of the calories for about 2% of the mass of the body. This equates to approximately the same amount of electricity to power a refrigerator lightbulb.</p><p>It&#8217;s also an exceptionally hard working organ. It has to take in a huge amount of input from the rest of the body, make sense of the current state, as well as balance that with prior experiences that could play into what is needed. This isn&#8217;t even touching on a whole range of other functions including invention, or emotional regulation, which is very much part of its job.</p><p>Due to this balance between the large workload and little energy, our brains have to be highly efficient. They employ multiple different mechanisms to reduce the amount of energy expended automatically. This manifests itself in many ways, including Inattentional Blindness, Automaticity, Habituation, and of course Cognitive Bias.</p><h2><strong>A Personal Struggle with Prejudice</strong></h2><p>When I was young, I was exposed to quite a few very prejudiced people. At the same time, both my parents, in their own way, instilled in me the qualities of empathy and acceptance. The bigoted mindset really didn&#8217;t make sense to me, yet I frequently encountered it. I found it repulsive and felt that I absolutely did not want to be like those people. As such, when I found my brain automatically having various prejudiced thoughts, I was appalled.</p><p>This caused me massive stress. When something stresses me, I tend to try to examine it and understand it better. This coping mechanism mostly serves me well, but this was a really big one. I didn&#8217;t want to be anything like the bigoted people I was exposed to, yet I found myself making snap judgements of people based on very little information, just like they did.</p><h2><strong>&#8220;That&#8217;s Not How Biases Work&#8221;</strong></h2><p>I first heard talk about biases at lunch with my colleagues. I really didn&#8217;t understand what they were talking about but it sounded like something to avoid.</p><p>Later I had a housemate who was working on her PhD in Behavioral Psychology, with her dissertation focused specifically on a particular set of biases. I recall a conversation with her about it, where I was absolutely positive that what I needed to do was to overcome biases. I remember her patient frustration, telling me, &#8220;that&#8217;s not how biases work.&#8221;</p><p>While I didn&#8217;t think about it at the time, this laid a foundation that served me well as I moved out of writing software and more focusing on how people interact with one another. I started learning more about how the brain actually works, and started seeing how that applied to my work as an agile coach. I was able to see how some teams would pull together, and how some would fracture, based on many different nuanced factors that had little or nothing to do with competence or even general sentiment toward one another. I also became increasingly frustrated and heartbroken when people who could benefit readily from finding common cause would end up getting in massive roiling conflicts over their differences that weren&#8217;t relevant to the most critical issue at hand.</p><h2><strong>Group Projects and Circular Firing Squads</strong></h2><p>This all came to a head relatively early in my studies at <a href="https://www.tomorrow.university/">Tomorrow University of Applied Sciences</a>. We had a group project where we were meant to help an actual company develop products to enable them to better monetize their product, and work to uplift the disadvantaged area that their production was based out of. It was an exciting prospect, and we were all aligned with their broader goals: the company, university, and our program was all oriented around sustainability.</p><p>Due to concerns with how companies tend to operate in developing nations, even companies that work hard to project a positive image, my group-mates became very concerned about this company&#8217;s interactions with the community they were working with. This built to a point where our first meeting with the company&#8217;s representative, which was supposed to be us sharing our ideas with her, was more like an ambush. The most frustrating thing was that even a small amount of research showed that this company was doing what one would hope a company in their position would do: treat the community they were working with as key stakeholders and had them deeply involved in the project.</p><p>Fortunately, that experience didn&#8217;t put off the company representative, and we ended up having a good interaction with them. All of my classmates were very intelligent and caring people who genuinely wanted to make the world a better place, and yet they were treating an ally as an enemy.</p><p>This is a story I&#8217;ve seen play out with heartbreaking regularity.</p><h2><strong>The Birth of Non-Judgmental Thinking</strong></h2><p>That experience prompted me to reach out to one of the co-CEO&#8217;s of our school, Dr. Thomas Funke, and ask if we had a class on Business Diplomacy. He had witnessed the same situation I laid out multiple times as well, so he recognised the need to have one. This is what led me to building a class for their MBA program about Cognitive-Bias and Social Identity Theory, called Non-Judgmental Thinking.</p><p>Building this class had me digging deeply into the science behind these two critical areas of study, and solidifying my understanding of how their dynamics play out. My former housemate, now a practicing Psychologist,  also helped by reviewing what I wrote and clarifying areas I misunderstood. I now find myself commonly needing to navigate what she so effectively did with me, helping people understand that biases are not something you can overcome. They are fundamental to how the brain works.</p><h2><strong>Bias Basics</strong></h2><p>Two of the biggest pioneers of the study of bias were Daniel Kahneman and Amos Tversky. Their Nobel winning work together was collected into the book Thinking Fast and Slow. Unfortunately Tversky had passed away before the Nobel and before the book was published, but Kahneman honors him throughout.</p><p>What they uncovered was that when processing information your brain essentially has two different modes:</p><ul><li><p><strong>System 1:</strong> Very fast pattern matching. Highly efficient, using very little energy. Has access to your entire long term memory. Error prone as it is completely optimized for speed. Happens before you are consciously aware.</p></li><li><p><strong>System 2: </strong>Slow and methodical processing. Uses a tremendous amount of energy. Can only access your short term memory, which is about 7 +/-2 items. This is where logic and cognition tends to live, and tends to be less error prone.</p></li></ul><p>The reason for this is tied to survival. When a predator, like a sabertooth tiger, jumps out at you, you don&#8217;t have time to have a deep think about what might be driving their behavior, you need to act immediately. All of your brain and body energy needs to be used to ensure you survive that encounter. Once you&#8217;re out of the immediate situation, then it&#8217;s possible to find the time to consider the dynamics that led to that encounter.</p><p>While fortunately most of us are not in a position to be pounced on by wild predators these days, these critical systems have not evolved much since then.</p><p>Non-physical threats, such as threats to status, are no different to our amygdala than that predator jumping out at us, and immediately our defenses snap into place. Also, our threat perception is very much tuned to our worldview.</p><h2><strong>The overwhelming desire for simplicity</strong></h2><p>The way our brains work is highly useful. It&#8217;s enabled us to survive for a very long time in an environment that was (and still can be) very dangerous. Further, it&#8217;s enabled us to advance to a point where we are much less likely to get eaten by a wild predator than many of our ancestors were.</p><p>System 1 works great, when things are simple and cause and effect is clear. If you have a great deal of experiences where reacting in a particular way would lead to a predictable good outcome, it is often exactly the system you need. This is tightly related to the intuition that trained observers develop, or highly experienced emergency responders. This is how I can spend a reasonably short amount of time interacting with your team, and have a clear sense of the health of their team dynamics, but I can&#8217;t necessarily offer a clear explanation of how I know.</p><p>The problem is, when things are complex, or unpredictable, even by a little bit, the system fails us. Unfortunately most of the situations in the modern world are, by nature, complex and multi-layered. We have advanced to a global society where we are more interconnected than ever before, and changes made in a completely different part of the world can have profound impacts on the lives of others.</p><p>We all want simple answers. They make it so we don&#8217;t have to spend as much of our precious brain energy and we can move on to other things. The reality is that simple answers to complex problems are almost always wrong, unless they are derived from a significant amount of experimentation. Anyone telling you that a complex and dynamic problem has a simple solution (e.g., immigration, geo-politics, the job market, or product development), is likely using your biases against you to manipulate you into serving their goals.</p><h2><strong>The Trap of Attribute Substitution</strong></h2><p>The most relevant mechanism here is Attribute Substitution. When presented with a hard question that requires System 2 effort, our brains unconsciously swap it for a simpler question that System 1 can answer.</p><ul><li><p><strong>Hard Question:</strong> &#8220;Is this complex economic policy sound?&#8221;</p></li><li><p><strong>Substitute Question:</strong> &#8220;Do I like the person proposing this?&#8221;</p></li></ul><p>Even when you are aware of the actual answer, the pull of the simple substitute is incredibly strong.</p><h2><strong>So What Can You Do?</strong></h2><p>Biases are unavoidable, and not a personal failing, but they often can make you jump to conclusions, or make snap judgements that don&#8217;t serve you well. While exploring this in depth would be a huge endeavor, there are several things you can do to operate more in line with how you want to.</p><p>Here&#8217;s a few quick tips:</p><ul><li><p><strong>Become bias aware:</strong> There are 100&#8217;s of biases and more are being discovered. While it would be impractical to attempt to learn them all in one session, you can start by spending time exploring them. Here&#8217;s one of my favorite presentations of them: <a href="https://upload.wikimedia.org/wikipedia/commons/c/ce/Cognitive_Bias_Codex_With_Definitions%2C_an_Extension_of_the_work_of_John_Manoogian_by_Brian_Morrissette.jpg">Cognitive Bias Codex with Definitions</a></p></li><li><p><strong>Challenge your assumptions:</strong> Try to find ways that what you think is certain, may not be accurate. Get other perspectives to give you more of a richer view, the more diverse the better.</p></li><li><p><strong>Practice kind self-reflection</strong>: While you won&#8217;t be able to prevent yourself from being impacted by your biases, it is completely within your control how you react when you realize it. Don&#8217;t beat yourself up about choices made, but instead try to learn about what other options you may have, and surface places you may need to make amends.</p></li><li><p><strong>Invite constructive feedback:</strong> Ask others you trust what you&#8217;re missing, or how things came across to them. Try to find people who are significantly different from you, as they are all affected by their biases as well. I&#8217;ve found that AI&#8217;s aren&#8217;t bad to help identify the biases that you might be operating under, but do be aware they are highly biased as well.</p></li></ul><p>I&#8217;ll touch on more biases and how to manage them in future posts, but recent events have me thinking about Attribute Substitution a lot.</p>]]></content:encoded></item></channel></rss>