Publishing the spec
Put a Task's agreed spec in your repository as files, behind a pull request
Publishing writes the spec into the repository the project is connected to, as files a person can read in a pull request and an agent can parse without a bridge. It is always a deliberate act on a Task: somebody decides the spec is ready to be read, and asks for it. Nothing publishes on a timer, on every edit, or when a Task completes.
There is no agent-facing way to publish. An agent can author the spec and read it back over the spec surface, but putting it in front of the team stays a decision a person takes.
Publishing a Task
Open the Task and press Publish spec. The button only appears once the project has a repository connected — see Connecting to source control.
Each Task publishes on its own branch, named for the project and the Task:
specbench/spec/pool-club/7-first-taskThe project is in there because two projects may publish into one repository, and the number because two Tasks may share a name — without either, one Task's publish would land in another's pull request. Renaming a Task moves its branch, so a pull request already standing for it is left behind rather than updated; rename before publishing rather than after.
Publishing needs the same standing as editing the spec: publishing puts the spec in front of the team, which is an authoring act.
What gets written
The whole published spec, not the Task's own changes:
.specbench/
contexts/
identity/
context.yaml
workstreams/
tasks-and-delivery.md
tasks/
port-the-task-slice.md
manifest.json- One YAML document per artefact, laid out by the element registry — every artefact kind knows where its file belongs. It is byte-for-byte the same document the spec surface exports, so what is published and what an agent reads can never drift apart.
- Workstream and Task framing as Markdown, because those are narrative records explaining why the work happened, not a surface anything writes back to.
manifest.json, mapping every entity to its file by identity — so a reader can find an artefact without walking the tree, and follow a rename without losing track of it, because identity stays put while the path moves.
Everything lands under the project's output path (.specbench by default). Files
outside it are never touched.
The published tree is replaced, not patched
An artefact that has been removed simply has no file in the next publish, and a renamed one moves. Nothing is swept up afterwards, and nothing lingers because the publisher forgot it.
The flip side: files you add by hand inside the output path are removed on the next publish. Keep hand-written notes outside it.
Two clocks: merged and done
Publishing renders through the Task's own workstream, because a Task still in flight has not reached the trunk. So the pull request shows the trunk together with that workstream's work, and the trunk itself only catches up when the Task completes.
Merging the pull request and completing the Task are separate acts on separate clocks. Merging is what proves the spec was agreed; the manifest is where a reader can tell which has happened, because it carries each Task's delivery state while the artefact documents carry none.
The spec records agreed intent, never what has been built. Implementers and CI build from it, and the spec moves on around it as further work is agreed.
Publishing twice
The render depends on nothing but the spec, so publishing twice with nothing changed in between writes nothing at all — no empty commit, and the pull request already standing is left as it is. Specbench tells you nothing changed rather than claiming a publish.
When it refuses
| What you see | What happened |
|---|---|
| Nowhere to publish to | The project has no repository connected. Connect one in Settings → Git. |
| Two artefacts would share a file | Two names produce the same file name — most often names differing only in punctuation. Nothing is written; rename either one. |
| The provider refused | The branch is protected, or the access the installation was granted has been narrowed or withdrawn. The repository is left exactly as it was. |
A refusal never leaves anything partial behind: the branch only moves once every file has been written, so the publish either lands whole or not at all.