Concepts · Workers

Workers

A worker is a durable principal you hire to own one responsibility — one worker per report you want to read. It runs bounded shifts on its schedule, produces artifacts against its standing job, optionally publishes them to an outlet, and reports to your Inbox in plain language.

Vocabulary

TermMeaning
WorkerThe durable principal: identity, title, job, template allow-list, status (active | paused | retired). Tenure ends only by decision.
TitleThe worker’s role, especially within a team (e.g. Illustrator). Colors how it signs its reports; no routing keys off it.
TeamA department: named for what it PRODUCES (its domain — members inherit it as their specialty), with an optionally designated outlet — the fence: everything the crew publishes ships there.
SpecialtyThe worker’s own WHAT — it steers what every shift plans and produces. Blank on a team = inherit the team’s produces; a solo worker must state one. No worker exists without a WHAT.
Solo outletA worker’s own channel, active only while solo. Joining a team defers to the team’s outlet — the solo outlet stays set but dormant, and wakes back up on leaving.
JobThe standing per-shift spec: what to produce, how many, at what caps, in what voice, and where it publishes. Singular by discipline — the countable things that run are runs and orders.
ShiftOne bounded activation: trigger → plan → execute → publish → report → halt. A shift always ends; its record links every run, order, artifact, and message it touched.
ScheduleThe WHEN primitive — a cron expression (UTC) that wakes a worker, or fires a single template directly.
TriggerWhat started a shift: schedule or manual run-now.
ReportOne Inbox message per shift, written in the worker’s own voice per its messaging spec. Figures come from the mechanical record — never invented.

The shift

one shiftascii
trigger (schedule or run-now)
   └─▶ SHIFT
        1. CONTEXT — read the catalog census + assigned work
        2. PLAN    — run a plan template (an internal, attributed run)
        3. EXECUTE — place a Generation Order (children fan out)
        4. PUBLISH — ship gated output to the job's outlet (optional)
        5. REPORT  — one Inbox report, in the worker's own voice
        └─▶ HALT   — a shift always ends; stop conditions escalate

Every run a shift creates is attributed to the worker (createdVia: "worker" + workerId), so the whole trail — plan runs, order children, artifacts, spend — is auditable per worker, per shift.

The job

Worker.jobjson
{
  "contentTypes": [{
    "key": "clipart",
    "planTemplate": "plan-clipart-batch",
    "targetTemplate": "generate-clip-art-asset-v2",
    "count": 50,
    "budgetUsd": 3.50
  }],
  "failureThreshold": 0.2,
  "defaultPriorities": "flowers, animals, space",
  "publishPolicy": "classified",
  "messaging": {
    "tone": "warm, direct, first person",
    "cadence": "every-shift",
    "requirements": ["per-type counts", "total spend"]
  }
}

Producing is not publishing: publishPolicy is the worker’s selection bar (classified publishes only work the classifier titled and categorized; none, the default, publishes nothing). Where it ships is the framework below — destination lives on the worker’s assignment, never in the job (and never on a goal).

Every field a content type takes

A contentType is one thing the worker makes. Each is planned, executed, capped, and published independently — a worker with six of them runs six small production lines every shift.

FieldMeaning
planTemplateThe template that decides WHAT to make. It emits a plan artifact — the auditable record of what the worker knew and chose — and nothing is generated until it settles.
targetTemplateThe template that MAKES each item. Every planned item becomes one child run of this template, under a single order.
countItems per shift. A count of 0 skips the content type entirely — no plan, no order, no cost. That is how you park a category until you want it.
budgetUsdHard cap for this content type, per shift, enforced against the recorded cost ledger. Reaching it stops the line and settles what completed.
itemFieldsWhich fields of a planned item are passed through as the child run’s intake.
requiredFieldsFields an item must carry to run at all. The planner is instructed, not trusted — an item missing one is dropped, not guessed at.
styleWhitelistThe worker’s style specialty. One knob, two jobs: it tells the planner which styles to choose among, and clamps anything off-list afterward.
intakeBaseIntake defaults every item inherits — quality tier, aspect ratio, the classifier’s category vocabulary.
planIntakeExtraExtra intake passed to the PLAN template only: audience, pack goal, a pack-wide base style.
publishPolicyAn object here ({ "mode": "auto" | "hitl" }), governing whether a finished pack is pushed to its ingest endpoint or staged for review. Not to be confused with the worker-level string of the same name.
Two fields named publishPolicy

