Skip to content

fix: bound pathless batch action lookup - #3083

Merged
chubes4 merged 2 commits into
mainfrom
fix-3077-bound-pathless-lookup
Aug 9, 2026
Merged

fix: bound pathless batch action lookup#3083
chubes4 merged 2 commits into
mainfrom
fix-3077-bound-pathless-lookup

Conversation

@chubes4

@chubes4 chubes4 commented Aug 9, 2026

Copy link
Copy Markdown
Member

Summary

  • replace the unbounded parent LIKE scan with an exact lookup using the canonical parent_job_id + durable batch_state.offset identity stored in Action Scheduler's indexed args column
  • retain fix: preserve pathless batch recovery semantics #3065 keyed, nested JSON, and serialized compatibility through status-separated compatibility windows ordered by the existing hook_status_scheduled_date_gmt index
  • cap every result at 100 rows plus one truncation sentinel and fail closed on truncation or database errors

Indexed and bounded strategy

BatchScheduler already produces a complete action identity: parent_job_id and offset. The durable batch state supplies the expected offset, while Action Scheduler stores the short canonical JSON in its indexed args column. The primary lookup therefore uses exact args, hook, and active statuses with LIMIT 101 instead of introducing another identity table or scheduler abstraction.

Historical #3065 argument shapes cannot all be represented by one exact indexed key. Their compatibility path queries pending and in-progress rows separately, following Action Scheduler's existing (hook, status, scheduled_date_gmt) index. Each query returns at most 100 inspectable rows plus one sentinel row.

Absence-proof semantics and compatibility

The existing boolean API remains compatible with its sole caller. true means recovery must skip because active work exists or because bounded evidence cannot prove absence. A truncated exact/compatibility window or query error therefore returns true; only exhausted exact, pending, and in-progress evidence can return false. This preserves the caller's fail-closed behavior without adding an incomplete-evidence state it does not need to distinguish.

Exact parent decoding remains unchanged for keyed JSON, nested JSON, keyed serialized, and nested serialized arguments. Freshness handling for in-progress rows and unconditional pending protection are also unchanged.

Query cardinality

  • canonical lookup: at most 101 rows
  • pending compatibility lookup: at most 101 rows
  • in-progress compatibility lookup: at most 101 rows
  • processing stops immediately on an active match, query failure, or truncation

The regression fixture models 10,000 unrelated actions and verifies that only the 101-row bounded result is materialized and truncation fails closed.

Tests

  • php tests/pathless-batch-recovery-bounds-smoke.php (13 passed)
  • php tests/recover-stuck-active-action-guard-smoke.php (18 passed)
  • php tests/recover-stuck-bounded-apply-smoke.php (16 passed)
  • php tests/recover-stuck-bounded-memory-smoke.php (13 passed)
  • php tests/prefix-policy-audit.php (11 passed)
  • Homeboy changed-file lint: pass, including PHPCS and PHPStan level 7
  • Homeboy architecture audit: pass, zero introduced findings

Baseline limitation

The local Homeboy test umbrella and focused PipelineBatchSchedulerTest invocation both reported zero executed tests before loading PHPUnit. This is test-discovery infrastructure rather than a test failure; focused behavioral and caller smokes above executed successfully. PR CI should provide the repository's configured WordPress PHPUnit environment.

No production recovery, mutation, release, deployment, version bump, changelog edit, or parallel scheduler abstraction was added.

Closes #3077

@chubes4

chubes4 commented Aug 9, 2026

Copy link
Copy Markdown
Member Author

Follow-up repair pushed in b6f9687b:

  • centralized the repeated query-error, active-match, and truncation guard in boundedEvidenceBlocksRecovery() without changing exact lookup, 101-row bounds, compatibility decoding, freshness, or fail-closed behavior
  • removed the unused configurable timestamp from the pathless action fixture

Verification:

  • pathless bounds smoke: 13/13
  • active action guard smoke: 18/18
  • bounded apply smoke: 16/16
  • bounded memory smoke: 13/13
  • changed-file PHPCS/PHPStan level 7: zero findings
  • architecture audit: zero introduced findings

The remaining test red described by CI is the malformed empty test.failures sidecar, not a code-test failure.

@chubes4
chubes4 merged commit 8bf95cb into main Aug 9, 2026
15 of 19 checks passed
@chubes4
chubes4 deleted the fix-3077-bound-pathless-lookup branch August 9, 2026 18:14
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.

fix: bound pathless batch active-action lookup

1 participant