Saphan StudioDocs
Reference/Command reference

saphan merge

Conflict-probe and land a gated stream in one serialized engine act

saphan merge

Conflict-probe and land a gated stream in one serialized engine act

saphan merge <stream> [flags]

Merge one gated stream's branch into its base, engine-led: the §3.2 preconditions are VERIFIED read-only before git is touched (stream at gated:accept or ready-to-merge, merge gate legal, branch exists, base checked out and clean, not already merged, base not diverged from origin); any failure is a named refusal with a remediation line and NOTHING is landed. After those checks, the engine materializes the current branch+trunk pair in a detached scratch worktree and runs git merge there with NO suite. A conflict refuses and names the unmerged paths; a clean probe lands in the same serialized engine act. Advisory verify-union records are never merge inputs.

The merge message is composed from the record (merge-message-v1) and reaches git via an -F file — byte-exact, blank lines included — then the merge·ready-to-merge gate row is recorded (unless the human already recorded it) and the merge commit's parsed trailers print as proof-of-done.

The human invoking this verb IS the merge act (§1.1): --actor names them, the engine executes mechanically, and no push path exists (§1.7).

saphan dry-run merge prints the ordinary-precondition preview and composed message, but does not run the ephemeral conflict probe or land. The real act performs both. The paste-ready fallback line is the manual path if the operator prefers their own terminal.

Options

OptionTypeDefaultDescription
--actorstringunsetthe human merging (falls back to env SAPHAN_ACTOR, then ~/.saphan/config's identity.actor; the engine is never an actor)

Examples

Everything below this line is written by hand and is not regenerated.

The whole merge

saphan merge add-rate-limits --workspace /srv/saphan

That is the entire line. Everything else — which branch, which base, the message — comes from the record, because a merge that took its subject from the operator's memory would be a different act from the one the gates approved.

Rehearsing it first

saphan dry-run merge add-rate-limits --workspace /srv/saphan

The rehearsal checks the ordinary preconditions read-only and prints the composed message. ⚠ It does not run the conflict probe — that happens only in the real act. So a green rehearsal tells you the paperwork is in order, not that the trees agree; if you want the conflict answer in advance, ask git directly with a merge-tree probe.

What a refusal looks like, and why each one is protective

STOP — merge preconditions (§3.2), nothing was executed:
  1. review-not-accepted: the review lane is engaged but no review decision is recorded
  2. stream is at "recommendation-ready" — the merge needs an accepted stop-2 gate

Each line names one missing precondition and nothing is landed. A merge is a human act: the engine verifies, composes and executes mechanically, and there is no path by which it merges on its own initiative.

On this page