aemrebarut/herdr-dagr/dagr-producer

Claude Code and agent skill by aemrebarut/herdr-dagr

Trust tier 3
  • community
Source check pending

Checking that the SKILL.md file is still in the repository.

Emit and maintain a dagr run file — a live, contract-valid JSON description of recursive projects, tasks, attempts, gates, evidence, policies, events, and operator-message resolutions that `dagr view` renders as a DAG. Use when orchestrating agents or tracking multi-step work that a dagr pane should display.

Install

npx vskill@latest install aemrebarut/herdr-dagr/dagr-producer

SKILL.md

dagr producer — write the run, prove the run

You are the producer: the single writer of a run file that dagr view renders live. dagr is a representation kernel: you assert task truth, and it derives only defined view signals from those facts. Missing or wrong facts still produce a missing or wrong graph; there is no workflow engine to repair it.

Contract version: `"dagr": 3` (v1/v2 files remain readable; write v3 for new runs).

Find your validator (before you write anything)

The check loop below is the only feedback you get, so resolve the dagr binary FIRST and stop if you can't:

  1. $DAGR_BIN if set;
  2. command -v dagr (on PATH);
  3. the plugin/repo build: <dagr repo>/target/release/dagr — inside a

herdr pane the runtime injects $HERDR_PLUGIN_ROOT, which IS the dagr repo root;

  1. fallback: cargo run --manifest-path <dagr repo>/Cargo.toml -- check ….

No validator available → do not start writing run files; say so and stop. An unvalidated run file is exactly the silent wrongness this whole system exists to prevent.

The loop (non-negotiable)

write run.json.tmp → dagr check run.json.tmp --strict --json → fix → repeat until []
→ THEN rename over run.json

Validate the candidate, then publish it — never the other way around. The pane renders whatever run.json holds, immediately; renaming an invalid candidate over it shows your error state to every viewer while you iterate. The safe transaction:

  1. Write the complete next document to run.json.tmp (same directory —

rename must be atomic, so same filesystem).

  1. dagr check run.json.tmp --strict --json. Exit 0 with [] is clean;

exit 1 means findings (E-codes are errors; W-codes mean representable- but-suspect — fix them unless you can say why not; --strict treats them as failures, prefer it). Exit 2 means the validator could not read the file at all — a path or tooling problem, never a document problem; stdout is empty on that path, so never treat empty output as clean. Stop, re-run the preflight, and never publish on a non-zero exit.

  1. Only when clean: mv run.json.tmp run.json (atomic rename — the pane

reloads on mtime and never sees a half-written or invalid file).

  1. On failure: fix the temp file and re-check. The previous live file

stays untouched — never leave run.json itself in an error state.

Where to write it: the pane looks for $DAGR_RUN first, then .dagr/run.json, then run.json under the workspace cwd — and waits on .dagr/run.json when none exists yet. Default to .dagr/run.json in the workspace root (gitignore it), and one run per file: parallel lanes inside a run are just tasks with disjoint deps, but a separate workflow gets its own run file and its own pane.

Object model in one breath

  • Project = the recursive visual scope. The run is the implicit root;

a subproject is simply a project with parent. A phase or workstream is also just a project, not another entity. Each task has one optional project home, while its dependency edges may cross any project boundary.

  • Task = the work item. Stable id you choose (never a pane id).

kind is an open set — impl · review · test · gate · question · docs · ship · … — pick the honest one (question for a task that exists to be answered by a human, gate for fan-ins; both change how dagr draws it). States: queued · working · review · blocked · done · failed · rejected · canceled · settled_unverified.

  • Attempt = one try at a task. id styled T·aN, 1-based n.

States: queued · working · done · failed · rejected · settled_unverified · lost. A retry never rewrites an attempt — it appends a new one with a `cause`. A task's history never moves backward — you never rewrite or delete an attempt. A task's state follows its latest attempt, so a send-back moves a done task back to working as its new attempt opens.

  • Event = append-only provenance: `attempt_started · attempt_settled ·

promoted · directive · message_resolved · note, ascending at` timestamps. Never rewrite or reorder events.

  • Evidence tier on every terminal outcome: verified (mechanically

checked — test run, commit receipt) · reported (typed envelope from the actor) · heuristic (inferred) · asserted (bare claim). "The agent said done" is at best reported. Missing envelope? That's settled_unverified — a real terminal state, not a soft done.

Invariants dagr check will hold you to

  1. Task state is a projection over attempts: working needs a

working attempt; done/rejected/settled_unverified need the latest attempt to match; failed accepts a latest attempt of failed or lost; queued forbids a working attempt, and forbids a latest attempt of done or settled_unverified — a task re-queued after a failed or rejected attempt is correct and expected; review needs at least one attempt. canceled is task-only: it withdraws planned work without rewriting or inventing an attempt.

  1. Causes point backward in time: attempt n>1 carries

cause (sent_back · gate_failed · followup · superseded) whose ref names an earlier attempt. initial only for n=1.

  1. The run is a DAG: no cycles through deps or gate

inputs. A gate's fan-in IS its deps; inputs exists only to override when the fan-in set differs from the dependency set. Encode true sequential work as dependencies; task declaration order is only the attempt-less sibling tiebreak.

  1. Terminal attempts carry `outcome` with result == state

and a real evidence tier; timestamps are real ISO-8601 and attempts end after they start.

  1. Ids are yours and unique: task ids never collide

with attempt ids. herdr pane ids go in locator, never in id.

  1. Live attempts are locatable and alive: working attempts want a

