# Concepts The vocabulary Orbit uses, and what each thing is actually for. If you have used any other issue tracker most of this will be familiar, and the places where Orbit differs are called out. ## Workspace The top level container. A workspace has members, teams, projects, docs, labels and settings, and nothing crosses between workspaces. One workspace per company is the normal setup. You can belong to several and switch between them from the top left, and each keeps its own everything. A workspace can restrict which email domains may join, on top of the server-level `ALLOWED_EMAIL_DOMAINS`. ## Members and roles Everyone in a workspace has one of four roles. Permissions are cumulative, so each role can do everything the one below it can. | Role | Can do | | --- | --- | | **Guest** | Read issues, projects and docs. Comment, react | | **Contributor** | Everything a guest can, plus create and update issues, upload attachments, manage their own views | | **Member** | Everything a contributor can, plus delete issues, delete anyone's comments, manage projects, cycles, milestones, labels, workflows, and write and publish docs | | **Admin** | Everything, plus invite and manage members, manage integrations and manage the workspace | Every authorization decision goes through `packages/shared/src/policy`, which is one file that both the server and the UI read. The server enforces it. The UI uses it to hide buttons you cannot use, never as the only gate. Guests are the useful one to understand: a contractor or a stakeholder can be in the workspace, read the board and comment, without being able to change work. > **Analytics Visibility Rule:** Analytics totals and aggregate charts span the entire workspace for every role (including guests and contributors) to prevent misleading partial dashboards. Issue-level drilldown rows follow team membership and report a withheld count. The longest cycle time list ranks the workspace candidates first, then removes rows outside the reader's team scope and reports how many ranked candidates were withheld. ## Teams Teams are how work is divided, and they own the parts of Orbit that need a boundary. Each team has: - A **key**, two to five letters, which prefixes every issue identifier. The Engineering team's issues are `ENG-1`, `ENG-2` and so on. - Its own **workflow states**. - Its own **sprints and cycles**. - Its own **board and issue list**. The demo workspace seeds Engineering (`ENG`), Design (`DES`) and Marketing (`MKT`). Teams also decide realtime delivery. A project and its milestones carry the scopes of the teams that own them, so a change is only pushed to people entitled to see it. ## Issues The unit of work. An issue has a title, a markdown description, a state, a priority, an assignee, multiple reviewers, labels, an estimate, and relations to other issues. Reviewers are subscribed automatically, and reviewed work appears in their My issues page alongside work assigned to them. Its **identifier** is the team key plus a number, like `ENG-42`. Identifiers are allocated atomically, so two people creating issues at the same moment never collide. Type an identifier in the command palette to jump straight to it. ### States Each state belongs to a category, and the category drives the board columns, progress and analytics. | Category | Meaning | | --- | --- | | Triage | Arrived, not yet decided on | | Backlog | Decided, not scheduled | | Todo | Scheduled, not started | | In Progress | Being worked on | | In Review | Waiting on review | | Done | Finished | | Canceled | Deliberately not doing it | Teams can rename states and add their own, but every state maps to one of these categories, which is what keeps analytics comparable across teams. ### Priority Urgent, High, Medium, Low, or none. Sorting by priority puts unset last, on the grounds that an unprioritised issue is not urgent. ### Relations Issues can block, be blocked by, relate to, or duplicate each other. Blocking is the one that changes behaviour: an issue blocked by another is flagged wherever it appears, so the block is visible before anyone plans around it. ### Duplicate detection When drafting a new issue, Orbit runs trigram similarity across existing issues in the same team. If similar issues already exist, up to four non-blocking suggestions appear beneath the title field with their current workflow state, allowing quick review before creating a duplicate. ### Estimates Points, on the usual scale. Optional. Sprints can track scope by issue count or by points, and analytics shows both. ## Labels Tags with a colour. A label is workspace wide by default, which is what makes it useful for things like `Bug`, `Performance` or `Docs`, and they are the main thing filters and saved views are built from. A label can instead be pinned to one team. A team label is only visible to that team, only pushed over realtime to that team, and only attachable to that team's issues. Pinning a workspace label to a team also takes it off the issues of every other team, so the rule holds for issues that already carried it rather than only for the next edit. Widening a team label back to the workspace touches no issue. Carrying an issue to another team works the same way round: the labels the new team cannot use come off it as it lands, and the workspace-wide ones stay. Manage both under **Settings**, **Labels**. Two labels may share a name when they live in different places, a workspace `Regression` alongside a team `Regression`. The API and the settings screen take ids, so that is unambiguous, but a name given to an MCP tool is not: when more than one label answers to it, the tool refuses and lists the ids rather than picking one. ## Workflow states The columns of a team board. Each one belongs to a single team, carries a position that fixes its place in the order, and carries a **category**, one of `triage`, `backlog`, `unstarted`, `started`, `review`, `completed` or `canceled`. The category is the part the rest of Orbit reads. It is what decides whether an issue counts as open on a sprint burndown, when `startedAt` and `completedAt` are stamped, and which bucket the standup board puts it in. Renaming a status or moving it in the order leaves the category alone; changing the category re-dates every issue sitting in that status, on the server, in the same transaction. Those issues did not move, so how long they have sat where they are is left alone. Deleting a status that still holds issues is refused until you name the status those issues move to, and a team always keeps at least one status. Manage them under **Settings**, **Workflow**. ## Sprints and cycles Timeboxed periods of work belonging to a team. A sprint has a start date, an end date, a set of issues, and a scope measured in issues or points. Orbit uses **sprint** and **cycle** for the same underlying thing. Cycles are the continuous, always-one-running flavour, sprints the named, planned flavour, and both are the same object. What a sprint gives you: - **Scope**, and how it changed after the sprint started. - **Burndown** of remaining work against time. - **Carryover**, meaning what did not finish when you complete the sprint. ### Lead time and cycle time The sprint analytics flow-time card summarizes completed issues associated with the selected sprint. It shows the median (`p50`) and the 85th percentile (`p85`) in calendar days. Unfinished and canceled issues do not contribute a duration. - **Lead time** runs from the issue's creation time to its durable completion time. It starts at creation even when the issue joined the sprint later. - **Cycle time** runs from the issue's `startedAt` time to its durable completion time. Orbit omits an issue from this calculation when it has no start time. Orbit also omits either duration when its end is earlier than its start. If no valid durations remain, the corresponding metric is unavailable. Lead time uses the creation timestamp from the current issue row. Cycle time uses the current mutable `startedAt` column. For an active sprint, Orbit labels that cycle-time coverage `current-column`. For a completed sprint, it labels the coverage `reconstructed-current-column` because close outcomes preserve the completion time but not the first start time. Editing `startedAt` later can therefore change a completed sprint's historical cycle-time distribution. Completing a sprint asks what to do with unfinished issues: move them to the next sprint, or back to the backlog. ## Projects and milestones Projects group related work that does not fit inside one team or one sprint. "Realtime Sync Engine" is a project; it has issues from Engineering and Design, runs across several sprints, and has a lead, a target date and a status. **Milestones** divide a project into stages, so progress is measured against something real rather than a percentage of a moving total. **Health and updates** track qualitative project status over time. An update captures a health category, markdown notes, the author, and a timestamp: - **On track** (`on_track`): The project is progressing according to schedule. - **At risk** (`at_risk`): Blockers, dependency delays, or capacity risks exist. - **Off track** (`off_track`): Key milestones or target dates will be missed without intervention. - **No update** (`no_update`): The initial state before a lead posts the first update. The workspace feed on the Projects page surfaces the latest update from every visible project in a single stream, giving leads and stakeholders visibility across the workspace without having to inspect each project individually. The difference from sprints in one line: a sprint is a period of time, a project is a body of work. An issue is usually in both. ## Docs Markdown documents with a rich editor, or a self-contained HTML page, living beside the issues they describe rather than in a separate tool. - Organised into **collections**, and nestable. - **Visibility** is workspace-wide, private to named people, or a published URL. - **Shareable** through a workspace link that still requires sign-in, or a public or unlisted link for people outside the workspace. Both are the same kind of link, a read only page outside the app, and the share dialog offers the workspace one beside the document link as soon as a doc is shared with the workspace. An HTML page gets its own URL and runs isolated from the app. - Commentable, and searchable alongside issues from the command palette. - Optionally bound to a path in a repository, so a doc can mirror a file. - A fenced `mermaid` block is drawn as a diagram, in the theme's own colours, with the source one click away. The rich editor previews it as you type. - Import a `.md` or `.html` file. HTML stays as one file, not a project. Specs, runbooks, meeting notes and architecture decisions are the things that end up here. ## Standup A Kanban board of the whole workspace. The toolbar has three controls, from left to right: - **AI only** includes work created by, assigned to, reviewed by, commented on, reacted to, or changed by a member marked as an AI agent. Workspace admins set **Member type** to **AI agent** or **Human** in member settings. This classification is specific to the workspace and does not change permissions. - **All work / To review / Assigned** chooses assignments and reviews together, reviewer tasks, or assignments alone. It applies to the member selected in the next control. Pick your name, marked **(You)**, to see your own work. With **All Members**, it includes work for everyone. - **All Members** opens the full member list with workload counts. Pick a person to switch immediately, or choose **All Members** to return to the workspace. Unassigned work is available when present. Hold **Option** and press **Tab** to switch forward, or **Shift+Tab** to switch backward. The member dropdown opens as you switch and closes when you release Option. The shortcuts wrap through the available choices. Filters stay in the URL when you reload or share the view. Counts and filters are calculated by the server across all matching tasks, including tasks beyond the first page. The AI filter combines with the work type, member selection, and standard issue filters. Deleted comments do not count as involvement; recorded issue activity remains part of the history. ## Views and filters A **filter** narrows what you are looking at: team, state, assignee, label, project, sprint, priority, estimate, dates, and combinations of those. A **saved view** is a filter you named and kept. Views are shared with the workspace or private to you, and a private view is delivered to its owner alone over the realtime stream. Views are the thing to reach for when you keep re-applying the same three filters. `Bugs in progress with no assignee` deserves to be a view. ## Inbox and notifications The inbox collects what happened that involves you: assignments, mentions, comments on issues you follow, state changes on work you are watching. It opens on **Activity**, which is everything people did: comments, replies, mentions, reactions, reviews, failed checks, document changes. Issue field moves such as `ENG-3 moved to In Progress` and assignments live on the **Status** tab instead, so a busy board cannot bury a comment. The two tabs are complements, so nothing is hidden, and Unread, Mentions and Pull requests still span both. In-app notification preferences are per event type, with quiet hours that respect your timezone. With conversation reads enabled, each pull request has one inbox row with its comments, reviews, lifecycle updates and current-head check failures in the history. Documents similarly group comments, replies, mentions and changes. Issue activity and issue field changes remain two separate conversations. Unread badges count conversations, not individual events. New activity clears a snooze or dismissal; marking a conversation read covers its existing events. See [Inbox conversations](features/inbox.md) for delivery behavior and rollout. ## Realtime Everything above is live. When someone changes something, the change writes to Postgres, publishes to Redis, and fans out over a websocket to everyone whose scope entitles them to see it. No refresh, no polling. The delivery scope matches the read permission, so a private view goes to its owner alone, and a project belonging to a team goes to that team. If you can see it, you get it live. If you cannot, it never reaches your browser. [Architecture](architecture.md) has the mechanism. ## Keyboard first Orbit assumes you would rather not use the mouse. Cmd K opens the command palette, `g` then a letter navigates, and single keys act on what is selected. Press ? for the list. [Keyboard shortcuts](keyboard-shortcuts.md) has all of them.