Files
tasks/cmd
zeekayandHanzo Dev 432713bae3 feat(store): tasksd upgrade — move a pre-principal store into this layout
An older binary addressed a shard by org alone (<data>/<org>/<ns>.db).
This one reads three levels down, so the first boot after the upgrade finds
nothing, creates empty shards beside the full ones, enumerates zero tenants
and never fires a schedule again — silently, with every byte still on disk
one directory up.

store.Upgrade inserts the two sentinel levels uniformly, including the old
empty-org dir (_ -> _/_/_). A rename within one filesystem: no page
rewritten, no re-encryption. Journals move before their database, so a run
that stops half way never leaves a database without the WAL holding its
last commits. Idempotent — a moved shard leaves nothing at its old path —
so a deploy can run it unconditionally ahead of the daemon.

Two refusals, both loud and both non-destructive:

  A master key is set. Pre-upgrade shards are plaintext and moving one does
  not encrypt it; the next boot would wrap a fresh DEK around a file it
  then failed to decrypt. Move first, encrypt second.

  A destination is occupied (ErrOccupied). The only way there is booting
  this binary before the move ran, which creates an EMPTY shard where the
  full one belongs — and anything started after that boot is in the empty
  one. Both files are kept, the other tenants still move, and the operator
  picks which is authoritative.

upgrade and migrate stay separate axes: upgrade moves EVERY shard forward
in time (layout), migrate moves ONE shard across space (nodes).

Also: refuse a socket path over sockaddr_un.sun_path by name. The kernel
answers "bind: invalid argument" and names neither the path nor the limit,
and a socket under a deployment's data directory sits close to it.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-28 20:43:30 -07:00
..