Skip to content

`petrova cairnet-onboard --wire-keys` ("D")

petrova cairnet-onboard --wire-keys (“D”)

Section titled “petrova cairnet-onboard --wire-keys (“D”)”

Date: 2026-05-24 Status: superseded Supersedes: none Superseded-by: docs/decisions/2026-05-24-cairnet-provision-keys-shape-correction.md (D’)

petrova cairnet-onboard already installs the emit-v2 kit, pins kit_tag and lock_commit into .petrova/contract.yaml, registers session hooks, and writes the buffer/flush plumbing. It then stops at a footnote labelled “PREREQUISITE A (operator, manual)”: the operator must visit HATCH, mint six per-role agent keys, and paste them into .petrova/cairnet.env. Until that happens, every CAIRNET emission falls into the lossless retention buffer and nothing reaches Pebble.

This is the only manual step in an otherwise fully-mechanical onboarding flow. It is also the step most prone to silent failure: the verb reports success, the kit installs cleanly, doctor returns green — and the operator forgets, mis-pastes, or pastes into the wrong project. The companion decision (“A”, 2026-05-24-hatch-bulk-agent-key-issuance.md) collapses the UI tedium from six form submits to one bulk paste, but the manual step itself remains. Closing it requires the substrate verb to be able to mint keys on the operator’s behalf.

The PETROVA philosophy is “make the mechanical floor harder to skip.” A manual step that blocks a mechanical pipeline violates that floor. D closes the loop.

Extend petrova cairnet-onboard with --wire-keys (and supporting flags) to provision agent keys directly via airlock’s admin API and persist them into .petrova/cairnet.env atomically.

  1. Verb surface:

    petrova cairnet-onboard <repo-path> --wire-keys \
    [--roles fleet,coordinator,reviewer,planner,bridge,other] \
    [--rotate] \
    --actor human:alex@devarno.com
    • Default --roles is the full CAIRNET enum (six roles).
    • Without --rotate, existing <producer>-<role>-NNN agents are skipped (idempotent).
    • With --rotate, existing agents have their keys rotated via rotateAgentKey.
    • --actor reuses the existing PETROVA_ALLOW_HUMAN_OVERRIDE pattern; the verb refuses to run without it (no silent service-to-service key minting).
  2. Auth path: The verb authenticates to airlock’s admin API using a dedicated capability-scoped key (agent_keys:create, agent_keys:rotate) issued out-of-band and stored in ~/.petrova/credentials (NOT in any repo). This is a one-time operator setup, documented in the airlock operator guide.

  3. Persistence: Keys are written into .petrova/cairnet.env in a single atomic file write (write-to-tmp + rename). .petrova/cairnet.env remains gitignored (already enforced per hermes/.gitignore). The verb emits a CAIRNET stone of type petrova.integration.wired recording producer + role list + agent IDs (NOT keys) so the wiring is auditable in Pebble.

  4. HATCH /agents UX shift: Once D ships, /agents becomes the surface for exceptional key operations (one-off agents, custom capability scopes, manual rotation outside the substrate flow). The bulk form added by A remains for repos not yet onboarded via PETROVA, and for retro-fitting existing repos. We do not deprecate A on D’s landing.

Scope explicitly excludes: capability beyond agent_keys:create|rotate for the verb’s admin key; provisioning for integrations other than CAIRNET; multi-tenant key minting (the verb operates on a single repo per invocation).

  • Leave provisioning manual; only ship A — keeps the floor partially mechanical. Rejected: the manual step’s silent-failure surface is exactly the kind of drift PETROVA exists to prevent.
  • Provision via session-cookie scraping — would avoid needing a new airlock capability scope, but couples the substrate to a browser auth flow and requires an interactive operator at verb invocation time. Rejected; makes CI/scripted onboarding impossible.
  • Provision via a service-to-service token with no human actor — simplest, but creates a credential that can mint other credentials with no human accountability. Rejected on threat-model grounds; the --actor human: requirement is load-bearing.
  • Skip stone emission for wiring events — saves one stone per onboarded repo. Rejected; the audit trail is the point. Stone emission is cheap.
  • Persist plaintext keys in a sealed vault rather than .petrova/cairnet.env — better threat model but adds a vault dependency to every governed repo. Defer until a substrate-wide secret-management decision lands; for now .gitignore + filesystem permissions is the contract.

For code:

  • petrova-codes (verb implementation, likely verbs/cairnet_onboard.py or equivalent): new --wire-keys, --roles, --rotate flags; new airlock admin client; atomic env-file writer; stone emission for petrova.integration.wired.
  • airlock: introduce capability scopes agent_keys:create and agent_keys:rotate for admin API keys (today admin endpoints assume session cookies); document scope grant flow.
  • hermes/.petrova/cairnet.env becomes the first repo wired via the new path (validates the loop).

For docs:

  • New substrate doc: petrova-codes/docs/operator/cairnet-key-provisioning.md covering the one-time ~/.petrova/credentials setup.
  • Update to petrova cairnet-onboard --help output (PREREQUISITE A footnote removed once --wire-keys is used).
  • This ADR is referenced from A’s “consequences” line about the deferred manual step.

For in-flight phases:

  • Future repo onboardings (post-HERMES) skip the manual step entirely.
  • HERMES itself is provisioned via A’s bulk form (already operator-driven), then re-validated against --wire-keys once D ships (rotate path).
  • Reduces the “PR-burden” of each onboarding by one human-in-the-loop coordination point.

For invariants:

  • Reinforces the “mechanical floor” intent (no new MR; clarifies MR-13/14 application).
  • Implicitly extends PETROVA_ALLOW_HUMAN_OVERRIDE to a second verb (cairnet-onboard’s —wire-keys); pattern was previously only used for petrova-codes registry verbs. Worth flagging in a future MR draft if the pattern proliferates further.
  • Companion: docs/decisions/2026-05-24-hatch-bulk-agent-key-issuance.md (“A”)
  • Preceding: docs/decisions/2026-05-24-contract-sha-hash-method-fix-hermes.md (closed HERMES Phase 1f and exposed the bottleneck)
  • Atlas doctrine: atlas/doctrines/petrova-contract-yaml-is-not-narrative.doctrine.md (related mechanical-floor learning)
  • Schema: petrova-codes/contracts/vendor/agentic-emission.v1.json (role enum + agent_id regex authoritative source)
  • Affected code surfaces: petrova-codes verbs/, airlock admin API, hatch/src/app/agents/page.tsx (UX intent shift only)