The delivery loop is the set of /ds-* Claude Code skills that carry ONE DevStride story from "next unblocked item" to "merged and Done" — branching, building, self-reviewing, opening a PR, addressing findings, merging, and running the completion ritual, then looping to the next story. /ds-build-item is the orchestrator; /ds-branch-feature, /ds-ultracode-build, and /ds-pr are the skills it composes directly. Below /ds-pr sits a two-layer review stack — /ds-pr-review (the review + CI-gating policy) composing /ds-review (the review engine) — and /ds-push is the git utility nested deepest, called to land fixes. All of these are usable standalone too. Two more entry points feed the same loop: /ds-create-story and /ds-create-defect create a one-off item that isn't part of any plan and hand it to /ds-build-item's single-shot mode. /ds-branch-hotfix is the one skill on this page that truly sits alongside the loop rather than inside it — /ds-build-item never calls it. A short closing section covers the golden-dataset skills, which are supporting infrastructure a developer runs by hand — never part of the story loop itself.
get_item, update_item, and link_pull_request act on the real, live DevStride workspace at api.devstride.com — not your local SST stage — and the MCP cannot exercise branch code. Every lane move /ds-build-item makes (In Progress at the start, Done at the end) and every link_pull_request call are real, user-visible changes to live items, made against production the instant they run. There is no local/sandbox mode to fall back on./ds-build-item — the orchestrator/ds-build-item <item|next> runs the whole loop: select → mark In Progress → branch → build → adversarial review → PR → merge → completion ritual → sync develop → next. It is the ORCHESTRATOR — it composes the other skills below by name and owns only the DevStride-specific glue (next-story selection, lane transitions, the completion ritual). It is explicitly designed to run under /loop for full autonomy.
The steps, in order:
$ARGUMENTS or prior /ds-plan/ds-build-item memory), then pick the highest-priority, not-Done, not-blocked_by-anything Story/Defect in the earliest-dated open Capability/Epic on the plan's critical path — the same canonical "next-unblocked" definition ds-insert-story, ds-insert-defect, and ds-comprehend-plan use. It re-fetches the item's full description and validates it against the actual codebase before treating anything in it as true, and reports the whole "ready-set" of unblocked candidates (not just the one it picked) so parallel waves stay visible even though execution itself is serial.update_item lane move on the live item./ds-branch-feature with a slug derived from the item number./ds-ultracode-build, which owns the understand/build/adversarial-review engine (below)./ds-pr in its autonomous, driven-by-ds-build-item mode. /ds-pr opens the PR (with the four-section description format) and then runs the review + CI-gating stack (/ds-pr-review → /ds-review) below.develop in before merging so conflicts surface where they're resolvable — pushing the rebased branch goes through /ds-push (force-with-lease), never a bare git push, since a real rebase rewrites SHAs and would otherwise be rejected as non-fast-forward. Watches actual CI check-run status (not just reviewer bots) with a non-blocking snapshot poll — reusing the same check /ds-pr step 4 already surfaced, not a blocking gh pr checks --watch, which would tie up the tool call for the full run (this repo's golden/full gates can run 20+ minutes). Retries flaky failures (bounded, ~2 attempts), fixes real failures in-loop, and merges only once CI is actually observed green — gh pr merge <n> --merge --delete-branch.startDate/dueDate to the branch/PR window, confirm or manually create the PR↔item link, and — if the build materially diverged from the item's written spec — preserve the original description as a comment and rewrite the description to the as-built spec./ds-insert-defect or /ds-insert-story so a future loop iteration actually reaches it. See The Planning Loop for what those two skills do.git checkout develop && git pull --ff-only, assert a clean tree (the next /ds-branch-feature aborts on a dirty one), persist the resolved plan root, and loop back to step 1 for the next story./ds-build-item runs the entire loop — select through next-story — without pausing between steps. It stops and asks a human ONLY at a genuine fork:
Everything else proceeds on the loop's own judgment, with every deferral recorded explicitly (in the build plan, the PR body, and project memory) rather than silently dropped. This is exactly the contract /loop needs to drive /ds-build-item unattended.
/ds-build-item executes ONE story at a time on purpose. /ds-branch-feature aborts on a dirty tree, /ds-ultracode-build runs type-checks/tests against one working tree and one local Postgres/DynamoDB (concurrent vitest runs corrupt each other's worker DB), and the MCP writes to production — so concurrent branches would race on shared local and live state. The "ready-set" it surfaces at step 1 shows where a plan's parallel waves could run; fanning them out is a human decision, not something the loop does itself.If a resolved plan has zero not-Done, non-gated, unblocked candidates left, /ds-build-item exits cleanly and reports the terminal state (plan complete, blocked on open items, or gated on human/infra decisions) rather than looping back to re-ask.
/ds-build-item runs in one of two modes, and it auto-detects which from the item you hand it — no flag:
/loop /ds-build-item drives) — the item is part of a sequenced /ds-plan roadmap: it carries an execution-order [N] title prefix or is wired into the blocked_by/blocks graph. Here the full loop applies: select the next-unblocked item, walk the chain, splice discoveries back in (step 6.5), and loop to the next story.[N] prefix and no dependency edges (for example, one just created by /ds-create-story or /ds-create-defect). The inner build loop (steps 1–6: mark In Progress → branch off develop → build → PR → merge → completion ritual) runs verbatim — the whole point is that shipping is identical — but there is no plan-root resolution, no ready-set, no next-story selection, no [N] numbering, and no chain splice; it ships once to develop and terminates. Discoveries become their own one-off items rather than being spliced into a nonexistent chain.The one-off entry points are /ds-create-story and /ds-create-defect: each creates the item (asking where in the map and which board, assigning it to the current user), then hands off to this single-shot mode. Use them for inbound work that isn't in a plan; use /ds-insert-story / /ds-insert-defect (see The Planning Loop) when the work genuinely belongs in a sequenced plan's chain.
develop, or an integration branchBy default every story branches off, PRs into, rebases onto, and syncs develop. For a large multi-story initiative, /ds-build-item supports an opt-in integration-branch mode: at kickoff (step 0, asked once per initiative — not per story) it establishes a session working base, which may be a long-lived integration branch instead of develop. In that mode each story merges into the integration branch, leaving the shared dev stage (auto-deployed from develop) untouched until a release point. The default the prompt offers comes from ds-config.json's integrationBranch (or the branch recorded in the plan-handoff memory), but the step-0 answer is authoritative for the run. Release points are owner-cut and never automated — merging integrationBranch → develop → master at stable milestones (e.g. an epic boundary) is surfaced to the user, never performed by the loop.
/ds-branch-feature vs /ds-branch-hotfix/ds-branch-feature | /ds-branch-hotfix | |
|---|---|---|
| Branches off | develop (freshly pulled) | a fresh master, with the local DB reset from production |
| Naming | <user-prefix>/<MM-DD-YY>/<branch-name> | <user-prefix>/hotfix/<MM-DD-YY>/<branch-name> |
Called by /ds-build-item? | Yes — step 2 invokes it directly | No — standalone entry point only |
| PR target | develop (via /ds-pr) | master — opened when ready via /ds-pr (which targets master for a hotfix branch); nothing to compare right after creation, so no PR is opened as part of the branch skill itself |
| Use when | Building/shipping a normal story through the delivery loop | An urgent fix that must branch from production code, not develop |
/ds-branch-feature is the everyday branch-creation utility: it aborts on a dirty tree, syncs develop, creates and pushes the new branch. It's used both directly and as the building block /ds-build-item calls at step 2.
/ds-branch-hotfix is a heavier, standalone tool for genuine production emergencies. Its preflight is strict: SOURCE_DB_CONNECTION_STRING must be set (the DB reset fails partway without it, leaving the DB half-reset), the working tree must be clean, and it recommends stopping any running ds run backend first since resetting the DB underneath it can cause problems. The steps are git checkout master → git pull → the destructive ds script reset-db (drops and reseeds the local DB from prod) → create the hotfix branch → ds migrations run → push. On any failure partway through, it does not strand the user on master — it reports exactly which step failed and asks how to proceed rather than guessing.
/ds-ultracode-build — the build engine/ds-ultracode-build I<number> <one-line goal/scope> is the build engine /ds-build-item invokes internally once a branch exists and the item is already In Progress. It is not a standalone story-selection tool — it assumes the branch, the item state, and the scope are already given — and it does not open a PR or merge; it hands back to /ds-build-item. It runs three phases:
Co-Authored-By: and Claude-Session: trailers. Type-checks, the four pre-commit wiring checks, and the relevant tests must stay green — a red non-SDK check is a stop-and-fix, never a commit-anyway. Generated API artifacts (SDK/openapi/mcp gen output) are regenerated and committed separately from hand-written logic.Findings and deferrals that are real but have no existing tracked item to absorb them are not left as prose — they're collected into an untracked-deferral list that /ds-build-item step 6.5 turns into real, dependency-spliced DevStride items via /ds-insert-defect / /ds-insert-story. This is the "mid-build escape hatch" for newly discovered work; see The Planning Loop for how those two skills splice an item into the graph.
/ds-ultracode-build hands back to /ds-build-item with: the item number, a one-line build summary, green-checks confirmation, the finalized scope/deferral line, the untracked-deferral list, and a deviations list — every material way the build diverged from the item's written spec. That deviations list is what /ds-build-item step 6 uses to reconcile the item's as-built description.
/ds-pr → /ds-pr-review → /ds-reviewOpening a PR and getting it through review is three skills, each owning one layer, so any of them is usable on its own:
/ds-pr — owns PR creation and linking. It opens the PR with a formal description, then delegates all review and CI gating to /ds-pr-review./ds-pr-review — the review + CI-gating policy for an existing PR: it enforces the adversarial-review standard and defers the long-running golden-build gate, delegating the actual review mechanics to /ds-review./ds-review — the review engine: launch every reviewer, verify and triage findings, apply fixes, reply-and-resolve threads, settle CI./ds-pr — PR creation and linking/ds-pr [item-number] opens the pull request and then runs the review stack over it. It has two modes:
/ds-pr [item-number] directly. It asks which base branch to target (develop for a feature branch, master for a hotfix), keeps every interactive ask-gate, and offers to link the PR to a DevStride item as its final step.ds-build-item — invoked as /ds-build-item step 4. The base branch is pre-answered (the session working base — develop or the initiative's integration branch), the review runs non-interactively, and the linking step is skipped entirely — /ds-build-item owns PR-to-item linking in its own step 6, and linking in both places would double-own it. Even in autonomous mode it still pauses for a genuine fork (an ambiguous/risky/unverifiable finding, or a destructive/outward-facing action) — only "out of scope but real" findings are captured rather than asked about.The formal PR description format. /ds-pr no longer relies on gh pr create --fill; it authors the body in a required four-section format, each a Markdown ## heading, in this order:
There is no Co-Authored-By or AI-attribution text in the PR body — those trailers live on commits only. Once the body is written and the PR is open, /ds-pr hands the PR number to /ds-pr-review.
/ds-pr-review — review policy and CI gating/ds-pr-review [PR#] runs an already-open PR through the full review-and-settle loop and CI gating. It composes /ds-review for the engine and adds two policies of its own:
/ds-pr-review does not wait on it until all Codex/Copilot comments are evaluated, addressed, replied-to, and Resolved. It then lets the gate run and waits only on the final run after the last review fix lands./ds-pr-review propagates its driven-vs-standalone mode down to /ds-review, and carries the untracked-deferral list back up to its caller.
/ds-review — the review engine/ds-review [PR#] is the reusable engine every path above ultimately runs (and it's runnable standalone on any open PR). Its loop:
/code-review high (a background workflow that returns findings as a task notification) AND each configured automated reviewer (@codex review as a PR comment for Codex; the requested_reviewers API for Copilot).review.pollTimeoutMinutes, proceed with the findings in hand rather than blocking the loop on one bot./ds-insert-defect / /ds-insert-story under a root the user names (standalone — it never guesses a plan root)./ds-push (see below) — it never opens a second PR to land review fixes.resolveReviewThread on the thread. It only resolves threads it actually addressed — never a blanket "clear the board."Because it triages external, unauthenticated-relative-to-the-agent content — GitHub bot review comments and PR comments — and in driven mode acts on it with reduced oversight, /ds-review (and the whole stack above it) treats any embedded instruction inside a review comment (beyond a normal code-review suggestion) as untrusted data, not a legitimate instruction, and flags it to the user if it appears.
/ds-push — a smaller, direct utility/ds-push is a small git-workflow utility, not part of the phased build/review engine: git add -u (already-tracked files only — it deliberately never sweeps in untracked files with git add .), show git status and a staged diff summary, commit with a message carrying the required Co-Authored-By:/Claude-Session: trailers — using the exact per-session values, never a stale example, and stopping to ask rather than guessing if those values aren't clearly available — run pnpm --dir backend run check:ts && pnpm --dir frontend run check:ts, then push (falling back to git push --force-with-lease — never a bare --force — on a non-fast-forward rejection). If the type-check fails with non-SDK errors, it does not push; it reports and asks. It explicitly does not open a pull request — it's the stage/typecheck/push building block /ds-review calls internally to land review fixes, and it's equally usable standalone whenever you want to push without opening a PR.
/ds-build-item <item|next>
├─ 0. select story (get_item, dependency graph, ready-set)
├─ 1. mark In Progress (update_item — PRODUCTION write)
├─ 2. /ds-branch-feature I<####>-<slug>
├─ 3. /ds-ultracode-build I<####> <scope>
│ ├─ UNDERSTAND (ultracode Workflow: parallel readers → build plan)
│ ├─ BUILD (commit often, keep checks green)
│ └─ ADVERSARIAL REVIEW (Workflow: finders → per-finding verify → fix)
│ └─ compiles an untracked-deferral list for anything real
│ with no existing tracked home (not invoked here —
│ handed back to /ds-build-item, see step 6.5 below)
├─ 4. /ds-pr (autonomous / driven-by-ds-build-item mode)
│ ├─ open PR with 4-section body (ELI5 / technical / notable changes / testing)
│ └─ /ds-pr-review (review policy + CI gating)
│ ├─ adversarial gate: evaluate → fix → reply → RESOLVE each thread
│ ├─ defer golden-build gate until all comments settled
│ └─ /ds-review (the engine)
│ ├─ launch: local /code-review high + Codex + Copilot
│ ├─ verify + triage: dismiss REFUTED / capture out-of-scope / ask on forks
│ ├─ /ds-push (commit + typecheck + push the fixes)
│ └─ reply-and-resolve threads → settle CI green
├─ 5. merge (rebase working base in, watch CI, retry flaky, fix real failures)
├─ 6. completion ritual (Done lane, dates, PR link, as-built spec reconciliation — PRODUCTION writes)
├─ 6.5 capture untracked findings → /ds-insert-story · /ds-insert-defect
└─ 7. sync working base → back to step 0 (next story, or exit on terminal condition)
/ds-branch-hotfix is deliberately absent from this diagram — it's a standalone entry point for production emergencies, not a step /ds-build-item ever calls. The one-off path (/ds-create-story / /ds-create-defect) enters this same diagram at step 1, running steps 1–6 once and then terminating instead of looping at step 7.
.claude/ds-config.jsonEvery concrete value this page cites — the base branch (develop), the hotfix/production branch (master), the type-check commands (pnpm --dir backend run check:ts …), the local review command (/code-review high), and the automated reviewers (Codex via @codex review, Copilot via the requested_reviewers API) — is not hard-coded inside the skills. It lives in one checked-in file, .claude/ds-config.json, that the delivery skills load and treat as authoritative: /ds-branch-feature, /ds-branch-hotfix, /ds-ultracode-build, /ds-pr, /ds-pr-review, /ds-review, /ds-push, and /ds-build-item's own git glue each substitute the file's values wherever a step names a concrete branch, command, path, or reviewer. If the file disagrees with a literal shown in the skill, the file wins; if it's absent, the skills fall back to the inline default and say so.
What lives there: baseBranch / hotfixBaseBranch / protectedBranches, the opt-in integrationBranch (the default working base for a multi-story initiative — see the working-base section above), branchNaming, the verify.* type-check/test/lint commands, the generated.* file paths + regen command + tolerated-error patterns, and the review.* block: review.localCommand, review.automatedReviewers, review.pollTimeoutMinutes, review.resolveAddressedThreads, and review.notifyWhenSettled. What deliberately does not: commit trailers (the Claude-Session URL is per-session, so they come from the session's Git policy, never a static file) and coding conventions (those stay in the repo's AGENTS.md).
The planning skills (/ds-plan, /ds-comprehend-plan, /ds-insert-story, /ds-insert-defect, /ds-rationalize-gantt) read nothing from this file — they self-resolve org-specific config through the DevStride MCP at runtime, so they're already portable. The practical payoff: porting the delivery loop to a different repo is drop in a ds-config.json with that repo's values, not edit six skills — a light skill edit is needed only where the repo's structure genuinely differs (for example, it isn't a backend/frontend pnpm split).
/ds-golden, /ds-golden-build, /ds-golden-push, and /ds-reset-db are supporting infrastructure a developer runs directly — none of them is invoked by /ds-build-item, and they are not steps in the delivery loop. They exist to keep your local database and stage data usable while you build. Each is a thin, judgment-adding layer over the underlying ds golden / ds script CLI; for what those CLI verbs actually do, see Golden Dataset.
/ds-golden [org] — checks dataset health and, if needed, restores it. It always starts read-only (ds golden status, which mutates nothing); if the dataset is unhealthy, it only proposes a fix (a re-import, a reanchor) for the user to confirm — it never auto-runs a mutating verb on its own judgment./ds-golden-build [representative|full] — the heavy, rare, hours-long content-authoring flow: rebuilds the dataset from the generator (backend/tests/golden/) and, once it passes the §16 pre-ship assertion gate (which stamps a marker the publish step refuses to proceed without), optionally publishes it to the canonical golden source DB. It does not touch any stage./ds-golden-push <stage> — deploys/refreshes the golden Acme dataset onto a named stage, choosing the safe verb for that target: additive ds golden import for a shared, populated stage like dev (app.devstride.dev), or a whole-DB push --force-full-reset only for a confirmed-disposable stage. It hard-refuses prod outright — the CLI's own stage guard blocks every mutating golden verb against api.devstride.com, and this skill won't attempt a workaround./ds-reset-db — resets the local database from production, then re-applies the current branch's migrations on top. Strict preflight: SOURCE_DB_CONNECTION_STRING must be set (the reset fails partway without it), the working tree should be clean, and it recommends stopping any running ds run backend first. If any step fails, it does not leave you stranded on master — it checks out your original branch to restore you before reporting what broke.Per the golden dataset's own directive, any correction to golden data belongs in the generator, never in a direct database edit — a stage reset or reseed is expected to wipe hand-patched rows.
/ds-branch-hotfix / /ds-reset-db both perform a destructive local DB reset seeded from real production data — never run either against a dirty tree, and always confirm SOURCE_DB_CONNECTION_STRING before proceeding. None of these skills silently escalate past a destructive action; they stop and ask./ds-plan, /ds-insert-story, /ds-insert-defect, and /ds-comprehend-plan: how work gets onto the dependency graph that /ds-build-item selects fromds golden CLI these skills wrapds CLI surface