Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
150 commits
Select commit Hold shift + click to select a range
5ba016a
Add the initiatives and initiative_projects tables
jarstelfox Oct 12, 2026
3e78648
Teach the shared model initiatives and not tracked
jarstelfox Oct 12, 2026
7f63ebc
Carry a project's filing through a label rename
jarstelfox Oct 12, 2026
d0957ea
Add initiatives storage and their write routes
jarstelfox Oct 12, 2026
04a19f0
Leave not-tracked projects out of what counts
jarstelfox Oct 12, 2026
2fab6c3
Read initiatives on the board, tracked by default
jarstelfox Oct 12, 2026
5a20ee9
Ask on Decide where each project belongs
jarstelfox Oct 12, 2026
aaba84d
Group the Overview by initiative
jarstelfox Oct 12, 2026
b8b176f
Lay the Roadmap out in initiative lanes
jarstelfox Oct 12, 2026
7c2a6db
Record the initiative lane amendments
jarstelfox Oct 12, 2026
44f42bc
Share one going rule and one tracking read
jarstelfox Oct 12, 2026
8f71dd8
Ask about initiatives once per project row
jarstelfox Oct 12, 2026
5ced2a9
Number lane rows and open linked lanes
jarstelfox Oct 12, 2026
b4920c3
Keep an asked initiative's band on the Overview
jarstelfox Oct 12, 2026
e52d98e
Split Unsorted from one-offs in Look back
jarstelfox Oct 12, 2026
586a9cd
Record lane numbering and the Unsorted word
jarstelfox Oct 12, 2026
49334b1
Count a filing as settling in goal_reached
jarstelfox Oct 12, 2026
e3cee2d
Load the roadmap when initiatives can't be read
jarstelfox Oct 12, 2026
05c0cf8
Test the close guard's open-PR branch
jarstelfox Oct 12, 2026
3b1f9ea
Push onto lists instead of copying them
jarstelfox Oct 12, 2026
b107035
Move Decide's question model and the lanes out
jarstelfox Oct 12, 2026
c1d1894
Say order as "priority", in the row's own number
jarstelfox Oct 12, 2026
dce2b74
Draw a lane's priority receipt once
jarstelfox Oct 12, 2026
9db0edd
Refuse a drag of a plan with no project to a lane
jarstelfox Oct 12, 2026
0a091e2
Count weeks past and say a close one way
jarstelfox Oct 12, 2026
0690caf
Make "Initiative page" a real link
jarstelfox Oct 12, 2026
d2c9395
Test a plan that fails after its filing saved
jarstelfox Oct 12, 2026
10f4598
Key Unsorted and no-project plans off the slugs
jarstelfox Oct 12, 2026
7de77c7
Word every Undo as "Put X back"
jarstelfox Oct 12, 2026
6709928
Test the Roadmap's initiative lanes
jarstelfox Oct 12, 2026
c186ae4
Name a closed initiative first on every view
jarstelfox Oct 12, 2026
17e93e6
Keep a project in sight after its home is answered
jarstelfox Oct 12, 2026
b8e0ddb
File where each row's chooser says, in bulk too
jarstelfox Oct 12, 2026
cf6ad23
Keep Track it in place and focus its chooser
jarstelfox Oct 12, 2026
53f3843
One gloss and one Move on a project's page
jarstelfox Oct 12, 2026
0e26b35
Name a guessed lead on an initiative's page
jarstelfox Oct 12, 2026
baeeea6
Show asked plans under Now on Now/next/later
jarstelfox Oct 12, 2026
16dbafb
Align Not tracked's band and record the words
jarstelfox Oct 12, 2026
cff6e72
Refuse filing into a closed initiative
jarstelfox Oct 12, 2026
735d32e
Test the roadmap reads initiatives again
jarstelfox Oct 12, 2026
00d0d26
Ask about a home on the project's worst row
jarstelfox Oct 12, 2026
912addc
Count Decide's heading as its sections count
jarstelfox Oct 12, 2026
4970d63
Unmount the new UI tests' React roots
jarstelfox Oct 12, 2026
1d7337d
Refuse a plan dropped on a closed lane
jarstelfox Oct 12, 2026
1c2f00c
Hold a Roadmap Undo's words where it was
jarstelfox Oct 12, 2026
417fa34
Hold a Decide row's Undo words in place
jarstelfox Oct 12, 2026
7dae7cc
Carry a home pick only while its chooser shows
jarstelfox Oct 12, 2026
421968f
Say File for filing, on every view
jarstelfox Oct 12, 2026
b911620
Say a promised end one way everywhere
jarstelfox Oct 12, 2026
591d151
Name each answer by the words it shows
jarstelfox Oct 12, 2026
c861151
Say where a Link put the plan, by its project
jarstelfox Oct 12, 2026
2c5233a
Open what a row's question or clash names
jarstelfox Oct 12, 2026
d86d639
Leave the focus off a linked plan's ends
jarstelfox Oct 12, 2026
aba585e
Keep a lane's grip on its label's line
jarstelfox Oct 12, 2026
df3f99c
Plain words for a band's count and a bad link
jarstelfox Oct 12, 2026
06993aa
Record round 3's rules in DESIGN.md
jarstelfox Oct 12, 2026
fb4a619
Ignore a home pick that is no longer offered
jarstelfox Oct 12, 2026
dfbc0de
Keep a home Undo's row where it was asked
jarstelfox Oct 12, 2026
08eec29
Leave j and k on the answer after an Undo
jarstelfox Oct 12, 2026
1ca8304
Ask the browser whether the page was handled
jarstelfox Oct 12, 2026
14eff97
Hold the project page's Undo words at once
jarstelfox Oct 12, 2026
73b5c0f
Read initiatives again on a closed 409
jarstelfox Oct 12, 2026
cb4845b
Document the closed 409 and the undo set_at
jarstelfox Oct 12, 2026
af12e92
Type the Roadmap's run of moves
jarstelfox Oct 12, 2026
f5f8b7a
Say a band's end counts in one place
jarstelfox Oct 12, 2026
88fe363
Drop a cast from a clash's click
jarstelfox Oct 12, 2026
51464ef
Test the closed 409 reload and early Undo words
jarstelfox Oct 12, 2026
8a82beb
File from a plan's details with a receipt and Undo
jarstelfox Oct 12, 2026
61677f8
Hold a drop's Undo words under the pointer
jarstelfox Oct 12, 2026
0cc85e1
Open a question's details on its Plan line
jarstelfox Oct 12, 2026
fcbfcc4
Keep Other answers reachable by Tab
jarstelfox Oct 12, 2026
ea4b408
One chooser for filing, on every view
jarstelfox Oct 12, 2026
a29da1a
Close the innermost thing on Escape
jarstelfox Oct 12, 2026
1b6108b
Offer Not tracked when filing a reopen elsewhere
jarstelfox Oct 12, 2026
92ca1b1
Say a Restart restarted
jarstelfox Oct 12, 2026
32ec678
Say an initiative's empty and reopened ends once
jarstelfox Oct 12, 2026
19253a7
Name a Roadmap question by the words it shows
jarstelfox Oct 12, 2026
960f12e
Start every band's detail at one x on a phone
jarstelfox Oct 12, 2026
a18c17f
Ask Still not tracked? in the Not tracked lane
jarstelfox Oct 12, 2026
7922eb7
Record round 4's rules in DESIGN.md
jarstelfox Oct 12, 2026
22806f8
Count reads after earlier tests' reads land
jarstelfox Oct 12, 2026
abc1600
Hold Undo's words through a later shift too
jarstelfox Oct 12, 2026
8cfd786
Guard a still pointer after every click
jarstelfox Oct 12, 2026
9b8ce25
Open File elsewhere below its home everywhere
jarstelfox Oct 12, 2026
aeb561c
Land j and k on a row that can take the focus
jarstelfox Oct 12, 2026
31d087b
Say why an Undo failed, and keep it to retry
jarstelfox Oct 12, 2026
0695daa
Test Track it's and a reopen's filing to the write
jarstelfox Oct 12, 2026
2e4498d
Ask a project's question on one plan, once
jarstelfox Oct 12, 2026
b980ab4
Close Other answers before Cancel on Escape
jarstelfox Oct 12, 2026
c04bc49
Let a wrapped answer button grow to fit
jarstelfox Oct 12, 2026
4127808
Lay out the Overview's initiative bands as the Roadmap's
jarstelfox Oct 12, 2026
bb598c8
Give Link the File in chooser's layout
jarstelfox Oct 12, 2026
548eefb
Keep one Undo for a run of lane moves
jarstelfox Oct 12, 2026
0a328af
Say where Now, next, later's asked Not tracked plans are
jarstelfox Oct 12, 2026
ff2bea4
Offer filing once in a plan's details
jarstelfox Oct 12, 2026
836abd7
Say Cleared when an edit empties a field
jarstelfox Oct 12, 2026
8804177
Say what Decide's Initiative switch counts
jarstelfox Oct 12, 2026
c2ce1a2
Line up a lane's unplanned names with its plans'
jarstelfox Oct 12, 2026
2508cb4
Record round 5's rules in DESIGN.md
jarstelfox Oct 12, 2026
6e60167
Never drop a row's focus on an answer that's off
jarstelfox Oct 12, 2026
7071f71
Show a receipt's row with it, not under a header
jarstelfox Oct 12, 2026
e7d6ffe
Let only a person's click start or end a hold
jarstelfox Oct 12, 2026
d421a37
Judge a press by when it was made
jarstelfox Oct 12, 2026
e695310
Remove a stray copy of HomeCalls' tests
jarstelfox Oct 12, 2026
cd53db6
Guard only what came under a still pointer
jarstelfox Oct 12, 2026
2f5d82c
Drop a Roadmap refocus at the next action
jarstelfox Oct 12, 2026
f81a986
Keep j and k off fields and aria-disabled answers
jarstelfox Oct 12, 2026
24de723
Say "to decide" in Decide's Initiative switch
jarstelfox Oct 12, 2026
8513dcc
Open Decide from an initiative's questions
jarstelfox Oct 12, 2026
634cb2e
Focus Other answers' first label, not an answer
jarstelfox Oct 12, 2026
a818530
Name every Undo by what it takes back
jarstelfox Oct 12, 2026
32cfc51
Say "marked Not tracked", not "set not tracked"
jarstelfox Oct 12, 2026
88064ef
Put both choosers' labels above on a phone
jarstelfox Oct 12, 2026
721c790
Refuse a bar let go over another lane
jarstelfox Oct 12, 2026
b06522a
Ask the goal question as a Roadmap row does
jarstelfox Oct 12, 2026
0d8bca7
Say "marked Not tracked" in every receipt too
jarstelfox Oct 12, 2026
7da7226
Record round 6's rules in DESIGN.md
jarstelfox Oct 12, 2026
9f10e2c
Keep one of each special home, never closed
jarstelfox Oct 12, 2026
e7a8beb
Stop a test helper leaking a rect stub
jarstelfox Oct 12, 2026
72a253e
Keep a bar's date change over another lane
jarstelfox Oct 12, 2026
6efd2ac
Judge a pressed control before its box moves
jarstelfox Oct 12, 2026
f9bd29d
Say Marked Not tracked on every view
jarstelfox Oct 12, 2026
d85f1ce
Mark the Roadmap's goal guess Suggested
jarstelfox Oct 12, 2026
62d27c4
Ask Unsorted's question in its Plan cell
jarstelfox Oct 12, 2026
f9d7c4d
Dim a kept control instead of outlining it
jarstelfox Oct 12, 2026
ea787d9
Record round 7's rules in DESIGN.md
jarstelfox Oct 12, 2026
bafc86f
Keep drafts out of every Projects count
jarstelfox Oct 12, 2026
627591a
Fold a project's drafts at the end of its PRs
jarstelfox Oct 12, 2026
098b6e0
Keep drafts one click away across the tab
jarstelfox Oct 12, 2026
247de07
Show drafts on the fake board
jarstelfox Oct 12, 2026
b3a0d9d
Record the draft rule in DESIGN.md
jarstelfox Oct 12, 2026
5fb32df
Merge remote-tracking branch 'origin/master' into initiatives
jarstelfox Oct 12, 2026
f92aab2
Pick the months the roadmap shows
jarstelfox Oct 14, 2026
f2624d5
Show a year of plans on the fake board
jarstelfox Oct 14, 2026
2716e08
Fix the roadmap window's review findings
jarstelfox Oct 14, 2026
d2c1988
Merge remote-tracking branch 'origin/master' into initiatives
jarstelfox Oct 20, 2026
30b9afd
Require sign-in to read initiatives
jarstelfox Oct 20, 2026
0c1ec32
Keep a filing through a case-only label rename
jarstelfox Oct 20, 2026
fa610d3
Make initiative filings honest and race-free
jarstelfox Oct 20, 2026
ad6d2c3
Count a draft from the day it's marked ready
jarstelfox Oct 20, 2026
4c0b0f4
Fix the initiative page and Overview bug-hunt items
jarstelfox Oct 20, 2026
83acb4f
Let Undo reopen work, and roll back one write
jarstelfox Oct 20, 2026
c547f34
Check every view key and the URL's week, group, years
jarstelfox Oct 20, 2026
74f2c70
Fix the Roadmap bug-hunt items
jarstelfox Oct 20, 2026
a1b008f
Speed up the Roadmap at prod scale
jarstelfox Oct 20, 2026
c545490
Close the remaining server gaps from round two
jarstelfox Oct 20, 2026
ac0fba0
Count what's left to decide the same everywhere
jarstelfox Oct 20, 2026
e82e8e4
Hold Roadmap rows where they were drawn
jarstelfox Oct 20, 2026
aa8164f
Limit the write chain, not every query
jarstelfox Oct 20, 2026
0a0d968
Serialize a plan edit that changes its project
jarstelfox Oct 20, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
221 changes: 208 additions & 13 deletions DESIGN.md

Large diffs are not rendered by default.

13 changes: 10 additions & 3 deletions app.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ import statsController from './controllers/stats.js';
import userNamesController from './controllers/user-names.js';
import projectsController from './controllers/projects.js';
import roadmapController, { canWrite, forgetProjectCaches } from './controllers/roadmap.js';
import { API_ROUTES, apiIndex } from './controllers/api-routes.js';
import initiativesController from './controllers/initiatives.js';
import { API_ROUTES, PROJECT_WRITES, apiIndex } from './controllers/api-routes.js';
import settingsController from './controllers/settings.js';
import { syncRepoIssues } from './lib/project-issue-sync.js';
import { loadSettingsWithRetry } from './lib/settings.js';
Expand Down Expand Up @@ -107,8 +108,6 @@ function projectsChanged() {
forgetProjectCaches();
pullManager.projectsChanged();
}
// every write the Projects tab can see
const PROJECT_WRITES = ['/project-issues', '/roadmap', '/settings', '/api/v1/project-issues', '/api/v1/roadmap', '/api/v1/settings'];
app.use(PROJECT_WRITES, function (req, res, next) {
if (req.method !== 'GET') {
res.on('finish', function () {
Expand All @@ -130,6 +129,14 @@ app.delete('/roadmap/:id', canWrite, roadmapController.remove);
app.get('/roadmap/:id/updates', roadmapController.updates);
app.post('/roadmap/:id/updates', canWrite, roadmapController.postUpdate);
app.delete('/roadmap/:id/updates/:update', canWrite, roadmapController.removeUpdate);
// initiatives, the layer above projects: read like the roadmap, written
// behind canWrite, every route under /initiatives (PROJECT_WRITES)
app.get('/initiatives', initiativesController.list);
app.post('/initiatives', canWrite, initiativesController.create);
app.put('/initiatives/file', canWrite, initiativesController.file);
app.patch('/initiatives/:id', canWrite, initiativesController.update);
app.delete('/initiatives/:id', canWrite, initiativesController.remove);
app.post('/initiatives/:id/move', canWrite, initiativesController.move);
app.get('/settings', settingsController.get);
app.patch('/settings', canWrite, settingsController.update);
app.post('/hooks/main', hooksController.main);
Expand Down
2 changes: 2 additions & 0 deletions bin/dump-schema
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ mysqldump "$@" \
project_issues \
issue_pull_links \
project_settings \
initiatives \
initiative_projects \
> $SCHEMA_FILE

sed -i -e "s/CREATE TABLE/CREATE TABLE IF NOT EXISTS/" $SCHEMA_FILE
5 changes: 5 additions & 0 deletions config.example.js
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,11 @@ module.exports = {
developerTeams: {
Store: ['login1', 'login2'],
},
// Repos whose projects are Not tracked until someone files them in an
// initiative: a project whose every labeled PR is in one of these
// leaves Decide, the counts and capacity. One PR in another repo ends
// it. Omit or [] for none.
// untrackedRepos: ['owner/ops'], // or just 'ops'
},

// The usual MySQL stuff. Like every other MySQL webapp, basically.
Expand Down
113 changes: 106 additions & 7 deletions controllers/api-routes.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import apiController from './api.js';
import initiativesController from './initiatives.js';
import projectsController from './projects.js';
import roadmapController, { canWrite } from './roadmap.js';
import settingsController from './settings.js';
Expand All @@ -13,11 +14,29 @@ import {
ROADMAP_ORIGINS,
ROADMAP_STATUSES,
DECIDE_MIN_PRS,
GROWTH_FLOOR,
INITIATIVE_GOAL_MAX,
INITIATIVE_KINDS,
INITIATIVE_NAME_MAX,
INITIATIVE_STATUSES,
STALL_DAYS,
UPDATE_DUE_DAYS,
WAITS_ON_MAX,
} from '../shared/dist/index.js';

/** Every write the Projects tab can see, board and API (app.js): each one
* that succeeds has open boards fetch again. */
export const PROJECT_WRITES = [
'/project-issues',
'/roadmap',
'/initiatives',
'/settings',
'/api/v1/project-issues',
'/api/v1/roadmap',
'/api/v1/initiatives',
'/api/v1/settings',
];

/**
* Every /api/v1 route in one table. app.js registers them from it, and
* GET /api/v1 lists it, so a script (or an agent) reading the list can't
Expand Down Expand Up @@ -47,7 +66,9 @@ export const API_ROUTES = [
'ready to merge, on hold, waiting on review, being worked on), and its numbers for ' +
'?start=&end= (YYYY-MM-DD days, default the last 30); ?project=<slug> narrows the numbers to one. ' +
'A PR counts toward its project label, or with none the project whose issue it links; ' +
'`double_labeled` holds the open PRs in two',
'`double_labeled` holds the open PRs in two. Each project says its `initiative` (slug, or null for ' +
'Unsorted), whether it is `tracked`, and whether it `grew` while not tracked. A project Not tracked because ' +
'its PRs are all in projects.untrackedRepos has `initiative: null` with `tracked: false`',
},
{
method: 'get',
Expand Down Expand Up @@ -122,15 +143,16 @@ export const API_ROUTES = [
`A plan whose PRs merged in the last ${UPDATE_DUE_DAYS} days, inside its issues' pace and, for a hard ` +
'end, inside its end, owes none, unless its last update said at risk or off track, or its open PRs ' +
`pile up: ${PILE_MIN} or more that grew by ${PILE_GROWTH} in ${UPDATE_DUE_DAYS} days, or whose median ` +
`age passed ${PILE_AGE_DAYS} days`,
`age passed ${PILE_AGE_DAYS} days. Not-tracked projects owe none`,
},
{
method: 'get',
path: '/api/v1/decide',
handlers: [projectsController.getDecide],
does:
'The decisions owed now, worst first, each with its project, roadmap item, and reasons (see ' +
'`decide`); days are the team’s (config.js projects.timeZone, default America/Los_Angeles)',
'The decisions owed now, worst first, each with its project, roadmap item, `initiative` (its home, or ' +
'the one asked about), and reasons (see `decide`); days are the team’s (config.js projects.timeZone, ' +
'default America/Los_Angeles). Not-tracked projects are left out, but for the ones that grew',
},
{
method: 'get',
Expand All @@ -139,7 +161,7 @@ export const API_ROUTES = [
does:
'Projects in flight each week against the developer count, on the roadmap (split by where the ' +
'work came from) and not; weeks after this one as if nothing changes. ?start=&end= (default 12 ' +
'weeks back to 26 ahead)',
'weeks back to 26 ahead). Not-tracked projects are left out',
},
{
method: 'get',
Expand All @@ -152,7 +174,8 @@ export const API_ROUTES = [
'What the board reads off them: `in_progress` (marked so, or planned with PRs moving since its ' +
'start, which the board shows as In progress) and `standing`, where its updates stand: `owed` ' +
'(its lead owes one), `vouched` (none owed: its PRs vouch for it), `current` (its latest stands), ' +
'or null (none yet, none owed)',
'or null (none yet, none owed). `untracked`: its project is Not tracked, so it owes nothing and ' +
'counting views leave it out',
},
{
method: 'post',
Expand Down Expand Up @@ -216,6 +239,63 @@ export const API_ROUTES = [
'Take back an update you posted; returns the latest update now ({update}, null with none). ' +
"403 for someone else's",
},
{
method: 'get',
path: '/api/v1/initiatives',
handlers: [initiativesController.list],
does:
'Every initiative in rank order (top first): slug, name, goal, owner, kind (`initiative`, `upkeep` for ' +
'Keep the lights on, `untracked` for Not tracked), status and `status_at`, the projects filed in it ' +
'(`projects`: each `{project, set_by, set_at, baseline_prs}`) and `span`, read off their plans: the earliest start, ' +
'the latest end under way, how many plans under way have an end or none, and `end_kind` (soft, ongoing, ' +
'or ended on `ended`). A project with no filing is Unsorted',
},
{
method: 'post',
path: '/api/v1/initiatives',
handlers: [canWrite, initiativesController.create],
does:
'Add an initiative, ranked last: {slug, name, goal?, owner?, kind?}; 409 when the slug is taken, or ' +
'when one of kind upkeep or untracked already exists (there is one of each)',
},
{
method: 'put',
path: '/api/v1/initiatives/file',
handlers: [canWrite, initiativesController.file],
does:
'File a project: {project, initiative: <slug> or null for none, expect?, baseline_prs?, set_at?, undo?}. ' +
'`expect` is the home you saw (a slug or null); 409 with the current `home` when it changed. 409 when ' +
'the initiative is closed, unless it is an undo (`undo: true`, or `set_at` sent). null is a 409 for a ' +
'project Not tracked because its PRs are all in projects.untrackedRepos, unless it is an undo. ' +
'Answers `project` as its label spells it, `before` and `home` (initiative, set_by, set_at, ' +
'baseline_prs); undo by sending `before` back with its set_at, baseline_prs and `undo: true`. ' +
'Into Not tracked with no baseline_prs, the count is its old baseline plus the PRs since (when it was ' +
'already not tracked), else its PR count now',
},
{
method: 'patch',
path: '/api/v1/initiatives/:id',
handlers: [canWrite, initiativesController.update],
does:
'Change its name, goal, owner or status (open, done, dropped). Only kind `initiative` closes (409 for ' +
'upkeep and untracked). Closing is a 409 naming the projects in it ' +
'still going (`live`: a plan under way or open PRs). {status: "open", restate: true} is Keep open; ' +
'{undo: {updated_at, status_at}} puts back the times a change replaced',
},
{
method: 'delete',
path: '/api/v1/initiatives/:id',
handlers: [canWrite, initiativesController.remove],
does: 'Delete an initiative that holds no projects (409 while it holds any), freeing its slug',
},
{
method: 'post',
path: '/api/v1/initiatives/:id/move',
handlers: [canWrite, initiativesController.move],
does:
'Move one initiative just above another: {before: <id>}, or {before: null} for the bottom. Only ' +
'initiatives’ ranks change, never a plan’s priority',
},
{
method: 'get',
path: '/api/v1/settings',
Expand Down Expand Up @@ -267,6 +347,14 @@ export function apiIndex(req, res) {
notes: 'up to 2000 characters',
waits_on: `ids of other items this one waits on, at most ${WAITS_ON_MAX}, never a loop`,
},
initiative: {
slug: 'required on create, a label-style slug like site-speed; kept for good',
name: `required on create, up to ${INITIATIVE_NAME_MAX} characters`,
goal: `one line, up to ${INITIATIVE_GOAL_MAX} characters`,
owner: 'a GitHub login, or null: orders its projects and takes the calls for ones with no lead',
kind: { values: INITIATIVE_KINDS, means: 'set on create: upkeep is Keep the lights on, untracked is Not tracked' },
status: INITIATIVE_STATUSES,
},
update: {
health: ROADMAP_HEALTHS,
body: 'up to 2000 characters, may be empty',
Expand All @@ -288,13 +376,24 @@ export function apiIndex(req, res) {
moving: 'parked, but its PRs changed after it was parked',
issues_done:
'every issue in its project is closed (`done`, `dropped`), and the plan running today hasn’t changed since the last one closed; `open` = its PRs still open',
unfiled: `in no initiative, with ${DECIDE_MIN_PRS} or more PRs or a plan under way (asked once any initiative exists; a project asked \`new\` is filed from that call)`,
no_project:
'an active plan with no project, which can’t be filed in an initiative until it has one (asked once any initiative exists); answer by PATCHing its `project`',
untracked_grew: `not tracked, and opened \`since\` PRs since it was set so: at least its count then (\`baseline\`) and ${GROWTH_FLOOR}`,
goal_reached:
'no project of the open `initiative` has a plan under way or PRs open, every plan in it stopped 14 days ago or more, and no project with no plan merged lately; Keep open quiets it until a plan or filing in it changes',
reopened_in_closed:
'its `initiative` is closed (`as` done or dropped), but it has open PRs or a plan under way again: the same rule that refuses a close. On the project’s own row when it has one',
},
to_clear:
'Make the call as a roadmap write. With no item: POST /api/v1/roadmap {name, project, status, ' +
'start, weeks, end_kind: "hard"}. With one: PATCH /api/v1/roadmap/:id with {status: "active", weeks, ' +
'end_kind: "hard"} to commit, {end_kind: "ongoing"} for upkeep with no end, ' +
'{status: "parked"}, {status: "done"}, or {status: "dropped"}. Any PATCH to an item counts as ' +
`a decision, and quiets a stall for ${STALL_DAYS} days.`,
`a decision, and quiets a stall for ${STALL_DAYS} days. Initiative calls are writes to ` +
'PUT /api/v1/initiatives/file (unfiled; untracked_grew: file it in the Not tracked initiative again ' +
'to keep it, or elsewhere) or PATCH /api/v1/initiatives/:id (goal_reached: status done or dropped, ' +
'or {status: "open", restate: true} to keep it open; reopened_in_closed: status open).',
},
settings: {
developer_teams:
Expand Down
Loading
Loading