Releases: GaugeWright/whipplescript
Release list
0.8.0 — 2026-09-28
A minor release because three published crates changed public types that a
dependent can match on or construct:
whipplescript-store:NormCommand,NormCommandResult,
NormReferenceRoleandResourceGapKindgained variants;
NormCommandResult::ActivationPlannedgainedeffects;NormVocabulary
gainedconstraintanddeployment;NormChartergainedcanonicalizers.whipplescript-kernel:AdmissionDoorgainedDeploy,RequirementImpact
gainedceiling,ProjectionGap::ExecutionUnavailablegainedrequirement,
norm_buck2_tests::test_reportandnorm_buck2_tests::judgetake a fourth
parameter,norm_projection::EvidenceProjection::capturetakes a type
parameter, andnorm_admission::AdmissionHostis nowCopy.whipplescript:host_runtime::ModelScanWitnessgaineddirectories.
Code that matches those enums without a wildcard arm, builds those structs with
a literal, calls those functions, or casts those enums to integers must follow
the change. The command line, stored data and configuration stay compatible:
nothing a whip user does needs to change.
Added
- The misuse log. Each invocation whip refuses with exit status 2 — an
unknown command, an unknown option, a missing argument — adds one JSON line
to~/.local/state/whipplescript/misuse.jsonl, so the commands people and
agents expect can be counted and the command surface improved from them.
Arguments that can hold a secret are written as<redacted>, and the log
never leaves the machine.WHIPPLESCRIPT_MISUSE_LOGnames another path, or
offkeeps no log.
Changed
- A malformed
whip issueorwhip assertsays what was wrong. Every
mistake used to print the command's whole usage line — forty alternatives
forwhip issue— and nothing else. The refusal now names the problem
(missing <id>,unknown option `--queue`, a tracker passed toready
as--tracker), shows the usage of that one subcommand, and for an unknown
subcommand suggests the nearest, including the verbs other trackers use
(closeforfinishorcancel). The exit status is still 2.
Fixed
- Closing a tracker item no longer leaves empty workspace stores behind.
whip issue finishopened the versioned-workspace stores to attest the
work's cut trail, and opening creates them, so every checkout an item was
closed from gained an untracked.whipplescript/branches.sqliteand
vcs-content.sqlite.issue finish,issue show --json,assertand a
keyedattestnow open them only where they already exist.
Verifying this release
Built on GaugeWright's own fleet. Every file's SHA-256 is in
whipplescript-0.8.0.intoto.json, signed with the key in
docs/release-provenance.pub:
minisign -V -p release-provenance.pub -m whipplescript-0.8.0.intoto.json
0.7.1 — 2026-09-28
A patch release: nothing it adds breaks what 0.7.0 accepted.
Added
whip issue label <id> <label>...andwhip issue unlabel <id> <label>.... Labels could only be set when an issue was filed, so a label
that marked an open question stayed after the question was answered. Labels
are a set: a change that alters nothing records nothing. Each change is an
event, so it surviveswhip issue rebuild, travels throughexportand
import, and resolves the same way on every copy at a merge.
Verifying this release
Built on GaugeWright's own fleet. Every file's SHA-256 is in
whipplescript-0.7.1.intoto.json, signed with the key in
docs/release-provenance.pub:
minisign -V -p release-provenance.pub -m whipplescript-0.7.1.intoto.json
0.7.0 — 2026-09-27
A minor release because a claim behaves differently: a claim of a blocked,
deferred or conflicted issue now fails where 0.6.0 let it succeed, and order
and soft dependencies rank an issue instead of holding it back. A workflow
that relied on either sees the difference, so this is not a patch. It is also
the first release whose whipplescript crate is on crates.io since 0.5.6.
Changed
- A tracker has one definition of ready, and a claim asks it (DR-0126).
whip issue ready,when <tracker> has ready issue, every claim — CLI,
workflow, agent todo tools, host actions — and the newwhip issue why <id>
decide readiness the same way. Before, a workflow saw blocked and conflicted
issues as ready, and a claim succeeded on a blocked or a closed issue. A claim
of a closed, canceled or archived issue now fails as not open, and a claim of
an open issue that is not ready fails with every reason. A person may pass
whip issue claim <id> --override "<why>"; the claim records the reason. orderandsoftdependencies no longer hold an issue back. They rank
it:dep add B depends-on A --kind ordersays A comes first, and a free
worker may still take B while A is claimed.hard,resource,review,
contractanddiscoveredstill gate.- Readiness is decided at the worker's instant, not the store's clock. A
claimttlon agiven clock atscenario lapses on the scenario's clock, a
claimttlon a hosted instance lapses at all (it was ignored there), and a
parked hosted instance wakes when a claim lapses or a deferral comes due.
Added
- Deferral:
whip issue defer <id> --until WHEN | --after ISSUE | --reached RECORD:STATUS | --demand LABEL:N [--review WHEN]. An issue stays
out of the ready set until the condition holds, then becomes ready with no
one acting. Every deferral has a review date;whip issue reviewlists the
ones past it and still unmet.waitsshows them andundeferlifts one early. - Ordering:
whip issue order A before Bandwhip issue rank PARENT CHILD....readyreturns issues in a derived order: a parent's rank leads
its children's, only the parent's assignee ranks its children (anyone else's
statement is kept as a proposal), and a dependency inherits the rank of what
waits on it. Contradictory rankings show inwhip issue conflicts.
Fixed
- The
whipplescriptcrate builds from its own package again. It embedded
the hosted executor's Dockerfile fromwhipplescript-host-do, a crate that is
never published, so crates.io's verification build could not find it and
0.6.0 of this one crate was not published. The ten others were. The recipe
now lives inside the crate, held byte for byte to the one host-do owns, and
every release packages and verifies all its crates before publishing any.
Verifying this release
Built on GaugeWright's own fleet. Every file's SHA-256 is in
whipplescript-0.7.0.intoto.json, signed with the key in
docs/release-provenance.pub:
minisign -V -p release-provenance.pub -m whipplescript-0.7.0.intoto.json
0.6.0 — 2026-09-24
A minor release rather than a patch, because it breaks source that 0.5.6
accepted: see Breaking below, and mint's scope and ttl, which are
gone. It is also the first release built on GaugeWright's own fleet rather than
on GitHub Actions. The archives, installers and formula are the same set as
before; what changes is how a release is verified. A GitHub build attestation
is bound to an Actions run, so this release carries an in-toto provenance
statement over every file's SHA-256 instead, signed with the key published in
docs/release-provenance.pub, and an SPDX SBOM.
Added
-
whip issue cancel <id> [--reason R]andwhip issue reopen <id> [--note N].
cancelwithdraws an open issue nobody will do and releases any claim on it
in the same transaction, withfinish's holder guard. A canceled issue is not
a closed one: nothing waiting on the issue closing is woken by it.reopen
returns a closed or canceled issue to open, and so to ready unless something
blocks it. Both append theissue.canceledandissue.reopenedevents every
store already folded, so a store written by 0.5.6 needs nothing. -
whip issue set <id> statusrefuses a status outside open, closed,
canceled and archived, as the compiler already did.cancelledused to be
stored silently, as a status no rule could match. -
mint credential from <parent> { … }(DR-0053 §5, as amended
2026-08-27) — spend a credential at an issuer's token endpoint for a scoped
child. The exchange is the author's, in the block formrequestestablished;
the custodian executes it so the minted token never enters whip. Three
refusals: an undeclared parent, an exchange presenting nothing, and an
exchange presenting a different credential than the one minted from. -
A minted credential can never reach further than the credential it was
minted from (DR-0053 §5, as amended 2026-08-27).The custodian registers a mint as
{parent}/mint-{fingerprint}and credential
names are/-separated, so the egress ceiling now walks up the name. Nearest
ancestor wins, so governance can narrow one mint further by naming it without
restating the parent's list — and a governed-but-unscoped parent bounds its
mints at nothing, rather than letting a child be the way around the ceiling.This is what
mintis bounded by instead of a declared scope.scopeand
ttlare gone fromCustodyOp::Mint: both were accepted and ignored
(_scope,let _ = ttl_secs), both are vendor protocol, and both belong in
the exchange body that actually goes on the wire. A clause beside the body
duplicating it is the separate modifier §5 refuses for credentials — and the
divergence was unresolvable, since §3 keeps the custodian from parsing the
body, so a declared scope could never be checked against the exchanged one.whip therefore does not police which scope a mint requests — that string's
meaning lives inside the vendor — and keeps the guarantee it can verify. -
A credential's egress reach is bounded by governance (DR-0053 §14, as
amended 2026-08-27).grant credential stripe_api -> credential:acme/stripe-live sealed at hardware grant request stripe_api for POST https://api.stripe.com/v1/refunds/*§14 grounded scope narrowing in the turn grant, which attaches only to
tellandinvoke. The rule-bodyrequest— the one construct that reaches
the custodian — had no list to consult, and an agent had no custody surface,
so the turn clause parsed, passed its class check, and bound nothing.The ceiling now lives in the signed envelope, where it binds regardless of
which construct uses the credential and no program text can widen it. It is
in the canonical form, so the signature covers it. Refused at check time for
a literal URL and at egress always. It applies once governance binds the
credential; a policy that never mentions one does not constrain it.Matching is component-wise against a parsed URL:
*never crosses from host
into path, and userinfo cannot impersonate a host. A leading*must stand
for a whole label —*.stripe.comis the subdomain wildcard,*stripe.com
is refused because it reads as narrowed while admittingevil-stripe.com. -
Agents can make authenticated requests, narrowed by their turn grant. A
credential_requesttool is offered only to a turn whose grant lists
requeston a credential, and enumerates exactly those credentials. A call
is admitted only when the turn's globs and the envelope's scope both admit
it — a turn narrows, never widens, the same way a file-store turn grant sits
under the store's ownallowglobs. The material never enters the agent's
process: the turn names a credential and the custodian substitutes at egress.
Changed
-
BREAKING — spend-table rates are whole micros of USD per Mtok.
input_per_mtok_usdand its three siblings becomeinput_micros_per_mtok,
output_micros_per_mtok,cache_read_micros_per_mtokand
cache_write_micros_per_mtok, each a non-negative whole number. $3.00/Mtok is
3000000.The unit moved into the key name because the two readings differ by a factor
of a million and nothing in a file says which one it means, so an old table is
refused by name rather than silently priced at a millionth of itself. The
message carries the replacement key and the conversion.Every published rate is exact in this unit, and
cost_microsnow accumulates
the four buckets inu128and rounds once, upward, rather than summingf64
dollars and rounding at the end — so a turn costing a fraction of a micro
costs one micro rather than nothing, and four buckets cannot each contribute
their own error. A spend cap therefore binds no later than it was told to.This also makes the table the one rate document the estate shares: GaugeDesk
prices WhippleScript's stats report from it rather than from a second table of
its own. -
A projection writes only the files that are not already right, and never
holds the manifest in memory.materialize_manifest_subsetloaded every
body into a vector before writing any of them, so projecting a tree cost the
sum of the tree — and the common case is that it had nothing to do at all,
becausecommit_turnimports a worktree and then projects the branch back
onto the same bytes. It now reads one and writes one, and
materialize_manifest_ontotakes a scan's own cache and skips every path that
cache can vouch for, under exactly the rulescan_diruses for the same
question — size and mtime unchanged, and that mtime strictly older than the
scan's stamp. Anything inside the racy granule is written, which is what
every path got before. The byte budget is now answered from recorded sizes
rather than by loading the closure to discover it does not fit. -
Importing a worktree no longer reads its largest file twice. The scan
hashes each file a window at a time rather than reading it whole, and
ContentBlobs::put_filelets a store that can write incrementally do so —
ContentStorewrites past the 4 MiB threshold straight into the row through
SQLite's incremental blob interface, verifying the bytes it writes against
the id it keyed them under so a file moving mid-import is refused rather than
stored under an id that does not describe it. Measured: importing an 80 MiB
recording grew the resident peak by 82 MB where it grew by 161 MB before.
Identity, representation below the threshold, and every other
ContentBlobsimplementation are unchanged — the seam has a default that
reads the file, which is what every caller did before it existed. -
A source span is no longer part of a program's identity (DR-0095).
ir_hashis nowstable_hash_hexof the.irsnapshot's identity
projection — the same document with its source offsets erased. So a
compiler change that only improves a diagnostic span rotates nothing, and
ir_hashis stable under formatting changes outside a rule body.
lowered_ir_report.accepted_program_digestgoes through the same projection.
The snapshot keeps its spans:to_snapshotis unchanged, all 25.ir
goldens are byte-identical, and a runtime event is still attributed back to
source through them.Scope, stated because it is narrower than "formatting is free": a reformat
still mints a new program version. A version row is
UNIQUE(program_id, source_hash, ir_hash)andsource_hashhashes the
source TEXT, so whitespace mints a row throughsource_hashwhatever
ir_hashdoes. And a rule'sbody_hashis still a digest of its body TEXT,
so a blank line inside a rule body still movesir_hash— deliberately,
because inside a"""prompt indentation is prose a model reads.This rotates
ir_hashonce, for every program that exists. It is the
same cost that was already being paid silently on every span fix, paid once
deliberately instead, and it lands on the mechanism built for it: a matching
source_hashwith a differingir_hashis re-attested with an
instance.program.reattestedevent, not refused. Which programs compile does
not change.
Fixed
-
A
mintexchange was invisible to the information-flow checker. It
shipped two days afterrequestand repeated that gap exactly: no
resource_for_bodyarm, so the token exchange — an egress under the parent
credential — had no sink and no payload reads. The parent is the sink
identity, since the child does not exist yet.Found by making
check_with_envelope's reader-set match exhaustive, on
the model of DR-0074'scollect_effect_binding_roots: everyIrEffectKind
is now named, several with an arm that does nothing and says why, so adding a
variant is a compile error rather than a silent escape. Writing themint
arm and noticing it could never fire is what ...
0.5.6 — 2026-08-24
Release Notes
The labeled turn projection now publishes a turn's content as ordered
segments alongside the existing assistant_text and tool_calls.
LabeledTurnOutput is the only supported way for an embedding host to obtain a
turn's content, and it exposed only the fold: one final assistant_text plus
a flat list of the calls that ran. That fold answers "what did the turn
conclude", but it discards the order content was produced in, and every
intermediate line of prose the model spoke alongside a tool call — so a turn
that narrates its work projected as if it had said nothing until its closing
line. A shell that replays a turn as a conversation could not, and the contract
directs hosts not to recreate transcript-folding from the runtime store.
TurnContentSegment is Prose(String) or Tool(ProjectedToolCall), and
segments carries them in the sequence the turn produced them — prose runs
interleaved with the calls they introduced, results correlated into position.
It is the same admitted content under the same turn-join label, so it carries
no read the folded fields do not already carry and does not widen the certified
flow_signature. Additive and compatible: assistant_text and tool_calls
are unchanged, so every existing consumer keeps its folded view.
Install whipplescript 0.5.6
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/GaugeWright/whipplescript/releases/download/v0.5.6/whipplescript-installer.sh | shInstall prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/GaugeWright/whipplescript/releases/download/v0.5.6/whipplescript-installer.ps1 | iex"Install prebuilt binaries via Homebrew
brew install GaugeWright/tap/whipplescriptDownload whipplescript 0.5.6
| File | Platform | Checksum |
|---|---|---|
| whipplescript-aarch64-apple-darwin.tar.xz | Apple Silicon macOS | checksum |
| whipplescript-x86_64-apple-darwin.tar.xz | Intel macOS | checksum |
| whipplescript-x86_64-pc-windows-msvc.zip | x64 Windows | checksum |
| whipplescript-aarch64-unknown-linux-gnu.tar.xz | ARM64 Linux | checksum |
| whipplescript-x86_64-unknown-linux-gnu.tar.xz | x64 Linux | checksum |
0.5.5 — 2026-08-20
Release Notes
An agent turn's request dialect becomes a named, declared property of a
provider binding rather than something recovered by reading a base URL.
ModelWire — anthropic-messages, openai-responses, openai-chat-compat,
coerced-tools — is separate from CoerceProvider, which answers whose
credential pays; the two were one enum, and a metered gateway is a single
payer identity fronting three dialects.
The wire used to be recovered by testing an admitted base URL for an
/anthropic suffix, with everything else taking the chat-completions wire as
"the wire that has always worked". That default was wrong in production: an
OpenAI model whose family carries tools only on the Responses API was sent its
tools on chat completions and refused at the first turn that carried any,
while this runtime's Responses builder sat unreachable behind a mapping with
no arm that produced it. A binding may now declare its wire in the signed
policy, and the declaration travels through the turn admission to the host.
The surface mapping survives only as a fallback for envelopes signed before
the field existed: it is total, and an unrecognized surface is an error rather
than a guess.
coerced-tools is a new dialect and the floor beneath the model catalogue:
chat completions with response_format pinned to a {reply, tool_calls[]}
schema and no native tool array at all, so a model that can honour a JSON
schema can drive the loop whatever its endpoint implements. DR-0064 records
it and states its cost — a tool request expressed as structured output is off
the format models are trained on — so native calling remains the default and
this remains a fallback. Brokering is unchanged: whip still executes every
tool the model requests, under the same lease, store policy, counter, and
capability gate.
Compatible with envelopes signed before this release. The wire field is
optional and omitted when absent, so an existing policy canonicalizes to the
bytes it was signed as and still verifies.
Install whipplescript 0.5.5
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/GaugeWright/whipplescript/releases/download/v0.5.5/whipplescript-installer.sh | shInstall prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/GaugeWright/whipplescript/releases/download/v0.5.5/whipplescript-installer.ps1 | iex"Install prebuilt binaries via Homebrew
brew install GaugeWright/tap/whipplescriptDownload whipplescript 0.5.5
| File | Platform | Checksum |
|---|---|---|
| whipplescript-aarch64-apple-darwin.tar.xz | Apple Silicon macOS | checksum |
| whipplescript-x86_64-apple-darwin.tar.xz | Intel macOS | checksum |
| whipplescript-x86_64-pc-windows-msvc.zip | x64 Windows | checksum |
| whipplescript-aarch64-unknown-linux-gnu.tar.xz | ARM64 Linux | checksum |
| whipplescript-x86_64-unknown-linux-gnu.tar.xz | x64 Linux | checksum |
0.5.4 — 2026-08-19
Release Notes
xAI's Grok models become a first-class model backend, and the harness loop
exports its settled context-window reading — the number its own compaction
trigger consumes — so an embedding product can finally show an honest
context meter instead of a billing sum that overcounts the window by the
number of tool rounds. The endpoint already
worked through openai-generic plus a hand-set base URL, but that spelling
made the credential an "OpenAI key" and left the operator to know the URL;
a first-class xai backend owns its credential surface and its default.
Added
xaimodel backend — xAI's Grok API as a first-class backend on the
model-backend axis (spec/std-coercion.md"Providers"): the Chat
Completions wire athttps://api.x.ai/v1, reachable everywhere the other
backends are — native coerce (WHIPPLESCRIPT_COERCE_PROVIDER=xai), the
owned agent harness (provider profiles and
WHIPPLESCRIPT_HARNESS_PROVIDER), and the hosted Durable Object doors
(coerce_config_json/ agent config / model broker). The credential is
XAI_API_KEYorwhip auth set xai— its own surface, never the OpenAI
one, and the Codex OAuth token never satisfies it. Grok context windows are
derived per family (fast variants 2M, grok-4/grok-code 256k, conservative
131k otherwise). Provider subprocess spawns (codex, claude) strip
XAI_API_KEYthe way they strip each other's keys.spec/std-coercion.md"Adding a model backend" — the exhaustive wiring
checklist a new backend must cover, distilled from this addition and from
theopenai-genericreachability lesson.- Settled context-window reading —
BrokeredTurnOutcome::last_input_tokens
(the final MAIN reply's prompt size), stamped once at the terminal into the
usage object underlast_input_tokensand projected by both hosts: the
Durable Object'susage_observation.last_input_tokensand the local host's
TurnExecution::usage(TurnUsageObservation). A gauge beside the meter:
billing settlement deliberately keeps carrying only the four summed
counters.
Install whipplescript 0.5.4
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/GaugeWright/whipplescript/releases/download/v0.5.4/whipplescript-installer.sh | shInstall prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/GaugeWright/whipplescript/releases/download/v0.5.4/whipplescript-installer.ps1 | iex"Install prebuilt binaries via Homebrew
brew install GaugeWright/tap/whipplescriptDownload whipplescript 0.5.4
| File | Platform | Checksum |
|---|---|---|
| whipplescript-aarch64-apple-darwin.tar.xz | Apple Silicon macOS | checksum |
| whipplescript-x86_64-apple-darwin.tar.xz | Intel macOS | checksum |
| whipplescript-x86_64-pc-windows-msvc.zip | x64 Windows | checksum |
| whipplescript-aarch64-unknown-linux-gnu.tar.xz | ARM64 Linux | checksum |
| whipplescript-x86_64-unknown-linux-gnu.tar.xz | x64 Linux | checksum |
0.5.3 — 2026-08-17
Release Notes
The authored half of durable-store upgrades (compiler half: 0.5.2). An
embedding host whose package assembly evolved resolves different authored
content under the reference an older build recorded; the replayed open
refuses — correctly, and permanently, stranding the instance's thread.
Added
GovernedHostRuntime::adopt_instance_from— a fork that waives only
source-content reproduction: identity, policy binding, position, and
quiescence are checked exactly as an ordinary fork; the source is never
executed again; its thread seeds a target resolved in full under the
current authoring;host.instance.forkedaudits the move.GovernedHostRuntime::newest_recorded_instance— names the adoption
source for a host that cannot replay an open to find it.
Install whipplescript 0.5.3
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/GaugeWright/whipplescript/releases/download/v0.5.3/whipplescript-installer.sh | shInstall prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/GaugeWright/whipplescript/releases/download/v0.5.3/whipplescript-installer.ps1 | iex"Install prebuilt binaries via Homebrew
brew install GaugeWright/tap/whipplescriptDownload whipplescript 0.5.3
| File | Platform | Checksum |
|---|---|---|
| whipplescript-aarch64-apple-darwin.tar.xz | Apple Silicon macOS | checksum |
| whipplescript-x86_64-apple-darwin.tar.xz | Intel macOS | checksum |
| whipplescript-x86_64-pc-windows-msvc.zip | x64 Windows | checksum |
| whipplescript-aarch64-unknown-linux-gnu.tar.xz | ARM64 Linux | checksum |
| whipplescript-x86_64-unknown-linux-gnu.tar.xz | x64 Linux | checksum |
0.5.2 — 2026-08-17
Release Notes
Durable stores survive toolchain upgrades. Consuming 0.5.1 from GaugeDesk
surfaced that the replayed-open guard stranded every pre-existing instance
after a compiler-evolving upgrade: the recorded ir_hash could never match
what the new toolchain derives for the identical authored program.
Fixed
- A replayed instance open re-attests the IR under the current compiler
when the authored identity (source_hash) matches and only the compiled
identity (ir_hash) differs. The current compile is registered as a program
version, the instance is re-pointed, andinstance.program.reattestedis
appended naming both IRs — an auditable event, never a silent acceptance.
A differingsource_hashstays refused: different authored content under a
replayed request is the integrity breach the guard exists for
(spec/agent-harness.md"Program identity across toolchains").
Added
RuntimeStore::reattest_instance_program, implemented for the native
SqliteStoreand the durable-objectDoSqliteStore.
Install whipplescript 0.5.2
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/GaugeWright/whipplescript/releases/download/v0.5.2/whipplescript-installer.sh | shInstall prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/GaugeWright/whipplescript/releases/download/v0.5.2/whipplescript-installer.ps1 | iex"Install prebuilt binaries via Homebrew
brew install GaugeWright/tap/whipplescriptDownload whipplescript 0.5.2
| File | Platform | Checksum |
|---|---|---|
| whipplescript-aarch64-apple-darwin.tar.xz | Apple Silicon macOS | checksum |
| whipplescript-x86_64-apple-darwin.tar.xz | Intel macOS | checksum |
| whipplescript-x86_64-pc-windows-msvc.zip | x64 Windows | checksum |
| whipplescript-aarch64-unknown-linux-gnu.tar.xz | ARM64 Linux | checksum |
| whipplescript-x86_64-unknown-linux-gnu.tar.xz | x64 Linux | checksum |
0.5.1 — 2026-08-17
Release Notes
Stop lands mid-stream. Cancellation of a brokered turn was cooperative only
between model rounds, so a Stop aimed at a long single-response turn waited for
the entire response to stream — indistinguishable, from an embedding UI, from
the Stop doing nothing.
Fixed
- The native transport releases a cancelled turn's provider stream instead
of draining it. The transport polls the durable cancellation surface between
streamed SSE lines (its own throttled store connection, latching on first
observation) and releases the stream at a complete-line boundary; what fully
arrived assembles exactly as a naturally ended body. - A released round settles
cancelled, keeping the text that arrived as
that round's durable assistant message, and starts no offered tool — a
truncated text tail parses exactly like a final answer, and settling it
completedwould launder a stop into a normal terminal. An unreleased
natural terminal still wins over a racing request, and transports without a
release surface keep the between-rounds observation unchanged
(spec/agent-harness.md"Cancellation").
Added
BrokeredTurnMachine::with_stream_releasedand the
BrokeredTurnContext::stream_releasedprobe, for hosts whose transports can
release an in-flight stream.Nonepreserves prior behavior exactly.
Install whipplescript 0.5.1
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/GaugeWright/whipplescript/releases/download/v0.5.1/whipplescript-installer.sh | shInstall prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/GaugeWright/whipplescript/releases/download/v0.5.1/whipplescript-installer.ps1 | iex"Install prebuilt binaries via Homebrew
brew install GaugeWright/tap/whipplescriptDownload whipplescript 0.5.1
| File | Platform | Checksum |
|---|---|---|
| whipplescript-aarch64-apple-darwin.tar.xz | Apple Silicon macOS | checksum |
| whipplescript-x86_64-apple-darwin.tar.xz | Intel macOS | checksum |
| whipplescript-x86_64-pc-windows-msvc.zip | x64 Windows | checksum |
| whipplescript-aarch64-unknown-linux-gnu.tar.xz | ARM64 Linux | checksum |
| whipplescript-x86_64-unknown-linux-gnu.tar.xz | x64 Linux | checksum |