More from Miguel Carranza
I recently wrote an internal Management 101 guide for new RevenueCat managers. It is not meant to be a universal management guide. Most universal management advice is either too vague to be useful or too generic to survive contact with a real company. My goal was simpler: explain what we expect from managers, why the role matters, what tends to feel weird at first, and where to start when things get messy. One of the sections I think matters most is the dopamine problem, because it is one of the most immediate changes. The weirdest part of becoming a manager is that your old scoreboard disappears. As an IC, you can point to things you shipped. Code merged. Bugs fixed. Systems improved. Customers helped. Even hard weeks usually have visible artifacts. Management work is slower and less satisfying in the short term. You can have a great week and nothing obvious happened. A project got slightly clearer. A candidate stayed warm. A conflict did not become a fire. A direct report heard feedback early enough to fix something. A team avoided a bad architectural decision. A future manager took one more step toward readiness. That is real work. It just does not always feel like it. This is one of the hardest parts of the transition from IC to manager, especially for Engineering Managers. You are used to being useful in a very concrete way. You know how to debug the issue, review the design, write the code, fix the incident, and unblock the team. Then suddenly a lot of your work becomes indirect. You need to stop trying to solve the problem in front of you. You need to make the team better at solving that type of problem in the future. It is also getting harder in the age of AI. Agentic coding is even more addictive. You can describe what you want, watch the agent work, review the diff, and get a working prototype or bug fix in minutes. The loop is fast and incredibly satisfying. This is why many new managers cling to coding, technical details, or direct execution. It gives them the old dopamine. It also feels useful when there is urgency: a project is at risk, a technical issue is blocking the team, or execution is moving slower than you think it should. Sometimes stepping in directly is the right call. If production is broken, do not sit there having a philosophical debate about leverage. Help. But most of the time, direct execution is a patch around the real problem. If the project only moves when you personally drive it, something else is broken. Maybe ownership is unclear. Maybe the team does not have enough context. Maybe the technical plan is too complex. Maybe the bar is too low. Maybe someone needs feedback. Maybe you have the wrong people on the problem. Maybe you are still acting like the tech lead because that is more comfortable than acting like the manager. Your job is to make the team capable of executing without you, either by hiring the right people, training people up, clarifying ownership, or raising the bar. If you keep solving the work yourself, you prevent yourself from learning the new job and prevent the team from growing into it. You need to rewire your satisfaction from “I shipped the thing” to “the team is stronger and shipping better because of the work I did.” That takes time. Some practical advice: Set weekly goals for yourself. Not vague goals like “be a good manager.” Concrete goals: write the 30/60/90 plan, give feedback to X, unblock Y, clarify ownership for Z, source X candidates, review hiring funnel metrics, talk to another manager about a problem. Create accountability. I use weekly emails. Use whatever works, but do not let weeks disappear into meetings. A full calendar is not evidence of impact. Write things down. Writing forces clarity and creates artifacts when the work itself is abstract. If you cannot write the decision clearly, you probably have not made the decision. If you cannot write the feedback clearly, you probably do not understand the behavior well enough yet. Look for compounding work. Better onboarding, better interview calibration, clearer team ownership, stronger tech leads, training people up, and improved decision-making pay off repeatedly. They may not feel as satisfying today, but they make the company more capable. Management is not a promotion from building. It is a different way of building. You are building the system around the work: the team, the standards, the ownership model, the feedback loops, the hiring bar, the culture, the decision-making. The hard part is that the system does not always give you a green checkmark at the end of the day. Do it anyway. Originally published as an X article on July 10, 2026 and archived here.
RevenueCat now has more than 150 team members. Around 100 of them are in my org. This is still a little crazy to me. My own org is now bigger than any company I had worked at before starting RevenueCat. As a technical founder, I always preferred computers over people. Computers are deterministic. People are emotional. But if you find real PMF, team building becomes unavoidable. You have to build more. You have to move faster. You have to do more things in parallel. And at some point, the company stops being a product that a small group of people can brute force into existence and becomes an organization that needs to keep improving without breaking itself every week. I have made a lot of mistakes over the last almost 9 years. Some were obvious in hindsight. Some were expensive. A few were probably unavoidable. These are 100 of the lessons I have learned getting to a 100-person org. Recruiting is a long game. Just because someone says no today does not mean it is a no forever. Build the relationship, leave a good impression, and keep the door open. Hiring is always a priority, even when you are ahead of the headcount plan. If the company is growing, it is much easier to fall behind than to stay ahead. External recruiting agencies rarely work. Their incentive is not to find the best fit; it is to close a candidate as fast as possible. Excellent recruiters are very hard to find. When you do find one, everyone’s life gets a lot easier. The brand compounds like every other company metric. Candidates who were unreachable a year ago may eventually reply. Great people attract more great people. Hire enough of them and recruiting starts to get its own kind of virality. Most people oversell when recruiting. Don’t. The best candidates see through the BS and value honesty about both the good and the bad. Candidates appreciate knowing the salary and process upfront. It saves time for both sides. Have a compensation philosophy you can explain and defend. People might take a pay cut, but nobody wants an unfair offer. Focus on candidate experience. Some people will inevitably get upset, but keep improving the process. Magic happens when candidates have a great experience even after being rejected: they re-apply later and even refer friends. Technical interviews are already stressful. Do not make them more stressful than necessary. Avoid obscure questions, make the interview close to the real job, and encourage collaboration. If your interview process works, do not bend it under pressure. Consistency and fairness come from sticking to a standard loop. Spend time looking at recruiting metrics: pass rates, interviewer variance, stage conversion, and close rates. They will help you debug calibration problems. At a certain scale, when multiple people run the same interview, assign a DRI to calibrate interviewers and review scorecards. Watch out for interviewers who always grade YES, but never STRONG YES or STRONG NO. Read between the lines. They are probably uncalibrated. A candidate with several STRONG YESes and one NO is often more interesting than someone with YESes across the board. Keep an eye on how many interviews your best ICs are doing. It can become distracting and hurt shipping velocity. Constantly train new interviewers through reverse shadowing. Being desperate for a hire usually turns into lowering the bar. Avoid the temptation. The flags you see during the interview process almost always show up 10x at work. Pedigree is a weak substitute for evidence. We all make mistakes when we see shiny resumes, but there are bad people at great companies too. Watch out for people who have seen scale, but have not done the scaling. They are easy to spot if you ask detailed questions about the problems they faced and how they solved them. Watch out for repeated short stints. Everyone can get unlucky once or make a bad judgment call. Multiple times is a pattern. Never skip reference calls. Even with a strong referral, do at least two. I have yet to see a candidate with weak references work out well. Backchannel references matter even more for executives. You will learn more there than in the interview process. If the references are not stellar, it is probably not worth the risk. Everyone wants feedback when they are rejected, but be careful with what you share. The reason is usually technical ability, culture fit, or both. A lot of people do not want to hear it. If they meet the bar, hiring users can be a great hack. They already know the product, including the good and the bad parts, so onboarding is much faster. Attitude and values alignment matter more than raw technical skill. If the foundations are there and the team is strong, the candidate can grow. A genius who is not aligned with the team is a recipe for disaster. Always hire pragmatic engineers. Avoid dogmatic ones. We only get to play with computers because we serve customers. Migrating to the trendiest architecture with zero customer impact is a red flag. Never hire an engineering leader you cannot have a nerdy conversation with. They need to be deeply technical. Do not settle for a therapist or coach. Everyone wants to work from home, but only a minority of people are disciplined and self-motivated enough to work remotely. Hire for flexibility, but be flexible too. Understand what motivates people. If they are doing great work and are excited about a different internal role, make room when the fit is real. You will mislevel candidates. It is okay. Under-leveling is easier to fix than over-leveling. Correct it as soon as it is obvious, and treat it as fixing a hiring mistake, not as a normal promotion. For every manager you hire, prepare a serious onboarding document: the team, their backgrounds, past reviews, strengths, current problems, and open questions. Then have them write a 30/60/90 plan. The easiest way to know if a new leader is working is to agree upfront on the success case and failure case in the 30/60/90 plan. The more objective it is, the clearer the decision becomes. Hiring mistakes do not mean the person sucks. They mean the person is not a fit for the current team. Not acting quickly is unfair to customers and coworkers. Do a postmortem after every separation, voluntary or involuntary. There is almost always something to learn. Do not be stingy with severance. You made the hiring mistake. Ultimately, that is on you. Most executives are full of shit. Many are career-driven status seekers who know how to sell themselves. The job is to find the actual builders, and they are rare. A great exec will make the company feel brand new. A mediocre one can destroy your culture, and if you are not careful, your company. Spend time with executive candidates in person. Watch how they think, work, and interact when they cannot perform a polished interview answer. Management sucks. Be suspicious of people who want to become managers. The best ones usually never wanted to be managers in the first place, but had to do the job and got good at it. The manager is not expected to do the IC job, but they better be able to do the job and be damn good. Management is not only managing ICs. It is also managing up. The best managers make fewer surprises happen. If you have a good team, managers should spend most of their time on delivery and some of their time on people. Sound the alarm if those percentages flip. Even the best managers need calibration, not just trust. Spend the time with them until they are calibrated. Only then do you get real leverage. Try to keep a healthy ratio between internal and external managers. Internal managers bring institutional knowledge. External managers bring management reps. Both sides need what the other has. Tricking people into management by starting them in technical leadership roles has been a useful way for us to scale, especially with established teams. But the transition from technical leader to actual manager needs to be very intentional. Hiring, org design, and long-term planning do not come naturally to most technical leaders. Middle managers initially have almost no incentive to terminate anyone. It creates conflict and feels optional. Support them through it. Once they see the team is better off without a bad fit, they start to understand. When managing managers, do not let them hire someone you would not want to manage yourself. Never promote someone out of fear or for retention. It almost always backfires. If every promotion case is obvious to the org, you avoid a lot of unnecessary drama. If a termination or “not meeting expectations” review is a surprise, it is a total management failure. A big counteroffer rarely works when someone is already leaving. By then it is too late. It is also unfair and proves the person was probably underpaid before. The only way to build a great team is to hire people better than you. Every hire resets the cultural and talent average. Aim to increase talent density, because otherwise it will naturally go down. B players hire C players. But even A players make hiring mistakes. Correct them quickly or they become a virus in the org. It only takes one unaligned or bad performer to destroy the motivation and momentum of a full team. Bad fits are rarely isolated incidents. There are always multiple signs. Performance issues will eventually become obvious to everyone. Focus on the middle performers. High performers and low performers are obvious. The people right on the line create the most problems because they are usually acted on too late. Top performers compare themselves against the very best people in the company. Reassure them when they are doing great work. On the other hand, underperformers compare themselves to other underperformers. That is how they convince themselves they are doing fine. The best people can stretch a lot. They often rise to the challenge. But watch their limits before they burn out or become the bottleneck. People usually do not burn out because of hard work. They burn out because they are doing shitty work or working with shitty people. Perfectionists can be great, but startups are hard for them. Help them embrace chaos. Things will break. The job is to keep reprioritizing and stop small cracks from becoming big fires. Even the best people have rough patches. Be empathetic, accommodate, and provide early feedback. But be clear that previous performance is not a guaranteed seat forever. Real startup people are not just the ones who enjoy the early stage. They are the ones who keep adapting as the company changes. You cannot build a company for everyone. The earlier you accept that, the more aligned your team will be. Write the company values down and never stop talking about them. Early employees shape the culture more than any values doc. Early employee morale is a good indicator of the state of the culture. Culture needs policing, even (especially) when things are going well. Have zero tolerance for illegal behavior and misconduct. Follow first principles, but remember that one of the best parts of starting a company is building a workplace you would have loved to work at. Do not be afraid to be unique. Don’t network for the sake of networking. It is mostly bullshit. Build great things instead, and the opportunities to meet and recruit interesting people will show up naturally. It is harder to run a 20-person org than a 100-person org. Between 20 and 40 people, systems break and communication lines grow exponentially. Fix the systems and org structure so you can keep scaling. Teams survive being small better than they survive unclear decision-making. Poor performers also have a harder time hiding in smaller teams. If there is no DRI, do not expect it to get done. Shared ownership usually means no ownership. Shipping velocity is a cultural advantage, and it almost always improves morale. If it is important, write it down. Writing is one of the most powerful leadership tools. Founder osmosis stops working around 50 people. Write things down and overcommunicate. Transparency in times of crisis pays dividends. Employees want to be treated like adults, and it builds trust. The same applies externally. Numeric goals are proxies. Missing one is not the end of the world if you learn. But beating the number while ignoring what is broken underneath masks critical issues. In order to preserve talent density, do light 30/60/90-day performance management for new hires. It forces early feedback and avoids surprises later. Do not listen to people who say founders should not waste time interviewing. That is bullshit. Hiring is the highest-leverage thing anyone at the company can do. Founder interviews help in three ways: you meet people you may not work with directly, candidates can ask direct questions, and hiring managers stay accountable. If the founder says no, there was probably a problem earlier in the process. At a certain seniority, it is not about who plays with computers best. It is about who knows the business and customers best, influences the team, and works autonomously without needing management. Create a culture where everyone is encouraged to talk to users. The more they hear the pain directly, the better and faster they will build. Always optimize for simplicity at startups: product, processes, systems, compensation, recruiting, everything. Optimize for simplifiers and avoid complexifiers. Small teams ship faster. This has always been true, and it is even more obvious in the age of AI. Reduce team size, give teams clear ownership, and have managers spend most of their time with the teams that are struggling. Praise people who go above and beyond and do things outside their scope. But a side quest should never replace the main quest. Keep an eye on median tenure, especially during rapid hiring. Sometimes you need to cool down before the team is ready to ingest and onboard more people. Reorgs are inevitable in a growing startup. Build a culture that understands they are necessary, not automatically negative, so you avoid unnecessary emotional damage. By the time a reorg is obvious, you are probably late. Re-evaluate the structure at least twice a year. When doing reorgs, start with an MVP: involve as few people as possible, make as few management changes as possible, and have a clear rollback plan. If you reach PMF and have built a decent pizza team, you have probably achieved more than most of your advisors. Be open to feedback, but do not let imposter syndrome override your gut. Only truly listen to the people who have actually done it. Get a real support system: coaches, other founders, people who understand the game. Family and friends can help, but they will never fully understand, and it is unfair to expect them to. The best way to spend less time managing bad people is to spend a lot more time hiring the right people. It’s never the smartest team that wins. It’s the one that persists, keeps going, day after day, doing thankless work to build something people want. Most companies fail. Life is too short to spend years building with people who drain you. Build a team you are inspired to work with and achieve the impossible.
They say only one out of 1000–2000 startups becomes a unicorn, and that only 1% of humans will ever finish a marathon. If you had asked my mother, though, she would have told you it was a thousand times more likely I’d build a billion-dollar tech company than finish a marathon. And I would’ve agreed. I was that kid in school with straight As who still almost failed PE. Two laps around the soccer field and I’d be hyperventilating. On New Year’s Eve last year, my co-founder Jacob slipped on the snow and broke his ankle. A gnarly injury. Fast-forward to March 1st, and he announces to the entire company and our investors that he is going to run the California International Marathon on December 7th. And also, he invited people to join him in his crazy adventure. I considered it for a split second and literally laughed out loud. This guy will do it, I thought. He’s delusional and stubborn enough to crawl the last 10 miles if necessary. But me? No chance. The longest run of my life was a single 10K, once, years ago. I ran it, and then immediately retired from the sport. But the idea stayed in the back of my mind. If Jacob crippled, needing surgery, with months of PT, could commit to running a marathon… what excuse did I realistically have? I was healthy. I had a head start. And honestly, after the twins were born, my exercise routine was basically nonexistent. Running was something I could technically do anywhere. My wife, fully aware of how much I hated running and how hard this would be for me, became a supporter. So I downloaded Runna. And I ran. I hated it. Deeply. Running felt like the most boring, repetitive, form of suffering ever invented. But something weird happened: I started seeing progress. Three miles stopped feeling like a death sentence. Then I ran 10. Then one random morning before giving a conference talk, I ran a half marathon by myself. And it didn’t even feel that hard. I started waking up earlier and earlier to get my mileage in before the morning meetings. Discipline compounds quietly, until suddenly you’re a different person. This year I traveled a lot. Yet running turned out to be the easiest habit to keep. I ran more than 900 km in 18 different cities. Running became a new, exciting way to explore a city. A nice way to start the day with a small win before all the startup chaos. This weekend, we did it. We ended the race in way more pain than we probably should have, but we crossed the finish line. And the biggest lesson I learned, bigger than training plans, pronation, and fueling… is this: You need to be a little crazy and do hard things. And that’s kind of the whole point. Life isn’t about being the best in the world. It’s about being the best version of yourself. Expanding what you thought your limits were. Rewiring your internal narrative from “I could never do that” to “actually, maybe I can.” I’m insanely proud of Jacob for this comeback story, and grateful (even if involuntarily) that he dragged me into another ridiculous adventure. It was worth it. And maybe this story nudges you toward something you’ve always dismissed as impossible. After running these 26.2 miles, building a decacorn feels easy. Okay, not easy, but you get the point. Will I do it again? I don’t know. If I had put this much time into surfing, I would suck a lot less at it and probably enjoy it more 😅. But I’ll keep running. It keeps me fit, clears my mind, and makes me a better version of myself. Which, in turn, helps me be a better founder, partner, and dad. Special thanks To Runna, genuinely a fantastic training app (and RC user!). To Marina, for the endless support and the childcare coverage while I disappeared for very long runs. To Andrew, Harlan, Bobby, Susannah, Sarah, Nacho, Chris, Mica, Matt, and Olga, for the advice, motivation, and for putting up with my running updates.
I’m back in Spain for my brother’s wedding. I rarely visit during the summer. The heat in my hometown is brutal, around 40 degrees Celsius (over 100 Fahrenheit for my imperial friends). Most people escape to the coast, just like my family did when I was a kid. I haven’t been here in years. As I drive along the coast, I find myself reflecting on a tweet about money and happiness, a vivid memory pulls me back in time. It’s August 22nd, 2007. The iPhone, the first real smartphone, has just been announced. It’s so cool, but of course I cannot afford it. It’s not even going to be released in Spain. I’ve just gotten my driver’s license, and I’m about to dive into my third year of Computer Science. I set up my clunky TomTom navigator knockoff, and hit the road. I’m on my way to meet Marina for our first real date. She’s cool, pretty, and kind. She likes the same music as I do, and even has distant relatives in California, the place we jokingly plan to visit someday (if I ever get enough cash). I’m listening to a pirated Blink-182’s self-titled CD. Pop-punk is pretty niche in the south of Spain, and it’s dying. Blink-182 has split up, and I missed my window to see my favorite band live. The Atlantic Ocean is as flat as a lake. This corner of Huelva’s coast is sheltered from any real waves, a stark contrast to the world-class surf breaks I drool over in magazines. And suddenly, reality hits: my childhood dreams of building a tech company in Silicon Valley, while vacationing in Southern California feel impossibly far. Even getting through my degree feels like a pipe dream. School isn’t fun anymore. It’s grueling, especially the parts I thought I’d enjoy, like algorithms and Data Structures. I might never become a Software Engineer. I feel stuck, trapped by my lack of direction. I am seriously considering quitting. But no degree means no job in the US, and good tech gigs are rare here in Spain. The only cool company is Tuenti, a new startup that is cloning Facebook. I’m nowhere near smart enough to land a job there though. Flash forward to today, 17 years later. It’s almost laughable to think about how hopeless things once seemed. Even now, it doesn’t feel like I’ve “made it.” The path and the results look nothing like what teenage me envisioned, but somehow, I’m realizing I’ve kind of checked off every box. I married Marina, and we live in Southern California with our two beautiful identical kids. We’ve become American citizens, and I’ve lived in the Golden State for nearly a third of my life. I’ve worked as a Software Engineer at a Silicon Valley startup, learned from the best, and found the best co-founder I could ask for. We launched our own company. Smartphones? They’re in everyone’s pockets now. Our product is in a third of all new apps shipped in the US. We’ve helped developers reach millionaire status, and we’ve made more money than I ever thought possible. But I’ve learned that a lot of money is a relative term. Somehow, I managed to hire insanely talented engineers—a bunch of them, ironically, from Tuenti. Blink-182 is back together, and I’ve been fortunate enough to see them live five times. I’ve even bumped into Tom Delonge after surfing world-class waves a few times. I’m literally just realizing how surreal all of this is. I tend to get caught up in the chaos of what’s next—the next big fire, the next goal—but sometimes you’ve got to stop, be present, and reflect on how far you’ve come. It wasn’t easy. It wasn’t without loss, sacrifice, and a fair share of doubts. Am I truly happy? Maybe not in a perfect, all-the-time kind of way. There are external things humans cannot control. But when I look at my life, I realize there’s no real reason not to be. The journey has been was worth it so far: the ups, the downs, the unexpected turns. So, here’s to your journey, whatever it looks like. Keep going, keep dreaming. It might not turn out the way you envisioned it, but it’s only impossible if you quit.
More in programming
My now-traditional “summary” of the conference along with my own commentary and thoughts.
Every year, browser vendors collaborate via the Interop project to synchronize their efforts on new HTML/CSS/JS features. This year, there’s a ton of super exciting features being considered! In this blog post, we’ll explore the CSS of the future, to get a glimpse of what we’ll soon be able to do.
Imprint’s average engineer is merging 4x more PRs than 2 years ago. Yay. Aggregated behind the average is something even more interesting: we have two teams that are merging 10x their PRs over that period. One engineer is merging 25x the PRs per week of our average engineer two years ago, and a number are merging 10x. That’s pretty neat, and the slope of the line suggests our average in a year is going to look much closer to today’s p90 than today’s p50. Even more importantly, we aren’t just shipping more, our quality has improved: incidents are down 42% half-over-half, and critical incidents are down 78% half-over-half. I think we’ve always known the quality/velocity tradeoff wasn’t a particularly useful construct, but that’s undeniable today. As we’ve walked this path, we–like everyone else progressing down it–have run into the problem of pull request review. The p50 pull request review took about 33 minutes to complete 2 years ago, but now takes us about 77 minutes. The slope here correlates tightly with the number of pull requests getting merged. Tightly enough that addressing it became one of my priorities for the week. We solved it! Just kidding, we’ve absolutely not solved it, but I think our current approach is an interesting one, which we call the small-change. The work discussed here was shaped and done by many folks at Imprint including Dan, Joy, Daniel, Lenny, Taylor, Ted, and Annie, among many others. Why review pull requests? There are four reasons we review pull requests: Knowledge sharing between author and reviewer – software engineering is generally learned via apprenticeship, and reviews are a primary mechanism of experienced engineers teaching others what good software looks like. We believe the current volume means that this knowledge sharing will have to move towards operating on clusters of pull requests, rather than individual pull requests Preventing errors – review has always been an expensive time to catch errors, and we believe that effective CICD along with harness verification techniques like poteto’s pstack are more effective mechanisms for preventing errors than review Preventing malicious behavior – my experience is that even careful code review will generally miss competent malicious behavior, although fortunately most malicious behavior is incompetent. We believe both sorts of behavior are best identified using a combination of fixed rules (modifying these specific objects/classes/files requires review), anti-abuse mechanisms that we’ve refined in our LLM-based member support experiences, auditing, and audit log inspection Compliance obligations in our documented controls – these can be changed, but today they require that an independent human reviews changes in a subset of our repositories In the modern development paradigm, we think there is a better solution for each of these problems. But, we also want to make these changes very cautiously. Small steps with small-change We believe we move fast by finding narrow, contained ways to validate new practices, so to iterate our way into an effective solution, we’ve developed the concept of a small-change. Here’s how it works: When a pull request is marked ready, CICD determines whether it is eligible to be a small-change. This is represented as a passing Github check. There is also a label for visibility, but it is the check itself, managed by the build and not human modifiable, that determines eligibility. (The label is used for initial filtering, but the check is still independently verified.) Something is a small-change if it meets all of these criteria: It is less than 1,000 lines of code There are no p1 or p2 findings from our ai-code-review automated review bot The author has “experience” in the service or application, defined as 10+ prior merged pull requests into that service or application’s directories. For changes working across multiple services or applications, the author must have experience in all of them to qualify Impacts fewer than N distinct services or applications. N is 1 on our frontend monorepo, and N is 3 in our backend monorepo, where typical changes will modify both a gRPC service and a common HTTP gateway Shared libraries and utilities files are not eligible for small-change Each repository has a .small_change file which allows per-path customization while we continue to tune the behaviors. For example, a service dealing with money movement can be excluded Our Slack automation tags every reference to a pull request with reacji labeling the state of that pull request, for example if it has failing tests, if it has been approved but tests are still running, or if it is ready to merge. We added a small-change reacji that indicates which of those pull requests meet the small-change criteria In our internal skills repository, we created two skills that have been distributed across harnesses: review-small-change which takes a list of repositories and reviews all open, non-draft, small-changes, including providing approval if they meet the review’s criteria (all checks pass including small-change check, and not touching on sensitive topics such as payments and security) review-pr-cluster which reviews batches of pull requests to identify common themes that came up, and suggest opportunities for discussion and adding verifications We set the social expectation that any error caused by a small-change is a failure in our system, and has to be solved at the system level: improvements to ai-code-review, to our verification mechanisms, to our CICD, to our harness, etc. This took about two days of infrequent attention to implement and rollout, although I imagine we will be tuning the knobs here for a long time. Maybe forever. fleet: centrally orchestrated harness I’ll briefly mention our other approach to reducing code review volume, which anchors on our centrally-orchestrated harness, fleet. (Which is similar to Stripe’s Minions although not following the one-shot approach in particular). We rely on fleet to implement and verify software in a highly controlled harness running in the cloud, with independent evaluation mechanisms to identify the correct number of independent reviewers for any given change. That number can be as low as one (e.g. fleet writes, one human reviews) for changes evaluated as safe. Results / next steps / reception I’ll be honest, it’s too early to give a useful result here. From early results, about 10% of changes qualify as a small-change. Those are now eligible for very fast approval, and generally get it unless they trip a flag, generally due to touching a security or money adjacent topic. While 10% is a small percentage, the core concept here is working, and ultimately will succeed or fail based on our ability to expand that percentage over the next few months in tandem with expanding our verification mechanisms to be increasingly comprehensive. This is ultimately going to fail or succeed depending on our ability to improve our verifications, which does require more difficult sorts of techniques to accomplish in low scale-complexity, high domain-complexity software than in the high scale-complexity, low domain-complexity products where many techniques like incremental rollouts are exceptionally effective. (Don’t get me wrong, they still work, they just provide less coverage when most users have different configuration and behavior.) Folks have not been uniformly excited about this, it’s a substantial change from how we’ve learned to be good engineers, and it’s uncomfortable to reevaluate whether a long-held best practice has become merely dogma. The most energizing part of the current cycle is that we get to reevaluate these practices we grew up on every week; the most painful part of the current cycle is that we’re likely to fall behind if we ever stop reevaluating them.
The park near my house has lots of chestnuts and my kids have been collecting them like crazy (it’s actually their favorite post-school activity). We accumulated quite a hoard. I thought it would be fun to make a launcher so we had something to do with our new chestnut collection. I wanted to go with a very simple crossbow-style design (like the famous D2 item) using latex tubing and a leather pouch for holding the chestnuts. This is what I came up with. It launches chestnuts about 220 feet, and it’s simple enough to build in an afternoon. The frame is a 42 inch 2x2 and a spare IKEA bed slat for the crossbeam, glued and screwed together. A 3/8 inch eye bolt goes through each end of the crossbeam, and the latex tubing is tied to those and to the pouch from a leather shepherd’s sling. Tying the tubing was the fiddliest part. It has to be stretched while you wrap it with butcher’s twine, so I clamped a couple of scrap blocks to my workbench to hold it. I like this design because the tubing can be wrapped around the eye bolts to easily add more tension and power. The Trigger My favorite part of the design was that I decided to use an archery release like this one for the trigger. It provides a safe and reliable way to hold the tubing back, and it’s made to let go cleanly. I 3D printed a little housing that mounts the release securely to the back of the stock, and the release clips onto a loop of archery D-loop cord on the back of the pouch. Then I added a dowel for a rear grip and an old handle I had previously removed from my shop vac. How Well Does It Work? We tried it at the park and it works surprisingly well. Aimed at about 35 to 40 degrees, it sends our chestnuts (on the small side, about 10 to 15 grams) about 220 feet. Thanks to the archery release, we haven’t had a single misfire. I got curious and did some rough math. To go that far with air drag, the chestnuts are leaving at somewhere around 85 to 100 mph, which works out to about the same energy as a paintball. So safety glasses are important and you never point it at anyone. You can find the 3D print on Printables and a full build guide on Instructables. Make sure to always use it with adult supervision :)
I have a lot of digital cross-stitch patterns and until recently they were a mess. My “collection” was a series of several hundred PDFs, disorganised and spread across my disk. Recently, I was looking for a pattern and it took me several minutes to find it. I had a brief moment of panic, thinking that I’d lost it, and the website this pattern came from is long since gone. Fortunately it did turn up, but it was clear I had to organise my pattern collection. Some people would use apps like Pattern Keeper or Flosshaven, but I just created another static website on my media drive. This is what it looks like: The patterns are arranged in a masonry layout with a preview thumbnail for each pattern, which is normally the first page of the PDF. If a pattern has multiple files – for example, different files for colour and black-and-white printing – there’s a list of links below the thumbnail. I can also add a source link to where I bought the pattern, if I want to find more patterns by the same author. Internally, it’s structured like my other static websites. The metadata for the patterns is stored in a JavaScript file, and then I have an HTML page which renders that metadata in this visual design. My pattern collection doesn’t change very often, so I’m adding new files by hand. There are no sorting or filtering options, because my collection is small enough that they’re unnecessary. I can scroll through the entire list in less than a minute and find whatever I need. I’d like to start making my own clothes soon, and I expect to copy this design to store clothing patterns. This collection now sits alongside my saved bookmarks, podcasts, TV shows, and more. I can keep all my patterns organised, and I won’t lose them in the depths of my hard drive. Technical tricks There are a couple of technical pieces I’m quite pleased with in this process: Masonry layout. I love the cascading grid style of a masonry layout, and I think they’re great when you have variable-sized content – like my pattern cards. I’ve been using them for over a decade; screenshots of my early web apps show my experiments with David Desandro’s Masonry.js library. Masonry layouts are now a native feature of CSS called “Grid Lanes”, which is simpler and more performant than the JavaScript approach. I’m excited to use these layouts in even more places. Thumbnails of PDFs. Most digital postage patterns are shipped as PDFs, and I’m creating the thumbnail images with my create_thumbnail tool. I had to extend my tool to support PDFs, which turned out to be straightforward with the pdf_oxide crate. I’d not come across Oxide before, but it’s a cross-language library for working with PDFs, and I can imagine using it in future. A coloured stripe for the palette. In the metadata for each project, I have the complete list of DMC thread colours and the pattern dimensions. I have a lookup table that converts DMC thread colours to hex codes, and then I’m able to create a linear gradient in CSS to render a coloured stripe of the pattern colours. Here’s an example from a pattern with four colours: border-bottom: 12px solid transparent; border-image: linear-gradient( to right, #7a451f 0%, #7a451f 25%, #985e33 25%, #985e33 50%, #e4bb8e 50%, #e4bb8e 75%, #361f0e 75%, #361f0e 100% ) 1; Building the HTML, CSS, and JavaScript was very quick – I have notes on how I build my media sites, and I’ve done it plenty of times before. I threw together the initial prototype in less than 15 minutes. The longer part was finding all the PDFs scattered across my disk – but now that’s done, and I know exactly where to find my patterns. [If the formatting of this post looks odd in your feed reader, visit the original article]