Skip to content

v0.3.0

Latest

Choose a tag to compare

@github-actions github-actions released this 26 Jul 10:02

Completes the grading rubric and the artifact surface. Grade B was published
from the start but could never be assigned, because nothing detected the
conditional cleanup it describes; that gap is now closed, and the last artifact
types the manifest reserved are detected.

Added

  • Conditional cleanup detection, and with it grade B. An uninstall routine
    gated on a stored setting — if (!get_option('..._delete_data')) return;, or
    the same removals wrapped inside the if — is now recognised, and the gating
    option and its default are reported in the cleanup block and the manifest.
    This is the plugin that is technically clean and practically dirty: the setting
    almost always defaults to off, so on a real site nothing is removed. Naming it
    B is more useful than folding it into A or C.

    A guard only counts when it actually gates cleanup — it bails out early, or a
    removal sits inside it — so an unrelated if (get_option('schema') === 'v2')
    in the same routine does not cost an otherwise clean plugin its A.

  • Directorieswp_mkdir_p and mkdir, with WP_CONTENT_DIR,
    WP_PLUGIN_DIR, and ABSPATH rewritten to portable {content_dir},
    {plugin_dir}, and {abspath} tokens, the same way {prefix} works for
    tables. A path that is only a root with nothing under it is skipped rather than
    reported as a directory the plugin created.

  • Rewrite rulesadd_rewrite_rule, add_rewrite_endpoint, and
    add_rewrite_tag. They weigh lightly: a rule is one entry in a single option
    and disappears on the next permalink flush.

  • Action Scheduler jobsas_schedule_recurring_action,
    as_schedule_single_action, as_schedule_cron_action, and
    as_enqueue_async_action. A queued job behaves like a cron event, so it weighs
    like one.

Fixed

  • A cron event scheduled with arguments is no longer reported as cleaned by an
    argument-less wp_clear_scheduled_hook().
    That call only removes events
    registered without arguments, so the event actually survives and keeps firing —
    Sediment was crediting a cleanup that does not happen. Clearing it needs
    wp_unschedule_hook(), which is what the generated uninstall.php now emits
    for those events.

  • The $wpdb handle is recognised when held as a property ($this->wpdb),
    not only as the global variable, so table creation and drops written that way
    are no longer missed. Recognition lives in one helper rather than three
    hand-rolled checks, and still requires the name wpdb — an alias under a
    different name is missed rather than guessed at.

  • Cleanup detection for the new types — as_unschedule_all_actions,
    as_unschedule_action, rmdir, and flush_rewrite_rules — so a plugin that
    tidies up after itself is credited for it.

Changed

  • A key written from several places counts as cleaned only when every write of
    it is cleaned.
    A hook scheduled both with and without arguments is one key
    with two fates; the previous "any write cleaned" merge could report such a
    plugin as spotless while an event kept firing.
  • Scores are held inside the band their letter allows, so a C with one stray
    transient can no longer outrank a B on a leaderboard.
  • Grade summaries no longer state which way a gating setting must be set.
    Sediment sees which option decides, not the polarity of the comparison, and
    "keep my data" gates are as common as "delete my data" ones — so the wording
    names the setting and its default rather than asserting a direction.
  • Every artifact type the manifest reserves is now populated by detection; the
    creates groups are unchanged, so consumers need no update. A finding type
    with no group now raises an error instead of vanishing from the document.
  • WordPress's own directories (uploads, plugins, themes, …) are recognised
    as core, so they are never attributed to a plugin or offered for deletion.

Security

  • A table name cut short by a dynamic tail is no longer claimed. Resolving
    "CREATE TABLE {$wpdb->prefix}logs{$suffix}" stops mid-name, and treating the
    fragment as the table invented one the plugin never creates — which a generated
    uninstall.php would then drop. Such names now require proof that the name
    ended before the cut.
  • wp_clear_scheduled_hook($hook, $args) no longer credits an argument-less
    event, since it clears only events registered with those exact arguments.
  • The $wpdb handle is accepted only as $wpdb, $this->wpdb, or
    self::$wpdb, so an unrelated object's ->wpdb cannot credit a table drop.