Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion PRIVACY.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ and there is no tenth:
"schema": 1,
"exception": "ManifestError",
"frames": [{"module": "hullwork.manifest", "function": "parse_manifest", "lineno": 707}],
"release": "0.1.0a7",
"release": "0.1.0a8",
"python": "3.12.13",
"platform": "linux",
"operation": "receiver",
Expand Down
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,8 @@ returns a verdict with the run attached. The oracle changes per signal; the mach
| a dependency advisory | *this version is vulnerable* | your own suite, run against the upgrade |
| a static finding | *this could be exploited* | a test naming the hostile input |

**Only the first row is in a release.** The second is built and unreleased — it is in no image you
can pull, and this page will say so until it is. The third does not exist.
**The first two rows are in a release** — the second since `0.1.0a8`, and it says no more often than
yes. The third does not exist.

**"I could not verify this" is a first-class answer**, and on this repository's own numbers — 160
code scanning alerts, five real — it is the answer about nine times in ten. Delivering it honestly
Expand Down Expand Up @@ -152,7 +152,7 @@ code, and writes nothing outside a directory you name. → above, and
[docs/install.md § 1](docs/install.md#1-try-the-agent-half)

**2. The evaluation stack — recommended for a first look.** Needs Docker and nothing else, with **no
clone and no build**: one compose file and a published image (`ghcr.io/easybytehub/hullwork:0.1.0a7`,
clone and no build**: one compose file and a published image (`ghcr.io/easybytehub/hullwork:0.1.0a8`,
amd64 and arm64). One container — the half that answers webhooks — which starts with no credentials at
all and says in a sentence what it cannot do yet.
→ [docs/install.md § 2](docs/install.md#2-the-evaluation-stack)
Expand All @@ -173,7 +173,7 @@ instance has ever run it, which is not support.
| | | |
|---|---|---|
| **Forges** | ✅ Forgejo · ✅ Gitea · ✅ GitHub | ⚠️ GitLab — the adapter is written, no instance has run it |
| **Error trackers** | ✅ GlitchTip, and anything posting a Sentry-compatible payload | ⚠️ Sentry's own route is built and **not in a release yet**; when it lands it is authenticated by the token in the URL and its signature is not verified — which is what GlitchTip offers at all. [`SECURITY.md`](SECURITY.md) says what that does not cover |
| **Error trackers** | ✅ GlitchTip and Sentry, and anything posting a Sentry-compatible payload | ⚠️ Both routes are authenticated by the token in the URL and **neither signature is verified**signing is what GlitchTip does not offer at all, so one credential is checked one way for both. [`SECURITY.md`](SECURITY.md) says what that does not cover |
| **Model endpoints** | ✅ anything speaking the Anthropic or OpenAI protocol family — Anthropic and OpenRouter both exercised | Your key, your endpoint. No provider is integrated and none is privileged |
| **Agents** | ✅ `claude-code`, exercised | Any container that takes a worktree and returns changed files qualifies: the agent is a contract, not an integration |
| **Your stack** | ✅ any Linux image with a shell, on this instance's architecture — you name the image your CI already uses | ❌ `distroless` and `scratch`, refused at registration rather than at attempt time |
Expand Down
2 changes: 1 addition & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ services:
#
# To run your own build instead — a change you are testing, or an architecture with no published
# image — add `build: .` beside this line from a checkout, and `docker compose up -d --build`.
image: ghcr.io/easybytehub/hullwork:0.1.0a7
image: ghcr.io/easybytehub/hullwork:0.1.0a8
ports:
- "127.0.0.1:8000:8000"
restart: unless-stopped
Expand Down
4 changes: 2 additions & 2 deletions docs/install.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,10 +93,10 @@ is the half that answers webhooks. Nothing here can push to anything.
curl -O https://raw.githubusercontent.com/easybytehub/hullwork/main/docker-compose.yml
docker compose up -d
curl http://127.0.0.1:8000/health
# {"status":"ok","version":"0.1.0a7"}
# {"status":"ok","version":"0.1.0a8"}
```

The image is `ghcr.io/easybytehub/hullwork:0.1.0a7`, built for amd64 and arm64, pinned in that compose
The image is `ghcr.io/easybytehub/hullwork:0.1.0a8`, built for amd64 and arm64, pinned in that compose
file rather than floating on `latest`. From a clone, `docker compose up -d --build` builds your own
instead — which is what you want if you are testing a change.

Expand Down
18 changes: 15 additions & 3 deletions docs/published-surface.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{
"_": "Generated by scripts/record-the-published-surface.py from the image itself. Do not hand-edit: a documented capability that is not in here is one nobody can run, and editing this file would make that true silently.",
"image": "ghcr.io/easybytehub/hullwork:0.1.0a7",
"version": "0.1.0a7",
"recorded": "2026-08-07",
"image": "ghcr.io/easybytehub/hullwork:0.1.0a8",
"version": "0.1.0a8",
"recorded": "2026-08-09",
"commands": {
"hullwork": [
"--help",
Expand Down Expand Up @@ -55,6 +55,18 @@
"--forge",
"--help"
],
"hullwork deps": [
"--checkout",
"--fix",
"--help",
"--into",
"--open",
"--verify"
],
"hullwork features": [
"--checkout",
"--help"
],
"hullwork approve": [
"--help"
],
Expand Down
31 changes: 15 additions & 16 deletions docs/status.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,18 @@ each claim is part of the claim.
> | signal | oracle | state |
> |---|---|---|
> | a production error | a test that fails first and passes after | **released**, and everything below describes it |
> | a dependency advisory | your own suite, run against the upgrade | **built and unreleased** — in no image you can pull |
> | a dependency advisory | your own suite, run against the upgrade | **released in `0.1.0a8`** — `hullwork deps`, and it refuses far more than it verifies |
> | a static finding | a test naming the hostile input | does not exist |
>
> The second row is work items 172–180. Its command is deliberately **not named here**: the guard on
> this repository's documentation refused the sentence that named it, and it was right to — a command
> a reader cannot run is an invitation to type it and be told it does not exist. What is actionable
> is the state, and the state is *not in an image you can pull*.
> The second row is work items 172–180. Until `0.1.0a8` this page named its state and deliberately
> **not its command**, because a command a reader cannot run is an invitation to type it and be told
> it does not exist. It is nameable now for exactly one reason: it is in an image you can pull.
>
> This page will keep saying so until a release contains it: documentation describes the released
> artefact, not the working tree (`CONTRIBUTING.md`, and item 165 records the three times that rule
> was learnt the hard way).
> Whether it is *worth* anything is a separate question from whether it exists, and the honest answer
> is measured. On four real third-party repositories before release: **one clean verdict.** The rest
> could not be measured at all — a suite that reaches the network, a pin in a file the image does not
> install from, an image the project brings ready-made — and each was reported as that, with the
> reason. The ratio is the feature. A tool that answered all four would be lying about three.

## What works today

Expand Down Expand Up @@ -59,14 +60,12 @@ its suite runs against a blank one per phase. That path has been exercised by **

## What does not exist yet

- **Only the GlitchTip webhook route is enabled in a release.** Sentry's is **built and unreleased**
as of 2026-08-09 (item 189): in the working tree it is authenticated by the token in the URL — the
same credential GlitchTip has, checked the same way, because GlitchTip cannot sign at all. Its
signature is deliberately not verified; that would need Sentry's client secret held in reversible
form, which is a storage decision this project has not made.

The image you can pull still answers `501` there, and this page will say so until a release
carries it — the same rule as the dependency signal above, and for the same reason.
- **Sentry's webhook route is enabled since `0.1.0a8`, and its signature is not verified.** It is
authenticated by the token in its URL — the same credential a GlitchTip route has, checked the same
way, because GlitchTip cannot sign its webhooks at all. Verifying Sentry's signature would need its
client secret held in reversible form, which is a storage decision this project has not made. So:
anyone who obtains the URL can post to it. Treat it as a secret, and `hullwork projects
rotate-secret` replaces it.
- **Of the notification channels, only `none` and `console` deliver.** `telegram` and `email` parse in
the manifest and are refused at delivery, because a transport nobody has exercised is a transport
whose first real run happens in front of a user.
Expand Down
12 changes: 7 additions & 5 deletions docs/what-hullwork-is.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,11 +102,13 @@ takes that as an inventory would be misled by this page rather than by the ones
| signal | state, 2026-08-09 |
|---|---|
| a production error | **released** |
| a dependency advisory | **built and unreleased** — work items 172–180, absent from `published-surface.json`, which records `0.1.0a7` |
| a dependency advisory | **released in `0.1.0a8`** — `hullwork deps`, work items 172–180, present in `published-surface.json` |
| a static finding | does not exist |

`CONTRIBUTING.md`'s rule is that documentation describes the released artefact rather than the
working tree, so no document may show that command until a release carries it — which is why it is
not named on this page either. The guard refused the first draft of this section for exactly that,
and naming a command a reader cannot run would invite them to type it and be told it does not
exist.
working tree, and it is the reason the middle row spent a day naming a state and refusing to name a
command: the guard refused the first draft of this section for exactly that. The rule did not soften
when the release landed — the row changed because the artefact did.

The third row is the honest one. Three oracles is the shape of the mechanism, not an inventory of
what you can run.
Loading