agent-ix/quire-cli
Explore, write, validate, link, and trace Markdown artifacts with Quire CLI.
Changelog
All notable changes to quire-cli are documented here.
The format is based on Keep a Changelog,
and this project adheres to Semantic Versioning.
The public contract under SemVer is the subcommand surface, exit codes, and JSON
output schemas (see spec/non-functional/NFR-006-cli-stability.md).
Unreleased
[0.36.1] - 2026-10-01
- Engine: quire-rs 0.50.1 (semantic-schema 0.3.0, quire-code-parse 0.2.2).
- Removed recorded versions, SHAs, measurements and pin copies from specs, tests and comments (#115).
[0.36.0] - 2026-10-01
- Engine: quire-rs 0.50.0. The pin moves forward to the v0.50.0 release. It embeds semantic-core 0.3.2 only: a module declaring semantic_core 0.3.0 is refused.
- Removed recorded revisions, digests and pin copies.
[0.35.1] - 2026-10-01
- Engine: quire-rs 0.49.1. The pin moves forward to the v0.49.1 release.
[0.35.0] - 2026-09-30
- Engine: quire-rs 0.49.0. The pin moves forward to the v0.49.0 release.
schema_digestremoved from the assurance export (#107). The assurance export no longer carries aschema_digestfield.- The
data_schemareference is{ schema }only. Adata_schemareference that also names a digest is rejected as ambiguous.
[0.34.0] - 2026-09-28
- Added
quire matrix(PLAT-1078, FR-026). Renders the engine's computedCoverageReport.coverage_matrix— requirement → criterion → binder symbols → computed status — on stdout as markdown (one## <document>table per requirement, statements cut to 80 characters, binders aspath:line:columnwith(ignored)markers),--format json(the engine's value verbatim plus theengineprovenance block) or--format tsv. It never writes a file.--strictexits 1 on zero criteria or on anyuntagged/tagged-by-ignored-testcriterion;method-without-symbolnever fails it.--scope/--moduleresolve exactly ascoverageresolves them, through the same shared computation. There is no--severityflag. - Engine: quire-rs 0.48.0 — changes what binds. Adds
coverage_matrixtocoverage --jsonfor modules declaring anobligations:source. A range in any trace form now binds nothing. Before 0.48.0 a legacy// Trace: A..Btag boundA, and a range inside averifiesorimplementsmarker minted one relation keyed on the literalA..B. Now neither endpoint binds, and noA..Brelation is minted. This holds for every range shape in all three forms. Each such range is reported once as arange-in-trace-tagdiagnostic. A legacy list that continues past a range still binds the other ids it names. As a result, totals,unbacked_rowsandbackedcan change for any repo that wrote ranges in its tags, soquire coverage --strictcan go from pass to fail on such a repo. Remedy: write each id out in full (FR-1-AC-1, FR-1-AC-2, …). Separately, an obligation's own id (for example an NFR-metric{document}-M-{row}id, or one rendered from the module'sid_format) now counts as declared, so a tag naming it no longer appears inuntracked_symbolsorunmatched_tags.
[0.33.0] - 2026-09-22
- Engine: quire-rs 0.47.1 (PLAT-974). The pin moves to the v0.47.1 release, whose semantic layer embeds
@agent-ix/semantic-core0.3.0 and requires bundle artifacts to list theiroperations. This is what the default Filament modules now declare. IT-145 now checks the pin's shape (byrev, with an exact=version) rather than a SHA restated across the changelog and specification;cargo --lockedchecks that the lock agrees. package-npmemits only the platforms actually built, and a post-publish resolvability gate closes the loop (PLAT-885). The launcher'soptionalDependenciesis now derived from the artifacts present in a given run, never from a hardcoded four-platform list — a platform this run didn't build is simply absent, not pinned to a version that was never published. A newquire-dist verify-publishedcommand (make dist-verify-published REGISTRY=<url>) asserts, after publish, that every declared platform package actually resolves at its pinned version in the target registry; it fails on an unresolved package and on an empty dependency set.0.32.1–0.32.3's already-published dangling pins are unchanged — this fixes the generator for future releases.- Added the
quire tracesubcommand (PLAT-879): structural forward (--id [--prefix]) and inverse (--symbol/--file) lookup over the quire-rs trace-search index (upstream FR-077/PLAT-844). Claims (verifies/implements) and citations stay in separate JSON subtrees and separate human sections, the second headedCitations (N) — NOT verification evidence; a zero-match query returnsresolved: falsewith exit code 0. Every claim/citation record carrieslanguageandconfidencederived per-record from the engine's ownlanguage_confidence, never a hardcoded per-language table. Added theskills/traceagent skill. - Bumped the
quire-rspin to7efe616880610469f4577139c76856e18ef20fc6(PLAT-844 merged), which carriessrc/symbols/trace_search.rsand theSymbolGraph.mentionsfieldquire tracedepends on. - Bumped the
quire-rspin to523e47f61ca5532c3c86064ed4872a1c5de3ed02(PLAT-850), carrying the Python (PLAT-868) and TypeScript (PLAT-882) symbol adapters' port from hand-rolled scanners to tree-sitter viaquire-code-parse. Still quire-rs 0.46.0: only the commit moves. The two ports change the symbols an extraction observes on Python/TypeScript sources but touch neither theassurance-v1schema nor this CLI's surface.
[0.32.3] - 2026-09-20
No source change from 0.32.2 (d61afb2, PLAT-850) — this release exists
solely to republish that commit's artifact correctly. 0.32.2's npm.ix
package was built before the commit that produced it was finalized: git commit --amend ran after the release build, not before, so the binary's own
quire provenance reported cli.sourceRevision as a commit (e723b59) the
amend then made unreachable from any branch, with cli.sourceState: "dirty".
The engine leg was unaffected (it's read from Cargo.lock content, not live
git state), and the behavioral fix itself was never in question — only the
published artifact's self-reported identity was wrong.
This build was produced from d61afb23e9a936658307ee2e49d8e627e096045c with
a clean working tree confirmed before compiling, never after. Its own quire provenance --json reports cli.sourceRevision: "d61afb23e9a936658307ee2e49d8e627e096045c",
cli.sourceState: "clean". The npm package version (0.32.3) does not match
the embedded CARGO_PKG_VERSION (0.32.2, from d61afb2's Cargo.toml,
deliberately left unchanged so the verified binary and the published
artifact are the same bytes) — this is a registry-label bump only, not a
crate version bump. 0.32.1 and 0.32.2 are deprecated on npm.ix; do not
resolve latest or a range to either.
This build covers linux-x64 only. @agent-ix/quire-cli@0.32.3's
optionalDependencies still declare darwin-arm64, linux-arm64, and
win32-x64 at 0.32.3, but no such versions exist on npm.ix for those three
platforms — the last version where all four platform packages exist is
0.32.0, so every release since 0.32.1 (including this one) carries three
dangling platform pins. npm install succeeds on those platforms (npm skips
a 404 on an optional dependency) and the launcher then exits 1 at every
invocation with "the prebuilt binary package ... is not installed." This
predates PLAT-850 and is not fixed here; see PLAT-885 for the gap and
fix options.
[0.32.2] - 2026-09-20
The npm.ix artifact published under this version was built dirty, from a
commit this repository's history no longer contains — see ## [0.32.3]
above. The source content described below is correct and is what actually
shipped in d61afb2; only the previously-published binary's own provenance
output was wrong. Deprecated on npm.ix in favor of 0.32.3. Because both
0.32.1 and 0.32.2 are deprecated, npm will not resolve latest or a
version range to either on any platform. On linux-x64 that leaves a
working, verified 0.32.3 above 0.32.0. On
darwin-arm64, linux-arm64, and win32-x64 it does not — no platform
package exists above 0.32.0 for those three (PLAT-885), so deprecating
0.32.1/0.32.2 leaves 0.32.0 as the newest install that actually runs
there, not merely the newest recommended one.
First published build of everything below that had been sitting under
## [Unreleased] — the npm distribution tooling, quire clauses, and the
85dfe9d5 engine advance were all implemented and merged to main across
earlier PRs without a version cut. Moved here rather than left orphaned above
a released version, the same drift the Fixed entry below is about.
Fixed
- The 0.32.0 entry below claims an engine pin that release did not ship. It
records the pin advancing to
616a7e97for explicit per-referencestatus_columnselection (quire-rs#409/#410). Thev0.32.0tag pinsa874fb64, which predates that commit, so the published 0.32.0 binary rejectsstatus_columnas an unknown field. Downstream work stalled for a week against a capability the changelog said was available. The engine pin in this release (acd1be6, a descendant of85dfe9d5, #83) does carry it. The historical entry is left in place and corrected here rather than rewritten.
Added
-
Rust-owned npm distribution tooling (FR-022..024, NFR-008, #61). A non-published workspace tool now owns the four-target package catalog, binary-format checks, deterministic package generation, Cargo/npm version synchronization, and release assertions. Rust tests exercise a clean offline npm install plus missing, wrong-target, unsupported-host, chmod, spawn, stream, exit-status, and signal paths. The cross-platform npm package remains; its sole Node file is the owner-approved minimal host in ADR-0002.
-
quire clauses(FR-021, #72).clauses evaluateresolves one exact authority/id/version clause set and returns its binding decision with the supplied context;clauses diffcompares two exact versions and reports added, removed and changed clauses by stable id. Both are wholly local — no network socket is opened and no command is executed (IT-158). TSV output carries a stable five-column header. IT-154..IT-157.
Changed
-
npm/build-packages.mjs,scripts/set_version.sh, embedded Node/Perl mutators, and duplicated launcher target metadata are removed. The manually dispatched release workflow invokesquire-dist; it was not dispatched and no package was published by this change. -
Engine pin advances to
85dfe9d5a937c52af6456f2e6aa3a6bc4c82db9f(quire-rs#422), which qualifies the engine on exact Rust 1.98.1 and contains quire-rs#381'sRegistry::clause_sets()/clause_set()API and rights-awareClauseSettypes. FR-020-CON-1 advances with it, so IT-145's six surfaces still agree. Theassurance_export.v1capability and engine-owned assurance schema are unchanged. -
Engine pin advances to
acd1be633a1a89cf5e21bc1abb9a91b7e2493838(PLAT-850), a descendant of85dfe9d5above that carries quire-rs's Rust AST port (PLAT-843, quire-rs#472, merged at456f73f),0df4206(quire-rs#407, bounded native unittest method recognition),616a7e9(quire-rs#409/#410, per-referencestatus_columnselection), and PLAT-845 (quire-rs#474, thread a function's own name into its body's container — changes 207 symbol ids across the measured corpus). quire-rs stays at semver 0.46.0; only the commit moves. No CLI surface, exit code, or JSON schema changes.
[0.32.1] - 2026-09-20
Superseded before merge, in-branch, once quire-rs main advanced to acd1be6
(quire-rs#474, PLAT-845) during PLAT-850's review. Pinned quire-rs
456f73f557183fa38b55956c8698e97cc9fe7d79 (PLAT-843 only) and was briefly
published to the internal npm.ix registry for verification; the amend that
produced 0.32.2 rewrote this release's commit out of the branch's history, so
no commit in this repository corresponds to it. See ## [0.32.2] above, which
carries the same change plus PLAT-845.
[0.32.0] - 2026-09-06
Added
-
Deterministic source-grounded assurance export (
quire assurance, #74). The new command exposes quire-rs's existingassurance-v1graph/export API without adding a second graph, schema, evidence envelope, execution path, or verdict. Repository/revision, exact module version, and the complete active schema-digest set are explicit and fail closed before stdout on drift. Compact output is the upstream byte sequence plus a newline;--prettychanges whitespace only. Diagnostics stay on stderr, empty success remains distinct from inability, and unreadable bounded inputs retain upstream's explicitunknownobservation. -
--moduleis repeatable, and the set it declares is closed (agent-ix/quire-rs#405, FR-017-AC-20/AC-21). The flag took a single value. A repository whosetraceability:model spans several modules could not name them all, so it fell back to discovery — and discovery re-admits the ambient install root.That fallback is the defect.
IX_FILAMENT_MODULES_PATHadds roots to~/.ix/filament/modulesrather than replacing them, so a module materialized at its pinned commit and also installed ambiently is loaded twice. Resolution is first-wins, so which copy answered a given document is not decided by the pin, and the ~90DuplicateModuleName/DuplicateArchetypelines saying so precede every batch and read as noise. The run produces a verdict it cannot attribute to a contract revision.quire coverage --scope . --module ./spec-artifacts-iso --module ./spec-domainThe roots are used in the order given and replace ambient discovery entirely: with any
--modulepresent, neitherIX_FILAMENT_MODULES_PATHnor the default install root is consulted.--helpstates that order, because a caller cannot tell an adding flag from a replacing one by watching it succeed.validate,propertiesandsymbolsresolve module sets through the same helper and take the same flag shape — two resolution orders would let the commands disagree about which module is in scope for one invocation.Additive: a single
--modulebehaves exactly as before, and omitting it still discovers.
Changed
-
Engine pin advances to
616a7e97c0e8c84aedda71dc198e94e3de3d9da6for explicit per-referencestatus_columnselection (quire-rs#409, merged as quire-rs#410), which also carries the canonical integration repair of four stale seeded validation-stack test pins. Global fallback on omission, the declared vocabulary, report-only defaults, strict unread-measurement gating, the assurance schema, and the QA7442 selector fixture are all unchanged. FR-020-CON-1 advances with it, so IT-145's six surfaces still agree. -
coverage --strictnow rejects structuredstatus-column-matches-nothingandhollow-denominatordiagnostics, retaining JSON output and default report-only behavior (contract-core IR51-02). -
Pinned quire-rs 0.46.0 at assurance-export merge
e3352a0644abcfd5f0ebad348bc7aca235925ecc(advanced again below, in the same release, toa874fb6) and added the compile-checkedassurance_export.v1capability token. The assurance payload itself remains the closed upstream contract and therefore receives no added CLI provenance field. Version publication remains owned by the shared release/pin gate inagent-ix/engineering-assurance#8; this change records compatibility without publishing or dispatching hosted CI. -
Engine pin advances to
a874fb641cb70da83c8c8b23f9fea0a44255b88a(still quire-rs 0.46.0, a descendant of the assurance-export merge above, so FR-020-CON-1 advances with it), which addsRegistry::load_module_set— the closed constructor the flag above is built on — along with the semantic-extraction surface (quire-rs FR-072). Asemanticvalidation reason now renders with a corrective remedy like every other typed reason rather than being unhandled.
[0.31.0] - 2026-08-29
Fixed
- Cargo and private-dependency drift now fails at the point of cause. Every
canonical
cargo-denyinvocation asserts the committed lock, the drift audit covers all resolver commands instead of build alone, and CI requiresREGISTRY_TOKENby name before configuring private Quire access. The engine pin advances to the Quire revision whose own workflows apply the same all-surface policy.
Added
-
Generic clause-set evaluation and diff.
quire clauses evaluateapplies module-supplied context without collapsing missing or incomparable values to false;quire clauses diffcompares two exact versions. Both provide human, JSON, and TSV output, and JSON carries theclause_setscapability. The CLI embeds no external publication content. -
--versionreports the engine, and every JSON payload carries provenance (#68, CR-104).quire --versionreported this crate's version alone. The engine is a git dependency pinned by tag inCargo.toml:20and no surface reported it at all, so a current CLI could link a stale engine and still print a confident number.Measured: the installed CLI 0.29.0 pins engine v0.42.0, while
binding_census— the only signal answering "did the trace binder read a single test?" — landed in v0.43.0. Four battle-testing passes reported ecosystem figures from a binary that could not emit it, and nothing in the output said so. Same shape as #52, where tags 0.24.0–0.28.0 all shipped binaries reporting 0.23.0.$ quire --version quire 0.30.2 (engine 0.45.0)"engine": { "cli": "0.30.2", "engine": "0.45.0", "capabilities": ["binding_census", "metrics_envelope", "…"] }Carried by
coverage --json,properties --jsonandextract. Upgrading a binary fixes one instance; putting provenance on the payload fixes the class, because it survives being saved to disk — and a saved payload is what a later reader actually reasons from.The engine version is read from
Cargo.lockbybuild.rs, not from a constant:quire-rs's own manifest says0.33.0while it shipsv0.45.0, so a constant would report a number nobody runs. A-<n>-g<sha>describe suffix travels verbatim and is never rounded to the nearest tag.capabilitiesis a token list, not version arithmetic. A consumer asserts it needsbinding_census, never that the engine is>= 0.43.0— a version comparison in a consumer is a second place the contract lives. Each token names an engine surface this binary calls, so a build linking an engine lacking one does not compile.
Changed
- FR-008-AC-5 narrowed (CR-104). It banned "a CLI version string in JSON
output", conflating two claims. A payload must still never carry a bare
version/schema_version/$schemanaming which contract revision it conforms to — that lets a payload assert its own conformance. Provenance under a namedengineobject is a different claim, and its absence was the defect. quire-rs FR-055-CON-2 is narrowed in the same terms, and its two published schemas define the optionalengineobject.
[0.30.2] — 2026-08-22
First release since 0.27.0 that actually publishes. Cargo.toml sat at
0.29.0 while v0.28.0, v0.29.0, v0.30.0 and v0.30.1 were tagged, and the
release workflow is workflow_dispatch-only — so no tag ran it, and the one
dispatch that did run refused to publish a binary reporting a stale version.
Those four tags shipped nothing.
Fixed
- Engine bumped to
quire-rsv0.44.1, which corrects two checks v0.44.0 shipped that were each measured against one corpus (agent-ix/quire-rs#235,#229).coverageno longer reportsvacuous-under-guardagainst TypeScript arrow functions. Onagent-ix/quointhat was 549 suspicions from 551 candidates; it is now 0, and the genuine Rust positives are unchanged.coverageno longer reportshollow-denominatorfor a count-shaped metric reading an honest zero. This repository's owncoverage.implementsreads 0 of 214 and was flagged as arithmetic over nothing.- Every metric in the
coverage --jsonpayload now carries a requiredshape(ratio|count), declared incoverage-v1.schema.json.
[0.30.0] — 2026-08-22
Output-contract release. Part of the metric-integrity programme (agent-ix/quoin#197).
Changed
-
BREAKING (human surface): results go to stdout, diagnostics to stderr (#59, #60, CR-012, FR-006-AC-5, FR-017-AC-1 amended).
quire coverage > out.txtproduced a 0-byte file while 90,462 bytes went to stderr, andCoverage: 1238/2390 rows backed (51%)— a census — rendered in the same red as every finding.This corrects a contradiction rather than introducing a contract: FR-006 has required primary result on stdout since v0.1, and FR-017-AC-1 said the opposite.
--jsonand--format tsvare unaffected — the census is emitted only in the human branch, so| jqis untouched and the #51 WONTFIX stands.
Added
properties --criteria(#59, FR-018-AC-10) renders one block per criterion — row id,document:line, shape, and the extraction spans. Those fields were--json-only, and--jsonon the pass-2 corpus is 597,636 bytes against an 869-byte census, so quoin'sspec-correctnesscould not be driven from the compact surface at all. Defaults to the actionable set;--allincludesexampleandunclassified.- The properties census carries the specific-shape split (quire-rs CR-095),
so
54%no longer travels without the8%beside it. - Row ids in
validate's assert findings (#58, engine CR-097). Was 15 of 496 findings carrying an id, with one distinct line per document; now every row-scoped failure carries its own line and its declaredid_columncell. suspicionsin the coverage payload (engine FR-064): a property suite whose assertions may never run, and an oracle that copies the code it judges.
Engine
- quire-rs v0.44.0 (from v0.42.0): the metric provenance envelope, the binding census, the honest properties headline, the skeptic layer, the corpus benchmark and the cross-corpus overfit check.
[0.29.0] — 2026-08-21
The first npm publish since 0.12.0. release.yml now asserts the built
binary's --version matches the version being released (#52) — the guard the
0.24.0–0.28.0 tags shipped without, every one of whose binaries reported
0.23.0.
Added
coveragehuman findings are actionable lines (#51). Every unbacked-row, status-lie, undeclared-status — and now no-symbol-row — census line leads with the row's own id and a clickabledocument:linelocus (TC-123 (spec/tests.md:9) has no backing symbol [traces-to]), instead of the reference kind repeated identically per row.no_symbol_rowsrenders for the first time; whatsource_excludesubtracted is counted on the census, andSymbolExtractiondiagnostics (refused glob list, unreadable source file) reach stderr instead of being dropped.- Agent-sized
coverageoutput (#53). Acoverageseverity pack —--severity coverage:{unbacked-row|status-lie|untracked-symbol|undeclared-status}=<off|warning|error>on the FR-048 machineryvalidateuses;offprojects a kind out of every output surface (suppression announced with its count),erroris a per-check gate. Totals and--strictalways judge the full computation, never the projection. And--format tsv: one nine-column tab-separated record per line on stdout (~36% of the JSON size), the first rendered surfaceno_symbol_rows,diagnostics,obligationsandimplementshave had. A typo'd coverage check in--severityis rejected, not silently ignored (#57). shared_trace_idsandvocabulary_coveragepass through--json(quire-rs v0.42.0 advisory lists), both absent when empty.
Changed
- quire-rs v0.40.0 → v0.42.0. v0.41.0 brought
undeclared_statusesreporting (CR-083) andsource_exclude(CR-085), both wired to the command line in the same release; v0.42.0 adds 1-basedlineon the five finding record kinds,excluded_source_files,shared_trace_idsandvocabulary_coverage. coverage --jsonhonours the global--pretty(#53). Compact single-line by default like every other JSON surface (FR-008-AC-1);--prettyrestores the previous indented shape. Whitespace-only — the payload parses identically.
Fixed
- npm launcher and platform packages had sat at 0.12.0 against a 0.23.0
Cargo.toml; versions are staged in lockstep by
scripts/set_version.shand guarded in CI (#52).
[0.24.0] – [0.28.0] — 2026-08-19 .. 2026-08-20
Tagged without CHANGELOG entries (and without set_version.sh — the defect
#52 closes; none of these reached npm). What each tag carried:
- 0.28.0 — quire-rs v0.41.0 capabilities reach the command line (#50):
undeclared statuses on both surfaces,
source_excludewired to the walk. - 0.27.0 — quire-rs v0.38.0 → v0.40.0 (#48).
- 0.26.2 — every published npm package declares AGPL-3.0, not MIT (#47).
- 0.26.1 — matrix trace/criterion bindings repaired (#44, #46).
- 0.26.0 — quire-rs v0.36.0 → v0.38.0 (#42).
- 0.25.1 — CI: bounded, retried musl toolchain install (#41).
- 0.25.0 — quire-rs v0.34.0 → v0.36.0 (#40).
- 0.24.0 — quire-rs v0.33.0 → v0.34.0 (#39).
[0.23.0] — 2026-08-18
Changed
-
quire-rs v0.30.0 → v0.33.0. The engine had moved five releases ahead of this CLI, so every capability added by ADR-0011 Phase 2 waves A–D was unreachable from any command line:
Engine FR What was unreachable FR-057 per-check corpus severity ( trace:/refs:/edges:/bundle:keys)FR-058 upward-trace completeness — orphan requirements and unimplemented needs FR-059 declared-vocabulary coverage — which values no document claims FR-060 from_vocabulary/column_vocabulariesin body-extraction assertsFR-061 combinatorial obligations from declared configuration dimensions Nothing in this crate changed to expose them:
validatealready routes the corpus packs andcoveragealready emits the obligation contract, so the bump is the fix. That is also why it went unnoticed — the CLI kept working, and simply answered from an older engine.
[0.22.0] — 2026-08-17
Changed
-
Engine bumped to quire-rs v0.30.0 — the post-merge review follow-ups for the ADR-0011 P1 wave (agent-ix/quire-rs#150–#153, CR-063..CR-065). Reaching this CLI:
coverage --jsongains two diagnostic reasons:obligation-row-states-nothing(a row whose statement cell is empty — the diagnostic FR-053-AC-8 always promised and never emitted) anduncatalogued-verification-method(aVerificationcell naming neither a catalog method id nor a catalog class, which nothing reported before).diagnostics[].reasonis a deliberately open vocabulary, so neither is a contract break for a consumer that pins the published schema.statement_hashnow normalizes to NFC before trimming, so an editor rewriting a decomposed accent no longer reads as a reworded requirement.- The
obligationslist is ordered by source declaration order rather than source name.
-
properties --jsonandvalidate --summarynow pass each document's scope-relative path to the engine (new FR-018-AC-7, IT-098). quire-rs FR-053-AC-14 makes an obligation source'sexclude:globs bind the classification surface as well as the coverage rollup, and it can only do so if this crate hands over the path. Before, a criterion in an excluded fixture stated no obligation incoverage --jsonand stated one here — and this payload is whatspec-correctnessgenerates property tests from, so the asymmetry became a generated test carrying a trace tag for an id nothing mints. Stdin passes no path, having no location a glob could match.
Fixed
make fmt-checkwas red onmain:tests/output_contract.rslanded unformatted in v0.21.0 (#37). The same class of miss as agent-ix/quire-rs#150, found by the same review.
[0.21.0] — 2026-08-17
Changed
-
Engine bumped to quire-rs v0.29.0 — the ADR-0011 engine surface (agent-ix/quire-rs#81 P1: FR-053 obligation record, FR-054 verification-method catalog, FR-055 published output contract, FR-056 requirement-quality lints). Reaching this CLI:
properties --jsonrecords gainobligation(quire-rs FR-053).nullfor a module declaring notraceability.obligations:source, so a corpus that has not adopted them sees the key with a null rather than a shape change. The nested object carriessource,statement_hash,method,criticalityand optionalparameters— and deliberately notid,statementordocument, because the record and its enclosing object already carry all three.coverage --jsongainsobligations, absent when the model declares no sources — so the payload is byte-identical for every module that has not adopted them.validategains thequality:*grammar (quire-rs FR-056):ambiguous-term,agentless-passive,mixed-modal. All advisory, and each addressable by--severity quality:<check>=off|warning|errorlike any other check. Report change: measured across 239 repositories, 20.2% of FR/NFR/StR documents gain at least one warning.
Added
- Output-contract conformance tests (IT-095, IT-096) validating the emitted
properties --jsonenvelope against quire-rs's publishedproperties-v1.schema.json. The engine publishes both schemas and gates the parts it emits; it never constructs this envelope, so without a test here the published schema would describe a shape nothing checked. The schema is read from the resolved quire-rs source rather than vendored — a copy is a second artifact that drifts.
[0.20.0] — 2026-08-17
Changed
-
Engine bumped to quire-rs v0.28.0 — archetype-only trace binding (quire-rs CR-062). Behavior reaching this CLI:
- A module declaring
document:on a trace target or a document reference no longer loads. The key is retired and the nested structs aredeny_unknown_fields, soquire validate/quire coveragefail loudly against a stale module rather than silently minting nothing. Pair this CLI withspec-artifacts-processv0.14.0 or later, which ships the matching collapse of nine declarations to three. coverage --jsonreaches nested matrices. Path binding enumerated one target per filename convention and could not seespec/<module>/matrix/tests.md; archetype binding types the document instead. Report change: repositories authoring nested module matrices gain minted ids and backed rows — measured across 238 repositories, dead trace tags fall 1,401 → 1,207 occurrences, andfilament-ide-rsalone goes 17/850 → 473/2,184 rows backed.- A mistyped matrix now mints nothing, where under path binding
frontmatter was irrelevant. Report change: a repository whose Test
Matrix declares the wrong
type:sees its test-case ids disappear — the fix is to correct the frontmatter, and the six ecosystem cases were corrected before quire-rs cut the release. - The
unreadable-declared-documentandabsent-declared-documentmachine reasons are withdrawn — v0.19.0 shipped them for the code path CR-062 deletes.archetype-matches-nothingis the surviving reason. Anything keying on the two withdrawn tokens must migrate.
Cut now because the ADR-0011 verification program (agent-ix/quire-rs#81) works against the installed CLI: an engine-before-module release ordering is unverifiable if the CLI the modules are validated with lags the engine.
- A module declaring
[0.19.0] — 2026-08-16
Changed
-
Engine bumped to quire-rs v0.27.0 — the SR-007 blockers (quire-rs CR-059..CR-061). Behavior reaching this CLI:
coverage --jsondistinguishes an absent declared auxiliarydocument:from an unreadable one:absent-declared-documentis a new machine reason, andunreadable-declared-documentnarrows to the always-wrong case (quire-rs FR-050-AC-19). A fleet module shipping an optional declaration across many repositories no longer reports a fault where there is none.- a model-level
traceability.exclude:scopes the criteria walk as well as every declaration (quire-rs FR-050-AC-13/15). Report change: a repository declaring the new key with criteria under those paths sees smallertotals.criteria/totals.property_shaped. - trace tags on benchmarks and fuzz targets now bind — a
criterion_group!-registered function or afuzz_target!invocation is leaf evidence, where before it minted no binding (quire-rs FR-051-AC-17). Report change: coverage rises for repositories whose benches or fuzz targets carry tracking tags, and correspondingly fewer tags land inuntracked_symbols.
This last one is why the bump is cut now rather than batched: the corpus measurements on agent-ix/quire-rs#75 and #78 must run on an engine that binds leaf evidence, or their numbers are stale on arrival.
[0.18.0] — 2026-08-16
Changed
- Engine bumped to quire-rs v0.26.0 — the SR-006 review follow-up program
(quire-rs CR-050..CR-058). Behavior reaching this CLI:
- a declared
document:that cannot be read, a declared archetype no document has, and a model with no trace targets are now reported incoverage --jsonunder a newdiagnosticskey instead of failing open (quire-rs FR-050-AC-19). The key is absent when empty, so a healthy repository's report is byte-identical to before. - the malformed-frontmatter warning carries its own machine reason,
malformed-frontmatter, distinct fromno-frontmatter(quire-rs FR-024-AC-12). ## 3.2 Ubiquitous Languageand other ISO-numbered headings contribute glossary terms again (quire-rs FR-044-AC-8).- the code walk's document-root exclusion is compared by canonicalized
identity, so a case-insensitive filesystem or a symlinked
spec/no longer ingests every spec document a second time as source.
- a declared
Fixed
--diagnostics jsonemitted non-fatal bundle warnings with"severity": "error". Everyvalidate --okfwarning took the error path, which hardcodes error severity, so the machine surface contradicted the exit code — which was correctly 0. Warnings now carry"severity": "warning"and"kind": "ValidationWarning".- A symlinked
spec/produced a silent empty corpus.spec_root_ofgated onis_dir(), which follows symlinks, while the corpus walker does not — so the check passed and the run reportedtotal: 0and exit 0. The derived root is now canonicalized, which also makescoverageandvalidate --okfresolve the same document root for the same repository; they previously differed, since onlyvalidatecanonicalized. - The missing-document-root error was a formatted string. It is now a typed
DocumentRootErrorcarrying a stableMissingDocumentRootkind into--diagnostics json, so a consumer can branch on it instead of matching prose. coveragenow applies the same path-safety guard to its derived document root thatvalidatehas always applied to its bundle root.
Added
- FR-017 and
FR-018 —
coverageandpropertiesshipped in v0.13.0 with no owning requirement, no acceptance criteria and no matrix rows. Both are now specified from working code, with IT-086..IT-097 covering them. Writing them down corrected two documented claims: the human census renders on stderr (stdout carries only the--jsonpayload), and thepropertiespayload is a{documents: [{document, archetype, criteria}]}envelope. fix's default-root behavior has coverage for the first time (IT-080), as does the code walk's exclusion ofspec/(IT-087).
[0.17.0] — 2026-08-15
Changed
- Engine bumped to quire-rs v0.25.0: lazy document bodies, declaration-driven body selection, and the frontmatter-less warning inversion (quire-rs CR-046..049).
- A markdown file under the document root with no frontmatter block is no
longer silently ignored: it emits one non-fatal warning naming its path
(quire-rs FR-024-AC-10). Silence was justified only by tolerating a
repository-root walk, which 0.16.0 removed — what remains inside
spec/is almost certainly an authoring mistake. validate --okfnow callsquire_rs::validate_bundlewith the document root and the reference root stated separately (quire-rs FR-049-AC-9), so a module'sdocument:/exclude:declarations keep resolving against the repository scope.
[0.16.0] — 2026-08-15
Changed
- BREAKING (traversal).
coverage,validate --okfandfixderive two roots from one--scope: the corpus is walked from<scope>/spec, while the code walk and the module's path-bound declarations keep using<scope>(quire-rs CR-045, FR-050-AC-17). Engine bumped to quire-rs v0.24.0. - A
--scopewith nospec/directory now exits non-zero with a diagnostic naming the missing document root, instead of silently walking the scope.quire validate --okf --scope path/to/bundletherefore fails unlesspath/to/bundle/specexists — pass a self-contained bundle as the positional argument instead, which is honored as given. - Repository-root files (
README.md,CHANGELOG.md,plan/*.md) are no longer read as spec documents. [RAN] this removed 9,172required 'type' is missingerrors across 223 repositories — because those files are never visited, not because they were classified away. - The minted-id set over a compliant repository (documents under
spec/) is byte-identical to a pre-split run:--scoperemains the relativization base for every emitted path.
[0.15.0] — 2026-08-14
Changed
- Engine bumped to quire-rs v0.21.0. A legacy trace comment carrying a
comma-separated list now binds every id it names rather than only the first
(quire-rs FR-051-AC-16). Paired with
spec-artifacts-processv0.13.0, which widens the declared patterns so there is a list to split — [RAN] 205 ids across 17 repos start binding with no source edit. Closes agent-ix/quire-rs#68.
[0.14.0] — 2026-08-14
Changed
- Engine bumped to quire-rs v0.20.0, which brings the traceability model two
declarations it could not express and stops the symbol adapters losing whole
files:
exclude:path globs on trace targets and document references, andarchetype+documentdeclared together (FR-050-AC-15).vocabularies.no_source_symbol— verification methods that mint no source symbol, socoverageexplains an eval row rather than accusing it (FR-050-AC-16).CoverageReportgainsno_symbol_rows, absent when the active module declares no such vocabulary, so existing output is unchanged.- Rust and TypeScript source scanning is string-aware in one lexer pass
(FR-051-AC-14/15). 33 files in quire-rs alone had been rejected as
unbalanced bracesand yielding zero symbols, so every trace tag in them bound to nothing.
This release is what unblocks spec-artifacts-process declaring
no_source_symbol: a manifest key fails module load outright against an engine
that does not know it, so the CLI has to ship first.
No changelog entry was written for 0.13.0; this entry does not attempt to reconstruct it.
[0.12.0] — 2026-08-08
Added
quire properties— per-criterion property-shape classification (quire-rs FR-052). Emitsrow_id,statement,line,shape,property,extractable,extraction, the{domain, precondition, oracle}spans and thesignalsaudit trail, as JSON under--jsonor a census otherwise.quire coverage --jsonemits only per-document counts, so the per-criterion records a property-test generator reads had no CLI surface before this. Never a finding: classification carries no severity and no check id and is not addressable by the FR-048grammar_severityregistry (FR-052-CON-1).quire validate --summarynow also prints the property-extractable ratio and the candidate count. Computed by calling the engine directly, not by reading a warning message back — classification emits no message, and routing it through one would make it a finding.
Changed
- Pinned to quire-rs v0.18.0.
Fixed
release.ymlcould never publish. The workflow isworkflow_dispatchonly by policy, but both publish steps were gated ongithub.event_name == 'push', so a dispatch built four binaries and skipped the GitHub Release and the npm publish alike — which is why npm sat at 0.4.1 against a 0.11.0Cargo.toml. Publishing is now an explicitpublishinput, defaulting to false, and the release tag is derived from the resolved version rather than fromGITHUB_REF_NAME.
0.2.4 — 2026-06-15
Added
quire validatenow accepts one or more document paths/globs and a scoped validation mode:quire validate --scope <dir> <glob> [glob...].- Scoped validation resolves relative globs under
--scope, loads repo/module search roots, and validates each document using frontmatterartifact_type.
Changed
--moduleremains available as the exact single-module compatibility path, while scoped validation is the ergonomic default for changed spec files.
0.2.3 — 2026-06-14
Added
- Prebuilt binaries for four targets published on each tag:
x86_64/aarch64Linux (musl, static),aarch64macOS, andx86_64Windows. - npm distribution:
@agent-ix/quire-cli(GitHub Packages) with per-platform optional dependencies carrying the prebuilt binary — no source build or access to the privatequire-rsrepo required to install. scripts/set_version.shsingle-sources the release version acrossCargo.toml, the npm packages, and this changelog.
Changed
- Release profile now strips symbols and uses
panic = "abort", so a panic SIGABRTs to exit 134 as documented in FR-007.
0.2.1 — 2026-06-12
Changed
- Bump
quire-rsto v0.4.2 (CR-007: escaped pipes in table cells).
0.2.0 — 2026-06-11
Added
quire lintsubcommand — evaluate a module's advisory lint rules against a document (FR-013).
Changed
- Surface module eager-load failures instead of deferring them (FR-004 CR).
0.1.1 — 2026-06-06
Changed
- Depend on
quire-rsvia a pinned git tag instead of a sibling path dependency.
0.1.0 — 2026-05-28
Added
- First release.
quirebinary withparse,extract,lookup,edit,validate, andschemasubcommands overquire-rs. (The render subcommand was removed upstream before this line stabilized — seespec/spec.md§2bis.) - Path-safety guard, stdin/stdout/stderr contract, exit-code contract, and JSON output encoding (FR-005..008).
- Static-binary, zero-unsafe, no-network, and CLI-stability gates (NFR-002..006).