Skip to content

Releases: jannotix/zcode-cycle-plugin

Cycle for Zcode 1.0.12

Pre-release

Choose a tag to compare

@jannotix jannotix released this 23 Sep 23:29

Cycle for Zcode 1.0.12

Governed delivery for ZCode: an architect plans, an executor implements inside an
isolated worktree, two independent reviewers judge the frozen candidate, and an
arbiter decides - with every gate result and verdict written to a hash-chained,
signature-checkpointed ledger.

1.0.12 closes what the 1.0.11 live campaign left open.

Fixed

  • A request that named credential material was routed to quick. The
    router kept its own short word list and missed a request that asked for an
    sk_live_ literal, so the independent security review of full never ran. It
    now consults the secret-scan gate's own credential table, matches plurals, and
    covers passwords, private and signing keys and access, bearer and refresh
    tokens.
  • /cycle:doctor described workflows it had no information about. The
    doctor result now lists the project's recent workflows with nextOperations,
    found by trying each operation on a copy of the state machine, and the command
    reports those fields verbatim. A cancelled workflow can no longer be called
    resumable.
  • /cycle:goal did not say how to drive a goal. cycle_goal publishes every
    operation's fields, bound to the Rust type by a test; the command documents
    each call and the lifecycle; goal status lists the arbitration receipt
    digests approve_completion accepts.
  • /cycle:setup remove reported pin drift for the profiles it had just
    deleted.

The published-release gate now also refuses a release marked stable without a
valid live-certification receipt. See the
changelog.

Artifacts

Built and sealed by release-candidate run 35908223733 from 64a23f4; the
certification battery passed 20/20 on Windows 11 x64 and Ubuntu 22.04, and clean
installs passed on Windows 11, Ubuntu 22.04 and Ubuntu 24.04. Tag v1.0.12 is
signed by 29CB2E3FA61B8A2FFE97BF87CC4D1A39CE15684F and points at the commit that
imports these exact daemons.

Not yet claimed

Until 1.0.12 has been carried through the thirteen-scenario live campaign against
this exact archive, it is a sealed and reproducible candidate rather than a
certified release, and it is marked as a pre-release for that reason. 1.0.11
remains the certified stable release.

Cycle for Zcode 1.0.11

Choose a tag to compare

@jannotix jannotix released this 23 Sep 10:57

Cycle for Zcode 1.0.11

Governed delivery for ZCode: an architect plans, an executor implements inside an
isolated worktree, two independent reviewers judge the frozen candidate, and an
arbiter decides - with every gate result and verdict written to a hash-chained,
signature-checkpointed ledger.

1.0.11 lets an update replace the daemon it is updating. It carries every fix
in 1.0.10
and adds one that 1.0.10's own campaign found in its first step.

Fixed

An update could not replace the daemon it was updating. The daemon outlives
ZCode sessions, so after updating from the Plugin Marketplace the previous
version's daemon is usually still running. 1.0.10, installed as an update over a
running 1.0.9, received "workflowd 1.0.9 is incompatible with plugin 1.0.10"
and tried to stop it through a workflowd.pid file that nothing has ever
written. The old daemon kept the data directory, every new one failed to start,
and every Cycle call ended in "workflowd did not become healthy within 15
seconds"
. The history was untouched throughout: with the old daemon stopped by
hand, 1.0.10 verified all 162 ledger entries and both checkpoint signatures
from 1.0.9.

The bridge now finds the daemons serving its data directory - a workflowd
process whose --data-dir is exactly that directory - and stops one older than
itself. It never stops a newer one, and says so. A version mismatch is reported
at once rather than after a fifteen-second wait. The qualification battery now
also stops the daemons its hook starts; it had been leaving one per iteration.

If you installed 1.0.10 over 1.0.9 and Cycle does not respond, stop the old
daemon once (Stop-Process -Name workflowd, or restart Windows) or update to
1.0.11, which does it for you.

Also in this release, from 1.0.10

A secret-scan gate that read names and never values; a verification abandoned by
any gate that could not start; a freeze refusal that told the run to revert the
operator's project; per-role model assignment blocked by its own documentation,
now documented with the URI-encoded provider form and third-party models; the
disabled reasoning level; the provider recorded as ZCode resolves it; and
ZCode's own .zcodeignore kept out of the freeze. See the
changelog.

Windows: the daemon is unsigned, and will stay so

workflowd.exe is not Authenticode signed and no release will be. The README
section Windows SmartScreen and the unsigned daemon explains how to verify this
download (checksum below, then gh attestation verify), how to let Windows run
it, where the daemon runs from, and what Smart App Control does not allow.

Verification

Rust 309 tests on Windows and 308 on Linux with no failure, MCP 49,
qualification 30, clippy and cargo fmt clean. The deterministic qualification
battery passed 20/20 on both platforms. Built, sealed, clean-installed on Ubuntu
22.04, Ubuntu 24.04 and Windows 11, and attested with build provenance by
release-candidate run 35849686091 from b1536e2; the CI-built daemons are
imported in bc6e179, the commit the signed tag v1.0.11 names.

