diff --git a/docs/DESIGN.md b/docs/DESIGN.md
index 12f2dd0..5937fae 100644
--- a/docs/DESIGN.md
+++ b/docs/DESIGN.md
@@ -86,6 +86,17 @@ For early development, a `--state-dir` option is useful so plans and manifests c
The registry describes plugin sources and install behavior. It should be human-editable because many Beat Saber plugins have small packaging differences.
+Artifact source preference:
+
+1. Prefer upstream GitHub release artifacts for normal plugins.
+2. Use BeatMods as compatibility, dependency, and verification metadata even
+ when the artifact comes from GitHub.
+3. Use BeatMods CDN artifacts only when the upstream artifact is inaccessible,
+ the package is effectively BeatMods-only, or the package is a framework or
+ library dependency that does not have a normal plugin release source.
+4. Record both the artifact source and any BeatMods `modVersion`/version-id/
+ `zipHash` metadata used to justify compatibility.
+
Example:
```toml
diff --git a/docs/ROADMAP.md b/docs/ROADMAP.md
index 9c98185..6b3768a 100644
--- a/docs/ROADMAP.md
+++ b/docs/ROADMAP.md
@@ -8,6 +8,10 @@ The initial tool should stay conservative:
- Python owns instance discovery, dry-run plans, activation, install state, uninstall, and `UserData` backups.
- Release assets are selected through registry and lockfile data.
+- Prefer upstream GitHub release artifacts for normal plugins. Use BeatMods as
+ compatibility/dependency metadata, and as an artifact source only for
+ inaccessible upstream artifacts, BeatMods-only packages, or framework/library
+ dependencies.
- Mutating operations apply an explicit plan and record exact file hashes.
- Nix packages `plugin-helper`, but does not directly manage the mutable Beat Saber tree.
@@ -64,12 +68,25 @@ All modes should still produce the same kind of explicit plan before applying.
## Proposed Milestones
1. Keep the Python safety harness stable: scan, plan, apply, uninstall, and backups.
-2. Model one real plugin end to end with the current TOML lockfile and local asset planning.
-3. Add a Nix function that fetches and unpacks one locked plugin asset into a normalized tree.
-4. Generate a full plugin-set derivation for one Beat Saber version.
-5. Teach `plugin-helper plan` to compare a Nix output tree against an instance.
-6. Add `--activation-mode copy|symlink|materialize`.
-7. Move compatibility and dependency metadata toward shared data that both Python and Nix can consume.
+2. Model BSIPA bootstrap as a first-class install phase, preferring upstream GitHub release artifacts while preserving BeatMods `zipHash`/version metadata when used for verification or fallback.
+3. Resolve BeatMods dependency closures by mod-version id for verified mods before ordinary batch planning, but keep artifact sourcing GitHub-preferred.
+4. Model one real plugin end to end with the current TOML lockfile and local asset planning.
+5. Add a Nix function that fetches and unpacks one locked plugin asset into a normalized tree.
+6. Generate a full plugin-set derivation for one Beat Saber version.
+7. Teach `plugin-helper plan` to compare a Nix output tree against an instance.
+8. Add `--activation-mode copy|symlink|materialize`.
+9. Move compatibility and dependency metadata toward shared data that both Python and Nix can consume.
+
+## Warning Follow-Ups From 1.44.1 Bootstrap
+
+The first 1.44.1 BSIPA/SongCore smoketest worked, but it produced warnings worth tracking separately from install success:
+
+- BSML, SiraUtil, and SongCore have older target game-version metadata even though BeatMods verifies the selected releases for 1.44.1. Decide whether plugin-helper should treat BeatMods verification as a compatibility override.
+- The first bootstrap used BeatMods CDN artifacts for speed. BSIPA, BSML, and SiraUtil have now been matched to byte-identical upstream GitHub release assets. SongCore remains a BeatMods CDN fallback because the BeatMods preferred repo `Kylemc1413/SongCore` currently exposes no matching 3.16.0 GitHub release asset.
+- BSML reports missing Windows fonts under Proton. This is likely cosmetic, but may affect Unicode text rendering in mod UI.
+- SongCore warns that `Beat Saber_Data/CustomWIPLevels/Cache` has no `Info.dat`. Either create the expected cache directory shape or classify this warning as harmless.
+- SongCore could not read the audio rate for the built-in `Magic.wav` custom level and approximated duration from map length. Check whether this is a bundled-song oddity or a broader audio metadata issue.
+- The smoketest launcher can leave Beat Saber running after timeout. Prefer explicit teardown and consider a helper command that starts, watches logs, and kills the process tree deterministically.
## Open Questions
diff --git a/docs/notes/install-and-verify-plugins-1.44.1.md b/docs/notes/install-and-verify-plugins-1.44.1.md
new file mode 100644
index 0000000..1dfb96a
--- /dev/null
+++ b/docs/notes/install-and-verify-plugins-1.44.1.md
@@ -0,0 +1,302 @@
+# Beat Saber 1.44.1 Plugin Install and Verification
+
+Tracking document for installing plugins into the Beat Saber 1.44.1 instance with
+`plugin-helper`, then verifying the game loads and the IPA log stays clean enough
+to continue.
+
+Goal for this pass: get a working 1.44.1 plugin set. If a plugin blocks startup,
+breaks song loading, or produces serious IPA errors, omit it and record the
+failure. Do not fix incompatible plugins today.
+
+## Source Baseline
+
+Use `docs/notes/mods-used-in-1.40.8.md` as the starting inventory.
+
+- 1.40.8 was installed through bs-manager plus some manual/private plugin drops.
+- 1.44.1 was installed through bs-manager for the game only.
+- 1.44.1 plugins should be installed through `plugin-helper`, not bs-manager.
+- BeatMods and GitHub release metadata may differ from the 1.40.8 set, so every
+ selected plugin needs an explicit source/version recorded before install.
+- Prefer upstream GitHub releases as the artifact source for normal plugins.
+ Use BeatMods as compatibility/dependency metadata by default, and as an
+ artifact source only when the upstream artifact is inaccessible, the package is
+ effectively BeatMods-only, or the package is a framework/library dependency
+ such as the .NET assemblies.
+
+## Current 1.44.1 Instance Observation
+
+As of 2026-06-28, the BSManager-managed 1.44.1 instance at
+`~/.local/share/BSManager/BSInstances/1.44.1` appears to be an unpatched vanilla
+game tree:
+
+- root `IPA/`, `IPA.exe`, `winhttp.dll`, `Libs/`, `Logs/`, and `UserData` are
+ absent
+- root `Plugins/` exists only because it was created manually and is empty
+- the only pre-existing `Plugins` directory was `Beat Saber_Data/Plugins`, which
+ contains Unity/runtime native DLLs and must not be treated as the BSIPA mod
+ folder
+
+By contrast, the Steam install for the same game version `1.44.1_20239` has
+BSIPA instrumentation and support files at the game root:
+
+- `IPA/`, `IPA.exe`, `winhttp.dll`
+- `Libs/`
+- populated root `Plugins/`
+- `Logs/_latest.log`
+- `UserData/`
+
+This means BSManager's mod installation step does more than place user-selected
+plugin DLLs. It also materializes the BSIPA loader and shared library substrate
+that make IPA logs and BSIPA plugin loading possible. `plugin-helper` needs to
+model that bootstrap layer separately from ordinary plugin batches.
+
+The vanilla BSManager 1.44.1 launch did not produce an IPA log because BSIPA was
+not present. It did produce a Unity `Player.log` under BSManager's shared Proton
+compatdata and reached Steam/game initialization. So the missing bootstrap layer
+is not proven to be required for vanilla Beat Saber to execute, but it is
+required for the modded workflow and may affect the BSManager launch behavior we
+are trying to reproduce.
+
+## Verification Loop
+
+Use the canonical smoketest workflow in `docs/SMOKETEST.md`.
+
+For each batch:
+
+1. Back up or snapshot the current 1.44.1 plugin state.
+2. Install the selected batch with `plugin-helper`.
+3. Start Beat Saber 1.44.1 with the foreground `timeout 10` Proton/FPFC launch.
+4. Watch the IPA log during launch and first menu load.
+5. Load a known-good custom song if the batch affects songs, playlists, maps, or
+ leaderboards.
+6. Record result in this document.
+7. If the game fails to load or logs serious plugin errors, remove the failing
+ plugin or batch and retry.
+
+Suggested log checks:
+
+- startup reaches main menu
+- no plugin dependency resolution failures
+- no repeated unhandled exceptions
+- no missing assembly errors
+- no hard failures from BSIPA, SiraUtil, BSML, SongCore, or CustomJSONData
+- custom songs still enumerate
+- playlist and downloader UI still opens when relevant
+
+## Status Legend
+
+- todo: not attempted
+- planned: source selected, ready to install
+- installed: copied into the instance
+- verified: game launched and basic behavior checked
+- verified with warning: game launched, but the log had a non-blocking warning to track
+- omitted: skipped for this 1.44.1 pass due to failure or missing compatible release
+- defer: intentionally left for a later pass
+
+## plugin-helper Work Needed
+
+Track the tool work discovered while using it for 1.44.1.
+
+| Item | Status | Notes |
+| --- | --- | --- |
+| Add or generate a 1.44.1 lockfile | todo | Need exact versions, sources, hashes, and target paths. |
+| Model BSIPA/bootstrap installation separately | todo | BSManager creates root `IPA/`, `IPA.exe`, `winhttp.dll`, `Libs/`, `Logs`, `UserData`, and root `Plugins/`. |
+| Resolve BeatMods dependency closure | todo | Use as metadata/advisory input even when downloading plugin artifacts from upstream GitHub. |
+| Install BeatMods library payloads into `Libs/` | todo | Include framework-library cases when required; these are likely exceptions to GitHub-preferred sourcing. |
+| Support local/private plugin payloads | todo | Needed for paid closed-source and manual plugins. |
+| Record install state for every copied file | todo | Required for rollback and clean omission testing. |
+| Add a batch install workflow or documented command sequence | todo | Useful for two-or-three-at-a-time validation. |
+| Add IPA log inspection helper | todo | Nice-to-have; manual log watching via `docs/SMOKETEST.md` is acceptable today. |
+
+## Batch Plan
+
+Install in small batches. Dependencies may be installed earlier than the plugin
+that made them necessary, but record that relationship when it is known.
+
+### Batch 0: Game and Loader Baseline
+
+Purpose: verify the clean 1.44.1 game and loader before adding gameplay mods.
+
+| Plugin | Status | Source/version | Verification notes |
+| --- | --- | --- | --- |
+| BSIPA | verified | GitHub `nike4613/BeatSaber-IPA-Reloaded` tag `4.3.7`, asset `BSIPA-net472-x64.zip`; BeatMods version id 2561, zipHash `947774ef1010ff809ae05e345e269a90` | GitHub asset is byte-identical to the BeatMods CDN zip used for initial bootstrap. Smoketest produced `Logs/_latest.log`; IPA reported game version 1.44.1 and BSIPA 4.3.7. |
+
+### Batch 1: Core Song Loading
+
+Purpose: get custom song loading working before UI, leaderboard, or cosmetic
+mods are added.
+
+| Plugin | Status | Source/version | Verification notes |
+| --- | --- | --- | --- |
+| SongCore | verified | BeatMods 3.16.0, version id 2564, zipHash `0af9c0a03074c17ca15c1b667a0e30c8`; BeatMods preferred repo `Kylemc1413/SongCore` currently has no matching 3.16.0 GitHub release asset | IPA loaded SongCore; full song refresh loaded 2 songs from `CustomLevels`. Keep as BeatMods CDN fallback until a matching upstream asset is found. |
+| BeatSaberMarkupLanguage | verified | GitHub `monkeymanboy/BeatSaberMarkupLanguage` tag `v1.14.1`, asset `BeatSaberMarkupLanguage-v1.14.1+bs.1.41.1-RELEASE.zip`; BeatMods version id 2567, zipHash `46149d03f8549e07f2c88fefde4337b2` | GitHub asset is byte-identical to the BeatMods CDN zip used for initial bootstrap. IPA loaded BSML; font fallback warnings only. |
+| SiraUtil | verified | GitHub `Auros/SiraUtil` tag `v3.3.1`, asset `SiraUtil-v3.3.1+bs.1.42.0.zip`; BeatMods version id 2565, zipHash `ae14f7d3192a919d5d996c802fbde037` | GitHub asset is byte-identical to the BeatMods CDN zip used for initial bootstrap. IPA loaded SiraUtil and installed app/menu installers. |
+
+### Batch 2: Custom Map Capabilities
+
+Purpose: enable common map extensions after basic song loading is proven.
+
+| Plugin | Status | Source/version | Verification notes |
+| --- | --- | --- | --- |
+| CustomJSONData | verified | GitHub `Aeroluna/CustomJSONData` tag `v2.6.8`, asset `CustomJSONData-2.6.8+1.40.0-bs1.40.0-7c2c32c.zip`; BeatMods version id 2327, zipHash `fed31638bbb678580ef760ec83cfd486` | GitHub asset is byte-identical to the BeatMods CDN zip. IPA loaded CustomJSONData 2.6.8+1.40.0; game reached main initialization; SongCore still loaded 2 custom songs. |
+| Heck | omitted | No BeatMods verified 1.44.1 entry found on 2026-06-28 | Required by Chroma/NoodleExtensions/Vivify; skip until a compatible source is identified. |
+| Chroma | omitted | No BeatMods verified 1.44.1 entry found on 2026-06-28 | Skip until Heck and a compatible Chroma source are identified. |
+| NoodleExtensions | omitted | No BeatMods verified 1.44.1 entry found on 2026-06-28 | Skip until Heck and a compatible NoodleExtensions source are identified. |
+| Vivify | omitted | No BeatMods verified 1.44.1 entry found on 2026-06-28 | Skip until Heck and a compatible Vivify source are identified. |
+
+### Batch 3: Downloaders and Playlists
+
+Purpose: restore in-game song discovery and playlist management.
+
+| Plugin | Status | Source/version | Verification notes |
+| --- | --- | --- | --- |
+| BeatSaverDownloader | verified with warning | BeatMods 6.0.7, version id 2217, zipHash `a740c6e68a9b5d1dfda3cc8e81f7cf06`; BeatMods preferred repo `Top-Cat/BeatSaverDownloader` exposes no release assets through the GitHub releases API | IPA loaded BeatSaver Downloader 6.0.7 and started its internal webserver. Warning: it probed for missing `BetterSongList.dll` with IPA library-loader `CRITICAL` lines, then continued. |
+| PlaylistManager | omitted | No BeatMods verified 1.44.1 entry found on 2026-06-28 | Skip until a compatible source is identified. |
+| BeatSaverUpdater | verified | GitHub `ibillingsley/BeatSaverUpdater` tag `1.2.11`, asset `BeatSaverUpdater-1.2.11-bs1.39.1-3698f98.zip`; BeatMods version id 2352, zipHash `d9ea8dd0cbaac66cbb02fa59a548e42b` | GitHub asset is byte-identical to the BeatMods CDN zip. IPA loaded BeatSaverUpdater 1.2.11. |
+| BeatSaverVoting | omitted | No BeatMods verified 1.44.1 entry found on 2026-06-28 | Skip until a compatible source is identified. |
+| BeatSaberPlaylistsLib | verified | BeatMods 1.7.2, version id 2175, zipHash `a3418b75ed7294a3856f3eca12bbd672`; BeatMods preferred repo `Meivyn/BeatSaberPlaylistsLib` exposes no release assets through the GitHub releases API | IPA loaded BeatSaberPlaylistsLib 1.7.2. |
+| BeatSaverSharp | verified | BeatMods 3.4.5, version id 1831, zipHash `be37e13e93d9ac7da4efbdc3f514fa8f`; BeatMods preferred repo `lolPants/BeatSaverSharp` was inaccessible through the GitHub releases API | IPA loaded BeatSaverSharp 3.4.5. |
+| ScoreSaberSharp | verified with warning | BeatMods 0.1.0, version id 445, zipHash `8713168c598577ee7c73fa3cf0e26f5c`; BeatMods lists `scoresaber.com` rather than a GitHub release source | IPA loaded ScoreSaberSharp 0.1.0. Warning: bare manifest does not declare files. |
+| BS Utils | verified | BeatMods 1.14.3, version id 2563, zipHash `918d13ac2821a3a17b2819f8861453e9`; BeatMods preferred repo `Kylemc1413/Beat-Saber-Utils` exposes no matching 1.14.3 GitHub release asset | IPA loaded BS Utils 1.14.3. |
+| Ini Parser | verified | BeatMods 2.5.9, version id 1352, zipHash `5df74ad1c6b120fecdc615dd55f15b88` | IPA loaded INI Parser 2.5.9. |
+| ImageSharp | verified | BeatMods 2.0.0, version id 1428, zipHash `b642fec88b0f84a0643ebd401d08da35` | IPA loaded ImageSharp 2.0.0. |
+| System.IO.Compression | verified with warning | BeatMods 4.6.57, version id 1763, zipHash `a4e9e26f61967e56168e08eecb01ab88` | IPA loaded System.IO.Compression 4.6.57. Warning: duplicate-library notice because the game also ships this assembly. |
+| System.IO.Compression.FileSystem | verified | BeatMods 4.7.3056, version id 1762, zipHash `e19f6fd395d54de7bfcbbbe3084dea28` | IPA loaded System.IO.Compression.FileSystem 4.7.3056. |
+
+### Batch 4: Leaderboards and Ranking
+
+Purpose: add online leaderboard/ranking integrations after core song behavior is
+stable.
+
+| Plugin | Status | Source/version | Verification notes |
+| --- | --- | --- | --- |
+| ScoreSaber | todo | TBD | Verify menu panel and song leaderboard. |
+| BeatLeader | todo | TBD | Verify menu panel and song leaderboard. |
+| LeaderboardCore | todo | TBD | Dependency for BeatLeader. |
+| AccSaber | todo | TBD | Manual/plugin-helper registry candidate. |
+| SongRankedBadge | todo | TBD | Verify song-list badges. |
+
+### Batch 5: Practice and Gameplay Tweaks
+
+Purpose: add small gameplay helpers two or three at a time.
+
+| Plugin | Status | Source/version | Verification notes |
+| --- | --- | --- | --- |
+| IntroSkip | todo | TBD | Verify song start behavior. |
+| FailButton | todo | TBD | Verify practice/fail UI behavior. |
+| EasyOffset | todo | TBD | Verify settings UI opens. |
+| GottaGoFast | todo | TBD | Verify startup and song load. |
+| HitsoundTweaks | todo | TBD | Verify settings and audio behavior. |
+| KeepMyOverridesPls | todo | TBD | Verify startup only unless override test is easy. |
+| SoundReplacer | todo | TBD | Verify startup and settings. |
+| KeyRemapper | todo | TBD | Manual install candidate. |
+| SquatToBegin | todo | TBD | Manual install candidate. |
+| JDFixer | todo | TBD | Manual install candidate. |
+
+### Batch 6: UI and Song Browser
+
+Purpose: restore song-list, menu, and visualization conveniences.
+
+| Plugin | Status | Source/version | Verification notes |
+| --- | --- | --- | --- |
+| BetterSongList | todo | TBD | Verify song browser opens and filters work. |
+| HitScoreVisualizer | todo | TBD | Verify settings UI and in-song display. |
+| DiTails | todo | TBD | Verify details panel. |
+| HideTheLogo | todo | TBD | Verify menu loads. |
+| SongChartVisualizer | todo | TBD | Verify chart UI. |
+| WhyIsThereNoLeaderboard | todo | TBD | Source TBD from 1.40.8 install. |
+| Setlist | todo | local build or release | Requires BeatLeader signed in, PlaylistManager, and BeatSaberPlaylistsLib; verify `Setlist` log lines. |
+| Custom Campaigns | todo | TBD | Manual install candidate. |
+
+### Batch 7: Cosmetic, Camera, and Lighting
+
+Purpose: add visual and stream-facing mods after functional mods are stable.
+
+| Plugin | Status | Source/version | Verification notes |
+| --- | --- | --- | --- |
+| AdBlocker | todo | TBD | Verify startup. |
+| HighlightBombs | todo | TBD | Verify in-song visuals. |
+| PitchBlack | todo | TBD | Verify lighting behavior. |
+| Dimmer | todo | TBD | Manual install candidate. |
+| ReeCamera | todo | TBD | Manual install candidate. |
+| ReeSabers | todo | TBD | Manual install candidate. |
+
+### Batch 8: Paid or Closed-Source Plugins
+
+Purpose: restore private plugin set only after public/dependency-heavy mods are
+known good.
+
+| Plugin | Status | Source/version | Verification notes |
+| --- | --- | --- | --- |
+| BeatSaberPlus_Chat | todo | local/private | Verify startup and module UI. |
+| BeatSaberPlus_ChatEmoteRain | todo | local/private | Verify startup. |
+| BeatSaberPlus_ChatIntegrations | todo | local/private | Verify startup. |
+| BeatSaberPlus_ChatRequest | todo | local/private | Verify startup. |
+| BeatSaberPlus_GameTweaker | todo | local/private | Verify startup. |
+| BeatSaberPlus_MenuMusic | todo | local/private | Verify startup. |
+| BeatSaberPlus_Multiplayer | todo | local/private | Verify startup. |
+| BeatSaberPlus_NoteTweaker | todo | local/private | Verify startup. |
+| BeatSaberPlus_SongChartVisualizer | todo | local/private | Verify startup. |
+| BeatSaberPlus_SongOverlay | todo | local/private | Verify startup. |
+| NalulunaMenu | todo | local/private | Verify startup and menu. |
+| NalulunaCounters | todo | local/private | Verify in-song counters. |
+| NalulunaLevelDetail | todo | local/private | Verify song detail panel. |
+| NalulunaSliceVisualizer | todo | local/private | Verify in-song visuals. |
+| NalulunaSongPreview | todo | local/private | Verify song preview. |
+| NalulunaMissIndicator | todo | local/private | Verify in-song visuals. |
+| NalulunaEnergy | todo | local/private | Verify in-song HUD. |
+| NalulunaFps | todo | local/private | Verify overlay. |
+| NalulunaPPCoin | todo | local/private | Verify startup. |
+| NalulunaRewinder | todo | local/private | Verify startup. |
+| NalulunaAvatars | todo | local/private | Verify avatar load. |
+| NalulunaShaders | todo | local/private | Verify dependency for Naluluna visuals. |
+| NalulunaSkybox | todo | local/private | Verify skybox sample manifest and skybox load. |
+| NalulunaUtils | todo | local/private | Verify dependency load. |
+
+## Shared Libraries and Dependency Packages
+
+These should be installed because selected plugins require them, not because they
+are user-facing features.
+
+| Package | Status | Required by | Source/version | Verification notes |
+| --- | --- | --- | --- | --- |
+| AssetBundleLoadingTools | todo | Vivify | TBD | Usually `Libs/`. |
+| BS Utils | verified | BeatSaverDownloader, BeatLeader | BeatMods 1.14.3, version id 2563, zipHash `918d13ac2821a3a17b2819f8861453e9` | IPA loaded BS Utils 1.14.3. |
+| CameraUtils | todo | Vivify | TBD | Verify no missing assembly errors. |
+| ImageSharp | verified | BeatSaberPlaylistsLib | BeatMods 2.0.0, version id 1428, zipHash `b642fec88b0f84a0643ebd401d08da35` | IPA loaded ImageSharp 2.0.0. |
+| Ini Parser | verified | BS Utils | BeatMods 2.5.9, version id 1352, zipHash `5df74ad1c6b120fecdc615dd55f15b88` | IPA loaded INI Parser 2.5.9. |
+| LookupID | todo | Chroma | TBD | Verify no missing assembly errors. |
+| OpenVR API | todo | TBD | TBD | Include only if a 1.44.1 dependency needs it. |
+| protobuf-net | todo | SongDetailsCache | TBD | Usually `Libs/`. |
+| SongDetailsCache | todo | BetterSongList, SongRankedBadge | TBD | Verify cache startup. |
+| System.IO.Compression | verified with warning | BeatSaberPlaylistsLib, System.IO.Compression.FileSystem | BeatMods 4.6.57, version id 1763, zipHash `a4e9e26f61967e56168e08eecb01ab88` | IPA loaded System.IO.Compression 4.6.57; logged a duplicate-library notice because the game also ships this assembly. |
+| System.IO.Compression.FileSystem | verified | BeatSaverDownloader | BeatMods 4.7.3056, version id 1762, zipHash `e19f6fd395d54de7bfcbbbe3084dea28` | IPA loaded System.IO.Compression.FileSystem 4.7.3056. |
+| Dynamic Bone | defer | TBD | TBD | Include only if a selected 1.44.1 mod requires it. |
+| Final IK | defer | TBD | TBD | Include only if a selected 1.44.1 mod requires it. |
+
+## Omitted Plugins
+
+Record plugins skipped for this 1.44.1 pass. This is not a fix list for today.
+
+| Plugin | Reason omitted | Evidence/log note | Follow-up |
+| --- | --- | --- | --- |
+| Heck | No BeatMods verified 1.44.1 entry found on 2026-06-28. | Not installed. | Revisit only with a compatible source. |
+| Chroma | No BeatMods verified 1.44.1 entry found on 2026-06-28. | Not installed. | Revisit after Heck is available. |
+| NoodleExtensions | No BeatMods verified 1.44.1 entry found on 2026-06-28. | Not installed. | Revisit after Heck is available. |
+| Vivify | No BeatMods verified 1.44.1 entry found on 2026-06-28. | Not installed. | Revisit after Heck is available. |
+| PlaylistManager | No BeatMods verified 1.44.1 entry found on 2026-06-28. | Not installed. | Revisit only with a compatible source. |
+| BeatSaverVoting | No BeatMods verified 1.44.1 entry found on 2026-06-28. | Not installed. | Revisit only with a compatible source. |
+
+## Batch Results
+
+| Batch | Date | Result | IPA log notes | Action |
+| --- | --- | --- | --- | --- |
+| 0 | 2026-06-28 | verified | BSIPA 4.3.7 installed and generated `Logs/_latest.log`. | Continue to dependency/plugin batches. |
+| 1 | 2026-06-28 | verified | BSML, SiraUtil, and SongCore loaded; SongCore loaded 2 custom songs. Warnings: older target game-version metadata, missing Windows fonts, missing `CustomWIPLevels/Cache/Info.dat`, and one built-in `Magic.wav` duration approximation. | Treat as acceptable bootstrap baseline. |
+| 2 | 2026-06-28 | verified | CustomJSONData loaded; startup reached main initialization; SongCore still loaded 2 custom songs. Warnings: older target game-version metadata, missing Windows fonts, and missing `CustomWIPLevels/Cache/Info.dat`. | Continue to downloader/playlist batch. |
+| 3 | 2026-06-28 | verified with warning | BeatSaverDownloader, BeatSaverUpdater, BeatSaberPlaylistsLib, BeatSaverSharp, ScoreSaberSharp, BS Utils, Ini Parser, ImageSharp, and System.IO.Compression packages loaded; startup reached main initialization; SongCore still loaded 2 custom songs. Warning: BeatSaverDownloader probed for missing `BetterSongList.dll` with IPA library-loader `CRITICAL` lines, then continued and started its internal webserver. | Stop here per request; consider installing BetterSongList before deeper downloader UI testing. |
+| 4 | | todo | | |
+| 5 | | todo | | |
+| 6 | | todo | | |
+| 7 | | todo | | |
+| 8 | | todo | | |
diff --git a/locks/1.44.1.lock.toml b/locks/1.44.1.lock.toml
new file mode 100644
index 0000000..d16173c
--- /dev/null
+++ b/locks/1.44.1.lock.toml
@@ -0,0 +1,134 @@
+beat_saber_version = "1.44.1"
+instance = "1.44.1"
+
+[[plugins]]
+id = "bsipa"
+repo = "nike4613/BeatSaber-IPA-Reloaded"
+tag = "4.3.7"
+asset = "BSIPA-net472-x64.zip"
+sha256 = "899b8a1dda91935bd5c19a211fa48e44e32f7be9ab82b6fc796709c753b7b2bc"
+install_strategy = "root-zip"
+reason = "BeatMods verified BSIPA 4.3.7 for Beat Saber 1.44.1 as version id 2561, zipHash 947774ef1010ff809ae05e345e269a90. GitHub asset is byte-identical to the BeatMods CDN zip used for initial bootstrap."
+
+[[plugins]]
+id = "beatsabermarkuplanguage"
+repo = "monkeymanboy/BeatSaberMarkupLanguage"
+tag = "v1.14.1"
+asset = "BeatSaberMarkupLanguage-v1.14.1+bs.1.41.1-RELEASE.zip"
+sha256 = "816613459853955e2b7c02123ed42f8e5bdbd946cc774fd5fcc4e80a6a09120a"
+install_strategy = "bsipa-zip"
+reason = "BeatMods verified BeatSaberMarkupLanguage 1.14.1 for Beat Saber 1.44.1 as version id 2567, zipHash 46149d03f8549e07f2c88fefde4337b2. GitHub asset is byte-identical to the BeatMods CDN zip used for initial bootstrap."
+
+[[plugins]]
+id = "sirautil"
+repo = "Auros/SiraUtil"
+tag = "v3.3.1"
+asset = "SiraUtil-v3.3.1+bs.1.42.0.zip"
+sha256 = "2253e5c31324e1e01b23480acba5ceee6b67eb8f16a079f58bc2f6ce7b12051f"
+install_strategy = "bsipa-zip"
+reason = "BeatMods verified SiraUtil 3.3.1 for Beat Saber 1.44.1 as version id 2565, zipHash ae14f7d3192a919d5d996c802fbde037. GitHub asset is byte-identical to the BeatMods CDN zip used for initial bootstrap."
+
+[[plugins]]
+id = "songcore"
+repo = "Kylemc1413/SongCore"
+tag = "beatmods-3.16.0"
+asset = "SongCore-3.16.0.zip"
+sha256 = "f9be5d66426d795c6c8af2a4da0150a298d2d6a65fbabcab316d379088a40019"
+install_strategy = "bsipa-zip"
+reason = "BeatMods verified SongCore 3.16.0 for Beat Saber 1.44.1 as version id 2564, zipHash 0af9c0a03074c17ca15c1b667a0e30c8. BeatMods points to Kylemc1413/SongCore, but that GitHub repo currently exposes releases only through 3.10.4, so this remains a BeatMods CDN fallback until a matching upstream release artifact is found."
+
+[[plugins]]
+id = "customjsondata"
+repo = "Aeroluna/CustomJSONData"
+tag = "v2.6.8"
+asset = "CustomJSONData-2.6.8+1.40.0-bs1.40.0-7c2c32c.zip"
+sha256 = "30555c77485d2837bd294608fe4e23c34415b89413997be67a6150318090b216"
+install_strategy = "bsipa-zip"
+reason = "BeatMods verified CustomJSONData 2.6.8+1.40.0 for Beat Saber 1.44.1 as version id 2327, zipHash fed31638bbb678580ef760ec83cfd486. GitHub asset is byte-identical to the BeatMods CDN zip."
+
+[[plugins]]
+id = "iniparser"
+repo = "rickyah/ini-parser"
+tag = "beatmods-2.5.9"
+asset = "IniParser-2.5.9.zip"
+sha256 = "b761293bea73ff3cb9998f404594aade617638aba4318203320189baf3449ff1"
+install_strategy = "bsipa-zip"
+reason = "BeatMods verified Ini Parser 2.5.9 for Beat Saber 1.44.1 as version id 1352, zipHash 5df74ad1c6b120fecdc615dd55f15b88. Use BeatMods CDN as a framework/library dependency payload."
+
+[[plugins]]
+id = "bs-utils"
+repo = "Kylemc1413/Beat-Saber-Utils"
+tag = "beatmods-1.14.3"
+asset = "BSUtils-1.14.3.zip"
+sha256 = "b450fa4561da5b5ad834a3dcf6f127c2d73e5f971aa6c986514a6b185d68edfe"
+install_strategy = "bsipa-zip"
+reason = "BeatMods verified BS Utils 1.14.3 for Beat Saber 1.44.1 as version id 2563, zipHash 918d13ac2821a3a17b2819f8861453e9. Upstream GitHub releases do not expose a matching 1.14.3 asset, so this remains a BeatMods CDN fallback."
+
+[[plugins]]
+id = "system-io-compression"
+tag = "beatmods-4.6.57"
+asset = "System.IO.Compression-4.6.57.zip"
+sha256 = "9067ddaf52c077f38a27ace6180a8134ceaaf1ecba752d08de81b4cc0c13aa43"
+install_strategy = "bsipa-zip"
+reason = "BeatMods verified System.IO.Compression 4.6.57 for Beat Saber 1.44.1 as version id 1763, zipHash a4e9e26f61967e56168e08eecb01ab88. Use BeatMods CDN as a framework/library dependency payload."
+
+[[plugins]]
+id = "system-io-compression-filesystem"
+tag = "beatmods-4.7.3056"
+asset = "System.IO.Compression.FileSystem-4.7.3056.zip"
+sha256 = "1b6f7a33a69980344717a37240ed80b022903a52968d4968f307cf754e3a03f7"
+install_strategy = "bsipa-zip"
+reason = "BeatMods verified System.IO.Compression.FileSystem 4.7.3056 for Beat Saber 1.44.1 as version id 1762, zipHash e19f6fd395d54de7bfcbbbe3084dea28. Use BeatMods CDN as a framework/library dependency payload."
+
+[[plugins]]
+id = "imagesharp"
+repo = "SixLabors/ImageSharp"
+tag = "beatmods-2.0.0"
+asset = "ImageSharp-2.0.0.zip"
+sha256 = "b2bf6d195f25e1298199a389e381ab42f163b284105ae6181259d74f2528301b"
+install_strategy = "bsipa-zip"
+reason = "BeatMods verified ImageSharp 2.0.0 for Beat Saber 1.44.1 as version id 1428, zipHash b642fec88b0f84a0643ebd401d08da35. Use BeatMods CDN as a framework/library dependency payload."
+
+[[plugins]]
+id = "beatsaberplaylistslib"
+repo = "Meivyn/BeatSaberPlaylistsLib"
+tag = "beatmods-1.7.2"
+asset = "BeatSaberPlaylistsLib-1.7.2.zip"
+sha256 = "dfb26cf90cb73834c405727418c0121d8546cad0403abd35a09437dab766bd32"
+install_strategy = "bsipa-zip"
+reason = "BeatMods verified BeatSaberPlaylistsLib 1.7.2 for Beat Saber 1.44.1 as version id 2175, zipHash a3418b75ed7294a3856f3eca12bbd672. Upstream GitHub exposes no release assets through the releases API, so this remains a BeatMods CDN fallback."
+
+[[plugins]]
+id = "beatsaversharp"
+repo = "lolPants/BeatSaverSharp"
+tag = "beatmods-3.4.5"
+asset = "BeatSaverSharp-3.4.5.zip"
+sha256 = "f5f37b27438e9b2fa1d9fbdf51a4f015f44ae04979cbdd9b90f6ae18583a6911"
+install_strategy = "bsipa-zip"
+reason = "BeatMods verified BeatSaverSharp 3.4.5 for Beat Saber 1.44.1 as version id 1831, zipHash be37e13e93d9ac7da4efbdc3f514fa8f. BeatMods upstream URL returned inaccessible via the GitHub releases API, so this remains a BeatMods CDN fallback."
+
+[[plugins]]
+id = "scoresabersharp"
+tag = "beatmods-0.1.0"
+asset = "ScoreSaberSharp-0.1.0.zip"
+sha256 = "7f30be996f8f0e997f2d848e34de1d03ef6dc744ffc32d3fe505881ca22c6cd3"
+install_strategy = "bsipa-zip"
+reason = "BeatMods verified ScoreSaberSharp 0.1.0 for Beat Saber 1.44.1 as version id 445, zipHash 8713168c598577ee7c73fa3cf0e26f5c. BeatMods lists scoresaber.com rather than a GitHub release source, so this remains a BeatMods CDN fallback."
+
+[[plugins]]
+id = "beatsaverdownloader"
+repo = "Top-Cat/BeatSaverDownloader"
+tag = "beatmods-6.0.7"
+asset = "BeatSaverDownloader-6.0.7.zip"
+sha256 = "4108b11eae11d09f8c4e838dde1dc36108f1f3fd4fff31b951e7c551fa59f5f1"
+install_strategy = "bsipa-zip"
+reason = "BeatMods verified BeatSaverDownloader 6.0.7 for Beat Saber 1.44.1 as version id 2217, zipHash a740c6e68a9b5d1dfda3cc8e81f7cf06. Upstream GitHub exposes no release assets through the releases API, so this remains a BeatMods CDN fallback."
+
+[[plugins]]
+id = "beatsaverupdater"
+repo = "ibillingsley/BeatSaverUpdater"
+tag = "1.2.11"
+asset = "BeatSaverUpdater-1.2.11-bs1.39.1-3698f98.zip"
+sha256 = "6237da05cbc044e99211cb0e569c917fe61bb0da25e42c61a6d438371548ebba"
+install_strategy = "bsipa-zip"
+reason = "BeatMods verified BeatSaverUpdater 1.2.11 for Beat Saber 1.44.1 as version id 2352, zipHash d9ea8dd0cbaac66cbb02fa59a548e42b. GitHub asset is byte-identical to the BeatMods CDN zip."
diff --git a/registry/plugins.toml b/registry/plugins.toml
index 0a6ca48..a38b295 100644
--- a/registry/plugins.toml
+++ b/registry/plugins.toml
@@ -21,3 +21,267 @@ repo = "not-dexter/accsaber-reloaded-plugin"
asset_patterns = ["1.40.8.zip"]
install_strategy = "bsipa-zip"
category = "leaderboard"
+
+[[plugins]]
+id = "bsipa"
+name = "BSIPA"
+repo = "nike4613/BeatSaber-IPA-Reloaded"
+asset_patterns = ["BSIPA-net472-x64.zip"]
+install_strategy = "root-zip"
+category = "core"
+
+[[plugins]]
+id = "beatsabermarkuplanguage"
+name = "BeatSaberMarkupLanguage"
+repo = "monkeymanboy/BeatSaberMarkupLanguage"
+asset_patterns = ["*RELEASE.zip"]
+install_strategy = "bsipa-zip"
+category = "library"
+
+[[plugins.dependencies]]
+id = "bsipa"
+constraint = ">=4.3.7"
+required = true
+
+[[plugins]]
+id = "sirautil"
+name = "SiraUtil"
+repo = "Auros/SiraUtil"
+asset_patterns = ["SiraUtil-*.zip"]
+install_strategy = "bsipa-zip"
+category = "library"
+
+[[plugins.dependencies]]
+id = "bsipa"
+constraint = ">=4.3.7"
+required = true
+
+[[plugins]]
+id = "songcore"
+name = "SongCore"
+repo = "Kylemc1413/SongCore"
+asset_patterns = ["SongCore-*.zip"]
+install_strategy = "bsipa-zip"
+category = "core"
+
+[[plugins.dependencies]]
+id = "bsipa"
+constraint = ">=4.3.7"
+required = true
+
+[[plugins.dependencies]]
+id = "beatsabermarkuplanguage"
+constraint = ">=1.14.1"
+required = true
+
+[[plugins.dependencies]]
+id = "sirautil"
+constraint = ">=3.3.1"
+required = true
+
+[[plugins]]
+id = "customjsondata"
+name = "CustomJSONData"
+repo = "Aeroluna/CustomJSONData"
+asset_patterns = ["CustomJSONData-*.zip"]
+install_strategy = "bsipa-zip"
+category = "library"
+
+[[plugins.dependencies]]
+id = "bsipa"
+constraint = ">=4.3.7"
+required = true
+
+[[plugins]]
+id = "iniparser"
+name = "Ini Parser"
+repo = "rickyah/ini-parser"
+asset_patterns = ["IniParser-*.zip"]
+install_strategy = "bsipa-zip"
+category = "library"
+
+[[plugins]]
+id = "bs-utils"
+name = "BS Utils"
+repo = "Kylemc1413/Beat-Saber-Utils"
+asset_patterns = ["BSUtils-*.zip"]
+install_strategy = "bsipa-zip"
+category = "library"
+
+[[plugins.dependencies]]
+id = "iniparser"
+constraint = ">=2.5.9"
+required = true
+
+[[plugins.dependencies]]
+id = "bsipa"
+constraint = ">=4.3.7"
+required = true
+
+[[plugins]]
+id = "system-io-compression"
+name = "System.IO.Compression"
+asset_patterns = ["System.IO.Compression-*.zip"]
+install_strategy = "bsipa-zip"
+category = "library"
+
+[[plugins]]
+id = "system-io-compression-filesystem"
+name = "System.IO.Compression.FileSystem"
+asset_patterns = ["System.IO.Compression.FileSystem-*.zip"]
+install_strategy = "bsipa-zip"
+category = "library"
+
+[[plugins.dependencies]]
+id = "system-io-compression"
+constraint = ">=4.6.57"
+required = true
+
+[[plugins]]
+id = "imagesharp"
+name = "ImageSharp"
+repo = "SixLabors/ImageSharp"
+asset_patterns = ["ImageSharp-*.zip"]
+install_strategy = "bsipa-zip"
+category = "library"
+
+[[plugins]]
+id = "beatsaberplaylistslib"
+name = "BeatSaberPlaylistsLib"
+repo = "Meivyn/BeatSaberPlaylistsLib"
+asset_patterns = ["BeatSaberPlaylistsLib-*.zip"]
+install_strategy = "bsipa-zip"
+category = "library"
+
+[[plugins.dependencies]]
+id = "songcore"
+constraint = ">=3.16.0"
+required = true
+
+[[plugins.dependencies]]
+id = "imagesharp"
+constraint = ">=2.0.0"
+required = true
+
+[[plugins.dependencies]]
+id = "system-io-compression"
+constraint = ">=4.6.57"
+required = true
+
+[[plugins.dependencies]]
+id = "bsipa"
+constraint = ">=4.3.7"
+required = true
+
+[[plugins]]
+id = "beatsaversharp"
+name = "BeatSaverSharp"
+repo = "lolPants/BeatSaverSharp"
+asset_patterns = ["BeatSaverSharp-*.zip"]
+install_strategy = "bsipa-zip"
+category = "library"
+
+[[plugins]]
+id = "scoresabersharp"
+name = "ScoreSaberSharp"
+asset_patterns = ["ScoreSaberSharp-*.zip"]
+install_strategy = "bsipa-zip"
+category = "library"
+
+[[plugins]]
+id = "beatsaverdownloader"
+name = "BeatSaverDownloader"
+repo = "Top-Cat/BeatSaverDownloader"
+asset_patterns = ["BeatSaverDownloader-*.zip"]
+install_strategy = "bsipa-zip"
+category = "downloader"
+
+[[plugins.dependencies]]
+id = "bs-utils"
+constraint = ">=1.14.3"
+required = true
+
+[[plugins.dependencies]]
+id = "beatsabermarkuplanguage"
+constraint = ">=1.14.1"
+required = true
+
+[[plugins.dependencies]]
+id = "bsipa"
+constraint = ">=4.3.7"
+required = true
+
+[[plugins.dependencies]]
+id = "scoresabersharp"
+constraint = ">=0.1.0"
+required = true
+
+[[plugins.dependencies]]
+id = "system-io-compression-filesystem"
+constraint = ">=4.7.3056"
+required = true
+
+[[plugins.dependencies]]
+id = "songcore"
+constraint = ">=3.16.0"
+required = true
+
+[[plugins.dependencies]]
+id = "beatsaversharp"
+constraint = ">=3.4.5"
+required = true
+
+[[plugins]]
+id = "beatsaverupdater"
+name = "BeatSaverUpdater"
+repo = "ibillingsley/BeatSaverUpdater"
+asset_patterns = ["BeatSaverUpdater-*.zip"]
+install_strategy = "bsipa-zip"
+category = "downloader"
+
+[[plugins.dependencies]]
+id = "bsipa"
+constraint = ">=4.3.7"
+required = true
+
+[[plugins.dependencies]]
+id = "beatsabermarkuplanguage"
+constraint = ">=1.14.1"
+required = true
+
+[[plugins.dependencies]]
+id = "songcore"
+constraint = ">=3.16.0"
+required = true
+
+[[plugins.dependencies]]
+id = "sirautil"
+constraint = ">=3.3.1"
+required = true
+
+[[plugins.dependencies]]
+id = "beatsaversharp"
+constraint = ">=3.4.5"
+required = true
+
+[[plugins]]
+id = "setlist"
+name = "Setlist"
+asset_patterns = ["Setlist.dll"]
+install_strategy = "dll-to-plugins"
+category = "ui"
+
+[[plugins.dependencies]]
+id = "beatleader"
+constraint = ">=0.9.0"
+required = true
+
+[[plugins.dependencies]]
+id = "playlistmanager"
+constraint = ">=1.7.0"
+required = true
+
+[[plugins.dependencies]]
+id = "beatsaberplaylistslib"
+constraint = ">=1.7.0"
+required = true