Reconcile Gitea distribution with current alpha behavior and release tooling

Hop-State: A_06FN55REVAR7VQG4BWJBCD8
Hop-Proposal: R_06FN55QTEWKH16NSR59YJYG
Hop-Task: T_06FN3MBF98GWD4NA5PA1RWG
Hop-Attempt: AT_06FN55BQ80H2S8WHNDD24G0
This commit is contained in:
Hop
2026-07-11 12:10:59 -07:00
parent 23a4891099
commit de99aad4d4
28 changed files with 1565 additions and 21 deletions
+65
View File
@@ -0,0 +1,65 @@
# Codex Desktop and agent workflow
## Codex Desktop
Users type into Codex normally. The installed skill makes prompt capture the
agent's first repository action:
```bash
hop begin --agent codex --heredoc <<'HOP_PROMPT_EOF'
<exact visible user message>
HOP_PROMPT_EOF
```
The agent adopts the returned `HOP_STATE_ID`, `HOP_TASK_ID`,
`HOP_ATTEMPT_ID`, and `HOP_WORKSPACE`, then confines reads, commands, edits, and
tests to that workspace.
The normal lifecycle is:
```bash
hop check P_... -- go test ./...
hop propose --summary "Implemented the requested behavior" P_...
hop land R_... -- go test ./...
```
No second landing authorization is requested unless the user explicitly asks
for review-first behavior.
## Follow-up messages
A later `hop begin` with the same Codex task session checkpoints existing
workspace effects, appends a new prompt state, and continues the same attempt.
The user does not carry state IDs between messages.
## Controller-grade capture
A harness that can persist before delivering a prompt to the model can use:
```bash
hop init
hop start --agent my-agent --heredoc <<'HOP_PROMPT_EOF'
Add password reset emails
HOP_PROMPT_EOF
eval "$(hop env P_...)"
```
Only deliver the prompt after `hop start` exits successfully. Controller-managed
follow-ups use:
```bash
hop prompt --from P_... --heredoc
```
This provides a stronger pre-delivery boundary than a Desktop skill, which can
only guarantee capture before project effects.
## Agent rules
- Never edit the canonical project root directly.
- Never mutate a frozen proposal.
- Do not bypass `hop land` with Git reset, checkout, worktree, or manual copying.
- Run validation against immutable checkpoints and the final integrated tree.
- Let Hop merge compatible concurrent work.
- Resolve genuine reconciliation workspaces without asking the user to perform
source-control mechanics, unless the underlying product intents are ambiguous.
+54
View File
@@ -0,0 +1,54 @@
# Architecture
Hop uses Git under the hood, but it is not merely a directory of metadata files
inside `.git`.
## Git responsibilities
Git provides:
- content-addressed blobs and trees;
- synthetic commits for immutable snapshots;
- detached worktrees for attempt isolation;
- three-way merge behavior;
- diffs and path inspection; and
- interoperability with existing repositories.
Hop never needs to move the user's active branch or rewrite the real index.
Private objects are pinned beneath `refs/hop/states/*`; accepted history is
mirrored at `refs/hop/accepted`.
## Hop responsibilities
`.hop/hop.db` is a SQLite WAL database containing:
- prompt/task/attempt identity;
- typed state edges and accepted lineage;
- evidence tied to exact source trees;
- session heads for Desktop follow-ups;
- materialized-root state; and
- immutable audit events.
## Project layout
```text
.hop/
├── hop.db
├── workspaces/
├── checks/
├── integration/
└── *.lock
```
`.hop/` is added to `.git/info/exclude`, not the public `.gitignore`. Hop refuses
initialization when `.hop` is already tracked as user-owned project content.
## Acceptance consistency
Acceptance is serialized and compare-and-swapped. SQLite is authoritative;
derived Git refs can be repaired by `hop doctor --repair`. Desktop landing also
tracks which accepted state is physically visible, allowing safe catch-up with
`hop sync` without treating a divergent folder as disposable.
For the full product direction, read the
[product blueprint](https://githop.xyz/hop/hop/src/branch/main/docs/product-blueprint.md).
+64
View File
@@ -0,0 +1,64 @@
# CLI reference
Add `--json` anywhere in a command for machine-readable output.
## Project and prompt lifecycle
| Command | Purpose |
|---|---|
| `hop init [path]` | Initialize Hop without moving the Git branch or index |
| `hop begin ...` | Desktop entry point: initialize if needed, capture prompt, continue session |
| `hop prompt ...` | Controller-managed prompt or follow-up capture |
| `hop checkpoint STATE` | Freeze current attempt progress |
| `hop check STATE -- COMMAND...` | Validate an immutable checkpoint |
| `hop propose [--summary TEXT] STATE` | Freeze a candidate proposal |
| `hop land PROPOSAL [-- COMMAND...]` | Accept and synchronize the visible root |
| `hop refresh PROPOSAL` | Explicitly prepare/reuse conflict reconciliation |
`hop start` aliases `hop prompt`; `hop reconcile` aliases `hop refresh`.
## Controller and synchronization commands
| Command | Purpose |
|---|---|
| `hop accept PROPOSAL [-- COMMAND...]` | Accept internally without changing visible files |
| `hop sync` | Materialize the current accepted tree from a safe accepted ancestor |
| `hop undo` | Create a forward-only acceptance that restores the previous accepted tree |
| `hop doctor [--repair]` | Validate database/object/ref consistency |
## Inspection
| Command | Purpose |
|---|---|
| `hop status` | Accepted head, attempts, and visible-root status |
| `hop graph` | State graph |
| `hop state STATE` | One state and its provenance |
| `hop env STATE` | Shell exports for an attempt |
| `hop diff STATE` | Diff represented by a state |
| `hop history` | Accepted lineage |
| `hop version` | Installed version |
## Skill distribution
```bash
hop skill install [--path SKILLS_DIR] [--force]
hop skill print
```
Without `--path`, the skill installs under
`${CODEX_HOME:-~/.codex}/skills/hop`.
## Exit codes
| Code | Meaning |
|---:|---|
| `0` | Success |
| `1` | Git, SQLite, filesystem, or internal failure |
| `2` | Invalid usage |
| `20` | Merge conflict; reconciliation workspace was prepared |
| `21` | Attempt or accepted head changed during compare-and-swap |
| `22` | Validation command failed |
| `23` | Visible-root divergence or overwrite collision |
Exit `20` is a continuation signal for an agent, not a request for the user to
manually merge files.
+58
View File
@@ -0,0 +1,58 @@
# Core concepts
Hop versions intent and source together. Git remains the content store; Hop adds
the causal state graph that explains which instruction produced which result.
## States
| Prefix | State | Meaning |
|---|---|---|
| `A_` | Accepted | Canonical Hop project revision |
| `P_` | Prompt | Durable instruction and pre-effect context |
| `C_` | Checkpoint | Immutable snapshot of attempt progress |
| `R_` | Proposal | Frozen candidate result |
| `F_` | Failed | Durable failed execution or validation result |
| `X_` | Cancelled | Terminal cancelled result |
Two states can reference the same Git tree and still be distinct occurrences.
For example, a prompt and checkpoint may contain identical files but represent
different moments and causal roles.
## Task
A task groups the prompts and attempts pursuing one user outcome. Follow-up
messages in the same Codex task stay connected automatically through
`CODEX_THREAD_ID`.
## Attempt and workspace
An attempt is one agent approach. Each attempt has a detached Git worktree under
`.hop/workspaces/`. Agents edit there instead of racing in the visible project
root.
## Evidence
`hop check` snapshots the workspace and runs validation against that immutable
tree. Evidence stores the command, redacted output, exit code, and exact tree
hash.
## Proposal
`hop propose` freezes a candidate tree. Later workspace edits cannot mutate the
proposal.
## Landing
`hop land` composes the proposal onto the current accepted state, runs optional
final-tree validation, advances accepted history with compare-and-swap, and
safely materializes the result into the visible project directory.
`hop accept` is lower-level controller behavior: it advances internal accepted
state but intentionally leaves the visible folder unchanged.
## Visible root
The visible root is the project directory selected in Codex. Hop only
materializes into it when it still matches an accepted Hop ancestor. Untracked,
ignored, staged, or ordinary file divergence that could be overwritten causes a
fail-closed error.
+60
View File
@@ -0,0 +1,60 @@
# Getting started
## Use Hop from Codex Desktop
1. [Install Hop](Installation).
2. Restart Codex Desktop if it was already open.
3. Select an existing Git project as the Codex working directory.
4. Ask Codex to make a normal change.
That is the full user workflow. Do not manually create `.hop`, route the prompt
through a terminal, or tell Codex to work inside `.hop/workspaces`. The Hop skill
does that coordination for the agent.
The skill is eligible for implicit activation on every repository task. Mention
`$hop` in the task if you want deterministic explicit activation.
## What happens on the first task
Before reading or changing project files, the agent runs `hop begin`. Hop then:
- initializes local state without moving the Git branch or index;
- stores the prompt after redacting detected credentials;
- creates an isolated attempt workspace;
- returns the state and workspace to the agent; and
- keeps all project-changing work inside that workspace.
The agent validates, proposes, and lands the result. A successful `hop land`
updates the visible project folder to the accepted tree.
## Confirm the result
From the selected project directory:
```bash
hop status
hop history
hop doctor
```
A normal Desktop result reports `Root: synchronized`.
## Ask for review before landing
Automatic landing is the default because the original task authorizes the
local code change. To stop at a proposal, say one of the following in the task:
- `review first`
- `proposal only`
- `do not land`
## Use another agent runtime
Install the embedded skill into that runtime's skills directory:
```bash
hop skill install --path /path/to/agent/skills --force
```
Controllers that can persist a prompt before model delivery should use
`hop start`, `hop env`, and `hop prompt`; see [Agent workflow](Agent-Workflow).
+45
View File
@@ -0,0 +1,45 @@
# Hop documentation
Hop is prompt-native version control for coding agents. It stores each prompt
as an immutable project state, gives agent work an isolated workspace, validates
the exact tree being accepted, and safely materializes accepted results into the
visible project folder.
## Start here
- [Installation](Installation)
- [Getting started](Getting-Started)
- [Core concepts](Core-Concepts)
- [Codex Desktop and agent workflow](Agent-Workflow)
- [Parallel agents and conflict resolution](Parallel-Agents-and-Conflicts)
## Reference and operations
- [CLI reference](CLI-Reference)
- [Architecture](Architecture)
- [Security and privacy](Security-and-Privacy)
- [Troubleshooting](Troubleshooting)
- [Upgrading and uninstalling](Upgrading-and-Uninstalling)
- [Release checklist](Release-Checklist)
## Thirty-second install
macOS or Linux:
```bash
curl -fsSL https://githop.xyz/hop/hop/raw/branch/main/scripts/install.sh | sh
```
Windows PowerShell:
```powershell
irm https://githop.xyz/hop/hop/raw/branch/main/scripts/install.ps1 | iex
```
Restart Codex Desktop, open a Git project, and ask Codex to work normally. The
installed skill activates Hop before the agent inspects or changes the project;
there is no separate prompt router and no required manual `hop init` step.
Hop is currently an alpha. Keep Git history and normal backups, read release
notes before upgrading, and report unexpected behavior with `hop doctor` output
after removing private paths or data.
+99
View File
@@ -0,0 +1,99 @@
# Installation
Packaged binaries are the recommended installation. They need Git 2.40 or
newer; they do not need a local Go toolchain.
## macOS and Linux
```bash
curl -fsSL https://githop.xyz/hop/hop/raw/branch/main/scripts/install.sh | sh
```
The installer:
1. detects macOS/Linux and `amd64`/`arm64`;
2. downloads the matching archive from the latest Gitea Release;
3. downloads `checksums.txt` and verifies SHA-256 before extraction;
4. installs the CLI to `~/.local/bin/hop`;
5. adds `~/.local/bin` to `.zprofile` or `.profile` when necessary; and
6. runs `hop skill install --force` for Codex.
Review before execution:
```bash
curl -fsSLO https://githop.xyz/hop/hop/raw/branch/main/scripts/install.sh
less install.sh
sh install.sh
```
Installer options are environment variables:
| Variable | Default | Purpose |
|---|---|---|
| `HOP_VERSION` | `latest` | Release tag such as `v0.1.0` |
| `HOP_INSTALL_DIR` | `~/.local/bin` | Binary destination |
| `HOP_INSTALL_SKILL` | `1` | Set to `0` to skip Codex skill installation |
| `HOP_MODIFY_PATH` | `1` | Set to `0` to leave shell profiles unchanged |
| `HOP_GITEA_URL` | `https://githop.xyz` | Gitea instance base URL |
| `HOP_REPOSITORY` | `hop/hop` | Alternate Gitea owner/repository |
Example:
```bash
HOP_VERSION=v0.1.0 HOP_INSTALL_DIR="$HOME/bin" sh install.sh
```
## Windows
In PowerShell as your normal user:
```powershell
irm https://githop.xyz/hop/hop/raw/branch/main/scripts/install.ps1 | iex
```
The script verifies the Windows archive, installs to
`%LOCALAPPDATA%\Programs\Hop`, updates the user PATH, and installs the Codex
skill. To pin a version after downloading the script:
```powershell
.\install.ps1 -Version v0.1.0
```
Use `-SkipSkill` only when another agent runtime will receive the skill. Use
`-SkipPath` when another tool manages your PATH.
## Go install
With Go 1.26 or newer:
```bash
go install githop.xyz/hop/hop/cmd/hop@latest
hop skill install --force
```
Put `$(go env GOPATH)/bin` on PATH if `hop` is not found.
## Build from source
```bash
git clone https://githop.xyz/hop/hop.git
cd hop
go test ./...
go build -trimpath -o hop ./cmd/hop
mkdir -p "$HOME/.local/bin"
install -m 755 hop "$HOME/.local/bin/hop"
"$HOME/.local/bin/hop" skill install --force
```
Source builds are intended for contributors and as a pre-release fallback.
## Verify
```bash
hop version
hop help
git --version
```
If Codex Desktop was open during installation, restart it. See
[Getting started](Getting-Started) next.
+49
View File
@@ -0,0 +1,49 @@
# Parallel agents and conflict resolution
Each independent prompt starts from an accepted state and receives its own
worktree. Multiple agents can therefore read, edit, and test the same codebase
without sharing a mutable working directory.
## Compatible work
Hop uses Git's real three-way content merge:
- disjoint files compose automatically;
- independent hunks in the same file compose automatically;
- identical same-file changes coalesce; and
- compatible rename/content and mode/content changes can compose.
Before acceptance, Hop validates the exact integrated tree rather than trusting
tests run only against an agent's stale starting point.
## Genuine conflicts
When Git cannot compose both intents, `hop land` exits with code `20` and
creates a fresh reconciliation attempt. The response includes:
- a reconciliation prompt state;
- a new isolated workspace;
- current accepted and proposed inputs; and
- conflict candidate paths.
The agent switches to that workspace, preserves both compatible intents,
resolves the conflict, runs `hop check`, creates a new proposal, and lands again.
Hop requires successful checked evidence before a reconciliation proposal can
be frozen.
Text conflicts usually contain diff3 markers. Delete/rename, binary, symlink,
mode, and directory conflicts may not, so the agent must inspect both input
states rather than assuming the provisional tree is resolved.
## What still needs a person
The agent should stop only when the source conflict exposes a real product
decision—for example, two prompts require mutually exclusive API behavior and
neither recorded intent determines the right result. Ordinary code overlap is
not user work.
## Visible-root safety
The selected project directory remains at the last accepted state while
reconciliation is underway. If that folder has user-owned divergence, Hop does
not overwrite it; `hop land` exits with code `23` and reports the paths.
+83
View File
@@ -0,0 +1,83 @@
# Release checklist
Hop releases are built on `githop.xyz` by Gitea Actions and uploaded by
GoReleaser as draft Gitea Releases.
The examples assume the canonical repository is `githop.xyz/hop/hop`.
## One-time Gitea setup
- Create the `hop/hop` repository and set its default branch to `main`.
- Configure `origin` as `https://githop.xyz/hop/hop.git`.
- Run a currently patched Gitea 1.26.x or newer, enable Actions, and enable
Actions for the repository. Hop's least-privilege workflow uses the 1.26 job
token permission model.
- Register trusted, isolated `ubuntu-latest` and `windows-latest` act runners.
- Allow the repository job token `code: read` and `releases: write`.
- Ensure `${{ secrets.GITEA_TOKEN }}` can create releases in this repository.
- Keep third-party Actions pinned to reviewed commit SHAs. When upgrading
GoReleaser, update its version and both hard-coded Linux archive checksums in
`.gitea/workflows/release.yml` from the official release checksum file.
- Permit release attachment MIME types for `.tar.gz`, `.zip`, and `.txt` in
Gitea's `[attachment] ALLOWED_TYPES` configuration.
- Enable the repository wiki, then push the files in `wiki/` to its wiki Git
repository.
## Public-launch gates
- Choose and add a `LICENSE`. The release workflow intentionally fails without
one; this is a product/legal decision, not a build default.
- Add `SECURITY.md` with a monitored private disclosure address.
- Create an offline-controlled release-signing key, publish its public key, and
add detached signing for `checksums.txt` before general availability.
- Confirm the `githop.xyz/hop/hop` Go import path serves valid `go-import`
metadata.
- Back up the Gitea database, repositories, release attachments, and Actions
secrets.
## Validate before tagging
```bash
go test -race ./...
go vet ./...
sh -n scripts/install.sh
goreleaser check
goreleaser release --snapshot --clean
```
Inspect `dist/` and test at least one archive on each operating system family.
Confirm `hop version` reports the snapshot/tag-injected version and
`hop skill install --force` installs usable skill files.
## Create a release
1. Update release notes and the expected version.
2. Create a signed semantic-version tag such as `v0.1.0-alpha.1`.
3. Push the tag to `githop.xyz`.
4. The `.gitea/workflows/release.yml` workflow runs race tests and vet, builds
six platform archives, generates `checksums.txt`, and uploads a draft.
5. Download the draft assets and independently verify checksums, version output,
skill installation, and a disposable Hop project.
6. Publish the Gitea draft only after those checks pass.
7. Test both one-command installers against the now-published release.
## Expected assets
```text
hop_darwin_amd64.tar.gz
hop_darwin_arm64.tar.gz
hop_linux_amd64.tar.gz
hop_linux_arm64.tar.gz
hop_windows_amd64.zip
hop_windows_arm64.zip
checksums.txt
```
## After the first release
- Create a Gitea-hosted Homebrew tap/cask fed by immutable release URLs and
checksums; do not publish placeholder hashes.
- Add Windows package-manager metadata only after the Windows artifact has been
tested on a real signed build.
- Establish release retention, package cleanup, rollback, and incident-response
procedures for the custom Gitea instance.
+52
View File
@@ -0,0 +1,52 @@
# Security and privacy
## Local data
Hop stores state in the project under `.hop/`. Prompt text, source trees,
commands, and check output are local unless the project or its filesystem is
copied elsewhere. SQLite data is not encrypted at rest.
`.hop/` is excluded through `.git/info/exclude`, so ordinary Git operations do
not publish it. Initialization refuses to hide a `.hop` directory that the
project already tracks.
## Credential redaction
Before persistence, Hop redacts high-confidence provider keys, contextual
tokens/passwords, private keys, authorization headers, and credential-bearing
URLs. The same sanitizer is applied to proposal summaries and recorded check
commands/output.
Detection is defense in depth, not a guarantee. Use environment variables or a
secret manager. Rotate any real credential pasted into any agent prompt even
when Hop reports a redaction.
## Installer and release integrity
Packaged installers download `checksums.txt` from the same published Gitea
Release and verify the selected archive before extraction. Gitea Releases are
created as drafts, after race tests, vetting, and cross-platform builds, then
must be reviewed before publication.
For stronger provenance before general availability, the release owner should
sign `checksums.txt` with an offline-controlled release key and publish the
public key independently. Checksum signing is listed as a launch gate in the
[release checklist](Release-Checklist).
## Runner trust
Release jobs execute on Gitea act runners. Only trusted, isolated runners should
receive release tags or release tokens. Do not run secret-bearing release jobs
from unreviewed fork pull requests.
## Filesystem safety
Hop does not use `reset --hard`, move the active branch, or write the user's
real Git index. Visible-root synchronization fails closed when files, ignored
destinations, or staged state could be overwritten.
## Reporting a vulnerability
Before the public security contact is configured, disclose vulnerabilities
privately to the repository owner rather than opening a public issue. Add a
`SECURITY.md` with the final contact before the first public release.
+77
View File
@@ -0,0 +1,77 @@
# Troubleshooting
## `hop: command not found`
Open a new terminal after installation. Confirm the install directory is on
PATH:
```bash
command -v hop
printf '%s\n' "$PATH"
```
The default Unix location is `~/.local/bin`. On Windows it is
`%LOCALAPPDATA%\Programs\Hop`.
## Codex does not activate Hop
```bash
hop skill install --force
```
Restart Codex Desktop. Mention `$hop` in a task as a deterministic activation
fallback.
## The installer cannot find a release
Only published Gitea Releases appear through the public releases API. Drafts
and an instance that is not live will return an error; published prereleases
are supported. Pin an existing tag with `HOP_VERSION`, or use the source build
until the first release is published.
## Git is too old
Hop requires Git 2.40 or newer for structured, explicit-base `merge-tree`
behavior:
```bash
git --version
```
Upgrade Git through the operating system package manager before retrying.
## Exit code 20: merge conflict
The agent should adopt the returned reconciliation prompt and workspace,
resolve both intents, run `hop check`, propose, and land again. Users should not
need to perform ordinary source merges.
## Exit code 22: validation failed
The accepted head did not advance. Inspect the recorded output, fix the attempt
workspace, and rerun the check.
## Exit code 23 or `Root: diverged`
Hop found visible files or index state it will not overwrite. Preserve those
changes. Capture them as a new Hop task or resolve them intentionally, then
retry `hop land`. Do not bypass this with `hop accept` in Desktop workflows.
## Internal ref or object warning
```bash
hop doctor
```
If SQLite is healthy and the report specifically identifies derived refs:
```bash
hop doctor --repair
```
Do not repair while a final validation command is running.
## A secret was pasted
Rotate it. Hop redaction reduces durable exposure but cannot prove that every
credential format, attachment, agent log, or external system omitted the value.
+70
View File
@@ -0,0 +1,70 @@
# Upgrading and uninstalling
## Upgrade packaged installations
Rerun the installer. It replaces the binary and refreshes the embedded skill:
```bash
curl -fsSL https://githop.xyz/hop/hop/raw/branch/main/scripts/install.sh | sh
```
Pin a release when required:
```bash
curl -fsSL https://githop.xyz/hop/hop/raw/branch/main/scripts/install.sh | \
HOP_VERSION=v0.1.0 sh
```
Windows:
```powershell
irm https://githop.xyz/hop/hop/raw/branch/main/scripts/install.ps1 -OutFile install.ps1
.\install.ps1 -Version v0.1.0
Remove-Item install.ps1
```
After upgrading:
```bash
hop version
hop skill install --force
hop doctor
```
Restart Codex Desktop when the installed skill changed.
## Upgrade Go installations
```bash
go install githop.xyz/hop/hop/cmd/hop@latest
hop skill install --force
```
## Project migrations
Hop opens and migrates older supported SQLite schemas automatically. Back up
important repositories before alpha upgrades and read the release notes for any
one-way schema change.
## Uninstall the CLI and skill
Unix default:
```bash
rm -f "$HOME/.local/bin/hop"
rm -rf "${CODEX_HOME:-$HOME/.codex}/skills/hop"
```
Windows PowerShell:
```powershell
Remove-Item -Force "$env:LOCALAPPDATA\Programs\Hop\hop.exe"
Remove-Item -Recurse -Force "$HOME\.codex\skills\hop"
```
Remove the Hop install directory from PATH if it is no longer used.
Uninstalling the program does not delete project-local `.hop/` histories. That
is intentional, so reinstalling restores access. Deleting a project's `.hop/`
directory permanently removes its prompt graph, evidence, workspaces, and
accepted Hop history; make a backup and treat that as destructive data removal.
+14
View File
@@ -0,0 +1,14 @@
## Hop
- [Home](Home)
- [Installation](Installation)
- [Getting started](Getting-Started)
- [Core concepts](Core-Concepts)
- [Agent workflow](Agent-Workflow)
- [Parallel agents and conflicts](Parallel-Agents-and-Conflicts)
- [CLI reference](CLI-Reference)
- [Architecture](Architecture)
- [Security and privacy](Security-and-Privacy)
- [Troubleshooting](Troubleshooting)
- [Upgrading and uninstalling](Upgrading-and-Uninstalling)
- [Release checklist](Release-Checklist)