onboard repo
Onboard a repo into the petrova line
Section titled “Onboard a repo into the petrova line”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.
Prerequisites
Section titled “Prerequisites”- Repo is reachable on GitHub (public or private with petrova auth).
- Operator has push access to
petrova-codes/petrova(the registry lives here). PETROVA_GITHUB_TOKEN(or the GitHub App env triple) configured for the--applystep.- Repo is locally cloned at
$PETROVA_WORKSPACE/<slug>(default: parent dir of petrova-codes). If not, clone it first — the readiness report needs filesystem access. - After the playbook PR merges, set a one-time
PETROVA_DISPATCH_TOKENsecret on the consumer repo so.github/workflows/petrova-notify-state.ymlcan firerepository_dispatchat petrova-codes on phase verb merges. SeePETROVA_DISPATCH_TOKENsetup at the end of this runbook. Optional — without it the workflow no-ops and the 30-min state-sweep cron is the safety net.
Flow (estimated 5–10 min)
Section titled “Flow (estimated 5–10 min)”1. Open Claude Code at petrova-codes root
Section titled “1. Open Claude Code at petrova-codes root”cd ~/code/workspace/petrova-codesclaude code2. Paste the onboarding prompt
Section titled “2. Paste the onboarding prompt”The prompt lives at core/playbook/prompts/05-petrova-onboard.md. Copy it
verbatim into the Claude Code session. The prompt is interactive —
it will:
- Ask which repo you’re onboarding.
- Read the consumer repo (read-only) and produce a readiness
report covering petrova-shape state, branch protection,
recommended
roleandprofile. - Confirm
fleets_allowed(default: empty). - Compose the registry-update PR payload as a JSON file.
- Run dry-run, show you the diff.
- After your go-ahead, run
--apply, return the PR URL.
3. Review and merge the registry PR
Section titled “3. Review and merge the registry PR”The registry PR appears in petrova-codes/petrova. CODEOWNERS for
registry.yaml (or any human approver) reviews it.
Things to check:
- The new entry’s
urlmatches the consumer’s actualgit remote get-url origin. profileis conservative — strict for production, standard for most, permissive only when intentional.fleets_allowedis empty unless the operator named specific fleets (and they exist).
Merge.
4. Verify the new slug is reachable
Section titled “4. Verify the new slug is reachable”git -C ~/code/workspace/petrova-codes pullpetrova status # new slug appearspetrova diagnose <slug> # returns structured contextpetrova validate <slug> # MR / convention complianceIf petrova status doesn’t show the new slug, the local registry is
stale — git pull and retry.
5. (Optional) Bootstrap the consumer
Section titled “5. (Optional) Bootstrap the consumer”If the readiness report flagged the consumer as missing control-loop
docs (CLAUDE.md, AGENTS.xml, MILESTONES.md):
cd ~/code/workspace/<slug>claude code# Paste core/playbook/prompts/00-bootstrap.mdBootstrap is its own session — it needs the consumer’s spec docs in context, not the petrova-codes 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:
# 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).
Recovery
Section titled “Recovery”| Problem | Fix |
|---|---|
| Slug already in registry | This 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 url | Operator typo or registry drift. Open a one-line request_review PR fixing the url. |
| Consumer not locally cloned | git clone it first; the prompt won’t proceed without filesystem access. |
PETROVA_GITHUB_TOKEN unset | Set it. Onboarding cannot complete in dry-run only. |
| Concurrent registry edit | Pull latest, recompose JSON with current registry contents, retry. |
| Branch protection on petrova-codes blocks the PR’s auto-merge | Expected. Petrova-hq is strict-profile; the registry PR needs human approval. |
What this runbook does NOT do
Section titled “What this runbook does NOT do”- 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_allowedis 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.
PETROVA_DISPATCH_TOKEN setup
Section titled “PETROVA_DISPATCH_TOKEN setup”The petrova_install_playbook verb deposits
.github/workflows/petrova-notify-state.yml into the consumer repo.
That workflow fires a repository_dispatch at
petrova-codes/petrova whenever a phase verb PR merges, so the
fleet-wide phases grid refreshes in <60s rather than waiting for the
30-min state-sweep cron.
The workflow needs a token with permission to call the dispatches
endpoint on petrova-codes/petrova. Without the secret it no-ops
(logged warning, no failure); the 30-min cron is the safety net.
Create the token (one-time per operator)
Section titled “Create the token (one-time per operator)”The token is reused across all consumer repos; you only mint it once.
- https://github.com/settings/personal-access-tokens/new
- Token name:
petrova-state-dispatch - Resource owner:
petrova-codes - Repository access → Only select repositories →
petrova-codes/petrova - Permissions → Repository permissions → set both:
- Actions: Read and write (for the dashboard’s
▶ trigger sweepbutton, which callsPOST /actions/workflows/.../dispatches). - Contents: Read and write (for the consumer-side
petrova-notify-state.ymlworkflow, which callsPOST /dispatches— a separate, contents-scoped endpoint).
- Actions: Read and write (for the dashboard’s
- Generate, copy the
github_pat_…string.
Install per consumer (after the playbook PR merges)
Section titled “Install per consumer (after the playbook PR merges)”gh secret set PETROVA_DISPATCH_TOKEN -R <owner>/<consumer-repo># paste token at the promptVerify by closing a phase in the consumer; the
petrova-notify-state workflow run should show Dispatched petrova-state-stale for slug=<consumer-repo> and the petrova-codes
state-sweep should fire within ~60s.