Conversation
status was an unbounded free-text column, so GROUP BY could not aggregate by state and exception text (including filesystem paths) landed in an indexed column. Add nullable status_reason, write only canonical base states, and backfill compound "<status> - <detail>" values without discarding detail. Readers still compose display from leftover compound rows, the new column, or engine_data.job_status_reason during rollout. resolve_status_match()/status_match_sql() prefix matching is only needed while JobStatusMigration is incomplete. Once status is bounded, exact IN matching is sufficient. The TypeError (has_owner_terminal_disposable_cleanup_signal() receiving null) is thrown when a worktree listing row has no metadata. That is a missing record, not a callee-null contract, so the caller should pass []. Data Machine now stores that exception in status_reason rather than status.
The DB round-trip test built its expectation with str_repeat(), leaving a trailing space, then asserted the stored status_reason matched it exactly. Storage trims on write, so the assertion failed on whitespace the layer deliberately discards rather than on any behaviour under test. JobStatusBoundedStorageTest is left unchanged: it exercises toStorage() directly, where no trim occurs, and it passes.
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.
Addresses the
statuscolumn half of #3514. See the correction comment on that issue — the retention/delete failure described in the original report is not a Data Machine bug and is not touched here.What was broken
wp_datamachine_jobs.statuswas an unbounded free-text column storing entire exception messages, including absolute filesystem paths and third-party error strings. Real values from one site:Consequences:
GROUP BY statusproduced one group per distinct error string rather than per state, so the column could not be aggregatedstatusWhat this changes
Separates state from detail:
statusbecomes bounded to the canonical states, with error detail stored in its own field. Includes a schema migration and a backfill that splits existing compound values at the established"<status> - <detail>"boundary, preserving the detail rather than discarding it.Readers keep working across the migration, and
statusbecomes safe to index and aggregate.Verification
tests/job-status-normalization-smoke.phppassestests/job-status-presentation-smoke.phppassesHonest gap: the two new PHPUnit suites (
tests/Unit/Core/Database/JobStatusStorageTest.php,tests/Unit/Core/JobStatusBoundedStorageTest.php, 208 lines total) could not be executed locally — they requireWP_UnitTestCaseand no WordPress test harness is installed here (/tmp/wordpress-tests-libabsent). I confirmed that is environmental and pre-existing rather than caused by this change, but it means that test code has not actually run. Worth a CI run before merge.Note on the TypeError from the issue
The original issue also flagged 332 jobs failing with
has_owner_terminal_disposable_cleanup_signal(): Argument #1 ($metadata) must be of type array, null given. I traced it and it is not actionable here:data-machine-code, not this repois_array( … ) ? … : array(), added 2026-07-04 (lint: i18n in data-machine (3) #865) and 2026-07-12 (Admin UI: Remove model/provider fields from AI step config modal #889)data-machine-codeis no longer installed on the site that produced those rowsThey are historical residue predating the guards. No fix is required and none is attempted.
AI assistance disclosure. Implemented by
xai/grok-4.6viaopencode run, from a task specification I wrote after aggregating the jobs table by status on a live site. I reviewed the diff, ran lint and the smoke tests, and separately traced the TypeError to its actual repository and guard commits rather than accepting the issue's original framing.Process note. Finalization happened outside Homeboy.
homeboy agent-task cookadmitted the task and then failed to claim its own detached Cook handoff on every attempt, with a healthy local daemon. Completed through an authorized direct-runtime fallback in an isolated worktree offorigin/main(be9b5d5eb).