Write Jobs To Be Done Entries
Every layer above L2 inherits its direction from a job. An agent profile, a skill procedure, and a checklist all answer to the progress the jobs layer names. So an entry naming a feature aims every layer below it at that feature.
Prerequisites
- Node.js 22+.
-
The layered architecture in place, with
CLAUDE.md,CONTRIBUTING.md, andJTBD.mdat the repository root. See Put Your Instructions on One Layered Architecture. - The skill pack installed, so an agent can author entries with you.
apm install forwardimpact/jidoka-skills
npx @forwardimpact/jidoka jtbd
1. Choose where the jobs live
The jobs layer has two shapes. The choice follows how the repository is packaged. It does not follow taste.
| Signal | Shape |
|---|---|
| One manifest at the root, or no per-package manifests | Single static JTBD.md |
| Many packages, each with its own manifest | Generated .jobs blocks |
In the static shape you author entries directly in
JTBD.md. In the generated shape each package declares
its jobs in the jobs array of its own manifest. The
check validates every entry and regenerates the marker-delimited
block in the package group's README.md and in the
root JTBD.md. Start static when you are unsure. For the
directory groups a monorepo uses, see
the Monorepo structure standard.
2. Reconstruct the job from a real moment
Start from a struggle story. Name one real decision. Then recover four things about it: the persona, what just happened, the progress they wanted, and what they hired instead. An entry invented at a desk only confirms what the team believes. Treat every entry as a hypothesis until a struggle story confirms it.
3. Write the entry to structure
Every entry requires User, Goal,
Trigger, Big Hire,
Little Hire, and Competes With. The
generated shape renders User and Goal as
one ## User: Goal heading. Forces and
Fired When apply to a product, because a product
carries an adoption decision. Omit both for a service or a library.
Here is a complete product entry. The persona and the product are illustrative. Copy the shape. Do not copy the content.
## Release Managers: Close a Release With Confidence
**Trigger:** A release goes out on Friday. On Monday the team finds one service
rolled back two days earlier and nobody noticed.
**Big Hire:** Help me know a release reached every environment in a healthy
state before I close it out.
**Little Hire:** Help me see which changes in a release have never run outside
staging.
**Competes With:** A hand-kept spreadsheet; asking each team lead in chat; the
deploy tool's own dashboard; hire nothing and wait for a customer report.
**Forces:**
- **Push:** Silent partial releases keep reaching customers first.
- **Pull:** Confidence that a closed release actually shipped everywhere.
- **Habit:** Treating a green deploy job as proof the release landed.
- **Anxiety:** Fear that one more dashboard adds noise and no answers.
**Fired When:** the platform moves to continuous deployment and the release
event disappears; a hiring freeze removes the role; the deploy vendor ships the
same view at no cost.
Three properties do most of the work here. Remove the product name
from the Big Hire. When the sentence goes meaningless, the job was
solution-shaped, and you wrote a feature request in job syntax.
Next, read the trigger. It must answer "what just
happened?". "Engineers who own deploys" is a role, so
it fails. Last, Competes With must name nonconsumption.
"Hire nothing and wait for a customer report" is usually
the real incumbent.
4. Split the Big Hire from the Little Hire
A Big Hire is the adoption decision for one persona-outcome pair. It
makes a team change what they use. Big Hires live in
JTBD.md with the full entry structure. A Little Hire
repeats, and it brings the same person back tomorrow. Little Hires
live closest to the work they serve: a package
README.md, a design document, or the code itself. An
entry that does both is two entries.
The line budget enforces the split.
jidoka instructions caps JTBD.md at 320
lines, because contributors read the whole file. When the file
approaches the cap, move Little Hires next to their code. Do not
shorten the Big Hires.
5. Balance the four forces and name the exit
Push and Pull move the persona toward the change. Habit and Anxiety hold them where they are. All four describe one decision from a different side.
| Force | What it names | It fails when |
|---|---|---|
Push |
The pain in the status quo | It names a missing feature |
Pull |
The desired future state | It lists what the product does |
Habit |
The current behavior that resists | It restates Push in other words |
Anxiety |
The fear that blocks adoption | It names a technical risk, not a fear |
Forces are asymmetric, and one usually dominates. When all four read as equally weighted, the author filled in a template. Pull collapses into a feature list most often. "Confidence that a closed release actually shipped everywhere" is a future state. "A per-environment dashboard with drift alerts" is a roadmap.
Fired When names the conditions that end the hire, so
it tells every layer below where the job stops applying. Include at
least one environmental shift beyond product failure. A reorg, a
budget cut, a tool ban, or a platform change all fire a product that
works exactly as designed. An entry whose
Fired When names only defects claims the job survives
any change in the world, and no job does.
6. Tag the job so a search finds it
Wrap every job, Big or Little, in a <job> tag. A
contributor or an agent then finds it without knowing which file
holds it.
<job user="<persona>" goal="<outcome>">
**Trigger:** <the moment that creates the job>.
**Big Hire:** <progress sought>. → **<product>**
**Little Hire:** <repeated daily progress>. → **<product>**
</job>
The user and goal attributes make each
search result describe itself. Keep the whole opening tag on one
line and inside 74 characters, and terminal output stays readable. A
goal that pushes the tag past that limit is also too long for a
heading. One search then finds every job in the repository:
rg '<job '.
7. Validate the entry
Run the check. In the generated shape it also reports any block that no longer matches its manifest.
npx @forwardimpact/jidoka jtbd # validate entries and check freshness
npx @forwardimpact/jidoka jtbd --fix # regenerate stale blocks in place
These are the failures a first entry hits.
| Finding | What to change |
|---|---|
<field> is required |
Add the missing required element as a string. |
must end with "." |
Add a period to the Big Hire or Little Hire sentence. |
duplicate bigHire |
Merge the entries, or differentiate the progress. |
invalid user |
Use a persona the check accepts. The hint lists them. |
.jobs must be an array |
Wrap a single job in []. One job is an array of
one.
|
| A file reported as stale | Run --fix and commit the regenerated file. |
Never hand-edit a generated block. Edit the manifest. Regenerate the block. Commit both files. A hand-edited block passes review and fails the next check, because the generator rewrites it from the manifest either way. In the static shape the check has nothing to regenerate, so the properties on this page carry the whole gate. A checklist is the durable way to hold a gate that no command enforces. See Write a Checklist That Verifies Instead of Teaches.
Verify
- Each Big Hire still states progress when you remove the product name.
- Each trigger names a moment and answers "what just happened?".
-
Each
Competes Withlist includes a hire-nothing option. -
Pullnames a future state and lists no feature. -
Each
Fired Whennames at least one shift in the world. -
Every job sits in a
<job>tag whose opening line fits 74 characters. -
npx @forwardimpact/jidoka jtbdexits zero with no findings.
What's next
Put Your Instructions on One Layered Architecture
Give every instruction file one owning question, one load moment, and one budget, so a bad agent run points at exactly one file instead of at a pile of prose.
Write a Checklist That Verifies Instead of Teaches
Place a READ-DO entry gate and a DO-CONFIRM exit gate at real pause points. Keep every item to one binary check. Tag both gates so one search finds every gate in your repository.
Author or Repair One Instruction Layer
Write or fix one layer at a time. Name the layer that owns a piece of text, move misplaced text, and bring an over-budget layer back under its cap without a loss of meaning.
Stop the Line on Instruction Drift
Wire the jidoka checks into your check script and your CI workflow. Read a finding. Route each finding to the fix that owns it. The line stops where the defect appears.