Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Committing

Final publication gates select execution resources in the original project's scope, using their final expanded shell commands. Waiting is visible and deadlines exclude contention. /job-kill ID can stop a job that holds a resource the gate needs.

Reviewed changes remain private until you agree to publish them. When a turn finishes with accepted changes and no review left pending, heph prepares the publication candidate, runs its final gates, drafts a message, and asks whether to commit. The dedicated dialog shows the branch, paths, and drafted message.

Choose Yes (y) to commit immediately with that message, without opening an editor. Choose Yes, but edit the message (e) to open the same draft in $VISUAL or $EDITOR, using the manual /commit editor handoff. Choose No (n), or press Esc, to leave the work private. No commit is offered for an empty review, a pending review, or a directory without Git. Queued prompts wait until you answer and publication finishes or is declined.

The publication lock stays held while the dialog is open and through the editor and commit. Both publication actions recheck upstream without releasing ownership: when nothing changed, the prepared candidate needs no further gate pass. Other heph publications wait, though turns and reviews can continue. Git operations outside heph can still move upstream; that requires rebuilding the candidate and rerunning its gates before committing. An overlap starts an automatic repair turn in the same session rather than guessing or asking you to start another turn.

To publish later using the editor-based workflow, type:

/commit

Heph shows preparing commit immediately and changes the input title to yellow commit pending until publication finishes or fails. Preparation, branch naming, gates, message drafting, waiting for another publication, and housekeeping run in the background; you can scroll and edit input while they run. New prompts, shell commands, and slash commands other than /help, /sidebar, and /quit wait until publication finishes. Unsent prompt or shell input is kept. The editor and Git take over the terminal only when the candidate is ready.

The work goes to the conversation's own branch, never to whatever you have checked out. The first /commit on a conversation names that branch from the work and says so:

-- publishing to new branch heph/wrap-lines

Heph integrates the conversation's accepted work onto its upstream (the tip of its branch, or of its base branch before the branch exists or while an explicit /base rebase is pending; Branches), builds a private index, reruns every due acceptance gate on the exact candidate tree, drafts a message, and opens it in your editor. Save to commit; save an empty message, as in git, to abort. The result shows as a -- line naming the branch:

-- committed 3f2a9c1 on new branch heph/wrap-lines (not checked out): Wrap long prompt lines

The gates run inside heph, each shown in the conversation as a gate call with its output, exactly as a turn's gates are: nothing scrolls past on a bare terminal. Only once they pass is the terminal handed over, to your hooks and your editor. A failing gate refuses the commit and automatically starts a new turn with the gate's name and output, asking the model to fix it. The repair uses the usual permissions, loop detection, gates, and review; your unfinished input stays in place. After reviewing the fix, heph offers to commit again; publication still requires your Yes. You can also run /commit explicitly. Cancellation and errors preparing or drafting the commit do not start a repair turn.

/commit Fix the off-by-one in the pager

commits with that message, no drafting and no editor.

The editor holds a separate publication lock, not the shared shadow lock. Other conversations can start turns and review while you edit the message. Another publication waits without a timeout. After acquiring publication ownership, heph rechecks committed upstream under the shadow lock. If upstream or the destination moved, it rebuilds the rebased candidate, releases publication ownership, reruns due gates, and reacquires ownership to check again before committing. Git still refuses the ref update if the destination branch moves after that check. Shadow lock waits also have no timeout; dead holders are recovered automatically.

After /base changes, /commit publishes the rebased state with the new base as parent and clears the pending rebase. Changes introduced by the base are included in checkout protection and final-gate selection. A rebase can publish new ancestry even when no file content changed.

Intentionally failing tests

To publish a reproducer or deliberately failing regression tests, stop any running turn and accept the changes with /review --skip-gates. Manual /review already skips gates; the flag makes that intent explicit. Then use:

/commit --skip-gates test: demonstrate the failing case

Without a message, /commit --skip-gates drafts one and opens your editor as usual. The flag must precede the message. Use -- to begin a literal message that starts with an option, for example /commit -- --skip-gates is documented. Unknown or repeated leading options are refused.

This bypasses only heph's final acceptance gates for this invocation, including when upstream movement requires rebuilding the candidate. No gate command runs and no gate-repair turn starts. Review, publication locks, conflict checks, branch-update checks, checkout protections, signing, and Git hooks still apply. Git hooks can still refuse the commit.

Progress, editor comments, and the committed result say gates skipped. The publication audit and any continuation receipt retain that policy without recording passing-gate coverage. A later /commit, automatic post-review offer, or next publication unit runs gates normally; no configuration or sticky session setting changes. Turn-level gates are unchanged, so use manual review to accept intentional failures rather than asking the model to repair them.

What goes in

The commit is the difference between the conversation's upstream and its accepted work: everything review accepted since the branch was last advanced, however many turns that spans. One /commit is one commit. The per-call history behind it stays in heph's shadow repository, so /blame still knows why each line was written, and whether you later merge, squash, or rebase the branch is your business and loses nothing heph keeps.

If the upstream moved since the last turn, heph replays the conversation's change on top of it in the private worktree first, as a rebase would. A clean result is gated as a whole before publication. An overlapping change remains private while heph automatically starts repair in the current session. The model receives the displaced private text and integrates its intent with the latest upstream. Repair edits go through permissions, acceptance gates, and review; after you accept them, heph offers publication again. It does not reuse your previous consent to publish new repairs. If the intent cannot be reconciled safely, the model should ask you a specific question.

The original accepted snapshot and pre-repair worktree are preserved. Unreviewed worktree edits still stop publication for /review, and cancellation or other commit errors do not start automatic repair. A gate bypass applies only to its original invocation; repair and the next automatic offer run gates normally.

