Search by

rmb32 / barnspec-cli

rogerbarnfather

Barnspec CLI — the wizard plus Writer/Glossary/StoryMap rendering commands as a standalone CLI transport package

Package info

bitbucket.org/rmb32/barnspec-cli/

Homepage

pkg:composer/rmb32/barnspec-cli

Statistics

Installs: 140

Dependents: 2

Suggesters: 0

v3.0.1 2026-10-30 09:14 UTC

This package is auto-updated.

Last update: 2026-10-30 09:27:41 UTC


README

Part of Barn.

The command line for Barnspec: capture user stories and acceptance scenarios through an interactive wizard (or from scripts), then turn them into readable Markdown, a glossary, a visual story map, and tracked work tickets.

Requirements

  • PHP 8.5+

Installation

composer require --dev rmb32/barnspec rmb32/barnspec-cli

Everything you capture is saved as JSON under .barnspec/ in your project — safe to commit.

Inside a barn (a project whose root holds .barn/barn.json), barnspec and wizard-reset use the barn's .barn/barnspec/ instead, from any folder inside it.

Capture stories

vendor/bin/barnspec create-area-of-business --title="Commerce" --meaning="Selling things online" \
    --phase="Launch" --phase-meaning="First release"
vendor/bin/barnspec create-story --area-of-business="Commerce" --role="Customer" --role-meaning="Someone who buys" \
    --goal="Update basket quantities" --reward="get exactly what they want" --stage=adjust
vendor/bin/barnspec refine                            # build out a story's Given/When/Then Scenarios
vendor/bin/barnspec create-scenario --file=scenario.json   # the same, for scripts and CI
vendor/bin/barnspec show                              # list captured areas of business
vendor/bin/barnspec show commerce --json              # one area's full outline

refine needs a real terminal. A story with no Scenario yet shows as rough on the story map.

A new area of business always starts with its first phase (--phase defaults to "Phase 1"). Areas, roles, stories, subjects and facts can be named by their slug (commerce) or by the title they were created with (Commerce). A story's reward follows "so that they…".

scenario.json names everything by title or slug. A parameter is only described (meaning, type) the first time its Fact or action uses it — a new Fact needs its parameters described even when another Fact of the same Subject already has one by that name. One fact can appear more than once:

{
    "area-of-business": "reservations",
    "role": "guest",
    "story": "find which rooms are free for their nights",
    "title": "search for rooms free from 10 November for 2 nights",
    "actionSentence": "search for rooms free for some nights",
    "actionParameters": {
        "check-in-date": { "meaning": "the first night of the stay", "type": "string", "value": "2026-11-10" },
        "nights": { "meaning": "how many nights the stay lasts", "type": "integer", "value": 2 }
    },
    "given": [
        { "subject": "room", "subjectMeaning": "a room the hotel lets", "fact": "is on offer",
          "factMeaning": "the room is part of what the hotel lets to guests",
          "parameters": { "room-number": { "meaning": "the number on the door", "type": "string", "value": "101" } } },
        { "subject": "room", "fact": "is on offer", "parameters": { "room-number": { "value": "102" } } }
    ],
    "outcome": "accepted",
    "then": []
}

title and meaning are optional and default to the action sentence, which lets several Scenarios share one action. A Fact's meaning is a state — it is read after both "Given" and "Then".

Change what you captured

Everything in a phase can be reworded or deleted until that phase is released.

vendor/bin/barnspec reword --area-of-business=front-desk --subject=stay --fact="is under way" \
    --meaning="the guest has arrived and is in the room"
vendor/bin/barnspec reword --area-of-business=front-desk --subject=stay --fact="is under way" --title="is in progress"
vendor/bin/barnspec reword --area-of-business=front-desk --action="check a guest in" --parameter=room \
    --meaning="the room they are given"
vendor/bin/barnspec reword --area-of-business=front-desk --story="check a guest in" --reward="the guest has a key"
vendor/bin/barnspec reword --area-of-business=front-desk --phase="Phase 1" --meaning="checking guests in and out"

vendor/bin/barnspec delete --area-of-business=front-desk --story="check a guest in"      # with its Scenarios
vendor/bin/barnspec delete --area-of-business=front-desk --story="check a guest in" --scenario="a typo"
vendor/bin/barnspec delete --area-of-business=front-desk --subject=stay --fact="is haunted"

