Skip to main content
Glama

Shift work: plan

shiftwork_plan
Read-only

Computes which checkpoint units can run now and in what dependency-ordered waves, returning the ready batch, widest wave width, and path-conflict holds without modifying the plan.

Instructions

Shift-work plan: which units of a checkpoint may run NOW, and in what waves — the batches its depends_on graph permits, computed read-only from the file. Call it before dispatching a wave: ready (the first batch) is what shiftwork_clock_in will brief, and width is how many agents the widest wave needs. A ready member beyond the cursor is clockable only once clock-in has briefed it; without that brief, clock-out refuses it. Use shiftwork_status instead when you only want progress counts, and work_plan when the graph is yours to hand over as nodes rather than a checkpoint on disk — this tool reads the checkpoint's own plan.units. Units already done or dropped count as satisfied and are left out of every batch; todo, in_progress and blocked stay in. Order inside a batch is plan.units order, because the checkpoint schema has no priority field. It never moves plan.cursor — the cursor is echoed unchanged so the pointer and the batch view can be read side by side — and never writes anything. Refusals are structured, never exceptions: work_plan's sentences for a duplicate id, an unknown dependency or a cycle, and shiftwork_status's for a checkpoint it cannot read; a plan whose units are all terminal answers an empty ready, which is an answer, not a refusal. depends_on says nothing about two units writing the same file; a unit's optional touches (repo-relative paths it will WRITE) does: no batch holds two units sharing a path, a unit held out of one is reported in held: [{id, batch, by, path}] (absent when no unit declares touches), and a bad path is refused with work_plan's sentence. A unit whose reviews names a unit that is undeclared, not in its depends_on, or in its own role is refused: unit <id> reviews <r> .... With job.budget declared it adds budget (spent, remaining, per_unit, affordable).

Input Schema

NameRequiredDescriptionDefault
checkpointYesPath to the shift-work checkpoint JSON file (by convention .shiftwork/checkpoint.json in the repo the job works on), absolute or relative to the server's working directory. The same file shiftwork_plan, shiftwork_clock_in and shiftwork_clock_out take; it must validate against assets/schemas/shiftwork-checkpoint.json.

Output Schema

