Skip to main content
Welcome. This site supports keyboard navigation and screen readers. Press ? at any time for keyboard shortcuts. Press [ to focus the sidebar, ] to focus the content. High-contrast themes are available via the toolbar.
serard@dev00:~/cv

Start with the Language

The mistake is to begin with Bash, PowerShell, Ansible, Chocolatey, Winget, Docker, or Terraform.

Those are implementation choices. The first question is: what is the domain?

In Domain-Driven Design, the model starts with a ubiquitous language. The team names the things that matter until developers, managers, platform engineers, and support staff can talk without translating every sentence.

Developer onboarding has that same need. A company needs shared words for:

  • "the workstation is ready"
  • "Git access has been verified"
  • "the toolchain is pinned"
  • "the first clone succeeded"
  • "the project builds"
  • "the setup is replayable"
  • "the update from 3.3.2.2 to 3.3.4.3 is safe"

Without names, every setup failure becomes an anecdote. With names, failures become domain events, states, and invariants.

Bounded Contexts

Onboarding is not one context. Treating it as one big script is the operational version of a god object.

The domain cuts naturally:

Bounded context Owns Does not own
PhysicalAccess room, desk, badge, power, Wi-Fi reachability Git permissions
IdentityAccess account, MFA, SSH key, certificates, groups SDK versions
WorkstationBootstrap OS profile, package manager, shell, editor product build logic
ToolchainBaseline pinned tools, version matrix, install policy human access approval
ProjectReadiness clone, restore, build, test, run, debug, local environment / cluster provisioning building access cards
UpdateLane candidate versions, transition probes, rollback decision first-day social onboarding

Each context has its own model. A Wi-Fi probe is not a Docker probe. A Git SSH key is not a package manager version. A project build is not an identity enrollment.

The contexts integrate through explicit contracts:

PhysicalAccess emits WifiVerified.
IdentityAccess emits GitAccessVerified.
ToolchainBaseline emits ToolchainPinned.
ProjectReadiness consumes those events and emits ProjectBuilt.

The same publish/consume pattern lifts one level. Where contexts integrate inside a machine by emitting and consuming events, teams integrate across the organization by publishing setup modules that IT subscribes to and integrates — the collaborative seam from the series introduction. It is the same contract discipline, with a larger blast radius.

Diagram
The onboarding context map. Upstream contexts emit verified events; ProjectReadiness consumes them and only then emits ProjectBuilt. UpdateLane re-runs the same contract against candidate versions.

This is where setup-as-code becomes much easier to reason about. The implementation can be iterative because each context can improve without rewriting the whole pipeline.

Events and Invariants

A setup domain should not rely on vague status text.

It should speak in events:

Event Meaning
DesktopPrepared the target workstation profile exists
WifiVerified network path required for setup is reachable
GitAccessVerified the configured identity can clone the required repository
ToolchainPinned required tools match the baseline
ProjectBuilt the real project builds on the prepared instance
InstanceSwitchedSuccessfully the team can use another fresh prepared instance without manual repair

Then it should define invariants:

  • A workstation is not ready until the project has built from a fresh clone.
  • A toolchain is not approved until all required versions are pinned or explicitly floated.
  • An update is not adopted until it passes the same probes as the current baseline.
  • A physical boundary is not hidden inside a script; it is represented as a named prerequisite or probe.
  • A failure without diagnostic evidence is itself a failure of the setup system.

That last point matters. The setup runner is not only responsible for doing work. It is responsible for explaining what failed.

Why This Becomes a DSL

The language starts in conversation:

"During setup, install VS Code before opening the project."
"During first clone, verify SSH and the corporate certificate chain."
"During update from 3.3.2.2 to 3.3.4.3, test Docker separately."
"Given three fresh instances, prove we can build and switch."

Then the same language appears in CI job names. Then in a YAML file. Then in a typed model. Then in analyzers. That is the familiar pattern from the site's DSL articles: stable operational vocabulary becomes a language.

The Ops DSL Ecosystem argues that operational knowledge deserves typed surfaces. Micro-DSLs and a Shared Kernel shows how a domain decomposes into bounded micro-DSLs instead of one monolith.

Welcome Setup-as-code follows the same path. It is not "just automation." It is the beginning of an onboarding DSL.

A setup domain you can name is a setup domain you can test.

Test your onboarding.

⬇ Download