Skip to content

Repository files navigation

Specification IDE

The product is not a language. The product is not an IDE. The product is the feedback loop: "does the machine understand what I want?"

As AI agents get better at writing code, the bottleneck shifts from implementation to intent. The developer who can precisely describe what they want gets correct software. The one who can't gets plausible-looking bugs.

The Specification IDE tightens that loop from hours to seconds.

Today:    Write prompt → Get code → Read code → Find misunderstanding → Re-prompt
            (minutes)    (seconds)   (minutes)      (frustrating)        (repeat)

Spec IDE: Write spec → Consistency check → Generate → Verify → Refine
           (seconds)      (instant)        (seconds)  (seconds) (seconds)

Table of Contents


The Core Idea

Every successful developer tool won by tightening a feedback loop:

Tool Loop it tightened
Compilers "Did I make a syntax error?"
REPLs "What does this evaluate to?"
Hot reload "What does this look like?"
TDD "Does this work?"
Type systems "Is this structurally sound?"
Spec IDE "Does the machine understand what I want?"

That last loop doesn't exist as a tool today. It's done manually by reading generated code. That's the opportunity.

How Engineers Actually Communicate Intent

At a whiteboard, skilled engineers use five modes simultaneously:

  1. Stories - "A user adds items, clicks buy, gets charged, sees a confirmation"
  2. Rules - "A user can never be charged twice for the same order"
  3. Processes - "An order goes from draft to confirmed to shipped to delivered"
  4. Boundaries - "The payment service handles charging; we assume it's up 99.9%"
  5. Trade-offs - "Speed matters more than perfect consistency for cart display"

No existing tool captures all five. TLA+ captures rules but is unreadable. Gherkin captures stories but can't express invariants. Natural language captures everything but is ambiguous.

The Specification IDE provides five facets - each natural for its mode of thought - all compiling to a single verifiable internal model.


The Spec Language

A .spec file is organized by feature. Each feature mixes five facet types as needed:

Full Example: checkout.spec

entities:
  User:
    id: UserId
    name: String
    logged_in: Boolean

  Cart:
    owner: User
    items: List<CartItem>
    displayed_total: Money

  Order:
    id: OrderId
    user: User
    items: List<OrderItem>
    total: Money
    status: OrderStatus
    payment: Payment?

  OrderStatus: enum(draft, confirmed, processing, shipped, delivered, cancelled, returned)

  Payment:
    id: PaymentId
    order: Order
    amount: Money
    status: PaymentStatus

  PaymentStatus: enum(pending, charged, failed, refunded)

feature "checkout":

  scenario "successful purchase":
    given:
      user.logged_in
      cart.has_items
      payment_method.valid

    when: user.clicks("buy")

    then:
      payment.charge(cart.total)
      order.create(items: cart.items, status: "confirmed")
      cart.clear()

    example:
      input:
        user: { id: "u1", name: "Alice" }
        cart: { items: [{ name: "Book", price: 12.99 }, { name: "Pen", price: 5.00 }] }
      output:
        payment: { amount: 17.99, status: "charged" }
        order: { total: 17.99, status: "confirmed" }
        cart: { items: [] }

  scenario "payment fails":
    given:
      user.logged_in
      cart.has_items

    when: user.clicks("buy")

    then:
      payment.charge(cart.total) -> fails
      cart.unchanged

  invariant "no double charge":
    for any order:
      count(order.payments) <= 1
    severity: critical
    on violation: "refund excess and alert ops"

  invariant "cart consistency":
    cart.displayed_total == cart.items_total
    severity: high

  flow "order lifecycle":
    states: draft, confirmed, processing, shipped, delivered, cancelled, returned

    draft -> confirmed
      when: payment.succeeds

    confirmed -> processing
      when: warehouse.accepts

    confirmed -> cancelled
      when: user.requests_cancellation
      allowed: "within 24 hours of confirmation"

    processing -> shipped
      when: warehouse.dispatches

    shipped -> delivered
      when: carrier.confirms_delivery

    shipped -> returned
      when: user.initiates_return
      allowed: "within 30 days of delivery"

    terminal: delivered, cancelled, returned

    on stuck in processing > "48 hours":
      "alert ops team"

  boundary "payment gateway":
    role: "external service"

    operations:
      charge(amount: Money, method: PaymentMethod) -> PaymentResult
      refund(payment_id: PaymentId) -> RefundResult

    guarantees:
      "charge is idempotent for same order and amount pair"
      "refund succeeds for any charged payment within 90 days"

    assumes:
      "available 99.9 percent of the time"
      "responds within 5 seconds"

    when unavailable:
      "queue charge for retry with exponential backoff"
      "show user payment processing state"

    when slow:
      "show progress indicator after 3 seconds"
      "timeout at 15 seconds"

  priorities "checkout experience":
    1. correctness: "never charge without recording order" [non-negotiable]
    2. durability: "never lose a confirmed order" [non-negotiable]
    3. availability: "checkout works if recommendation service is down" [strong]
    4. latency: "checkout completes under 3 seconds p95" [target]
    5. consistency: "cart display may lag by up to 5 seconds" [acceptable]

