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::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”)
@yah:ticket(R605-F12, “Sovereign groups have no voting axis, so non-voting membership is inexpressible and the raft guard is enforced by an absent field”)
@yah:status(review)
@yah:at(2026-08-20T05:15:30Z)
@yah:assignee(agent:bundle-anthropic-ashguard)
@yah:parent(R605)
@arch:see(.yah/docs/working/W325-isolated-x86-build-capacity.md)
@yah:next(“OPERATOR INTENT (2026-08-19) that the model cannot currently record: us-west-003 is a NON-VOTING member of the us-west-001-based (prod) sovereign group, and us-west-011 is a DIFFERENT sovereign (dev) from 001/003. The dev/prod split is already declared correctly. The non-voting membership is not — us-west-003.toml declares no sovereign_group at all.”)
@yah:next(“THE GAP: MachineConfig::sovereign_group is a single Optionno-voter sat inert on three nodes asserting something nothing enforced.”)
@yah:next(“PROPOSED SHAPE (recommended): a second axis, e.g. sovereign_role = voter | non-voter (default voter for back-compat, or make it required), with judge_join permitting a same-group join only for voters. Then us-west-003 stamps prod + non-voter, the intent is machine-readable, and the raft guard stops depending on omission. us-west-004 (R605-T7) would take the same shape.”)
@yah:next(“TOUCHES TWO COPIES OF THE PREDICATE, do not fix only one: cloud::judge_join renders the camp-side refusal, but the predicate itself lives in workload_spec::sovereign::join_permitted because yubaba’s POST /raft/add-learner gate asks the same question and there is deliberately no yubaba -> cloud edge. Also re-read yubaba serve --sovereign-group, whose node-side gate is narrower on purpose (an unset flag means ‘declared nothing’, not ‘declared standalone’).”)
@yah:gotcha(“THE CODE AND THE OPERATOR CURRENTLY DISAGREE ABOUT 003, and a reader should know which is which before editing. judge_join’s own doc comment asserts ‘prod and dev are both stamped, and us-west-002/003/015 are deliberately not raft members’ — i.e. R742-F1 modelled 003 as STANDALONE. The operator’s model is that it is a NON-VOTING MEMBER of prod. Those are different claims, not a wording difference: standalone means no blast-radius relationship to 001 at all. Do not silently ‘correct’ either side; this ticket is the reconciliation.”)
@yah:gotcha(“FLEET STATE AS DECLARED (2026-08-19): prod = us-west-001, us-south-001, us-east-001. dev = us-west-011, us-west-013, us-west-014. NO sovereign_group declared = us-west-002, us-west-003, us-west-015. Verify against the files rather than trusting this list — xtask/tests/fleet_sovereign_groups.rs pins the roster and will need updating in the same change (it also asserts the stamp parses as a TOP-LEVEL key, which matters because 003 has a long comment block before [allocatable] where a stamp would silently become a member of that table).”)
@yah:gotcha(“SEPARATE AXIS, DO NOT ENTANGLE: mesh membership is not sovereign membership. The standing rule is ONE mesh for the entire fleet regardless of group (operator, 2026-08-19), so us-west-003 and us-west-011 enrolling in headscale is unrelated work with no design question in it — see R605-T10. A voting axis on sovereign_group must not become a reason to keep any node off the mesh.”)
@yah:gotcha(“SHARED-TREE COLLISION, live 2026-08-20: R772 (Miravel:spade, session:ce6d74a9) is refactoring oss/yubaba/crates/cloud/src/validate.rs at the same time and the file is currently RED - error[E0425] cannot find function load_machines at validate.rs:753, a half-landed extraction of the machine-loading walk that check_inert_taints / check_retired_arch_tags / the new check_unroled_sovereign_members all duplicate. That error is NOT from this ticket. Told them by party.chat and asked them to absorb check_unroled_sovereign_members into load_machines rather than leave one holdout. Do not hand-fight the file.”)
@yah:gotcha(“R772 ALSO BROKE THREE PRE-EXISTING INGRESS TESTS, again not this ticket: two_services_fronting_one_node_collate_into_one_front_door, a_cross_service_hostname_clash_is_reported_with_both_declarations, one_mirrors_broken_declaration_does_not_hide_the_rest - all failing with ‘providers.compute.use = hetzner - no such provider’. Cause is their new CloudConfig::load(workspace_root) at validate.rs:750 inside collate_workspace_ingress; the fronted_mirror fixture declares the slot but never writes infra/providers/hetzner.toml, and CloudConfig::load runs cross_ref_validate. Left alone deliberately - peer-owned.”)
@yah:gotcha(“TRAP THAT MADE THREE OF MY OWN TESTS PASS FOR THE WRONG REASON: the machine-lint sweeps SKIP unparseable TOMLs by design (a peer’s half-written scaffold must not sink the sweep). So a test fixture missing a REQUIRED MachineConfig field - mesh_tags is the one that bites - is silently skipped, the lint finds nothing, and every assert-empty test passes vacuously. Only the one test asserting found.len() == 1 noticed. write_sovereign_machine now always writes mesh_tags = [] and carries a comment saying why. Check this before trusting any new test in cloud::validate.”)
@yah:verify(“cargo test -p yah-workload-spec –lib sovereign (from oss/yah-base) – 9 passed, 0 failed. Covers both new refusals (a_non_voting_member_does_not_join_its_own_group, a_non_voting_target_has_no_quorum_to_join), the back-compat pin (the_default_role_is_the_pre_r605_f12_meaning), and the one-spelling round-trip across TOML/CLI/JSON.”)
@yah:verify(“cargo test -p yubaba –lib sovereign (from oss/yubaba) – 13 passed, 0 failed. Includes a_non_voting_joiner_is_refused_by_role_not_by_group, a_non_voting_target_refuses_every_joiner, a_group_without_a_role_key_is_a_voter_not_a_refusal (the deployed-fleet back-compat seam), a_peer_reports_its_role_in_the_toml_spelling.”)
@yah:verify(“cargo test -p yubaba –test raft_sovereign_group (from oss/yubaba) – 11 passed, 0 failed, up from 8. Three new end-to-end against real single-node rafts: a_non_voting_member_of_the_same_group_is_refused, a_non_voting_leader_refuses_to_grow_its_quorum, a_node_publishes_its_role_and_the_leader_reads_it_there (which also proves the request body cannot vote a non-voter in - the leader dials the joiner).”)
@yah:verify(“cargo test -p xtask –test fleet_sovereign_groups (from repo root) – 2 passed, 0 failed. THE DECISIVE ONE: parses the real .yah/infra/machines/.toml through the actual MachineConfig deserializer. Confirms us-west-003 = prod + non-voter on disk, all six pre-existing voters now stamped sovereign_role = voter explicitly, and neither key swallowed by a table header.”)
@yah:verify(“cargo test -p yah-cloud –lib (from oss/yubaba) – 891 passed, 3 failed, where all 3 failures were R772’s ingress-collate tests and none were mine. A clean re-run is BLOCKED, not failing: R555’s in-flight AdmissionGrant.secrets field breaks velveteen-exec, and yah-cloud is not a root workspace member so its dev-deps can only resolve from the oss/yubaba workspace. Re-run once R555 lands.”)
@yah:handoff(“LANDED, operator chose the second-axis shape (Call 1 = A, 2026-08-20). sovereign_role = voter | non-voter now sits beside sovereign_group, and ONE predicate judges both: workload_spec::sovereign::join_permitted(Membership, Membership) where Membership { group: Option<&str>, role: SovereignRole }. Permitted iff same non-None group AND both sides Voter. Both copies of the predicate call it - cloud::judge_join (camp-side) and yubaba::sovereign_group::judge (node-side) - so the rule itself cannot drift; only the prose differs, which was already the R742-F1 split.”)
@yah:handoff(“WHY THE ROLE IS CHECKED ON BOTH SIDES, since only the joiner half was asked for: a join grows a quorum and it takes two nodes. Refusing a non-voting JOINER is the us-west-003 case. Refusing a non-voting TARGET is the same assertion read from the other end - a box declared non-voting that is serving add-learner is already holding a raft seat its own declaration forbids, and permitting there would paper over the contradiction. Both refusals name the role rather than the group when the groups match, because a message reading ‘cross-group join refused: prod and prod’ reads as a bug in the check.”)
@yah:handoff(“THE DEFAULT IS THE LOAD-BEARING DECISION AND IT IS DELIBERATELY PERMISSIVE. An absent sovereign_role resolves to Voter (MachineConfig::sovereign_membership, the ONE place the Option is resolved). Reason: before this field, declaring a group WAS declaring quorum eligibility, so absence has to keep meaning that or the change silently retires six live voters. The permissiveness is bounded at the other end by cloud::validate::check_unroled_sovereign_members, which makes yah cloud validate FAIL on a group stamp with no role beside it - so the default can be reached by choice but not by silence. MachineConfig::sovereign_role stays Optionyah cloud validate, WARNING in the apply preflight - same split as inert-taint/retired-arch-tag, because an unwritten role changes no placement decision and the machine may be declared in a tree this camp does not own). yubaba/src/{sovereign_group,lib,main}.rs (–sovereign-role flag, ServerState.sovereign_role, /raft/status publishes it always-never-null, gate both directions). yubaba-test-harness/src/solo_node.rs (solo_node_with_sovereign_role). .yah/infra/machines/cargo run -p xtask -- emit-schemas from the repo root - it was queued behind ~7 concurrent peer cargo builds for the whole session. Nothing else is required to make this pushable.”)
@yah:handoff(“ALSO NOT RE-CONFIRMED: cargo test -p yah-cloud --lib needs a clean run. Its last real run was 891 passed / 3 failed with all three failures belonging to R772’s ingress-collate work and none to this ticket. The re-run is BLOCKED not failing - R555’s in-flight AdmissionGrant.secrets field breaks velveteen-exec, and yah-cloud is not a root workspace member so its dev-deps only resolve from the oss/yubaba workspace where that break lives. Re-run from oss/yubaba once R555 lands.”)
@yah:verify(“cargo run -p xtask – emit-schemas (from repo root) – wrote 8 files, exit 0 after an 18m24s build queued behind ~7 concurrent peer cargo jobs. .yah/schema/machine.toml.schema.json now carries the sovereign_role property (anyOf SovereignRole | null, with the full doc comment) and the SovereignRole definition as a oneOf over the two string enums voter / non-voter. The schema-drift-guard gate for THIS ticket is closed.”)
@yah:gotcha(“emit-schemas IS ALL-OR-NOTHING AND WILL PICK UP A PEER’S UNCOMMITTED WORK. Running it to close this ticket’s machine-schema drift also regenerated .yah/schema/secret.toml.schema.json (+34) from R555-F5’s in-flight SecretAccess::Recipes / RecipeMatch source. That output is CORRECT for the tree as it stands and was not hand-edited, but it means the schema diff in the working tree is not purely R605-F12’s: machine.toml.schema.json (+32) is this ticket, secret.toml.schema.json (+34) is R555. Told Ashguard:spade by party.chat so they carry it with their commit rather than regenerating on top. Anyone splitting these commits needs to split the schema diff too.”)
@yah:handoff(“ALL GATES CLOSED as of 2026-08-20. Both items listed as outstanding in the earlier handoff notes are done: emit-schemas ran (machine.toml.schema.json carries sovereign_role + the SovereignRole voter/non-voter enum, drift guard satisfied), and cargo test -p yah-cloud –lib is 896 passed / 0 failed once R555 and R772 settled. 45 tests green across workload-spec (9), yubaba lib (13), yubaba raft integration (11), yah-cloud lib (10 of this ticket’s, within 896), xtask fleet (2). Ready for review. NOTE for whoever commits: the working tree’s schema diff is not purely this ticket - .yah/schema/machine.toml.schema.json (+32) is R605-F12, .yah/schema/secret.toml.schema.json (+34) is R555-F5, both correct generated output from one emit-schemas run. Ashguard:spade has agreed to carry theirs.”)
@yah:verify(“cargo test -p yah-cloud –lib (from oss/yubaba) – 896 passed, 0 FAILED, 4 ignored. The blocked check from earlier is now clean: R555 landed the velveteen-exec and TransformRecipe.secrets fixes, R772’s ingress-collate work settled (they replaced the CloudConfig::load in collate_workspace_ingress with a narrower machines-only loader, so cross_ref_validate can no longer fail the collate over an unrelated provider typo). All 45 R605-F12 tests across the four crates are green simultaneously on one tree.”)
@yah:verify(“Confirmed by NAME rather than by total, since a passing count proves nothing about which tests ran: cargo test -p yah-cloud –lib – role voter voting lists all ten of this ticket’s cloud tests green - a_non_voting_member_is_refused_into_its_own_group, a_non_voting_target_has_no_quorum_to_grow, a_refusal_names_the_group_when_fixing_the_role_would_not_help, an_unwritten_role_still_joins_its_group, a_non_voter_is_still_in_the_group_it_names, sovereign_role_round_trips_and_is_omitted_when_unwritten, a_group_with_no_role_is_reported_with_the_declaring_file, either_stated_role_is_clean, a_machine_in_no_group_is_not_asked_for_a_role, unroled_findings_are_ordered_by_file_so_output_is_stable.”)
Structs§
- Bucket
LogEntry - A bucket declaration logged in
topology.tomlbyyah cloud bucket create. - Bucket
Spec - Camp
Cloud Dbs - 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 ascloud:<name>(two-segment id), distinct from a service-localcloud:<service>:<name>. - Cloud
Config - All cloud config loaded from a workspace root (the parent of
.yah/). - CloudDb
- A remote cloud database (
[[db.cloud]]). The connectionurlis stored in TOML but the credential never is —auth_token_envnames 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. - Connect
Spec - Declared reach for a BYO
staticnode (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 ofservice.toml; each[[db.<env>]]array entry names one database. The environment tag drives backend selection at query time (see the data-workbench’sdb.query/ thesql_*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]]).pathis resolved relative to the workspace root and opened as a local file — read/write, no network, no auth. - Domain
Config - A routing manifest for one domain, from
.yah/domains/<name>.toml. - Domain
Route - One entry in a
DomainConfig’s route table. - GitSource
- A git source for a component (R561-F1, “BYO git”).
- Infra
Origin - Provenance for a
MachineConfigorProviderConfigpulled in from a linked.yah/infra/sources.tomlentry, rather than declared in this camp’s own.yah/infra/(R615-F2 / W274). - Infra
Source - One
[[source]]entry in.yah/infra/sources.toml(R615-F1 / W274) — an external infra root this camp borrows machines/providers from. - Ingress
Edge - One declared edge: a front door, the slots it fronts, and the nodes it is placed on (W305 F2).
- Legacy
Mirror Config - Per-camp mirror declaration from
.yah/cloud/mirrors/<id>/mirror.toml(folder form) or the legacy.yah/cloud/mirrors/<id>.toml(flat form). - Legacy
Service Config - Per-service config from
.yah/cloud/services/<name>.toml. - Machine
Config - Per-machine TOML from
.yah/infra/machines/<name>.toml. - Machine
Registration [registration]— facts observed about a running box, written by the fleet rather than declared by an operator (R707-T1).- Mirror
Assignment - One mirror→machine placement entry in
topology.toml. - Mirror
Config - A service mirror — the projection of a
ServiceConfigonto concrete infra. Lives at.yah/services/<svc>/mirrors/<env>.toml. - Node
Allocatable - 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 to127.0.0.1:<port>when the pond is up and returns a clear error when it is not. Eitherport(defaulting to a libSQL/sqldHTTP endpoint) or a fullurlmust be given. - Port
Mapping - Provider
Config - A provider account/runtime binding from
.yah/infra/providers/<id>.toml. - Required
Spec - F16 placement constraints declared on a
MirrorProviderSlot, lives under[providers.<role>] required = { regions = [...], mesh_tags = [...] }inmirrors/<env>.toml. - Secret
Config - A camp’s declaration of one cluster secret, from
.yah/infra/secrets/<slug>.toml. - Service
Component - One component of a
ServiceConfig. Thekind(e.g."mesofact-static","almanac","container") selects which reconciler runs against the pointed-at workload manifest. - Service
Config - An operator-facing service declaration from
.yah/services/<svc>/service.toml. - Service
With Mirrors - A loaded service plus its per-environment mirrors.
- Sources
Config .yah/infra/sources.toml— the ordered list of external infra roots this camp borrows from (R615-F1 / W274).- Topology
Config - Mirror-to-machine assignment table from
.yah/cloud/topology.toml. - Workload
Config - A workload declaration loaded from
.yah/cloud/workloads/<name>.toml.
Enums§
- Cloud
Config Error - Error surfaced by
CloudConfig::loadwhen a workload TOML fails validation. - Front
Door - Which front door actually serves a domain’s requests (R594-F12).
- Infra
Source Kind - 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.
- Ingress
Decl - A mirror’s
ingressdeclaration, in either spelling. - Ingress
Provider - Which public-ingress provider fronts this mirror’s compute (W267, R594-F11).
- Join
Verdict - What
judge_joindecided about one proposed cluster join. - Mirror
Provider Slot - A provider slot inside a
MirrorConfig. Two shapes: - Mirror
Shape - Topological shape of a mirror — how its providers sit relative to each other.
- Pond
DbKind - Wire protocol of a
PondDb. - Provider
- Tag for the infrastructure provider kind. Drives which fields are valid in
a
ProviderConfigbody or aMirrorProviderSlot::Inlineblock. - Route
Mode - Body of a
DomainRoute. Three modes: - Secret
Encoding - How a
SecretConfig’s vault text becomes the bytes delivered to the container (R706 / W294). - Secret
Target Decl - Advisory mount shape on a
SecretConfig. Mirrorsworkload_spec::SecretTargetin a TOML-friendly, externally-tagged-free shape (akinddiscriminator reads better in a hand-written manifest than serde’s default enum encoding). - Source
Mode - Write-gate for a linked
InfraSource(R615-F1 / W274). - Sovereign
Role - Whether a node in a sovereign group may hold a seat in that group’s quorum — R605-F12.
- Taint
Effect - How a key in
MachineConfig::taintscan affect placement. - Workload
Config Error - Error from loading or validating a single workload TOML file.
Constants§
- AFFINITY_
TAINT_ KEYS - Taint keys a workload may name in
yah.placement.requires-taintto require a node (W305/R742-T4 affinity vocabulary). - DEFAULT_
YUBABA_ PORT - Default yubaba listen port, used when
[connect].yubaba_portis omitted. - NATIVE_
EXEC_ MESH_ TAG - The mesh tag a node declares to advertise that its kamaji can run native (fork+exec) workloads — R860-T5 / W338 §“Placement consequences” 3.
Functions§
- canonical_
tier - Map legacy mirror file stems to their canonical tier names.
- domain_
serving_ service - The route-driven domain whose route table binds a component of
service, if any. Used by static publishers to pick up the per-route response headers a service’s paths were declared with. - group_
is_ drainable - Whether a placement group may be drained off its node (W338 §Placement consequences 2): false as soon as any member is an Appliance.
- is_
private_ ipv4 - Whether a bare host string is an RFC1918 private IPv4 literal.
- judge_
join - May
joinerjoin the clustertargetbelongs to? — W305/R742-F1. - live_
taint_ keys - Every key the scheduler can act on, sorted — for error messages that tell the operator what the legal vocabulary actually is instead of only what was wrong.
- 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, arch:x86"and"tag:build-worker,arch:x86"parse identically. - node_
selector_ node - Parse the R833-F8 imperative node-selector off a workload’s annotations —
the single machine
namethe operator pinned the run to (--where=node:us-west-003). Absent or blank ⇒None(“no constraint”), which is every workload built before this axis existed. - normalize_
mount - Normalize a component
mountto a storage/URL key prefix: strip the surrounding slashes."/app","app/","/app/"→"app";"/",""→""(the service root). - placement_
group - The workloads that must be placed together with
ws: the transitive closure oflocalrequirement edges overWorkloadSpec::effective_requirements, starting at the requirer (R860-T4 / W338 §“Each member keeps its own mesh identity”). - private_
ipv4_ from_ url - Host of an
http://host:portURL iff it is an RFC1918 private IPv4 —10/8,172.16/12,192.168/16.Nonefor anything else, loopback and the100.64/10mesh range included: neither is a LAN literal. - provider_
has_ machine_ driver - True iff
providerhas an auto-provision driver (create/destroy via API). Driver-backed providers requirelocation+server_type; BYOstaticnodes (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). - route_
headers_ for_ service - The
ROUTE_HEADERSWorker-binding value forservice, read from the workspace’s domain manifests."[]"when no route-driven domain routes the service, or when the one that does declares no headers. - route_
path_ prefix - The key prefix a domain route pattern serves under:
"/*"→"","/app/*"and"/app"→"app". The twin ofnormalize_mounton the routing side. - taint_
effect - Classify one node taint key. See
TaintEffect.