{
  "version": "act 2.0.0",
  "slug": "safe-to-merge",
  "name": "safe-to-merge",
  "description": "Decide whether a change is safe to merge \u2014 runs `act gate`, the deterministic verdict (MERGE / REVIEW / BLOCK / UNKNOWN) over every changed function. Use before merging a branch or approving a PR.",
  "url": "https://act101.ai/docs/skills/safe-to-merge",
  "body_md": "# safe-to-merge\n\nDelegate to the **`gate`** tool (CLI twin: `act gate`). The verdict rules live\nin the engine \u2014 one source of truth; this skill describes how to run it and\nread the result, it does not re-specify the rules.\n\n## Run\n\n| Scope | Call |\n|---|---|\n| Working tree vs HEAD (default) | `gate` with no params / `act gate` |\n| PR branch vs its base | `gate` with `base_ref` = the base (e.g. `origin/main`) / `act gate --base-ref origin/main` |\n\nCLI exit codes: 0 MERGE, 1 BLOCK, 2 REVIEW, 3 UNKNOWN, 4 execution error \u2014\nCI scripts branch on exact codes (they are identifiers, not a severity scale).\n\n## What the engine does\n\nDiscovers every changed function from the git diff (rename-aware; same-file\nexact-body renames are paired as signature changes), then composes the\nverification trio per function: `verify_diff_semantics` (hunk classes \u2014\nguard-condition changes count as behavior), `verify_test_impact` (does any\ntest reach it \u2014 syntactic call-graph floor with import resolution),\n`verify_side_effects` (effect delta, dropped cleanup). Broadly: format- or\nsignature-only changes with test reach merge; tested behavior changes ask for\nreview; untested behavior/signature changes and dropped cleanup block; anything\nthe grammar cannot model degrades to UNKNOWN with `modeled_kinds` quoted.\nChanged test code is exempt from the reach rule. The authoritative matrix is in\n`act-analysis`'s `gate` module \u2014 read the per-function `reason` field; it cites\nthe rule that fired.\n\n## Honesty caveat (read first)\n\nThese are AST/heuristic analyses, not a proof. UNKNOWN means \"not verified\" \u2014\nnever present it as MERGE; the engine enforces this (UNKNOWN outranks MERGE\nand REVIEW in the overall verdict). Per-grammar degradation is real: grammars\nwithout branch-CFG modeling cannot rule out behavior changes in body edits and\nreturn UNKNOWN with the evidence quoted.\n\n## Tier\n\n**Engineer** (the verify trio's tier; named Pro before V2). Tier-blocked runs\nand premium-language files report UNKNOWN with the blocking dimension named \u2014\nreport that, do not guess a verdict.\n\n## Reading the result\n\n`verdict` is the overall worst case over `functions[]`. Each record carries:\n`classification`, `tested` + `impacted_tests`, `effects_added`/`effects_removed`,\n`dropped_cleanup`, `modeled_kinds`, per-function `verdict`, and `reason`.\n`skipped[]` lists changed files that did not gate (no grammar) \u2014 mention them\nin your summary so coverage is honest."
}