Bootstrap your first repo
The fastest way to onboard a repo to ArchRails is to commit a single empty file and let the platform generate the first draft of your architecture for you. You review the result in a normal PR, edit anything that doesn't match reality, and merge. That's it — no out-of-band setup, no separate dashboard wizard.
What bootstrap actually does
Bootstrap reads the CALM document(s) you already have in your repo and produces a
first draft of .archrails/config.yml — the small file that tells
ArchRails which CALM files describe your architecture, which branches are governed,
and which code paths map to which CALM nodes.
Bootstrap scans your whole repo for *.calm.json files, with a scoring
boost for conventional locations (architecture/, arch/,
topology/, system/, files named calm.json or
architecture.json). Keep yours wherever fits your codebase. For each
CALM node, bootstrap infers a likely mapping path from your directory
layout; anything it can't pin down is marked
REVIEW REQUIRED so it's obvious in the PR review.
*.calm.json file checked in before
you open the bootstrap PR. If you don't yet have CALM you have two options:
-
Scaffold it via the MCP tool — in your IDE, start an
ArchRails architect-mode session (
archrails mcp start --mode architect) and ask the agent to callgenerate_calm. The tool walks your repo deterministically, emits an initialarchitecture/<repo>.calm.jsonwith one node per service-directory manifest (package.json/pom.xml/go.mod/pyproject.toml/*.csproj/Cargo.toml) and oneconnectsrelationship per cross-service import the parser resolves. Every inference site is stamped withREVIEW REQUIREDso you walk the file with the agent and resolve each marker before committing. - Hand-author it — follow the Declare nodes lesson. Useful when your architecture has cross-service edges the scaffolder won't find (network protocols rather than source imports — typical for microservices).
Step 1 · Commit an empty config
On a new branch, create the directory and an empty file:
git checkout -b archrails/bootstrap mkdir -p .archrails touch .archrails/config.yml git add .archrails/config.yml git commit -m "chore: bootstrap ArchRails" git push -u origin archrails/bootstrap
The file is genuinely empty — zero bytes. That empty file is the signal: “ArchRails, fill this in for me.”
Step 2 · Open the PR
Open a pull request against your default branch (or whichever branch you want bootstrap to target). Title and body are up to you; a typical first PR looks like:
Title: chore: bootstrap ArchRails
Body: Empty .archrails/config.yml so ArchRails generates the
initial architecture from this repo.
The moment that PR is open, ArchRails runs — you'll see a check appear within seconds.
Step 3 · Review the generated config
A minute or two later, a follow-up commit from github-actions[bot] will
appear on your branch:
chore: regenerate .archrails/config.yml via ArchRails bootstrap
That commit adds the populated .archrails/config.yml. Your existing
*.calm.json files are untouched — bootstrap reads them to derive the
config but never writes to them. A small example of the generated config for a Java
service might look like:
# .archrails/config.yml — generated by ArchRails # Paths were inferred from your repo structure. # Adjust any path marked REVIEW REQUIRED before merging. version: 1 governance: governed_branches: - main sources: - id: architecture provider: calm file: "architecture/system.calm.json" mapping: # confidence: high - path: "customer-portal" node: customer-portal # confidence: high - path: "orders-server" node: orders-server # ⚠ REVIEW REQUIRED — no code directory matched for 'orders-db' (type: database). # Likely infrastructure-only or external — uncomment and set a path if this # node represents code in this repo. # - path: "" # node: orders-db integrations: github: app: archrails
Three things to notice:
-
governance.governed_branchesdefaults to your tenant's default branch list. Only PRs landing on a governed branch get architecture review — experimental branches stay out of the way. -
Each
mappingentry binds a path to a node. Thenode:value is theunique-idfrom your CALM file. Bootstrap picks a path-aligned slug (customer-portal↔customer-portal/) so the binding is obvious; keep that convention when you add nodes by hand. -
Anything ArchRails couldn't confidently match to a directory is left
as a commented-out
REVIEW REQUIREDblock. The database node above, for instance, is referenced by other nodes but doesn't have a corresponding folder — a human needs to uncomment and point it at the right location, or leave it commented out if the node has no code in this repo (it's infrastructure-only or external).
.archrails/config.yml. The recommended
shape is to put repository: <repo-url> directly on the relationship's
destination endpoint (no need to declare the foreign node locally). A
legacy metadata.repository on the node spec is also accepted. Both are
covered in detail in Declare relationships.
Step 4 · Edit the REVIEW REQUIRED placeholders
Pull the bot commit down and edit the config like any other file:
git pull $EDITOR .archrails/config.yml $EDITOR architecture/system.calm.json
Replace each REVIEW REQUIRED with the right value,
delete nodes that don't exist, add ones the inference missed. The
Declare nodes and
Declare relationships lessons cover
the field reference in detail.
Push your edits to the same branch. ArchRails re-validates on each push — the PR check stays red until every placeholder is resolved and every relationship references a real node.
github-actions[bot] pushes the bootstrap follow-up, GitHub Actions
deliberately doesn't fire workflows triggered by another workflow's
GITHUB_TOKEN — that's GitHub's loop-prevention behaviour, not an
ArchRails quirk. You won't see a new Architecture Governance run on that SHA. The
check fires again as soon as you push a commit (the placeholder edits in
Step 4 do this). If you only want to verify the bot's output without
editing yet, push an empty commit:
git pull git commit --allow-empty -m "ci: re-trigger ArchRails review" git push
Step 5 · Merge and you're live
When the check is green, merge. The next PR opened against a governed branch will be reviewed against this architecture — new dependencies that aren't declared, services that move to undeclared hosts, controls that aren't met — all flagged automatically.
.archrails/config.yml and ArchRails will regenerate from scratch. Useful
after a major refactor — though typically you'll just edit the existing config by hand.
Troubleshooting
The bot commit never appears on my branch.
Check the ArchRails check on your PR — the message will say where it stopped. The two most common causes:
- The branch you opened the PR against isn't listed in any existing
governed_branches. For the very first bootstrap PR this is fine; for re-bootstraps make sure the target branch matches. - Your installation is gated to specific repositories and this one isn't in the allowlist yet. A tenant admin needs to add it via the dashboard's Team Roster page.
Almost every node says REVIEW REQUIRED.
Inference works best when each major service has its own top-level directory whose
name matches what the service actually is. If your repo is a single
flat src/ tree, bootstrap can't tell which classes belong to which
service — you'll need to fill the paths in by hand. The
Declare nodes lesson covers
owned_paths in detail.
Can I commit my own .archrails/config.yml instead of an empty one?
Yes — bootstrap only runs when the file is empty. If you commit a populated config, ArchRails skips bootstrap and goes straight to validating PRs against it. Hand-authoring is the right call once you've done it once or twice and know the shape.
What happens to existing *.calm.json files in my repo?
Bootstrap reads your *.calm.json files to derive the config but
never writes to them. Whatever you've drafted by hand — whether under
architecture/, alongside your services, or anywhere else — stays
exactly as you wrote it. Bootstrap only adds .archrails/config.yml.
What if my repo has no *.calm.json yet?
Bootstrap won't have anything to derive the config from, so it will skip
regenerating the file and leave your empty .archrails/config.yml
in place. Two on-ramps:
-
Scaffold via the MCP tool. Start architect mode
(
archrails mcp start --mode architect) and ask the agent to callgenerate_calm. The tool walks your repo deterministically and emits an initial CALM underarchitecture/<repo>.calm.json. You and the agent then walk theREVIEW REQUIREDmarkers, resolve each one, and commit. Bootstrap picks up the new CALM on the next push. -
Hand-author it. Follow the
Declare nodes lesson. This is
the better choice when your services communicate over network protocols
(HTTP, AMQP, gRPC) rather than source-code imports — the scaffolder infers
edges from
importstatements, which microservices rarely have across service boundaries.
How does generate_calm decide what's a node and what
isn't?
Two passes, both deterministic. First the manifest pass: any directory at
depth ≤ 2 from the workspace root containing a
package.json, pom.xml, build.gradle,
build.gradle.kts, pyproject.toml,
setup.py, go.mod, Cargo.toml,
composer.json, Gemfile, or any
*.csproj file becomes a node. Second the folder-path pass:
directories under services/, apps/,
packages/, modules/, or components/
also become nodes even without a recognised manifest — for example, a
database directory that ships only a Dockerfile. Cross-service
connects relationships are inferred from imports across twelve
languages (TypeScript, JavaScript, Python, Java, Kotlin, Swift, Dart, Go,
C#, Ruby, PHP, Rust, C/C++, and COBOL copybooks). Anything that doesn't pin
down structurally is stamped
REVIEW REQUIRED and waits for you in
the PR.