Vibe — Specification

Actors

Actor Kind Evidence

Developer

Human, primary

vibe/cli/textual_ui/app.py:322

Scripter / CI

Human, primary

vibe/core/programmatic.py:27

ACP Client (editor/IDE)

System, primary

vibe/acp/acp_agent_loop.py:267

LLM Provider

System, supporting

vibe/core/llm/backend/factory.py:7

Subagent (explore)

System, internal

vibe/core/agents/models.py:152

MCP Server

System, supporting

vibe/core/tools/mcp/registry.py:21

Vibe Code / Nuage

System, supporting

vibe/core/nuage/client.py:22

uc overview
Note

This catalog — UC-1..UC-7 and SUC-1..SUC-6 — is recovered from code. Whether it is the intended complete set of user goals, and which use cases are core versus experimental, could not be confirmed from code and is deferred to the Product Owner (see OPEN_QUESTIONS.adoc).

Persona Use Cases (Cockburn, Fully Dressed)

UC-1: Run an interactive coding session

Primary Actor

Developer

Trigger

Developer runs vibe/ (optionally with a positional prompt) in a trusted directory [vibe/cli/entrypoint.py:35-40].

Stakeholders & Interests
  • Developer — wants the task done with control over each tool action.

  • LLM Provider — receives the conversation and returns tool calls.

Preconditions
Main Success Scenario
  1. Developer submits a message.

  2. System appends the message and runs the middleware pipeline [vibe/core/agent_loop.py:855-937].

  3. System sends the conversation to the LLM.

  4. System receives an assistant message; if it contains tool calls, the System resolves permissions and runs the tools concurrently [vibe/core/agent_loop.py:1217-1259].

  5. Steps 2–4 repeat until the assistant emits no tool call.

  6. System displays the final assistant message.

Extensions
  • 4a. A tool’s permission is ASK: System prompts; on rejection it records the rejection and feeds it back to the LLM [vibe/core/agent_loop.py:1098-1116].

  • 2a. The turn or price limit is reached: middleware stops the loop [vibe/core/middleware.py:49-78].

  • 2b. Context tokens cross the model threshold: System auto-compacts (UC extension, see arc42 Chapter 6).

  • *. Developer presses Escape: in-flight tools are cancelled and the turn ends cleanly [vibe/core/agent_loop.py:1244-1259].

Postconditions
Business Rules

BR-1, BR-2, BR-3, BR-4 (see Cross-cutting Business Rules).

UC-2: Run Vibe programmatically

Primary Actor

Scripter / CI

Trigger

vibe/ -p "<prompt>" [README.md:254-262].

Preconditions

An API key is configured.

Main Success Scenario
  1. System runs headless with the auto-approve agent [vibe/cli/cli.py:235-250].

  2. System runs the agent loop, enforcing --max-turns and --max-price.

  3. System emits the result through the selected output formatter — text, json or streaming-json [vibe/core/output_formatters.py:46-119].

  4. System exits.

Extensions
  • 2a. session_cost exceeds --max-price: PriceLimitMiddleware stops the run [vibe/core/middleware.py:65-78].

  • 2b. --max-turns reached: TurnLimitMiddleware stops the run.

  • 1a. --enabled-tools is set: only the listed tools are available [README.md:270].

Postconditions

The result is on stdout in the chosen format; exit code reflects success or a limit interruption.

Business Rules

BR-3, BR-5.

UC-3: Resume a past session

Primary Actor

Developer

Trigger

vibe/ --continue or vibe/ --resume [ID] [vibe/cli/cli.py:128-190].

Preconditions

session_logging.enabled is true; at least one saved session exists.

Main Success Scenario
  1. --continue resolves the latest session for the current TTY/working directory; --resume ID resolves a specific session; --resume with no ID opens a picker.

  2. System replays the non-system messages into the agent loop and reattaches the session and parent ids [vibe/cli/cli.py:180-190].

  3. The interactive session continues from the restored state.

Extensions
  • 0a. session_logging.enabled is false: System reports the feature is unavailable and exits [vibe/cli/cli.py:134-139].

Postconditions

The session continues; new messages append to the same (or a forked) session folder.

Business Rules

BR-2.

UC-4: Plan before acting

Primary Actor

Developer

Trigger

Developer selects the plan agent (--agent plan or Shift+Tab) [README.md:113-138].

Preconditions

None beyond UC-1.

Main Success Scenario
  1. System runs the read-only plan agent; only safe tools auto-approve [vibe/core/agents/models.py:117].

  2. System writes a live markdown plan file [vibe/core/plan_session.py:11-42].

  3. Developer reviews (and may edit) the plan.

  4. Developer (or the agent via exit_plan_mode) confirms; System switches to accept-edits or default and executes [vibe/core/tools/builtins/exit_plan_mode.py:62-137].

Extensions
Postconditions

The agent is in an executing profile and proceeds per the agreed plan.

Business Rules

BR-4.

