feat(plugins): B3 safe_uninstall — 3-step wizard, orphan table preservation, sandboxed pre-hook#54
Merged
Merged
Conversation
There was a problem hiding this comment.
Sorry @DavidsonGomes, you have reached your weekly rate limit of 500000 diff characters.
Please try again later or upgrade to continue using Sourcery
32af339 to
dc679fc
Compare
…vation, sandboxed hook
- plugin_schema.py: PluginSafeUninstall, PluginPreUninstallHook, PluginUserConfirmation
models + validators (block_uninstall enforcement, preserved_tables slug-prefix check,
safe_uninstall_enabled_requires_confirmation, no _orphan_* refs in readonly SQL)
- routes/plugins.py: uninstall gate (admin-only, confirmation_phrase, exported_at check,
zip_password); sandboxed pre-hook subprocess (no secrets, read-only DB copy, 600s timeout);
cascade-DELETE filtering for preserved_host_entities; orphan table rename
(_orphan_{slug}_{table}); EVONEXUS_ALLOW_FORCE_UNINSTALL=1 escape hatch with audit;
reinstall SHA256 check against plugin_orphans before orphan recovery
- app.py: plugin_orphans table migration (id, slug, tablename, orphaned_at,
orphaned_by_user_id, original_plugin_version, original_sha256, original_publisher_url,
recovered_at, UNIQUE(slug, tablename))
- PluginUninstall.tsx: 3-step wizard (regulatory reason+checkbox → ZIP password → typed
phrase); force-uninstall orange banner; integrated in PluginDetail.tsx
- docs/plugin-contract.md: full plugin.yaml contract for public_pages + safe_uninstall
Vault §B3 mitigations: S1 block_uninstall gate, S2 admin enforcement, S3 sandboxed hook,
S4 no _orphan_* SQL refs, S5 AES-256 ZIP password, S6 force-uninstall audit trail.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
dc679fc to
ad7cbec
Compare
3 tasks
jbmendonca
pushed a commit
to jbmendonca/evo-nexus
that referenced
this pull request
May 15, 2026
…vation, sandboxed hook (evolution-foundation#54) - plugin_schema.py: PluginSafeUninstall, PluginPreUninstallHook, PluginUserConfirmation models + validators (block_uninstall enforcement, preserved_tables slug-prefix check, safe_uninstall_enabled_requires_confirmation, no _orphan_* refs in readonly SQL) - routes/plugins.py: uninstall gate (admin-only, confirmation_phrase, exported_at check, zip_password); sandboxed pre-hook subprocess (no secrets, read-only DB copy, 600s timeout); cascade-DELETE filtering for preserved_host_entities; orphan table rename (_orphan_{slug}_{table}); EVONEXUS_ALLOW_FORCE_UNINSTALL=1 escape hatch with audit; reinstall SHA256 check against plugin_orphans before orphan recovery - app.py: plugin_orphans table migration (id, slug, tablename, orphaned_at, orphaned_by_user_id, original_plugin_version, original_sha256, original_publisher_url, recovered_at, UNIQUE(slug, tablename)) - PluginUninstall.tsx: 3-step wizard (regulatory reason+checkbox → ZIP password → typed phrase); force-uninstall orange banner; integrated in PluginDetail.tsx - docs/plugin-contract.md: full plugin.yaml contract for public_pages + safe_uninstall Vault §B3 mitigations: S1 block_uninstall gate, S2 admin enforcement, S3 sandboxed hook, S4 no _orphan_* SQL refs, S5 AES-256 ZIP password, S6 force-uninstall audit trail. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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.
Summary
PluginSafeUninstall,PluginPreUninstallHook,PluginUserConfirmationPydantic models; 4 validators (block_uninstall gate, preserved_tables slug-prefix, enabled-requires-confirmation, no_orphan_*refs in readonly SQL)confirmation_phrasecheck,exported_atfile existence,zip_passwordforwarding; sandboxed pre-hook subprocess (no secrets, read-only DB copy, 600 s timeout,must_produce_filecheck); cascade-DELETE filtering forpreserved_host_entities; orphan table rename (_orphan_{slug}_{table});EVONEXUS_ALLOW_FORCE_UNINSTALL=1escape hatch with mandatory audit; reinstall SHA256 check againstplugin_orphansbefore recoveryplugin_orphansmigration (id, slug, tablename, orphaned_at, user, original_version, original_sha256, original_publisher_url, recovered_at)showUninstallWizardstate; falls back to legacywindow.confirm()for plugins withoutsafe_uninstall.enabledpublic_pages+safe_uninstallcapabilitiesVault mitigations covered
block_uninstall: truegate (409 Conflict)BRAIN_REPO_MASTER_KEY, read-only DB copy_orphan_*table refs in readonly SQLplugin_uninstall_forceaudit action)Test plan
block_uninstall: true→DELETE /api/plugins/<slug>returns 409safe_uninstall.enabled: true— non-admin returns 403confirmation_phrase→ 400exported_atpath to non-existent file → 400must_produce_file: truebut empty output_dir → 400_orphan_{slug}_{table},plugin_orphansrow insertedconfirmed_sha256_change: trueEVONEXUS_ALLOW_FORCE_UNINSTALL=1→ bypasses all gates, logsplugin_uninstall_forcesafe_uninstall.enabled→ fallback towindow.confirm()🤖 Generated with Claude Code