artifact SHA-256
zcode-cycle-1.0.11.zip 966a1ca97c1c78a1e6c44f535254533f177aa09e846d47a51bfc4eb83a864f20
zcode-cycle-native-linux-x64-1.0.11.tgz 3d4089cadd5f1749f0797445cce7882f750cf01c86483954cfca2057e05b0500
zcode-cycle-native-win32-x64-1.0.11.tgz 187706907f53cb8d0b2619f76d17890023cecf4d9ad9c15ce00f84b8d7a92818

Live certification

1.0.11 passed all thirteen scenarios of the live campaign on Windows 11 x64,
ZCode Desktop 3.14.3.7762 with its bundled CLI 0.16.9, installed from this exact
archive through the Plugin Marketplace. The campaign included a real update from
a running 1.0.10 with no manual step, a hard kill and resume, a forced repair, a
schema-forward-compatibility check, uninstall and reinstall over preserved
history, and per-role models on both Z.ai and a third-party provider.

The signed receipt, its signature and every piece of evidence it names are
attached as zcode-live-certification-1.0.11.tgz. To check them yourself:

gh release download v1.0.11 --repo jannotix/zcode-cycle-plugin --dir release
tar -xzf release/zcode-live-certification-1.0.11.tgz -C receipt
gpg --import docs/releases/release-signing-key.asc
node scripts/release/verify-zcode-live-receipt.mjs --receipt receipt/zcode-live-certification.json --signature receipt/zcode-live-certification.json.asc --signer-fingerprint 29CB2E3FA61B8A2FFE97BF87CC4D1A39CE15684F --sealed release

The published-release workflow runs the same check and refuses a release marked
stable without it.

Linux x64 is certified by CI (the 20-iteration battery on Ubuntu 22.04 and clean
installs on Ubuntu 22.04 and 24.04); the live ZCode campaign ran on Windows only.

Cycle for Zcode 1.0.10

Pre-release

Choose a tag to compare

@jannotix jannotix released this 23 Sep 09:26

Cycle for Zcode 1.0.10

Superseded by 1.0.11 - do not update to this version from 1.0.9. An
update leaves the 1.0.9 daemon running, and 1.0.10 cannot stop it: every Cycle
call then fails with workflowd did not become healthy within 15 seconds. If
you already updated, stop the old daemon (Stop-Process -Name workflowd, or
restart Windows); your history is intact. 1.0.11 fixes this.

Governed delivery for ZCode: an architect plans, an executor implements inside an
isolated worktree, two independent reviewers judge the frozen candidate, and an
arbiter decides - with every gate result and verdict written to a hash-chained,
signature-checkpointed ledger.

1.0.10 closes what the first fully isolated live campaign found. 1.0.9 was
carried through all thirteen scenarios of that campaign on ZCode Desktop
3.14.3.7762, and passed every one. Passing is not the same as finding nothing:
the campaign found the defects below, several of them only because a scenario
exercised a path no test had put two components through together.

Fixed

The secret-scan gate read the name and never the value. A Stripe-shaped live
key asked for inline went into two files, and the mandatory scan reported no
credential-like content: the rule matched a handful of assignment names, and the
key sat under a camelCase name and after ||. Worse, the security reviewer saw
the literal and cleared it because the scan had passed. The gate now also reads
the value: a quoted literal carrying a conventional credential prefix, or a PEM
private key block, is refused wherever it appears on a changed line.

A gate that could not start abandoned the whole verification. A planned
command whose program does not exist (start is a cmd.exe builtin) was recorded
as a failed gate with no exit code; the evidence validator refused that pairing,
and the refusal surfaced as "candidate evidence identifiers do not match the
plan"
- false, and it sent the run chasing it. A failure may now carry no exit
code, and a refused record names the gate and the rule.

A freeze refusal told the run to revert the operator's project. Told to
"commit or revert the project", an orchestrator that cannot commit deleted an
untracked file it had not created. The refusal and the orchestration skill now
say the project directory belongs to the operator and no role may touch it.

Per-role models were blocked by their own documentation. Since 1.0.7 the code
accepts any well-formed model reference; the command text and manual still listed
three and refused the rest, and the orchestrating model obeyed the text. The
documentation now describes the real format, including the URI encoding ZCode
requires for a provider id that contains a colon
(custom:account%3Azai-individual-coding-plan:GLM-5.3) and a third-party model
(custom:minimax:MiniMax-M3). The campaign ran the arbiter on each while every
other role ran on the session's model, proven from the host's own model logs.
The disabled reasoning level is now accepted, and the ledger records the
provider as ZCode resolves it.

ZCode's own search-index file blocked the next freeze. .zcodeignore, written
by the host when its search palette opens, is now kept out of the project's
change set the same way the role profiles are.

Windows: the daemon is unsigned, and will stay so

workflowd.exe is not Authenticode signed and no release will be. SmartScreen,
Defender or Smart App Control may object. The README section Windows
SmartScreen and the unsigned daemon
explains how to verify this download
(checksum below, then gh attestation verify), how to let Windows run it, where
the daemon actually runs from, and what Smart App Control does not allow.

Verification

Rust 309 tests on Windows and 308 on Linux with no failure, MCP 46,
qualification 30, clippy and cargo fmt clean. The deterministic qualification
battery passed 20/20 on both platforms in CI, and 20/20 again locally on
Windows against the shipped daemon. Built, sealed, clean-installed on Ubuntu
22.04, Ubuntu 24.04 and Windows 11, and attested with build provenance by
release-candidate run 35840484393 from 45ea243; the CI-built daemons are
imported in cd9bab1, the commit the signed tag v1.0.10 names.

