request_review
Generic write surface: open a PR with arbitrary file changes and request review. The lower-level primitive other write verbs may compose. Does NOT mark auto-merge — human approval gates the merge.
Upholds: MR-3 · MR-12
Side effects: Creates a branch, applies file edits, opens a PR with reviewers requested.
Constraints
Section titled “Constraints”REPO_IN_REGISTRY— target_repo must appear in registry.yaml.FLEETS_ALLOWED— If actor is fleet:*, registry.yaml entry’s fleets_allowed must include the fleet ID.FILES_NONEMPTY— files array must contain ≥1 entry.NO_PRIVILEGED_PATHS— files[].path must not match privileged patterns: ^.github/workflows/, ^.*.env$, ^secrets/, ^deploy/credentials/. Editing these requires explicit human invocation.GROUNDING_NONEMPTY— grounding must cite at least one source: a decision doc path, a north-star section, an MR, or a finding (MR-12).
Input shape
Section titled “Input shape”titlestring(required)rationalestring(required) — Free-text ‘why’. Goes into the PR body’s Why section.filesarray(required)- items:
pathstring(required)operationstring(required) enum:create,modify,deletecontentsstring— Required when operation ∈ {create, modify}.patchstring— Optional unified diff; mutually exclusive with contents.
- items:
branchstring— Optional override; default petrova/request-review/. reviewersarraylabelsarraygroundingarray(required)- items:
kindstring(required) enum:decision_doc,north_star,spec,meta_rule,finding,human_inputrefstring(required)
- items:
Output shape
Section titled “Output shape”pr→PRRefdiff_preview→DiffPreview
Example
Section titled “Example”Input:
{ "envelope": { "verb": "request_review", "target_repo": "smo1-io", "idempotency_key": "f8a5ee806d31cc579fa03b2c6d7e8f9012b3c4d5e6f7a8b9c0d1e2f304152637", "dry_run": true, "actor": "fleet:smo1-implementer", "triggered_by": { "kind": "friction_item", "ref": "M2.2" } }, "params": { "title": "feat(meow-web): render scoring chips on links grid (M2.2)", "rationale": "M2.2 milestone wants pawprintz/treatz/niblz visible on the links grid; this PR wires the existing types into the grid component.", "files": [ { "path": "meow-web/src/components/links-grid.tsx", "operation": "modify", "contents": "..." } ], "grounding": [ { "kind": "decision_doc", "ref": "docs/decisions/2026-04-28-bootstrap-complete.md" }, { "kind": "north_star", "ref": "docs/north-star/intent.md#scoring" } ] }}Output (output_dry_run):
{ "envelope": { "verb": "request_review", "status": "dry_run", "idempotency_key": "f8a5ee806d31cc579fa03b2c6d7e8f9012b3c4d5e6f7a8b9c0d1e2f304152637", "mr_citations": [ "MR-3", "MR-12" ] }, "result": { "diff_preview": { "files": [ { "path": "meow-web/src/components/links-grid.tsx", "operation": "modify" } ], "branch": "petrova/request-review/f8a5ee80", "commit_message": "feat(meow-web): render scoring chips on links grid (M2.2)" } }}Recipe
Section titled “Recipe”Schema: spec/verbs/request_review.schema.json
Upholds: MR-3 (sibling files), MR-12 (CLAUDE.md is a projection).
Emits: PR with arbitrary file changes; humans review and merge.
When to use
Section titled “When to use”The generic write surface. Use when no other verb fits — file edits that aren’t structurally a decision/milestone/phase event.
Required params
Section titled “Required params”{ "title": "<conventional commit-style PR title>", "rationale": "<why this change; lands in PR body>", "files": [ {"path": "<relative/path>", "operation": "create|modify|delete", "contents": "<full file contents for create/modify>"} ], "grounding": [ {"kind": "decision_doc|north_star|spec|meta_rule|finding|human_input", "ref": "<path or identifier>"} ]}Optional: reviewers[], labels[], branch (default petrova/request-review/<key8>).
Constraints
Section titled “Constraints”filesnon-empty.groundingnon-empty (MR-12 enforcement — no ungrounded claims).- No privileged paths:
^.github/workflows/,*.env,^secrets/,^deploy/credentials/. Editing these requires human invocation, not agent fleets. - Fleet actors must appear in target’s
fleets_allowed.
Two patterns
Section titled “Two patterns”Pattern A: Modify an existing file (you must provide full contents)
Section titled “Pattern A: Modify an existing file (you must provide full contents)”# Step 1: read current contents (manual — outside this verb's scope)current=$(gh api repos/owner/name/contents/path -q .content | base64 -d)
# Step 2: produce new contents (your edit)new="$current... your modification..."
# Step 3: emitcat > /tmp/petrova-input.json <<JSON{ "title": "fix: handle empty UTM", "rationale": "...", "files": [{"path": "src/utm.ts", "operation": "modify", "contents": ${new@Q}}], "grounding": [{"kind": "finding", "ref": "docs/findings/...md"}]}JSONPattern B: Create a new file
Section titled “Pattern B: Create a new file”cat > /tmp/petrova-input.json <<'JSON'{ "title": "docs: add deployment runbook", "rationale": "Operator asked for one after the 2026-04-29 deploy.", "files": [{"path": "docs/runbooks/deploy.md", "operation": "create", "contents": "# Deploy\n\n..."}], "grounding": [{"kind": "human_input", "ref": "2026-04-29 conversation with alex"}]}JSONpetrova request_review smo1-io --input /tmp/petrova-input.jsonLimitations
Section titled “Limitations”- The verb commits one file at a time via the GitHub Contents API. Atomic multi-file commits would require the Trees API (TASKSET 7+). In practice that’s fine for petrova-shaped PRs (1–3 files).
- For
modify, you provide the new full contents. The verb does not diff or merge — it overwrites. If concurrent edits land in the meantime, the verb’s commit will fail with a SHA mismatch and the caller retries with fresh contents.