Skip to content

next

Read-only oracle: computes the single legal next petrova verb for a repo (register-repo, onboard, phase-open, verify-round, or plan) from diagnose() output plus a direct filesystem check for .petrova/contract.yaml. Performs NO writes of any kind — it recommends a move, it never invokes one.

Upholds: (read-only) Side effects: None. Read-only. Does not call any write verb.

  • REPO_IN_REGISTRY — Not enforced as a precondition — an unregistered slug is a legal input that resolves to move=register-repo rather than a thrown error.
  • scope string enum: full — Reserved for future narrowing of which signals feed the oracle. Currently unused — the oracle always reads the full diagnose() scope.
  • move string (required) enum: register-repo, onboard, phase-open, verify-round, plan
  • reason string (required) — Always populated — never bare, even for the ‘plan’ fallback.
  • signal_gap string — Present only when the move is a downgrade to ‘plan’ because diagnose() output lacked a signal the oracle needed — names the missing signal. Absent for a ‘plan’ that reflects genuine ‘nothing pending’ or ‘work in progress’ rather than an inability to tell.
  • repo → RepoSlug
  • checked_at → IsoDate

Input:

{
"envelope": {
"verb": "next",
"target_repo": "kahn-hq",
"idempotency_key": "0000000000000000000000000000000000000000000000000000000000000000",
"dry_run": false,
"actor": "fleet:kahn-diagnostics",
"triggered_by": {
"kind": "schedule",
"ref": "cron:hourly"
}
},
"params": {
"scope": "full"
}
}

Output (output_applied):

{
"envelope": {
"verb": "next",
"status": "applied",
"idempotency_key": "0000000000000000000000000000000000000000000000000000000000000000",
"mr_citations": []
},
"result": {
"move": "verify-round",
"reason": "phase open, no active/planned milestones remain, and no verification-round-shaped decision found in recent history",
"repo": "kahn-hq",
"checked_at": "2026-04-29T14:30:00Z"
}
}

(no recipe yet — see SKILL guide)