Mission: Build a native, cross-platform application for reproducible Linux environments hosted on a self-managed Proxmox VE homelab.
Product promise: Define an environment once, provision it on Proxmox, then manage and access it from desktop or mobile whenever needed.
Status: Implementation in progress; Phase 0 feasibility remains open.
Audience: Coding agent / autonomous implementation agent
Approach: Vertical slices, small changes, documented decisions, working software at every milestone.
A user can:
- Connect the application to a self-hosted VMAnyware control plane.
- Connect that control plane to one Proxmox VE host or cluster endpoint.
- Inspect managed environments and their runtime status.
- Create a Debian-based environment from a prepared Proxmox template.
- Configure CPU, memory, disk, and SSH public key.
- Follow provisioning progress until the VM is ready.
- Start and stop the VM.
- Connect over SSH from desktop and mobile where networking permits.
- Create and restore VM snapshots.
- Delete an instance while retaining its environment definition, then recreate it.
- Self-hosted first: no mandatory vendor cloud or account service.
- Definition ≠ instance: deleting a VM must not delete its reusable definition unless explicitly requested.
- Proxmox is the first provider, not the domain model: keep provider-specific details behind an adapter.
- Reproducibility over magic: inputs, image/template versions, provisioning steps, and limitations must be explicit.
- Secure by default: least-privilege Proxmox credentials, verified TLS/SSH host keys, no exposed Proxmox admin API.
- Asynchronous operations: VM creation, snapshotting, and restoration are tracked jobs, not long blocking HTTP requests.
- Cross-platform with honest parity: share domain logic and UI where practical, but verify native/mobile capabilities independently.
- No premature infrastructure: no Kubernetes, multi-cloud, marketplace, multi-tenant SaaS, or plugin framework in the MVP.
Treat this as the default, not as permission to add dependencies without evaluating them.
| Area | Initial choice | Notes |
|---|---|---|
| Desktop/mobile app | Tauri 2, React, TypeScript | Validate iOS and Android constraints in Phase 0. |
| Shared client logic | Rust crates where useful | Keep shared logic independent of platform UI. |
| Control plane API | Rust + Axum | Single self-hosted Linux service. |
| Persistence | SQLite + SQL migrations | Appropriate for a single control-plane instance and MVP. |
| Virtualization provider | Proxmox VE API | No shelling into Proxmox for normal lifecycle operations. |
| Guest initialization | Proxmox templates + Cloud-Init | Start with one documented Debian template. |
| Environment definition | Versioned YAML schema | Validate strictly; never execute arbitrary config implicitly. |
| SSH | Rust SSH library and/or platform-native integration | Prove interactive PTY support on desktop and mobile early. |
| Networking | Private LAN/VPN first | Do not expose the Proxmox management API to the public internet. |
| Testing | Rust tests, API integration tests, UI checks | Use a test Proxmox environment; do not run destructive tests against an unconfirmed production host. |
Do not assume one SSH implementation or terminal renderer works equally well on every platform. Phase 0 must test this.
┌──────────────────────────────────────────────────────────┐
│ Native clients: macOS / Linux / Windows / iOS / Android │
│ Tauri + React/TypeScript │
│ Environment catalog · provisioning · snapshots · SSH │
└──────────────────────────┬───────────────────────────────┘
│ HTTPS + client authentication
┌──────────────────────────▼───────────────────────────────┐
│ VMAnyware control plane (self-hosted Linux service) │
│ │
│ Axum API │
│ Domain model and validation │
│ Operation orchestrator / job state │
│ SQLite persistence │
│ Environment schema and template renderer │
│ Proxmox provider adapter │
└──────────────────────────┬───────────────────────────────┘
│ Proxmox API over verified TLS
┌──────────────────────────▼───────────────────────────────┐
│ Proxmox VE │
│ VM templates · clones · lifecycle · snapshots · storage │
└──────────────────────────────────────────────────────────┘
SSH path:
Client ── direct SSH over LAN/VPN ──> Guest VM
Optional later: secure tunnel/broker if direct routing is unavailable.
domain: provider-neutral environment definitions, instances, snapshots, operations and state transitions.application/orchestrator: use cases and job execution.providers/proxmox: translate domain operations to Proxmox API calls and normalize results.persistence: SQLite repositories and migrations.api: HTTP routes, request validation, authentication and response types.client: API client, app UI, SSH experience and platform integrations.- Do not leak Proxmox response types throughout the domain model.
- Do not introduce a generic provider abstraction until the first Proxmox implementation demonstrates the necessary interface. Keep the seam narrow and practical.
Suggested initial repository:
vmanyware/
├── apps/
│ └── client/ # Tauri 2 + React + TypeScript
├── crates/
│ ├── domain/ # Provider-neutral models and state rules
│ ├── config-schema/ # YAML parsing and validation
│ ├── api-client/ # Typed HTTP client
│ └── ssh-core/ # SSH primitives, if shared implementation works
├── server/
│ ├── api/
│ ├── application/
│ ├── orchestrator/
│ ├── providers/
│ │ └── proxmox/
│ ├── persistence/
│ └── main.rs
├── templates/
│ └── debian-dev.yaml
├── examples/
│ └── kernel-lab.yaml
├── migrations/
├── docs/
│ ├── architecture.md
│ ├── decisions/
│ ├── development.md
│ └── proxmox-setup.md
├── ROADMAP.md
└── README.md
This is a target layout, not a requirement to create empty crates immediately. Start with the smallest coherent workspace and extract modules when there is a real boundary.
The definition must be versioned and separate from a live VM instance.
Example starting point (adjust names to the final schema; do not assume this is already implemented):
apiVersion: vmanyware.dev/v1
kind: Environment
metadata:
name: kernel-lab
description: Linux kernel development environment
spec:
image: debian-13
resources:
cpu: 4
memoryMiB: 8192
diskGiB: 40
provisioning:
cloudInit: true
sshAuthorizedKeys:
- ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA vmanyware-example
packages:
- build-essential
- clang
- gdb
- qemu-system-x86
- git
lifecycle:
snapshotAfterProvisioning: trueRequirements:
Implemented schema and defaults are documented in docs/definitions.md.
Public keys are inline contents; server-side key-file path resolution is not supported.
- Define and document the exact schema and defaults.
- Reject unknown or invalid fields unless forward compatibility explicitly requires another policy.
- Never store private SSH keys in environment YAML.
- Do not assume
imagenames map automatically to Proxmox templates. Maintain an explicit mapping from VMAnyware image identifiers to known template IDs and versions. - Keep secrets out of logs, error messages, state snapshots and generated diagnostics.
- Make configuration export deterministic.
- Record the definition version/hash used to create each instance.
- State clearly that recreating a VM from a definition is not the same as restoring its previous disk contents.
- Configuration reproducibility: same VM resources, template identifier, network choices and provisioning declaration.
- Software reproducibility: pinned image/template versions and package versions where possible.
- Work-state recovery: restore a snapshot or retain a persistent disk; do not claim this follows automatically from the definition.
The MVP must achieve level 1 and document level 2 limitations. Snapshot support provides a first path to level 3.
Start with these conceptual entities:
EnvironmentDefinition: reusable, versioned desired configuration.EnvironmentInstance: a concrete VM managed by VMAnyware.ProviderReference: provider name, Proxmox node, VMID and other required identifiers.Operation: asynchronous action with ID, type, status, progress/message where available, timestamps and safe error details.Snapshot: snapshot ID/name, VM reference, creation time and description where supported.TemplateReference: VMAnyware image identifier mapped to a known Proxmox template and version.
Keep the state model explicit:
- Desired state: what the user requested.
- Observed state: what Proxmox currently reports.
- Operation state: progress/result of a create/start/stop/snapshot/restore/delete task.
Do not equate “start API request accepted” with “guest ready for SSH”. Readiness must be a separate step and should have a timeout and clear failure state.
Operations should be safe to retry where possible. Handle duplicate requests, timeouts after a provider-side success, stale state and concurrent conflicting actions.
Use versioned routes (for example /api/v1). Exact response schemas must be documented and tested.
| Method | Route | Purpose |
|---|---|---|
GET |
/api/v1/health |
Service health, without leaking secrets |
GET |
/api/v1/environments |
List definitions and linked instances |
POST |
/api/v1/environments |
Validate definition and provision instance |
GET |
/api/v1/environments/{id} |
Read definition and runtime state |
PUT |
/api/v1/environments/{id} |
Update definition only when safe and explicitly supported |
POST |
/api/v1/environments/{id}/start |
Start instance |
POST |
/api/v1/environments/{id}/stop |
Stop instance |
POST |
/api/v1/environments/{id}/recreate |
Recreate instance from retained definition |
DELETE |
/api/v1/environments/{id}/instance |
Delete instance, retain definition |
DELETE |
/api/v1/environments/{id} |
Delete definition and instance only with explicit confirmation |
GET |
/api/v1/environments/{id}/snapshots |
List snapshots |
POST |
/api/v1/environments/{id}/snapshots |
Create snapshot |
POST |
/api/v1/environments/{id}/snapshots/{snapshotId}/restore |
Restore snapshot |
GET |
/api/v1/operations/{operationId} |
Read asynchronous operation state |
API rules:
- Long-running operations return an operation identifier, typically with
202 Accepted. - Validate request bodies and resource bounds before calling Proxmox.
- Use structured errors with stable error codes and safe user-facing messages.
- Add pagination only when needed; do not overbuild it for the initial single-user case.
- Do not expose arbitrary Proxmox API passthrough routes.
- Do not log authorization headers, tokens, private keys, Cloud-Init secrets or full sensitive payloads.
Goal: Resolve high-risk platform and infrastructure questions before building the full product.
Tasks:
- Create the repository and minimal Rust workspace.
- Create a minimal Tauri 2 app and verify development/build setup. (macOS arm64: dev/release builds and native bridge pass. Android ARM64/x86_64 debug APKs now build; Android 15 x86_64 actual bridge/key-restart/painted-launch passes. No mobile SSH or release claim.)
- Document the supported OS versions and toolchain. (Current macOS development baseline and unverified targets in docs/platforms.md; no release/minimum-OS guarantee.)
- Connect a Rust prototype to a disposable/test Proxmox VE environment using a dedicated least-privilege API token. (Local pve-lab: Rust probe reads 9.2.2, online node and empty visible inventory with a privilege-separated token and no ACL grants.)
- Verify TLS certificate handling and API-token permissions. (Local pve-lab: explicit CA/hostname verified; bad token, untrusted CA and wrong hostname rejected; effective token privileges confirmed empty. Template/provisioning ACLs remain unverified.)
- Read VM inventory and inspect a known template. (pve-lab: stopped Debian 13 template 9000, verified image/import/8 GiB Cloud-Init configuration; scoped reader HTTP config and Rust template listing pass. No guest boot.)
- Prototype clone → Cloud-Init configuration → start → poll task → verify readiness. (Disposable lab clone 9000→202: provider tasks OK, corrected target-specific user-data, first-boot Cloud-Init exit 0/done without fatal or recoverable errors, strict SSH/resources verified. Administrative manual prototype only; application mutation methods and least-privilege execution remain absent. See docs/cloud-init-compatibility.md.)
- Prototype create/list/restore snapshot on a disposable VM.
- Test SSH authentication, host-key verification, interactive PTY and terminal resizing on desktop. (Real macOS Tauri UI/IPC/agent/local-shell fixture passes, including resize/Ctrl-C/reconnect; normal startup, real guest/agent and mobile validation remain open.)
- Test whether the chosen terminal and SSH approach works on both iOS and Android.
- Record mobile limitations and any platform-specific implementation required. (ADRs 0034/0047/0048: application-key Unix path plus Android APK/native launch preparation; Android SSH/keyboard/lifecycle and iOS proof remain open.)
- Write short ADRs for the decisions that materially affect architecture.
Acceptance criteria:
- A disposable VM can be cloned and started through the API.
- Proxmox TLS is verified; no insecure certificate bypass is the default.
- Required Proxmox permissions are documented.
- SSH/terminal feasibility has been tested on desktop and both mobile OS families, or the MVP limitation is explicitly recorded.
- A short technical risk report identifies the next implementation path.
Exit rule: Do not proceed on the assumption that one shared terminal implementation works everywhere. If mobile PTY support is uncertain, resolve it with a working prototype or make a documented, deliberate MVP trade-off.
Goal: Establish the smallest maintainable structure.
Tasks:
- Add formatting, linting and test commands for Rust and TypeScript. (
make check, server/client variants and isolated SSH checks exist; current Linux server and frontend checks pass, native checks require WebKitGTK.) - Add a README with setup and development commands.
- Implement core domain types and validation.
- Define lifecycle and operation states.
- Add YAML schema parsing and deterministic serialization.
- Add SQLite schema and migrations.
- Add structured tracing and safe error handling. (Allowlisted JSON request/lifecycle events and fixed errors; subprocess redaction/shutdown tests pass.)
- Add a development configuration example that contains no secrets.
Acceptance criteria:
- Domain tests cover valid/invalid definitions and state transitions.
- Migrations run from a clean database.
- Invalid configuration fails before any provider call.
- No credentials are committed or printed in logs.
- A new contributor or agent can build and test the project using the README.
Goal: Manage an existing VM through a documented API.
Tasks:
- Implement the Axum service and versioned API routes. (Loopback Axum service; health, definitions, inventory, operations, preview/preflight and read-only VM status routes exercised by local HTTP/TLS tests. Confirmed start/shutdown enqueue routes are locally tested; other mutations remain pending.)
- Implement Proxmox client configuration and verified TLS. (Trusted/untrusted TLS and hostname checks covered by local fixtures; live host verification pending.)
- Support listing nodes/templates/managed VMs as required by the domain.
- Implement VM start and stop. (Confirmed HTTP enqueue, durable executor and fixed start/graceful-shutdown transport pass local HTTPS tests. Generated-HTTPS real binary start/restart/no-replay passes; approved real-target behavior remains unverified.)
- Poll and track Proxmox tasks without blocking the HTTP request.
- Persist operations and their terminal states.
- Add request validation, timeouts and safe error mapping.
- Add control-plane authentication before exposing it beyond localhost/private network. (Whole-API bearer authentication and fail-closed configuration pass local router/actual binary tests; listener stays loopback and remote verified-TLS/client integration remain pending.)
- Document the dedicated Proxmox user, token and minimum required permissions.
Acceptance criteria:
- An API client can list and start/stop a known test VM.
- Long-running work is represented by a persistent operation ID.
- A service restart does not silently lose the record of in-progress operations.
- Provider errors are translated into safe, actionable API errors.
- The service does not require a Proxmox administrator credential.
Goal: Create a VM from a reusable definition.
Tasks:
- Document how to prepare/import a supported Debian template in Proxmox. (Proposed Debian 13 amd64 procedure reviewed against official sources; real-host support validation pending.)
- Implement an explicit VMAnyware image-to-Proxmox-template mapping. (Strict server catalog and offline plan; live template verification pending.)
- Implement clone and resource configuration. (Opt-in confirmed create API and production worker now pass generated-HTTPS end-to-end journeys with clone/resources and optional disk expansion, restart and no duplicate mutations. Real-host validation remains open; ADR 0043.)
- Apply Cloud-Init settings and SSH public keys. (Durable fixed settings, attested image-default user, seed checks/regeneration and full local API/worker path pass. Actual mapped-template/guest validation remains open.)
- Implement provisioning/readiness polling with timeout and failure handling. (Durable stage/task recovery, fixed five-minute guest deadline and strict Cloud-Init/IP checks pass local storage/HTTPS tests. A minimal workflow completes only after guest proof; real infrastructure acceptance remains open.)
- Persist definition, definition hash, provider reference and operation state. (Local registration now retains canonical YAML/hash/revision and endpoint-scoped node/VMID in schema 3; instance observation operations are persisted; durable start/shutdown intent/provider-task linkage now passes local restart tests; provisioning intent/definition/catalog/plan/stage linkage is now locally tested; provisioning execution/readiness remain pending.)
- Implement environment list/detail views in the API. (Registered associations have bounded list/detail reads and scoped read-only observations; ownership reconciliation, lifecycle state and provisioning remain pending.)
- Implement deletion of an instance while retaining its definition. (Read-only retained-target/volume scope and permission-backed HA/replication review pass nine targeted generated-HTTPS/API checks. Fixed provider-effect/candidate/preservation scope now passes ten targeted checks and remains execution-disabled. Full-scope data-loss approval and schema-13 no-replay journal now pass storage/migration checks; independent GET-only VM/volume absence observation passes three HTTPS tests; schema-14 atomic retirement and retained deleted identities now pass local task/absence/storage/client checks. Standalone fixed DELETE/revalidating no-replay executor and GET-only recovery now pass eight HTTPS checks; independent default-off runtime/worker and actual generated-provider process crash/restart checks now pass; Full-scope confirmed HTTP enqueue and an actual authenticated server/generated-provider worker journey now pass; retained native commands now compile/pass 14 focused checks plus shared server-hash and affected native checks; explicit client review/dual consent/status now builds and passes focused Firefox simulated-IPC checks; scoped server GET recovery now passes eight HTTP/SQLite checks and actual no-provider/write-off restart recovery; Native saved-operation readers now compile/pass eight new and 14 affected checks; Client history/manual-ID recovery now builds/passes focused Firefox simulated-IPC checks; actual isolated Linux native deletion/restart recovery now passes with identical API retry, one provider DELETE, retained definition and unchanged GET-only recovery without provider/write flags; real deletion remains open. ADRs 0058–0064.)
- Implement recreation from the retained definition. (Read-only recreation preview now binds the retired source ID/hash/revision and exact saved YAML to a current-catalog target plan without provider access, reservation or enqueue; focused API/storage tests cover unchanged source, invalid requests and archived-definition integrity. Schema-15 atomic recreation storage now saves immutable source lineage, fresh approval and a distinct instance identity in the existing provisioning journal, with restart/key/source isolation tests passing. Confirmed HTTP enqueue and source-scoped GET recovery now pass focused retry/restart/refusal tests without provider requests; production API/worker generated-HTTPS recreation now passes clone-to-readiness, optional disk expansion, database reopen, fresh clone marker, source preservation and no-replay recovery. Source-bound live preflight now passes generated-HTTPS/HTTP checks with matching saved-source plan, explicit capability/check distinction and no reservation/mutation; native read-only retained review/clear now compile and pass five focused HTTPS tests; native retained confirmation/same-key retry/source-scoped status now compile/pass focused HTTPS tests with fresh-identity and readiness validation; explicit client deleted-source/target review, confirmation, same-key retry, status and new-guest SSH trust handoff now build/pass focused Firefox simulated-IPC checks; actual isolated Linux WebView/native/authenticated-server/worker/generated-HTTPS recreation now passes with identical lost-response retry, six expected mutations, preserved source/lineage and a distinct ready guest/SSH trust handoff; source-scoped latest-100 saved recreation history now passes HTTP/SQLite isolation/restart/corruption tests without provider or writes; stateless native source history/detail GET readers now compile/pass focused HTTPS and affected retained-workflow tests without installing consent; client saved-source history/manual-ID/refresh now builds and passes focused Firefox simulated-IPC checks with historical-state wording and no restored consent/SSH action; actual isolated Linux app/server restart recovery now passes with provider/catalog removed, all writes false, GET-only reads and unchanged provider/journal/source/target records; updated-APK acceptance and real VM acceptance remain open; ADRs 0065–0068.)
- Ensure partial failures are reported and recoverable; do not silently leave unmanaged VMs.
Acceptance criteria:
- A valid definition creates a VM from the documented template.
- CPU, memory, disk and SSH public key match the requested values where supported.
- Provisioning does not report “ready” until the configured readiness checks pass.
- A deleted instance can be recreated without rewriting its definition.
- A failed clone/provisioning operation leaves a visible error and has a documented cleanup/retry path.
- The same definition produces deterministic configuration inputs, while acknowledging that generated VM IDs and runtime addresses differ.
Goal: Support safe recovery and basic VM lifecycle management.
Tasks:
- List snapshots for an environment instance. (Scoped server/API listing passes generated-HTTPS tests; remote React/Firefox list flow and frontend build pass. Actual native compilation and three HTTPS command tests also pass with an isolated dependency prefix; actual isolated native WebView/IPC/authenticated-server/generated-provider listing also passes; real-provider evidence remains open. See docs/snapshots.md.)
- Create a snapshot with a validated, unique name and optional description. (Preflight, durable executor, confirmed HTTP and actual isolated native UI creation pass against generated HTTPS infrastructure. Read-only scoped server recovery also passes HTTP/SQLite tests; native recovery GET commands also pass HTTPS tests; client read-only history/saved-ID flow passes focused Firefox checks; actual app/server restart recovery of a succeeded operation also passes with provider configuration removed and writes off. Real-provider acceptance remains open. ADRs 0054/0055; docs/snapshots.md.)
- Restore a selected snapshot with an explicit destructive-action confirmation. (Read-only stopped-VM/disk-only restore preflight passes generated-HTTPS/API tests; explicit data-loss approval and durable no-replay journal now pass SQLite tests. Fixed one-shot rollback and opt-in executor now pass generated-HTTPS tests; actual server capability tests also pass. Confirmed idempotent HTTP enqueue, capability reporting and generated-provider queue-to-result checks now pass. Native retained restore prepare/confirm/read/ack commands now compile and pass 14 focused HTTPS tests. Explicit client VM/snapshot review, independent data-loss consent and retained status now build and pass focused Firefox simulated-IPC checks. Actual isolated native restore now passes against generated infrastructure, including same-key retry after a deliberately lost HTTP reply and exactly one provider rollback POST. Scoped read-only saved restore history/detail now pass 11 HTTP/SQLite tests without provider access or write flags. Native fixed GET recovery commands now compile and pass nine focused HTTPS tests without preparing consent. Explicit client saved-history/manual-ID/read-only refresh now builds and passes focused Firefox checks. Actual native app/server restart recovery now passes with provider configuration removed, all write flags off, GET-only reads and unchanged succeeded journal. Real guest-state recovery and platform/release gates remain open. ADRs 0056/0057.)
- Track snapshot and restore tasks as operations.
- Handle unsupported storage/snapshot conditions with clear errors.
- Document snapshot consistency and storage requirements.
- Distinguish snapshots from independent backups in the UI and documentation.
- Add guardrails for deletion and conflicting operations.
Acceptance criteria:
- Snapshot creation and restoration work on the supported test storage configuration.
- A restore operation cannot be mistaken for a successful result before Proxmox completes it.
- Unsupported snapshot operations fail safely and explain why.
- The UI makes the selected VM and snapshot clear before a destructive restore.
Goal: Deliver the core user journey on desktop and mobile.
Tasks:
- Implement control-plane connection setup and secure credential handling. (Actual Android x86_64 native verified HTTPS, private CA, bearer refusal and read-only recovery pass against an owned production service through direct emulator host-alias networking. Direct deployment, other platforms and full credential-storage acceptance remain open.)
- Implement environment catalog and detail screens.
- Implement create-environment form and configuration validation. (Actual Android definition/plan/explicit confirmation/API/production worker/readiness and SSH handoff pass with a generated HTTPS provider; direct emulator HTTPS/SSH transport also passes, with no real VM/deployment proof. ADRs 0052–0053.)
- Implement operation progress, errors and retry affordances.
- Implement start/stop/recreate/delete actions with confirmation where needed. (Start/graceful shutdown confirmation/resume pass simulated-IPC browser tests; native commands compile/pass HTTP tests. Isolated Linux WebKit/Tauri/Axum/generated-HTTPS start/shutdown also passes; remote HTTPS retained prepare/confirm/same-key/status commands now pass focused native tests, and remote start/graceful-shutdown React UI now builds/passes simulated-IPC checks; actual isolated Linux remote WebView/IPC/HTTPS/API/worker start/shutdown now also passes with one provider mutation per action despite identical-key accepted-response-loss retries; saved remote lifecycle recovery, packaged startup/real provider and full platform acceptance remain open.)
- Implement snapshot list/create/restore flows.
- Implement SSH connection management and known-host verification. (Application-key source passes Linux localhost tests and actual Android native strict trust/PTY/OS-shell checks. The integrated native creation fixture uses an explicit synthetic-guest endpoint override through the direct emulator host alias; deployed networking, full IME, real guest and other-platform gates remain open.)
- Implement a usable terminal experience on desktop.
- Implement a mobile terminal layout, software keyboard handling, special keys and reconnection.
- Test the same core journey on macOS, Linux, Windows, iOS and Android.
- Document platform-specific limitations and required permissions.
Acceptance criteria:
- The user can complete the main workflow without opening the Proxmox web UI.
- All long-running operations show progress and actionable failure states.
- Mobile layouts remain usable at small screen sizes.
- Secrets are stored using appropriate platform facilities where supported.
- SSH host keys are verified and unknown/changed host keys are handled explicitly.
- Platform support claims match tested capabilities; no untested parity claims.
Goal: Make the MVP safe to run on a real homelab.
Tasks:
- Review the threat model and trust boundaries. (Current-source review maps assets, attackers and ten boundaries to implementation/evidence, with residual risks and release work explicitly retained; docs/security.md. No penetration-test or deployment-security claim.)
- Ensure control-plane authentication is required on non-loopback interfaces.
- Restrict CORS and network binding to documented safe defaults.
- Add rate/size limits appropriate to the API. (Production process-wide admission now bounds burst/refill and concurrent handlers before authentication; focused refusal/refill/auth-order tests pass. Existing body limits remain; deployed proxy/connection/time/size acceptance stays open. ADR 0071.)
- Review secret redaction and error messages.
- Test expired/invalid tokens, TLS failures, network interruptions and Proxmox unavailability.
- Test app and service upgrades, migrations and restart recovery. (Current packaged server now passes isolated same-version stopped-directory backup/restore across three processes, retaining definition/operation/history/idempotency and removing post-backup state. An opt-in previous-schema fixture now also proves SQL schema-14 to current packaged schema-15 migration, preserving legacy definition/terminal operation/key and enforcing new lineage triggers across restart/restore. Older-binary upgrade, populated mutation-journal migration, app upgrade, systemd ownership/sandbox and real-provider recovery acceptance remain open.)
- Package the control plane as a Linux service with a documented configuration file. (Local Linux x86_64 optimized archive now includes systemd/sysusers, root-only config/template examples, copy-only staging installer, checksums and install/TLS/backup/upgrade/uninstall documentation. Staging/reinstall, unit syntax and actual packaged-process auth/restart/persistence checks pass; real target service-manager/sandbox/TLS acceptance remains open. ADR 0069.)
- Package clients for the platforms that have passed acceptance testing. (Current Android ARM64/x86_64 debug APKs now build and are packaged with verified signatures, version/ABI/SDK declarations, exact embedded-native hashes and manual install/connect/SSH instructions. Fresh exact-APK runtime/physical-device and release signing acceptance remain open; ADR 0070.)
- Write installation, backup/restore, troubleshooting and uninstall documentation.
- Tag a release candidate only when all required acceptance criteria pass.
Acceptance criteria:
- No default configuration exposes the Proxmox management API publicly.
- Proxmox credentials are least-privilege and can be revoked.
- The control plane can restart without corrupting stored definitions or losing operation history.
- Installation and recovery steps have been tested from a clean setup.
- Known limitations and security assumptions are documented.
The MVP is complete when all of the following work end-to-end:
- Connect client to the self-hosted control plane.
- Connect control plane to a supported Proxmox VE environment securely.
- Create an environment from the supported YAML definition.
- Clone a prepared Debian template and configure its resources.
- Configure SSH public-key access through Cloud-Init.
- Follow provisioning until the VM is ready.
- Start and stop the VM.
- Connect by SSH from supported desktop and mobile clients, subject to documented network requirements.
- Create and restore a snapshot.
- Delete the VM but retain the definition.
- Recreate the VM from the retained definition.
- See errors and recover from a failed or interrupted operation.
- Complete the workflow without using the Proxmox web UI.
- Install and operate the service using the documented instructions.
Do not implement these unless the user explicitly changes the scope:
- Additional hypervisors (libvirt, VMware, Hyper-V, cloud providers).
- Public hosted SaaS/control plane.
- Multi-tenant organizations, invitations, RBAC matrix or collaboration.
- Kubernetes deployment or distributed control plane.
- VM migration, HA orchestration or cluster scheduling.
- Full graphical console streaming (VNC/SPICE).
- Marketplace/community template repository.
- Snapshot replication or independent backup system.
- Automatic public relay/tunnel service.
- Arbitrary shell command execution on the Proxmox host.
- Automatic installation of a guest agent unless required and documented for the chosen template.
- Billing, analytics or telemetry by default.
These are implementation requirements, not optional polish:
- Use a dedicated Proxmox account/API token with only the permissions required for the supported workflows.
- Verify TLS for Proxmox API connections. Do not ship
danger_accept_invalid_certsor equivalent insecure defaults. - Never expose arbitrary Proxmox API passthrough to clients.
- Do not store private SSH keys in environment definitions or send them to the control plane for direct SSH connections.
- Verify SSH host keys; make first-use and changed-key behavior explicit.
- Store client credentials in platform-appropriate secure storage where possible.
- Require authentication when the control plane listens on a network interface.
- Redact credentials, tokens, private keys and sensitive Cloud-Init data from logs.
- Require explicit confirmation for destructive actions such as VM deletion and snapshot restoration.
- Never run generated YAML, scripts or user input on the Proxmox host as arbitrary shell commands.
- Bound resource values and validate identifiers before provider calls.
- Document that the control plane is a privileged service and must be reachable only through a trusted network or a securely configured access path.
- Unit tests: schema validation, domain transitions, operation state, error mapping and serialization.
- Provider tests: mock HTTP responses for Proxmox tasks, API failures, expired credentials and timeouts.
- Integration tests: run against a disposable Proxmox VM/template and test storage.
- End-to-end tests: create → ready → SSH → snapshot → modify → restore → delete instance → recreate.
- Platform smoke tests: launch the app and verify connection setup on each supported OS.
- Security tests: invalid credentials, certificate mismatch, changed SSH host key, malformed definitions, oversized payloads and unauthorized operations.
- Recovery tests: control-plane restart during a running operation and reconciliation against observed Proxmox state.
Never make destructive integration tests depend on a real user's default Proxmox environment. Require an explicitly configured test target and explicit confirmation before running them.
- Read this roadmap and the existing repository before making changes.
- Inspect existing code and conventions; do not overwrite functioning work to match the suggested folder layout.
- Start with Phase 0. Do not jump directly to a large implementation.
- Implement one small vertical slice at a time.
- Before each phase, list the intended changes and the acceptance criteria being targeted.
- After each slice, run relevant formatting, linting and tests; report actual results.
- Update this roadmap by checking off completed items only when evidence supports completion.
- Record significant architecture choices in short ADRs under
docs/decisions/. - Ask before destructive actions, production infrastructure changes, credential changes or operations that could affect existing VMs.
- Do not fabricate test results, successful builds, platform support or API behavior. Clearly mark untested items.
- Prefer official Proxmox and Tauri documentation when confirming API or platform behavior.
- Keep dependencies minimal and justify each new runtime dependency.
- Do not introduce abstractions, generic frameworks or extra infrastructure without a demonstrated requirement.
- If a decision is blocked by missing credentials, a test host or hardware, implement a mock/testable seam and document what remains blocked. Never invent credentials or infrastructure.
- At the end of each work session, report: files changed, behavior implemented, commands/tests run and their actual outcomes, known risks, and the single next recommended task.
A task is complete only when:
- the implementation exists;
- the relevant tests or a documented manual verification have run;
- errors and edge cases have been considered;
- docs/configuration examples have been updated when needed;
- no secret or unsafe default was introduced;
- the agent reports evidence rather than merely claiming completion.
Do not implement the full roadmap immediately. Start by:
- Inspecting the repository and available development environment.
- Proposing the smallest Phase 0 spike plan.
- Identifying the exact unknowns for Proxmox API access, Cloud-Init and mobile SSH/PTY support.
- Creating only the minimal project skeleton and tests needed for those spikes.
- Reporting findings and recommending the next phase.
Use these as starting points and verify current details during implementation:
- Proxmox VE API Viewer: https://pve.proxmox.com/pve-docs/api-viewer/
- Proxmox VE Administration Guide: https://pve.proxmox.com/pve-docs/pve-admin-guide.html
- Tauri documentation: https://v2.tauri.app/
- Axum documentation: https://docs.rs/axum/latest/axum/
- SQLite documentation: https://www.sqlite.org/docs.html
- Cloud-Init documentation: https://cloudinit.readthedocs.io/
A reproducible systems lab, available from any device.
The first version should do a few things reliably: define, provision, access, snapshot, restore and recreate. Build a trustworthy end-to-end workflow before expanding the provider matrix or adding infrastructure.