1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
[]
# `cloud` is squatted on crates.io (an unrelated 0.0.0 crate), so the published
# name carries the yah- prefix per W230. Consumers keep the short `cloud` extern
# name via `cloud = { package = "yah-cloud", … }` — same trick this manifest
# already uses for workload-spec and local-driver — so no `use` path changed.
= "yah-cloud"
= true
= true
= true
= true
= true
= "Declarative cloud substrate for yah-managed camps: .yah/cloud/ config schema, MachineProvider drivers (Hetzner + local containerd), cloud-init rendering, and the pond/mesofact reconcilers."
= ["cloud", "provisioning", "hetzner", "cloud-init", "reconciler"]
= ["config", "development-tools"]
# R743-T7: integration tests are declared explicitly below, not autodiscovered
# from tests/*.rs — `tests/main.rs` mods four former per-file binaries into one
# `main` target so they link once. Only affects `[[test]]` discovery; the
# `examples/load_probe.rs` example is still picked up automatically.
= false
# R542 gate CLEARED (2026-07-23): this crate is LAST in the workspace's publish
# order and every dep it waited on is now satisfiable — yah-base, kamaji and
# velveteen were already on crates.io; yah-hetzner + yah-almanac published today;
# velveteen-exec publishes in the same wave, ahead of this workspace (qed before
# yubaba in scripts/release-all.sh's OSS_ORDER). Dropping publish=false; the
# `cloud` name is squatted so it ships as `yah-cloud` (see [lib] name below and
# the `package =` aliases at every consumer).
[]
# Lib target keeps the short name so the crate's own tests/examples
# (`use cloud::…`) and every downstream `cloud::` path stay valid.
= "cloud"
= "src/lib.rs"
[]
# Enable the local-docker MachineProvider (tier 1 integration testing).
# Requires a reachable containerd socket: Colima (`colima start --runtime containerd`)
# on macOS, or the system socket on Linux.
= ["dep:containerd-client", "dep:prost-types"]
# Derive JsonSchema on the public config types so xtask can emit per-kind
# JSON Schemas to .yah/schema/*.toml.schema.json (R222 B4). Off by default;
# the cloud crate's runtime binary deps don't carry schemars.
= ["dep:schemars", "workload-spec/json-schema", "local-driver/json-schema"]
[]
# Signalling a previously-spawned local-process workload (SIGTERM/SIGKILL on
# re-reconcile) and probing whether its recorded pid is still alive. Already in
# this workspace's tree via kamaji; declared here so the local_process
# reconciler doesn't shell out to `kill`.
= "0.2"
# WorkloadSpec — typed wire format for yubaba workloads. Used by WorkloadConfig
# to validate workload TOML against the schema (R092-F1).
= { = "yah-workload-spec", = "0.8.46" }
# Almanac feed configs + OnChangeConfig — dispatch_on_change maps on_change
# to the correct reconciler (R330-F4). Cross-workspace since R746-T10 (it lives
# in oss/mesofact now), so it drops the `path =` and resolves through this
# workspace's `[patch.crates-io]` block like every other out-of-tree dep.
= { = "0.8.46" }
# Shared credential vault — HetznerDriver::from_default_sources() reads
# hetzner-api-token / hetzner-s3-access-key / hetzner-s3-secret-key
# from this vault, falling back to HETZNER_* env vars (R040-F9).
= { = "0.8.46" }
# Shared Hetzner Cloud API client — transport, bearer auth, and server/SSH-key
# operations. Cloud crate adds S3 bucket ops and MachineProvider trait impl on top.
= { = "../hetzner", = "0.8.46" }
# R859-F2: the floating-IP seam + the pure ingress-failover planner, which used
# to live in this crate's `provider::floating_ip`. Extracted so `yubaba` can
# depend on the planner without depending on `cloud` — the same carve-out
# R374-F3 made for `yah-local-driver` below, and made again here by operator
# decision (2026-09-08) rather than reversing it. Short extern name `floating_ip`.
= { = "yah-floating-ip", = "../floating-ip", = "0.8.46" }
# R859-F3: the Hetzner/OVH/Vultr HTTP clients that used to be
# `provider::{hetzner,ovh,vultr}_floating_ip`. Moved out for the same reason as
# the seam above — the fleet daemon needs them to actually MOVE an IP, and it
# must not link `cloud` to get them. What stayed here is the envoy verb layer
# (`provider::floating_ip_envoy`) and the `fob` credential lookup.
= { = "yah-floating-ip-adapters", = "../floating-ip-adapters", = "0.8.46" }
# Object-store trait + R2 impl — publish_to_r2 delegates PUT/GET ops here (R498-F5).
= { = "0.8.46" }
# W272 mesofact bundle store (R599-F1) — content-addressed blob/manifest publish.
# `store` feature pulls the ObjectStore-backed publish/materialize surface.
= { = "0.8.46", = ["store"] }
# Local-tier infrastructure primitives (docker-CLI driver + S3 SigV4 helpers).
# Both cloud and yubaba depend on this — moved out of cloud in R374-F3 so
# yubaba could own MinIO lifecycle without a reverse yubaba→cloud dep.
= { = "yah-local-driver", = "0.8.46" }
# Kamaji supervisor — the dev-tier capability drivers (yah-pg-dev,
# yah-smtp-dev, yah-s3-fs) run as host binaries through the Native fork+exec
# backend (R490-F2; W199's "ideal native-backend case"), so dev-tier workloads
# share one supervision primitive instead of each calling Command::spawn.
= { = "0.8.46", = ["native-integration"] }
# Forge executor + transform recipe loader. Cloud's static-asset reconciler
# materializes derived assets (W164) by lowering recipes → ForgeSpec and
# handing them to a `dyn ForgeExecutor`. The dep edge intentionally stops
# here: no cloud → qed edge, only cloud → task (R438-T13 architectural rule).
= { = "0.8.46" }
= { = "0.8.46" }
= { = "1.0", = ["derive"] }
= "1.0"
= "0.8"
= "1.0"
= "1.0"
= "0.1"
= { = "0.12", = false, = ["json", "rustls-tls", "stream"] }
# R876-T23: the camp-pond calls sign with the operator's key like every other
# yubaba client (pasetors + reqwest; no yubaba runtime).
= { = "0.8.46" }
= { = "1", = ["rt", "rt-multi-thread", "macros", "process", "net", "time", "sync", "fs", "io-util"] }
# A few reconcilers' HTTP surfaces (sync_status, mesofact_static, static_asset,
# cloud_vps, pond). The floating-ip providers' axum mocks left with them in
# R859-F3, so this is no longer load-bearing for those.
= { = "0.8", = false, = ["http1", "json", "tokio"] }
= "0.1"
= { = "0.12", = ["std"] }
= "0.10"
= "0.4"
= { = "0.4", = false, = ["clock", "serde"] }
= "0.22"
= "0.2"
= "1"
# Per-transform tmp output dir (W164 materialize step) — recipe writes to a
# tmp file we BLAKE3-verify before renaming into .yah/cache/derive/transform/.
= "3"
# containerd gRPC client (optional — only with local-docker feature)
= { = "0.4", = true }
= { = "0.11", = true }
# JSON Schema derivation (optional — only with json-schema feature).
# The xtask `emit-schemas` task enables this; runtime binaries don't.
= { = "0.8", = true }
[]
= "3"
# Parses rendered cloud-init in tests to guard against the YAML footgun where a
# `: ` in a bare runcmd scalar turns the entry into a mapping (R330-F28 #12).
= "0.9"
= { = "1", = ["rt", "rt-multi-thread", "macros", "test-util"] }
# ── Integration-test targets (R743-T7) ───────────────────────────────────────
# Two, not one, and the split is deliberate. See tests/main.rs's module docs for
# the full reasoning; the short version is that `.yah/qed/pond-smoke.toml` runs
# `cargo test -p cloud --test pond_smoke`, pond_smoke is the only test in the
# crate that binds a fixed external address (MinIO 127.0.0.1:9000) and manages
# named docker containers, and both of its tests assert wall-clock spinup
# budgets that sibling tests on libtest's thread pool would perturb.
# live_workspace_smoke + mesofact_static_e2e + pg_driver_live + whisper_derive_e2e.
[[]]
= "main"
= "tests/main.rs"
# Deliberately isolated. Do not fold into `main`.
[[]]
= "pond_smoke"
= "tests/pond_smoke.rs"