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,
/commitrefuses 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 iscommitted 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-commithook runs on the candidate and can refuse; -
prepare-commit-msgruns before the editor, andcommit-msgafter it, and can rewrite the message or refuse; -
commit.gpgSignsigns, and can ask for its passphrase; -
post-commitruns 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.