<?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:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Ryan Brooks on Medium]]></title>
        <description><![CDATA[Stories by Ryan Brooks on Medium]]></description>
        <link>https://medium.com/@spikeheap?source=rss-19e2ee7a60d0------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*deRkRCpLE_OdTDCsJdidNg.jpeg</url>
            <title>Stories by Ryan Brooks on Medium</title>
            <link>https://medium.com/@spikeheap?source=rss-19e2ee7a60d0------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sat, 09 May 2026 18:34:34 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@spikeheap/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[FSA Non-Series gravel wheelset bearing replacement]]></title>
            <link>https://spikeheap.medium.com/fsa-non-series-gravel-wheelset-bearing-replacement-5d759c03ed53?source=rss-19e2ee7a60d0------2</link>
            <guid isPermaLink="false">https://medium.com/p/5d759c03ed53</guid>
            <category><![CDATA[maintenance]]></category>
            <category><![CDATA[gravel-bikes]]></category>
            <category><![CDATA[cycling]]></category>
            <dc:creator><![CDATA[Ryan Brooks]]></dc:creator>
            <pubDate>Wed, 08 Sep 2021 11:10:23 GMT</pubDate>
            <atom:updated>2021-09-08T11:11:43.672Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*HQFMamEeMwBNUpF2qboM3Q.jpeg" /><figcaption>Rear hub on the FSA Non-Series off-road wheelset</figcaption></figure><p>My Sonder Camino Ti arrived in November 2020 with the <a href="https://shop.fullspeedahead.com/en/wheelsets/mtb-gravel/non-series-off-road-wheelset">FSA Non-Series off-road wheelset</a>. After 9 months of mixed British riding, including a long, gritty winter in the Peak District, both wheels developed a bit of play and looked like they needed new bearings.</p><p>FSA/Vision have technical documents with <a href="https://shop.fullspeedahead.com/en/files/index/download/id/b2ff4887328d298e4187533fdf15a551357/">lists of service parts</a> for the wheels, but these use non-standard part names, and mapping these to the international standard was only possible once I stripped the wheels down and read them off the bearings themselves.</p><h4>Front wheel</h4><ul><li>Vision/FSA code: MR199</li><li>Actual size: 15x26x7mm</li><li>Quantity: 2</li><li>Bearing code: 15267–2RS (2RS just means there are 2 rubber seals, which helps protect the bearing from grime)</li></ul><p>These can be removed with a <a href="https://www.bearingprotools.com/products/bearing-puller?variant=32121629343849">bearing puller</a>, and refitted with a standard bearing press with 15x26x7mm drifts, such as <a href="https://www.bearingprotools.com/collections/presses/products/bearing-press-for-bicycles-with-t-bar-handles?variant=32895187189865">this one</a>.</p><h4>Rear wheel</h4><ul><li>Vision/FSA code: MR200</li><li>Actual size: 17x28x7mm</li><li>Quantity: 2</li><li>Bearing code: 17287–2RS (2RS just means there are 2 rubber seals, which helps protect the bearing from grime)</li><li>The freehub contains a couple of the same bearings, but I couldn’t remove them, and ended up ordering <a href="https://www.velozone.co.uk/products/vision-non-series-wheels-sh11-el298-freehub">a full replacement freehub (EL298)</a>.</li></ul><p>As these have different dimensions, they need a slightly different-sized <a href="https://www.bearingprotools.com/products/bearing-puller?variant=32121629147241">bearing puller</a>.</p><p>To fit/refit the bearings, you’ll need <a href="https://www.bearingprotools.com/collections/presses/products/over-axle-bearing-press?variant=32243512508521">a press with over-axle drifts</a> because the captive axle gets in the way of a standard press once you have the first bearing in. There’s also a cheaper alternative approach if you have a socket set — Youtube is your friend there.</p><p>I’ve found <a href="https://www.hendersonbearings.co.uk">Henderson Bearings</a> to ship quickly and last a decent time, though I don’t know enough to say whether their “Enduro” branding is just marketing or a lot better for bikes.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=5d759c03ed53" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Riding the EnglanDURO route]]></title>
            <link>https://spikeheap.medium.com/riding-the-englanduro-route-b86e3e3daef1?source=rss-19e2ee7a60d0------2</link>
            <guid isPermaLink="false">https://medium.com/p/b86e3e3daef1</guid>
            <category><![CDATA[coast-to-coast]]></category>
            <category><![CDATA[adventure]]></category>
            <category><![CDATA[gravel-cycling]]></category>
            <category><![CDATA[cycling]]></category>
            <category><![CDATA[gravel]]></category>
            <dc:creator><![CDATA[Ryan Brooks]]></dc:creator>
            <pubDate>Fri, 30 Jul 2021 10:13:04 GMT</pubDate>
            <atom:updated>2021-07-31T09:44:35.052Z</atom:updated>
            <content:encoded><![CDATA[<h4>A quiet, challenging, mostly off-road route from Liverpool to Scarborough</h4><figure><img alt="Wide cobbled bridleway above a reservoir on the Trans-Pennine Trail" src="https://cdn-images-1.medium.com/max/1024/1*XePS2yiT529HCReUwUD4ww.jpeg" /><figcaption>Woodhead Reservoir, three quarters of the way up the biggest climb of the trip</figcaption></figure><p>It’s been a long time since my <a href="https://teampedal.com">last multi-day adventure ride</a> back in 2013. I’d almost forgotten what it was like to get into the trance. Spinning the pedals, taking in the scenery, thinking about the next milestone, and yet still feeling a long way from the end. This time I was riding along with audiobooks and music instead of friends and family (thanks jobs and pandemic 🙄), but as soon as I set off I felt that calm focus of knowing there was only one thing to do today, and it would take all day.</p><p>I should mention that I didn’t bivy or ride self-supported, which is a bit against the spirit of the Racing Collective events. With my dad just round the corner and eager for a road trip, we had a great excuse for a family adventure even though he can’t cycle. I was quite grateful for this in the end — not just because I get on well with my parents, but also it was nice to have someone to chat to. Riding solo suits many people, but I found myself itching for someone to share my highs and lows with as the trip unfolded.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ZkCEY1EYPZAH9k7iBDVCdg.jpeg" /></figure><h4>The route</h4><p>The Racing Collective’s <a href="https://www.theracingcollective.com/englanduro.html">EnglanDURO event</a> is the first weekend of August. I had other commitments, so rode it a week or so early. The route starts at the Liverpool seafront, and snakes its way northeast to the sandy beaches of Scarborough. Despite passing through Liverpool, Warrington, Stockport, Wakefield, Castleford and York, the towpaths, bridleways and cycle routes never felt too built-up or busy.</p><p>Before leaving I was a bit nervous about the trails being busy with walkers. There’s a lot of distance to cover, but it’s not cool to shoot past people at 25km/h just because you’ve got a goal. Thankfully this wasn’t a problem at all. Other than a slow canal-side section in York where many were enjoying the sun, paths were often wide enough to ride at a reasonable speed, and elsewhere it was pretty quiet.</p><p>My parents live in Castleford, so it made a perfect break in the trip, breaking it into a longer 170km first day with 1500m height gain. That left day two with 130km and 500m less height gain (in theory).</p><figure><img alt="View of the River Mersey in Liverpool from the cyclepath, with some railings in between" src="https://cdn-images-1.medium.com/max/1024/1*P3YQyrY6uUANhzvUvAUUzg.jpeg" /></figure><p>We set off early to drive to Liverpool, and I was cycling along the waterfront by 8am, passing a steady stream of commuters, runners and dog walkers. The cycleway is wide, flat, and has great views to shipyards and the wrecks of old piers across the water. It felt great to build up some momentum right at the start, even though there wasn’t time to stop and look at the myriad statues and memorials along the front. I soon joined the <a href="https://www.transpenninetrail.org.uk">Trans-Pennine Trail</a> around Hale, which I’d be following for most of the day, and the first hike-a-bike section, carrying the bike up a switchback of stairs by Ditton Marsh. After the fast, open start, the slow trudge up the steps felt like a bit of a setback, but don’t fear: there are only a handful of these on the entire route.</p><p>The first 80 kilometres wind peacefully along the Mersey with the terrain and views changing frequently. I’d been expecting more “industrial heartland”, but the cycle route manages to hide it away behind trees and inclines. Blips of business like John Lennon Airport were short-lived and soon forgotten. Despite the gentle gradients, I wasn’t fooled. The climb over Woodhead Pass loomed in the distance, waiting to see if I had enough energy left for the last big push. Thankfully that climb ramps up slowly, at least until you cross the A628 when you wonder when you’ll need to push. The reward is continuously amazing views (e.g. the photo at the top of this page), and friendly exchanges with other cyclists and walkers. No-one is finding that climb easy!</p><figure><img alt="An elevation profile for the Liverpool to Castlefood ride. The first half is almost flat, followed by a 400m climb over Woodhead Pass that then drops back down to the finish." src="https://cdn-images-1.medium.com/max/1024/1*5zpLC5iBEcI9qkrnaBsxqw.png" /><figcaption>Elevation profile for Liverpool to Castleford</figcaption></figure><p>With the biggest climb behind me, I had a big grin on my face down to Penistone. The official route turns off Windle Edge to touch Winscar Reservoir before descending off-road to Townhead. This path is now private land with no access, so I retraced my steps back to the main road. From Townhead the route jumps back off-road to follow the River Don down into Penistone, where the last significant climb of the day awaited.</p><figure><img alt="A gentle gravel trail beside a field of short grass, with rolling Yorkshire hills in background" src="https://cdn-images-1.medium.com/max/1024/1*fAPcOetgUdTLSO7nhSebqg.jpeg" /><figcaption>The descent into Bretton Country Park</figcaption></figure><p>After spending so long climbing, the long undulating descent was a playground for the energy I somehow managed to conjour in my legs. The area around Bretton Country Park and Yorkshire Sculpture Park was absolutely beautiful, with fast, flowy, open trails. A short glance at the lake at Pugneys Park was next, before joining the canal towpath that I knew would take me all the way into Castleford. There was a tiny hitch joining the canal — the last 100m of the path that joins Pugneys to the canal was closed. A bit of back-tracking (and some helpful people who’d just come the other way) led me out, and then it was just glorious, flat towpath that led to food, stretching and sleep after eleven and a half hours on the bike.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ldgDfnt1aZAWUOMfqm0f7w.jpeg" /><figcaption>The stretch of canal before Methley</figcaption></figure><h4>A route of two halves</h4><p>I’d been quite nervous about the second day, and cautious about how much my pace would drop with tired legs, so I set off before 7:30am. I don’t know where this fear came from — we didn’t have a deadline to arrive in Scarborough other than “before the fish &amp; chip shops close”, but when you’ve not done the distance in a while it’s easy to assume you’ll be crawling along at a snails pace.</p><figure><img alt="A Sonder Camino gravel bike on a bridge above Castleford Wier on the River Aire" src="https://cdn-images-1.medium.com/max/1024/1*ZqIBMlnyBqOMQ33I8j-1EQ.jpeg" /><figcaption>Castleford weir. It was this photo on the Racing Collective site that made me realise the route passes so close to my parents’ house</figcaption></figure><p>Thankfully for said tired legs, I started with a gentle stretch along the towpath with cool, clear skies and a little dew on the ground. I had a crisis of confidence when the route turned off onto a walkers-only footpath through Fairburn Ings. Normally I’d figure out a cycle-friendly alternative, but being a bit tired and wanting to make progress, I decided there probably wouldn’t be anyone there so it’d be okay. My guess was correct, and I popped out the other side to start the first climb of the day over to Ledsham, which was a nice quiet path through the woods.</p><p>The following 30km on road and paved towpaths felt fast, and set the tone for the day. Where the first day had been 60% dirt, day two was 70% paved, which had the unexpected benefit of increasing my pace even though I was a bit more tired. Slowing down in York to carefully pass walkers and other cyclists enjoying the sun, I was reminded that today was supposed to be overcast with rain. Lucky!</p><figure><img alt="A gravel bike propped against a fencepost with a dry mud track to the right, rolling hills in the background, and slightly cloudy blue skies" src="https://cdn-images-1.medium.com/max/1024/1*PNFp392ijZ9v0tkk_xyMHA.jpeg" /><figcaption>The hills before Kirkham Priory</figcaption></figure><p>After York things returned to what I’d expect from a ride in Yorkshire. Hills. Up and down. Short, sharp efforts. And great views. Passing Kirkham Priory brought back childhood memories, and I was more than happy to wait for the trains to pass in the valley before the crossing reopened. There’s a significant climb that reaches 17%, which was a really convenient point to lose signal and have my audiobook cut out. Again, it’s hard to complain because the road was quiet, and the surface pretty good.</p><figure><img alt="A “17% incline” road sign, letting me know hard times are ahead" src="https://cdn-images-1.medium.com/max/1024/1*mWL8GptBju_7mHnG5qKxOg.jpeg" /><figcaption>🥵 At least they let you know it’s coming</figcaption></figure><p>I’d studied the elevation profile for day two, so I knew that after this climb there was a good rest before the final significant hill of the day. The big one, albeit a lot smaller than Woodhead Pass of yesterday. I realised I could make it to Scarborough. One more big hill wouldn’t stop me, and my legs felt pretty good. I passed the <a href="https://www.google.co.uk/maps/place/High+Hoyland/@53.6188288,-1.5863622,13z/data=!4m5!3m4!1s0x487962e2e4c8f809:0xaa545db0fd699f74!8m2!3d53.593721!4d-1.5822551">Cayley Arms</a>, crossing the main road to start the climb. Fortunately it’s closed on Tuesdays, otherwise I can’t say for sure that I wouldn’t have succumbed to the lure of a cold drink and a rest. At the base of a steep climb it would have been a bad call.</p><figure><img alt="Wide open fields with woodland in the background" src="https://cdn-images-1.medium.com/max/1024/1*rTB8igCyD5n2Hgh_3FKmfg.jpeg" /><figcaption>Near the summit in North Riding Forest Park</figcaption></figure><p>The climb up into North Riding Forest Park was actually pretty pleasant. The road had no traffic and only the occasional walker. It’s gruellingly steep in places, but gets its steepness out of the way in the first half before trading road for track and easing off the closer you get to the top. The last gentle climb followed tracks through fields. On any other day these would have been a joy to ride, but after several days of warm sun the track was rock hard and pitted with footsteps and hoofprints. This left a knobbly trail that juddered the gravel bike and shook me to my core as I tried to build up speed after the slow climb. Things just got better and better as field led to smooth, wide forest track, and I chased a motorbike as we both sprinted down the long straight trail with tall trees either side. What a feeling. This was the last big climb of the trip, and I knew Dad was parked up at the end of the trail with snacks and cool drinks. It was only when I met Dad that I heard the bad news…</p><figure><img alt="A trail barred with two gates and signs saying to keep out. They really don’t want you in there!" src="https://cdn-images-1.medium.com/max/1024/1*Oa5YGq6s7AUijLmP_zwdZQ.jpeg" /><figcaption>🤬 I thought t<a href="https://www.openstreetmap.org/way/236041216#map=16/54.2717/-0.6188">his track</a> was blocked</figcaption></figure><p>They <em>really</em> don’t want anyone in there. I’d already used my “I’m normally good so it’s okay if I break the rules” card back at Fairburn Ings this morning. Fair cop. A quick look at the map showed this is the only track north. My only option seemed to be to head south to Ebberston and suck up a stretch on the busy A170 before turning north again to get back to the route. I was a bit demoralised at the thought of going in precisely the wrong direction, and doing a 15km round-trip to bypass 1km of closed path, and my mood didn’t improve as I realised the descent to Ebberston wiped out all my height gain. In Snainton I turned and re-climbed the hill, grumpy until I remembered how fortunate I was to be out there in the first place. Sure it was an unexpected hill, but it just meant I got to spend more time on the bike. I was still well on track to arrive in Scarborough in time for dinner. It was worth climbing back up for the stretch across Wykeham Forest and a steep descent on road towards Hackness.</p><p>Update: Thanks to <a href="https://twitter.com/northyorkmoors/status/1421136482417455106?s=20">North York Moors NP</a>, it looks like I just missed a bridleway to the right of this photo.</p><p>The route left the road for one last hurrah, climbing up gently in woodland on established trails. Eager to drop into Scarborough, of course it was here that I met a walker who just needed someone to talk to. What started as a request for directions took a surprising turn into a life story about divorce, moving to Birmingham, and disdain for their neighbours. I felt quite uncomfortable when he started sharing his views about people on benefits, but chose escaping over setting him straight. They were so reluctant to let me go, striking up new lines of conversation. I hope they find someone to talk to.</p><p>Thankfully the last stretch into Scarborough was uneventful. A surge of “almost there” energy had me racing to the seafront, where a huge number of people were making the most of what had turned out to be a warm, sunny day.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*wfDYR8enMalS6joVVeiVPA.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*VeOaZOZiXBFfN24HxvF5PQ.jpeg" /><figcaption>The pier in Scarborough. The sea is such a great place to end a ride</figcaption></figure><p>The only thing left to do was hide the bike in the car, meet some friends on the beach, and fight off seagulls while we devoured fish and chips.</p><p>Would I recommend the route? Absolutely.</p><figure><img alt="My father in a wheelchair with me looking ridiculous in cycling lycra next to him, by the beach. We’re both enjoying fish and chips, and I’m pointing at them to show it was the main reason for the ride." src="https://cdn-images-1.medium.com/max/640/1*1BC8eTmYhlF0Hs_rgynUOQ.jpeg" /><figcaption>What’s a trip to the seaside without fish and chips?</figcaption></figure><h4>Route alterations &amp; roadblocks</h4><p>If you’re riding EnglanDURO21, or just following the route sometime soon, here’s a summary of the alterations I had to make. You can see my full tracks on Strava for <a href="https://www.strava.com/activities/5691283829">day one</a> and <a href="https://www.strava.com/activities/5695664642">day two</a>.</p><ol><li>Windle Edge/Pennine Sailing Club (<a href="https://www.google.co.uk/maps/place/High+Hoyland/@53.6188288,-1.5863622,13z/data=!4m5!3m4!1s0x487962e2e4c8f809:0xaa545db0fd699f74!8m2!3d53.593721!4d-1.5822551">Google maps</a>). The track is now private land, so stay on Windle Edge (don’t turn into the sailing club) into Townhead to rejoin the route.</li><li>Pugneys Park near the end of the lake (<a href="https://www.google.co.uk/maps/place/53°39&#39;36.6%22N+1°30&#39;03.4%22W/@53.6601632,-1.5031217,491m/data=!3m2!1e3!4b1!4m6!3m5!1s0x0:0x0!7e2!8m2!3d53.6601603!4d-1.5009331">Google maps</a>) has fenced off the track, but if take the north fork at the point on the map (rather than north-east following the route) you can join it a little further on.</li><li>The Fairburn Ings entrance from the Aire &amp; Calder Navigation towpath (<a href="https://www.google.co.uk/maps/place/53°44&#39;07.7%22N+1°20&#39;36.9%22W/@53.7354792,-1.3457817,490m/data=!3m2!1e3!4b1!4m13!1m6!3m5!1s0x487941e91bceea19:0xc385ec51e4499bf2!2sRSPB+Fairburn+Ings!8m2!3d53.7443881!4d-1.3173071!3m5!1s0x0:0x0!7e2!8m2!3d53.7354757!4d-1.3435928">Google maps</a>) is <a href="https://www.openstreetmap.org/way/37773996#map=16/53.7366/-1.3448">footpath-only</a>. If you’re early in the morning or late in the evening this is <em>probably</em> fine, but the path is quite narrow in places so best avoided when it’s busier. To avoid it completely, stay on the A656 and follow it into Allerton Bywater before turning right onto Newton Lane to rejoin the route (<a href="https://www.openstreetmap.org/directions?engine=graphhopper_bicycle&amp;route=53.7320%2C-1.3537%3B53.7428%2C-1.3453#map=15/53.7393/-1.3505">see diversion on OpenStreetMap</a>). This diversion only adds a couple of hundred metres to the day.</li></ol><h4>Links</h4><ul><li>Huge thanks to the Racing Collective for putting the route together: <a href="https://www.theracingcollective.com/englanduro.html">https://www.theracingcollective.com/englanduro.html</a></li><li>Day one track: <a href="https://www.strava.com/activities/5691283829">https://www.strava.com/activities/5691283829</a></li><li>Day two track: <a href="https://www.strava.com/activities/5695664642">https://www.strava.com/activities/5695664642</a></li><li>#EnglanDURO21 Spotify playlist: <a href="https://open.spotify.com/playlist/0BgDygP557YMg5KMSsflAO?si=55af91d8c27044e6">https://open.spotify.com/playlist/0BgDygP557YMg5KMSsflAO?si=55af91d8c27044e6</a></li><li>The Twilight of Democracy on Audible: <a href="https://www.audible.co.uk/pd/Twilight-of-Democracy-Audiobook/0241481821">https://www.audible.co.uk/pd/Twilight-of-Democracy-Audiobook/0241481821</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=b86e3e3daef1" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Rapha’s (free) repair service]]></title>
            <link>https://spikeheap.medium.com/raphas-free-repair-service-8a874939e590?source=rss-19e2ee7a60d0------2</link>
            <guid isPermaLink="false">https://medium.com/p/8a874939e590</guid>
            <category><![CDATA[cycling]]></category>
            <category><![CDATA[repair]]></category>
            <dc:creator><![CDATA[Ryan Brooks]]></dc:creator>
            <pubDate>Fri, 09 Apr 2021 11:24:26 GMT</pubDate>
            <atom:updated>2021-04-09T11:24:26.328Z</atom:updated>
            <content:encoded><![CDATA[<p>I was a bit dazed when I came off my bike and rolled down the road. Having got past the initial joy of “all my limbs still work, ish”, through the thankfullness of seeing the big dent in the front of my helmet, and into “ow, my face actually hurts quite a bit”, I realised this had been an expensive mistake.</p><p>The bike came out of things pretty well, and just needed the mech hanger bending out, a new GRX shifter and some bar tape. The hardest part of getting that back on the road was sourcing the shifter, with both Shimano and SRAM components being in short supply this year. My clothing was another story…</p><p>Suprisingly enough, most road cycling clothing isn’t built to be bounced along the tarmac, and I managed to damage everything I was wearing except my shoes (thankfully my ready-to-be-replaced overshoes took the brunt of that damage). I’d picked a terrible time to do this, as a few things were really new. My 3-week-old Castelli bib tights had a big hole in them, and my month-old POC helmet had a big dent too. For some context on how pleased I was with Rapha, I’ve been comparing them with these two brands:</p><ul><li>POC ignored tweets and a couple of emails. They mention a crash replacement programme in North America, but not Europe, but I never got an answer about whether they do or not. The helmet was amazing, but the service less so.</li><li>Castelli’s <a href="https://saddleback.co.uk/pages/crash-replacement/">UK replacement policy</a> is oddly complex, with extra discount if you’ve bought directly from Saddleback. This one was the most frustrating — the almost-new bib tights needed a replacement panel, and it felt very wasteful having them destroyed for 40% discount on a full-RRP set. In the end I picked up a brand new set from <a href="https://www.sigmasports.com/item/Castelli/Sorpasso-ROS-Bib-Tight/R1RC">Sigma Sports</a> with a reasonable discount (though not 40%), and am waiting for Alpkit’s repair stations to open up as lockdown lifts. Hopefully I’ll end up with a slightly scrappy pair for mountain biking 🤷‍♂️.</li></ul><p>The thinnest, lightest thing I was wearing was my Rapha Brevet high-visibility jacket, which came off peppered with holes and a couple of tears. I <em>love</em> this jacket. It’s reflective stripes are perfect for winter riding when you end up in the dark more often, and it still packed down small and breathes really well. Maybe a little too well after the fall…</p><p>Here’s a few “before” photos</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*MJBu_BkY-amRqL58ZKyL9Q.jpeg" /><figcaption>The right arm of the Rapha Brevet jacket had a couple of holes.</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*undG70_1dYYxfd-JPhqcPA.jpeg" /><figcaption>Somehow I tore the shoulder along the seam too.</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*3BnfhuuZuf4UMK_konfNGw.jpeg" /><figcaption>The back panel was grazed, with many tiny holes and a few you could almost poke a finger through.</figcaption></figure><p>Of all the damaged clothing, this was the one I assumed was destined for the bin. It’s a couple of years old, and a very fine material.</p><p>I knew Rapha had a <a href="https://www.rapha.cc/gb/en/repair-service">free repairs service</a>, but couldn’t find anything on the internet other than a forum post that said they’d got a free replacement and it had taken 5 weeks. With nothing to lose, I took the photos above, sent them to Rapha and had it in the post the next day.</p><p>Three and a half weeks later a package turned up, and in a nice little “first aid” tote bag was my repaired jacket. Here are a few photos of their handiwork:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*9p72xOqRnu-mdFyFh7hULQ.jpeg" /><figcaption>The torn shoulder seam was repaired with a small patch. Maybe epaulettes will make a comeback in cycling?</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/724/1*sMaslKilrFD626i9859_JA.jpeg" /><figcaption>The grazed back panel has been covered with another layer of fabric. This covers part of the lower reflective band, but is really robust.</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*CDXchEhgDxOzHnsqY3rCIA.jpeg" /><figcaption>The arm was sown back together. This made the fit a bit closer, but is really neat.</figcaption></figure><p>I’m more than satisfied with the repair. Sure, it’s no longer as-new, and the back panel adds a little more bulk to the jacket, but when there’s all the other expenses of replacing clothing and components I couldn’t be happier that I’ve not had to shell out (excuse the pun) on a new jacket.</p><p>Five stars, but I hope I don’t need to use the service again anytime soon!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=8a874939e590" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Pull-Request style: 100 hills to die on]]></title>
            <link>https://spikeheap.medium.com/pull-request-style-100-hills-to-die-on-703475d36d74?source=rss-19e2ee7a60d0------2</link>
            <guid isPermaLink="false">https://medium.com/p/703475d36d74</guid>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[programming-tips]]></category>
            <dc:creator><![CDATA[Ryan Brooks]]></dc:creator>
            <pubDate>Thu, 31 Dec 2020 16:01:20 GMT</pubDate>
            <atom:updated>2020-12-31T16:01:20.430Z</atom:updated>
            <content:encoded><![CDATA[<p>Back in the early days, once we’d whittled our keyboards from a block of granite, we’d debate tabs vs spaces. Then we moved onto fixed display widths. Many a good friendship was lost to these worthy causes.</p><p>Then one day, something happened to restore peace. Swanky editors with soft-wrap, style guides, and EditorConfig united developers around one principle: consistency. Consistency was hard to argue against, and as tooling made it easier to promote/enforce we started to realise that the actual choice didn’t matter that much really.</p><p>So our armies retreated to our caves, ushering in an age of peace and productivity. But with that peace came complacency, and murmurings started again, this time around code collaboration. The Git Flow Wars of the 2010s saw the resurgence of trunk-based development and a return of the endless debate, this time around whether git rebase was a silver bullet or a corrupting force of evil.</p><p>Now we’re well into the age of the Pull Request, and the questions are coming back. Who should merge them? How big should they be? What should they contain? How should we review them? Disciples of the many “One True Way”s are out in force, but we already know the answer: it probably doesn’t matter what you pick as long as you’re consistent. Consistency within a team or organisation is what we’re after, not consistency across a career.</p><p>As a technical lead, delivery manager, or just someone hoping for a quiet life, here’s a checklist of the subjective debates that risk bikeshedding and becoming a time-sink. When they crop up in reviews it’s a “smell”, a signal that the team has a diverging understanding of concepts that we need to be able to rally around. It’s tempting to set up a session to talk about how you <em>should</em> be doing things, but that’s a red herring. The first thing you need to do is get agreement on how you <em>are</em> doing things, and write that down. We can call it a Team Charter, a Ways of Working document, or anything meaningful to your team. The important thing is to document the decision. For an extra point capture a simple “why”.</p><p>Once we’ve captured our baseline, we can apply some agile goodness and iteratively improve the way we work. Retrospectives are a great place to reflect on how your ways of working help or hinder you, agree experiments to try, and evaluate their effectiveness.</p><h4>The list</h4><p>There’s nuance to many things on this list, and there may be objectively “better” options, but often they’re marginal gains rather than the only way to avoid catastrophe.</p><p>The list is grouped into three areas: commit etiquette, pull request scope, and how we merge.</p><p>Commit etiquette:</p><ul><li>Step-by-step commits.</li><li>Merge main into the branch or rebase?</li><li>The perfect commit history.</li><li>All commits pass CI (e.g. enforced git precommit hooks)</li><li>Commit messages. Is there a format? Do we use semantic commit messages? Should every message contain <a href="https://gitmoji.dev">Gitmoji</a>?</li><li>Should lint fixes be a separate commit?</li></ul><p>Pull request scope:</p><ul><li>“Scouting” and refactoring as a separate commit or different PR?</li><li>Coverage &amp; quality creep. Is it okay for a single PR to leave the codebase slightly worse?</li><li>PR size. This is the big one! Should there be one PR per card/issue, or many tiny increments?</li><li>Do you use/how do you use “draft” PRs? Are they for presenting ideas, or work in progress. What’s their lifespan?</li><li>PR descriptions. Do you have a a standard template? What do you expect to see in a description?</li><li>Do we use labels? If so, how?</li><li>Are chained PRs allowed?</li><li>“Fix in this PR” vs “I’ll add that in another PR”.</li></ul><p>Merging:</p><ul><li>Squash, merge, or rebase into main?</li><li>Request changes vs comment vs approve. What are the implications of each type of response?</li><li>How do we request review (ask on Slack, auto-post, email notifications…)? Is a review open to all, or do you invite specific reviewers? What if you’re not invited but care?</li><li>What’s the review process? What’s in scope? Do you value high level or low level comments, and when is each type appropriate?</li><li>Minimum reviewers</li><li>Does it need to be up-to-date with main before merge?</li><li>Who decides if it <em>can</em> be merged? The author or the reviewer?</li><li>Who merges the PR (again: author or reviewer)?</li></ul><h4>Record your ways of working</h4><p>Now you’ve figured out how you work, you’ll want to write it down. Without wanting to open another can of worms, there are a couple of qualities common to team charters which are actually read, honoured and evolved by teams I’ve worked with:</p><ol><li>They’re short and concise. It feels good to write 2000 words on the primacy of meaningful commit messages, but think about your reader. A new team member doesn’t want to lose two weeks trawling a book on how they should collaborate. Brevity is key. Short documents are easier to scan, and brief (1 paragraph) points are more easily pointed to. If you <em>really </em>need to write more to explain your decision, capture this elsewhere (Decision Records are great for this).</li><li>Each point is linkable. Being able to point at a specific rule in a pull request comment or chat makes conversations more concrete, and lowers the barrier to entry for reading and following. Most wikis and markdown renderers add IDs to headings so you can link to a point in the document, for example <a href="https://github.com/rubocop-hq/ruby-style-guide#indent-when-to-case">this rule</a> in the Ruby Style Guide on GitHub.</li></ol><h4>Conclusion</h4><p>Create a style guide for your ways of working, and encourage slow, thoughtful evolution over time. And don’t assume that what works well for your team is inherently the One True Way.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=703475d36d74" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Generic names are a smell]]></title>
            <link>https://spikeheap.medium.com/generic-names-are-a-smell-9357f0380b91?source=rss-19e2ee7a60d0------2</link>
            <guid isPermaLink="false">https://medium.com/p/9357f0380b91</guid>
            <category><![CDATA[software-development]]></category>
            <dc:creator><![CDATA[Ryan Brooks]]></dc:creator>
            <pubDate>Fri, 27 Nov 2020 09:49:34 GMT</pubDate>
            <atom:updated>2020-11-27T09:49:34.176Z</atom:updated>
            <content:encoded><![CDATA[<p>Names are powerful. Good names are intuitive, and communicate intent and meaning to the reader. Good names help us have discussions without ambiguity, and gently nudge us towards a shared understanding of the thing.</p><p>Bad names, on the other hand, slyly make our lives harder. They hide ambiguity, and introduce tension into discussions. They make agreement harder, with different parties taking the name to mean different things. Sometimes none of these match the original intent, or even what the thing does.</p><p>The worst of it is that bad names are crafty. They sneak into conversations, documentation and code. Often, they <em>look</em> like good names, until it’s too late.</p><p>One reason for this is that software development exists in an abstract world, where we strive for generality. We hope that by solving the general case we can promote reuse, or maximise the use-cases our system satisfies.</p><p>These intentions are noble, but I think this leads us to prematurely over-generalise. When we do it too soon, it’s all too easy to make poor design decisions because the ambiguity is hidden behind names which mean little to us.</p><h4>Whose backend are we talking about?</h4><p>This is most obvious when we’re talking about architectural components. I want to single out “Backend” and “Frontend” as pervasive examples of overly generic names. If you see these in the wild, beware! If they come up in conversation, there’s a high likelihood that what people think these terms mean will differ within the group.</p><p>As an example, a recent Hacker News <a href="https://kartick.substack.com/p/make-your-backend-layer-as-thin-as">article</a> talked about making “your backend as thin as possible”. The article has a number of other problems, but biggest of all is that “frontend” is completely meaningless. In one organisation it might mean a single-page JavaScript application, in another it’s a Node process serving a website. “Backend” doesn’t help much either. Maybe it means a single Django app on a server that does all of your organisation’s business logic. Maybe it’s a backend-for-a-frontend (that’s a bit meta), with a load of micro-services in the background.</p><p>I know what you’re thinking: “frontend” isn’t ambiguous, and it doesn’t mean what you just wrote. But this is a real example. I know real live people, good engineers, who refer to a Node app as a “frontend” and at the same time have React components in the browser making API calls to that app. This might sound crazy, but it’s a simple and straightforward evolution, where the names “backend” and “frontend” were used on day one, and stuck.</p><h4>Great, but what does “better” look like?</h4><p>Figuring out what’s better is hard. Naming is one of the hardest problems in software engineering. Rather than offering a prescription for naming that can’t fit everyone’s needs, instead there’s two questions I ask when I see any name:</p><ol><li>Does this name help me understand what problem it solves, and how it works?</li><li>Do these names mean something else (more generic, specific, or just different) in another context?</li></ol><p>With these two tests, we can validate potential names. Sometimes all our options will fail one or both of these tests, so we’ve got the option to pick the least-bad one, or rethink the problem entirely. If we can’t find names that pass these tests I treat that as a smell. Are we trying to wedge something into an abstraction that doesn’t fit? As with all smells, it’s not definitive proof that you’re doing something wrong. It’s just a hint, a thread to pull.</p><h4>A practical example</h4><p>Let’s assume we have a headless content management system (CMS), with a lightweight application which uses the CMS content (among other things) to serve HTML, CSS, etc. to the browser. We <em>could</em> call the lightweight application the “frontend”, and the CMS the “backend”, but this doesn’t convey any meaning to a new engineer. These names fail the first test. At first glance it <em>looks</em> like the names convey some standard meaning, but as we’ve already covered, they don’t even tell us how it works or where it might live in our stack — a backend could be an API or a something serving HTML. So, these names fail the second test as well.</p><p>To name these better, we need more information. Let’s say the CMS serves a wide range of content for people in a care home. We know that the CMS is the only source of internally curated content, but we’ll aggregate content from third parties later on. The lightweight application serving content to the browser is only for residents, but has additional features such as chat.</p><p>A few options come to mind for the CMS component (there are myriad more, and that bike shed is left as an exercise for the reader):</p><ol><li>“CMS”. Pretty basic, but short is good, right? This passes the first test of helping me understand what the service does, but doesn’t help me understand how it works.</li><li>“Headless CMS”. Okay, now we have a bit of information about how I might interact with it, and what it does. This <em>looks</em> like it passes the first test, but our noses tell us to hang on — it helps us understand the technology, but not the problem it’s solving for our users. It also fails the second test of being too generic. Our CMS solves a specific problem, so we can use the name to reflect that.</li><li>“Residents local content API”, flips things around a bit. This looks like it passes the first test. I can tell from the name what I’d expect the CMS to contain, and how I’d interact with it. It’s also clear it has something to do with residents, though it’s not obvious whether it’s authored by them, served to them, or both. It also passes the second test — the name <em>feels</em> about the right level of specificity. Another CMS could be added without confusion, and we could introduce an external content API without needing to rename anything.</li><li>“Residents local video series API” makes our name even more specific, but maybe we’ve gone too far. Are we confident that we’ll only ever add series of videos? Does the one audiobook on the CMS invalidate that name?</li></ol><p>Even in this simple example, a whole bunch of questions come up. You know you’re on the right path when those questions are specific to your teams, organisation, and users.</p><h4>Summing up</h4><p>Next time you’re naming a service, application, or component in your code, validate them against these two tests.</p><ol><li>Does this name help me understand what problem it solves, and how it works?</li><li>Do these names mean something else (more generic, specific, or just different) in another context?</li></ol><p>If they pass first time then great! You’ve increased your confidence.</p><p>If you’ve tried this approach, or tackle this another way, I’d love to hear about it in the comments or [on Twitter](<a href="https://twitter.com/spikeheap">https://twitter.com/spikeheap</a>).</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=9357f0380b91" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Running a remote hack day]]></title>
            <link>https://spikeheap.medium.com/running-a-remote-hack-day-94fc6a9b9550?source=rss-19e2ee7a60d0------2</link>
            <guid isPermaLink="false">https://medium.com/p/94fc6a9b9550</guid>
            <category><![CDATA[remote-working]]></category>
            <category><![CDATA[event-planning]]></category>
            <category><![CDATA[remote]]></category>
            <category><![CDATA[hackathons]]></category>
            <dc:creator><![CDATA[Ryan Brooks]]></dc:creator>
            <pubDate>Sat, 11 Apr 2020 15:15:19 GMT</pubDate>
            <atom:updated>2020-04-20T07:11:26.921Z</atom:updated>
            <content:encoded><![CDATA[<p>A couple of weeks ago we held our first <a href="https://remotehack.space">Remote Hack</a>, a free, fully-remote hack day. Here’s what we did, how it went, and how you can run one.</p><p><strong>Planning the day</strong></p><p>To get things moving we set up a Slack organisation, a GitHub repository with a static site using <a href="https://pages.github.com">GitHub Pages</a>, and bought the <a href="https://remotehack.space">remotehack.space</a> domain name. We wanted to keep organisation and attendance lightweight, so after starting with a GitHub PR approach like <a href="https://sushack.github.io">SusHack</a> we opted to open signups for the remote-hack Slack group and use chat/signups to gauge interest. We shared details on local Slack groups (Digital Oxford, Sheffield Digital) and Twitter.</p><p>We already had access to a paid Zoom account (to work around the 40 minute limit on free accounts), so created a link and shared it in the Slack. The barrier of Slack signup worked well for preventing random Zoom trolls from finding the link on Google, and made sure we had a common place to come together, kick off the day, and talk.</p><p>That’s it. We were conscious that a smaller group would likely be more sociable and reduce the challenges for the organisers, so didn’t push too hard on social media.</p><p><strong>On the day</strong></p><p>The start of an in-person hack day often revolves around a whiteboard to collect ideas (and a load of free pastries and coffee). To make this work for a distributed event we used the <a href="https://github.com/remotehack/remotehack.github.io/issues">GitHub issue tracker</a> and asked people to add ideas in the lead-up to the event.</p><p>We opened up the Zoom call 30 minutes early, and as people trickled in we had a great, informal chat before getting into things, setting the scene and then going through the ideas on the issue tracker and picking groups.</p><p>People worked in different ways. Ben and Gabor were keen to try out Visual Studio Code’s <a href="https://docs.microsoft.com/en-us/visualstudio/liveshare/use/vscode">remote collaboration feature</a> , while Mike and I paired most of the day using <a href="https://screen.so">Screen</a>. Adam and Ed hacked alone. Most of us ducked out of the Zoom call, but continued to chat on Slack.</p><p>When we’ve run in-person hack days like <a href="https://web.archive.org/web/20160129214444/http://summerofhacks.io/">Summer of Hacks</a> (the domain is dead, but the yellow lives on) lunch has been a pretty big deal. We’ve been fortunate to have sponsors cover custom Mexican food for lunch and use that as a lever to get everyone back together to chat and be sociable.</p><p>We <em>really</em> love burritos:</p><h3>JSOxford on Twitter</h3><p>Thanks so much to @HaybrookIT for a fantastic lunch today at #RTHack</p><p>How do you translate that into a remote hack day? We had the great idea of doing a distributed lunch, and just all ordering our burritos (or whatever took our fancy) to be delivered at the same time.</p><p>Around 1pm we rejoined the Zoom call and hung out for half an hour, chatting away as Ben and Sarah ate burritos (I’d failed to make an order in time, so just had FOMO instead), before splitting back out into our groups and cracking on.</p><p>We’d planned to close up around 5pm, and came back together at 4:30 to show, tell and chat a bit more. Mike and I were so close to adding machine learning to the sentiment-bot (well, except for me having a .dev domain problem preventing any dependencies from downloading, and Mike not having ngrok set up). By 5:30 we’d been around the groups, chatted a bit more, and closed up to go our separate ways. I headed straight downstairs for a cocktail and a call with the family.</p><h4>What worked?</h4><p>• A communal group call worked well for a small number of people, but could quickly become unwieldy with larger numbers. We managed to avoid the webinar-style call with everyone except the presenter muted, and really wanted to highlight the social aspect of the event.</p><p>• Starting small. Running a day with 5–6 people I knew pretty well was a pleasure, and created a great atmosphere.</p><p>• Keeping the chat going on Slack. At work I find this quite distracting, but it was great to have light-hearted interruptions during the day. It probably helped that Mike and I were building a Slack sentiment analysis bot…</p><p>• <a href="https://screen.so">Screen</a> for remote multiplayer/pairing. It felt like the good old days of ScreenHero, and Mike and I took turns sharing screens.</p><p>• It didn’t feel like work. Even though we were coding, it felt fun, sociable, and there was no pressure to deliver anything.</p><h4>What didn’t work so well?</h4><p>• Distributed lunch orders. I forgot! It’s also quite nice to jump back into home life — I went to catch up with Nev and have a quick lunch, but felt I should be back to be part of the day. When you’re all on-site there isn’t that contention, but I’m not sure which way I’d want it to go.</p><h4>What would I try next time?</h4><p>• Shorten the round-table ideas session first thing. We ended up talking about each idea fairly extensively, so I’d like to try keeping it to a 1–2 sentence summary of the idea, and then flesh the idea out in breakout groups so we can get started sooner.</p><p>We’ll be running the next event on Saturday the 25th of April. You should join us: <a href="https://remotehack.space">https://remotehack.space</a>.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=94fc6a9b9550" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Lessons learned from the NPD Find & Explore project]]></title>
            <link>https://spikeheap.medium.com/lessons-learned-from-the-npd-find-explore-project-6b044649b165?source=rss-19e2ee7a60d0------2</link>
            <guid isPermaLink="false">https://medium.com/p/6b044649b165</guid>
            <category><![CDATA[software-development]]></category>
            <dc:creator><![CDATA[Ryan Brooks]]></dc:creator>
            <pubDate>Thu, 13 Jun 2019 17:31:00 GMT</pubDate>
            <atom:updated>2019-06-13T17:35:19.899Z</atom:updated>
            <content:encoded><![CDATA[<h3>Lessons learned from a recent project</h3><p>Earlier this year I had the pleasure of working with the Department for Education, Nimble and Paper on the Alpha and Beta phases of a Find &amp; Explore tool for the National Pupil Database. Having reflected on that experience, here’s a few lessons I hope I can apply to future projects, in no particular order.</p><h4>You can’t just waltz in at full speed</h4><p>Complex organisations have complex processes. Take the time early on to map out these processes through the lenses of the different departments. As an example, in addition to the GDS process (Discovery → Alpha → Beta → Live) we had Architecture Review Board and Technical Design Authority gates for technical architecture, as well as the Agile Security Framework, and Data Protection Impact Assessment. These disparate processes were entirely necessary for each groups’ governance, and once we knew about them we were able to reuse documentation across each piece.</p><h4>Don’t leave assumptions unchecked</h4><p>I felt fairly relaxed when we found out we’d be given a subscription on Azure to deploy our environments using ARM templates, but this feeling was based on a bunch of assumptions. We were caught out a bit when restrictive policies and naming conventions were introduced later on. Talking more with the Ops/Infra teams would have eased this pain, and would have surfaced some key information about the platform and its state of development which only came to light later on.</p><h4>Being an outsider can be a real boundary</h4><p>We experienced a couple of instances where we had to work hard to gain trust and alleviate suspicion because we weren’t full-time employees within the organisation, and a couple of times it was assumed we didn’t understand the nuances because we weren’t really part of government. This skepticism can be really valuable to make sure the right decisions are being made, but it made it much harder to get buy-in for some of the changes we were proposing. Other members of the team were exceptional at prioritising building relationships to overcome this barrier, and in at least one case this paid off with a key ally pushing to overcome some internal bureaucratic hurdles so we could deliver quicker.</p><p><a href="https://twitter.com/nimphal">Nev</a> summed this up better than I could:</p><blockquote>The lesson from this is patience — if you are doing a good thing and believe in it, then persevere.</blockquote><h4>Interactive exercises are more valuable than just talking</h4><p>The team brought some interesting exercises to meetings with users and other stakeholders, for example UI sketching to capture what the users thought a perfect workflow could look like. Even basic exercises like retros and lean agendas worked well to get people involved. It may be novelty, but its amazing what a pack of post-its and sharpies can achieve.</p><h4>Relationships are the single most important factor of success</h4><p>Our project would have faltered in the final weeks were it not for a couple of amazing colleagues in the enterprise architecture team pushing to broker a compromise between the security and cloud infrastructure teams which allowed us to meet our deadlines.</p><h4>Trust your experience</h4><p>This was my first time for a number of things:</p><ul><li>Working on a government project</li><li>Being part of a GDS-style cross-functional team</li><li>Being Technical Architect on a project with a single developer</li><li>Working with agency contract Ruby developers</li></ul><p>When it came to estimates, I second-guessed myself. Maybe I was being too pessimistic. Perhaps I’m just not a very efficient developer. Agencies are used to working with solo developers, and agencies seem to get a lot done. Maybe I should revise those estimates.</p><p>My “pessimistic” estimates were pretty accurate in the end, but I revised them. I should have trusted my experience and shunned the self-doubt. In future I’ll use that to start a conversation rather than talking myself out of it. I could still be wrong!</p><h4>People play the long game</h4><p>If the project is short and someone doesn’t agree with it, they can probably just wait it out, especially if the project team is external or will disband once it’s completed. This sounds cynical, but if they’ve seen lots of short-lived projects come and go they’re likely to experience change fatigue. They’ll also learn that they’ll outlive failing projects, and that it’s (maybe often) not worth the emotional or cognitive effort of engaging with something that seems flawed. This is a vicious circle, where a lack of engagement increases the chances of the project floundering, or just not meeting their needs, which then validates the initial resistance to engaging with it.</p><p>I’ve not got an answer about how to overcome this, other than that getting them onboard is almost certainly more important than it appears when you hit that first resistance.</p><h4>The team is key</h4><p>This isn’t new, but it’s good to reinforce that the team makes all the difference, especially when things get tough. During the last few weeks of the project we encountered a number of technical and process challenges which knocked us back and slightly off-course. This could have been a horrible environment, as the impending hard deadline ratcheted up pressure from ourselves to deliver what we’d set out to. I’ve been there before, and that stress leads to long hours, which leads to a whole host of other problems.</p><p>What actually happened was everyone came together to keep us afloat and (relatively) sane. Having a friendly, supportive environment in the office each day made the last weeks much more enjoyable, and helped prevent us spiralling off individually as we tackled our own challenges. Tacking on “check ins” (thanks for starting that Urska!) to see how everyone’s feeling, and openly promoting mental well-being and the importance of looking after yourself first is paramount. Kudos to Jon for always putting people first, and not faltering when times got tough.</p><p>When you’re part of a great team it’s easy to take it for granted. The lesson I’ve taken from this project is to be thankful, and to take the time to let people know when they’ve made an impact.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=6b044649b165" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Invest in internal tooling]]></title>
            <link>https://medium.com/honest-focus/invest-in-internal-tooling-8bf038e45e07?source=rss-19e2ee7a60d0------2</link>
            <guid isPermaLink="false">https://medium.com/p/8bf038e45e07</guid>
            <category><![CDATA[management-and-leadership]]></category>
            <category><![CDATA[software-development]]></category>
            <dc:creator><![CDATA[Ryan Brooks]]></dc:creator>
            <pubDate>Tue, 31 Jul 2018 10:42:15 GMT</pubDate>
            <atom:updated>2018-07-31T10:51:38.390Z</atom:updated>
            <content:encoded><![CDATA[<h4>Empower colleagues to solve their problems early to retain your development velocity</h4><blockquote>Hi Ryan, could you do me a favour and just confirm this user’s account please?</blockquote><p>This request didn’t pop up in Slack in the first days of a new user confirmation feature. I was seeing this a couple of years later. The single line of Ruby was well known amongst the developers (it’s hardly rocket surgery) as we’d get a couple of requests a month, and within minutes we’d marked that account as confirmed and got back to more interesting challenges.</p><p>I see it over and over again. I fall for the same thing myself, even though I should know better: failing to automate menial tasks that encumber our non-developer colleagues because there’s “more important stuff to do”.</p><p>In our case, we’d gone as far as to create an issue to track adding a user confirmation function to the admin dashboard. It was hard to prioritise it above revenue-generating stories and it languished. A couple of years (!) later we sat down with the support team and figured out this was one of two things they regularly came up against which required the dev team. This was understandably frustrating for them — support resolution times were a key metric of their performance so having to fire off a message to a group of developers who would much rather stay focussed on their current work ground them down.</p><p>It took a couple of hours to change this from something only a developer could do to a task that can be resolved by any member of the team. Not only did this empower the support team, it also reduced the amount of urgent interruptions the dev team was getting.</p><h4>Value non-developers</h4><p>Developer time often takes precedence because it’s so easily tied to the delivery of new features. When there’s a push for features and pressure from investors it’s easy to sideline other functions of the business. Sales and Support often benefit from being able to get insights into the system, flip check-boxes, and set up new accounts. Spending time to make their lives easier reaps dividends (if you’ll excuse the pun) not just in their productivity but also in engagement with the developers. Small businesses really need to fight to keep everyone on the same side, and it’s easy for boundaries to emerge when people feel hard-done-by.</p><h4>What do you tackle?</h4><p>Good candidates for enhancement fall into two categories:</p><ol><li>Simple administrative tasks, for example adding users to a client organisation.</li><li>Reporting and business intelligence.</li></ol><p>It may be that the development team can come up with a list of internal requests they see often, but in the spirit of engaging the whole business a great place to start is to interview representatives from each business function with a question:</p><blockquote>If we could do one thing that would make your work easier, what would it be?</blockquote><p>And if you like variety, a more open question which allows you to work through to the solution is:</p><blockquote>What hiccups are there in your workflow? Where are you left needing answers from developers, or just guessing?</blockquote><p>The development team can weigh in on the complexity of the fixes. Value isn’t just measured in time, but there’s a handy graph to give you an idea of how to evaluate time-saved vs development effort by XKCD:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/571/1*eGXW9bxRyxdA21uJRPtwkw.png" /><figcaption>Is it worth the time? — <a href="https://xkcd.com/1205/">https://xkcd.com/1205/</a></figcaption></figure><h4>Quick fix ideas</h4><p>One of the most common quick-fixes is to add an admin dashboard, such as <a href="https://github.com/sferik/rails_admin">RailsAdmin</a>. With very little custom code, your non-technical internal users can add, edit, and maybe delete records from your application. This (obviously) requires a degree of caution, but resolves a host of tiny support requests.</p><p>It’s also very common to see the business requesting simple reports from the developers, e.g. the number of registrations by month for the past quarter. Maybe these rear their heads for investor meetings or quarterly all-hands, but they always point to a more subtle problem — the business lacks Business Intelligence tools. Spending half a day installing <a href="https://www.metabase.com">Metabase</a> may not only prevent these requests coming through, but also empower other parts of the business to investigate your data and start making more informed decisions. One of our clients still raves about the impact Metabase had on the whole business over a year and a half later!</p><h4>So, when do you enhance?</h4><p>“Soon, when we have a bit more time” is a popular response. The future always feels like it’ll be a little less busy, a little more structured. The truth is that future never comes; once the imminent hurdle is overcome the next challenge comes into view.</p><p>The time to do it is now. Always. Making tiny improvements to the working lives of your non-developer colleagues pays back many times over, compounding productivity on both sides as developers are interrupted less often (or at least, for less meanial sidetracks 😛).</p><p>The most common approach to setting aside time seems to be adding one or two items into a sprint as nice-to-haves, but this feels like it subverts the principle of the sprint because they’re often seen as lower priority (and we all know everything in the sprint scope is equal… sometimes).</p><p>Another way which looks very promising is to have one week of improvements every 4–6 sprints. I read an article a while ago which described lining up sprint starts with the beginning of a month, which built in both the internal improvements iteration week <em>and</em> made it easier to other parts of the business to know when sprints would start/finish (if anyone can remember where that was from I’d appreciate the link!).</p><p>There’s always the good, old 20% time approach. We’ve successfully run “Fun Friday Afternoons” where we were a bit tight and only had 10% time. The point is to experiment and see what works well for <em>your</em> team.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=8bf038e45e07" width="1" height="1" alt=""><hr><p><a href="https://medium.com/honest-focus/invest-in-internal-tooling-8bf038e45e07">Invest in internal tooling</a> was originally published in <a href="https://medium.com/honest-focus">Honest Focus</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Security is not a "pro" feature]]></title>
            <link>https://medium.com/honest-focus/security-is-not-a-pro-feature-151eec09fdfa?source=rss-19e2ee7a60d0------2</link>
            <guid isPermaLink="false">https://medium.com/p/151eec09fdfa</guid>
            <category><![CDATA[open-source]]></category>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[security]]></category>
            <dc:creator><![CDATA[Ryan Brooks]]></dc:creator>
            <pubDate>Fri, 01 Jun 2018 09:51:23 GMT</pubDate>
            <atom:updated>2018-06-01T09:51:23.192Z</atom:updated>
            <cc:license>https://creativecommons.org/licenses/by-nd/4.0/</cc:license>
            <content:encoded><![CDATA[<h3>Security is not a “pro“ feature</h3><p>We rely on Open Source for a huge portion of the Internet (and beyond), yet many projects still rely on goodwill and donated effort in order to survive. Sometimes that’s not enough, and organisations like <a href="https://rubytogether.org/">Ruby Together</a> have helped to make critical pieces of developer infrastructure more sustainable. Other projects have taken the approach of introducing premium tiers, adding enhanced functionality to libraries, tools and services in an effort to generate revenue and enable the (sometimes sole) developer to spend more time on the project.</p><p>Sustainability in Open Source software development is hugely important, but we need to walk the path carefully.</p><p>How do you choose which features to include in the “pro” version of your library or product? Include too few and users may not see the value in upgrading; include too many and you may not see enough adoption of the free tier to funnel into your paid version. But I think feature choice goes further than that.</p><p>Developers are starting to adopt <a href="https://serverless.com/">serverless patterns</a> for side-projects to keep hosting costs down. Message queues and background processing are <a href="http://edgeguides.rubyonrails.org/active_job_basics.html">built in</a> to modern frameworks. Federated authentication is just a <a href="https://github.com/omniauth/omniauth">library</a> <a href="https://github.com/jaredhanson/passport">away</a>. The lines between enterprise and personal projects are blurring.</p><p>As a community we need to push best practices. Maintainability. Accessibility. Security. Probably not in that order. We have a responsibility to remove barriers to developers using our software so they fall into the <a href="https://blog.codinghorror.com/falling-into-the-pit-of-success/">Pit of Success</a>. If we withhold features from these categories from our free version, we’re making secure, maintainable, accessible software harder to produce, which doesn’t feel like a good thing.</p><p>Now, I’m going to pick on the excellent <a href="https://github.com/rmosolgo/graphql-ruby">Ruby GraphQL library</a> purely because finding it prompted me to write this post and having a concrete example makes it easier to think about. Authoring and maintaining this project is no small feat, and in an effort to make the project sustainable the author has created <a href="http://graphql.pro/">GraphQL::Pro</a>, which adds a number of features to the free library, provides a GraphQL subscriptions stack, and adds prioritised support. The first feature jumps out:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*-WCKL2JlzUAcYsN333RmRQ.png" /><figcaption>GraphQL::Pro offers fine-grained authorisation as a paid feature</figcaption></figure><p>It would be unfair to say that the free version <em>prevented</em> you from doing authorisation. A few <a href="https://blog.codeship.com/how-to-implement-a-graphql-api-in-rails/">walkthroughs</a> exist demonstrating authorisation within mutations, and it’s feasible to implement your own authorisation layer in the Open Source gem. But, if this were a free feature would we expect to see better GraphQL implementations in Ruby, with less data potentially exposed to maliciously crafted queries?</p><p>Unfortunately this approach isn’t limited to independent library producers. Elastic hides almost all their security features behind a subscription (which <a href="https://www.reddit.com/r/elasticsearch/comments/62n2h6/pricing_for_xpack_gold/">reportedly</a> costs &gt;$5k USD per node):</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*T4JI3iOo4Mcmp9P-Y4BCSA.png" /><figcaption>Elastic thinks only Gold customers should have encrypted communications…</figcaption></figure><p>For many organisations, this just means Kibana or ElasticSearch end up behind an nginx proxy or with no security at all. Considering how great Kibana is for visualising data, it’s easy to see how these unsecured applications end up accumulating more sensitive data. If Elastic provided RBAC and encrypted communications as part of their free tier, would we see smaller businesses picking up better security practices?</p><p>Elastic’s pricing highlights how the need to generate revenue has eaten into features that should be the right of every citizen of the Internet. Developers should be encouraged and pushed to do better security, for the sake of our users. It’s pretty easy to argue that LDAP, AD &amp; SAML authentication are primarily used by larger organisations who have more ability to pay these license fees, but shouldn’t we be promoting encryption at rest for every use case? Doesn’t <em>every</em> Kibana installation deserve encrypted communications?</p><p>Frustratingly, while Elastic “opened up” X-Pack <a href="https://www.elastic.co/products/x-pack/open">recently</a>, all the Security features remain “pro”:</p><h3>Ryan Brooks on Twitter</h3><p>@elastic I&#39;ve just seen https://t.co/78oTMrRXSN. Great news! Is authentication/authorisation &amp;amp; RBAC from Security included in the free/open features?</p><h3>elastic on Twitter</h3><p>@spikeheap The code is open, but it&#39;s still a subscription feature.</p><p>I <strong>absolutely</strong> support efforts to make Open Source projects sustainable. Charging for the use of libraries and services is a completely valid way to generate revenue, and we all need to eat. However, I’m conscious that we may be creating modern crippleware, where the free tier necessitates poor security practices or forces the ones who know better (and have the capital) to upgrade.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=151eec09fdfa" width="1" height="1" alt=""><hr><p><a href="https://medium.com/honest-focus/security-is-not-a-pro-feature-151eec09fdfa">Security is not a &quot;pro&quot; feature</a> was originally published in <a href="https://medium.com/honest-focus">Honest Focus</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
    </channel>
</rss>