Arrangement Guide
An Arrangement is a YAML configuration file that tells SpecSoloist how to build your project: where to put generated files, which language and tools to use, and what setup commands to run before tests.
Think of it as the bridge between your specs (the what) and your build environment (the how).
Auto-Discovery
SpecSoloist automatically looks for arrangement.yaml in the current working directory. You can also specify one explicitly:
sp compile mymodule --arrangement path/to/arrangement.yaml
sp conduct --arrangement path/to/arrangement.yaml
sp test mymodule # also picks up arrangement.yaml automatically
Scaffolding
Generate an arrangement for your project with sp init:
# Generic Python arrangement
sp init myproject --arrangement python
# Named template (includes language-specific tools and examples)
sp init myproject --template python-fasthtml
sp init myproject --template nextjs-vitest
sp init myproject --template nextjs-playwright
# List all available templates
sp init --list-templates
Annotated Example
# arrangement.yaml
target_language: python
output_paths:
implementation: src/mypackage/{path}.py # {path} includes subdirs; {name} is the leaf
tests: tests/test_{name}.py
environment:
tools:
- uv
- pytest
setup_commands:
# These run in the build directory before each test run
- uv sync
dependencies:
# Package name → version specifier (PEP 440 for Python, semver for npm)
# Injected into soloist prompts so agents know exact API versions to target
python-fasthtml: ">=0.12,<0.13"
starlette: ">=0.27"
build_commands:
lint: uv run ruff check src/
test: uv run python -m pytest {file} -v
env_vars:
DATABASE_URL:
description: "PostgreSQL connection string"
required: true
example: "postgres://user:pass@localhost:5432/mydb"
OPENAI_API_KEY:
description: "OpenAI key for AI features"
required: false
example: "sk-..."
model: claude-haiku-4-5-20251001 # optional: pin LLM model for this project
Fields
| Field | Description |
|---|---|
target_language |
Target language (e.g. python, typescript) |
specs_path |
Directory where spec files are discovered (default: src/); used by sp list, sp status, sp graph, and sp conduct |
output_paths.implementation |
Path template for generated implementation files. {name} = leaf spec name, {path} = relative path including subdirectories |
output_paths.tests |
Path template for generated test files. Same {name} and {path} placeholders |
output_paths.overrides |
Per-spec path overrides (see below) |
environment.tools |
Tools the agent should use (informational, injected into prompts) |
environment.setup_commands |
Shell commands run before each test invocation |
environment.dependencies |
Package versions to pin (name → specifier); injected as a "Dependency Versions" table in prompts |
build_commands.lint |
Command to lint the generated code (optional) |
build_commands.test |
Command template to run tests ({file} is the test path) |
env_vars |
Declared environment variable names — values never stored (see below) |
static |
Verbatim files/directories to copy after compilation (see below) |
model |
LLM model to use; overridden by --model CLI flag or SPECSOLOIST_LLM_MODEL env var |
specs_path
Override where SpecSoloist looks for spec files (default: src/):
This affects sp list, sp status, sp graph, and sp conduct. Useful when your spec files live outside src/ — for example in a dedicated specs/ directory or at the project root.
You can also override per-command with --arrangement:
output_paths.overrides
Override the default output paths for specific specs. The default implementation and tests templates apply to all specs; overrides lets you set different paths for individual ones:
output_paths:
implementation: src/{name}.py
tests: tests/test_{name}.py
overrides:
auth:
implementation: src/myapp/auth.py
tests: tests/myapp/test_auth.py
db:
implementation: src/myapp/db.py
# tests path falls back to the default template
Each key under overrides is the spec name (without .spec.md). You can override implementation, tests, or both — omitting one falls back to the default template.
Tip: Using {path} in the default template (e.g., src/mypackage/{path}.py) often eliminates the need for overrides, since specs in subdirectories automatically map to the corresponding source subdirectory. Overrides are still useful when specs need to go to a completely different package or non-standard location.
setup_commands
Shell commands executed in the build directory before running tests. Use them to install dependencies or prepare the environment:
Commands run in order. If any command fails, the test run is aborted and the failure is reported.
dependencies
Pin the exact package versions your project uses. SpecSoloist injects these into every soloist prompt as a "Dependency Versions" table, so agents target the right API:
For Python use PEP 440 specifiers; for npm use semver ranges.
env_vars
Declare the environment variables your project expects. Values are never stored — only names, descriptions, and whether they're required:
env_vars:
DATABASE_URL:
description: "PostgreSQL connection string"
required: true
example: "postgres://user:pass@localhost:5432/mydb"
STRIPE_KEY:
description: "Stripe secret key"
required: false
example: "sk_live_..."
sp doctor --arrangement arrangement.yaml checks that all required: true variables are set in your environment and warns about any that are missing.
Soloist agents are also informed of these variables (names and descriptions only) so generated code can reference them correctly.
static
Declare verbatim files or directories to copy into the output after sp conduct finishes compiling specs. Use this for hand-crafted assets — docs, templates, scripts, help files — that are part of the project but not generated from specs:
static:
- source: help/
dest: src/myapp/help/
description: "Bundled help guides — hand-written"
- source: templates/
dest: src/myapp/templates/
- source: scripts/seed.py
dest: scripts/seed.py
- source: ARRANGEMENT.md
dest: ARRANGEMENT.md
overwrite: false # don't clobber user edits
source/dest: paths relative to the directory containingarrangement.yaml.overwrite: iffalse, skips copying when the destination already exists. Default:true.description: optional human-readable note (visible to agents and insp schema).
sp doctor warns when a source path does not exist on disk. Missing sources do not fail the build.
model
Pin the LLM model for this project:
Precedence (highest to lowest): --model CLI flag → arrangement model field → SPECSOLOIST_LLM_MODEL env var → provider default.
Example: A TypeScript Project
target_language: typescript
output_paths:
implementation: src/{name}.ts
tests: tests/{name}.test.ts
environment:
tools:
- node
- npm
setup_commands:
- npm install
dependencies:
"@ai-sdk/openai": "^0.0.9"
next: "^14"
build_commands:
lint: npx eslint src/
test: npx vitest run {file}
env_vars:
OPENAI_API_KEY:
description: "OpenAI API key for AI SDK"
required: true
example: "sk-..."
See src/specsoloist/arrangements/ for the bundled template files.