Anatomy of a spec
How nima writes a spec from a beacon: research, the decision pause, the required sections, bug-repair specs, and how to read or edit the result.
A spec is a document that nima writes from a beacon's evidence and your codebase. It has a fixed set of sections, so an AI coding agent or an engineer can work from it without asking what was meant.
On for every workspace. Starting a generated spec is a signed-in session API call (POST /v1/beacons/:id/promote); no API key, MCP tool or Slack action starts one, so call it from a signed-in session or ask the nima team. The call is declared under the copilot_chat plan feature, and a workspace whose plan lacks that feature can get 403 INSUFFICIENT_PERMISSIONS with details.feature set to copilot_chat. Reading specs works with an API key or over MCP.
Starting a spec from a beacon
A generated spec starts when a signed-in user calls POST /v1/beacons/:id/promote. Any workspace role (owner, admin or member) can make the call, but only with a signed-in session: the route carries no API scope, so an API key or OAuth token gets a 403. The call takes one optional body field, repositoryId.
The spec document exists as soon as the call returns. It is titled, empty, and already linked to the beacon's evidence: up to 20 signals, the top-ranked ones. The response carries beaconId, specId, evidenceCount and the progress notification.
nima picks the repository in this order:
- The
repositoryIdyou passed. - The only indexed repository, when the workspace has exactly one.
- Otherwise, one inferred from the beacon's evidence. Research can search up to 3 repositories.
The call can fail in these ways:
| Status | Reason |
|---|---|
| 400 | The beacon is dismissed, has no evidence, or no repository is indexed yet (or the one you passed is not indexed in this workspace). |
| 409 | The beacon is already promoted. |
| 409 | Spec generation started for the beacon less than 10 minutes ago. The 10 minutes count from the start of the run, including time spent waiting for a decision, and after them nima lets you promote again. |
A hand-written spec is different: POST /documents creates an ordinary document with no research and no generation stages. See Specs API.
Spec generation stages: researching, deciding, writing, failed
A spec that nima is generating carries a stage in specMetadata.generation.stage, and get_document_markdown returns the same value as generationStage.
| Stage | Meaning |
|---|---|
researching | An agent is reading the codebase and knowledge graph. The body is empty. |
deciding | Research is done and nima is waiting for a person to pick an approach or answer questions. |
writing | The writer is producing the document. |
failed | The run gave up. The body stays empty and will not change on its own. |
The stage is cleared when the spec is written. A failed run clears the beacon's promotion marker and leaves the empty draft, and promoting the beacon again reuses that draft instead of creating a second one. Promoting a spec to a ticket is refused while any stage other than failed is set.
What spec research looks at
Spec research is a tool-using agent that gathers findings before the writer starts. It has these tools:
| Tool | What it answers |
|---|---|
| Codebase search | Which files and symbols relate to the request. |
| Module context | What a module does and what depends on it. |
| Git activity | Who changed that area recently and how often bugs were fixed there. This is where ownership risks come from. |
| Knowledge graph query | What the product already does and what the team decided before. |
| Conflict detection | Whether the request collides with existing specs. |
| Traceability | Which product concepts map to which code modules and files, and which specs already reference them. |
| Slack questions | Questions for the team (next section). |
When a beacon involves a bug, the agent also gets a tool that reads the suspect code.
Search returns the nearest match whether or not the thing you asked about exists. nima tracks which words of a request it could not find anywhere, and treats a feature it cannot locate as one to build rather than one to fix. See Code intelligence.
Questions posted to Slack during research
Spec research can post up to 5 questions to the workspace's Slack updates channel. The message is headed *Spec Generation Questions* — _Spec from N signal(s)_, where N is the number of signals the run was started with, and each question is labelled Q1, Q2 and so on with its category and context. Replies in the thread feed the knowledge graph.
If Slack is not connected, no updates channel is set, or the updates channel is silent, nima posts nothing. Either way, the research agent is told to carry its unresolved questions into the spec's Open Questions section.
The decision pause and the 24-hour default
nima pauses a spec run only when it has a real choice to hand over: more than one viable approach, or at least one open question. A run with one obvious approach and no questions never pauses.
When it pauses, the stage becomes deciding. nima asks for one approach and at most 3 questions, with its own pick pre-selected on each.
- Who answers. Only the person who promoted the beacon can answer. The call is
POST /v1/specs/:notificationId/decisions, made with a signed-in session, and a different user or workspace gets a 404. The body isapproachIdplus up to 3answers, each withquestionId,pickIndex(-1means custom text only) and optionalcustomTextup to 500 characters. Answering starts the write immediately, and resubmitting is harmless.:notificationIdis theidof thenotificationobject the promote call returned. Read the choices fromGET /notifications/:notificationId(signed-in session):metadata.brief.approaches[].idandmetadata.brief.questions[], each withid,optionsand nima'sagentPickIndex. Before research finishes, the call returns 409. - If nobody answers. After 24 hours nima writes the spec with its own picks. Every unconfirmed decision is marked
(assumed by nima — not yet confirmed)in the Decisions section, so you can search a spec for that phrase to find choices nobody made. - How you are told. With watches turned on for the workspace, the promoter gets one message titled
nima needs a decision on "<title>"per open question, plus one for the approach when there is more than one. Each message states the question and the time after which nima proceeds with its own pick. The link in it opens the web app, which lands on Integrations and has no decision view, so answer with the API call above.
Required spec sections
nima validates every written spec against a fixed template, and a spec that misses a required section is sent back to the writer once; a second miss fails the run (stage failed).
| Section | What it holds | Rule the validator checks |
|---|---|---|
| Customer Voice | Quotes from the beacon's signals, in the customer's words. | Required. |
| Problem | What is wrong today, with no solution in it. | Required. |
| Approaches Considered | One ### subsection per candidate, with effort, what it reuses and its risks. | Required. Exactly one approach carries **Chosen:** yes. |
| Proposed Solution | The chosen approach, written out. | Required. |
| Acceptance Criteria | Conditions an engineer can check. | Required. Written as a checklist. |
| Edge Cases | Scenarios that could break the change. | Required. Each has a **Desired outcome:** line. |
| Effort | A level and the reasoning. | Required. Contains **Level:** set to low, medium or high. |
| Risks & Tech Debt | One callout per risk, with a mitigation. | Required. |
| Open Questions | What nima could not resolve. | Optional; not checked by the validator. |
| Decisions | Questions that were settled, and how. | Optional, omitted when empty. |
| Not Doing | Each rejected approach and why it lost. | Optional, omitted when empty. |
Decisions and Not Doing are left out rather than left empty, so a spec with no Decisions section means nothing was decided.
Rejected approaches appear twice: in Approaches Considered with their risks, and in Not Doing with the reason. A reviewer who disagrees with the choice can see what else was on the table.
Bug-repair specs: Repair Evidence and Repair Verification
nima writes a bug-repair spec when any signal the run was started with (the top 20) is classified as a bug or carries incident evidence from an error tracker. Such a run must build a repair dossier before writing.
The dossier holds:
- Observed behavior against expected behavior.
- Diagnosis status:
unknown,hypothesisorconfirmed. - Evidence, with the ids it came from.
- Investigation still needed: the missing evidence and the steps that would tell competing causes apart (required whenever the cause is not confirmed).
- Containment, kept apart from the repair itself.
- A regression scenario.
- Success and failure signals, and an observation window.
- A rollback trigger.
nima appends two generated sections, ## Repair Evidence and ## Repair Verification, and rebuilds Problem, Proposed Solution and Acceptance Criteria from the dossier, so the cause is never stated more strongly than the evidence supports. A reviewer pass checks the result before it is accepted. Every Repair Verification section ends by stating that recovery remains unverified without representative traffic or verification evidence, and that an alert closing on its own does not prove the repair.
Evidence added while a spec is being written
Signals added to a beacon while its spec is generating are attached to the draft, but the writer does not use them. nima sends the promoter a notification, "New evidence while the spec was being written", suggesting a re-run if the evidence should be part of the spec. The notice is an in-app notification, readable with a signed-in session at GET /notifications. The admin panel does not show it. To re-run with the new evidence, wait until the run has finished, then delete the spec (DELETE /documents/:id, owner or admin). Deleting it returns the beacon to ready, or to held if nima started the spec on its own. Then promote the beacon again. Within 10 minutes of the run starting, a second promote returns 409. After that, nima treats the run as abandoned even if it is still researching or waiting for a decision, and a second promote starts a separate run with a new draft, so wait until the first run has finished or failed.
Reading and editing a spec
To read a spec, call get_document_markdown over MCP or GET /documents/:id/markdown. Both return the title, status, cardId, version and generationStage, and return the body in windows: follow pagination.nextOffset until it is null and keep version unchanged between windows.
To edit a spec, send the whole document to PUT /documents/:id/markdown with a key that holds documents:write. That scope carries delete permission, so only a workspace owner or admin can grant it, and MCP clients cannot hold it. The route replaces the body and returns 204. It returns 409 if someone changed the document at the same time. Take a snapshot first with POST /documents/:id/snapshot (scope versions:write), because the replacement is not recoverable otherwise; see Spec versions API.
A spec's status starts at draft, and by hand you can only write draft. The other statuses are set by the delivery flow. See Specs API and Spec sections API.
After the spec: ticket, PR and shipping
A finished spec is a draft. Promote it to a ticket and nima links the pull requests that deliver it, checks each push for drift against the spec, and marks the spec shipped when the last linked PR merges. Delivery covers that path. A coding agent that works from the spec runs as an agent operation.