Skip to content

Releases: TAIPANBOX/stack-single

stack-single 1.4.4

Choose a tag to compare

@TAIPANBOX TAIPANBOX released this 28 Oct 23:02
daee42e

stack-single 1.4.4

A patch that moves seven images to newer releases: TokenFuse 1.20.1 to 1.20.3, the console 1.7.0 to 1.7.3, the caddy and tunnel images to 1.7.3, the trailryx-node record seal from 1.4.0 to 1.5.0, and the chain verifier (agent-conform) from 2.0.1 to 2.0.2. The console and the tunnel are built on Go 1.27.3, which fixes GO-2026-6809 in crypto/x509. agent-conform is rebuilt for the same fix.

Upgrade first

  1. Run ./install.sh again from this release. A box with its own operator files names them as before (CLIENT_KEYS_FILE=... IDENTITY_MAP_FILE=...). The installer checks each new image's signature, pulls it by digest and recreates the services whose image changed. Nothing else needs to be set.
  2. TokenFuse 1.20.2, included in 1.20.3, prices gpt-6.1-terra at its own row. Until now the model had no row, so each call was estimated and recorded at the fallback price of 15 USD (input) and 75 USD (output) per million tokens. It is now priced at OpenAI's Standard list, about a fifteenth of that. Budgets for that model burn that much more slowly, and the x-fuse-price response header no longer says fallback for it. Nothing to configure. A row for the model in TOKENFUSE_PRICE_BOOK still wins over the built-in row; this launcher does not set that variable.
  3. Agent tokens are on by default, so a default box writes a new high event. The default is TOKENFUSE_AGENT_TOKENS='require'. TokenFuse 1.20.3 now writes an identity_mismatch event (severity high) to the bus for a call with an unknown client key (reason unknown_key, with a sha256: fingerprint of 16 hex digits, never the key) and for a call with no key (reason missing_key), where it wrote nothing before. A known key that the static list does not name is still refused and still not reported. The client gets the same answer as before. An alert on high identity_mismatch events will see these on a box that had none. The volume is bounded at one event per source per minute, and sixty a minute for the gateway.
  4. trailryx 1.5.0 changes nothing on a stock install. The seal signs only when TRAILRYX_SIGNER is set, and this launcher does not set it, so the record seal runs as before. A node with TRAILRYX_SIGNER=keyryx and no TRAILRYX_KEYRYX_KID now refuses to start. That variable is the RFC 7638 thumbprint, 43 base64url characters, of the Keyryx key the seal signs under. Each Keyryx signature is also checked before it is stored: one that does not verify leaves its root queued, and a pack built while the root is queued says it is unsigned. This applies only to a box whose operator has set the Keyryx signer by hand, since this launcher does not wire it.
  5. The console, the tunnel and agent-conform have no operator-visible change recorded for this release. Their change is the Go 1.27.3 base.

What changed

Image 1.4.3 1.4.4
tokenfuse (MCP broker, gateway, OpenAI gateway, FOCUS export) v1.20.1 v1.20.3
tokenfuse-control-plane v1.20.1 v1.20.3
genaryx-console v1.7.0 v1.7.3
stack-caddy v1.1.48 v1.7.3
stack-wg (tunnel) v1.1.48 v1.7.3
trailryx-node (record seal) v1.4.0 v1.5.0
agent-conform (chain verifier) v2.0.1 v2.0.2

Each is pinned by tag and digest in compose.yaml and components.json:

  • tokenfuse sha256:2b82c87733a8165922f8f6c737a1d19bc0e0156335e88db6c190b17cc2a4a484
  • tokenfuse-control-plane sha256:64b9476edeced2c4436d4a5f5bfcbb78b0217f1d85c75af4ec045e21475fe07e
  • genaryx-console sha256:0db4758c9f3dd2231184063af4f80bce491480f6d7238c02bcbac83abb8d708a
  • stack-caddy sha256:41d37fc74013bf5b0c64a41acc5bbc9fb0af3de7dfeb69787e54f028118b05b7
  • stack-wg sha256:1c70d34197586768164fa8bc3a220a4978bef48351023db318a3053dc8eed7a2
  • trailryx-node sha256:f15215cd9708724e83fbd8493f2bf7d2a11980b37edf3b887081d8e17da18bab
  • agent-conform sha256:65c0c1ef78effe96f09c5684a203616fed396375e182bedb142a5beaa178b713

The installer reads these from compose.yaml (docker compose config --images), so install.sh names none of them and needs no change. The image-verify fixtures, the teeth cases that plant faults next to these pins, and the README and CLAUDE.md lines that name the console and TokenFuse versions follow them.