UC-5: Delegate work to a subagent

Primary Actor

Developer (indirectly, via the agent)

Trigger

The agent invokes the task tool [vibe/core/tools/builtins/task.py:107-150].

Main Success Scenario
  1. System spawns a nested agent loop running the named subagent (explore by default).

  2. The subagent works without user interaction and returns a response, the turns used and a completion flag.

  3. The parent conversation continues with the subagent’s result.

Postconditions

The subagent’s work is summarised back without overloading the parent context [README.md:142-156].

Business Rules

BR-4 (subagent profile bounds its tools).

UC-6: Teleport a session to the cloud

Primary Actor

Developer

Trigger

/teleport or vibe/ --teleport [vibe/cli/commands.py:115-120].

Preconditions

The plan is teleport-eligible; the working directory is a git repository [vibe/cli/plan_offer/decide_plan_offer.py:61-62].

Main Success Scenario
  1. System validates the git repository.

  2. System confirms the working commit is pushed [vibe/core/teleport/git.py:27-100].

  3. System starts a remote Vibe Code workflow and attaches a remote event source [vibe/core/teleport/teleport.py:46-150].

  4. The session continues in the cloud; events stream back to the UI.

Extensions
  • 1a. Not a git repo / commit not pushed: System emits a TeleportPushRequiredEvent and waits.

  • 0a. Not authenticated: System emits a TeleportAuthRequiredEvent.

Postconditions

The session runs as a remote workflow; the UI shows its events.

Business Rules

BR-6.

UC-7: Complete first-run setup

Primary Actor

Developer

Trigger

vibe/ is run with no API key configured, or vibe/ --setup [README.md:204-209].

Main Success Scenario
  1. System shows the Welcome screen, then the auth-method choice [vibe/setup/onboarding/screens/welcome.py:46-80].

  2. Developer chooses browser sign-in or manual API-key entry.

  3. System persists the key to ~/.vibe/.env (or the OS keyring) [vibe/setup/auth/api_key_persistence.py:38-64].

Postconditions

An API key is available for all future sessions.

Business Rules

BR-7.

System Use Cases (per interface)

SUC-1: The vibe/ command-line interface

Input & validation

Flags parsed by argparse: -v/--version, positional PROMPT, -p/--prompt, --max-turns (int), --max-price (float), --enabled-tools (repeatable; glob or re: regex), --output (text|json|streaming), --agent, --setup, --workdir (path, validated), --add-dir (repeatable path), --trust, --teleport (hidden), -c/--continue, --resume [ID]. --continue and --resume are mutually exclusive [vibe/cli/entrypoint.py:19-134].

Processing

main() validates --workdir, resolves trust, then delegates to run_cli [vibe/cli/entrypoint.py:166-211].

Output & status

Interactive mode opens the TUI; programmatic mode prints in the chosen format and exits with a status code reflecting success or a limit interruption.

Error responses

An untrusted directory prompts for trust; an invalid --workdir aborts with an error.

Environment

VIBE_HOME, LOG_LEVEL, LOG_MAX_BYTES, VIBE_* config overrides [vibe/cli/entrypoint.py epilog].

SUC-2: In-session slash commands

The CommandRegistry registers 23 commands [vibe/cli/commands.py:39-177]: help, config, model, thinking, reload, clear, copy, log, debug, compact, exit, status, teleport, proxy-setup, resume (/continue), rename, mcp (/connectors), voice, leanstall, unleanstall, rewind, loop, data-retention. Input is the text after /; unknown commands fall through to the autocompletion menu.

SUC-3: The vibe-acp ACP server

Input & validation

ACP requests over stdio; --setup triggers onboarding [vibe/acp/entrypoint.py:32-108].

Processing

VibeAcpAgentLoop manages ACP sessions; new_session and load_session create or restore them.

Output

ACP session updates; a reduced command set is advertised (help, compact, reload, log, proxy-setup, leanstall, unleanstall, data-retention) [vibe/acp/commands/registry.py:45-89].

Error responses

JSON-RPC 2.0 errors — UnauthenticatedError, InvalidRequestError, SessionNotFoundError, ContextTooLongError, ConfigurationError [vibe/acp/exceptions.py:1-141].

SUC-4: The built-in tool contract

Each tool subclasses BaseTool with a Pydantic args model, a result model and a BaseToolConfig declaring the permission tier; run() is an async generator [vibe/core/tools/base.py:122-152]. Tools raise ToolError (user-facing) or ToolPermissionError. The numeric limits:

Tool Default permission Limits / validation

bash

ASK

Timeout 300 s (overridable); stdout+stderr capped at 16 000 bytes; sudo always asks [vibe/core/tools/builtins/bash.py:220-257].

read_file

ALWAYS

Read cap 64 000 bytes; */.env sensitive [vibe/core/tools/builtins/read_file.py:58-67].

write_file

ASK

Write cap 64 000 bytes; */.env sensitive [vibe/core/tools/builtins/write_file.py:41-48].

