swarm repositories / source
aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormain <main@swarm.moe>2026-06-14 23:49:59 -0400
committermain <main@swarm.moe>2026-06-14 23:49:59 -0400
commitf9f897b32cad3bf10fcc06774887254922eaea74 (patch)
treef90d4800c379a6c20371a05d550c6439c3984df2
parent4735637ead09c4e8d4b9a0409d7ea2538eb9cb40 (diff)
downloadrust_starter-f9f897b32cad3bf10fcc06774887254922eaea74.zip
Scrub hardcoded Rust toolchain defaultsHEADmain
Teach rust-bootstrap to use the latest system Rust toolchain, derive rust-version only from active rustc when needed, and initialize Git before applying the fresh template in an empty directory.
-rw-r--r--AGENTS.md2
-rw-r--r--docs/bootstrap-fresh.md49
-rw-r--r--docs/bootstrap-retrofit.md13
-rw-r--r--docs/rust-linting-proposal.md40
-rw-r--r--skills/rust-bootstrap/SKILL.md9
-rw-r--r--template/fresh/Cargo.toml5
-rw-r--r--template/fresh/crates/app/Cargo.toml1
-rw-r--r--template/fresh/rust-toolchain.toml5
8 files changed, 84 insertions, 40 deletions
diff --git a/AGENTS.md b/AGENTS.md
index f758059..8075028 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -15,7 +15,7 @@ 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`.
+- Use the latest system Rust toolchain; do not copy a hardcoded Rust version from this starter.
- 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.
diff --git a/docs/bootstrap-fresh.md b/docs/bootstrap-fresh.md
index b3c9112..2db3ccc 100644
--- a/docs/bootstrap-fresh.md
+++ b/docs/bootstrap-fresh.md
@@ -9,7 +9,7 @@ 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
+- the latest system Rust toolchain is used instead of a hardcoded starter version
- 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
@@ -21,8 +21,8 @@ Before copying the template, decide:
- actual workspace members
- package naming
- license policy
-- exact pinned stable toolchain
-- actual MSRV / `rust-version`
+- active system Rust toolchain from `rustc --version` and `cargo --version`
+- whether the target should record a `rust-version`; if so, derive it from the active system `rustc`
- 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
@@ -44,11 +44,17 @@ 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, Cargo target-dir slug, and version/toolchain values.
+Do not copy them mechanically. Replace the placeholder members, names, license, and Cargo target-dir slug. Do not copy a Rust version from the starter; inspect the active system toolchain.
## Sequence
-### 1. Seed `AGENTS.md` first
+### 1. Initialize Git for an empty target
+
+If the target directory is empty and is not already inside a Git worktree, run
+`git init` before copying template files. The starter assumes normal versioned
+Rust work; beginning from an unversioned empty directory is gratuitous entropy.
+
+### 2. Seed `AGENTS.md`
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).
@@ -59,22 +65,25 @@ 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
+### 3. Write the root manifest
Start from the template root manifest and adapt:
- workspace member list
- package metadata
-- pinned `rust-version`
- repo-wide Clippy carve-outs
+If the target records `workspace.package.rust-version`, derive it from the
+active system `rustc --version`; do not invent a minimum supported Rust version
+from memory and do not paste one from this starter.
+
Keep the command vectors in `[workspace.metadata.rust-starter]` even if you later wrap them with a different local runner.
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 `3000`-line limit across `*.rs` files. Tighten it if the repo already has sharper discipline.
-### 3. Install project-local Cargo target config
+### 4. Install project-local Cargo target config
Create or adapt the target repo's `.cargo/config.toml` before running Cargo commands:
@@ -96,11 +105,18 @@ remains the fallback.
If `.cargo/config.toml` already exists, merge the `[build] target-dir` value
without overwriting unrelated Cargo configuration.
-### 4. Pin the toolchain
+### 5. Use the latest system Rust toolchain
+
+Inspect `rustc --version` and `cargo --version` early, before deciding whether a
+lint is noisy or broken. Lint output is part of the toolchain contract, and the
+contract here is the latest Rust toolchain already selected by the system.
-Write `rust-toolchain.toml` early, before deciding whether a lint is noisy or broken. Lint output is part of the toolchain contract.
+The template `rust-toolchain.toml` deliberately avoids a numbered channel. Do
+not replace it with a remembered version. If the target repo needs a rustup
+override, use the active system toolchain; if the target environment does not
+use rustup, omit the file rather than fabricating a pin.
-### 5. Make every crate inherit lint policy
+### 6. Make every crate inherit lint policy
Each member crate must contain:
@@ -111,13 +127,13 @@ workspace = true
Do not rely on memory or convention here; add it explicitly.
-### 6. Add `clippy.toml` only if it carries real configuration
+### 7. 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`.
-### 7. Add a thin runner
+### 8. 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.
@@ -135,7 +151,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.
-### 8. Keep the deep gate opt-in
+### 9. Keep the deep gate opt-in
The template only installs the fast gate. Add the deeper posture when the repo is mature enough:
@@ -153,20 +169,21 @@ The template only installs the fast gate. Add the deeper posture when the repo i
- 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
+- do not hardcode a Rust version from the starter or from memory
## 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>"`
+- fresh bootstraps in an empty target directory start with `git init`
- 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
- each member crate opts into `[lints] workspace = true`
-- `rust-toolchain.toml` pins an exact stable patch and includes `clippy` plus `rustfmt`
+- the target uses the latest system Rust toolchain; any `rust-version` value is derived from the active system `rustc`
- `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
diff --git a/docs/bootstrap-retrofit.md b/docs/bootstrap-retrofit.md
index c099e5f..f9cc38c 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
+- move stale hardcoded Rust versions toward the latest system toolchain unless an explicit external MSRV constraint forbids it
- 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
@@ -26,6 +27,7 @@ Before editing, inspect all of the places the repo may already encode lint polic
- any existing auto-fix or canonicalization commands
- `clippy.toml`
- `rust-toolchain.toml`
+- active `rustc --version` and `cargo --version`
- editor settings
- existing oversized source files, checked-in generated code, and any current file-length checks
@@ -94,9 +96,15 @@ 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
+### 2. Use the latest system Rust toolchain
-Add `rust-toolchain.toml` if missing. If present but floating, pin it.
+Inspect the active system `rustc --version` and `cargo --version`. Do not paste
+a Rust version from this starter and do not preserve a stale numeric toolchain
+pin unless the target repo has an explicit external MSRV or compatibility
+constraint.
+
+If the target records `rust-version`, derive it from the active system `rustc`
+unless that explicit constraint says otherwise.
### 3. Install project-local Cargo target config
@@ -191,6 +199,7 @@ If the repo wants CI to detect canonicalization drift rather than rewriting file
- 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`
+- the target uses the latest system Rust toolchain unless an explicit external MSRV or compatibility constraint says otherwise
- 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 ba5b5cf..64c90fa 100644
--- a/docs/rust-linting-proposal.md
+++ b/docs/rust-linting-proposal.md
@@ -14,7 +14,7 @@ The best current design is:
3. Keep the runner orchestration-only: source-file cap, `fmt --check`, `clippy`, tests, then optional deeper gates.
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.
+5. Use the latest system Rust toolchain; never copy a hardcoded Rust version from the starter.
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.
@@ -146,24 +146,26 @@ Clippy’s usage docs are explicit here: `--no-deps` is for linting only a selec
That is useful for a narrow crate-local loop, but it is the wrong default for a workspace-wide industrial gate. The starter profile should lint the whole workspace, not silently skip member crates that happen to be path dependencies.
-### 6. `rust-version` is part of lint policy
+### 6. `rust-version` must come from the system toolchain, not the template
Clippy uses the crate’s MSRV configuration, and the docs note that it defaults to the `rust-version` field in `Cargo.toml`.
Implication:
-- every starter-pack workspace should set `rust-version`
-- the field should reflect the actual supported minimum, not a decorative guess
+- if a starter-pack workspace sets `rust-version`, derive it from the active system `rustc --version`
+- do not preserve a hardcoded Rust version in the starter template
+- do not invent an MSRV unless the target repo has an explicit external compatibility constraint
-### 7. Pinned toolchains are part of the enforcement story
+### 7. The latest system toolchain is part of the enforcement story
The rustup toolchain file supports exact channels, components, profile, and targets. For strict linting, that matters because Clippy output changes over time.
Implication:
-- pin an exact stable patch release in `rust-toolchain.toml`
-- include `clippy` and `rustfmt`
-- prefer `profile = "minimal"` unless the repo has a real reason not to
+- inspect `rustc --version` and `cargo --version` during bootstrap and retrofit
+- use the latest toolchain already selected by the system
+- include `clippy` and `rustfmt` when a rustup-managed target writes `rust-toolchain.toml`
+- do not encode a stale numeric toolchain in the starter template
### 8. `unexpected_cfgs` plus `check-cfg` is one of the highest-value newer strengthenings
@@ -212,7 +214,6 @@ resolver = "3"
[workspace.package]
edition = "2024"
-rust-version = "1.xx"
version = "0.1.0"
[workspace.lints.rust]
@@ -377,12 +378,16 @@ Check in a `rust-toolchain.toml` like:
```toml
[toolchain]
-channel = "1.xx.0"
+channel = "stable"
profile = "minimal"
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.
+Use the latest system Rust toolchain. The template deliberately avoids a
+numbered channel because stale examples become silent policy. If the target
+repo records `rust-version`, derive it from the active system `rustc --version`;
+if the target environment does not use rustup, omit `rust-toolchain.toml` rather
+than fabricating a pin.
### 4. Exception policy
@@ -517,7 +522,9 @@ If the repo publishes libraries, add `cargo semver-checks` to the deeper release
#### Periodic canary job
-Run a scheduled CI job against the latest stable toolchain without updating the pinned toolchain file. Let it warn, not block merges. That gives early visibility into upcoming Clippy churn while preserving deterministic mainline CI.
+Run a scheduled CI job after system toolchain updates. Let it warn, not block
+merges. That gives early visibility into upcoming Clippy churn without
+tempting the starter to carry a stale Rust version.
## Choices I Reject
@@ -547,21 +554,22 @@ It is useful as a canary or opt-in experiment, not as the default industrial pro
Not until Cargo’s own lint namespace stabilizes.
-### Floating toolchains in strict CI
+### Copying a hardcoded Rust version from the starter
-If the goal is "force industrial-grade linting", ambient toolchain drift is the enemy.
+If the goal is "force industrial-grade linting", a stale template version is
+the enemy. Inspect the active system toolchain and use that.
## Proposed AGENTS.md One-Liner
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); 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.
+> 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); run `git init` first when bootstrapping an empty target directory; use the latest system Rust toolchain and never copy a hardcoded Rust version from the starter; install project-local `.cargo/config.toml` with `[build] target-dir = "/data/main/cargo-target/<project-slug>"` without changing user-global Cargo config; 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, 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 starter pack should standardize the newer Cargo-centric pattern already emerging locally, initialize Git for empty fresh targets, use the latest system Rust toolchain instead of stale template versions, add repo-local Cargo target-dir config for `/data/main/cargo-target/<project-slug>`, 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.
diff --git a/skills/rust-bootstrap/SKILL.md b/skills/rust-bootstrap/SKILL.md
index e29e1c6..a77c7ce 100644
--- a/skills/rust-bootstrap/SKILL.md
+++ b/skills/rust-bootstrap/SKILL.md
@@ -15,6 +15,9 @@ Then choose exactly one surface.
Use this when the target repo is blank or when you are setting up Rust linting from scratch.
+If the target directory is empty and is not already inside a Git worktree, run
+`git init` before applying the template.
+
Read:
- [docs/bootstrap-fresh.md](/home/main/programming/projects/rust_starter/docs/bootstrap-fresh.md)
@@ -23,8 +26,10 @@ Read:
Apply the template deliberately:
-- replace placeholder members, names, and version/toolchain values
+- replace placeholder members and names
- replace the placeholder Cargo target-dir slug in `.cargo/config.toml`
+- use the latest system Rust toolchain; never choose or copy a hardcoded Rust version from the starter
+- if the target records `rust-version`, derive it from the active system `rustc --version`
- 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
@@ -47,6 +52,7 @@ Retrofit is diff-aware ratchet work:
- do not paste the fresh template wholesale
- preserve stricter local policy
- preserve justified local exceptions
+- use the latest system Rust toolchain unless the target repo has an explicit external MSRV constraint
- 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
@@ -55,6 +61,7 @@ Retrofit is diff-aware ratchet work:
## Guardrails
- Re-open the repo docs when details matter; do not rely on memory.
+- Never infer a Rust version from these docs or templates; inspect the active system toolchain.
- 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.
diff --git a/template/fresh/Cargo.toml b/template/fresh/Cargo.toml
index ee35453..57d0dd9 100644
--- a/template/fresh/Cargo.toml
+++ b/template/fresh/Cargo.toml
@@ -1,4 +1,6 @@
-# Replace the member list, package metadata, and toolchain/MSRV values deliberately.
+# Replace the member list and package metadata deliberately.
+# If the target records `rust-version`, derive it from the latest system
+# `rustc --version`; do not copy a Rust version from this template.
[workspace]
members = ["crates/app"]
@@ -7,7 +9,6 @@ resolver = "3"
[workspace.package]
edition = "2024"
license = "MIT"
-rust-version = "1.90"
version = "0.1.0"
[workspace.lints.rust]
diff --git a/template/fresh/crates/app/Cargo.toml b/template/fresh/crates/app/Cargo.toml
index ce1808a..51c7dac 100644
--- a/template/fresh/crates/app/Cargo.toml
+++ b/template/fresh/crates/app/Cargo.toml
@@ -2,7 +2,6 @@
name = "app"
edition.workspace = true
license.workspace = true
-rust-version.workspace = true
version.workspace = true
[lints]
diff --git a/template/fresh/rust-toolchain.toml b/template/fresh/rust-toolchain.toml
index 66f329f..52f2d51 100644
--- a/template/fresh/rust-toolchain.toml
+++ b/template/fresh/rust-toolchain.toml
@@ -1,4 +1,7 @@
+# Non-versioned on purpose: use the active system rustup channel, not a stale
+# Rust version copied from this starter.
+
[toolchain]
-channel = "1.90.0"
+channel = "stable"
profile = "minimal"
components = ["clippy", "rustfmt"]