Releases: HexaEightTeam/hbia-agent
Release list
HBIA r6 — fetch returns a Response, binary bodies preserved, workspace bundle
The leaf runtime's fetch now behaves like fetch, and binary responses survive it. Adds the
workspace UI as a downloadable bundle.
Agent source only — Bridge 1.9.21 / ASK 1.9.161 / JWT 1.9.292 are unchanged from r5, and the
runtime stays pinned at 8.0.28. --probe returns 0 on Windows and Linux with no new integrity
registration, because the rows registered for r5 still describe these builds.
heia.fetch returns a Response
const r = heia.fetch(url); // quickjs: synchronous, Asyncify suspends the stack
const data = r.json();r = await heia.fetch(url) # pyodide: async, as it has always been
data = await r.json()ok, status, headers, and text() / json() / bytes() to choose a form — the same shape
fetch gives you, for the same reason: the bytes are what arrived, and any decode is the caller's
decision.
Binary responses are no longer destroyed. The body used to be decoded as UTF-8 before a unit saw
it, which replaced every invalid sequence with U+FFFD, irreversibly. A unit fetching a PDF received
something that was still a string and no longer a PDF, and nothing downstream could tell. The body
now crosses as real bytes — an ArrayBuffer in QuickJS, a bytes object in Python — so
PdfReader(io.BytesIO(r["body"])) works.
heia is available in Python without an import, because it is the runtime rather than a package the
author chose. import heia still works.
Egress
allowed_hosts: ["*"]for units that fetch URLs discovered at run time — search results, links
inside a page. Must be keyless ("name": ""): injecting a secret into a request bound for a host
the runtime picked would hand that secret to whatever URL was discovered, so it is refused at build
and again at run time.- Hostnames reached through
*are put to a resolver that declines to answer for known-malicious
domains. It fails open — a resolver that cannot be reached must not read as a host that was blocked. - Loopback and link-local are refused regardless of declaration. Loopback is the machine's own
control plane;169.254.0.0/16is where every cloud puts instance metadata, which hands out
credentials to anything that can make an HTTP request. An ordinary LAN address (10.x, 172.16-31.x,
192.168.x) is reachable — a skill that publishes a site and fetches from another internal host
is a real case, and it is separated from the two above precisely so allowing it does not allow them. - A public IP literal is refused under
*, since it skips the DNS check that is the whole protection.
Build refuses what used to ship broken
A pyodide unit that calls heia.fetch from a synchronous def, or with async def but no await,
is now a build failure. Pyodide has no synchronous fetch: the call returned a coroutine, indexing it
raised, and units written that way wrap the call in a bare except — so every fetch silently
returned nothing while the unit reported success.
Ingest
Goal 6 is now shown an audit of units.json against what was actually built — a unit planned as
pyodide and built as quickjs, a planned library that no unit declares. It is reported, not
enforced: a gate can be satisfied by deleting the requirement, which is exactly how a capability
went missing three runs running. Goal 6 decides whether to send the run back or record, and owns
that decision.
The leaf-building contract is 14 sections, down from 29. Everything describing Node-RED JSON that
build_leaf generates is gone, along with the worked examples — a model does not need to be taught
Python, and every example it was given came back copied complete with the example's own quirks.
The workspace
hexaeight-workspace-dist.zip is the built UI, the Bootsharp browser-auth runtime, and a
dependency-free static server.
hexaeight-activate install-workspace --serveDownloaded and verified the same way as the agent, extracted under the runtime root, and served by
an ordinary express app — so it sits behind nginx or a load balancer without argument
(--behind-proxy, --base /path).
Installing and updating
dotnet tool install --global HexaEight.Activate
hexaeight-activate install-agent # agent + the pinned Node toolchain + MCP config
hexaeight-activate install-workspace
hexaeight-activate newtoken # interactive: licence code + Authenticator approvalinstall-agent now also provisions Node-RED, the QuickJS and Pyodide leaf runtimes, and Claude
Code, pinned by a lockfile shipped inside the package and installed with npm ci — so two machines
provisioned a month apart run identical code.
hexaeight-activate update installs only the components whose version moved, and restarts only
what that implies: the agent restart brings Node-RED with it; a router update restarts the agent
too; a workspace update restarts nothing and just wants a browser refresh. whats-new lists what
each component changed.
Platform coverage
win-x64, linux-x64 and osx-arm64 are published. osx-x64 (Intel Mac) and linux-arm64 are
not: the attestation hash can only be produced by building and running on the target architecture,
and we have no such machine. install-agent exits 2 there and points at support@hexaeight.com
rather than installing a near-match the platform would refuse.
See HASHES.md for SHA-256 per download and the PROTECTION HASH per platform, and for why those are
two different things.
HBIA r5 — Bridge 1.9.21 / ASK 1.9.161
First release with the approved-build gate working end to end — an agent can now be told which
builds may call it, and both halves are proven: an unlisted build is refused, and approving it
admits the same binary without a restart.
Built on Bridge 1.9.21 / ASK 1.9.161 / JWT 1.9.292, .NET 8 self-contained, runtime pinned to
8.0.28, single-file with IncludeAllContentForSelfExtract=true. Nothing needs to be installed
to run these.
Downloads
| platform | file | SHA-256 |
|---|---|---|
| Windows x64 | hexaeight-agent-win-x64.exe |
4FC727D15F6E46152ED5B4DBE56C7FF004901D5514F667680E7E348CA358681D |
| Linux x64 | hexaeight-agent-linux-x64 |
384BFA57A6D7216C63EA135C6C1B86D1F43D6DDDC60C7CFD750D409478BBDF78 |
| macOS arm64 | hexaeight-agent-osx-arm64 |
1DBC782B90CDC910D70556256BBBAC824D5B81D26B78C8EDD718CA14D996E70A |
PROTECTION HASHES
What a peer's approved-build gate matches on — the hash of the extracted entry dll, not of the
file you downloaded. All three verified blessed against the live platform (--probe returns 0).
win-x64 6230A870E4825659E3A011E7C4FD6ABD80D1BDEC966BBEBC076C519398F4E57F5DD7A54B6B4C0E70967713DDF0A417CCA877A24539E76D1330D5F2D9B9064CEB
linux-x64 51652F55027CBB41779BA78317E28CBBC92D0ECFFEA049F3C8FB395E2B26EC48A5C3591453B14298D0E4789995C6C238B710D5C51B6AF6B586EB32523EF7ECD7
osx-arm64 8FD1377D7A7A535FD1174F05084B28E81650A52FCFCE210245D3E97C4DCE8A6C12D48432B2E4F2A9E3CF21D961EB685C63433E9FD94CC29C93CD0A251A7F5343
All three ship inside HexaEight.Activate 1.0.11 (approved-build list v5), so verify-env approves
them automatically and nobody copies a hash by hand.
What's new
The gate is enforced by the agent. Earlier builds never read the allowlist: the Bridge does not
auto-load it, and the agent never asked it to, so every agent ran permissive while the policy on
disk said otherwise. It now loads the list at startup and prints which state it is in —
ENFORCING or NOT enforcing — because a gate that is quietly open is worse than no gate.
Live reload. approve-builds runs in a separate process, so the agent watches the file.
Approving a peer takes effect immediately; restarting an agent to admit a caller was exactly the
outage this feature exists to prevent.
--init-policy gates on origin. It measures the running build's own PROTECTION HASH by sealing
to itself, approves that, and drops the wildcard. Measured, not guessed — what a build attests
depends on how it was published. If it cannot measure, it leaves the gate open and says so, rather
than tightening on a value it is unsure of and locking you out of your own agent.
Refusals say what they are. A blocked build used to surface as a JSON parse error, which reads
as a broken envelope and points nowhere near the allowlist. Both envelope routes now check the
decision first: the operator's log names the sender and the reason, while the caller gets only
denied — a prober cannot tell an unapproved build from an unauthorised sender.
Runtime pinned to 8.0.28. The platform validates an IL hash computed per (assembly, runtime,
OS), so the bundled .NET patch level is part of a build's identity. Left floating, a publish on a
machine with a different runtime pack silently produces different hashes and every agent from that
build is refused, with no source change to explain it.
Verifying
sha256sum hexaeight-agent-linux-x64 # 1. the file is ours
./hexaeight-agent --probe # 2. run once; 0 = platform trusts this build
hexaeight-activate verify-libs # 3. libraries match nuget.orgverify-libs finding nothing is itself a red flag: official releases place their assemblies on disk
so they can be checked.
Notes
- macOS is Apple Silicon only. Intel needs its own build — the IL hash is per-OS and
cross-publishing cannot produce it. - Self-published agents remain first class:
approve-builds --add-hash <PROTECTIONHASH>admits your
own build alongside the official ones. Prefer--add-hashover--add-file, which has to infer
which file your publish shape attests and refuses the peer silently when it guesses wrong.