reword takes --title, --meaning or both (a story takes --goal and --reward); what you leave out stays as it is. Every Scenario that uses it keeps using it under the new words. A parameter is reached through its fact (--subject, --fact, --parameter) or its action (--action, --parameter).

delete says what goes, including each Scenario's Work tickets and last run, and asks before deleting; pass --yes in a script. A subject, fact, action or parameter is deleted only once no Scenario uses it, and a subject only once it has no facts.

Once a phase is released, its stories, their roles and Scenarios, the subjects, facts and actions those Scenarios use, and the phase itself are locked: reword and delete refuse, and the change goes through an elaboration instead (see below).

Phases

vendor/bin/barnspec release-phase --area-of-business=commerce            # the active phase
vendor/bin/barnspec release-phase --area-of-business=commerce --phase=launch
vendor/bin/barnspec create-phase --area-of-business=commerce --title="Growth" --meaning="More to sell"

One phase is active at a time: release it before starting the next.

A phase is released only once it is proven: every story in it needs a passing scenario-bridge run behind each of its Scenarios, with their tickets done. An elaboration that only rewords, restages or retires has nothing to prove. Until then release-phase names each story that isn't proven and stops, before it asks anything. A phase with no stories in it can't be released.

Once it is proven, release-phase lists what the release locks, and asks before releasing; pass --yes in a script. Then it asks about every story released in an earlier phase whose reward nobody has settled yet (see below). Leave an answer blank to come back to it next time. Pass --skip-impact-review, or run it without a terminal, and it lists them instead. Either way, the phase is released.

Record whether a reward was delivered

A story's Scenarios prove the role can do what it wanted. Its Impact says whether that gave them what the story promised:

vendor/bin/barnspec record-impact --area-of-business=reservations --story=book-a-room \
    --state=achieved --observation="I booked without phoning the front desk" \
    --source=role --who="Sam (guest)"
