billet
A stateless, configurable manager for cloud development Hosts (Azure VMs) and the repos' devcontainer Workspaces that run on them.
Concepts
- Host — a cloud VM that runs containers.
- Workspace — a repository's devcontainer running on a Host.
- HostProvider — the backend seam that implements Host lifecycle (Azure VM today; DevPod / Dev Box later).
- Berth — the Workspace runtime contract billet publishes under
templates/workspace/, versioned independently of billet byberth.version(ADR-0012). - Locker — one named compose volume persisting one tool's state under the login user's home, declared only in the consumer's compose file.
The full glossary, the map of the five contexts billet collaborates with, the live consumer inventory and the open questions are in the context map.
Architecture
billet is decomposed by volatility (Löwy closed architecture). Higher layers may import
lower ones; never the reverse:
| Layer | Role |
|---|---|
billet.cli |
Typer client / composition root |
billet.workspace |
Workspace subsystem (contracts, engine, manager) |
billet.host |
Host subsystem (manager) |
billet.access |
ResourceAccess (Azure VM provider, registry, ssh-config, container, source) |
billet.contracts |
data contracts + service Protocols (the HostProvider seam) |
billet.infrastructure |
side-effecting primitives (az, ssh, process) |
billet.shared |
cross-cutting utilities |
The rationale for this decomposition — the volatility axes, the dedicated contracts
layer, the HostProvider seam, and dry-run/plan layering — is recorded in
ADR-0001. The Workspace subsystem and
its devcontainer.json-as-data-contract boundary are recorded in
ADR-0002; the multi-workspace port↔container binding
contract in ADR-0003. What billet does
and does not create in the cloud — it owns registry-described instances (cold provision,
start, deallocate, connectivity) and only adopts durable infrastructure like networks and
identity — is recorded in ADR-0005.
The runtime contract a Workspace implements for billet to reach it is the Berth, named and
versioned in ADR-0012. Its entrypoint repairs the ownership of
named-volume mount targets at container start instead of relying on the image to pre-create
them (ADR-0013). What billet
may write into a container it started, and what it never writes — anything a build reads — is
the definition/state boundary of ADR-0014. The
doctor verb reports each Workspace's Berth drift against the Berth the installed billet
ships, over one SSH session per Host (ADR-0015); its runtime
report (container state and the entrypoint's Locker-ownership log) is next.
Status
Both subsystems run in Python. The Host subsystem (billet host up|stop|pin-ip|specs) drives the
VM; the Workspace subsystem (billet add|ls|doctor|start|stop|connect|ssh-config|rm) clones,
builds, bootstraps, and connects a repo's devcontainer on a Host, reading each repo's
.devcontainer/devcontainer.json as a read-only data contract. The Python tool now fully
replaces the original shell scripts lifted from gswa-backend, which have been removed.
Because those facts are read live, billet ssh-config renders only the Workspaces already
cloned on a running Host; any other is skipped with a warning instead of failing the whole
run, so one un-started Workspace never withdraws the other aliases
(ADR-0010).