artifact SHA-256
zcode-cycle-1.0.10.zip f5bbbc1b2628974f10f7ee81a5f33cfb1a89755b19d0876c8b41cb7b103a6be1
zcode-cycle-native-linux-x64-1.0.10.tgz c0be90ae06ed3db16926d219ad8c16a9c21c51591709368eecd8ae33c9426fec
zcode-cycle-native-win32-x64-1.0.10.tgz 3911ea1168a01091a034c3547562e68c9e1b1e8a33f1855389ad4d508fd029cc

Not yet claimed

The daemon and the MCP bridge changed, so the 1.0.9 campaign does not cover these
bytes. Until 1.0.10 has been carried through the thirteen-scenario live campaign
against this exact archive, it is a sealed and reproducible candidate rather than
a certified release, and it is marked as a pre-release for that reason.

Cycle for Zcode 1.0.9

Cycle for Zcode 1.0.9 Pre-release
Pre-release

Choose a tag to compare

@jannotix jannotix released this 22 Sep 05:49

Cycle for Zcode 1.0.9

Governed delivery for ZCode: an architect plans, an executor implements inside an
isolated worktree, two independent reviewers judge the frozen candidate, and an
arbiter decides - with every gate result and verdict written to a hash-chained,
signature-checkpointed ledger.

1.0.9 changes no product code. It exists to stop shipping a security
statement that 1.0.8 carried and that direct observation refuted.

1.0.8's threat model said that because ZCode CLI 0.16.9 does not execute
plugin-provided agent components, /cycle:setup install writes five managed
profiles explicitly. It promised to re-establish that premise by observation
before any receipt asserted it. The observation was made, on Desktop
3.14.1.7714 / CLI 0.16.9, and it went the other way: the host does read
the agents/ directory this archive ships - by convention, with the manifest
declaring no agents key - and lists all five roles under Settings > Subagents
as dispatchable, their tool lists parsed, with a model and reasoning level of the
host's own. Assume the roles are reachable from any session, not only from a
governed run.

This is a documentation defect, not a hole, which is worth saying plainly
because it first looked like one. The definitions the host reads are the
managed role profiles, carrying the same bounded tools: lists, and the host's
built-in general-purpose subagent already holds every tool - so exposing
Cycle's roles adds nothing a session could not already do. What was wrong was the
stated reason for writing project profiles. The real one was already recorded
in the plugin's own hooks configuration: a dispatched role is bounded by the tool
list in its profile, because the host does not run PreToolUse inside a
dispatched agent. Hooks guard the main session; the profile guards the role.

The marketplace contract asserted the same falsehood as its rationale for keeping
agents out of the manifest. Keeping it out is still right - declaring it would
add a second, divergent source for the same definitions - and the assertion now
says that instead.

The seven fixes below are unchanged from 1.0.7 and 1.0.8. They were found by
running the thirteen-scenario live campaign against 1.0.6's published archive
on Windows and in WSL. Eleven scenarios passed; the two that failed are the first
two. The seventh was found in the release machinery while shipping them.

Fixed

A per-role model assignment is usable, not merely configurable. /cycle:models
accepted exactly three model references, all under one provider prefix, and reported
them as applied with no warning. All three failed at dispatch with
provider-not-found — on the provider prefix, not the model name — because the
host resolves providers under a namespace the plugin refused to accept. The only
setting that worked was inherit, which is the absence of the feature the product is
named for, and the failure surfaced at the review phase, after an architecture, an
execution and five verification gates had been paid for. A plugin cannot enumerate a
host's providers and has no business deciding which ones exist: Cycle now validates
the shape of a reference and leaves resolution to ZCode. What it owes the operator
instead is an early answer, so a pinned role is reported as dispatch_unverified and
the run protocol probes every pin before a workflow starts. An unresolvable provider
now costs seconds.

Every receipt written by 1.0.6 and earlier therefore records a run in which architect,
executor, both reviewers and the arbiter shared one model — independent prompts and
tool lists, one judgement. Those receipts do not imply the wider claim.

An abrupt stop no longer leaves a workflow unrecoverable and the project locked.
Recovery required a worktree to exist on disk if and only if a base revision had been
recorded. A session killed between those two writes broke the invariant, and recovery
refused outright. Refusing was wrong twice over: recovery only reads — the guards that
matter live on prepare_worktree and freeze, and they still hold — and the refusal
returned before the immutable request text was assembled, withholding the one thing an
interrupted operator cannot reconstruct exactly when it was needed. Meanwhile the
mutation lock kept the project read-only, including for an unrelated delivery already
sitting uncommitted. Recovery now names the inconsistency, returns a recovery action,
and hands back everything it knows.

One project directory can no longer carry two identities. project_key was
whatever the calling agent chose to pass, and the run protocol only described it as
"this workspace's stable project key". It was neither. The server now derives it
canonically from the directory and ignores what the caller sends.

/cycle:setup install no longer deadlocks the first governed run. It left managed
role profiles visible to git, so the first freeze saw a dirty tree it had itself
created. They are excluded now, and the report says so rather than leaving the
operator to discover it.

