Skip to content
Agent Orchestration
Skill

/schema-workflow

Internal, invoked from the orchestration context: drives a schema-typed MCP item through its gate-enforced phases, filling required notes.

BOOST
From plugin
task-orchestrator
20929 skills4 agents2 commands
Install
$ npx -y skills add jpicklyk/task-orchestrator --skill schema-workflow --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/schema-workflow

Context preview

The summary Claude sees to decide when to auto-load this skill.

Internal, invoked from the orchestration context: drives a schema-typed MCP item through its gate-enforced phases, filling required notes.

SKILL.md

schema-workflow.SKILL.md
name: schema-workflow
description: "Internal, invoked from the orchestration context: drives a schema-typed MCP item through its gate-enforced phases, filling required notes."
user-invocable: false

Schema Workflow

Drive any schema-tagged MCP work item through its gate-enforced lifecycle. This skill is schema-driven — it reads note requirements and authoring guidance from the item's tag schema at runtime, never hardcoding what notes should contain.

**When this skill applies:** Any item whose `type` field matches a schema defined in `work_item_schemas:` in `.taskorchestrator/config.yaml`, or whose tags match a schema in `note_schemas:` (legacy). Items without a matching type or tags advance freely (no gates).

---

Entry Point

Start by loading the item's context:

get_context(itemId="<uuid>")

The response tells you everything needed to proceed:

| Field | What it means | |-------|--------------| | `currentRole` | Which phase the item is in (queue, work, review, terminal) | | `canAdvance` | Whether the gate is satisfied for the next `start` trigger | | `missing` | Required notes not yet filled for the current phase | | `expectedNotes` | All notes defined by the schema, with `exists` and `filled` status (keys-only — no description/guidance/skill) | | `guidanceKey` | Key of the first unfilled required note with guidance; resolve its text via `query_items(operation="schema", itemId=...)` | | `noteSchema` | The full schema definition matching the item's tags |

If `currentRole` is `terminal`, the item is already complete — nothing to do.

If `noteSchema` is null or empty, no schema matches the item. This means either:

  • `.taskorchestrator/config.yaml` doesn't exist or has no `work_item_schemas` or `note_schemas` section
  • The item's `type` field doesn't match any configured schema key in `work_item_schemas`
  • The item's tags don't match any configured schema key in `note_schemas` (legacy fallback)
  • No `default` schema exists as a fallback

Inform the user: "No schema found for this item's type/tags. Use `/manage-schemas` to configure gate workflows." The item can still advance freely — this is non-blocking, but gate enforcement won't apply.

---

Phase Progression Loop

Each phase follows the same pattern: **fill required notes, then advance.**

Step 1 — Identify missing notes

From `get_context`, check the `missing` array. These are the required notes that must be filled before the gate allows advancement.

If `missing` is empty and `canAdvance` is true, skip to Step 3.

Step 2 — Fill notes using guidanceKey

For each missing note, `guidanceKey` names the note with authoring guidance; resolve its text via `query_items(operation="schema", itemId=...)` and follow it.

manage_notes(
  operation="upsert",
  notes=[{
    itemId: "<uuid>",
    key: "<note-key>",
    role: "<note-role>",
    body: "<content following the resolved guidance>"
  }]
)

Keep the body distilled prose; route verbatim artifacts (test output, diffs, logs) through `bodyFromFile` instead of pasting them inline.

**How guidanceKey works:**

  • `get_context` returns `guidanceKey` (a note key) for the first unfilled required note
  • After filling that note, call `get_context` again to get the key for the next one
  • Resolve the key's `guidance` text via `query_items(operation="schema", itemId=...)`
  • If `guidanceKey` is null, no unfilled required note has guidance — use the note's `description` (also from the schema op) as a general guide

**Skill-assisted note filling:**

  • If the `get_context` response includes `skillPointer` (a non-null string), invoke that skill via the Skill tool before filling the note
  • The skill provides a structured evaluation workflow — follow its steps, then use the output to fill the note
  • `skillPointer` is derived from the first unfilled required note's `skill` field in the schema
  • If `skillPointer` is null, use the resolved `guidanceKey` text as the authoring guide
  • `description`/`guidance`/`skill` are not in `expectedNotes` (keys-only) — fetch them via `query_items(operation="schema", itemId=...)`

**Batch filling:** If you already know the content for multiple notes (e.g., from a completed plan or implementation), fill them all in one `manage_notes` call. You only need to re-check `get_context` between notes when you need the next `guidanceKey` for authoring direction.

Step 3 — Advance to the next phase

advance_item(transitions=[{ itemId: "<uuid>", trigger: "start" }])

The response confirms the transition:

| Field | Check | |-------|-------| | `applied` | Must be `true` — if `false`, the gate rejected (notes still missing) | | `newRole` | Phase you moved to (`previousRole` is omitted from success results) | | `expectedNotes` | Notes required for the new phase (fill these next) | | `unblockedItems` | Other items that were waiting on this one |

**If the gate rejects:** The response lists which notes are missing. Fill them (Step 2), then retry. Do not call `get_context` first — `advance_item` already told you what's needed.

**If the response instead has `applied: false` with `errorCode: "resource_unavailable"` (`errorKind: "transient"`):** this is NOT a note-gate rejection — do not fill more notes and do not retry the same call. A shared resource this item declares via a `resources:` trait is currently held by another item entering WORK. Report the contended `contendedResources` key(s) (and `retryAfterMs` if present) back to the orchestrator/user rather than spin-retrying; see `/status-progression` → "resource_unavailable" for the full recovery pattern.

Step 4 — Repeat or finish

After advancing, check whether the new phase has its own required notes:

  • If `expectedNotes` in the advance response shows unfilled required notes → loop back to Step 2
  • If `newRole` is `terminal` → the item is complete
  • Otherwise, continue work in the new phase and fill notes as progress is made

---

Phase-Specific Guidance

The schema defines which not

Read more
Ships withtask-orchestrator

Server-enforced workflow discipline for AI agents. Prompt-based frameworks hope the LLM follows instructions. This one blocks the call if it doesn't.

Get the whole plugin

Other skills on task-orchestrator.