Two custom tables, per-site (not centralised β the atomic claim UPDATE joins against the posts table, and post IDs are only unique within a single site’s own posts table on Multisite): {$wpdb->prefix}lh_tasks_status and, as of 1.8.0, {$wpdb->prefix}lh_tasks_dependencies. Everything else lives in WordPress’s own posts, postmeta, terms/term_relationships/term_taxonomy tables (or their per-site equivalents on Multisite).
Post type
lh_tasks-task_post
Post status (native WordPress)
draft / pending / lh_tasks-active / private / future / trash. lh_tasks-active (added 1.6.0, replaces publish for this CPT) is required for a task to be claimable via claim_next_task(), and is registered public => false β front-end read access is gated per-task via map_meta_cap, not blanket-public. create_task() defaults to lh_tasks-active; pass draft or pending for a task that shouldn’t be visible/claimable until reviewed.
Workflow status ({$wpdb->prefix}lh_tasks_status table)
Status key (namespace lh_tasks-) |
Label | Notes |
|---|---|---|
new_task |
New | Initial state; claimable (subject to post_status = lh_tasks-active) |
claim_task |
Claimed | Set atomically by claim_next_task(); renew_task() (the renew-claim heartbeat) keeps a task in this status while pushing claimed_at forward |
prog_task |
In Progress | For workers that separate “claimed” from “started”; not set automatically |
pend_task |
Pending | Manual/human-workflow use. Also set automatically (1.8.0) when a task waiting in New loses a blocked_by prerequisite to Cancelled, the trash or deletion |
fail_task |
Failed | Set automatically when retries are exhausted, with the claim released (1.18.0; was block_task, “Blocked”, renamed so it is not confused with a task held back by a blocked_by prerequisite, which stays New and is skipped by claims). Open, for a person to triage; edit-task with status New and reset_retries requeues it with its full retries |
res_task |
Resolved | Set by complete_task(); terminal |
clos_task |
Closed | Manual final closure after resolution; terminal |
cncl_task |
Cancelled | Terminal |
defr_task |
Deferred | Parked for later β deliberately worth doing eventually, not urgent now. Not in return_open_statuses() (won’t dilute the dashboard widget/default list) and not terminal (promotable back to New later via reassign_task()) |
Status key naming (e.g. pend_task not pending_task) is unchanged from when these were post_status values constrained to 20 characters β the table column isn’t constrained the same way, but there was no reason to rename and break continuity with existing data/consumers. The one exception is block_task, renamed to fail_task in 1.18.0 because the old name was actively misleading.
Table columns (as of 1.6.0, table version 2.0): post_id (PK), status, claim_token, assigned_to (BIGINT UNSIGNED NULL β hard requirement), assignee (BIGINT UNSIGNED NULL β current claim holder), claimed_at, retry_count, max_retries, created_at, updated_at.
Table version 2.1 (1.18.0) changes data, not columns: migrate_2_0_to_2_1(), run once per site from maybe_create_table() on init, moves block_task rows to fail_task, and repairs two keys that edit-task stored before 1.17.1 validated statuses: can_task to cncl_task and resolved to res_task. These are plain row updates, so no progress-log entries are written and no status actions fire. The version is in the lh_tasks_status_table_version option.
Dependencies ({$wpdb->prefix}lh_tasks_dependencies table, 1.8.0)
One row per “task waits on blocker” edge, and the only store of blocked_by (it replaced the _lh_tasks-blocked_by post meta, which was migrated and deleted). Columns: task_id, blocker_id (primary key together), created_at; indexed on blocker_id. Version option lh_tasks_dependencies_schema_version. Rows for a permanently deleted task are removed in either column.
Taxonomies
-
lh_tasks_queueβ non-hierarchical, non-public. Routing/lane, e.g.email-triage. Admin column shown on the Tasks list screen. -
lh_tasks_task_typeβ non-hierarchical, non-public. Classification of the kind of work, e.g.github_triage. Distinct from queue: a queue can carry more than one task type and vice versa. Admin column shown on the Tasks list screen. -
lh_tasks_priority(1.15.0) β a locked set of four terms (low, normal, high, urgent), ranked by term metaorder(10, 20, 30, 40). Each task carries one. Version optionlh_tasks_priority_schema_version. See Architecture notes.
Post meta (all keys prefixed _lh_tasks-)
| Meta key | Type | Description |
|---|---|---|
payload |
JSON string | Machine-actionable spec for agent tasks: the ability to run and its params |
result |
JSON string | Output on completion, or an error object on failure |
due_date |
MySQL datetime | Optional |
source_plugin |
string | Slug of the plugin that created this task, e.g. lh-crm
|
source_post_id |
int | ID of the originating post in the source plugin |
progress_log |
array of objects | Appended to by reassign_task(), update_task(), add_note(), complete_assigned_task(), LH_Tasks_dependencies_class::flag_dependents(), LH_Tasks_follow_up_class, renew_task() (only when a note is given), and edit_task(). Each entry: timestamp, event (reassigned, heartbeat, admin_override, prerequisite_dropped, note (1.10.0), marked_done (1.11.0, when the assigned member marks it done from their profile, with their note if they gave one), follow_up and follow_up_escalated (1.16.0, written by the daily follow-up with actor 0, and never counted as activity), or updated, which also records fields and, if the task was claimed, claimed_by), from_status/to_status (reassigned, admin_override and prerequisite_dropped only), from_assignee/to_assigned_to (reassign only), retries_reset_from (admin_override with reset_retries, 1.18.0: the retry count before it was reset), actor (WP user ID), note
|
follow_up |
array | Where an assigned task is in the follow-up cycle, including when the last follow-up was sent (at); activity after that time starts the cycle again. 1.16.0 |
claim_started |
Unix timestamp | When the current claim was made, set on lh_tasks_task_claimed; the start of the maximum lease for automatic renewal. 1.17.0 |
ability_calls |
int | Count of write ability calls made with this task (succeeded or failed, not refused). 1.17.0 |
last_ability |
array | The last such call: ability, time_gmt, success, renewed. 1.17.0 |
assignee, assigned_to, claim_token, claimed_at, retry_count, and max_retries live in the status table, not postmeta β see above. The follow-up’s BuddyPress notifications carry two notification meta keys, lh_tasks_blog_id and lh_tasks_link, recording the task’s site and link (1.16.0).
