Install and use dstack
Install the skills
npx skills@latest add RobertDeRose/dstack --all
Create a project
Run /setup-project in a new project directory. The skill asks one question at a time for the project’s purpose,
intended users, current scope, key boundaries, kind, and language profiles. Supported kinds are library, CLI, service,
application, infrastructure, documentation, and other. Select one or more recognized language profiles for a polyglot
root policy, or select exclusive other for only the universal baseline. Setup does not infer or fabricate missing
facts.
The skill resolves the stable channel by default or --unstable explicitly, verifies its installed template matches the
exact selected commit, renders the bundle, initializes Git and Beads when available, and validates the documentation.
Existing repositories are routed to /migrate-workflow; already managed repositories are routed to /update-project
with explicit consent.
Deliver features
/plan-features
/start-feature feature-name
/implement-feature feature-name
/implement-task task-selector
/close-feature feature-name
/audit-project
Use bd prime at session start. Use /implement-task <task-selector> for exactly one standalone executable issue. Use
/implement-feature for reviewed feature children; it continues until the feature implementation coordinator closes.
Beads owns live readiness and dependencies; docs/src/planned-features.md is only the human roadmap. When
/audit-project creates or updates corrective Beads records, it performs one ordinary non-force bd dolt push to the
configured native remote after validation. It does not create remotes or publish Git branches. The audit also requires
read-only Git history comparison; a bd prime stealth-mode message forbids Git mutations, not this required evidence.
If the execution context denies read-only Git inspection, the result must be reported as audit state: incomplete, not
as a completed audit with Git comparison silently excluded.
Repository-layout preflight
New and older projects remain single-package unless monorepo conversion is explicit. Before setup or update, supply the complete 1-32 package list and inspect the JSON layout preflight. It reports each preserved display name, slug, profile list, exact destination, occupied state, and collision paths. Rendering does not start when a package is invalid, overlaps another package, uses a root-owned path, differs only by case, traverses a symlink, or exceeds the bounded list. Existing package destinations are reported as collisions for later additive-render reconciliation; they are never permission to overwrite project files.
During update, a newly occupied <package-path>/mise.toml remains byte-identical. Its generated alternative is written
to migration/copier-adoption-candidates/<package-path>/mise.toml; tooling and documentation execution stop until the
operator compares the files, chooses the supported result, removes the candidate, and reruns /update-project. Ordinary
Copier-managed conflicts continue to use Copier’s configured inline or reject-file recovery.
Update
npx skills updaterefreshes installed skill definitions and scripts./update-projectapplies the newest revision from the recorded stable or unstable channel to a managed repository. Pass--stableor--unstableto change the preserved channel. Repeat--add-profileand--remove-profilefor explicit idempotent profile changes; their sets must be disjoint and the result nonempty./update-project --adopt --unstableexplicitly bootstraps dstack itself as an unstable template consumer; reconcile every generated candidate before validation or commit./migrate-workflowadopts an existing legacy Markdown workflow before normal updates.
Migration first asks for the exact base branch and either a fresh branch or an explicitly named branch/worktree to
resume. It never discovers or selects a resume candidate automatically. Git is mandatory. authorize-session records
the base SHA, branch, absolute worktree, and repository; after baseline, every command requires that record to be
tracked and byte-identical to HEAD and its single original introduction commit. Resume additionally requires the
user’s exact generated phrase and writes a separate audit record rather than mutating identity.
Migration captures the legacy hk hook/step inventory before adoption. Candidate reconciliation is additive: a removed
step or changed same-key definition blocks verification until restored or explicitly approved with both behaviors and a
reason. If the legacy config cannot be evaluated, migration stops for manual inventory confirmation rather than treating
the generated policy as equivalent. Durable manifests, reports, baselines, session-authority audits, and legacy-task
archives must be committed. Delivered-record candidates under migration/delivered-record-candidates/ are transient
local review material: never stage or commit them. Template-adoption candidates under
migration/template-adoption-candidates/ are separate adoption conflicts; reconcile each one and remove that directory
before the adoption checkpoint. Conditional adoption backups require an explicit retain/remove disposition. Repeated
unchanged scans do not churn committed migration evidence. For migration brief fields, the helper first extracts clear
current values from README/docs, AGENTS.md, manifests, and CI. It prompts only for missing, stale, or conflicting
values; it does not ask the user to restate documented context. Project purpose, users, scope, and boundaries remain
structured Copier context rendered into the reader overview and roadmap, and are also available to agents through
AGENTS.md. Language profiles are inferred from manifests and CI when possible. Project brief and semantic questions
still use an evidence-backed recommendation when a decision is genuinely unresolved, with a concise decision title, why
it is needed, current evidence/uncertainty, controlled behavior, a concrete example, choices/safe default, and the
consequence of deferral. After reconciliation, the rendered project provisioner must install the locked tools and Git
hooks before an ordinary checkpoint commit. Preserve the existing project hook policy and do not activate a generated
strict docs step while legacy task files remain; defer it until archival or make it migration-aware.
Documentation-step skips are not a migration path. Rerun the actual strict hook after each fix; a plan-only invocation
is not validation. If the existing policy cannot be sequenced or made migration-aware, stop with the named blocking step
instead of requesting approval to skip it. Whole-hook bypass is never allowed. Final verification requires durable
passed checkpoint evidence and treats migration markers as provenance only; they do not weaken normal documentation
validation after finalization. After final verification, migration reports completion and presents the configured
delivery action: merge, create a PR, or leave it complete without delivery.
Beads initialization and every import/verification command require nonsymlinked repository-local metadata, embedded
database location/name, project ID, repository root, and issue prefix. Uninitialized migrations use the primary checkout
on the dedicated migration branch. Native bd init commits collaborative controls, discovers Git origin, configures
Dolt synchronization, and establishes worktree sharing; dstack inspects that commit and amends it through project hooks.
Formula-only state remains uninitialized, and global/shared fallback fails. Subsequent commands use native repository
discovery while dstack checks authority identity before and after mutations. Push issue history with bd dolt push;
fresh clones recover it with bd bootstrap. Beads import dry-run is nonmutating and reconciles every manifest ID
against actual deterministic metadata, including completed phases. Apply handles at most two incomplete features by
default and uses bounded Dolt commits rather than one transaction per field or relationship. Repeat it until
remaining: 0; reduce to --batch-size 1 or select --feature <slug> for narrow recovery. It begins with an explicit
APPLY STARTED notice and reports existing, recovered, pending, conflicting, completed, remaining, and total features.
Per-feature phases persist, but retries trust them only after real-record reconciliation. A terminated fresh import
resumes its persisted identities; it is not a migration-session resume. Missing native workflow/formula labels stop
import. Preview repair-beads-labels, review every ID/label, then use --apply for additive-only restoration; extras
block before mutation, and an empty repair writes nothing. Status transitions use bd update --status for Beads 1.1
compatibility.
Adoption preserves recorded project identity first. Otherwise it derives the project name from the primary Git checkout
and the default branch from origin/HEAD. Supply explicit project name, slug, and default branch when evidence is
missing or incorrect. Run beads-authority --init, inspect the native Beads commit, apply the README formatting
exclusion, and amend it through ordinary hooks. Keep embedded Dolt storage, credentials, locks, sockets, and other
runtime state ignored. Once initialization is committed, native Beads shares the authority with linked worktrees.
prepare --apply regenerates implemented-feature navigation from standalone completed records.
draft-delivered-records --apply can create transient historical record candidates from legacy tasks, design paths, and
imported Beads identities, but candidates do not establish truth or belong in commit history. Inspect one feature at a
time, reconcile its actual implemented record, then supply a unique feature-naming summary, non-generated corroborating
path, related Git commit, and rationale to review-delivered-record. Before finalization, candidate files must exist
and match their recorded digests; if one disappears, redrafting clears its prior review metadata and semantic review
must be repeated. Finalization derives and verifies the exact live Beads graph, including absence of unexpected migrated
records, rejects artifact-path collisions, preflights all archive paths and reviewed candidates, stages and journals
every move, rolls back validation failure, seals archive digests/task identities, and persists state before deletion. A
leftover journal requires explicit recovery rather than guessed continuation. Only after finalize --apply succeeds,
verify --beads confirms migration_finalized: true, and the user explicitly authorizes cleanup may the agent delete
migration/delivered-record-candidates/; rerun verification afterward. Final verification compares the exact recursive
archive and feature inventory; manifest booleans alone cannot authorize evidence removal. It requires a native
Git-origin remote and emits one authoritative state: complete or mechanically complete with semantic reconciliation
pending.
Legacy managed projects keep their recorded profiles. When none are recorded, update preflight inspects only root
pyproject.toml, tsconfig.json/package.json, Cargo.toml, go.mod, mix.exs, and flake.nix, then presents
recognized profile suggestions for confirmation. It never applies suggestions automatically.
Enable generated GitHub Pages
Generated projects include a default-disabled Documentation workflow. From the generated project, install and authenticate external GitHub CLI with repository administration access, then run:
mise run docs:deployment:enable
The helper resolves the current GitHub repository, creates or updates Pages with build_type=workflow, sets
DOCS_DEPLOYMENT_ENABLED=true only after Pages configuration succeeds, and prints the Pages URL. Repeating the command
updates the existing configuration. A failure names the operation and never reports success.
For manual recovery, install gh from https://cli.github.com/ if needed, then run:
gh api --method PUT repos/OWNER/REPO/pages -f build_type=workflow
gh variable set DOCS_DEPLOYMENT_ENABLED --body true --repo OWNER/REPO
gh api repos/OWNER/REPO/pages --jq .html_url
Use POST instead of PUT when Pages does not exist. If the final URL query failed, verify state before retrying because the variable may already be set.
Failure boundaries
Setup refuses non-empty unmanaged destinations. For a new destination, direct helper invocation also rejects missing, blank, multiline, or NUL-containing brief values and names the required flags. This is an intentionally breaking pre-v1 setup contract; Purposeful project scaffold does not support updating or adopting older answer sets.
Update refuses missing or invalid Copier state and unreachable revisions. Stable never falls back to untagged code; unstable explicitly resolves the source default-branch HEAD. If Beads is unavailable, setup reports initialization and verification as outstanding rather than claiming a complete workflow installation.
Tool provisioning and recovery
Setup and conflict-free updates run the generated project provisioner after rendering. It executes, in order:
mise lock --yes --platform linux-x64,linux-arm64,macos-x64,macos-arm64
mise install --locked
mise x -- hk install --mise
The lock/install commands ignore user-global mise tools. For the Nix profile, the provisioner validates the three
supported nixfmt-rs lock entries and removes only its macOS x64 entry before locked installation; all other tools retain
the four-platform lock. hk hook installation runs only when Git exists and is reported separately. After native Beads
initialization, setup runs bd hooks install and verifies bd hooks list --json; conflict-free updates do the same
after successful tooling. These Beads hooks are separate from hk and are reported in beads_hooks. Setup with
--no-git-init can therefore finish lock/install work while reporting hooks as skipped-no-git; --skip-post-setup
performs no generated code and reports all tooling stages as skipped.
Profile source checks skip when no matching files exist. Package checks skip without their root manifest. A selected manifest with missing project-owned pytest, Vitest, or Credo fails with the named prerequisite; flake checks similarly require system Nix. Matching Nix inputs fail clearly on unsupported macOS x64.
A missing mise executable, failed lock resolution/download, failed locked install, or failed hk/Beads hook does not roll
back the scaffold. Inspect the returned tooling and beads_hooks stages and run each listed recovery command. For
Beads hook recovery, use:
bd hooks install
bd hooks list --json
The general tooling rerun command is:
python3 scripts/setup-tooling.py --json
Do not commit an empty or stale mise.lock. A Copier conflict skips provisioning entirely: resolve every conflict,
account for every changed path, then rerun the project provisioner. /update-project keeps readiness false while
conflicts, degraded tooling, a missing/stale lock, or unclassified changed paths remain.