Skip to content

agent-ix/quire-cli

v0.1.1AGPL-3.0-or-later

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_digest removed from the assurance export (#107). The assurance export no longer carries a schema_digest field.
  • The data_schema reference is { schema } only. A data_schema reference 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 computed CoverageReport.coverage_matrix — requirement → criterion → binder symbols → computed status — on stdout as markdown (one ## <document> table per requirement, statements cut to 80 characters, binders as path:line:column with (ignored) markers), --format json (the engine's value verbatim plus the engine provenance block) or --format tsv. It never writes a file. --strict exits 1 on zero criteria or on any untagged/tagged-by-ignored-test criterion; method-without-symbol never fails it. --scope/--module resolve exactly as coverage resolves them, through the same shared computation. There is no --severity flag.
  • Engine: quire-rs 0.48.0 — changes what binds. Adds coverage_matrix to coverage --json for modules declaring an obligations: source. A range in any trace form now binds nothing. Before 0.48.0 a legacy // Trace: A..B tag bound A, and a range inside a verifies or implements marker minted one relation keyed on the literal A..B. Now neither endpoint binds, and no A..B relation is minted. This holds for every range shape in all three forms. Each such range is reported once as a range-in-trace-tag diagnostic. A legacy list that continues past a range still binds the other ids it names. As a result, totals, unbacked_rows and backed can change for any repo that wrote ranges in its tags, so quire coverage --strict can 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's id_format) now counts as declared, so a tag naming it no longer appears in untracked_symbols or unmatched_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-core 0.3.0 and requires bundle artifacts to list their operations. This is what the default Filament modules now declare. IT-145 now checks the pin's shape (by rev, with an exact = version) rather than a SHA restated across the changelog and specification; cargo --locked checks that the lock agrees.
  • package-npm emits only the platforms actually built, and a post-publish resolvability gate closes the loop (PLAT-885). The launcher's optionalDependencies is 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 new quire-dist verify-published command (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 trace subcommand (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 headed Citations (N) — NOT verification evidence; a zero-match query returns resolved: false with exit code 0. Every claim/citation record carries language and confidence derived per-record from the engine's own language_confidence, never a hardcoded per-language table. Added the skills/trace agent skill.
  • Bumped the quire-rs pin to 7efe616880610469f4577139c76856e18ef20fc6 (PLAT-844 merged), which carries src/symbols/trace_search.rs and the SymbolGraph.mentions field quire trace depends on.
  • Bumped the quire-rs pin to 523e47f61ca5532c3c86064ed4872a1c5de3ed02 (PLAT-850), carrying the Python (PLAT-868) and TypeScript (PLAT-882) symbol adapters' port from hand-rolled scanners to tree-sitter via quire-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 the assurance-v1 schema 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 616a7e97 for explicit per-reference status_column selection (quire-rs#409/#410). The v0.32.0 tag pins a874fb64, which predates that commit, so the published 0.32.0 binary rejects status_column as 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 of 85dfe9d5, #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 evaluate resolves one exact authority/id/version clause set and returns its binding decision with the supplied context; clauses diff compares 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 invokes quire-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's Registry::clause_sets() / clause_set() API and rights-aware ClauseSet types. FR-020-CON-1 advances with it, so IT-145's six surfaces still agree. The assurance_export.v1 capability and engine-owned assurance schema are unchanged.

  • Engine pin advances to acd1be633a1a89cf5e21bc1abb9a91b7e2493838 (PLAT-850), a descendant of 85dfe9d5 above that carries quire-rs's Rust AST port (PLAT-843, quire-rs#472, merged at 456f73f), 0df4206 (quire-rs#407, bounded native unittest method recognition), 616a7e9 (quire-rs#409/#410, per-reference status_column selection), 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 existing assurance-v1 graph/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; --pretty changes whitespace only. Diagnostics stay on stderr, empty success remains distinct from inability, and unreadable bounded inputs retain upstream's explicit unknown observation.

  • --module is 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 whose traceability: 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_PATH adds roots to ~/.ix/filament/modules rather 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 ~90 DuplicateModuleName / DuplicateArchetype lines 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-domain
    

    The roots are used in the order given and replace ambient discovery entirely: with any --module present, neither IX_FILAMENT_MODULES_PATH nor the default install root is consulted. --help states that order, because a caller cannot tell an adding flag from a replacing one by watching it succeed.

    validate, properties and symbols resolve 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 --module behaves exactly as before, and omitting it still discovers.

Changed

  • Engine pin advances to 616a7e97c0e8c84aedda71dc198e94e3de3d9da6 for explicit per-reference status_column selection (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 --strict now rejects structured status-column-matches-nothing and hollow-denominator diagnostics, 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, to a874fb6) and added the compile-checked assurance_export.v1 capability 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 in agent-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 adds Registry::load_module_set — the closed constructor the flag above is built on — along with the semantic-extraction surface (quire-rs FR-072). A semantic validation 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-deny invocation asserts the committed lock, the drift audit covers all resolver commands instead of build alone, and CI requires REGISTRY_TOKEN by 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 evaluate applies module-supplied context without collapsing missing or incomparable values to false; quire clauses diff compares two exact versions. Both provide human, JSON, and TSV output, and JSON carries the clause_sets capability. The CLI embeds no external publication content.

  • --version reports the engine, and every JSON payload carries provenance (#68, CR-104). quire --version reported this crate's version alone. The engine is a git dependency pinned by tag in Cargo.toml:20 and 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 --json and extract. 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.lock by build.rs, not from a constant: quire-rs's own manifest says 0.33.0 while it ships v0.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.

    capabilities is a token list, not version arithmetic. A consumer asserts it needs binding_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/$schema naming which contract revision it conforms to — that lets a payload assert its own conformance. Provenance under a named engine object 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 optional engine object.

[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-rs v0.44.1, which corrects two checks v0.44.0 shipped that were each measured against one corpus (agent-ix/quire-rs#235, #229).
    • coverage no longer reports vacuous-under-guard against TypeScript arrow functions. On agent-ix/quoin that was 549 suspicions from 551 candidates; it is now 0, and the genuine Rust positives are unchanged.
    • coverage no longer reports hollow-denominator for a count-shaped metric reading an honest zero. This repository's own coverage.implements reads 0 of 214 and was flagged as arithmetic over nothing.
    • Every metric in the coverage --json payload now carries a required shape (ratio | count), declared in coverage-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.txt produced a 0-byte file while 90,462 bytes went to stderr, and Coverage: 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. --json and --format tsv are unaffected — the census is emitted only in the human branch, so | jq is 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 --json on the pass-2 corpus is 597,636 bytes against an 869-byte census, so quoin's spec-correctness could not be driven from the compact surface at all. Defaults to the actionable set; --all includes example and unclassified.
  • The properties census carries the specific-shape split (quire-rs CR-095), so 54% no longer travels without the 8% 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 declared id_column cell.
  • suspicions in 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

  • coverage human 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 clickable document:line locus (TC-123 (spec/tests.md:9) has no backing symbol [traces-to]), instead of the reference kind repeated identically per row. no_symbol_rows renders for the first time; what source_exclude subtracted is counted on the census, and SymbolExtraction diagnostics (refused glob list, unreadable source file) reach stderr instead of being dropped.
  • Agent-sized coverage output (#53). A coverage severity pack — --severity coverage:{unbacked-row|status-lie|untracked-symbol|undeclared-status}=<off|warning|error> on the FR-048 machinery validate uses; off projects a kind out of every output surface (suppression announced with its count), error is a per-check gate. Totals and --strict always 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 surface no_symbol_rows, diagnostics, obligations and implements have had. A typo'd coverage check in --severity is rejected, not silently ignored (#57).
  • shared_trace_ids and vocabulary_coverage pass 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_statuses reporting (CR-083) and source_exclude (CR-085), both wired to the command line in the same release; v0.42.0 adds 1-based line on the five finding record kinds, excluded_source_files, shared_trace_ids and vocabulary_coverage.
  • coverage --json honours the global --pretty (#53). Compact single-line by default like every other JSON surface (FR-008-AC-1); --pretty restores 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.sh and 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_exclude wired 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 FRWhat was unreachable
    FR-057per-check corpus severity (trace:/refs:/edges:/bundle: keys)
    FR-058upward-trace completeness — orphan requirements and unimplemented needs
    FR-059declared-vocabulary coverage — which values no document claims
    FR-060from_vocabulary / column_vocabularies in body-extraction asserts
    FR-061combinatorial obligations from declared configuration dimensions

    Nothing in this crate changed to expose them: validate already routes the corpus packs and coverage already 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 --json gains 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) and uncatalogued-verification-method (a Verification cell naming neither a catalog method id nor a catalog class, which nothing reported before). diagnostics[].reason is a deliberately open vocabulary, so neither is a contract break for a consumer that pins the published schema.
    • statement_hash now normalizes to NFC before trimming, so an editor rewriting a decomposed accent no longer reads as a reworded requirement.
    • The obligations list is ordered by source declaration order rather than source name.
  • properties --json and validate --summary now 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's exclude: 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 in coverage --json and stated one here — and this payload is what spec-correctness generates 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-check was red on main: tests/output_contract.rs landed 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 --json records gain obligation (quire-rs FR-053). null for a module declaring no traceability.obligations: source, so a corpus that has not adopted them sees the key with a null rather than a shape change. The nested object carries source, statement_hash, method, criticality and optional parameters — and deliberately not id, statement or document, because the record and its enclosing object already carry all three.
    • coverage --json gains obligations, absent when the model declares no sources — so the payload is byte-identical for every module that has not adopted them.
    • validate gains the quality:* grammar (quire-rs FR-056): ambiguous-term, agentless-passive, mixed-modal. All advisory, and each addressable by --severity quality:<check>=off|warning|error like 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 --json envelope against quire-rs's published properties-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 are deny_unknown_fields, so quire validate / quire coverage fail loudly against a stale module rather than silently minting nothing. Pair this CLI with spec-artifacts-process v0.14.0 or later, which ships the matching collapse of nine declarations to three.
    • coverage --json reaches nested matrices. Path binding enumerated one target per filename convention and could not see spec/<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, and filament-ide-rs alone 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-document and absent-declared-document machine reasons are withdrawn — v0.19.0 shipped them for the code path CR-062 deletes. archetype-matches-nothing is 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.

[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 --json distinguishes an absent declared auxiliary document: from an unreadable one: absent-declared-document is a new machine reason, and unreadable-declared-document narrows 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 smaller totals.criteria / totals.property_shaped.
    • trace tags on benchmarks and fuzz targets now bind — a criterion_group!-registered function or a fuzz_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 in untracked_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 in coverage --json under a new diagnostics key 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 from no-frontmatter (quire-rs FR-024-AC-12).
    • ## 3.2 Ubiquitous Language and 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.

Fixed

  • --diagnostics json emitted non-fatal bundle warnings with "severity": "error". Every validate --okf warning 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_of gated on is_dir(), which follows symlinks, while the corpus walker does not — so the check passed and the run reported total: 0 and exit 0. The derived root is now canonicalized, which also makes coverage and validate --okf resolve the same document root for the same repository; they previously differed, since only validate canonicalized.
  • The missing-document-root error was a formatted string. It is now a typed DocumentRootError carrying a stable MissingDocumentRoot kind into --diagnostics json, so a consumer can branch on it instead of matching prose.
  • coverage now applies the same path-safety guard to its derived document root that validate has always applied to its bundle root.

Added

  • FR-017 and FR-018 — coverage and properties shipped 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 --json payload), and the properties payload 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 of spec/ (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 --okf now calls quire_rs::validate_bundle with the document root and the reference root stated separately (quire-rs FR-049-AC-9), so a module's document:/exclude: declarations keep resolving against the repository scope.

[0.16.0] — 2026-08-15

Changed

  • BREAKING (traversal). coverage, validate --okf and fix derive 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 --scope with no spec/ 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/bundle therefore fails unless path/to/bundle/spec exists — 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,172 required 'type' is missing errors 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: --scope remains 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-process v0.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, and archetype + document declared together (FR-050-AC-15).
    • vocabularies.no_source_symbol — verification methods that mint no source symbol, so coverage explains an eval row rather than accusing it (FR-050-AC-16). CoverageReport gains no_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 braces and 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). Emits row_id, statement, line, shape, property, extractable, extraction, the {domain, precondition, oracle} spans and the signals audit trail, as JSON under --json or a census otherwise. quire coverage --json emits 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-048 grammar_severity registry (FR-052-CON-1).
  • quire validate --summary now 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.yml could never publish. The workflow is workflow_dispatch only by policy, but both publish steps were gated on github.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.0 Cargo.toml. Publishing is now an explicit publish input, defaulting to false, and the release tag is derived from the resolved version rather than from GITHUB_REF_NAME.

0.2.4 — 2026-06-15

Added

  • quire validate now 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 frontmatter artifact_type.

Changed

  • --module remains 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/aarch64 Linux (musl, static), aarch64 macOS, and x86_64 Windows.
  • npm distribution: @agent-ix/quire-cli (GitHub Packages) with per-platform optional dependencies carrying the prebuilt binary — no source build or access to the private quire-rs repo required to install.
  • scripts/set_version.sh single-sources the release version across Cargo.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-rs to v0.4.2 (CR-007: escaped pipes in table cells).

0.2.0 — 2026-06-11

Added

  • quire lint subcommand — 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-rs via a pinned git tag instead of a sibling path dependency.

0.1.0 — 2026-05-28

Added

  • First release. quire binary with parse, extract, lookup, edit, validate, and schema subcommands over quire-rs. (The render subcommand was removed upstream before this line stabilized — see spec/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).