Files
Hop/skills/hop/references/protocol.md
T
Hop 7139b9e1a7 Automatically push every accepted Hop transition
Hop-State: A_06FN6FF8HFSFD9ANGK6BY4G
Hop-Proposal: R_06FN6FDTK9G17RXFFT82ZYR
Hop-Task: T_06FN6CFVXVVAP1KZAJ2X62R
Hop-Attempt: AT_06FN6CFVXTRZ8ZDG28QR5Z0
2026-07-11 15:13:13 -07:00

223 lines
9.8 KiB
Markdown

# Hop agent protocol
## State graph
```text
A accepted
├─ P prompt, persisted before project effects
│ └─ C checkpoint
│ └─ R proposal
└─ P independent prompt
A + R ──land──> A next accepted state
```
State prefixes:
| Prefix | Kind | Meaning |
|---|---|---|
| `A_` | accepted | Canonical project revision |
| `P_` | prompt | Exact instruction and pre-effect context |
| `C_` | checkpoint | Immutable workspace progress |
| `R_` | proposal | Frozen candidate result |
| `F_` | failed | Durable failed execution or validation state |
| `X_` | cancelled | Durable cancelled state |
Prompt, checkpoint, and proposal states may reference identical Git trees while remaining distinct causal occurrences.
## Environment contract
| Variable | Purpose |
|---|---|
| `HOP_ROOT` | Canonical project root containing `.hop/hop.db` |
| `HOP_STATE_ID` | Prompt state authorizing the current instruction |
| `HOP_TASK_ID` | Logical task grouping related prompts and attempts |
| `HOP_ATTEMPT_ID` | Current agent approach/run |
| `HOP_WORKSPACE` | Only directory the agent may modify |
| `HOP_AGENT` | Optional runtime name used by `hop begin` when `--agent` is omitted |
Interactive agents may begin without these variables. `hop begin` returns the
equivalent IDs and workspace. Integrations should identify themselves with
`HOP_AGENT` or `--agent` and pass a stable `--session` value when available.
That session binds later messages to unfinished work; without it, each
invocation begins independent work. The Codex adapter uses `CODEX_THREAD_ID` as
the default session and `codex` as the default runtime name. Follow-ups before
acceptance continue the attempt; the first prompt after acceptance starts a
fresh task and attempt at the latest accepted state.
## Command contract
### Human or controller
```bash
hop init
hop start --agent <name> "<exact initial prompt>"
hop env <prompt-state>
hop prompt --from <state> "<exact follow-up prompt>"
hop accept <proposal> -- <final validation command>
hop sync
hop undo
```
`hop start` creates the task, attempt, prompt state, and detached workspace before returning. The controller may deliver the prompt only after exit `0`.
`hop prompt` captures a checkpoint of current workspace effects before creating the follow-up prompt state.
### Agent
POSIX shell:
```bash
hop begin --heredoc <<'HOP_PROMPT_EOF'
<exact current user message>
HOP_PROMPT_EOF
```
PowerShell:
```powershell
$hopPrompt = @'
<exact current user message>
'@
$hopPrompt | hop begin --heredoc
```
Then continue in the returned workspace:
```bash
hop state "$HOP_STATE_ID" --json
hop status --json
hop check "$HOP_STATE_ID" -- <command>
hop propose --summary "<summary>" "$HOP_STATE_ID"
hop land <proposal-state> -- <final validation command>
hop refresh <proposal-state>
hop push
```
An adapter may set `HOP_AGENT=<runtime>` or pass `--agent <runtime>`. If it has
a stable conversation/run identifier, it should also pass `--session <id>` on
every `hop begin`. Codex normally needs neither explicit flag because
`CODEX_THREAD_ID` supplies its session adapter automatically.
`hop check` snapshots the attempt and runs the command in a detached worktree materialized from that exact checkpoint. Edits made concurrently in the live workspace do not change the tested tree.
`hop propose` freezes the current nonignored workspace tree. Later workspace edits cannot change the proposal.
The initial task prompt authorizes the agent to run `hop land` after successful
validation; a second user approval is not required. Manual review is an opt-in
mode: stop at the proposal only when the user explicitly asks to review or
approve before acceptance. Validation failure, visible-root divergence,
unresolved product ambiguity, or newly required destructive/external scope
stops automatic acceptance. Path overlap and a stale accepted head do not:
Hop merges, retries, or prepares agent reconciliation.
`hop land` is the interactive working-root operation. It performs a real Git
three-way content merge, so compatible edits in the same file and identical
changes compose automatically. It validates and advances accepted state, then
safely materializes that tree into the selected visible project root. The root
must still match an accepted Hop ancestor, and ignored or untracked destination
collisions block before acceptance. Materialization uses a disposable index
and never moves HEAD, the active branch, or the user's real index.
When the three-way merge has genuine unresolved conflicts, `hop land` returns
exit `20` and automatically prepares a reconciliation prompt in the original
task but a fresh isolated attempt/workspace. Its JSON includes
`reconciliation.prompt`, `workspace`,
`conflicts`, and the proposal/current accepted states. The agent adopts that
prompt/workspace, resolves both intents, checks, proposes, and lands again.
Structural, binary, delete/rename, mode, and symlink conflicts may have no text
markers, so the agent must inspect both returned input states. Hop requires a
successful `hop check` on the resolved tree before reproposal. The user is not
asked to coordinate ordinary code conflicts. `hop refresh` is the idempotent
explicit form of the same preparation step.
`hop accept` is the controller/kernel operation. It advances SQLite and
`refs/hop/accepted` but intentionally leaves the visible root untouched.
`hop sync` safely catches a stale accepted-ancestor root up to the current
accepted state, including projects created with older Hop builds.
After every successful `hop land` or `hop accept`, Hop automatically performs a
non-forced push of the accepted commit when the active branch has an
unambiguous upstream. No remote is a normal local-only mode. Push failure does
not undo acceptance; `hop push` retries the current accepted commit. Agents
must never replace a non-fast-forward rejection with a force-push.
`hop begin` is the interactive-agent entry point. It initializes Hop when
necessary and captures the current message before the agent performs project
work. Runtime adapters identify themselves through `HOP_AGENT` or `--agent`
and use `--session` to supply a stable conversation/run key. A later
`hop begin` with the same session checkpoints the prior workspace before
appending a follow-up while that work remains unfinished. Reconciliation
transfers the session to its fresh attempt. After a proposal is accepted, the
next `hop begin` starts from the latest accepted state and never reopens the
completed workspace. Codex Desktop supplies `CODEX_THREAD_ID` as its default
session key, so its adapter does not need to add `--session` explicitly.
Pass the original message to `hop begin` without model-side redaction. Hop's
sanitizer replaces detected credential values before any durable write and
returns only typed redaction counts. Do not place the value in any later
command, summary, output, or source file.
## Exit codes
| Code | Meaning |
|---:|---|
| `0` | Success |
| `1` | Git, SQLite, filesystem, or internal error |
| `2` | Invalid CLI usage |
| `20` | Genuine three-way merge conflict; reconciliation workspace prepared |
| `21` | Accepted or attempt head changed during compare-and-swap |
| `22` | Validation command failed |
| `23` | Visible project root diverged or contains an overwrite collision |
A failed `hop check` or final landing check persists its evidence. A blocked or failed landing does not advance accepted state.
## Capture modes
### Interactive agent skill
The user types normally in their agent interface. The Hop skill makes
`hop begin` its first project action and then directs every operation into the
returned workspace. This is a pre-project-effect boundary: the runtime has
already received the prompt, but no repository inspection, command, or
modification may precede the durable prompt state. Codex Desktop is one such
adapter; it provides session continuity through `CODEX_THREAD_ID`.
### Controller-grade pre-delivery capture
```bash
hop init
hop start --agent <runtime> "Add password reset emails"
```
Use the returned workspace and environment to launch the agent. For example, conceptually:
```bash
eval "$(hop env P_...)"
<agent-command> "<the same exact prompt>"
```
The exact agent command is harness-specific. This stronger mode stores the
prompt before the model receives it. A future trusted prompt-submission hook can
provide the same boundary inside compatible agent clients.
## Failure handling
- **Missing Hop environment:** run `hop begin` before project work and use the returned state and workspace.
- **Check failure:** fix the live workspace, checkpoint/check again, then create a new proposal.
- **Review-only request:** preserve and report the proposal without landing it.
- **Frozen proposal needs changes:** record a follow-up prompt; never mutate the stored proposal.
- **Merge conflict on landing:** continue automatically in the returned
reconciliation prompt/workspace; inspect both inputs, resolve textual and
structural conflicts, validate, propose, and land again. Stop only for
product ambiguity, not ordinary textual overlap.
- **Visible-root conflict:** preserve the proposal and the user's files. Do not substitute controller-only `hop accept`; resolve or capture the visible changes, then land again.
- **Controller-accepted root is stale:** run `hop sync`; it succeeds only from an accepted ancestor and never overwrites divergence.
- **Automatic push warning:** retry once with `hop push`; preserve a diverged remote and never force-push it.
- **Ref inconsistency:** run `hop doctor`; use `hop doctor --repair` only outside final validation.
- **Secrets:** Hop redacts high-confidence provider keys plus contextual tokens,
passwords, private keys, authorization headers, and credential-bearing URLs
before durable storage. It also sanitizes recorded check commands/output and
proposal summaries. Detection is defense in depth, not a substitute for
environment variables or a secret manager. Never repeat a detected secret.