Skip to content

fix: Recover profiles left with no framework - #28

Merged
ResurrectedTrader merged 1 commit into
mainfrom
fix/orphaned-framework
Aug 18, 2026
Merged

fix: Recover profiles left with no framework#28
ResurrectedTrader merged 1 commit into
mainfrom
fix/orphaned-framework

Conversation

@ResurrectedTrader

Copy link
Copy Markdown
Owner

Two ways a profile could end up with an empty framework, and no way out of either in basic mode, where no framework control is rendered at all -- the Frameworks nav is filtered out, /frameworks redirects to /profiles, and the profile dropdown is gated on advanced_mode. The launch then fails with "No framework assigned. Assign a framework to this profile.", telling the user to do something the UI does not let them do. The only repair was accidental: opening the editor fires the auto-assign effect, so saving an untouched profile writes the field back.

FrameworkBootstrap now adopts framework-less profiles whenever there is nothing to choose -- no frameworks yet, or exactly one -- because the assignment it would make is the only one the user could make by hand. With two or more it still declines, but says so instead of returning silently: that empty value is the deliberate post-delete state and guessing could launch a profile against the wrong game directory. ProfileForm also shows the dropdown, in either mode, when the saved profile has no framework.

The other way in is a handoff. The successor signals Adopted at the top of Main and only then runs Migration and FrameworkBootstrap, so the predecessor stays alive and message-driven right through the migration. Every repository save rewrites its whole file from an in-memory list the OLD schema parsed, so a single run counter arriving in that window drops every field the successor just added -- and frameworks.json survives, so the bootstrap never retried. DataWriteGate closes before the successor is spawned: from then on the data directory belongs to it and this process only reads. It reopens only where no successor can still be migrating (it exited without signalling, or never started); one that is alive but silent leaves the gate closed, since read-only beats two writers on one directory.

Two ways a profile could end up with an empty `framework`, and no way out
of either in basic mode, where no framework control is rendered at all --
the Frameworks nav is filtered out, /frameworks redirects to /profiles,
and the profile dropdown is gated on advanced_mode. The launch then fails
with "No framework assigned. Assign a framework to this profile.", telling
the user to do something the UI does not let them do. The only repair was
accidental: opening the editor fires the auto-assign effect, so saving an
untouched profile writes the field back.

FrameworkBootstrap now adopts framework-less profiles whenever there is
nothing to choose -- no frameworks yet, or exactly one -- because the
assignment it would make is the only one the user could make by hand. With
two or more it still declines, but says so instead of returning silently:
that empty value is the deliberate post-delete state and guessing could
launch a profile against the wrong game directory. ProfileForm also shows
the dropdown, in either mode, when the saved profile has no framework.

The other way in is a handoff. The successor signals Adopted at the top of
Main and only then runs Migration and FrameworkBootstrap, so the
predecessor stays alive and message-driven right through the migration.
Every repository save rewrites its whole file from an in-memory list the
OLD schema parsed, so a single run counter arriving in that window drops
every field the successor just added -- and frameworks.json survives, so
the bootstrap never retried. DataWriteGate closes before the successor is
spawned: from then on the data directory belongs to it and this process
only reads. It reopens only where no successor can still be migrating (it
exited without signalling, or never started); one that is alive but silent
leaves the gate closed, since read-only beats two writers on one directory.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@ResurrectedTrader
ResurrectedTrader merged commit 1338b75 into main Aug 18, 2026
7 checks passed
@ResurrectedTrader
ResurrectedTrader deleted the fix/orphaned-framework branch August 18, 2026 21:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant