A useful coding run should leave more than a convincing final message. It should leave changed files, checks you can examine, and enough saved state to understand what happened if the process stops.
That is the problem Hornet addresses. It gives a local model a coding goal, organizes the work into small scoped cells, and keeps the goal, attempts, questions, and execution evidence on disk.
This walkthrough uses Hornet 0.15.1, Python 3.13 on Windows, LM Studio, and a new Ubuntu worker VM in VirtualBox. We will repair one Python function, inspect the result, and see how to return to unfinished work. The commands follow the release’s starter walkthrough; the live-model measurements later in this article come from the separately documented 0.15.0 trial.
Hornet was created and is led by Daniel F. MacDonald, with engineering contributions credited in the project. It is available under AGPL-3.0-only.
- Source and current documentation
- Installable PyPI release: matrixswarm-hornet 0.15.1
- Signed starter release
What a durable coding goal contains
Hornet separates the saved work from the model’s current working context.
A coding cell has an explicit task, permitted files, an expected result with a declared type, acceptance checks, and execution limits. The controller records those commitments, runs the work, and checks the result before accepting completion. Larger goals can be divided into ordered cells within configured limits; this first exercise deliberately uses one.
The active request contains bounded context and references to retained evidence. Source is read as needed. Earlier exchanges can leave the active request while their full records remain available on disk. This limits what each request carries without treating an old failure as if it never happened.
| Situation | What Hornet retains or does |
|---|---|
| An attempt fails | Keeps its conditions, errors, and verification evidence |
| The model needs a decision | Saves a question and waits for an explicit answer |
| The controller is interrupted | Uses checkpoints and operation receipts to assess whether work can resume |
| A goal completes | Keeps its workspace and exports candidate changes for review |
| A finished file needs a follow-up | Creates a revision workspace that records its parent |
The current workers and model roles run sequentially. A plan with multiple cells is not a claim that several models are working concurrently.
The detailed behavior is documented in the CLI reference.
1. Prepare the host and obtain the starter
For the documented path, have these installed on Windows:
- Python 3.13, available through the Python launcher;
- VirtualBox and Windows OpenSSH;
- LM Studio and a model compatible with the request protocol used below;
- GnuPG, such as Gpg4win, for release verification.
Allow one CPU, 2 GiB of RAM, and disk space for the Ubuntu image and worker VM. Those are the worker’s requirements; the local model needs its own host memory and compute capacity.
The arrangement is straightforward:
Windows host
Hornet controller → LM Studio on 127.0.0.1:1234
│
└── pinned SSH on 127.0.0.1:2224
│
dedicated Ubuntu VM
model-requested file and code operations
The model stays on the host. Its requested coding operations run inside the VM. This walkthrough uses Hornet’s own CLI and worker setup.
From the v0.15.1 release, download the starter ZIP, checksum manifest, detached signature, public signing key, and verification instructions. The named starter includes an installable wheel and setup helpers. GitHub’s automatic source ZIP is a different download and does not contain that wheel.
Follow VERIFY-RELEASE.md before extracting the starter:
- Inspect the public key and compare the complete primary fingerprint with a trusted, independently obtained MatrixSwarm release identity.
- Verify the detached signature over
SHA256SUMSand check the expected signing identity. - Match the downloaded files against the authenticated SHA-256 manifest. The supplied all-files verification loop expects the files named in that manifest to be present.
- Extract the verified starter into a new directory.
The published primary fingerprint is:
8086 C2A9 440B 9226 FA7A 78E5 BC01 80CF 9A93 5966
A key and a checksum obtained from the same download location provide a consistency check; that alone does not independently establish who owns the key. The verification guide explains this distinction and supplies the exact GnuPG and PowerShell commands.
2. Install Hornet and check a local file contract
Open PowerShell in the extracted starter directory. Keep that working directory for the commands in this article.
The following path installs the wheel included in the signed starter into a fresh Python 3.13 environment:
py -3.13 -m venv .venv
.\.venv\Scripts\python.exe -m pip install --no-index --no-deps .\matrixswarm_hornet-0.15.1-py3-none-any.whl
.\.venv\Scripts\hornet.exe --version
.\.venv\Scripts\python.exe .\tools\first_run.py --project .\my-first-goal
Look for:
matrixswarm-hornet 0.15.1
INSTALLATION CHECK PASSED
The commands call the environment’s executable directly. There is no need to activate a PowerShell script or change script execution policy.
The first-run helper creates a new project, runs local diagnostics, and writes a small hello.txt file. It then verifies a contract requiring that file to exist, contain the expected text, and meet a minimum size. It also copies the coding goal into the project for the next steps.
This check uses no model and no worker. It establishes that the installed CLI and local contract path work. It does not establish that LM Studio or the VM is ready. The helper refuses to overwrite an existing project; use a fresh directory for another trial.
The PyPI installation option
Hornet is also installable from PyPI:
python -m pip install matrixswarm-hornet
python -m hornet --version
python -m hornet --help
Run those commands inside the Python environment you intend to use. For a version-pinned reproduction of this article, select matrixswarm-hornet==0.15.1.
Choose one installation route. The remaining commands below use the starter’s .venv created above. Installing through an unrelated global python will not populate that environment, and the PyPI package alone does not supply this extracted starter directory’s VM-setup layout.
The package supports Python 3.9 and later and has no runtime Python dependencies. We use 3.13 to match the documented first-user setup. PyPI’s embedded README reflects the uploaded release snapshot; use the current GitHub README for current installation prose.
3. Create a new dedicated worker VM
Use the Ubuntu 22.04 AMD64 cloud VMDK from the official Jammy cloud-image directory. Obtain its checksum manifest and signature, establish trust in that manifest, and use the full SHA-256 for the exact VMDK downloaded.
Do not substitute an ISO, an OVA, or a checksum from a different daily image. The documented validation used the October 20, 2026 image; a newer image is a different input and is not covered by that particular trial.
The worker setup expects Python 3, Git, and OpenSSH server in the image. It does not silently upgrade the guest or install missing guest packages. See the complete worker setup guide for image and provisioning details.
Install the setup-only ISO-building dependency, then supply your image path and verified checksum:
.\.venv\Scripts\python.exe -m pip install pycdlib==1.14.0
$image = 'C:\Downloads\jammy-server-cloudimg-amd64.vmdk'
$imageHash = 'PASTE_THE_FULL_SHA256_FOR_THAT_IMAGE'
$vmFolder = Join-Path $env:USERPROFILE 'VirtualBox VMs'
.\.venv\Scripts\python.exe .\tools\prepare_worker.py --project .\my-first-goal --image $image --image-sha256 $imageHash --vm-parent $vmFolder --name hornet-first-goal --port 2224
Replace the image path and hash placeholders. Choose an unused VM name and loopback port. The helper creates a new worker; it does not adopt an existing VM or overwrite an established worker configuration.
During setup it generates fresh SSH keys, pins the worker’s host key, restricts the local private directory, and binds SSH forwarding to loopback. Shared folders, shared clipboard, and drag-and-drop are not enabled. The VM uses NAT and has outbound networking.
The guest hornet account has no sudo access. Its SSH key is restricted to the worker entry point, but the model can still request Python execution as that guest user. The dedicated VM supplies the execution boundary. Separate goal directories share its account; they are not separate sandboxes for hostile code. Keep unrelated secrets out of the VM.
Wait for the first boot, then check readiness:
.\.venv\Scripts\hornet.exe --root .\my-first-goal worker-status --worker-config worker.json --json
Proceed when the result shows ready: true. An early connection refusal can mean the VM is still starting. A persistent failure calls for inspecting its console and cloud-init output. A host-key mismatch requires checking the saved identity, not disabling verification.
The generated my-first-goal/private/ directory contains the SSH identity, host-key material, and seed ISO. Retain it for this worker and exclude it from Git and uploads.
4. Connect the local model
Load a compatible model in LM Studio, open its Developer tab, and start the local server. LM Studio documents this in its local server guide.
For the endpoint used by the starter, inspect the available model IDs:
Invoke-RestMethod http://127.0.0.1:1234/v1/models | ConvertTo-Json -Depth 6
Set $model to the exact ID returned for your chosen model. The documented Gemma example uses:
$model = 'google/gemma-4-12b'
Use that value only if it is the model your server actually exposes. The starter uses lmstudio-json, a constrained-JSON request mode; a server being generally OpenAI-compatible does not guarantee it supports every option this mode needs. The CLI documentation records testing with LM Studio 0.4.26 and that Gemma model. Model behavior and speed will vary.
5. Give it one precise coding goal
The starter’s calculator.py deliberately returns its input:
def double(n):
"""Return twice an integer (the starter intentionally needs a repair)."""
return n
There is a useful trap here: the existing tests check the integer return type and the zero case. This incorrect function can pass those tests. A green test suite is only as informative as the behavior it exercises.
The supplied demo-goal.txt makes the missing behavior explicit:
Fix calculator.py so double(n) returns 2*n for an integer n, with an integer return type.
Required examples: double(-3) == -6, double(0) == 0, double(7) == 14.
Only calculator.py may change. Preserve its public function name and argument.
Keep the existing tests unchanged. Use one coding cell and verify the required behavior.
That gives the run a small file scope, concrete examples, a return-type requirement, and a constraint against solving the task by rewriting the existing tests.
Start the goal with the documented limits:
.\.venv\Scripts\hornet.exe --root .\my-first-goal autowork --worker-config worker.json --goal-file demo-goal.txt --model $model --base-url http://127.0.0.1:1234/v1 --protocol lmstudio-json --max-cells 1 --max-turns 30 --max-tools 40 --cell-turns 10 --cell-tools 16 --context-chars 16000 --max-tokens 2048 --timeout 120 --json
The command is long because its limits are explicit:
| Setting | Meaning in this exercise |
|---|---|
--max-cells 1 |
Keep the plan to one coding cell |
--max-turns 30, --max-tools 40
|
Bound model requests and tool operations across the goal |
--cell-turns 10, --cell-tools 16
|
Bound the individual coding cell |
--context-chars 16000 |
Bound active working context in characters |
--max-tokens 2048 |
Cap a model response’s output tokens |
--timeout 120 |
Set the socket-operation timeout; not an overall completion deadline |
The context setting is a character budget, not a token count or a change to the model’s loaded context window. Backend framing adds overhead. Use the recorded usage to assess the actual run.
Hornet prepares a separate goal workspace in the VM. Planning and verification roles establish checks before coding, and the controller keeps the frozen checks outside the worker’s editable source. It requires new source changes, the suite, and the applicable cell and goal checks before reporting completion.
For this autonomous goal, success means completed, with the coding cell ready_for_review. A zero process exit, waiting_for_user, or paused is not equivalent to completed coding work.
6. Inspect the changed source and saved evidence
Save the exact run_dir returned by the command:
$run = 'PASTE_THE_EXACT_RUN_DIR_FROM_THE_RESULT'
.\.venv\Scripts\hornet.exe --root .\my-first-goal goal-files $run
.\.venv\Scripts\hornet.exe --root .\my-first-goal questions $run
Use that run’s paths rather than guessing the newest directory. goal-files connects file hashes, cell identities, changes, and revision provenance; it rebuilds this view from validated evidence.
There are two locations to understand:
-
Inside the VM: each autonomous goal has its own source directory under
/home/hornet/workspace/goals/, with its generated workspace ID. The original worker baseline remains separate. -
On the controller: the project retains the run directory, normally beneath
my-first-goal/coding/recipes/, containing its goal, checkpoints, cell jobs, results, and evidence.
Within the reported run, the useful records include:
| Record | What to inspect |
|---|---|
goal.json and goal-acceptance.json
|
Original requirements and frozen overall checks |
recipe-checkpoint.json |
Saved execution phase, source state, and counters |
goal-status.json |
Derived progress and outcome view |
file-index.json |
File hashes and the cells responsible for them |
cells/<cell-id>/return-manifest.json |
Declared result, changed-file hashes, and references to checks and attempts |
cells/<cell-id>/jobs/<job-run>/changes.json |
Exported changed-file content and tracked diff |
The job’s verification/ and attempts/ directories |
Verification rounds and retained attempt evidence |
goal-completion.json |
Links the completed goal to its source state, receipts, and final evidence |
Open the calculator.py entry in the job’s changes.json: its content field contains the exported source. Compare it with the starter and read the recorded diff. Confirm that only the allowed file changed and that the function handles the required examples while preserving its interface.
For this exercise, a minimal repair is to preserve the function and return 2 * n. Inspect the actual exported implementation rather than assuming it took that form.
The resulting behavior should be:
| Call | Required result |
|---|---|
double(-3) |
-6 |
double(0) |
0 |
double(7) |
14 |
Read the assertions as well as their verdicts. Hornet can verify that checks ran and that declared result types matched; a model-authored assertion can still misunderstand the task. Exported work remains a candidate for your review, with integration into your own source as a separate step.
7. Answer a saved question or resume unfinished work
If the run returns waiting_for_user, list its questions with the command above. Copy the exact question ID and answer that question:
.\.venv\Scripts\hornet.exe --root .\my-first-goal answer $run q-EXACT_ID --text 'Your answer'
.\.venv\Scripts\hornet.exe --root .\my-first-goal autoresume $run --json
Replace both placeholders with the actual run and a substantive answer. Saving the answer does not start execution. autoresume explicitly continues the autonomous goal.
While a required question waits, the controller process can exit. There is no response deadline or repeated model inference consuming resources while you are away. Resuming without an answer keeps the work waiting. The question is allowed to be more patient than a chat window.
Use autoresume for an interrupted autonomous goal too. Standalone work jobs use resume instead. A completed goal is not unfinished work to resume; use a revision for a new request.
Keep the project, run evidence, worker keys, VM, and source intact. Resume checks identities and saved source state before continuing. For supported worker operations, durable receipts can resolve a lost reply when the operation and its completed result match.
A started operation without a completed receipt remains uncertain. Hornet stops for inspection instead of assuming it is safe to repeat. This supports recovery from specific interruptions; it does not promise exactly-once effects in external systems or universal recovery from every power loss.
8. Make a targeted revision and retain the parent
After the first goal completes, a small follow-up is:
.\.venv\Scripts\hornet.exe --root .\my-first-goal revise $run --file calculator.py --goal 'Add triple(n) returning 3*n for integers. Preserve double(n).'
A revision creates another workspace and records the parent. It selects the requested file scope and declared dependencies, then uses new checks and retained regression checks. Inspect the revision’s own result and run directory just as you did for the original.
Declared dependencies are not a complete static analysis of every consumer in a codebase. Start with a scope you can review.
After the controller exits, you can shut down the demo VM through VirtualBox’s ACPI mechanism:
& 'C:\Program Files\Oracle\VirtualBox\VBoxManage.exe' controlvm hornet-first-goal acpipowerbutton
Restart the same retained VM before resume or revision:
& 'C:\Program Files\Oracle\VirtualBox\VBoxManage.exe' startvm hornet-first-goal --type headless
Adjust the executable path and VM name if you chose different ones. Shutting down the worker preserves it; deleting it would remove part of the saved working environment.
What has actually been validated
The published validation record reports an earlier 0.15.0 live trial on a fresh Python 3.13 environment, on an existing Windows host, with a newly provisioned Ubuntu 22.04 VM and Gemma 12B:
| Observation | Recorded result |
|---|---|
| Model requests | 16 |
| Tool calls | 5 |
| Peak input | 3,084 tokens |
| Changed source | Only calculator.py
|
| Independent behavior checks | [-6, 0, 14] |
| Original worker baseline | Preserved |
These are observations from one deliberately small goal. They are not a general reliability benchmark, a speed promise, or a prediction of another model’s request count.
For 0.15.1, the release work added packaging, publication metadata, license, documentation, and distribution checks. The executable baseline and demo were retained apart from the version string. The publication record reports that the PyPI and TestPyPI files match the original signed GitHub artifacts, with fresh installation, version, and first-goal file-contract checks passing on Windows Python 3.13 and an Ubuntu workflow runner. The PyPI publication workflow records the successful verification.
Those publication checks did not run a new live-model benchmark. Keeping that distinction visible makes the evidence more useful.
If the first run stops
| Symptom | Useful next step |
|---|---|
| First-run helper refuses the project | Preserve the existing directory and choose a new project name |
| Local diagnostics pass, model calls fail | Check LM Studio’s server, exact model ID, endpoint, and protocol support |
| Worker is not ready | Inspect first-boot progress, VM state, and cloud-init output |
| Worker host key differs | Investigate the identity and saved pin |
| Goal waits for a user | Save an answer to the exact question, then explicitly resume |
| Budget is exhausted | Inspect retained attempts and checks before deciding on another attempt |
| Operation outcome is uncertain | Keep the evidence and inspect the worker before continuing |
| Tests pass but no new change appears | Inspect the requirement and changed-file evidence; a no-op is not a completed repair |
Hornet’s first exercise is intentionally modest. A single function is enough to follow the entire path from a written requirement to a changed file, executable checks, and a retained record.
That is a useful place to begin evaluating a coding tool: give it a task you understand, examine what it changed, and inspect what it kept when something did not go to plan.
Start with the signed starter and first-goal guide. For project attribution and contribution details, see AUTHORS.md and CONTRIBUTING.md.
Victory Always.
🌐 Links & Resources:
Hornet source: https://github.com/matrixswarm/hornet
Hornet on PyPI: https://pypi.org/project/matrixswarm-hornet/
Try MatrixSwarm: https://matrixswarm.com
Join the Community / Discord: https://discord.gg/2USbWVBVV
Download Server: https://github.com/matrixswarm/matrixswarm
Youtube: https://www.youtube.com/channel/UCMjiY4_-W2KP5fHXO0eC2ug
Top comments (0)