Risk routing sees the code a change touches. No path could raise Authentication,
Authorization, Cryptography or Secrets: only the request text could, and only by
literal marker. A change to auth.js therefore routed to quick — no independent
reviews — unless the author happened to write "authentication" in their request. The
campaign demonstrated exactly that, twice, on the same fixture. Paths now raise a
category on their own, matched as whole tokens so auth.js counts and authors.md
does not, with documentation taking precedence over everything else.

The uninstall documentation named the wrong directory. It said ZCode keeps the
marketplace's cached copy of the plugin. That cache is emptied completely. What
remains is ZCode's mirror of the marketplace source under
plugins/marketplaces/<marketplace>/, and it is larger than the installation was,
because it carries every platform's daemon rather than only yours. Someone following
the old wording would check the plugin cache, find it empty, and conclude the removal
was complete.

Fixed in the release machinery

The daemon version gate no longer passes the daemons it exists to reject.
Assembling this release copied the 1.0.5 daemons into the plugin and wrote a
manifest declaring them 1.0.9. They had been sitting in the untracked staging
directory since that release — nothing clears it — and the gate reported no problem.

That gate had already failed once on these same two files. Until 1.0.6 it scanned the
executable for the expected version as a substring, and in a 39 MB binary the sequence
turns up on its own, so the 1.0.5 Linux daemon was read as declaring 1.0.6. It was
rewritten to execute workflowd --version. But --version was added in 1.0.6, so
the one daemon that cannot answer is one older than the flag — precisely the case the
gate is for — and not answering was recorded as the same unverified state used for a
daemon built for another platform, which is a legitimate skip. Both callers blocked
only on a daemon that answered and answered wrong. The daemon that would not speak
walked past both.

What shipped as 1.0.6 is unaffected: the release workflow builds both daemons from
source on their own platforms before assembling, so the published archive carries
genuine binaries. The defect was in what a local assembly stages and what the merge
gate would have allowed into the repository — and since the native manifest takes its
product version from the plugin manifest rather than from the binary, the result
carried an honest digest beside a version nobody had read.

A result now records whether the machine could execute the file at all. Runnable and
silent is a failure; not runnable here is a skip, left to the CI job that can run it.
Assembly additionally refuses when a staged daemon is missing outright, because that
copy used to throw after the previous plugin directory had been removed.

Known ZCode limitations

Uninstalling the plugin empties its cache but leaves ZCode's mirror of the marketplace
source — roughly 76 MB, including a native daemon for every platform rather than only
yours — in your ZCode profile. This is host behaviour: the mirror and its registry
belong to ZCode, and a plugin reaching in to erase entries would be a worse fault than
the disk space it recovers. The retained copy is inert. Remove the marketplace itself
to reclaim the space. Your audit data is untouched by an uninstall, which is why the
control plane lives outside the plugin tree.

The Windows daemon is unsigned; authenticode.json records NotSigned. That is a
declared limitation of this release, not a failure, and the clean-install job verifies
it is unsigned rather than badly signed.

Schema

Unchanged at schema 18. A newer schema opens in the documented safe read-only mode
rather than refusing or migrating downward.

Verification

Rust 304 tests, MCP 46, qualification 27, clippy and cargo fmt clean. Built,
sealed, clean-installed on Ubuntu 22.04, Ubuntu 24.04 and Windows 11, and
attested with build provenance by release-candidate run 35649883755 from
6b6b72c191544bb8308d739183ed191df2996b47 - the commit this tag names, and one
on which both the release and the quality workflow are green.

artifact SHA-256
zcode-cycle-1.0.9.zip 3c4d0abf4eceadb4aa7a544e05756d4e7491e1755428e5387a13dbaa30279744
zcode-cycle-native-linux-x64-1.0.9.tgz 67b41fa2ee00a9759f2ac4fd11e16411659b363ac7b70be3cd60f1e5f5a382d9
zcode-cycle-native-win32-x64-1.0.9.tgz e61508681d3240a886c8c1147336fbd3c89b5214dd1ada02a0082add2b6280a9

One test changed on the way here, and no product code. Three Windows lifecycle
tests failed together on a loaded CI runner...

Read more

Cycle for Zcode 1.0.8

Cycle for Zcode 1.0.8 Pre-release
Pre-release

Choose a tag to compare

@jannotix jannotix released this 20 Sep 00:16

Important

Superseded by 1.0.9. Install 1.0.9 instead.

The threat model this archive ships states that ZCode CLI 0.16.9 does not
execute plugin-provided agent components. That was checked by direct
observation on Desktop 3.14.1.7714, and it is false: the host reads the
agents/ directory this archive contains and lists all five roles as
dispatchable subagents.

It is a documentation defect rather than a hole - the definitions the host
reads are the managed role profiles themselves, with the same bounded tool
lists, and the built-in general-purpose subagent already holds every tool.
But an archive should not carry a security statement its own certification
refuted, which is the whole reason 1.0.9 exists. No product code differs
between the two.

Cycle for Zcode 1.0.8

Governed delivery for ZCode: an architect plans, an executor implements inside an
isolated worktree, two independent reviewers judge the frozen candidate, and an
arbiter decides — with every gate result and verdict written to a hash-chained,
signature-checkpointed ledger.

1.0.8 changes no product code. It carries the same seven fixes as 1.0.7 and
exists because the certification host moved while 1.0.7 was being set up for its
live campaign. Install this instead of 1.0.7.

