Yard: the record of how a change was built
A specification says what the product must do, and the trace shows which tests check it. Yard keeps the third record on every branch: what your coding agent planned, asked, and decided, and what you answered. It ships with open-source Loft, in its plugin for Claude Code and Codex.
What a diff leaves out
Say you ask your coding agent to let customers pause a subscription. An afternoon later the branch holds a change to the specification, the code, and its tests. The diff shows what changed, and the specification says what the product must now do. Neither shows that the agent asked whether a paused subscription keeps its billing date, that you said it should, or that you sent its first change to the specification back because it left out the email a customer gets when a pause ends. That history usually stays in a chat transcript that nobody opens again.
Yard keeps it on the branch, as a Yard Log: typed records the agent writes as it works, and the answers you give when it asks. A reviewer reads the Yard Log next to the diff, and the next agent on the branch reads it before it starts.
Three records in one repository
Loft is the first pillar of the Software Plant: a product contract that people ratify and agents build against, kept honest by deterministic checks. Yard is the pillar for coordinating production. Its first part, Yard Client, ships with open-source Loft, and it keeps a Yard Log for each branch beside the two records Loft already keeps.
my-product/spec/What the product must do: features, requirements, and acceptance criteria, checked byloft checkand pinned when published.loft.trace.yamlWhich tests verify each criterion, checked byloft reconcile..yard/feat/pause-subscription/How this branch's change was planned, asked about, decided, and built....The code and its tests.
Set a repository up once. Install loft as a dev dependency, or with Cargo, then create the specification and register git's merge driver:
npm install --save-dev @ask-loft/loft # or: cargo install --locked loft-cli
npx loft init
npx loft merge-driver --install --command "npx --no-install loft"
loft init writes an empty specification and the agent skills. The merge driver makes git merge the specification and every Yard Log record by record, by key, instead of line by line. With a loft on your path, loft merge-driver --install needs no --command.
Where Yard came from
Yard started as a habit. During a long build we kept a Claude artifact open as a working document: the plan, the open questions, each decision as it was made, and what each step left done. It became the page we read most that week, and it lived apart from the code it described.
We prototyped the idea on its own as a Claude Code plugin with a local page, then moved it into loft. Like the rest of Loft, Yard was specified in the open format before it was built, and every change to it since went into the specification first. How we build Loft with coding agents in general is in Building Loft with Claude Code.
Opening a Yard Log
In Claude Code, add the plugin from Loft's marketplace with /plugin marketplace add Ask-Loft/loft, then /plugin install loft@ask-loft. A project where loft init ran already enables the plugin in its committed settings, so Claude Code offers it to everyone who trusts the project. The plugin runs loft itself. Where loft is a dev dependency rather than on your path, set the plugin's loftCommand setting to npx --no-install loft or pnpm exec loft.
Then cut a branch and ask for the work. For the pause feature:
git switch -c feat/pause-subscription
/loft:yard Let customers pause a subscription for up to three months.
The yard skill also loads by itself when an agent plans work on a branch; the command makes sure of it. The agent's first write opens the branch's Yard Log with the stages it foresees: shape, specify, and build, the first one active and the others planned, so you see the road before any code is written.
The plugin starts the Yard page and keeps one running for the machine, at http://127.0.0.1:7411/. It listens on the loopback interface only. If that port is taken, set the plugin's yardPort setting.
What a Yard Log holds
A Yard Log is a list of stages with typed blocks inside them. A block kind exists only where you act on it, where its state changes over time, or where it keeps a report from loft. Everything else the agent has to say is Markdown, with tables and Mermaid diagrams where they help. That leaves eight kinds:
stage- A step of the work, with a goal that names what it leaves done, such as "a paused subscription skips its renewal".
task- A unit of a stage, marked active when it starts and done when it ends. A correction you asked for is a task of type fix.
question,approval,plan- What the agent puts to you: questions with options, a change to approve or reject with a reason, a plan for the build.
decision- A choice you made, with what follows from it.
note- What a stage produced, what it means for the next step, and what is left open.
loft- A report of
loft's, kept as it was when recorded: the change to the specification, check findings, trace coverage, or a publish.
Only you write answers and decisions. The agent writes the rest through six tools the plugin gives it, and every earlier version of a block stays in the log. Each task is marked as it runs rather than all at once at the end of its stage, which is what lets the page show where the time went.
Ask once, answer anywhere
When the agent reaches a decision point, it sends all of that point's questions together, gives each a recommended option with the reasoning for every option, and waits. For the pause feature it asks whether a paused subscription keeps its billing date and whether the customer hears from you when the pause ends.
You answer on the Yard page or in Claude Code's own dialog, whichever is in front of you. The first answer counts, and the other place closes. Questions the agent asks through Claude Code's AskUserQuestion, the plans it presents from plan mode, and the tasks it creates all reach the Yard Log on their own, so the page misses nothing that was asked in the terminal. After you answer, the agent records a decision: the billing date stays, and paused cycles are skipped, so renewal reminders skip them too.
-
DoneShape the pause
How a pause treats billing is settled.
Started 2:00 PM, ended 2:06 PM
Decision 1The billing date stays; paused cycles are skipped. Renewal reminders skip paused cycles too.QuestionDoes a paused subscription keep its billing date?answered- Keep the date, skip paused cyclesrecommendedThe customer is billed on the same day of the month before and after a pause.
- Move the date by the length of the pauseEvery later renewal shifts, and so does every reminder.
Answered Product owner 2:05 PM in the terminal
-
ActiveSpecify the pause
-
PlannedPlan the build
-
PlannedBuild the pause
The Yard page
The page follows every Yard Log of every repository on the machine, live. A log reads as a timeline of its stages and blocks, newest or oldest first, or as a Gantt chart of the session, with tasks, subagents, loft runs, and the time spent waiting on you laid out by the clock. A button in the header gathers everything that waits on you and opens it in a panel over the live page, so you can answer while the log keeps moving. Blocks that changed since your last visit are marked. Above the chart, one bar splits the session's busy time into loft runs, subagent runs, active tasks, waits on you, and the rest of the agent's work.
- Loft runs: 4 min, 8%
- Subagent runs: 4 min, 8%
- Active tasks: 23 min, 46%
- Waits on you: 11 min, 22%
- Agent work: 8 min, 16%
- Not idle: 50 min
Where the repository holds a Loft specification, the agent records loft's reports instead of retelling them: the change to the specification against the branch it was cut from, the findings of loft check with a reason for each one left in place, and trace coverage once the tests are linked. The page draws each report in its own form. It also shows the tokens each stage took, per agent, so the cost of specifying a change sits beside the cost of building it.
-
DoneSpecify the pause
An approved change to the specification says how a pause works, end to end.
Started 2:06 PM, ended 2:24 PM
DoneFixAdd the email at the end of a pauseAdded a requirement and its criterion for the email a customer gets when a pause ends, after the first change was rejected for leaving it out. fmt and check pass with no findings.
New since your last visit
main agentversion 22:21 PM▸ 1 earlier version
loftSpec changeOne new Feature for pausing a subscription, and one changed criterion of renewal. No change to how invoices are drawn.
Compared with develop at
4c1e9a7b2d.-
Billing
-
Subscriptions
-
Pause a subscriptionadded
-
When a customer pauses a subscription, the system shall hold it for up to three months.added
- A pause longer than three months is refused.added
- The billing date stays the same after a pause.added
-
When a pause ends, the system shall email the customer.added
- The email goes out on the day the pause ends.added
-
When a customer pauses a subscription, the system shall hold it for up to three months.added
-
Renew a subscription
-
The system shall charge each subscription on its billing date.
- A renewal inside a pause is skipped.changed
-
The system shall charge each subscription on its billing date.
-
Pause a subscriptionadded
-
Subscriptions
▸ 7 nodes changed
Recorded
4c1e9a7b2don feat/pause-subscription, with changes not committed, by loft, 2:21 PMapprovalApprove the change to the specificationapprovedApproved Product owner 2:24 PM on the page
-
Billing
loft recorded the spec change as a tree of the nodes it added and changed, and the approval stands right after it.The loop, written into the skill
The yard skill carries the workflow we use for every change, so it doesn't need restating each session. It follows the Loft loop, Author → Ratify → Implement → Reconcile → Decide, with the Yard Log keeping each step.
- Ask for the change on a new branch
- Opens the Yard Log with its stages and sends the first decision point's questions together
- Answer on the page or in the terminal
- Writes the change to the specification, passes
loft check, records the change, and asks for approval - Approve the change, or reject it with a reason
- Commits the specification on its own, then presents the build in plan mode, step by step against the criteria
- Approve the plan
- Builds test-first, marks each task as it runs, links the trace, and closes the Yard Log before the merge
Two rules carry most of the weight. The change to the specification is approved before it is committed, and committed on its own, so the code is checked against criteria you have already read. The build is then planned in plan mode from that specification, naming the criteria each step meets; if you change a requirement midway, the agent presents again only the steps the change touches. If you ask only for a plan, the agent stops once the plan is written and leaves the build stages planned until you ask for the build.
-
DonePlan the build
A bounded build plan covers the approved pause and its tests.
Started 2:24 PM, ended 2:29 PM
planBuild the pauseapprovedApproved Product owner 2:29 PM in the terminal
Outcome
Build the specification approved in
4c1e9a7: a customer can pause a subscription for up to three months, renewals inside the pause are skipped, the billing date stays, and an email goes out when the pause ends.Four bounded tasks
- Pause and resume in the billing model. Store the pause with its end date and refuse one longer than three months. Meets "A pause longer than three months is refused."
- Skip renewals inside a pause. The renewal job skips a cycle inside a pause and keeps the billing date. Meets the changed renewal criterion and "The billing date stays the same after a pause."
- Email when a pause ends. Send it once, on the day the pause ends. Meets "The email goes out on the day the pause ends."
- Link the trace. Each test is written first, fails, then passes; link it to its criterion and run
loft reconcile.
When the work is finished, ask the agent to close the Yard Log. It commits the closed log, and then the branch merges. Run loft publish on the publish branch afterwards, and the change becomes part of the next published, immutable version of the contract; the agent records that publish in the Yard Log the merge brought in.
A Yard Log lives in git
A Yard Log is YAML under .yard/<branch>/, committed in each commit of the work, so it travels with the branch and is read in review. Answers you gave since the last commit go in with the next one, along with each session's token totals and activity. When a merge brings two copies of one Yard Log together, the merge driver joins them record by record.
If your team keeps plans off git, add .yard/ to .gitignore. The agent sees that git ignores the folder and commits nothing of it; the log stays on your machine, and the page works the same. What belongs to the machine rather than a branch, such as the page server's address and each session's events, lives in ~/.yard/.
Built with Yard
Once the first version worked, we built the rest of Yard with it. Each ticket got its own branch and its own Yard Log, and each began the same way: the agent read the ticket, asked its questions on the page, and had its change to the specification approved before writing code.
The logs showed what the transcripts had hidden. Work that a subagent did without a stage of its own went uncounted, so it now counts toward the stage of the agent that launched it and is drawn inside that stage's bar. Part of each stage went on corrections we had asked for, so a task can be a fix, and the page marks fixes apart. A status pane built earlier for Claude Code turned out to show nothing the Yard page didn't, so we removed it, through the specification like any other change.
Claude Code and Codex
Yard's core keeps the log, the submissions, the reports, and the page without knowing which agent writes to them. Each agent host has a native adapter that turns its tools and events into Yard's commands, and both adapters are built from one skill source with a short adaptation per host. A Claude Code session on one branch and a Codex session on another appear side by side on the same page.
In Codex, add the same marketplace with codex plugin marketplace add Ask-Loft/loft, then codex plugin add loft@ask-loft, or choose it in /plugins. Review and trust the plugin's hooks in /hooks, and keep features.hooks = true in Codex's configuration, since the skill alone leaves the hooks off. Then ask for the work with $yard. Answer Codex's questions on the Yard page: a background watcher passes each answer into the session, so the agent picks it up without polling. Plans from both agents look the same on the page. The adapter works with local Codex sessions.
The Codex adapter was itself built in Codex, with Yard keeping its log, while a Claude Code session checked that the Claude adapter still worked.
Try it on one branch
Pick a change you were about to start anyway. Set the repository up with loft init and the merge driver, add the plugin, cut the branch, and ask for the work with the yard skill. Answer the first questions on the page, read the change to the specification before you approve it, and read the closed Yard Log beside the diff before you merge. The source and the full command reference are in the Loft repository on GitHub.