What the upstream releases changed:

  • TokenFuse 1.20.2 (its pull requests #484 to #489): zstd-sys moves to 2.1.2 for RUSTSEC-2026-0410. RUSTSEC-2026-0391 and RUSTSEC-2026-0403 stay as a recorded, temporary exception in TokenFuse's own audit, and its audit script fails once the exit condition is met: DataFusion 56, or any release that takes parquet and arrow-ipc 60.
  • TokenFuse 1.20.3 (its pull requests #491 and #492): with TOKENFUSE_AGENT_TOKENS=require, a call with an unknown client key, or with no key, is now written to the event bus as an identity_mismatch event (high), with a fingerprint and never the key. The client's answer is unchanged.
  • trailryx-node 1.5.0 (its pull requests #112 and #113): the Keyryx signer signs under one pinned key and checks each signature. No record, journal, pack or wire format changes, and the frozen section of COMPATIBILITY.md is unchanged.

Checked locally

  • Each new digest was read from the registry with docker buildx imagetools inspect on 2026-10-28. Each index digest equals the value pinned above.
  • Each new image has its cosign signature tag (sha256-<digest>.sig) in the registry. The signature identity is checked by the installer's cosign run, which the CI install job exercises.
  • The provenance of genaryx-console v1.7.3 and stack-wg v1.7.3 names golang:1.27.3-alpine.
  • The tokenfuse and tokenfuse-control-plane v1.20.3 index digests were read the same way, and their signature tags are present.
  • The agent-conform v2.0.2 index digest was read the same way and matches the pinned one, and its signature tag is present in the registry.
  • git grep finds no old tag or digest outside docs/releases/.
  • 49 of the 54 gates in .github/workflows/gates.yml (every one except gates-have-teeth, which is listed under Not measured) pass on this Mac, including the new no-key-in-a-message gate. Five need tools it does not have running: shellcheck (shell-lint) and a Docker daemon (broker-blocks-raw-secrets, identity-files-are-checked, metered-doors-require-keys, openai-door). CI runs them.

Not measured

  • No box was installed or upgraded with these pins. The forge upgrade follows separately.
  • cosign was not run on the new images here, since cosign is not installed on this machine.
  • agent-conform v2.0.2: its provenance names the Go base by digest (sha256:f20d83a8...), which did not match the golang:1.27.3 or golang:1.27.3-alpine tags when checked on 2026-10-28. The Go 1.27.3 build is therefore not confirmed here, and the agent-stack-go v2.0.2 release notes were not read.
  • The console 1.7.x and the caddy and tunnel 1.7.3 release notes were not read beyond the provenance check.
  • TokenFuse 1.20.3's new bus event has not been run live. Upstream measured the refusal on a v1.20.1 gateway on 2026-10-28 and says the fix itself has not run live yet.
  • TokenFuse 1.20.2 was not run against a live OpenAI response. Its gpt-6.1-terra price is proven by unit tests and the regenerated contract, not by a recorded call.
  • trailryx 1.5.0 was not run against a live Keyryx. Its tests use a stub.
  • The full gates-have-teeth.sh run on this Mac was not clean: a baseline cache directory went missing during the run, and the gates that need Docker or shellcheck are red here. CI is the run of record for it.
  • No stack-single release is cut by this change. The tag goes on the merge commit when it is cut.

stack-single 1.4.3

Choose a tag to compare

@TAIPANBOX TAIPANBOX released this 26 Oct 07:20
dc0b380

stack-single 1.4.3

A patch that moves TokenFuse from 1.19.0 to 1.20.1, a security fix. Before TokenFuse 1.20.1, a JSON-RPC batch sent to the MCP broker skipped every check the broker keys on tools/call: the policy decision, the identity requirement, the scan of the arguments and the tool-call record. The broker forwarded the batch to the upstream as it came. TokenFuse 1.20.1 refuses it before anything is forwarded. Upgrading is recommended for every box that runs the broker.

Upgrade first

  1. Run ./install.sh again from this release. A box with its own operator files names them as before (CLIENT_KEYS_FILE=... IDENTITY_MAP_FILE=...). The installer verifies the two new TokenFuse images' signatures, pulls them by digest and recreates the services that run them.
  2. A client that sends JSON-RPC batches to the MCP broker now gets an error. The answer is JSON-RPC -32600 (Invalid Request) with a null id, and HTTP 400. Send each message on its own. The Model Context Protocol removed batching in its 2025-06-18 revision, so a client on the current protocol is not affected.
  3. TokenFuse 1.20.0, which this release passes through, requires TOKENFUSE_DELEGATION_URL to be an origin. install.sh writes http://$GATEWAY_PROBE:4100, an origin with no path, so nothing changes here. 1.20.0 also reads TOKENFUSE_DELEGATION_ORIGINS and TOKENFUSE_MCP_PROOF_ORIGINS for a gateway reached at more than one address; this launcher sets neither and keeps its one origin.

What changed

Image 1.4.2 1.4.3
tokenfuse (MCP broker, gateway, OpenAI gateway, FOCUS export) v1.19.0 v1.20.1
tokenfuse-control-plane v1.19.0 v1.20.1
  • Both are pinned by tag and digest in compose.yaml and components.json (#155): the gateway image sha256:8de459eca2a10ae36a01d0249b91c3b0c62b50b47ad2c4a309e2ea02e0a460dd, the control plane sha256:157d5801367674e7af8625b391fba8e26e3b72fe95dcb5e435cebee5555fa92a. Each is an amd64 and arm64 manifest list with a cosign signature, and the gateway image's build provenance names commit 27a0a2f at refs/tags/v1.20.1 of TAIPANBOX/tokenfuse. The image-verify fixtures, a teeth case and the README sentence that names the TokenFuse pin follow them.
  • TokenFuse 1.20.1 also clears five RustSec advisories, among them a timing issue in crypto-bigint, by moving its P-256 code to p256 0.14 with the wire format unchanged.

Measured

  • forge, 2026-10-26, upgrading from 1.4.2 to the tree of this release (fc7ebd5), with agent tokens on and its own operator files: installer exit 0, 59 checks ok, none failed. The MCP broker, the gateway, the OpenAI gateway and the control plane came up on v1.20.1, healthy, with no restart; install.sh status 49 ok.
  • The batch, before and after, on that box. One request to the MCP broker carrying a JSON-RPC batch of two tools/call, admitted by an agent token. On 1.4.2 (TokenFuse 1.19.0) the batch reached typryx and wardryx made no decision. On 1.4.3 the broker answered HTTP 400 with -32600, logged that it forwarded nothing, and typryx logged nothing.
  • Agent tokens on the same box, using docs/evidence/agent-token-audience/measure.sh (agent agent://home.taipanbox.dev/agents/operator, BUDGET_USD=0.000001): 10 of 10 expectations held, among them a single tools/call through the broker that typryx answered.
  • One proof sent twice to the gateway, five seconds apart: the first was admitted and stopped at the budget step (402), the second was refused at the gateway's own door (401 agent_token_refused, logged as Replayed).
  • CI on #155: eight checks green, six of them full installs with these pins.

Not measured

  • A box with agent tokens off was not upgraded live; the CI install legs cover that path.
  • A second installer run on the measured box was not made, so this release does not record that a re-run recreates nothing.
  • The FOCUS export runs only under the routines profile, which forge does not enable, so its new image was pinned and verified but not run there.
  • A gateway reached at a second address was not exercised: this launcher sets one origin.

stack-single 1.4.2

Choose a tag to compare

@TAIPANBOX TAIPANBOX released this 26 Oct 01:45
300cba2

stack-single 1.4.2

A patch that moves every Go image this launcher pins to a release built on Go 1.27.3, which fixes GO-2026-6809 in crypto/x509. Three of the moves also bring the service releases in between (wardryx 2.4.0, heraldyx 0.8.1, keyryx 0.1.2), so read Upgrade first.

Upgrade first

  1. Run ./install.sh again from this release. A box with its own operator files names them as before (CLIENT_KEYS_FILE=... IDENTITY_MAP_FILE=...). The installer verifies each new image's signature, pulls it by digest and recreates the services it changes; on the measured box below that was the eight moved services plus the gateways, the console and caddy, while the database, the control plane, the record seal and costcrew kept running.
  2. wardryx 2.4.x with agent tokens on. With agent tokens on, the installer sets WARDRYX_AGENT_TOKEN_ISSUER, and wardryx 2.4 accepts each agent DPoP proof for one decision only: a proof presented twice is refused with 403 agent_token_proof_invalid. TokenFuse 1.19.0, pinned here, sends each request's own proof once per decision, and refuses a replayed proof at its own door before wardryx is asked (measured on a live box, below). This launcher does not set WARDRYX_APPROVER_JWKS, so approvals decided with a key work as before.
  3. heraldyx 0.8.x reads a stream file entry only while it is a regular file. The entry this launcher writes, /var/lib/keyryx-alerts/keyryx.ndjson, is the file the Keyryx witness writes on its own keyryxalerts volume, mounted read only into heraldyx. A box whose operator replaced it with a link or a directory must point the entry at the real file.
  4. keyryx 0.1.2 and later write attestations 0640 in 0750 directories. Attestations written by keyryx 0.1.1 keep 0600. This launcher does not wire a reader of attestations, so nothing here needs them; a box that wires one can run the one-time chmod in keyryx's docs/releases/v0.1.2.md.

What changed

Image 1.4.1 1.4.2
heraldyx v0.8.0 v0.8.2
idryx v1.3.0 v1.3.1
keyryx v0.1.1 v0.1.3
scopyx v1.1.0 v1.1.1
scopyx (chromium) v1.1.0-chromium v1.1.1-chromium
typryx v0.5.0 v0.5.1
vouchryx v0.6.0 v0.6.1
wardryx v2.3.0 v2.4.1
  • Each image is pinned by tag and digest in compose.yaml, components.json and install.sh (#153). Every one was built on golang:1.27.3 or golang:1.27.3-alpine, read from its build provenance. The teeth cases, the image-verify fixtures, scripts/typed-data-mode.sh and the README lines that name these pins follow them.
  • The README's own-files example names the broker and agents entries that agent tokens need (#152).

Measured

  • forge, 2026-10-26, upgrading from 1.4.1 to the tree of this release (a7e9a44), with agent tokens on and its own operator files: installer exit 0, 59 checks ok, none failed; every service came up on its new image with no restart; install.sh status 49 ok. A second run: 59 ok, no container recreated, .env unchanged.
  • Agent tokens on the same box with wardryx 2.4.1, using docs/evidence/agent-token-audience/measure.sh (agent agent://home.taipanbox.dev/agents/operator, BUDGET_USD=0.000001): 10 of 10 expectations held. Each run produced two wardryx decisions, one for the gateway and one for a broker tools/call, each policy_allow with attestation dpop-key, and no agent_token_proof_invalid. The same measurement on 1.4.1, before the upgrade, gave the same result.
  • One proof sent twice to the gateway, five seconds apart (longer than the gateway's three-second decision cache): the first was admitted (a wardryx allow, then 402 at the budget step), the second was refused at the gateway's own door (401 agent_token_refused, logged as Replayed), so wardryx was not asked.
  • CI on #153: eight checks green, six of them full installs with these pins.

Not measured

  • A box with agent tokens off was not upgraded live; the CI install legs cover that path.
  • The one-time chmod of older Keyryx attestations was not run: nothing on this launcher reads them.
  • TokenFuse stays at 1.19.0 here; stack-k8s pins 1.20.0, which this release does not take.

stack-single 1.4.1

Choose a tag to compare

@TAIPANBOX TAIPANBOX released this 25 Oct 17:26
8786fda

stack-single 1.4.1

A patch for a box that turns agent tokens on with its own client keys file and identity map, and for any box with agent tokens whose gateway is published on an address other than loopback. Three defects, measured on forge on 2026-10-25 when it turned agent tokens on after its 1.4.0 upgrade. Each has a test that was red on 1.4.0, a teeth case and a feature scenario.

Upgrade first

  1. A box with its own identity map must bind the enrolled agent in unit agents. vouchryx enrols agent://<trust domain>/agents/operator in unit agents, and the gateway refuses that agent's own token (403 unit_contradicts_map) unless the map binds it in the same unit. Add a unit with id agents, a keys[] entry with key id agents, unit agents and agents agent://<trust domain>/agents/*, and a matching <secret>:agents line in the keys file. The installer keeps that key off the static allow-list, so it admits nothing on its own. Without the binding this release refuses the map before it writes anything. A box whose keys the installer minted has the binding already.
  2. A box with agent tokens on whose gateway is published on one address (GATEWAY_BIND in .env): run ./install.sh again. From 1.3.0 to 1.4.0 such a box had the doors' proof origins written for loopback on every run, so every agent token was refused at both doors. This release writes the address the box has.
  3. Nothing else changes. A box with agent tokens off, or one whose gateway is on loopback and whose keys the installer minted, sees no difference.

What changed

  • ADD_BROKER_KEY=1 installs on the first run (invariant 48, D15). The installer appended the broker's line to the operator's keys file, then refused the map's own broker binding, because the keys checked against the map were read from the file before the line was added. The appended line now joins those keys, as the minted broker key does.
  • The doors' DPoP origins follow the bind the box has (invariant 11, D16). The agent-tokens block wrote TOKENFUSE_DELEGATION_URL, MCP_BROKER_DELEGATION_URL and wardryx's door origins from the bind this run started with, before .env was read, so a re-run with nothing in the environment named loopback. The block now takes the bind from .env first.
  • A map that cannot admit the enrolled agent is refused (invariant 48, D17). A map that bound agent://<trust domain>/agents/* only to the broker's unit was accepted, and the gateway then refused the operator agent's valid token. The installer now refuses such a map by name.

Measured

  • forge, 2026-10-25, turning agent tokens on with its own files on 1.4.0. D15: the first run appended the broker's line, then stopped on "the identity map of the gateway binds key id(s) broker that no client key carries". D16: the origins named 127.0.0.1 on a box published on 192.168.1.10; a valid token was refused 401 at the gateway (Token(WrongKey) in its log), and a proof addressed to 127.0.0.1 passed the token door. D17: with the broker-only binding the gateway answered a valid token 403 unit_contradicts_map.
  • forge, the same day, the tree of this release, its own files carrying the agents binding and nothing in the environment but the two file names: 59 installer checks ok, none failed; the origins named 192.168.1.10; no container recreated or restarted; the sorted content of .env unchanged. docs/evidence/agent-token-audience/measure.sh (its agent id set to the box's trust domain): 10 of 10 expectations held. A token was issued, admitted past identity at the gateway (402 at the budget step) and at the broker, and a typed tools/call was answered. A tampered token was refused 401 at both doors.
  • Red first: broker-key-is-the-keys-file-line.sh cases C (D15, the keys checked held only felyx) and G (D17, the map was accepted), and agent-tokens-are-wired.sh section K (D16, http://127.0.0.1:4100 for a box bound to 192.168.1.10), each red on 1.4.0 and green here; each has a teeth case that plants the fault again and goes red.

Not measured

  • ADD_BROKER_KEY=1 end to end on a live box with this release: forge's keys file already held the broker's line when this tree ran. Case C measures the fixed path against scratch files.
  • A CI install leg with an operator's own files and agent tokens on: no leg runs that combination; these three are measured by the gates and on forge.
  • Every run with agent tokens on rewrites the token lines of .env and moves them to its end, so the file's bytes change while its values do not.
  • The DPoP door origins (TODO(1.4.0, D13) in install.sh): the gateway still accepts a proof for one origin only, so on a box whose origin is its LAN address, a proof addressed to http://tokenfuse-gateway:4100 by an agent on the agents network does not match it. Read from the code, not run.

stack-single 1.4.0

Choose a tag to compare

@TAIPANBOX TAIPANBOX released this 25 Oct 16:26
a5018e2

stack-single 1.4.0 (a minor release: it was planned as 1.3.2 and renamed, because it turns the record plane on by default and removes the containers of profiles that are off, both of which an operator sees)

Seven defects were measured on a forge upgrade from 1.1.35 to 1.3.1 on 2026-10-19, and one on a fresh 1.3.1 box (gcp2). Each has a gate, teeth cases and a feature file in this release. The static allow-lists a 1.3.1 re-run widened are cut back on this run. One more defect, in this release's own installer, was found on its first live run (forge, 2026-10-25) and fixed before the tag (D14).

Upgrade first

  1. The record plane now starts on every box that does not set WITH_RECORD=0. It is a core control and runs the pinned trailryx-node image, with no build. A box that must stay without it runs WITH_RECORD=0 ./install.sh, and that run stops and removes record-seal if it was running.
  2. Installer-managed profiles this run turns off lose their containers; operator-started profiles keep theirs. record, typed, typed-risk-signal, delegation and openai-door are started by this installer from its flags, so a run that turns one off stops and removes its containers, by name. egress, egress-browser, finops, routines and manual are started by you, and this installer never removes them. A RUNNING container of one of those is started again at this run's pinned image, so an upgrade leaves no old image behind; a stopped one stays stopped. The closing report lists each one it kept, with its image.
  3. A box given its own CLIENT_KEYS_FILE must add its broker's key to that file. Agent tokens are on by default, and the MCP broker needs a key of its own. Add a line <secret>:broker (the secret, a colon, then the word broker), bound in your identity map to agent://<trust domain>/agents/*. Or run ADD_BROKER_KEY=1 ./install.sh, and the installer mints the secret and appends that line, keeping the file's mode, once the identity map binds broker. Without one of those the installer refuses before it writes anything. The README said broker:<secret> before this release; that form was never read. A box whose keys an earlier run took from its keys file keeps them in .env and need not name the file again, but with agent tokens on the broker's line has to come from that file, so such a re-run is refused by name: name the file and the map again (with ADD_BROKER_KEY=1 if the file has no broker line yet), or run WITH_AGENT_TOKENS=0.
  4. A box that ran 1.3.1 more than once had the agents' and the fire drills' keys put on its static allow-lists. This run removes both ids from the gateway's list and the broker's list, unless you name them in STATIC_KEY_IDS. The closing report says which ids it removed. To keep the agents' static key while you move the agents to tokens, name it on every run: STATIC_KEY_IDS=agents ./install.sh. The choice is not sticky: a run without it removes the agents' key again, which is the secure behaviour, so keep naming it until the agents use a token. The key must be one the box holds; the installer refuses a name it does not hold. Until an agent uses a token, a call it makes with a removed static key is refused 401 agent_token_required.
  5. Then re-run ./install.sh. Nothing else needs doing: the volumes of an upgraded box are re-owned to their services' users on every run.

What changed

  • Every read-write volume of a non-root service is re-owned to its uid, recursively, on every run (CLAUDE.md invariant 49). The gateway's retained-reservation journal and typryx's ledger were left with the uid of an earlier release, so the gateway stopped and the typed plane could not write. The one-shots now chown -R each volume.
  • A compose profile this run does not name has no container left behind (invariant 50). The cleanup covers every profile the compose file defines, not two by hand. After the 1.1.35 to 1.3.1 upgrade the FinOps console still ran its 0.6.0 image.
  • The record plane is on by default (invariant 51). WITH_RECORD=1 no longer builds trailryx from source; only BUILD_FROM_SOURCE=1 does.
  • The bus directory can be entered by others, but nothing is written in it by anyone but the setup script (invariant 52). The FinOps console's stream was created correctly, but the directory above it did not let its uid in. Measured on a fresh 1.3.1 box as "permission denied" on open.
  • A re-run keeps exactly the static allow-list the last run wrote; felyx and the broker are named on every run the box holds them; the installer's own agents and fire-drills keys are cut from a widened list (invariant 53, amending 47). A second run no longer adds them; an upgrade removes them unless STATIC_KEY_IDS names them, and the closing report says so.
  • The broker's key line is <secret>:broker everywhere, and ADD_BROKER_KEY=1 adds it (invariant 48). The refusal names both ways out.
  • A re-run whose keys are kept in .env is refused by name, not by a shell error (invariant 48, D14). With agent tokens on and no CLIENT_KEYS_FILE named, the check read the unset variable, stopped on a shell error and printed the refusal meant for a box that gave a keys file; with ADD_BROKER_KEY=1 it wrote .env before stopping. 1.3.1 refused the same box cleanly.

Measured

  • forge, 2026-10-19, upgrade 1.1.35 to 1.3.1: the broker line refusal (logs 19 to 31); the gateway's journal and typryx's ledger left with an earlier uid (logs 31 to 35); the FinOps console still on image v0.6.0 after the upgrade; the second install run widened the allow-list to the agents' and drills' keys.
  • gcp2, 2026-10-19, a fresh 1.3.1 box: the FinOps console started with "permission denied" on open of its own stream (its logs 13b).
  • The gates: broker-key-is-the-keys-file-line.sh, volumes-are-reowned.sh, profiles-off-are-removed.sh, record-plane-is-on-by-default.sh, costcrew-can-reach-its-stream.sh, and agent-tokens-are-wired.sh extended with a two-run section and a section for a .env that a 1.3.1 re-run widened. Each of those gates was run red on 1.3.1, before its fix, and failed for the stated reason. The new teeth cases ran against the fixed tree, where each planted fault goes red.
  • forge, 2026-10-25, on 1.3.1: the FinOps console v0.10.0 ran once the bus directory was 0751; set back to 0750 it stopped on "permission denied" on open, 7 restarts in 12 seconds.
  • forge, 2026-10-25, the first live run of this installer, upgrading 1.3.1 to 1.4.0. From the main of that day it stopped on D14 before writing anything. From the fixed tree a plain run refused by name, with .env and the running containers unchanged. With WITH_AGENT_TOKENS=0, the box's setting since 1.3.1, the upgrade ran: 56 checks ok, none failed; record-seal started on trailryx-node 1.4.0 and sealed a pack of 633 records in 4 segments, which its own check reports VERIFIED (unsigned: the root has no keyryx signature yet); the running FinOps console was kept at its pinned image and opened its stream (bus directory 0751, its stream 10003:10001 0640); no container restarted. A second run: 56 ok, none failed, no container recreated, .env unchanged.
  • broker-key-is-the-keys-file-line.sh case F was red on the main of 2026-10-25 (10 problems, among them CLIENT_KEYS_FILE: unbound variable) and green on the fix; its teeth case removes the guard and the gate goes red.

Not measured

  • The upgrade with agent tokens on, on a box with its own keys: forge ran it with WITH_AGENT_TOKENS=0, as it has run since 1.3.1. gcp2 was not run for this release.
  • A record pack signed by keyryx: the forge pack is unsigned. Whether the record plane seals typryx's four event types was not checked in that pack.
  • An operator-started container re-upped at this run's pins is measured by the cleanup gate's stub only. Compose recreates a container whose configuration changed, which a digest pin does change, and no gate measures that on a live stack; on forge the FinOps console already ran at this release's pin, so that path was not exercised. A re-up that fails stops the run and names the service.
  • The DPoP door origins (TODO(1.4.0, D13) in install.sh): the gateway still accepts a proof for one origin only. The setting that lists them is not in any tokenfuse release this pin reads, and this release does not wait for it.

stack-single 1.3.1

Choose a tag to compare

@TAIPANBOX TAIPANBOX released this 19 Oct 18:57
b733655

stack-single 1.3.1

A patch for the upgrade from 1.1.x, and for any box that holds a provider key. Upgrading a box with Felyx configured to 1.2.0 or 1.3.0 left the gateway and wardryx restarting in a loop; this release lets that upgrade through, and makes the one change that decides who pays an explicit choice.

Upgrade first

  1. If .env has GENARYX_COPILOT_KEY (Felyx's key from before 1.2.0) and you give no key file, the installer now stops before changing anything. Since 1.2.0 the gateway holds the provider key and pays for every agent's calls with it, and refuses an agent that sends its own key. 1.2.0 and 1.3.0 moved Felyx's key there without asking. Choose one:
    • let the gateway hold it: GATEWAY_HOLDS_COPILOT_KEY=1 ./install.sh (the .env value is moved into ./upstream/anthropic/key, never printed), or ANTHROPIC_KEY_FILE=<a file holding the key> ./install.sh;
    • or keep each caller paying with its own key: remove the GENARYX_COPILOT_KEY line from .env. Felyx then has no model until a key file is given.
  2. A key file that 1.2.0 or 1.3.0 already wrote is kept, and is now owned by its door's own user. Nothing to do.
  3. Then re-run ./install.sh as for 1.3.0; its Upgrade section still applies.

What changed

  • Each door's provider key file is owned by the user that door runs as (uid 20010 for the gateway, 20011 for the OpenAI door), mode 0400. 1.2.0 and 1.3.0 wrote it for uid 10001, so the gateway could not read it ("TOKENFUSE_UPSTREAM_KEY_FILE cannot be used: Permission denied") and did not start. Every run now re-owns an existing file to its door.
  • Who pays is never changed in silence. Felyx's old key is moved into the gateway's file only on GATEWAY_HOLDS_COPILOT_KEY=1; with neither that nor ANTHROPIC_KEY_FILE, a box holding only that key stops before anything is written and says why.
  • wardryx reads its policy archive after the upgrade. The archive directory was re-owned to wardryx's user but the files already in it were not, so wardryx stopped on "permission denied" reading its own archive. The directory is now re-owned with its contents.
  • The gate scripts/no-provider-key-outside-the-gateway.sh reads each door's uid from compose.yaml instead of requiring uid 10001, which is how the wrong owner passed every check. Four teeth cases, two scenarios.

Measured

  • forge, 2026-10-19, an upgrade from 1.1.35 to 1.2.0: the gateway refused to start on the key file's owner, wardryx restarted on its archive, and the box was rolled back to 1.1.35 from its backups. A fresh 1.3.0 install on a GCP VM given ANTHROPIC_KEY_FILE failed its gateway checks the same way.

Not measured

  • The 1.1.35 to 1.3.1 upgrade on forge, which is the next step of the run that found these.

stack-single 1.3.0

Choose a tag to compare

@TAIPANBOX TAIPANBOX released this 19 Oct 17:42
02fdd82

stack-single 1.3.0

This is a minor release, not a patch. The default credential changes: agent tokens are required, a static client key is admitted only when its id is named on a list, and vouchryx starts on every box. A re-run keeps the static keys a box already had, so an agent that worked before keeps working until it moves to a token. The release also pins tokenfuse v1.19.0 and four other components to their 2026-10-19 releases.

Upgrade first

1. Re-run ./install.sh on every existing box, once. Until that re-run, a box keeps its current compose file, images and .env. The re-run writes the new pins, turns agent tokens on, starts vouchryx and prints the static-key list described in item 2.

2. Agents with static keys keep working through the re-run, and should move to tokens. The installer keeps every static key id the box already had. The closing report prints them under "static keys still admitted; move these agents to tokens", so that list is the set of agents to move. A fresh box lists felyx and broker, the two clients that cannot sign a proof. Moving an agent to a token takes it off the list. Today one agent per box can be enrolled for a token (agent://<RECORD_TRUST_DOMAIN>/agents/operator, its secret in $STACK_DIR/agent-token.key), because vouchryx reads its registry from one variable. Other agents stay on the list until that changes.

3. A new static key needs STATIC_KEY_IDS. Name its key id in STATIC_KEY_IDS (comma-separated). Without the name its calls are refused 401 agent_token_required. The installer refuses a name that is not one of the box's own keys. A box given its own CLIENT_KEYS_FILE must also add a broker:<secret> line, bound in its identity map, or run with WITH_AGENT_TOKENS=0. Without one of those the installer refuses before it installs anything.

4. WITH_AGENT_TOKENS=0 is the weaker way back. It writes TOKENFUSE_AGENT_TOKENS=off, clears both static-key lists and leaves every file in place. The closing report calls it the weaker setting, because static keys are then the only credential. Use it to step back, then move the agents to tokens.

5. vouchryx runs by default. With agent tokens on, the installer starts vouchryx, enrols the operator agent and writes its enrolment secret to $STACK_DIR/agent-token.key (mode 0600). The secret is never printed and never written to .env. vouchryx publishes no port. A box that does not want it runs WITH_AGENT_TOKENS=0.

6. The tokenfuse-cloud state rewrite is one-way. tokenfuse v1.19.0 keeps paired-device tokens as digests. The first save after the upgrade rewrites the device map, and a v1.18.0 control plane cannot authenticate devices from the new state file. To roll back, pair each device again. A device request signed before the restart, or in the same second as it, is refused once, and the device retries with a fresh timestamp.

7. The costcrew console runs with -insecure-http. costcrew 0.10.0 refuses a non-loopback listener unless it has -behind-tls or -insecure-http. The console stays published on 127.0.0.1:8321 only, so reach it through an SSH tunnel to that port.

8. The governed profile in tokenfuse v1.19.0 changes nothing on this box. The gateway and the MCP broker default to the governed profile, which sets defaults for every variable left unset. This launcher writes each of those variables in compose.yaml, so the profile changes no behaviour here. A gateway run by hand from the image, outside this launcher, takes the governed defaults unless it sets TOKENFUSE_PROFILE=observe.

9. The broker's key file changes owner. $STACK_DIR/broker/key is now owned by uid 20012 (group 10001), mode 0400, the broker's own uid. The installer makes the change, so nothing is needed by hand.

Breaking

  • Static client keys are no longer admitted by default. A static key is refused 401 agent_token_required unless its id is on the list. Migration: items 2 and 3.
  • vouchryx starts on a default box. Migration: item 5, or WITH_AGENT_TOKENS=0.
  • The tokenfuse-cloud device state is rewritten one way. Migration: item 6.

What is new, by PR

  • #142, no credential on any argument list. Closes the exposure of credentials in a process's argument list during install, in the health checks that prove a key is accepted, and in the console clone URL. Each check request now goes to a throwaway container on stdin. The console clone gives git its token through a credential helper that reads it from the environment of that one command, so the clone's .git holds no token. The shell lint refuses a function named after a common developer command. Adds invariant 46, gate scripts/no-secret-on-argv.sh and features/no-secret-on-argv.feature. Not breaking.
  • #143, agent tokens required by default. Covers a named static-key list and wardryx verifying tokens.
    • Agent tokens are on unless WITH_AGENT_TOKENS=0. The gateway and the MCP broker run TOKENFUSE_AGENT_TOKENS=require. The installer writes the static-key lists and prints them in the closing report (items 2 to 4).
    • wardryx v2.3.0 verifies the agent's token and its DPoP proof itself, against the issuer, audience, key set and revocation list the installer writes.
    • Pins: tokenfuse v1.19.0 (gateway, OpenAI door, MCP broker and control plane), wardryx v2.3.0, idryx v1.3.0, costcrew v0.10.0 and trailryx-node v1.4.0, each by tag and digest.
    • The costcrew console runs with -insecure-http (item 7). The broker's key file changes owner (item 9).
    • Invariant 47 added, invariants 14, 15 and 40 amended. scripts/agent-tokens-are-wired.sh extended. 256 scenarios across 28 feature files, each bound to a test.

Not proven

  • The install legs on a fresh Ubuntu runner (.github/workflows/install.yml): cosign verification of the new digests, the agent-token exchange at the doors, the 401 body and the door origins. CI runs them on the release pull request.
  • A box installed before this release and then re-run. The static-key lists, the new pins and the control-plane state rewrite have not been measured on an installed box.
  • The tokenfuse-cloud digest rewrite and the re-pairing on rollback, as tokenfuse measured them. Not measured on this box.
  • Trailryx 1.4.0 sealing typryx's four event types on the record plane. Not measured for this release.
  • One enrolled agent per box is the only supported shape, and a real agent framework calling the doors with its own token was not measured.
  • The costcrew console reached through an SSH tunnel.

stack-single 1.2.0

Choose a tag to compare

@TAIPANBOX TAIPANBOX released this 19 Oct 07:30
7156d09

stack-single 1.2.0

This is a minor release, not a patch. The first re-run mints client keys, starts two keyryx services, moves wardryx approvals to keyryx, moves the containers onto new networks and new uids, and refuses some values that were accepted before.

Upgrade first

1. Re-run ./install.sh on every existing box, once, before the new images take traffic. The compose file now requires GATEWAY_CLIENT_KEYS, and services run under new uids: wardryx 20001, vouchryx 20002, typryx 20005, the gateway planes 20010 to 20013, keyryx 20100 and 20101. The gateway's policy-plane key is rewritten from viewer to pep. A box that is not re-run has no client key in .env, and docker compose up stops at the missing key. ./install.sh status says the same and names the fix.

2. Client keys are required, and agents must send one. The installer mints a key for Felyx (GENARYX_COPILOT_FUSE_KEY in .env) and one for the operator's agents ($STACK_DIR/agent-key, mode 0600, never printed). An agent must send x-fuse-key with an agent id under agents/, and every MCP broker tools/call needs x-fuse-agent-id. To bring your own keys, give CLIENT_KEYS_FILE and IDENTITY_MAP_FILE together: a map alone is refused, because its bindings would name keys the box does not have.

3. The MCP broker blocks raw secrets and flagged tool listings. A tool call that carries a raw cloud key is refused, and so is a tool listing that is flagged. The broker asks wardryx about every tool call and fails closed, so a tool the policy denies stays denied, and wardryx must be up. Agents that send raw secrets as tool arguments need to take them from the vault instead.

4. Approvals are signed through keyryx. wardryx signs approvals with keyryx by default (WARDRYX_APPROVAL_SIGNER=keyryx). An HMAC approval is refused from the switch unless WARDRYX_APPROVAL_V2_UNTIL is set to an instant at least ten minutes after the re-run. If holds granted under the old signer are still pending, set it in .env before the re-run. If none are pending, leave it unset.

5. keyryx starts on every box. keyryx (custody) and keyryx-witness run with no profile. The root keys are written once to $STACK_DIR/keyryx (mode 0400) and never replaced. An existing root key file that is empty is refused, and nothing is overwritten. Back up $STACK_DIR/keyryx, because the root key wraps custody's private keys.

6. Event streams change owner on the first re-run. Each stream is owned by the plane that writes it, mode 0640, group 10001, and no plane can create files in the bus directory. A reader outside group 10001 can no longer read a stream. To see them: docker run --rm -v agent-stack_events:/vol busybox ls -ln /vol.

7. The networks change. The default network is replaced by edge, front, core, agents and browser-policy. A container you run beside the stack that must reach an agent moves to agent-stack_agents. A hand-configured costcrew SSO needs edge added by hand. The old agent-stack_default network stays after the re-run as an orphan, and you can remove it once nothing is attached to it.

8. The gateway holds the provider key only if you give it one. ANTHROPIC_KEY_FILE=/path/to/key ./install.sh writes the key to ./upstream/anthropic (mode 0400, uid 10001). Without it, the gateway forwards the caller's own key, as before, and says so at startup. OPENAI_KEY_FILE does the same for the OpenAI door.

9. Mail is sent over TLS. heraldyx 0.8.0 uses STARTTLS by default, and a server on port 465 selects implicit TLS by itself. A server that does not offer STARTTLS is refused, and plain is allowed only for a loopback host. Set SMTP_TLS in .env before you start if your server needs a different mode. The installer asks for the mode after the server address, and refuses a value it does not read before anything is installed.

10. The demo issuer's line gets |unbound. vouchryx 0.5.0 and later refuse a subject token with no cnf.jkt unless its issuer line ends in |unbound, and the demo IdP sends unbound tokens. A rerun with WITH_DELEGATION_DEMO_ISSUER=1 rewrites the demo line in .env and changes no other line. An operator's own VOUCHRYX_TRUSTED_ISSUERS line is never touched. Add |unbound to your own line only if your identity provider issues unbound tokens on purpose.

11. Agent tokens stay off unless you turn them on (WITH_AGENT_TOKENS=1). When they are on, the audience is one https identifier, https://stack-single.<trust domain>, shared by the gateway and the broker. An agent asks for it in its token request with resource= (RFC 8707; audience= also works). A request that names no audience is refused audience_not_allowed, because vouchryx would otherwise fall back to its own issuer, which the allow-list does not name. The agent's DPoP proof to the gateway or the broker carries ath, the hash of the token (RFC 9449). A token minted for the old http:// audience stops verifying, so the enrolled agent must exchange its secret again. Do the rerun in one restart window. A box that gave its own keys file must add a broker:<secret> line first.

12. Install needs outbound HTTPS, and every image is checked before it starts. The installer downloads cosign v3.1.3 from GitHub, checks it against a pinned SHA-256, and runs cosign verify on each TAIPANBOX image before pulling it. It needs outbound HTTPS to github.com, release-assets.githubusercontent.com, tuf-repo-cdn.sigstore.dev and ghcr.io. An image without a signature from a TAIPANBOX release workflow is refused, and nothing is started. A box that cannot reach those hosts cannot install or re-run. BUILD_FROM_SOURCE=1 builds locally and is not signed or checked, as before.

13. A downgraded typed box needs one run. A box that ran WITH_TYPED=1 with a .env that says TYPED_MODE='off', or that lost the stub on an earlier re-run, needs one WITH_TYPED=1 ./install.sh to record the stub. TYPED_MODE=off turns the stub off, and it stays off. An unknown TYPED_MODE value is refused.

14. Some trust domains are refused. RECORD_TRUST_DOMAIN may use letters, digits, dots and hyphens. Underscores are refused, and so is mockryx.local, because the fire drills' key is bound to it.

15. A compose.override.yaml you wrote is refused when TYPED_MODE is jev or own-model, because typryx then needs a route out and the installer does not overwrite a file it did not write. Move the file aside, or set TYPED_MODE=stub.

16. The pins moved. tokenfuse v1.18.0 (with the taint-gateway key file the installer writes when agent tokens are on), tokenfuse-control-plane v1.18.0, vouchryx v0.6.0, wardryx v2.2.1, idryx v1.2.2, keyryx v0.1.1, agent-conform v2.0.1, heraldyx v0.8.0, scopyx v1.1.0 (and chromium), typryx v0.5.0, costcrew v0.9.0, genaryx-console, stack-caddy and stack-wg v1.1.48, trailryx-node v1.3.1. Each is pinned by digest in compose.yaml and components.json. costcrew 0.8.0 names analysts agent://<host>/costcrew/<name>. This launcher binds no analyst id, so nothing needs rebinding here.

What is new, by PR

  • #131, typed stub. WITH_TYPED=1 records the stub as TYPED_MODE='stub', so a plain re-run keeps the typed plane. TYPED_MODE=off turns it off and keeps it off. See item 13.
  • #132, client keys and the broker. Keys are minted when none are given, the gateways run identity strict enforce, and the broker blocks raw secrets and flagged tool listings. Tool pinning stays off, because it needs an approved lock file. See items 2 and 3.
  • #133, pins and the pep key. tokenfuse v1.15.0, wardryx 2.0.0, vouchryx v0.3.0 and costcrew v0.7.0. The gateway's policy-plane key becomes pep, which a re-run writes. A box that is not re-run keeps viewer, and wardryx 2.0.0 then refuses it with 403, so the gateway and the broker fail closed.
  • #134, networks. Agent-facing containers sit on internal networks. edge is the only route out, and the browser is off core. See items 7 and 15.
  • #135, provider key. The gateway reads the provider key from a 0400 file that the installer writes, so no agent-facing service holds it. The fire drills' key is minted and bound to agent://mockryx.local/*. See item 8 and item 14.
  • #136, agent tokens. With WITH_AGENT_TOKENS=1, vouchryx runs, the installer mints one enrolment key per agent, and the gateway and the broker accept an agent token beside the static keys. Static keys keep working. See item 11.
  • #138, keyryx. The installer installs keyryx v0.1.0 (custody and a separate witness), writes the root keys as files, re-owns every stream to its producer at 0640, and wires wardryx approvals through keyryx. See items 4, 5 and 6.
  • #139, digest pins and signatures. Every image is pinned by digest, and every TAIPANBOX image is checked against its keyless signature before it is pulled. See item 12.
  • #140, the wave's pins. The images of the 2026-10-17 agent-security wave, the nine conflicts closed, and the demo issuer and mail TLS items above. The agent-tokens gate now checks one https audience for both doors, and the demo-issuer migration has its own gate.

#137 (an actions bump) is open and is not in this release.

Not proven

  • install.sh has not been run on a box that was installed before this release and then re-run. CI's install legs install fresh on Ubuntu. The re-owned streams, the pep rewrite, the approval switch and the network move have not been measured on an old box.
  • The approval switch and WARDRYX_APPROVAL_V2_UNTIL: the rule is written from the wardryx 2.0.0 and 2.2.0 notes. No pending HMAC hold was measured across the switch.
  • The agent-token door was measured on a compose stack, not on an installed box (see docs/evidence/agent-token-audience/RUN.md). The gateway's and the broker's live admission of a real agent framework was not measured.
  • Mail through each TLS mode against a live server. The mode values ...
Read more

stack-single 1.1.35

Choose a tag to compare

@TAIPANBOX TAIPANBOX released this 15 Oct 13:19
8b9351f

stack-single 1.1.35

The notifier moves to heraldyx v0.7.0. This tag also adds ./install.sh status, a read-only
check of a running box, and a Docker healthcheck on the four services the installer probes on
their health path. Nothing else moves: the console, TokenFuse and the other pins are the ones
v1.1.34 shipped.

A default install starts no new container. The notifier does send one new kind of mail: once a
recipient is configured, it sends a daily pulse (see below).

What moves

  • heraldyx v0.6.0 -> v0.7.0 (HERALDYX_IMAGE, the heraldyx service at compose.yaml:286,
    and components.json). heraldyx 0.7.0 is tag v0.7.0 on 6f9971d, its release notes are
    docs/releases/v0.7.0.md in that repository, and its image index digest is
    sha256:0774468fb06c78dc0172f99f6c7fb024423d52921c7051ddd0b0d684f22b9ef7 (amd64 and arm64). The
    points an operator meets:
    • A daily pulse. Once per 24 hours the notifier sends one mail that says it is running and
      gives the numbers it saw. A day with a daily summary carries the pulse in that summary instead,
      so there is still one mail, not two. It is on by default once a recipient is set. Set
      HERALDYX_PULSE_HOURS=0 in .env to turn it off; the compose file now passes the variable
      through, default 24 (compose.yaml, the heraldyx service).
    • Acknowledgements. --ack <key> --for 4h --by <name> holds alerts below critical about one
      condition for a bounded time; --unack <key> ends it and --acks lists what is in force. A
      critical is always sent.
    • Maintenance windows. --maintenance <duration> --note <text> --by <name> opens one by hand,
      with --scope <source> to hold one source only, and --maintenance-end closes it. A window
      always sends a closing mail.
    • Quiet hours (HERALDYX_QUIET, HERALDYX_TZ) are in heraldyx 0.7.0 and off by default. Set
      HERALDYX_QUIET=HH:MM-HH:MM and an IANA HERALDYX_TZ in .env to hold alerts below critical in
      those hours; the compose file passes both through, empty by default. The README section "The
      notifier's daily pulse and quiet hours" documents the three settings.
    • The acknowledgement and window commands write control.json beside the notifier's state file,
      on the heraldyxstate volume. That volume is owned by uid 65532, the user the notifier runs as
      (init-volumes, compose.yaml:68), so the file can be written.
    • No variable is required by heraldyx 0.7.0. Nothing in .env changes.
  • ./install.sh status (#128). It runs the checks the install runs at its end, against a stack
    that is already up, and prints one line per check. It exits 0 when every check passes and 1 when
    one fails. It installs nothing, pulls no image, starts, stops or restarts no container, issues no
    device and sends no mail. The checks that would write to the event bus, or send a call the stack
    records, print as skip and run only in the install. If the box has no .env, it says so and
    stops. See the README section "Checking an installed box again".
  • Healthchecks on four services (#128). Docker now watches tokenfuse-gateway,
    tokenfuse-gateway-openai (when the OpenAI door is on), tokenfuse-cloud and console. Each
    probes the same /healthz the installer probes, with bash, since those images carry bash and no
    HTTP client. docker compose ps shows healthy or unhealthy. A healthcheck only reports:
    nothing restarts a service because of it. wardryx, idryx, typryx and vouchryx have no
    healthcheck, because their images are distroless. ./install.sh status is the check that covers
    them.
  • CI (#128). Each install leg in .github/workflows/install.yml ends with install.sh status,
    and checks that the read changed nothing.
  • heraldyx pin (#129). The one HERALDYX_IMAGE pin above, merged as 4342ca6.

Measured

Read when these notes were written, not copied from the pull requests:

  • docker buildx imagetools inspect ghcr.io/taipanbox/heraldyx:v0.7.0: the index digest above,
    listing linux/amd64 and linux/arm64.
  • Tag v0.7.0 in TAIPANBOX/heraldyx resolves to 6f9971d, the merge of heraldyx #111.

Upgrading

  • The notifier. The image is the compose default, so pulling and restarting the one service
    moves it: docker compose pull heraldyx and then docker compose up -d heraldyx. The state
    file and the dispatch journal persist across the restart (heraldyx invariant 5). Rolling back
    to heraldyx 0.6.0 with a 0.7.0 state file was not run.
  • The pulse is new mail. A box with ALERT_TO set starts getting one pulse mail every 24 hours
    after the restart. The mail says the notifier is alive; its absence is the signal to look. To
    keep the old silence, set HERALDYX_PULSE_HOURS=0 in .env and restart the notifier.
  • ./install.sh status needs root, or a user in the docker group, and a .env at the stack
    directory. It changes nothing, so it is safe to run on a live box.

Not proven

  • ./install.sh status and the four healthchecks were run by CI's install legs on Ubuntu, as
    #128 and #129 record. They were not run on a live box for this tag.
  • The pulse, an acknowledgement and a maintenance window were not run in a running stack for this
    tag. heraldyx 0.7.0's own notes say what was measured for those.
  • The upgrade commands above were not run on a box for this tag.

stack-single 1.1.34

Choose a tag to compare

@TAIPANBOX TAIPANBOX released this 15 Oct 00:25
eb36b5a

stack-single 1.1.34

The console moves to genaryx-console:v1.1.46, and TokenFuse to v1.14.0 on the gateway, the
OpenAI door, the MCP broker, focus-export and the control plane. This tag carries no other
change. It also corrects one comment in compose.yaml: the note above GENARYX_COPILOT_FUSE_KEY_REF
said the pinned console ignored that reference. It reads it, since genaryx invariant 24, so the
note now says so.

A default install starts nothing new. The OpenAI door is still off unless OPENAI_DOOR=1 is set,
the MCP broker stays out of a default install, and the firewall stays in enforce.

What moves

  • genaryx-console v1.1.45 -> v1.1.46 (CONSOLE_IMAGE, the console service at
    compose.yaml:1202 and the verdryx-drift service at compose.yaml:1542, and
    components.json). Index digest
    sha256:54218cfb989f7499da3a92d52d917ef8bc67b938d1b54070ba63e88fdf164bdd (amd64 and arm64).
    The image is built by stack-k8s tag v1.1.46, from the run that finished with success
    (38656056258). The console repository publishes no GitHub release, so the commits it was built
    from are named in the image's source labels and not restated here.
  • TokenFuse v1.13.2 -> v1.14.0: the gateway (tokenfuse-gateway, compose.yaml:901), the
    OpenAI door (tokenfuse-gateway-openai, compose.yaml:1089), the MCP broker
    (tokenfuse-mcp-broker, compose.yaml:635), focus-export (compose.yaml:1444) and the
    control plane (tokenfuse-cloud, TOKENFUSE_CLOUD_IMAGE, compose.yaml:868), with
    components.json. Index digests tokenfuse:v1.14.0
    sha256:c659d9bb51ce48b1082343d9d19d64cf3ac79fde617ea59bc09720d2a4f87c65 and
    tokenfuse-control-plane:v1.14.0 sha256:673a487da6da8270cabd15d522c5608ba5008e02c0a3972a42e569a112969e77.
    Both list linux/amd64 and linux/arm64. The release is annotated tag 443f399 (PR #444) and
    a published GitHub release with 17 assets, not a draft or a prerelease. Its notes are
    docs/releases/v1.14.0.md at the tag. The points an operator meets:
    • A gateway restarted while its control plane is down answers budget-governed calls
      503 seed_pending until it has read the seed. The TokenFuse notes call this the intended
      refusal, not a fault.
    • A stream carrying a denied tool call ends with the refusal, not with the call.
    • Trace files and FOCUS exports carry new nullable columns (pii_findings, x_price_basis,
      x_pii_findings). Old files keep reading; a reader that selects columns by position must
      read by name.
    • The price book prices openai/ ids at OpenAI's list rate, so a cost charged at the fallback
      rate can change.
    • The TokenFuse upgrade is "replace the image tag with v1.14.0". This tag moves the compose
      image pins to match, and nothing else in the launcher's settings moves.
  • The compose comment above GENARYX_COPILOT_FUSE_KEY_REF. The console pinned here reads that
    reference (genaryx invariant 24, crates/api/src/copilot/state.rs at the v1.1.45 source commit
    fd7a1ab). Notes only: nothing runs differently.

No other pin moves. wardryx v1.5.0, idryx v1.2.1, heraldyx v0.6.0, typryx v0.4.1 and
trailryx-node v1.2.1 are unchanged from v1.1.33.

Measured

Read on 2026-10-15 from the registry, the releases and the source checkouts, not copied from the
notes above:

  • docker buildx imagetools inspect on genaryx-console:v1.1.46, tokenfuse:v1.14.0 and
    tokenfuse-control-plane:v1.14.0. Each index digest matches the value above, and each lists
    linux/amd64 and linux/arm64.
  • gh release view v1.14.0 in TAIPANBOX/tokenfuse: published 2026-10-14T23:28:35Z, not a draft,
    not a prerelease, 17 assets. The tag resolves to 443f399.
  • gh run view 38656056258 in TAIPANBOX/stack-k8s: the console image workflow for tag v1.1.46
    completed with success.
  • .githooks/pre-push: all 32 checks passed on the release commit, on 2026-10-15.
  • scripts/gates-have-teeth.sh on a clean tree of the release commit: OK: 394 cases, exit 0,
    on 2026-10-15.

Upgrading

  • No new switch. The launcher writes no TokenFuse switch that was not already accepted. The
    firewall switch is still ${TOKENFUSE_FIREWALL:-enforce}.
  • TokenFuse 1.14.0. Its upgrade is the image tag, v1.14.0. The operator-facing points are
    listed under "What moves" above. A gateway restarted while its control plane is down answers
    budget-governed calls 503 seed_pending until the seed is read.
  • Console v1.1.46 against v1.1.45. The console changes are the commits in the image's source
    labels, not restated here. This launcher's settings do not move for them.

Not proven

  • TokenFuse v1.14.0 in a running stack. No live provider call was made through the new images
    here. The seed gate's restart case was reproduced on one host only, per the TokenFuse notes.
  • install.sh with these pins on a box. CI's install legs run it on Ubuntu; it was not run here.
  • Console v1.1.46 in a running stack. The image exists and its pin is in place; a stack built
    from this tag has not been run here.
  • The seed_pending window has not been measured on a stack built from this tag.