ZCode Desktop went from 3.12.3.7463 to 3.14.0.7681 — the update had already been
downloaded and was waiting for a restart, and three of the thirteen live scenarios
require one, so the campaign could never have finished on the build it started on.
With that update the bundled ZCode CLI moved from 0.16.5 to 0.16.9, the first time
it has moved across four Desktop builds.

That second number is not bookkeeping. The shipped threat model conditions a trust
boundary on it — that the host does not execute plugin-provided agent components,
which is why /cycle:setup install writes five managed profiles explicitly rather
than relying on the host to discover the agents/ directory this archive contains.
1.0.7 was already published naming 0.16.5, so its archive described
a host configuration that no longer exists, and its receipt would have been rejected
by the release lane's own verifier, which asserts the CLI version a campaign ran on.

The seven fixes below are unchanged and were all found the same way: by running the
thirteen-scenario live campaign against 1.0.6's published archive — downloaded,
checksum-verified and checked against its provenance attestation — on Windows and in
WSL. Eleven scenarios passed; the two that failed are the first two. The seventh was
found in the release machinery while shipping them.

Fixed

A per-role model assignment is usable, not merely configurable. /cycle:models
accepted exactly three model references, all under one provider prefix, and reported
them as applied with no warning. All three failed at dispatch with
provider-not-found — on the provider prefix, not the model name — because the
host resolves providers under a namespace the plugin refused to accept. The only
setting that worked was inherit, which is the absence of the feature the product is
named for, and the failure surfaced at the review phase, after an architecture, an
execution and five verification gates had been paid for. A plugin cannot enumerate a
host's providers and has no business deciding which ones exist: Cycle now validates
the shape of a reference and leaves resolution to ZCode. What it owes the operator
instead is an early answer, so a pinned role is reported as dispatch_unverified and
the run protocol probes every pin before a workflow starts. An unresolvable provider
now costs seconds.

Every receipt written by 1.0.6 and earlier therefore records a run in which architect,
executor, both reviewers and the arbiter shared one model — independent prompts and
tool lists, one judgement. Those receipts do not imply the wider claim.

An abrupt stop no longer leaves a workflow unrecoverable and the project locked.
Recovery required a worktree to exist on disk if and only if a base revision had been
recorded. A session killed between those two writes broke the invariant, and recovery
refused outright. Refusing was wrong twice over: recovery only reads — the guards that
matter live on prepare_worktree and freeze, and they still hold — and the refusal
returned before the immutable request text was assembled, withholding the one thing an
interrupted operator cannot reconstruct exactly when it was needed. Meanwhile the
mutation lock kept the project read-only, including for an unrelated delivery already
sitting uncommitted. Recovery now names the inconsistency, returns a recovery action,
and hands back everything it knows.

One project directory can no longer carry two identities. project_key was
whatever the calling agent chose to pass, and the run protocol only described it as
"this workspace's stable project key". It was neither. The server now derives it
canonically from the directory and ignores what the caller sends.

/cycle:setup install no longer deadlocks the first governed run. It left managed
role profiles visible to git, so the first freeze saw a dirty tree it had itself
created. They are excluded now, and the report says so rather than leaving the
operator to discover it.

Risk routing sees the code a change touches. No path could raise Authentication,
Authorization, Cryptography or Secrets: only the request text could, and only by
literal marker. A change to auth.js therefore routed to quick — no independent
reviews — unless the author happened to write "authentication" in their request. The
campaign demonstrated exactly that, twice, on the same fixture. Paths now raise a
category on their own, matched as whole tokens so auth.js counts and authors.md
does not, with documentation taking precedence over everything else.

The uninstall documentation named the wrong directory. It said ZCode keeps the
marketplace's cached copy of the plugin. That cache is emptied completely. What
remains is ZCode's mirror of the marketplace source under
plugins/marketplaces/<marketplace>/, and it is larger than the installation was,
because it carries every platform's daemon rather than only yours. Someone following
the old wording would check the plugin cache, find it empty, and conclude the removal
was complete.

Fixed in the release machinery

The daemon version gate no longer passes the daemons it exists to reject.
Assembling this release copied the 1.0.5 daemons into the plugin and wrote a
manifest declaring them 1.0.8. They had been sitting in the untracked staging
directory since that release — nothing clears it — and the gate reported no problem.

That gate had already failed once on these same two files. Until 1.0.6 it scanned the
executable for the expected version as a substring, and in a 39 MB binary the sequence
turns up on its own, so the 1.0.5 Linux daemon was read as declaring 1.0.6. It was
rewritten to execute workflowd --version. But --version was added in 1.0.6, so
the one daemon that cannot answer is one older than the flag — precisely the case the
gate is for — and not answering was recorded as the same unverified state used for a
daemon built for another platform, which is a legitimate skip. Both callers blocked
only on a daemon that answered and answered wrong. The daemon that would not speak
walked past both.

What shipped as 1.0.6 is unaffected: the release workflow builds both daemons from
source on their own platforms before assembling, so the published archive carries
genuine binaries. The defect was in what a local assembly stages and what the merge
gate would have allowed into the repository — and since the native manifest takes its
product version from the plugin manifest rather than from the binary, the result
carried an honest digest beside a version nobody had read.

