Repository navigation
Releases: TAIPANBOX/stack-single
Release list
stack-single 1.4.4
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
- Run
./install.shagain 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. - TokenFuse 1.20.2, included in 1.20.3, prices
gpt-6.1-terraat 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 thex-fuse-priceresponse header no longer saysfallbackfor it. Nothing to configure. A row for the model inTOKENFUSE_PRICE_BOOKstill wins over the built-in row; this launcher does not set that variable. - 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 anidentity_mismatchevent (severity high) to the bus for a call with an unknown client key (reasonunknown_key, with asha256:fingerprint of 16 hex digits, never the key) and for a call with no key (reasonmissing_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 highidentity_mismatchevents 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. - trailryx 1.5.0 changes nothing on a stock install. The seal signs only when
TRAILRYX_SIGNERis set, and this launcher does not set it, so the record seal runs as before. A node withTRAILRYX_SIGNER=keyryxand noTRAILRYX_KEYRYX_KIDnow 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. - 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-sysmoves 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 anidentity_mismatchevent (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.mdis unchanged.
Checked locally
- Each new digest was read from the registry with
docker buildx imagetools inspecton 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 grepfinds no old tag or digest outsidedocs/releases/.- 49 of the 54 gates in
.github/workflows/gates.yml(every one exceptgates-have-teeth, which is listed under Not measured) pass on this Mac, including the newno-key-in-a-messagegate. 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 thegolang:1.27.3orgolang:1.27.3-alpinetags 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-terraprice 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.shrun 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
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
- Run
./install.shagain 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. - 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. - TokenFuse 1.20.0, which this release passes through, requires
TOKENFUSE_DELEGATION_URLto be an origin.install.shwriteshttp://$GATEWAY_PROBE:4100, an origin with no path, so nothing changes here. 1.20.0 also readsTOKENFUSE_DELEGATION_ORIGINSandTOKENFUSE_MCP_PROOF_ORIGINSfor 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.yamlandcomponents.json(#155): the gateway imagesha256:8de459eca2a10ae36a01d0249b91c3b0c62b50b47ad2c4a309e2ea02e0a460dd, the control planesha256:157d5801367674e7af8625b391fba8e26e3b72fe95dcb5e435cebee5555fa92a. Each is an amd64 and arm64 manifest list with a cosign signature, and the gateway image's build provenance names commit27a0a2fatrefs/tags/v1.20.1of 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 top2560.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 status49 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(agentagent://home.taipanbox.dev/agents/operator,BUDGET_USD=0.000001): 10 of 10 expectations held, among them a singletools/callthrough 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 asReplayed). - 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
routinesprofile, 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
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
- Run
./install.shagain 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. - 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 with403 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 setWARDRYX_APPROVER_JWKS, so approvals decided with a key work as before. - 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 ownkeyryxalertsvolume, 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. - 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
chmodin keyryx'sdocs/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.jsonandinstall.sh(#153). Every one was built ongolang:1.27.3orgolang:1.27.3-alpine, read from its build provenance. The teeth cases, the image-verify fixtures,scripts/typed-data-mode.shand 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 status49 ok. A second run: 59 ok, no container recreated,.envunchanged. - Agent tokens on the same box with wardryx 2.4.1, using
docs/evidence/agent-token-audience/measure.sh(agentagent://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 brokertools/call, eachpolicy_allowwith attestationdpop-key, and noagent_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
402at the budget step), the second was refused at the gateway's own door (401 agent_token_refused, logged asReplayed), 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
chmodof 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
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
- A box with its own identity map must bind the enrolled agent in unit
agents. vouchryx enrolsagent://<trust domain>/agents/operatorin unitagents, 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 idagents, akeys[]entry with key idagents, unitagentsand agentsagent://<trust domain>/agents/*, and a matching<secret>:agentsline 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. - A box with agent tokens on whose gateway is published on one address (
GATEWAY_BINDin.env): run./install.shagain. 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. - 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=1installs 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_URLand wardryx's door origins from the bind this run started with, before.envwas read, so a re-run with nothing in the environment named loopback. The block now takes the bind from.envfirst. - 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.1on a box published on192.168.1.10; a valid token was refused401at the gateway (Token(WrongKey)in its log), and a proof addressed to127.0.0.1passed the token door. D17: with the broker-only binding the gateway answered a valid token403 unit_contradicts_map. - forge, the same day, the tree of this release, its own files carrying the
agentsbinding and nothing in the environment but the two file names: 59 installer checks ok, none failed; the origins named192.168.1.10; no container recreated or restarted; the sorted content of.envunchanged.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 (402at the budget step) and at the broker, and a typedtools/callwas answered. A tampered token was refused401at both doors. - Red first:
broker-key-is-the-keys-file-line.shcases C (D15, the keys checked held onlyfelyx) and G (D17, the map was accepted), andagent-tokens-are-wired.shsection K (D16,http://127.0.0.1:4100for a box bound to192.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=1end 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
.envand 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)ininstall.sh): the gateway still accepts a proof for one origin only, so on a box whose origin is its LAN address, a proof addressed tohttp://tokenfuse-gateway:4100by an agent on the agents network does not match it. Read from the code, not run.
stack-single 1.4.0
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
- The record plane now starts on every box that does not set
WITH_RECORD=0. It is a core control and runs the pinnedtrailryx-nodeimage, with no build. A box that must stay without it runsWITH_RECORD=0 ./install.sh, and that run stops and removesrecord-sealif it was running. - Installer-managed profiles this run turns off lose their containers; operator-started profiles keep theirs.
record,typed,typed-risk-signal,delegationandopenai-doorare 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,routinesandmanualare 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. - A box given its own
CLIENT_KEYS_FILEmust 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 wordbroker), bound in your identity map toagent://<trust domain>/agents/*. Or runADD_BROKER_KEY=1 ./install.sh, and the installer mints the secret and appends that line, keeping the file's mode, once the identity map bindsbroker. Without one of those the installer refuses before it writes anything. The README saidbroker:<secret>before this release; that form was never read. A box whose keys an earlier run took from its keys file keeps them in.envand 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 (withADD_BROKER_KEY=1if the file has no broker line yet), or runWITH_AGENT_TOKENS=0. - 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 refused401 agent_token_required. - 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 -Reach 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=1no longer builds trailryx from source; onlyBUILD_FROM_SOURCE=1does. - 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_IDSnames them, and the closing report says so. - The broker's key line is
<secret>:brokereverywhere, andADD_BROKER_KEY=1adds it (invariant 48). The refusal names both ways out. - A re-run whose keys are kept in
.envis refused by name, not by a shell error (invariant 48, D14). With agent tokens on and noCLIENT_KEYS_FILEnamed, the check read the unset variable, stopped on a shell error and printed the refusal meant for a box that gave a keys file; withADD_BROKER_KEY=1it wrote.envbefore 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, andagent-tokens-are-wired.shextended with a two-run section and a section for a.envthat 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
.envand the running containers unchanged. WithWITH_AGENT_TOKENS=0, the box's setting since 1.3.1, the upgrade ran: 56 checks ok, none failed;record-sealstarted 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,.envunchanged. broker-key-is-the-keys-file-line.shcase F was red on the main of 2026-10-25 (10 problems, among themCLIENT_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)ininstall.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
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
- If
.envhasGENARYX_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.envvalue is moved into./upstream/anthropic/key, never printed), orANTHROPIC_KEY_FILE=<a file holding the key> ./install.sh; - or keep each caller paying with its own key: remove the
GENARYX_COPILOT_KEYline from.env. Felyx then has no model until a key file is given.
- let the gateway hold it:
- 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.
- Then re-run
./install.shas 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 norANTHROPIC_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.shreads each door's uid fromcompose.yamlinstead 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_FILEfailed 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
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_requiredunless 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
.githolds no token. The shell lint refuses a function named after a common developer command. Adds invariant 46, gatescripts/no-secret-on-argv.shandfeatures/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 runTOKENFUSE_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.shextended. 256 scenarios across 28 feature files, each bound to a test.
- Agent tokens are on unless
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
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=1records the stub asTYPED_MODE='stub', so a plain re-run keeps the typed plane.TYPED_MODE=offturns 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 keepsviewer, 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.
edgeis the only route out, and the browser is offcore. 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.shhas 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 ...
stack-single 1.1.35
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, theheraldyxservice atcompose.yaml:286,
andcomponents.json). heraldyx 0.7.0 is tagv0.7.0on6f9971d, its release notes are
docs/releases/v0.7.0.mdin 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=0in.envto turn it off; the compose file now passes the variable
through, default24(compose.yaml, theheraldyxservice). - Acknowledgements.
--ack <key> --for 4h --by <name>holds alerts below critical about one
condition for a bounded time;--unack <key>ends it and--ackslists 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-endcloses 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:MMand an IANAHERALDYX_TZin.envto 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.jsonbeside the notifier's state file,
on theheraldyxstatevolume. 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
.envchanges.
- A daily pulse. Once per 24 hours the notifier sends one mail that says it is running and
./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 asskipand 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-cloudandconsole. Each
probes the same/healthzthe installer probes, with bash, since those images carry bash and no
HTTP client.docker compose psshowshealthyorunhealthy. A healthcheck only reports:
nothing restarts a service because of it.wardryx,idryx,typryxandvouchryxhave no
healthcheck, because their images are distroless../install.sh statusis the check that covers
them. - CI (#128). Each install leg in
.github/workflows/install.ymlends withinstall.sh status,
and checks that the read changed nothing. - heraldyx pin (#129). The one
HERALDYX_IMAGEpin above, merged as4342ca6.
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,
listinglinux/amd64andlinux/arm64.- Tag
v0.7.0inTAIPANBOX/heraldyxresolves to6f9971d, 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 heraldyxand thendocker 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_TOset 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, setHERALDYX_PULSE_HOURS=0in.envand restart the notifier. ./install.sh statusneeds root, or a user in thedockergroup, and a.envat the stack
directory. It changes nothing, so it is safe to run on a live box.
Not proven
./install.sh statusand 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
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, theconsoleservice at
compose.yaml:1202and theverdryx-driftservice atcompose.yaml:1542, and
components.json). Index digest
sha256:54218cfb989f7499da3a92d52d917ef8bc67b938d1b54070ba63e88fdf164bdd(amd64 and arm64).
The image is built by stack-k8s tagv1.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 digeststokenfuse:v1.14.0
sha256:c659d9bb51ce48b1082343d9d19d64cf3ac79fde617ea59bc09720d2a4f87c65and
tokenfuse-control-plane:v1.14.0sha256:673a487da6da8270cabd15d522c5608ba5008e02c0a3972a42e569a112969e77.
Both listlinux/amd64andlinux/arm64. The release is annotated tag443f399(PR #444) and
a published GitHub release with 17 assets, not a draft or a prerelease. Its notes are
docs/releases/v1.14.0.mdat the tag. The points an operator meets:- A gateway restarted while its control plane is down answers budget-governed calls
503 seed_pendinguntil 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.
- A gateway restarted while its control plane is down answers budget-governed calls
- The compose comment above
GENARYX_COPILOT_FUSE_KEY_REF. The console pinned here reads that
reference (genaryx invariant 24,crates/api/src/copilot/state.rsat 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 inspectongenaryx-console:v1.1.46,tokenfuse:v1.14.0and
tokenfuse-control-plane:v1.14.0. Each index digest matches the value above, and each lists
linux/amd64andlinux/arm64.gh release view v1.14.0inTAIPANBOX/tokenfuse: published 2026-10-14T23:28:35Z, not a draft,
not a prerelease, 17 assets. The tag resolves to443f399.gh run view 38656056258inTAIPANBOX/stack-k8s: the console image workflow for tagv1.1.46
completed with success..githooks/pre-push: all 32 checks passed on the release commit, on 2026-10-15.scripts/gates-have-teeth.shon 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 calls503 seed_pendinguntil 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.shwith 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_pendingwindow has not been measured on a stack built from this tag.