Atelier is a local-first Agentic Development Environment control plane for Pi. The CLI is atlr.
Atelier owns reviewed-plan execution, task reconciliation, authorization, durable evidence,
validation closure, Working State, and code-provider orchestration. Editors, Jujutsu/Git, Beads,
codesearch, Octocode, and validation commands retain their native responsibilities.
This repository uses the dstack documentation-first, Beads-backed development workflow.
Install the workflow skills:
npx --yes [email protected] add RobertDeRose/dstackThe setup workflow validates the scaffold and initializes Beads when bd is available. Start a session with:
bd prime
bd ready --type epic --label workflow:feature --json --limit 0
bd ready --jsonUse the installed lifecycle skills:
/plan-features
/start-feature <slug>
/implement-feature <slug>
/implement-task <task-selector>
/close-feature <slug>
/audit-project
Install the locked developer tools, then validate or serve the documentation:
mise install --locked
mise run docs:check
mise run docs:serveRun the complete quality contract with mise run check; apply deterministic fixes with mise run fix.
Changelog-visible feat, fix, perf, and refactor commits require a semantic subsystem scope. Generated projects
initially accept any syntactically valid scope because project boundaries are not known to the template.
When the stable subsystems are known:
- Add a
scopes = ["..."]allowlist tocog.toml. - Replace this guidance with a short table describing when each scope applies.
- Update the Commit messages section in
AGENTS.mdso agents use the same taxonomy.
Prefer stable ownership boundaries over feature numbers, ticket identifiers, action names, or incidental files. Run
cog check after changing the allowlist.
The project was generated from RobertDeRose/dstack with Copier. Commit the scaffold before applying future template
updates with /update-project. Updates preserve the recorded stable or unstable channel and always record the exact
template commit used.
Current release: 0.14.0-alpha.46. Alpha.46 makes agent-turn progress surface selection lifecycle-explicit, so before_agent_start always uses Pi's native working indicator even while Pi still reports idle, and makes guided pause evidence chronological so later paused footer refreshes cannot create false latency failures.
Atelier establishes an immutable session workspace from the canonical startup directory. New development workspaces initialize with securityMode: "core-only": workspace permission prompts and the OS shell sandbox are disabled so the foundational code-intelligence, Beads, and Jujutsu/Git workflow can be exercised without safety-layer friction. Core still records workflow state, observations, retrieval, validation, evidence, and task constraints.
This mode is intentionally unsafe. Do not use it with untrusted repositories or unattended privileged work. Set securityMode: "enforced" in .atelier/config.json to restore workspace-policy decisions and the configured Seatbelt/Bubblewrap backend.
Pi /trust remains independent and controls only project-local Pi resources.
This remains an interactive alpha.
Atelier currently provides:
- durable
ManualEditplan review with exact plan hashes and structural diffs; - preview-before-mutation task-provider reconciliation;
- exact approval bound to source revisions, every approved workspace repository, retrieval provenance, provider identity, reconciliation digest, and reviewed task constraints; later retrieval drift is recorded but cannot revoke authority while source and task bindings remain exact;
- atomic task claim and execution activation with reviewed task constraints;
- restart-safe execution, invalidation, recovery-checkpoint, mutation, validation, and retrieval evidence;
- an authoritative task-closure predicate requiring current required validations, an exact final-diff review, a local commit/change, and the configured clean-repository state;
- Jujutsu-first and Git-compatible repository providers, including workspace-wide scoped commits, combined diff review, validation freshness, metadata finalization, and closure across changed repositories;
- Beads, memory, and disabled task providers;
- codesearch, Octocode, mock, and disabled code providers;
- CLI and Pi integration, including a responsive two-line footer with model/context, workflow mode, human-readable task titles, code-index health, and provider-native Jujutsu/Git cleanliness;
- expandable TUI-only Markdown report cards for status, workflow context, code intelligence, changed paths, validation, evidence, and ready-work inspection without adding those reports to model context;
- approval-only plan activation that leaves Pi idle until the user explicitly requests implementation;
- a request-scoped interactive observation pipeline with asynchronous Git/Jujutsu status, bounded provider caches, immediate phase feedback, and
/performancelatency diagnostics; and - durable bounded UI evidence for footer renders, report cards, phase transitions, model Bash streaming/completion, direct-shell denials, and final agent settlement.
The fuzzy file palette, project tree, Yazi/skim adapters, and richer Helix-native IDE surfaces remain future work. They are intentionally gated on the guarded workflow rather than being treated as current features.
The supported development toolchain is pinned by the repository:
- Node.js 24.18.0;
- Aube and the tools declared through mise;
- TypeScript 7 through the lockfile/toolchain;
- Jujutsu, Beads, and codesearch for their corresponding live integrations;
- Bun and Pi for the interactive extension path.
Git can be used as the repository compatibility provider. Optional providers are not required for the deterministic fixture suite.
mise install
mise run init
npm run build
node ./bin/atlr.mjs --version
npm run checkbin/atlr.mjs launches built JavaScript from dist/. Development-only source execution remains
available as npm run atlr:dev -- ... and npm run launch:dev.
The package publishes built JavaScript and declarations through:
dist/packages/core/src/index.js
dist/packages/core/src/index.d.ts
dist/apps/pi-extension/src/index.js
Atelier establishes the canonical startup directory as the immutable filesystem workspace for the current session. No Atelier trust command, trust database, or persistent workspace approval is required.
cd /path/to/repository
atlr launchThe first launch creates the small .atelier/ project configuration automatically. Use atlr doctor when you want to inspect setup without changing project files; use atlr doctor --json for machine-readable diagnostics.
Pi /trust remains independent. It controls loading project-local Pi resources; it does not grant Atelier filesystem authority. Atelier evaluates concrete filesystem effects against workspace containment, likely-secret paths, privilege escalation, and VCS/checkpoint recoverability.
atlr doctor is observational: it does not open the ledger, start providers, or create project state. Its human-readable report ends with an Operational or Degraded status and any detected issues.
Shareable project data lives under .atelier/:
.atelier/config.json project configuration
.atelier/PLAN.md reviewed plan
.atelier/validation.json validation and closure policy
.atelier/workspace.json optional multi-repository workspace
Runtime state is user-owned and outside the repository. By default it is stored at:
${XDG_STATE_HOME:-~/.local/state}/atelier/repositories/<root-hash>/atelier.db
${XDG_STATE_HOME:-~/.local/state}/atelier/repositories/<root-hash>/code/codesearch-index-state.json
ATLR_STATE_HOME or user configuration can relocate runtime state. Atelier reads the user-wide
~/.config/atelier/config.json first, then applies repository .atelier/config.json as the override
layer for declarative settings. ATLR_USER_CONFIG selects a different global file. Repository
configuration cannot redirect the ledger or caches, and it cannot select editor, Beads, Jujutsu,
codesearch, or Octocode executables. Those commands come only from user configuration, controlled
defaults, or ATLR_EDITOR. A user-specified external octocodeConfigPath also remains authoritative;
otherwise the repository may use its project-local provider config. Legacy .atelier/*.db and
codesearch selection-state files are ignored and migrated; mutable provider state never participates
in Git or Jujutsu working-copy snapshots.
.atelier/config.json, PLAN.md, validation.json, and workspace.json remain intentionally trackable.
Every approvable task includes a structured execution contract in its atlr:task marker. For example:
<!-- atlr:task
{
"id": "ATLR-001",
"priority": 1,
"type": "task",
"execution": {
"writePaths": [
"src/example.ts",
"tests/example.test.ts"
],
"allowDependencyChanges": false,
"validations": [
"focused"
],
"allowFullSuite": false,
"allowLocalChange": true
}
}
-->Free-form Scope and Out-of-scope sections remain human context; the execution object is the reviewed task-constraint source. Missing, unknown, inconsistent, absolute, out-of-root, or non-source entries fail preparation. See
docs/src/features/exact-plan-execution/plan-format.md for the complete contract.
A normal CLI workflow is:
# `atlr launch` initializes a project automatically. For CLI-only work:
atlr init --beads
atlr plan "describe the objective"
atlr review
atlr plan prepare --json
atlr approve --approval APPROVAL_ID --digest RECONCILIATION_DIGEST --yes
atlr statusPreparation records and approval rechecks:
- the exact reviewed plan hash;
- task-provider name and version;
- the complete reconciliation digest and conflicts;
- the primary source snapshot;
- revision bindings for every approved workspace repository;
- retrieval provider/index bindings used by the plan;
- the reviewed task constraints and their digest.
Rejection performs no provider mutation. Approval reconciles the provider, verifies convergence, claims one approved-plan ready task, and atomically installs the execution grant plus its reviewed task constraints. A later approved task still requires explicit activation:
atlr execute TASK_ID --yesCancellation revokes the active execution without silently closing the task:
atlr cancel --reason "why execution stopped"In Pi, /atelier-stop ends only the current turn, /atelier-pause keeps the execution/task active while
denying agent mutation, /atelier-resume re-enables it without starting a turn, and /cancel atomically
revokes execution without waiting for idle. Denial, Escape, or normal settlement never schedules a forced
follow-up. The completion predicate is enforced when closure is requested, not by preventing the user
from regaining control.
Plan approval constrains the active task; it does not create a second filesystem permission system. The reviewed execution contract limits agent work to exact source paths, explicitly named validations, optional dependency manifests, task closure, and an optional path-scoped local commit/change. Workflow mode and task identity remain hard constraints, while the workspace policy independently decides whether each concrete filesystem effect is contained and exactly recoverable.
The workspace policy evaluates four things:
- resolved path containment inside the immutable session workspace;
- likely-secret and privilege-escalation consequences;
- VCS path state through Git or Jujutsu;
- exact recovery through VCS state or a verified Atelier checkpoint.
Ordinary non-secret reads, new files, clean tracked mutations/deletions, and content-preserving untracked mutations proceed without approval. Dirty tracked destruction and recoverable untracked/ignored destruction receive an automatic checkpoint. Outside-workspace effects, likely-secret access, privilege escalation, indeterminate destructive path sets, and any operation Atelier cannot restore exactly ask once for the concrete consequence.
Git checkpoints preserve the exact index, staged/unstaged and partially staged contents, modes, renames, symlinks, ignored files, and affected untracked files without changing branch history or staging user work. Jujutsu checkpoints capture and verify the native operation-log boundary. Checkpoints are associated with the triggering Pi session and tool call and expose an explicit restore command.
Pi's model Bash tool and direct user_bash execution share the same pre-execution evaluator. A command
inherits repository-read authorization only when both the hardened classifier and concrete-effect parser
agree that every effect is a routine read. Seatbelt on macOS or Bubblewrap on Linux is used when available.
When neither backend is available, every exact command requires a one-operation approval that explicitly
states it will run without OS-level confinement. That approval is consumed by one invocation only. Sandbox
confinement alone never turns an indeterminate destructive operation into a recoverable one.
Existing targets and nearest existing ancestors are resolved securely, so lexical traversal, nested
symlinks, broken symlinks, and nonexistent descendants cannot escape the workspace boundary.
.atelier/validation.json declares argument-array commands and the closure policy. A minimal manifest:
{
"closurePolicy": {
"requireValidation": true,
"requireFinalDiffReview": true,
"requireLocalChange": true,
"requireCleanSource": true,
"requireCleanRepository": true
},
"validations": {
"check": {
"command": ["npm", "run", "check"],
"category": "full",
"required": true
}
}
}When requireValidation is true, configuration and task closure require at least one applicable
validation with required: true. Readiness distinguishes a missing focused selection, a selection that
matched no required check, and a manifest with no required validation. The removed approval field is
rejected rather than silently ignored. Validation output is bounded and redacted, execution is
abort-aware, and evidence includes repository and environment fingerprints. Repository, command,
toolchain, platform, architecture, PATH, or lockfile drift makes prior evidence stale.
Pi exposes atlr_validate as the model-facing typed validation tool. It plans or runs configured declared
validations without routing them through generic Bash. Failed declared checks fail the tool operation; an
explicitly interrupted check returns a structured interrupted result so user cancellation is not recast as
a validation failure. Durable validation evidence is retained in both cases. A reviewed constraint is not an instruction: a user request not
to validate remains binding.
A typical completion sequence is:
atlr repo commit --message "feat: implement approved task"
atlr validate plan
atlr validate focused
# or: atlr validate run check
atlr repo review-diff
atlr task close TASK_ID --reason "implemented and verified"repo review-diff prints the exact task diff, hashes it, then records review only if the diff is still
unchanged. Task closure is blocked unless all configured requirements are current. Pi may display one
passive incomplete-task notice, but it does not enqueue another agent turn. The same predicate is used by
CLI, Pi, Working State, and task closure.
Jujutsu is preferred and Git is the compatibility provider. Repository observations are explicit: provider command failures throw a degraded/error state and are never converted into an empty path list or clean diff. Git diff evidence includes staged and unstaged changes, while baseline diff evidence also includes untracked source files.
atlr repo status --json
atlr changed --jsonStart Atelier with an explicit common workspace root when repositories are siblings or nested below a shared directory:
atlr --workspace ../workspace workspace status
atlr --workspace ../workspace launchDeclare repository identities in .atelier/workspace.json. Each repository receives an independent VCS snapshot. Task execution paths use repository-id::relative/path when they target a non-primary repository. Exact approval and resume bind every repository independently; secondary drift invalidates execution rather than reusing stale evidence.
A reviewed task can commit approved source changes in every changed repository, produce one repository-labelled final diff, track validation freshness across all source roots, and finalize workflow metadata per repository during closure. Commits are sequential: if a later repository fails, Atelier records the completed repository set and stops for explicit recovery rather than claiming an automatic cross-repository rollback.
No persistent trust or workspace approval is created. The explicit workspace applies only to the current process.
Atelier owns the provider-neutral contract, budgets, normalized evidence, provenance, freshness, and reuse. External providers own indexing and retrieval.
atlr code providers --json
atlr code status --provider codesearch
atlr code index --provider codesearch
atlr code search "where is execution approval implemented" --mode hybrid
atlr code symbols ExecutionWorkflowCoordinatorExplicit CLI and /code-symbols requests perform direct human-requested symbol lookup. The model-facing
symbol tool remains inventory-gated. Provider display signatures are normalized to canonical identifiers,
exact definitions rank before references, and resolved/unresolved state is repository-scope qualified.
Provider-first retrieval is advisory, not an authorization gate. Atelier presents provider tools first and records degraded/fallback decisions, but typed reads and explicitly approved shell inspection remain available when provider evidence is incomplete, wrong, excluded, or budget-limited.
Retrieval evidence is isolated by provider, workspace, repository scope, source revision, and provider index revision. Equivalent current evidence can be reused; revision drift invalidates it.
When Octocode uses a cloud embedding model, Core forwards only the documented provider credentials from
its own process environment: VOYAGE_API_KEY, JINA_API_KEY, GOOGLE_API_KEY, OPENAI_API_KEY,
OCTOHUB_API_KEY, and TOGETHER_API_KEY. For example, set VOYAGE_API_KEY before running
atlr code index --provider octocode. Repository configuration cannot select credential names or values;
unrelated environment secrets remain excluded from provider subprocesses.
Launch the supported interactive path with:
atlr launch
# or
mise run launchPi reserves /trust for Pi-owned project resources. Atelier does not register another trust command and does not use Pi trust as filesystem authority. The Atelier workspace policy is established from the startup directory or --workspace.
Structured inspection commands render as expandable report cards in Pi transcript scrollback. Each report
has a divider and a concise ➤ summary; Pi's expansion control switches it to ▼ and reveals the full
Markdown body. Sparse summaries use bold field/value lines, while dense task lists and code results retain
tables or grouped sections. Short lifecycle events continue to use transient notifications.
Core slash commands include:
/plan
/review
/approve
/execute
/atelier-stop
/atelier-pause
/atelier-resume
/cancel
/status
/workflow # ledger/status-only by default; add full or refresh for Working State
/state # compatibility alias for /workflow
/performance # bounded latency, subprocess, hashing, cache, and SQLite diagnostics
/code-status
/code-index
/code-search
/code-symbols
/changed
/validate
/evidence
/commit
/review-diff
/close
The registered model tools include:
atlr_code_status
atlr_code_search
atlr_code_symbols
atlr_state
atlr_validate
atlr_commit
atlr_task_close
Explicit user prohibitions such as "do not use Bash", "do not validate", "do not commit", or "do not
close" form a temporary turn policy that blocks those tools before an exceptional approval prompt. A
"stop after" instruction is also injected into the current-turn prompt, while /atelier-stop is the
enforceable active-turn control. A reviewed task constraint permits a bounded workflow operation; it never instructs the model to use it.
Each Pi session owns its own Atelier Core, repository root, review state, retrieval session, and index coordination. Shutdown awaits provider disposal before closing SQLite. Compaction receives a projection of durable Working State; conversation text remains non-authoritative.
Deterministic CI runs on the pinned Node version and executes:
npm ci
npm run check
npm pack --dry-runnpm run check performs release-metadata checks, type checking, all deterministic tests, a stable build,
and the smoke workflow. Environment-dependent live conformance is separate and manually dispatchable for
real Jujutsu, codesearch, Beads, and Pi/Bun installations. Fixture conformance is never represented as a
live provider result.
- The default development
core-onlymode intentionally bypasses workspace permission decisions and OS sandboxing; usesecurityMode: "enforced"before running untrusted or unattended work. - In enforced mode, static shell effect analysis is deliberately conservative. Interpreter, build-system, and compound commands ask when their persistent effects cannot be enumerated exactly.
- Seatbelt and Bubblewrap are platform facilities, not a complete VM boundary; network policy remains a separate concern and privileged execution always asks.
- Live provider conformance depends on locally available external tools and is separate from deterministic CI.
- Multi-repository commit, diff-review, validation-freshness, and closure transactions are delivered, but cross-repository commit rollback is manual after a recorded partial failure and coordinated editing UX remains limited.
- Every turn reconstructs authoritative Working State, but Pi's transcript and compaction mechanism still exist.
- The current palette, tree, navigator, and diff surfaces are functional command surfaces rather than a complete IDE chrome.