The Five Facets

Facet Purpose What it generates
Scenarios Concrete stories with example data Unit tests, integration tests, agent few-shot examples
Invariants Cross-cutting rules that must always hold Runtime assertions, monitoring rules, alert conditions
Flows State machine lifecycles State machine validators, stuck-state detectors, lifecycle diagrams
Boundaries Contracts with external/internal services Circuit breakers, retry policies, health checks, fallback code
Priorities Explicit trade-offs between competing concerns Performance budgets, SLO definitions, degradation logic

One source of truth. Everything derived. Change the spec, everything updates.

Why Each Facet Exists Separately

  • Scenarios alone cause combinatorial explosion for state machines (one per transition path)
  • Invariants are cross-cutting - they don't belong in any single scenario
  • Flows are the natural formalism for lifecycles that scenarios can't express compactly
  • Boundaries make integration contracts explicit - the #1 cause of production failures is mismatched assumptions between components
  • Priorities capture trade-offs that live nowhere in code but determine every architectural decision

Architecture

Feature Specs → Parser → AST → Unifier → BCG (Behavioral Contract Graph)
                                            |
                    +-----------+-----------+-----------+
                    |           |           |           |
              Consistency   Agent       Test       System
               Engine      Prompt    Generator      Map
                  |           |           |           |
             Warnings &   Generated   Auto        Flow
             Gap Reports    Code      Tests      Diagram
                              |
                          Verifier → Pass: Ship it
                              |
                        Clarification
                         Questions

The BCG - Behavioral Contract Graph

The BCG is the heart. All five facets compile into one directed graph:

Scenarios   →  Paths through the graph (with concrete data on edges)
Flows       →  Subgraphs (named state machines)
Invariants  →  Global annotations (properties every reachable node must satisfy)
Boundaries  →  Interface edges (assume/guarantee labels)
Priorities  →  Weights on annotations (verification strictness)

This is what enables cross-facet checking:

  • A scenario must trace a valid path through a flow
  • No scenario's outcome may violate an invariant
  • Flow transitions depending on external services must reference a boundary
  • Priority levels determine how strictly each invariant is verified

The Consistency Engine

Runs on the spec itself, instantly, before any code is generated. It's the type-checker for intent.

What it catches:

ERROR    Dead-end state "stuck_state" has no outgoing transitions
WARNING  State "orphan" is unreachable from initial state
WARNING  Scenario "refund flow" doesn't match any flow transition
INFO     Transition confirmed->shipped has no scenario coverage
INFO     2 of 6 transitions covered by scenarios (33%)

Every problem caught here would have been a bug in generated code.

Code Generation Pipeline

BCG → Serializer → Structured Prompt → LLM Provider → Generated Code → Verifier

