A specification is a family of documents that defines a system about to be built. Write the least amount of document required. The value is in the thinking the writing induces, not in the artifact it solidifies as.
Two worked specifications ground this discipline. READ BOTH before you write a spec. They are the shape every step below is teaching you to produce.
context-reel spec the snippets in Section 3 are drawn from.The snippets quoted throughout Section 3 are excerpts from these files. Read the full specs to see each step in its finished context.
A spec is a family of documents, not one thing. Pick by the ambiguity you need to kill.
| Situation | Document |
|---|---|
| Regulated, contractual, safety-critical | SRS |
| Non-trivial build, design consensus needed | Design doc |
| Cross-team or contentious, durable consensus | RFC |
| One load-bearing decision and its rationale | ADR |
| What to build and why it matters to users | PRD |
| Trivial, obvious, no real trade-offs | Write code |
Three idioms make a requirement testable. Name them once near the top, then obey them everywhere.
SHALL is the synonym of MUST. Pick one per document.Paste this clause under Status so the keywords bind:
The key words MUST, MUST NOT, SHOULD, SHOULD NOT, and MAY in this
document are to be interpreted as described in RFC 2119 and RFC 8174
when, and only when, they appear in all capitals.
Ubiquitous The <system> MUST <response>.
Event-driven When <trigger>, the <system> MUST <response>.
State-driven While <state>, the <system> MUST <response>.
Unwanted If <condition>, then the <system> MUST <response>.
Optional Where <feature is present>, the <system> MUST <response>.
Write the sections in this order, top to bottom. Each step names the section, the rule, and a snippet from the
context-reel.spec.mdreference.
The section order to produce:
One line that states the system's defining tension.
The thesis is your compression test. If you cannot say the system in one line, the scope is not clear enough to write yet.
# context-reel Spec
_N_ Models, 1 History.
<system> Spec.Mark the draft state, then bind the keywords.
## Status
Draft.
The key words MUST, MUST NOT, SHOULD, SHOULD NOT, and MAY in this
document are to be interpreted as described in RFC 2119 and RFC 8174
when, and only when, they appear in all capitals.
Draft while the system is unshipped.Name which document this is. Justify the weight by elimination.
Say why not the heavier doc, and why not the lighter one. This is where you defend the cost of the page.
## Document Type
This is a design doc. It defines the product contract for context-reel.
context-reel is not safety-critical or contractual enough for an SRS.
It is not a single decision, so it is not an ADR. The ambiguity is
product shape, vocabulary, interaction model, and trust boundary.
The landscape and why now. Name the center of gravity.
## Context
context-reel is a chat workspace where multiple frontier models
share one history.
The chat is the product center. The editor, config roster, document
rail, and shortcut rail support the same shared history.
Define every load-bearing term as a controlled set. One concept, one name.
This is the highest-leverage section. A blurred term becomes a blurred requirement. Define the words a reviewer could otherwise conflate, like provider versus model versus selected model.
## Vocabulary
**Provider** is the company or service that offers models, such as
OpenAI, Anthropic, Google, or xAI.
**Model** is one model offered by a provider, such as GPT 5.5.
**Configured model** is a saved roster entry naming a provider, one
model, a display name, and the key environment variable.
**Selected model** is the configured model selected for the next
submitted message.
Bulleted. Each goal is one measurable capability.
## Goals
- One shared history contains turns from multiple frontier models.
- The selected model answers the next message.
- Every model receives the same history as context when it answers.
- Provider API keys stay on the server.
- One concept has one name in the UI, code, tests, and documentation.
The section everyone skips. It is your scope fence.
A non-goal is something that could reasonably be in scope and is deliberately left out. It is not a negated requirement. "Shall not crash" is a requirement, not a non-goal.
## Non-Goals
- context-reel does not define agents.
- context-reel does not define a lead model.
- context-reel does not define swarm orchestration.
- context-reel does not treat README prose as the specification.
The craft. Group by surface. One requirement, one capability.
Four properties decide a requirement: necessary, unambiguous, singular, verifiable. Verifiable is the controlling one. If a test cannot mark it pass or fail, it is not a requirement.
Use a sub-heading per area, then bullet the requirements under it. context-reel uses: Application, Chat, Models, Editor, Shortcuts, Streaming, Secrets, Markdown Rendering, Persistence, Documentation, Tests.
- context-reel MUST send the full history with each chat request.
- If no model is selected, then context-reel MUST prevent submission.
- When the user submits a message, context-reel MUST append the user
message to the history immediately.
- While a response is streaming, context-reel MUST provide a stop control.
The strongest move in this spec: turn Step 5 into requirements that fail on drift. Name the one true term, ban the synonyms, and make a test fail when the banned word appears.
- context-reel MUST use the term "selected model" for the configured
model selected by the user.
- context-reel MUST NOT use agent, lead, active, primary, owner,
captain, orchestrator, or target as synonyms for selected model.
- context-reel tests MUST fail if code, UI, or documentation
introduces agent or lead-model vocabulary.
Pull every secret rule into one named block so the boundary is auditable in one place.
### Secrets
- context-reel MUST read provider API key values only on the server.
- context-reel MUST NOT send provider API key values to the browser.
- context-reel MUST NOT write provider API key values to IndexedDB,
localStorage, sessionStorage, or history.
Prose. Overview first, then the parts that touch the trade-offs.
The design restates the requirements as one coherent picture. It adds no new rules. It names the boundaries the requirements imply.
## Proposed Design
context-reel keeps three top-level work areas mounted: editor, chat,
and config. View changes hide and show areas without destroying state.
Chat is the center. Editor, config, document rail, and shortcut rail
are downstream support surfaces.
Markdown rendering is a trust boundary. Output must be sanitized or
escaped before any Svelte {@html} injection.
The concerns a feature-by-feature read misses.
## Cross-Cutting Concerns
### Security
Provider API key values are secrets. They stay server-side.
Model output is untrusted. It must not become executable DOM.
### Privacy
The history is local user data. Transmit it only as part of an
explicit chat request.
### Observability
Streaming failures must be visible. Silent failure is not acceptable.
### Accessibility
Roster controls must have stable accessible names.
Given, When, Then. One block per feature. Binary outcomes.
Each block proves one requirement. The outcome is observable, never an implementation detail.
Given the roster contains multiple configured models
When the user selects one model
Then context-reel marks that model as the selected model
And context-reel does not label it agent, lead, active, or owner
Given a configured model uses OPENAI_API_KEY
When context-reel stores the roster in the browser
Then the browser storage contains OPENAI_API_KEY
And the browser storage does not contain the API key value
Given model output contains raw HTML with script behavior
When context-reel renders the message
Then the raw HTML does not execute
And the rendered DOM contains no executable script from that output
Weak words feel like requirements and verify like wishes. Replace each with a measurable threshold.
| â Vague | â Verifiable |
|---|---|
| The system should be fast. | The system MUST return p95 under 200 ms. |
| The UI should be user-friendly. | A user MUST complete checkout in 3 clicks. |
| Support many concurrent users. | Support 1,000 users at p95 under 500 ms. |
| Find by name, date, etc. | List every field. Delete "etc." |
The recurring ways specs fail. Each is cheap to spot.
The tells:
Check every gate before you stop. Each is pass or fail.
Pick the lightest document. Write one only when it earns its cost. Build it in order: title, status, type, context, vocabulary, goals, non-goals, requirements, design, concerns, acceptance. Name the idiom: RFC 2119, EARS, Given-When-Then. Ban the weak word. Verifiable or it is not a requirement. Then stop.