← Docs home

📋 Spec Kit

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.


📚 Reference Specs — READ THESE FIRST

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.

The snippets quoted throughout Section 3 are excerpts from these files. Read the full specs to see each step in its finished context.


1. 🧭 Pick the Lightest Document

A spec is a family of documents, not one thing. Pick by the ambiguity you need to kill.

1.1 The Decision Matrix
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
1.2 Do This
1.3 Do Not Do This

2. ⚖ïļ The Laws You Write Under

Three idioms make a requirement testable. Name them once near the top, then obey them everywhere.

2.1 RFC 2119 Keywords

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.
2.2 EARS: One Shape Per Requirement
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>.
2.3 Given, When, Then

3. ðŸĶī The Build, Step by Step

Write the sections in this order, top to bottom. Each step names the section, the rule, and a snippet from the context-reel.spec.md reference.

The section order to produce:

  1. Title and thesis
  2. Status
  3. Document Type
  4. Context
  5. Vocabulary
  6. Goals
  7. Non-Goals
  8. Product Requirements
  9. Proposed Design
  10. Cross-Cutting Concerns
  11. Acceptance Criteria

Step 1 — Title and Thesis

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.

Step 2 — Status

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.

Step 3 — Document Type

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.

Step 4 — Context

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.

Step 5 — Vocabulary

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.

Step 6 — Goals

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.

Step 7 — Non-Goals

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.

Step 8 — Product Requirements

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.

8.1 Group by Surface

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.

8.2 One Capability Each
8.3 Pick the EARS Shape
- 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.
8.4 Enforce the Vocabulary

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.
8.5 Make the Trust Boundary a Group

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.
8.6 Do Not Do This

Step 9 — Proposed Design

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.

Step 10 — Cross-Cutting Concerns

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.

Step 11 — Acceptance Criteria

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

4. ðŸšŦ Ban Weak Words

Weak words feel like requirements and verify like wishes. Replace each with a measurable threshold.

4.1 The Rewrite
❌ 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."
4.2 The Banned List

5. ðŸŠĪ Anti-Patterns and Tells

The recurring ways specs fail. Each is cheap to spot.

The tells:


6. ✅ Done When

Check every gate before you stop. Each is pass or fail.


🏁 Closing

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.