Add runtime observation and systemd restart adapter
This commit is contained in:
@@ -114,7 +114,7 @@ Each row is a delivery milestone, not a completion claim. Expand its record befo
|
||||
| 2 | Server configuration editing with byte preservation | 1 | accepted |
|
||||
| 3 | Client keys, encrypted vault, and existing-client import | 2 | accepted |
|
||||
| 4 | Backups, safe Commit, and full restoration | 3 | accepted |
|
||||
| 5 | Runtime observation and systemd restart adapter | 4 | pending |
|
||||
| 5 | Runtime observation and systemd restart adapter | 4 | blocked |
|
||||
| 6 | Client configuration delivery and reissue lifecycle | 5 | pending |
|
||||
| 7 | Complete terminal management workflow | 6 | pending |
|
||||
| 8 | Alpine Testcontainers integration | 7; suitable disposable Docker environment | pending |
|
||||
@@ -1391,9 +1391,435 @@ no Git commit, deployment or production access occurred.
|
||||
|
||||
### Milestone 5 — Runtime observation and systemd restart adapter
|
||||
|
||||
Implement `wireguard-uapi` runtime queries and the `zbus` systemd adapter behind narrow interfaces. Track service job completion and timeout, then verify interface/client correspondence before recording applied state and releasing addresses. Require backup before restart.
|
||||
Status: accepted (2026-10-20T22:59:39+03:00; scoped fixture acceptance and independent integrated re-review complete).
|
||||
Prerequisites: milestones 1–4 accepted; pinned native Rust environment and
|
||||
compatible approved `rustix` and `zbus` dependencies. Ordinary
|
||||
M5 acceptance uses injected adapters and temporary saved stores without root or
|
||||
host-service/network access. Real WireGuard and systemd acceptance stays assigned
|
||||
to milestones 8 and 9 respectively, not silently waived.
|
||||
|
||||
Acceptance: ordinary tests exercise successful and failed jobs, missing/mismatched interfaces, unavailable statistics, and no automatic rollback using controlled adapters. Real runtime/systemd acceptance remains explicitly pending until milestones 8 and 9; mocks cannot close those later gates.
|
||||
#### Outcome and scope
|
||||
|
||||
Deliver a read-only Linux WireGuard runtime adapter, a systemd D-Bus restart
|
||||
adapter, and application orchestration for an explicitly confirmed restart:
|
||||
complete backup, restart the configured unit, await its job, verify the configured
|
||||
interface/peers, persist verification through M4, then publish applied state and
|
||||
release reserved addresses. Supply safe public runtime/statistics views for the
|
||||
future TUI without deriving client identity or online status from aliases.
|
||||
|
||||
Read SPEC.md Operations and states, Client screen and statistics, and Backups and
|
||||
restoration; ADRs 0001 and 0003; PERSISTENCE.md, BACKUP_FORMAT.md, DEVELOPMENT.md,
|
||||
DEPENDENCIES.md, TESTING.md, and the current application/domain code. Commit and
|
||||
restore must retain their strict no-runtime-mutation behavior.
|
||||
|
||||
Out of scope: TUI/screens, automatic refresh scheduling in a render loop, delivery
|
||||
or QR, automatic failed-restart rollback/retry, reload/syncconf as an alternative
|
||||
apply path, additional service managers/interfaces, production tests, and creation
|
||||
of the Alpine/VM harnesses. Keep management startup safely incomplete; do not
|
||||
introduce a new restart CLI or run real adapters in default tests.
|
||||
|
||||
#### Existing code and integration constraints
|
||||
|
||||
- `Application` owns the saved store/bytes, byte-preserving document, `ClientStates`,
|
||||
vault draft and historical verification. Resolve runtime settings from the
|
||||
current saved generation, including settings restored from a backup, not a stale
|
||||
constructor copy or archive-supplied arbitrary bus/service destination.
|
||||
- `Application::create_pre_restart_backup` archives installed bytes and sets a
|
||||
pending boundary flag. `mark_verified_after_runtime_check` is crate-private:
|
||||
it checks that boundary and saved generation, validates an observed Snapshot,
|
||||
installs verification state through SavedStore's journal, then advances memory.
|
||||
Wire these existing boundaries into the real sequence; do not bypass them with
|
||||
a direct state-file write or public "mark verified" setter.
|
||||
- `PersistedState` v1 holds reservations and a historical UTC timestamp. Reopen is
|
||||
always Unknown. Commit/restore clear stale verification; M5 records the timestamp
|
||||
only after matching runtime and successful journaled write. BACKUP_FORMAT.md
|
||||
ties archive historical status to that saved generation, not merely the date.
|
||||
- The existing `pre_restart_backup_pending` boolean is not proof of a successful
|
||||
restart. Scope/invalidate authorization per attempt, failure, cancellation and
|
||||
saved-generation change; an old successful backup must never authorize later
|
||||
unrelated verification. Refine the internal contract if needed, preserving M4
|
||||
guarantees and tests. No new concurrency/version-control scheme is required.
|
||||
- `Snapshot` includes aliases and a narrow ClientAddresses model; kernel peers do
|
||||
not contain aliases or managed comment timestamps. Do not compare raw kernel
|
||||
structures directly against Snapshot equality or invent runtime metadata.
|
||||
- M2 `ConfigDocument::peers()` retains full AllowedIPs and redacted issues; some
|
||||
valid peers cannot project into M1 Client. Include every authoritative peer in
|
||||
technical verification, or fail closed as unverifiable. Never ignore unsupported
|
||||
records to obtain a matching reduced subset. Missing/invalid managed alias alone
|
||||
must not be mistaken for evidence of a different runtime peer.
|
||||
- Cargo already contains time, rustix, tempfile and persistence/crypto dependencies.
|
||||
The approved `wireguard-uapi` 3.0.1 public read path cannot guarantee complete,
|
||||
bounded dumps (M5-R1-04). Use existing approved `rustix` with narrow `net`/`event`
|
||||
features for a checked read-only Generic Netlink GET adapter; add approved zbus
|
||||
only when needed. Inspect current official APIs/features and Rust compatibility.
|
||||
Do not assume older zbus blocking examples
|
||||
apply to the selected version. No unapproved direct Tokio/executor/mock crate
|
||||
or utility subprocess fallback is authorized.
|
||||
|
||||
#### Context and implementation steps
|
||||
|
||||
Run tasks sequentially with one writer under the established model policy:
|
||||
GPT-6-Sol/medium coordinator; GPT-6-Luna/high implementer, independent reviewer and
|
||||
repairer. Dispatch owned files, exact interfaces, acceptance IDs, checks and
|
||||
required evidence. Workers do not mark milestones accepted or edit PLANS.md.
|
||||
|
||||
| Task | Owner | Files and deliverable |
|
||||
| --- | --- | --- |
|
||||
| M5.1 | implementer | `src/runtime.rs`, narrow domain/application views and `docs/RUNTIME.md`: public observation model, saved technical projection and pure comparison contract |
|
||||
| M5.2 | implementer | runtime adapter modules, Cargo files/library exports: approved-rustix read-only WireGuard Generic Netlink codec/transport with isolated conversion/error tests; split pure decoder then bounded socket transport |
|
||||
| M5.3 | implementer | `src/service.rs`, child modules if necessary: zbus systemd restart/job observation with deadline and a mockable transport boundary |
|
||||
| M5.4 | implementer | `src/app.rs`, narrow M4 state/persistence integration: confirmed restart orchestration, per-attempt authorization, durable verification and honest failure results |
|
||||
| M5.5 | implementer | `tests/runtime_restart.rs`, test-only adapters, README/RUNTIME/PERSISTENCE documentation: integrated success, order and failure scenarios |
|
||||
| M5.6 | reviewer, repairer | Independent integrated review, bounded fixes and re-review, including M4 persistence regressions |
|
||||
| M5.7 | coordinator | Integrated gates, evidence/findings and milestone acceptance/handoff in PLANS.md |
|
||||
|
||||
M5.1 defines public observations keyed by PublicKey, with explicit interface
|
||||
presence/unavailability, peer AllowedIPs, last handshake, received/transmitted
|
||||
byte counters, and observation time. Preserve zero/never-handshaken separately
|
||||
from unavailable data. Counters are current interface values, may reset after a
|
||||
restart, and are not historical usage or proof of online/offline status. Traffic
|
||||
is reported from the server interface's perspective. Alias display joins by
|
||||
public key using saved metadata, never list index or filename.
|
||||
|
||||
Define technical equivalence independently of counters, handshake, peer ordering,
|
||||
route ordering, aliases, dynamically learned endpoints and timestamps. Verify the
|
||||
expected configured interface exists and the complete saved peer public-key set
|
||||
and normalized AllowedIPs match, including absence of deleted/extra peers and
|
||||
an empty valid peer set. Report missing/extra/mismatched/unverifiable records with
|
||||
public identities and categories. Duplicate/ambiguous saved identities or partial
|
||||
runtime dumps cannot pass. Do not claim comparison of fields the adapter cannot
|
||||
observe. Retain full route sets for legacy peers; enrich M1 projection narrowly
|
||||
only if required and do not drop valid data to fit Snapshot.
|
||||
|
||||
Document the boundary between technical match and M4's narrow observed Snapshot:
|
||||
use saved aliases only after technical peer/route equivalence is established,
|
||||
not as alleged kernel observations. If the complete document cannot be safely
|
||||
verified/represented for durable marking, keep the operation unverifiable and
|
||||
reservations retained rather than passing a fabricated subset to M4.
|
||||
|
||||
M5.2 uses the configured interface via Linux WireGuard/netlink APIs only; no set,
|
||||
add/remove, module loading, host route manipulation or external `wg` invocation.
|
||||
Handle multipart responses and peer/AllowedIPs fragments according to the
|
||||
[kernel protocol](https://docs.kernel.org/netlink/specs/wireguard.html); require
|
||||
matching request sequence, an error-free terminal `NLMSG_DONE`, no interrupted
|
||||
dump and a complete response before claiming absence or equality. Bound
|
||||
reads/waits and aggregate limits. Convert no-device, permission, malformed data,
|
||||
transport failure and timeout to distinct actionable, redacted outcomes.
|
||||
|
||||
WireGuard library structures may include server private or preshared keys even
|
||||
when only public statistics are needed. Never derive/log their full Debug, retain
|
||||
them in public observations, or serialize them as status data. Minimize lifetime
|
||||
and clear supported owned buffers; document unavoidable library copies honestly.
|
||||
Default tests exercise supplied decoded inputs/test transport, never a host socket.
|
||||
|
||||
M5.3 connects to the system bus and fixed systemd Manager API for the validated
|
||||
configured unit, requests an actual restart, and follows the returned job to its
|
||||
terminal result. Subscribe/install observation before submission so immediate
|
||||
completion cannot be missed; correlate by the actual job and unit, ignore unrelated
|
||||
signals, and handle disconnection/name-owner changes or subscription failure.
|
||||
Successful request submission, job disappearance, or a unit already being active
|
||||
is not completed restart evidence. Accept only the documented successful terminal
|
||||
result, then let runtime verification decide whether VPN configuration matches.
|
||||
Account for wg-quick oneshot units that are active/exited; do not demand a daemon
|
||||
PID or long-running process that WireGuard itself does not require.
|
||||
|
||||
Use a monotonic configured deadline across D-Bus connection/subscription/request,
|
||||
job waiting and post-job verification rather than resetting it on each retry.
|
||||
Backup completion precedes service mutation but may have a separate filesystem
|
||||
failure boundary. A timeout bounds the application's wait, not proof that systemd
|
||||
stopped its job. Report "may still complete" when appropriate; do not retry a
|
||||
restart or issue broad cancellation/rollback automatically. Ordinary test code
|
||||
uses a supplied job event/transport adapter; no real system bus is contacted.
|
||||
|
||||
M5.4 adds explicit preparation/confirmation for restart and draft discard suitable
|
||||
for a future TUI. Preview/cancel does not save/discard a draft or call systemd.
|
||||
On confirmed discard-and-restart, reject unresolved persistence recovery, validate
|
||||
saved input and configured unit, complete the pre-restart backup, discard only
|
||||
as authorized and restart only the saved configuration. Never implicitly Commit.
|
||||
A backup failure leaves protected state and draft unchanged and submits no job.
|
||||
|
||||
Check compatibility with service-managed config rewriting, notably wg-quick
|
||||
SaveConfig behavior: do not edit administrator-owned settings to work around it
|
||||
or claim saved-generation verification when shutdown has overwritten intended
|
||||
peer changes. Detect an unsafe/unverifiable apply precondition and explain it;
|
||||
use a safe test fixture/service setup, not an automatic production setting change.
|
||||
|
||||
Demote stale current verification when a restart is submitted; a failed request,
|
||||
job, read or comparison cannot leave a misleading previously Verified state.
|
||||
Keep reservations and recovery information conservative. Read back the complete
|
||||
runtime after successful job completion within the deadline; do not require a
|
||||
client to connect or handshake, since correct peers can be idle. Periodic
|
||||
read-only observations may report correspondence, but must not release deleted
|
||||
addresses or persist successful restart history by bypassing the explicit sequence.
|
||||
|
||||
Only a matching full observation from the successful attempt can reach M4's
|
||||
journaled verification boundary. If the saved-generation check or state write
|
||||
fails after VPN restart, report "runtime changed, verification not durably
|
||||
recorded" rather than full success. Retain reservations/in-memory safety and
|
||||
honor RecoveryRequired before later mutations. Do not rollback the VPN, repeat
|
||||
restart automatically, mark the old history as current, or remove the backup.
|
||||
|
||||
M5.5 uses fake monotonic time and deterministic adapter event sequences, temporary
|
||||
saved stores and synthetic configuration. Assert call order: backup completed
|
||||
before restart request; successful job before runtime verification; matched
|
||||
observation before journaled state publication; persistence success before memory
|
||||
and reservation release. Failures must be visible by stage, including whether
|
||||
a restart was submitted/may still be active, backup location, and any required
|
||||
manual recovery. Avoid sensitive D-Bus/library error text in reports.
|
||||
|
||||
#### Acceptance and validation
|
||||
|
||||
- [x] M5-A1: public read-only observation distinguishes missing/unavailable/unknown,
|
||||
no handshake and valid zero counters; public-key joins and counter resets do not
|
||||
invent online state, aliases, traffic history, or successful apply.
|
||||
- [x] M5-A2: configured-interface runtime adapter consumes complete bounded peer
|
||||
data, including fragmented route lists, and exposes only public information;
|
||||
no runtime mutations, secret Debug output or default host access occur.
|
||||
- [x] M5-A3: pure verification covers dual-stack and IPv4-only peers, reordered
|
||||
sets, empty peers, missing/extra/deleted peers, route mismatches, malformed or
|
||||
partial observations, and unsupported saved shapes without subset success.
|
||||
- [x] M5-A4: service adapter targets only the configured systemd unit, tracks the
|
||||
returned job without a fast-completion race, and handles unrelated events,
|
||||
failed/canceled jobs, disconnects, permission errors and monotonic timeout.
|
||||
- [x] M5-A5: explicit cancellation preserves the draft; confirmed draft discard
|
||||
never commits. Failed mandatory backup submits no restart and preserves draft,
|
||||
saved bytes, reservations and previous historical evidence.
|
||||
- [x] M5-A6: successful restart alone is insufficient: interface/peer verification
|
||||
must pass before M4 marking; idle clients need no handshake to be applied.
|
||||
- [x] M5-A7: each failure invalidates that attempt's authorization; a stale backup
|
||||
flag, old successful job, read-only refresh or old verified Snapshot cannot mark
|
||||
a later generation applied or release a reserved address.
|
||||
- [x] M5-A8: verified state and timestamp become visible only after M4 journaled
|
||||
state persistence succeeds. Injected post-restart write/recovery failure retains
|
||||
safe reservations and reports changed runtime without false overall success.
|
||||
- [x] M5-A9: reopening still treats verification timestamps as historical; Commit
|
||||
and restore retain their no-runtime-mutation behavior and invalidate stale apply
|
||||
evidence. Archived settings changes select the restored unit/timeout correctly.
|
||||
- [x] M5-A10: timeouts do not imply a job was canceled; no automatic restart retry,
|
||||
live setting rewrite, reload/syncconf fallback or VPN rollback is introduced.
|
||||
- [x] M5-A11: full M1–M4 regressions and integrated M5 fake-adapter tests pass with
|
||||
no root, Docker, real system bus/interface, production paths or secret reads.
|
||||
- [x] M5-A12: independent review closes actionable runtime/service/race/persistence
|
||||
findings; documentation clearly defers real WireGuard checks to M8 and actual
|
||||
systemd/D-Bus acceptance to M9 rather than claiming them from mocks.
|
||||
|
||||
Planned commands from the repository root once M5 targets/lockfile exist:
|
||||
|
||||
```sh
|
||||
cargo test --locked runtime
|
||||
cargo test --locked service
|
||||
cargo test --locked --test runtime_restart
|
||||
cargo test --locked --test commit_restore
|
||||
cargo test --locked --test config_preservation
|
||||
cargo test --locked --test vault_import
|
||||
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
|
||||
git diff --check
|
||||
```
|
||||
|
||||
Ensure filters execute actual tests and report counts and exit status. Resolve
|
||||
approved dependencies and update Cargo.lock before locked gates. Default tests
|
||||
must remain deterministic, unprivileged and independent of a daemon/bus/network.
|
||||
No bare management launch, actual restart, or host WireGuard probing is permitted.
|
||||
|
||||
#### Progress
|
||||
|
||||
- [x] Description prepared against accepted M1–M4 interfaces and current documents.
|
||||
- [x] 2026-10-20T20:44:56+03:00 preparation: confirmed M1–M4 accepted in this plan, inspected the worktree and role configuration; stopped before dispatch because the active coordinator model/effort is not exposed for verification.
|
||||
- [x] 2026-10-20T21:39:34+03:00 execution resumed: verified the active session's latest turn context as `gpt-6-sol`/`medium` in its local session record, and confirmed the four configured roles use `gpt-6-luna`/`high`; reread required project documents and inspected the actual repository. The earlier model-verification blocker is resolved.
|
||||
- [x] M5.1 — implementer delivered pure public observation and full saved-peer comparison in `src/runtime.rs`, `docs/RUNTIME.md` and library export. Independent R1 review found wrong-interface acceptance and two test gaps; repairer fixed all three; fresh R2 re-review found no remaining actionable M5.1 finding. Final `cargo test --locked runtime` passed (14 matching tests, including 10 runtime-module tests; 104 library tests filtered). This is partial M5 work, not milestone acceptance.
|
||||
- [x] M5.2 — after confirming `wireguard-uapi` 3.0.1's incomplete/unbounded public read API, a read-only explorer identified existing approved `rustix` `net`/`event` as a bounded transport route. Implementers delivered a checked pure decoder (`src/runtime/netlink.rs`) and nonblocking read-only socket transport (`src/runtime/transport.rs`) with synthetic/fake-I/O tests. Independent R2 and R3 reviews found three on-wire/error defects; repairer fixed all, and independent re-review closed them. Latest focused `cargo test --locked runtime` passed 29 matching tests; fmt, Clippy and diff checks passed. No host socket or real WireGuard behavior was tested; M8 remains responsible for isolated real adapter validation.
|
||||
- [x] M5.3 — approved `zbus` 5.19.0 async-io adapter and pure job tracker implemented in `src/service.rs` and `src/service/dbus.rs`, with a shared monotonic deadline and signals installed before restart. Independent R1 review found alias/primary-unit mismatch; repairer resolved `GetUnit` + `Unit.Id` before restart and R2 re-review closed the finding. `cargo test --locked service::` passed 18 fake/pure tests; fmt, Clippy and diff checks passed. No system bus or real service was contacted; M9 VM acceptance remains pending.
|
||||
- [x] M5.4 — `Application` now exposes saved-bound restart preview, explicit cancel/restart/discard choices and redacted stage-aware reports; backup precedes discard/submission, full technical match and one-use attempt authorization precede M4 journaled marking. SaveConfig/recovery/stale-generation checks and fake adapter tests added. Independent R1 found false “may still complete” on known terminal job failure; repairer corrected it and fresh R2 review closed the finding. Latest `cargo test --locked app` passed 33 matching tests; fmt, Clippy and diff checks passed. No host bus/interface was accessed.
|
||||
- [x] M5.5 — added `tests/runtime_restart.rs` public preview/cancel/restored-settings integration tests (2 passed), private fake-adapter/clock deadline coverage in `src/app.rs` (34 app-filtered tests passed), and README/RUNTIME/PERSISTENCE documentation distinguishing synthetic M5 evidence from later real M8/M9 validation. `cargo test --locked` passed 161 library units plus 25 integration tests; fmt, Clippy and diff checks passed. Full independent integrated review remains M5.6.
|
||||
- [x] M5.6 — fresh independent integrated review found six actionable API, reporting, documentation and deadline findings; repairer addressed them in two bounded rounds, and independent re-review closed all six. The reviewer found no remaining actionable scoped M5 issue. Real kernel/systemd behavior remains M8/M9 work.
|
||||
- [x] M5.7 — coordinator inspected the integrated worktree, ran every planned command on the final revision, recorded results below, and accepted M5-A1–A12 for the specified synthetic/fake-adapter scope.
|
||||
|
||||
#### Review and repair
|
||||
|
||||
R1 independent reviewer findings and R2 disposition:
|
||||
|
||||
- M5-R1-01 (P1, `src/runtime.rs` interface observation/comparison): a peer/route
|
||||
match from the wrong interface could pass. Repairer added observed interface
|
||||
identity and a configured-name argument to comparison; wrong-name regression
|
||||
now fails closed. R2 independently confirmed closure.
|
||||
- M5-R1-02 (P2, `src/runtime.rs` test coverage): no direct invariance test for
|
||||
handshake changes and counter resets. Repairer added one; R2 confirmed closure.
|
||||
- M5-R1-03 (P2, `src/runtime.rs` test coverage): missing malformed-route and
|
||||
structural-document subset-match regressions. Repairer added both; R2
|
||||
confirmed closure.
|
||||
- M5-R1-04 (blocking dependency/API limitation, M5.2): independent reviewer
|
||||
confirmed `wireguard-uapi` 3.0.1 `src/linux/socket/wg_socket.rs:87-108`
|
||||
loops on `iter.next()` without a deadline and uses
|
||||
`while let Some(Ok(response))`, allowing a receive error after a fragment to
|
||||
terminate the loop and return a partial `Device` as success. The public API
|
||||
provides no completeness proof or read timeout. Secret-bearing decoded fields
|
||||
can be kept private by careful consumption, but that does not fix boundedness
|
||||
or completeness. An abandoned timeout thread also cannot cancel the read.
|
||||
Resolution: read-only explorer verified `rustix` 1.1.5 provides public safe
|
||||
AF_NETLINK/NETLINK_GENERIC socket and polling APIs when its approved direct
|
||||
dependency enables `net`/`event`. It does not provide a WireGuard codec, so
|
||||
M5.2 must implement a small checked decoder with explicit complete-dump and
|
||||
aggregate-limit fixture tests, followed by a bounded socket transport. This
|
||||
is an implementation choice within the approved dependency list, not a new
|
||||
direct dependency or specification change. No unsafe fallback or
|
||||
partial-success adapter is accepted; this finding remains open until tested.
|
||||
- M5-R2-01 (P1, `src/runtime/transport.rs` request IFNAME encoding): the initial
|
||||
builder put the NUL outside `nla_len`; repairer included it in the payload and
|
||||
added exact-byte assertions. Independent R3 re-review confirmed closure.
|
||||
- M5-R2-02 (P2, `src/runtime/transport.rs` family errors): type validation made
|
||||
`NLMSG_ERROR` handling unreachable; repairer added checked errno mapping for
|
||||
no-device, permission and transport failures and injected tests. Independent
|
||||
R3 re-review confirmed closure.
|
||||
- M5-R3-01 (P1, `src/runtime/transport.rs` IFNAME attribute number): initial
|
||||
request used type 3 (private key) instead of kernel-defined IFNAME type 2;
|
||||
repairer corrected it and added a literal numeric assertion independent of
|
||||
the implementation constant. R3 reviewer follow-up confirmed closure.
|
||||
- M5.3-R1 (P2, `src/service.rs`/`src/service/dbus.rs` alias correlation): the
|
||||
tracker initially compared `JobRemoved.unit` to the configured literal, which
|
||||
can be an alias while systemd reports the primary unit name. Repairer added
|
||||
bounded read-only `GetUnit`/`Unit.Id` resolution before `RestartUnit`; the
|
||||
request still targets the configured name and the terminal event must match
|
||||
both primary ID and returned job path. Synthetic alias/failure/order tests
|
||||
passed; fresh R2 reviewer confirmed closure.
|
||||
- M5.4-R1-01 (P2, `src/app.rs` service failure report): submitted terminal
|
||||
`JobRemoved` failures were incorrectly reported as possibly still completing.
|
||||
Repairer distinguished terminal failure from ambiguous request/wait timeout
|
||||
or disconnect while preserving submission/manual-recovery fields. Synthetic
|
||||
cases for failed, dependency, timeout, canceled, skipped and unknown results
|
||||
passed; fresh R2 reviewer confirmed closure.
|
||||
|
||||
M5-R1-04 is now resolved at the implementation-choice level with a bounded
|
||||
`rustix` decoder/transport and synthetic tests; actual kernel behavior is
|
||||
deferred to M8 and has not been claimed here.
|
||||
|
||||
Integrated review finding IDs below are prefixed `M5-I` to distinguish them
|
||||
from earlier task-local reviewer IDs:
|
||||
|
||||
- M5-I-R1-01 (P1): a public raw systemd adapter could be called without the
|
||||
mandatory application backup. Repairer made it crate-private and added a
|
||||
compile-fail public-API doctest; independent R2 confirmed closure.
|
||||
- M5-I-R1-02 (P1): a public domain verification setter bypassed the application
|
||||
sequence. Repairer restricted it to the crate; R2 confirmed closure.
|
||||
- M5-I-R1-03 (P2): runtime failures collapsed to one uninformative category.
|
||||
Repairer added six redacted runtime-failure categories; R2 confirmed closure.
|
||||
- M5-I-R1-04 (P2): TESTING.md incorrectly described the `wireguard-uapi` read
|
||||
adapter. Repairer documented the actual approved-rustix path; R2 confirmed.
|
||||
- M5-I-R2-05 (P2): expiry of the shared application deadline could be reported
|
||||
as a generic runtime-read failure or mismatch. Repairer added a distinct
|
||||
deadline result and deterministic before/after-read fake-clock tests; the
|
||||
independent reviewer re-reviewed and closed it.
|
||||
- M5-I-R2-06 (P2): RUNTIME.md called the now crate-private service adapter a
|
||||
public API. Repairer corrected the boundary description; independent
|
||||
re-review closed it.
|
||||
|
||||
The fresh integrated reviewer reported no further actionable issue against
|
||||
M5-A1–A12 after the second repair round. Review and tests use synthetic state;
|
||||
they do not establish real kernel or systemd/D-Bus behavior.
|
||||
|
||||
#### Evidence and handoff
|
||||
|
||||
Planning inspected current Cargo dependencies, Application backup/verification
|
||||
boundaries, persistence/state schemas, backup metadata rules and M4 evidence.
|
||||
M4 records independent R5 acceptance and coordinator results: 108 library unit,
|
||||
9 Commit/restore, 9 preservation and 5 import tests, plus completion gates.
|
||||
Those are historical recorded results; this planning task did not rerun Cargo
|
||||
checks, add dependencies/source, dispatch agents or contact a system bus/VPN.
|
||||
|
||||
2026-10-20 preparation confirmed `.codex/config.toml` requests `gpt-6-sol`/
|
||||
`medium`, all four `.codex/agents/*.toml` request `gpt-6-luna`/`high`, and the
|
||||
available spawn-agent catalog lists those models and efforts. The active primary
|
||||
session exposes only the GPT-6 family, not its exact model or effort; project
|
||||
defaults can be overridden by a live session. Thus the mandatory coordinator
|
||||
verification is incomplete. The worktree already had a user change to this
|
||||
M5 description; it was preserved. `rustc`/Cargo reported 1.97.1, rustfmt
|
||||
1.9.0 and Clippy 0.1.97. `git diff --check` passed before this status edit.
|
||||
No M5 code, tests, dependencies, worker dispatch or acceptance checks ran during
|
||||
that earlier preparation.
|
||||
|
||||
The active session was subsequently verified by matching `CODEX_SESSION_ID` to
|
||||
its local rollout record and reading the latest `turn_context` model and effort:
|
||||
`gpt-6-sol` / `medium` (2026-10-20T18:36:50.175Z). The four role files explicitly
|
||||
configure `gpt-6-luna` / `high`; M5 workers will be spawned with those effective
|
||||
model/effort overrides and their configured roles. This resolves the prior
|
||||
configuration blocker without substituting models.
|
||||
|
||||
2026-10-20T21:50:55+03:00 coordinator validation of the partial integrated
|
||||
revision (all exit 0): `cargo fmt --all -- --check`,
|
||||
`cargo clippy --locked --all-targets -- -D warnings`, `cargo test --locked`
|
||||
(118 library unit, 9 Commit/restore, 9 config-preservation and 5 vault-import
|
||||
tests passed; main/doc tests 0), `cargo build --locked --release`,
|
||||
`cargo test --locked runtime` (14 matching tests, of which 10 are in the runtime
|
||||
module), each of the three named M4 integration targets (9/9/5 passed), release
|
||||
`--help` and `--version`, and `git diff --check`. No service or runtime_restart
|
||||
test target exists yet, so those planned checks were unavailable and not counted
|
||||
as passing. `wireguard-uapi` and `zbus` are not in the retained manifests/lockfile.
|
||||
No root, Docker, host interface, system bus, production data, Alpine or VM test
|
||||
was used. Passing partial gates does not establish M5-A2 or M5-A4–A12.
|
||||
|
||||
2026-10-20T22:03:03+03:00 continuation: active coordinator session rollout
|
||||
again showed `gpt-6-sol` / `medium`; role files still specify `gpt-6-luna` /
|
||||
`high`. Worktree remained the prior partial M5 result. Read-only explorer
|
||||
examined cached `wireguard-uapi`/`rustix` sources and kernel protocol docs;
|
||||
no socket or production state was accessed. The chosen `rustix` route needs
|
||||
checked Generic Netlink family resolution, exact sequence/DONE/error handling,
|
||||
fragment coalescing, monotonic deadline and strict limits before M5-A2 can pass.
|
||||
|
||||
Final M5.7 validation on the integrated revision (all exit 0):
|
||||
`cargo test --locked runtime` (32 matching tests),
|
||||
`cargo test --locked service` (19 matching tests),
|
||||
`cargo test --locked --test runtime_restart` (2),
|
||||
`cargo test --locked --test commit_restore` (9),
|
||||
`cargo test --locked --test config_preservation` (9),
|
||||
`cargo test --locked --test vault_import` (5),
|
||||
`cargo fmt --all -- --check`,
|
||||
`cargo clippy --locked --all-targets -- -D warnings`,
|
||||
`cargo test --locked` (163 library unit tests, 25 integration tests and one
|
||||
compile-fail doctest passed; binary tests 0),
|
||||
`cargo build --locked --release`, release `--help` and `--version`, and
|
||||
`git diff --check`. The release binary reports that the management interface
|
||||
is not implemented, as expected. Tests were unprivileged synthetic/fake-adapter
|
||||
checks; no Docker, Alpine, systemd VM, host bus/interface, production path,
|
||||
private key or real restart was accessed. M8 and M9 still require their own
|
||||
real-system acceptance and cannot inherit a passing result from these checks.
|
||||
|
||||
Next action: stop after accepted M5. M6 may begin only on a separate request;
|
||||
M8 Alpine and M9 disposable-VM validation remain future milestones.
|
||||
|
||||
M5.3 prerequisite decision: use approved `zbus` 5.19.0 with `async-io` and
|
||||
default features disabled. A standard-library wake/park executor with one
|
||||
monotonic deadline can bound connection setup, match-rule registration, method
|
||||
calls and signal waits without an unapproved direct runtime dependency. Subscribe
|
||||
and install observation before `RestartUnit`; buffer/handle a fast completion
|
||||
that arrives before the method reply. Confirm real signal and alias behavior in
|
||||
the disposable systemd VM at M9; fake events here are not VM evidence.
|
||||
|
||||
#### Decisions and discoveries
|
||||
|
||||
M4 verification persistence already supplies the intended durable boundary, but
|
||||
its pending-backup flag is only one prerequisite. M5 must establish restart/job
|
||||
and runtime evidence before invoking it and invalidate per-attempt authority.
|
||||
Aliases are server metadata, not kernel data; verification must separate technical
|
||||
correspondence from display/domain projection. A successful service job and a
|
||||
successful durable application record are distinct stages with distinct failures.
|
||||
|
||||
Primary API references for implementation (check the chosen version at dispatch):
|
||||
[systemd D-Bus](https://www.freedesktop.org/software/systemd/man/latest/org.freedesktop.systemd1.html),
|
||||
[wireguard-uapi](https://docs.rs/wireguard-uapi/latest/wireguard_uapi/), and
|
||||
[zbus](https://docs.rs/zbus/latest/zbus/). These references do not pin new versions.
|
||||
|
||||
#### Outcome
|
||||
|
||||
M5.1–M5.7 are complete. Accepted for the milestone's explicitly scoped
|
||||
synthetic/fake-adapter checks after independent integrated review, two repair
|
||||
rounds, re-review and all planned coordinator gates. No real WireGuard or
|
||||
systemd/D-Bus result is claimed; M8/M9 remain future acceptance stages. No Git
|
||||
commit, deployment or production access occurred. Stop after M5; do not start M6
|
||||
without a separate request.
|
||||
|
||||
### Milestone 6 — Client configuration delivery and reissue lifecycle
|
||||
|
||||
@@ -1421,14 +1847,14 @@ Acceptance: real D-Bus job handling, separate restart verification, address rele
|
||||
|
||||
## Current progress and resume point
|
||||
|
||||
- Milestones 1–4 are accepted; milestones 5–9 remain pending.
|
||||
- Milestones 1–5 are accepted; milestones 6–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.
|
||||
- Milestone 2 delivered a lossless in-memory WireGuard configuration editor, versioned metadata, and behavioral preservation tests.
|
||||
- Milestone 3 delivered secret-safe key handling, a versioned encrypted vault, caller-buffer reconciliation, and a bounded read-only source-directory import adapter.
|
||||
- Milestone 4 delivered versioned private backups, journaled saved-file Commit and recovery, previewed full restore, durable address reservations and historical verification bookkeeping, with independent R5 closure and coordinator gates.
|
||||
- Next action: stop after accepted M4; begin M5 only if separately requested.
|
||||
- M1–M4 integrated gates and independent reviews passed. No Alpine or VM results are claimed.
|
||||
- Milestone 5 delivered public runtime observations and technical comparison, an approved-rustix bounded read-only netlink adapter, a zbus systemd job adapter, restart orchestration, and synthetic integration tests. Independent integrated review and repairs closed all actionable scoped findings; all planned gates passed. Real kernel/systemd validation remains deferred to M8/M9.
|
||||
- M1–M5 integrated gates and independent reviews passed. No Alpine or VM results are claimed.
|
||||
|
||||
## Plan maintenance
|
||||
|
||||
|
||||
Reference in New Issue
Block a user