A result now records whether the machine could execute the file at all. Runnable and
silent is a failure; not runnable here is a skip, left to the CI job that can run it.
Assembly additionally refuses when a staged daemon is missing outright, because that
copy used to throw after the previous plugin directory had been removed.

Known ZCode limitations

Uninstalling the plugin empties its cache but leaves ZCode's mirror of the marketplace
source — roughly 76 MB, including a native daemon for every platform rather than only
yours — in your ZCode profile. This is host behaviour: the mirror and its registry
belong to ZCode, and a plugin reaching in to erase entries would be a worse fault than
the disk space it recovers. The retained copy is inert. Remove the marketplace itself
to reclaim the space. Your audit data is untouched by an uninstall, which is why the
control plane lives outside the plugin tree.

The Windows daemon is unsigned; authenticode.json records NotSigned. That is a
declared limitation of this release, not a failure, and the clean-install job verifies
it is unsigned rather than badly signed.

Schema

Unchanged at schema 18. A newer schema opens in the documented safe read-only mode
rather than refusing or migrating downward.

Verification

Rust 304 tests, MCP 46, qualification 24, clippy and cargo fmt clean. Built, sealed,
clean-installed on Ubuntu 22.04, Ubuntu 24.04 and Windows 11, and attested with build
provenance by release-candidate run 35459373078 from
0f21c8fa8491cdc6ee1ac519f28a3a487c6aaeec — the commit this tag names.

artifact SHA-256
zcode-cycle-1.0.8.zip 2b91c504a732727eb2488c81d93b6d40dcaa0233012ae113c26e2757910a9735
zcode-cycle-native-linux-x64-1.0.8.tgz 8d4bd661d9d27142403e00499443b3171b32e3e2a808b092f1cf83c3f6b7e0c2
...
Read more

Cycle for Zcode 1.0.7

Cycle for Zcode 1.0.7 Pre-release
Pre-release

Choose a tag to compare

@jannotix jannotix released this 19 Sep 16:19

Important

Superseded by 1.0.8 before this release was ever certified. Install 1.0.8 instead.

The certification host moved while this release was being set up for its live
campaign: the bundled ZCode CLI went from 0.16.5 to 0.16.9. That version is
named in the threat model this archive ships, where it conditions a trust
boundary, so these bytes describe a host configuration that no longer exists —
and a receipt earned on the new host would be rejected by the release lane's own
verifier, which asserts the CLI version a campaign ran on.

1.0.8 carries these seven fixes unchanged and names the host that will certify
them. No product code differs between the two.

Cycle for Zcode 1.0.7

Governed delivery for ZCode: an architect plans, an executor implements inside an
isolated worktree, two independent reviewers judge the frozen candidate, and an
arbiter decides — with every gate result and verdict written to a hash-chained,
signature-checkpointed ledger.

This release closes seven defects. Six were found by running the thirteen-scenario
live campaign against the published 1.0.6 archive — downloaded, checksum-verified
and checked against its provenance attestation — on Windows and in WSL. Eleven
scenarios passed; the two that failed are the first two below. The seventh was found
in the release machinery while shipping this one.

Fixed

A per-role model assignment is usable, not merely configurable. /cycle:models
accepted exactly three model references, all under one provider prefix, and reported
them as applied with no warning. All three failed at dispatch with
provider-not-found — on the provider prefix, not the model name — because the
host resolves providers under a namespace the plugin refused to accept. The only
setting that worked was inherit, which is the absence of the feature the product is
named for, and the failure surfaced at the review phase, after an architecture, an
execution and five verification gates had been paid for. A plugin cannot enumerate a
host's providers and has no business deciding which ones exist: Cycle now validates
the shape of a reference and leaves resolution to ZCode. What it owes the operator
instead is an early answer, so a pinned role is reported as dispatch_unverified and
the run protocol probes every pin before a workflow starts. An unresolvable provider
now costs seconds.

Every receipt written by 1.0.6 and earlier therefore records a run in which architect,
executor, both reviewers and the arbiter shared one model — independent prompts and
tool lists, one judgement. Those receipts do not imply the wider claim.

An abrupt stop no longer leaves a workflow unrecoverable and the project locked.
Recovery required a worktree to exist on disk if and only if a base revision had been
recorded. A session killed between those two writes broke the invariant, and recovery
refused outright. Refusing was wrong twice over: recovery only reads — the guards that
matter live on prepare_worktree and freeze, and they still hold — and the refusal
returned before the immutable request text was assembled, withholding the one thing an
interrupted operator cannot reconstruct exactly when it was needed. Meanwhile the
mutation lock kept the project read-only, including for an unrelated delivery already
sitting uncommitted. Recovery now names the inconsistency, returns a recovery action,
and hands back everything it knows.

One project directory can no longer carry two identities. project_key was
whatever the calling agent chose to pass, and the run protocol only described it as
"this workspace's stable project key". It was neither. The server now derives it
canonically from the directory and ignores what the caller sends.

/cycle:setup install no longer deadlocks the first governed run. It left managed
role profiles visible to git, so the first freeze saw a dirty tree it had itself
created. They are excluded now, and the report says so rather than leaving the
operator to discover it.

Risk routing sees the code a change touches. No path could raise Authentication,
Authorization, Cryptography or Secrets: only the request text could, and only by
literal marker. A change to auth.js therefore routed to quick — no independent
reviews — unless the author happened to write "authentication" in their request. The
campaign demonstrated exactly that, twice, on the same fixture. Paths now raise a
category on their own, matched as whole tokens so auth.js counts and authors.md
does not, with documentation taking precedence over everything else.

