swarm repositories / source
aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormain <main@swarm.moe>2026-06-13 12:10:55 -0400
committermain <main@swarm.moe>2026-06-13 12:10:55 -0400
commit4735637ead09c4e8d4b9a0409d7ea2538eb9cb40 (patch)
tree344558bb4616293e7f9f3bcdc4dae6cbbcc0b608
parent89dba1d9c0034e6bc544b0f002a65ffe0b29e7dc (diff)
downloadrust_starter-4735637ead09c4e8d4b9a0409d7ea2538eb9cb40.zip
Update Rust starter bootstrap posture
Install project-local Cargo target-dir guidance and template config, keep Cargo output under /data/main/cargo-target/<project-slug>, preserve the global shared target fallback, and raise the source-file cap to 3000 lines.
-rw-r--r--AGENTS.md1
-rw-r--r--README.md2
-rw-r--r--docs/bootstrap-fresh.md46
-rw-r--r--docs/bootstrap-retrofit.md44
-rw-r--r--docs/rust-linting-proposal.md76
-rw-r--r--docs/rust-style-doctrine.md2
-rw-r--r--skills/rust-bootstrap/SKILL.md4
-rw-r--r--template/fresh/.cargo/config.toml5
-rw-r--r--template/fresh/Cargo.toml8
-rw-r--r--template/fresh/check.py2
10 files changed, 157 insertions, 33 deletions
diff --git a/AGENTS.md b/AGENTS.md
index e08e08c..f758059 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -13,6 +13,7 @@ Choose exactly one surface:
House rules:
- Keep lint semantics in root `Cargo.toml`; keep runners, CI, and editor config orchestration-only.
+- Install project-local `.cargo/config.toml` with `[build] target-dir = "/data/main/cargo-target/<project-slug>"`; do not alter user-global Cargo config.
- 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).
diff --git a/README.md b/README.md
index 1647e9d..0eabb59 100644
--- a/README.md
+++ b/README.md
@@ -2,6 +2,6 @@
Source of truth for bootstrapping or ratcheting strict Rust lint posture.
-- `template/fresh/`: fresh starter template with manifest-owned lint and check policy
+- `template/fresh/`: fresh starter template with project-local Cargo target-dir config, manifest-owned lint policy, and thin check policy
- `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 b0dd3f8..b3c9112 100644
--- a/docs/bootstrap-fresh.md
+++ b/docs/bootstrap-fresh.md
@@ -10,6 +10,7 @@ Install the `rust-starter` lint posture cleanly:
- root `Cargo.toml` owns lint levels
- every crate inherits workspace lint policy
- `rust-toolchain.toml` is pinned exactly
+- project-local `.cargo/config.toml` routes Cargo output to `/data/main/cargo-target/<project-slug>`
- `clippy.toml` stays tiny and only carries structured config
- the runner stays thin and reads canonicalization and verification command vectors plus the source-file cap from workspace metadata instead of restating policy
@@ -22,10 +23,11 @@ Before copying the template, decide:
- license policy
- exact pinned stable toolchain
- actual MSRV / `rust-version`
+- Cargo target-dir slug under `/data/main/cargo-target`, normally the target repo directory name
- whether tests should allow `expect`, `unwrap`, or `panic`
- 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
+- whether the default `3000`-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
@@ -34,6 +36,7 @@ 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/config.toml](/home/main/programming/projects/rust_starter/template/fresh/.cargo/config.toml)
- [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 +44,7 @@ Use these as the concrete baseline:
- [template/fresh/crates/app/Cargo.toml](/home/main/programming/projects/rust_starter/template/fresh/crates/app/Cargo.toml)
- [template/fresh/crates/app/src/main.rs](/home/main/programming/projects/rust_starter/template/fresh/crates/app/src/main.rs)
-Do not copy them mechanically. Replace the placeholder members, names, license, and version/toolchain values.
+Do not copy them mechanically. Replace the placeholder members, names, license, Cargo target-dir slug, and version/toolchain values.
## Sequence
@@ -69,13 +72,35 @@ Keep the command vectors in `[workspace.metadata.rust-starter]` even if you late
The fresh template exports an ordered `canonicalize_commands` pipeline. Keep it repo-owned in the root manifest and make the default `check` path run it automatically before the verification gate so humans and agents do not need to remember a separate pre-pass.
-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.
+Also keep the source-file cap in `[workspace.metadata.rust-starter.source_files]`. The starter default is a hard `3000`-line limit across `*.rs` files. Tighten it if the repo already has sharper discipline.
-### 3. Pin the toolchain
+### 3. Install project-local Cargo target config
+
+Create or adapt the target repo's `.cargo/config.toml` before running Cargo commands:
+
+```toml
+[build]
+target-dir = "/data/main/cargo-target/<project-slug>"
+```
+
+Use the target repo directory name as the default slug. If two repos share a
+directory basename, append a short path hash or another stable disambiguator.
+The point is a clean, checked-in per-repo target directory under the global
+Cargo target volume, not a source-tree `target/` directory and not command-line
+`--target-dir` folklore.
+
+This is a repo-local ratchet. Do not mutate user-global Cargo config during
+bootstrap; if a repo has not opted in yet, the developer's global Cargo config
+remains the fallback.
+
+If `.cargo/config.toml` already exists, merge the `[build] target-dir` value
+without overwriting unrelated Cargo configuration.
+
+### 4. 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.
-### 4. Make every crate inherit lint policy
+### 5. Make every crate inherit lint policy
Each member crate must contain:
@@ -86,13 +111,13 @@ workspace = true
Do not rely on memory or convention here; add it explicitly.
-### 5. Add `clippy.toml` only if it carries real configuration
+### 6. 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`.
-### 6. Add a thin runner
+### 7. 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.
@@ -110,7 +135,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.
-### 7. Keep the deep gate opt-in
+### 8. Keep the deep gate opt-in
The template only installs the fast gate. Add the deeper posture when the repo is mature enough:
@@ -126,13 +151,17 @@ The template only installs the fast gate. Add the deeper posture when the repo i
- do not enable `clippy::restriction` wholesale
- do not enable `clippy::nursery` wholesale
- do not duplicate lint policy in scripts, CI, and editor config
+- do not pass `--target-dir` from runners, CI, or command vectors; use `.cargo/config.toml`
+- do not change user-global Cargo config as part of bootstrapping a target repo
- do not leave placeholder toolchain or MSRV values unreviewed
## 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)
+- target `.cargo/config.toml` contains `[build] target-dir = "/data/main/cargo-target/<project-slug>"`
- 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` preserves the global wildcard/glob carve-outs; compact `*` imports are intentionally allowed for token economy
- 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]`
- root `Cargo.toml` contains `[workspace.metadata.rust-starter.source_files]` with an intentional `max_lines` value
@@ -141,5 +170,6 @@ The template only installs the fast gate. Add the deeper posture when the repo i
- `clippy.toml` is either tiny and justified or absent
- the default `check` path canonicalizes before verification, and a non-mutating `verify` path exists for CI or drift detection
- no runner or CI file duplicates the Clippy allowlist
+- no runner, CI file, or manifest-owned command vector passes `--target-dir`
Read [docs/rust-linting-proposal.md](/home/main/programming/projects/rust_starter/docs/rust-linting-proposal.md) only when you need rationale or policy nuance.
diff --git a/docs/bootstrap-retrofit.md b/docs/bootstrap-retrofit.md
index 5c337e6..c099e5f 100644
--- a/docs/bootstrap-retrofit.md
+++ b/docs/bootstrap-retrofit.md
@@ -11,6 +11,7 @@ Migrate the repo toward the `rust-starter` posture while staying diff-aware:
- preserve justified local carve-outs
- delete duplicated policy only after it has been re-homed into the manifest
- never paste the fresh template wholesale over a living repo
+- add or preserve project-local Cargo target-dir config under `/data/main/cargo-target/<project-slug>`
- add a hard source-file line cap without erasing stricter local limits or justified generated-code exemptions
## First Pass: Inventory The Existing Surfaces
@@ -18,6 +19,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`
+- `.cargo/config.toml` and any runner-side `--target-dir` usage
- `AGENTS.md` and any nested agent instruction files
- `check.py`, `xtask`, shell wrappers, `justfile`, or other runners
- CI workflow files
@@ -96,41 +98,65 @@ doctrine by entering the target repo, not only by invoking this bootstrap skill.
Add `rust-toolchain.toml` if missing. If present but floating, pin it.
-### 3. Install workspace lint tables
+### 3. Install project-local Cargo target config
+
+Add or merge a target repo `.cargo/config.toml`:
+
+```toml
+[build]
+target-dir = "/data/main/cargo-target/<project-slug>"
+```
+
+Use the target repo directory name as the default slug; append a short stable
+disambiguator if the basename would collide with another local repo. Preserve
+unrelated Cargo config if the file already exists.
+
+Do not mutate user-global Cargo config during retrofit. This is an incremental
+repo-local opt-in: repos without the file continue to inherit the developer's
+global default. Also do not encode target-dir through runner flags or CI. If a
+script currently passes `--target-dir` only to keep artifacts off the source
+disk, migrate that intent into `.cargo/config.toml` and remove the flag after
+the config is present.
+
+### 4. Install workspace lint tables
Move repo-wide policy into root `[workspace.lints.*]`.
-### 4. Make member crates inherit explicitly
+Preserve the starter profile's wildcard/glob carve-outs unless the target repo
+has a stronger explicit reason to ban them. Compact `*` imports are a house
+style affordance for token economy, not a smell to suppress globally.
+
+### 5. Make member crates inherit explicitly
Add `[lints] workspace = true` to every member crate.
-### 5. Re-home script flags into the manifest
+### 6. 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.
-### 6. Tighten local suppression discipline
+### 7. Tighten local suppression discipline
Prefer:
- `#[expect(..., reason = "...")]` for temporary or evidence-backed suppressions
- `#[allow(..., reason = "...")]` only for stable local policy
-### 7. Simplify the runner
+### 8. 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.
-### 8. Install the source-file cap
+### 9. 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.
+Default to `3000` 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.
-### 9. Add deep-gate posture if the repo is ready
+### 10. 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.
@@ -161,8 +187,10 @@ If the repo wants CI to detect canonicalization drift rather than rewriting file
- 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)
+- target `.cargo/config.toml` routes Cargo output to `/data/main/cargo-target/<project-slug>` without changing user-global Cargo config
- every member crate inherits that policy explicitly
- scripts and CI no longer restate Clippy allowlists
+- scripts, CI, and manifest-owned command vectors do not pass `--target-dir`
- manifest-owned canonicalization exists where the repo wants auto-fixes, instead of living in shell aliases or tribal memory
- valid repo-specific exceptions remain intact and justified
- stricter pre-existing rules remain stricter
diff --git a/docs/rust-linting-proposal.md b/docs/rust-linting-proposal.md
index 65f800f..ba5b5cf 100644
--- a/docs/rust-linting-proposal.md
+++ b/docs/rust-linting-proposal.md
@@ -13,8 +13,9 @@ The best current design is:
```
3. Keep the runner orchestration-only: source-file cap, `fmt --check`, `clippy`, tests, then optional deeper gates.
-4. Pin an exact stable toolchain so lint drift is a conscious upgrade event.
-5. Centralize repo-wide Clippy carve-outs and structural thresholds in the root manifest, and force local suppressions to carry reasons.
+4. Check in project-local Cargo target-dir config so opted-in repos build under `/data/main/cargo-target/<project-slug>`.
+5. Pin an exact stable toolchain so lint drift is a conscious upgrade event.
+6. Centralize repo-wide Clippy carve-outs and structural thresholds in the root manifest, and force local suppressions to carry reasons.
The local corpus already converges on this. The newer `adequate_*`, `memcp`, `outpost`, and `picmash` workspaces are structurally superior to the older `check.py` / shell-script pattern because they put policy in manifest tables instead of command-line tails.
@@ -73,6 +74,7 @@ Across the stricter workspaces, the same repo-wide Clippy exceptions keep reappe
- numeric pragmatism: `cast_*`, `float_cmp`, `implicit_hasher`
- blanket-annotation fatigue: `must_use_candidate`, `return_self_not_must_use`
- API-shape micro-optimizations: `needless_pass_by_value`, `trivially_copy_pass_by_ref`, `ref_option`, `unused_async`
+- token-economy imports: `wildcard_imports`, `enum_glob_use`, and rustc glob import/reexport lints
That is not random drift anymore. It is a de facto house profile and should be made explicit.
@@ -181,6 +183,22 @@ Implication:
- library-heavy repos should define `[workspace.lints.rustdoc]`
- the deeper check posture should include a docs build
+### 10. Cargo config is the right home for project-local target dirs
+
+Cargo supports `build.target-dir` in `.cargo/config.toml`, and command-line `--target-dir` overrides it. The clean starter posture is therefore a checked-in repo-local config:
+
+```toml
+[build]
+target-dir = "/data/main/cargo-target/<project-slug>"
+```
+
+Implication:
+
+- use `.cargo/config.toml` for repo-local target-dir policy
+- do not pass `--target-dir` from check runners, CI, or manifest-owned command vectors
+- do not mutate user-global Cargo config during bootstrap or retrofit
+- repos not yet retrofitted can continue to inherit the developer's global Cargo default
+
## Proposed Starter-Pack Design
### 1. Source-of-truth layout
@@ -206,6 +224,9 @@ unused_crate_dependencies = "warn"
unused_lifetimes = "deny"
unused_qualifications = "deny"
unused_results = "deny"
+ambiguous_glob_imports = "allow"
+ambiguous_glob_reexports = "allow"
+hidden_glob_reexports = "allow"
[workspace.lints.rustdoc]
broken_intra_doc_links = "deny"
@@ -229,6 +250,9 @@ missing_errors_doc = "allow"
missing_panics_doc = "allow"
multiple_crate_versions = "allow"
+enum_glob_use = "allow"
+wildcard_imports = "allow"
+
items_after_statements = "allow"
many_single_char_names = "allow"
match_same_arms = "allow"
@@ -269,9 +293,6 @@ clippy_command = [
"--workspace",
"--all-targets",
"--all-features",
- "--",
- "-D",
- "warnings",
]
test_command = ["cargo", "test", "--workspace", "--all-targets", "--all-features"]
doc_command = ["cargo", "doc", "--workspace", "--all-features", "--no-deps"]
@@ -318,7 +339,7 @@ Add the source-file cap alongside the command vectors:
```toml
[workspace.metadata.rust-starter.source_files]
-max_lines = 2500
+max_lines = 3000
include = ["*.rs", "**/*.rs"]
exclude = []
```
@@ -329,7 +350,28 @@ Why this belongs here:
- keeping the threshold in root metadata still makes the manifest the policy source of truth
- the runner can stay generic by enforcing a small schema instead of hard-coding repo-specific paths or numbers
-### 2. Toolchain posture
+### 2. Project-local Cargo target directory
+
+Check in `.cargo/config.toml`:
+
+```toml
+# Replace `rust-starter-template` with the target repository slug.
+# This is a repo-local ratchet only; do not mutate user-global Cargo config.
+
+[build]
+target-dir = "/data/main/cargo-target/rust-starter-template"
+```
+
+Use the repo directory basename as the default slug. If two local repos would
+collide, append a short stable disambiguator. The goal is to keep artifacts off
+the source disk without depending on wrappers or repeating `--target-dir` in
+every command.
+
+This is deliberately not a global Cargo-config migration. A repo opts in by
+checking in the file; otherwise the user's existing global Cargo default remains
+the fallback.
+
+### 3. Toolchain posture
Check in a `rust-toolchain.toml` like:
@@ -342,7 +384,7 @@ components = ["clippy", "rustfmt"]
Use an exact stable patch at scaffold time and bump it deliberately. Do not float on `"stable"` if the goal is reproducible strictness.
-### 3. Exception policy
+### 4. Exception policy
This is the center of gravity. If the exception policy is wrong, the rest becomes theater.
@@ -402,7 +444,7 @@ The starter baseline should cherry-pick only the restriction lints with durable
That is aggressive without becoming absurd.
-### 4. Fast gate versus deep gate
+### 5. Fast gate versus deep gate
#### Fast gate
@@ -410,7 +452,7 @@ This should be the canonical local verification gate:
1. enforce the source-file cap from `workspace.metadata.rust-starter.source_files`
2. `cargo fmt --all --check`
-3. `cargo clippy --workspace --all-targets --all-features -- -D warnings`
+3. `cargo clippy --workspace --all-targets --all-features`
4. `cargo test --workspace --all-targets --all-features`
This is the default industrial baseline.
@@ -438,7 +480,7 @@ Add a heavier gate for mature repos:
If the feature graph explodes, degrade to `--each-feature` or grouped feature subsets instead of abandoning feature-matrix coverage entirely.
-### 5. Strong optional strengthenings
+### 6. Strong optional strengthenings
#### Explicit `check-cfg` declarations
@@ -483,6 +525,12 @@ Run a scheduled CI job against the latest stable toolchain without updating the
That is the old pattern. It is operationally inferior to manifest-owned policy.
+### Passing `--target-dir` from runners or CI
+
+That is target-dir folklore, not policy. Put repo-local Cargo output routing in
+`.cargo/config.toml`; leave user-global Cargo config alone and keep command
+vectors portable.
+
### Treating `clippy::too_many_lines` as a file-size limit
That lint is about function length. It is not a substitute for a hard source-file cap, and pretending otherwise guarantees drift.
@@ -507,13 +555,13 @@ 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: 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.
+> 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); install project-local `.cargo/config.toml` with `[build] target-dir = "/data/main/cargo-target/<project-slug>"` without changing user-global Cargo config; 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.
## Bottom Line
-The starter pack should standardize the newer Cargo-centric pattern already emerging locally, harden it with toolchain pinning, distinguish manifest-owned policy from runner orchestration, export a first-class canonicalization pipeline, enforce a manifest-backed hard source-file cap, tighten suppression discipline with `reason = "..."`, and add an optional deeper gate for feature matrices, docs, dependency hygiene, and public API drift.
+The starter pack should standardize the newer Cargo-centric pattern already emerging locally, add repo-local Cargo target-dir config for `/data/main/cargo-target/<project-slug>`, harden it with toolchain pinning, distinguish manifest-owned policy from runner orchestration, export a first-class canonicalization pipeline, enforce a manifest-backed hard source-file cap, tighten suppression discipline with `reason = "..."`, and add an optional deeper gate for feature matrices, docs, dependency hygiene, and public API drift.
The single strongest improvement over the current local state is not any one lint. It is moving the center of gravity from bespoke scripts to manifest-owned policy.
@@ -523,6 +571,8 @@ Primary sources:
- Cargo manifest `lints` section: <https://doc.rust-lang.org/cargo/reference/manifest.html#the-lints-section>
- Cargo workspaces and inherited lint tables: <https://doc.rust-lang.org/cargo/reference/workspaces.html#the-lints-table>
+- Cargo configuration and `build.target-dir`: <https://doc.rust-lang.org/cargo/reference/config.html#buildtarget-dir>
+- Cargo build cache layout: <https://doc.rust-lang.org/cargo/reference/build-cache.html>
- `cargo fix`: <https://doc.rust-lang.org/cargo/commands/cargo-fix.html>
- Cargo’s unstable `[lints.cargo]` namespace: <https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#cargo-lints>
- Clippy overview and lint-group guidance: <https://doc.rust-lang.org/stable/clippy/>
diff --git a/docs/rust-style-doctrine.md b/docs/rust-style-doctrine.md
index 1a1ef20..c45874e 100644
--- a/docs/rust-style-doctrine.md
+++ b/docs/rust-style-doctrine.md
@@ -8,6 +8,6 @@ Make illegal states unrepresentable. Stringly closed worlds, ad-hoc tuples, bool
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.
+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. Wildcard imports are acceptable and often desirable when they make a dense local vocabulary cheap; real name-resolution ambiguity remains a compiler problem, but lint taste should not tax import sites for token economy. 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 a6d30d2..e29e1c6 100644
--- a/skills/rust-bootstrap/SKILL.md
+++ b/skills/rust-bootstrap/SKILL.md
@@ -24,7 +24,9 @@ Read:
Apply the template deliberately:
- replace placeholder members, names, and version/toolchain values
+- replace the placeholder Cargo target-dir slug in `.cargo/config.toml`
- keep repo-wide policy in root `Cargo.toml`
+- keep Cargo target-dir policy in project-local `.cargo/config.toml`, not runner flags
- 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
@@ -48,11 +50,13 @@ Retrofit is diff-aware ratchet work:
- 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
+- add or preserve project-local `.cargo/config.toml` for `/data/main/cargo-target/<project-slug>` without touching user-global Cargo config
## 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.
+- Install Cargo target-dir posture through target `.cargo/config.toml`; do not rely on wrappers or mutate global Cargo config.
- 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/template/fresh/.cargo/config.toml b/template/fresh/.cargo/config.toml
new file mode 100644
index 0000000..a6d7589
--- /dev/null
+++ b/template/fresh/.cargo/config.toml
@@ -0,0 +1,5 @@
+# Replace `rust-starter-template` with the target repository slug.
+# This is a repo-local ratchet only; do not mutate user-global Cargo config.
+
+[build]
+target-dir = "/data/main/cargo-target/rust-starter-template"
diff --git a/template/fresh/Cargo.toml b/template/fresh/Cargo.toml
index 41a5c1a..ee35453 100644
--- a/template/fresh/Cargo.toml
+++ b/template/fresh/Cargo.toml
@@ -19,6 +19,9 @@ unused_crate_dependencies = "warn"
unused_lifetimes = "deny"
unused_qualifications = "deny"
unused_results = "deny"
+ambiguous_glob_imports = "allow"
+ambiguous_glob_reexports = "allow"
+hidden_glob_reexports = "allow"
[workspace.lints.rustdoc]
bare_urls = "deny"
@@ -42,6 +45,9 @@ missing_errors_doc = "allow"
missing_panics_doc = "allow"
multiple_crate_versions = "allow"
+enum_glob_use = "allow"
+wildcard_imports = "allow"
+
items_after_statements = "allow"
many_single_char_names = "allow"
match_same_arms = "allow"
@@ -111,6 +117,6 @@ canonicalize_commands = [
]
[workspace.metadata.rust-starter.source_files]
-max_lines = 2500
+max_lines = 3000
include = ["*.rs", "**/*.rs"]
exclude = []
diff --git a/template/fresh/check.py b/template/fresh/check.py
index 424497e..2ae2acd 100644
--- a/template/fresh/check.py
+++ b/template/fresh/check.py
@@ -12,7 +12,7 @@ from pathlib import PurePosixPath
ROOT = Path(__file__).resolve().parent
WORKSPACE_MANIFEST = ROOT / "Cargo.toml"
-DEFAULT_MAX_SOURCE_FILE_LINES = 2500
+DEFAULT_MAX_SOURCE_FILE_LINES = 3000
DEFAULT_SOURCE_FILE_INCLUDE = ("*.rs", "**/*.rs")
IGNORED_SOURCE_DIRS = frozenset(
{".direnv", ".git", ".hg", ".jj", ".svn", "__pycache__", "node_modules", "target", "vendor"}