02 KYRO
Case file 02
A Linear-style issue tracker, built to try ideas
KYRO is an issue tracker I built for myself: issues and projects, human-readable keys like ENG-42, a drag-and-drop board, sprints, and a home page for what to do next. The point is to try new ideas and see how a tracker could be more useful.
- Year
- 2026
- Role
- Solo: product, design, code
- Stack
- Next.js, Supabase, Drizzle
- Built in
- 32 commits, 10 PRs
- Status
- Live

Why
A playground for my own ideas: what would make an issue tracker more useful?
What I built
Issues, projects, a kanban board, workspaces with invites, sprints that roll forward on their own, and a Mine / Team home.
Where it is
Live, with open sign-up. Anyone can create a workspace and try it.
Why it exists
A tracker nobody asked for
I'm the only user. KYRO is where I try out ideas and see what makes a tracker more useful.
Placeholder: what got you started, and what you wanted to explore that existing trackers didn't give you.
Key decisions
The calls behind the features
From the decision log I kept while building, written down after each feature shipped.
decision 1
How should sprints start and roll forward?
A background cron job
The app has no job runner or queue to run it on.
Reconcile when a page loadswent with this
The same way the current cycle was already worked out live elsewhere in the app.
An admin sets a cadence once (for example, 2-week sprints starting Monday). On page load, the app tops up the queue of planned sprints and activates the one that's due. Activation uses up a planned slot, so it generates, activates, then generates again to keep the count right.
The costNo true background schedule. A Vercel Cron upgrade is noted for later, not built.
decision 2
Should an overdue sprint close itself?
Auto-complete it
Its unfinished issues would be dealt with without anyone deciding.
A person completes itwent with this
Move unfinished issues to the next sprint, back to the backlog, or review them one by one.
Completing a sprint needs a human decision about the issues that didn't get done, so reconciliation activates sprints but never completes one.
decision 3
Who can configure sprints and see the Team view?
A new Team entity or capability flag
A much larger, separate piece of work.
The existing owner and admin roleswent with this
Reused for both sprint settings and Team visibility.
The app has no finer-grained permission system yet to extend, and building one was out of scope.
decision 4
What about mock-up buttons with nothing behind them?
Half-build them
Nudge, Escalate, Reassign, Rebalance and Assign would ship as dead clicks.
Skip them entirelywent with this
Leave them out until the workflows exist.
They implied workflows this app doesn't have, like notifications or escalation.
decision 5
Blocked tickets: ship the schema now and the UI later?
Schema only, populate later
Smaller change now.
A minimal mark and clear control nowwent with this
Plus a blocked reason and date on each issue.
Without a way to mark an issue blocked, the Blocked section could never show real data. It's a new flag: the existing “blocks” relation between issues is a different concept.
decision 6
Ticket detail: replace the full page with a side panel?
Replace the full page
One way to see a ticket.
Add a panel alongside itwent with this
The full page stays, reachable from an “Open full page” link in the panel.
The full page's data fetching was pulled out into one shared module, so the page and the panel use the same source of truth. Checking one ticket no longer means leaving Home.
decision 7
Advanced fields when creating an issue: collapsed or visible?
Collapsed under “Advanced”
What the spec said.
Every field visiblewent with this
Estimate, due date, cycle, milestone, parent, relations and attachments, all on the form.
I reversed my own spec mid-build. Placeholder: why visible won.
Honest substitutes
When the mock-up wanted data the app didn't have
The Home redesign mock-up had fields with nothing real behind them. Each got an honest substitute instead of made-up numbers.
Points added mid-sprint
Approximated from each issue's creation date compared with the sprint's start date.
Reviews waiting
The app has no review concept, so it became a “stuck” signal: issues sitting idle in progress.
On leave
Dropped entirely. Nothing in the app tracks leave.
How it got built
Spec, plan, decision log, then code
Each big feature started as a spec file. PLAN.md tracked what was built and what's next, and FEATURE_LOG.md recorded why.
2–3 Jul 2026
The core tracker
Issue keys and numbering, the issues list and creation, issue detail with inline edits and comments, projects, the kanban board and the home briefing. Then members and invites, with an invitation-received UI (PR #3, #4).
5 Jul 2026
Multiple workspaces
The multiple-workspaces feature and a workspaces page (PR #5).
8–9 Jul 2026
Theme, advanced create and profiles
Advanced issue creation, user profiles with onboarding, then logos and a switch to a green theme (PR #6, #7).
24 Aug 2026
Sprints
Cadence settings, a sprints hub and a planning board with bulk assign (PR #8).
6 Sep 2026
Home redesign
Mine and Team views, the ticket side panel, keyboard shortcuts, and a new background on the top section (PR #9, #10).
What broke
Bugs worth remembering
The panel wouldn't close
Closing updated local state, but the URL never changed: router.push silently did nothing on a search-param-only change. Switched to router.replace, which also keeps panel toggles out of browser history.
Out of database connections
postgres.js opens 10 connections per process and the Supabase session pooler allows 15 in total, so dev, prod and scripts ran it out. Capped the pool at 5.
Dates broke raw SQL
Raw SQL fragments threw on Date parameters with prepare turned off. They now bind ISO strings.
The product
What it looks like







Still open
Known gaps
- 01
Board order
Board positions are fractional numbers that need renormalizing after many drops in the same slot. Not built yet.
- 02
Pagination
Nothing past 100 issues in the list or 300 on the board.
- 03
Issue key prefix
Taken from the workspace name, and not yet editable in settings.
- 04
Scheduled sprints
Sprints roll forward on page load; a Vercel Cron job is the noted upgrade.
What I learned
What I learned
Placeholder: what building KYRO taught you, and what you'd try next.
