Add application read models and thin TUI command adapter

This commit is contained in:
2026-10-30 23:02:35 +02:00
parent 9a143e975e
commit 7123197ec4
12 changed files with 2669 additions and 703 deletions
+13 -13
View File
@@ -135,7 +135,7 @@ Each row is a delivery milestone, not a completion claim. Expand its record befo
| 23 | Readable saved-state Commit and restore scenarios | 22 | accepted |
| 24 | Session-owned first delivery and password reissue scenarios | 23 | accepted |
| 25 | Explicit restart verification scenario | 24 | accepted |
| 26 | Application read models and thin TUI command adapter | 25 | pending |
| 26 | Application read models and thin TUI command adapter | 25 | accepted |
| 27 | Integrated refactoring acceptance and architecture handoff | 26 | pending |
### Milestone 1 — Rust foundation, settings, and domain states
@@ -4099,7 +4099,7 @@ Focused commands `cargo test --locked app::` (67), `runtime::` (25), `service::`
### Milestone 26 — Application read models and thin TUI command adapter
Status: pending. Prerequisite: M25 accepted.
Status: accepted (2026-10-30T23:01:09+02:00; independent R1–R4 re-review, evidence verification and integrated Rust gates passed). Prerequisite: M25 accepted. M1–8 and M10–25 are accepted; M9 is retired and not a prerequisite. This session's coordinator GPT-6-Sol/medium was user-confirmed; `.codex/config.toml` and explicit worker dispatch use GPT-6-Luna/high. Initial tree clean at `9a143e9`; pinned Rust/Cargo 1.97.1 verified. TUI previously reparsed saved config for peer count; app deletion already supports some exact-host-route peers outside manageable `ClientStates`.
#### Outcome and scope
@@ -4107,10 +4107,10 @@ TUI consumes public application facts and action eligibility without parsing sav
| Task | Owner | State | Bounded deliverable |
| --- | --- | --- | --- |
| M26.1 | implementer | pending | Secret-free application view and per-action eligibility |
| M26.2 | implementer | pending | Migrate TUI projection and command execution adapter |
| M26.3 | implementer | pending | Split command/result/navigation responsibilities where justified |
| M26.4 | reviewer; repairer; coordinator | pending | UI parity/authorization/lifecycle review, repair and RUST acceptance |
| M26.1 | implementer `/root/m26_read_model` | complete | `ApplicationView` and per-action eligibility built from authoritative peer and session facts; app/TUI/workflow focused checks, fmt and Clippy passed |
| M26.2 | implementer `/root/m26_tui_projection` | complete | TUI view consumes app read model; selection-bound guards/hints use per-action eligibility; TUI/workflow/client-delivery focused checks, fmt and Clippy passed |
| M26.3 | implementer `/root/m26_command_adapter` | complete | Application command/prepared-context adapter extracted under events; TUI/workflow/client-delivery focused checks, fmt and Clippy passed; broad terminal/render split deferred as no cohesive gain |
| M26.4 | reviewer `/root/m26_review`; repairer `/root/m26_repair`; coordinator | complete | M26-R1 removed unprojectable saved peer, R2 unrelated issue overblock, R3 false Removed row and R4 capability-issue reissue mismatch closed on re-review; evidence and integrated RUST verified |
1. Move ClientDisplay/SessionDisplay projection responsibilities to an application-owned read model. Include saved peer count, draft/saved public client differences, issue classification, reservation/apply facts and vault-initialized state. Keep UI-only selection, scroll, dialog focus, rendered strings/styles and worker generation in TUI. Raw ConfigDocument/SavedBytes/vault/password/payload must not be fields of the public view.
2. Represent action eligibility explicitly per action with typed reasons where useful. Audit current guards first: rename, delete, first delivery and restart do not necessarily have identical eligibility. In particular inspection-only management projection must not accidentally prohibit an already-supported deletion by public key. Never silently enable actions for malformed/ambiguous peers. Eligibility is guidance for presentation; application execution revalidates its actual preconditions.
@@ -4121,12 +4121,12 @@ TUI consumes public application facts and action eligibility without parsing sav
#### Acceptance and validation
- [ ] M26-A1: TUI no longer parses saved server bytes to obtain application facts; read model is secret-free and includes all authoritative records.
- [ ] M26-A2: per-action availability matches existing handlers, with authoritative revalidation; selection/cancel/draft/QR behavior preserved.
- [ ] M26-A3: worker generation/continuation/shutdown tests, responsive help/list/footer buffer tests and synthetic PTY workflows pass without weakened assertions.
- [ ] M26-A4: reviewer checks UI parity and boundary direction; RUST passes; actual module layout documented.
- [x] M26-A1: TUI no longer parses saved server bytes to obtain application facts; read model is secret-free and includes all authoritative records.
- [x] M26-A2: per-action availability matches existing handlers, with authoritative revalidation; selection/cancel/draft/QR behavior preserved.
- [x] M26-A3: worker generation/continuation/shutdown tests, responsive help/list/footer buffer tests and synthetic PTY workflows pass without weakened assertions.
- [x] M26-A4: reviewer checks UI parity and boundary direction; RUST passes; actual module layout documented.
Focused commands: `cargo test --locked tui::`, `cargo test --locked --test tui_workflow`, `cargo test --locked --test client_delivery`. Evidence: docs/evidence/milestone-26.md. Outcome: not accepted. Handoff: M27 after acceptance.
Focused commands `cargo test --locked tui::` (88), `--test tui_workflow` (9), `--test client_delivery` (5), and affected `app::` (74) exited 0 on the integrated tree. Final coordinator `cargo fmt --all -- --check`, `cargo clippy --locked --all-targets -- -D warnings`, `cargo test --locked` (library 352 passed, 2 ignored; integration/doc tests passed), `cargo build --locked --release`, and `git diff --check` exited 0. Independent reviewer closed M26-R1 (removed unprojectable peer omission), R2 (unrelated issue reissue overblock), R3 (false Removed row from repair) and R4 (capability-issue reissue mismatch); all 11 evidence hashes and final gate results were rechecked. [M26 evidence](docs/evidence/milestone-26.md) identifies inputs, fixes and host/synthetic limits. No fresh Alpine or VM/systemd run is claimed. Outcome: accepted for M26 host/synthetic scope. Stop after M26; M27 starts only on a separate request.
### Milestone 27 — Integrated refactoring acceptance and architecture handoff
@@ -4159,7 +4159,7 @@ Evidence: docs/evidence/milestone-27.md. Outcome: not accepted. Handoff: stop af
## Current progress and resume point
- M25 is accepted for host/fixture scope: bound preview/preparation and ordered restart verification moved into one scenario; independent review and required Rust gates passed. M25-R1 evidence gap was closed on re-review. [M25 evidence](docs/evidence/milestone-25.md) records final inputs and limits. M26–M27 remain pending; M9 remains retired/unaccepted and its real-system limitations remain unchanged.
- M26 is accepted for host/synthetic scope: app-owned secret-free facts and per-action eligibility drive TUI presentation, while the command adapter owns prepared contexts and the worker keeps generation/lifecycle control. Independent R1–R4 closure and required Rust gates passed. [M26 evidence](docs/evidence/milestone-26.md) records final inputs and limits. M27 remains pending; M9 remains retired/unaccepted and its real-system limitations remain unchanged.
- M18 was accepted on 2026-10-29: structured, accurate in-app Help, responsive wrapping and bounded scrolling passed independent R1/R2 closure, synthetic/PTY checks and pinned Rust completion gates. [M18 evidence](docs/evidence/milestone-18.md) records final inputs and limits. At that handoff, M19 had not started.
@@ -4188,7 +4188,7 @@ Evidence: docs/evidence/milestone-27.md. Outcome: not accepted. Handoff: stop af
- Milestone 8 delivered reviewed opt-in Alpine Testcontainers coverage for real IPv4 WireGuard peers, application lifecycle, saved/runtime separation, restoration, import/reissue, backup failures and the real Rustix reader. Host gates and three fresh real-container runs passed on one stable source fingerprint; M8-A1–A10 accepted. Real IPv6 behavior is unverified by user-authorized scope.
- Milestone 9 is retired and unaccepted: the reviewed disposable VM preparation and guarded first start did not establish Debian/systemd acceptance. The exact VM was powered off after the user stopped work. M9.2–M9.3 were not started; M9-A1–A9 are unchecked.
- M18–M25 handoffs remain complete. Stop after M25; begin M26.1 only on a separate request. Keep M16 validation limitations separate from TUI evidence. Do not access production, commit, deploy or resume VM work.
- M18–M26 handoffs remain complete. Stop after M26; begin M27.1 only on a separate request. Keep M16 validation limitations separate from TUI evidence. Do not access production, commit, deploy or resume VM work.
## Plan maintenance