# Local dev defaults. Override path with SANDO_CONFIG. listen = "127.0.0.1:7766" db_path = "./sando.db" topology_path = "../sando.toml" # Hostname (/proc/sys/kernel/hostname) this daemon may build on. build::run # refuses to compile on any other host, so a misdeployed daemon can't build on # prod. Required. build_host = "fw13" workdir = "./work" release_root = "./releases" # Shared cargo target dir across per-sha worktrees — incremental rebuilds reuse # the previous sha's compiled deps instead of clean-compiling each fresh # worktree. Safe because builds are serialized. Omit for per-worktree target/. cargo_target_dir = "./cargo-target" # Dropped and recreated on every migration_dry_run. Leave unset to skip. # The role must be SUPERUSER on the scratch cluster: the gates reset it, seed the # dump's owner role into it, and drop stale mnw_test_* clones left by a killed # run (including foreign-owned ones, which DROP DATABASE refuses without # superuser). The daemon asserts this at startup and refuses to boot otherwise. # ALTER ROLE sando SUPERUSER; scratch_db_url = "postgres://sando@127.0.0.1/sando_scratch" # Role that owns the objects in a prod pg_dump. The dump carries `ALTER ... OWNER # TO ` for every object, so it must exist in the scratch cluster before a # restore; reset_scratch creates it NOLOGIN and grants it CREATE on public, so no # manual SQL is needed on a fresh box. Must match the prod DB owner. scratch_owner_role = "makenotwork" # Databases the migration_dry_run gate dry-runs, in order: restore that # database's prod dump into a scratch DB, then run the worktree's migrations on # top. `backup` names a [[backup]] entry in the topology (sando.toml). Omit the # whole key to get just the first entry, which is the historical behavior. # # The server check leaves `scratch_db` unset, so it runs against scratch_db_url # itself and leaves it in migrated state for the cargo_test gate to reuse. Every # other check must name its own database; the daemon creates it (DROP + CREATE) # at the start of the check, so a new entry owes no host bootstrap step. [[migration_check]] dir = "server/migrations" backup = "server" # multithreaded applies its own 36+ migrations at boot (multithreaded/src/main.rs, # `sqlx::migrate!()`) against its own database, so it carried the server's # exposure with none of the server's gate: an edited already-applied migration # would not fail a dry run, it would fail to boot in prod. `owner_role` is that # dump's owner — pg_dump emits `ALTER ... OWNER TO multithreaded` for every # object, and the role must exist in the scratch cluster before the restore. [[migration_check]] dir = "multithreaded/migrations" backup = "multithreaded" scratch_db = "sando_scratch_mt" owner_role = "multithreaded" # TypeScript frontends the code_smoke gate compiles. Both build scripts downgrade # a tsc error to a cargo::warning so the Rust build still succeeds against a # stale static/dist/; this is where that failure is fatal instead. See the # frontend_build docs in daemon/src/config.rs. [[frontend_build]] dir = "server/frontend" [[frontend_build]] dir = "multithreaded/frontend" # Companion crates built from the same worktree/sha as the server and staged # into the release bundle, so a contract-coupled service can't drift out of # lockstep. mnw-cli is the public git-SSH server that proxies to /api/internal/* # — a two-month drift is what broke git hosting during the 0.10.14 deploy. Which # nodes install it is set per-node in the topology (see prod-1 in sando.toml). [[companion]] name = "mnw-cli" manifest_dir = "mnw-cli" bin = "mnw-cli" # multithreaded (forums.makenot.work) runs on alpha-west-1, the same host as the # server, x86_64, so the build host can compile it and the never-cross-compile # rule is satisfied. Its own deploy path was multithreaded/deploy/deploy-hetzner.sh, # which cross-compiled on macOS via cargo zigbuild and scp'd to root@ — against # that rule, and 41 commits behind by the time it was found (2026-07-30). # # mt is a single file to install because it embeds its own `static/` tree # (multithreaded/src/static_assets.rs). It used to serve those assets off disk # beside the binary, which the one-file companion mechanism cannot ship. # # Note this is a companion and NOT an entry in `bin_names`: bin_names lists the # bin targets of the SERVER crate, resolved under its own target/release, so # naming multithreaded there would fail the build looking for a binary the # server never produces. Wiki sando-mt-pom-pipelines had it wrong. [[companion]] name = "multithreaded" manifest_dir = "multithreaded" bin = "multithreaded" # Crates the cargo_test gate runs, in order. This list used to be hardcoded to # `server`, so every other crate in the repo shipped ungated — including # mnw-cli, which is BUILT as a companion and installed onto prod-1 in the same # promote it ships. All of these were verified green on 2026-07-21 before being # added; the gate stops at the first red one. # # scratch_db exports DATABASE_URL/TEST_DATABASE_URL. Only the server needs it # (its sqlx macros type-check against a live DB). Leaving it off elsewhere keeps # crates that ship offline `.sqlx` data in offline mode. [[test_target]] dir = "server" features = ["fast-tests"] scratch_db = true # Companion: ships to prod-1, so it is gated first among the rest. [[test_target]] dir = "mnw-cli" [[test_target]] dir = "multithreaded" scratch_db = true [[test_target]] dir = "pom" [[test_target]] dir = "wam" # docengine left the repo for Libraries/docengine on 2026-07-30 and is consumed # through the [[aux_repo]] checkout, which sits BESIDE the worktree rather than # under it. `dir = "shared/docengine"` therefore stopped resolving that day and # quietly became a warn-and-skip, indistinguishable from a bisect skip: the gate # stayed green having run one crate fewer than it claims. `aux_repo` names the # checkout, and `dir` is empty because the crate is at that repo's root. # # Still worth gating despite living in another repo: the checkout is at branch # HEAD and is compiled into these binaries, so a break there breaks this build. [[test_target]] aux_repo = "docengine" all_features = true # No tests of its own yet; listed so a compile break still fails the gate. [[test_target]] dir = "shared/egui-updater" [[test_target]] dir = "shared/kberg" all_features = true [[test_target]] dir = "shared/livechat" all_features = true [[test_target]] dir = "shared/ops-core" [[test_target]] dir = "shared/ops-exec" all_features = true [[test_target]] dir = "shared/pom-contract" [[test_target]] dir = "shared/s3-storage" [[test_target]] dir = "shared/synckit-client" all_features = true [[test_target]] dir = "shared/tagtree" # ---- products ---- # Products this daemon ships. Declaring any of these means this file is no longer # both halves: the daemon keys stay here and each product points at its own # pipeline config. `mnw` points back at this same file, which is what keeps the # rest of it meaningful and what makes the change a pure addition — the routes # an operator types (`/promote/b`) still address MNW, and pom lives under # `/apps/pom/`. [app.mnw] config = "sando-daemon.toml" # pom is intake-only: Bento builds it on astra (aarch64) and Hetzner (x86_64), # Sando gates and promotes what arrives. See sando-pom.toml. [app.pom] config = "sando-pom.toml"