The uninstall documentation named the wrong directory. It said ZCode keeps the
marketplace's cached copy of the plugin. That cache is emptied completely. What
remains is ZCode's mirror of the marketplace source under
plugins/marketplaces/<marketplace>/, and it is larger than the installation was,
because it carries every platform's daemon rather than only yours. Someone following
the old wording would check the plugin cache, find it empty, and conclude the removal
was complete.

Fixed in the release machinery

The daemon version gate no longer passes the daemons it exists to reject.
Assembling this release copied the 1.0.5 daemons into the plugin and wrote a
manifest declaring them 1.0.7. They had been sitting in the untracked staging
directory since that release — nothing clears it — and the gate reported no problem.

That gate had already failed once on these same two files. Until 1.0.6 it scanned the
executable for the expected version as a substring, and in a 39 MB binary the sequence
turns up on its own, so the 1.0.5 Linux daemon was read as declaring 1.0.6. It was
rewritten to execute workflowd --version. But --version was added in 1.0.6, so
the one daemon that cannot answer is one older than the flag — precisely the case the
gate is for — and not answering was recorded as the same unverified state used for a
daemon built for another platform, which is a legitimate skip. Both callers blocked
only on a daemon that answered and answered wrong. The daemon that would not speak
walked past both.

What shipped as 1.0.6 is unaffected: the release workflow builds both daemons from
source on their own platforms before assembling, so the published archive carries
genuine binaries. The defect was in what a local assembly stages and what the merge
gate would have allowed into the repository — and since the native manifest takes its
product version from the plugin manifest rather than from the binary, the result
carried an honest digest beside a version nobody had read.

A result now records whether the machine could execute the file at all. Runnable and
silent is a failure; not runnable here is a skip, left to the CI job that can run it.
Assembly additionally refuses when a staged daemon is missing outright, because that
copy used to throw after the previous plugin directory had been removed.

Known ZCode limitations

Uninstalling the plugin empties its cache but leaves ZCode's mirror of the marketplace
source — roughly 76 MB, including a native daemon for every platform rather than only
yours — in your ZCode profile. This is host behaviour: the mirror and its registry
belong to ZCode, and a plugin reaching in to erase entries would be a worse fault than
the disk space it recovers. The retained copy is inert. Remove the marketplace itself
to reclaim the space. Your audit data is untouched by an uninstall, which is why the
control plane lives outside the plugin tree.

The Windows daemon is unsigned; authenticode.json records NotSigned. That is a
declared limitation of this release, not a failure, and the clean-install job verifies
it is unsigned rather than badly signed.

Schema

Unchanged at schema 18. A newer schema opens in the documented safe read-only mode
rather than refusing or migrating downward.

Verification

Rust 304 tests, MCP 46, qualification 24, clippy and cargo fmt clean. Built, sealed,
clean-installed on Ubuntu 22.04, Ubuntu 24.04 and Windows 11, and attested with build
provenance by release-candidate run 35453712382 from 4dbab330c00ac05ffee68d2e221dc4201042d4fb — the commit this tag names.

artifact SHA-256
zcode-cycle-1.0.7.zip 2f2d1b79859452de81b391584a11f3aea2f1c0d525159d11f5df73de0b089a32
zcode-cycle-native-linux-x64-1.0.7.tgz 56027ee21f3f3c57ffb5f32181fe423b89c3f1d2f57a4884ff3efb534446c9f8
zcode-cycle-native-win32-x64-1.0.7.tgz 0eafc541a9362dbf1d6f140768094d6e5169945bb81af72379d1b293d850dbf1

Both native archives are byte-identical to the ones produced by an earlier seal of
a different commit, so the daemon builds reproduce across runs. The plugin ZIP
differs in exactly two of its seventy-one entries - provenance.intoto.json and
SBOM.cdx.json, the only files that name the commit they were built from. Every
other entry matches byte for byte.

Not yet claimed

This build has not been through the thirteen-scenario live campaign. Every fix
above is covered by tests and the whole release lane is green, but the live campaign
is what found six of the seven defects this release closes — in a 1.0.6 that was also
entirely green, and that had itself been sealed and attested. Until 1.0.7 has been
certified live against these exact bytes, this is a sealed and reproducible candidate
rather than a certified release, and it is marked as a pre-release for that reason.

Cycle for Zcode 1.0.6

Cycle for Zcode 1.0.6 Pre-release
Pre-release

Choose a tag to compare

@jannotix jannotix released this 18 Sep 23:34

Cycle for Zcode 1.0.6

Governed delivery for ZCode: an architect plans, an executor implements inside an
isolated worktree, two independent reviewers judge the frozen candidate, and an
arbiter decides — with every gate result and verdict written to a hash-chained,
signature-checkpointed ledger.

This release closes the four defects the second live thirteen-scenario campaign
found against the sealed 1.0.5 archive, plus two found in the release machinery
itself while shipping it.

Fixed

