Framework upgrades must not destroy operator-owned config under ~/.config/mosaic #791
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Framework upgrades (
mosaicself-update / install.sh re-run / framework-vN migration) mustnever destroy operator-owned configuration under
~/.config/mosaic. A recent framework-v3upgrade wiped operator-owned directories, silently degrading a running agent fleet. This issue
captures the failure class and tracks a durable fix.
Failure class
The updater does not distinguish framework-owned paths (which it is entitled to overwrite
verbatim on upgrade — e.g.
CONSTITUTION.md,AGENTS.md, guides, tools) from operator-ownedpaths (which it must treat as sacred). When an upgrade replaces/prunes subtrees that contain
operator files, operator state is lost with no snapshot and no warning.
Operator-owned paths that MUST be protected (audit for completeness — this list is a starting set):
agents/*.conf— per-agent runtime configurationfleet/agents/*.env— per-agent fleet environment files (systemdEnvironmentFilesources)memory/— operator/framework memory notespolicy/*.md— operator policy overlays*.local.mdoverlays —SOUL.local.md,USER.local.md,STANDARDS.local.mdtools/_lib/credentials.jsonand any secret-bearing operator filesObserved evidence (one operator's incident — narrative only, not part of the requirement)
On a v3 upgrade:
~/.config/mosaic/agents/*.conf(whole dir gone) and~/.config/mosaic/fleet/agents/*.env(dir gone); same event class previously removed a harvestermosaic-agent@systemd services boot unit DEFAULTS(runtime/workdir) on restart because
EnvironmentFile=-...is absent-tolerant, so a restartsilently downgrades agent identity. Running agents survived only as pre-wipe processes. This is
evidence of the class; the fix must be operator-agnostic.
Options evaluated
then restores anything it did not intentionally migrate; snapshot retained for rollback. Fixes
blast radius; enables
mosaic restore.manifest; operator dirs are declared off-limits and never touched. Fixes the root cause.
Defense-in-depth; also catches non-upgrade losses.
jarvis-brain
infra/fleetinstall.sh re-links confs). A recovery path, not prevention.Recommendation (what works best — combination)
from an explicit framework-owned path manifest and never write outside it. Everything under
the operator-owned list above is off-limits. This eliminates the failure class at the root.
mutation, snapshot operator dirs to a timestamped, non-world-readable backup
(
~/.local/state/mosaic/backups/pre-update-<ts>/or equivalent); on completion restoreanything touched-but-not-intentionally-migrated; keep N snapshots for rollback (
mosaic restore). Guards against manifest bugs / unforeseen operator paths.mosaic doctor/mosaic fleet regencommand that rebuilds derivable config deterministically.for non-upgrade losses.
Rationale: (b) prevents the class; (a) bounds the blast radius of any miss and gives rollback;
(d) gives deterministic recovery; (c) is cheap insurance. (b)+(a) are the must-haves.
Recovery / regeneration story for a currently-wiped state
For the fleet
EnvironmentFilelosses specifically: DO NOT perform any service-level fleetrestart while
fleet/agents/*.envis absent (a restart boots unit defaults and silentlydowngrades identity). Recovery order: regenerate
~/.config/mosaic/fleet/agents/*.envfrom SSOT(the fleet install/link script) → verify each unit's
EnvironmentFileresolves and the intendedruntime/workdir is present → only then
systemctl --user restart mosaic-agent@<name>. Provide amosaic fleet regen(or documented install.sh--relink) that performs this deterministically.Acceptance criteria
(unit test asserting an upgrade run touches no path outside the manifest).
never contains logged secret values;
mosaic restore(or equivalent rollback) works.mode-0600/dir-0700, excluded from any repo, and no secret value is emitted to logs/stdout.
mosaic fleet regen(or documented recovery command) regenerates derivable config from SSOT.+ secret-handling surface.
Gates & scope
TDD tests-first ≥85%; trunk-based squash PR; independent review (author ≠ reviewer); secrev on the
backup/restore + secret-handling surface. Framework-PR firewall: operator-agnostic only — no
SOUL.md/USER.md/operator specifics in framework code; web1 details live in this issue narrativeas evidence only. Capacity-fill; must not preempt M5-001 or #790.
jason.woltje referenced this issue2026-07-16 20:51:05 +00:00