Define Rust environment and toolchain

This commit is contained in:
2026-10-18 21:42:33 +03:00
parent 7b475bfcc8
commit c2b899dd1e
15 changed files with 2058 additions and 9 deletions
+218 -8
View File
@@ -4,7 +4,7 @@
This is the living execution plan for WireGuard Admin version 1. It records milestone scope, progress, review findings, and evidence so a new agent can resume from repository files without relying on chat history.
Read [AGENTS.md](AGENTS.md), [the specification](docs/SPEC.md), [architectural decisions](docs/adr/), [implementation order](docs/IMPLEMENTATION.md), and [the glossary](CONTEXT.md) before execution. The specification defines behavior; this plan schedules its delivery. Approved dependencies and Alpine/VM testing rules are in AGENTS.md. Do not change requirements to make a milestone pass.
Read [AGENTS.md](AGENTS.md), [the specification](docs/SPEC.md), [architectural decisions](docs/adr/), [implementation order](docs/IMPLEMENTATION.md), and [the glossary](CONTEXT.md) before execution. The specification defines behavior; this plan schedules its delivery. Approved dependencies are in [DEPENDENCIES.md](docs/DEPENDENCIES.md); Alpine/VM testing rules are in [TESTING.md](docs/TESTING.md). Do not change requirements to make a milestone pass.
Creating this plan does not start implementation or change the active model. All milestones below are initially pending, and no validation results are claimed.
@@ -110,7 +110,7 @@ Each row is a delivery milestone, not a completion claim. Expand its record befo
| ID | Milestone | Prerequisites | State |
| --- | -------------------------------------------------------- | ----------------------------------------- | ------- |
| 1 | Rust foundation, settings, and domain states | None | pending |
| 1 | Rust foundation, settings, and domain states | None | accepted |
| 2 | Server configuration editing with byte preservation | 1 | pending |
| 3 | Client keys, encrypted vault, and existing-client import | 2 | pending |
| 4 | Backups, safe Commit, and full restoration | 3 | pending |
@@ -122,9 +122,218 @@ Each row is a delivery milestone, not a completion claim. Expand its record befo
### Milestone 1 — Rust foundation, settings, and domain states
Create one Cargo package with thin startup/library separation, reproducible lockfile, validated TOML settings, executable-relative paths, public-key identities, and explicit draft/saved/applied states. Implement dual-stack first-free allocation and deferred address release. Provide help/version without root or vault access; management startup requires root. Do not create a nonfunctional full module tree.
Status: accepted (2026-10-18T18:59:35Z; independent R2 re-review and coordinator gates passed).
Prerequisites: no previous milestone; verified GPT-6-Sol/medium coordinator and
GPT-6-Luna/high workers, the pinned native Rust environment, and registry access
or cached approved dependencies. Docker, root, a running VPN, and musl linking
are not required for this milestone.
Acceptance: settings and allocation tests cover invalid input, exhaustion, IPv4-only existing clients, and reserved deleted addresses; path resolution does not depend on the working directory. Build, default tests, formatting, and Clippy pass without touching live services.
#### Outcome and scope
Deliver a compilable single-package foundation that can read validated settings
relative to the executable, represent client identities and draft/saved/applied
states, and allocate IPv4/IPv6 addresses without touching a real server.
Startup supports `--help` and `--version` without root, settings, or vault access.
Management startup checks root before attempting privileged operations.
This is a foundation, not a working VPN manager. Until later milestones wire in
the TUI, management startup must explain that the management interface is not
implemented and exit nonzero without reading a real server config or changing
anything. Do not display a successful management session for a placeholder.
Read SPEC.md sections Purpose, Data locations, Data sources, New client parameters,
and Operations and states; all three ADRs; and docs/ENVIRONMENT.md,
docs/PROJECT_LAYOUT.md, docs/DEPENDENCIES.md, and docs/DEVELOPMENT.md.
No WireGuard document edits, key generation, vault/import, backups/Commit writes,
systemd/runtime adapters, QR, TUI, or container infrastructure are implemented here.
#### Context and implementation steps
At preparation, the repository contained design/Codex documents and
rust-toolchain.toml, but no Cargo.toml, Cargo.lock, or source tree. The
toolchain pin is 1.97.1 and the created manifest uses edition 2024. Local
system tools match; rustup is absent.
Musl standard library/linker readiness remains deferred to milestone 8.
Execute the tasks below sequentially with one implementation writer. For each
task dispatch, the coordinator supplies exact document sections and the interface
contract established by the prior task. Workers do not edit PLANS.md or accept work.
| Task | Owner | Files and deliverable |
| ---- | --------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| M1.1 | implementer | Cargo.toml, Cargo.lock, src/main.rs, src/lib.rs, narrow startup/error modules as needed, README.md and .gitignore: package scaffolding, arguments, root boundary, safe incomplete-management behavior |
| M1.2 | implementer | src/config.rs, config/wireguard-admin.example.toml, settings tests: typed settings, validation, and executable-relative paths |
| M1.3 | implementer | src/domain.rs and child modules only if needed, domain tests: public-key identity, change states, address allocation and reservation rules |
| M1.4 | reviewer, then repairer as needed | Independently inspect the integrated M1 changes and acceptance evidence; coordinator assigns bounded repair files and finding IDs |
| M1.5 | coordinator | Run integrated gates, update outdated scaffolding statements, record evidence and acceptance in this plan |
M1.1 creates package `wireguard-admin`, binary `wireguard-admin`, library
`wireguard_admin`, edition 2024, and rust-version 1.97.1. Keep main thin, parse
only the small agreed argument surface with std, and test the effective-UID
boundary through an injectable/pure decision rather than requiring root tests.
Unknown arguments fail clearly. Preserve existing documentation/configuration.
Add narrow ignores for local deployment data without hiding config examples or
synthetic fixtures. Do not create placeholder files for all future modules.
M1.2 uses TOML with explicit required fields for interface name, server config
path, client source directory, server endpoint, IPv4 and IPv6 allocation ranges,
DNS addresses, systemd unit, and nonzero restart timeout. Data root is optional
and defaults to executable-directory/Backup with data and archives beneath it.
Choose and document a fixed settings filename alongside the executable; do not
add a new CLI settings override. Resolve relative configured paths consistently
against that directory, never the process working directory. Separate parsing,
validation, and resolution so tests do not read the host environment. Do not
require referenced production files or systemd to exist to validate settings.
Validate address families, ranges, endpoint syntax, usable service/interface
names, DNS values, and timeout. Do not resolve DNS over the network in a settings
test. Endpoint validation must support a hostname or IP with a port and bracketed
IPv6. Document the resulting settings schema in the example and README.
M1.3 represents a public key as a validated 32-byte identity with standard
WireGuard Base64 parsing; duplicate aliases remain valid. Keep applied snapshots
separate from saved and draft state. Model unavailable runtime state explicitly.
Pass existing/server/reserved addresses as inputs; do not query real interfaces.
Deletion from draft alone must not reserve an address as if saved; committed
removal retains the address until an explicit successful-apply transition.
Discarded drafts restore saved allocation availability. This milestone tests
these transitions as pure model behavior, not an actual Commit implementation.
Allocate the first usable free address with bounded work proportional to the
occupied set, not subnet size. Exclude supplied server/occupied/reserved addresses
and IPv4 network/broadcast addresses where applicable. Handle /31, /32 and narrow
IPv6 ranges explicitly, avoid arithmetic overflow, and return clear exhaustion
errors. Manual addresses must match the configured family/range and be available.
Do not silently add IPv6 to imported IPv4-only model records.
Approved direct dependencies for this milestone: serde (derive), toml, thiserror,
ipnet, time when timestamps are needed, base64 for public-key representations,
and rustix for the effective-UID query. Use tempfile as a dev-dependency for
filesystem/subprocess fixtures if needed. Select compatible versions/features;
no unapproved crate or premature crypto/TUI/container dependency. Generate the
initial Cargo.lock once dependency choices are resolved; then use --locked.
#### Acceptance and validation
- [x] M1-A1: package/library/binary compile under the pinned native toolchain;
Cargo.lock is tracked and no unrelated dependency or file scaffolding is added.
- [x] M1-A2: help/version work without root or settings, unknown arguments fail,
and management startup rejects non-root before privileged access. Root-path
behavior is covered by injection, without running the application as root.
- [x] M1-A3: valid TOML yields typed settings; missing/invalid fields produce
actionable errors without opening a real server config, vault, or service.
- [x] M1-A4: executable-relative paths and defaults remain identical from two
different working directories; test via pure path inputs or subprocesses,
not parallel process-wide current-directory mutation.
- [x] M1-A5: valid/invalid public keys, repeated aliases, explicit unknown runtime
state, draft discard, and saved/applied divergence have behavioral coverage.
- [x] M1-A6: IPv4/IPv6 first-free selection, manual selection, occupied/server
exclusions, tiny ranges, exhaustion, and deferred release are verified. A large
IPv6 range test demonstrates that allocation does not scan the entire subnet.
- [x] M1-A7: all standard gates pass without root/Docker/production access;
a fresh independent reviewer has no unresolved actionable findings.
- [x] M1-A8: README describes the limited executable and setup honestly; commands,
example settings, and source paths match actual implementation. Update the
design-only statement in AGENTS.md when source scaffolding really exists.
Planned commands from the repository root after Cargo.toml and lockfile exist:
```sh
cargo metadata --locked --no-deps --format-version 1
cargo fmt --all -- --check
cargo clippy --locked --all-targets -- -D warnings
cargo test --locked
cargo build --locked --release
./target/release/wireguard-admin --help
./target/release/wireguard-admin --version
```
Expected: zero exits for these commands, successful help/version without settings,
and all ordinary tests pass as an unprivileged user. Argument/root rejection and
working-directory independence are exercised by tests. Record actual focused test
commands when test names exist. Do not execute a bare management launch as root.
No Alpine build, container tunnel, or VM/systemd check is claimed by M1 acceptance.
#### Progress
- [x] Preparation: toolchain configuration and environment observations recorded;
this is not application implementation or milestone acceptance.
- [x] M1.1 — implementer (`/root/implementer_m1_1`), 2026-10-18T18:47:43Z; package and startup boundary integrated.
- [x] M1.2 — implementer (`/root/implementer_m1_2`), 2026-10-18T18:50:19Z; typed settings, validation, paths, example, and tests integrated.
- [x] M1.3 — implementer (`/root/implementer_m1_3`), 2026-10-18T18:54:21Z; domain model, allocation, and tests integrated.
- [x] M1.4 — fresh reviewer (`/root/reviewer_m1_r1`) R1 and R2, repairer (`/root/repairer_m1_r1`) for domain finding; all findings closed 2026-10-18T18:59:35Z.
- [x] M1.5 — coordinator integrated validation and acceptance completed 2026-10-18T18:59:35Z.
#### Review and repair
| Finding | Iteration | Location and impact | Owner | Resolution and evidence | State |
| --- | --- | --- | --- | --- | --- |
| M1-R1-01 | R1/R2 | `src/domain.rs` constructor can claim verified without a matching applied snapshot; misleading state | repairer | constructor rejects inconsistent Verified; Commit/mismatch demote stale Verified; 13 focused, 22 total tests passed; R2 confirmed | closed |
| M1-R1-02 | R1/R2 | `AGENTS.md` still claims no Rust application exists | coordinator | opening statement updated to limited scaffold; R2 confirmed | closed |
| M1-R1-03 | R1/R2 | `Cargo.lock` existed outside Git index | coordinator | `git add -N Cargo.lock`; `git ls-files --error-unmatch Cargo.lock` succeeds; R2 confirmed; no commit/content staging | closed |
#### Evidence and handoff
Preparation verified local rustc/Cargo 1.97.1, formatter and Clippy availability;
rustup/musl readiness limitations are in docs/ENVIRONMENT.md. This execution
verified the active coordinator turn as `gpt-6-sol`/`medium` from session
turn context; project agent files and `[agents]` defaults specify
`gpt-6-luna`/`high`. The repository had no Cargo manifest/source and a clean
worktree at 2026-10-18T18:45:43Z. Current rustc/Cargo are 1.97.1, with
rustfmt 1.9.0 and Clippy 0.1.97. No prior milestone exists.
M1.1 added `Cargo.toml`, `Cargo.lock`, `src/{main,lib,startup}.rs`, and updated
README/.gitignore. The coordinator inspected those files and the working tree.
The worker reported passing locked metadata, fmt, Clippy, four startup tests,
release build, release help/version, and diff check; integrated M1 gates remain
pending. Cargo registry search failed, but approved `rustix` 1.1.5 resolved
from local cache.
M1.2 added `src/config.rs`, the example settings TOML, approved
`serde`/`toml`/`thiserror`/`ipnet` dependencies, and README settings guidance.
The coordinator inspected the files. The worker reported five focused settings
tests and nine total tests passing, along with locked metadata, fmt, Clippy,
release build, and diff check. Cargo resolution required an approved
network-enabled retry after sandbox DNS failure. Independent review remains
pending. M1.3 added `src/domain.rs`, its library declaration, and approved
`base64` dependency. The coordinator inspected the files. The worker reported
12 focused domain tests, 21 total tests, locked metadata, fmt, Clippy, and
release build passing. The three implementer turns were independently verified
from their session turn contexts as `gpt-6-luna`/`high`. Next: fresh review of
the integrated milestone.
R1 reviewer turn context was also verified as `gpt-6-luna`/`high`. R1 ran
locked metadata, fmt, Clippy, 21 tests, release build, and help/version; all
passed. It reported findings M1-R1-01 through M1-R1-03 above. No production,
container, VM, or root management launch was used.
Repairer turn context was verified as `gpt-6-luna`/`high`. Its domain repair
passed 13 focused tests, 22 total tests, fmt, Clippy, and release build.
The coordinator updated AGENTS.md and marked Cargo.lock intent-to-add in the
Git index after a sandbox write denial and approved escalation. `git ls-files`
now recognizes it; no Git commit was created. R2 re-review closed all three findings with no new
actionable issues. Its turn context was verified as `gpt-6-luna`/`high`.
Coordinator integrated gates on 2026-10-18: `cargo metadata --locked
--no-deps --format-version 1`, `cargo fmt --all -- --check`, `cargo clippy
--locked --all-targets -- -D warnings`, `cargo test --locked` (22 passed),
`cargo build --locked --release`, release `--help`, release `--version`, and
`git diff --check` all exited 0. Unknown argument and a bare management launch
as UID 1000 exited 2 with clear diagnostics, as expected. `git ls-files
--error-unmatch Cargo.lock` exited 0; the file is intent-to-add in the Git
index and its contents are not staged or committed. Unit/fixture evidence only;
Alpine WireGuard and disposable systemd VM checks are later milestones and
were not run. No production configuration, key, service, or VPN was accessed.
#### Decisions and discoveries
Use the already installed native compiler release as the reproducible baseline,
not an unpinned stable channel. The toolchain file is consumed by rustup proxies;
the current system-packaged binaries require explicit version checks. This is an
environment constraint, not permission to install packages or alter global tools.
#### Outcome
Accepted 2026-10-18T18:59:35Z after independent review and integrated gates.
The executable currently exposes help/version and safe startup errors; settings
and domain operations are library logic. Management/TUI behavior remains for
later milestones. Stop here; next milestone is 2 and has not started.
### Milestone 2 — Server configuration editing with byte preservation
@@ -176,10 +385,11 @@ Acceptance: real D-Bus job handling, separate restart verification, address rele
## Current progress and resume point
- All milestones are pending; application implementation has not started.
- The approved dependency list and container testing methodology are recorded in AGENTS.md.
- Next action when execution is requested: verify the coordinator model/effort, inspect the repository, expand milestone 1, and dispatch its first bounded worker task.
- No workers have been dispatched by creation of this document; no build, container, or VM results are claimed.
- Milestone 1 is accepted; milestones 2–9 remain pending.
- The approved dependency list is in [DEPENDENCIES.md](docs/DEPENDENCIES.md); container testing methodology is in [TESTING.md](docs/TESTING.md).
- Milestone 1 is expanded and the Rust environment is pinned.
- Next action, only on a later request: prepare Milestone 2; no work on it has started.
- M1 integrated gates and independent re-review passed. No container or VM results are claimed.
## Plan maintenance