Skip to content

Task classes

A task class is a named category of work. It binds three things:

  1. matchers — when an incoming kickoff belongs to this class;
  2. a workflow — how the work executes;
  3. a risk tier — how much approval a result needs.

Recipes keep their class in recipes/<name>/task_class.yaml; standalone classes live under config/task_classes/. Both are picked up by the classifier.

Required fields

Field Required Meaning
name yes Canonical snake_case id, unique across the registry
description yes What belongs here (minimum length enforced)
default_workflow yes Workflow used when nothing overrides it
risk_class yes low · medium · high · critical

Optional fields

Field Default Meaning
task_class — Alias for name in recipe-local files; must equal name when present
version — Recipe version string
artifact_contract_ref "" Contract that governs outputs
matches — keywords, regex, path_globs
default_gates [] Gates applied to every run of this class
max_parallel_runs 0 Concurrency cap; 0 = unlimited
budget_cap_usd 0 Per-run ceiling; 0 = inherit
tags [] Free-form labels
heterogeneity — Advisory lane-diversity metadata

heterogeneity is advisory

It documents which lanes form a diverse panel or must stay separate for authorship. Execution routes on workflow.yaml model_lane fields, not on this block.

Risk classes

Class What it permits
low Auto-promotion is acceptable
medium Shadow and benchmark before promotion
high A human gate is required
critical Dual human approval plus an immutable safety-constraint check

Risk is a property of the task, not of a run's outcome. A medium class does not become low because a run passed.

How a kickoff is classified

mini-ork run calls the classifier with the kickoff text. It scores every class it can see:

Signal Weight
Keyword hit (case-insensitive, word-boundary) 1 per hit
Regex match +2
Class-name alias in the text +3

The highest score wins; ties break lexicographically, and a kickoff that matches nothing falls back to generic. A class with no matches block scores zero and can therefore never win on its own.

Two ways to control the result:

mini-ork classify ./kickoff.md                 # show the decision, dry run
mini-ork run code-fix ./kickoff.md             # force the recipe by name
mini-ork run --task-class code_fix ./kickoff.md

classify writes a task_runs row unless --dry-run is passed.

When classification goes wrong

A wrong class usually means the kickoff is vague. Before adding keywords, state the change and its acceptance check in the first paragraph — the matchers read the same text a planner will.

Matchers

The schema declares three matcher groups:

matches:
  keywords:
    - fix
    - bug
    - patch
    - update
    - refactor
  path_globs:
    - "**/*"
  regex: []
  • keywords — case-insensitive words in the title or description.
  • regex — POSIX ERE patterns over title + description.
  • path_globs — globs matched against files expected to be touched.

Broad globs are not free routing

The shipped code-fix class matches path_globs: ["**/*"], so it will accept almost any path. Its keywords do the real discrimination. When you add your own class, make the matchers specific — a class that matches everything will shadow generic and win ties unpredictably.

Example

name: code_fix
description: "Single-patch code change: bug fix, small feature, refactor of a single function"

artifact_contract_ref: artifact_contract.yaml
default_workflow: workflow.yaml

matches:
  keywords: [fix, bug, patch, update, refactor]
  path_globs: ["**/*"]
  regex: []

default_gates:
  - scope_gate
  - budget_gate
  - deployment_gate

risk_class: medium

artifact_contract_ref and default_workflow are recipe-relative here: they resolve alongside the task_class.yaml that declares them.

Adding a class

  1. Create recipes/<name>/ with task_class.yaml, workflow.yaml and artifact_contract.yaml.
  2. Keep task_class (and the contract's task_class) equal to name.
  3. Give the class at least one discriminating keyword or regex.
  4. Run mini-ork validate — it checks cross-file consistency, not just each file's schema.
  5. Run mini-ork classify on a representative kickoff and confirm the winner.