The noya-cli Manual
noyafmt and noyavalidate: format and validate YAML from the command line. noya-cli is one of the six crates of the noyalib family and
releases in lockstep with the core library at the identical =0.0.X.
This manual is the rendered form of the Markdown in the repository’s
docs/
directory; the repository copy is canonical. The family manual for the
core library, with the user guide, migrations, and policies, is at
https://sebastienrousseau.github.io/noyalib/manual/.
Pages
Install, quick start, and the full surface are in the README. The CHANGELOG is the complete release record.
CLI flag reference
The full surface for both binaries — noyafmt and noyavalidate
— with worked examples for every flag. The same content is
available via --help and the man pages installed under
/usr/share/man/man1/ (or complete/{noyafmt,noyavalidate}.1
when installed from the tarball).
The clap command tree is regenerated at build time via the same
noya_cli::{noyafmt_command, noyavalidate_command} builders that
drive the runtime parser, so this file, the manpages, and the
shell completions cannot drift from each other.
noyafmt
noyafmt [OPTIONS] [FILE]...
Auto-format YAML via the noyalib CST. Reads YAML from FILE
arguments (or stdin via --stdin) and rewrites them through
noyalib’s lossless CST formatter. Comments, anchor positions, and
document structure are preserved byte-for-byte; only whitespace
and quoting are normalised.
Flags
| Flag | Type | Default | Description |
|---|---|---|---|
--check | bool | off | Verify each FILE is formatted; print the list of files that need formatting and exit 1 if any do. Non-destructive. Suitable as a pre-commit / CI gate. Conflicts with --write. |
--write | bool | off | Rewrite each FILE in place. Default is to print the formatted source to stdout. Conflicts with --check. |
--stdin | bool | off | Read from stdin, write to stdout. Mutually exclusive with FILE arguments. |
--indent N | 1 to 16 | 2 | Indentation width in spaces; a value outside 1 to 16 is a usage error (exit 2). |
-h, --help | — | — | Print help (long form on --help). |
-V, --version | — | — | Print the version. |
Positional arguments
| Argument | Repeatable | Description |
|---|---|---|
FILE | yes | YAML files to format. Pass --stdin to read from stdin instead. |
Examples
# Default: read FILE, print formatted YAML to stdout.
noyafmt config.yaml
# Rewrite in place.
noyafmt --write config.yaml
# CI gate — exit 1 if any file needs formatting.
noyafmt --check ci/*.yaml
# Editor integration: pipe through stdin.
cat config.yaml | noyafmt --stdin
# Custom indent width.
noyafmt --write --indent 4 config.yaml
# Multiple files at once.
noyafmt --write services/*.yaml deployments/*.yaml
Exit codes
| Code | Meaning |
|---|---|
| 0 | All files are formatted (or were rewritten when --write) |
| 1 | At least one file is not formatted (--check) or a parse error occurred |
| 2 | Usage error (conflicting flags, missing argument) |
| 3 | I/O error (file not found, permission denied) |
noyavalidate
noyavalidate [OPTIONS] [FILE]...
Check YAML syntax (and optional JSON Schema). Reads the YAML
documents in each FILE (or stdin), reports syntax errors via
the miette fancy renderer, and — when --schema PATH is given —
validates each parsed document against a JSON Schema 2020-12
contract (the schema may itself be written in YAML or JSON).
--fix rewrites the input in-place through the lossless CST
formatter, normalising whitespace and quoting without changing
semantics. When the input is stdin, the formatted output is
written to stdout instead.
Flags
| Flag | Type | Default | Description |
|---|---|---|---|
-s PATH, --schema PATH | path | — | Validate each document against the JSON Schema 2020-12 at PATH (the schema may itself be YAML or JSON). |
--fix | bool | off | Rewrite FILE in place via the CST formatter (lossless: byte-faithful for everything except normalised whitespace and line endings). With stdin input, the formatted bytes go to stdout. |
-q, --quiet | bool | off | Suppress success output. |
-h, --help | — | — | Print help (long form on --help). |
-V, --version | — | — | Print the version. |
Positional arguments
| Argument | Required | Description |
|---|---|---|
FILE | optional | YAML files to validate. Use - (alone) or omit for stdin. Every file is checked; the exit code is the highest any file produced. |
Examples
# Syntax-only check, errors via miette fancy renderer.
noyavalidate config.yaml
# Schema validation against a YAML-flavoured JSON Schema.
noyavalidate --schema schemas/config.schema.yaml config.yaml
# Schema validation against a JSON-flavoured schema.
noyavalidate --schema schemas/config.schema.json config.yaml
# Read from stdin.
cat config.yaml | noyavalidate
# Format-fix in place.
noyavalidate --fix config.yaml
# Format-fix from stdin to stdout.
cat config.yaml | noyavalidate --fix > clean.yaml
# Combined: schema-validate then format-fix.
noyavalidate --schema schema.yaml --fix config.yaml
# Quiet mode for CI: only errors are printed.
noyavalidate --quiet --schema schema.yaml ci/*.yaml
Exit codes
| Code | Meaning |
|---|---|
| 0 | All documents valid (and fixed if --fix) |
| 1 | Parse error or schema violation |
| 2 | Usage error |
| 3 | I/O error |
Shell completions
Pre-generated completion scripts ship in the release tarball under
complete/:
| Shell | File |
|---|---|
| bash | complete/noyafmt.bash, complete/noyavalidate.bash |
| fish | complete/noyafmt.fish, complete/noyavalidate.fish |
| zsh | complete/_noyafmt, complete/_noyavalidate |
| PowerShell | complete/_noyafmt.ps1, complete/_noyavalidate.ps1 |
System packages install them to the right location automatically.
For local install (cargo install noya-cli), regenerate via
cargo xtask completions.
Man pages
Roff-format man pages ship as doc/noyafmt.1 and
doc/noyavalidate.1. System packages install to
/usr/share/man/man1/; for local install, regenerate via
cargo xtask manpages.
Related
- Recipes — common workflows (CI gates, pre-commit hooks, schema validation patterns)
- Crate README — installation, package channels, build-from-source
noyafmt + noyavalidate recipes
Common workflows. Each recipe is a self-contained snippet you can drop into your project or CI.
CI: format gate
Block PRs that introduce unformatted YAML.
GitHub Actions
# .github/workflows/yaml-fmt.yml
name: YAML format
on: [pull_request]
jobs:
fmt:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: cargo install noya-cli --locked
- run: noyafmt --check $(git ls-files '*.yaml' '*.yml')
GitLab CI
yaml-fmt:
image: rust:1.89-bookworm
before_script:
- cargo install noya-cli --locked
script:
- noyafmt --check $(git ls-files '*.yaml' '*.yml')
Pre-commit hook
# .pre-commit-config.yaml
repos:
- repo: local
hooks:
- id: noyafmt
name: noyafmt --check
entry: noyafmt --check
language: system
files: \.(yaml|yml)$
CI: schema gate
Block PRs that violate a JSON Schema contract.
GitHub Actions
name: YAML schema
on: [pull_request]
jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: cargo install noya-cli --locked
- name: Validate Kubernetes manifests
run: |
for f in k8s/**/*.yaml; do
noyavalidate --schema schemas/k8s.schema.yaml "$f" || exit 1
done
Editor integration
VS Code on save
Pair noyafmt with VS Code’s editor.formatOnSave. The recommended
path is the dedicated noyalib-lsp
extension, which provides format-on-save, diagnostics, and hover.
For lighter-weight integration:
// .vscode/tasks.json
{
"version": "2.0.0",
"tasks": [{
"label": "noyafmt: write",
"type": "shell",
"command": "noyafmt",
"args": ["--write", "${file}"],
"problemMatcher": []
}]
}
Neovim
-- ~/.config/nvim/lua/yaml-fmt.lua
vim.api.nvim_create_autocmd("BufWritePost", {
pattern = { "*.yaml", "*.yml" },
callback = function()
vim.fn.system("noyafmt --write " .. vim.fn.expand("%"))
vim.cmd("e!") -- reload buffer
end,
})
For the richer experience (diagnostics, hover, code actions) use
noyalib-lsp via nvim-lspconfig.
Bulk operations
Format every YAML in a tree
find . -name '*.yaml' -o -name '*.yml' | xargs noyafmt --write
Validate every Kubernetes manifest
find k8s -name '*.yaml' -exec \
noyavalidate --schema schemas/k8s.schema.yaml --quiet {} +
Generate canonical diff after a refactor
When mass-renaming keys across many YAML files, format both before and after to reduce the diff to the actual semantic change:
git stash # save WIP
noyafmt --write **/*.yaml && git commit -m 'fmt' # format baseline
git stash pop # apply WIP
noyafmt --write **/*.yaml # format after
git diff # only semantic changes
Pipeline integration
kubectl apply only when format-clean
noyafmt --check k8s.yaml && kubectl apply -f k8s.yaml
Helm chart linting
helm template ./chart \
| noyavalidate --schema schemas/k8s.schema.yaml -
Render-then-validate Argo CD application
argocd app manifests my-app \
| noyavalidate --schema schemas/argo-app.schema.yaml -
Troubleshooting
“permission denied” rewriting a file
--write opens FILE for writing. If the file is read-only or
owned by another user, the write fails with exit 3 (I/O error).
Use chmod +w FILE or sudo.
Schema validation passes locally, fails in CI
The schema file path is resolved relative to the working
directory of the noyavalidate invocation, not relative to the
input file. In GitHub Actions, ${{ github.workspace }} is the
repo root; ensure your --schema path is relative to that.
--fix changed more than I expected
The CST formatter normalises whitespace, quoting, and indentation
to a canonical form. It does not change document semantics:
keys, values, comments, anchors, and tags survive byte-for-byte.
If a --fix produced unexpected output, file an issue with the
input — the formatter is documented as preserving everything that
isn’t trivia.
Stdin closes the process before output
When piping --stdin you may need to terminate the input with
Ctrl-D (^D) on a new line:
noyafmt --stdin
key: value
^D
For programmatic use (CI scripts), redirect a file or use <<<
heredoc syntax.
CLI ecosystem comparison
This comparison describes delivery and workflow characteristics. It is not a claim that every tool has the same scope.
| Project | Comment-preserving format | JSON Schema | Native packages | Generated manpages |
|---|---|---|---|---|
noya-cli | Yes | 2020-12 | deb and rpm | Yes |
yq | Operation-dependent | No | Project-dependent | Project-dependent |
yamllint | Lint only | No | Project-dependent | Project-dependent |
| Prettier YAML | Reprints documents | No | npm | No |
The meaningful distinction is the editing model. noyafmt and
noyavalidate --fix use noyalib’s concrete syntax tree, so an edit need not
reprint unrelated comments or whitespace. Use each upstream project’s current
documentation before making a tool-selection decision.
For the complete command surface, see CLI reference.
Benchmarks
The cli_dispatch Criterion harness measures command dispatch and representative
format and validation workloads in release mode.
cargo bench --bench cli_dispatch
Record the CPU, operating system, Rust version, commit, input size, feature set, and full command with any reported result. Compare measurements from the same machine and power profile. CI compiles and smoke-runs benchmark targets, but does not reject a change using noisy shared-runner wall-clock thresholds.
The headline format measurement in the README is descriptive project data, not a cross-machine performance guarantee.
Architecture
noya-cli ships two binaries, noyafmt and noyavalidate, over one
shared library so the binaries, their manpages, and their shell
completions are generated from a single definition and cannot drift.
Layers
src/lib.rsdefines the command-line surface once: theclapderive structsNoyafmtCliandNoyavalidateCli, and the buildersnoyafmt_commandandnoyavalidate_commandthat return the underlyingclap::Commandtrees. Both binaries parse argv through these; the build script consumes the same trees.src/bin/noyafmt.rsformats YAML through noyalib’s CST formatter withrustfmt-style ergonomics:--checkfor CI gates,--writefor in-place rewrites, stdin to stdout for editors.src/bin/noyavalidate.rsvalidates syntax, renders errors withmiette, validates each document against a JSON Schema 2020-12 contract when--schemais given (the schema may be YAML or JSON), and with--fixrewrites the input through the CST formatter, normalising whitespace and quoting without changing meaning. The README documents the exit codes.build.rsgenerates the manpages (clap_mangen) and the bash, fish, zsh, and PowerShell completions (clap_complete) intoOUT_DIRat build time.make assetscopies them intodocs/andcomplete/so the committed copies never lag--help; the version gate checks the manpages carry the crate version.
Install contract
GNUmakefile implements the Unix contract: make, make test,
make install and make uninstall honouring PREFIX (default
/usr/local) and DESTDIR, installing binaries, manpages, and
completions to FHS paths. CI stages an install into a temporary
DESTDIR on every push. pkg/ carries the Homebrew formula, Scoop
manifest, AUR PKGBUILD, and flake.nix, all generated from the
release build; the channel manifests roll after each release’s
artefacts exist because they embed checksums.
Testing
Integration tests run the binaries as processes. Two libFuzzer targets
feed arbitrary argv through the clap trees (fuzz_argv) and the
derive structs (fuzz_derive_parse); CI replays the seed corpus on
every push.
Lockstep
The crate pins noyalib at the identical =0.0.X and releases with
it (core ADR-0005).
Engineering policies
Version and dependency policy
noya-cli releases in strict lockstep with noyalib. Version 0.0.58 must pin
the core at exactly =0.0.58. Release work uses feat/v0.0.58; each subsequent
iteration increments exactly 0.0.1.
Minimum Rust version
The minimum supported Rust version is 1.89.0. The manifest declares the floor and CI verifies it. A change to the floor is a breaking-axis change and requires a changelog entry.
Generated assets
Manpages and completions are generated from the Clap definitions. Change the
command source and run make assets; never edit generated copies directly.
Compatibility
Exit codes, command names, flags, configuration semantics, and formatting output
are public behaviour. During 0.0.x, the patch component is the breaking axis.
Family-wide policies live in the core
POLICIES.md.
Repository standard compliance grade
Assessment date: 2026-09-20. Source rubric:
/Users/seb/Code/REPO-STANDARD.md. The workspace auditor evaluates checked-in
signals conservatively and does not treat a workflow file as proof that a run
passed.
Result
17/24 signals (71%). README template: pass. Strict candidate tier: L1.
| Category | Signals | Summary |
|---|---|---|
| Identity and README | 3/3 | Canonical structure, policy, badges, and toolchain evidence |
| Documentation | 2/3 | Manual and architecture present; complete L3 evidence remains open |
| Build and install UX | 2/3 | Native build, generated manpages and completions; static L2 detector does not recognize the GNUmakefile shape |
| Releases and binaries | 3/3 | Automated multi-platform release and provenance signals |
| Packaging | 1/3 | Packaging exists; Repology and reproducibility evidence remain incomplete |
| CI quality gates | 2/3 | Matrix and coverage signals present; full L3 powerset evidence remains open |
| Supply chain | 3/3 | Audit, signing, provenance, and policy signals present |
| Community | 1/3 | Foundation files present; template and docs-lint detection remain gaps |
The cumulative tier remains L1 because every L2 category must pass. Priority work is explicit Repology tracking, reproducible-build verification, and making the existing GNUmakefile, issue/PR templates, and markdown lint gates legible to the portfolio audit.
Detailed README reference
noya-cli
noyafmt and noyavalidate —
the YAML formatter and validator built on the noyalib
library.
Contents
- Install — every channel mapped
- Requirements — toolchain floor, platforms, the core pin
- Quick Start — common workflows
noyafmt— formatter referencenoyavalidate— validator + autofix reference- GitHub Action and pre-commit
- Exit codes — for shell pipelines and CI gates
- Examples — runnable demo scripts
- Shell completions and man pages
- Verification — cosign + SLSA cookbook
- When not to use these tools
- Documentation
- License
Install
| Channel | Command |
|---|---|
| Pre-built binaries | download for 8 targets (Linux gnu/musl, macOS, Windows on x86_64/aarch64) from the latest release — each with manpages, completions, SHA-256, and SLSA provenance |
| Linux packages | .deb and .rpm on the latest release |
| Homebrew (macOS/Linux) | brew install sebastienrousseau/tap/noya-cli |
| Scoop (Windows) | scoop bucket add sebastienrousseau https://github.com/sebastienrousseau/scoop-bucket then scoop install noya-cli |
| AUR (Arch) | noyalib-bin, e.g. yay -S noyalib-bin |
| Cargo (crates.io) | cargo install noya-cli --locked |
| Cargo (from source) | cargo install --locked --path . |
| GNU Make (binaries + manpages + completions) | make install — honors PREFIX (default /usr/local) and DESTDIR; make uninstall reverses it |
| Container (GHCR) | docker run --rm -v "$(pwd):/work" -w /work ghcr.io/sebastienrousseau/noya-cli:latest config.yaml validates; add --entrypoint noyafmt to format. Multi-arch, SLSA-attested, cosign-signed; first published with v0.0.41. |
Formatter only, if you do not need noyavalidate
cargo install noya-cli --locked --no-default-features --features noyafmt
The default install includes noyavalidate, whose schema errors are
rendered by miette with source
excerpts and carets — worth the weight for a validator, since pointing at
the offending line is the job. It does mean the default pulls 130
crates against 32 for the formatter alone, most of the difference
being miette’s fancy renderer and its backtrace stack.
If you only ever run noyafmt, the command above is a smaller supply
chain and a faster build. Nothing is degraded for anyone who wants the
diagnostics — it is a choice, not a default.
Releases ship the crate archive with a CycloneDX SBOM and sigstore bundles, plus the pre-built binary archives and Linux packages above, each with SHA-256 and a SLSA build-provenance attestation — see Verification.
MSRV: Rust 1.89.0, the floor shared across the noyalib family and the
maintainer’s other Rust crates (noyalib ADR-0014). The
toolchain-driven floor is lower: criterion 0.8 (the benchmark dev-dependency) declares
rust-version = 1.86, so cargo check --all-targets and the
bench suite fail on 1.85 (criterion@0.8.2 requires rustc 1.86),
though cargo check --lib still builds. clap_builder 4.6 in the
CLI dep tree is edition-2024. We publish the number we verify.
Requirements
- Rust 1.89.0 or newer to build from source:
rust-versionin the manifest, enforced by themsrv-coreCI job on every push. - Any tier-1 platform. CI runs the tests on Linux, macOS, and Windows with the stable, beta, and nightly toolchains; stable is the gate, beta and nightly are early warning.
- The matching core. This crate pins
noyalibat the identical=0.0.Xand releases in lockstep with it; Cargo resolves that pin for you. - Nothing at runtime: the binaries are static where the platform allows (musl on Linux) and link only the C runtime elsewhere.
Quick Start
# Format a file in-place; comments + indentation preserved.
noyafmt --write config.yaml
# CI gate — exits 1 if any file would change.
noyafmt --check ci/*.yaml
# Validate syntax + JSON Schema 2020-12.
noyavalidate --schema schema.yaml deploy.yaml
# Validate + auto-fix obvious type slips (port: "8080" → 8080).
noyavalidate --schema schema.yaml --fix deploy.yaml
noyafmt
YAML formatter mirroring the rustfmt / prettier ergonomics:
noyafmt config.yaml # print formatted source to stdout (default)
noyafmt --write config.yaml # rewrite in place
noyafmt --check ci/*.yaml # CI gate
noyafmt --indent 4 config.yaml # override default 2-space indent
cat foo.yaml | noyafmt --stdin # editor pipe (Vim, Emacs, …)
git ls-files '*.yaml' | xargs noyafmt --check
The formatter runs through noyalib’s lossless CST: comments, anchor positions, and document structure are preserved byte-for-byte; only whitespace and quoting are normalised.
| Flag | Effect |
|---|---|
--check | Verify each FILE is formatted; print files that need formatting; exit 1 if any do. Non-destructive. |
--write | Rewrite each FILE in place. Default is to print to stdout. Mutually exclusive with --check. |
--stdin | Read from stdin, write to stdout. Mutually exclusive with FILE arguments. |
--indent N | Indentation width in spaces, 1 to 16 (default: 2). |
noyavalidate
YAML syntax checker with optional JSON Schema 2020-12 enforcement and schema-driven autofix.
noyavalidate manifest.yaml # syntax only
noyavalidate --schema schema.yaml deploy.yaml # + schema check
noyavalidate --schema schema.yaml --fix deploy.yaml # + autofix
cat manifest.yaml | noyavalidate # stdin
The autofix engine
(coerce_to_schema)
rewrites string-shaped scalars into the schema’s expected type
when the parse succeeds. Loops until convergence; unparseable
inputs (port: "abc" against type: integer) are left in place
so a follow-up validate_against_schema call surfaces the
residue.
Diagnostics use miette for
rustc-style source pointers:
× schema violation: "8080" is not of type "integer"
╭─[deploy.yaml:3:7]
2 │ replicas: 3
3 │ port: "8080"
· ─┬───
· ╰── here
4 │ host: api
╰────
help: pass --fix to coerce string-shaped scalars to the
schema's declared type.
| Flag | Effect |
|---|---|
-s, --schema PATH | Validate each document against JSON Schema 2020-12 at PATH (the schema may itself be YAML or JSON). |
--fix | Rewrite FILE in place via the CST formatter (lossless: byte-faithful for everything except normalised whitespace / line endings). With stdin input, the formatted bytes go to stdout. |
-q, --quiet | Suppress success output. |
GitHub Action and pre-commit
One step in CI, no toolchain on the runner:
- uses: sebastienrousseau/noya-cli@v0.0.58
with:
paths: config/ deploy.yaml
schema: schema.json # optional
The action downloads the release binaries for the runner’s platform and
verifies their build provenance attestation with gh attestation verify
(built by this repository’s release workflow at the requested tag); where
the gh CLI or a token is missing it checks only the SHA-256 published in
the same release and says so with a warning. It then runs
noyafmt --check and noyavalidate (with the schema when given) over the
YAML under paths; directories are searched for *.yaml and *.yml.
Either failure fails the step, and tool output cannot issue workflow
commands. version must be X.Y.Z.
The same checks as hosted pre-commit hooks:
repos:
- repo: https://github.com/sebastienrousseau/noya-cli
rev: v0.0.58
hooks:
- id: noyafmt-check
- id: noyavalidate
noyafmt (runs noyafmt --write, so the hook fails when it reformatted a
file), noyafmt-check and noyavalidate (checks every staged file) are
the three hook ids; pass --schema schema.json through args to validate.
pre-commit builds the hooks with cargo install without --locked, so
dependencies resolve to their newest compatible versions rather than this
repository’s Cargo.lock. For a locked build, run
cargo install noya-cli --locked and point a repo: local hook with
language: system at the installed binaries.
Exit codes
| Code | noyafmt | noyavalidate |
|---|---|---|
| 0 | success (or no changes if --check) | all valid |
| 1 | parse / I/O error, or --check found unformatted file(s) | parse error or schema violation |
| 2 | invalid usage (bad arg combination) | invalid usage |
| 3 | — | I/O error (read / write) |
Examples
End-to-end runnable demos under
examples/:
| Script | What it shows |
|---|---|
format-precommit.sh | Drop-in git pre-commit hook gating commits on noyafmt --check. |
validate-k8s.sh | CI step that runs noyavalidate --schema over a directory of Kubernetes manifests. |
fix-quoted-numbers.sh | Walkthrough of the --fix autofix flow: quoted scalar → schema-typed integer, with the surrounding comment preserved. |
chmod +x crates/noya-cli/examples/*.sh
crates/noya-cli/examples/fix-quoted-numbers.sh
Shell completions and man pages
Tarball releases ship pre-built completions for bash, fish, zsh,
and PowerShell, plus roff man pages. Distro packages drop them
into the standard system locations
(/usr/share/bash-completion/completions/,
/usr/share/man/man1/, …).
make install places all of them in the standard locations. If
installing via cargo install, the pre-built copies live in this
repository (complete/, docs/*.1) — or regenerate them from the
clap definitions:
git clone https://github.com/sebastienrousseau/noya-cli
cd noya-cli
make assets # regenerates complete/* and docs/*.1 via build.rs
CI enforces that the committed copies are bit-identical to what the
clap definitions generate (make check-assets), so they cannot
drift from --help.
Verification
Every release artefact (crate archive, SBOM) ships with a cosign keyless signature and a SLSA build-provenance attestation. Verify before trusting a download:
COSIGN_EXPERIMENTAL=1 cosign verify-blob \
--certificate-identity-regexp '^https://github\.com/sebastienrousseau/noya-cli/\.github/workflows/release\.yml@refs/tags/v[0-9]+\.[0-9]+\.[0-9]+$' \
--certificate-oidc-issuer 'https://token.actions.githubusercontent.com' \
--bundle <artefact>.bundle \
<artefact>
gh attestation verify <artefact> --repo sebastienrousseau/noya-cli --signer-workflow sebastienrousseau/noya-cli/.github/workflows/release.yml
Full cookbook including the offline / FIPS-bound flow:
pkg/VERIFY.md.
When not to use these tools
- You need to format YAML faster than human-perceivable
latency.
noyafmtruns end-to-end on a 1 MiB document in ~10 ms; for<100 KBdocuments that’s already invisible. But for a streaming editor pipeline that wants per-keystroke formatting, the LSP server (noyalib-lsp) issues incrementalTextEdit[]s instead. - You need YAML 1.1-only behaviour, top to bottom.
noyavalidatefollows YAML 1.2; thelegacy_booleansopt-in is exposed at the library level but not yet plumbed through the CLI. - You need to embed the formatter or validator in your own
Rust binary. Use the
noyaliblibrary directly — every CLI feature flows through public library APIs (cst::format_with_config,validate_against_schema,coerce_to_schema).
Documentation
The four entry points, identical across every repo in the family:
-
User Manual — this crate’s rendered book: its guides, architecture, and release notes; the family manual for the core library is at https://sebastienrousseau.github.io/noyalib/manual/
-
API reference — rustdoc on docs.rs
-
Developer docs — this repo’s dev entry point, pointing at the family guide
-
Ecosystem map — the six crates, the lockstep model, the scorecard
-
Engineering policies (MSRV, SemVer, security, performance, concurrency, platform support, feature flags):
doc/POLICIES.md -
Security policy:
SECURITY.md -
CLI flag reference:
docs/cli-reference.md -
Recipes (CI gates, pre-commit, editor integration):
docs/recipes.md -
Workspace README: https://github.com/sebastienrousseau/noyalib#readme
-
Per-channel install + verify:
pkg/VERIFY.md -
Library API the binaries call into: https://docs.rs/noyalib
Conformance
Every push runs the official yaml-test-suite
through noyavalidate’s exit code, from the same vendored suite and the same
core commit as the noyalib core: 406 of 406 (valid cases exit 0, invalid
cases exit non-zero). A two-document configuration that uses most of YAML at
once (tests/fixtures/ultra-complex/) validates, and noyafmt’s output
parses to exactly the same JSON. Details and the family table:
noyalib.com/conformance.
License
Dual-licensed under Apache 2.0 or MIT, at your option.
noya-cli v0.0.17 Release Notes
Lockstep release with noyalib v0.0.17 (ADR-0005: publishes =0.0.17
pinned to the core).
What changed
crossbeam-epochbumped to 0.9.20 (RUSTSEC-2026-0204, invalid-pointer-dereference), previously present via a transitive dep.noyalibpin=0.0.16->=0.0.17; crate version bumped in lockstep.
Repository hardening (CI/docs only)
Coverage, MSRV, CodeQL, and OpenSSF Scorecard gates plus upstream cargo-vet audit imports were added across the satellites in this cycle; branch protection now makes commit signing unskippable. No user-facing change.
Upgrading
Requires Rust 1.86.0+.
noya-cli v0.0.16 Release Notes
Lockstep release with noyalib v0.0.16 (ADR-0005 strict-lockstep: the
noyafmt / noyavalidate binaries publish =X.Y.Z pinned to the core).
No change to the CLI contract (flags, exit codes, output).
What changed
noyalibpin=0.0.15→=0.0.16and the crate version bumped in lockstep.- MSRV raised 1.85.0 → 1.86.0, matching the single lockstep floor adopted in v0.0.16.
- Release workflow publish steps made idempotent for clean re-runs.
Corrected after release (ships in v0.0.17)
crossbeam-epochRUSTSEC-2026-0204 (invalid-pointer-dereference) was present in the v0.0.16 lockfile via a transitive dependency and bumped to the patched 0.9.20 onmainafterward.
Engineering / CI (post-release, no user-facing change)
- Signed-history enforcement, upstream audit imports, and a
dependabot-vetauto-refresh workflow. - New CI gates brought toward the core’s bar: a coverage gate, an MSRV
gate, CodeQL, and OpenSSF Scorecard.
src/lib.rs(the shared clap command tree) is at 100 % coverage; the enforced binary floor is set at the honest testable ceiling, since the residual is defensive I/O and parser-disagreement error arms unreachable via valid input.
What did not change
- The
noyafmt/noyavalidateflag surface, exit codes, and output. #![forbid(unsafe_code)]— intact.
Upgrading
cargo install noya-cli --version 0.0.16 --locked
Requires Rust 1.86.0+.