BLOG/ENTERPRISE AUTOMATION
THEME
ENTERPRISE AUTOMATION

An end-to-end platform: golden-path modules for the whole org

A platform team publishes build, deploy, and notify kits to a registry. Dozens of app teams compose them in a few lines and ship the same way. This is the whole modules series in one runnable workflow — sources, scopes, versions, and a graph you can see.

Jul 1, 2026 OrchStep Team 9 minROLE: Platform EngineerSCALE: Enterprise
RUNNABLE DEMO
Full source for this post: blog/golden-paths
VIEW SOURCE

Every platform team has the same recurring nightmare: forty repos, forty slightly-different deploy pipelines, and a security requirement that has to land in all of them by Friday. Each app team copied a "good" pipeline once, then drifted. There is no single place to make the change, because there is no single thing — just forty forks of an idea.

This is the post the rest of the Reusable Modules series was building toward. We've covered composing workflows like Lego bricks, the three trust tiers, how to design a module that doesn't rot, and running a private registry for your org. Now we put it together: a platform team owns a small set of golden-path modules, every app team composes them, and one change to a kit reaches everyone.

Registry architecture: a platform team publishes versioned kits to a registry that many app teams consume

Who talks to whom

The shape above is the whole model. A platform team publishes versioned kits — build-kit, deploy-kit, notify-kit — to a registry. App teams don't fork them; they depend on them by @scope and semver constraint. The platform team ships a fix as a new tag, and every team on a compatible constraint picks it up on their next run. The arrows only point one way, and there's exactly one source of truth per capability.

The app team's side: a few lines

Here's what an app team writes. Three kits imported, one release task that composes them. The whole pipeline — build, scan, roll out, announce — is the platform team's logic; the app team supplies its service name.

orchstep.yml
name: platform-golden-path
defaults:
  service: "checkout"
  target: staging

# The platform team owns these kits. App teams compose, never fork.
modules:
  - { name: build,  source: "./modules/build-kit" }
  - { name: deploy, source: "./modules/deploy-kit" }
  - { name: notify, source: "./modules/notify-kit" }

tasks:
  # `orchstep run release --var service=payments`
  release:
    desc: "Ship a service down the org golden path"
    steps:
      - { name: ci,       module: build,  task: ci,       with: { service: "{{ vars.service }}" } }
      - { name: rollout,  module: deploy, task: rollout,  with: { service: "{{ vars.service }}", target: "{{ vars.target }}" } }
      - { name: announce, module: notify, task: announce, with: { service: "{{ vars.service }}" } }

The demo uses local module folders so it runs anywhere. Run it:

orchstep run release --var service=payments
📦 Loaded module 'build' from './modules/build-kit'
📦 Loaded module 'deploy' from './modules/deploy-kit'
📦 Loaded module 'notify' from './modules/notify-kit'
Workflow: platform-golden-path
Task: release
  Step: ci
  ...
  [ok] ci
  Step: rollout
  ...
  [ok] rollout
  Step: announce
  ...
  [ok] announce
Result: success

From local folders to a registry

To go org-wide, the platform team publishes the kits and the app teams swap the source — the tasks: block doesn't change at all. Only the resolution does:

LOCAL SOURCE (DEV)
modules:
  - { name: build,  source: "./modules/build-kit" }
  - { name: deploy, source: "./modules/deploy-kit" }
  - { name: notify, source: "./modules/notify-kit" }
REGISTRY @SCOPE (ORG)
registries:
  acme:
    url: github.com/acme/platform-modules

modules:
  - { name: build,  source: "@acme/build-kit",  version: "^2.1.0" }
  - { name: deploy, source: "@acme/deploy-kit", version: "^1.2.0" }
  - { name: notify, source: "@acme/notify-kit", version: "^0.4.0" }

The registries: block maps the acme scope to the repo; modules live at modules/@acme/<name>/ and ship as tags like deploy-kit/v1.2.0. A ^1.2.0 constraint means "the highest compatible 1.x," so that Friday security fix in build-kit reaches all forty teams on their next run — no PRs to forty repos. For reproducible builds, each consumer commits an orchstep.lock that pins every module to an exact commit and content hash; orchstep module verify is the CI gate that fails the build if a pinned module ever drifts.

See the whole platform as a graph

The payoff of composing instead of copy-pasting: the assembled pipeline is a structure you can look at, not 300 lines of bash to read. Drop the workflow into the visualizer and the composition renders as a graph — every called module task, every step, every branch:

The full platform golden-path workflow rendered as a graph in the OrchStep visualizer

This is the same view your team gets live: orchstep serve launches a local web dashboard that renders the flow, shows each run, and lets you drill into per-step context. A new engineer can see how the org ships before they've read a single line of YAML — and orchstep run release --dry-run resolves the entire multi-module assembly and prints the plan without executing anything.

What you gained

ConcernForty forked pipelinesGolden-path modules
Source of truthforty reposone registry per capability
Shipping a fix to everyoneforty PRsone tag, picked up by ^ constraints
Reproducibility"whatever main was"orchstep.lock + module verify
Onboardingread forty pipelinesone graph, one golden path
Driftinevitablethe constraint is the contract
App-team effortown the whole pipelinecompose in a few lines

The enterprise option

The demo above is entirely free: the engine and every open module feature — local modules, remote Git sources, the public @scope registries, the lockfile, validate/install/search — ship in the open binary. For modules you can't host publicly, OrchStep Pro adds a private registry: orchstep module publish pushes a kit to an on-disk registry, module list-private shows what's there, and teams consume it as @yourco/<name> exactly like the public scopes. That's the bridge for internal kits that can't live in a public repo. See Pro Features.

Where this isn't the answer

A platform of golden-path modules earns its keep when many teams ship the same shape of thing. If you're one team with one service, this is over-engineering — keep your pipeline as plain tasks and revisit when a second team wants the same thing. And remember the current limit: the open resolver fetches over anonymous Git, so public-repo registries or the Pro @private/ scope are your options for shared kits today.

Where to go next

Forty repos drifting from one good idea? Publish the idea as a kit, tag it v1.0.0, and let every team depend on ^1.0.0 instead of forking it.

#PLATFORM-ENGINEERING#MODULES#GOLDEN-PATHS#REGISTRY
Try it in two minutes — one binary, no signup.
curl -fsSL https://orchstep.dev/install.sh | sh

RELATED — ENTERPRISE AUTOMATION