job.publishPolicy is a string deciding whether individual artifacts publish to the outlet. job.contentTypes[].publishPolicy is an object deciding whether a finished pack is pushed to its ingest endpoint. They are independent, and both default to publishing nothing — a worker can cheerfully publish every asset while never shipping a single pack.

Composite output: the publish leg

Some work is bigger than one artifact. A themed pack is a plan, dozens of assets, product mockups, and a cover — and it is worthless delivered in pieces. After an order settles cleanly, the shift runs a publish leg: it composes the cover from the pack’s own hero assets, assembles one payload, and delivers it signed to the outlet’s ingest URL. Everything is idempotent on the order id, so re-publishing is always safe.

A pack that is not clean is never pushed. Failed items, a cover that could not be generated or categorized, or a missing outlet each leave the pack staged — and the reason is recorded in the shift report rather than swallowed. See Publish packs with a worker team for the full build.

Teams, designations, and where work ships

One law governs distribution: designations and sections decide where work ships. Demand has its own hierarchy: the team’s produces (its domain) → the worker’s specialty (narrower, inherited when blank) → goals (measurable campaigns, refining further). The resolved specialty steers every shift’s planning — and a worker cannot exist without one.

  1. On a designated team → the team’s outlet. Period. A team with an outlet is a publishing contract for the whole crew — the fence. A member’s Solo outlet defers (kept, dormant), a matching sibling section can’t poach, and no goal can redirect. “This team publishes only to X” is provable, with zero asterisks. A team without an outlet is organizational only.
  2. Otherwise, the home site’s sections sort — the section outlet matching the artifact’s category claims it (/flowers catches flowers): permanent site taxonomy that outlives any goal.
  3. The rest lands on the worker’s Solo outlet. No home channel → unpublished, never a wrong page. A hard pin for a solo worker is a team of one.

Every publish records its provenance (routedVia) and every assignment change is logged — designations are audit-grade. One artifact can still appear in many outlets via syndication: carrying is the outlet’s act, not the worker’s.

Stop conditions

A shift halts — never silently — when a stop condition trips: hard budget caps, a child-failure rate above the job’s threshold, or empty and skipped plans. Every breach files a high-priority task and an Inbox alert in the worker’s name, with the technical detail attached behind a disclosure.

The inbox speaks human

Workers communicate in natural language: what happened, what was done, what needs you. A report may be plain (the voice layer falls back to the mechanical summary on any failure) — but it may never be lost, and it may never omit assigned work.

What a report must contain

The prose is short on purpose, so the record rides with it rather than inside it. Every report carries a manifest behind a disclosure: each image with its URL and category, each pack with the address it published to, its cover, tags and facts — and, for anything that did not ship, the reason it was staged instead.

You can make specific facts contractual with messaging.requirements. Each entry becomes a “must include” instruction, so a pack worker can be required to name the address it published to every single shift:

job.messagingjson
"messaging": {
  "cadence": "every-shift",
  "voice": "plain English, first person",
  "requirements": [
    "how many images you created, and their categories",
    "for each pack: its title and the address it published to",
    "any pack that did NOT publish, and why it was staged instead",
    "the total spend, and the per-item cost"
  ]
}

Steering a worker

You steer a worker by assigning work, not by editing its job: goals carry measurable targets it plans against every shift, and scheduled tasks are day directives it checks off itself. See Assigned work.