Vibe — Specification
Actors
| Actor | Kind | Evidence |
|---|---|---|
Developer |
Human, primary |
|
Scripter / CI |
Human, primary |
|
ACP Client (editor/IDE) |
System, primary |
|
LLM Provider |
System, supporting |
|
Subagent ( |
System, internal |
|
MCP Server |
System, supporting |
|
Vibe Code / Nuage |
System, supporting |
|
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 |
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
-
-
An API key is configured, or onbarding (UC-7) runs first.
-
The working directory is trusted, or the developer accepts the trust prompt [vibe/core/trusted_folders.py:75-122].
-
- Main Success Scenario
-
-
Developer submits a message.
-
System appends the message and runs the middleware pipeline [vibe/core/agent_loop.py:855-937].
-
System sends the conversation to the LLM.
-
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].
-
Steps 2–4 repeat until the assistant emits no tool call.
-
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
arc42Chapter 6). -
*. Developer presses Escape: in-flight tools are cancelled and the turn ends cleanly [vibe/core/agent_loop.py:1244-1259].
-
- Postconditions
-
-
Success: the conversation is persisted as
meta.json
messages.jsonland the TTY last-session pointer is updated [vibe/core/session/session_logger.py:36-97].
-
- 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
-
-
System runs headless with the
auto-approveagent [vibe/cli/cli.py:235-250]. -
System runs the agent loop, enforcing
--max-turnsand--max-price. -
System emits the result through the selected output formatter — text, json or streaming-json [vibe/core/output_formatters.py:46-119].
-
System exits.
-
- Extensions
-
-
2a.
session_costexceeds--max-price:PriceLimitMiddlewarestops the run [vibe/core/middleware.py:65-78]. -
2b.
--max-turnsreached:TurnLimitMiddlewarestops the run. -
1a.
--enabled-toolsis 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.enabledis true; at least one saved session exists. - Main Success Scenario
-
-
--continueresolves the latest session for the current TTY/working directory;--resume IDresolves a specific session;--resumewith no ID opens a picker. -
System replays the non-system messages into the agent loop and reattaches the session and parent ids [vibe/cli/cli.py:180-190].
-
The interactive session continues from the restored state.
-
- Extensions
-
-
0a.
session_logging.enabledis 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
planagent (--agent planorShift+Tab) [README.md:113-138]. - Preconditions
-
None beyond UC-1.
- Main Success Scenario
-
-
System runs the read-only
planagent; only safe tools auto-approve [vibe/core/agents/models.py:117]. -
System writes a live markdown plan file [vibe/core/plan_session.py:11-42].
-
Developer reviews (and may edit) the plan.
-
Developer (or the agent via
exit_plan_mode) confirms; System switches toaccept-editsordefaultand executes [vibe/core/tools/builtins/exit_plan_mode.py:62-137].
-
- Extensions
-
-
3a. Developer edits the plan file: the change is detected and the updated plan is injected into the conversation [vibe/core/agent_loop.py:939-956].
-
- 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
tasktool [vibe/core/tools/builtins/task.py:107-150]. - Main Success Scenario
-
-
System spawns a nested agent loop running the named subagent (
exploreby default). -
The subagent works without user interaction and returns a response, the turns used and a completion flag.
-
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
-
/teleportor 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
-
-
System validates the git repository.
-
System confirms the working commit is pushed [vibe/core/teleport/git.py:27-100].
-
System starts a remote Vibe Code workflow and attaches a remote event source [vibe/core/teleport/teleport.py:46-150].
-
The session continues in the cloud; events stream back to the UI.
-
- Extensions
-
-
1a. Not a git repo / commit not pushed: System emits a
TeleportPushRequiredEventand 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
-
-
System shows the Welcome screen, then the auth-method choice [vibe/setup/onboarding/screens/welcome.py:46-80].
-
Developer chooses browser sign-in or manual API-key entry.
-
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, positionalPROMPT,-p/--prompt,--max-turns(int),--max-price(float),--enabled-tools(repeatable; glob orre:regex),--output(text|json|streaming),--agent,--setup,--workdir(path, validated),--add-dir(repeatable path),--trust,--teleport(hidden),-c/--continue,--resume [ID].--continueand--resumeare mutually exclusive [vibe/cli/entrypoint.py:19-134]. - Processing
-
main()validates--workdir, resolves trust, then delegates torun_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
--workdiraborts 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;
--setuptriggers onboarding [vibe/acp/entrypoint.py:32-108]. - Processing
-
VibeAcpAgentLoopmanages ACP sessions;new_sessionandload_sessioncreate 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 |
|---|---|---|
|
ASK |
Timeout 300 s (overridable); stdout+stderr capped at
16 000 bytes; |
|
ALWAYS |
Read cap 64 000 bytes; |
|
ASK |
Write cap 64 000 bytes; |
|
ASK |
Content cap 100 000 bytes; fuzzy threshold 0.9 [vibe/core/tools/builtins/search_replace.py:70-77]. |
|
ALWAYS |
100 matches, 64 000 output bytes, 60 s timeout [vibe/core/tools/builtins/grep.py:36-83]. |
|
ALWAYS |
At most 100 items [vibe/core/tools/builtins/todo.py:54-56]. |
|
ASK |
Subagent allowlist defaults to |
|
ALWAYS |
1–4 questions, 2–4 options each [vibe/core/tools/builtins/ask_user_question.py:27-75]. |
|
ASK |
Timeout 30 s default / 120 s max; 120 000-byte content cap [vibe/core/tools/builtins/webfetch.py:62-77]. |
|
ASK |
120 s timeout [vibe/core/tools/builtins/websearch.py:49-55]. |
|
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
VibeConfigPydantic model; kebab-case keys via field aliases [vibe/core/config/_settings.py:495-644]. - Processing
-
Project
.vibe/config.tomldirectories (BFS, ≤4 levels) then~/.vibe/config.tomlare 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
Evidence: vibe/core/types.py:47-138 (AgentStats), vibe/core/types.py:219-329 (LLMMessage), vibe/core/agents/models.py:48-94 (AgentProfile), vibe/core/rewind/manager.py:16-49 (Checkpoint, FileSnapshot), vibe/core/session/session_loader.py:16-17 (Session), vibe/core/types.py:183-187 (ToolCall).
State Machine — Agent 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].
Validation Rules (EARS)
-
When a tool call is resolved, the System shall determine a permission tier of
ALWAYS,ASKorNEVERbefore executing it [vibe/core/tools/base.py:83-113]. -
While the active agent is
planorchat, the System shall reject mutating tools [vibe/core/middleware.py:174-216]. -
If
session_costexceeds--max-price, the System shall stop the conversation loop [vibe/core/middleware.py:65-78]. -
When a folder containing
.vibe/is first entered, the System shall require a trust decision before loading its project config [vibe/core/trusted_folders.py:75-122]. -
While
enable_telemetryis false or no API key is present, the System shall not send usage telemetry [vibe/core/telemetry/send.py:88-95].
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 |
BR-3 |
Tool execution honours the |
BR-4 |
The active agent profile bounds tool autonomy; |
BR-5 |
Programmatic mode forces the |
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 |
|
Warning
|
Whether each business rule is a hard product requirement or an
implementation choice is deferred to the Product Owner and Domain
Expert (see |
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
Feedback
Was this page helpful?
Glad to hear it! Please tell us how we can improve.
Sorry to hear that. Please tell us how we can improve.