forked from Crockan/MercuryToolbox
chore(release): prepare public source release
This commit is contained in:
@@ -0,0 +1,103 @@
|
||||
# Jade Discipline
|
||||
|
||||
Jade Discipline is the repository-wide Rust standard for Mercury Toolbox / 水星工具箱.
|
||||
|
||||
## Goals
|
||||
|
||||
- Default strictness: rules are either `deny` or `allow`; `warn` is 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 `allow` is 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.toml` plus 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 `.ps1` files must opt into `Set-StrictMode -Version Latest`, set `$ErrorActionPreference = 'Stop'`, avoid automatic-variable reassignment, and stay free of `Invoke-Expression`.
|
||||
- Root `Cargo.toml` should not carry broad `allow` exemptions for design, API, or optimization lints. If a lint is not globally denied, that is not the same thing as globally allowing it.
|
||||
- Global `allow` is 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 marked `publish = false` because 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`, and `miette` are 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 and `udeps` noise.
|
||||
- Workspace line coverage is enforced on logic-bearing source files. Thin binary entrypoints in `src/main.rs` and repetitive CLI argument shims in `src/cli.rs` are 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.rs`](../crates/managed/src/flow_opcode_table.rs) are 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 in [`managed/src/flow.rs`](../crates/managed/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-end `pwsh` ecosystem 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 `-ExemptLoom` flag 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
|
||||
|
||||
```powershell
|
||||
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-tools` or `pwsh -NoProfile -File .\scripts\install-jade-tooling.ps1` before considering an exemption.
|
||||
- Do not bake exemptions into `just` recipes, 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.
|
||||
|
||||
```powershell
|
||||
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
|
||||
|
||||
- `dev` is optimized for local debugging without dropping compile throughput.
|
||||
- `release` is the day-to-day shipping profile.
|
||||
- `release-fast` and `release-size` are reserved for speed-first and size-first builds.
|
||||
- `.cargo/config.toml` owns warning-to-error promotion, future incompatibility reports, and PowerShell-friendly network behavior.
|
||||
|
||||
## PowerShell Gate
|
||||
|
||||
- `scripts/check-powershell.ps1` is the Jade gate for repository PowerShell.
|
||||
- The gate runs `Invoke-ScriptAnalyzer` with [PSScriptAnalyzerSettings.psd1](../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.ps1` is 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.ps1` and `scripts/generate-ai-skill.ps1` are the only supported writers for the generated AI prompt and Codex skill.
|
||||
- `scripts/check-ai-prompt.ps1` and `scripts/check-ai-skill.ps1` self-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`, and `ctxpack` before falling back to raw dumps.
|
||||
|
||||
## Local Workflow
|
||||
|
||||
1. Install or update the required cargo tooling with `scripts/install-jade-tooling.ps1`; the local loop expects `cargo-nextest`, `cargo-llvm-cov`, `cargo-deny`, `cargo-udeps`, `just`, and `bacon`.
|
||||
2. Start new user-facing features from [the Jade feature template](templates/jade-feature-template.md) 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](templates/daily-maintenance-template.md) and `.codex-progress\quality-security-backlog.md`.
|
||||
3. Keep public APIs fully documented, including `# Errors` and `# Panics` where applicable.
|
||||
4. Use `just check`, `just test`, `just clippy`, and `just jade-skip-coverage` for the broad local loop, then switch to subsystem loops such as `just code-check`, `just data-test`, `just runtime-check`, `just windows-test`, `just managed-clippy`, or `just ai-check` when the edit is narrower. Keep `just test` as the fast normal path; use `just stable-test` for warning-free incremental cleanup plus ignored slow Windows integrations.
|
||||
5. Use `just miri`, `just fuzz`, `just sanitizer`, `just no-panic`, and `just loom` only as focused edit loops for a specific failing gate. They are not exemptions and not an optional Jade tier: `just jade` runs the complete hardening gate set through `scripts/check-jade.ps1`.
|
||||
6. Use `bacon` when you want background compile or test feedback while you keep editing, and prefer the matching scoped jobs such as `bacon code`, `bacon runtime`, `bacon windows`, `bacon managed-test`, or `bacon ai` before falling back to the whole-workspace jobs.
|
||||
7. Run `pwsh -NoProfile -File .\scripts\check-jade.ps1` before 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.
|
||||
8. Treat any new lint, warning, panic surface, UB finding, fuzz crash, sanitizer report, or Loom interleaving failure as a repository bug, not as backlog.
|
||||
9. 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`.
|
||||
Reference in New Issue
Block a user