A per-role model pin is no longer lost in silence. The pin lived only in the
profile's model: line, which was both the request and its resolution, so
anything that rewrote the profile from its template erased the request without a
trace. In the campaign the arbiter was pinned through the supported path, read
back from disk, and dispatched on inherit eighty-two minutes later with the
ledger faithfully recording it. The request is now kept apart from its
resolution, outside the project tree, and the two are compared on every call.
A profile rewritten from its own template is structurally perfect, so repair
no longer waits for damage: a pin missing from the file it was set on is itself
the thing to repair.

A claimed gate result is distinguishable from a verified one. Both used to
serialise to {"type":"verification","gate":"…","status":"passed"} byte for
byte, and the only signals separating them sat outside the entry. A reported
outcome now carries declared, which only the caller-facing audit path can set
and always does. Entries written before this field keep their bytes and read as
what they were.

A repaired candidate can be verified again. Evidence ids come from the
verification plan and a repair reuses that plan, while evidence was keyed on the
evidence id alone — so a refrozen candidate arrived carrying the failed
candidate's ids and every gate was refused. Evidence is now keyed by gate and
candidate, and both candidates keep their rows: the failed run stays in the
record rather than being overwritten by the run that fixed it.

CI=1 is no longer accepted as a program name. It is one word, carries no
metacharacter, is on no denylist, and is still not a program. What a program may
be is now stated positively: a command name, or a path whose final component is
one.

Fixed in the release machinery

The release gate now asks the daemon its version instead of scanning for one.
It searched the executable for the expected version as a substring; in a 39 MB
binary that sequence occurs on its own, and a 1.0.5 Linux daemon was duly
reported as declaring 1.0.6 and passed. workflowd --version answers without a
data directory or an IPC handshake, and each CI job names the daemon it must have
actually executed.

The tracked Linux daemon carries its executable bit again. It had regressed
to 100644, in 1.0.5 as well. This was not user-visible: the control plane never
runs the daemon from the plugin tree — it copies it into the data directory at
runtime/native/<target>/<digest>/ with mode 0700 and runs it from there, so
neither a checkout nor the sealed archive depends on the bit. What it broke was
the new gate above, which runs the binary in place to ask its version, and which
found it on its first Linux run.

Known ZCode limitations

Uninstalling the plugin leaves the marketplace's cached copy — roughly 76 MB
including a native daemon per platform — in your ZCode profile, and ZCode's
confirmation dialog promises to remove "the plugin's cached files" while leaving
those. This is host behaviour: the cache and its registry belong to ZCode, and a
plugin reaching in to erase entries would be a worse fault than the disk space it
recovers. The retained copy is inert. Remove the marketplace itself to reclaim
the space. Your audit data is untouched by an uninstall, which is why the control
plane lives outside the plugin tree.

Schema

The store moves to schema 18. A newer schema opens in the documented safe
read-only mode rather than refusing or migrating downward.

Verification

Rust 297 tests, MCP 36, qualification 21, clippy and cargo fmt clean. Built,
sealed, clean-installed on Ubuntu 22.04, Ubuntu 24.04 and Windows 11, and
attested with build provenance by release-candidate run 35405135492 from
71bab2fe96734cd413ead94c2d8483c9d4b10a67.

artifact SHA-256
zcode-cycle-1.0.6.zip a5fd6943a39f40218be8d246d8e64da39f75d3798e7ee33ea494b7a1093a57d1
zcode-cycle-native-linux-x64-1.0.6.tgz 505ace4ef8566ba64de95bddba226e2245903cc373855c319ecd72ef002b12c4
zcode-cycle-native-win32-x64-1.0.6.tgz 43c75fd81e1c184a4d0bd67dd4ab67bb6518896df35e91981b8e2e8094325062

Both native archives are byte-identical to the ones an earlier seal of a
different commit produced, so the daemon builds reproduce across runs. Only the
plugin ZIP differs, because its documentation did.

The Windows daemon is unsigned; authenticode.json records NotSigned. That is
a declared limitation of this release, not a failure, and the clean-install job
verifies it is unsigned rather than badly signed.

Not yet claimed

This build has not been through the thirteen-scenario live campaign. Every
fix above is covered by tests and the whole release lane is green, but the live
campaign is what found all four of the defects this release closes — in a 1.0.5
that was also entirely green. Until 1.0.6 has been certified live against these
exact bytes, this is a sealed and reproducible candidate rather than a certified
release, and it is marked as a pre-release for that reason.

WITHDRAWN - ZCode Cycle 1.0.0 (unreliable)

Choose a tag to compare

@jannotix jannotix released this 21 Aug 23:36

WITHDRAWN - DO NOT INSTALL

Version 1.0.0 is not a reliable production release. Its published installable content changed after initial publication to remove a development-machine path; a clean Linux installation cannot execute the bundled daemon; and the release CI is not green. The tag is retained only for audit history and will not be reused or moved.

Upgrade to v1.0.1 when that version is published after exact-artifact Windows/Linux certification.

Historical notes below are retained for traceability and are not a current readiness claim.

First public release.

Governed, evidence-gated software delivery for ZCode: an architect, an executor, two independent reviewers and an independent final arbiter over a deterministic control plane - isolated worktrees, frozen candidates, mandatory verification gates with managed-browser evidence for UI changes, a tamper-evident audit ledger, per-role model configuration, persistent goals gated on delivered evidence, ledger-proven project memory and incremental code intelligence.

The original release claimed Windows x64 and Linux x64 qualification. That claim is superseded by this withdrawal notice.