swarm repositories / source
aboutsummaryrefslogtreecommitdiff
path: root/docs/bootstrap-fresh.md
blob: b3c911210a7ee260cb46b204a83e8553b9afab35 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
# Fresh Bootstrap

Use this surface when the target repo is blank or when you are setting up Rust linting from scratch.

## Goal

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
- 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

## Inputs To Set Deliberately

Before copying the template, decide:

- actual workspace members
- package naming
- 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 `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

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)
- [template/fresh/check.py](/home/main/programming/projects/rust_starter/template/fresh/check.py)
- [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.

## Sequence

### 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:

- workspace member list
- package metadata
- pinned `rust-version`
- repo-wide Clippy carve-outs

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

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.

### 5. Make every crate inherit lint policy

Each member crate must contain:

```toml
[lints]
workspace = true
```

Do not rely on memory or convention here; add it explicitly.

### 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`.

### 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.

Default runner shape:

- `check`: enforce the file cap, run canonicalization, then verify formatting, lint, and tests
- `verify`: enforce the file cap without mutating files; this is the non-writing CI-friendly path
- `deep`: `check` plus docs
- `fix` / `canon`: canonicalization only

If the target repo already prefers another orchestration surface, keep that surface only if it remains policy-thin:

- okay: `xtask`, `just`, shell wrapper, CI job that calls the canonical commands
- not okay: restating dozens of `-A` and `-D` flags in scripts

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

The template only installs the fast gate. Add the deeper posture when the repo is mature enough:

- `cargo hack clippy --workspace --all-targets --feature-powerset`
- `cargo hack test --workspace --feature-powerset`
- `cargo doc --workspace --all-features --no-deps`
- `cargo deny check`
- optionally `cargo nextest` and `cargo semver-checks`

## Do Not Do These

- do not use `--no-deps` as the workspace-wide Clippy default
- 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
- each member crate opts into `[lints] workspace = true`
- `rust-toolchain.toml` pins an exact stable patch and includes `clippy` plus `rustfmt`
- `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.