Skip to content

refactor: architectural cleanup — dead guards + long-deprecated shims (−593 LOC)#1173

Merged
chubes4 merged 2 commits intomainfrom
arch-cleanup-audit
Apr 23, 2026
Merged

refactor: architectural cleanup — dead guards + long-deprecated shims (−593 LOC)#1173
chubes4 merged 2 commits intomainfrom
arch-cleanup-audit

Conversation

@chubes4
Copy link
Copy Markdown
Member

@chubes4 chubes4 commented Apr 23, 2026

Summary

Architectural cleanup sweep — removes ~600 LOC of dead code that should have been gone a long time ago. No behavior change, zero external-plugin breakage.

Kind Count Net LOC
Dead `class_exists('WP_Ability')` / `class_exists('WP_Abilities_Registry')` guards 105 sites across 106 files −303
Long-deprecated shims (dead since 0.39.0 – 0.48.0, zero live callers) 3 files deleted + 2 methods −290
Total 116 files −593

Shipped as two reviewable commits:

  1. `038c71b3 refactor: drop dead WP_Ability / WP_Abilities_Registry guards`
  2. `6e1ea610 remove: long-deprecated shims (SiteContext, SiteContextDirective, DuplicateDetection, ToolExecutor::getAvailableTools, ToolManager::getAvailableToolsForChat)`

Why now

Kicked off from a broader architectural-cleanup audit. Homeboy's existing audit detectors (#674, #675, #676, #677, #776, #957) already do a great job on duplicate functions, god files, repeated fields, parallel implementations, etc. — but don't detect either of these two classes of issue:

  • Dead reachability guards. Plugin header requires WP 6.9 / PHP 8.2. `WP_Ability` and `WP_Abilities_Registry` both ship in WP 6.9 core. Every `if ( ! class_exists( 'WP_Ability' ) ) { return; }` guard in `inc/Abilities/` is unreachable. Similarly for the `class_exists(...) ? WP_Abilities_Registry::get_instance() : null` ternaries in `ToolPolicyResolver` / `ActionPolicyResolver`.
  • Stale `@deprecated` shims. Nothing flags deprecations that are 30+ minor versions behind current. Filed upstream on homeboy as follow-ups so future audits catch these automatically.

Both patterns suggested as new homeboy audit detectors — issues will link back here.

Commit 1 — dead-guard sweep

Mechanical pass via `homeboy refactor transform`. The transform set is persisted in `homeboy.json` as `drop_wp_ability_dead_guards` so the pattern is reusable (and re-runnable if new dead guards creep back in).

Three rules:

Rule Scope Hits
`simple_guard` `inc/Abilities/**/*.php` 83
`combined_guard_registered` `inc/Abilities/**/*.php` 17
`combined_guard_registered_engine` `inc/Engine/**/*.php` 1
`ternary_registry_guard` `inc/**/*.php` 4

