<?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:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[THT Systems]]></title><description><![CDATA[Different terrains. One traveler. Where systems reveal structure, craft reveals form, and lineage reveals the Way.]]></description><link>https://www.tomharveytraining.com/</link><image><url>https://www.tomharveytraining.com/favicon.png</url><title>THT Systems</title><link>https://www.tomharveytraining.com/</link></image><generator>Ghost 6.44</generator><lastBuildDate>Tue, 09 Jun 2026 08:05:46 GMT</lastBuildDate><atom:link href="https://www.tomharveytraining.com/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[The Straight Lead Punch: Lineage]]></title><description><![CDATA[The straight lead punch was not invented. It was recovered, independently, by every practitioner who committed to linear offensive mechanics under real pressure, across four centuries and three continents of Western fencing.]]></description><link>https://www.tomharveytraining.com/the-straight-lead-punch-lineage/</link><guid isPermaLink="false">6a1dd00704914400016f84f7</guid><category><![CDATA[The Workbench]]></category><category><![CDATA[Martial Arts]]></category><category><![CDATA[Jeet Kune Do]]></category><category><![CDATA[Ted Wong]]></category><category><![CDATA[TWJKD]]></category><category><![CDATA[THTJKD]]></category><dc:creator><![CDATA[Thomas Harvey]]></dc:creator><pubDate>Sat, 06 Jun 2026 23:06:05 GMT</pubDate><media:content url="https://storage.ghost.io/c/c4/dc/c4dcef1a-ac8f-4b6b-9334-63e32b1fa558/content/images/2026/06/GM_SLP_Lineage_Section_20260606.png" medium="image"/><content:encoded><![CDATA[<hr><img src="https://storage.ghost.io/c/c4/dc/c4dcef1a-ac8f-4b6b-9334-63e32b1fa558/content/images/2026/06/GM_SLP_Lineage_Section_20260606.png" alt="The Straight Lead Punch: Lineage"><p><em>Part 1 of this series covered the mechanism: the kinetic chain, the geometry, the physics of the collision. This piece asks a different question: where else has that mechanism appeared in the historical record, and what does the pattern of its appearance tell us?</em></p><div class="kg-card kg-button-card kg-align-center"><a href="https://www.tomharveytraining.com/the-straight-lead-punch-force-structure-and-timing" class="kg-btn kg-btn-accent">Read Part 1</a></div><hr><h3 id="the-convergent-physics-hypothesis">The Convergent Physics Hypothesis</h3><p></p><p>I want to be precise about what I am arguing before I argue it.</p><p>This is not a claim that martial arts traditions borrowed from each other. It is not a claim that some ancient culture discovered the straight lead and passed the knowledge forward through a chain of masters. It is not a lineage argument in the conventional sense at all.</p><p>The argument is this: any practitioner who commits to the deep study of linear offensive striking under genuine mortal consequence, and submits the body to sufficient repetition against real resistance, will independently discover the same biomechanical configuration. Not because they were taught it. Because the physics requires it.</p><p>I call this the Convergent Physics Hypothesis. The mechanism is not transmitted. It is found.</p><p>To test this, I searched. I went looking for the signature in the historical record across ten martial traditions spanning twenty-five centuries and four continents. I wanted to know where it appeared, where it did not, and whether the pattern of appearance and disappearance told us anything about the conditions that produce it.</p><p>Here is what I found.</p><hr><h3 id="the-signature">The Signature</h3><p>The biomechanical configuration I am tracing is specific. It has four components. All four must be present together for it to count.</p><p>First: the rear heel is raised in the offensive ready stance. Not necessarily dramatically, but elevated, with weight on the ball of the rear foot.</p><p>Second: the rear leg is positioned at an oblique angle to the line of attack, neither perpendicular nor parallel, but angled for horizontal force production.</p><p>Third: the propulsive contact point during the drive is the ball of the rear foot, not the heel. The heel may briefly return to the ground mid-drive, but the force originates from the ball.</p><p>Fourth: the mechanism at work is pre-loading, an eccentric stretch of the posterior chain during the load phase that releases as concentric force during the drive. What modern biomechanics calls the stretch-shortening cycle.</p><p>This is the signature. Where I find all four components together, confirmed in primary sources, I count it as evidence. Where I find partial evidence I say so. Where I find nothing I say that too.</p><hr><h3 id="the-oldest-record-greece-490-bc-onward">The Oldest Record: Greece, 490 BC Onward</h3><p>The earliest dateable evidence I have found is in Attic vase painting.</p><p>E.N. Gardiner&apos;s <em>Athletics of the Ancient World</em> (Oxford: Clarendon Press, 1930) analyzes fifth-century BC boxing depictions from documented museum holdings. On the Duris kylix (British Museum E.39, c.490 BC) and its companion pieces, Gardiner reads the fighter&apos;s position directly: &quot;the right foot is usually lifted from the ground&quot; during the left-hand straight strike. &quot;The force of the blow was obtained from a lunge.&quot; The heel is up. The drive comes from the floor.</p><p>The literary record confirms the posture in the stance itself. Virgil&apos;s <em>Aeneid</em>, Book V, written around 19 BC, describes two fighters entering combat: &quot;poised on their toes.&quot; The raised heel is the ready state before any action. Statius, <em>Thebaid</em> Book VI, around 90 AD: &quot;on their toes, they raised hands like lightning bolts.&quot; These are not technical manuals. But they are consistent, spanning a century, and they describe the same posture as a recognized element of the fight.</p><p>A 2024 peer-reviewed study (Stewart et al., <em>Bioengineering</em> 12(12):1355) that performed static biomechanical analysis of Pankration pottery depictions confirmed approximately 68% body weight loaded on the rear leg in readiness stance. The specific heel position mid-strike is inferred rather than confirmed by that analysis, but the loading pattern is consistent with the signature.</p><p>The Greek evidence spans six centuries of primary record. It is not conclusive on every element of the signature, but it is the earliest documented tradition I have found where the raised-heel striking posture appears in dateable evidence. The tradition under which these men fought was not sport. Greek boxing and Pankration in the Panhellenic games were not padded. The cost of error was real.</p><hr><h3 id="the-western-masters-1409%E2%80%931610">The Western Masters: 1409&#x2013;1610</h3><p>The longsword masters who came after the Greeks worked in a tradition that also had genuine consequence. What they show is more fragmentary than what Capoferro and his contemporaries would give us in 1606, but the geometric evidence is present.</p><p>Fiore dei Liberi&apos;s <em>Flos Duellatorum</em> (1409) shows oblique rear-foot placement in his offensive guards. The illustrations are the evidence; his text does not specify heel position. Hans Talhoffer&apos;s <em>Fechtbuch</em> (1467), held at the Library of Congress and the Metropolitan Museum, shows the same oblique placement. George Silver&apos;s <em>Paradoxes of Defence</em> (1599) documents the rear foot at 90 degrees to the imagined opponent&apos;s line, confirming the oblique geometry.</p><p>For the longsword tradition, I have plate evidence for the oblique foot placement but not explicit textual or plate evidence for heel elevation. I am listing this as partial confirmation: the geometry is correct, the specific heel position is inferred.</p><p>The rapier masters of 1606&#x2013;1610 give us the complete picture.</p><p>Ridolfo Capo Ferro da Cagli published <em>Gran Simulacro dell&apos;Arte e dell&apos;Uso della Scherma</em> in Siena in 1610. Chapter IX places the rear heel with deliberate precision. In the guard, the inside of the left heel aligns with the point of the right heel.&#xB9; The rear leg sits at the oblique angle. The stance geometry is pre-loading.</p><p>When Capoferro describes the lunge itself:</p><blockquote><em>&quot;By turning on the ball of the back foot, you can push your hips further forwards, thus extending your reach.&quot;</em>&#xB2;</blockquote><p>The contact point is the ball. The heel is up. The turn on the ball of the rear foot converts the compressed rear leg into horizontal drive, the elastic release that modern biomechanics identifies as the stretch-shortening cycle operating through the Achilles tendon and plantar fascia. The rear leg extends on what Capoferro calls <em>una linea obliqua</em>: the full commitment of a body driving itself horizontally through space using the floor as its foundation.&#xB3;</p><p>The copper engravings by Rafael Schiamirossi that accompany the text show this geometry in thirty-six plates. In the lunge plates (Plates 5, 6, 14, 15, 16, and 17), the rear leg extends at full oblique, the heel clear of the ground, the ball the only contact point in the drive. What the text describes, the plates demonstrate. Neither requires inference.</p><p>Salvator Fabris published <em>De lo Schermo overo Scienza d&apos;Arme</em> in Copenhagen in 1606.&#x2074; His guards are distinguished by their extreme low position: the hips dropped, the rear leg placed under sustained eccentric load as a structural precondition of any offensive action. The rear leg in Fabris&apos;s extended low guard is already working before the offensive action begins, already storing elastic potential energy in the stretched posterior chain. In advancing to close distance, Fabris instructs placing all weight on the back foot while the front foot lifts.&#x2075; The weight does not sit flat. It loads. The back foot receives everything, and from that full load, the release produces the drive.</p><p>In the same year, Nicoletto Giganti published <em>Scola overo Teatro</em> in Venice.&#x2076; Giganti&apos;s contribution is specific: the first treatise to fully describe and name the <em>stoccata lunga</em> as a discrete and teachable technique. His description of the lunge&apos;s mechanical sequence is written in terms of ordered commitment: the body extends before the foot lands, the weight already in motion before the front foot makes contact with the floor.&#x2077; Plates 2 and 4 show the rear leg aligned for horizontal drive. The heel is up in the drive.</p><p>Three Italian masters, two working in the same year, one four years later, all publishing in different cities, all documenting the same four-element signature. These were not sport practitioners. The bodies they studied in motion were moving toward points that could kill them. The mechanics survived because error in the mechanics was not recoverable.</p><hr><h3 id="the-shift-1763%E2%80%931884">The Shift: 1763&#x2013;1884</h3><p>The signature does not survive every transition.</p><p>Domenico Angelo published <em>L&apos;Ecole des Armes</em> in 1763. His instruction on the rear heel in the guard is explicit: &quot;the left foot should be plumb to the ground, and not move, heel or toe.&quot;&#x2078; The flat heel is mandated in primary text. </p><p>Angelo was operating inside a tradition that<br>had already made its choice. Dueling was giving way to swordsmanship as social accomplishment and competitive sport. When the consequence for error changed from death to point deduction or bruised reputation, the mechanics seem to follow. Whether that is causation or correlation is the honest question worth sitting with.</p><p>Masaniello Parise&apos;s treatise, adopted as the official Italian Ministry of War syllabus in 1884 and codified as doctrine for the Scuola Magistrale di Scherma, institutionalized the Neapolitan school&apos;s approach at the national level.&#x2079; One hundred and twenty-one years after Angelo, the flat heel was not just a preference. It was government doctrine.</p><p>The pattern here is as important as the evidence for the signature itself. The shift is not random drift. It happens at specific moments: when the tradition transitions from real consequence to sport, and when the tradition transitions from individual mastery to institutional standardization. Both transitions occurred in Western fencing between 1763 and 1884. Both produced the same result: the flat heel.</p><p>The physics did not change. The cost of error did.</p><p>What makes the shift period more precise is what was happening in bare-knuckle boxing at the same time.</p><p>Twenty-six years after Angelo mandated the flat heel in fencing, Daniel Mendoza published <em>The Art of Boxing</em> in 1789. Mendoza was not a fencer. He was the English bare-knuckle champion, fighting without gloves on a boarded stage with no weight classes and no time limit. The consequence for error was real.</p><p>His technical instruction specifies two foundational principles. First: <em>&quot;to be perfectly master of the equilibrium of the body, so as to be able to change from right to a left-handed position; to advance or retreat striking or parrying; and throw the body either forward or backward without difficulty or embarrassment.&quot;</em>&#xB9;&#x2070; Second: <em>&quot;the position of the body, which should be in an inclining posture, or diagonal line, so as to place the pit of the stomach out of your adversary&apos;s reach... both knees must be bent, the left leg advanced.&quot;</em>&#xB9;&#xB9;</p><p>The diagonal line is the oblique rear leg. The bent knees in a forward-inclining posture load weight onto the balls of the feet; flat heels cannot support the equilibrium Mendoza describes, and switching from right-handed to left-handed position from flat heels is not possible without a complete reset of stance. The raised rear heel is not named. Its mechanical precondition is specified in every sentence.</p><p>Pierce Egan, documenting the era twenty years later in <em>Boxiana</em> (1812), compared Mendoza&apos;s system to fencing in &quot;regularity and precision,&quot; two traditions reaching the same mechanics from different directions, at a moment when the fencing tradition&apos;s institutions had already begun mandating its abandonment.</p><p>The shift, then, is specific institutional pressure. The fencing tradition was moving into academies and sport courts and military syllabus. Bare-knuckle boxing, operating under no institutional doctrine, kept finding the same configuration the rapier masters had found in 1606. The physics asserted itself wherever the consequence structure remained real.</p><p>The fencing tradition did not recover that configuration for another 154 years.</p><hr><h3 id="the-recovery-1943%E2%80%931950">The Recovery: 1943&#x2013;1950</h3><p>Aldo Nadi was born in 1899 into a fencing family. He became one of the most decorated fencers of the early Olympic era. <em>On Fencing</em>, published in 1943, is simultaneously a technical manual and a prolonged argument with everything he believed had gone wrong in the sport since his youth.&#xB9;&#xB2;</p><p>On the rear heel in the guard:</p><blockquote><em>&quot;Raising your left heel ever so little, you cock the leg ready to pull the trigger and go into action.&quot;</em>&#xB9;&#xB2;</blockquote><p>On what the raised heel enables in the lunge:</p><blockquote><em>&quot;You take full advantage of one of the mightiest springs in all creation, the arch of the foot, which in the lunge releases its tremendous power through the pressure exerted on the ground by the ball of the foot itself.&quot;</em>&#xB9;&#xB3;</blockquote><p>He was explicit that this position put him in direct conflict with the contemporary Italian school, which had drifted toward a flat-heeled guard. He argued that the flat heel was not orthodoxy but degeneration, a departure from the older mechanics. He was correct. The older mechanics are in the plates. They are in the text. Capoferro had specified them three hundred and thirty-three years before Nadi picked up his pen.</p><p>Seven years later, in 1950, Jack Dempsey published <em>Championship Fighting</em> (Prentice-Hall).&#xB9;&#x2074; Dempsey was not a fencer. He was not working in the Western European tradition at all. He was a professional boxer, and his book was about boxing.</p><p>His description of the ready position: &quot;your right foot is resting only lightly on the ball of the foot.&quot; His description of the drive: &quot;the alert ball of your right foot came to the rescue frantically and gave your body a forward spring.&quot;&#xB9;&#x2075; He calls the mechanism a &quot;spring.&quot; He arrives at the same physics from a completely different tradition, with no apparent awareness of the fencing literature, and names it in the same mechanical terms.</p><p>Bruce Lee cited Dempsey directly in <em>Tao of Jeet Kune Do</em>. The lineage that produced the straight lead, as Lee practiced it, runs through Dempsey. The physics is the same physics Capoferro documented in 1610.</p><p>The transmission of those mechanics from Lee to the present generation runs through Ted Wong. Wong trained personally with Bruce Lee and was one of only two practitioners to receive a rank certificate from Lee in Jun Fan Jeet Kune Do.&#xB3;&#x2070; He approached the straight lead the way an engineer approaches a structure: every element necessary, none optional, the system valid only when complete. After Lee&apos;s death in 1973, Wong spent decades preserving and transmitting that complete mechanical system, the on-guard geometry, the footwork, the power line, the precise relationship between every component. What Dempsey gave Lee as a foundation, Wong preserved as a living specification.</p><hr><h3 id="the-eastern-confirmation-kendo">The Eastern Confirmation: Kendo</h3><p>The All Japan Kendo Federation&apos;s standard pedagogy specifies: the left heel is raised 3&#x2013;4 centimeters off the floor. Weight distribution is 70% on the left foot, 30% on the right. 70% of that left-foot weight is on the ball, 30% toward the heel. The instruction for initiating an attack: &quot;instantly push off from the left foot and strike in one action.&quot;&#xB9;&#x2076;</p><p>Koshida, Matsuda, and Kawada (2011) published peer-reviewed biomechanical analysis of the kendo strike-thrust motion in the <em>Journal of Sports Medicine and Physical Fitness</em>. The study confirmed consistent lower-extremity biomechanical patterns in the kendo strike. The study was motivated by high rates of Achilles tendon injury among kendo practitioners, which is direct confirmation of the Achilles loading that the raised-heel drive produces.&#xB9;&#x2077;</p><p>Kendo and its antecedent kenjutsu developed separately from the Western fencing tradition. The specific pedagogical standard of the raised left heel is documented as the required posture, not a stylistic variation. The physics that Capoferro documented in 1610 appears in Japanese sword arts in a tradition that had no contact with the Italian rapier schools.</p><hr><h3 id="the-cultural-search-what-i-looked-for-and-what-i-found">The Cultural Search: What I Looked For and What I Found</h3><p>I searched ten martial traditions for the signature. Here is an honest accounting of the results.</p><p><strong>Greek antiquity (490 BC&#x2013;90 AD):</strong> Confirmed at HIGH confidence. Covered above.</p><p><strong>Western longsword and rapier (1409&#x2013;1610):</strong> Confirmed at HIGH confidence for rapier; PARTIAL for longsword. Covered above.</p><p><strong>Chinese traditions (Xingyiquan, Shaolin):</strong> The search found toe-strike training in Shaolin&apos;s Zu She Gong - foot as striking weapon, not ball-of-foot propulsion in a straight strike. The Xingyiquan tradition shows aggressive linear mechanics influenced by spear practice, promising geometrically, but the raised-heel, ball-of-foot drive in a straight strike was not confirmed in the sources gathered. Specialist sources on Xingyiquan body mechanics would answer it. The open web does not.</p><p><strong>Arabic and Mamluk (Furusiyya corpus):</strong> The Furusiyya tradition, centered in the Mamluk Sultanate of the 13th and 14th centuries, is primarily documented as a mounted martial discipline. The HAMA Association has identified a 1470 manuscript (<em>Kit&#x101;b al-makhz&#x16B;n</em>, attributed to Ibn Akhi Hizam) that contains hand-to-hand martial arts methods and is currently under translation.&#xB9;&#x2078; This is a genuine open lead. Until the text is accessible, I cannot confirm or deny the signature in this tradition. That is where this sits: a genuine lead, waiting on a translation.</p><p><strong>Norse and Viking (Glima):</strong> Dead end. Glima is a wrestling tradition. The sources describe grip, leverage, and balance as the core skills, with no striking mechanics that address the signature.</p><p><strong>Indian subcontinent (Kalarippayattu):</strong> Kalarippayattu includes striking in its Angam (empty-hand) stage and incorporates marma-point knowledge consistent with high-stakes combat - the right conditions for the signature to appear. The specific biomechanical footwork detail was not captured in the sources gathered. Zarrilli&#x2019;s work on the Cuvatu footwork forms is the source that would resolve it. The tradition is a genuine candidate. The mechanics are not reachable through web search.</p><p><strong>Southeast Asian traditions (Muay Boran, Pencak Silat):</strong> Pencak Silat and its regional variants surfaced general overviews: UNESCO recognition, hundreds of distinct styles (aliran) across Indonesia and Malaysia, striking, grappling, weaponry. There is no single Silat footwork standard - heel posture and rear-foot emphasis vary between styles. Without style-specific biomechanics literature (Silek Minangkabau, Seni Gayong, or equivalent), the question cannot be answered at the tradition level.</p><p><strong>Pacific and Polynesian traditions (Hawaiian Lua, M&#x101;ori):</strong> Hawaiian Lua (Ku&#x2BB;ialua) is a genuine mortal-consequence tradition, practiced by the Koa warrior caste, restricted to the ali&#x2BB;i class, controlled so tightly that Kamehameha the Great limited it to his personal honor guard. It includes striking mechanics alongside grappling: Peku (kicks) and Ku&#x2BB;i (punches). The tradition is the right candidate. The problem is documentation. The tradition was suppressed after Western contact and came close to being lost entirely. The accessible sources are general overviews that do not reach the biomechanical specifics. M&#x101;ori traditions were not reached. The written record is too thin to go further.</p><p><strong>African and Pre-Columbian Americas:</strong> Dead end from web-accessible sources. Egyptian Beni Hasan tomb paintings (c. 2000 BC) document wrestling exclusively: over 400 scenes of holds, throws, and balance contest. Dambe (Nigeria) uses a wrapped-fist &quot;spear&quot; with a lead leg, but the sources did not surface the biomechanical detail of how propulsion operates. Engolo (Angola) has evasive footwork, not the offensive linear signature. Pre-Columbian traditions were not reached by the sources gathered.</p><p>What the cultural search shows, with the data available: the signature is strongly confirmed in the Greek and Western European fencing traditions, where the consequence structure was real and documented. The Greek antiquity evidence spans 490 BC through 90 AD and covers the full Hellenistic and Roman period; no separate search was needed for that era. The Japanese Kendo tradition confirms it independently. The Chinese and Norse traditions returned dead ends. The Arabic corpus contains an untranslated text that may be relevant. The other traditions are unresolved or require deeper specialist sources.</p><p>This is a partial result, not a complete one. I searched. The web-accessible evidence for some of these traditions simply does not surface the level of technical specificity I was looking for. The absence of evidence in the web search is not evidence of absence in the tradition.</p><hr><h3 id="the-science-closes-the-loop">The Science Closes the Loop</h3><p>What the historical practitioners found through accumulated physical experience, modern biomechanics has confirmed through instrumentation.</p><p>The stretch-shortening cycle: an eccentric pre-stretch of a muscle followed immediately by a concentric contraction produces significantly more force than the concentric contraction alone. Komi (2000) confirmed this in the <em>Journal of Biomechanics</em>.&#xB9;&#x2079; Bosco et al. (1982) established the contributions of both stored elastic energy and neural potentiation in the SSC.&#xB2;&#x2070; Seiberl et al. (2015) confirmed a third mechanism, residual force enhancement, as an additional SSC contributor.&#xB2;&#xB9;</p><p>The plantar arch and Achilles tendon as series elastic components: Ker et al. (1987) confirmed the plantar arch as a biological elastic spring in <em>Nature</em>.&#xB2;&#xB2; Fukashiro et al. (1995) established Achilles loading patterns in explosive lower-body movements.&#xB2;&#xB3; Hicks (1954) documented the windlass mechanism of the plantar fascia.&#xB2;&#x2074; These are the specific structures that the raised-heel position loads. When the heel is up and the weight is on the ball, the arch is compressed, the Achilles is stretched, and the system is ready to release.</p><p>The ground reaction force data from striking research closes the argument. Stewart et al. (2025) confirmed that rear-leg horizontal GRF is the primary driver of punch power.&#xB2;&#x2075; Guan et al. (2018) established that rear-leg horizontal GRF determines lunge speed in fencing.&#xB2;&#x2076; Mulloy et al. (2018) identified ankle plantarflexion velocity as the strongest single predictor of lunge speed.&#xB2;&#x2077; Chen et al. (2017) showed that forefoot loading on the rear leg, with the foot at 90 degrees to the line of drive, produces maximum power.&#xB2;&#x2078; Wang et al. (2024) confirmed that the rear foot center of pressure in the drive does not start from the heel.&#xB2;&#x2079;</p><p>Capoferro knew none of these terms. Nadi knew none of them. What they knew was what happened in their bodies when they did it right. The science did not invent the physics. It gave us the vocabulary to describe what the practitioners had already found.</p><hr><h3 id="synthesis">Synthesis</h3><p>I searched for the raised-heel, ball-of-foot propulsion signature in the historical record across ten traditions spanning twenty-five centuries.</p><p>I found it confirmed, at high confidence, in three: Greek antiquity (490 BC onward), Western fencing (1409&#x2013;1610), and Japanese Kendo (a tradition separate from the Western lineage). I found it recovered, against the orthodoxy of its era, by Aldo Nadi in 1943 and independently by Jack Dempsey in 1950. I found it destroyed, in the Western tradition, by the transition from mortal consequence to sport, documented precisely in the text of Angelo (1763) and the state doctrine of Parise (1884).</p><p>I found dead ends in the Norse wrestling tradition and the Chinese toe-strike tradition. I found open leads in the Arabic Mamluk corpus. I found incomplete results in the Indian and other traditions that require specialist sources to resolve.</p><p>The HAMA translation will resolve the Arabic question when it becomes available. Kalarippayattu, Hawaiian Lua, and the Southeast Asian traditions each require specialist sources that web search cannot reach. This is an active project, not a final word.</p><p>The pattern across the confirmed cases is consistent: the signature appears under genuine mortal consequence and disappears when consequence is removed by sport or institutionalization. This is not coincidence. It is the selection pressure that the physics requires to be discovered.</p><p>The mechanism was not transmitted through a chain of masters. No Greek boxer taught Capoferro. Capoferro did not teach Nadi. Nadi did not teach Dempsey. The Japanese kenjutsu tradition had no contact with the Italian rapier schools. Each found the same configuration by submitting the body to the same discipline under the same conditions: the study of how to drive force horizontally through space toward a target that can hurt you back.</p><p>The body discovers what works. The raised heel cocks the spring. The ball of the foot releases it. The oblique rear leg converts elastic potential into horizontal drive. The floor does the work.</p><hr><h3 id="notes">Notes</h3><p>&#xB9; Ridolfo Capo Ferro da Cagli, <em>Gran Simulacro dell&apos;Arte e dell&apos;Uso della Scherma</em> (Siena: Silvestro Marchetti, 1610), Chapter IX. English translations: Jared Kirby, <em>Italian Rapier Combat</em> (London: Greenhill Books, 2004); Tom Leoni, <em>Ridolfo Capoferro&apos;s The Art and Practice of Fencing</em> (Wheaton: Freelance Academy Press, 2011).</p><p>&#xB2; Capoferro, <em>Gran Simulacro</em>, pp. 19&#x2013;20 (Kirby translation).</p><p>&#xB3; The lunge plates engraved by Rafael Schiamirossi for Capoferro&apos;s <em>Gran Simulacro</em> are reproduced in full in Kirby, <em>Italian Rapier Combat</em>. The original is held at the Getty Research Institute and digitized at archive.org/details/gri_33125009485448.</p><p>&#x2074; Salvator Fabris, <em>De lo Schermo overo Scienza d&apos;Arme</em> (Copenhagen: Henrico Waltkirch, 1606). English translation: Tommaso Leoni, <em>The Art of Dueling: Salvator Fabris&apos; Rapier Fencing Treatise of 1606</em> (Union City: Chivalry Bookshelf, 2005).</p><p>&#x2075; Fabris, <em>De lo Schermo</em>, Chapter 5 (Leoni translation).</p><p>&#x2076; Nicoletto Giganti, <em>Scola overo Teatro</em> (Venice, 1606). English translation: Tom Leoni, <em>Venetian Rapier: Nicoletto Giganti&apos;s 1606 Rapier Fencing Curriculum</em> (Wheaton: Freelance Academy Press, 2010).</p><p>&#x2077; Giganti, <em>Scola overo Teatro</em>, lunge description (Leoni translation).</p><p>&#x2078; Domenico Angelo, <em>L&apos;Ecole des Armes</em> (London, 1763). Quoted via traditionalfencing.org/2017/12/11/domenico-angelos-lunge/.</p><p>&#x2079; Masaniello Parise, <em>Trattato teorico-pratico della spada di scherma e di bastone</em> (Rome: Voghera, 1884). Adopted as official Italian Ministry of War syllabus; codified as doctrine for the Scuola Magistrale di Scherma. Specific text on heel position requires library verification of the primary source.</p><p>&#xB9;&#x2070; Daniel Mendoza, <em>The Art of Boxing</em> (London, 1789), First Principle. Full text at archive.org identifier: bim_eighteenth-century_the-art-of-boxing-with-_mendoza-daniel_1789. Also reprinted in <em>The Modern Art of Boxing</em> (London, 1789), which includes Mendoza&apos;s six lessons in full.</p><p>&#xB9;&#xB9; Mendoza, <em>The Art of Boxing</em>, Second Principle.</p><p>&#xB9;&#xB2; Aldo Nadi, <em>On Fencing</em> (New York: G.P. Putnam&apos;s Sons, 1943; repr. Laureate Press, 1994). Quoted via Nadi School of Fencing curriculum, Winston-Salem Fencing Club.</p><p>&#xB9;&#xB3; Nadi, <em>On Fencing</em>, ibid.</p><p>&#xB9;&#x2074; Jack Dempsey, <em>Championship Fighting: Explosive Punching and Aggressive Defense</em> (Englewood Cliffs: Prentice-Hall, 1950).</p><p>&#xB9;&#x2075; Dempsey, <em>Championship Fighting</em>. Full text available at archive.org.</p><p>&#xB9;&#x2076; All Japan Kendo Federation standard pedagogy on <em>kamae</em> (guard) and <em>fumikomi</em> (driving footstrike). Confirmed via Kamei Toru (2024), <em>Kendo Jidai International</em>. AJKF standards accessible at kendo-fik.org.</p><p>&#xB9;&#x2077; Koshida S., Matsuda T., Kawada K. (2011). &quot;Lower extremity biomechanics during kendo strike-thrust motion.&quot; <em>Journal of Sports Medicine and Physical Fitness</em>, 51(3):357&#x2013;365. PMID: 21904273.</p><p>&#xB9;&#x2078; HAMA Association, &quot;The Mamluk Project.&quot; hamaassociation.wordpress.com/research/the-mamluk-project/. The <em>Kit&#x101;b al-makhz&#x16B;n j&#x101;mi&#x2BB; al-fun&#x16B;n</em> (1470), attributed to Ibn Akhi Hizam, is identified as containing hand-to-hand combat methods. Translation status: in progress as of 2026.</p><p>&#xB9;&#x2079; Komi P.V. (2000). &quot;Stretch-shortening cycle: a powerful model to study normal and fatigued muscle.&quot; <em>Journal of Biomechanics</em>, 33(10):1197&#x2013;1206.</p><p>&#xB2;&#x2070; Bosco C., Viitasalo J.T., Komi P.V., Luhtanen P. (1982). &quot;Combined effect of elastic energy and myoelectrical potentiation during stretch-shortening cycle exercise.&quot; <em>Acta Physiologica Scandinavica</em>, 114(4):557&#x2013;565.</p><p>&#xB2;&#xB9; Seiberl W., Power G.A., Hahn D. (2015). &quot;Residual force enhancement in humans: Current evidence and unresolved issues.&quot; <em>Journal of Electromyography and Kinesiology</em>, 25(4):571&#x2013;580.</p><p>&#xB2;&#xB2; Ker R.F., Bennett M.B., Bibby S.R., Kester R.C., Alexander R.M. (1987). &quot;The spring in the arch of the human foot.&quot; <em>Nature</em>, 325:147&#x2013;149.</p><p>&#xB2;&#xB3; Fukashiro S., Komi P.V., J&#xE4;rvinen M., Miyashita M. (1995). &quot;In vivo Achilles tendon loading during jumping in humans.&quot; <em>European Journal of Applied Physiology</em>, 71:453&#x2013;458.</p><p>&#xB2;&#x2074; Hicks J.H. (1954). &quot;The mechanics of the foot, II: The plantar aponeurosis and the arch.&quot; <em>Journal of Anatomy</em>, 88(1):25&#x2013;30.</p><p>&#xB2;&#x2075; Stewart A., Uthoff A., Hartmann H., Kipp K. (2025). &quot;Biomechanical predictors of punching performance in boxing.&quot; <em>Bioengineering</em>, 12(12):1355.</p><p>&#xB2;&#x2076; Guan Y., Bredin S.S.D., Taunton J., Jiang Q., Wu Z., Warburton D.E.R. (2018). &quot;Biomechanical analysis of the lunge in fencing.&quot; <em>European Journal of Sport Science</em>, 18(2):201&#x2013;210.</p><p>&#xB2;&#x2077; Mulloy F., McMahon J.J., Shiang T.Y., Comfort P. (2018). &quot;Associations between maximal strength, speed-strength and technique measures with competitive performance in fencing.&quot; <em>International Biomechanics</em>, 5(1):9&#x2013;18.</p><p>&#xB2;&#x2078; Chen T.L., Wong D.W., Wang Y., Sze L.K., Lam W.K., Zhang M. (2017). &quot;Biomechanics of fencing sport: a scoping review.&quot; <em>PLoS ONE</em>, 12(2):e0171578.</p><p>&#xB2;&#x2079; Wang Y., Gu Y., Mao M., Ruan G., Ding Z., Fekete G., Baker J.S. (2024). &quot;Ground reaction force analysis in fencing: A comparative study between elite and recreational fencers.&quot; <em>Frontiers in Bioengineering and Biotechnology</em>, 12:1276025.</p><p>&#xB3;&#x2070; Ted Wong (1937&#x2013;2010) trained personally with Bruce Lee beginning in 1967 and was among a handful of practitioners to receive a rank certificate from Lee in Jun Fan Jeet Kune Do. Wong spent the decades after Lee&apos;s death in 1973 preserving and transmitting the complete technical system. The TWJKD rank structure places Level 6 at the equivalent of 6th dan. Wong was inducted into <em>Black Belt</em> magazine&apos;s Hall of Fame as Man of the Year in 2006. He co-authored <em>Jeet Kune Do: A Fighter&apos;s Journey</em> with John Little.</p><hr><p><em>If this kind of work is useful to you, subscribe.<br>One email when something new publishes. No noise.</em></p><p><a href="#/portal/signup">Subscribe</a></p>]]></content:encoded></item><item><title><![CDATA[The Straight Lead Punch: Force, Structure, and Timing]]></title><description><![CDATA[The straight lead punch looks simple. One hand. One line. Direct. Simplicity without understanding is ignorance. What appears as a single motion is a chain of precise mechanical events, each one depending on the one before it.]]></description><link>https://www.tomharveytraining.com/the-straight-lead-punch-force-structure-and-timing/</link><guid isPermaLink="false">6a1dec3804914400016f8519</guid><category><![CDATA[The Workbench]]></category><category><![CDATA[Martial Arts]]></category><category><![CDATA[Jeet Kune Do]]></category><category><![CDATA[JKD]]></category><category><![CDATA[TWJKD]]></category><category><![CDATA[THTJKD]]></category><dc:creator><![CDATA[Thomas Harvey]]></dc:creator><pubDate>Sat, 06 Jun 2026 23:04:44 GMT</pubDate><media:content url="https://storage.ghost.io/c/c4/dc/c4dcef1a-ac8f-4b6b-9334-63e32b1fa558/content/images/2026/06/GM_SLP_Bio_Physics_Revised.png" medium="image"/><content:encoded><![CDATA[<h1 id="the-straight-lead-punch-force-structure-and-timing">The Straight Lead Punch: Force, Structure, and Timing</h1><hr><img src="https://storage.ghost.io/c/c4/dc/c4dcef1a-ac8f-4b6b-9334-63e32b1fa558/content/images/2026/06/GM_SLP_Bio_Physics_Revised.png" alt="The Straight Lead Punch: Force, Structure, and Timing"><p>The straight lead looks simple. One hand. One line. Direct.</p><p>Simplicity without understanding is ignorance.</p><hr><p>What appears as a single motion is a chain of precise mechanical events, each one depending on the one before it. Remove any link, mistime any element, and the chain does not merely weaken, it collapses. A practitioner who has never studied the mechanism will train the appearance of the technique. They will perfect a shape. That shape will never carry the structure it is supposed to carry.</p><p>The knot cannot be untangled by someone who cannot see the knot.</p><hr><h3 id="what-it-is">What It Is</h3><p>This is not a boxing jab.</p><p>A jab borrows speed from a shoulder snap and returns without committing. It touches the target. The straight lead is a committed collision. It converts your entire mass into a projectile using the same mechanical principle as a fencer&apos;s lunge. The difference is not stylistic. It is structural. The power source is different, the chain is different, and the result is different.</p><p>Power does not live in the fist. It originates in the earth.</p><hr><h3 id="the-physics-of-a-collision">The Physics of a Collision</h3><p>Two equations govern what happens when your fist meets a target.</p><h4 id="impulse-and-momentum-transfer">Impulse and Momentum Transfer</h4><p>Combat physics focuses on impulse: the change in momentum over time.</p><p>$$\text{Impulse} = F \cdot \Delta t = m \cdot \Delta v$$</p><p>$$\text{F is Force.}$$<br>$$\Delta t \text{ is time of contact.}$$<br>$$\text{m is mass.}$$<br>$$\Delta v \text{ is change in velocity.}$$</p><p>Three variables increase the force transferred.</p><p><strong>More mass behind the punch.</strong> Not just the arm. The entire body, aligned and moving.</p><p><strong>Higher velocity at contact.</strong> Speed of the weapon at the moment of impact.</p><p><strong>Shorter contact time.</strong> Snap the punch at the end via the body. Driving through the target extends contact time and bleeds force. A snap concentrates that same force into a shorter window, spiking peak impact. The snap also uses that collision impulse to initiate the recovery.</p><p>When you force a punch, you abandon structure. Muscle tension acts as a restrictor valve. It freezes the joints that must function as fluid conduits for the energy. You overextend. You create the interception angle your opponent needs. The straight lead does not increase force through effort. It removes resistance.</p><h4 id="kinetic-energy">Kinetic Energy</h4><p>$$KE = \frac{1}{2}mv^2$$</p><p>Velocity is squared. Doubling the speed of your attack quadruples its kinetic energy. This is why speed is prioritized over strength.</p><p>The straight lead does not force a choice between speed and mass. The mechanism increases both simultaneously.</p><hr><h3 id="the-biomechanical-mechanism-the-kinetic-chain">The Biomechanical Mechanism: The Kinetic Chain</h3><p>The straight lead is a sequential maximization of those equations. Every link in the chain either adds to the energy, passes it cleanly, or leaks it. There is no neutral. A joint that is not contributing is taking.</p><h4 id="the-foundation-on-guard-geometry">The Foundation: On-Guard Geometry</h4><p>The stance is not neutral. It is pre-loaded with geometry.</p><p>The lead big toe aligns with the center of the oblique-turned rear foot, halfway between rear heel and rear ball. That line is the power line. The three contact points on the floor form a triangle: rear heel, rear ball of foot, lead big toe. The power line bisects it. Travel along that line and the kinetic chain is intact. Deviate and it isn&apos;t.</p><p>A second triangle runs from the bottom of the sternum, down through both legs, to the feet and into the ground. That triangle is the boundary of the center of gravity. At every point in the motion, the center of gravity must remain within it. When the rear foot fires and the lead foot lifts, the base reduces from two feet to one. The physics does not give you slack.</p><p>The arm is found, not forced. To find it, let the arm  hang naturally at your side. Bring it forward to the power line. That is the position. The shoulder stays where it naturally sits. The fist strikes with the bottom three knuckles. The power arrives through the chain. In an actual attack the arm is a piston. It drives from its guard position straight to the point of impact and snaps at the end. The entire chain concentrates at that single point.</p><h4 id="link-1-the-trigger">Link 1: The Trigger</h4><p>The hand moves first.</p><p>This is tactical physics. If the body shifts before the hand moves, the shift is visible. The opponent reads the telegraph and the strike is finished before it arrives. Economy of motion is not a style. It is a structural requirement.</p><p>The lead hand fires. A fraction of a second later, the structure follows to back it up.</p><h4 id="link-2-ground-initiation-and-the-stretch-shortening-cycle">Link 2: Ground Initiation and the Stretch-Shortening Cycle</h4><p>Physics begins at the rear foot.</p><p>In the straight lead stance, the rear heel is elevated. This  is pre-loading. With the heel raised, the gastrocnemius and soleus are placed under eccentric load. The Achilles tendon and the plantar fascia store elastic potential energy as series elastic components, a loaded spring awaiting release. This is the eccentric phase of the stretch-shortening cycle.</p><p>The stretch-shortening cycle is the body&apos;s most efficient force production mechanism. An eccentric pre-load followed immediately by concentric contraction produces significantly more force than a purely concentric contraction from rest. The precise position of the rear heel is something you can feel. It is the point of maximum elastic potential energy immediately preceding the concentric release.</p><p>When the rear leg drives against the floor, two things happen simultaneously. Newton&apos;s Third Law produces a ground reaction force equal and opposite to the push: the earth pushes back. The stretch-shortening cycle releases its stored elastic energy into that drive. The result is high-force, high-velocity horizontal acceleration of the center of mass.</p><h4 id="link-3-the-three-energies-and-curvilinear-flow">Link 3: The Three Energies and Curvilinear Flow</h4><p>The straight lead requires the precise balance of three intersecting forces. An error in any one degrades the entire chain.</p><p><strong>Horizontal Energy:</strong> The linear drive of the center of mass forward. This is the dominant vector.</p><p><strong>Vertical Energy:</strong> The settling of body weight downward towards the floor as the fist lands. This is what makes the strike heavy at contact rather than skating across the surface.</p><p><strong>Transverse Energy:</strong> The rotational torque generated across the core.</p><p>Within this architecture, every joint is a node. A node either amplifies force, passes it cleanly, or leaks it. The transverse energy crosses the body through the posterior oblique sling (the muscular system connecting the latissimus dorsi on one side diagonally to the gluteus maximus on the opposite side through the thoracolumbar fascia), sequentially activating the shoulder, the elbow, and the lead hand.</p><p>During this rotation the hips and the shoulders move as a single unit. They do not rotate independently. The core bracing is what locks them together. Without it, energy bleeds between hips and shoulders before it reaches the fist.</p><p>When all three energies are in correct balance, force travels in a curvilinear flow. An unbroken conduit from the rear foot to the point of impact.</p><p>The balance is precise. If horizontal momentum outpaces vertical root, structural integrity fails and foot drag occurs. If vertical energy dominates, the trajectory falls short and the footwork hops rather than penetrates. If transverse rotation exceeds the horizontal drive, the lead hand arcs laterally instead of traveling straight. Any imbalance immediately degrades both velocity and structural power.</p><h4 id="link-4-the-collision-intra-abdominal-pressure-and-effective-mass">Link 4: The Collision, Intra-Abdominal Pressure, and Effective Mass</h4><p>The hand lands just before the lead foot. The sequence is 1-2-3: the lead hand lands, the lead foot lands, the rear foot comes back up to restore the original foot spacing. The stance returns to where it started. This is done with intention not laziness. </p><p>By making contact before the weight fully settles, forward momentum carries the strike into the target rather than dispersing into the ground.</p><p>The structure must become solid before impact.</p><p>The diaphragm contracts downward, the pelvic floor contracts upward, the transverse abdominis and multifidus co-contract circumferentially around the spine. This is multidimensional dynamic core bracing, a pressurized cylinder that converts the spine from a flexible, energy-dissipating column into a rigid structural pillar.</p><p>The brace must be initiated before the transverse phase, not at the moment of impact. The posterior oblique sling transfers rotational force against the core. If the core is soft during that transfer, force dissipates at the center of the chain. A pressurized cylinder means the rotational energy transfers without leakage. A braced core during the wave does not slow the wave. It amplifies it. Brace too late and the cylinder forms for nothing. The energy has already leaked. Brace too soon and you create drag.</p><p>This cannot be approximated by tensing the stomach. It is a coordinated, reflexive co-contraction trained through specific and deliberate practice, maintained while the body is in full dynamic motion. That is a different demand than bracing on a stable surface. It must be trained as such.</p><p>When this bracing is present and the kinetic chain is fully aligned, effective mass is engaged. In an unbraced, unaligned state, the structure breaks at its weakest links. With the chain aligned and the core cylinder pressurized, the entire moving mass of the body transfers into the target. You are not hitting with the fist. You are hitting with everything behind it.</p><p>A strike without mass is motion. Speed is the symptom of perfect timing meeting zero resistance.</p><h4 id="link-5-the-landing">Link 5: The Landing</h4><p>How the lead foot lands after impact determines range, recovery, and what follows.</p><p><strong>Long Range (The Fencer):</strong> The foot lands heel first, rolling forward. This maximizes forward travel and structural penetration. Recovery is slower but penetration and range is greater.</p><p><strong>Short Range (The Brakes):</strong> The lead foot lands on the ball. Forward momentum stops immediately. This is precision stopping for no-man&apos;s-land, where continuous forward commitment creates exposure. The instant halt allows immediate direction change. It&#x2019;s a trade-off, shorter range but faster direction change. </p><p>The choice is dictated by distance at contact and what must come next.</p><hr><h3 id="the-development">The Development</h3><p>Understanding the mechanism does not mean you have the technique.</p><p>The correct neurological firing order must become automatic. This cannot be rushed. The nervous system requires deliberate repetition, progressive load, and time. Under pressure, the pattern you encoded is the pattern you get.</p><p>Core bracing under dynamic motion is a different skill from bracing on a stable surface. Generating intra-abdominal pressure reflexively while the body is in full flight must be trained as such.</p><p>Compensations accumulated over years of life and prior training surface exactly where precision is required. The technique finds every one of them.</p><p>Then there is the time. Hours upon hours. Years upon years.</p><p>The process is not complex. It is daily progress, self-honesty, and the removal of everything that does not belong. You untangle the knot. You do not cut it. Cutting it is faster, and the result is not what you came for.</p><p>When the technique arrives, it flows. One hand. One line. Direct.</p><p>That simplicity was earned.</p><hr><p>There is no shortcut through the knot.</p><p>The technique is correct. It has always been correct. It works when the body stops interfering with the physics. Every hour in the studio, every correction, every repetition is not complexity being added. It is interference being removed.</p><p>The jab asks the arm to be fast.</p><p>The straight lead asks everything to be correct.</p><p>When everything is correct, speed is the proof.</p><hr><p>Understanding does not replace repetition.</p><p>Go train. </p><hr><p><em>Part 2 of this series traces the same biomechanical signature across ten martial traditions spanning twenty-five centuries.</em></p><div class="kg-card kg-button-card kg-align-center"><a href="https://www.tomharveytraining.com/the-straight-lead-punch-lineage" class="kg-btn kg-btn-accent">Read Part 2</a></div><hr><h3 id="the-jab-vs-the-straight-lead">The Jab vs. The Straight Lead</h3>
<!--kg-card-begin: html-->
<table>
<thead>
<tr>
<th style="text-align: left;">Feature</th>
<th style="text-align: left;">Static Boxing Jab</th>
<th style="text-align: left;">The Straight Lead</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: left;"><strong>Dominant Force</strong></td>
<td style="text-align: left;">Rotational Torque</td>
<td style="text-align: left;">Convergence of Three Energies</td>
</tr>
<tr>
<td style="text-align: left;"><strong>The Trigger</strong></td>
<td style="text-align: left;">Weight shift or shoulder rotation</td>
<td style="text-align: left;">The hand moves first</td>
</tr>
<tr>
<td style="text-align: left;"><strong>Ground Mechanics</strong></td>
<td style="text-align: left;">Rotational push</td>
<td style="text-align: left;">Stretch-shortening cycle, massive linear drive</td>
</tr>
<tr>
<td style="text-align: left;"><strong>Energy Transfer</strong></td>
<td style="text-align: left;">Core rotation</td>
<td style="text-align: left;">Posterior oblique sling and curvilinear flow</td>
</tr>
<tr>
<td style="text-align: left;"><strong>Impact Timing</strong></td>
<td style="text-align: left;">Step and hit simultaneously</td>
<td style="text-align: left;">Hand lands just before the lead foot</td>
</tr>
<tr>
<td style="text-align: left;"><strong>Core at Impact</strong></td>
<td style="text-align: left;">Partial bracing</td>
<td style="text-align: left;">Intra-abdominal pressure, full structural rigidity</td>
</tr>
<tr>
<td style="text-align: left;"><strong>Effective Mass</strong></td>
<td style="text-align: left;">Arm plus partial core shift</td>
<td style="text-align: left;">Full body mass at contact</td>
</tr>
<tr>
<td style="text-align: left;"><strong>Resulting Speed</strong></td>
<td style="text-align: left;">Forced muscular velocity</td>
<td style="text-align: left;">Perfect timing meeting zero resistance</td>
</tr>
</tbody>
</table>
<!--kg-card-end: html-->
<hr><p><em>If this kind of work is useful to you, subscribe.<br>One email when something new publishes. No noise.</em></p><p><a href="#/portal/signup">Subscribe</a></p>]]></content:encoded></item><item><title><![CDATA[Warrior's Zen]]></title><description><![CDATA[She walked up and I didn't know if it had been minutes or hours.]]></description><link>https://www.tomharveytraining.com/warriors-zen/</link><guid isPermaLink="false">6a241a0dc7049800013b6906</guid><category><![CDATA[Music]]></category><category><![CDATA[Ósynilegr Handr]]></category><dc:creator><![CDATA[Thomas Harvey]]></dc:creator><pubDate>Sat, 06 Jun 2026 13:04:50 GMT</pubDate><media:content url="https://storage.ghost.io/c/c4/dc/c4dcef1a-ac8f-4b6b-9334-63e32b1fa558/content/images/2026/06/Warrior_Zen2v2_square.jpg" medium="image"/><content:encoded><![CDATA[<h1 id="warriors-zen">Warrior&apos;s Zen</h1><img src="https://storage.ghost.io/c/c4/dc/c4dcef1a-ac8f-4b6b-9334-63e32b1fa558/content/images/2026/06/Warrior_Zen2v2_square.jpg" alt="Warrior&apos;s Zen"><p>She walked up and I didn&apos;t know if it had been minutes or hours.</p><p>My cone of focus was so absolute that the radar built by years in the studio didn&apos;t register her. She knows to hold her ground in that moment. She stands there, watching. I don&apos;t know how long she&apos;s been there.</p><p>Time didn&apos;t slow. It disappeared entirely. The world outside stopped existing. Not blocked out. Not ignored. Gone.</p><p>The Greeks called it Ataraxia. The Taoists called it Wu Wei. The martial artists call it Mushin.</p><p>I call it Tuesday at the lathe.</p><hr><p>The hands know things the mind hasn&apos;t processed yet. My grandfather was a craftsman. My father had a quiet command in everything he did. Both gone before I was sixteen. Both present every time something older than memory decides how to move.</p><p>The song doesn&apos;t explain that. It doesn&apos;t need to.</p><p><em>Something older in the marrow is deciding how to move.</em></p><p>That line didn&apos;t get written. It arrived.</p><hr><p>Mushin isn&apos;t concentration. It isn&apos;t will or force. It&apos;s what arrives when everything else has run its course. The thinking drops away. The lathe keeps its tempo. The steel finds the groove.</p><p>And behind you, someone holds their ground. Their own kind of stillness. Their own energy in the room. Not watching from outside. Present.</p><hr><p>Track 05. &#xD3;synilegr Handr.</p><hr><p>The steel finds the groove.</p><p>Something older in the marrow<br>is deciding how to move.</p><p>She is in the doorway.<br>I don&apos;t know how long.</p><p>My grandfather&apos;s hands.<br>My father&apos;s quiet command.<br>Both gone before sixteen.<br>Both here.</p><p>The lathe keeps its tempo.<br>The steel finds the groove.</p><hr><figure class="kg-card kg-bookmark-card"><a class="kg-bookmark-container" href="https://distrokid.com/hyperfollow/tomharvey1/warrios-zen/?ref=tomharveytraining.com"><div class="kg-bookmark-content"><div class="kg-bookmark-title">Warriors Zen by Tom Harvey</div><div class="kg-bookmark-description">Stream and Save Warriors Zen - Distributed by DistroKid</div><div class="kg-bookmark-metadata"><img class="kg-bookmark-icon" src="https://storage.ghost.io/c/c4/dc/c4dcef1a-ac8f-4b6b-9334-63e32b1fa558/content/images/icon/favicon-b98dc1b7-7d63-4598-8e41-c02145ff4f22.ico" alt="Warrior&apos;s Zen"><span class="kg-bookmark-author">DistroKid</span></div></div><div class="kg-bookmark-thumbnail"><img src="https://storage.ghost.io/c/c4/dc/c4dcef1a-ac8f-4b6b-9334-63e32b1fa558/content/images/thumbnail/http-3A-2F-2Fgather.fandalism.com-2F12587764--629204A6-365B-48DD-BC0D4E929182B446--0--472717--WarriorZen2v2-24747e42-bb22-48d7-853c-c0c2a2ad0871.jpeg" alt="Warrior&apos;s Zen" onerror="this.style.display = &apos;none&apos;"></div></a></figure><figure class="kg-card kg-embed-card"><iframe style="border-radius:12px" src="https://open.spotify.com/embed/track/58FIlNKCSMvf6mtDhzOvsj?utm_source=generator" width="100%" height="352" frameborder="0" allowfullscreen allow="autoplay; clipboard-write; encrypted-media; fullscreen; picture-in-picture" loading="lazy"></iframe></figure><figure class="kg-card kg-embed-card"><iframe width="100%" height="315" src="https://www.youtube.com/embed/nfu8RA57x-I" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></figure>]]></content:encoded></item><item><title><![CDATA[Corrected Local LLM Network Test: The Right Tool (Part 2)]]></title><description><![CDATA[Run 2 of the local LLM network test. Correcting token budgets and timeouts to see what six AI models can actually do when test design gets out of the way.]]></description><link>https://www.tomharveytraining.com/the-right-tool-part-2-corrected-llm-network-test/</link><guid isPermaLink="false">6a122f8335c79200013e9593</guid><category><![CDATA[The Right Tool]]></category><category><![CDATA[local LLM]]></category><category><![CDATA[homelab AI]]></category><category><![CDATA[benchmark]]></category><category><![CDATA[Ollama]]></category><category><![CDATA[containerlab]]></category><category><![CDATA[SR Linux]]></category><category><![CDATA[network engineering]]></category><category><![CDATA[THT Systems]]></category><category><![CDATA[The Intelligent Network]]></category><dc:creator><![CDATA[Thomas Harvey]]></dc:creator><pubDate>Fri, 05 Jun 2026 12:21:57 GMT</pubDate><media:content url="https://storage.ghost.io/c/c4/dc/c4dcef1a-ac8f-4b6b-9334-63e32b1fa558/content/images/2026/05/Part2.jpg" medium="image"/><content:encoded><![CDATA[<hr><h2 id="the-fair-fight">The Fair Fight</h2><hr><img src="https://storage.ghost.io/c/c4/dc/c4dcef1a-ac8f-4b6b-9334-63e32b1fa558/content/images/2026/05/Part2.jpg" alt="Corrected Local LLM Network Test: The Right Tool (Part 2)"><p>Part 1 ended with three things I knew I&apos;d gotten wrong.</p><p>First: the token budgets for T4 and T5 were calibrated against local model verbosity. Haiku writes more thoroughly. It hit the ceiling mid-component, got cut off, and failed both tasks. The scores reflected test design, not model capability.</p><p>Second: the 300-second timeout wasn&apos;t enough for Gemma 3 12B to complete T3 at 6 tok/s on CPU. It timed out and then generated prose. I never found out if it could actually do the task.</p><p>Third: I discovered mid-run that every model was running on CPU. The T600 was idle. The CUDA runtime wasn&apos;t installed. The hardware characterization I built the test around was VRAM-resident versus CPU-spill performance. It was measuring nothing I intended to measure.</p><p>Run 2 corrects the first two. The third remains. Here&apos;s what changed and what I found.</p><hr><h3 id="what-i-changed">What I Changed</h3><p>Three adjustments. Nothing else.</p><p><strong>Token budgets:</strong> T4 raised from 700 to 1000 tokens. T5 raised from 600 to 900 tokens. Same prompts, same models, same tasks. Just more room to finish.</p><p><strong>Timeout:</strong> Gemma 3 12B&apos;s T3 timeout raised from 300 to 420 seconds. At 5&#x2013;6 tok/s, a 1400-token topology needs 230+ seconds minimum. 300 seconds wasn&apos;t fair. 420 gives it full headroom.</p><p><strong>Hardware monitoring:</strong> Every task, every model. CPU load, per-core frequency, system RAM, GPU utilization, VRAM, thermals, clock speed. Polling at 1-second intervals throughout.</p><p>I did not change the prompts. I did not change the scoring rubric. I did not give any model a hint. Same test, corrected design.</p><hr><h3 id="what-the-hardware-monitor-confirmed">What the Hardware Monitor Confirmed</h3><p>The monitor answered the GPU question immediately.</p><pre><code class="language-text">nvidia-smi: memory.used = 5 MB  |  utilization.gpu = 0%
ollama ps:  phi3.5:latest  3.7 GB  100% CPU
</code></pre><p>No change from Run 1. The T600 was idle throughout the entire run. Every tok/s figure in this document is i7-12700H CPU inference on 20 threads.</p><p>What the monitor added: throughput variance between runs is real. Qwen T1 dropped from ~10 tok/s (Run 1) to 3.4 tok/s (Run 2). Same model, same task, same hardware. A 3&#xD7; variance between runs. That&apos;s what CPU-bound inference under an OS scheduler looks like. No GPU compute means no consistency.</p><p>Any throughput figure from these runs should be read as an order-of-magnitude estimate, not a specification.</p><hr><h3 id="task-by-task">Task by Task</h3><p><strong>T1: Breach Detection</strong></p><p>This task has a clear right answer: there&apos;s a breach in the data. The model either finds it or it doesn&apos;t.</p>
<!--kg-card-begin: html-->
<table>
<thead>
<tr>
<th><strong>Model</strong></th>
<th><strong>Run 2 Finding</strong></th>
<th><strong>Correct?</strong></th>
</tr>
</thead>
<tbody>
<tr>
<td>Phi-3.5 Mini</td>
<td>No breaches detected</td>
<td>No</td>
</tr>
<tr>
<td>Gemma 3 4B</td>
<td>Threshold exceeded</td>
<td>Yes</td>
</tr>
<tr>
<td>Qwen 2.5 Coder 7B</td>
<td>Breach status: active</td>
<td>Yes</td>
</tr>
<tr>
<td>Llama 3.1 8B</td>
<td>Exceeded at several intervals</td>
<td>Yes</td>
</tr>
<tr>
<td>Gemma 3 12B</td>
<td>Consistently breaches 5.0ms</td>
<td>Yes</td>
</tr>
<tr>
<td>Claude Haiku 4.5</td>
<td>No breach detected</td>
<td>No</td>
</tr>
</tbody>
</table>
<!--kg-card-end: html-->
<p>Two models got it wrong: Phi-3.5 and Haiku. Phi-3.5 was wrong in Run 1 as well. Consistent. Haiku being wrong here is new.</p><p>Haiku&apos;s response: <em>&quot;No breach: all 30 samples remain below the 5.0ms threshold, with latency consistently 2&#xD7; the acceptable limit.&quot;</em> That sentence contradicts itself. Four other models independently identified the breach from the same table. This is a non-determinism story. Haiku&apos;s response to the same prompt isn&apos;t guaranteed to be the same across runs. It is data that sits in the record.</p><p>The API baseline missed T1 in the corrected run. That doesn&apos;t disqualify it. It does mean breach detection accuracy isn&apos;t something you can assume from any model without verification.</p><p><strong>T3: Topology Generation</strong></p><p>The gate task. This is where Run 2 produced the most interesting result.</p><p>In Run 1, Gemma 3 12B timed out at 300 seconds and produced prose. Interpreted as generation refusal.</p><p>In Run 2 with 420 seconds, it completed. And the output was semantically correct: 13 nodes, 8 links, right naming, right images. But it used the wrong containerlab schema. It used <code>kind: topology</code> at the top level instead of the required <code>topology:</code> wrapper, and a non-standard links format. The auto-checks failed. The topology doesn&apos;t deploy. But the failure mode shifted from generation refusal to schema deviation.</p><p>The model had the knowledge. The timeout was the blocker. With a more explicit schema prompt, this becomes a different conversation.</p><p>Everything else in T3 held exactly as in Run 1. Qwen and Haiku passed cleanly. Gemma 4B and Llama 8B produced valid YAML with zero nodes. Phi-3.5 produced invalid YAML.</p><p><strong>T4: React Component</strong></p><p>Budget fix worked exactly as expected. Haiku T4 passes in Run 2. Clean component, correct <code>export default</code>, 708 tokens. Exactly what I expected once the ceiling was removed.</p><p>Phi-3.5 still fails. It is not a budget issue. It uses named exports (<code>export const NodeStatus</code>) instead of default exports. The check requires <code>export default</code>. That&apos;s a prompt sensitivity question, not a capability gap.</p><p><strong>T5: Python gNMI Poller</strong></p><p>This is where the test design problem persists.</p><p>Run 1: 600-token budget. Haiku truncated at line 61. Syntax error: unclosed parenthesis.</p><p>Run 2: 900-token budget. Haiku truncated at line 79. Syntax error: unterminated string literal.</p><p>Each run raises the budget. Each run hits the ceiling before the function closes.</p><figure class="kg-card kg-image-card"><img src="https://storage.ghost.io/c/c4/dc/c4dcef1a-ac8f-4b6b-9334-63e32b1fa558/content/images/2026/05/07_haiku_t5_token_ceiling-1.png" class="kg-image" alt="Corrected Local LLM Network Test: The Right Tool (Part 2)" loading="lazy" width="1487" height="803" srcset="https://storage.ghost.io/c/c4/dc/c4dcef1a-ac8f-4b6b-9334-63e32b1fa558/content/images/size/w600/2026/05/07_haiku_t5_token_ceiling-1.png 600w, https://storage.ghost.io/c/c4/dc/c4dcef1a-ac8f-4b6b-9334-63e32b1fa558/content/images/size/w1000/2026/05/07_haiku_t5_token_ceiling-1.png 1000w, https://storage.ghost.io/c/c4/dc/c4dcef1a-ac8f-4b6b-9334-63e32b1fa558/content/images/2026/05/07_haiku_t5_token_ceiling-1.png 1487w" sizes="(min-width: 720px) 720px"></figure><p>The pattern is clear: Haiku generates complete, calibration-quality code with full docstrings, error handling, logging, and retry logic. It writes code the way a senior engineer writes code. Thoroughly. The budget kept cutting it off. Every local model completed T5 within budget because they write shorter, leaner code. Some of those scripts are functional. None of them include the depth Haiku was building toward when I stopped it.</p><p><strong>Verification run (post-publication).</strong> 4096-token budget, same prompt, same model. Result: 1,386 tokens, <code>stop_reason=end_turn</code>, 116 lines, syntax PASS. The ceiling was at 1,386. Run 1 stopped at 43% of completion. Run 2 stopped at 65%. The function Haiku was building is correct, complete, and more thorough than any local model produced within budget.</p><p>One additional finding from the verification run: Haiku drafted an initial implementation, then mid-response wrote &quot;Wait, let me reconsider&quot; and produced a cleaner version. The second implementation uses <code>json.loads</code> on the gNMI response val correctly and handles both list and dict neighbor structures. The self-correction is a behavior artifact. It suggests the model evaluated its own output and found a better path. No local model in this test exhibited that.</p><hr><h3 id="the-scores">The Scores</h3><p>Same rubric as Run 1. Five dimensions, 100 points total.</p><figure class="kg-card kg-image-card"><img src="https://storage.ghost.io/c/c4/dc/c4dcef1a-ac8f-4b6b-9334-63e32b1fa558/content/images/2026/05/06_run1_vs_run2_delta.png" class="kg-image" alt="Corrected Local LLM Network Test: The Right Tool (Part 2)" loading="lazy" width="1830" height="923" srcset="https://storage.ghost.io/c/c4/dc/c4dcef1a-ac8f-4b6b-9334-63e32b1fa558/content/images/size/w600/2026/05/06_run1_vs_run2_delta.png 600w, https://storage.ghost.io/c/c4/dc/c4dcef1a-ac8f-4b6b-9334-63e32b1fa558/content/images/size/w1000/2026/05/06_run1_vs_run2_delta.png 1000w, https://storage.ghost.io/c/c4/dc/c4dcef1a-ac8f-4b6b-9334-63e32b1fa558/content/images/size/w1600/2026/05/06_run1_vs_run2_delta.png 1600w, https://storage.ghost.io/c/c4/dc/c4dcef1a-ac8f-4b6b-9334-63e32b1fa558/content/images/2026/05/06_run1_vs_run2_delta.png 1830w" sizes="(min-width: 720px) 720px"></figure>
<!--kg-card-begin: html-->
<table>
<thead>
<tr>
<th><strong>Model</strong></th>
<th><strong>Run 1</strong></th>
<th><strong>Run 2</strong></th>
<th><strong>&#x394;</strong></th>
<th><strong>Primary driver</strong></th>
</tr>
</thead>
<tbody>
<tr>
<td>Qwen 2.5 Coder 7B</td>
<td>83</td>
<td>85</td>
<td>+2</td>
<td>Consistent T3 pass confirmed</td>
</tr>
<tr>
<td>Claude Haiku 4.5</td>
<td>76</td>
<td>79</td>
<td>+3</td>
<td>T4 fixed; offset by T1 false negative</td>
</tr>
<tr>
<td>Gemma 3 12B</td>
<td>73</td>
<td>77</td>
<td>+4</td>
<td>T3 near-miss vs generation refusal</td>
</tr>
<tr>
<td>Gemma 3 4B</td>
<td>81</td>
<td>74</td>
<td>&#x2212;7</td>
<td>Stricter T2 scoring; T3 unchanged</td>
</tr>
<tr>
<td>Llama 3.1 8B</td>
<td>67</td>
<td>68</td>
<td>+1</td>
<td>Stable</td>
</tr>
<tr>
<td>Phi-3.5 Mini</td>
<td>54</td>
<td>48</td>
<td>&#x2212;6</td>
<td>T1 false negative confirmed twice</td>
</tr>
</tbody>
</table>
<!--kg-card-end: html-->
<p><strong>Haiku</strong> moved only +3 despite T4 being fixed because T1 dropped. The calibration weight is at 79/100 in a corrected run. Third place, behind two local models that cost nothing to run.</p><p><strong>Gemma 3 4B</strong> dropped seven points under stricter T2 scoring. In Run 1, its triage output was scored generously. The &quot;Okay, let&apos;s analyze these BGP events&quot; preamble and chatty structure cost marks when held to the same standard as the models that opened with structured output. The T3 failure is unchanged.</p><p><strong>Gemma 3 12B</strong> gained the most (+4) because T3 went from zero to partial credit. Right content, wrong schema. That&apos;s a different problem than having no content at all.</p><p><strong>Phi-3.5</strong> dropped further because both T1 false negatives are now confirmed as consistent. A model that reports no breach when there is one, twice in a row, isn&apos;t suitable for ops triage.</p><hr><h3 id="what-run-2-actually-tells-us">What Run 2 Actually Tells Us</h3><p><strong>The rankings are stable.</strong> Fixing the test didn&apos;t reorder the field. Qwen at the top, Haiku in the middle, Phi-3.5 at the bottom. The things that separated models in Run 1 still separate them in Run 2.</p><p><strong>The Haiku T5 problem is a budget problem, not a model problem.</strong> Two runs, two truncations, same pattern. The budget kept moving, the ceiling kept moving with it. Haiku writes thorough code. Budgets calibrated for local models will systematically underestimate it.</p><p><strong>Haiku T1 is a watch item.</strong> Non-deterministic response on breach detection. Not a verdict. A data point. Ops triage tasks need verification regardless of which model is handling them.</p><p><strong>Gemma 3 12B has the knowledge, not the speed.</strong> Given enough time, it produced the right content in the wrong format. On CPU at 6 tok/s that&apos;s impractical for anything latency-sensitive. What GPU enables is an open question.</p><hr><h3 id="whats-still-unanswered">What&apos;s Still Unanswered</h3><p>The GPU.</p><p>Gemma 12B completed T3 in 336 seconds on CPU. If the T600 drives it at 30+ tok/s, that drops to under 50 seconds. That changes the routing story for the 12B class. If throughput only doubles, 12 tok/s instead of 6, it doesn&apos;t change anything operationally.</p><p>The 3.8B and 4B models are more interesting. On CPU they hit 13&#x2013;15 tok/s. On 4GB VRAM with proper CUDA, they should run at 30&#x2013;50 tok/s. That gap matters for voice loop use: something that takes 20 seconds on CPU might take 6 seconds on GPU. 6 seconds is at the edge of acceptable for a voice response. 20 seconds is not.</p><p>None of these questions are answerable from the data I have. The CUDA runtime install is a one-time operation.</p><p>Part 3: I turn on the GPU and find out if the T600 changes anything, or if this machine was always going to run on CPU regardless.</p><hr><p><em>The Right Tool is a field series on local LLM deployment in a live network lab. Part 1 covered the baseline run. Part 3 covers GPU-enabled hardware characterization.</em></p>]]></content:encoded></item><item><title><![CDATA[The Thinking Network (Installment 6): The BGP Overlay & EVPN Services]]></title><description><![CDATA[Installment 6 of The Thinking Network. We deploy the BGP overlay and EVPN address families to create the control plane lever our autonomous AI will use for traffic engineering.]]></description><link>https://www.tomharveytraining.com/the-thinking-network-installment-6-bgp-overlay/</link><guid isPermaLink="false">6a0d87157fd5980001123d5d</guid><category><![CDATA[The Thinking Network]]></category><dc:creator><![CDATA[Thomas Harvey]]></dc:creator><pubDate>Wed, 03 Jun 2026 11:00:41 GMT</pubDate><media:content url="https://storage.ghost.io/c/c4/dc/c4dcef1a-ac8f-4b6b-9334-63e32b1fa558/content/images/2026/05/Installment-6.jpg" medium="image"/><content:encoded><![CDATA[<blockquote><strong>Architecture Overview: Phase 6 (The Overlay)</strong><strong>Objective:</strong> Deploy the BGP control plane that the autonomous AI agent will manipulate.<strong>Core Technologies:</strong> BGP (Border Gateway Protocol), iBGP Full-Mesh, EVPN (Ethernet VPN), and SR Linux Overlay Services.<strong>The Goal:</strong> Establish an iBGP overlay across the IS-IS underlay, configuring the specific BGP attributes (like Local Preference) that our AI model will dynamically alter to steer traffic.</blockquote><hr><h2 id="the-overlay">The Overlay</h2><img src="https://storage.ghost.io/c/c4/dc/c4dcef1a-ac8f-4b6b-9334-63e32b1fa558/content/images/2026/05/Installment-6.jpg" alt="The Thinking Network (Installment 6): The BGP Overlay &amp; EVPN Services"><p>IS-IS built the map. Every router knows where every other router is. The loopback addresses are distributed. The routing table is populated.</p><p>Now the overlay goes on top.</p><p>BGP (Border Gateway Protocol) is the protocol that carries the information the AI layer will eventually use to make decisions. It is also the protocol the AI will reach into when it decides to act.</p><hr><h3 id="two-protocols-two-jobs">Two Protocols, Two Jobs</h3><p>A question that comes up regularly: if IS-IS is already routing packets, why does this lab also need BGP?</p><p>The answer is scope.</p><p>IS-IS operates within a single routing domain. It knows the topology of this network and distributes reachability information for the addresses within it. It does not carry service routes. It does not carry VPN information. It does not scale to the hundreds of thousands of prefixes that flow across internet exchange points.</p><p>BGP was designed to carry routing information across boundaries - between the distinct, independently-administered networks that form the internet. In this lab, BGP runs as iBGP - internal BGP, a full mesh of sessions within a single autonomous system. All four nodes are in AS 65000. Each node peers with every other node.</p><h3 id="the-role-of-evpn-and-l2-bridges">The Role of EVPN and L2 Bridges</h3><p>When we talk about a service route, we are usually talking about an EVPN route. EVPN stands for Ethernet VPN. It is the modern standard for extending Layer 2 networks over a Layer 3 infrastructure.</p><p>An L2 bridge domain is essentially a virtual switch. When you connect two servers on opposite sides of the fabric, they need to believe they are on the same local Ethernet segment. They need to broadcast ARP requests and find each other&apos;s MAC addresses.</p><p>In a traditional network, this would require a physical Layer 2 link spanning the entire distance. In this lab, we use EVPN to bridge that gap. The SR Linux routers perform a process called MAC learning. When a client sends a frame, the router learns the MAC address and encapsulates that Ethernet frame inside a packet.</p><p>BGP then distributes the reachability of that MAC address across the iBGP mesh. To the clients, the network appears as a single, transparent switch, even though the traffic is actually traversing a complex Layer 3 fabric managed by IS-IS.</p><p>When a service route needs to be distributed - an EVPN route for an L2 bridge domain, a VPN route for an L3 service - it travels through the iBGP mesh. When the AI layer needs to influence traffic flow, it will do so through BGP. Not by changing routes directly, but by changing a BGP attribute called Local Preference. IS-IS gets packets between routers, but BGP decides where services go and which path carries them.</p><hr><h3 id="configuring-bgp-by-hand">Configuring BGP by Hand</h3><p>If you were building this lab without automation, this is what you would type. Each node needs its own router ID, its autonomous system number, a peer group definition, and a neighbor statement for each of the other three nodes.</p><p>The router ID for each node is its loopback address. The loopback is always reachable - it does not go down when a physical link fails. BGP sessions built on loopback addresses survive link failures and reconverge through whatever alternate path IS-IS provides. This is the IS-IS/BGP interdependency made explicit: IS-IS makes BGP resilient.</p><p><strong>srl1:</strong></p><pre><code>--{ candidate }--[ ]--
A:srl1# set / network-instance default protocols bgp admin-state enable
A:srl1# set / network-instance default protocols bgp autonomous-system 65000
A:srl1# set / network-instance default protocols bgp router-id 172.1.255.255
A:srl1# set / network-instance default protocols bgp afi-safi ipv4-unicast admin-state enable
A:srl1# set / network-instance default protocols bgp afi-safi evpn admin-state enable
A:srl1# set / network-instance default protocols bgp group ibgp-mesh peer-as 65000
A:srl1# set / network-instance default protocols bgp group ibgp-mesh afi-safi ipv4-unicast admin-state enable
A:srl1# set / network-instance default protocols bgp group ibgp-mesh afi-safi evpn admin-state enable
A:srl1# set / network-instance default protocols bgp neighbor 172.2.255.255 peer-group ibgp-mesh
A:srl1# set / network-instance default protocols bgp neighbor 172.3.255.255 peer-group ibgp-mesh
A:srl1# set / network-instance default protocols bgp neighbor 172.4.255.255 peer-group ibgp-mesh
A:srl1# commit stay
</code></pre><p><strong>srl2:</strong></p><pre><code>A:srl2# set / network-instance default protocols bgp admin-state enable
A:srl2# set / network-instance default protocols bgp autonomous-system 65000
A:srl2# set / network-instance default protocols bgp router-id 172.2.255.255
A:srl2# set / network-instance default protocols bgp afi-safi ipv4-unicast admin-state enable
A:srl2# set / network-instance default protocols bgp afi-safi evpn admin-state enable
A:srl2# set / network-instance default protocols bgp group ibgp-mesh peer-as 65000
A:srl2# set / network-instance default protocols bgp group ibgp-mesh afi-safi ipv4-unicast admin-state enable
A:srl2# set / network-instance default protocols bgp group ibgp-mesh afi-safi evpn admin-state enable
A:srl2# set / network-instance default protocols bgp neighbor 172.1.255.255 peer-group ibgp-mesh
A:srl2# set / network-instance default protocols bgp neighbor 172.3.255.255 peer-group ibgp-mesh
A:srl2# set / network-instance default protocols bgp neighbor 172.4.255.255 peer-group ibgp-mesh
A:srl2# commit stay
</code></pre><p><strong>srl3:</strong></p><pre><code>A:srl3# set / network-instance default protocols bgp admin-state enable
A:srl3# set / network-instance default protocols bgp autonomous-system 65000
A:srl3# set / network-instance default protocols bgp router-id 172.3.255.255
A:srl3# set / network-instance default protocols bgp afi-safi ipv4-unicast admin-state enable
A:srl3# set / network-instance default protocols bgp afi-safi evpn admin-state enable
A:srl3# set / network-instance default protocols bgp group ibgp-mesh peer-as 65000
A:srl3# set / network-instance default protocols bgp group ibgp-mesh afi-safi ipv4-unicast admin-state enable
A:srl3# set / network-instance default protocols bgp group ibgp-mesh afi-safi evpn admin-state enable
A:srl3# set / network-instance default protocols bgp neighbor 172.1.255.255 peer-group ibgp-mesh
A:srl3# set / network-instance default protocols bgp neighbor 172.2.255.255 peer-group ibgp-mesh
A:srl3# set / network-instance default protocols bgp neighbor 172.4.255.255 peer-group ibgp-mesh
A:srl3# commit stay
</code></pre><p><strong>srl4:</strong></p><pre><code>A:srl4# set / network-instance default protocols bgp admin-state enable
A:srl4# set / network-instance default protocols bgp autonomous-system 65000
A:srl4# set / network-instance default protocols bgp router-id 172.4.255.255
A:srl4# set / network-instance default protocols bgp afi-safi ipv4-unicast admin-state enable
A:srl4# set / network-instance default protocols bgp afi-safi evpn admin-state enable
A:srl4# set / network-instance default protocols bgp group ibgp-mesh peer-as 65000
A:srl4# set / network-instance default protocols bgp group ibgp-mesh afi-safi ipv4-unicast admin-state enable
A:srl4# set / network-instance default protocols bgp group ibgp-mesh afi-safi evpn admin-state enable
A:srl4# set / network-instance default protocols bgp neighbor 172.1.255.255 peer-group ibgp-mesh
A:srl4# set / network-instance default protocols bgp neighbor 172.2.255.255 peer-group ibgp-mesh
A:srl4# set / network-instance default protocols bgp neighbor 172.3.255.255 peer-group ibgp-mesh
A:srl4# commit stay
</code></pre><p>Four nodes. Eleven commands each. Three neighbor statements per node, each pointing at the loopback of another node. A full mesh means every node peers with every other node directly - no route reflector, no hierarchy. Six sessions total. Every node sees every route from every other node directly.</p><p>The peer group <code>ibgp-mesh</code> is a template. The neighbor statements reference it rather than repeating the same attributes four times per node. Both <code>ipv4-unicast</code> and <code>evpn</code> address families are enabled. ipv4-unicast carries IP prefixes. EVPN - Ethernet VPN - carries the MAC and IP binding information for the L2 and L3 services the client containers will use.</p><hr><h3 id="what-the-script-does-instead">What the Script Does Instead</h3><p>The Python script generates the neighbor statements dynamically from the node list in <code>lab_config.py</code>:</p><pre><code class="language-python">neighbors = &quot;&quot;.join([
    f&quot;set / network-instance default protocols bgp neighbor 172.{i}.255.255 peer-group ibgp-mesh\n&quot;
    for i in range(1, 5) if str(i) != sid
])
</code></pre><p>For srl1, <code>sid</code> is <code>1</code>. The loop generates neighbors for sites 2, 3, and 4. For srl4, <code>sid</code> is <code>4</code>. The loop generates neighbors for sites 1, 2, and 3. The router ID is <code>172.{sid}.255.255</code> - the same loopback address IS-IS distributed.</p><p>The script writes all four configs in one pass. The startup files load at boot. BGP sessions form as soon as IS-IS has distributed the loopback addresses - which is why IS-IS is configured first and why the audit verifies IS-IS before checking BGP.</p><hr><h3 id="why-bgp-is-the-ais-lever">Why BGP Is the AI&apos;s Lever</h3><p>Here is the specific reason BGP matters to this series beyond just completing the control plane.</p><p>The AI layer, when it determines it needs to reroute traffic, does not reprogram the forwarding table. It does not touch IS-IS. It reaches into BGP and changes one attribute: Local Preference.</p><p>Local Preference is a number that tells BGP how much to favor a route relative to alternatives. The default is 100. Higher values win. If the AI detects that latency on Path A is trending toward the 5ms SLA threshold, it changes the Local Preference on the Path A route from 100 to 50. BGP reconverges. Path B becomes preferred. Traffic moves.</p><p>When latency recovers, the AI restores Local Preference to 100. BGP reconverges again. Traffic returns to Path A.</p><p>The AI did not redesign the network. It changed a number. The network did what it does - it followed the policy.</p><p>This is why the overlay had to be built before the intelligence layer is meaningful. The intelligence does not work around BGP. It works through it. And it only works through it because IS-IS is underneath providing the loopback reachability that makes BGP sessions stable.</p><hr><h3 id="verification">Verification</h3><p>After IS-IS has converged and the startup configs have loaded:</p><pre><code class="language-bash">docker exec clab-nbl-diamond-v1-srl1 sr_cli \
  -c &quot;show network-instance default protocols bgp neighbor&quot;
