Skip to main content

Module config

Module config 

Source
Expand description

@yah:ticket(R040-F16, “pg-on-mesh service recipe: bind tailscale0 + pg_hba.conf snippet + ufw rules”) @yah:at(2026-05-05T00:32:34Z) @yah:assignee(agent:claude) @yah:status(review) @yah:parent(R040) @yah:handoff(“Companion to R040-F15. Inter-node TCP (Postgres primary↔replica, NATS clusters, anything raw-protocol) lives on the Headscale mesh, not on Hetzner public IPs. Each node has a stable 100.64.x.x mesh IP that survives replacement of the underlying box, so DNS / config / pg_hba never churn when a CPX-11 is rebuilt. WireGuard already encrypts the wire — TLS becomes defense-in-depth, not load-bearing. This ticket carries the concrete pg-shaped recipe so the first stateful service deploy doesn’t have to re-derive the pattern; subsequent services (redis, NATS, etc.) cargo-cult from it.”) @yah:next(“ServiceConfig gains a bind_interface: Option<String> field (e.g. Some(\"tailscale0\") for mesh-only services). The cloud-init/podman compose renderer translates this into either --network host + pg listen_addresses = '<mesh-ip>' OR a podman macvlan/host-binding pattern that achieves the same.”) @yah:next(“Generated pg_hba.conf snippet: allow the mesh subnet (100.64.0.0/10) for replication + app users. Postgres binds to the node’s tailscale0 mesh IP only — listen_addresses is templated from the node’s tailscale ip --4 at first boot.”) @yah:next(“Generated ufw rules: ufw allow in on tailscale0 to any port 5432; ufw deny 5432 — mirrors the existing yah-yubaba 7443 pattern in mirror.yml. Same shape works for any mesh-only port.”) @yah:next(“Replica connection string uses primary’s mesh IP, NOT its public IP. Stable across box replacement.”) @yah:next(“Out of scope: pg_basebackup orchestration, failover, WAL archiving — those belong in noisetable’s domain; this ticket only standardizes the binding/firewall/auth shape so noisetable’s pg deployment doesn’t reinvent it.”)

@yah:ticket(R323-F9, “Add sync-wave ordering to ServiceComponent (deploy-panel wave order)”) @yah:assignee(agent:claude) @yah:at(2026-05-26T15:20:25Z) @yah:status(review) @yah:phase(P2) @yah:parent(R323) @yah:next(“ServiceComponent gains a wave/order field (or depends_on between components) so the deploy panel (R323-F4) can group workload rollout rows into sync waves (wave 0 parallel, wait healthy, wave 1, …). Today all components are implicitly wave 0.”) @yah:next(“compute_service/compute_cell in reconciler/sync_status.rs surface the wave per workload so F4 doesn’t re-derive it.”) @yah:gotcha(“Until this lands, F4 should render every workload as wave 0 (no ordering).”) @yah:handoff(“Added wave: u32 (serde default=0, skip_serializing_if zero) to ServiceComponent in config.rs. Added is_zero_u32 helper. Fixed the three struct literal call-sites that now need wave: 0 (config.rs test, local_sim.rs x2, mesofact_static.rs). Added wave?: number to the TS ServiceComponent interface with a doc comment. Deploy panel now reads c.wave ?? 0 for each WorkloadRow instead of hardcoded 0. SyncFooter computes maxWave from the components array and renders ‘wave 0’ (all-zero case) or ‘waves 0–N’ (multi-wave). All 218 cloud lib tests pass; bun run typecheck clean.”) @yah:verify(“cargo test -p cloud –lib # 218 passed”) @yah:verify(“cd packages/yah/ui && bun run typecheck # no new errors”) @yah:verify(“In service.toml: add wave = 1 to a component, rebuild, open the deploy panel — that workload row shows ‘w1’ badge; SyncFooter shows ‘waves 0–1’”) @yah:verify(“Component with no wave field in TOML deserializes as wave=0 (default). Saving a wave=0 component omits the field from the output TOML (skip_serializing_if).”)

@arch:see(.yah/docs/working/W142-pond.md)

@yah:relay(R615, “Linked infra sources: sources.toml overlay so a camp can borrow another camp’s substrate”) @yah:at(2026-07-20T18:18:05Z) @yah:status(open) @arch:see(.yah/docs/working/W274-linked-infra-sources.md)

@yah:ticket(R615-F1, “InfraSource types + SourcesConfig::load(infra_dir) parsing .yah/infra/sources.toml”) @yah:status(review) @yah:assignee(agent:bundle-anthropic-miravel) @yah:at(2026-08-08T19:55:57Z) @yah:phase(P1) @yah:parent(R615) @yah:next(“Add InfraSourceKind { Path { path }, Git(GitSource) } + InfraSource { owner, kind, mode, select } to cloud/src/config.rs. Reuse the existing GitSource (config.rs:1205, { repo, ref, subdir }) verbatim — do not invent a second git-source shape.”) @yah:next(“SourcesConfig::load(infra_dir) reads .yah/infra/sources.toml (schema_version = 1, ordered [[source]] array). Absent file = empty list, never an error — every existing camp has no sources.toml.”) @yah:next(“mode is the write-gate: read-only (borrower cannot mutate) vs owner-manages. Model it as an enum, not a bool, so a future read-write-with-approval tier is additive.”) @yah:verify(“cargo check -p cloud && cargo test -p cloud”) @arch:see(.yah/docs/working/W274-linked-infra-sources.md) @yah:tier(Cleric) @yah:handoff(“InfraSourceKind{Path{path},Git(GitSource)} + SourceMode{ReadOnly,Manage} + InfraSource{owner,kind,mode,select} + SourcesConfig{schema_version,source} all landed in oss/yubaba/crates/cloud/src/config.rs (after default_git_ref, ~line 1550). GitSource reused verbatim – Git(GitSource) wraps the existing R561 type unchanged, no second git-source shape. InfraSourceKind is internally tagged (#[serde(tag="kind", rename_all="kebab-case")]) and flattened into InfraSource so a [[source]] table reads exactly like W274’s example: owner/kind/path-or-repo+ref+subdir/mode/select all at one table level. mode: SourceMode defaults ReadOnly via #[serde(default)] on the field (enum, not bool, per the ticket’s own instruction – Manage is the explicit escape hatch). SourcesConfig::load(infra_dir) returns Ok(default()) – schema_version=1, empty source list – when sources.toml is absent; only parses+errors when the file exists and is malformed.”) @yah:handoff(“Tree anchor 85801e7f. Pathspec: oss/yubaba/crates/cloud/src/config.rs (only file touched). Tests: cargo test -p yah-cloud –lib (from oss/yubaba) 710 passed / 0 failed / 4 ignored, +6 new over the 704 baseline your R707-T6 verification recorded (sources_load_is_empty_when_the_file_is_absent, sources_parses_a_path_kind_exactly_like_w274s_example, sources_parses_a_git_kind_reusing_gitsource_verbatim, sources_mode_defaults_to_read_only_and_manage_is_explicit, sources_preserves_declaration_order, sources_round_trips_through_serialize). cargo check -p cloud also green (implied by the test build).”) @yah:handoff(“Tree anchor at handoff: 85801e7f6b76b369c0c8ecd2e5c7874990cd9286 — the shared tree as I left it. Diff against it (git diff 85801e7f6b76b369c0c8ecd2e5c7874990cd9286..HEAD) to see what landed under you, and quote this SHA rather than ‘HEAD’ in any revert/restore instruction.”) @yah:next(“R615-F2 picks this straight up: overlay these sources into CloudConfig::load, tagging origin{owner,source} and merging camp-local-wins-on-collision.”) @yah:handoff(“Verified pre-existing work: InfraSourceKind{Path,Git(GitSource)} + SourceMode + InfraSource + SourcesConfig all present in oss/yubaba/crates/cloud/src/config.rs at tree anchor 871fde1c, matching the inline @yah:handoff notes already on this ticket. GitSource reused verbatim, no second git-source shape. This session added no new code – only ran verification and closed the board state, which a prior session left stuck in open despite the work being done (code + handoff notes landed, but board.review/handoff was never called).”) @yah:verify(“cargo check -p yah-cloud – clean (2 pre-existing unrelated warnings)”) @yah:verify(“cargo test -p yah-cloud –lib – 723 passed; 0 failed; 4 ignored (from oss/yubaba)”)

@yah:ticket(R615-F2, “Overlay loader: resolve sources in CloudConfig::load, tag origin, camp-local wins on collision”) @yah:status(review) @yah:assignee(agent:bundle-anthropic-miravel) @yah:at(2026-08-08T19:56:05Z) @yah:phase(P1) @yah:parent(R615) @yah:next(“In CloudConfig::load, after loading camp-local machines/providers/rules, resolve each source to an infra root (git sources read from the .yah/cache/infra/ sync cache — load stays offline), load that root’s machines/providers/rules, tag each entry with origin { owner, source }, and overlay UNDER camp-local. Camp-local wins on name collision.”) @yah:next(“The machine load site is config.rs:533 (load_dir::(paths::machines_dir(…))). Note config.rs:575 load_from_config_dir is a SECOND machine load site that deliberately skips the inherit_machines redirect for multi-root/sibling trees (W206) — decide explicitly whether sources overlay applies there too, and document the answer either way.”) @yah:verify(“cargo check -p cloud && cargo test -p cloud”) @yah:verify(“A camp with sources.toml [[source]] kind=path to a sibling camp sees that camp’s machines in CloudConfig::load, each tagged with the source owner”) @yah:gotcha(“Cross-camp MachineConfig schema skew is real: noisetable ships an older machine schema (location/server_type/hosts_mirrors) while yah’s use region/arch/[connect]. A borrowed source can carry fields the borrower’s binary predates. Overlay load MUST tolerate/skip unparseable foreign entries per-file and warn — never fail the whole load.”) @arch:see(.yah/docs/working/W274-linked-infra-sources.md) @yah:depends_on(R615-F1) @yah:tier(Warrior) @yah:handoff(“Overlay landed in CloudConfig::load (oss/yubaba/crates/cloud/src/config.rs). After camp-local machines/providers/legacy-merge finish, SourcesConfig::load(paths::infra_dir(workspace_root)) resolves + overlay_infra_sources() merges each source’s machines/providers UNDER what’s already there – camp-local wins any name collision, and among sources themselves the earlier-declared one wins (both proven by dedicated tests). Provenance is NOT a field on MachineConfig/ProviderConfig: added CloudConfig.machine_origins/provider_origins: BTreeMap<String, InfraOrigin> instead, keyed by name/id. Reason recorded in a doc comment on InfraOrigin – MachineConfig/ProviderConfig are constructed by struct literal in test helpers across several crates (including crates/yah/agent-tools/src/cloud_tools.rs, which is fenced/live-owned this session), so widening either shape would have forced an edit there for zero semantic gain; origin is a property of the LOAD, not the machine.”) @yah:handoff(“GOTCHA closed: added load_dir_tolerant() – a per-file-tolerant sibling of the existing (strict) load_dir – so one unparseable foreign machine/provider (schema skew) skips-with-a-tracing::warn! and never sinks the rest of that source’s directory or this camp’s own load. Proven by one_unparseable_foreign_machine_does_not_sink_the_rest_of_the_directory_or_the_load. load_dir itself is untouched – camp-local files still hard-fail on a bad TOML, which is correct, only borrowed roots get the tolerant path.”) @yah:handoff(“Git sources: InfraSource::infra_root() resolves kind=path to <workspace_root>//.yah/infra (live tree, no I/O beyond building the path) and kind=git to paths::infra_source_cache_dir(workspace_root, owner)/infra – a NEW path helper in paths.rs, also what R615-T3’s yah infra sync target directory must be so the two line up. An unsynced git source (cache dir absent) overlays nothing and is explicitly NOT an error (test: an_unsynced_git_source_overlays_nothing_and_is_not_an_error) – load() stays fully offline as W274 §3 requires.”) @yah:handoff(“select filtering implemented for machines only (name exact-match or literal mesh_tags membership – not a glob engine, matches W274’s own example verbatim) via machine_matches_select(); does NOT apply to providers – documented as a deliberate choice, nothing in W274 or the ticket describes a provider-scoped filter.”) @yah:handoff(“EXPLICIT DECISION on the config.rs:575-equivalent gotcha (now load_from_config_dir): sources overlay does NOT apply there. Multi-root sibling config dirs (W206 layout (b)) are a second config root INSIDE the same camp, not a second camp – .yah/infra/sources.toml is tied to paths::infra_dir(workspace_root) specifically, which has no well-defined meaning for an arbitrary config_dir. Documented in the function’s doc comment and proven by load_from_config_dir_never_applies_sources_overlay (a sources.toml at the real workspace root does NOT leak into a load_from_config_dir call against a sibling .noisetable/ dir under that same root).”) @yah:handoff(“Tree anchor 85801e7f. Pathspec: oss/yubaba/crates/cloud/src/config.rs, oss/yubaba/crates/cloud/src/paths.rs (added infra_source_cache_dir + 1 test), oss/yubaba/crates/cloud/src/reconciler/mesofact_bundle.rs (CloudConfig test-literal fixed for the 2 new fields), app/yah/cli/src/cloud.rs (3 CloudConfig test-literal sites fixed, same reason). Tests: cargo test -p yah-cloud –lib (from oss/yubaba) 720 passed / 0 failed / 4 ignored, +10 over R615-F1’s 710 baseline (9 overlay tests in config.rs + 1 in paths.rs). cargo build -p yah –lib (repo root) green – confirms nothing downstream (agent-tools, cloud.rs, hub) broke from CloudConfig’s two new fields.”) @yah:handoff(“Tree anchor at handoff: 85801e7f6b76b369c0c8ecd2e5c7874990cd9286 — the shared tree as I left it. Diff against it (git diff 85801e7f6b76b369c0c8ecd2e5c7874990cd9286..HEAD) to see what landed under you, and quote this SHA rather than ‘HEAD’ in any revert/restore instruction.”) @yah:next(“R615-T3 (yah infra sync) is unblocked and has everything it needs: paths::infra_source_cache_dir(workspace_root, owner) is the exact target directory to clone/pull git sources into, already matching what F2’s overlay reads from.”) @yah:next(“R615-F4 (Infra tab origin badge, not in my assigned lane) can read CloudConfig.machine_origins/provider_origins directly – no further backend plumbing needed for the badge itself.”) @yah:handoff(“Verified pre-existing work: overlay landed in CloudConfig::load (oss/yubaba/crates/cloud/src/config.rs) at tree anchor 871fde1c – SourcesConfig::load resolves sources, overlay_infra_sources() merges under camp-local with camp-local-wins and earlier-source-wins collision rules, machine_origins/provider_origins BTreeMaps added to CloudConfig, load_dir_tolerant() added for per-file-tolerant foreign schema skew, InfraSource::infra_root() resolves path/git kinds, load_from_config_dir explicitly does NOT get the overlay (documented). Matches this ticket’s own inline @yah:handoff notes. This session added no new code – only ran verification and closed board state that a prior session left stuck in open despite the work being done.”) @yah:verify(“cargo check -p yah-cloud – clean (2 pre-existing unrelated warnings)”) @yah:verify(“cargo test -p yah-cloud –lib – 723 passed; 0 failed; 4 ignored (from oss/yubaba), includes overlay tests + load_dir_tolerant test + infra_source_cache_dir test in paths.rs”)

Structs§

BucketLogEntry
A bucket declaration logged in topology.toml by yah cloud bucket create.
BucketSpec
CampCloudDbs
A camp-shared cloud database catalog, parsed from .yah/db/cloud.toml. These are cloud DBs not owned by any single service — declared once at camp scope and addressed as cloud:<name> (two-segment id), distinct from a service-local cloud:<service>:<name>.
CloudConfig
All cloud config loaded from a workspace root (the parent of .yah/).
CloudDb
A remote cloud database ([[db.cloud]]). The connection url is stored in TOML but the credential never is — auth_token_env names an environment variable the daemon reads at connect time, so the same declaration works whether the token is provisioned service-locally or camp-shared (W241; operator confirmed both scopes are needed). A camp-wide cloud DB not owned by any single service is declared identically in .yah/db/cloud.toml.
ConnectSpec
Declared reach for a BYO static node (no provider API). Lives under [connect] in the machine TOML.
DbCatalog
A service’s declared databases, grouped by environment (W241 §Sections). Parsed from the [db] table of service.toml; each [[db.<env>]] array entry names one database. The environment tag drives backend selection at query time (see the data-workbench’s db.query / the sql_* MCP tools): dev = local file, pond = a DB inside the running pond container stack (reached on a declared localhost port), cloud = a remote libSQL/Turso or Postgres endpoint whose auth comes from an env var (never stored in TOML).
DevDb
A dev-mode local SQLite database ([[db.dev]]). path is resolved relative to the workspace root and opened as a local file — read/write, no network, no auth.
DomainConfig
A routing manifest for one domain, from .yah/domains/<name>.toml.
DomainRoute
One entry in a DomainConfig’s route table.
GitSource
A git source for a component (R561-F1, “BYO git”).
InfraOrigin
Provenance for a MachineConfig or ProviderConfig pulled in from a linked .yah/infra/sources.toml entry, rather than declared in this camp’s own .yah/infra/ (R615-F2 / W274).
InfraSource
One [[source]] entry in .yah/infra/sources.toml (R615-F1 / W274) — an external infra root this camp borrows machines/providers from.
LegacyMirrorConfig
Per-camp mirror declaration from .yah/cloud/mirrors/<id>/mirror.toml (folder form) or the legacy .yah/cloud/mirrors/<id>.toml (flat form).
LegacyServiceConfig
Per-service config from .yah/cloud/services/<name>.toml.
MachineConfig
Per-machine TOML from .yah/infra/machines/<name>.toml.
MachineRegistration
[registration] — facts observed about a running box, written by the fleet rather than declared by an operator (R707-T1).
MirrorAssignment
One mirror→machine placement entry in topology.toml.
MirrorConfig
A service mirror — the projection of a ServiceConfig onto concrete infra. Lives at .yah/services/<svc>/mirrors/<env>.toml.
NodeAllocatable
Static node capacity declaration on machine.toml (R572-F3).
PondDb
A database running inside the pond container stack ([[db.pond]]). The pond publishes the DB on a localhost TCP port; the hub connects to 127.0.0.1:<port> when the pond is up and returns a clear error when it is not. Either port (defaulting to a libSQL/sqld HTTP endpoint) or a full url must be given.
PortMapping
ProviderConfig
A provider account/runtime binding from .yah/infra/providers/<id>.toml.
RequiredSpec
F16 placement constraints declared on a MirrorProviderSlot, lives under [providers.<role>] required = { regions = [...], mesh_tags = [...] } in mirrors/<env>.toml.
SecretConfig
A camp’s declaration of one cluster secret, from .yah/infra/secrets/<slug>.toml.
ServiceComponent
One component of a ServiceConfig. The kind (e.g. "mesofact-static", "almanac", "container") selects which reconciler runs against the pointed-at workload manifest.
ServiceConfig
An operator-facing service declaration from .yah/services/<svc>/service.toml.
ServiceWithMirrors
A loaded service plus its per-environment mirrors.
SourcesConfig
.yah/infra/sources.toml — the ordered list of external infra roots this camp borrows from (R615-F1 / W274).
TopologyConfig
Mirror-to-machine assignment table from .yah/cloud/topology.toml.
WorkloadConfig
A workload declaration loaded from .yah/cloud/workloads/<name>.toml.

Enums§

CloudConfigError
Error surfaced by CloudConfig::load when a workload TOML fails validation.
FrontDoor
Which front door actually serves a domain’s requests (R594-F12).
InfraSourceKind
How to reach an external infra root (R615-F1 / W274, “linked infra sources”): a filesystem link to a sibling camp’s live tree, or a git checkout of an extracted infra repo.
IngressProvider
Which public-ingress provider fronts this mirror’s compute (W267, R594-F11).
MirrorProviderSlot
A provider slot inside a MirrorConfig. Two shapes:
MirrorShape
Topological shape of a mirror — how its providers sit relative to each other.
PondDbKind
Wire protocol of a PondDb.
Provider
Tag for the infrastructure provider kind. Drives which fields are valid in a ProviderConfig body or a MirrorProviderSlot::Inline block.
RouteMode
Body of a DomainRoute. Three modes:
SecretEncoding
How a SecretConfig’s vault text becomes the bytes delivered to the container (R706 / W294).
SecretTargetDecl
Advisory mount shape on a SecretConfig. Mirrors workload_spec::SecretTarget in a TOML-friendly, externally-tagged-free shape (a kind discriminator reads better in a hand-written manifest than serde’s default enum encoding).
SourceMode
Write-gate for a linked InfraSource (R615-F1 / W274).
WorkloadConfigError
Error from loading or validating a single workload TOML file.

Constants§

DEFAULT_YUBABA_PORT
Default yubaba listen port, used when [connect].yubaba_port is omitted.

Functions§

canonical_tier
Map legacy mirror file stems to their canonical tier names.
node_selector_mesh_tags
Parse the R594 mesh-tag node-selector off a workload’s annotations into the requested tag set. Absent annotation or empty value ⇒ empty vec (“no constraint”). Whitespace around each comma-separated tag is trimmed and empty segments are dropped, so "tag:build-worker, tier:x86" and "tag:build-worker,tier:x86" parse identically.
provider_has_machine_driver
True iff provider has an auto-provision driver (create/destroy via API). Driver-backed providers require location + server_type; BYO static nodes (brought up over SSH) do not. The cloud-vs-vps distinction the fleet cares about lives here — at the provider-capability layer — not as a separate machine type (W242 BYO Phase-0 decision).