CLI
The qualifier crate installs a binary called qualifier.
cargo install qualifier
Commands
Write records:
qualifier record <kind> <location> [message] Record an annotation
qualifier reply <target> <message> Reply to an existing record
qualifier resolve <target> [message] Resolve (close) an existing record
qualifier emit <type> <subject> --body JSON Emit a raw record of any type
<kind> accepts the built-in kinds (pass, fail, blocker, concern,
comment, praise, suggestion, waiver, resolve) or any custom string.
<location> is a path with an optional span (e.g., src/auth.rs:42).
<target> is an id-prefix (≥4 chars) or a <location>.
Inspect:
qualifier show <artifact> Show annotations for an artifact
qualifier ls [--kind K] List artifacts (optionally by kind)
qualifier praise <artifact> Show who annotated and why (alias: blame)
qualifier review [subject] Check freshness of span-bound annotations
Maintain:
qualifier compact <artifact> [options] Compact a .qual file
All commands that produce output accept --format json for machine-readable output.
Typical workflows
Record and resolve an issue
# Record a concern at a specific line
qualifier record concern src/parser.rs:42 "Panics on malformed input"
# See it
qualifier show src/parser.rs
# Reply (id-prefix, min 4 chars — or a location)
qualifier reply a1b2 "Good catch, fixed in latest commit"
qualifier reply src/parser.rs:42 "Good catch, fixed in latest commit"
# Close it
qualifier resolve a1b2
Threaded conversations
qualifier show src/parser.rs
src/parser.rs
Records (4):
concern L42 "Panics on malformed input" alice 2026-03-01 a1b2c3d4
├── comment "Good catch, fixed in latest commit" bob 2026-03-01 b2c3d4e5
└── resolve "Resolved" alice 2026-03-01 c3d4e5f6
praise "Excellent property-based test coverage" bob 2026-02-24 e5f6a7b8
Replies and resolves are threaded under their parent with tree-drawing characters.
Show details for one artifact
qualifier show src/parser.rs
src/parser.rs
Records (3):
concern L42–58 "Panics on malformed UTF-8 input" alice 2026-02-24 a1b2c3d4
praise "Excellent property-based test coverage" bob 2026-02-24 e5f6a7b8
suggestion "Consider adding fuzzing targets" carol 2026-02-24 f1f2f3f4
Use --all to include resolved/superseded records. Use --pretty to force colored output.
Record a quality concern with full options
qualifier record concern src/parser.rs "Panics on malformed UTF-8 input" \
--suggested-fix "Replace .unwrap() on line 42 with error propagation" \
--tag robustness --tag error-handling \
--issuer "mailto:alice@example.com" \
--span 42:58
--span overrides any span parsed from <location>. When the source file is
readable, content_hash is auto-computed.
Emit a raw record (raw or non-annotation types)
# A SPDX license record
qualifier emit license src/lib.rs --body '{"spdx":"MIT"}'
# A custom URI-typed record (round-trips via Record::Unknown)
qualifier emit https://example.com/lint/v1 src/parser.rs \
--body '{"rule":"no-panic","matches":3}'
emit is a low-level passthrough: the body is preserved verbatim. For
--type annotation, the body is validated against the annotation schema;
other types are not validated.
Compact old annotations
# Preview what compaction would do
qualifier compact src/parser.rs --dry-run
# Prune superseded annotations
qualifier compact src/parser.rs
# Collapse everything to a single epoch annotation
qualifier compact src/parser.rs --snapshot
# Compact every .qual file in the repo
qualifier compact --all
List artifacts
qualifier ls --kind blocker
qualifier ls --unqualified # artifacts with no annotations
Batch annotation (for agents)
# Pipe overrides JSONL from stdin: {kind, location, message, ...}
cat overrides.jsonl | qualifier record --stdin
# Or pipe complete records (envelope + body)
cat records.jsonl | qualifier emit --stdin
Configuration
Qualifier uses layered configuration (highest wins):
| Priority | Source | Example |
|---|---|---|
| 1 | CLI flags | --issuer mailto:me@example.com |
| 2 | Environment | QUALIFIER_ISSUER |
| 3 | Project config | .qualifier.toml |
| 4 | User config | ~/.config/qualifier/config.toml |
| 5 | Built-in defaults |