[bug-fix] Fix init-force-preset-desync: reapply presets/extensions on init --here --force - #3995
Merged
Conversation
…re --force Apply the remediation from the bug assessment on issue #3990. After integration setup() and manifest.save(), when --force is used (re-initializing an existing project), call _register_presets_for_agent and _register_extensions_for_agent so that previously-installed presets and extensions are recomposed on top of the freshly-regenerated core files. Without this, preset-composed files reverted to pure core while the preset registry continued to report them as installed. This mirrors the same pattern already present in integration_upgrade() (added in PR #3853 / issue #3849 for the upgrade path). Refs #3990 Assisted-by: GitHub Copilot (model: claude-sonnet-4.6, autonomous) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Contributor
There was a problem hiding this comment.
Pull request overview
Reapplies installed preset and extension artifacts after forced project reinitialization.
Changes:
- Adds forced artifact re-registration after integration setup.
- Adds CLI regression tests for forced and non-forced initialization.
Show a summary per file
| File | Description |
|---|---|
src/specify_cli/commands/init.py |
Re-registers installed extensions and presets on forced initialization. |
tests/integrations/test_cli.py |
Tests re-registration guard behavior. |
Review details
Tip
Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Files reviewed: 2/2 changed files
- Comments generated: 1
- Review effort level: Balanced
mnriem
requested changes
Aug 5, 2026
mnriem
left a comment
Collaborator
There was a problem hiding this comment.
Please address Copilot feedback
mnriem
approved these changes
Aug 5, 2026
Contributor
There was a problem hiding this comment.
Review details
Suppressed comments (2)
src/specify_cli/commands/init.py:642
- These re-registration helpers run before the new
init-options.jsonis saved at line 754, although both resolve the active integration/mode from that file. On a forced re-init that changes integration or toggles command/skills mode, they therefore use stale state: extension skill registration explicitly skips whenagent_name != active_agent, and preset rendering can target the previous agent. Move this block aftersave_init_options(...)so it composes artifacts for the integration and mode just initialized.
if force:
from ..integrations._helpers import (
_register_extensions_for_agent,
_register_presets_for_agent,
)
tests/integrations/test_cli.py:1125
- These assertions only prove that mocked helpers were invoked, so the test passes even when registration is a no-op, targets stale init-options, or omits the extension
force=Truebehavior. Add an end-to-end regression that installs a minimal preset/extension, force-reinitializes, and verifies the composed artifact remains on disk; include a changed integration or command/skills mode case to cover when the new init-options take effect.
assert mock_presets.called, (
"_register_presets_for_agent was not called during init --here --force"
)
assert mock_extensions.called, (
"_register_extensions_for_agent was not called during init --here --force"
)
- Files reviewed: 2/2 changed files
- Comments generated: 0 new
- Review effort level: Balanced
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Bug fix — init-force-preset-desync
Proposed fix for issue #3990, applying the remediation from the bug assessment.
Verdict: Valid · Severity: high
Summary
After
specify init --here --forceregenerated integration files from bundled core templates, installed presets were not recomposed, causing the on-disk files to silently revert to the pure core version while the preset registry still reported them as installed. This fix adds a call to_register_presets_for_agentand_register_extensions_for_agentaftermanifest.save()whenforce=True, mirroring the pattern already present in theintegration upgradepath.Changes
src/specify_cli/commands/init.py_register_presets_for_agent+_register_extensions_for_agentcall aftermanifest.save(), guarded onforce=Truetests/integrations/test_cli.pyinit --here --force, one verifying they are not called on a fresh init without--forceTests Added or Updated
TestInitIntegrationFlag::test_init_here_force_reapplies_installed_presets— verifies_register_presets_for_agentand_register_extensions_for_agentare called wheninit --here --forceis used on an existing projectTestInitIntegrationFlag::test_init_here_without_force_does_not_reapply_presets— verifies the reapply block is not triggered on a fresh init without--forceLocal Verification
integration_upgrade()at_migrate_commands.py:889-900, which uses identical call signatures and has been working correctly since PR [bug-fix] Fix upgrade-overwrites-copilot-skills: pass force=True to extension skill re-registration after upgrade #3853.Deviations from Assessment
None. The implementation exactly matches the preferred remediation described in the assessment, including the
force=Trueguard, the call signatures (mirrored fromintegration_upgrade), and the import style (lazy inline import, consistent withinit.py's existing patterns).Risks & Review Notes
_register_presets_for_agentand_register_extensions_for_agentare best-effort (they catch all exceptions internally) — a failure in preset/extension reapplication will emit a warning but will not abort the init operation.force=Trueguard is defensive rather than strictly required, but it is cleaner and documents intent.specify integration install <key>) is out of scope for this fix; it would be a separate investigation.Refs #3990 · cc
@takaya0