The Software Craftsman’s Day One: Why My First Week of Startup Life Had No Business Logic
Series: Startup JourneyBeing made redundant from a position where I defined patterns and practices for a high-performance team, I decided to take the leap to create my own startup. As I write now, this has felt like a violent acceleration of the clock. One day you feel the safety of an established enterprise; the next, there I am, standing on a clean slate. When I finally received my new laptop last week, I felt the sudden urge to rush, install the software I needed, and start churning out lines of code.
But my own discipline over the years took over - true craftsmanship rejects the illusion of hurried progress.
Years ago, I learned a fundamental lesson in cloud architecture: refuse click-ops and always rely on Infrastructure as Code (IaC) as your source of truth. Clicking through console windows to provision a database, where you instantly forget the exact steps you just took, builds technical debt that cannot be tracked, audited, or most crucially, reliably reproduced.
I had actually meant to start one week prior, but as I received my refurbished laptop, there was an issue that meant I needed to return the machine for repair. This meant I had to wipe it and wait over a week for repairs.
This taught me something: why not apply the same discipline of IaC to your own local environment? If “click-ops” is a sin in the cloud, then clicking through manual installers and executing rogue brew commands should be too.
To scale with pride and precision, I spent my first week doing something counter-intuitive. I created a tool and ecosystem that separates the hardware from the environment using IaC principles - designed to be liberating, not confining.
The Onboarding Tax: How KT Nightmares Led to Local IaC
The conviction to spend my first week writing zero business logic didn’t come from a standard practice or theoretical textbook; it was forged in the exhausting final four months of my previous corporate role.
My final four months was an exhausting Knowledge Transfer (KT) to an incoming team. They were talented engineers, but they had never worked within our company let alone our specific environment, and none of the legacy team would be remaining to guide them. I found myself trying to condense ten years of deep, institutional system knowledge into a compressed onboarding window.
But the real bottleneck wasn’t teaching them our system design, it was the developer laptop environment.
On paper, a new developer could get “up and running” in about a week. But that was a surface-layer illusion. For months afterward, they would constantly hit silent road-blocks. I’d find myself saying, “Oh, you need to configure your SSH config this way,” or “Right, you need this custom script to establish an AWS SSM tunnel to bypass that gateway.”
Onboarding wasn’t a single event; it was a slow, manual drip-feed of wiki pages, legacy scripts, and tribal knowledge. It was “wiki-ops” at its worst. What should have taken minutes took weeks, dragging down both the new engineers and the peers who had to constantly stop their own work to debug a local path.
Enter rig: A Blueprint, Not a Cage
To solve this onboarding tax permanently, I spent my first several days crafting rig.
Named after the nautical verb to equip a vessel with sails, standing tackle, and running gear - rig is a lightweight, POSIX-compliant developer toolchain dispatcher and provisioning system. To ensure it runs everywhere without dependency hell, it is built strictly for /bin/sh. This means it executes with zero pre-requisites across macOS, Linux distributions, and even within CI/CD runners.
brew haven’t been configured with the different Linux distributions in mind, yet.Instead of a chaotic series of manual installers, setting up a new machine with our corporate standard is now a two-step process:
# Clone the repository
git clone https://github.com/your-user/rig.git
cd rig && ./rig install
Once executed, rig injects a single clean hook into your shell profile (.zshrc or .bashrc), marked clearly by # rig-tools:
eval "$("/path/to/rig-tools/rig" env)" # rig-tools
This single line evaluates a returned environment dynamically, allowing our developer tooling to evolve over time without having to re-install profile scripts.
You might ask: Why not just use an industry-standard configuration manager like Chef or Puppet?
In the enterprise space, tools like Chef or Puppet are often used to force compliance. They lock developers in a sterile box, dictating exactly how local machines must behave. It is an authoritarian approach to Developer Experience (DX) that strips away engineering personality and, frankly, makes talented developers want to quit.
I wanted a tool that was elective, not prescriptive.
By leveraging a modular domain architecture (separating language runtimes from tools) and adhering strictly to XDG configuration standards (storing persistent, non-clobbering key-value states in ~/.config/rig/config), rig acts as a launchpad, not a straightjacket. It guarantees every developer shares a baseline, reliable environment for our company’s projects, while leaving them completely free to customise their editors, local paths, and shells.
# rig doctor ensures the environment hasn't drifted
rig doctor
# Modular updates for languages and tools
rig update
rig lang java
rig tool vim obsidian
We have turned what used to be weeks of peer-assisted debugging into a background task that takes minutes. If my laptop hardware fails tomorrow, I don’t face a week of downtime. I get a replacement machine, run rig install, and I am back to writing code in under five minutes.
Combine this with my standard rule “If you didn’t commit and push your code to a branch, you didn’t work today”, and we have an almost zero down-time developer productivity at the end of week 1.
Once installed, a developer now has a useful tool (rig), ready to help them perform tasks within the company. Its intended now that this will be extended for any repetitive tasks that I might find myself performing through my journey.
Usage: rig <command> [options]
Commands:
install
Initiate the install script for the current platform
update
Update installed packages and toolchains
doctor
Verify environment
tool <-l|tool>
Configure/Install provided tool.
Use "rig tool -l" to list available tools.
Current: 1password, aws, colima, gcloud, git, localstack, obsidian,
orbstack, tmux, vim
lang <-l|lang>
Configure/Install provided language support.
Use "rig lang -l" to list available languages
Current: java
env
Print environment include for use in shell scripts.
NOTE: This will be added by 'install' to your environment, e.g.
eval "$("/home/your-name/devel/rig-tools/rig" env)"
config [-n] <key> [new-value]
Get the current value or update the existing value with [new-value] if
provided. The '-n' flag when present will not clobber the existing value.
help
Show this help
Config Values
SKIP_INCLUDE When this setting is 'true' the install/update/doctor commands
will not attempt to add to your env, any other value will or
when missing is treated as false.
Where to From Here?
Using these same fundamental principals, I’ve now been working on centralising my documentation strategy to function as what I’m calling an “Anti-AI AI Strategy” - we value the human creativity, but empower the mind with the tools to perform their role.
In my next post, I’ll be talking about how I created a general contract for software projects to be documentation-first that encourages pipelines to centralise documentation in a shared company Google Drive (Architecture) with the dual-purpose goal of humans being able to centrally read the documentation, and more crucially; give Gemini Notebook the ability to have precise context on what the actor is interacting with the notebook for.
Discussion
This post is syndicated on Dev.to. You can leave a comment there to join the conversation natively on this page.
Loading comments from Dev.to...