diff --git a/session-logs/2026-06/2026-06-23-howard-ampipit-migration-recovery-rmm.md b/session-logs/2026-06/2026-06-23-howard-ampipit-migration-recovery-rmm.md new file mode 100644 index 00000000..b5267c37 --- /dev/null +++ b/session-logs/2026-06/2026-06-23-howard-ampipit-migration-recovery-rmm.md @@ -0,0 +1,89 @@ +# Session — AMPIPIT migration + Recovery Environment RMM add-on (2026-06-23) + +## User +- **User:** Howard Enos (howard) +- **Machine:** Howard-Home +- **Role:** tech + +## Session Summary + +Picked the AMPIPIT project (then at `C:\AMPIPIT`) back up to work on the headline feature: a local recovery partition with an RMM agent baked in so offline/broken Windows can be repaired remotely. Ran a multi-agent review of the codebase: AMPIPIT is a mature Rust+Slint Windows deploy/recovery toolkit (Phases 0-5 code-complete, 832+ tests, pre-release; Phase 6 hardware validation pending). The recovery-partition + RMM feature is fully designed (ADR-007/ADR-014/ADR-047) but unbuilt — it is AMPIPIT's v1.2/v2 work. A feasibility spike confirmed the GuruRMM endpoint agent can run in WinPE (GO-WITH-WORK: pure Rust, no .NET, console mode exists, SChannel TLS, remote script execution works), with one must-fix: ephemeral identity creating a ghost agent per PE boot. + +Verified directly in the GuruRMM agent source that the must-fix is solvable with zero GuruRMM change: `agent/src/device_id.rs` reads `HKLM\SOFTWARE\GuruRMM\DeviceId` before minting a new UUID (`get_device_id` -> `read_any_persisted`, registry first; new UUID only when no location has one). So AMPIPIT's recovery launcher can pre-seed that registry key (ideally from the offline Windows volume's existing device-id so the recovery boot rejoins the fleet as the same agent). Authored ADR-045 (RmmAdapter trait) and ADR-048 (GuruRMM recovery-partition agent + PE-stable identity) in AMPIPIT's DECISIONS.md, and created an `ampipit-build` skill encoding the project's coordinator/agent routing, Ollama-first rule, ADR-047 first-party-core gate, and review chains. + +Migrated AMPIPIT into the fleet at Howard's request, with a hard constraint of losing no work and abandoning the public GitHub. Created a PRIVATE Gitea repo `azcomputerguru/ampipit`, pushed the complete history (49 commits + 2 tags), verified the remote `main` SHA matched local, then added it as a submodule at `projects/msp-tools/ampipit` (matching the guru-rmm pattern). `C:\AMPIPIT` was left in place (Howard chose "not yet" on removal); GitHub got nothing new and is now stale/safe to delete. + +The product direction then pivoted significantly: AMPIPIT becomes the engine behind a paid GuruRMM **add-on** (the "Recovery Environment" integration). The shipped product has NO Claude (Claude is a test-time convenience only); remote control of the recovery env is via GuruConnect (first-party). The MSP configures recovery settings in the RMM, pushes the image to fleet/site/machine, installs a recovery partition, then repairs/backs-up/reinstalls Windows through the RMM. Captured this as Feature 10 in `guru-rmm/docs/RMM_THOUGHTS.md` (Status: Raw). Howard corrected an over-optimistic "build in place from the machine's own WinRE with only in-box tools" claim — that is best-case, not guaranteed; the design must work on ALL Windows machines (incl. no/disabled WinRE) and needs a detect-and-fallback PE-base source plus flexible multi-source Windows-ISO delivery (official download / RMM-hosted on B2 / client 3rd-party storage / pushed / pre-staged). Recorded this in the AMPIPIT design doc, sent Mike a 6-question Discord DM to unblock shaping, and launched a background feasibility spike on the no-WinRE recovery-partition path. + +## Key Decisions + +- **Remote agent = GuruRMM (first-party), not ScreenConnect.** Rides the pluggable `RemoteAccessProvider` trait per ADR-047; never compiled into core. Later refined: GuruConnect for interactive remote control + GuruRMM agent for fleet/scripts; Claude NOT in shipped product. +- **Identity fix needs no GuruRMM change.** Verified read-first registry behavior in `device_id.rs`; AMPIPIT pre-seeds `HKLM\SOFTWARE\GuruRMM\DeviceId` at recovery boot. Preferred source = the offline volume's existing device-id (same fleet record). +- **Migrate AMPIPIT as a private Gitea submodule**, not a monorepo folder — best preserves independent history (Howard's stated priority) and matches guru-rmm/guru-connect. Created under the shared `azcomputerguru` Gitea account (owns claudetools/gururmm). +- **No public GitHub.** Howard is deleting the public repo; AMPIPIT is private on Gitea only. Pushed nothing new to GitHub. +- **AMPIPIT = paid GuruRMM add-on / integration** (some partners enable it; costs extra; billing deferred until it works). Engine stays a separate submodule the RMM calls. +- **Fleet agents take over AMPIPIT work; do not duplicate agents into ClaudeTools.** AMPIPIT's 6 submodule agents kept as reference (they don't load in fleet-rooted sessions). The `ampipit-build` skill (to move into ClaudeTools) carries AMPIPIT's rules into the fleet session. +- **PE-base reliability is the crux and is unresolved.** Must not assume local WinRE; supply our own pushed/hosted base WIM as the universal fallback. Windows ISO delivery must be multi-source with fallbacks. + +## Problems Encountered + +- **Git slip on the guru-rmm submodule.** The submodule was checked out on an in-progress feature branch (`fix/software-uninstall-polish`), so the first "Feature 8" RMM_THOUGHTS commit (`0f873f6`) landed on that branch and was pushed. Fixed: `git reset --hard bd6dd27` + `git push --force-with-lease` restored the branch/origin to exactly `bd6dd27` (only my own top commit removed); then switched to `main`, where Mike had already used Feature 8/9 today, so the entry was re-added as **Feature 10** (`af3445b`) and the submodule was returned to the feature branch at `bd6dd27` (session-start state). +- **No Gitea API token in vault — only passwords.** The `services/gitea*` entries store passwords, not tokens. Used Gitea Basic auth over the API. `azcomputerguru` is the shared user account (type=user, owns the org-named repos), not a Gitea org — so repo creation used `POST /user/repos` as `azcomputerguru`, not `/orgs/.../repos`. +- **Over-stated feasibility.** Claimed local-WinRE in-box build as a guarantee; Howard corrected it. Reframed to detect-and-fallback and recorded the open feasibility questions. + +## Configuration Changes + +**AMPIPIT submodule (`projects/msp-tools/ampipit`, repo `azcomputerguru/ampipit`):** +- Created `.claude/skills/ampipit-build/SKILL.md` (new skill). +- Created `docs/RECOVERY_RMM_DESIGN_SLICE.md` (design slice; later updated with verified identity finding + reliability/source strategy section 8). +- Edited `DECISIONS.md` — authored ADR-045 + ADR-048; reframed ADR-048 to GuruConnect/Claude-test-only. +- Edited `.gitignore` — added `/.claude/worktrees/`. +- Preserved `.claude/settings.local.json` (machine-local, gitignored) by copying from `C:\AMPIPIT`. + +**GuruRMM submodule (`projects/msp-tools/guru-rmm`):** +- `docs/RMM_THOUGHTS.md` — added Feature 10 (Recovery Environment add-on) to index + full section, on `main`. + +**ClaudeTools (parent):** +- `.gitmodules` + gitlink — added submodule `projects/msp-tools/ampipit` (tracks main). +- `.claude/memory/project_ampipit.md` — new project memory. +- `.claude/memory/MEMORY.md` — added project_ampipit index line. + +## Credentials & Secrets + +- No new credentials created or rotated. Created a new **private Gitea repo** `azcomputerguru/ampipit` (a resource, not a secret). +- Used existing vault entries (values not printed): `services/gitea` (shared `azcomputerguru` Gitea account password — used for repo create + all pushes to the new repo) and `services/gitea-howard` (Howard's Gitea password — used only for an API auth sanity check). Both already vaulted; no changes. + +## Infrastructure & Servers + +- **Gitea:** `git.azcomputerguru.com`. New private repo `azcomputerguru/ampipit`. Existing: `azcomputerguru/gururmm`, `azcomputerguru/claudetools`. `azcomputerguru` is the shared push account (Gitea user, type=user) that owns these repos. +- **GuruRMM agent endpoints:** `wss://rmm-api.azcomputerguru.com/ws` (websocket), `https://rmm-api.azcomputerguru.com` (enroll), outbound 443/TLS (SChannel via native-tls on Windows). +- **GuruRMM agent identity (Windows):** `HKLM\SOFTWARE\GuruRMM\DeviceId` + `%ProgramData%\GuruRMM\.device-id`. Server dedups on `(site_id, device_id)`. +- **Discord:** Mike user id `264814939619721216`; DM sent (message_id `1519187310640631872`). + +## Commands & Outputs + +- Gitea repo create (Basic auth as `azcomputerguru`): `POST /api/v1/user/repos {name:ampipit, private:true}` -> `201 created azcomputerguru/ampipit private=True`. +- Push full history: `git push gitea --all` (9 refs: main + 8 worktree-agent-* branches) + `--tags` (v0.4.0-m4-close, v0.5.0-m5-close). Verified: remote main `41b5dfab...` == local; 49 == 49 commits. +- Submodule add: `git -c http.extraHeader="Authorization: Basic " submodule add ... projects/msp-tools/ampipit` -> HEAD 41b5dfa. +- guru-rmm branch fix: `git reset --hard bd6dd27 && git push --force-with-lease origin fix/software-uninstall-polish` -> `+ 0f873f6...bd6dd27 (forced update)`. +- Discord DM: `printf '%s' '<6 questions>' | bash .claude/scripts/discord-dm.sh mike` -> `[OK] sent to mike (DM)`. + +## Pending / Incomplete Tasks + +- **Mike to answer the 6 Feature 10 questions** (Discord DM): image storage/delivery, agent big-file channel, "machine in recovery" model, App Center fit, GuruConnect-in-WinPE resourcing, official-download reinstall baseline. +- **No-WinRE recovery-partition feasibility spike** running in background — verdict pending (can we build a bootable recovery partition on a machine with no usable WinRE; PE-base source + fallback; edge cases). +- **GuruConnect-in-WinPE feasibility spike** — to run after Mike's input (gates the remote-control half). +- **Move `ampipit-build` skill into ClaudeTools** `.claude/skills/` (Howard confirmed) — held so it reflects the final add-on/GuruConnect/Claude-test-only framing; update routing to fleet agents; remove the submodule copy. +- **AMPIPIT design slice remaining:** `RecoveryProfile` struct + `src/recovery/` pipeline steps into SPEC.md; refresh REC-*/RA-* in REQUIREMENTS.md. +- **AMPIPIT Phase A engine build** (recovery install pipeline, RemoteAccessProvider impls, repair-script library) — after spike + Mike, via fleet `coding -> code-review -> security-review`. +- **C:\AMPIPIT** left in place (Howard chose not to delete yet); GitHub repo `Howweird/AMPIPIT` to be deleted by Howard. +- **Advance parent guru-rmm submodule pointer** to pick up Feature 10 on a normal sync (left at session-start state this session). + +## Reference Information + +- AMPIPIT design doc: `projects/msp-tools/ampipit/docs/RECOVERY_RMM_DESIGN_SLICE.md`. +- RMM feature: `projects/msp-tools/guru-rmm/docs/RMM_THOUGHTS.md` Feature 10. +- ADRs: AMPIPIT `DECISIONS.md` ADR-045 (RmmAdapter), ADR-048 (recovery agent + identity), ADR-047 (first-party core), ADR-007/ADR-014 (remote access / recovery agent). +- Commit SHAs — ampipit: `41b5dfa` (skill+design slice), `b8c0fd1` (ADR-045/048), `ab1b7c5` (ADR-048 reframe), `4324c07` (reliability/source). guru-rmm: `af3445b` (Feature 10 on main); feature branch restored to `bd6dd27`. claudetools: `8e512d1` (submodule add). +- GuruRMM agent source for PE: `projects/msp-tools/guru-rmm/agent/` — `device_id.rs` (identity), `main.rs` (run/install), `scripts.rs`/`websocket.rs` (remote exec), `Cargo.toml` (features: native-service default, legacy console build). +- Feasibility: GuruRMM-agent-in-WinPE = GO-WITH-WORK; build console agent via `cargo build --no-default-features --features legacy` or `gururmm-agent run`.