Bootstrap On A New Machine (Humans And AI Agents)
A complete, ordered runbook to take a bare machine to a running Detent. Every
step has a verification command — do not proceed until it passes. An AI agent
can execute these steps top to bottom; replace each <...> placeholder. The
detent-orchestration
repo is a real, working instance of this setup to copy from.
-
Install Detent.
brew install digitaldrywood/tap/detent(macOS/Linux),go install github.com/digitaldrywood/detent/cmd/detent@latest, or a platform installer from Install. Verify:detent version. -
Install and authenticate the GitHub CLI. Install
gh, then choose scopes for the tracker mode:# ProjectV2-backed board mode. gh auth login --scopes "repo,read:org,read:project,project" # For existing auth: gh auth refresh -h github.com --scopes "repo,read:org,read:project,project" # Boardless issue-field mode. gh auth login --scopes "repo,read:org" # Boardless label mode. gh auth login --scopes "repo"Verify the required classic PAT scopes independently. Boardless issue-field and label modes do not require
read:projectorproject; label mode also does not requireread:orgunless another workflow setting needs it.gh auth status 2>&1 | rg '\brepo\b' gh auth status 2>&1 | rg '\bread:org\b' gh auth status 2>&1 | rg '\bread:project\b' gh auth status 2>&1 | rg "(^|[[:space:],'\"])project([[:space:],'\"]|$)"Use
github_token: ghinglobal.yamlso Detent resolves this token at startup. -
Install and sign in to the Codex CLI. Install the OpenAI Codex CLI and sign in. Detent dispatches every agent through
codex app-server. Verify:codex --version. -
Choose the GitHub status source. For the current/default compatibility path, choose the GitHub ProjectV2 board Detent will drive and get its node id (starts with
PVT_):gh project list --owner <org-or-user> --format json --limit 50This verifies the token can read ProjectV2 boards. The write
projectscope is verified when Detent first performs an intentional board mutation. The board only needs to exist — Detent auto-provisions missingStatusandPriorityoptions on first run. The option names must match yourWORKFLOW.mdstates, and Detent keeps knownStatusoptions in canonical board order.For boardless issue-field mode, skip ProjectV2 board creation and instead confirm the repository's organization has a single-select issue field named
Status:gh api /orgs/<org>/issue-fields --jq '.[] | select(.name == "Status")'For boardless label mode, skip ProjectV2 board creation and organization issue-field setup, then confirm the repository has status labels with the configured prefix:
gh api repos/<owner>/<repo>/labels --paginate --jq '.[].name' | rg '^detent:' -
Clone the repository you want Detent to work on (its checkout becomes
workspace.source_root):git clone <repo-url> <source-root> -
Author the project contract. Copy the mode-specific template as a starting point, then edit it. For from-zero board creation, interview questions, issue intake, and the first-dispatch smoke test, follow Project Onboarding:
GITHUB_MODE="${GITHUB_MODE:?set GITHUB_MODE to project_v2, issue_field, or label}" curl -fsSL "https://raw.githubusercontent.com/digitaldrywood/detent/main/docs/templates/WORKFLOW.${GITHUB_MODE}.md" \ -o <source-root>/WORKFLOW.mdThe maintained templates are
WORKFLOW.project_v2.md,WORKFLOW.issue_field.md,WORKFLOW.label.md, and the CLI-only local-status templateWORKFLOW.github_local.md. Non-code artifact workflows can start fromWORKFLOW.non_code_artifact.md. A runnable local example with seeded work items, artifact metadata, API payloads, and artifact-gate transitions lives indocs/examples/non-code-artifact. Existing GitHub-backedWORKFLOW.mdcopies must be migrated manually: require an open pull request that is marked ready for review and is not a draft before declaringstatus: complete, usegh pr ready <number>as the remedy, and verifygh pr view <number> --json isDraft --jq '.isDraft'returnsfalse. Known deployed copies requiring this audit includedigitaldrywood/video-studio(tracked by video-studio#57),digitaldrywood/ghostreel, and thehostlet.clickworkflow. They setserver.kanban.mode: integrationfor trusted project boards; change that toread_onlyonly for an observer or shared dashboard, explicit no-writes choice, or failed post-authorization write probes. They also include a## Required Execution FlowwithFor Todo,For In Progress,For Rework, andFor Mergingsections so merge workers have a terminal instruction: invoke$go-workflow:ship, merge and move the issue toDone, move it toReworkwith an actionable defect, or leave it inMergingwith a concrete external blocker recorded. Before dispatchingMerging, confirm the Detent host's Codex environment exposes$go-workflow:ship; otherwise install or enable that workflow, or replace theFor Mergingsection with equivalent project-local merge instructions.For ProjectV2 mode, set
tracker.project_slug(yourPVT_id). For boardless issue-field mode, settracker.github_status_source: issue_field,tracker.repository: <repo-owner>/<repo-name>, and optionallytracker.status_field. For boardless label mode, settracker.github_status_source: label,tracker.repository: <repo-owner>/<repo-name>, andtracker.status_label_prefix. For externally owned or open-source repositories where Detent must not pollute issues, labels, fields, Projects, or issue comments, usetracker.kind: github_localfromWORKFLOW.github_local.md; do not settracker.github_status_source, configuretracker.local_sqlite.path, and import explicit issue numbers withdetent github-local import <project-id> <issue-number> --state Todo. In every mode, setworkspace.source_root(<source-root>),workspace.root(a worktrees directory),write_probe_issuefor ProjectV2 or issue-field status-write proof, and the prompt body. In label mode, setwrite_probe_issueonly when using legacy/deep issue-object probes. If the repository already has aWORKFLOW.md, audit its prompt body for the same Required Execution Flow andCurrent Detent status: {{ issue.state }}line before dispatching Detent against it. Registered projects can usegithub_token: ghinglobal.yaml; leavetracker.api_keyout of the workflow unless you are intentionally using a workflow-local token. The full field reference is in Quick Start.Interactive alternative: when Detent starts without a resolved
global.yamland without aWORKFLOW.mdin the current directory, it serves the/onboardingweb wizard. Openhttp://localhost:<port>/onboardingto walk through tracker, credentials, project, agent, and write steps for generatingWORKFLOW.md. The first step asks for ProjectV2 board, organization issue field, or repository labels; label-mode users should choose Repository labels, then enter the repository and status label prefix such asdetent:. The wizard hides ProjectV2 fields for boardless modes. Then return to the runbook for board creation, global registration, issue intake, and the smoke test. -
Create global config and register the project:
detent init detent add-project --id <id> \ --workflow <source-root>/WORKFLOW.md \ --workdir <source-root>Edit the resolved
global.yamland setgithub_token: ghwith any desiredenv,log_level, andportoverrides. -
Verify everything:
detent doctor --allow-write-probesEvery check must pass before starting Detent. If Detent is already running on the configured port, the server-port check may fail because the live service owns the port. In that case, validate the rest of the setup without the port collision, then verify the running service:
detent doctor --port 0 --allow-write-probes curl -fsS http://127.0.0.1:4000/health | jq -e '.status == "ok" and .mode == "running"' -
Start Detent and confirm the dashboard:
detent --host 127.0.0.1 --port 4000 ss -ltnp | rg ':4000|detent' curl -fsS http://127.0.0.1:4000/api/v1/stateKeep
127.0.0.1for SSH tunnels. For VPN access, use the selected private or Tailscale IP instead and verify it from another machine:detent --host <tailscale-or-private-ip> --port 4000 curl -fsS http://<tailscale-or-private-ip>:4000/api/v1/stateUse
--host 0.0.0.0only when every host interface is trusted for dashboard access; it is not limited to Tailscale. -
Dispatch work. Move an issue to
Todothrough the configured status source: ProjectV2Status, issue-fieldStatus, thedetent:todostatus label, or the local SQLite state used bygithub_local. Detent claims it, creates an isolated worktree, dispatches an agent, and the issue appears under Running on the dashboard. Drive the rest through the configured status source (Todo→In Progress→Human Review→Merging→Done).