Skip to content

Fleets

A fleet is an agent-side identity that PETROVA admits to a repo’s verb surface. Fleets diagnose and plan locally; they emit PRs through the verb layer. The fleets_allowed registry field is the gate.

Every verb invocation carries an actor field of the form <kind>:<id>:

KindExampleUse
human:human:alex@devarno.comDirect human invocation via CLI.
fleet:fleet:kahn-implementerAgent fleet bot. Gated by fleets_allowed.
system:system:cron-schedulerInternal automation. Bypasses fleet gate.

The fleet: prefix is the only one constrained by fleets_allowed. Humans and system processes write under their own accountability — the fleet gate exists because fleets are programs, and programs without a registry-declared identity are ungoverned.

A registry entry’s fleets_allowed array enumerates which fleet IDs may write to that repo:

- slug: kahn-hq
fleets_allowed:
- kahn-implementer
- kahn-diagnostics
- kahn-reviewer
- kahn-planner

A fleet:not-listed actor invoking any write verb against kahn-hq fails with FLEETS_ALLOWED — at dry-run time, before any side effect. Adding a new fleet is itself a request_review PR against registry.yaml.

Empty is the safe default. New entries land with fleets_allowed: [] (humans only). Fleets are added explicitly, once their identity is real and their scope agreed. No “permissive by default” — the consequences are too asymmetric.

PETROVA gates two distinct things:

  • Identity (the fleet: prefix in actor) — who is asking? Gated by fleets_allowed in the registry.
  • Auth (the PETROVA_GITHUB_TOKEN or GitHub App credentials) — can we actually push to GitHub? Gated by GitHub’s permissions.

A fleet can be listed but not authenticated (its credentials expired) — --apply errors with AUTH_MISSING before reaching the identity check. A fleet can be authenticated but not listed--apply errors with FLEETS_ALLOWED after schema validation. Both gates fire independently.

The verb fails with FLEETS_ALLOWED. The fleet should:

  1. Not retry. Same input → same failure forever.
  2. Surface the gap to a human.
  3. The human opens a request_review PR against petrova-hq/registry.yaml adding the fleet to the relevant repo’s fleets_allowed.
  4. After merge + a local git pull, retry succeeds.

This puts a human in the loop for every fleet-capability expansion, which is exactly what the gate exists to do.