diff options
| author | main <main@swarm.moe> | 2026-04-17 22:08:47 -0400 |
|---|---|---|
| committer | main <main@swarm.moe> | 2026-04-17 22:08:47 -0400 |
| commit | 372d366f541f4560a304d4d374bebc31aec6e8c3 (patch) | |
| tree | 0ee6a8f869fd31cb33b7031c5991c17a1dfdf79d | |
| parent | 8048d67e5917b771be9aa819094aebf3936d0e98 (diff) | |
| download | rust_starter-372d366f541f4560a304d4d374bebc31aec6e8c3.zip | |
Install Rust style doctrine
| -rw-r--r-- | AGENTS.md | 6 | ||||
| -rw-r--r-- | README.md | 2 | ||||
| -rw-r--r-- | docs/bootstrap-fresh.md | 28 | ||||
| -rw-r--r-- | docs/bootstrap-retrofit.md | 29 | ||||
| -rw-r--r-- | docs/rust-linting-proposal.md | 2 | ||||
| -rw-r--r-- | docs/rust-style-doctrine.md | 13 | ||||
| -rw-r--r-- | skills/rust-bootstrap/SKILL.md | 9 | ||||
| -rw-r--r-- | skills/rust-bootstrap/agents/openai.yaml | 4 | ||||
| -rw-r--r-- | template/fresh/AGENTS.md | 8 |
9 files changed, 82 insertions, 19 deletions
@@ -1,5 +1,10 @@ This repo is the source of truth for bootstrapping or ratcheting Rust lint posture. +Read [docs/rust-style-doctrine.md](/home/main/programming/projects/rust_starter/docs/rust-style-doctrine.md) +before meaningful Rust style decisions. New and retrofitted Rust projects should +link to that doctrine from their own `AGENTS.md` so future agents inherit the +same taste surface. + Choose exactly one surface: - Fresh bootstrap: read [docs/bootstrap-fresh.md](/home/main/programming/projects/rust_starter/docs/bootstrap-fresh.md) and adapt the files under [template/fresh](/home/main/programming/projects/rust_starter/template/fresh). @@ -10,6 +15,7 @@ House rules: - Keep lint semantics in root `Cargo.toml`; keep runners, CI, and editor config orchestration-only. - Make every member crate opt into `[lints] workspace = true`. - Pin an exact stable toolchain in `rust-toolchain.toml`. +- Install a target `AGENTS.md` link to [docs/rust-style-doctrine.md](/home/main/programming/projects/rust_starter/docs/rust-style-doctrine.md). - Prefer `#[expect(..., reason = "...")]` for temporary local suppressions. - Retrofit is ratchet work: preserve stricter local policy and justified local carve-outs; do not blindly paste the template. @@ -3,5 +3,5 @@ Source of truth for bootstrapping or ratcheting strict Rust lint posture. - `template/fresh/`: fresh starter template with manifest-owned lint and check policy -- `docs/`: fresh-bootstrap and retrofit guidance plus policy rationale +- `docs/`: fresh-bootstrap and retrofit guidance, policy rationale, and the Rust style doctrine - `skills/`: bundled Codex skills for Rust bootstrap and slop extermination 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. diff --git a/skills/rust-bootstrap/SKILL.md b/skills/rust-bootstrap/SKILL.md index 499bf04..a6d30d2 100644 --- a/skills/rust-bootstrap/SKILL.md +++ b/skills/rust-bootstrap/SKILL.md @@ -1,11 +1,13 @@ --- name: rust-bootstrap -description: Bootstrap or retrofit industrial-grade Rust linting by using the `rust_starter` repo as the source of truth. Use when Codex needs to set up strict Rust lint/check posture from scratch in a new repo, or ratchet an existing Rust repo toward manifest-owned lint policy without blindly overwriting valid local exceptions or stricter existing rules. +description: Bootstrap or retrofit industrial-grade Rust linting and Rust style inheritance by using the `rust_starter` repo as the source of truth. Use when Codex needs to set up strict Rust lint/check posture from scratch in a new repo, ratchet an existing Rust repo toward manifest-owned lint policy, or install the canonical Rust style doctrine link into a target AGENTS.md. --- # Rust Bootstrap Read [AGENTS.md](/home/main/programming/projects/rust_starter/AGENTS.md) first. +Read [docs/rust-style-doctrine.md](/home/main/programming/projects/rust_starter/docs/rust-style-doctrine.md) +before making Rust style decisions or writing target `AGENTS.md` guidance. Then choose exactly one surface. @@ -16,6 +18,7 @@ Use this when the target repo is blank or when you are setting up Rust linting f Read: - [docs/bootstrap-fresh.md](/home/main/programming/projects/rust_starter/docs/bootstrap-fresh.md) +- [docs/rust-style-doctrine.md](/home/main/programming/projects/rust_starter/docs/rust-style-doctrine.md) - [template/fresh](/home/main/programming/projects/rust_starter/template/fresh) Apply the template deliberately: @@ -24,6 +27,7 @@ Apply the template deliberately: - keep repo-wide policy in root `Cargo.toml` - keep `clippy.toml` tiny or delete it - keep runners thin and orchestration-only +- create or adapt target `AGENTS.md` so it links to the canonical Rust style doctrine ## Retrofit @@ -34,6 +38,7 @@ Read: - [docs/bootstrap-retrofit.md](/home/main/programming/projects/rust_starter/docs/bootstrap-retrofit.md) - [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) Retrofit is diff-aware ratchet work: @@ -42,10 +47,12 @@ Retrofit is diff-aware ratchet work: - preserve justified local exceptions - move duplicated script or CI flags into manifest-owned policy - delete duplicate policy copies only after the manifest is authoritative +- add or preserve a target `AGENTS.md` link to the canonical Rust style doctrine ## Guardrails - Re-open the repo docs when details matter; do not rely on memory. +- Install style inheritance through target `AGENTS.md`; do not assume future agents will remember this skill. - Use [docs/rust-linting-proposal.md](/home/main/programming/projects/rust_starter/docs/rust-linting-proposal.md) for rationale, not as a paste target. - If a target repo already exceeds the template in some area, keep the stricter local posture. - If a target repo intentionally diverges, adapt the pattern instead of forcing uniformity. diff --git a/skills/rust-bootstrap/agents/openai.yaml b/skills/rust-bootstrap/agents/openai.yaml index 2dbdc72..6a4010a 100644 --- a/skills/rust-bootstrap/agents/openai.yaml +++ b/skills/rust-bootstrap/agents/openai.yaml @@ -1,4 +1,4 @@ interface: display_name: "Rust Bootstrap" - short_description: "Bootstrap or tighten Rust linting" - default_prompt: "Use rust_starter to bootstrap or retrofit industrial-grade Rust linting." + short_description: "Bootstrap Rust linting and style inheritance" + default_prompt: "Use rust_starter to bootstrap or retrofit industrial-grade Rust linting and install the Rust style doctrine link." diff --git a/template/fresh/AGENTS.md b/template/fresh/AGENTS.md new file mode 100644 index 0000000..c5e927b --- /dev/null +++ b/template/fresh/AGENTS.md @@ -0,0 +1,8 @@ +# AGENTS.md + +Before meaningful Rust edits, read the [Rust Style Doctrine](/home/main/programming/projects/rust_starter/docs/rust-style-doctrine.md). +It intentionally rejects several pieces of conventional Rust advice; preserve +those inversions instead of translating them back into generic approachable code. + +Run `./check.py check` after meaningful local edits. Use `./check.py verify` +when you need a non-mutating CI-style gate. |