Files
stack/packages/mosaic/framework/tools/fleet
code-infra-01 825e56d454
ci/woodpecker/pr/ci Pipeline was successful
fix(#1367): close both secret channels — trap-swept staging and file-to-file assembly (review 263)
Blocker 2 (secret at rest on error paths): all staging now lives in ONE
per-run mktemp -d removed by an EXIT/INT/TERM trap; a curl dying rc=7
mid-run (the reviewer's transport-failure case) leaves nothing behind.
M10 pins it against a dying mock in an isolated TMPDIR; trap-removed
mutant killed.

Blocker 1 (bash -x trace channel, upheld above landed parity because
this is the admin-token minter): secrets are assembled FILE-TO-FILE —
stage_auth/stage_user take token/password FILE PATHS and build the curl
configs with jq --rawfile; the password is generated straight into its
staging file; bodies are composed by jq from the template + password
file. No secret is ever expanded into a shell word a trace would print.
M11 runs a real bash -x and asserts the admin-token value, the minted
token value, and any password-shaped 32-char expansion are all absent;
expansion mutant killed (measured: the mutant's trace shows
'+ PW_VALUE=<32 chars>', the fixed script's trace shows paths only).

Header comment corrected to state what is actually true, including the
explicit note that detect-platform's gitea_write_auth_config still
leaks under -x — that parity gap is now tracked as #1369, opened per
review 263 and fred's ruling; issue-comment/pr-review/pr-edit left
untouched in this PR.
2026-08-21 23:20:24 -05:00
..

Fleet tools

Seat lifecycle tools for a Mosaic fleet. Paths are relative to packages/mosaic/framework/tools/fleet/ (deployed to ~/.config/mosaic/tools/fleet/).

Script Purpose
start-agent-session.sh launch, stop, or attach a roster-driven agent session (reads <seat>.env.generated, honours MOSAIC_TMUX_SOCKET)
seat-logins.sh project seat tokens into tea logins named <instance>-<seat> (dry-run by default, --apply, --adopt)
mint-seat-credential.sh create the Gitea account for a seat on every configured instance, mint a token, write the seat's credential slot, then project it into tea
start-interaction-service.sh, print-interaction-effective-policy.sh, start-tmux-holder.sh operator interaction service and tmux holder

Onboarding a seat's credential

MOSAIC_ADMIN_SEAT=<admin-seat> MOSAIC_SEAT_EMAIL_DOMAIN=<domain> mint-seat-credential.sh <seat>
  • The admin token is read from $MOSAIC_BRAIN_HOME/fleet/agents/<admin-seat>/secrets/gitea-<instance>-<admin-seat>.token. It is never printed.
  • MOSAIC_SEAT_EMAIL_DOMAIN is required (no default): the framework ships no estate-specific domain.
  • Instances default to the map shared with seat-logins.sh; MOSAIC_GITEA_INSTANCES="a b" limits the set and MOSAIC_GITEA_URL_<INSTANCE> overrides a server URL (hyphens in the instance name become underscores in the variable, as in seat-logins.sh).
  • The seat slot is written from the mint response: .token, .scopes (what was granted), .principal, each mode 600.
  • tea absent is a warning, not a failure: REST-path wrappers work with the token alone.
  • Regression suite: test-mint-seat-credential.sh (hermetic, mock curl, no network).