Plus a few hand-fixes the transform couldn't reach cleanly:

  • `inc/Abilities/SEO/IndexNowAbilities.php` had an inverted guard-intent (the class-exists negation flipped the registration branch). Transform correctly refused to rewrite; simplified by hand.
  • `inc/Engine/Actions/Handlers/LogHandler.php` had a positive-form `if ( class_exists( 'WP_Ability' ) ) { ... }` wrapper with a dead fallback; unindented body, removed the fallback.
  • `inc/Abilities/File/ScaffoldAbilities::get_ability()` collapsed the redundant registry presence check (the registry always exists in 6.9+).
  • `inc/Engine/AI/Tools/ToolPolicyResolver::filterByAbilityPermissions()` had an inverted `function_exists('WP_Abilities_Registry')` check that can never be true (it's a class, not a function). Simplified to a direct registry call.

Commit 2 — long-deprecated shims

Five shims deprecated between 0.39.0 and 0.48.0. All have zero live callers in DM core or consumer plugins.

Verified downstream: greppedboth `data-machine-events`, `data-machine-socials`, and `intelligence` — none reference any of the removed symbols. Events already uses the unified `datamachine/check-duplicate` ability and registers `EventDuplicateStrategy` on the `datamachine_duplicate_strategies` filter, so it's unaffected by the `DuplicateDetection` class removal.

  • `DataMachine\Core\WordPress\SiteContext` — site context moved to SITE.md auto-regeneration in 0.48.0 (Consolidate SiteContext into SITE.md — remove duplicate site context system #871). Class was a no-op wrapper over a cleared transient.
  • `DataMachine\Engine\AI\Directives\SiteContextDirective` — unregistered in 0.48.0 and left as a no-op stub.
  • `DataMachine\Core\WordPress\DuplicateDetection` — replaced by `DuplicateCheckAbility` + `SimilarityEngine` in 0.39.0 (Unified duplicate detection primitive — consolidate 3 algorithms into 1 Ability-based system #731). Only caller was `inc/Core/Steps/Publish/Handlers/WordPress/WordPress.php` running `findExistingPostByTitle()` as a fallback after `datamachine/check-duplicate` already returned no-match — pure belt-and-suspenders since the ability's `checkPublishedPosts()` is a byte-for-byte superset of the legacy query (same `get_posts` shape, same `SimilarityEngine::titlesMatch`, same 14-day default). Migrated the handler to rely on the ability exclusively and inlined the `DEFAULT_LOOKBACK_DAYS = 14` constant.
  • `ToolExecutor::getAvailableTools()` / `ToolManager::getAvailableToolsForChat()` — both deprecated in 0.39.0 in favor of `ToolPolicyResolver::resolve()`. Only callers were two delegation tests (`test_deprecated_executor_delegates_to_resolver`, `test_deprecated_manager_delegates_to_resolver`) that verified they still delegated — removed tests and shims together. Updated three docs (`docs/ai-tools/tools-overview.md`, `docs/core-system/tool-execution.md`, `docs/development/hooks/core-filters.md`) to stop recommending the removed method in executable examples.

Validation

  • `php -l` on every modified file: clean (437 files total, 0 errors).
  • PSR-4 autoload sanity-load on 5 representative modified ability classes: all load clean.
  • Downstream grep on `data-machine-events`, `data-machine-socials`, `intelligence`: zero references to any removed symbol.
  • `homeboy test` couldn't complete — unrelated test-env issue (no MySQL bound in the worktree) — but `raw_output` shows "PHPUnit exited with code 1 but all tests passed" (0 test failures detected), and the PHPStan errors are all pre-existing (tracked under existing `audit` labels).
  • `homeboy validate` fails with a shell-syntax error — filed as validate-syntax.sh fails under sh(1): uses bash-only process substitution but is invoked with sh homeboy#1276 (unrelated tooling bug, blocks nothing here).

Follow-ups not in this PR

These are the things I deliberately didn't tackle, because they want their own review thread:

  • `ToolManager::get_global_tools()` is marked `@deprecated` but is actually used more than `get_all_tools()` internally — it's de facto API, not dead. Either unmark it or migrate the 6+ internal self-callers. Separate PR.
  • `BaseOAuth2Provider::refresh_token()` (0.31.1) — still exercised by `BaseOAuth2ProviderTest` delegating to `do_refresh_token()`. Migration is mechanical but nonzero-risk. Separate PR.
  • `FileConstants::is_protected()` / `is_user_layer()` (0.42.0) — need call-site verification sweep before removal. Separate PR.
  • Ability base-class extraction (the 90+ copy-pasted `__construct` / `registerAbility` / `doing_action+did_action` scaffolding blocks). Estimated ~1600 LOC savings. Separate PR — this is a structural change that deserves its own review. Intelligence did the equivalent thing at a smaller scale via `Intelligence_Wiki_Ability_Base` (Automattic/intelligence#154, saved 518 LOC across 11 wiki abilities).

AI assistance

  • AI assistance: Yes
  • Tool(s): Claude Code (Opus 4.7)
  • Used for: Drafted the audit methodology, ran the `homeboy refactor transform` sweep, hand-fixed the three guard variants the transform couldn't reach, deleted the deprecated shims, migrated the `DuplicateDetection` caller, updated docs, verified downstream plugins, drafted commit messages + PR body. Chris reviewed the approach mid-session and steered the scope (migrate the legacy fallback, file the homeboy tooling bugs, bound the work to zero-caller deletions only).

chubes4 added 2 commits April 23, 2026 19:22
Plugin header requires WP 6.9 where WP_Ability and WP_Abilities_Registry
both ship in core — every `if ( ! class_exists( 'WP_Ability' ) ) return;`
bootstrap guard in inc/Abilities/ and adjacent is unreachable, same for
`class_exists( 'WP_Abilities_Registry' ) ? ...::get_instance() : null`
ternaries in the tool/action policy resolvers.

Mechanical sweep via `homeboy refactor transform` — transform set persisted
to homeboy.json (`drop_wp_ability_dead_guards`) so the pattern is reusable.
Three rules total:

- simple_guard: remove standalone `if ( ! class_exists( 'WP_Ability' ) )`
  bootstrap guards (83 hits across inc/Abilities).
- combined_guard_registered: drop the WP_Ability half of combined
  `if ( ! class_exists(...) || self::$registered )` guards (18 hits,
  including one in inc/Engine via a separate rule).
- ternary_registry_guard: collapse unreachable ternaries in
  ToolPolicyResolver + ActionPolicyResolver (4 hits).

Plus a few hand-fixes the transform couldn't reach cleanly:

- inc/Abilities/SEO/IndexNowAbilities.php had an inverted guard-intent that
  the transform correctly refused to rewrite; simplified by hand so the
  registered-guard early-return actually matches the rest of the file.
- inc/Engine/Actions/Handlers/LogHandler.php had a positive-form
  `if ( class_exists( 'WP_Ability' ) ) { ... }` wrapper with a dead
  fallback; unindented the body, removed the fallback.
- inc/Abilities/File/ScaffoldAbilities::get_ability() collapsed the
  now-redundant registry presence check.
- inc/Engine/AI/Tools/ToolPolicyResolver::filterByAbilityPermissions() had
  an inverted `function_exists('WP_Abilities_Registry')` check that can
  never be true (it's a class, not a function) — simplified to a direct
  registry call.

Net: 106 files, −303 LOC with zero behavior change.
…licateDetection, ToolExecutor::getAvailableTools, ToolManager::getAvailableToolsForChat)

Five shims deprecated between 0.39.0 and 0.48.0 with zero live callers in
DM core or consumer plugins (data-machine-events, data-machine-socials,
intelligence). Plugin is now on 0.78 — dragging these along any longer is
pure noise.

- `DataMachine\Core\WordPress\SiteContext`
  Site context moved to SITE.md auto-regeneration in 0.48.0 (#871). The
  class was a no-op wrapper over a cleared transient. No callers.

- `DataMachine\Engine\AI\Directives\SiteContextDirective`
  Same migration — the directive was unregistered in 0.48.0 and left
  behind as a no-op stub. No callers.

- `DataMachine\Core\WordPress\DuplicateDetection`
  Replaced by `DuplicateCheckAbility` + `SimilarityEngine` in 0.39.0.
  The only remaining caller (inc/Core/Steps/Publish/Handlers/WordPress)
  was running the legacy `findExistingPostByTitle()` as a fallback after
  `datamachine/check-duplicate` already returned no match — pure belt-
  and-suspenders since the ability's published-post strategy is a
  byte-for-byte superset of the legacy query. Migrated the handler to
  rely on the ability exclusively and inlined the 14-day default.
  data-machine-events's EventDuplicateStrategy already registers on
  `datamachine_duplicate_strategies` — unaffected.

- `ToolExecutor::getAvailableTools()`
- `ToolManager::getAvailableToolsForChat()`
  Both deprecated in 0.39.0 in favor of `ToolPolicyResolver::resolve()`.
  Only callers were two delegation tests that verified they still
  delegated — removed tests and shims together. Updated three docs
  (`docs/ai-tools/tools-overview.md`, `docs/core-system/tool-execution.md`,
  `docs/development/hooks/core-filters.md`) to stop recommending the
  removed method in executable examples.

Net: 10 files, −290 LOC.
@chubes4 chubes4 merged commit 107fa2d into main Apr 23, 2026
1 check passed
@chubes4 chubes4 deleted the arch-cleanup-audit branch April 23, 2026 23:28
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