# Changelog
All notable changes to **simdutf8-cli** are documented here.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to
[Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
Nothing yet.
## [0.2.7] — 2026-06-02
Maintenance release — expanded testing and a dependency refresh; no functional
changes to the CLI.
### Added
- **Property-based ("exhaustive") tests** (`tests/proptest_validation.rs`, via
`proptest`): randomized invariants over `validate`/`is_valid` vs
`std::str::from_utf8`, `json_escape`/`json_record`/`json_block` JSON
round-trips, `build_sarif` always emitting re-parseable SARIF, `safe_join`
path confinement, and the `read_capped` size cap.
- **Three new fuzz targets** (`fuzz/`), bringing the suite to eight:
`validate_prefix` (the reported `valid_up_to` is a real UTF-8 boundary and
validation is deterministic), `render_blocks` (the text/JSON stdout
renderers), and `sarif_markdown` (the SARIF → Markdown rendering path).
### Changed
- Version bumped 0.1.6 → 0.2.7.
- Refreshed the lockfile to the latest semver-compatible dependency versions
(`cargo update`): `ignore` 0.4.26, `regex` 1.12.4, `regex-syntax` 0.8.11,
`syn` 2.0.118, `quote` 1.0.46, `memchr` 2.8.2, `smallvec` 1.15.2, `bitflags`
2.13.0, `chrono` 0.4.45, `log` 0.4.33, `cc` 1.2.65, `yoke` 0.8.3, `getrandom`
0.4.3, `js-sys`/`wasm-bindgen` 0.2.125, plus transitive cleanups.
## [0.1.6] — 2026-06-02
Version bumped to **0.1.6** (built on the `simdutf8` 0.1.5 library).
### Added
- **Quality-gate harness.** `scripts/quality_gates.sh` runs the crate's Rust
gates (fmt, clippy, test, test+SIMD, audit, deny, machete, tree-duplicates,
rust-doctor, hakari, changelog-version, fuzz, bats) with a pass/skip/fail
summary; `--strict` fails fast, `--fast` skips slow/nightly gates. Each gate
self-skips when its tool is missing.
- **Per-gate runners** under `tests/scripts/`: `test_cargo_fmt.sh`,
`test_cargo_clippy.sh`, `test_cargo_audit.sh`, `test_cargo_deny.sh`,
`test_rust_doctor.sh`, `test_cargo_kani.sh`, `test_cargo_tree_duplicates.sh`,
`test_cargo_vet.sh`, `test_cargo_udeps.sh`, `test_csaf_ndaal.sh`,
`test_fuzzing_targets.sh` (alongside `test_cargo_hakari.sh`), each report-only
by default with `--strict`, archiving to
`documentation/rust/<gate>/<TIMESTAMP>/`, and each with a `*.bats` sister.
`quality_gates.sh` now also runs the kani / vet / udeps / csaf gates (which
self-skip when not installed or not applicable).
- **CSAF 2.1 advisory** `csaf/2026/087/ndaal-sa-2026-087.json` (informational)
announcing this release, with the five hash sidecars and a regenerated
`index.txt` / `changes.csv` discovery index (see `skills/csaf`); validated by
`tests/scripts/validate_csaf.py`.
- **Published to crates.io** as `simdutf8-cli` 0.1.6
(`cargo install simdutf8-cli`).
- **Release binaries** for five platforms — `x86_64`/`aarch64-apple-darwin`,
`x86_64`/`aarch64-unknown-linux-gnu` and `x86_64-pc-windows-gnu`
(Linux/Windows cross-compiled with `cargo-zigbuild`) — packaged under
`dist/v0.1.6/` with per-archive and aggregate `SHA-256`/`SHA-512`/`SHA3-512`
checksums, a CycloneDX SBOM, and release notes (the `.tar.gz` are attached to
the GitLab `v0.1.6` release, not committed). Tagged `v0.1.6`.
### Changed
- Renamed the localized READMEs to the ndaal convention: `README.de.md` →
`LIESMICH.md`, `README.fr.md` → `LISEZMOI.md` (see `CLAUDE.md`).
- **Recursive directory walking.** A directory argument is now walked
recursively (via the `ignore` crate) instead of being rejected. The walker
**respects `.gitignore` / `.ignore` by default** (even outside a git repo),
skips hidden files, and never follows symlinked directories. New flags:
- `--exclude <GLOB>` — exclude paths matching a gitignore-style glob
(repeatable).
- `--no-ignore` — do not respect `.gitignore` / `.ignore` files.
- `--hidden` — include hidden files and directories.
Explicitly named files are always validated; ignore rules apply only while
walking directories, and every discovered file is still opened/read through
the hardened `PathPolicy`.
### Fixed
- Migrated `clippy.toml` (valid kebab-case config only; lint *levels* moved to
`Cargo.toml [lints.clippy]`) and `deny.toml` (v2 `[advisories]`/`[licenses]`
schema) to the current tool schemas, so `cargo clippy` and `cargo deny check`
run cleanly with the repository's own configuration. `rust-doctor` now scores
**100/100**.
## [0.1.0] — 2026-06-02
Initial release: a security-hardened command-line front-end for the
[`simdutf8`](https://crates.io/crates/simdutf8) crate.
### Added
- **UTF-8 validation CLI** over files and standard input, built on
`simdutf8::basic` (fast yes/no) and `simdutf8::compat` (exact error location,
matching `std::str::from_utf8`).
- **Exit-code contract**: `0` all valid, `1` at least one invalid, `2` an
operational/security error.
- **Output formats** (`--format`): `text` (default), `json`, `sarif` (SARIF
2.1.0, strict-validated), and `markdown` (GitHub-Flavored, derived from the
SARIF). See `skills/rust-sarif.md`.
- **Auto-generated reports**: `report.sarif` + `report.md` are written to
`--output-dir` (default current directory) unless `--no-report` is given. Both
are validated after creation; the write is scoped through a `cap-std`
capability handle so a crafted name cannot escape the output directory.
- **Hardened path handling** (`src/path_security.rs`): path-traversal rejection
(`--base-dir` confinement), symlink-escape / TOCTOU mitigation, symlink denial
(`--no-follow-symlinks`), regular-file-only enforcement, and a configurable
read cap (`--max-size`, default 64 MiB). Includes a lexical `safe_join`
primitive for confining attacker-influenced relative paths.
- **Vendored upstream test-suite**: the `simdutf8` crate's own tests are reused
verbatim in `tests/upstream_tests.rs` (run the SIMD-implementation tests with
`--features public_imp`).
- **Example encoding fixtures** generated by `examples/generate_fixtures.rs`
(ASCII, multilingual UTF-8, UTF-8 BOM, UTF-16 LE/BE, UTF-32 LE, Latin-1, and
deliberately corrupt UTF-8) and committed under `tests/fixtures/`.
- **Library example** `examples/validate_bytes.rs`.
- **Fuzz targets** (`fuzz/`, `cargo +nightly fuzz`): `validate_vs_std`
(differential vs the standard library), `read_capped`, `json_escape`,
`sarif_build`, and `safe_join` (path traversal).
- **Documentation**: user guide, administrator guide, troubleshooting guide, and
README in English, German, and French.
### Security
- `#![forbid(unsafe_code)]` across the binary and library.
- No `println!`/`eprintln!` and no `std::fs::read_to_string`/`write` shortcuts,
matching the repository's hardening conventions.
- SARIF `artifactLocation.uri` values are percent-encoded (RFC 3986) so file
names containing spaces or non-ASCII characters still pass strict SARIF URI
validation.
- `cargo audit`: no advisories across the dependency tree.
### Known issues
- At release the committed `clippy.toml` and `deny.toml` targeted older tool
schemas and blocked `cargo clippy` / `cargo deny check`. This was corrected
post-release (see _Unreleased → Fixed_).
[0.1.0]: https://gitlab.com/vPierre/ndaal_public_simdutf8_cli/-/tags/v0.1.0
[0.1.6]: https://gitlab.com/vPierre/ndaal_public_simdutf8_cli/-/compare/v0.1.0...v0.1.6
[0.2.7]: https://gitlab.com/vPierre/ndaal_public_simdutf8_cli/-/compare/v0.1.6...v0.2.7
[unreleased]: https://gitlab.com/vPierre/ndaal_public_simdutf8_cli/-/compare/v0.2.7...HEAD