Skip to content

onboard repo

The end-to-end flow for admitting a new repo to the petrova control plane. After a successful run, the repo is reachable via every verb, visible in petrova status / petrova dashboard, and (if the operator chose) governed by agent fleets.

  • Repo is reachable on GitHub (public or private with petrova auth).
  • Operator has push access to petrova-hq/petrova (the registry lives here).
  • PETROVA_GITHUB_TOKEN (or the GitHub App env triple) configured for the --apply step.
  • Repo is locally cloned at $PETROVA_WORKSPACE/<slug> (default: parent dir of petrova-hq). If not, clone it first — the readiness report needs filesystem access.
Terminal window
cd ~/code/workspace/petrova-hq
claude code

The prompt lives at core/prompts/05-petrova-onboard.md. Copy it verbatim into the Claude Code session. The prompt is interactive — it will:

  1. Ask which repo you’re onboarding.
  2. Read the consumer repo (read-only) and produce a readiness report covering petrova-shape state, branch protection, recommended role and profile.
  3. Confirm fleets_allowed (default: empty).
  4. Compose the registry-update PR payload as a JSON file.
  5. Run dry-run, show you the diff.
  6. After your go-ahead, run --apply, return the PR URL.

The registry PR appears in petrova-hq/petrova. CODEOWNERS for registry.yaml (or any human approver) reviews it.

Things to check:

  • The new entry’s url matches the consumer’s actual git remote get-url origin.
  • profile is conservative — strict for production, standard for most, permissive only when intentional.
  • fleets_allowed is empty unless the operator named specific fleets (and they exist).

Merge.

Terminal window
git -C ~/code/workspace/petrova-hq pull
petrova status # new slug appears
petrova diagnose <slug> # returns structured context
petrova validate <slug> # MR / convention compliance

If petrova status doesn’t show the new slug, the local registry is stale — git pull and retry.

If the readiness report flagged the consumer as missing control-loop docs (CLAUDE.md, AGENTS.xml, MILESTONES.md):

Terminal window
cd ~/code/workspace/<slug>
claude code
# Paste core/prompts/00-bootstrap.md

Bootstrap is its own session — it needs the consumer’s spec docs in context, not the petrova-hq root.

6. (Optional) Add petrova-act capability declaration

Section titled “6. (Optional) Add petrova-act capability declaration”

If the consumer has an AGENTS.xml but no <capability id="petrova-act"> block, add it via petrova request_review:

Terminal window
# Read the new template's capability block from
# core/templates/AGENTS.xml.tmpl, splice it into the consumer's
# AGENTS.xml just before </agents>, then:
petrova request_review <slug> \
--input /tmp/capability-add.json \
--triggered-by-kind human_request \
--triggered-by-ref "post-onboarding capability declaration"

This is purely informational for the consumer’s orchestrator — verbs work without it (gating happens in registry.yaml’s fleets_allowed, not in the consumer’s XML).

ProblemFix
Slug already in registryThis is an update, not an onboard. Re-target as a request_review modifying the existing entry.
git remote get-url origin doesn’t match registry urlOperator typo or registry drift. Open a one-line request_review PR fixing the url.
Consumer not locally clonedgit clone it first; the prompt won’t proceed without filesystem access.
PETROVA_GITHUB_TOKEN unsetSet it. Onboarding cannot complete in dry-run only.
Concurrent registry editPull latest, recompose JSON with current registry contents, retry.
Branch protection on petrova-hq blocks the PR’s auto-mergeExpected. Petrova-hq is strict-profile; the registry PR needs human approval.
  • Does not push to the consumer repo’s main branch (everything is PR-based per the control-plane decision).
  • Does not auto-grant agent-fleet access. Empty fleets_allowed is the safe default; fleets are added in subsequent registry PRs as their identity gets defined.
  • Does not auto-bootstrap. The bootstrap session is run separately with the consumer’s spec docs in context.