Skip to content

Start a project

These steps take you from an empty directory to your first merged MR. Commands in bash blocks run in a terminal. Commands that start with / run inside a Claude Code session opened at the project root (run claude there).

Each step ends with a Check. If the check does not pass, fix that step before moving on. Later steps assume the earlier ones worked.

This list covers the harness, not your application. Blueprint does not know your stack. make doctor checks all of it and tells you what each missing tool costs.

Tool Needed for Without it
git, make, python3 Everything: the scripts, gates, and hooks Hard requirement. make doctor fails.
claude (Claude Code) Every skill and agent in .claude/: the whole review chain, /kickoff, /mr, /release The git, CI, changelog, and release tooling still work. There are no review agents.
glab (GitLab) or gh (GitHub), authenticated The duplicate-MR gate, issue-title lookup in wt new <issue>, stale-reference checks, and every skill that reads or writes the tracker check-issue-collision.sh cannot see open MRs, wt new <issue> cannot name the branch (pass a full branch name instead), and the stale-reference gate fails closed. Scripts choose the CLI from your origin remote’s host.
jq Parsing forge JSON in the collision gate and the pre-MR security hook Those two checks degrade.
direnv Loading each worktree’s .envrc automatically Optional. Run source .envrc by hand instead.

Everything else (Docker, Node, a language toolchain) is your project’s dependency, not Blueprint’s. Add checks for those to the “Project-specific checks” section of scripts/doctor.sh.

Clone Blueprint, then replace its history with a fresh one of your own:

Terminal window
git clone https://gitlab.com/macrodream/blueprint.git my-project
cd my-project
rm -rf .git
git init -b main
git add -A
git commit -m "chore: scaffold from blueprint"

Removing .git starts your project at a single commit, with no Blueprint history. From here on the files are yours.

Check: git log --oneline shows exactly one commit.

Create an empty project in GitLab. Don’t let GitLab add a README, or your first push will be rejected. Then connect and push:

Terminal window
glab auth login # once per machine
git remote add origin git@gitlab.com:<group>/<project>.git
git push -u origin main

glab, scripts/wt new <issue>, the duplicate-MR gate, and the /kickoff, /import-spec, and /mr skills all find your project through origin. Without a remote they have nothing to talk to.

Check: glab repo view prints your project, and glab issue list runs without an error. An empty list is fine.

These are set in the GitLab UI. Nothing in the repository can set them, and make customize can only remind you about them.

  • Settings → Merge requests: turn on Pipelines must succeed. Turn on Delete source branch by default. Choose a merge method, then record the same choice as MERGE_METHOD in .claude/skills/mass-merge/SKILL.md. That skill updates branches the way the forge will merge them.
  • Settings → Repository → Protected branches: protect main, with Allowed to push set to nobody and Allowed to merge set to Maintainers.
  • Settings → Repository → Branch defaults: set the default branch to main.
  • Manage → Labels: create no-changelog. The changelog-check job skips any MR that carries it.
  • Settings → CI/CD → Variables: add whatever your runners need, such as cache credentials for self-hosted runners.

Check: Settings → Repository → Protected branches lists main with nobody allowed to push.

Open Claude Code in the project root and run /kickoff. It asks five questions, one at a time:

  1. What you are building: a name and one sentence
  2. Who uses it: three to five user types, each with their goal and their biggest frustration with today’s tools
  3. The stack: language, framework, database, deployment
  4. What the first version does: four to eight user-facing capabilities
  5. The GitLab project path, such as mygroup/my-project. This is optional, but without it no issues are created.

It then writes CLAUDE.md (project name, stack, persona summaries), writes full personas to .claude/personas.md, and, if you gave a project path, creates one feat: issue per capability.

Take question 2 seriously. The personas drive /voc, a simulated user panel that runs before design work on every user-facing feature. Vague personas produce vague feedback. /voc output is a design aid, never a substitute for hearing from real users.

Setting up by hand instead: replace [PROJECT NAME] and every [FILL IN …] marker in CLAUDE.md and CONTRIBUTING.md, replace the example personas (Alex, Jordan, Sam, Maya) in .claude/personas.md, and delete the SETUP CHECKLIST comment at the top of CLAUDE.md.

Check: grep -n "PROJECT NAME" CLAUDE.md prints nothing.

/kickoff records your stack in CLAUDE.md but does not set up the build. Do that next, and do it before installing the git hooks in step 6. The lint and typecheck targets in the Makefile are stubs that exit with an error, and the pre-commit hook runs both. Install the hooks first and every commit is blocked until they are filled in.

