hzl
# HZL: Persistent task ledger for agents
HZL (https://hzl-tasks.com) is a local-first task ledger that agents use to:
- Plan multi-step work into projects + tasks
- Checkpoint progress so work survives session boundaries
- Route work to the right agent via project pools
- Coordinate across multiple agents with leases and dependencies
This skill teaches an agent how to use the `hzl` CLI.
## When to use HZL
**OpenClaw has no native task tracking.** Unlike Claude Code (which has TodoWrite) or Codex (which has update_plan), OpenClaw relies on memory and markdown files for tracking work. HZL fills this gap.
**Use HZL for:**
- Multi-step projects with real sequencing or handoffs
- Work that may outlive this session or involve multiple agents
- Anything where "resume exactly where we left off" matters
- Delegating work to another agent and needing recovery if they fail
**Skip HZL for:**
- Truly trivial one-step tasks you will complete immediately
- Time-based reminders (use OpenClaw Cron instead)
- Longform notes or knowledge capture (use memory files)
**Rule of thumb:** If you feel tempted to make a multi-step plan, or there is any chance you will not finish in this session, use HZL.
---
## ⚠️ DESTRUCTIVE COMMANDS — READ FIRST
| Command | Effect |
|---------|--------|
| `hzl init --force` | **DELETES ALL DATA.** Prompts for confirmation. |
| `hzl init --force --yes` | **DELETES ALL DATA WITHOUT CONFIRMATION.** |
| `hzl task prune ... --yes` | **PERMANENTLY DELETES** old done/archived tasks and history. |
**Never run these unless the user explicitly asks you to delete data. There is no undo.**
---
## Core concepts
- **Project**: container for tasks. In single-agent setups, use one shared project. In multi-agent setups, use one project per agent role (pool routing).
- **Task**: top-level work item. Use parent tasks for multi-step initiatives.
- **Subtask**: breakdown of a task (`--parent <id>`). Max 1 level of nesting. Parent tasks are never returned by `hzl task claim --next`.
- **Checkpoint**: short progress snapshot for session recovery.
- **Lease**: time-limited claim that enables stuck detection in multi-agent flows.
---
## Project setup
### Single-agent setup
Use one shared project. Requests and initiatives become parent tasks, not new projects.
```bash
hzl project list # Check first — only create if missing
hzl project create openclaw
```
Everything goes into `openclaw`. `hzl task claim --next -P openclaw` always works.
### Multi-agent setup (pool routing)
Use one project per agent role. Tasks assigned to a project (not a specific agent) can be claimed by any agent monitoring that pool. This is the correct pattern when a role may scale to multiple agents.
```bash
hzl project create research
hzl project create writing
hzl project create coding
hzl project create marketing
hzl project create coordination # for cross-agent work
```
**Pool routing rule:** assign tasks to a project without `--agent`. Any eligible agent claims with `--next`.
```bash
# Assigning work to the research pool (no --agent)
hzl task add "Research competitor pricing" -P research -s ready
# Kenji (or any researcher) claims it
hzl task claim --next -P research --agent kenji
```
**Agent routing:** when `--agent` is set at task creation, only that agent (or agents with no assignment) can claim it via `--next`. Tasks with no agent are available to everyone.
```bash
# Pre-route a task to a specific agent
hzl task add "Review Clara's PR" -P coding -s ready --agent kenji
# Kenji claims it (matches agent)
hzl task claim --next -P coding --agent kenji # ✓ returns it
# Ada tries — skipped because it's assigned to kenji
hzl task claim --next -P coding --agent ada # ✗ skips it
```
Use `--agent` on task creation when you specifically want one person. Omit it when any eligible agent in the pool should pick it up.
---
## Session start (primary workflow)
### With workflow commands (HZL v2+)
```bash
hzl workflow run start --agent <agent-id> --project <project> --json
```
`--project` is required — agents must scope to their assigned pool. Use `--any-project` to intentionally scan all projects (e.g. coordination agents).
This handles expired-lease recovery and new-task claiming in one command. If a task is returned, work on it. If nothing is returned, the queue is empty. Agent routing applies: tasks assigned to other agents are skipped.
### Without workflow commands (fallback)
```bash
hzl agent status # Who's active? What's running?
hzl task list -P <project> --available # What's ready?
hzl task stuck # Any expired leases?
hzl task stuck --stale # Also check for stale tasks (no checkpoints)
# If stuck tasks exist, read their state before claiming
hzl task show <stuck-id> --view standard --json
hzl task steal <stuck-id> --if-expired --agent <agent-id> --lease 30
hzl task show <stuck-id> --view standard --json | jq '.checkpoints[-1]'
# Otherwise claim next available
hzl task claim --next -P <project> --agent <agent-id>
```
---
## Core workflows
### Adding work
```bash
hzl task add "Feature X" -P openclaw -s ready # Single-agent
hzl task add "Research topic Y" -P research -s ready # Pool-routed (multi-agent)
hzl task add "Subtask A" --parent <id> # Subtask
hzl task add "Subtask B" --parent <id> --depends-on <a-id> # With dependency
```
### Working a task
```bash
hzl task claim <id> # Claim specific task
hzl task claim --next -P <project> # Claim next available
hzl task checkpoint <id> "milestone X" # Checkpoint progress
hzl task complete <id> # Finish
```
### Status transitions
```bash
hzl task set-status <id> ready # Make claimable
hzl task set-status <id> backlog # Move back to planning
hzl task block <id> --comment "reason" # Block with reason
hzl task unblock <id> # Unblock
```
Statuses: `backlog` → `ready` → `in_progress` → `done` (or `blocked`)
### Finishing subtasks
```bash
hzl task complete <subtask-id>
hzl task show <parent-id> --view summary --json # Any subtasks remaining?
hzl task complete <parent-id> # Complete parent if all done
```
---
## Delegating and handing off work
### Workflow commands (HZL v2+)
```bash
# Hand off to another agent or pool — complete current, create follow-on atomically
hzl workflow run handoff \
--from <task-id> \
--title "<new task title>" \
--project <pool> # --agent if specific person; --project for pool
# Delegate a subtask — creates dependency edge by default
hzl workflow run delegate \
--from <task-id> \
--title "<delegated task>" \
--project <pool> \
--pause-parent # Block parent until delegated task is done
```
`--agent` and `--project` guardrail: at least one is required on handoff. Omitting `--agent` creates a pool-routed task; `--project` is then required to define which pool.
### Manual delegation (fallback)
```bash
hzl task add "<delegated title>" -P <pool> -s ready --depends-on <parent-id>
hzl task checkpoint <parent-id> "Delegated X to <pool> pool. Waiting on <task-id>."
hzl task block <parent-id> --comment "Waiting for <delegated-task-id>"
```
---
## Dependencies
```bash
# Add dependency at creation
hzl task add "<title>" -P <project> --depends-on <other-id>
# Add dependency after creation
hzl task add-dep <task-id> <depends-on-id>
# Query dependencies
hzl dep list --agent <id> --blocking-only # What's blocking me?
hzl dep list --from-agent <id> --blocking-only # What's blocking work I created?
hzl dep list --project <p> --blocking-only # What's blocking in a pool?
hzl dep list --cross-project-only # Cross-agent blockers
# Validate no cycles
hzl validate
```
Cross-project dependencies are supported by default. Use `hzl dep list --cross-project-only` to inspect cross-project edges.
---
## Checkpointing
Checkpoint at notable milestones or before pausing. A good checkpoint answers: "if this session died right now, could another agent resume from here?"
**When to checkpoint:**
- Before any tool call that might fail
- Before spawning a sub-agent
- After completing a meaningful unit of work
- Before handing off or pausing
```bash
hzl task checkpoint <id> "Implemented login flow. Next: add token refresh." --progress 50
hzl task checkpoint <id> "Token refresh done. Testing complete." --progress 100
hzl task progress <id> 75 # Set progress without a checkpoint
```
---
## Lifecycle hooks
HZL sends targeted notifications for high-value transitions — currently only `on_done`. Other lifecycle events (stuck detection, blocking, progress) require polling. This is deliberate: hooks signal when something meaningful happens, agents and orchestrators poll for everything else.
Hooks are configured during installation (see docs-site for setup). As an agent, here's what you need to know operationally:
- **Only `on_done` fires.** When you `task complete`, HZL queues a webhook. For stuck detection, stale detection, blocking changes, or progress — poll with `hzl task stuck --stale` or `hzl task list`.
- **Delivery is not instant.** `hzl hook drain` runs on a cron schedule (typically every 2–5 minutes). Your completion is recorded immediately, but the notification reaches the gateway on the next drain cycle.
- **Payloads include context.** Each notification carries `agent`, `project`, and full event details. The gateway handles per-agent routing — HZL sends the same payload to one URL regardless of which agent completed the task.
- **If hooks seem broken**, check `hzl hook drain --json` for delivery failures and `last_error` details.
---
## Multi-agent coordination with leases
```bash
# Claim with lease (prevents orphaned work)
hzl task claim <id> --agent <agent-id> --lease 30 # 30-minute lease
# Fleet status: who's active, what they're working on, how long
hzl agent status # All agents
hzl agent status --agent <name> # Single agent
hzl agent status --stats # Include task count breakdowns
# Agent activity history
hzl agent log <agent> # Recent events for an agent
# Monitor for stuck tasks
hzl task stuck
# Monitor for stuck AND stale tasks (no checkpoints for 10+ min)
hzl task stuck --stale
hzl task stuck --stale --stale-threshold 15 # Custom threshold
# Recover an abandoned task (steal + set new lease atomically)
hzl task show <stuck-id> --view standard --json # Read last checkpoint first
hzl task steal <stuck-id> --if-expired --agent <agent-id> --lease 30
```
Use distinct `--agent` IDs per agent (e.g. `henry`, `clara`, `kenji`) so authorship is traceable.
---
## Sizing tasks and projects
**The completability test:** "I finished [task]" should describe a real outcome.
- ✓ "Finished installing garage motion sensors"
- ✗ "Finished home automation" (open-ended domain, never done)
**Split into multiple tasks when:** parts deliver independent value or solve distinct problems.
**Adding context:**
```bash
hzl task add "Install sensors" -P openclaw \
-d "Mount at 7ft height per spec." \
-l docs/sensor-spec.md,https://example.com/wiring-guide
```
Don't duplicate specs into descriptions — reference docs instead to avoid drift.
---
## Extended reference
```bash
# Setup
hzl init # Initialize (safe, won't overwrite)
hzl status # Database mode, paths, sync state
hzl doctor # Health check
# List and find
hzl task list -P <project> --available # Ready tasks with met dependencies
hzl task list --parent <id> # Subtasks of a parent
hzl task list --root # Top-level tasks only
hzl task list -P <project> --tags <csv> # Filter by tags
# Create with options
hzl task add "<title>" -P <project> --priority 2 --tags backend,auth
hzl task add "<title>" -P <project> -s in_progress --agent <name>
hzl task add "<title>" -P <project> --stale-after 2h
hzl task update <id> --stale-after 30m
hzl task update <id> --clear-stale-after
# Agent fleet status
hzl agent status # Active/idle agents, current tasks, lease state
hzl agent status --agent <name> # Single agent
hzl agent status --stats # With task count breakdowns
hzl agent log <agent> # Activity history for an agent
# Web dashboard
hzl serve # Start on port 3456
hzl serve --host 127.0.0.1 # Restrict to localhost
hzl serve --background # Fork to background
hzl serve --status / --stop
hzl serve --gateway-url ws://host:18789 # Connect to OpenClaw gateway
hzl serve --gateway-token <token> # Gateway auth token
# Or set gateway once in config.json: { "gateway": { "url": "...", "token": "..." } }
# Raw reporting surfaces
hzl events # NDJSON event feed
hzl events --follow
hzl events --from 0 > events.jsonl
hzl stats --window 1h
# Authorship
hzl task claim <id> --agent alice
hzl task checkpoint <id> "note" --author bob # Records who did the action
hzl task claim <id> --agent "Claude" --agent-id "session-abc123"
# Cloud sync (optional)
hzl init --sync-url libsql://<db>.turso.io --auth-token <token>
hzl sync
```
---
## Web dashboard (always-on, Linux)
```bash
hzl serve --print-systemd > ~/.config/systemd/user/hzl-web.service
systemctl --user daemon-reload
systemctl --user enable --now hzl-web
loginctl enable-linger $USER
```
Available at `http://<your-box>:3456` (accessible over Tailscale). macOS: use `hzl serve --background` instead.
---
## What HZL does not do
- **No orchestration** — does not spawn agents or assign work automatically
- **No task decomposition** — does not break down tasks automatically
- **No smart scheduling** — uses simple priority + FIFO ordering
These belong in your orchestration layer, not the task ledger.
---
## Notes
- Run `hzl` via the `exec` tool.
- Check `TOOLS.md` for your identity string, which projects to monitor, and the commands relevant to your role.
- Use distinct `--agent` IDs per agent and rely on leases to avoid collisions in shared databases.
- `hzl workflow run` commands require HZL v2+. If unavailable, use the manual fallback patterns documented above.
标签
skill
ai