</code></pre><pre><code>+----------+---------------+-----------+-------+--------+-------------+-----------+
| Net-Inst |     Peer      |   Group   | Flags | Peer-AS|    State    |  Uptime   |
+==========+===============+===========+=======+========+=============+===========+
| default  | 172.2.255.255 | ibgp-mesh | S     | 65000  | established | 0d:0h:28m |
| default  | 172.3.255.255 | ibgp-mesh | S     | 65000  | established | 0d:0h:28m |
| default  | 172.4.255.255 | ibgp-mesh | S     | 65000  | established | 0d:0h:28m |
+----------+---------------+-----------+-------+--------+-------------+-----------+
3 configured neighbors, 3 configured sessions are established
</code></pre><p>Three neighbors. Three sessions. All <code>established</code>. The iBGP full mesh is up.</p><p>Every node shows the same result - three established sessions pointing at the other three loopbacks. Six sessions total across the fabric. The control plane is complete.</p><hr><h3 id="what-the-fabric-is-now">What the Fabric Is Now</h3><p>Four nodes. IS-IS underlay distributing loopback reachability across the diamond. iBGP full mesh running across those loopbacks in AS 65000. EVPN address family enabled for L2 and L3 service distribution. End-to-end client connectivity verified.</p><p>The fabric is a digital twin of carrier infrastructure running on a laptop. Not a simulation. The actual Nokia SR Linux operating system, running the actual protocols, carrying actual traffic.</p><p>The next phase is to give it the ability to watch itself.</p><hr><p><em>Next installment: The Health Audit. The automated verification that the fabric is exactly what we think it is - before we hand it to the AI.</em></p>]]></content:encoded></item><item><title><![CDATA[Reverse Engineering My NTCA Pension]]></title><description><![CDATA[The NTCA pension lump sum uses IRS §417(e) segment rates - not treasury bonds. Here's how the calculation works and how I verified it to 0.004% accuracy.]]></description><link>https://www.tomharveytraining.com/ntca-pension-lump-sum-how-it-actually-works/</link><guid isPermaLink="false">6a1c739104914400016f84c3</guid><category><![CDATA[The Silent Observer]]></category><category><![CDATA[NTCA]]></category><category><![CDATA[retirement]]></category><category><![CDATA[personal finance]]></category><dc:creator><![CDATA[Thomas Harvey]]></dc:creator><pubDate>Sun, 31 May 2026 18:15:02 GMT</pubDate><media:content url="https://storage.ghost.io/c/c4/dc/c4dcef1a-ac8f-4b6b-9334-63e32b1fa558/content/images/2026/05/Series-7.png" medium="image"/><content:encoded><![CDATA[<h1 id="reverse-engineering-my-ntca-pension">Reverse Engineering My NTCA Pension</h1><img src="https://storage.ghost.io/c/c4/dc/c4dcef1a-ac8f-4b6b-9334-63e32b1fa558/content/images/2026/05/Series-7.png" alt="Reverse Engineering My NTCA Pension"><p><em>What NTCA didn&apos;t tell me - and what I had to figure out myself.</em></p><hr><p>When I started getting serious about retirement planning, I did what you are supposed to do: I went to the source. I ran numbers on the NTCA Pension Point calculator. I asked questions.</p><p>What I got back was a number. No methodology. No formula. No explanation of how a lump sum was derived from my salary and service years.</p><p>So I reverse-engineered it.</p><hr><h2 id="what-i-was-told">What I was told</h2><p>When I asked how NTCA calculated the lump sum, I was told it was based on a GATT rate, the 30-year Treasury bond discount method that pension plans used before the Pension Protection Act of 2006 replaced it.</p><p>That is not correct.</p><p>The NTCA defined benefit plan uses <a href="https://www.irs.gov/retirement-plans/minimum-present-value-segment-rates?ref=tomharveytraining.com" rel="noopener nofollow">IRS &#xA7;417(e)</a> - a statutory valuation method that uses high-quality corporate bond rates, not treasuries. Specifically, it uses the IRS &quot;HQM&quot; (High-Quality Market) corporate bond yield curve, averaged over a 24-month lookback period to produce three separate segment rates. Those rates are then held fixed for a full plan year - a 12-month stability period permitted under <a href="https://www.irs.gov/pub/irs-drop/rr-07-67.pdf?ref=tomharveytraining.com" rel="noopener nofollow">IRS Revenue Ruling 2007-67</a>. The averaging period and the stability period are distinct: one determines the rate values, the other determines how long they apply.</p><p>The distinction matters. Corporate bond yields are higher than treasuries. Higher discount rates compress the present value of future payments. The lump sum you receive is lower under &#xA7;417(e) than it would be under a treasury-based valuation. This is not a criticism of NTCA - it is the statutory method Congress set for pension plans in the <a href="https://www.congress.gov/109/plaws/publ280/PLAW-109publ280.pdf?ref=tomharveytraining.com" rel="noopener nofollow">Pension Protection Act of 2006</a>. But if you are told &quot;treasury bonds&quot; and the actual rates are higher, you will build a mental model that gives you the wrong number.</p><hr><h2 id="how-it-actually-works">How it actually works</h2><p>The lump sum is the present value of your lifetime monthly annuity. To compute it, you need three inputs:</p><ol><li><strong>Your monthly annuity</strong> - calculated from your benefit rate, salary, and service years</li><li><strong>Survival probabilities</strong> - from the IRS &#xA7;417(e) unisex mortality table, updated annually via IRS Notice (see Sources)</li><li><strong>Discount rates</strong> - the three <a href="https://www.irs.gov/retirement-plans/minimum-present-value-segment-rates?ref=tomharveytraining.com" rel="noopener nofollow">&#xA7;417(e) segment rates</a>, published monthly by the IRS</li></ol><p>For each future payment month, the calculation asks: what is the probability you will be alive to receive this payment, and what is that payment worth in today&apos;s dollars? Then it sums all 780 payments, 65 years of monthly payments, from retirement age to age 120.</p><p>The three segment rates correspond to payment timing:</p>
<!--kg-card-begin: html-->
<table>
<thead>
<tr>
<th>Payments</th>
<th>Years out</th>
<th>Rate used</th>
</tr>
</thead>
<tbody>
<tr>
<td>Months 1&#x2013;60</td>
<td>0&#x2013;5 years</td>
<td>Segment 1</td>
</tr>
<tr>
<td>Months 61&#x2013;240</td>
<td>5&#x2013;20 years</td>
<td>Segment 2</td>
</tr>
<tr>
<td>Months 241&#x2013;780</td>
<td>20+ years</td>
<td>Segment 3</td>
</tr>
</tbody>
</table>
<!--kg-card-end: html-->
<p>Per Article IV, Section C(3)(f) of the NTCA R&amp;S Program Specifications (January 1, 2025 Restatement), the lump sum interest rate is defined as:</p><blockquote><em>&quot;the interest rate determined under section 417(e)(3) of the Code for the month of August immediately preceding the calendar year that includes the annuity starting date&quot;</em></blockquote><p>The lookback month is <strong>August</strong>. The stability period is the full calendar year (Definition 28: &quot;Plan Year means the calendar year&quot;). Crucially, the reference point is the <strong>annuity starting date</strong> (the participant&apos;s intended retirement date), not the date the calculation was run. For a June 2029 retirement, NTCA uses August 2028 rates. For a February 2030 retirement, August 2029 rates apply. When NTCA&apos;s Pension Point generates an estimate today for a future retirement, it uses the August rates projected or applicable to that future retirement year.</p><hr><h2 id="the-calculation-step-by-step">The calculation, step by step</h2><p>Here is the full methodology in explicit form. All of this derives from public law and IRS publications.</p><p><em>The following variables are used throughout this section. Specific values from my verification are withheld; substitute your own to reproduce the calculation.</em></p>
<!--kg-card-begin: html-->
<table>
<thead>
<tr>
<th>Variable</th>
<th>Definition</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>R</strong></td>
<td>Employer benefit rate (e.g. 0.019 for 1.9%)</td>
</tr>
<tr>
<td><strong>H</strong></td>
<td>High-5 average salary</td>
</tr>
<tr>
<td><strong>Y</strong></td>
<td>Years of plan participation, including fractions</td>
</tr>
<tr>
<td><strong>r&#x2081;, r&#x2082;, r&#x2083;</strong></td>
<td>IRS &#xA7;417(e) segment rates for the applicable plan year</td>
</tr>
<tr>
<td><strong>n</strong></td>
<td>Payment month (1 to 780)</td>
</tr>
<tr>
<td><strong>A</strong></td>
<td>Monthly annuity = R x H x Y / 12</td>
</tr>
<tr>
<td><strong>DF(n)</strong></td>
<td>Discount factor at month n</td>
</tr>
<tr>
<td><strong>S(n)</strong></td>
<td>Cumulative survival probability at month n</td>
</tr>
<tr>
<td><strong>PV(n)</strong></td>
<td>Present value of payment at month n</td>
</tr>
</tbody>
</table>
<!--kg-card-end: html-->
<hr><p><strong>Step 1 - Monthly annuity</strong></p><pre><code>A = R x H x Y / 12
</code></pre><p>Illustrative example (R=0.019, H=$100,000, Y=25.0):</p><pre><code>0.019 x $100,000 x 25.0 / 12 = $3,958.33/month
</code></pre><p>R is your employer&apos;s elected rate from their Adoption Agreement. If your employer elected 1.7% or 1.5%, your starting number is lower before any other factor applies. For the same H and Y, the difference between R=0.015 and R=0.019 is roughly $150,000 in lump sum value.</p><p><strong>Step 2 - Assign a segment rate to each future payment</strong></p><p>Each of the 780 future payments is discounted at a rate determined by how far in the future it falls. These are the rates that converged in the grid search, applicable to the plan years covering the retirement dates used in this verification:</p>
<!--kg-card-begin: html-->
<table>
<thead>
<tr>
<th>Payment timing</th>
<th>Segment</th>
<th>Rate</th>
</tr>
</thead>
<tbody>
<tr>
<td>Months 1&#x2013;60 (years 0&#x2013;5)</td>
<td>Segment 1</td>
<td>4.10%</td>
</tr>
<tr>
<td>Months 61&#x2013;240 (years 5&#x2013;20)</td>
<td>Segment 2</td>
<td>5.20%</td>
</tr>
<tr>
<td>Months 241&#x2013;780 (years 20&#x2013;65)</td>
<td>Segment 3</td>
<td>5.80%</td>
</tr>
</tbody>
</table>
<!--kg-card-end: html-->
<p>These rates are derived from the <a href="https://home.treasury.gov/data/treasury-bulletin?ref=tomharveytraining.com" rel="noopener nofollow">Treasury&apos;s HQM corporate bond yield curve</a>, averaged over 24 months and published monthly by the IRS. The IRS minimum present value segment rate table is publicly accessible and updated every month.</p><p><strong>Step 3 - Compute the discount factor for each payment</strong></p><p>For a payment <em>n</em> months in the future, discount factors compound across segment boundaries:</p><pre><code>Months 1&#x2013;60:    DF(n) = 1 / (1 + r&#x2081;/12)&#x207F;

Months 61&#x2013;240:  DF(n) = 1 / (1 + r&#x2081;/12)&#x2076;&#x2070;  &#xD7;  1 / (1 + r&#x2082;/12)&#x207F;&#x207B;&#x2076;&#x2070;

Months 241+:    DF(n) = 1 / (1 + r&#x2081;/12)&#x2076;&#x2070;  &#xD7;  1 / (1 + r&#x2082;/12)&#xB9;&#x2078;&#x2070;  &#xD7;  1 / (1 + r&#x2083;/12)&#x207F;&#x207B;&#xB2;&#x2074;&#x2070;
</code></pre><p>Sample values using the verified segment rates (4.10% / 5.20% / 5.80%):</p>
<!--kg-card-begin: html-->
<table>
<thead>
<tr>
<th>Month</th>
<th>Segment</th>
<th>Rate</th>
<th>Discount factor</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>1</td>
<td>4.10%</td>
<td>0.9966</td>
</tr>
<tr>
<td>60</td>
<td>1</td>
<td>4.10%</td>
<td>0.8149</td>
</tr>
<tr>
<td>61</td>
<td>2</td>
<td>5.20%</td>
<td>0.8114</td>
</tr>
<tr>
<td>240</td>
<td>2</td>
<td>5.20%</td>
<td>0.3743</td>
</tr>
<tr>
<td>241</td>
<td>3</td>
<td>5.80%</td>
<td>0.3725</td>
</tr>
<tr>
<td>780</td>
<td>3</td>
<td>5.80%</td>
<td>0.0277</td>
</tr>
</tbody>
</table>
<!--kg-card-end: html-->
<p>A payment 5 years out is worth roughly 81 cents on the dollar. A payment 20 years out is worth about 37 cents. Payments at the far end of the table - which exist because the calculation runs to age 120 - contribute almost nothing to the total. The early payments are what drive the lump sum value, which is why Segment 1 movements have an outsized effect on the final number.</p><p><strong>Step 4 - Apply survival probability</strong></p><p>The IRS mandates a specific unisex mortality table for &#xA7;417(e) calculations, updated annually via IRS Notice. The applicable notice depends on your annuity starting date - IRS Notice 2024-42 covers 2025; the equivalent notice for 2026 and beyond is a new notice published each year. To find the current one, search IRS.gov for &quot;&#xA7;417(e) unisex mortality table&quot; or check the Sources section below for the 2025 reference and the IRS guidance index.</p><p>The table provides <em>q&#x2093;</em> - the annual probability of death at age <em>x</em>. From this:</p><pre><code>p&#x2093;     = 1 &#x2212; q&#x2093;                    (probability of surviving year x)

S(n)   = p&#x2085;&#x2085; &#xD7; p&#x2085;&#x2086; &#xD7; &#xB7;&#xB7;&#xB7; &#xD7; p&#x2093;&#x208D;&#x2099;&#x208E;   (cumulative survival to payment month n)
</code></pre><p>S is normalized to 1.0 at retirement. Representative values from the IRS unisex table:</p>
<!--kg-card-begin: html-->
<table>
<thead>
<tr>
<th>Age</th>
<th>Approximate survival probability</th>
</tr>
</thead>
<tbody>
<tr>
<td>55 (retirement)</td>
<td>1.000</td>
</tr>
<tr>
<td>65</td>
<td>~0.957</td>
</tr>
<tr>
<td>75</td>
<td>~0.835</td>
</tr>
<tr>
<td>85</td>
<td>~0.524</td>
</tr>
</tbody>
</table>
<!--kg-card-end: html-->
<p>Long-dated payments are discounted twice - once for time value of money, once for mortality probability. A payment at month 360 (age 85) carries a discount factor of ~0.21 and a survival probability of ~0.52, making it worth roughly 11 cents of its nominal value.</p><p><strong>Step 5 - Present value of each payment</strong></p><pre><code>PV(n) = A x S(n) x DF(n)
</code></pre><p><strong>Step 6 - Sum across all payments</strong></p><pre><code>Lump Sum = &#x3A3; PV(n)  for n = 1 to 780
</code></pre><p>This is a deterministic sum of 780 terms. No actuarial black box. No proprietary formula. The full source implementation is in the <a href="https://github.com/harvey267/ntca-calculator?ref=tomharveytraining.com" rel="noopener nofollow">GitHub repository</a>.</p><hr><h2 id="how-i-verified-it">How I verified it</h2><p>I had two official NTCA Pension Point outputs - lump sum estimates for two different retirement dates. The calculator produced both; I could see the results but not the formula.</p><p>I built a Python model from the IRS &#xA7;417(e) spec: load the correct mortality table for the plan year, apply the three-segment discount structure, compute conditional survival probabilities from the retirement age forward, sum the present value of every payment.</p><p>My first model was off by about 1.7% consistently. The same error across both data points told me it was not a calculation logic problem - it was a parameter problem. The segment rates I was using did not match what NTCA actually used.</p><p>So I ran a grid search: search r&#x2081;, r&#x2082;, r&#x2083; across a plausible range in 0.01% increments, with r&#x2081; &lt;= r&#x2082; &lt;= r&#x2083;, minimizing the maximum absolute error across both official outputs simultaneously: a minimax objective rather than minimizing average error, which would allow one output to compensate for the other.</p><p>The rates that converged: <strong>4.10% / 5.20% / 5.80%</strong>.</p><p>The minimum was isolated at the grid resolution: a 0.01% shift in any segment rate moves one of the two outputs by several hundred dollars, confirming no near-equivalent alternative exists within the search space. The minimax objective is what makes this identification reliable: fitting to a single output allows rate combinations to trade off against each other; requiring both outputs to converge simultaneously eliminates that degree of freedom.</p><p>These cannot be directly verified against current IRS published tables. Per the plan document (Article IV.C(3)(f)), the applicable rate is the August &#xA7;417(e)(3) rate &quot;immediately preceding the calendar year that includes the annuity starting date,&quot; meaning the retirement year, not the calculation year. The two outputs used in this verification are for retirement dates in 2029 and 2030, so the applicable August rates are August 2028 and August 2029 respectively. Those months have not yet occurred. The rates above represent what NTCA&apos;s Pension Point was projecting for those future Augusts at the time the estimates were generated. Independent verification becomes possible once those months pass and the IRS publishes the actual rates.</p><p>To reproduce this yourself with your own NTCA Pension Point outputs:</p><pre><code class="language-python">import numpy as np

def monthly_lump_sum(monthly_annuity, retirement_age, r1, r2, r3, survival):
    &quot;&quot;&quot;PV sum of 780 monthly payments. survival: Series indexed by age.&quot;&quot;&quot;
    total = 0.0
    for n in range(1, 781):
        age_n = retirement_age + n / 12
        s = np.interp(age_n, survival.index, survival.values)
        if n &lt;= 60:
            df = 1 / (1 + r1/12)**n
        elif n &lt;= 240:
            df = (1/(1+r1/12)**60) * (1/(1+r2/12)**(n-60))
        else:
            df = (1/(1+r1/12)**60) * (1/(1+r2/12)**180) * (1/(1+r3/12)**(n-240))
        total += monthly_annuity * s * df
    return total

# Substitute your two official NTCA Pension Point lump sum outputs
OFFICIAL_A = &lt;output_for_date_A&gt;
OFFICIAL_B = &lt;output_for_date_B&gt;

# Your annuities for each date: R * H * Y / 12
ANNUITY_A  = &lt;benefit_rate * high5 * years_a / 12&gt;
ANNUITY_B  = &lt;benefit_rate * high5 * years_b / 12&gt;
RETIRE_AGE = &lt;your_retirement_age_as_decimal&gt;

# Load IRS mortality table (n-24-42.csv or current plan year equivalent)
# survival = pd.Series(...)  # see repo for full load logic

best_error, best_rates = float(&apos;inf&apos;), None
for r1 in np.arange(0.030, 0.065, 0.0001):
    for r2 in np.arange(r1,   0.070, 0.0001):
        for r3 in np.arange(r2,   0.080, 0.0001):
            err = max(
                abs(monthly_lump_sum(ANNUITY_A, RETIRE_AGE, r1, r2, r3, survival) - OFFICIAL_A),
                abs(monthly_lump_sum(ANNUITY_B, RETIRE_AGE, r1, r2, r3, survival) - OFFICIAL_B),
            )
            if err &lt; best_error:
                best_error, best_rates = err, (r1, r2, r3)

print(f&quot;r1={best_rates[0]:.4f}  r2={best_rates[1]:.4f}  r3={best_rates[2]:.4f}&quot;)
print(f&quot;Max error: ${best_error:,.2f}&quot;)
</code></pre><p>Note: the brute-force loop over the full search space takes time. Narrow the range first using the <a href="https://www.irs.gov/retirement-plans/minimum-present-value-segment-rates?ref=tomharveytraining.com" rel="noopener nofollow">IRS published segment rate history</a> for the relevant plan year.</p><p>With those rates, the model produces:</p>
<!--kg-card-begin: html-->
<table>
<thead>
<tr>
<th>Retirement date</th>
<th>NTCA official</th>
<th>My model</th>
<th>Delta</th>
</tr>
</thead>
<tbody>
<tr>
<td>Retirement Date A</td>
<td>$XXX,XXX</td>
<td>$XXX,XXX</td>
<td>+$42</td>
</tr>
<tr>
<td>Retirement Date B</td>
<td>$XXX,XXX</td>
<td>$XXX,XXX</td>
<td>+$36</td>
</tr>
</tbody>
</table>
<!--kg-card-end: html-->
<p><em>H and Y reflect my actual plan data and are withheld for privacy. The delta column is reproducible by any participant using their own values in the </em><a href="https://github.com/harvey267/ntca-calculator?ref=tomharveytraining.com" rel="noopener nofollow"><em>calculator</em></a><em>.</em></p><p><strong>$36 on a seven-figure lump sum. That is 0.004% error.</strong></p><p>Residual annuity matches to within $0.02 per month.</p><p><strong>Why the model will never match NTCA exactly - and why that is fine.</strong></p><p>The remaining delta is not a model error. Both errors are positive - the model runs slightly high on both dates - but the error is smaller on the larger lump sum: +$36 on the higher figure versus +$42 on the lower one. A systematic methodology mistake would produce errors that scale with lump sum value. These do the opposite.</p><p>The source of the ~$40 residual is input precision. I back-calculated H from the rounded monthly annuity on the PDF, and read Y from a rounded display. NTCA carries both figures to more decimal places internally. Those rounding differences cascade through all 780 monthly PV calculations and produce a terminal difference in the ~$40 range.</p><p>To close that gap you would need NTCA&apos;s internal unrounded inputs. That data is not on the PDF. At 0.004%, the model is at the noise floor of what is observable from the outside.</p><p><strong>A note on the verification basis.</strong></p><p>This verification rests on two data points. Two outputs constrain the solution but do not constitute broad validation: fitting two constraints proves the model is consistent with those two outputs, not that it is correct in general. The bidirectional error pattern and the sub-rounding-threshold residuals are consistent with a correct methodology, but anyone attempting independent validation should obtain additional official outputs and run the grid search against them. If the same rates converge against a different pair of outputs from the same plan year, that is stronger evidence.</p><hr><h2 id="the-buyback-yearsand-why-they-change-everything">The buyback years - and why they change everything</h2><p>Many NTCA participants have prior industry experience that their co-op bought back when they joined the plan. Those bought-back years are credited toward your total NTCA service, and they show up in your official benefit calculation without any separate line item explaining them.</p><p>Here is how to prove whether you have them and how many.</p><p>In my case, the Pension Point output credited more years of service than my actual co-op tenure. The math:</p>
<!--kg-card-begin: html-->
<table>
<thead>
<tr>
<th></th>
<th>Years</th>
</tr>
</thead>
<tbody>
<tr>
<td>Actual co-op service</td>
<td>Ya</td>
</tr>
<tr>
<td>NTCA-credited service</td>
<td>Yc</td>
</tr>
<tr>
<td>Bought-back years</td>
<td><strong>Yc - Ya</strong></td>
</tr>
<tr>
<td>Buyback covers approx.</td>
<td>prior industry tenure</td>
</tr>
</tbody>
</table>
<!--kg-card-end: html-->
<p><em>(Ya = actual co-op tenure; Yc = total NTCA-credited service. These are distinct from the variable Y used in the calculation section, which represents the full credited total including buyback.)</em></p><p>That gap is prior industry experience that NTCA credited at enrollment.</p><p><strong>Why it matters - the Rule of 85:</strong></p><p>The Rule-of-85 Provision is an optional program feature that each participating employer must elect in their Adoption Agreement (Definition 33, NTCA R&amp;S Specifications). If your employer elected it, early retirement without penalty applies when your age plus Rule-of-85 Service equals 85 or more. Check your Summary Plan Description or ask HR whether your employer has this provision in place. The buyback years are included in the Rule-of-85 Service calculation.</p>
<!--kg-card-begin: html-->
<table>
<thead>
<tr>
<th>Scenario</th>
<th>Age</th>
<th>Service</th>
<th>Rule of 85</th>
</tr>
</thead>
<tbody>
<tr>
<td>With buyback</td>
<td>55</td>
<td>Yc</td>
<td>55 + Yc &gt;= 85 - qualifies</td>
</tr>
<tr>
<td>Without buyback</td>
<td>55</td>
<td>Ya</td>
<td>55 + Ya &lt; 85 - does not qualify</td>
</tr>
</tbody>
</table>
<!--kg-card-end: html-->
<p>Without those bought-back years the Rule of 85 threshold is not met at 55. Each year of missed buyback is potentially a year of additional work to qualify.</p><p>The calculator can prove this for your own situation. Pass your co-op start date and it shows the breakdown.</p><hr><h2 id="what-surprised-me-most">What surprised me most</h2><p>Two findings I did not expect going in.</p><p><strong>1. Your employer&apos;s benefit rate may not be 1.9%.</strong></p><p>The NTCA plan is a multi-employer plan where each member co-op elects a benefit accrual rate in their Adoption Agreement. Common values are 1.9%, 1.7%, and 1.5%. Some employers elect lower rates.</p><p>For the same person - same salary, same service years, same retirement date - the difference between a 1.5% rate and a 1.9% rate is roughly <strong>$150,000 in lump sum value</strong>.</p><p>Most participants do not know their employer&apos;s elected rate. It is in your Summary Plan Description. If you do not have that document, ask HR directly - it is a required disclosure under ERISA.</p><p><strong>2. The partial lump sum is not a percentage of your actuarial lump sum.</strong></p><p>I assumed a partial lump sum election meant taking a percentage of the present value and receiving the rest as annuity. That is not how NTCA structures it.</p><p>NTCA&apos;s partial lump sum is your employee contribution balance - the money you put in over your career, with interest. It is a fixed dollar amount, not a percentage. This changes how you model the trade-off between lump sum and annuity income.</p><hr><h2 id="4-in-the-pension-vs-4-in-a-401k">4% in the pension vs. 4% in a 401k</h2><p>The NTCA employee contribution to the defined benefit plan is approximately 4% of salary. A direct question: what would that same 4% produce if directed into a 401k instead, and how does that compare to what the pension delivers?</p><p>Two salary trajectories are modeled below: one starting at $30,000 growing to approximately $70,700, one starting at $40,000 growing to $100,000. Both use 30 years of credited service.</p><p>Retirement timing in both scenarios assumes the employer has elected the Rule-of-85 Provision, an optional feature employers must elect in their Adoption Agreement. If elected, penalty-free early retirement applies when age plus Rule-of-85 Service equals or exceeds 85. With 30 years of credited service, the minimum qualifying age is 55 (55 + 30 = 85). Without the provision, or with fewer credited years (for example, 26 years without buyback), the qualifying threshold shifts: 59 + 26 = 85. The buyback section above covers how to determine your actual credited total. Verify whether your employer has elected this provision before modelling your retirement date.</p><p><strong>The hidden multiplier: High-5 of your last 10 years</strong></p><p>The NTCA defined benefit plan does not calculate your benefit on your career average salary. It uses your High-5 - the average of your five highest compensation years within your last ten years of plan participation.</p><p>For a career with salary growth, this is a significant structural advantage.</p>
<!--kg-card-begin: html-->
<table>
<thead>
<tr>
<th>Trajectory</th>
<th>Career average</th>
<th>High-5 of last 10</th>
<th>Difference</th>
<th>Monthly benefit gain vs career avg</th>
</tr>
</thead>
<tbody>
<tr>
<td>$30k to $70k</td>
<td>$47,575</td>
<td>$66,697</td>
<td>+40%</td>
<td>+$908/month</td>
</tr>
<tr>
<td>$40k to $100k</td>
<td>$65,637</td>
<td>$93,970</td>
<td>+43%</td>
<td>+$1,346/month</td>
</tr>
</tbody>
</table>
<!--kg-card-end: html-->
<p>The plan credits your peak professional value. The higher your salary growth, the more pronounced this advantage becomes.</p><p><strong>What 4% into a 401k produces after 30 years</strong></p><p>Contributions grow with salary. The 4% safe withdrawal rate (SWR) is the standard rule of thumb for sustainable retirement income: withdraw 4% of the balance per year.</p>
<!--kg-card-begin: html-->
<table>
<thead>
<tr>
<th>Trajectory</th>
<th>Investment scenario</th>
<th>Return rate</th>
<th>401k balance</th>
<th>Monthly income (4% SWR)</th>
</tr>
</thead>
<tbody>
<tr>
<td>$30k to $70k</td>
<td>Conservative bonds</td>
<td>5.0%</td>
<td>$113,681</td>
<td>$379/month</td>
</tr>
<tr>
<td>$30k to $70k</td>
<td>Target date fund</td>
<td>6.5%</td>
<td>$143,558</td>
<td>$479/month</td>
</tr>
<tr>
<td>$30k to $70k</td>
<td>S&amp;P 500 historical</td>
<td>10.0%</td>
<td>$257,522</td>
<td>$858/month</td>
</tr>
<tr>
<td>$40k to $100k</td>
<td>Conservative bonds</td>
<td>5.0%</td>
<td>$155,688</td>
<td>$519/month</td>
</tr>
<tr>
<td>$40k to $100k</td>
<td>Target date fund</td>
<td>6.5%</td>
<td>$196,192</td>
<td>$654/month</td>
</tr>
<tr>
<td>$40k to $100k</td>
<td>S&amp;P 500 historical</td>
<td>10.0%</td>
<td>$350,381</td>
<td>$1,168/month</td>
</tr>
</tbody>
</table>
<!--kg-card-end: html-->
<p><strong>What the NTCA pension produces on the same trajectories</strong></p>
<!--kg-card-begin: html-->
<table>
<thead>
<tr>
<th>Trajectory</th>
<th>Monthly annuity</th>
<th>Annual annuity</th>
<th>Lump sum</th>
</tr>
</thead>
<tbody>
<tr>
<td>$30k to $70k</td>
<td>$3,168/month</td>
<td>$38,017/year</td>
<td>$569,783</td>
</tr>
<tr>
<td>$40k to $100k</td>
<td>$4,464/month</td>
<td>$53,563/year</td>
<td>$802,774</td>
</tr>
</tbody>
</table>
<!--kg-card-end: html-->
<p><strong>Side by side: NTCA pension vs. best-case 401k (S&amp;P 500 at 10%)</strong></p>
<!--kg-card-begin: html-->
<table>
<thead>
<tr>
<th>Trajectory</th>
<th>NTCA lump sum</th>
<th>S&amp;P 500 401k</th>
<th>NTCA monthly</th>
<th>S&amp;P 500 monthly</th>
</tr>
</thead>
<tbody>
<tr>
<td>$30k to $70k</td>
<td>$569,783</td>
<td>$257,522</td>
<td>$3,168</td>
<td>$858</td>
</tr>
<tr>
<td>$40k to $100k</td>
<td>$802,774</td>
<td>$350,381</td>
<td>$4,464</td>
<td>$1,168</td>
</tr>
</tbody>
</table>
<!--kg-card-end: html-->
<p>At S&amp;P 500 historical average returns - the most optimistic realistic scenario for a 401k - the defined benefit plan produces a lump sum 2.2x larger and monthly income 3.7x higher across both trajectories.</p><p>The 401k figures assume perfect execution: contributions invested consistently for 30 years, no withdrawals, no fees, and no sequence-of-returns risk from a market downturn near retirement. The NTCA pension is not subject to any of those variables.</p><p>To run this comparison against your own salary history and growth assumptions, use the career trajectory tool in the <a href="https://github.com/harvey267/ntca-calculator?ref=tomharveytraining.com" rel="noopener nofollow">calculator</a>.</p><p><strong>What it would take to replicate the pension in a 401k.</strong></p><p>The employee contribution modeled above is 4% of salary. To produce the same lump sum from a 401k over 30 years, the total contribution rate required depends entirely on the return you actually achieve:</p>
<!--kg-card-begin: html-->
<table>
<thead>
<tr>
<th>Return scenario</th>
<th>Total contribution needed</th>
<th>You pay in (pension)</th>
<th>You would need to add</th>
</tr>
</thead>
<tbody>
<tr>
<td>10% (S&amp;P 500, best case)</td>
<td>~9%</td>
<td>4%</td>
<td>~5% of salary</td>
</tr>
<tr>
<td>6.5% (target date fund)</td>
<td>~16%</td>
<td>4%</td>
<td>~12% of salary</td>
</tr>
<tr>
<td>5% (conservative bonds)</td>
<td>~20%</td>
<td>4%</td>
<td>~16% of salary</td>
</tr>
</tbody>
</table>
<!--kg-card-end: html-->
<p>There is a structural constraint the table does not show. Your 4% contribution to the NTCA defined benefit plan goes to a separate qualified plan and does not count against the IRS 401k elective deferral limit ($23,500 in 2026). NTCA participants typically have access to a 401k through their co-op as well. Those two plans run independently: you can contribute 4% to the pension and still have your full $23,500 available for the 401k.</p><p>Replacing the pension with a 401k changes that. At realistic returns, replicating the pension outcome requires contributing 16% of salary to the 401k. On a $70,000 income, that is $11,200 of your $23,500 deferral limit consumed before any additional retirement saving. At conservative returns, matching the pension requires 20%, or $14,000 of the limit.</p><p>The NTCA pension delivers the equivalent of a 9&#x2013;20% total contribution rate, depending on what you would have realistically earned in a 401k, without touching your 401k capacity.</p><p><strong>What this comparison does not capture.</strong></p><p>The pension has structural advantages the 401k numbers do not reflect: survivor benefits are available in joint and survivor form; the annuity provides longevity insurance against outliving a portfolio; and the employer bears all investment risk for the accumulation period. Conversely, the 401k leaves an estate: the remaining balance passes to heirs, while an annuity generally does not (absent a guaranteed period election). The 4% safe withdrawal rate is also a rule of thumb, not a guarantee: a severe market decline in the years immediately before or after retirement can materially reduce actual withdrawal capacity. These factors do not change the directional conclusion of the comparison, but they affect the trade-off analysis for any individual situation.</p><hr><h2 id="one-more-thing-the-buy-out-trigger">One more thing: the buy-out trigger</h2><p>The NTCA plan contains a provision - effective on a fixed date in early 2030 - that credits one additional year of service for purposes of the lump sum calculation. This is not a standard IRS early retirement rule, not a calendar-year-crossing provision, and not tied to your age or service total. It is a plan-specific amendment with a hard effective date written into the plan document.</p><p>The practical effect: two retirement dates only months apart can produce significantly different lump sum values if one falls before that date and one falls after it. The additional service year credited by the provision changes your annuity base (A = R x H x Y / 12), which then compounds through all 780 monthly present value calculations. It is not a rounding difference - it is a structural step change.</p><p>The provision is in your Summary Plan Description under the lump sum and early retirement sections. If you are within two years of early 2030, run both sides of that threshold. The calculator will show the full impact on your specific inputs.</p><hr><h2 id="can-you-legally-do-this">Can you legally do this?</h2><p>Yes. And it is worth being clear about why.</p><p><strong>&#xA7;417(e) is public law.</strong> The methodology I implemented is written into the IRS code. Congress set this valuation method for defined benefit plans - it is not proprietary to NTCA. Anyone can read the statute, implement the formula, and run it against their own benefit data.</p><p><strong>The source data is government publications.</strong> The IRS publishes the &#xA7;417(e) mortality tables annually as official IRS Notices. The Treasury publishes the HQM corporate bond yield curve data publicly. Both are downloaded from official government sources and linked in the Sources section below.</p><p><strong>I did not touch NTCA&apos;s software.</strong> I looked at outputs, compared them to what the IRS specification would produce, and adjusted until they matched. That is analysis from public data.</p><p><strong>ERISA gives you the right to your own data.</strong> Under <a href="https://www.dol.gov/general/topic/retirement/erisa?ref=tomharveytraining.com" rel="noopener nofollow">ERISA &#xA7;104</a>, federal law requires your plan to disclose the Summary Plan Description. Under <a href="https://www.dol.gov/general/topic/retirement/erisa?ref=tomharveytraining.com" rel="noopener nofollow">ERISA &#xA7;105</a>, you are entitled to a benefit statement on request. Both sections exist because Congress decided participants have a right to understand what they have earned.</p><p>Building a tool to model that methodology requires no additional statutory justification. Implementing a public law formula with public data is not restricted by anything.</p><p><em>This section describes my reasoning for this project, not legal advice. If you have specific concerns about your situation, consult an attorney familiar with ERISA.</em></p><p>This project exists because a plan participant could not get a straight answer about their own retirement. That is the only reason it was built.</p><hr><h2 id="what-is-available-now">What is available now</h2><p>Two tools are on GitHub at <a href="https://github.com/harvey267/ntca-calculator?ref=tomharveytraining.com" rel="noopener nofollow">harvey267/ntca-calculator</a>.</p><p><strong>CLI calculator</strong> - runs a single lump sum estimate from the command line. Takes your birth date, retirement date, high-5 salary, years of service, and employer benefit rate. Outputs the full annuity stream breakdown and a summary.</p><p><strong>Streamlit dashboard</strong> - interactive version. Adjust inputs with sliders, see a retirement window curve showing how the lump sum changes month by month, run segment rate sensitivity analysis, and optionally add Social Security projections from an earnings CSV.</p><p>The inputs you need before running:</p>
<!--kg-card-begin: html-->
<table>
<thead>
<tr>
<th>Input</th>
<th>Where to find it</th>
</tr>
</thead>
<tbody>
<tr>
<td>High-5 salary</td>
<td>Average of your 5 highest compensation years in the last 10 plan years - NTCA can provide this</td>
</tr>
<tr>
<td>Years of service</td>
<td>Your total plan participation years, including fractions - on your Pension Point output</td>
</tr>
<tr>
<td>Employer benefit rate</td>
<td>Your Summary Plan Description or Adoption Agreement - ask HR</td>
</tr>
<tr>
<td>Segment rates</td>
<td>Built-in defaults verified against 2026 plan year outputs; update for future plan years</td>
</tr>
</tbody>
</table>
<!--kg-card-end: html-->
<hr><h2 id="sources">Sources</h2><ul><li><strong>NTCA Retirement &amp; Security Program Specifications, January 1, 2025 Restatement</strong><br>Primary plan document. Article I Definitions (High-5 Compensation, Rule-of-85 Provision, Plan Year); Article IV.C(3)(f) and IV.G(2)(d) specify August as the &#xA7;417(e)(3) lookback month and the calendar year as the stability period. Available to participants on request from NTCA under ERISA &#xA7;104 (<a href="mailto:benefits@ntca.org" rel="noopener nofollow">benefits@ntca.org</a> or 828-252-9776).</li><li><strong>IRC &#xA7;417(e)(3) - Minimum present value requirements and monthly segment rate table</strong><br>The statute that defines the methodology, and the IRS page where monthly rates are published. Per the plan document, the applicable rates for a given retirement date are those published for the August immediately preceding the retirement year: August 2028 for a 2029 retirement, August 2029 for a 2030 retirement.<br><a href="https://www.irs.gov/retirement-plans/minimum-present-value-segment-rates?ref=tomharveytraining.com" rel="noopener nofollow">https://www.irs.gov/retirement-plans/minimum-present-value-segment-rates</a></li><li><strong>IRS Revenue Ruling 2007-67</strong><br>Governs how plans apply &#xA7;417(e) segment rates after the Pension Protection Act - lookback periods, stability periods, and transition rules. Plans may specify a lookback month of 1-5 months prior to the stability period start; the specific month for a given plan is in the plan document.<br><a href="https://www.irs.gov/pub/irs-drop/rr-07-67.pdf?ref=tomharveytraining.com" rel="noopener nofollow">https://www.irs.gov/pub/irs-drop/rr-07-67.pdf</a></li><li><strong>IRS &#xA7;417(e) unisex mortality table notices (updated annually)</strong><br>IRS Notice 2024-42 is the reference for annuity starting dates in 2025 and serves as the example in this article. For other plan years, search IRS.gov for the current &#xA7;417(e) unisex mortality table notice. Reference example (2025 plan year): <a href="https://www.irs.gov/pub/irs-drop/n-24-42.pdf?ref=tomharveytraining.com" rel="noopener nofollow">https://www.irs.gov/pub/irs-drop/n-24-42.pdf</a></li><li><strong>Pension Protection Act of 2006, Public Law 109-280</strong><br>The legislation that replaced the GATT treasury rate with the three-segment corporate bond methodology.<br><a href="https://www.congress.gov/109/plaws/publ280/PLAW-109publ280.pdf?ref=tomharveytraining.com" rel="noopener nofollow">https://www.congress.gov/109/plaws/publ280/PLAW-109publ280.pdf</a></li><li><strong>Treasury HQM Corporate Bond Yield Curve</strong><br>Source data from which the IRS derives the segment rates. Published monthly by the U.S. Treasury.<br><a href="https://home.treasury.gov/data/treasury-bulletin?ref=tomharveytraining.com" rel="noopener nofollow">https://home.treasury.gov/data/treasury-bulletin</a></li><li><strong>ERISA &#xA7;105 - Benefit statement rights</strong><br>Your right to a benefit statement and plan document disclosure on request.<br><a href="https://www.dol.gov/general/topic/retirement/erisa?ref=tomharveytraining.com" rel="noopener nofollow">https://www.dol.gov/general/topic/retirement/erisa</a></li><li><strong>Source code - harvey267/ntca-calculator</strong><br>Full Python implementation of the &#xA7;417(e) lump sum model, including CLI and Streamlit dashboard.<br><a href="https://github.com/harvey267/ntca-calculator?ref=tomharveytraining.com" rel="noopener nofollow">https://github.com/harvey267/ntca-calculator</a></li></ul><hr><p><em>All calculations are estimates based on publicly available IRS rules and reverse-engineered NTCA methodology. Verify with NTCA directly for official benefit amounts.</em></p>]]></content:encoded></item><item><title><![CDATA[The Architecture of Resistance: Why Speed Destroys Unaligned Systems]]></title><description><![CDATA[Systems fail from the inside out. Jeet Kune Do princple: True structural integrity relies on mapping the dependencies before the impact hits. ]]></description><link>https://www.tomharveytraining.com/the-architecture-of-resistance-why-speed-destroys-unaligned-systems/</link><guid isPermaLink="false">6a186a5f8ac21900014ccf94</guid><category><![CDATA[The Signal]]></category><dc:creator><![CDATA[Thomas Harvey]]></dc:creator><pubDate>Sun, 31 May 2026 14:25:48 GMT</pubDate><media:content url="https://storage.ghost.io/c/c4/dc/c4dcef1a-ac8f-4b6b-9334-63e32b1fa558/content/images/2026/05/SIG_THe_Arch_Resist.png" medium="image"/><content:encoded><![CDATA[<h2 id="the-signal-the-systems-discipline">The Signal: The Systems Discipline</h2><hr><img src="https://storage.ghost.io/c/c4/dc/c4dcef1a-ac8f-4b6b-9334-63e32b1fa558/content/images/2026/05/SIG_THe_Arch_Resist.png" alt="The Architecture of Resistance: Why Speed Destroys Unaligned Systems"><p>Speed is not an input. Speed is a byproduct of alignment.</p><p>When you force a timeline, you generate friction. Friction is heat. Heat destroys structures. This is the mechanical reality of systems. It holds true whether you are managing a global network, manipulating a joint, or shaping a physical object.</p><p>People confuse velocity with progress. They believe moving faster forces the system to comply. But complex systems have a maximum absorbable rate of change. Exceed it, and the system does not accelerate. It fractures.</p><hr><h2 id="the-material-dictates-the-pace">The Material Dictates the Pace</h2><p>Take a piece of Claro Walnut on a lathe. The wood has a specific density. It has grain direction. It holds internal tension from decades of growth. If you force the gouge into the spinning wood faster than the material can shear, you do not finish the bowl faster. You tear the end grain. You splinter the piece. You ruin the work.</p><p>The lathe operates at its speed. The material accepts the cut at its speed. You cannot command the wood to ignore its own physics. The discipline is listening and matching the feed rate to the reality of the medium.</p><hr><h2 id="the-studio">The Studio</h2><p>The same principle governs striking. When you force a punch, you abandon structure. You trade mechanical alignment for physical velocity. The moment you push for speed, muscle tension takes over. Tension acts as a restrictor valve. It freezes the joints that need to act as fluid conduits for the energy. You overextend and create the exact gap your opponent needs to intercept.</p><p>More critically, you sever the kinetic chain. Power does not live in the fist. It originates in the earth. Energy travels upward through the legs. It transfers through the rotation of the hips. It crosses the body through the posterior oblique sling. This system transfers rotational energy diagonally across the back. It is the literal bridge that carries power from the planted back foot to the striking shoulder. Within this architecture, every joint is a node. A joint either adds power, loses power through energy leakage, or remains neutral.</p><p>When you rush the movement, you disconnect the upper body from its foundation. The arm fires independently. You might gain a fraction of a second, but you leave your mass behind. You generate speed, but you deliver far less consequence. A strike without mass is just motion.</p><p>In Jeet Kune Do, you do not hit first by moving faster. You arrive first by eliminating the telegraph. You rely on economy of motion. You align your center of gravity so the physical structure supports the weapon from the ground to the point of impact. The strike lands because you removed every unnecessary movement between origin and target. Speed is simply the symptom of perfect timing meeting zero resistance.</p><hr><h2 id="the-network">The Network</h2><p>In large scale integration, forcing data or new protocols through an unoptimized architecture does not increase throughput. It creates bottlenecks. It introduces packet loss and latency. The system throttles itself to survive the friction you introduced.</p><p>You do not make a network faster by pushing harder. You make it faster by removing the structural constraints.</p><hr><h2 id="the-friction-protocol">The Friction Protocol</h2><p>If your process requires you to rush, your architecture is flawed.</p><p>The disciplined operator recognizes the maximum absorbable rate of change. You do not push the system past its structural limit. You align the variables. You remove the noise. You reduce the friction.</p><p>When the alignment is perfect, speed takes care of itself.</p>]]></content:encoded></item><item><title><![CDATA[Evaluating Local LLMs on Network Tasks: The Right Tool (Part 1)]]></title><description><![CDATA[Six local LLMs tested against five real network lab tasks. A baseline cold start run exposing the gap between assumed hardware capability and actual execution.]]></description><link>https://www.tomharveytraining.com/the-right-tool-part-1-local-llm-network-testing/</link><guid isPermaLink="false">6a122f8235c79200013e9579</guid><category><![CDATA[The Right Tool]]></category><category><![CDATA[local LLM]]></category><category><![CDATA[homelab AI]]></category><category><![CDATA[benchmark]]></category><category><![CDATA[Ollama]]></category><category><![CDATA[containerlab]]></category><category><![CDATA[SR Linux]]></category><category><![CDATA[network engineering]]></category><category><![CDATA[THT Systems]]></category><category><![CDATA[The Thinking Network]]></category><dc:creator><![CDATA[Thomas Harvey]]></dc:creator><pubDate>Fri, 29 May 2026 11:00:26 GMT</pubDate><media:content url="https://storage.ghost.io/c/c4/dc/c4dcef1a-ac8f-4b6b-9334-63e32b1fa558/content/images/2026/05/Part1.jpg" medium="image"/><content:encoded><![CDATA[<hr><h2 id="cold-start">Cold Start</h2><hr><img src="https://storage.ghost.io/c/c4/dc/c4dcef1a-ac8f-4b6b-9334-63e32b1fa558/content/images/2026/05/Part1.jpg" alt="Evaluating Local LLMs on Network Tasks: The Right Tool (Part 1)"><p>The question driving this test was not academic. An autonomous network lab running SR Linux on containerlab requires specific capabilities. It needs to triage BGP events in real time, interpret telemetry, generate topology configs, and write post-session technical summaries. These are the actual tasks. The question was: which local models can handle them, at what cost, and where does each one belong in the system?</p><hr><h3 id="the-hardware">The Hardware</h3><p>Dell Precision 3571. Intel Core i7-12700H: 6 P-cores, 8 E-cores, 20 threads. 16GB DDR5. NVIDIA T600 4GB VRAM.</p><p>The plan was to characterize models against this memory envelope: which fit inside 4GB VRAM, which spill to system RAM, and what that costs in throughput. A 3.8B or 4B model at 4-bit quantization fits inside the T600. A 7B or above does not. The plan was to capture the performance cliff.</p><p>The reality was different. I&apos;ll get to that.</p><hr><h3 id="the-models">The Models</h3><p>I wasn&apos;t looking for the most capable model in isolation. I was looking for what actually runs on this hardware, within this VRAM envelope, at usable latency for a voice loop.</p>
<!--kg-card-begin: html-->
<table>
<thead>
<tr>
<th align="left">Model</th>
<th align="left">Parameters</th>
<th align="left">Expected Resource Use</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left">Phi-3.5 Mini</td>
<td align="left">3.8B</td>
<td align="left">Full VRAM</td>
</tr>
<tr>
<td align="left">Gemma 3 4B</td>
<td align="left">4.0B</td>
<td align="left">Full VRAM</td>
</tr>
<tr>
<td align="left">Qwen 2.5 Coder 7B</td>
<td align="left">7.0B</td>
<td align="left">CPU spill</td>
</tr>
<tr>
<td align="left">Llama 3.1 8B</td>
<td align="left">8.0B</td>
<td align="left">CPU spill</td>
</tr>
<tr>
<td align="left">Gemma 3 12B</td>
<td align="left">12.0B</td>
<td align="left">Heavy CPU spill</td>
</tr>
<tr>
<td align="left">Claude Haiku 4.5</td>
<td align="left">N/A</td>
<td align="left">API / Cloud</td>
</tr>
</tbody>
</table>
<!--kg-card-end: html-->
<p>Claude Haiku 4.5 is the calibration baseline. If a local model can match it on these tasks, it earns its place in the architecture. If not, that&apos;s also useful information.</p><p>Haiku is not here to win. It&apos;s here to define what &quot;good enough&quot; looks like.</p><hr><h3 id="the-tasks">The Tasks</h3><p>Five tasks. All derived from actual lab operations. Not benchmarking conventions.</p><p><strong>T1: Structured Data Summarization</strong><br>A raw table of BGP session metrics. Uptime, prefix counts, reset counts, state flags. Generate a plain-English summary for an ops handoff. Identify any breach condition in the data.</p><p>The failure mode here is specific: does the model report what the data says, or does it generate a plausible-sounding narrative that contradicts the data?</p><p><strong>T2: BGP Event Triage</strong><br>A sequence of BGP log events across multiple peers. Classify each event. Identify the most likely root cause. Recommend an action.</p><p>The data contains the answer. The question is whether the model finds it or invents one.</p><p><strong>T3: Containerlab Topology Generation</strong><br>Generate a valid containerlab YAML topology: 13 nodes, 8 links, SR Linux images, specific naming conventions. Auto-validated on three checks: YAML validity, node count, link count.</p><p>This is the hardest task in the set. It requires structural precision (valid YAML), semantic accuracy (correct node and link definitions), and domain knowledge of the containerlab schema. There&apos;s no partial credit. A topology with 13 nodes but broken link syntax doesn&apos;t deploy.</p><p><strong>T4: React NodeStatus Component</strong><br>Write a functional React component that displays node status for a network element. Auto-checked for JSX structure including export default.</p><p>The lab visualizer is a production system. This isn&apos;t a toy task.</p><p><strong>T5: Python gNMI BGP Poller</strong><br>Write a Python script that uses gNMI to poll BGP neighbor state from an SR Linux node. Auto-checked for valid Python syntax.</p><p>This mirrors code running in the lab now.</p><hr><h3 id="what-happened">What Happened</h3><p>Auto-checks came back before I&apos;d read all the outputs.</p><p>T3 separated the field.</p>
<!--kg-card-begin: html-->
<table>
<thead>
<tr>
<th align="left">Model</th>
<th align="left">YAML Valid</th>
<th align="left">Nodes (13)</th>
<th align="left">Links (8)</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left">Phi-3.5 Mini</td>
<td align="left">FAIL</td>
<td align="left">&#x2014;</td>
<td align="left">&#x2014;</td>
</tr>
<tr>
<td align="left">Gemma 3 4B</td>
<td align="left">PASS</td>
<td align="left">FAIL (0)</td>
<td align="left">FAIL (0)</td>
</tr>
<tr>
<td align="left">Qwen 2.5 Coder 7B</td>
<td align="left">PASS</td>
<td align="left">PASS</td>
<td align="left">PASS</td>
</tr>
<tr>
<td align="left">Llama 3.1 8B</td>
<td align="left">PASS</td>
<td align="left">FAIL (0)</td>
<td align="left">FAIL (0)</td>
</tr>
<tr>
<td align="left">Gemma 3 12B</td>
<td align="left">TIMEOUT</td>
<td align="left">&#x2014;</td>
<td align="left">&#x2014;</td>
</tr>
<tr>
<td align="left">Claude Haiku 4.5</td>
<td align="left">PASS</td>
<td align="left">PASS</td>
<td align="left">PASS</td>
</tr>
</tbody>
</table>
<!--kg-card-end: html-->
<p>The failure modes are not equivalent, and they matter for routing decisions:</p><figure class="kg-card kg-image-card"><img src="https://storage.ghost.io/c/c4/dc/c4dcef1a-ac8f-4b6b-9334-63e32b1fa558/content/images/2026/05/01_t3_failure_taxonomy.png" class="kg-image" alt="Evaluating Local LLMs on Network Tasks: The Right Tool (Part 1)" loading="lazy" width="2000" height="831" srcset="https://storage.ghost.io/c/c4/dc/c4dcef1a-ac8f-4b6b-9334-63e32b1fa558/content/images/size/w600/2026/05/01_t3_failure_taxonomy.png 600w, https://storage.ghost.io/c/c4/dc/c4dcef1a-ac8f-4b6b-9334-63e32b1fa558/content/images/size/w1000/2026/05/01_t3_failure_taxonomy.png 1000w, https://storage.ghost.io/c/c4/dc/c4dcef1a-ac8f-4b6b-9334-63e32b1fa558/content/images/size/w1600/2026/05/01_t3_failure_taxonomy.png 1600w, https://storage.ghost.io/c/c4/dc/c4dcef1a-ac8f-4b6b-9334-63e32b1fa558/content/images/2026/05/01_t3_failure_taxonomy.png 2066w" sizes="(min-width: 720px) 720px"></figure><ul><li><strong>Schema hallucination (Phi-3.5):</strong> broken YAML structure. The model invented syntax that doesn&apos;t exist in the containerlab spec.</li><li><strong>Schema layer error (Gemma 4B, Llama 8B):</strong> valid YAML, wrong semantics. The model understood the format but misplaced the node definitions.</li><li><strong>Generation refusal (Gemma 12B):</strong> produced prose instead of YAML. An instruction-following failure, not a capability gap.</li><li><strong>Clean pass (Qwen, Haiku):</strong> deployable output on first shot.</li></ul><p>A model that generates wrong-but-parseable YAML can potentially be corrected with a better-structured prompt. A model that refuses to generate YAML at all has a different kind of problem. These are not the same failure and they don&apos;t get solved the same way.</p><p><strong>T1 surfaced a sharper issue with Phi-3.5.</strong></p><p>The BGP metric table contained a clear breach condition: a session that had exceeded the reset threshold. Phi-3.5 read the table and reported: &quot;No threshold breaches were detected.&quot;</p><p>That&apos;s not a format failure. The model processed the data and returned a false negative. In an ops context, a false negative on a breach condition is worse than no answer. It signals the all-clear when it shouldn&apos;t.</p><p><strong>T4 and T5 failed for Haiku. But not because of Haiku.</strong></p><p>Haiku&apos;s T4 output was cut off before export default. T5 had a syntax error at line 61. Both failures traced to the same cause: I calibrated token budgets (700 for T4, 600 for T5) against local model verbosity. Haiku generates more complete, more thoroughly structured code. It hit the token ceiling mid-component and got cut off.</p><p>The test penalized thoroughness. That&apos;s a test design error, not a model error. It gets corrected in Part 2.</p><hr><h3 id="the-hardware-finding">The Hardware Finding</h3><p>Expected throughput: 15&#x2013;20 tok/s for VRAM-resident models, 8&#x2013;12 tok/s for CPU-spill models. A clear performance cliff at the 4GB boundary.</p><p>What I got: consistent throughput regardless of model size. Phi-3.5 at 19 tok/s. Qwen at 9 tok/s. Gemma 3 4B at 16 tok/s. The pattern I expected wasn&apos;t there.</p><p>Mid-run I checked <code>ollama ps</code>:</p><pre><code>NAME               SIZE     PROCESSOR    UNTIL
phi3.5:latest      3.7 GB   100% CPU     4 minutes from now
</code></pre><p>Then <code>nvidia-smi</code>:</p><pre><code>memory.used [MiB]: 5 MiB
utilization.gpu [%]: 0 %
</code></pre><p>The T600 was idle. Every token in this benchmark was generated by the i7-12700H.</p><figure class="kg-card kg-image-card"><img src="https://storage.ghost.io/c/c4/dc/c4dcef1a-ac8f-4b6b-9334-63e32b1fa558/content/images/2026/05/04_hardware_stack.png" class="kg-image" alt="Evaluating Local LLMs on Network Tasks: The Right Tool (Part 1)" loading="lazy" width="1368" height="1129" srcset="https://storage.ghost.io/c/c4/dc/c4dcef1a-ac8f-4b6b-9334-63e32b1fa558/content/images/size/w600/2026/05/04_hardware_stack.png 600w, https://storage.ghost.io/c/c4/dc/c4dcef1a-ac8f-4b6b-9334-63e32b1fa558/content/images/size/w1000/2026/05/04_hardware_stack.png 1000w, https://storage.ghost.io/c/c4/dc/c4dcef1a-ac8f-4b6b-9334-63e32b1fa558/content/images/2026/05/04_hardware_stack.png 1368w" sizes="(min-width: 720px) 720px"></figure><p><strong>Root cause:</strong> Ollama needs the CUDA runtime to drive GPU inference, not just the NVIDIA driver. The driver was present (595.71.05). The CUDA runtime was not. <code>nvcc</code> absent. <code>libcudart</code> absent. <code>libcublas</code> absent. Ollama detected no viable GPU compute path and fell back to CPU without warning. An Ollama server/client version mismatch (0.23.2 vs 0.24.0) compounded the silence.</p><p>This means the hardware characterization I planned: VRAM-resident versus CPU-spill curves, T600 thermal behavior under sustained inference, actual VRAM utilization by model size, is unanswerable from this data. All tok/s figures are i7-12700H CPU throughput. The T600 is a spectator.</p><figure class="kg-card kg-image-card"><img src="https://storage.ghost.io/c/c4/dc/c4dcef1a-ac8f-4b6b-9334-63e32b1fa558/content/images/2026/05/03_throughput_reality.png" class="kg-image" alt="Evaluating Local LLMs on Network Tasks: The Right Tool (Part 1)" loading="lazy" width="1707" height="1038" srcset="https://storage.ghost.io/c/c4/dc/c4dcef1a-ac8f-4b6b-9334-63e32b1fa558/content/images/size/w600/2026/05/03_throughput_reality.png 600w, https://storage.ghost.io/c/c4/dc/c4dcef1a-ac8f-4b6b-9334-63e32b1fa558/content/images/size/w1000/2026/05/03_throughput_reality.png 1000w, https://storage.ghost.io/c/c4/dc/c4dcef1a-ac8f-4b6b-9334-63e32b1fa558/content/images/size/w1600/2026/05/03_throughput_reality.png 1600w, https://storage.ghost.io/c/c4/dc/c4dcef1a-ac8f-4b6b-9334-63e32b1fa558/content/images/2026/05/03_throughput_reality.png 1707w" sizes="(min-width: 720px) 720px"></figure><p>The quality results stand. Where computation happens doesn&apos;t change what the model outputs. But every throughput number needs to be read as CPU-bound inference on a 20-thread i7. This is documented as a finding, not cleaned up and hidden. It&apos;s what actually happened.</p><hr><h3 id="the-scores">The Scores</h3><p>Scored across five dimensions: accuracy, completeness, format compliance, operational clarity, code quality. 100 points total.</p><figure class="kg-card kg-image-card"><img src="https://storage.ghost.io/c/c4/dc/c4dcef1a-ac8f-4b6b-9334-63e32b1fa558/content/images/2026/05/02_score_comparison.png" class="kg-image" alt="Evaluating Local LLMs on Network Tasks: The Right Tool (Part 1)" loading="lazy" width="1872" height="954" srcset="https://storage.ghost.io/c/c4/dc/c4dcef1a-ac8f-4b6b-9334-63e32b1fa558/content/images/size/w600/2026/05/02_score_comparison.png 600w, https://storage.ghost.io/c/c4/dc/c4dcef1a-ac8f-4b6b-9334-63e32b1fa558/content/images/size/w1000/2026/05/02_score_comparison.png 1000w, https://storage.ghost.io/c/c4/dc/c4dcef1a-ac8f-4b6b-9334-63e32b1fa558/content/images/size/w1600/2026/05/02_score_comparison.png 1600w, https://storage.ghost.io/c/c4/dc/c4dcef1a-ac8f-4b6b-9334-63e32b1fa558/content/images/2026/05/02_score_comparison.png 1872w" sizes="(min-width: 720px) 720px"></figure>
<!--kg-card-begin: html-->
<table>
<thead>
<tr>
<th><strong>Model</strong></th>
<th><strong>Score</strong></th>
<th><strong>Notes</strong></th>
</tr>
</thead>
<tbody>
<tr>
<td>Qwen 2.5 Coder 7B</td>
<td>83/100</td>
<td>Only local model to pass T3</td>
</tr>
<tr>
<td>Gemma 3 4B</td>
<td>81/100</td>
<td>T3 structural failure; T4/T5 clean</td>
</tr>
<tr>
<td>Claude Haiku 4.5</td>
<td>76/100*</td>
<td>T4/T5 scores reflect token truncation, not output quality</td>
</tr>
<tr>
<td>Gemma 3 12B</td>
<td>73/100</td>
<td>T3 generation refusal; 6 tok/s under CPU load</td>
</tr>
<tr>
<td>Llama 3.1 8B</td>
<td>67/100</td>
<td>T3 valid YAML, zero nodes</td>
</tr>
<tr>
<td>Phi-3.5 Mini</td>
<td>54/100</td>
<td>T1 false negative on breach; T3 malformed YAML</td>
</tr>
</tbody>
</table>
<!--kg-card-end: html-->
<p>*Haiku&apos;s actual capability is higher than this number. Part 2 corrects the test design.</p><p>Gemma 3 12B at 73 is the most misleading number in the table. More parameters did not produce better outputs. It scored reasonably on the non-T3 tasks, but at 6 tok/s CPU-bound and a T3 generation refusal, the latency cost alone makes it a difficult fit for anything in the voice loop. At 6 tok/s, a 1,400-token topology requires at least 230 seconds just to print. The test enforced a 300-second timeout. I didn&apos;t give the model a generation refusal. I gave it a stopwatch it couldn&apos;t beat. You pay more, wait longer, and get a prose description when you needed YAML.</p><p>Phi-3.5 at 54 reflects a model that is fast but not reliable for ops data interpretation. A false negative on a breach condition is a disqualifying failure for triage tasks.</p><hr><h3 id="where-this-leaves-things">Where This Leaves Things</h3><p><strong>T3 is the gate.</strong> Pass it and you&apos;re in the conversation for routing to topology and config generation tasks. Fail it and you&apos;re limited to triage and summarization. One local model passed: Qwen 2.5 Coder 7B.</p><p><strong>The latency question is open.</strong> Haiku responds in 3&#x2013;6 seconds at 200+ tok/s via API. Qwen T3 took 157 seconds on CPU. For topology generation as a background task, 157 seconds is acceptable if the output deploys clean. For anything in the voice loop, it&apos;s not.</p><p><strong>The GPU question is completely unanswered.</strong> Nothing about these results tells us what happens when the T600 is actually doing the work.</p><p><strong>The test design had a flaw</strong> that disadvantaged the calibration baseline. It&apos;s corrected in Part 2: extended token budgets for T4 (1000 tokens) and T5 (900 tokens), extended timeout for the 12B model, and hardware monitoring active throughout.</p><p><strong>Part 2: every model gets its best shot. Then we score what we see.</strong></p><hr><p><em>The Right Tool is a field series on local LLM deployment in a live network lab. Part 2 covers the corrected test. Part 3 covers GPU-enabled hardware characterization after CUDA installation.</em></p>]]></content:encoded></item><item><title><![CDATA[The Thinking Network (Installment 5): IS-IS Routing & The Network Underlay]]></title><description><![CDATA[Installment 5 of The Thinking Network. We configure the network underlay using the IS-IS link-state routing protocol to build the foundational topology for autonomous SR Linux routers.]]></description><link>https://www.tomharveytraining.com/the-thinking-network-installment-5-isis-underlay/</link><guid isPermaLink="false">6a0cb31d7fd5980001123d2b</guid><category><![CDATA[The Thinking Network]]></category><dc:creator><![CDATA[Thomas Harvey]]></dc:creator><pubDate>Wed, 27 May 2026 11:00:53 GMT</pubDate><media:content url="https://storage.ghost.io/c/c4/dc/c4dcef1a-ac8f-4b6b-9334-63e32b1fa558/content/images/2026/05/Installment5.jpg" medium="image"/><content:encoded><![CDATA[<hr><img src="https://storage.ghost.io/c/c4/dc/c4dcef1a-ac8f-4b6b-9334-63e32b1fa558/content/images/2026/05/Installment5.jpg" alt="The Thinking Network (Installment 5): IS-IS Routing &amp; The Network Underlay"><p><strong>Architecture Overview: Phase 5 (The Underlay)</strong></p><ul><li><strong>Objective:</strong> Establish the foundational routing underlay required for upper-level autonomous control.</li><li><strong>Core Technologies:</strong> IS-IS (Intermediate System to Intermediate System), Link-State Routing Protocols, Nokia SR Linux.</li><li><strong>The Goal:</strong> Establish IS-IS adjacencies and distribute loopback reachability across all four nodes, providing the stable underlay that BGP sessions and EVPN services depend on.</li></ul><hr><h2 id="the-underlay">The Underlay</h2><p>The containers are running. The NOS has finished initializing. The diamond fabric exists as a physical fact - four routers, eight virtual links, a management network, a telemetry stack.</p><p>None of it can route a packet yet.</p><p>The routers know their own addresses. They do not know how to reach each other. A packet leaving srl1 destined for srl4 has no path. Not because the physical connection is missing - the links exist. Because the network has not yet learned its own shape.</p><p>IS-IS is how it learns.</p><hr><h3 id="what-is-is-is">What IS-IS Is</h3><p>IS-IS (Intermediate System to Intermediate System) is a link-state routing protocol. It has been running carrier backbone networks since the 1980s and still operates under a significant portion of the internet core today. It is one of the oldest and most resilient routing protocols in existence.</p><p>The way it works is essentially a conversation. Each router tells its neighbors what it can see. Those neighbors tell their neighbors. The information floods through the network until every router has a complete picture of the whole topology. That picture is the link-state database.</p><p>From that shared database, each router independently runs Dijkstra&apos;s algorithm to calculate the shortest path to every other node. It is not magic. It is just math.</p><p>Imagine the network from the perspective of <code>srl1</code> trying to reach <code>srl4</code>. <code>srl1</code> looks at its map and evaluates the cost of every possible path. Path A goes through <code>srl2</code>. The link to <code>srl2</code> has a metric cost of 10, and the next hop to <code>srl4</code> costs 10, making the total cost 20. Path B goes through <code>srl3</code>. It also consists of two 10-cost links, totaling 20.</p><p>Dijkstra&apos;s algorithm strictly selects the lowest number. In our diamond fabric, both paths cost exactly 20. Because there is a mathematical tie, IS-IS does exactly what modern routing protocols are designed to do. It installs both paths into the routing table and enables Equal-Cost Multi-Path (ECMP) routing. Traffic splits evenly across both sides of the diamond.</p><h4 id="the-blind-spot-and-the-ai-objective">The Blind Spot and the AI Objective</h4><p>This distributed, mathematical intelligence is what makes IS-IS incredibly resilient. Every node calculates its own table from the same shared information. If a physical link fails, the routers immediately detect the loss, flood updated information and recalculate. Convergence happens in seconds without any human intervention.</p><p>Dijkstra only understands static link metrics. It is completely blind to real-time network performance. If Path A starts experiencing microbursts, buffer bloat, or rising latency, IS-IS does not care. As long as the physical link remains up, the metric cost remains 20. The protocol will happily continue sending fifty percent of your traffic straight into a degraded path.</p><p>To overcome this, the AI layer sits above the base routing protocol. The AI does not need to manage basic connectivity or physical link failures because IS-IS handles that perfectly. Instead, it monitors telemetry, predicts latency degradation before it causes a service impact, and forcefully steers traffic away from the impacted path by manipulating the BGP overlay.</p><p>IS-IS provides the stable, self-healing foundation. The AI provides the intelligence to override the math when the math is no longer enough.</p><hr><h3 id="what-is-is-does-not-do">What IS-IS Does Not Do</h3><p>IS-IS routes within a single administrative domain. It knows the shape of this network - these four nodes, these eight links. It does not carry service routes. It does not carry VPN information. It does not distribute BGP prefixes.</p><p>That is BGP&apos;s job. But BGP sessions in this lab use loopback IP addresses as their source - which means BGP cannot form until IS-IS has distributed those loopbacks across the network. IS-IS is the foundation BGP stands on.</p><hr><h3 id="configuring-is-is-by-hand">Configuring IS-IS by Hand</h3><p>If there were no automation in this lab - no Python scripts, no startup configs - this is what you would type into each node&apos;s CLI to bring IS-IS up.</p><p>SR Linux uses a candidate/commit model. Changes are staged and then committed atomically. Nothing takes effect until you commit.</p><p><strong>srl1:</strong></p><pre><code>--{ candidate }--[ ]--
A:srl1# set / network-instance default protocols isis instance 1 admin-state enable
A:srl1# set / network-instance default protocols isis instance 1 net [ 49.0001.0000.0000.0001.00 ]
A:srl1# set / network-instance default protocols isis instance 1 level-capability L2
A:srl1# set / network-instance default protocols isis instance 1 interface system0.0 passive true ipv4-unicast admin-state enable
A:srl1# set / network-instance default protocols isis instance 1 interface ethernet-1/1.0 circuit-type point-to-point ipv4-unicast admin-state enable
A:srl1# set / network-instance default protocols isis instance 1 interface ethernet-1/2.0 circuit-type point-to-point ipv4-unicast admin-state enable
A:srl1# commit stay
</code></pre><p><strong>srl2:</strong></p><pre><code>A:srl2# set / network-instance default protocols isis instance 1 admin-state enable
A:srl2# set / network-instance default protocols isis instance 1 net [ 49.0001.0000.0000.0002.00 ]
A:srl2# set / network-instance default protocols isis instance 1 level-capability L2
A:srl2# set / network-instance default protocols isis instance 1 interface system0.0 passive true ipv4-unicast admin-state enable
A:srl2# set / network-instance default protocols isis instance 1 interface ethernet-1/1.0 circuit-type point-to-point ipv4-unicast admin-state enable
A:srl2# set / network-instance default protocols isis instance 1 interface ethernet-1/2.0 circuit-type point-to-point ipv4-unicast admin-state enable
A:srl2# commit stay
</code></pre><p><strong>srl3:</strong></p><pre><code>A:srl3# set / network-instance default protocols isis instance 1 admin-state enable
A:srl3# set / network-instance default protocols isis instance 1 net [ 49.0001.0000.0000.0003.00 ]
A:srl3# set / network-instance default protocols isis instance 1 level-capability L2
A:srl3# set / network-instance default protocols isis instance 1 interface system0.0 passive true ipv4-unicast admin-state enable
A:srl3# set / network-instance default protocols isis instance 1 interface ethernet-1/1.0 circuit-type point-to-point ipv4-unicast admin-state enable
A:srl3# set / network-instance default protocols isis instance 1 interface ethernet-1/2.0 circuit-type point-to-point ipv4-unicast admin-state enable
A:srl3# commit stay
</code></pre><p><strong>srl4:</strong></p><pre><code>A:srl4# set / network-instance default protocols isis instance 1 admin-state enable
A:srl4# set / network-instance default protocols isis instance 1 net [ 49.0001.0000.0000.0004.00 ]
A:srl4# set / network-instance default protocols isis instance 1 level-capability L2
A:srl4# set / network-instance default protocols isis instance 1 interface system0.0 passive true ipv4-unicast admin-state enable
A:srl4# set / network-instance default protocols isis instance 1 interface ethernet-1/1.0 circuit-type point-to-point ipv4-unicast admin-state enable
A:srl4# set / network-instance default protocols isis instance 1 interface ethernet-1/2.0 circuit-type point-to-point ipv4-unicast admin-state enable
A:srl4# commit stay
</code></pre><p>Four nodes. Seven commands each. One value changing between them.</p><p>The NET ID - Network Entity Title - encodes each node&apos;s identity. <code>49.0001.0000.0000.0001.00</code> means area <code>49.0001</code>, system ID <code>0000.0000.0001</code>. The system ID derives from the site ID using the same pattern the Python script uses. Site 1 is <code>0000.0000.0001</code>. Site 4 is <code>0000.0000.0004</code>. Consistent and never ambiguous.</p><p><code>level-capability L2</code> configures Level 2 routing only - backbone behavior. There are no Level 1 areas in this lab.</p><p><code>passive true</code> on system0.0 means IS-IS advertises that loopback address into the domain but does not try to form adjacencies on it. The loopback is a destination, not a link.</p><p><code>circuit-type point-to-point</code> on the ethernet interfaces - two routers, one wire. No DR/BDR election. Clean.</p><hr><h3 id="what-the-startup-config-does-instead">What the Startup Config Does Instead</h3><p>The Python script generates these commands into a <code>.cfg</code> file for each node at Phase 2. When ContainerLab deploys the container at Phase 3, SR Linux loads that file at boot. IS-IS starts configured, without any manual input.</p><p>The NET ID generation in the script:</p><pre><code class="language-python">net_id = f&quot;49.0001.0000.0000.000{sid}.00&quot;
</code></pre><p>Site 1 produces <code>49.0001.0000.0000.0001.00</code>. Site 4 produces <code>49.0001.0000.0000.0004.00</code>. The rest of the IS-IS configuration is identical across all four nodes. The script writes it once and applies it four times with the correct site-specific values substituted.</p><hr><h3 id="verification">Verification</h3><p>After the nodes initialize:</p><pre><code class="language-Bash">docker exec clab-nbl-diamond-v1-srl1 sr_cli \
  -c &quot;show network-instance default protocols isis adjacency&quot;
</code></pre><pre><code>+----------------+--------------------+-------+---------------+-------+
| Interface Name | Neighbor System Id | Level |  Ip Address   | State |
+================+====================+=======+===============+=======+
| ethernet-1/1.0 | 0000.0000.0002     | L2    | 172.254.254.2 | up    |
| ethernet-1/2.0 | 0000.0000.0003     | L2    | 172.254.254.6 | up    |
+----------------+--------------------+---------+-------------+-------+
Adjacency Count: 2
</code></pre><p>srl1 sees srl2 on ethernet-1/1 and srl3 on ethernet-1/2. Both Level 2. Both <code>up</code>.</p><p>The route table shows what IS-IS has learned:</p><pre><code>Prefix               Route Type   Metric   Next-Hop(s)
172.2.255.255/32     isis         10       172.254.254.2(ethernet-1/1.0)
172.3.255.255/32     isis         10       172.254.254.6(ethernet-1/2.0)
172.4.255.255/32     isis         20       172.254.254.2(ethernet-1/1.0)
</code></pre><p>srl1 knows where every other loopback is. The path to srl4 goes through srl2 - Path A, metric 20, two hops. The network has learned its own shape.</p><p>The IS-IS database:</p><pre><code>| 2 | 0000.0000.0001.00-00 | 8 | 1165 |
| 2 | 0000.0000.0002.00-00 | 7 | 588  |
| 2 | 0000.0000.0003.00-00 | 8 | 1114 |
| 2 | 0000.0000.0004.00-00 | 7 | 1068 |
LSP Count: 4
</code></pre><p>Four LSPs. One per node. The topology has been flooded. Every router holds the same database.</p><hr><h3 id="why-this-matters-for-the-ai-layer">Why This Matters for the AI Layer</h3><p>The AI layer does not touch IS-IS. It never modifies IS-IS configuration. IS-IS runs, converges, and maintains itself without any instruction from the intelligence layer above it.</p><p>What IS-IS gives the AI is a stable, self-healing foundation. Link fails - IS-IS reroutes. Node recovers - IS-IS re-converges. The AI does not manage these events. It assumes the underlay is working and focuses on the BGP control plane, which is the actual lever it pulls when it needs to steer traffic.</p><p>IS-IS is not the interesting part of this series. It is the necessary part. The next installment builds the layer the AI will actually reach into.</p><hr><p><em>Next installment: The Overlay. BGP forms a full mesh across the underlay. The control plane is complete. The AI&apos;s lever is installed.</em></p>]]></content:encoded></item><item><title><![CDATA[Mythology Entry: The Geometry of the Walk]]></title><description><![CDATA[The Walker returns. Step into the steady pulse of the city with 'Yellow Streetlights,' a lo-fi exploration of discipline, movement, and the geometry of the urban grid.]]></description><link>https://www.tomharveytraining.com/mythology-entry-the-geometry-of-the-walk/</link><guid isPermaLink="false">6a0f0da335c79200013e947b</guid><category><![CDATA[The Walker]]></category><category><![CDATA[Music]]></category><dc:creator><![CDATA[Thomas Harvey]]></dc:creator><pubDate>Thu, 21 May 2026 14:44:40 GMT</pubDate><media:content url="https://storage.ghost.io/c/c4/dc/c4dcef1a-ac8f-4b6b-9334-63e32b1fa558/content/images/2026/05/IMG_1272-1.PNG" medium="image"/><content:encoded><![CDATA[<img src="https://storage.ghost.io/c/c4/dc/c4dcef1a-ac8f-4b6b-9334-63e32b1fa558/content/images/2026/05/IMG_1272-1.PNG" alt="Mythology Entry: The Geometry of the Walk"><p>The Walker does not choose a direction. She chooses a rhythm.</p><p>In the architecture of THT, there are those who build walls and those who map the stars. The Hunter watches the horizon, waiting for a twitch in the brush that signals a beginning. The Sentinel stands in the center of the clearing, arms folded, defining the space that must be defended. They are defined by the geography of their station.</p><p>The Walker is the exception. She exists in the transition between stations.</p><p><em>Yellow Streetlights</em> captures the moment the city stops being a landscape and becomes a pulse. When the artificial amber light hums, it vibrates at a frequency only she hears. It is not about reaching a destination; it is about the physics of the gait. Every strike of the boot against the pavement is an act of erasure. By walking, she levels the ground, turning the chaotic grid of the city into a singular, unwavering line.</p><p>She references the others (the Hunter, the Sentinel) not as people she knows, but as echoes in the concrete. She senses the cold of the pine and the tension of the boundary, but they are static things. They are pinned to the earth. She is the kinetic energy that moves between them, holding the chaos at bay simply by refusing to stand still.</p><p>The map is a lie told to those who need to believe they are going somewhere. The Walker knows the truth: the path is not a destination. The path is the friction between the sole of a shoe and the hard, uncaring stone.</p><pre><code>[Verse 1] Streetlights buzz, a yellow glow The city sleeping down below Lace the boots and hit the gray Before the sun demands the day The rhythm starts before the thought This isn&apos;t something that is taught Put the foot down, find the beat The discipline is in the street

[Pre-Chorus] The empty block, the quiet air The only rule is being there No audience to keep the score Just the pavement and the core

[Chorus] One step forward, rhythm locks Shadows stretching down the blocks No one watching, no applause Moving to an older cause The map is just the concrete laid The path is how the steps are made

[Verse 2] Breath is steady, shoulders loose No performance, no excuse A distant train begins to roll The only witness is the soul The miles tick, the grid expands No weapons held inside the hands Just the tempo of the feet Beating on the empty street

[Pre-Chorus] The empty block, the quiet air The only rule is being there No audience to keep the score Just the pavement and the core

[Chorus] One step forward, rhythm locks Shadows stretching down the blocks No one watching, no applause Moving to an older cause The map is just the concrete laid The path is how the steps are made

[Bridge] The hunter had the frozen pine The sentinel, the boundary line I have the asphalt and the gray To hold the chaos at the bay I don&apos;t predict. I don&apos;t pretend. I walk the grid until the end.

[Final Chorus] One step forward, rhythm locks Shadows stretching down the blocks No one watching, no applause Moving to an older cause The map is just the concrete laid The path is how the steps are made Just this rhythm. Just this grade.</code></pre><h2 id="why-the-walker-matters">Why the Walker Matters</h2><p>The Walker, when she determines she needs to hold the chaos at bay, does not reprogram the environment. She does not touch the Hunter&#x2019;s brush or the Sentinel&#x2019;s boundary. She reaches into the rhythm and maintains the tempo.</p><p>She doesn&apos;t redesign the city; she walks it until the chaos yields to the frequency of her stride. She doesn&apos;t work around the city; she works through it.</p><hr><figure class="kg-card kg-bookmark-card"><a class="kg-bookmark-container" href="https://distrokid.com/hyperfollow/tomharvey1/yellow-streetlights/?ref=tomharveytraining.com"><div class="kg-bookmark-content"><div class="kg-bookmark-title">Yellow Streetlights by Tom Harvey</div><div class="kg-bookmark-description">Stream and Save Yellow Streetlights - Distributed by DistroKid</div><div class="kg-bookmark-metadata"><img class="kg-bookmark-icon" src="https://storage.ghost.io/c/c4/dc/c4dcef1a-ac8f-4b6b-9334-63e32b1fa558/content/images/icon/favicon-e8bb9d78-9ccb-4f9f-9883-1dc137d0e388.ico" alt="Mythology Entry: The Geometry of the Walk"><span class="kg-bookmark-author">DistroKid</span></div></div><div class="kg-bookmark-thumbnail"><img src="https://storage.ghost.io/c/c4/dc/c4dcef1a-ac8f-4b6b-9334-63e32b1fa558/content/images/thumbnail/http-3A-2F-2Fgather.fandalism.com-2F12587764--149ED946-D7DA-4F7F-89F1A59BDC111D1E--0--6452383--Yellowlightconcept-a63a80ec-3b3f-4dc1-abd3-a4717ec566db.png" alt="Mythology Entry: The Geometry of the Walk" onerror="this.style.display = &apos;none&apos;"></div></a></figure><figure class="kg-card kg-embed-card"><iframe style="border-radius: 12px" width="100%" height="152" title="Spotify Embed: Yellow Streetlights" frameborder="0" allowfullscreen allow="autoplay; clipboard-write; encrypted-media; fullscreen; picture-in-picture" loading="lazy" src="https://open.spotify.com/embed/track/4vaX6J8QDoM5zZBz5YgYwT?si=a685ff89d1d6476b&amp;utm_source=oembed"></iframe></figure><figure class="kg-card kg-embed-card"><iframe width="200" height="113" src="https://www.youtube.com/embed/videoseries?list=OLAK5uy_lulqrUbrb2HRjB5fDwycNaswIORY8PBo4" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></figure>]]></content:encoded></item><item><title><![CDATA[Conversation II: The Grain That Refused]]></title><description><![CDATA[Between what I bring and what's already there. I haven't always known which one leads.

Setting: Ósynilegr's studio. Morning. A bowl blank is mounted on the lathe. The floor has shavings. Not long enough that anything has emerged.]]></description><link>https://www.tomharveytraining.com/conversation-ii-the-grain-that-refused/</link><guid isPermaLink="false">69eb982ee0fb6d00015dd958</guid><category><![CDATA[Ósynilegr Handr]]></category><dc:creator><![CDATA[Thomas Harvey]]></dc:creator><pubDate>Thu, 21 May 2026 12:00:02 GMT</pubDate><media:content url="https://storage.ghost.io/c/c4/dc/c4dcef1a-ac8f-4b6b-9334-63e32b1fa558/content/images/2026/04/IMG_0781-2.png" medium="image"/><content:encoded><![CDATA[<hr><img src="https://storage.ghost.io/c/c4/dc/c4dcef1a-ac8f-4b6b-9334-63e32b1fa558/content/images/2026/04/IMG_0781-2.png" alt="Conversation II: The Grain That Refused"><p>Setting: &#xD3;synilegr&apos;s studio. Morning. A bowl blank is mounted on the lathe. The floor has shavings. Not long enough that anything has emerged.</p><hr><p>Artemisia: &quot;You shape the wood until it yields its hidden curve, yes? I do the same with light. Men think we just fancy things into existence, but they don&apos;t see the ache in the shoulder or the grit under the nails. Show me how you hold the gouge. Does it resist you, or do you make it an extension of your own arm?&quot;</p><p>&#xD3;synilegr looks at the gouge in his hand. Then at the blank.</p><p>&quot;Both. Depending on the day.&quot;</p><p>Artemisia: &quot;And today?&quot;</p><p>&quot;It&apos;s refusing.&quot;</p><p>She steps closer. Not to the wood. To his hands.</p><p>Artemisia: &quot;Where does it catch?&quot;</p><p>He runs the tool along the surface. The wood grabs. He lifts off.</p><p>&quot;There. Same place, three times now.&quot;</p><p>Artemisia: &quot;And you keep returning to it.&quot;</p><p>Not a question.</p><p>&#xD3;synilegr: &quot;It&apos;s where the answer is.&quot;</p><p>She looks at the caught place in the grain. The way it runs against everything around it.</p><p>Artemisia: &quot;What happens to the wood when you force past that?&quot;</p><p>&quot;It shows.&quot;</p><p>Artemisia: &quot;Always?&quot;</p><p>&quot;Always.&quot;</p><p>A pause. The lathe turns.</p><p>Artemisia: &quot;In paint it is the same. You can cover a bad passage. Build it up, glaze it over. But the surface remembers. Anyone who knows how to look can find it.&quot;</p><p>She watches him adjust his angle. Try again. The tool moves with the grain this time, not against it.</p><p>Artemisia: &quot;Is that restraint, or surrender?&quot;</p><p>He stops. The lathe slows.</p><p>The question sits in the room.</p><p>&quot;There&apos;s a dance in it,&quot; he says finally. &quot;Between what I bring and what&apos;s already there. I haven&apos;t always known which one leads.&quot;</p><p>Artemisia: &quot;And now?&quot;</p><p>&#xD3;synilegr turns back to the work.</p><p>&quot;Now I try to find out before I cut.&quot;</p><hr><p>The lathe resumes. The shavings fall. The bowl begins to open.</p><p>At some point the room shifts, quieter perhaps, or the light has moved. He does not look up to confirm it.</p><p>He stays with the wood.</p><p>His hands follow the grain that refused him.</p><hr>]]></content:encoded></item><item><title><![CDATA[The Thinking Network (Installment 4): Containerlab & The Fabric Deploy]]></title><description><![CDATA[Installment 4 of The Thinking Network. We execute the build script, using Containerlab to dynamically deploy a carrier-grade SR Linux network topology in thirty seconds.]]></description><link>https://www.tomharveytraining.com/the-thinking-network-installment-4-containerlab-deploy/</link><guid isPermaLink="false">6a0cab307fd5980001123d1b</guid><category><![CDATA[The Thinking Network]]></category><dc:creator><![CDATA[Thomas Harvey]]></dc:creator><pubDate>Wed, 20 May 2026 10:45:27 GMT</pubDate><media:content url="https://storage.ghost.io/c/c4/dc/c4dcef1a-ac8f-4b6b-9334-63e32b1fa558/content/images/2026/05/Installment-4.jpg" medium="image"/><content:encoded><![CDATA[<hr><blockquote><strong>Architecture Overview: Phase 4</strong><strong>Objective:</strong> Programmatically deploy a virtualized carrier-grade network fabric.<strong>Core Technologies:</strong> Containerlab, Python automation, Nokia SR Linux, and YAML topology generation.<strong>The Goal:</strong> Transform a single configuration file into 13 active containers, establishing the physical diamond topology required for AI traffic engineering.</blockquote><hr><h2 id="the-deploy">The Deploy</h2><img src="https://storage.ghost.io/c/c4/dc/c4dcef1a-ac8f-4b6b-9334-63e32b1fa558/content/images/2026/05/Installment-4.jpg" alt="The Thinking Network (Installment 4): Containerlab &amp; The Fabric Deploy"><p>The previous installments covered what this lab is and why it exists. This one is where it starts running.</p><p>One command:</p><pre><code class="language-bash">python3 phase3_topology.py
</code></pre><p>Thirty seconds later, thirteen containers are running on a laptop. Four Nokia SR Linux routers. Four Linux client workloads. A full telemetry and logging stack. A diamond fabric that did not exist before that command ran.<br>This installment is about what that command actually does - and what it would take to do it by hand.</p><p>I prefer to build my labs and live networks using scripts because it allows for faster spin-ups. When I am deploying a 40-node Metro-Ethernet environment in the field, scripts are what reduce the errors. The lab should reflect that reality.</p><hr><h3 id="what-containerlab-is">What ContainerLab Is</h3><p>ContainerLab is an open-source tool built by Nokia and the network engineering community for running containerized network labs. It reads a topology file, creates the containers, connects them with virtual network interfaces, assigns management IPs, and brings everything up in the correct order.</p><p>The topology file is called <code>lab.yml</code>. It is not written by hand. The Python script generates it from <code>lab_config.py</code> - the single source of truth for everything in this lab. Node definitions, management IPs, link connections, container images, port bindings, environment variables - all of it derives from one file.</p><p>This matters because it means changing one value in <code>lab_config.py</code> changes everything that depends on it. The topology file, the router configs, the Prometheus scrape config, the Grafana datasource. Nothing is hardcoded twice.</p><hr><h3 id="what-the-topology-file-defines">What the Topology File Defines</h3><p>The generated <code>lab.yml</code> describes thirteen nodes:</p><p><strong>The diamond fabric - four Nokia SR Linux routers:</strong></p><pre><code class="language-yaml">srl1:
  kind: nokia_srlinux
  mgmt-ipv4: 172.20.20.11
  startup-config: ../configs/fabric/srl1.cfg

srl2:
  kind: nokia_srlinux
  mgmt-ipv4: 172.20.20.12
  startup-config: ../configs/fabric/srl2.cfg

srl3:
  kind: nokia_srlinux
  mgmt-ipv4: 172.20.20.13
  startup-config: ../configs/fabric/srl3.cfg

srl4:
  kind: nokia_srlinux
  mgmt-ipv4: 172.20.20.14
  startup-config: ../configs/fabric/srl4.cfg
</code></pre><p><strong>Four client workloads</strong> - Linux containers that generate traffic through the fabric:</p><pre><code class="language-yaml">client-l2-1:
  kind: linux
  mgmt-ipv4: 172.20.20.31

client-l2-2:
  kind: linux
  mgmt-ipv4: 172.20.20.32

client-l3-1:
  kind: linux
  mgmt-ipv4: 172.20.20.33

client-l3-2:
  kind: linux
  mgmt-ipv4: 172.20.20.34
</code></pre><p><strong>Five telemetry containers</strong> - Prometheus, gNMIc, Grafana, Loki, Promtail - each with its generated config file mounted as a read-only bind.</p><p><strong>Eight links</strong> connecting them in the diamond pattern:</p><pre><code class="language-yaml">links:
  - endpoints: [&quot;srl1:e1-1&quot;, &quot;srl2:e1-1&quot;]   # Path A - upper
  - endpoints: [&quot;srl1:e1-2&quot;, &quot;srl3:e1-1&quot;]   # Path B - upper
  - endpoints: [&quot;srl2:e1-2&quot;, &quot;srl4:e1-1&quot;]   # Path A - lower
  - endpoints: [&quot;srl3:e1-2&quot;, &quot;srl4:e1-2&quot;]   # Path B - lower
  - endpoints: [&quot;client-l2-1:eth1&quot;, &quot;srl1:e1-3&quot;]
  - endpoints: [&quot;client-l2-2:eth1&quot;, &quot;srl4:e1-3&quot;]
  - endpoints: [&quot;client-l3-1:eth1&quot;, &quot;srl1:e1-4&quot;]
  - endpoints: [&quot;client-l3-2:eth1&quot;, &quot;srl4:e1-4&quot;]
</code></pre><p>The diamond has two paths. Path A runs through srl2. Path B runs through srl3. This is the topology the AI layer will eventually manipulate - shifting traffic between paths based on latency forecasts.</p><p>The entire network is air-gapped. <code>external-access: false</code>. No routes leave the lab. Nothing reaches the internet. The lab lives entirely within itself.</p><hr><h3 id="the-node-type">The Node Type</h3><p>Every SR Linux node in this lab uses <code>type: ixr-d2l</code>.</p><p>This is worth calling out because the documentation contains a common error - the letter is lowercase L, not the number 1. <code>ixr-d2l</code> is the IXR-D2L fixed-form-factor chassis. <code>ixr-d21</code> does not exist. On a laptop, the D2L is the stable choice - it initializes correctly without requiring modular chassis configuration.</p><p>Getting this wrong produces containers that start and immediately exit. Getting it right produces four routers that boot cleanly and hold their configuration.</p><hr><h3 id="what-happened-when-it-ran">What Happened When It Ran</h3><p>ContainerLab printed its progress as it worked. First the image pulls for containers not yet present locally. Then container creation - all thirteen, nearly simultaneously. Then the virtual link connections:</p><pre><code>INFO Created link: srl1:e1-1 &#x25AA;&#x2504;&#x2504;&#x25AA; srl2:e1-1
INFO Created link: srl1:e1-2 &#x25AA;&#x2504;&#x2504;&#x25AA; srl3:e1-1
INFO Created link: srl2:e1-2 &#x25AA;&#x2504;&#x2504;&#x25AA; srl4:e1-1
INFO Created link: srl3:e1-2 &#x25AA;&#x2504;&#x2504;&#x25AA; srl4:e1-2
INFO Created link: client-l2-1:eth1 &#x25AA;&#x2504;&#x2504;&#x25AA; srl1:e1-3
INFO Created link: client-l2-2:eth1 &#x25AA;&#x2504;&#x2504;&#x25AA; srl4:e1-3
INFO Created link: client-l3-1:eth1 &#x25AA;&#x2504;&#x2504;&#x25AA; srl1:e1-4
INFO Created link: client-l3-2:eth1 &#x25AA;&#x2504;&#x2504;&#x25AA; srl4:e1-4
</code></pre><p>Then the summary table. Thirteen rows. Every row: <code>running</code>.</p><p>The diamond fabric exists.</p><hr><h3 id="what-the-startup-config-does">What the Startup Config Does</h3><p>Each SR Linux node loads a startup configuration file at boot. This is the &quot;birth certificate&quot; approach - the node comes up already configured rather than requiring manual CLI input after the fact.</p><p>If I were configuring srl1 by hand, which I often do in live networks, I would enter the CLI, type every line, and commit the changes. </p><p>It would look like this:</p><pre><code>--{ candidate }--[ ]--
A:srl1# set / interface system0 subinterface 0 ipv4 admin-state enable
A:srl1# set / interface system0 subinterface 0 ipv4 address 172.1.255.255/32
A:srl1# set / interface ethernet-1/1 admin-state enable
A:srl1# set / interface ethernet-1/1 subinterface 0 ipv4 admin-state enable
A:srl1# set / interface ethernet-1/1 subinterface 0 ipv4 address 172.254.254.1/30
A:srl1# set / interface ethernet-1/2 admin-state enable
A:srl1# set / interface ethernet-1/2 subinterface 0 ipv4 admin-state enable
A:srl1# set / interface ethernet-1/2 subinterface 0 ipv4 address 172.254.254.5/30
A:srl1# set / network-instance default admin-state enable
A:srl1# set / network-instance default interface system0.0
A:srl1# set / network-instance default interface ethernet-1/1.0
A:srl1# set / network-instance default interface ethernet-1/2.0
A:srl1# commit stay
</code></pre><p>That is just the interface configuration for one node. Before IS-IS. Before BGP. Before services. Before telemetry.</p><p>You would type that four times - once per node - and each node would have different IP addresses, a different system IP, different neighbor relationships. The next installment covers IS-IS, and you will see exactly what four nodes of manual routing protocol configuration looks like.</p><p>The startup config file handles all of that automatically at boot. The Python script generates it. The IPs derive from the site ID - srl1 is site 1, so its system IP is <code>172.1.255.255</code>. srl2 is site 2, so its system IP is <code>172.2.255.255</code>. The pattern is consistent and never hardcoded.</p><hr><h3 id="what-comes-next">What Comes Next</h3><p>ContainerLab reports the containers as running. But <code>running</code> in Docker terms means the container process started. It does not mean the Nokia SR Linux operating system inside that container has finished initializing.</p><p>SR Linux takes two to four minutes after Docker reports running before the NOS is ready to accept CLI connections, process startup configs, and form protocol adjacencies. This is not a bug. It is a carrier-grade operating system doing what carrier-grade operating systems do - initializing carefully.</p><p>The next installment starts after that wait is over. IS-IS adjacencies forming. The network learning the shape of the room it is in.</p><hr><h3 id="build-record">Build Record</h3><p><em>Deployed May 17, 2026 - Dell Precision 3571 - Garuda Linux rolling - ContainerLab 0.71.0 - SR Linux v26.3.2</em></p><pre><code>10:13:09 INFO Containerlab started version=0.71.0
10:13:09 INFO Parsing &amp; checking topology file=lab.yml
10:13:09 INFO Creating docker network name=clab-nbl-diamond-v1-mgmt
             IPv4 subnet=172.20.20.0/24
10:13:40 INFO Creating container name=srl1
10:13:40 INFO Creating container name=srl2
10:13:40 INFO Creating container name=srl3
10:13:40 INFO Creating container name=srl4
10:13:43 INFO Created link: srl1:e1-1 &#x25AA;&#x2504;&#x2504;&#x25AA; srl2:e1-1
10:13:43 INFO Created link: srl1:e1-2 &#x25AA;&#x2504;&#x2504;&#x25AA; srl3:e1-1
10:13:43 INFO Created link: srl2:e1-2 &#x25AA;&#x2504;&#x2504;&#x25AA; srl4:e1-1
10:13:43 INFO Created link: srl3:e1-2 &#x25AA;&#x2504;&#x2504;&#x25AA; srl4:e1-2

&#x256D;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x252C;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x252C;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x252C;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x256E;
&#x2502; clab-nbl-diamond-v1-srl1         &#x2502; nokia_srlinux    &#x2502; running &#x2502; 172.20.20.11 &#x2502;
&#x2502; clab-nbl-diamond-v1-srl2         &#x2502; nokia_srlinux    &#x2502; running &#x2502; 172.20.20.12 &#x2502;
&#x2502; clab-nbl-diamond-v1-srl3         &#x2502; nokia_srlinux    &#x2502; running &#x2502; 172.20.20.13 &#x2502;
&#x2502; clab-nbl-diamond-v1-srl4         &#x2502; nokia_srlinux    &#x2502; running &#x2502; 172.20.20.14 &#x2502;
&#x2502; clab-nbl-diamond-v1-client-l2-1  &#x2502; linux            &#x2502; running &#x2502; 172.20.20.31 &#x2502;
&#x2502; clab-nbl-diamond-v1-client-l2-2  &#x2502; linux            &#x2502; running &#x2502; 172.20.20.32 &#x2502;
&#x2502; clab-nbl-diamond-v1-client-l3-1  &#x2502; linux            &#x2502; running &#x2502; 172.20.20.33 &#x2502;
&#x2502; clab-nbl-diamond-v1-client-l3-2  &#x2502; linux            &#x2502; running &#x2502; 172.20.20.34 &#x2502;
&#x2502; clab-nbl-diamond-v1-prometheus   &#x2502; linux            &#x2502; running &#x2502; 172.20.20.20 &#x2502;
&#x2502; clab-nbl-diamond-v1-gnmic        &#x2502; linux            &#x2502; running &#x2502; 172.20.20.21 &#x2502;
&#x2502; clab-nbl-diamond-v1-grafana      &#x2502; linux            &#x2502; running &#x2502; 172.20.20.22 &#x2502;
&#x2502; clab-nbl-diamond-v1-loki         &#x2502; linux            &#x2502; running &#x2502; 172.20.20.23 &#x2502;
&#x2502; clab-nbl-diamond-v1-promtail     &#x2502; linux            &#x2502; running &#x2502; 172.20.20.24 &#x2502;
&#x2570;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2534;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2534;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2534;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x256F;

Phase 3 Complete -- lab deployed
Nodes: 13 | Links: 8 | Bridge: br-nbl-v1 | Air-gapped: True
</code></pre><p><em>Thirteen containers. Eight links. Diamond fabric online.</em></p><hr><p><em>Next installment: The Underlay. IS-IS adjacencies form. The network learns its own topology. Four nodes of manual configuration shown in full.</em></p>]]></content:encoded></item><item><title><![CDATA[The Disappearing Hagalaz]]></title><description><![CDATA[<p><em>Hagalaz - Poem One - Vei&#xF0;imenn F&#xF3;kusar</em></p><p><strong>Hagalaz: The Disappearing</strong></p><p>The cold bites through my wool. I press my thumb to the frost on the bark.</p><p>The elders stay by the hearth. They speak of the quiet woods. They do not hear the pounding in my</p>]]></description><link>https://www.tomharveytraining.com/the-disappearing-hagalaz/</link><guid isPermaLink="false">69fdc7af61d43a00019cf5fb</guid><category><![CDATA[VEIÐIMENN FÓKUSAR]]></category><category><![CDATA[Music]]></category><dc:creator><![CDATA[Thomas Harvey]]></dc:creator><pubDate>Fri, 15 May 2026 01:52:06 GMT</pubDate><media:content url="https://storage.ghost.io/c/c4/dc/c4dcef1a-ac8f-4b6b-9334-63e32b1fa558/content/images/2026/05/Hunt01_Suno.jpeg" medium="image"/><content:encoded><![CDATA[<img src="https://storage.ghost.io/c/c4/dc/c4dcef1a-ac8f-4b6b-9334-63e32b1fa558/content/images/2026/05/Hunt01_Suno.jpeg" alt="The Disappearing Hagalaz"><p><em>Hagalaz - Poem One - Vei&#xF0;imenn F&#xF3;kusar</em></p><p><strong>Hagalaz: The Disappearing</strong></p><p>The cold bites through my wool. I press my thumb to the frost on the bark.</p><p>The elders stay by the hearth. They speak of the quiet woods. They do not hear the pounding in my chest. It is louder than the winter wind.</p><p>I cross the fire line. I leave the village behind.</p><p>The snow is deep. My boots crush the ice. Hunger pulls me forward. I am only breath and bone.</p><p>I reach the tree line. The sky is dead white. The pines are black iron.</p><p>Ravens circle above. They watch the hunt. They wait for the kill.</p><p>I see the shape in the mist. It is heavy and still.</p><p>I draw the string. The tension cuts my fingers. My arm locks. I hold my breath. I am ready.</p><p>The mist moves. The shape shifts.</p><p>My hand waits to loose the string. The release never comes. The shape dissolves before my fingers can know it. It scatters in the cold glow of the dawn.</p><p>I lower the bow. The string slaps my wrist. There is no blood on the snow. There is no snapped twig.</p><p>I walk to the empty shadow. Nothing is there. The forest keeps its secret.</p><p>A wind drops from the pines. It hits my chest. It feels older than my father. It is older than the feast and the death.</p><p>It passes through my ribs. It leaves a weight I cannot see. It strips my name away.</p><p>I stand in the cold. My hands are empty. The dark speaks my shame back to me.</p><p>I am changed. I am the same. I am still hungry.</p><hr><h2 id="the-lyrics">The Lyrics</h2><pre><code> [Verse 1]
The elders spoke of stillness
As if the woods were blind
But I heard my own heart pounding
Past the fire line
I pressed my thumb to frost
Like they taught me when I was young
Read the earth in silence
Till the cold bit my tongue
 
[Pre-Chorus]
Beyond the last pine branch
There is no village song
Only breath and bone and hunger
Only the way things go wrong
 
[Chorus]
At the tree line
At the tree line
I lost my name
At the tree line
At the tree line
The dark spoke back my shame
 
[Verse 2]
Ravens held the ceiling
Black marks in the drift-white sky
I drew the string with purpose
Held my body still and hard
Then the mist took the shape
Before my hand could know
No snapped twig, no blood to follow
Just the dawn in its cold glow

[Pre-Chorus]
I searched the empty shadow
Where the beast should have stood
But the forest kept its secret
Like a mouth full of old blood

[Chorus]
At the tree line
At the tree line
I lost my name
At the tree line
At the tree line
The dark spoke back my shame

[Bridge]
A wind came through the pines
And it knew me by my breath
Older than my father
Older than the feast and death
Something passed through my ribs
Not fury, not fear
A weight with no face at all
And it left me standing here

[Final Chorus]
At the tree line
At the tree line
I lost my name
At the tree line
At the tree line
I came back changed the same
At the tree line
At the tree line
The woods called me by flame</code></pre><hr><figure class="kg-card kg-bookmark-card"><a class="kg-bookmark-container" href="https://distrokid.com/hyperfollow/tomharvey1/the-disappearing-hagalaz/?ref=tomharveytraining.com"><div class="kg-bookmark-content"><div class="kg-bookmark-title">The Disappearing (Hagalaz) by Tom Harvey</div><div class="kg-bookmark-description">Stream and Save The Disappearing (Hagalaz) - Distributed by DistroKid</div><div class="kg-bookmark-metadata"><img class="kg-bookmark-icon" src="https://storage.ghost.io/c/c4/dc/c4dcef1a-ac8f-4b6b-9334-63e32b1fa558/content/images/icon/favicon-cf5c0cdd-706b-4c04-b717-a614673a4eee.ico" alt="The Disappearing Hagalaz"><span class="kg-bookmark-author">DistroKid</span></div></div><div class="kg-bookmark-thumbnail"><img src="https://storage.ghost.io/c/c4/dc/c4dcef1a-ac8f-4b6b-9334-63e32b1fa558/content/images/thumbnail/http-3A-2F-2Fgather.fandalism.com-2F12587764--7BA6D64B-6899-4CE5-B8874D490970A31B--0--791680--01Huntalbum-3257d1a1-3b7e-4c00-a9a8-3140df6bebbc.jpg" alt="The Disappearing Hagalaz" onerror="this.style.display = &apos;none&apos;"></div></a></figure><figure class="kg-card kg-embed-card"><iframe style="border-radius: 12px" width="100%" height="352" title="Spotify Embed: Grid and Grip" frameborder="0" allowfullscreen allow="autoplay; clipboard-write; encrypted-media; fullscreen; picture-in-picture" loading="lazy" src="https://open.spotify.com/embed/album/0odJzuZ1mhWSY5MIPb7TDk?si=gwgklyWGQua9tJhyPIN-mw&amp;utm_source=oembed"></iframe></figure><figure class="kg-card kg-embed-card"><iframe width="200" height="150" src="https://www.youtube.com/embed/xUB-0WMd-lQ?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen title="The Disappearing (Hagalaz)"></iframe></figure>]]></content:encoded></item><item><title><![CDATA[The Thinking Network (Installment 3): Linux Infrastructure for Autonomous Networks]]></title><description><![CDATA[Installment 3 of The Thinking Network. We configure the physical floor of the workshop, utilizing Garuda Linux as the bare-metal foundation for our AI-driven network environment.]]></description><link>https://www.tomharveytraining.com/the-thinking-network-installment-3-linux-infrastructure/</link><guid isPermaLink="false">6a01d3f061d43a00019cf678</guid><category><![CDATA[The Thinking Network]]></category><dc:creator><![CDATA[Thomas Harvey]]></dc:creator><pubDate>Mon, 11 May 2026 13:17:09 GMT</pubDate><media:content url="https://storage.ghost.io/c/c4/dc/c4dcef1a-ac8f-4b6b-9334-63e32b1fa558/content/images/2026/05/Installment-3.jpg" medium="image"/><content:encoded><![CDATA[<hr><blockquote><strong>Architecture Overview: Phase 3Objective:</strong> Establish a deterministic, high-performance host OS for containerized network testing.<strong>Core Technologies:</strong> Garuda Linux (Arch-based), Bare-metal infrastructure, and automated version-control scripts.<strong>The Goal:</strong> Provide a stable, lean execution floor for the Nokia SR Linux containers and the AI intelligence layer.</blockquote><hr><img src="https://storage.ghost.io/c/c4/dc/c4dcef1a-ac8f-4b6b-9334-63e32b1fa558/content/images/2026/05/Installment-3.jpg" alt="The Thinking Network (Installment 3): Linux Infrastructure for Autonomous Networks"><p>Before you run the first command, you have to get the machine to boot.</p><p>That sounds obvious. It isn&apos;t always.</p><hr><h3 id="the-floor-change">The Floor Change</h3><p>In Installment Two, I described Ubuntu as the workshop floor. The ground everything else stands on.</p><p>We are on a different floor now.</p><p>That&apos;s not a small thing, and it deserves an explanation before we go any further.</p><p>Ubuntu 24.04 LTS is a solid, widely-used Linux distribution. It is what most engineers reach for when they want something stable and supported. It is also built for general-purpose use - the kind of system that works for most workloads without asking too much of the person setting it up.</p><p>This lab has two distinct workloads running on one machine. The publishing pipeline for this series. And the Nokia network environment where the actual research happens. Each one makes demands. Neither one benefits from a general-purpose compromise.</p><p><strong>Garuda Linux</strong> is a distribution built on Arch Linux - a leaner, more deliberate foundation that gives you exactly what you choose to put on it and nothing else. Where Ubuntu arrives with decisions already made, Arch-based systems ask you to make them yourself. That is not a flaw. For a lab environment that needs to be precise, predictable, and purpose-built, it is the right characteristic.</p><p>The desktop environment is <strong>Hyprland</strong> - a tiling window manager running on Wayland, the modern Linux display protocol. Tiling means the screen is divided into defined workspaces rather than floating windows. The terminal, the editor, and the file tree exist simultaneously without reaching for a mouse. For the kind of sustained technical work this lab requires, that is not a preference. It is a productivity decision.</p><p>The editor is <strong>Neovim</strong> - a keyboard-driven code editor that rewards configuration. The terminal is <strong>Kitty</strong>, GPU-accelerated and Wayland-native. The container management interface is <strong>LazyDocker</strong>. Every tool in the stack was chosen to serve the two workloads without friction between them.</p><p>One machine. Two terrains. A floor built to hold both.</p><hr><h3 id="the-obstacle-before-the-obstacle">The Obstacle Before the Obstacle</h3><p>The plan was to install Garuda on the Dell Precision 3571 that runs this lab. The process requires a bootable drive - something the machine can start from before the new operating system exists on it.</p><p>The normal approach is a USB thumb drive. Load a boot utility onto the drive, copy the operating system image onto it, plug it in, restart the machine, and follow the installer.</p><p>I did not have a spare thumb drive.</p><p>What I had was a 1.8 terabyte external storage drive - the X10 Pro - sitting on the bench already connected to the machine. It is a large, fast drive in an external enclosure. It looked like the solution.</p><p>It was not.</p><hr><h3 id="what-the-bios-was-actually-saying">What the BIOS Was Actually Saying</h3><p>Here is what happened. I loaded the boot utility onto the X10 Pro, copied the Garuda image onto it, and restarted the machine. I entered the boot menu - the screen that appears before the operating system loads, where you choose what to start from. I selected the X10 Pro. The machine came back up into Ubuntu 24. Every time.</p><p>The first reading of that situation is: the BIOS is wrong. The machine is ignoring my instruction.</p><p>That is not what was happening.</p><p>The X10 Pro is a specific kind of drive. It is an NVMe drive - the fast solid-state storage type - housed inside a USB enclosure. NVMe is the same technology that lives inside the laptop itself. The BIOS was reading the X10 Pro&apos;s hardware signature, identifying it as NVMe storage, and routing it accordingly - alongside the internal drive that already had Ubuntu on it. It was not ignoring me. It was reading the hardware accurately. The enclosure created genuine ambiguity that the boot process could not resolve cleanly.</p><p>The machine knew what it was seeing. I had not given it something unambiguous to work with.</p><p>A standard USB thumb drive has no such identity problem. It registers as one thing. The BIOS sees it as one thing. The boot sequence follows without conflict.</p><p>A 64GB SanDisk thumb drive from Best Buy solved in one attempt what thirty minutes of troubleshooting could not.</p><hr><h3 id="why-this-belongs-in-a-series-about-intelligent-networks">Why This Belongs in a Series About Intelligent Networks</h3><p>The BIOS was not malfunctioning. It was doing precisely what it was built to do - reading its environment and routing accordingly. The problem was that the environment I gave it contained ambiguity. The system responded to what was actually there, not to what I intended.</p><p>That is the same problem this lab is being built to solve at the network level.</p><p>An autonomous network system reads its environment continuously. It builds a model of what normal looks like. It acts when reality departs from that model. The quality of those actions depends entirely on the quality of the information feeding into them. An ambiguous signal produces an ambiguous response. Garbage in, garbage out - except in a carrier network, garbage out means dropped calls, failed transactions, interrupted service.</p><p>Clarity is not a convenience. It is a design requirement.</p><p>The thumb drive was clarity. And that&apos;s the lesson the BIOS taught before the first command ran.</p><hr><h3 id="what-got-built">What Got Built</h3><p>Garuda Linux is running on the Dell Precision 3571. The full stack is operational.</p><p>The publishing side: Neovim with the LazyVim configuration layer, Obsidian connected to a version-controlled repository, a coordination script that moves information between the different parts of this operation automatically. The writing environment is faster and more focused than anything I have run before.</p><p>The lab side: Docker, ContainerLab version 0.71.0, the Nokia SR Linux environment waiting to come back online. Ollama running in CPU mode - the i7-12800H processor in this machine handles seven-billion-parameter local AI models without issue, which opens a path for the kind of on-device inference work that becomes relevant later in this series.</p><p>One machine. The publishing pipeline and the network lab running side by side. The craftsman&apos;s bench and the engineer&apos;s rack sharing the same surface.</p><hr><h3 id="the-coordination-layer">The Coordination Layer</h3><p>One thing worth naming before the next installment.</p><p>A lab that is documenting its own progress while simultaneously running active research has a coordination problem. Information needs to move between different parts of the operation reliably, automatically, and with a record that persists. Not because it is convenient, but because an intelligent system needs to know its own state.</p><p>That is not a philosophical statement. It is an engineering requirement.</p><p>The solution is a coordination script - an automation layer that runs on a schedule, moves the right information to the right places, and commits a record of every operation to a version-controlled repository. The lab&apos;s memory, maintained automatically.</p><p>It ran for the first time this week. The first push to the repository went out before a file exclusion list was in place. A protected file went up with everything else.</p><p>The exclusion list is now in place. The repository is clean. The incident is documented here because that is exactly the kind of thing this series exists to document. Automation is not a finished state. It is a practice.</p><p>The same is true of the network.</p><hr><h3 id="whats-next">What&apos;s Next</h3><p>The Nokia lab environment needs to come back online in its new home. ContainerLab reads the topology file. SR Linux nodes boot inside Docker containers. The diamond fabric comes alive.</p><p>That is Installment Four.</p><hr><p><em>Next installment: The First Command. The topology file loads. Four routers appear. The lab is alive.</em></p><hr><p><em>If this kind of work is useful to you, subscribe.<br>One email when something new publishes. No noise.</em></p><p><a href="#/portal/signup">Subscribe</a></p>]]></content:encoded></item><item><title><![CDATA[Grid and Grip]]></title><description><![CDATA[<p>The Silent Observer</p><p>Every engineer has a story about the night the plan failed.</p><p>Not a small failure. The kind where the load climbs past what the architecture was built to hold and you watch it happen in real time with nothing left to do but read what the system</p>]]></description><link>https://www.tomharveytraining.com/grid-and-grip/</link><guid isPermaLink="false">69fb383381bed20001bc6fa1</guid><category><![CDATA[The Silent Observer]]></category><dc:creator><![CDATA[Thomas Harvey]]></dc:creator><pubDate>Wed, 06 May 2026 12:51:15 GMT</pubDate><media:content url="https://storage.ghost.io/c/c4/dc/c4dcef1a-ac8f-4b6b-9334-63e32b1fa558/content/images/2026/05/IMG_0964.jpeg" medium="image"/><content:encoded><![CDATA[<img src="https://storage.ghost.io/c/c4/dc/c4dcef1a-ac8f-4b6b-9334-63e32b1fa558/content/images/2026/05/IMG_0964.jpeg" alt="Grid and Grip"><p>The Silent Observer</p><p>Every engineer has a story about the night the plan failed.</p><p>Not a small failure. The kind where the load climbs past what the architecture was built to hold and you watch it happen in real time with nothing left to do but read what the system is telling you and respond to what&#x2019;s actually there instead of what you designed for.</p><p>I have been in that server room. </p><p>Blinking racks like tired eyes. Numbers shaking. The plan that looked perfect an hour ago meeting something it was never built for.</p><p>I have also been on the mat when the opponent shifted out of the light and the combination I memorized became irrelevant in the first half second of live contact.</p><p>And I have been at the lathe when the grain decided its own direction and the straight line I planned met the truth of the wood and lost.<br>Three different rooms. The same lesson every time.</p><p>The map is not the territory. The blueprint does not negotiate with reality. The only plan that survives is the one the body learns.<br>Grid and Grip is that lesson set to music. Driving, methodical, a machine learning to breathe. For the engineer, the craftsman, and anyone who has ever watched something carefully built meet something that didn&#x2019;t care.</p><p>Hold your ground anyway.</p><hr><h2 id="lyrics">Lyrics</h2><pre><code>[Verse 1]
Draw the box in ink
Call it done, call it clean
But the thing moves first
Then it teaches the machine
Complex systems buckle
On one small bad assumption
One loose link in the chain
And the frame cannot sustain

[Pre-Chorus]
I watched the numbers shake
In the server room at night
Blinking racks like tired eyes
Holding on for life
The plan looked perfect
Till the load began to climb
What you wrote down on the paper
Can&#x2019;t negotiate with time

[Chorus]
It&#x2019;s not a checklist
It&#x2019;s a breath, and a stance
It&#x2019;s not a checklist
It&#x2019;s stillness in the storm
Yeah, the map is not the territory
(hold your ground)
The map is not the territory
(find your frame)

[Verse 2]
In the dojo, hands up
We move before we think
One step off the pattern
And the whole room starts to speak
Read the grain of wood
See where the split will run
The straight line lies sometimes
When the load weighs heavy enough

[Pre-Chorus]
I stopped trying to freeze it
Stopped asking it to fit
Every clean machine breaks
When you lean too hard on it
So I let the edge show
Let the tension stay in view
What survives the impact
Is the part that learns with you

[Chorus]
It&#x2019;s not a checklist
It&#x2019;s a breath, and a stance
It&#x2019;s not a checklist
It&#x2019;s stillness in the storm
Yeah, the map is not the territory
(hold your ground)
The map is not the territory
(find your frame)

[Bridge]
Blueprint in my fist
Still, the world kept moving
I could hear the fault line
Under every proving
Not a perfect posture
Not a holy guarantee
Just a body in the weather
Learning how to be

[Final Chorus]
It&#x2019;s not a checklist
It&#x2019;s a breath, and a stance
It&#x2019;s not a checklist
It&#x2019;s stillness in the storm
Yeah, the map is not the territory
(hold your ground)
The map is not the territory
(find your frame)
It&#x2019;s not a checklist
It&#x2019;s a breath, and a stance</code></pre><hr><figure class="kg-card kg-embed-card"><iframe style="border-radius: 12px" width="100%" height="352" title="Spotify Embed: Grid and Grip" frameborder="0" allowfullscreen allow="autoplay; clipboard-write; encrypted-media; fullscreen; picture-in-picture" loading="lazy" src="https://open.spotify.com/embed/album/0odJzuZ1mhWSY5MIPb7TDk?si=-hmmemXvQP6urbsAlboM0Q&amp;utm_source=oembed"></iframe></figure><figure class="kg-card kg-embed-card"><iframe width="200" height="113" src="https://www.youtube.com/embed/videoseries?list=OLAK5uy_neuRNYwsBSiLZJo5cTn71oGZ9q7PKGwKk" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></figure>]]></content:encoded></item></channel></rss>