Skip to content

Multisite stranding guard [4/4]: Decline a deactivation that would strand sites the host cannot reach - #49

Open
d4mation wants to merge 1 commit into
34-stranding-noticefrom
35-strand-guard
Open

Multisite stranding guard [4/4]: Decline a deactivation that would strand sites the host cannot reach#49
d4mation wants to merge 1 commit into
34-stranding-noticefrom
35-strand-guard

Conversation

@d4mation

@d4mation d4mation commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

What: Wire the guard — Conflict\Detector::deactivation_would_strand_sites(), and the DEACTIVATE-branch check in Conflict\Resolver that declines the deactivation and queues the stranding notice instead.

Usage:

// On multisite, with a per-site host and a network-active standalone, the DEACTIVATE policy now
// leaves the standalone active rather than stripping it from the sites the host never loads on.
Config::set_host_plugin_basename( plugin_basename( __FILE__ ) );

Why this way:

The predicate lives on the Detector, not the Resolver. CLAUDE.md's rule is that the resolver reaches the checker through the detector, "without the resolver knowing a container exists." The detector already holds the checker, so the guard is a read-only method there — no constructor change, no Provider change, and the resolver's DEACTIVATE branch just asks it.

Opt-in and single-site-safe. With no host basename it returns false on a single string compare, ahead of any option read; is_plugin_active_for_network() is false off a network, so the whole predicate is false on single site. Every other topology — both network-active, both per-site, a per-site standalone — deactivates exactly as before, which is what keeps existing hosts from regressing.

Proven end to end, not just in unit tests. ConflictTest drives both the decline and the still-deactivate cases on the real multisite env against active_sitewide_plugins, skipping on single site; DetectorTest covers the four topologies and the opt-out.

Stack created with GitHub Stacks CLIGive Feedback 💬

Summary by CodeRabbit

  • New Features

    • Added a multisite safeguard that prevents deactivation when it could leave sites without the required host plugin.
    • Added an opt-in host configuration for enabling the safeguard.
    • Added notifications explaining when deactivation is declined and why.
  • Documentation

    • Documented the multisite safeguard, its configuration, and resolution behavior.
  • Bug Fixes

    • Prevented standalone plugins from being deactivated prematurely when the host plugin is not network-active.

@coderabbitai

coderabbitai Bot commented Aug 21, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Enterprise

Run ID: 02db9ec2-0762-4891-ad36-1842e35f738f

📥 Commits

Reviewing files that changed from the base of the PR and between cd4de69 and 46a3d4a.

📒 Files selected for processing (7)
  • CLAUDE.md
  • docs/conflict-handling.md
  • src/Conflict/Detector.php
  • src/Conflict/Resolver.php
  • tests/unit/Conflict/DetectorTest.php
  • tests/unit/Conflict/ResolverTest.php
  • tests/unit/Scenario/ConflictTest.php

Included review availability: Your plan provides up to 12 included reviews per hour; 5 remain after this review.


📝 Walkthrough

Walkthrough

The PR adds a multisite stranding guard to conflict resolution. It detects unsafe network deactivation, preserves the standalone plugin, queues a notice, tests safe and unsafe topologies, and documents the behavior.

Changes

Multisite stranding protection

Layer / File(s) Summary
Detect stranding topology
src/Conflict/Detector.php, tests/unit/Conflict/DetectorTest.php
The detector checks the configured host basename and network activation state. Tests cover network-active and site-only activation combinations.
Guard resolver deactivation
src/Conflict/Resolver.php, tests/unit/Conflict/ResolverTest.php
The resolver skips deactivation and queues a stranding notice when the detector reports an unsafe topology.
Validate and document multisite behavior
tests/unit/Scenario/ConflictTest.php, docs/conflict-handling.md, CLAUDE.md
Scenario tests cover guarded and normal deactivation. Documentation describes the guard and its configuration conditions.

Estimated code review effort: 2 (Simple) | ~15 minutes

Merge Risk: ⚪ Minimal · up to 46a3d

The change adds a localized multisite deactivation guard with associated tests and documentation; no actionable merge-blocking risk remains.

Suggested reviewers: nikolaystrikhar

Sequence Diagram(s)

sequenceDiagram
  participant Resolver
  participant Detector
  participant PluginState
  participant NoticeQueue
  Resolver->>Detector: Check whether deactivation would strand sites
  Detector->>PluginState: Read network activation state
  PluginState-->>Detector: Return standalone and host status
  Detector-->>Resolver: Return stranding result
  Resolver->>NoticeQueue: Queue stranding notice when needed
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 19 functions across 5 files. (2 skipped: 2 unsupported.)
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically describes the multisite guard that declines deactivation when it would strand sites.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch 35-strand-guard

Comment @coderabbitai help to get the list of available commands.

@d4mation
d4mation marked this pull request as draft August 21, 2026 14:15
@d4mation
d4mation force-pushed the 35-strand-guard branch 2 times, most recently from 5ff7e1c to b274f75 Compare August 21, 2026 14:36
@d4mation d4mation changed the title Decline a deactivation that would strand sites the host cannot reach Multisite stranding guard [4/4]: Decline a deactivation that would strand sites the host cannot reach Aug 21, 2026
@d4mation
d4mation marked this pull request as ready for review August 21, 2026 15:05
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