# Parallel-Fan-out Strategy: Phases 9 + 10 + 11 (and the Phase 12 GUI tab) > **For Claude:** This is a coordinator document, not an implementation plan. Each lane it points to has its own step-level plan that uses `superpowers:executing-plans`. Run the prep lane first; then the three follow-on lanes can execute concurrently in their own worktrees. **Goal:** Land Phases 9, 10, 11, and the Phase 12 GUI tab as quickly as possible by maximizing concurrent work across worktree-isolated agents. **Reality:** The naive "three worktrees, all branched off main" approach hits a hard wall — every lane wants to edit `gui/src/main.rs`, two of them want to edit `daemon/src/{dbus,state}.rs`, and at least one tab will need plumbing through `gui/src/bus.rs`. A direct fan-out merges sequentially in practice because every lane has a `main.rs` conflict to resolve. **Strategy:** A small **prep lane** establishes shared scaffolding — `AppContext`, the `--first-run` flag branch in `main.rs`, and the daemon's pending-flag query D-Bus methods — *before* the fan-out. After prep merges, the three follow-on lanes are file-disjoint and merge in any order. --- ## Conflict map (no prep) | File | Phase 9 + 12-GUI | Phase 10 (first-login) | Phase 11 (TOTP) | |---|:---:|:---:|:---:| | `gui/src/main.rs` | adds `Policy` + `Recovery` ViewStack tabs | adds `--first-run` flag + alternate startup branch | adds `TOTP` ViewStack tab | | `gui/src/bus.rs` | adds 5 policy/recovery methods | adds 1 pending-status method | adds ~3 TOTP methods | | `gui/src/keys_page.rs` | constructor migrates to `AppContext` | — | — | | `gui/src/app_context.rs` | **creates** | reads | reads | | `daemon/src/dbus.rs` | — | adds `GetPendingStatus` | adds 3 TOTP methods | | `daemon/src/state.rs` | — | promotes `has_pending` out of `#[cfg(test)]` | adds TOTP enrollment surface | | `daemon/src/policy_apply.rs` | — | — | renders `pam_google_authenticator.so` when TOTP required | | `common/src/types.rs` | — | adds `PendingStatus` wire type | adds `TotpEnrollment` + `TotpRecoveryCodes` wire types | | `daemon/Cargo.toml` | — | — | adds `totp` feature, `totp-rs`, `data-encoding` deps | | `Cargo.toml` workspace | — | — | adds `totp-rs`, `data-encoding`, `qrcode` to `[workspace.dependencies]` | | `gui/Cargo.toml` | — | — | adds `qrcode` (feature-gated) | | `debian/control` | — | maybe (Depends) | adds `Recommends: libpam-google-authenticator` | | `gui/src/firstrun.rs` | — | **creates** | — | | `gui/src/totp_page.rs` | — | — | **creates** | | `gui/src/policy_page.rs` + `recovery_page.rs` | **creates** | — | — | | `daemon/src/totp/mod.rs` | — | — | **creates** | **Read:** four files (`gui/src/main.rs`, `gui/src/bus.rs`, `daemon/src/dbus.rs`, `daemon/src/state.rs`) collide across two or three lanes. Without prep, every fan-out merge resolves them by hand. ## Conflict map (with prep lane in place) After the prep lane lands the shared scaffolding: | File | Phase 9 + 12-GUI | Phase 10 | Phase 11 | |---|:---:|:---:|:---:| | `gui/src/main.rs` | adds 2 lines (tab registrations) | **untouched** — uses prep's `--first-run` branch | adds 1 line (tab registration) | | `gui/src/bus.rs` | adds 5 methods (additive) | **untouched** — prep has the pending methods | adds 3 methods (additive) | | `daemon/src/dbus.rs` | — | **untouched** — prep has `GetPendingStatus` | adds 3 methods | | `daemon/src/state.rs` | — | **untouched** — prep promoted `has_pending` | adds TOTP methods | | `gui/src/app_context.rs` | reads | reads | reads | **Read:** the only remaining `main.rs` collisions are tab-registration lines from Lane A and Lane C — those slot into the same ViewStack but on disjoint lines and resolve trivially. All three lanes can land in any order. --- ## The four lanes ### Prep lane (single-agent, ~1 hr wall-clock) **Plan:** [2026-04-27-prep-shell-and-pending.md](2026-04-27-prep-shell-and-pending.md) Establishes the cross-cutting infrastructure. Drops Task 1 from the existing Phase 9 plan (AppContext refactor moves here). Adds the daemon's `GetPendingStatus` D-Bus method that Phase 10 needs. Adds `--first-run` flag parsing + a stub `firstrun::run()` so Phase 10 fills it without re-touching `main.rs`. **Acceptance gate:** workspace tests pass, the `--first-run` flag is parseable but no-ops with a placeholder, the new D-Bus methods round-trip through the p2p test fixture. **MUST land first.** All three follow-on lanes branch off the merge of prep into main. ### Lane A — GUI policy + recovery (Phase 9 + Phase 12 GUI tab) **Plan:** [2026-04-27-phase-9-and-12-gui.md](2026-04-27-phase-9-and-12-gui.md) (already written — pre-merge of prep, drop Task 1). **File footprint:** `gui/src/{policy_form,policy_page,recovery_page}.rs` (new), additive `gui/src/bus.rs` policy + recovery methods, two `add_titled_with_icon` lines in `main.rs`, optional `keys_page.rs` ToastOverlay tweak. ### Lane B — First-login flow (Phase 10) **Plan:** [2026-04-27-phase-10-firstrun.md](2026-04-27-phase-10-firstrun.md) **File footprint:** `gui/src/firstrun.rs` (new — fills the prep stub), `gui/data/authforge-firstrun.desktop` (new autostart), `debian/authforge-gui.install` (install autostart entry). ### Lane C — TOTP support (Phase 11) **Plan:** [2026-04-27-phase-11-totp.md](2026-04-27-phase-11-totp.md) **File footprint:** `daemon/src/totp/mod.rs` (new), additions to `daemon/src/{state,dbus,policy_apply}.rs`, `daemon/Cargo.toml` feature flag, `gui/src/totp_page.rs` (new), one `main.rs` tab line, `common/src/types.rs` (two new wire types), `debian/control`, workspace + GUI `Cargo.toml`. --- ## Execution model ### Prep lane ```bash git worktree add .claude/worktrees/prep-shell-and-pending -b feature/prep-shell-and-pending cd .claude/worktrees/prep-shell-and-pending # follow 2026-04-27-prep-shell-and-pending.md task-by-task # tests + clippy + fmt + release build green # merge --no-ff back to main git worktree remove .claude/worktrees/prep-shell-and-pending git branch -d feature/prep-shell-and-pending ``` ### Three concurrent follow-on lanes After prep merges, dispatch three subagents in parallel via `superpowers:dispatching-parallel-agents`: ```text Subagent 1 (worktree feature/phase-9-and-12-gui): → executes 2026-04-27-phase-9-and-12-gui.md (skip Task 1, prep handled it) Subagent 2 (worktree feature/phase-10-firstrun): → executes 2026-04-27-phase-10-firstrun.md Subagent 3 (worktree feature/phase-11-totp): → executes 2026-04-27-phase-11-totp.md ``` Each lane verifies tests + clippy in its own worktree before reporting. Once all three return green, merge them serially into main in any order. The `gui/src/main.rs` ViewStack-tab additions from Lane A and Lane C may produce a 1-line conflict per merge — resolve by including both tab lines. ### Merge order rule **Any order works.** The conflict on `gui/src/main.rs` is bounded to "both lanes added a tab line in the same area." Resolve by keeping both. No semantic interaction. --- ## Risks | Risk | Mitigation | |---|---| | Prep lane mis-defines the `AppContext` shape and Lane A's plan needs revision. | Lane A's plan is already in this repo and was written assuming the AppContext shape that prep will land. Prep mirrors the structure verbatim — see prep Task 1. If prep's Task 1 deviates, update Lane A's plan in the same commit. | | Concurrent `cargo` runs across three worktrees race on `~/.cargo/registry` lock. | Brief synchronization (per Phase 4+5 closeout note), not a hang. Acceptable. | | Phase 11 introduces a `totp` Cargo feature that's default-on; CI must build with feature off too. | Add a `cargo build --workspace --no-default-features` line to the CI workflow as part of Lane C's Task 1. | | Lane B's `--first-run` runtime behavior depends on a daemon that's running. | Watchdog keeps the modal alive 60s; if no daemon, the modal logs and exits gracefully (mirrors Phase 8's disconnect-banner pattern). Spelled out in Phase 10 Task 4. | | Lane C's `pam_google_authenticator.so` must already be installed for the rendered profile to validate. | `debian/control` lists it as `Recommends:`, not `Depends:` — installing the daemon doesn't pull it in unless the user opts in. Daemon's `policy_apply::apply` uses the existing rollback path if `pam-auth-update` rejects the profile. | | Three subagents producing simultaneous output saturates the main session's context. | Subagents run with `report in under 200 words` instructions in their dispatch prompts; details live in commit messages. | --- ## Once-fully-landed roll-up After all four lanes merge: - Phase 9: ✅ Code complete (GUI smoke deferred to Phase 14) - Phase 10: ✅ Code complete (full-flow VM smoke deferred to Phase 14) - Phase 11: ✅ Code complete (TOTP enrollment + recovery codes; `pamtester` smoke deferred to Phase 14) - Phase 12: ✅ Done (backend, GUI tab, end-to-end CLI all in) **Roadmap progress** jumps from 13/19 to **17/19** in the same session, leaving only Phase 13 (deb finalization), 14 (PPA + smoke), 17 (integration tests), 18 (user docs), and the v1.0 release tag.