What Where Why it matters
lint, typecheck, test, build (optionally format-check) Makefile: uncomment the block for your stack, or write your own The pre-commit hook runs format-check, lint, and typecheck when they exist. CI and agents call the same targets.
Stack CI jobs .gitlab-ci.yml: uncomment the matching ci/*.yml include, then set the variables at the top of that file Without an include, CI runs only the governance jobs
Version-bearing files scripts/release.sh: add every file that holds the version /release bumps exactly these
Edit-time reminders and guards .claude/hooks/post-edit-checks.sh and .claude/hooks/pre-tool-safety.sh Point the reminders and blocked-file patterns at your stack’s real paths
Dependency updates Keep renovate.json (GitLab) or .github/dependabot.yml (GitHub), and delete the other Only one should run

.gitlab-ci.yml includes:

include:
- local: ci/python.yml # Python: ruff, pytest, coverage, pip-licenses
- local: ci/node.yml # Node.js: eslint, vitest, coverage, license-checker
- local: ci/docker.yml # Docker: kaniko build verification
- local: ci/go.yml # Go: golangci-lint, go test, govulncheck

scripts/release.sh version files:

Terminal window
# package.json:
sed -i '' "s/\"version\": \".*\"/\"version\": \"${VERSION}\"/" package.json
# pyproject.toml:
sed -i '' "s/^version = \".*\"/version = \"${VERSION}\"/" pyproject.toml

.claude/hooks/post-edit-checks.sh patterns. When Claude edits a matching file, a reminder names the review to run:

# Django models → remind to check migrations
if re.search(r"models\.py$", file_path):
messages.append("models.py modified — run the schema-check agent")
# Prisma schema → remind to migrate
if re.search(r"schema\.prisma$", file_path):
messages.append("schema changed — run prisma migrate dev")

.claude/hooks/pre-tool-safety.sh blocks edits to lock files and existing migrations, and warns on CI config and .env files. Adjust its patterns to your stack. It blocks with exit code 2 and allows with exit code 0.

Then run the checklist:

Terminal window
make customize

It scans the repository and marks each item [✓] done, [ ] to do, or [!] warning. It only reports and never edits a file, so run it as often as you like. The GitLab settings from step 3 always appear as manual reminders, because a script cannot verify them.

If your stack has no type checker, make typecheck a no-op (for example @echo "no type checker") rather than leaving the failing stub.

Check: make lint and make typecheck exit 0, and make customize shows [ ] only for items you have decided to skip.

6. Install the hooks and check your machine

Section titled “6. Install the hooks and check your machine”
Terminal window
make setup # installs hooks/pre-commit and hooks/pre-push into .git/hooks
make doctor # checks git, make, python3, claude, glab/gh, jq, direnv

From now on, git commit runs format-check, lint, and typecheck (each only if the Makefile defines it), and git push runs make pre-push-checks: the duplicate-MR gate and the two parity gates.

Check: make doctor reports no failures.

CLAUDE.md in the repository tells Claude about this project. global-claude-md.example holds the rules that make Claude run the review agents at the right moments, rather than treating them as optional. Those rules belong in your personal ~/.claude/CLAUDE.md, which applies to every repository you open.

Terminal window
mkdir -p ~/.claude
# No global file yet:
cp global-claude-md.example ~/.claude/CLAUDE.md
# Already have one? Don't overwrite it. Append, then read the result:
cat global-claude-md.example >> ~/.claude/CLAUDE.md

If you append, remove any rule that conflicts with your existing ones. The file affects every project, not just this one.

Check: in a new Claude Code session, ask “Which reviews does a bug fix need?” The answer should match the bug-fix row of the fast-path table.

main is protected, so the setup work lands the way every later change will, through a branch and an MR:

Terminal window
git checkout -b chore/project-setup
git add -A
git commit -m "chore: configure project from blueprint"
git push -u origin chore/project-setup

Then run /mr in Claude Code. It checks the branch, writes the description, and opens the MR. It never merges; you do that.

Check: the MR pipeline is green. Expect the governance jobs (changelog-check, gate-selftest-parity, prepush-parity, stale-references, tooling-self-tests) plus your stack’s jobs. Merge it.

/import-spec path/to/spec.md # PRD, spec, or feature list → tracker issues
/import-design path/to/guide.md # design guide or token export → frontend/CLAUDE.md

/import-spec shows you the features it parsed and creates issues only after you confirm. If the spec has phases, it creates a milestone for each phase. Skip it if /kickoff already created the issues you need.

/import-design is for projects with a UI. It lets ux-design and ux-review check work against your actual design system rather than general guidance.

Check: glab issue list shows the issues you expect.

/dotplanning plans a milestone, so one has to exist. It comes from /import-spec if your spec had phases. Otherwise create one in GitLab (Plan → Milestones) and assign the issues to it. Then:

/dotplanning 0.1

It maps every feature in the milestone to the screens, endpoints, models, and docs it needs. It flags anything with no issue or design behind it, lists the decisions to make before coding, and orders the work into workstreams, naming each one’s review chain. It asks you whether each issue is release::committed, release::reserve, or release::stretch, and never guesses. The report is written to ~/Downloads/dotplanning-<version>-<date>.html, and it offers to file issues for the gaps (skip with --no-file).

Run it once per milestone, before the first feature branch. Re-run only if the scope changes materially.

Check: the report opens, and every 🔴 gap or open question is either filed as an issue or answered.

From here on, work repeats one loop per issue:

Terminal window
scripts/wt new 12 # branch feat/12-<title>, worktree ../my-project-wt/12-<title>
cd ../my-project-wt/12-<title>
source .envrc
claude # work the issue; Claude runs the reviews for its change class
# inside Claude Code: /mr → opens the MR, records the reviews, adds "Closes #12"
# merge on a green pipeline, then from the main checkout:
scripts/wt prune # removes worktrees whose branches have merged

Which reviews run depends on the kind of change. This is a summary; the Fast paths by change class table in CLAUDE.md is the authority.

Change Reviews, in order
Bug fix with a known cause regression-checktest-scaffold (if untested) → changelog/mr
Docs only docs (for a new page) → /mr
Backend-only feature architect → pre-MR gate batch → test-scaffoldchangelog/mr
New user-visible feature (full stack) /vocarchitectux-design → implement → pre-MR gate batch → ux-review + accessibilitytest-scaffoldchangelog/mr

When the milestone’s work is merged, run /pre-release full, fix what it blocks on, and cut the release with /release (see Release workflow).

For the details of the loop, read Issues are the unit of work and A day in the life. /kaizen audits the loop itself for friction once you have a few MRs behind you.