5.7 KiB
Context
The root project currently discovers every Python package, including cloud, through one setuptools configuration and resolves dependencies without a committed lockfile. The cloud code depends inward on Runtime and workflow packages, while composition-safety tests prohibit those inner packages from importing cloud back. The packaging migration must preserve that dependency direction and all existing Python import paths while preparing the repository for separately runnable cloud and host applications.
Goals / Non-Goals
Goals:
- Configure a uv workspace with one shared lockfile and explicit internal workspace dependencies.
- Retain the existing root project as the
device-agent-runtimemember to minimize migration risk. - Move the existing
cloudPython package into apackages/cloud-platformmember published asdevice-cloud-platform. - Preserve
cloud.*imports, tests, local Runtime commands, and current feature behavior. - Define repeatable workspace-aware commands for synchronization, tests, builds, and package selection.
- Keep the dependency graph one-directional: cloud platform depends on device Runtime, never the reverse.
Non-Goals:
- Creating a runnable distributed cloud control plane or host worker.
- Adding remote dispatch, heartbeat endpoints, authentication, PostgreSQL, or scheduler processes.
- Splitting
cloud.sdkinto a separate namespace distribution during this migration. - Moving the Vue/Vite console into the Python workspace.
- Changing public REST/MCP contracts or Runtime execution behavior.
Decisions
D1: Keep the Runtime project at the repository root
The root pyproject.toml remains the device-agent-runtime project and becomes the workspace root. This avoids relocating all established inner packages at once and keeps existing developer commands and editable installs recognizable.
Alternative considered: move all Runtime packages under packages/device-runtime. Rejected for this change because it multiplies path, package-discovery, test, and documentation churn without being required to establish workspace isolation.
D2: Extract cloud as one distribution before splitting applications
The existing cloud package moves under packages/cloud-platform/cloud and is built by a new device-cloud-platform project. Its current cloud.sdk subpackage stays in the same distribution so the public import path remains stable and Python namespace-package coordination is unnecessary.
The subsequent cloud integration change may add apps/cloud-api and apps/device-host-agent as workspace members that depend on device-cloud-platform and, where needed, device-agent-runtime.
Alternative considered: create Runtime, cloud domain, SDK, API, and host-agent distributions in one migration. Rejected because package-boundary failures would be difficult to distinguish from new distributed behavior.
D3: Express internal dependencies as uv workspace sources
device-cloud-platform declares a normal project dependency on device-agent-runtime, with [tool.uv.sources] marking it as a workspace source. The Runtime project does not declare a dependency on the cloud project. The workspace uses a single committed uv.lock generated from all members.
D4: Preserve import paths and enforce ownership with tests
Moving package files must not rename cloud.* modules. Existing tests remain runnable from the workspace root. Packaging tests additionally verify that each member builds, imports resolve from the intended distribution, and forbidden reverse dependencies remain absent.
D5: Keep heavy optional concerns out of packaging scope
The migration does not change current dependency semantics merely to optimize installation size. Optional dependency groups can be introduced only when existing tests demonstrate that Runtime and cloud installations remain complete and documented; behavioral cloud work remains deferred.
Risks / Trade-offs
- [Risk] Moving
cloud/changes source paths used by tests or tooling. -> Mitigation: preservecloud.*imports, update only path-sensitive configuration, and run the full non-integration suite from a clean workspace environment. - [Risk] Editable installs can hide missing build metadata. -> Mitigation: build every member and test imports from built wheels in addition to editable workspace tests.
- [Risk] A shared lockfile can resolve dependencies unused by a selected member. -> Mitigation: keep member dependency declarations accurate and verify member-scoped
uv run --packagecommands. - [Risk] Existing developer environments may retain stale editable paths. -> Mitigation: document a clean
uv syncmigration and verify the workspace with a newly created environment in CI. - [Trade-off]
cloud.sdkis not independently installable yet. -> Accepted to avoid namespace and API churn; it can be separated later under a deliberately stable top-level package name if distribution size becomes material.
Migration Plan
- Add workspace configuration to the root project and create the
packages/cloud-platformproject metadata. - Move the
cloudpackage without changing module names, then update setuptools discovery and path-sensitive tests. - Declare the cloud-to-runtime workspace dependency and generate
uv.lock. - Update development and CI commands to use
uv sync, root tests, member-scoped builds, and lock verification. - Run the complete non-integration test suite and build/import smoke tests for both distributions.
- Roll back by restoring the
cloudpackage to the root discovery set and removing workspace metadata and the generated lockfile; no data migration is involved.
Open Questions
- None blocking. Separate
cloud-apianddevice-host-agentmembers are intentionally owned by the follow-up cloud integration change.