Best practices
Vibstr's primitives are deliberately minimal. Three statuses, one terminal close-state, labels for everything else. This page is the opinionated guide to using them well — and, just as importantly, the things to not reach for.
If you have already done the quick start, you have seen the surface. This page is about the rails the surface sits on.
The setup checklist
Run through this once per project, in order. Most of it is two-minute decisions that you will regret later if you skip.
1. Name the project after the codebase. Not the team, not the client, not the quarter. The project is a container for items, builds, members, areas, categories, labels, and prompt templates — it tracks a body of code. One project per repo is the common shape. One project per client also works if the client has one repo. Two repos? Two projects. This sounds pedantic until the first time you have an item open against the wrong codebase and cannot tell.
2. Define 3 to 5 categories. Stop at 5. The defaults (Bug / Change / Task / Note) cover most of what most teams need. You can rename, recolour, reorder, or replace them — but five is the cap, and the cap exists for a reason. The moment you reach for a sixth category you are reaching for the kind of taxonomy that breaks teams over six months. Use a label instead.
3. Define your areas. Areas are the chunks of your app — top-level directories, screens, or subsystems. Aim for between 5 and 15. Less than 5 and the area chip is useless; more than 15 and nobody picks the right one. Use the group-separator feature (---Frontend, ---Backend) to split a long list into clusters — the dropdown will render them as headed groups. Areas are project-scoped, free-text, and you can add more any time.
4. Connect Claude Code. Settings → Connect Claude Code → copy the master snippet → paste into Claude Code → tell Claude: Add this to my CLAUDE.md. Done. After that, Claude drives the loop automatically — plans first, derives items, commits with closes #42, runs the build-report curl. You don't have to remember any of it. This is the killer feature — once builds report themselves, Vibstr knows what shipped when. The full deep-dive is on the Claude Code page.
5. Link your GitHub repo. Settings → GitHub. Format is owner/repo (no https://github.com/ prefix). Once set, every commit hash in the Builds tab becomes a clickable link to GitHub, and the deterministic #NN parser picks up references in commit messages with zero AI credit cost. Do not skip this — the parser is one of the better wins in the product and you only get it after the link.
6. Add labels for the workflow stages your team actually uses. Status is fixed at open / checking / done. Labels carry everything else: in-design, in-review, blocked, qa-failed, ready-to-ship, regression, priority. Project-scoped, multi-select per item, 8 colours. We use them aggressively. Vibstr's Board view (Kanban-style) pivots on labels — set yours up now and you get the swimlanes for free.
7. Turn on the audit log if you have collaborators. Settings → Platform → Audit log. Captures every meaningful admin mutation — who flipped which feature flag, who deleted which project, who renamed which prompt template. It is chris-only by default; broaden it through the platform-admin allow-list when you trust the audit log enough to share it.
That is the whole setup. Five minutes if you are moving fast, fifteen if you are deliberating about category names — which, again, you should not be.
Why labels carry the workflow
This is the most-asked question in user feedback: "Can I add an in-progress status?"
No. And the no is not because we forgot to make it configurable.
Status is the close-eligibility axis. Open means "not done." Checking means "done but waiting on verification." Done means "shipped, terminal, audited, indexed in the changelog." Three states map to three different things you can do with an item — work it, verify it, archive it. Adding a fourth state ("in progress" or "in review" or "blocked") forces every other code path that touches status to grow a branch, and you have just turned Vibstr into Jira.
Labels are the right escape hatch. They are descriptive, configurable, multi-select, and they stay out of the close-eligibility logic. If your team's stages are triage → ready → in-progress → in-review → ready-to-ship, create five labels named exactly that and pivot the Board view on them. Status stays at open / checking / done; labels carry the stage. This is how every tracker we admire works internally — they expose the configurability and we have learned to look past it.
The anti-pattern: do not create labels named status:in-progress or stage:review. Just create the label in-progress and review. The colon prefix is a tell that you are trying to recreate status configurability through labels, which is the worst of both worlds — you get all the cognitive cost of a status field without the close-eligibility logic to back it up.
The plan-driven ship loop
Vibstr ships Vibstr through plans. Every release after 1.10.7 was filed, tracked, and closed via this exact workflow. The pattern is:
Step 1. Write a plan in markdown. Settings → Plans → New, or click the Plans tab and use the + New Plan button. Frontload the why and the themes, not the line-by-line. The plan body is what the AI will read to derive items, so write it like you would write a brief: goal at the top, acceptance criteria, then the work in rough order.
Step 2. Click Derive items. The AI extracts each task / step / acceptance criterion from your body and proposes a list of { type, area, description } triples. Edit the preview inline, skip the duds, approve the rest. One AI credit charged per derive run, regardless of how many items it produces. The full mechanics are on the Plans page.
Step 3. Items inherit plan_id and target_build_id from the plan. Now your plan, your items, and the build that will close them all live in the same context. The plan card shows 0 / 8 done · linked to v1.11.2; the Builds tab hero card for v1.11.2 shows the plan back-linked under "Plans for this build."
Step 4. Implement. Make commits. Each commit message has closes #NN lines for the items it shipped:
git commit -m "Add the cleanup migration -- closes #232
Implements the CTE-based de-dupe for vibelog_builds rows
accumulated through 1.10.x and 1.11.x."
The full commit body matters. Earlier versions of the curl recipe only sent --pretty=%s (subject only) which hid closes references in the body. The 1.11.1 recipe in CLAUDE.md switched to --pretty=%B (full body) so multi-line closes lines work.
Step 5. Push. The auto-ingest super-function receives the build report. The #NN parser runs FIRST — deterministic, zero AI credits — and closes every item referenced in the commit message. Anything still open then goes to the AI semantic matcher, which costs one credit and catches whatever the commit message did not name explicitly.
Step 6. Ship the build. The plan's progress chip ticks from 0 / 8 done to 8 / 8 done · 100%. The Builds tab hero card shows the changelog. The audit log captures every status change. You file zero items by hand.
We have shipped five sub-releases this way at the time of writing — 1.10.7, 1.10.8, 1.10.9, 1.11.0, 1.11.1, and now 1.11.2. The conductor (the human who decides what ships) writes the plan; the implementing agent reads it; commits close the loop. The product proved itself by being how we built the product.
reported_build vs build_id
Two different builds, two different fields, two different meanings. This catches everyone exactly once.
reported_build is the build the item was found in — historical truth. The user reported the bug against v1.4.2; that is what reported_build records. It never changes (unless you fix a typo).
build_id is the build that closed the item — ship truth. The bug shipped its fix in v1.4.5; that is what build_id records. It is null until the item closes; it gets set when a build report references the item via #NN, when the AI semantic matcher matches it, or when you manually close the item with a build attached.
Keep them separate. Do not conflate. Do not put the closing build into reported_build "for consistency" — you lose the regression history. Do not ignore reported_build for new items — when a user comes back six months later asking "did v2.0 break this?" you want the answer.
The drawer right rail surfaces both: "Reported in: v1.4.2" near the top, "Closed in: v1.4.5" near the bottom. The Builds tab closes #NN flow only writes build_id. The capture form's Build chip writes reported_build for items you create against an existing build.
BYO Anthropic key
If you burn through your trial AI budget ($1 USD covers ~100 typical Haiku calls over the 14-day trial; 0 platform AI post-trial regardless of tier — we never mark up AI compute), bring your own Anthropic key. Settings → Account → AI provider → paste your sk-ant-... key and save. Once saved:
- The three Anthropic-using Edge Functions (
vibstr-ai-chat,vibelog-process-output,vibstr-derive-items) use your key instead of the platform's. - The daily-limit gate is bypassed entirely. You are paying Anthropic directly; we do not take a cut.
- The raw key is one-way once saved — Vibstr never returns it through the API again. You can replace it or clear it, but you cannot read it back. Treat the saved key like a webhook secret you have already deployed.
- The audit log records
account.anthropic_key.setandaccount.anthropic_key.clearevents. The audit row carries only the timestamp; the key value (and any prefix beyond the publicsk-ant-) is never logged.
The BYO path is the right call once you are deriving plans daily, running paste-output against large item lists, or doing AI-Assist for a real workflow. The platform key is fine for poking around. We unbundled compute from the product on purpose — the people who need a lot of AI should pay for it directly, not subsidise everyone via a flat fee.
Anti-patterns
A short list of things to not do. Each is something a real user has tried and bounced off.
Do not use status as workflow. Three statuses is the floor for a reason. If you find yourself wanting in-progress, you are looking at the wrong axis — use a label. The other tracker that conflates status with workflow is the one you left to come here; do not recreate it inside Vibstr.
Do not put 12 categories on a project. Categories are for the kind of work, not the topic. Bug, Change, Task, Note covers most teams. Add Schema if you do enough migrations to want them grouped. Stop. The taxonomy gets worse the more options you add — choice fatigue is real and items end up uncategorised.
Do not track "in progress" in Vibstr. Your editor tab, your current branch, the standup channel — those are the source of truth for what you are doing right now. Vibstr tracks what is open (queued for someone to do), what is checking (waiting on verification), and what shipped (done). The middle "actively being worked on" state is your problem and your tool's, not Vibstr's.
Do not use Vibstr for a roadmap. Plans are documents that derive items; they are not quarterly objectives. The list of "what's open" is the list of work that has been described concretely enough to act on. The list of "what we want to ship in Q3" is something else and lives elsewhere — a doc, a wiki page, the SPEC.md in your repo. Trying to make Vibstr be both is how you get every-tracker-is-bad outcomes.
Do not forget to set the GitHub repo. This shows up in the user-feedback bin every release. The deterministic closes #NN parser is one of the most-loved features and you have it disabled until you set vibelog_projects.github_repo. Settings → GitHub → paste the owner/repo slug → done. Two minutes, immediate payoff.
Closing
These are the rails. Everything in the product was built to make the loop above feel inevitable — write a plan, derive items, commit with closes #NN, watch the build report itself and the changelog write itself. Build whatever workflow you want on top.
If something on this page disagrees with what the product does, the page is wrong. File an issue and we will fix it.