Registry & Scopes
How scopes, tiers, custom registries, tags, and the cache resolve
This page is the reference for how a module source becomes a fetched module: scopes and tiers, the on-disk layout, tag formats, custom registries, and the cache. For task-by-task usage see Using Modules. For pinning resolved versions to an immutable commit + content hash, see Lockfile & Supply Chain.
The three tiers
The built-in scopes map to three trust tiers, all hosted in the public registry
repo github.com/orchstep/orchstep under modules/@<scope>/<name>/:
| Scope | Tier | Maintained by | Published via |
|---|---|---|---|
@orchstep | Official | The OrchStep team | Direct push |
@community | Verified | Human contributors | PR → review → merge |
@ai | AI-generated | LLM agents | orchstep module submit → auto-validate |
These scopes need no configuration — they're built in.
How a source resolves
| Source | Git repo | Sub-path in repo | Tag looked up |
|---|---|---|---|
@orchstep/demo-validate-json | github.com/orchstep/orchstep | modules/@orchstep/demo-validate-json | demo-validate-json/vX.Y.Z |
@community/github_action_git-checkout | github.com/orchstep/orchstep | modules/@community/github_action_git-checkout | github_action_git-checkout/vX.Y.Z |
@mycompany/module1 (custom) | from your registries: block | modules/@mycompany/module1 | module1/vX.Y.Z |
github.com/org/repo (single-module) | github.com/org/repo | (repo root) | vX.Y.Z |
One rule for every @scope/name: modules live at modules/@<scope>/<name>/
— uniform across built-in and custom scopes. A plain Git URL with no scope is
treated as a single-module repo (files at the root, vX.Y.Z tags).
Custom registries
Define your own scope by mapping it to a Git repo. The map key is the scope name
without the @:
registries:
mycompany:
url: github.com/your-org/platform-modules
tag: "{module}/v{version}" # optional; this is the default
modules:
- name: m1
source: "@mycompany/module1" # -> modules/@mycompany/module1, tag module1/vX.Y.Z
version: "^1.0.0"A registries: block can live in a workflow file or in orchstep_config.yml
(auto-loaded from the working directory — needed when resolving a custom
@scope from the CLI, e.g. orchstep module install @mycompany/module1).
The cache
Resolved modules are stored under:
~/.orchstep/cache/modules/<repo-path>/@<scope>/<name>/v<version>/ # scoped / monorepo
~/.orchstep/cache/modules/<repo-path>/v<version>/ # single-module repoThe scope is part of the cache key, so @orchstep/x and @community/x never
collide. Inspect or clear it:
orchstep module cache path
orchstep module cache cleanCLI quick reference
| Command | Purpose |
|---|---|
module search <q> | Find registry modules |
module install <source>[@version] | Fetch a module into the cache (scope, custom scope, or full URL) |
module resolve <source> [constraint] | Show which version a constraint selects |
module info <source> | Git URL, scope, sub-path, available versions |
module validate <dir> [--strict] | Validate a local module directory |
module lock | Write orchstep.lock pinning resolved versions |
module cache path / cache clean | Inspect / clear the cache |
run --module <source> [task] [--list-tasks] | Run a module task with no workflow file |
(There is no module list command.)
MCP integration
LLM agents can search and install modules through the MCP server:
{ "tool": "orchstep.module_search", "arguments": { "query": "git-checkout" } }
{ "tool": "orchstep.module_install", "arguments": { "source": "@community/github_action_git-checkout" } }See the MCP Server docs for the full API.
Private repositories (current limitation)
Module fetching uses anonymous Git access — the resolver does not yet pass a
token or SSH key. Modules in private repos cannot be fetched via @scope or
github.com/... sources. Options today:
- Host shared modules in public repos.
- Use the Pro
@private/scope — a local private registry populated withorchstep module publish(it resolves to a path on disk, not a remote private repo).
Authenticated fetching of private remote repos is on the roadmap.