Repository navigation
Run The Maps And Root Notes Migration
Note
Goal: Move the vault onto the shape agentm-vault plan 07 leaves the code expecting: Home.md and Filing.md retired for the generated root map, numbered map pages gone because a type's page paginates in place, and a map for each calendar year.
Prereqs:
- The code has merged to
mainand deployed in one step: your clone fast-forwarded, which makes the Python scripts live, andagentmdandagentmdreamrebuilt from the same commit, with the daemon restarted on the new binary. - You have shell access to the machine the vault and the daemon run on.
- The configured vault path resolves to the vault you're migrating (or
MEMORY_ROOTnames its memory root for this shell). - You run this outside the nightly
02:00–06:00window. - If
Filing.mdexists in this vault, a reviewed draft ofindex.mdis ready that foldsFiling.md's write-authority table into it.
scripts/migrate/maps_and_root_notes.py moves the vault to match the code. The numbered map pages, Home.md and Filing.md go. A stray day note at the calendar root moves into its year with its body unchanged. Every link naming what went is repointed where it may be, and index.md takes the reviewed draft. The script runs as a dry run, then --apply against a confirmed count, then --finish once the maps have been regenerated. --revert RUN_ID undoes an applied run.
-
Quiesce the runner and the daemon. Both write into the vault outside the nightly window, and a write between the dry run and the apply makes the apply refuse:
launchctl bootout gui/$(id -u)/com.agentm.runner launchctl bootout gui/$(id -u)/com.agentm.daemon
-
Record what the night owes before you change anything. A class card whose link the migration repoints no longer matches its enrichment fingerprint, so the night owes it again. Step 11 compares against what you save here:
agentmd enrich -dry-run agentmd ledger --pending --limit 0 --json > /tmp/pending-before.json -
Dry-run the migration. Nothing on disk changes yet:
python3 scripts/migrate/maps_and_root_notes.py --index-draft <path-to-reviewed-index-draft>
Omit
--index-draftonly ifFiling.mddoesn't exist in this vault. A type's page under the page threshold is held and reported, not deleted; add--also-delete TYPE(repeatable) only when you want that page gone.The dry run prints a summary (files, held pages, repointed links, whether
index.mdhas a draft) and then amanifest:section: one line per file that goes or moves, each naming why it goes and thegit checkoutcommand that restores it. It records the plan under the engine state directory and prints the exact--applycommand to run next. -
Paste the printed manifest into the plan's progress file before anything goes. It is the record of what is about to go and how to bring any one file back by hand, apart from
--revert. -
Apply it, using the exact command the dry run printed:
python3 scripts/migrate/maps_and_root_notes.py --apply --plan <PLAN> --confirm-count <N>
It refuses if the vault no longer matches the dry run, or if your count doesn't match the plan's, and writes nothing either way. On success it reports
journal matches the dry run: yes. OnNO, stop and read the journal (see Troubleshooting). -
Bring the daemon back. The dreaming pass and the embeddings run against a live daemon, as they do every night. The runner stays stopped until step 13, because its hourly jobs write to cards:
launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.agentm.daemon.plist launchctl kickstart -k gui/$(id -u)/com.agentm.daemon
Confirm it with
agentmd status;launchctl listalone isn't proof (see Memory daemon reference). Once it is running, the daemon commits the migration's changes to the vault. -
Regenerate the maps with one pass by hand, reading its report first. The pass runs every dreaming job, not only the maps, so see what it would change before you let it:
agentmdream run -force agentmdream run -force -apply
-forceskips the pass's gate so it runs now. The first command changes nothing and prints what each job would write. Expect the maps (moc-root.md,moc-memory.mdand each type's page) and the calendar year maps. Anything else it would write, such as a collapsed copy or a date gloss, rewrites a card; note which cards, for step 11. -
Regenerate needs-review:
python3 harness/skills/memory/scripts/needs_review.py --vault <memory-root> --write
The nightly Python cycle (
dream.py) does this too; run it here rather than waiting for the night. -
Finish it:
python3 scripts/migrate/maps_and_root_notes.py --finish --plan <PLAN>
This checks every post-condition the gates will enforce: the three named maps exist,
mocs/and the calendar root hold their shape, each year's map lists exactly that year's facet notes,moc-root.mdlists every area's map, and no note anywhere still names what went. It writes the marker only when all of them hold. A failure lists what's wrong and writes nothing; fix it and re-run--finishagainst the same plan. -
Commit the marker by hand. It's a new dot-named file (
<memory-root>/memory/.maps-and-root-notes-complete), which the daemon does not commit on its own.--finishprints the exactgit addandgit commitcommand; run it as printed. -
Re-measure what the night owes:
agentmd enrich -dry-run
The deep count should match step 2, and the light count should rise by no more than one for each class card the plan's
linkslist rewrote. A card that was already pending adds nothing. Any other movement means a card was rewritten outside the plan, by step 7's pass or by another writer. Then stop the daemon as in step 1, sinceagentmd ledgerruns without it, and follow Run the card backfill steps 5 and 8. Rebuild the ledger, forget each target on step 2's pending list (under its new path when this run moved it), and measure again: the counts should match step 2. Bring the daemon back as in step 6. -
Reindex the embeddings:
agentmd embed
Every deleted or moved path drops out of the dense arm until this runs, and skipping it reads as a retrieval regression.
-
Bring the runner back:
launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.agentm.runner.plist launchctl kickstart -k gui/$(id -u)/com.agentm.runner
-
Run the full gate battery:
bash scripts/check-all.sh
The battery runs
check-root-notes,check-calendar-rootand the retrieval gate (see CI gates reference). The retrieval gate names six flipped question ids and says how many more. If it moves, read what each flipped question expects before calling it drift: a question that expects a map, or a note this run moved, moved because of the migration.
-
python3 scripts/check-root-notes.pyandpython3 scripts/check-calendar-root.pyboth reportclean(see CI gates reference). -
memory/.maps-and-root-notes-completeexists at the memory root, and is committed. -
memory/mocs/moc-root.mdlists every area's map, andmemory/mocs/moc-memory.mdlists every memory type. - The deep, light and unchanged counts in
agentmd enrich -dry-runmatch step 2, or the light count is higher only by the class cards the plan'slinkslist rewrote. -
bash scripts/check-all.shpasses locally.
-
The dry run plans nothing.
Home.md,Filing.mdand every numbered map page are already gone.--finishstill needs an applied journal before it writes the marker, so apply the empty plan with--confirm-count 0, then run steps 7 to 10. -
--applyrefuses with "the vault is not what the dry run read." Something wrote to the vault between the dry run and the apply. Re-run the dry run (step 3) and apply the fresh plan. -
--applyrefuses on a file-count mismatch. You typed the wrong--confirm-count, or the vault moved. Re-run the dry run and copy its printed command verbatim. -
--applyreportsjournal matches the dry run: NO. Part of the run didn't land as planned. Read<engine state dir>/maps-and-root-notes/journal-<run_id>.json: itslandedobject names which of the deletions, moves, links and index failed. Don't run--finishagainst this plan;--revertthe run (below) and start again once you know why. - The dry run refuses the index draft. A draft must carry the write-authority table exactly once and link no retired note. Fix the draft and re-run the dry run.
- The dry run refuses a file with uncommitted changes. A file the run would delete or move has changes the vault hasn't committed, so no commit would restore it as it is. Commit it in the vault, then re-run the dry run.
-
--finishreports post-conditions that fail. Each line names what's still wrong: a missing map (steps 7 and 8 haven't run), amocs/or calendar-root finding (see CI gates reference), or a note that still names what went.--finishdoesn't repoint links itself, so fix the note by hand. Re-run--finish --plan <PLAN>once the lines clear. -
You need to undo an applied run. Run
python3 scripts/migrate/maps_and_root_notes.py --revert <RUN_ID>. The script restores every file the run wrote. It removes thememory/.maps-and-root-notes-completemarker if it exists. The script first checks that each file still holds what the run wrote. A run applied before that check existed is checked against the plan its dry run recorded in<engine state dir>/maps-and-root-notes/plan-<RUN_ID>.json. If that plan file is missing, the revert refuses. -
--revertrefuses and names files that changed since the run. Something wrote to each named file after the run. For example, a line was added to the moved day note, or the night re-enriched a card whose links the run repointed. Restoring the file would lose that write. The script restores nothing and leaves the marker. To revert anyway, save each later write. Put each named file back as the run left it; the first vault commit after the apply holds that state. Run--revertagain. Add the saved writes back by hand.
- scripts/migrate/maps_and_root_notes.py — the migration this page runs.
- CI gates reference § check-root-notes, check-calendar-root, check-class-directories, check-memory-root-shape — the gates this migration brings from report-only to enforcing.
-
Memory daemon reference § the dreaming binary — the
mocsandcalendarjobs that write the maps--finishchecks for. - Run the card backfill — the sibling migration whose shape this page follows, and whose ledger steps step 11 names.
- AgentM Vault design — the governing design for the shape this migration brings the vault to.
🔧 How-to
- Install machine-wide (recommended)
- Your first install
- Your first Agent View dispatch
- Configure a new project
- Re-detect a configured project
- Update an installed harness
- Use auto-context in phases
- Audit the vault
- Find missing note links
- Use AgentMemory in any agent
- Drop a card in the inbox
- Tune auto-orchestration
- Run without a vault
- Choose a storage backend
- Back the vault with Google Drive
- Set up Obsidian on the vault
- Find your way around the vault
- Run the memory-root trims migration
- Run the root casing migration
- Run the projects migration
- Run the card backfill
- Run the maps and root notes migration
- Persist a morning report
- Enable on-device notifications
- Enable the daily email
- Ingest an article
- Capture from your phone
- Archive a finished project
- Tune the archive
- Read the morning note and the nightly scorecard
- Read the weekly field brief
- Review flagged memories
- Use the daily calendar