Skip to content

M8-09 Carry out the migration of an existing installation

No Date Ruling Reason
D-M8-09-1 2026-10-24 The guide is docs/operations/discord-migration.md, in the order of 22 13 (prerequisites, import bot, login, mapping and dry runs, source, pilot, full import and parallel operation, switch-over, revert, completion, troubleshooting); every step names its check and its way back, limits only by their keys, values of an installation only as placeholders like <guild_id>. A command the rehearsal runs stands alone in a fenced sh block directly after the HTML comment <!-- rehearsal: <name> -->, invisible on GitHub and on the site. The long-running --follow mirror and the shell line that reads the token are not marked: the first never ends on its own, the second is no bothy import command. Brief design note 1; a marker outside the fence keeps the block a plain sh block for both renderers.
D-M8-09-2 2026-10-24 TestMigrationRehearsal (services/server/test/importtool/rehearsal_test.go) is the repository's proof of PLAN 14 exit criterion 2; the live run on a real Discord server and installation is the owner's step after this ticket. The test reads every marked block of the guide and runs its lines literally: bothy import discord ... through importtool.Main, bothy import login --server <url> through bothyapi.Login with the URL of the line (the login command lives in package main and cannot be imported), > file keeps the standard output in that file; a quote, an unknown placeholder, an unknown command or a marked block the test never runs fails it. The console steps go through the API as Robin with step-up, as the console sends them. Brief design note 2 and "Tests" (the guide and the rehearsal cannot drift).
D-M8-09-3 2026-10-24 The rehearsal fixture is built in the test from the fixture of the other import tests (guild_basic.json plus the messages of world_test.go) with a media channel and its post, the Discord bot of the agent Lotse mapped to agent:lotse with answers in three channels and a busy output, and active threads in the announcement channel and the channel without category; there is no testdata/guild_rehearsal.json. The test trigger of each channel is a message in one of its imported threads, not in a main thread. Attachment URLs carry the port of the fake CDN chosen at run time, so a static file cannot hold them; the operator answers in a main thread only when mentioned and then opens a new thread (09 require_mention, auto_thread), so an imported thread is the probe of 22 13.3 step 4.
D-M8-09-4 2026-10-24 The read mirror (--follow, --once) registers SIGINT and SIGTERM itself (signal.NotifyContext in execute of run.go), so a stop finishes the current batch, frees the lease and exits 0, as the tool README and the guide say; TestFollowStopsOnSignal sends both signals to the test process. A full --apply run and switch keep the default (the process ends at once; the next run resumes or takes over the lease). The red team of this ticket reproduced that the binary passes context.Background() to the tool, so the stop the guide asks for before the full import or switch left the lease held: a reproduced Major of M8-05's behaviour, fixed here with a test as the brief allows.