The BCG serializer produces a deterministic, section-organized prompt:

  • ## ENTITIES - data model
  • ## FLOW - state machines with transitions
  • ## SCENARIOS - behavior with concrete examples
  • ## INVARIANTS - rules the code must maintain
  • ## BOUNDARIES - external service contracts
  • ## PRIORITIES - trade-off ordering
  • ## IMPLEMENTATION CONTEXT - target language, framework

Three LLM providers: Anthropic (Claude), OpenAI, Ollama (local). All via raw fetch() - no SDK dependencies.

Static verification checks the generated code against the BCG: balanced syntax, entity name presence, flow state presence, confidence scoring.


Running Locally

Prerequisites

Build

git clone <repo-url>
cd specification-ide
pnpm install
pnpm build

Run Tests

pnpm test          # all 108 tests across 4 packages

Launch the Extension

Option A: VS Code debugger (recommended)

  1. Open the project in VS Code
  2. Press F5 (or Run > Start Debugging)
  3. A new "Extension Development Host" window opens with the examples/ folder

Option B: Manual

# Build everything
pnpm build

# Then in VS Code:
# 1. Open Command Palette (Cmd+Shift+P)
# 2. "Developer: Install Extension from Location..."
# 3. Select packages/spec-vscode/

Configure Code Generation (optional)

In VS Code settings (Cmd+,), search for spec-ide:

Setting Default Description
spec-ide.codegen.provider anthropic anthropic, openai, or ollama
spec-ide.codegen.apiKey - API key (or set ANTHROPIC_API_KEY / OPENAI_API_KEY env var)
spec-ide.codegen.model (provider default) Model identifier
spec-ide.codegen.language TypeScript Target programming language
spec-ide.codegen.framework - e.g. Express, FastAPI, Django
spec-ide.codegen.ollamaUrl http://localhost:11434 Ollama server URL

UI/UX Walkthrough

What You See When You Open a .spec File

The extension activates on any .spec file. Opening checkout.spec:

1. Syntax Highlighting

Keywords (feature, flow, scenario, invariant, boundary, priorities), strings, numbers, entity names (PascalCase), transition arrows (->), priority levels ([non-negotiable]) - all colored distinctly.

2. Real-Time Diagnostics

As you type, the full pipeline runs (300ms debounce). Squiggly underlines appear:

  • Red (error): dead-end states, parse errors
  • Yellow (warning): unreachable states, orphan scenarios, unknown entity references
  • Blue (info): uncovered transitions, coverage statistics

Add a state stuck_state to a flow without any outgoing transition - a red underline appears instantly.

3. Smart Completions (Ctrl+Space)

Context-aware completions:

Context What you get
Top level (col 0) feature, entities with snippet templates
Inside a feature scenario, flow, invariant, boundary, priorities with full scaffolds
After severity: critical, high, medium, low
Inside [ non-negotiable, strong, target, acceptable
Anywhere Entity names (User, Cart, Order...) and state names (draft, confirmed...) from the BCG

4. Hover Information

  • Hover over User → User (entity) with all fields and their types
  • Hover over OrderStatus → OrderStatus (enum) with values listed
  • Hover over draft → draft (initial) - Flow: order lifecycle
  • Hover over delivered → delivered (terminal) - Flow: order lifecycle

5. Go-to-Definition (Cmd+Click / F12)

  • Cmd+Click on User anywhere → jumps to the entity declaration
  • Cmd+Click on draft → jumps to the flow definition
  • Works cross-file: entities in entities.spec, flows in checkout.spec - navigation works between them

6. Flow Graph Visualization

Click the Graph icon in the editor title bar (or run Spec: Show Flow Graph from command palette):

 [draft] ──> [confirmed] ──> [processing] ──> [shipped] ──> [delivered]
                  |                               |
                  v                               v
             [cancelled]                     [returned]
  • SVG rendered in a webview panel beside the editor
  • BFS layered layout
  • Initial states in green, terminal states in red/orange
  • Live-updates as you edit the spec

7. Code Generation

Click the Sparkle icon in the editor title bar (or Spec: Generate Code):

  1. Progress notification: "Generating code from specification..."
  2. BCG is serialized to a structured prompt and sent to your configured LLM
  3. Generated code opens in a new editor tab beside your spec
  4. Result notification: "Code generated (85% confidence, model: claude-sonnet-4-5-20250929)"

Multi-File Workflow

Split specs across files for larger systems:

project/
  entities.spec       <- shared entity declarations
  checkout.spec       <- checkout feature
  payments.spec       <- payment boundary and scenarios
  shipping.spec       <- shipping flows

All .spec files are discovered automatically via WorkspaceManager. The BCG is built from the unified merge of all files. Cross-file references resolve correctly - no false "unknown entity" warnings. Diagnostics are attributed to the correct source file.


Project Structure

specification-ide/
  packages/
    spec-lang/          @spec-ide/lang       Lexer, parser, AST definitions
    spec-bcg/           @spec-ide/bcg        BCG types, AST->BCG builder, expression utils
    spec-check/         @spec-ide/check      Consistency rules, pipeline, merge, workspace
    spec-codegen/       @spec-ide/codegen    Serializer, LLM providers, verification
    spec-vscode/        spec-ide             VS Code extension (syntax, diagnostics, completions,
                                             hover, go-to-def, flow graph, codegen command)
  examples/
    checkout.spec                            Reference spec for an e-commerce checkout
  docs/
    SPEC-IDE.md                              Master vision document
    LANGUAGE.md                              Spec language design
    ARCHITECTURE.md                          BCG, consistency engine, verification loop
    BUILD.md                                 Engineering blueprint, tech choices

Package Dependency Graph

spec-lang  (no deps - parser, AST)
    |
spec-bcg   (depends on spec-lang - graph builder)
    |
spec-check (depends on spec-lang, spec-bcg - consistency rules)
    |
spec-codegen (depends on spec-lang, spec-bcg - LLM codegen)
    |
spec-vscode  (depends on spec-check, spec-codegen - IDE integration)

Tech Stack

  • Language: TypeScript, "type": "module" throughout
  • Build: pnpm workspaces + Turborepo
  • Parser: Chevrotain (TypeScript-native, excellent error recovery)
  • Tests: Vitest
  • Extension bundler: esbuild (CJS output, vscode external)
  • LLM integration: Raw fetch() with AbortController timeouts - no SDK dependencies

Build Status

Package Tests Status
@spec-ide/lang 18 Lexer, parser, AST
@spec-ide/bcg 15 Graph types, builder, expression utils, scenario matching
@spec-ide/check 33 5 rules, pipeline, AST merge, workspace pipeline
@spec-ide/codegen 42 Serializer, 3 providers (timeout + validation), verify, generate
spec-ide (vscode) - Extension bundle: 447KB
Total 108 All passing

Consistency Rules

Rule Severity What it catches
flow-completeness error Non-terminal states with no outgoing transitions
flow-reachability warning States unreachable from initial state
reference-integrity warning References to undeclared entities
scenario-flow-alignment warning/info Orphan scenarios, uncovered transitions
coverage-report info Node and edge coverage statistics

Design Documents

Document Contents
SPEC-IDE.md Master vision - core thesis, three modes of work, what the IDE generates
LANGUAGE.md The specification language - five facets, three formalization levels, design rationale
ARCHITECTURE.md BCG internals, consistency engine, verification loop, IDE layout
BUILD.md Engineering blueprint - tech choices, repo structure, week-by-week plan

The Honest Part

From the design docs:

Claiming "never write code again" is dishonest. Performance optimizations, platform workarounds, library-specific integration - these require human judgment at the code level. The honest pitch: write code only for the parts that require human judgment.

The framework doesn't pretend specs replace code. The spec owns behavioral truth. The code owns implementation truth. When they conflict, the IDE flags it.


License

TBD

About

Tightens the loop 'does the machine understand what I want?'. A spec language with a consistency checker, codegen with verification, a VS Code extension and a web playground.

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages