g1t/apps/web/app/lib/roadmap.ts
| 1 | /** |
| 2 | * What a project will have and does not yet: the pages the project menu |
| 3 | * shows as Soon, each with a page of its own saying what it will be. One |
| 4 | * place, so the menu and those pages never disagree. |
| 5 | * |
| 6 | * Each entry says what it is for, what it will do, and what to use today, |
| 7 | * so a Soon is a promise someone can read, not a greyed-out word. |
| 8 | */ |
| 9 | |
| 10 | export type RoadmapItem = { |
| 11 | /** In the address: `/<owner>/<project>/soon/<key>`. */ |
| 12 | key: string; |
| 13 | title: string; |
| 14 | /** |
| 15 | * Where it lives: a project page whose tabs it joins, or the workspace, |
| 16 | * for what spans projects (boards, the roadmap, packages, the fleet). |
| 17 | */ |
| 18 | section: "Code" | "Issues" | "Agents" | "Deployments" | "Observability" | "Security" | "Insights" | "Workspace"; |
| 19 | /** One line, for the menu's tooltip and the page's lead. */ |
| 20 | summary: string; |
| 21 | /** Why it matters, in two or three sentences. */ |
| 22 | why: string; |
| 23 | /** What it will do. */ |
| 24 | plans: string[]; |
| 25 | /** What to use until it exists: a project page, by its path under the project. */ |
| 26 | today?: { label: string; path: string }; |
| 27 | }; |
| 28 | |
| 29 | export const ROADMAP: RoadmapItem[] = [ |
| 30 | // --- Work --------------------------------------------------------------- |
| 31 | { |
| 32 | key: "board", |
| 33 | title: "Board", |
| 34 | section: "Workspace", |
| 35 | summary: "Issues and pull requests as a board, a table or a roadmap, with fields of your own.", |
| 36 | why: "One view of everything in flight, arranged the way your team thinks about it. Agents move the cards as they work, so the board is never out of date.", |
| 37 | plans: [ |
| 38 | "Board, table and roadmap views of the same items, saved and shared", |
| 39 | "Custom fields: status, priority, size, iteration, dates, anything", |
| 40 | "Group and filter by owner, outcome, label, agent or state", |
| 41 | "Cards move by themselves as agents open, revise and land changes", |
| 42 | "Across projects: one board can hold work from any of the workspace's projects", |
| 43 | "Attach a board to a project, so it shows on that project too", |
| 44 | ], |
| 45 | }, |
| 46 | { |
| 47 | key: "roadmap", |
| 48 | title: "Roadmap", |
| 49 | section: "Workspace", |
| 50 | summary: "Outcomes on a timeline, with their dependencies across projects.", |
| 51 | why: "An outcome is what should be true when the work is done. On a roadmap you see when each is expected, what it waits on in other projects, and how much has landed.", |
| 52 | plans: [ |
| 53 | "Outcomes as bars on a timeline, from start to target", |
| 54 | "Progress from merged work, not from guesses", |
| 55 | "Dependencies across projects, drawn from the project graph", |
| 56 | "Slip warnings when the work left outgrows the time left", |
| 57 | ], |
| 58 | today: { label: "Outcomes", path: "plans" }, |
| 59 | }, |
| 60 | { |
| 61 | key: "milestones", |
| 62 | title: "Milestones", |
| 63 | section: "Issues", |
| 64 | summary: "Dates to land outcomes by, with what is left and what is at risk.", |
| 65 | why: "A milestone groups the issues that must land together, by a date. g1t shows what remains and which agent or person holds each part.", |
| 66 | plans: [ |
| 67 | "Issues and outcomes grouped under a due date", |
| 68 | "Burn-down from merged pull requests", |
| 69 | "At-risk items flagged before the date, not after", |
| 70 | ], |
| 71 | today: { label: "Issues", path: "issues" }, |
| 72 | }, |
| 73 | |
| 74 | // --- Code --------------------------------------------------------------- |
| 75 | { |
| 76 | key: "branches", |
| 77 | title: "Branches", |
| 78 | section: "Code", |
| 79 | summary: "Every branch: who is on it, how far behind it is, and its preview.", |
| 80 | why: "With agents opening branches by the dozen, a list of names is not enough. Each branch shows its pull request, its checks, its live preview and how stale it is.", |
| 81 | plans: [ |
| 82 | "Branches with their pull request, checks and preview address", |
| 83 | "Ahead and behind the default branch, with one-click catch-up by an agent", |
| 84 | "Protection rules: required checks, reviews and the merge queue", |
| 85 | "Stale branches cleaned up on a schedule you set", |
| 86 | ], |
| 87 | today: { label: "Pull requests", path: "pulls" }, |
| 88 | }, |
| 89 | { |
| 90 | key: "tags", |
| 91 | title: "Tags", |
| 92 | section: "Code", |
| 93 | summary: "Tags, and the releases made from them.", |
| 94 | why: "A tag marks a version of the code. Each links to its release notes and to the deployment that shipped it.", |
| 95 | plans: ["Tags with their commit, release and deployment", "Signed tags verified", "Rules for who may create and move them"], |
| 96 | today: { label: "Commits", path: "commits" }, |
| 97 | }, |
| 98 | { |
| 99 | key: "compare", |
| 100 | title: "Compare", |
| 101 | section: "Code", |
| 102 | summary: "Any two branches, tags or commits, side by side.", |
| 103 | why: "See exactly what changed between two points, with the sessions and pull requests that changed it.", |
| 104 | plans: ["Diff any two refs", "The pull requests and agent sessions between them", "Open a pull request from the comparison"], |
| 105 | today: { label: "Commits", path: "commits" }, |
| 106 | }, |
| 107 | { |
| 108 | key: "docs", |
| 109 | title: "Docs", |
| 110 | section: "Code", |
| 111 | summary: "Pages about the project that agents keep current as the code changes.", |
| 112 | why: "A wiki goes stale the day it is written. g1t's docs live with the code, and when a change makes a page wrong, an agent proposes the fix in the same pull request.", |
| 113 | plans: [ |
| 114 | "Pages written in Markdown, kept in the repository", |
| 115 | "Agents update pages a change makes wrong, in the same pull request", |
| 116 | "Architecture pages drawn from the code itself", |
| 117 | "Search across every project's docs", |
| 118 | ], |
| 119 | today: { label: "Files", path: "code" }, |
| 120 | }, |
| 121 | |
| 122 | // --- Agents ------------------------------------------------------------- |
| 123 | // At work, Sessions and Memory are built (see project-nav.ts), and so is |
| 124 | // the workspace's Agent fleet. |
| 125 | { |
| 126 | key: "playbooks", |
| 127 | title: "Playbooks", |
| 128 | section: "Agents", |
| 129 | summary: "How agents should work here: conventions, commands and checks.", |
| 130 | why: "Every project has its own way of doing things. Today every agent run already reads the repository's AGENTS.md and CLAUDE.md, at the root and in the directories it touches, and reviews read .g1t/review.md, all from the default branch. Playbooks build on those files with structure g1t can act on, not just read.", |
| 131 | plans: [ |
| 132 | "Instructions per kind of work: fixes, features, reviews, upgrades", |
| 133 | "Commands to build and test that g1t runs before every change, not just tells the agent about", |
| 134 | "Paths agents may not touch without a person, enforced on push", |
| 135 | "Learned from reviews: what people corrected becomes a proposed rule", |
| 136 | ], |
| 137 | today: { label: "Instructions, on Agents", path: "agents" }, |
| 138 | }, |
| 139 | |
| 140 | // --- Deployments ---------------------------------------------------------- |
| 141 | { |
| 142 | key: "environments", |
| 143 | title: "Environments", |
| 144 | section: "Deployments", |
| 145 | summary: "Staging, production and others, with approvers and branch rules.", |
| 146 | why: "Production and previews exist today. Environments add the rest: staging, QA, per-customer, each with its own variables, approvers and rules for what may deploy there.", |
| 147 | plans: [ |
| 148 | "Named environments with their own variables and secrets", |
| 149 | "Required approvers before a deploy", |
| 150 | "Branch rules: what may deploy where", |
| 151 | "Promote a deployment from one environment to the next", |
| 152 | ], |
| 153 | today: { label: "Deployments", path: "deployments" }, |
| 154 | }, |
| 155 | { |
| 156 | key: "releases", |
| 157 | title: "Releases", |
| 158 | section: "Deployments", |
| 159 | summary: "Tagged releases with notes written from what landed.", |
| 160 | why: "Release notes from the pull requests and sessions that made the release: what changed, why, and who or what changed it.", |
| 161 | plans: ["Notes drafted from merged work", "Assets and checksums attached", "Published to the project's page and a feed"], |
| 162 | today: { label: "Commits", path: "commits" }, |
| 163 | }, |
| 164 | { |
| 165 | key: "packages", |
| 166 | title: "Packages", |
| 167 | section: "Workspace", |
| 168 | summary: "The workspace's package registry: npm, containers and more.", |
| 169 | why: "Publish packages from workflows to g1t's registry, with the same access as the code.", |
| 170 | plans: ["npm, OCI containers, Cargo, PyPI and Go modules", "Published from any project's workflows", "Private packages for the workspace"], |
| 171 | }, |
| 172 | { |
| 173 | key: "flags", |
| 174 | title: "Feature flags", |
| 175 | section: "Deployments", |
| 176 | summary: "Turn features on per environment or per user, without a deploy.", |
| 177 | why: "Ship code dark and turn it on when ready, for some users first, at the edge, with no deploy.", |
| 178 | plans: ["Flags read at the edge by deployed apps", "Rollouts by percentage, user or environment", "Flags cleaned up by agents when fully on"], |
| 179 | today: { label: "Deployments", path: "deployments" }, |
| 180 | }, |
| 181 | |
| 182 | // --- Security ------------------------------------------------------------- |
| 183 | // The overview, secret scanning and dependency upkeep are built: see |
| 184 | // routes/repo/security.tsx. |
| 185 | { |
| 186 | key: "code-scanning", |
| 187 | title: "Code scanning", |
| 188 | section: "Security", |
| 189 | summary: "Code scanned for vulnerabilities on every change.", |
| 190 | why: "Scanning on every pull request, with findings explained in the review and fixed by the author's agent.", |
| 191 | plans: ["Static analysis on every pull request", "Findings in the review, with a fix", "Baselines so only new findings block"], |
| 192 | }, |
| 193 | { |
| 194 | key: "firewall", |
| 195 | title: "Firewall", |
| 196 | section: "Security", |
| 197 | summary: "Rules for who may reach the project's deployed apps.", |
| 198 | why: "Deployed apps run on Cloudflare. Rate limits, bot protection and IP rules, per app and environment.", |
| 199 | plans: ["Rate limits and bot protection", "IP and country rules", "Password-protected previews"], |
| 200 | today: { label: "Deployments", path: "deployments" }, |
| 201 | }, |
| 202 | |
| 203 | // --- Observe ------------------------------------------------------------ |
| 204 | { |
| 205 | key: "logs", |
| 206 | title: "Logs", |
| 207 | section: "Observability", |
| 208 | summary: "Requests, errors and CPU time of each deployment, and its logs.", |
| 209 | why: "Every deployed app's logs and numbers, by deployment, so a regression points at the change that caused it.", |
| 210 | plans: ["Live and searchable logs", "Requests, errors, latency and CPU by deployment", "Compare a preview with production"], |
| 211 | today: { label: "Deployments", path: "deployments" }, |
| 212 | }, |
| 213 | { |
| 214 | key: "errors", |
| 215 | title: "Errors", |
| 216 | section: "Observability", |
| 217 | summary: "Errors from the running app, each becoming an issue an agent can take.", |
| 218 | why: "An error in production should become a fix, not a dashboard. Each new error is grouped, explained, and turned into an issue with the context an agent needs.", |
| 219 | plans: ["Errors grouped with stack and request", "One click to an issue for an agent", "Incidents with a timeline and who was told"], |
| 220 | today: { label: "Issues", path: "issues" }, |
| 221 | }, |
| 222 | { |
| 223 | key: "uptime", |
| 224 | title: "Uptime", |
| 225 | section: "Observability", |
| 226 | summary: "Checks that the app answers, from around the world.", |
| 227 | why: "Know the app is down before your users tell you, and who was told.", |
| 228 | plans: ["Checks from many places", "Alerts by email and webhook", "A public status page"], |
| 229 | }, |
| 230 | { |
| 231 | key: "analytics", |
| 232 | title: "Web analytics", |
| 233 | section: "Observability", |
| 234 | summary: "Who visits the deployed apps, without cookies.", |
| 235 | why: "Visits, pages and referrers for each app, private by design, from Cloudflare's own analytics.", |
| 236 | plans: ["Visits, pages, referrers and countries", "No cookies, no personal data", "Per deployment and per preview"], |
| 237 | }, |
| 238 | |
| 239 | // --- Insights ------------------------------------------------------------- |
| 240 | { |
| 241 | key: "delivery", |
| 242 | title: "Delivery", |
| 243 | section: "Insights", |
| 244 | summary: "Lead time, deploy frequency, change failure rate and time to restore.", |
| 245 | why: "The four numbers that say how well a team ships, measured from what actually happened in g1t.", |
| 246 | plans: ["DORA metrics from merges and deployments", "Review and queue time", "Trends by week and by project"], |
| 247 | }, |
| 248 | { |
| 249 | key: "costs", |
| 250 | title: "Costs", |
| 251 | section: "Insights", |
| 252 | summary: "What the project costs, by agent run, sandbox, build and app.", |
| 253 | why: "Usage is charged by the workspace; here it is broken down for one project, so you can see what each part of the work costs.", |
| 254 | plans: ["Cost by kind of work and by issue", "Cost per merged change", "Budgets per project"], |
| 255 | }, |
| 256 | { |
| 257 | key: "impact", |
| 258 | title: "Agent impact", |
| 259 | section: "Insights", |
| 260 | summary: "How much of the work agents do, and how well.", |
| 261 | why: "The share of changes agents author, how often their work lands first time, and where people still step in.", |
| 262 | plans: ["Agents' share of merged changes", "First-time pass rate of checks and reviews", "Where people correct agents most"], |
| 263 | }, |
| 264 | ]; |
| 265 | |
| 266 | export function roadmapItem(key: string): RoadmapItem | undefined { |
| 267 | return ROADMAP.find((item) => item.key === key); |
| 268 | } |
| 269 | |
| 270 | export function roadmapIn(section: RoadmapItem["section"]): RoadmapItem[] { |
| 271 | return ROADMAP.filter((item) => item.section === section); |
| 272 | } |