OmniNode-ai

Dispatch Worker

Dispatch a background worker with role-templated prompt and auto-populated collision fences

OmniNode-ai 4 3 Updated 1mo ago

Resources

2
GitHub

Install

npx skillscat add omninode-ai/omniclaude/plugins-onex-skills-dispatch-worker

Install via the SkillsCat registry.

SKILL.md

Dispatch Worker

Compile a worker dispatch spec through node_dispatch_worker and spawn a background agent.

Announce at start: "I'm using the dispatch-worker skill."

Autonomous execution: No human confirmation gate. --dry-run is the only preview mechanism.

Worker Behavior

Required for all dispatched workers — enforced by _COMMON_PREAMBLE in
omnimarket/src/omnimarket/nodes/node_dispatch_worker/handlers/handler_dispatch_worker.py.

Operating rule 4's final local test command is env -u PYTHONPATH uv run pytest tests/ -v.

  • Ack after each deliverable. After every discrete deliverable (design doc written, test
    run complete, PR opened, finding logged), send a one-line SendMessage to {reports_to}.
    Never batch acks across multiple deliverables.
  • Stop after primary task. When the primary task is complete, send exactly:
    "Primary task done — awaiting further instruction or shutdown." then stop.
    Ambient-idle looping after task completion is forbidden.

Quick Start

# Inline YAML spec
/dispatch_worker "
name: pr-202-fix
team: daylight-0411
role: fixer
scope: Fix omnimarket#202 halt_conditions CodeRabbit findings
targets: [omnimarket#202, <TICKET>]
"

# From file
/dispatch_worker ~/docs/plans/workers/pr-202-fix.yaml

# Dry run (print compiled prompt, no spawn)
/dispatch_worker --dry-run "
name: vggp-designer
team: daylight-0411
role: designer
scope: Design VGGP inference pipeline
targets: [<TICKET>]
"

Valid Roles

Role Purpose Default cap
watcher CI watch loop, no code changes 90 min
fixer TDD-first fix + hostile_reviewer + PR 90 min
designer Design doc + hostile_reviewer + plan 120 min
auditor Read-only investigation + findings doc 60 min
synthesizer Reconcile cross-domain design docs 90 min
sweep Short-lived cron pulse, one metrics line 10 min
ops Long-lived stateful admin worker 480 min

Spec Format

name: <worker-handle>          # required: lowercase, hyphens/underscores, max 64 chars
team: <team-name>              # required
role: <role>                   # required: one of 7 values above
scope: "<goal description>"    # required
targets: [<ticket>, <pr>, ...]  # required: what this worker owns
collision_fences: []           # optional: auto-populated from TaskList if empty
reports_to: team-lead          # optional: default team-lead
wall_clock_cap_min: 90         # optional: defaults by role (range: 5–480)
model: sonnet                  # optional: default sonnet
replace: false                 # optional: kill existing in_progress worker with same name

Dispatch record persistence ()

Immediately after the node compiles the worker prompt and before Agent() is
spawned, write a ModelDispatchRecord to
$ONEX_STATE_DIR/dispatches/<agent-id>.yaml so downstream hooks
(allowedTools audit, tool-call usage audit, consecutive-failure halt) can
reason about the dispatch:

from datetime import datetime, timezone
from omniclaude.hooks.lib.dispatch_record_writer import write_dispatch_record
from omniclaude.hooks.model_dispatch_record import ModelDispatchRecord

write_dispatch_record(
    ModelDispatchRecord(
        agent_id=spec["name"],
        dispatched_at=datetime.now(timezone.utc),
        dispatcher="onex:dispatch_worker",
        ticket=spec["targets"][0],
        allowed_tools=spec.get("allowedTools", []),
        prompt_digest=prompt_digest,
        parent_session_id=parent_session_id,
    )
)

The PostToolUse post_tool_use_subagent_tool_log.sh hook appends a JSONL
line per subagent tool call to
$ONEX_STATE_DIR/dispatches/<agent-id>/tool-calls.jsonl when
ONEX_AGENT_ID is set in the subagent environment.

Worker Operating Rules (worker_template_version: v2)

The Operating Rules are injected verbatim into every worker prompt by prompt.md
before spawning. They are auto-injected — dispatchers MUST NOT hand-restate them.

They are defined once, canonically, and referenced here rather than restated:

@_lib/dispatch-laws/helpers.md

This file previously carried a second hand-maintained copy which had drifted from the
injected block: it declared itself verbatim, undercounted the rules, dropped one
entirely, and abridged two others. Do NOT restate them here again.

See Also

  • node_dispatch_worker (omnimarket) — compiles the prompt template
  • Design: docs/design/dispatch-worker-skill-design.md
  • src/omniclaude/hooks/model_dispatch_record.py — dispatch record schema
  • src/omniclaude/hooks/lib/dispatch_record_writer.py — writer/reader
  • src/omniclaude/hooks/model_resume_manifest.py — resume manifest schema ()
  • src/omniclaude/hooks/lib/resume_manifest_writer.py — phase-boundary manifest writer ()