vendor/bin/barnspec record-impact --area-of-business=reservations --story=book-a-room --phase=suites \
    --state=none --observation="guests still phone to book a suite" \
    --source=measured --who="front desk call log" --observed-at=2026-10-01
  • --state: evaluating (too early to say), achieved, none (works, but did not deliver) or superseded (the need moved on).
  • --source: role, on-their-behalf (the client, a manager, a support desk), measured or team. achieved is settled only by role or on-their-behalf. From measured or team it stays open until they say so too. none and superseded are settled whoever says them.
  • --phase is needed only when the story shipped in more than one released phase that is still being evaluated (its own, and each elaboration's).
  • --observed-at defaults to today. Left out in a terminal, the other answers are asked for.

To see what still needs an answer without releasing anything, and to see what was recorded:

vendor/bin/barnspec outstanding-impacts --area-of-business=reservations         # add --json for scripts
vendor/bin/barnspec show reservations                                           # each story's phase and impacts

write adds an Impact line to each released story, and the story map gives each released card a 🎯 badge. Neither changes a story's colour: a story can pass every Scenario and still have delivered nothing.

Change a released story

A released story's Scenarios no longer change directly; create-scenario refuses and tells you what to run. Elaborate the story in the active phase instead — it is merged into the story when that phase is released:

vendor/bin/barnspec elaborate-story --area-of-business=reservations --story=cancel-their-booking \
    --reward="they are not held to a stay they will not take, and asking twice does no harm"
vendor/bin/barnspec elaborate-story --area-of-business=reservations --story=cancel-their-booking \
    --goal="cancel their booking" --revise               # change the open elaboration's wording
vendor/bin/barnspec elaborate-story --area-of-business=reservations --story=cancel-their-booking \
    --stage=resolve                                     # move it to another stage when the phase is released

Capture into it with create-scenario, adding one key to the usual file:

{ "...": "...", "elaboration": true }
{ "...": "...", "amends": "cancel-a-booking-that-has-already-been-cancelled" }

amends replaces one of the story's Scenarios with this one (it may keep the same title). refine offers a released story once it is elaborated and captures into the elaboration.

vendor/bin/barnspec retire-scenario --area-of-business=reservations --story=cancel-their-booking \
    --scenario=cancel-a-confirmed-booking               # stops holding when the phase is released
vendor/bin/barnspec withdraw-from-elaboration --area-of-business=reservations --story=cancel-their-booking \
    --scenario=cancel-a-confirmed-booking               # undo a pending addition, amendment or retirement

show lists each elaboration under its story; write adds an "Elaboration in …" section while it is open and a "Changes in …" record once merged; the story map draws it as its own card in its phase.

Place a story on the lifecycle backbone

Every story can sit at one stage of the role's life with the business. The vocabulary is fixed across every area of business, so their maps line up column for column:

StageThe role…
establishgains what it needs to take part — signs up, registers, is granted access, or creates the thing later stories act on
adjustchanges something that already exists without completing the core exchange — edits details, reconfigures, corrects a mistake
transactcompletes the exchange the area of business exists for — pays, places the order, submits, publishes
resolvegets what already happened to a settled state — tracks it, chases it, disputes a charge, claims a refund, asks for help
closeends something for good — cancels, closes, deletes, archives

--stage is optional everywhere. A story without one is Unassigned, which is a permanent home for stories that are not about a lifespan at all (reporting, compliance, notification), not a to-do list.

vendor/bin/barnspec restage-story --area-of-business=commerce --story=update-basket-quantities --stage=transact
vendor/bin/barnspec restage-story --area-of-business=commerce --story=update-basket-quantities --clear

restage-story works until the story's phase is released. After that, the stage changes through an elaboration, like its wording: elaborate-story ... --stage=close.

Render what you've captured

vendor/bin/barnspec write commerce --output-dir=docs/stories/commerce   # one doc per Story
vendor/bin/barnspec glossary commerce --output=docs/glossary.md
vendor/bin/barnspec glossary --output-dir=docs/glossary         # every area + index.md
vendor/bin/barnspec map --output-dir=docs/map --stories-dir='../stories/{area-of-business}'   # HTML story map

The map links each card to its Story's document and each area to its glossary. --stories-dir and --glossary-dir are relative to --output-dir; {area-of-business} in --stories-dir stands for each area's slug, so Stories written one folder per area (as above) are found. Story slugs are only unique within an area, so one folder per area is the safe layout. --glossary-dir defaults to ../glossary, the folder glossary --output-dir=docs/glossary writes.

The story map's columns are the five lifecycle stages (plus Unassigned, when anything sits there) and its rows are Phases, newest at the top; each card carries its role as a chip. Each card shows its status: ✏️ rough (no scenarios yet), 📋 expressed (scenarios, nothing ticketed), 🔨 in progress, 📦 built but not proven by a passing scenario-bridge run, or ✅ fulfilled. A legend above the map says what each icon means. Each Phase row says whether it is released, ready to release (every story in it fulfilled) or in progress; released rows start folded shut. The map is the same one the GUI draws, from the same query, so the two always agree. write includes a story's stage and that stage's meaning in the Markdown document; show prints it in square brackets after each story.

Track work

vendor/bin/barnspec work:create commerce basket-quantity-updates caps-at-the-stock-level \
    --title="Cap quantity" --description="Never add more than is in stock" --reference=SHOP-42
vendor/bin/barnspec work:list commerce basket-quantity-updates caps-at-the-stock-level
vendor/bin/barnspec work:status commerce SHOP-42 in-progress

work:status takes the ticket's id or the reference it was created with. A reference shared by two tickets in the same area is refused; name one by its id.

A ticket belongs to a Scenario, so each command names the area, the Story and the Scenario within it. There is no work:confirm: a Scenario goes green only when vendor/bin/scenario-bridge run passes against it, and work:list prints that last run beside the colour. Run work:create with no arguments in a real terminal to pick an area, role, Story and Scenario instead. A Story with no Scenario captured yet is refused — run refine first.

Start over

vendor/bin/wizard-reset           # preview what would be deleted
vendor/bin/wizard-reset --force   # delete the areas of business and Scenarios under .barnspec/

Prefer a browser?

Install Barnspec GUI alongside this package and the barnspec binary gains a gui command that serves it and opens it:

composer require --dev rmb32/barnspec-gui
vendor/bin/barnspec gui

Run any command with --help. The Barnspec quick start (docs/quick-start.md in rmb32/barnspec) shows the wizard and the scripted commands side by side.

Related packages

More docs

Internals · History

License

Proprietary. See LICENSE. Copyright (c) Roger Barnfather.