stack doctor
Report drift, failing checks and pending offers without changing anything
stack doctor
Diagnose the project and print a report. Nothing is written, nothing is
prompted. Think terraform plan: it is exactly the report
stack setup shows before asking to apply.
Doctor never invokes a coding agent. It runs the configured file, script, network, Nix, and acceptance checks against the current repository and runtime state. It does not install dependencies or repair files.
Progress is printed to stderr as sections and checks run, including an elapsed-time
message every ten seconds while waiting. JSON stdout stays machine-readable.
Ctrl+C cancels checks and their subprocesses. The command has a five-minute
overall deadline; use --timeout 15m when intentionally running longer builds.
Time spent entering a devshell before doctor starts is outside that deadline.
The report has one section per reconciler:
| Section | What it observes |
|---|---|
codegen | Host-side generated artifacts (env payloads, manifests) that would be rewritten |
files | Generated files whose content drifted from stackpanel.files.entries, and stale files left by the previous generation |
fileops | Adopted whole files, managed blocks, and path-owned keys inside JSON/YAML/TOML documents, including plan-time collisions between modules |
checks | stackpanel.doctor checks: runtime and repo scope run every time; build scope is listed, and realized with --build |
addons | Adoption offers you have not decided on yet |
Run inside the devshell for the full report. Outside it, only the sections that do not need the evaluated config can run, and the report says so.
Exit status
1 when any error-severity finding is present: a critical check failed, a
file could not be adopted (adopt = "refuse"), or a reconciler could not
diagnose. 0 otherwise, even with pending changes - pending changes are
applied by stack setup, they are not a doctor failure.
With --strict, pending changes, incomplete reconciler coverage, and any selected
enabled check that did not pass also cause exit status 1. A failed check is fatal
in this mode even when its ordinary severity is a warning. Missing or malformed
evaluated configuration is a failure. An evaluated empty manifest is valid; an
unavailable manifest is incomplete verification. Undecided addon offers remain
informational.
Usage
stack doctor # full report
stack doctor --json # machine-readable report
stack doctor --only files # just generated-file drift
stack doctor --skip checks # everything but the checks
stack doctor --build # also realize build-scope checks with nix
stack doctor --onboarding # rerun the saved setup contract, without an agent
stack doctor --strict --scope repo,build --build --jsonOnboarding verification
--onboarding reads the accepted plan from this repository's saved setup manifest
and reruns its exact configuration, required-file, build, and test checks. It
implies --strict --scope repo,build --build, does not change the manifest, and
does not invoke an agent. It cannot be combined with --expectations, --scope,
or --setup-session. Run setup again after verification to resume Studio setup.
If a generated Bun project is missing bun.lock and Bun's types, run bun install
in that repository's devshell before rerunning doctor.
--scope selects doctor check scopes (repo, runtime, build); it does not
exclude the generated-file reconcilers. Build checks selected without --build
are reported as skipped and fail strict mode.
--expectations <file> implies strict mode and verifies an explicit onboarding
contract. For example:
{
"version": 1,
"config": [
{ "path": ["enable"], "equals": true },
{ "path": ["apps", "web"], "exists": true },
{ "path": ["modules", "playwright", "enable"], "equals": true }
],
"requiredChecks": []
}Paths refer to the evaluated stackpanelConfig output. requiredChecks can list
known doctor check IDs that must remain enabled and actually pass. A required
check excluded by a scope filter, removed from configuration, or left unbuilt
fails verification. Expectations cannot be combined with filters that omit the
codegen, files, fileops, or checks reconcilers.
Configuration assertions use a fresh, pure Nix evaluation with locked inputs;
flake.lock must already exist and is not updated by verification. Generated-file
and check execution still use the current shell's manifests, so enter a fresh
target shell after config edits. Experimental stack setup does this automatically
and keeps its accepted expectations fixed through repair.
JSON reports include coverage entries with complete, skipped, or error
status, plus checkResults entries recording individual check outcomes. Reports
are emitted before returning a verification failure, so callers should inspect
both JSON and exit status. Argument, input-loading, or startup errors can prevent
a report from being produced.
Scaffold and browser evidence
Onboarding expectations may also contain files (repository-relative regular
files) and commands (id, scope, dir, and an argv array). Commands execute
inside the devshell with a five-minute timeout and bounded diagnostics. Build
commands require --build; skipped checks fail strict verification. Required
paths cannot escape the repository through traversal or symlinks.
stack doctor --strict --scope runtime --setup-session <session-id> --json--setup-session implies strict mode and requires the runtime reconciler and
scope. It checks the expected local agent identity, repository, devshell readiness,
selected service processes/listeners, and any requested browser acknowledgement.
The browser must have loaded the project and established a live authenticated
event connection. Old sessions, disconnected browsers, and restarted agents do
not pass. Doctor observes these states; setup starts services and opens Studio.
Ordinary doctor runs do not require an open browser.
Flags
| Flag | Type | Default | Description |
|---|---|---|---|
--json | bool | false | Print the report as JSON |
--only | strings | none | Run only these reconcilers (repeatable) |
--skip | strings | none | Skip these reconcilers (repeatable) |
--build | bool | false | Realize build-scope doctor checks with nix build |
--strict | bool | false | Fail on drift, incomplete coverage, or a selected check that did not pass |
--scope | strings | all | Run checks in the selected scopes: repo, runtime, build |
--setup-session | string | none | Verify an expiring runtime/browser setup session; implies strict mode |
--expectations | string | none | Validate an onboarding expectations JSON file; implies strict mode |
--onboarding | bool | false | Rerun the accepted setup contract, without an agent |
--timeout | duration | 5m | Maximum doctor runtime, including all checks |
Global Flags
These flags are inherited from parent commands.
| Flag | Type | Default | Description |
|---|---|---|---|
--daemon, -d | bool | false | Run in daemon mode (no TUI, for background processes) |
--no-color | bool | false | Disable color output |
--no-tui | bool | false | Disable interactive TUI mode |
--verbose, -v | bool | false | Enable verbose output |