You already have a project
A repo with CI, a ticket tracker, your own slash commands and an open branch. What init touches, what it leaves alone, and the one folder the verify stage needs.
The first three Start pages use an empty repo. This page is for a repo that already has history, CI, tickets and your own commands. Everything below was run on 2026-10-08 against a stand-in repo (acme-app: a package.json with test, build and lint scripts, a .github/workflows/ci.yml, two commands under .claude/commands/) with codeloop from the current branch. Outputs are pasted from that run.
What init writes, and what it leaves alone
codeloop init --tools claude No specific stack detected, using generic config
Detected scripts.test, scripts.lint, scripts.build in package.json (npm)
~ .claude/commands/ left alone (pass --yes to write into it)
Initializing codeloop...
Tools: claude | Stack: Generic project
quality_checks from package.json: Lint (npm run lint), Build (npm run build)
Created:
+ .codeloop/lanes/analyze.yaml
+ .codeloop/lanes/build.yaml
+ .codeloop/lanes/deploy.yaml
+ .codeloop/lanes/learn.yaml
+ .codeloop/lanes/market.yaml
+ .codeloop/lanes/plan.yaml
+ .codeloop/lanes/scan.yaml
+ .codeloop/lanes/triage.yaml
+ .codeloop/rules.md
+ .codeloop/gotchas.md
+ .codeloop/patterns.md
+ .codeloop/principles.md
+ .codeloop/board.json
+ .codeloop/.gitignore
+ .codeloop/config.yaml
Done.
9 lanes in .codeloop/lanes/, 39 skills indexed in .codeloop/skills.index.yaml.
codeloop serve opens the board in a browser.
Next, type:
codeloop start "<your feature>"
codeloop inboxFour things to know from that output:
- A
.claude/commands/folder with files in it is left alone. Nothing is written next to your commands unless you pass--yes. With--yes, the ten shipped commands go in and a file that already exists is kept and listed underSkipped (already exist):with a~; the repo above keeps its own/test.CLAUDE.md, your workflows and yourpackage.jsonare not touched, and only.codeloop/is new ingit status. - Scripts in
package.jsonbecome quality checks.scripts.lintandscripts.buildare written toquality_checks:inconfig.yaml. The test command inconfig.yamlstays commented out; the build stage runsnpm testfrom.codeloop/lanes/build.yamlwhatever the config says, so change that line for another runner. - Stack detection reads one file.
tsconfig.jsonmeans TypeScript;pyproject.toml,setup.py,requirements.txtorPipfilemeans Python;go.modmeans Go. Apackage.jsonon its own is "Generic project".--starter node-typescriptpicks the Node starter without atsconfig.json. - Your own commands are indexed. The 39 skills are the bundled ones plus the two under
.claude/commands/it found; with--yesit is 64.grep fix-ticket .codeloop/skills.index.yamlshows yours askind: command.
There is no flag to skip one of the ten commands. Delete what you do not want after init --yes; codeloop update does not bring a deleted file back, it lists it as not installed and refreshes only the skill files that exist with an older version comment. init --hooks and init --ci github write only the hook and only the workflows.
Tickets from Linear, Jira or GitHub
A ticket-style prefix on the title is read as the ticket id, not refused — codeloop card show then prints ticket ACME-412:
codeloop start "ACME-412: add CSV export" \
--persona dev --can "download every invoice as one CSV" --so "I stop exporting by hand" --size Screated c-001 in build at stage research for ACME-412 (specs/001-add-csv-export/)
Next: run the /design skill to write specs/001-add-csv-export/research.md, then `codeloop next c-001`.codeloop card show c-001 c-001 build research add CSV export
As a dev, I can download every invoice as one CSV, so that I stop exporting by hand.
ticket ACME-412 · size S
skill: design
output: specs/001-add-csv-export/research.md
check: codeloop check research c-001 --min-sources 3The ticket id is stripped from the title and the spec folder name; add CSV export is what shows everywhere else. The refusal is still there for a mechanism in the title itself — /, a path, a function name — --force overrides that one. When the title already says what the user gets and the ticket id lives elsewhere (the tracker's own slug, say, not a prefix you want to keep), pass --ticket:
codeloop card propose build "Rate-limit the invoices API" --ticket ACME-413 \
--persona dev --can "call the invoices API without a spike taking it down" \
--so "one client cannot block the rest" --size Sproposed c-002 for build: Rate-limit the invoices API
Next: `codeloop approve c-002` puts it in the build lane, or `codeloop reject c-002 "<why not>"` drops it.--ticket works on start and card propose alike, and wins over a prefix parsed from the title if both are given. There is still no Linear, Jira or GitHub Issues importer; codeloop import reads Spec Kit and BMAD folders only. --source still takes a URL for a link inbox shows under the card, independent of ticket:.
Your own slash commands in a lane
init indexed the commands under .claude/commands/, so a lane can name them. This lane runs /api-contract and then /fix-ticket, with your own npm test as the second stage's check and a gate after it:
cat > .codeloop/lanes/contract.yaml <<'EOF'
id: contract
version: 1
metric: { name: cycle_time_days, source: cards, target: "<2" }
trigger: { manual: true }
wip: 2
retries: 3
stages:
- id: contract
skill: api-contract
output: "{spec}/contract.md"
done: { cmd: "codeloop check file {spec}/contract.md --has 'mismatches:'" }
- id: fix
skill: fix-ticket
done: { cmd: "npm test" }
gate: { name: fixed, approver: owner }
EOF
codeloop lane lint
codeloop card new contract "Invoices API matches its OpenAPI file" \
--persona dev --can "trust that every invoices route matches openapi.yaml" \
--so "clients stop breaking on undocumented fields" --size S 9 lanes ok
created c-001 in contract at stage contract (specs/001-invoices-api-matches-its-openapi-file/)
Next: run the /api-contract skill to write specs/001-invoices-api-matches-its-openapi-file/contract.md, then `codeloop next c-001`.codeloop brief c-001 prints the stage brief an agent gets: the check command, then your command's text verbatim under ## Skill: api-contract, then the rules (write only the output file, never approve or advance). A command you add later is picked up by codeloop adopt, which rebuilds the index. Lanes has the lane file reference.
The usecases folder the verify stage needs
The build lane's verify stage runs codeloop verify, and the Start pages stop before it. With nothing under usecases/, the stage fails:
codeloop next c-002 acceptance line US1 has no use case in usecases/
c-002 failed the verify check (1 so far)
Next: acceptance line US1 has no use case in usecases/. The /qa skill produces evidence/002/verify.md. Then `codeloop next c-002`.One file per acceptance line, under the card's number. The smallest one runs your existing test command:
mkdir -p usecases/002
cat > usecases/002/uc-001.yaml <<'EOF'
id: uc-002-01
accept: US1
failure_mode: "the export is empty or the test suite is skipped"
layers:
cli: { run: "npm test", expect: { exit: 0 } }
EOF
codeloop next c-002c-002 is waiting for you at verify (gate local, owner approves)
Next: read evidence/002/verify.md, then `codeloop approve c-002`, or `codeloop reject c-002 "<what to change>"`.evidence/002/verify.md now holds result: pass, the commit SHA, and one row per use case. accept: names the acceptance line in spec.md; failure_mode: is the sentence that says what the check guards; expect: can also carry stdout:. Stages and checks has the api layer and verify --mutate.
After init and one card, the repo root has four new folders: .codeloop/, specs/, usecases/, evidence/.
CI you already have, and the Feature trailer
codeloop init --ci github writes three workflows next to yours and does not read yours. codeloop-pr.yml runs npm ci, npm run build, npm test, codeloop lane lint, and then a step named "Every commit carries a Feature trailer" that fails the PR if any commit on the branch has no Feature: <card-id> trailer. codeloop-staging.yml does nothing until deploy.staging.command is set in config.yaml. codeloop-prod.yml runs on a v* tag under the production environment.
The trailer comes from the commit-msg hook, installed by codeloop init --hooks. It adds Feature: <id> when the branch name contains an id shaped like c-012 or ACME-412 and the message has none. Verified on two branches:
git checkout -q -b feat/ACME-412-csv-export && git commit -q --allow-empty -m "add export" && git log -1 --format=%B
git checkout -q -b feat/csv-export-no-id && git commit -q --allow-empty -m "add more" && git log -1 --format=%Badd export
Feature: ACME-412
add moreSo a branch opened before init, with no id in its name, gets no trailer and its existing commits have none either; the PR workflow would fail it. Three fixes, pick one: add the trailer to the open commits (git rebase -i with git interpret-trailers), rename the branch to carry the ticket id before the next commit, or delete the trailer step from codeloop-pr.yml if you do not want the link between commits and cards. If your own ci.yml already runs the tests, delete the duplicate npm test line from codeloop-pr.yml too; lane lint and the trailer step are the parts your CI does not have.
Turning the follow-on lane off
When a build card reaches done, the engine starts a card in the market lane:
c-002 done
started c-004 in market
Next: nothing left on this card. `codeloop inbox` shows what else is waiting.Two lines cause that, and both have to go. .codeloop/lanes/build.yaml ends with on_done: { start: market }, and .codeloop/lanes/market.yaml has trigger: { on: lane.done, lane: build }; either one alone starts the card. Remove the on_done line and set the market trigger to manual: true:
perl -ni -e 'print unless /^on_done:/' .codeloop/lanes/build.yaml
perl -pi -e 's/^trigger: \{ on: lane.done, lane: build \}/trigger: { manual: true }/' .codeloop/lanes/market.yaml
codeloop lane lint
codeloop lane list 9 lanes ok
analyze v1 pull → compare → judge → findings cron 0 9 * * FRI
build v1 research → mock → spec → build → verify → review → staging → live manual
deploy v1 staging → verify → prod → smoke on git.tag
learn v1 capture → bump → promote manual
market v1 brief → draft → publish → measure manual
plan v1 gather → research → rank → story cron 0 9 * * MON
scan v1 scan cron 0 7 * * MON
triage v1 capture → classify → dedupe → file cron 0 20 * * *The cron lanes (analyze, plan, scan, triage) only run when codeloop run --agent is on a schedule; nothing starts on its own in a repo where you only type commands.
Next: Initiatives, epics, features and priority, for where a card sits once there are more than a few.