12 KiB
Jade Discipline
Jade Discipline is the repository-wide Rust standard for Mercury Toolbox / 水星工具箱.
Goals
- Default strictness: rules are either
denyorallow;warnis not part of the policy surface. - Default observability: every command must remain easy to inspect from plain CLI output and machine-readable JSON.
- Default auditability: lint gates, toolchain choices, and verification commands are written down and reproducible.
- Default optimizability: development and release profiles are explicit instead of ad hoc.
- Default narrow exemptions: repository-wide
allowis treated as hazardous; when a lint must be suppressed, prefer the smallest code-local scope that still explains the exception. - Default hardening: Miri, fuzzing, sanitizer, no-panic, and Loom checks are Jade gates, not optional tiers.
Repository Interpretation
- The workspace applies the Jade lint baseline through root
Cargo.tomlplus per-crate[lints] workspace = true. - The required hard gate is
cargo clippy --all-targets --all-features -- -D warnings -W clippy::pedantic -W clippy::nursery. - PowerShell scripts under
scripts/are part of the same discipline surface. Executable.ps1files must opt intoSet-StrictMode -Version Latest, set$ErrorActionPreference = 'Stop', avoid automatic-variable reassignment, and stay free ofInvoke-Expression. - Root
Cargo.tomlshould not carry broadallowexemptions for design, API, or optimization lints. If a lint is not globally denied, that is not the same thing as globally allowing it. - Global
allowis reserved for two cases only: a rule that is provably irrelevant to the repository with no realistic future exception, or a naming-only rule that would conflict with the project naming constitution. If a narrower suppression is possible, the narrower suppression wins. - Local suppressions should start at the smallest reasonable scope: item before impl block, impl block before module, module before crate. When
const, borrowing, or#[must_use]can be added instead of suppressing, code changes are preferred over lint waivers. cargo_common_metadata = "deny"is kept, and every crate is explicitly markedpublish = falsebecause Mercury Toolbox is a local toolbox rather than a published crate set.- Tokio-specific guidance is intentionally not applied because the current project has no async runtime, no Tokio dependencies, and no task scheduler to observe.
tracing,tracing-subscriber,criterion,proptest,insta,rstest,anyhow, andmietteare approved workspace dependencies for future expansion. They are pinned now, but only crates with a concrete use case should inherit them to avoid dependency drift andudepsnoise.- Workspace line coverage is enforced on logic-bearing source files. Thin binary entrypoints in
src/main.rsand repetitive CLI argument shims insrc/cli.rsare excluded from the line-rate denominator because they are covered instead by command-specific integration tests plus the PowerShell ecosystem gate. - Auto-generated lookup tables such as
managed/src/flow_opcode_table.rsare also excluded from the line-rate denominator. They are generated data snapshots rather than authored control flow, and they are verified indirectly through decoder tests that exercise the consuming logic inmanaged/src/flow.rs. - Because Mercury Toolbox is a workspace of many tiny binaries rather than one deep library crate, the repository coverage floor is
80%line coverage after those wrapper exclusions, paired with a mandatory end-to-endpwshecosystem run. - Hardening checks are introduced into the main Jade gate. If a machine cannot run one, the run must use the matching
-ExemptMiri,-ExemptFuzz,-ExemptSanitizers,-ExemptNoPanic, or-ExemptLoomflag plus a non-empty reason. Missing tools, missing harnesses, or platform discomfort are failures by default, not quiet skips. - Exemptions follow the same narrowness rule as lint suppressions: exempt one gate for one reviewed reason, fix the root cause as soon as the underlying toolchain supports it, and never convert the exemption into a broad permanent policy.
Hard Gates
pwsh -NoProfile -File .\scripts\check-jade.ps1 -VerificationConfiguration ReleaseFast
The script is the authoritative entry point. Expanded, it runs cargo fmt --all --check, cargo check --all-targets --all-features, coverage-backed cargo llvm-cov --jobs 1 nextest --all-features --summary-only, strict Clippy, root and fuzz-workspace cargo +nightly udeps, root and fuzz-workspace cargo deny, the mandatory hardening gates, generated AI asset drift checks, PowerShell analysis, the ecosystem probe, and the selected verification build profile.
The hardening sub-gate is scripts/check-jade-hardening.ps1. Its default -Only All path runs the no-panic source scan, Miri JSON-family tests, Loom runtime capture model, JSON-family fuzz target, and address sanitizer tests. The -Only switch exists only for focused local repair loops; it is not a Jade tier and it does not prove the repository is clean.
The fuzz/ workspace is intentionally separate from the root Cargo workspace. Jade still audits it by running locked metadata generation, cargo +nightly udeps, and cargo deny against the fuzz manifest. Keep fuzz/Cargo.lock committed so fuzz dependency resolution is reproducible.
Hardening Exemptions
Hardening exemptions are explicit audit records, not convenience switches.
- Use the exact gate flag, such as
-ExemptFuzz, and include the matching non-empty reason parameter. - Prefer fixing missing tooling with
just jade-toolsorpwsh -NoProfile -File .\scripts\install-jade-tooling.ps1before considering an exemption. - Do not bake exemptions into
justrecipes, CI defaults, docs, or agent prompts. - Keep exemption reasons narrow enough to identify one machine, one platform issue, or one temporary toolchain gap.
- Remove the exemption as soon as the underlying issue is fixed.
The no-panic source gate has its own local escape hatch for rare invariants. The only accepted form is an adjacent Rust comment: // jade: allow-panic because: <reason>. Prefer Result, Option handling, ok_or_else, and ? over adding that comment.
Install
Install or refresh the toolchain and cargo subcommands used by the standard.
pwsh -NoProfile -File .\scripts\install-jade-tooling.ps1
The tooling script installs cargo-udeps and cargo-llvm-cov, so they stay in the active toolchain set as required Jade commands.
install-jade-tooling.ps1 also ensures PSScriptAnalyzer is available for the PowerShell gate.
The hardening baseline also installs nightly miri, nightly rust-src, and cargo-fuzz. The repository no-panic gate is an audited source scan that denies panic!, .unwrap(), and .expect() in JSON-family production paths unless a narrow // jade: allow-panic because: <reason> comment is placed directly beside the call site.
just and bacon are part of the local Jade tooling baseline now: just is the thin task runner over the repo scripts, and bacon is the continuous Rust feedback loop for the edit-compile-test idle gap.
Generated AI assets are part of the repository surface too: the compact prompt under docs\ai\ and the generated Codex skill under skills\mercury-toolbox\ should both stay reproducible from their scripts instead of being hand-edited drift.
On Windows, profiler helpers have extra OS prerequisites that Cargo cannot install for you: cargo flamegraph falls back to blondie unless DTrace is configured, and that blondie path requires an elevated shell; samply additionally requires xperf.exe from Windows Performance Toolkit.
For local one-shot profiling runs, use scripts/cargo-flamegraph-windows.ps1 to relay through UAC instead of trying to teach the full Jade gate to self-elevate.
When you pass -LogPath, that wrapper writes a compact relay log to the requested path and the full elevated-session transcript to a sibling *.transcript.txt file so PowerShell-side failures stay auditable.
sccache is part of the local Jade tooling baseline now and is configured as the default Cargo rustc-wrapper; use sccache --show-stats when verifying cache behavior after cargo clean.
Profiles And Cargo Config
devis optimized for local debugging without dropping compile throughput.releaseis the day-to-day shipping profile.release-fastandrelease-sizeare reserved for speed-first and size-first builds..cargo/config.tomlowns warning-to-error promotion, future incompatibility reports, and PowerShell-friendly network behavior.
PowerShell Gate
scripts/check-powershell.ps1is the Jade gate for repository PowerShell.- The gate runs
Invoke-ScriptAnalyzerwith PSScriptAnalyzerSettings.psd1 and treats any reported diagnostic as a hard failure. - Naming-only analyzer rules such as approved verbs or singular nouns are intentionally left out of the hard gate because Jade reserves hard failures for completion and safety issues, not broad stylistic noise.
scripts/toolbox-commands.ps1is treated as a dot-sourced helper inventory rather than an executable script, so the strict-mode header requirement applies to the executable entry scripts instead.
AI Asset Gate
scripts/generate-ai-prompt.ps1andscripts/generate-ai-skill.ps1are the only supported writers for the generated AI prompt and Codex skill.scripts/check-ai-prompt.ps1andscripts/check-ai-skill.ps1self-heal generated asset drift by regenerating once, then fail only if the regenerated files still do not match.- The generated skill exists partly to stop dumb whole-file reads in agent workflows: it explicitly routes AI toward
fileprobe,outline,snip,chunkcat,hitsnip,defsnip,codeshape,refs, andctxpackbefore falling back to raw dumps.
Local Workflow
- Install or update the required cargo tooling with
scripts/install-jade-tooling.ps1; the local loop expectscargo-nextest,cargo-llvm-cov,cargo-deny,cargo-udeps,just, andbacon. - Start new user-facing features from the Jade feature template so behavior, tests, generated assets, and handoff notes stay aligned from the first commit. For daily low-risk maintenance, start from the daily maintenance template and
.codex-progress\quality-security-backlog.md. - Keep public APIs fully documented, including
# Errorsand# Panicswhere applicable. - Use
just check,just test,just clippy, andjust jade-skip-coveragefor the broad local loop, then switch to subsystem loops such asjust code-check,just data-test,just runtime-check,just windows-test,just managed-clippy, orjust ai-checkwhen the edit is narrower. Keepjust testas the fast normal path; usejust stable-testfor warning-free incremental cleanup plus ignored slow Windows integrations. - Use
just miri,just fuzz,just sanitizer,just no-panic, andjust loomonly as focused edit loops for a specific failing gate. They are not exemptions and not an optional Jade tier:just jaderuns the complete hardening gate set throughscripts/check-jade.ps1. - Use
baconwhen you want background compile or test feedback while you keep editing, and prefer the matching scoped jobs such asbacon code,bacon runtime,bacon windows,bacon managed-test, orbacon aibefore falling back to the whole-workspace jobs. - Run
pwsh -NoProfile -File .\scripts\check-jade.ps1before claiming the repository is clean. If a hardening gate truly cannot run, pass the specific-Exempt*flag and reason so the missing coverage is visible in logs. - Treat any new lint, warning, panic surface, UB finding, fuzz crash, sanitizer report, or Loom interleaving failure as a repository bug, not as backlog.
- If a lint or hardening check forces an exception, document it in code or command-line reason at the narrowest scope instead of adding a new workspace-wide
allow.