Chainlink Orchestrator
This skill is the planning half of Worklink. It turns a vague or multi-step Chainlink parent into ready leaf issues that the deterministic Worklink executor can safely claim. The planner is allowed to mutate Chainlink issue structure; it is not allowed to execute the implementation.
Contract
Trigger: You need to prepare a parent issue for Worklink execution, especially when the parent is too broad for one backend run or lacks testable acceptance criteria.
Requires: Run from the Chainlink repo (your agent home / $MIMIR_HOME for
operator-tracked issues). Read the parent issue and relevant spec/doc first. Use the bundled
planner prompt at mimir/prompt_templates/decompose.md as the canonical leaf
template.
Guarantees:
- Parent work is split into reviewable leaf subissues.
- Each Worklink-ready leaf has the exact template the executor validates:
Acceptance criteria, checklist items,Review criteria, andWorklink notes. - Dependency edges are represented with
chainlink issue block <ID-that-is-blocked> <BLOCKER>; the blocked issue id comes first, then the blocker. - Only leaves with independently testable criteria receive the
worklink:readylabel.
Does not: Implement code, run Worklink executor jobs, close issues, open PRs, or label vague placeholders as ready.
Planner flow
- Read the parent:
chainlink issue show <parent-id>. - Read the design/spec named by the parent, if any.
- Identify the smallest reviewable leaves. Each leaf should have one coherent change, an observable outcome, and a focused validation command/evidence.
- Create each leaf with
chainlink issue subissue <parent-id> --description "$DESC". - Add dependency edges with
chainlink issue block <ID-that-is-blocked> <BLOCKER>(blocked issue first, blocker second; do not transpose them). - Label only executable leaves with
worklink:ready. - Leave a parent comment summarizing leaf ids, dependency edges, ready leaves, and not-ready leaves.
Required leaf template
Use this exact structure. The executor refuses new issues that do not carry it. The canonical copy is mimir.worklink.planning.LEAF_TEMPLATE_MARKDOWN; the planner prompt renders that constant and tests assert this skill stays in sync with it.
Acceptance criteria:
- [ ] <observable, testable outcome>
- [ ] <focused validation command or evidence requirement>
Review criteria:
- <what a reviewer/operator should verify before approval>
Worklink notes:
- Scope: <files/subsystems expected to change, or "docs only">
- Out of scope: <nearby work not included in this leaf>
- Suggested test command: <advisory validation command for the backend to consider>
When not to decompose
Do not use Worklink planning for:
- one-turn conversational answers,
- issues whose success criteria are still a product decision,
- operator-gated work where approval is needed before any leaf is executable,
- tasks that require secrets, credentials, or off-platform side effects the executor cannot observe,
- broad research questions without a concrete artifact and validation command.
For those, leave a normal Chainlink comment explaining the gate or create a
non-ready planning subissue without worklink:ready.
Shell-safe comment/description pattern
For multi-line descriptions, write the body to a temp file and use command substitution to avoid shell quoting corruption:
cat > /tmp/worklink-leaf.md <<'DESC'
Acceptance criteria:
- [ ] ...
Review criteria:
- ...
Worklink notes:
- Scope: ...
- Out of scope: ...
- Suggested test command: ...
DESC
chainlink issue subissue <parent-id> --description "$(cat /tmp/worklink-leaf.md)" "<title>"
If adding worklink:ready fails because the label does not exist, create or use
whatever project label convention the parent already established; do not proceed
silently with an unlabeled executable leaf.
Ready-queue poller (slice 3 — autonomous dispatch)
pollers.json + scripts/poller.py in this skill are the autonomous execution half.
Once installed and configured (see frontmatter env), the scheduler runs the
worklink-ready-queue poller on its cron (default every 10 min). Each fire:
- Lists open
worklink:readyleaves, intersects them withchainlink issue readyactionability, and counts active Chainlink locks. A pre-labeled leaf blocked by open dependencies stays untouched until Chainlink reports it ready; once its blocker closes it is eligible on the next poller fire. - Computes free slots from
worklink.yamldefaults.max_concurrentminus active claims. Default cap is 2;WORKLINK_MAX_CONCURRENTis only a legacy fallback when the YAML key is absent. - Launches
mimir worklink run <id>detached for up to that many actionable leaves, then returns immediately (a run can take minutes; the poller's own 60s budget would otherwise kill it). The detached run does the claim/evidence/transition in the deterministic core executor.
The detached run inherits the poller's env, so pass_env must carry anything
the run needs — notably GITHUB_TOKEN: the core executor's _open_pr
(gh pr create) runs on the controller side in this subprocess (not in the
worker), so without the token gh can't authenticate and review-ready runs fail
at PR creation → thrash to worklink:blocked. (Manual bash -lc dispatch hides
this — it inherits the container's token.)
Safety properties (do not bypass these in the poller):
- Per-issue exclusivity is guaranteed by
chainlink locks claiminside the run, not by the poller — a duplicate launch for the same id simply fails to claim and exits. - Shedding under pressure: the poller declares
priority: normalinpollers.json, so the scheduler's arbiter suppresses the whole fire under TIGHT (and worse). The in-turnworklink_runtool consults the arbiter directly; the operator CLI (mimir worklink run) bypasses both — it always proceeds. - Stale recovery: a worker that dies leaves a claim; the core TTL reaper
(
MIMIR_WORKLINK_REAPER_CRON) steals it back toworklink:ready(orworklink:blockedonce attempts are spent).
The poller never decides what is implementable — only the planner half (and
the worklink:ready label it applies) does. The poller dispatches only the
subset that is both marked ready and currently unblocked by Chainlink, so it is
safe to apply worklink:ready ahead of dependency availability.