Skip to content

Build master @ bc50cd5bunreleased — 31 commits past v1.282.0Last reviewed Last changed Grade fresh (aging >60d, stale >120d)Source / History

Set Up Your Operator Repo ​

Your identity, fleet registry (machines.json) and project manifests (provisions/*.json) belong in an operator repo, a git repo of your own that is separate from the BoB source checkout. This page takes a machine from "no operator declared" to "operator repo holds the fleet, with history". For what the operator repo is and why it exists, see Operators.

Terminal only. These commands edit git repos and $BOB_HOME outside any session.

Before you start ​

  • A clean BoB source checkout (git -C ~/projects/bigbrain status shows nothing).

  • Know where the operator repo should live. ~/projects/bob-operator is the checked default, so a repo there is found with no pointer at all.

  • Check where you stand:

    bash
    bob operator show        # exit 3 = no operator declared yet

What bob operator init writes ​

bob operator init <dir> --link does four things, and commits nothing:

WritesWhat it is
operator.jsonYour identity: id, label, forge, people[], routes, bob_upstream, secrets[] (names and sources only).
machines.jsonA placeholder fleet with one example machine, example-laptop — only when no fleet exists yet. While the BoB checkout still holds machines.json, init leaves it out ([=] machines.json (not written — the fleet at … still resolves …)), so this host keeps resolving until migrate moves the real fleet in.
provisions/README.md, README.md, .gitignore, .github/workflows/validate.ymlThe rest of the scaffold, plus the CI workflow that runs BoB's validators.
$BOB_HOME/.bob-operator (only with --link)The pointer that makes BoB resolve this repo.

It also runs git init in <dir>, and prints the operator id it used — when you leave out --id, the id is derived from the directory name, so check it.

init exits 1 and writes nothing when <dir> is:

  • inside the BoB source checkout, $BOB_HOME, or any git worktree of the BoB repo — operator data never lives in the product or the deploy target, and no flag overrides this;
  • a directory that already holds operator.json (--force rewrites the scaffold files);
  • inside an existing git repo with tracked files (--into-existing scaffolds into it anyway).

Set it up (first time) ​

  1. Scaffold and link.

    bash
    bob operator init ~/projects/bob-operator --id <your-slug> --label "<Your Name>" --link

    Pass --forge-owner <account> if your repos live under a different account than the id.

  2. Make both trees clean. migrate refuses unless the BoB checkout and the operator repo have no uncommitted changes, and the scaffold is uncommitted. Edit operator.json first (at least people[] and forge), then commit the scaffold:

    bash
    cd ~/projects/bob-operator
    git add -A && git commit -m "chore: scaffold operator repo"
    git -C ~/projects/bigbrain status --short     # must print nothing
  3. Dry-run the move. This prints what moves (with each path's commit count), what stays in the source, and what happens to the placeholder. It changes nothing.

    bash
    bob operator migrate

    Expect machines.json and every provisions/<project>.json in "would move with history". provisions/_bob-home.json and provisions/_default.json belong to the product and stay in the source.

  4. Move it.

    bash
    bob operator migrate --apply

    Add --force only if the dry run named a file already at a migrated path in the operator repo. The command:

    • replays every commit that touched those paths into the operator repo (git format-patch → git am --3way), so history comes along;
    • removes the paths from the BoB checkout on a new branch, chore/2270-move-operator-data.
  5. Publish both sides.

    bash
    cd ~/projects/bob-operator && git push -u origin HEAD      # after creating the remote
    cd ~/projects/bigbrain && git push -u origin chore/2270-move-operator-data
    gh pr create --fill                                         # merge it, then deploy

Verify ​

bash
bob operator show                          # exit 0: resolved and valid, names the rung
node ~/.claude/scripts/fleet/machine.js whoami   # prints THIS machine's entry
bob doctor                                 # the operator line names your repo

whoami must print a real machine. If it still fails, the operator repo's machines.json is not your fleet. Check it before doing anything else.

Recovery: the scaffold is shadowing a live fleet ​

Only an operator repo scaffolded before #2627 can get here — init no longer writes the placeholder while a real fleet resolves. Symptom: you ran init --link but not migrate, and now machine: could not resolve current host, bob doctor and fleet snapshots all read example-laptop.

  1. Park the placeholder so the fallback to the BoB checkout's machines.json takes over again. This takes effect immediately:

    bash
    cd ~/projects/bob-operator
    git rm --cached -q machines.json 2>/dev/null; mv machines.json ~/machines.scaffold.json
    node ~/.claude/scripts/fleet/machine.js whoami     # your real entry again (with a legacy-location warning)
  2. Commit so the operator tree is clean: git add -A && git commit -m "chore: park the scaffold machines.json".

  3. Migrate deliberately: run step 3 (dry run) and step 4 above. With the placeholder gone, migrate --apply needs --force only if the dry run names another file already in the operator repo.

Deleting $BOB_HOME/.bob-operator is not the fix. A repo at ~/projects/bob-operator is still found on the default rung, so the placeholder keeps shadowing. At any other location, unlinking hides operator.json as well, and every manifest write (bob provision add, --init) is refused.

A second machine ​

The operator repo already exists, so do not run init again. It refuses a directory that holds operator.json, and --force would rewrite your files with the scaffold. Clone the repo to the checked default instead:

bash
git clone <your operator repo URL> ~/projects/bob-operator
bob operator show                          # resolves on the "default" rung — no pointer needed

For any other location, export BOB_OPERATOR=<dir> in your shell profile.