setup-secrets skill
The AI-driven sibling of onboarding.md. When a project has a manifest but no provisioned values yet, the user can ask the agent to "set up secrets" and the agent runs the eight-step setup-secrets skill instead of walking the user through the bash commands by hand.
This page covers what the skill does, the on-disk state file, and the resume contract that lets a re-run pick up exactly where the previous attempt stopped.
Russian translation: pending — will land alongside the broader Russian docs sweep.
When to use
- A project has
<repo>/.devboy/secrets.tomlwithrequired = [...]paths anddevboy secrets list --jsonreports any of them asmissing. - The user asked the agent to "provision missing secrets" / "bootstrap secret framework" / "set up secrets".
- The
setupskill (crates/devboy-skills/skills/00-self-bootstrap/setup/) detected a manifest with required paths and delegated. - A re-run after a partial setup — the wizard skips already-
donephases automatically.
For a broken setup (corrupt vault, daemon down) use the repair skill instead. For creating the manifest itself the user runs setup first; this skill assumes the manifest exists.
Eight-step flow
The skill is idempotent: every step records its outcome in ~/.devboy/secrets/setup-state.toml. A re-run reads the file and resumes from the first step whose status is not done / skipped.
Each step emits one structured message of shape {step, status, summary, next_options} and waits for the user before continuing (next / skip / abort). The skill never advances on its own.
The CLI runner exposed by crates/devboy-cli/src/secrets_setup.rs covers a slimmer four-phase subset — Scan / Propose / Provision / Doctor — which is the credentials-only path most projects need. The eight-step flow is the broader procedure that includes vault bootstrapping; the four-phase runner maps onto steps 5 and 8 directly and is what most callers integrate with first.
State file
Path: ~/.devboy/secrets/setup-state.toml (override with $DEVBOY_SECRETS_HOME).
Schema:
Status values:
pending— step has not run yet.in-progress— step started, has not settled. Only present mid-run.done— step completed successfully.skipped— step deemed not applicable (Touch IDon Linux,optionalpaths the user skipped,provisionwhen nothing was missing).failed— step encountered an error the wizard could not recover from. The next run picks up from this step.
last_step advances monotonically as the wizard reaches each phase, so a status renderer can show "you got to step 4 of 8" without iterating the table.
Resume contract
The skill — and the four-phase CLI runner — never re-do a step that has already settled. The contract:
- A step with status
doneorskippedis treated as final. The wizard does not re-prompt, re-scan, or re-provision; it emits oneSkippedevent with reasonalready doneand moves on. - A step with status
failedis treated as not yet settled. The next run re-attempts it. This is the recovery path: the user fixes whatever caused the failure (kills the dialog, restarts the daemon, edits the manifest) and re-runs the same command. - A step with status
pendingorin-progressis also treated as not yet settled.in-progressonly appears mid-step; the wizard never advanceslast_stepto "completed" without flushing a terminal status. - The state file is written after every settled phase, so an interrupted wizard mid-phase still leaves a coherent file.
To force a fresh run, delete the state file:
The entry.sh helper (P26.1) re-creates a fresh state file with every step pending. Resume is opt-in by not deleting the file.
Typed view
The devboy-cli::secrets_setup::SetupState struct is the typed projection of setup-state.toml for in-process callers — the future devboy secrets setup --resume sub-command, doctor checks, status renders. Shape:
A missing or malformed file maps to a fresh SetupState (scanned=false, last_step=0); the wizard treats both the same way, so callers don't have to special-case "first run".
Failure handling
The eighth step is the only assertion of overall success. Any earlier step that returns failed halts the wizard with a structured message indicating the step, the path (when applicable), and the recommended next action. The agent surfaces the message and waits.
Common failure modes:
vault_statefailed — keychain probe panicked. User fixes the keychain (re-login, unlock); the wizard re-probes on the next run.create_vaultfailed — disk full / permissions. State file records the reason; the user resolves and re-runs.required/provisionfailed — the user cancelled the dialog, the dialog timed out, or the daemon rejected the value. The wizard records the path that failed and stops; the user retries the same path on the next run.doctorfailed — pretty rare after steps 1-7 settle, but it does happen ifvalidationskipped a transient probe failure. The wizard reads the doctor error code and points the user at the failing path.
Provision dialog: what the user sees
When the wizard reaches step 5 (provision a missing path), it opens the native provision dialog (devboy secrets ui --provision <path>). The dialog now fuses three sources of metadata so the user sees the same procedure the provider's own docs publish:
The dialog opens as a modal overlay on top of the inventory (egui) / a centered modal in the terminal (TUI) — the inventory stays visible underneath. ESC or a click on the dimmed backdrop dismisses it. Content is ordered most-actionable-first.
When the path's provider segment does not match any loaded catalog the catalog-derived blocks collapse silently and the dialog renders only the manifest-side rows — the pre-S2 behaviour.
The variant chip in the inventory row (when the catalog declares more than one variant) re-arms the dialog with the selected variant's metadata; nothing else in the user's input is affected.
The builder lives in crates/devboy-secrets-ui-bin/src/catalog_metadata.rs::metadata_from_catalog_and_entry and is exercised by cargo test -p devboy-secrets-ui-bin catalog_metadata.
Choosing a backend
Where the provision dialog's Save writes depends on the backend the UI resolved at startup:
The UI handles the locked → unlocked transition itself: a modal asks for the passphrase (eye-toggle, wrong-passphrase shown in red, Use keychain instead escape hatch), and a top-bar switcher flips backends live. First run with no vault file offers a create flow with a one-time recovery-phrase gate.
First-run onboarding. When nothing is configured anywhere (no sources.toml, no .dvb, no env passphrase), the UI opens an onboarding wizard: a backend picker for keychain / local-vault / HCP Vault, combinations allowed, one marked primary. It writes sources.toml and creates the local vault if asked. The HCP Vault entry carries an access = "read" | "readwrite" mask — read narrows the source's capabilities to READ | LIST | VALIDATE.
Full walkthrough: local-vault.md ("Unlocking from the secrets UI", "First-run onboarding wizard", "External Vault as a read-source"). Contracts: scenarios/vault-unlock.feature, scenarios/onboarding.feature.
See also
- ADR-023 §3.4 — provision dialog contract.
- ADR-023 §3.8 — formal spec of the eight-step flow.
onboarding.md— manual equivalent for users without an agent.agent-protocol.md— MCP tool surface used in steps 5-6 (secrets_request_provision,secrets_poll_status).scenarios/ui-catalog-rendering.feature— Gherkin contract for the provision dialog's catalog binding.scenarios/vault-unlock.feature— Gherkin contract for the local-vault unlock / create flow.local-vault.md— local-vault file format, the UI unlock paths, recovery, and backup.crates/devboy-skills/skills/00-self-bootstrap/setup-secrets/SKILL.md— the skill manifest and procedure walkthrough the agent loads at activation time.crates/devboy-cli/src/secrets_setup.rs— the CLI-side scanner / proposer / wizard runner, includingread_setup_state.