locator ({"pane": "wX:pN"}) and a populated liveness — prompt_acknowledged (bool), last_output_at (timestamp string), queued_input (count of composer lines typed but unsubmitted, 0 when none — a number, not a bool; a bool rejects the whole document). Update last_output_at when your agents produce output; staleness is rendered, silence is the enemy.

  1. Blocked names its unblocker; promotion is an event, not

an inference — emit {"type": "promoted", "task": ...} when a fan-in completes.

  1. Project containment is not dependency. Give each task one truthful

visual home; keep every blocker in deps, including cross-project edges. Never duplicate a task into two projects to make both impacts visible.

  1. Operator messages retain their authority and id. The pane delivers a

[DAGR OPERATOR MESSAGE] envelope to you. Respect recommend_and_return versus may_decide_and_continue; preserve message_id in the resolution event. dagr transports the request but does not act on it for you.

Recipes

Every recipe below has a complete, strict-clean companion document under examples/ in this skill directory — held clean by the dagr test suite. The fragments here show the shape; when you assemble a real file, crib from the example, because the fragments alone omit cross-references (a cause.ref needs its referent declared, a working attempt needs locator + liveness) that dagr check will hold you to.

Initialize a run
json
{
"dagr": 3,
"run": {
"id": "run-myjob-v01", "title": "what this run is",
"started_at": "2026-02-01T09:00:00Z",
"orchestrator": {"pane": "wX:p1"}
},
"generated_at": "2026-02-01T09:00:00Z",
"projects": [],
"tasks": [],
"events": []
}

Refresh generated_at on every write — it anchors every "Nm ago" on screen, and a stale value renders a staleness banner.

Set run.orchestrator automatically from your own $HERDR_PANE_ID when available (or a stable Herdr agent target otherwise). This is where m queues operator messages; do not point it at a worker. No user onboarding step or extra controller is required.

Shape projects and subprojects before tasks

Use the smallest hierarchy that provides honest visual homes. Do not create separate phases or workstreams arrays:

json
"projects": [
{"id": "APP", "title": "Application"},
{"id": "API", "title": "API stream", "parent": "APP", "owner": "api-lead"},
{"id": "UI", "title": "UI stream", "parent": "APP", "owner": "ui-lead"}
]

A task in API uses "project": "API". If a UI task depends on it, keep the UI task in UI and put the API task id in its deps; the renderer shows the cross-project edge. Do not duplicate the task or force it into the common parent. Omit project only for genuinely run-level work.

Start coarse: declare the useful project skeleton, immediate work, and meaningful gates. Add discovered tasks as they become relevant; publish operator-visible work, not every internal agent, tool, or runtime step. Dagr derives queued-row waits, ready, unassigned, and needs answer from deps, owner/actor, and kind; never encode those as extra fields.

Open a task and start its first attempt
json
{
"id": "L1", "title": "impl: core lane", "kind": "impl",
"owner": "l1-dev", "state": "working", "deps": [],
"attempts": [{
"id": "L1·a1", "n": 1, "cause": {"type": "initial"},
"actor": "l1-dev", "model": "fable",
"locator": {"pane": "wX:p3"},
"state": "working", "started_at": "2026-02-01T09:05:00Z",
"liveness": {"prompt_acknowledged": true, "last_output_at": "2026-02-01T09:05:00Z"}
}]
}

Append {"at": ..., "type": "attempt_started", "task": "L1", "attempt": "L1·a1", "actor": "l1-dev"} to events.

model is a free string rendered verbatim — dagr never rewrites it, so YOU pick the display form. Use a short model·effort chip: fable·xhigh, sol5.6·max, luna5.6·max, terra5.6·max. The pane gives the column 12 cells (terra5.6·max fills it exactly); longer strings get truncated with an ellipsis, and narrow layouts drop the chip before they clip your title.

Settle an attempt (with proof)

Set attempt state, ended_at, and outcome (result must equal the state); mirror the task state; append an attempt_settled event. (ended_at is when the work stopped; the settled event's at is when the verdict landed — they may differ, and the gap is real information: a pane that stopped at 09:50 whose rejection landed at 10:12 records both.) Prefer the strongest evidence you have.

The decision rule: the tier describes your evidence for the settlement claim. done requires that someone claimed completion — however weakly; the tier grades the claim's evidence. When nobody claimed anything and you are inferring from a runtime signal (pane exit, silence, a green prompt), the state is settled_unverified — that is what the state is for. The four honest settlements, spelled out completely in `examples/06-evidence-tiers.json`:

This is the start of the file. Read the full SKILL.md on GitHub.

Security

  • Security scanPassed, 95 of 100Pattern checks on the skill's files.
  • Model reviewPassed

Quality evaluation

  • Task evaluationNot runNo evaluation yet. Run one in Skill Studio.

Source

Popularity

Repository stars
89
Repository forks
4
7-day trend score
22

Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.

Works with

Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.

  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • Codex
  • Gemini CLI
  • Cline
  • Amp
  • Roo Code
  • Goose
  • Continue
  • Kilo Code
  • Junie
  • Trae
  • OpenHands
  • Qwen Code
  • AI Agent
  • Tabnine Chat
  • Sourcegraph Cody
  • Amazon Q
  • Firebase Genkit
  • Sweep
  • Devin
  • Phind
  • Mentat
  • Claude Desktop
  • Aider
  • GPT Pilot
  • Plandex
  • bolt.new
  • v0
  • Replit Agent
  • Anse
  • TypingMind
  • BetterChatGPT
  • LibreChat
  • Warp AI
  • Pieces
  • Fig AI
Embed badge
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/aemrebarut/herdr-dagr/dagr-producer/badge)](https://verified-skill.com/skills/aemrebarut/herdr-dagr/dagr-producer)

Something wrong with this skill or its page? Tell us.