| name | setup |
| description | Set up, extend, or diagnose the railyard delivery system: inventories what is installed, installs prerequisites (Compound Engineering, ponytail, roundhouse, agent-utilities, gh-stack, tmux/jq) with one consent, asks what the fleet hosts are and enrolls each through roundhouse:fleet-hosts, validates configuration, and reports readiness. For diagnosing an existing installation use railyard:doctor. Use when the user asks to set up, install, configure, onboard, or fix railyard or the delivery system, or when a required dependency turns out to be missing. |
Railyard Setup
Bring a host from bare to delivery-ready, grow the fleet, or diagnose why
something stopped working. Setup is idempotent: run it again any time and it
only proposes what is actually missing. A zero-fleet, zero-config outcome is
valid — the router's built-in defaults and local delivery work with nothing
configured — so never manufacture configuration the user does not want.
1. Inventory (read-only, no consent needed)
Collect the current state before asking anything:
- Installed plugins on each available harness:
claude plugin list and
codex plugin list --json. Note versions for railyard, roundhouse,
agent-utilities, compound-engineering (needs 3.20.0+ for
ce-babysit-pr), and ponytail.
- Known marketplaces:
novotnyllc/marketplace,
EveryInc/compound-engineering-plugin, and DietrichGebert/ponytail.
- Fleet config:
ROUNDHOUSE_CONFIG, else
${XDG_CONFIG_HOME:-$HOME/.config}/roundhouse/config.json.
- Tooling:
gh auth state, the gh-stack extension and its agent skills,
tmux, jq, node, chezmoi (optional), op (optional, for the
one-password toolbox skill).
- Optional extras already present: the Oracle Pro cache
(
~/.config/railyard/oracle-pro.json), a model-routing catalog
(~/.config/railyard/model-routing.json).
- Credential presence for whatever the installed plugins actually need —
check existence only, never read or print a value:
gh auth status for
GitHub; ZAI_API_KEY and LITELLM_PROXY_API_KEY when the Codex
zai_litellm GLM provider is configured; op sign-in state when the
one-password skill is installed; any other key an installed skill's own
docs name. A missing key is reported with where to set it (shell
environment via dotfiles, or 1Password injected through the one-password
skill) — never ask the user to paste a secret into the conversation.
Summarize present/missing in one table before proposing anything.
2. Prerequisites (one consent for the required set)
The required dependencies install together as one grouped step under a
single setup consent — ask once for the whole required set, never per group
and never per command. Consent for setup is consent for setup: the same act
that installs railyard authorizes its documented required plugins, so they are
not separate questions. On Claude Code use the question tool with the
recommended option first. Never install silently, never use sudo — user
package managers only. The optional extras below are offered separately, and
the security-boundary steps in §3a and §5 (signing, SSH-certificate
enrollment, the privilege broker) always keep their own explicit per-host
consent — those are never folded into this one.
-
Plugins and marketplaces (required for delivery):
claude plugin marketplace add novotnyllc/marketplace
claude plugin install railyard@novotnyllc roundhouse@novotnyllc agent-utilities@novotnyllc
claude plugin marketplace add EveryInc/compound-engineering-plugin
claude plugin install compound-engineering@compound-engineering-plugin
claude plugin marketplace add DietrichGebert/ponytail
claude plugin install ponytail@ponytail
Codex mirrors: codex plugin marketplace add … then
codex plugin add <name> --marketplace <marketplace>. Use update instead
of install for anything present but stale. Compound Engineering and
ponytail are not separate questions: installing railyard authorizes its
documented required plugins as one group, so they install automatically with
the same consent that installed railyard — one grouped install, ask nothing
extra. If Compound Engineering is below 3.20.0, updating it is required, not
optional. ponytail is installed as a plugin for its hooks; skip its MCP
server — railyard has hooks, and the MCP is the fallback for hookless
harnesses. After every Codex install or update, re-trust that plugin's hooks
with roundhouse's approval helper (node <roundhouse>/scripts/codex-plugin-hooks.mjs approve PLUGIN@MARKETPLACE) —
all current hooks, fresh hashes, whether or not they existed on this machine
before; hooks must just work.
-
Stacked-PR tooling (required for dependent-stack delivery):
gh extension install github/gh-stack --force plus
gh skill install github/gh-stack --all --agent codex --scope user --force
and the --agent claude-code twin.
-
Shell tooling (required for fleet transport and 1Password): tmux,
jq, and yq via the user's package manager
(brew install tmux jq yq on macOS) — yq is the same tier of
prerequisite as jq; the fleet config's YAML authoring surface depends
on it.
-
macOS app testing (optional; offer when the user builds macOS/iOS
apps): tart-xcode-runner@novotnyllc runs Xcode builds and XCUITests in
disposable Tart VMs so UI tests never seize the host display — plus the
tart CLI (brew install cirruslabs/cli/tart) it depends on. Skipping
disables nothing else; deliver will suggest it again the first time
macOS app work would benefit.
-
3. Configuration interview (defaults in brackets)
Only ask what the inventory shows unset; restate each answer before writing.
- What are the hosts? [this machine only] — ask for the list of machines
that belong to the fleet: display name and SSH alias for each (aliases must
already resolve in
~/.ssh/config; never invent one). "Just this machine"
is a complete answer — skip everything host-related. Capture WSL/Windows
pairs on shared hardware (physical_host + wsl_interop_via) so the
interop maintenance lane works from day one. For each named host,
delegate the entire add flow — config entry, reachability, SSH-certificate
enrollment ceremony, target prerequisites, readiness — to
roundhouse:fleet-hosts. Enrollment is in scope for setup, and its signing
and privileged steps each get their own explicit consent naming the exact
host; adding or removing machines later goes through the same skill.
- Development root [
~/dev] — where project checkouts live.
- Cross-host handoff project [none] — the shared Git repo for
checkpoint-based handoff, if any.
- Codex remote-control host [none] — only for a native-Windows
destination driven by Codex Desktop; skipping disables nothing else.
- Model-routing catalog [none — built-in defaults] — the no-config
profile (Sol orchestration/review, Luna implementation) is the recommended
default; only write a catalog if the user has explicit routing policy.
- Oracle [skip] — if the user has ChatGPT Pro and wants Oracle reviews,
record availability per the oracle skill's cached-detection rules.
- Fleet sync [skip] — mention it exactly once, as one paragraph, and
never default it on: roundhouse's opt-in desired-state sync keeps the
user-scope agent surface — plugins with their enabled state, standalone
skills, agents, hooks, MCP servers, and allowlisted harness config keys —
consistent across every machine and harness, with groups, per-host
history, rollback, an apply-time review of every changed item on the host
where it will run, and one owned scheduler entry per host that absorbs the
fleet-update autoupdate run. It is owned by roundhouse's own store — a jj
repository colocated with git under the config root's
store/ — and
cooperates with chezmoi or another personal sync engine when present as an
upstream. On opt-in, run §3a;
declining is a complete answer and disables nothing else.
- Auto-sync + update schedule [none] — opt-in daily or weekly unattended
maintenance. If fleet sync was taken, §3a already installed the single
owned entry and this is answered — do not add a second one. Standalone,
install the OS-scheduler entry from
roundhouse:fleet-update's
"Unattended schedule" section (which runs the desired-state sync and then
package updates) (launchd agent on macOS, systemd user timer
on Linux, per-user scheduled task on Windows) that runs the harness with
the fixed unattended-maintenance prompt. Removable any time by deleting
the scheduler entry.
Write the fleet config to
${XDG_CONFIG_HOME:-$HOME/.config}/roundhouse/config.json (0600), then
validate it with the roundhouse fleet CLI
("<roundhouse>/scripts/roundhouse" validate-config). A validation
failure is fixed in the interview loop, never hand-waved.
3a. Fleet sync enrollment (only on opt-in)
Resolve CLI to that same <roundhouse>/scripts/roundhouse. Work these in
order — each step is a named command, and a refusal is a stop, never
something to route around.
- jj —
jj --version; roundhouse's store wants 0.43 or newer. Install
it through the host's own user package manager when absent (brew install jj on macOS, apt on Linux, winget on Windows) — never sudo, never a
downloaded installer. jj is required: fleet-init runs jj git init --colocate and refuses without it, so a host that cannot get jj cannot
stand up or join the store — resolve jj before continuing.
- Private store remote — create it or verify the one the user names; a
private GitHub repo is the suggested shape (
gh repo create OWNER/NAME --private). Relay the warning as-is: the store is a trusted-write
surface on every fleet machine — the hooks and skills it carries execute
as the user on all of them — so a public or wrongly-shared store is a
fleet-wide compromise, not a leak.
- This host's store credential — delegate to
roundhouse:fleet-hosts
step 5, on its own consent: an SSH deploy key generated on this host and
kept in ~/.ssh, or a token held by a credential helper. Never embed the
credential in the remote URL, never reuse it for anything else, and never
move it between machines.
- Stand up the store —
"$CLI" fleet-init (jj git init --colocate,
repo config, scaffold — it leaves no [signing] block yet), then
"$CLI" fleet-enroll (mint this host's node key and commit the
self-signed roster that lists it; that commit is the store's genesis and
the step that reports the store id). The order is deliberate: init leaves
no signing block, and enroll adds it only once the key that satisfies it
exists.
- Set the remote, then verify privacy —
"$CLI" fleet-set-remote <url>
(the URL must pass roundhouse's predicate, which refuses credential-bearing
URLs outright), then "$CLI" fleet-verify-remote before any first push.
It probes the remote unauthenticated: only an authentication refusal proves
privacy; a publicly readable remote and an inconclusive probe both refuse,
and neither is a cue to push anyway. Then "$CLI" fleet-seed to discover
this host and write its hosts/<name>.yaml + applied/<name>.yaml.
- The single owned scheduler entry — install exactly one and absorb the
existing fleet-update autoupdate entry into it, removing the old one:
two local runners racing one plugin cache is the failure this prevents.
macOS keeps fleet-update's own name,
~/Library/LaunchAgents/com.novotnyllc.roundhouse.autoupdate.plist;
Linux is a systemd user timer; Windows is a per-user scheduled task
installed through the WSL interop lane on a paired host. Its program runs
the harness with 's fixed unattended prompt
— that text is maintained in lockstep with fleet-agents'
sync doctrine, so copy it, never paraphrase. On Windows the entry is
interactive-session-only; staleness while logged off is expected, not a
fault, and setup says so at install time.
4. Diagnosis
Diagnosing an existing installation — sync drift, broken hosts, "why isn't
X working" — is railyard:doctor's job, not setup's. If the inventory in
step 1 surfaces breakage rather than absence, hand off to the doctor.
5. Boundaries
- Signing (
certify-ssh-node) and privilege-broker enrollment always get
their own explicit consent naming the exact host, even inside a larger
setup flow.
- Never write credentials, tokens, or secrets into config.
- Never modify Compound Engineering. Setup mutates other machines only
through the consented
roundhouse:fleet-hosts flow.
6. Readiness report
Finish with one table: each prerequisite, host, and config item, its state
(installed/enrolled/configured/skipped-by-choice/missing), and the exact next
command for anything deferred. If everything required is green, say the host
is delivery-ready and name the entry points: plain "implement/fix/ship X"
routes through railyard:deliver; fleet or multi-task
objectives through railyard:orchestrate; growing or shrinking the
fleet through roundhouse:fleet-hosts.