NameRequiredDescriptionDefault
heldNoPresent only when a unit declares `touches`: one {id, batch, by, path} per unit held out of batch `batch` because `by`, admitted there, already writes `path`.
readyNobatches[0] — the units clock_in may brief now; [] when every unit is done or dropped.
widthNoThe largest batch length: the widest fan-out.
budgetNoPresent only when job.budget is declared: the limit, what the log records as spent, units in flight (each reserving one unit and one per-unit estimate), what remains, the per-unit token estimate (the job's lower-median line, 60000 before any) and how many more units fit.
cursorNoplan.cursor, echoed unchanged.
reasonNoWith result `error`: one sentence saying why the call was refused.
resultYes`plan` on success; `error` with `reason` when the checkpoint cannot be read or its graph cannot batch.
winnerNoWith ranking: the first candidate's id, null when none is validated.
batchesNoUnit ids by wave: batch k holds every non-terminal unit whose dependencies all sit in batches below k.
rankingNoPresent only for job.kind experimentation (#265): validated candidates as {id, score, sha}, score in experiment.direction then id; score is the reported string. A candidate is validated when a done unit that reviews it reported a validated-sha equal to the commit it submitted.
sequenceNoThe batches flattened in order.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed4 schema fields changedv0.38.0
    • addedOutput schema / properties / budget
      Added value: +{
      +  "description": "Present only when job.budget is declared: the limit, what the log records as spent, units in flight (each reserving one unit and one per-unit estimate), what remains, the per-unit token estimate (the job's lower-median line, 60000 before any) and how many more units fit.",
      +  "type": "object"
      +}
    • addedOutput schema / properties / held
      Added value: +{
      +  "description": "Present only when a unit declares `touches`: one {id, batch, by, path} per unit held out of batch `batch` because `by`, admitted there, already writes `path`.",
      +  "items": {
      +    "type": "object"
      +  },
      +  "type": "array"
      +}
    • addedOutput schema / properties / ranking
      Added value: +{
      +  "description": "Present only for job.kind experimentation (#265): validated candidates as {id, score, sha}, score in experiment.direction then id; score is the reported string. A candidate is validated when a done unit that reviews it reported a validated-sha equal to the commit it submitted.",
      +  "items": {
      +    "type": "object"
      +  },
      +  "type": "array"
      +}
    • addedOutput schema / properties / winner
      Added value: +{
      +  "description": "With ranking: the first candidate's id, null when none is validated.",
      +  "type": [
      +    "string",
      +    "null"
      +  ]
      +}
  2. Changed3 schema fields changedv0.36.2
    • addedInput schema / properties / checkpoint / description
      Added value: +"Path to the shift-work checkpoint JSON file (by convention .shiftwork/checkpoint.json in the repo the job works on), absolute or relative to the server's working directory. The same file shiftwork_plan, shiftwork_clock_in and shiftwork_clock_out take; it must validate against assets/schemas/shiftwork-checkpoint.json."
    • addedOutput schema / properties
      Added value: +{
      +  "batches": {
      +    "description": "Unit ids by wave: batch k holds every non-terminal unit whose dependencies all sit in batches below k.",
      +    "items": {
      +      "items": {
      +        "type": "string"
      +      },
      +      "type": "array"
      +    },
      +    "type": "array"
      +  },
      +  "cursor": {
      +    "description": "plan.cursor, echoed unchanged.",
      +    "type": "string"
      +  },
      +  "ready": {
      +    "description": "batches[0] — the units clock_in may brief now; [] when every unit is done or dropped.",
      +    "items": {
      +      "type": "string"
      +    },
      +    "type": "array"
      +  },
      +  "reason": {
      +    "description": "With result `error`: one sentence saying why the call was refused.",
      +    "type": "string"
      +  },
      +  "result": {
      +    "description": "`plan` on success; `error` with `reason` when the checkpoint cannot be read or its graph cannot batch.",
      +    "type": "string"
      +  },
      +  "sequence": {
      +    "description": "The batches flattened in order.",
      +    "items": {
      +      "type": "string"
      +    },
      +    "type": "array"
      +  },
      +  "width": {
      +    "description": "The largest batch length: the widest fan-out.",
      +    "type": "integer"
      +  }
      +}
    • addedOutput schema / required
      Added value: +[
      +  "result"
      +]
  3. First observedv0.36.0

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only declare readOnlyHint and openWorldHint=false; the description adds substantial behavior beyond that: never moves plan.cursor, never writes, refusals are structured rather than exceptions, terminal units are treated as satisfied, and a bad `touches` path or invalid `reviews` reference is refused with a named sentence. Output fields (`ready`, `width`, `held`, `budget`) and their absence conditions are also disclosed.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The purpose and the routing guidance to siblings are front-loaded in the first two sentences, which is exactly right. It is a long, dense block afterward, and a few clauses (repeated refusal-by-reference to work_plan's and shiftwork_status's sentences) could be tightened, but nearly every sentence carries operational information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only planner with one parameter and an output schema, the description covers everything an agent needs: batch composition rules, ordering, cursor behavior, empty-ready semantics, holds from path conflicts, review validation, and budget output. Nothing material is left to inference.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and the single `checkpoint` parameter is well documented in the schema, so the baseline would be 3. The description adds real meaning by explaining which part of that file is consumed (plan.units, depends_on, touches, reviews, job.budget) and that cursor is echoed unchanged.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Names a specific verb and resource: computes which units of a checkpoint may run now and in what waves, derived read-only from the depends_on graph. It immediately distinguishes itself from shiftwork_status and work_plan, so an agent can route without opening schemas.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives an explicit call point ("Call it before dispatching a wave") and names both alternatives with the condition that selects each: shiftwork_status for progress counts only, work_plan when the graph is supplied as `nodes` rather than read from disk. It also explains the downstream dependency on shiftwork_clock_in and clock-out.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.