swarm repositories / source
aboutsummaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
authormain <main@swarm.moe>2026-04-17 22:08:47 -0400
committermain <main@swarm.moe>2026-04-17 22:08:47 -0400
commit372d366f541f4560a304d4d374bebc31aec6e8c3 (patch)
tree0ee6a8f869fd31cb33b7031c5991c17a1dfdf79d /docs
parent8048d67e5917b771be9aa819094aebf3936d0e98 (diff)
downloadrust_starter-372d366f541f4560a304d4d374bebc31aec6e8c3.zip
Install Rust style doctrine
Diffstat (limited to 'docs')
-rw-r--r--docs/bootstrap-fresh.md28
-rw-r--r--docs/bootstrap-retrofit.md29
-rw-r--r--docs/rust-linting-proposal.md2
-rw-r--r--docs/rust-style-doctrine.md13
4 files changed, 57 insertions, 15 deletions
diff --git a/docs/bootstrap-fresh.md b/docs/bootstrap-fresh.md
index 89bf757..b0dd3f8 100644
--- a/docs/bootstrap-fresh.md
+++ b/docs/bootstrap-fresh.md
@@ -6,6 +6,7 @@ Use this surface when the target repo is blank or when you are setting up Rust l
Install the `rust-starter` lint posture cleanly:
+- target `AGENTS.md` links to the canonical Rust style doctrine
- root `Cargo.toml` owns lint levels
- every crate inherits workspace lint policy
- `rust-toolchain.toml` is pinned exactly
@@ -25,11 +26,14 @@ Before copying the template, decide:
- whether the repo is library-heavy enough to keep rustdoc linting in the fast gate or only the deep gate
- whether unsafe Rust is forbidden or tightly-governed
- whether the default `2500`-line source-file cap should stay as-is or be tightened for this repo
+- how to merge the Rust style doctrine link into any existing target `AGENTS.md` guidance
## Files To Start From
Use these as the concrete baseline:
+- [docs/rust-style-doctrine.md](/home/main/programming/projects/rust_starter/docs/rust-style-doctrine.md)
+- [template/fresh/AGENTS.md](/home/main/programming/projects/rust_starter/template/fresh/AGENTS.md)
- [template/fresh/Cargo.toml](/home/main/programming/projects/rust_starter/template/fresh/Cargo.toml)
- [template/fresh/rust-toolchain.toml](/home/main/programming/projects/rust_starter/template/fresh/rust-toolchain.toml)
- [template/fresh/clippy.toml](/home/main/programming/projects/rust_starter/template/fresh/clippy.toml)
@@ -41,7 +45,18 @@ Do not copy them mechanically. Replace the placeholder members, names, license,
## Sequence
-### 1. Write the root manifest first
+### 1. Seed `AGENTS.md` first
+
+Create or adapt the target repo's `AGENTS.md` so it links to
+[docs/rust-style-doctrine.md](/home/main/programming/projects/rust_starter/docs/rust-style-doctrine.md).
+Use [template/fresh/AGENTS.md](/home/main/programming/projects/rust_starter/template/fresh/AGENTS.md)
+as the starting point for a blank repo. If the target already has instructions,
+merge the link without erasing local rules.
+
+The point is inheritance: future agents entering the repo must encounter the
+Rust style doctrine without knowing this bootstrap skill exists.
+
+### 2. Write the root manifest
Start from the template root manifest and adapt:
@@ -56,11 +71,11 @@ The fresh template exports an ordered `canonicalize_commands` pipeline. Keep it
Also keep the source-file cap in `[workspace.metadata.rust-starter.source_files]`. The starter default is a hard `2500`-line limit across `*.rs` files. Tighten it if the repo already has sharper discipline.
-### 2. Pin the toolchain second
+### 3. Pin the toolchain
Write `rust-toolchain.toml` early, before deciding whether a lint is noisy or broken. Lint output is part of the toolchain contract.
-### 3. Make every crate inherit lint policy
+### 4. Make every crate inherit lint policy
Each member crate must contain:
@@ -71,13 +86,13 @@ workspace = true
Do not rely on memory or convention here; add it explicitly.
-### 4. Add `clippy.toml` only if it carries real configuration
+### 5. Add `clippy.toml` only if it carries real configuration
The default template only relaxes `expect`, `unwrap`, and `panic` inside tests. If the target repo does not want that, delete the file instead of leaving inert config behind.
Do not move global allow/deny policy into `clippy.toml`.
-### 5. Add a thin runner
+### 6. Add a thin runner
The template `check.py` is intentionally small. It reads canonicalization and verification commands plus the source-file policy from workspace metadata, enforces the file cap, and then runs the Rust commands.
@@ -95,7 +110,7 @@ If the target repo already prefers another orchestration surface, keep that surf
If the repo has checked-in generated Rust that should not count against the cap, express that with explicit `exclude` patterns under `[workspace.metadata.rust-starter.source_files]` instead of weakening the global limit.
-### 6. Keep the deep gate opt-in
+### 7. Keep the deep gate opt-in
The template only installs the fast gate. Add the deeper posture when the repo is mature enough:
@@ -116,6 +131,7 @@ The template only installs the fast gate. Add the deeper posture when the repo i
## Acceptance Checklist
- root `Cargo.toml` contains `[workspace.lints.rust]`, `[workspace.lints.rustdoc]`, and `[workspace.lints.clippy]`
+- target `AGENTS.md` links to [docs/rust-style-doctrine.md](/home/main/programming/projects/rust_starter/docs/rust-style-doctrine.md)
- root `Cargo.toml` owns warning-fatality policy, e.g. `warnings = "deny"` under `[workspace.lints.rust]`, rather than hiding it in runner flags
- root `Cargo.toml` contains canonical command vectors in `[workspace.metadata.rust-starter]`
- root `Cargo.toml` contains an ordered `canonicalize_commands` pipeline in `[workspace.metadata.rust-starter]`
diff --git a/docs/bootstrap-retrofit.md b/docs/bootstrap-retrofit.md
index a2910ce..5c337e6 100644
--- a/docs/bootstrap-retrofit.md
+++ b/docs/bootstrap-retrofit.md
@@ -6,6 +6,7 @@ Use this surface when the target repo already has Rust linting, but you want to
Migrate the repo toward the `rust-starter` posture while staying diff-aware:
+- install the canonical Rust style doctrine link in target `AGENTS.md`
- preserve stricter existing rules
- preserve justified local carve-outs
- delete duplicated policy only after it has been re-homed into the manifest
@@ -17,6 +18,7 @@ Migrate the repo toward the `rust-starter` posture while staying diff-aware:
Before editing, inspect all of the places the repo may already encode lint policy:
- root and member `Cargo.toml`
+- `AGENTS.md` and any nested agent instruction files
- `check.py`, `xtask`, shell wrappers, `justfile`, or other runners
- CI workflow files
- any existing auto-fix or canonicalization commands
@@ -36,6 +38,7 @@ Use these as the baseline, not as paste targets:
- [template/fresh](/home/main/programming/projects/rust_starter/template/fresh)
- [docs/rust-linting-proposal.md](/home/main/programming/projects/rust_starter/docs/rust-linting-proposal.md)
+- [docs/rust-style-doctrine.md](/home/main/programming/projects/rust_starter/docs/rust-style-doctrine.md)
The fresh template tells you the shape to converge toward. The proposal doc tells you why.
@@ -80,45 +83,54 @@ Keep `clippy.toml` only for structured knobs such as test allowances.
Apply tightenings in this order:
-### 1. Pin or refresh the toolchain
+### 1. Install style inheritance
+
+Add or preserve a target `AGENTS.md` link to
+[docs/rust-style-doctrine.md](/home/main/programming/projects/rust_starter/docs/rust-style-doctrine.md).
+Do not overwrite local agent instructions; merge the doctrine link into them.
+
+This is intentionally infectious. Future agents should read the Rust style
+doctrine by entering the target repo, not only by invoking this bootstrap skill.
+
+### 2. Pin or refresh the toolchain
Add `rust-toolchain.toml` if missing. If present but floating, pin it.
-### 2. Install workspace lint tables
+### 3. Install workspace lint tables
Move repo-wide policy into root `[workspace.lints.*]`.
-### 3. Make member crates inherit explicitly
+### 4. Make member crates inherit explicitly
Add `[lints] workspace = true` to every member crate.
-### 4. Re-home script flags into the manifest
+### 5. Re-home script flags into the manifest
Take inline `cargo clippy -- -A/-D ...` tails from scripts and CI, and migrate them into the root manifest in grouped, commented form.
That includes `-D warnings`: if warnings are meant to be fatal, encode that as
`warnings = "deny"` under `[workspace.lints.rust]` instead of leaving it as a command-line tail.
-### 5. Tighten local suppression discipline
+### 6. Tighten local suppression discipline
Prefer:
- `#[expect(..., reason = "...")]` for temporary or evidence-backed suppressions
- `#[allow(..., reason = "...")]` only for stable local policy
-### 6. Simplify the runner
+### 7. Simplify the runner
Once the manifest is authoritative, collapse the runner to orchestration-only plus generic manifest-backed checks such as the source-file cap.
If the repo already has an auto-fix pass, re-home it into root `workspace.metadata.rust-starter.canonicalize_commands` and make the default local `check` path invoke it before the verification gate instead of relying on engineers or agents to remember a separate pre-pass.
-### 7. Install the source-file cap
+### 8. Install the source-file cap
Add `[workspace.metadata.rust-starter.source_files]` to the root manifest and set `max_lines` deliberately.
Default to `2500` if the repo has no existing stance. If the repo already enforces a stricter cap, keep the stricter value. If the repo has checked-in generated Rust that would make the rule meaningless, exclude those paths explicitly instead of disabling the whole mechanism.
-### 8. Add deep-gate posture if the repo is ready
+### 9. Add deep-gate posture if the repo is ready
Add `cargo hack`, docs, and dependency-hygiene checks only when the repo can support them without turning the whole effort into churn theater.
@@ -148,6 +160,7 @@ If the repo wants CI to detect canonicalization drift rather than rewriting file
## Acceptance Checklist
- repo-wide policy lives in root `[workspace.lints.*]`
+- target `AGENTS.md` links to [docs/rust-style-doctrine.md](/home/main/programming/projects/rust_starter/docs/rust-style-doctrine.md)
- every member crate inherits that policy explicitly
- scripts and CI no longer restate Clippy allowlists
- manifest-owned canonicalization exists where the repo wants auto-fixes, instead of living in shell aliases or tribal memory
diff --git a/docs/rust-linting-proposal.md b/docs/rust-linting-proposal.md
index 88e5612..65f800f 100644
--- a/docs/rust-linting-proposal.md
+++ b/docs/rust-linting-proposal.md
@@ -507,7 +507,7 @@ If the goal is "force industrial-grade linting", ambient toolchain drift is the
Use this style:
-> Set up Rust linting with the `rust-starter` industrial profile: pin an exact stable `rust-toolchain.toml`; put repo policy only in root `[workspace.lints.{rust,rustdoc,clippy}]` plus manifest-owned canonicalization and verification command vectors and source-file-cap metadata in `workspace.metadata`; make every crate opt into `[lints] workspace = true`; make the default local `check` path canonicalize first, but keep a non-mutating `verify` path for CI; cherry-pick restriction bans instead of enabling `clippy::restriction`; keep repo-wide Clippy carve-outs centralized and commented in `Cargo.toml`; and require local suppressions to use `#[expect(..., reason = "...")]` unless a permanent `#[allow(..., reason = "...")]` is truly justified.
+> Set up Rust linting with the `rust-starter` industrial profile: link target `AGENTS.md` to [docs/rust-style-doctrine.md](/home/main/programming/projects/rust_starter/docs/rust-style-doctrine.md); pin an exact stable `rust-toolchain.toml`; put repo policy only in root `[workspace.lints.{rust,rustdoc,clippy}]` plus manifest-owned canonicalization and verification command vectors and source-file-cap metadata in `workspace.metadata`; make every crate opt into `[lints] workspace = true`; make the default local `check` path canonicalize first, but keep a non-mutating `verify` path for CI; cherry-pick restriction bans instead of enabling `clippy::restriction`; keep repo-wide Clippy carve-outs centralized and commented in `Cargo.toml`; and require local suppressions to use `#[expect(..., reason = "...")]` unless a permanent `#[allow(..., reason = "...")]` is truly justified.
That is long, but it is precise and inferable by a model.
diff --git a/docs/rust-style-doctrine.md b/docs/rust-style-doctrine.md
new file mode 100644
index 0000000..1a1ef20
--- /dev/null
+++ b/docs/rust-style-doctrine.md
@@ -0,0 +1,13 @@
+# Rust Style Doctrine
+
+This doctrine deliberately rejects several pieces of conventional engineering wisdom. Do not silently translate it back into "clear, simple, approachable Rust." Where it conflicts with common advice, the conflict is usually intentional: agent-maintained code prefers static truth, compact representation, and powerful abstraction over novice readability, defensive ceremony, and lowest-common-denominator style. Notice the inversion and obey it.
+
+Rust code is a typed semantic artifact for agents, compilers, analyzers, and refactoring tools. Optimize for correctness, static structure, token economy, and intentional shape before ordinary human approachability. The code should look designed top-down around the domain, not accreted around incidents. Delete dead paths, compatibility husks, redundant layers, speculative knobs, ceremonial wrappers, and explanatory scaffolding. Hot sites should be small and exact; cold files may contain large definitions, tables, macros, derives, and helper machinery if they make the live surface leaner.
+
+Make illegal states unrepresentable. Stringly closed worlds, ad-hoc tuples, bool flags, walls of optionals, and folklore invariants are design failures. If a value has semantics, give it a domain type. Use enums, newtypes, structured IDs, typestates, phase-separated types, traits, generics, const generics, and total transformations to move truth into the type system. Prefer algebraic modeling, pattern matching, iterator algebra, composable APIs, and higher-order transforms. A good module should feel like a small calculus: constrained inputs, explicit states, predictable outputs.
+
+Overabstraction is not a crime. Weak abstraction is. The usual danger in agentic code is not that the model invents PLT machinery too powerful to follow; it is that it spills simple concrete structs, flags, guards, and named intermediates until the real invariant is smeared across the context window. Advanced math is often clearer to agents than bulk mundane plumbing. Trade shallow readability for structural correctness when the abstraction genuinely compresses the domain. DRY is stronger than YAGNI. Prefer one precise abstraction over five simple repetitions that must be kept mentally synchronized.
+
+Use the full language. Macros are first-class tools for uniformity, token economy, and invariant enforcement. Operator overloading is encouraged when the operation has the expected algebraic meaning. Prefer unqualified imports at call sites: import the symbol you mean, then use it bare. Prefer compact, domain-faithful names, including mathematical names, non-camel aliases, and Unicode identifiers when they match standard notation and reduce ambiguity. Destructure aggressively when it removes noise. Do not write Rust as Python with types sprinkled on top.
+
+Fail hard unless recovery is real. `Result` is for recoverable failure, not ritual anxiety; impossible states should be impossible, and irrecoverable states should panic early with domain context. Formatting, linting, type checking, dependency pruning, and semantic navigation are part of the build contract. Run `cargo fmt` after meaningful edits. Deny strict Clippy by default, including pedantic lints, with explicit recorded exceptions for low-value noise. Use rust-analyzer before textual search for definitions, references, diagnostics, and refactors. The machine should be austere, analyzable, and exact.