search_replace

ASK

Content cap 100 000 bytes; fuzzy threshold 0.9 [vibe/core/tools/builtins/search_replace.py:70-77].

grep

ALWAYS

100 matches, 64 000 output bytes, 60 s timeout [vibe/core/tools/builtins/grep.py:36-83].

todo

ALWAYS

At most 100 items [vibe/core/tools/builtins/todo.py:54-56].

task

ASK

Subagent allowlist defaults to explore [vibe/core/tools/builtins/task.py:51-53].

ask_user_question

ALWAYS

1–4 questions, 2–4 options each [vibe/core/tools/builtins/ask_user_question.py:27-75].

webfetch

ASK

Timeout 30 s default / 120 s max; 120 000-byte content cap [vibe/core/tools/builtins/webfetch.py:62-77].

websearch

ASK

120 s timeout [vibe/core/tools/builtins/websearch.py:49-55].

skill, exit_plan_mode

ALWAYS

— [vibe/core/tools/builtins/skill.py:35-36, vibe/core/tools/builtins/exit_plan_mode.py:35-36].

SUC-5: The config.toml file format

Input & validation

TOML, parsed into a 60+-field VibeConfig Pydantic model; kebab-case keys via field aliases [vibe/core/config/_settings.py:495-644].

Processing

Project .vibe/config.toml directories (BFS, ≤4 levels) then ~/.vibe/config.toml are merged field-by-field with declared merge strategies [vibe/core/config/builder.py:24-122].

Error responses

Invalid TOML or schema violations surface as a config error before the session starts.

SUC-6: MCP server configuration

mcp_servers entries declare transport (http|streamable-http| stdio), url or command/args, headers, env, and timeouts — startup_timeout_sec (default 10.0) and tool_timeout_sec (default 60.0). Tools are exposed as {server}_{tool} [vibe/core/config/_settings.py:226-243, vibe/core/tools/mcp/registry.py:80-150].

Supplementary Specifications

Entity Model

entity model

State Machine — Agent Profile

sm profile

The state machine above shows only the four built-in profiles reachable through the interactive mode-switch cycle, in the order default → plan → accept-edits → auto-approve [vibe/core/agents/manager.py:166-181]; the further built-in profiles chat, explore and lean are selected explicitly and are not part of the cycle.

The plan and chat profiles are read-only; accept-edits auto-approves edits only; auto-approve approves everything [vibe/core/agents/models.py:110-199, vibe/core/middleware.py:174-216].

Activity — One Conversation Turn

act turn

Validation Rules (EARS)

Cross-cutting Business Rules

ID Rule

BR-1

A folder must be trusted before its project config is loaded [vibe/core/trusted_folders.py:75-122].

BR-2

Session continuation and resume require session_logging.enabled [vibe/cli/cli.py:134-139].

BR-3

Tool execution honours the ALWAYS / ASK / NEVER tier [vibe/core/tools/base.py:83-113].

BR-4

The active agent profile bounds tool autonomy; plan/chat are read-only [vibe/core/agents/models.py:110-199].

BR-5

Programmatic mode forces the auto-approve agent [vibe/cli/cli.py:47-48].

BR-6

Teleport requires a teleport-eligible plan and a git repository with the working commit pushed [vibe/core/teleport/git.py:27-100].

BR-7

Telemetry is sent only when enable_telemetry is true and an API key is present [vibe/core/telemetry/send.py:88-95].

Warning

Whether each business rule is a hard product requirement or an implementation choice is deferred to the Product Owner and Domain Expert (see OPEN_QUESTIONS.adoc).

Acceptance Criteria (Gherkin)

These criteria are derived from code behaviour. The canonical "done" definition per use case — and per-test traceability — is deferred to the Product Owner and Developer.

Feature: Tool permission enforcement (UC-1, BR-3)

  Scenario: An ASK-tier tool is rejected
    Given the active agent is "default"
    And the LLM requests a "bash" command
    When the developer rejects the approval prompt
    Then the command is not executed
    And a rejection result is sent back to the LLM
    And tool_calls_rejected is incremented

Feature: Programmatic price ceiling (UC-2, BR-5)

  Scenario: The price limit stops the run
    Given vibe runs with --prompt and --max-price 1.0
    When the estimated session_cost exceeds 1.0 dollars
    Then the conversation loop stops
    And the partial result is emitted in the chosen output format

Feature: Session resume requires logging (UC-3, BR-2)

  Scenario: Resume with logging disabled
    Given session_logging.enabled is false
    When the developer runs vibe --continue
    Then vibe reports that resume is unavailable
    And vibe exits without starting a session

Feature: Trust gate (UC-1, BR-1)

  Scenario: First entry into an untrusted project
    Given a directory contains a .vibe folder
    And the directory is not in trusted_folders.toml
    When the developer starts vibe there
    Then vibe asks the developer to trust the folder
    And project config is loaded only after the developer accepts