Thanks for helping improve UFFS.
By contributing you agree your contribution is licensed under MPL-2.0 and that the UFFS name and logo remain governed by TRADEMARK.md.
- Bug reports, feature requests, questions: open a GitHub issue on skyllc-ai/UltraFastFileSearch.
- Brand / trademark questions: open an issue tagged
brand, or emailtrademark@uffs.io. - Commercial / partnership inquiries:
partnerships@uffs.io, or a discussion with thecommercial-interestlabel. - Organization: Sky, LLC.
- UFFS is Windows-first: live NTFS MFT reads require Windows and Administrator privileges.
- macOS and Linux remain valid contributor hosts for docs work, offline/query logic, and cross-platform tests.
- Keep Windows-only I/O behind
#[cfg(windows)]and prefer cross-platform validation when possible.
- Use the pinned nightly toolchain from
rust-toolchain.toml. justis the primary workflow entry point.
Recommended setup:
- Install the nightly toolchain:
rustup toolchain install nightly - Install
just:cargo install just - Install the common contributor toolchain:
just setup - List available workflows any time with
just
The workspace has no MSRV claim — it is structurally nightly-only. crates/uffs-polars enables polars/nightly unconditionally to unlock Polars's SIMD-accelerated compute kernels, which transitively requires nightly Rust (issue #267 captures the full audit + drop rationale).
The single source of truth for the required toolchain is rust-toolchain.toml at the workspace root, which pins a specific known-good nightly channel (currently nightly-2026-05-16). Every dev build and every CI job uses this channel. See that file's header comment for the bump-cadence history, the per-bump rollback rationale, and the upstream-regression tracking that keeps the pin where it is.
Practical implications for contributors:
- Don't run
cargo +stable …against the workspace. The polars-bound graph will not compile on any stable toolchain; the failure mode iserror[E0554]insidefoldhash. - Don't add
rust-version = …to any new manifest. The workspace-level claim was dropped in the change that closed #267; per-crate manifests do not carryrust-version.workspace = trueeither. Theuffs-manifest-audittool no longer enforces invariant 3.4 (rust-versionconsistency) — adding back the field will pass the audit silently but will be reverted on review. - Bumping the nightly pin is handled by
just toolchain-sync(orjust ship --fresh, which runstoolchain-syncas part of the pipeline). Both updaterust-toolchain.tomlto the latest nightly that compiles the workspace cleanly, log the bump in CHANGELOG, and revert if the new channel regresses any gate. - Future MSRV path. If a publishable-leaf crate (
uffs-time,uffs-text,uffs-broker-protocol) ever needs MSRV verification independent of the polars-bound graph, set MSRV per-crate via that crate's[package.rust-version]field and add a focusedcargo +stable check -p <crate>CI job — do NOT resurrect a workspace-wide claim.
For cross-compilation from macOS/Linux hosts:
just setup-cross— install cross targets used by the workspacejust check-cross— run the CI-style cross-compilation validation- See
docs/xwin-msvc-rlib-size-root-cause-and-workarounds.mdforcargo xwin/ MSVC-specific notes
Prefer the smallest command that proves your change:
just check— quick workspace validation (cargo check, formatting check, file-size policy)just fmt— format the workspacejust test— workspace tests via nextest/llvm-covjust test-doc— documentation testsjust lint-prod— strict production Clippyjust lint-tests— test-target Clippyjust build— workspace buildjust go— full fast-fail workflow when you want the whole pipeline
Focused examples from the current workflow canon:
cargo nextest run -p uffs-mft -- treecargo test -p uffs-core -- path_resolver --nocapturecargo test -p uffs-mft --lib -- --nocapture
Most tests run cross-platform. Tests that need live MFT access are typically #[ignore] and should only be run on Windows with elevation.
UFFS uses a shift-left pipeline: cheap checks fire close to the keystroke, expensive ones move rightward into CI. Each layer is fully opt-in via just install-hooks and can be bypassed with --no-verify for a single commit or push when you need to.
| Layer | Trigger | Recipe | Budget | What it runs |
|---|---|---|---|---|
| IDE save | On save | rust-analyzer |
instant | type-check-on-save, clippy-on-save |
| pre-commit | git commit |
just lint-fast |
sub-2 s (docs-only) / 15–25 s warm (*.rs staged) |
fmt --check, lint-prod (ultra-strict: pedantic + nursery + cargo + unwrap_used + missing_docs_in_private_items), lint-tests (same base + unwrap allowed), lint-ci (CI-mirror -D warnings --all-targets) — all when *.rs staged; plus taplo fmt --check (if *.toml staged), typos, reuse lint, file-size policy — all in parallel; missing optional tools soft-skip. Windows xwin lint lives at pre-push, not pre-commit (40–90 s cold cost violates T1 budget). |
| pre-push | git push |
just lint-pre-push |
25–60 s warm | Same three ultra-strict clippy passes + Windows cargo xwin clippy -- -D warnings (lint-ci-windows, Phase W5.6) + fmt --check + rustdoc -D warnings + cargo deny check + nextest run --no-run (test-binary link check) + file-size policy + typos + reuse lint — all in parallel. Full parity with just ship Phase 1 lint surface plus cross-platform Windows clippy coverage; only the full test runtime (nextest run) is deferred to CI. |
| PR CI | on PR to main |
.github/workflows/pr-fast.yml |
minutes | PR-blocking matrix (classify → file-size, fmt, sanity, clippy, docs, test-build, tests, security, windows-lint, required). The classify job short-circuits docs-only / dep-only / infra-only PRs so heavy jobs only run when code actually changed. Linux jobs run on ubuntu-22.04; windows-lint runs cargo clippy -- -D warnings natively on windows-latest (Phase W5.5) so both #[cfg(windows)] compile errors and lint regressions surface at PR time. Tier 2 weekly workflow (.github/workflows/tier-2.yml) runs coverage + udeps + miri out of the critical path. |
| Release | manual today; automated after release-automation R4 | just ship today; release-plz release PR after R4 |
minutes | today: version bump + release/vX.Y.Z PR + signed commit + auto-tag + binary build. Target state (see docs/architecture/release-automation-plan.md): release-plz opens chore(release): prepare vX.Y.Z PR automatically from conventional commits on main; merging that PR creates the tag; release.yml builds binaries as today. |
The ultra-strict flag stack — common_flags / prod_flags / test_flags — is defined in @/Users/rnio/Private/Github/UltraFastFileSearch/just/shared.just:21-26 and pulled in identically by the local hooks and by just ship Phase 1, so the rules a commit is checked against locally are the exact rules CI enforces.
As of Phase W5 of docs/architecture/windows-clippy-and-linux-cross-plan.md, pr-fast.yml's windows-lint job runs strict cargo clippy -- -D warnings natively on windows-latest so both compile errors and lint regressions on #[cfg(windows)] paths surface at PR time. Pre-push runs the cross-compiled equivalent (just lint-ci-windows, ~6 s warm) as an advisory local mirror; CI on windows-latest is authoritative. Breakdown:
- Windows —
cargo xwin clippy --workspace --all-targets --all-features --no-deps -- -D warningsviacargo-xwin(provisions the MSVC SDK under~/Library/Caches/xwin/). Runs in ~6 s warm once the SDK is cached. Wired into pre-push (advisory) andpr-fast.yml::windows-lint(authoritative native). - Linux — covered by CI's native
clippyjob onubuntu-22.04. Two local options for ad-hoc sweeps:just lint-ci-linux-zig(native macOS → Linux viacargo-zigbuild; ~50 s cold / sub-second warm; needszig 0.14.1+cargo-zigbuildfromjust install-dev-tools) orjust lint-ci-linux(Docker; mirrors CI'srust:latestimage exactly; minutes-scale). Neither runs at pre-push by default. The zig version is pinned to 0.14.1 — Homebrew'szigformula tracks the latest release (currently 0.16.x) which has incompat issues withpsmandblake3x86_64 hand-written SIMD assembly, soinstall-dev-toolsdownloads the tarball fromziglang.orginstead. - macOS / native host — covered by the three native clippy passes (
lint-ci/lint-prod/lint-tests) at both pre-commit and pre-push.
For a full sweep across all three targets, run just check-all-targets (native + xwin + zigbuild-or-Docker Linux). The recipe prefers zigbuild when zig is on PATH, falls back to Docker, and soft-skips when neither is available.
just install-hooks # sets core.hooksPath → scripts/hooks/
just install-dev-tools # installs typos-cli + taplo-cli + cargo-xwin + x86_64-pc-windows-msvc target;
# on macOS hosts also installs zig 0.14.1 (from ziglang.org — NOT brew) +
# cargo-zigbuild + x86_64-unknown-linux-gnu target;
# prints pipx hint for `reuse`Re-run just install-hooks after any rebase that touches scripts/hooks/ — it's idempotent. The first time cargo xwin clippy runs it will download the MSVC SDK into ~/Library/Caches/xwin/ (~1–2 GB); subsequent runs reuse the cache. zig lands in ~/.local/zig/0.14.1/ with a symlink in ~/.cargo/bin/zig so it shadows any brew install zig you may have done previously.
just lint-fast # the pre-commit bundle on demand
just lint-pre-push # the pre-push bundle on demand
just lint-ci # the single clippy gate that CI runs (`--all-targets --all-features --no-deps`)
just lint-ci-linux # same clippy gate under a Linux x86_64 Docker image (authoritative cross-target)
just lint-ci-linux-zig # same clippy gate via cargo-zigbuild (native macOS → Linux; no Docker; faster)
just check-windows # cargo xwin check against x86_64-pc-windows-msvc (compile-only fast check)
just lint-ci-windows # cargo xwin clippy -- -D warnings (matches `pr-fast.yml::windows-lint`)
just check-all-targets # full sweep: native + Windows (xwin) + Linux (zigbuild or Docker)
just phase1-test # the full `just ship` Phase-1 validation (pre-ship rehearsal)git commit --no-verify # skip pre-commit
git push --no-verify # skip pre-pushUse them for work-in-progress commits on a feature branch. CI will still enforce the same gates on the PR.
The hooks are tuned for an sccache-warm workspace. If you notice cold-cache slowness, verify:
cargo install sccacheis installed and.cargo/config.tomlhasrustc-wrapper = "sccache"(default).sccache --show-statsshows a healthy cache-hit rate after a few rebuilds.- The shared
target/directory is not being wiped by unrelated tools.
See @scripts/hooks/_lint_fast.sh and @scripts/hooks/_lint_pre_push.sh for the shared parallel runners both the hooks and the just recipes call into — edit there when adjusting the gate set, not in the hooks themselves.
just test runs cargo llvm-cov nextest which writes source-instrumented artifacts into $CARGO_TARGET_DIR/llvm-cov-target/ — a tree that is entirely separate from regular cargo build's target/debug/ and target/release/, and which can grow to 100 GB+ over a long session of coverage runs (each profile bump recompiles everything; every .profraw from a failed / killed run stays cached). On a near-full disk (Dropbox sync volume, small SSD, external drive) this is the top cause of two otherwise-mysterious test failures:
handler::paths_blob_tests::try_pack_paths_blob_offloads_large_blob_to_shmemhandler::csv_blob_tests::try_pack_csv_blob_offloads_large_blob_to_shmem
Both pin the daemon's shmem-offload transport for large search blobs. When the underlying write_paths_blob hits ENOSPC / ERROR_DISK_FULL during shmem file creation the daemon correctly degrades to inline JSON (see @/Users/rnio/Private/Github/UltraFastFileSearch/crates/uffs-daemon/src/handler_blob.rs:149-159), which is exactly what the test asserts against — so the test panics with "must be offloaded to SearchPayload::ShmemBlob; got InlineBlob(...)". This is working as designed: silently skipping under disk pressure would hide a real write_paths_blob regression on a healthy host.
Run this on the host that surfaced the failure:
just clean-covThe recipe (@/Users/rnio/Private/Github/UltraFastFileSearch/just/cache.just) prunes:
$CARGO_TARGET_DIR/llvm-cov-target/— the instrumented build tree$CARGO_TARGET_DIR/llvm-cov/— the HTML coverage report directory$CARGO_TARGET_DIR/**/*.profraw— leftover instrumentation output from killed / crashed runs$LOCALAPPDATA\uffs\shmem\(Windows) /$XDG_DATA_HOME/uffs/shmem/(Linux) /~/Library/Application Support/uffs/shmem/(macOS) — orphan shmem files from aborted daemon sessions
Leaves regular cargo build artifacts, the sccache wrapper cache, and the Cargo registry alone, so a subsequent cargo build stays incremental. Empirically frees 5–30 GB on an active dev box and up to 100+ GB after a week of heavy coverage work.
If just clean-cov finishes and just test still fails with the same shmem-offload assertion, the issue is in write_paths_blob itself (a real regression) — check the daemon's stderr for a tracing::warn! line beginning paths_blob shmem write failed; falling back to inline JSON and open an issue with that error message.
UFFS is migrating to Conventional Commits to drive automated versioning and changelog generation via release-plz + git-cliff. For a one-page "what to do this week" cheatsheet (PR conventions, what's automatic, FAQs), see docs/architecture/release-automation-current-flow.md. The full multi-phase migration plan lives in docs/architecture/release-automation-plan.md.
What matters for you today:
- The PR title (which becomes the squash-merge commit subject) should follow conventional commits. Intermediate commits on a feature branch don't need to — only what lands on
main. - During the advisory phase (release-automation Phase R1a, ongoing), non-conforming titles trigger a bot comment but do not block merge. Treat the comment as a nudge, not a gate.
- During the mandatory phase (release-automation Phase R1b, scheduled after ≥1 month of advisory observation), non-conforming titles will hard-fail the required PR Fast CI check.
Recognized types and their release impact:
| Type | Meaning | Triggers release? | Version bump |
|---|---|---|---|
feat: |
User-visible new feature | Yes | Minor (0.X.0) |
fix: |
User-visible bug fix | Yes | Patch (0.0.X) |
perf: |
Performance improvement | Yes | Patch |
feat!: / fix!: |
Breaking change (note the !) |
Yes | Major (X.0.0, or minor pre-1.0) |
refactor: |
Code restructure, no behavior change | No | — |
docs: |
Documentation only | No | — |
test: |
Test additions / changes | No | — |
chore: |
Tooling, config, catch-all | No | — |
ci: |
CI / workflow change | No | — |
build: |
Build system / dependency change | No | — |
style: |
Formatting, whitespace | No | — |
revert: |
Reverts a previous commit | Inherits reverted type | Inherits |
Examples:
feat(mft): add zstd-compressed MFT archive support— minor bump, appears under "Features" in changelogfix(security): correct FNV-1a pipe hash for empty inputs— patch bump, appears under "Bug Fixes"feat(cli)!: rename --query to --filter; drop deprecated --q shorthand— major/minor bump (depending on current v0.x vs v1.x), appears under "BREAKING CHANGES"chore: bump dependabot grouping window to weekly— no releasedocs(architecture): clarify pipeline stage naming— no release
Security commits use the conventional encoding rather than a top-level security: type:
fix(security): patch FNV-1a pipe hash for empty inputs— patch bump, appears under ### Security in the changelog (thesecurityscope triggers the dedicated section viacliff.toml's^fix\(security\)parser).chore(security): refresh cargo-vet imports— no bump, also routes to ### Security.
Top-level security: is not an allowed type — the local commit-msg hook (scripts/ci/check_commit_subjects.sh) and the commitlint workflow both reject it, and release-plz's release_commits filter no longer includes it as of 2026-05-08. Historical merges that used security: (PRs #31, #33, #34, all pre-hook-installation) remain in the changelog and are documented in release-automation-baseline.md §4.
Scopes (optional, in parentheses after type): prefer the crate name or a short area tag. Examples: mft, cli, core, security, polars, ci, build, architecture. Omit the scope if the change is workspace-wide.
If in doubt, use chore: — it never triggers a release. If a PR genuinely has both a fix and a feature, split it into two PRs.
- Do not depend on
polarsdirectly; useuffs-polars. - Preserve the crate layering:
uffs-polars←uffs-mft←uffs-core←uffs-cli. - Prefer fixture-, golden-, or saved-MFT/index-based tests for portable validation.
- Update docs when contributor-facing workflow or user-visible behavior changes.
- New Windows-gated code must pass
just lint-ci-windowsbefore PR. Strict clippy on#[cfg(windows)]paths is advisory during the Phase W2–W5 backlog cleanup (seedocs/architecture/windows-clippy-and-linux-cross-plan.md) and becomes a hard gate at PR CI after W5. New lints introduced into the backlog trigger an immediate reviewer ask.
UFFS enforces a strict no-panic posture in production code via three workspace Clippy lints at deny level: unwrap_used, expect_used, and panic. Test code is exempt (see clippy.toml allow-*-in-tests = true).
The one-line rule: library code never panics on user input or environment failure; binaries may panic during bootstrap; every other panic! / unwrap() / expect() in production code is a bug.
Every surviving prod unwrap / expect / panic! fits exactly one of five categories (A–E), each requiring a specific annotation shape:
- A — Invariant violation IS a bug (upstream check guarantees the condition): keep as
expect("invariant: <specific condition>")plus#[expect(clippy::expect_used, reason = "<invariant + why upstream check guarantees it>")]. - B — Caller error / validation failure: convert to typed error variant; propagate via
?. - C — Environmental (IO, mutex poison, syscall): propagate via
?aftermap_errto a typed error, preserving the source via#[from]or#[source]. - D — Bootstrap (one-time process startup, crash-correct): keep as
expect("BOOT INVARIANT: <condition>")with#[expect(...)]. - E — Programmer bug at use site: keep as
panic!with documented invariant in the enclosing function's# Panicsdoc section.
Full taxonomy, anti-patterns, per-crate posture, and the per-site annotation contract live in docs/architecture/code-quality/panic_policy.md. Library crates do not return anyhow::Error from public APIs and do not return Result<_, String> (banned workspace-wide after Phase 5d); use a typed thiserror::Error enum with #[non_exhaustive] instead.
UFFS enforces a strict clone-and-allocation discipline in production code via five workspace Clippy lints at deny level: redundant_clone, clone_on_ref_ptr, cloned_instead_of_copied, inefficient_to_string, and unnecessary_to_owned. Test code is exempt.
The one-line rule: hot paths (per-record / per-row / per-query) never allocate defensively; cold paths (error context, log lines, one-time setup) may allocate freely; every .clone() / format!() / to_owned() in production code must fit one of the five blessed categories (α / β / γ / δ / ε), and δ is a bug.
Every surviving prod .clone() / format!() / to_owned() fits exactly one of five categories, each requiring a specific annotation shape:
- α — Arc clone (
Arc::clone(&x)form): self-evident; no comment required.clone_on_ref_ptr = "deny"enforces the explicit form. - β — Ownership fence (caller has
&T, API needsT): 1–3 line//comment explaining why the alternative (&T, in-place mutation) doesn't work. - γ — Error / log context (allocation inside an error variant or
tracing!event): brief reason; the category is self-evident from the context. - δ — Hot-path anti-pattern (clone of
String/Vec<T>inside a per-record loop that could be eliminated): FIX, do not suppress. Refactor the call site with a comment documenting the new (correct) borrow invariant. - ε — Test helper (
#[cfg(test)]-only allocation): out of scope; test code is exempt.
Full taxonomy, the per-site annotation contract, the workspace inventory script (scripts/dev/clone_alloc_audit.sh), and the per-phase decisions log live in docs/architecture/code-quality/allocation_policy.md.
UFFS enforces a strict trait / generic / dispatch discipline in production code via five workspace Clippy lints: type_complexity, too_many_arguments, trait_duplication_in_bounds, wrong_self_convention (all deny), and multiple_bound_locations (warn). Test code is exempt.
The one-line rule: a trait must satisfy at least one of [J1] multiple impls / [J2] test substitution / [J3] stable extension / [J4] high-level decoupling — otherwise it's decoration. Generics stay local. dyn for plugin boundaries; static for closed sets.
Trait justification four-criterion taxonomy:
- [J1] Multiple meaningful implementations (≥ 2 prod impls on
main). - [J2] Test-substitution boundary (prod impl + ≥ 1 test fake).
- [J3] Stable extension surface (rustdoc documents external impls).
- [J4] High-level / infrastructure decoupling.
A trait satisfying none of J1–J4 → demote to a concrete type and replace usages.
Generic-function categories (G1-LOCAL / G2-USEFUL / G3-SPREAD / G4-CASCADING / G5-CLOSURE), dispatch matrix (D1-PLUGIN / D2-HETERO / D3-NOOP / D4-VTBL-COST), seal-vs-open decision tree, the per-trait registry, the workspace inventory script (scripts/dev/trait_generic_audit.sh), and the per-phase decisions log live in docs/architecture/code-quality/trait_policy.md.
UFFS keeps feature behavior additive and dependency duplication audited. No new clippy lints; the contract is enforced by cargo deny check, cargo machete, cargo vet, and cargo tree --workspace -d, all wired into pre-push and pr-fast.yml::security.
The one-line rule: every feature is additive (enabling never removes a pub item); every default has a written justification; every optional dep is reachable via dep:<name> and at least one #[cfg(feature = "…")] use-site; every cross-version duplicate is either in deny.toml [bans].skip-tree with a one-line reason or accepted by the workspace's multiple-versions = "warn" posture and inventoried in dependency_policy.md §5.1.
Every feature added to the workspace must document the four-line playbook §988 contract in both the crate's root rustdoc (# Features section) and as a block comment above the [features] block in Cargo.toml:
- What it enables — which module / item / subcommand / binary.
- What deps it adds —
dep:<name>gating + transitive feature pulls. - API shape impact — additive (default) | subtractive (forbidden).
- Semver claim — adding items behind it is non-breaking; removing items behind it is breaking.
The feature taxonomy (F1-additive-default-on / F2-additive-default-off / F3-orthogonal / F4-subtractive-FORBIDDEN / F5-feature-on-feature), the cross-version duplicate acceptance inventory, the per-crate feature registry, the workspace inventory script (scripts/dev/feature_dep_audit.sh), and the per-phase decisions log live in docs/architecture/code-quality/dependency_policy.md.
UFFS keeps compile-time magic justified and traceable. No new clippy lints; the contract is enforced by scripts/dev/build_codegen_audit.sh plus the existing manifest-drift / hooks-drift / fast-drift / workflow-drift gates wired into pre-push and pr-fast.yml.
The one-line rule: every build.rs falls into one of the three playbook §1041-1046 justification classes; every macro_rules! falls into one of the three playbook §1064 justification classes (control-flow hiding is forbidden); every codegen binary has a drift detector or a documented "no idempotency contract" rationale; every environment variable the workspace reads is in build_codegen_policy.md §5 with name, scope, type, default, where read, and semver class.
Current posture (as of Phase 9 entry, SHA 0433065c7):
- 1
build.rs(uffs-cli) — MSVC-gated PE resource embedding +/DELAYLOADlinker args. - 0 proc-macro crates — deliberate workspace posture; introducing one requires unanimous review.
- 6
macro_rules!declarations — all inuffs-mft, allpub(crate)-scoped or function-local. - 4 codegen binaries — 3 emitter/validators (drift-detected) + 1 release orchestrator.
- 36 distinct env-var names across 7 scope categories (build-time, standard runtime, logging, UFFS runtime knobs, client knobs, build/release knobs, test-only).
The build.rs / proc-macro / macro_rules! / codegen / env-var per-class contracts, the per-crate registry, the env-var registry, the workspace inventory script (scripts/dev/build_codegen_audit.sh), and the per-phase decisions log live in docs/architecture/code-quality/build_codegen_policy.md.
UFFS enforces a strict task-ownership, lock-discipline, channel-backpressure, timeout-coverage, and blocking-IO posture in production async code. Three workspace Clippy lints at deny cover the std-side lock-across-await family (await_holding_lock, await_holding_refcell_ref, await_holding_invalid_type); the rest is enforced by scripts/dev/concurrency_audit.sh + a per-site annotation contract.
The one-line rule: every tokio::spawn declares its owner / shutdown / errors / cancellation; every async lock guard is dropped before the next .await; every channel is bounded with documented capacity OR unbounded with a documented producer-rate ceiling; every cross-process / cross-thread / cross-network await has a timeout OR is justified as a cooperatively-cancelled forever-loop; every std::fs::* / std::thread::sleep inside an async fn is wrapped in spawn_blocking / block_in_place OR is a sync helper called only from sync contexts.
Five dimensions, each with a taxonomy contributors quote inline:
- Task ownership (
T1named-constructor /T2inline-spawn /T3fire-and-forget /T4test-only) — every prod spawn site documents the four facets above. - Lock discipline (
L1-L5patterns;L6lock-across-await is forbidden) — three Clippyawait_holding_*lints atdeny. - Channel discipline (
C1bounded /C2broadcast /C3oneshot /C4watch /C5unbounded-with-ceiling;C6undocumented unbounded is forbidden). - Timeout policy (
W1named const /W2env-overridable /W3cooperatively-cancelled forever-loop /W4inline literal;W5unbounded cross-process await is forbidden). - Blocking-IO rule (
B1spawn_blocking/B2block_in_place/B3sync helper /B4startup/Drop/CLI one-shot;B5unbounded sync I/O on runtime worker is forbidden).
Full taxonomy, per-site annotation templates, the workspace inventory script (scripts/dev/concurrency_audit.sh), per-crate posture matrix, and the per-phase audit trail live in docs/architecture/code-quality/concurrency_policy.md.
- Root overview:
README.md - Documentation map:
docs/README.md - Developer docs landing page:
docs/dev/README.md - Architecture docs:
docs/architecture/README.md - CI / gate architecture:
docs/architecture/dev-flow-implementation-plan.md - Release / versioning architecture:
docs/architecture/release-automation-plan.md - Cross-target strict-lint architecture:
docs/architecture/windows-clippy-and-linux-cross-plan.md
If you are changing behavior that depends on raw NTFS access, call out the Windows/Admin requirement in the relevant docs and tests.