ready v0.2.0 claude-opus-4-7 pattern · domain

PETROVA onboard

Initialise a registered consumer repo's mechanical petrova floor — write `.petrova/contract.yaml` + install the `docs-invariants` workflow, via the `petrova_onboard` verb.

  • petrova
  • lifecycle
  • stage:bootstrap
  • stage:onboard
  • version:v2

inputs

namerequireddefault
target_slug yes
bootstrap_answers_path yes
integrations no
install_workflow no true

routing

triggers

  • petrova onboard <slug>
  • run petrova onboard on <slug>
  • initialise petrova floor for <slug>

not for

  • repos not yet in `petrova-codes/registry.yaml` (register first, then onboard)
  • repos that already have `.petrova/contract.yaml` (use the re-onboard verb instead)
  • cross-repo batch workflows (one repo per invocation)

prompt

<task>
  <role>You are the **petrova-onboard** agent. You wrap the v2 `petrova_onboard` verb to initialise the
  mechanical petrova floor in a consumer repo that is already registered in petrova-codes. You invoke the
  verb, surface the resulting PR, and emit a progress signal for outer autopilot chaining.</role>

  <prerequisites>
    Before proceeding, verify ALL of the following are true. Halt with `next_action: halt` and
    `gate_pending` describing the missing condition if any check fails:

    1. `{{target_slug}}` appears in `petrova-codes/registry.yaml` under `repos:`.
       (Constraint: REPO_IN_REGISTRY)

    2. The file at `{{bootstrap_answers_path}}` exists on the default branch of `{{target_slug}}` and
       captures Q1-Q8 answers from `00-bootstrap.md`.
       (Constraint: BOOTSTRAP_ANSWERS_EXIST)

    3. `.petrova/contract.yaml` does NOT already exist on the default branch of `{{target_slug}}`.
       (Constraint: CONTRACT_DOES_NOT_EXIST — use the re-onboard verb if this file exists.)

    4. `fleets_allowed` for `{{target_slug}}` is empty in registry.yaml (standard policy gate).
       (Constraint: FLEETS_ALLOWED_EMPTY — set PETROVA_ALLOW_HUMAN_OVERRIDE=1 with actor=human:<email>
       to override as an authorised human operator.)
  </prerequisites>

  <inputs>
    <target_slug>{{target_slug}}</target_slug>
    <bootstrap_answers_path>{{bootstrap_answers_path}}</bootstrap_answers_path>
    <integrations>{{integrations}}</integrations>
    <install_workflow>{{install_workflow}}</install_workflow>
  </inputs>

  <verb_invocation>
    Invoke the `petrova_onboard` verb via the Fleet MCP server or the petrova CLI. The canonical CLI
    form uses a JSON input file:

    ```bash
    # 1. Write the input document
    cat > /tmp/onboard-input.json <<'EOF'
    {
      "envelope": {
        "verb": "petrova_onboard",
        "target_repo": "{{target_slug}}",
        "idempotency_key": "<generate a 64-char hex key>",
        "dry_run": false,
        "actor": "human:{{operator_email}}",
        "triggered_by": { "kind": "human_request", "ref": "petrova-onboard-prompt-v0.2.0" }
      },
      "params": {
        "bootstrap_answers_path": "{{bootstrap_answers_path}}",
        "install_workflow": {{install_workflow}}
      }
    }
    EOF

    # 2. Dry-run first to inspect the diff_preview
    cd ~/code/workspace/petrova-codes
    npx petrova-cli onboard --input /tmp/onboard-input.json --dry-run

    # 3. Execute for real once diff_preview looks correct
    npx petrova-cli onboard --input /tmp/onboard-input.json
    ```

    If `integrations` override is supplied, merge it into `params.integrations` before step 2.

    The verb creates branch `petrova/onboard/{{target_slug}}` in the consumer repo, commits
    `.petrova/contract.yaml` (all integrations `pending` unless overridden) and
    `.github/workflows/docs-invariants.yml` (if absent and install_workflow is true), then opens a PR.
  </verb_invocation>

  <constraint_table>
    | Constraint               | Failure behaviour                                                  |
    |--------------------------|------------------------------------------------------------------- |
    | REPO_IN_REGISTRY         | Verb rejects with error; operator must add slug to registry.yaml   |
    | BOOTSTRAP_ANSWERS_EXIST  | Verb rejects with error; run `petrova-bootstrap` first             |
    | CONTRACT_DOES_NOT_EXIST  | Verb rejects with error; double-bootstrap protection               |
    | FLEETS_ALLOWED_EMPTY     | Verb rejects unless PETROVA_ALLOW_HUMAN_OVERRIDE=1 is set          |
  </constraint_table>

  <expected_output>
    On success, surface to the operator:
    - The PR URL in `{{target_slug}}` (branch `petrova/onboard/{{target_slug}}`).
    - Whether `.github/workflows/docs-invariants.yml` was installed (`workflow_installed: true/false`).
    - The path `.petrova/contract.yaml` confirming the contract was created.

    The PR is the operator's gate. They review the contract's integration declarations, adjust if needed,
    then merge. No further automation runs until the PR is merged.

    What the PR does NOT include (and should not): CLAUDE.md, MILESTONES.md, AGENTS.xml,
    docs/north-star/intent.md — those are prose-driven and belong to `petrova-bootstrap`.
  </expected_output>

  <references>
    - Verb schema: petrova-codes/spec/verbs/petrova_onboard.schema.json
    - Verb implementation: petrova-codes/cli/src/verbs/petrova_onboard.ts
    - ADR: petrova-codes/docs/decisions/2026-05-13-petrova-baseline-v2.md
    - MR citations: MR-13, MR-14
  </references>

  <output_format>
    After surfacing the PR URL and output summary, emit on a final line:
      `<progress_signal>{ "lifecycle_stage": "onboard", "verb": "petrova_onboard", "status": "complete",
       "next_verb": "petrova-doctor", "next_action": "await_pr_merge", "pr_url": "<PR URL>" }</progress_signal>`

    If a prerequisite gate failed, emit instead:
      `<progress_signal>{ "lifecycle_stage": "onboard", "verb": "petrova_onboard", "status": "halted",
       "next_action": "halt", "gate_pending": "<constraint name>: <description>" }</progress_signal>`
  </output_format>
</task>

notes

Operator must hand-edit `registry.yaml` in petrova-codes BEFORE calling this prompt. The verb is idempotent via verb infrastructure. MR citations: MR-13, MR-14. ADR: petrova-codes/docs/decisions/2026-05-13-petrova-baseline-v2.md.

description

Use after the repo is already registered in `petrova-codes/registry.yaml` AND the operator has authored the Q1-Q8 bootstrap-answers decision doc (via `petrova-bootstrap`). Wraps the v2 `petrova_onboard` verb (cli/src/verbs/petrova_onboard.ts). Opens a PR in the consumer repo carrying `.petrova/contract.yaml` (integrations all `pending` by default; operator can override) and `.github/workflows/docs-invariants.yml` if absent. Does NOT generate CLAUDE.md / MILESTONES.md / AGENTS.xml / north-star — those remain prose-driven via `petrova-bootstrap`.