This does not yet implement the full always-current branch-and-base guarantee. Once a publication branch exists, ordinary synchronization still selects its tip rather than automatically rebasing its published history onto an advancing base.

Working in several commits

Ask for several commits, separate commits, or one commit per step when you want separate review-and-publication cycles. The agent is instructed to implement only the next independently reviewable unit, including its tests and documentation, then stop for gates, review, and the commit offer. Manual git commit calls inside its private worktree do not satisfy this request.

The agent uses submit_for_review to hand over the current unit's title, summary, proposed commit message, and ordered remaining-work list. A successful handoff stops generation, including later calls in the same response. It does not approve publication. Heph takes the unit through the usual gates, review, and commit dialog, using the proposed message instead of requesting a separate draft. /commit without a message still opens the editor; an explicit message overrides the proposal.

Once the sequence is active, an ordinary response after edits or review feedback is not a completion handoff. Heph continues work on the current unit before opening automatic review. Once the submitted unit is fully approved, heph goes straight to preparing the commit offer; you do not need to ask what is left. Verification-only repairs can re-submit accepted work without manufacturing an edit or repeating review. Partial or interrupted sequence work does not automatically offer a commit. You can still stop generation and use /review or /commit explicitly.

Only verified successful publication unlocks automatic continuation of the next remaining unit. Acceptance alone is not publication. A declined offer, cancelled commit, failed gate, or aborted Git command leaves the sequence paused; /commit can publish it later. Review and gate repairs stay in the current unit. The agent submits each subsequent unit separately, with an empty remaining-work list for the final unit. Queued developer input takes precedence over automatic continuation and receives the unit's scope and verified receipt.

/sequence shows the active unit's phase and remaining work. /sequence cancel stops sequencing without discarding accepted changes. Both wait for an active turn, review, or publication to finish. To combine units or change the sequence, make that decision explicit, or cancel sequencing and continue normally.

The original submission and publication receipt survive restarts. Reopening a conversation resumes a published unit's unstarted continuation at most once. A continuation that already started and was interrupted stays paused for your instructions; it is not replayed automatically. Navigation and forks do not inherit an unrelated unit. Changed branch/base configuration or a target branch that no longer contains the receipt cannot automatically resume it.

The agent must also ask about earlier unpublished work before starting the sequence. The handoff refuses to include carried accepted work unless include_unpublished records an explicit inclusion decision. One /commit still includes all accepted work since the last publication, not just the latest unit. Before any tool handoff establishes a sequence, the instruction-based stop-and-publish workflow still applies, but there is no automatic continuation.

Your checkout

What you have checked out decides only one thing: whether your checkout moves with the commit.

  • You have the conversation's branch checked out. The commit moves the branch under you, so your index and files follow: the committed paths are brought up to the new commit. Because of that, /commit refuses when one of those paths is staged, or differs in your checkout from the branch, and says which; commit, stash, or move that edit first. The result line is committed 3f2a9c1 on heph/wrap-lines: ....

  • Anything else is checked out (another branch, the base branch, a detached HEAD). Your checkout is not read and not written; dirty files, even in the same paths, neither refuse the commit nor change. The result line says (not checked out).

Either way your other files, staged or not, are neither committed nor disturbed.

/commit also refuses while the conversation's worktree holds anything no review has decided: a review you put off or stopped partway, or files you changed there by hand. Only what a review accepted is published. /review shows exactly what is waiting and lets you decide it (Review); then /commit again.

How the commit is made

The commit is made with git's own plumbing in your repository, with the terminal handed back, so it looks exactly like one of yours:

  • your pre-commit hook runs on the candidate and can refuse;

  • prepare-commit-msg runs before the editor, and commit-msg after it, and can rewrite the message or refuse;

  • commit.gpgSign signs, and can ask for its passphrase;

  • post-commit runs once the branch has moved.

Your identity and configuration apply. Your HEAD, index, and checkout are not touched except as above, and your repository receives nothing but the commit's objects, the branch update, and its reflog entry (heph: /commit on ref <name>). The branch moves only if it still points where the candidate was built; if something moved it in between, nothing is committed and heph says to retry. /commit needs git 2.36 or newer and says so on an older one.

[git] attribution adds a trailer, placed where your trailer.* configuration says and never twice; by default there is none (Git).

The draft is written by the commit-message model from the diff, your last twenty commit messages for style, and the reasons the model gave for its changes during the turn. The post-review dialog shows it before y commits it as drafted; choose e to edit it first without preparing or drafting again.

Final gates and hooks run in the private worktree with the configured command environment, including the project-wide shared CARGO_TARGET_DIR. Publication is serialized across heph processes.

Existing conversations

The first turn on a conversation created by an older heph build migrates it to private workspace semantics. Old snapshots included the whole dirty checkout, so heph does not adopt the latest snapshot wholesale. It walks that conversation's turns and replays the before/after snapshots of turns that recorded applied work. If committed upstream overlaps legacy work, upstream remains in the reconstructed base and the displaced legacy text is reported instead of silently discarded. Before replacing any files, heph also commits the exact old worktree under a durable rescue ref. Whatever it holds beyond that conversation's last snapshot is carried onto the reconstruction and shown in the migration turn as unreviewed changes, so its review is the point where stale or unrelated hunks are separated from work to keep.

/commit refuses until this first migration turn completes; a resumed old pending review remains legacy, so send one subsequent turn before publishing it.

Legacy accepted files may still be present unstaged in your checkout. With the conversation's branch checked out, /commit can consume one when its bytes, file type, link target, and executable mode exactly match the private candidate.

What is coming

/push and opening a pull request from heph; the git_commit tool, which lets the model queue the commit during the turn, so "add the feature and commit it" is one prompt; and heph exec --commit. See What Is Not Here Yet.