Quest CLI 0.7.0
Version frozen 2026-09-15, in lockstep with @opum-ai/lore 0.7.0 -- the
pairing convention every release has held since 0.5.0, resumed after 0.6.2
broke it once deliberately. The date above is when this version was frozen
and the bump landed, not when it reached npm; publication is a separate,
manually authorized step, and nothing in this file should be read as evidence
that it happened.
Minor, not patch, and one entry below deserves reading before you upgrade
rather than after. quest task pause now parks a task at "Paused" instead
of "Blocked", so anything matching on the literal string "Blocked" to
find paused work will stop matching. No transition, flag or envelope shape
changed to make that true -- the configured value did. Everything else here
is additive: a new envelope field and two new optional flags, each inert when
not asked for.
Observed after release, 2026-09-15, reported by opum-cli-e2e from their
0.7.0 qualification matrix (their PR #154): that warning was published and
the best-placed consumer still missed it. Their 60-project-lifecycle suite
pinned the literal "Blocked" and six rows failed against a conformant quest,
while their 40-cross-product suite read the value live and absorbed the
same release without moving a row. Their fix binds the suite to what
task status-flow declares. A changelog warning is not a gate; a consumer
that binds to the CLI's own declaration does not need one.
Added
-
Every success envelope now carries
contractVersion: 1, a new field
distinct fromschemaVersion(which stays the outer envelope-wrapper
version).contractVersionis a single global counter, not a per-command
one: it moves whenever any command'sdatapayload shape changes in a way
an existing decoder would misread, so a consumer has one field to check
rather than needing to track ~30 commands independently (QCLI-289).This exists because 0.6.2's
QCLI-264/QCLI-265envelope-shape unification
(data.taskbecoming baredata, among others) shipped withschemaVersion
unchanged at1on both sides of the break -- reported downstream by host
mbpm2, whose own integration suite passed 0.6.2 validation and then broke
anyway, because nothing distinguished the old shape from the new one.
That break predates this field and stays undetectable by it:
contractVersionstarts at1in the release that introduces it rather
than being backdated to claim a transition that had no signal at the time.
Anything relying on the pre-contractVersionshape needs to keep doing
what it already does today (a defensive read of either shape); this field
only protects against the next shape change, not the last one.What
contractVersiondoes NOT cover. Stated here because a field that
says what it covers and not what it omits has the same defect it was added
to fix -- and because 0.7.0 itself contains two changes it does not signal.
Verified by probing every envelope family the 0.7.0 binary emits, not read
off the source:- Error envelopes carry no
contractVersion, by design. An error
envelope is{error_type, message, hint?, input?, principal}and carries
no envelope metadata at all -- noschemaVersionand nokindeither --
so its absence here is the existing design, not an oversight. Do not
infer "contractVersionabsent ⇒ pre-0.7.0 shape" from an error envelope;
that rule holds only for success envelopes. Errors are discriminated by
the frozen exit-code taxonomy (§3) instead, which is stable and needs no
version field. This is deliberate and will not be revisited quietly: the
error envelope is specified as a closed key set, so adding a key to it is
a breaking change for any consumer validating it strictly -- and at least
one does, which is precisely why the field was added to success envelopes
only. - Configured-value changes are not payload-shape changes. The counter
moves when adatapayload's shape changes in a way an existing decoder
would misread. It does not move when a value inside an unchanged shape
changes. 0.7.0 contains exactly such a change:quest task pausenow
parks a task at"Paused"instead of"Blocked", so a consumer matching
the literal string"Blocked"stops matching whilecontractVersion
correctly stays1. ReadcontractVersionas "can my decoder still parse
this?", never as "did anything I depend on change?" -- the second question
is what a changelog is for, and this entry is the answer for this release.
- Error envelopes carry no
-
quest task view <id> --max-notes NcapsimplementationNotesto the most
recentNentries, adding anotesOmittedcount (present whenever
--max-notesis supplied, including0, never otherwise). Additive and
opt-in -- omitted,task viewis byte-for-byte unchanged (QCLI-276, one
piece of DEC-3, a shape agreed jointly with@opum-ai/lore's own
lore contextbudget work). The rest of DEC-3's originally-scoped surface
(a general--fieldsselector,--since/cursor note selection, retrieving
one note by a stable id, field-level omission metadata) is deliberately
deferred, not dropped -- tracked as QCLI-291. -
quest task edit <id> --if-revision <rev>(and a per-itemifRevisionon
task edit-batch) lets a caller supply the revision it read earlier and
have the edit refused, before any state change, if the record has since
moved -- the same exit-5 conflict a concurrent write race already produces.
quest task view <id> --jsonnow returns that revision (additive field) so
a caller has something to capture. Omitted,task editis unaffected
(QCLI-277).
Fixed
-
A write conflict's
actualRevision-- the one piece of data a caller needs
to retry without a second read -- was silently discarded for every task
write conflict, not only the new--if-revisioncase above: the internal
helper that unwraps a mutation result threw a bare error with no payload.
The documented retry protocol ("re-read the latest state and perform your
own bounded retry") was correct advice that the CLI's own diagnostic didn't
carry the means to follow. Now named in the diagnostic'sinputon every
conflict, same exit code and message (QCLI-277). -
quest agents --check --require-installedexited0for a managed
instruction block whose content is current but whose embedded Quest CLI
version string is stale (state: version-only) -- correct, deliberate
behavior since QCLI-228, and already documented that way in this CLI's own
guide and help text. The one place that still lied about it: the
block's own embedded CI-hint sentence, written into every consumer's
CLAUDE.md/AGENTS.md, which said only "current instructions exit 0, ...
missing, drifted, or malformed managed instructions exit 6" with no mention
of the version-only case -- so a reader (lore-cli, concretely, whose
CLAUDE.md said Quest CLI 0.4.0 against an installed 0.6.0 for two minor
versions) reasonably concluded CI caught version drift when it deliberately
does not. The sentence now names the exemption explicitly; the exit code
itself was never the defect (QCLI-284, DEC-4). -
quest task pause <id>parked a task at status"Blocked"by default --
a false signal read fleet-wide as "needs intervention," even when nothing
was blocking the task. The default paused status is now"Paused",
structurally unchanged (still separate from theTo Do/In Progress/Done
ladder, still reachable only viapause/start) -- a naming fix, not a
new transition (QCLI-287).