@nowline/cli 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +190 -0
- package/README.md +372 -0
- package/dist/cli/args.d.ts +54 -0
- package/dist/cli/args.d.ts.map +1 -0
- package/dist/cli/args.js +165 -0
- package/dist/cli/args.js.map +1 -0
- package/dist/cli/formats.d.ts +61 -0
- package/dist/cli/formats.d.ts.map +1 -0
- package/dist/cli/formats.js +153 -0
- package/dist/cli/formats.js.map +1 -0
- package/dist/cli/help.d.ts +3 -0
- package/dist/cli/help.d.ts.map +1 -0
- package/dist/cli/help.js +90 -0
- package/dist/cli/help.js.map +1 -0
- package/dist/cli/output-path.d.ts +57 -0
- package/dist/cli/output-path.d.ts.map +1 -0
- package/dist/cli/output-path.js +70 -0
- package/dist/cli/output-path.js.map +1 -0
- package/dist/commands/init.d.ts +20 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +80 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/render.d.ts +15 -0
- package/dist/commands/render.d.ts.map +1 -0
- package/dist/commands/render.js +435 -0
- package/dist/commands/render.js.map +1 -0
- package/dist/commands/serve.d.ts +16 -0
- package/dist/commands/serve.d.ts.map +1 -0
- package/dist/commands/serve.js +287 -0
- package/dist/commands/serve.js.map +1 -0
- package/dist/convert/parse-json.d.ts +7 -0
- package/dist/convert/parse-json.d.ts.map +1 -0
- package/dist/convert/parse-json.js +34 -0
- package/dist/convert/parse-json.js.map +1 -0
- package/dist/convert/printer.d.ts +6 -0
- package/dist/convert/printer.d.ts.map +1 -0
- package/dist/convert/printer.js +334 -0
- package/dist/convert/printer.js.map +1 -0
- package/dist/convert/schema.d.ts +33 -0
- package/dist/convert/schema.d.ts.map +1 -0
- package/dist/convert/schema.js +77 -0
- package/dist/convert/schema.js.map +1 -0
- package/dist/core/parse.d.ts +24 -0
- package/dist/core/parse.d.ts.map +1 -0
- package/dist/core/parse.js +58 -0
- package/dist/core/parse.js.map +1 -0
- package/dist/diagnostics/adapt.d.ts +46 -0
- package/dist/diagnostics/adapt.d.ts.map +1 -0
- package/dist/diagnostics/adapt.js +109 -0
- package/dist/diagnostics/adapt.js.map +1 -0
- package/dist/diagnostics/format.d.ts +18 -0
- package/dist/diagnostics/format.d.ts.map +1 -0
- package/dist/diagnostics/format.js +41 -0
- package/dist/diagnostics/format.js.map +1 -0
- package/dist/diagnostics/index.d.ts +5 -0
- package/dist/diagnostics/index.d.ts.map +1 -0
- package/dist/diagnostics/index.js +5 -0
- package/dist/diagnostics/index.js.map +1 -0
- package/dist/diagnostics/json.d.ts +8 -0
- package/dist/diagnostics/json.d.ts.map +1 -0
- package/dist/diagnostics/json.js +24 -0
- package/dist/diagnostics/json.js.map +1 -0
- package/dist/diagnostics/model.d.ts +44 -0
- package/dist/diagnostics/model.d.ts.map +1 -0
- package/dist/diagnostics/model.js +2 -0
- package/dist/diagnostics/model.js.map +1 -0
- package/dist/diagnostics/text.d.ts +6 -0
- package/dist/diagnostics/text.d.ts.map +1 -0
- package/dist/diagnostics/text.js +43 -0
- package/dist/diagnostics/text.js.map +1 -0
- package/dist/generated/templates.d.ts +4 -0
- package/dist/generated/templates.d.ts.map +1 -0
- package/dist/generated/templates.js +9 -0
- package/dist/generated/templates.js.map +1 -0
- package/dist/generated/version.d.ts +11 -0
- package/dist/generated/version.d.ts.map +1 -0
- package/dist/generated/version.js +8 -0
- package/dist/generated/version.js.map +1 -0
- package/dist/i18n/locale.d.ts +56 -0
- package/dist/i18n/locale.d.ts.map +1 -0
- package/dist/i18n/locale.js +107 -0
- package/dist/i18n/locale.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +60 -0
- package/dist/index.js.map +1 -0
- package/dist/io/config.d.ts +2 -0
- package/dist/io/config.d.ts.map +1 -0
- package/dist/io/config.js +5 -0
- package/dist/io/config.js.map +1 -0
- package/dist/io/exit-codes.d.ts +12 -0
- package/dist/io/exit-codes.d.ts.map +1 -0
- package/dist/io/exit-codes.js +15 -0
- package/dist/io/exit-codes.js.map +1 -0
- package/dist/io/read.d.ts +13 -0
- package/dist/io/read.d.ts.map +1 -0
- package/dist/io/read.js +53 -0
- package/dist/io/read.js.map +1 -0
- package/dist/io/write.d.ts +32 -0
- package/dist/io/write.d.ts.map +1 -0
- package/dist/io/write.js +61 -0
- package/dist/io/write.js.map +1 -0
- package/dist/version.d.ts +13 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +20 -0
- package/dist/version.js.map +1 -0
- package/man/fr/nowline.1 +424 -0
- package/man/fr/nowline.5 +1864 -0
- package/man/nowline.1 +517 -0
- package/man/nowline.5 +1784 -0
- package/package.json +66 -0
- package/scripts/bundle-templates.mjs +105 -0
- package/scripts/compile.mjs +131 -0
- package/src/cli/args.ts +252 -0
- package/src/cli/formats.ts +207 -0
- package/src/cli/help.ts +92 -0
- package/src/cli/output-path.ts +98 -0
- package/src/commands/init.ts +99 -0
- package/src/commands/render.ts +566 -0
- package/src/commands/serve.ts +322 -0
- package/src/convert/parse-json.ts +57 -0
- package/src/convert/printer.ts +376 -0
- package/src/convert/schema.ts +105 -0
- package/src/core/parse.ts +93 -0
- package/src/diagnostics/adapt.ts +148 -0
- package/src/diagnostics/format.ts +70 -0
- package/src/diagnostics/index.ts +4 -0
- package/src/diagnostics/json.ts +30 -0
- package/src/diagnostics/model.ts +48 -0
- package/src/diagnostics/text.ts +62 -0
- package/src/generated/templates.ts +12 -0
- package/src/generated/version.ts +18 -0
- package/src/i18n/locale.ts +133 -0
- package/src/index.ts +60 -0
- package/src/io/config.ts +11 -0
- package/src/io/exit-codes.ts +18 -0
- package/src/io/read.ts +70 -0
- package/src/io/write.ts +94 -0
- package/src/version.ts +21 -0
package/man/nowline.5
ADDED
|
@@ -0,0 +1,1784 @@
|
|
|
1
|
+
.Dd $Mdocdate$
|
|
2
|
+
.Dt NOWLINE 5
|
|
3
|
+
.Os
|
|
4
|
+
.Sh NAME
|
|
5
|
+
.Nm nowline
|
|
6
|
+
.Nd Nowline DSL roadmap file format
|
|
7
|
+
.Sh DESCRIPTION
|
|
8
|
+
A
|
|
9
|
+
.Pa .nowline
|
|
10
|
+
file is an indentation-significant outline that defines a roadmap.
|
|
11
|
+
The file itself is the product; every other artefact (SVG, PNG, PDF,
|
|
12
|
+
HTML, Markdown+Mermaid, XLSX, MS Project XML) is a view of it produced
|
|
13
|
+
by
|
|
14
|
+
.Xr nowline 1 .
|
|
15
|
+
.Pp
|
|
16
|
+
This page documents the file format.
|
|
17
|
+
For the rendering pipeline and visual contracts, see
|
|
18
|
+
.Pa specs/rendering.md
|
|
19
|
+
in the source repository.
|
|
20
|
+
For the CLI surface, see
|
|
21
|
+
.Xr nowline 1 .
|
|
22
|
+
.Pp
|
|
23
|
+
The canonical, prose source for everything below is
|
|
24
|
+
.Pa specs/dsl.md
|
|
25
|
+
in the source repository; this page is a hand-authored reference
|
|
26
|
+
distilled from it.
|
|
27
|
+
.Sh FILE STRUCTURE
|
|
28
|
+
A
|
|
29
|
+
.Pa .nowline
|
|
30
|
+
file has up to four sections in strict order:
|
|
31
|
+
.Bl -enum -offset indent
|
|
32
|
+
.It
|
|
33
|
+
.Sy nowline
|
|
34
|
+
directive (optional, recommended). Must be the first non-comment,
|
|
35
|
+
non-blank line if present.
|
|
36
|
+
.It
|
|
37
|
+
.Sy include
|
|
38
|
+
declarations (optional). Pull in other
|
|
39
|
+
.Pa .nowline
|
|
40
|
+
files.
|
|
41
|
+
.It
|
|
42
|
+
.Sy config
|
|
43
|
+
section (optional). Rendering configuration: styles, defaults,
|
|
44
|
+
scale, calendar, symbols.
|
|
45
|
+
.It
|
|
46
|
+
.Sy roadmap
|
|
47
|
+
section (required). Content: persons, teams, anchors, labels, sizes,
|
|
48
|
+
statuses, swimlanes, items, milestones, footnotes.
|
|
49
|
+
.El
|
|
50
|
+
.Pp
|
|
51
|
+
.Sy config
|
|
52
|
+
and
|
|
53
|
+
.Sy roadmap
|
|
54
|
+
are section markers, not indent-containers.
|
|
55
|
+
Keywords inside each section appear at the top level (not indented
|
|
56
|
+
under the marker).
|
|
57
|
+
Indentation is used where nesting is real: style properties under a
|
|
58
|
+
.Sy style
|
|
59
|
+
block, items under a
|
|
60
|
+
.Sy swimlane ,
|
|
61
|
+
team members under a
|
|
62
|
+
.Sy team .
|
|
63
|
+
.Pp
|
|
64
|
+
Indentation is significant.
|
|
65
|
+
Two-space indent is canonical; one tab is also accepted.
|
|
66
|
+
Spaces and tabs must not be mixed inside a single file \(em the
|
|
67
|
+
parser rejects mixed indentation with an error identifying the first
|
|
68
|
+
offending line.
|
|
69
|
+
.Pp
|
|
70
|
+
Strings are double-quoted
|
|
71
|
+
.Pq Qq Auth refactor ,
|
|
72
|
+
not bare or single-quoted.
|
|
73
|
+
Properties are
|
|
74
|
+
.Sy key:value
|
|
75
|
+
pairs on the same line as the entity; values containing spaces must
|
|
76
|
+
be double-quoted.
|
|
77
|
+
Property keys never use
|
|
78
|
+
.Sq = .
|
|
79
|
+
.Pp
|
|
80
|
+
Built-in keywords and property names are kebab-case
|
|
81
|
+
.Pq Sy capacity-icon , Sy days-per-week , Sy in-progress .
|
|
82
|
+
Author-chosen identifiers may use any combination of letters,
|
|
83
|
+
digits, underscores, and dashes
|
|
84
|
+
.Pq Sy auth-refactor , Sy authRefactor , Sy auth_refactor ;
|
|
85
|
+
they must start with a letter or underscore.
|
|
86
|
+
.Pp
|
|
87
|
+
Comments use
|
|
88
|
+
.Sq //
|
|
89
|
+
for single-line and
|
|
90
|
+
.Sq /* */
|
|
91
|
+
for multi-line.
|
|
92
|
+
A trailing
|
|
93
|
+
.Sq \e
|
|
94
|
+
continues a line; indentation on the continuation line is cosmetic.
|
|
95
|
+
Use
|
|
96
|
+
.Sq \e\e
|
|
97
|
+
for a literal backslash.
|
|
98
|
+
.Sh DIRECTIVE
|
|
99
|
+
The
|
|
100
|
+
.Sy nowline
|
|
101
|
+
directive declares which DSL major version a file targets:
|
|
102
|
+
.Bd -literal -offset indent
|
|
103
|
+
nowline v1
|
|
104
|
+
.Ed
|
|
105
|
+
.Pp
|
|
106
|
+
The version is integer-only
|
|
107
|
+
.Pq Sy v1 , Sy v2 , Sy v3 , ...
|
|
108
|
+
and is independent of the npm package version.
|
|
109
|
+
Within a DSL major, the parser must accept every valid file written
|
|
110
|
+
for that major; new syntax may be added between package minor/patch
|
|
111
|
+
releases, but no breaking change to an existing valid
|
|
112
|
+
.Sy nowline v1
|
|
113
|
+
file ships without bumping the directive to
|
|
114
|
+
.Sy v2 .
|
|
115
|
+
When the parser encounters a version newer than it supports, it
|
|
116
|
+
emits an error identifying the required version.
|
|
117
|
+
When the directive is omitted, the parser assumes the latest
|
|
118
|
+
version it supports.
|
|
119
|
+
.Pp
|
|
120
|
+
The directive line accepts optional file-level properties after the
|
|
121
|
+
version.
|
|
122
|
+
The only directive property today is
|
|
123
|
+
.Sy locale: ,
|
|
124
|
+
a BCP-47 tag controlling localized rendering and validator
|
|
125
|
+
messages:
|
|
126
|
+
.Bd -literal -offset indent
|
|
127
|
+
nowline v1 locale:fr-CA
|
|
128
|
+
.Ed
|
|
129
|
+
.Pp
|
|
130
|
+
Unknown directive keys are an error so typos surface immediately.
|
|
131
|
+
See
|
|
132
|
+
.Pa specs/localization.md
|
|
133
|
+
for the locale model and precedence chain.
|
|
134
|
+
.Pp
|
|
135
|
+
The
|
|
136
|
+
.Sy nowline
|
|
137
|
+
directive is the only construct that does not follow the universal
|
|
138
|
+
declaration pattern
|
|
139
|
+
.Pq see Sx GRAMMAR :
|
|
140
|
+
no identifier, no title, just the keyword and version.
|
|
141
|
+
.Sh INCLUDES
|
|
142
|
+
.Sy include
|
|
143
|
+
pulls another
|
|
144
|
+
.Pa .nowline
|
|
145
|
+
file into the current file:
|
|
146
|
+
.Bd -literal -offset indent
|
|
147
|
+
include "shared/teams.nowline"
|
|
148
|
+
include "brand-styles.nowline" roadmap:ignore
|
|
149
|
+
include "partner.nowline" config:isolate roadmap:isolate
|
|
150
|
+
.Ed
|
|
151
|
+
.Pp
|
|
152
|
+
Two optional properties \(em
|
|
153
|
+
.Sy config:
|
|
154
|
+
and
|
|
155
|
+
.Sy roadmap:
|
|
156
|
+
\(em control how the included file's content is handled.
|
|
157
|
+
They operate on two independent categories:
|
|
158
|
+
.Bl -tag -width "Roadmap (content)"
|
|
159
|
+
.It Sy Config
|
|
160
|
+
The included file's
|
|
161
|
+
.Sy scale ,
|
|
162
|
+
.Sy style ,
|
|
163
|
+
.Sy symbol ,
|
|
164
|
+
.Sy default ,
|
|
165
|
+
and
|
|
166
|
+
.Sy calendar
|
|
167
|
+
declarations.
|
|
168
|
+
.It Sy Roadmap
|
|
169
|
+
The included file's
|
|
170
|
+
.Sy roadmap
|
|
171
|
+
declaration plus all its content (persons, teams, anchors, labels,
|
|
172
|
+
sizes, statuses, swimlanes, items, milestones, footnotes).
|
|
173
|
+
.El
|
|
174
|
+
.Pp
|
|
175
|
+
.Sy config:
|
|
176
|
+
modes:
|
|
177
|
+
.Bl -tag -width "isolate"
|
|
178
|
+
.It Sy merge Pq default
|
|
179
|
+
Child config items are merged into the parent.
|
|
180
|
+
On collision, the
|
|
181
|
+
.Em parent wins
|
|
182
|
+
and the parser emits a warning identifying the shadowed definition
|
|
183
|
+
and source file.
|
|
184
|
+
.It Sy ignore
|
|
185
|
+
Child config is dropped entirely.
|
|
186
|
+
If child roadmap content is merged, it resolves styles from the
|
|
187
|
+
parent's post-merge config.
|
|
188
|
+
.It Sy isolate
|
|
189
|
+
Child config is only available within the child file; parent config
|
|
190
|
+
is only available in the parent.
|
|
191
|
+
Neither side bleeds into the other.
|
|
192
|
+
.El
|
|
193
|
+
.Pp
|
|
194
|
+
.Sy roadmap:
|
|
195
|
+
modes:
|
|
196
|
+
.Bl -tag -width "isolate"
|
|
197
|
+
.It Sy merge Pq default
|
|
198
|
+
Child content entities are merged into the parent.
|
|
199
|
+
On collision,
|
|
200
|
+
.Em parent wins
|
|
201
|
+
and a warning is emitted.
|
|
202
|
+
A swimlane collision drops the swimlane's contained items as well.
|
|
203
|
+
Merged content resolves styles from the post-merge config.
|
|
204
|
+
.It Sy ignore
|
|
205
|
+
Child content is dropped.
|
|
206
|
+
Use for shared style libraries
|
|
207
|
+
.Pq Sy include "brand.nowline" roadmap:ignore .
|
|
208
|
+
Shared label, status, and size vocabulary uses
|
|
209
|
+
.Sy roadmap:merge ,
|
|
210
|
+
not
|
|
211
|
+
.Sy roadmap:ignore .
|
|
212
|
+
.It Sy isolate
|
|
213
|
+
Child content stays scoped to the child file and uses only the
|
|
214
|
+
child's config.
|
|
215
|
+
The child must contain a
|
|
216
|
+
.Sy roadmap
|
|
217
|
+
declaration (needed for the region label).
|
|
218
|
+
The isolated content renders as a visually distinct region with its
|
|
219
|
+
own border.
|
|
220
|
+
.El
|
|
221
|
+
.Pp
|
|
222
|
+
Includes are processed depth-first, in file order.
|
|
223
|
+
When the processor encounters an
|
|
224
|
+
.Sy include ,
|
|
225
|
+
it processes that child (and its includes recursively) before
|
|
226
|
+
continuing with the next declaration.
|
|
227
|
+
Config is merged before roadmap content at each level.
|
|
228
|
+
.Pp
|
|
229
|
+
Diamond includes (A includes B and C, both include D) are valid;
|
|
230
|
+
D is processed once on first encounter.
|
|
231
|
+
Duplicate includes of the same file in a single file are an error.
|
|
232
|
+
Circular includes are an error.
|
|
233
|
+
.Pp
|
|
234
|
+
Includes are resolved relative to the including file's directory.
|
|
235
|
+
Paths use forward slashes on all platforms.
|
|
236
|
+
Includes must appear before
|
|
237
|
+
.Sy config
|
|
238
|
+
and
|
|
239
|
+
.Sy roadmap
|
|
240
|
+
\(em they are the first declarations in a file (after the optional
|
|
241
|
+
.Sy nowline
|
|
242
|
+
directive).
|
|
243
|
+
.Pp
|
|
244
|
+
For any include whose
|
|
245
|
+
.Sy roadmap:
|
|
246
|
+
mode is not
|
|
247
|
+
.Sy ignore ,
|
|
248
|
+
if the child file declares a
|
|
249
|
+
.Sy roadmap ,
|
|
250
|
+
the parent and child must agree on
|
|
251
|
+
.Sy start: \(em
|
|
252
|
+
both absent, or both present with identical values.
|
|
253
|
+
A mismatch is an error reported on the parent's
|
|
254
|
+
.Sy include
|
|
255
|
+
line; this is an explicit exception to the
|
|
256
|
+
.Qq parent wins
|
|
257
|
+
merge behaviour because
|
|
258
|
+
.Sy start:
|
|
259
|
+
defines the shared timeline baseline.
|
|
260
|
+
.Sh CONFIG SECTION
|
|
261
|
+
The optional
|
|
262
|
+
.Sy config
|
|
263
|
+
section marker appears before
|
|
264
|
+
.Sy roadmap .
|
|
265
|
+
Config keywords sit at the top level (not indented under the
|
|
266
|
+
marker) and define rendering vocabulary, defaults, axis settings,
|
|
267
|
+
day arithmetic, and custom symbols.
|
|
268
|
+
.Pp
|
|
269
|
+
Five config keywords:
|
|
270
|
+
.Sy scale ,
|
|
271
|
+
.Sy style ,
|
|
272
|
+
.Sy symbol ,
|
|
273
|
+
.Sy default ,
|
|
274
|
+
.Sy calendar .
|
|
275
|
+
Every config entry is optional; if
|
|
276
|
+
.Sy config
|
|
277
|
+
is omitted, all built-in defaults apply.
|
|
278
|
+
.Ss style \(em named visual definition
|
|
279
|
+
A
|
|
280
|
+
.Sy style
|
|
281
|
+
declares a named visual treatment.
|
|
282
|
+
Properties are indented beneath:
|
|
283
|
+
.Bd -literal -offset indent
|
|
284
|
+
style enterprise "Enterprise readiness"
|
|
285
|
+
bg: blue
|
|
286
|
+
fg: navy
|
|
287
|
+
text: white
|
|
288
|
+
border: solid
|
|
289
|
+
icon: shield
|
|
290
|
+
|
|
291
|
+
style risky
|
|
292
|
+
border: dashed
|
|
293
|
+
fg: orange
|
|
294
|
+
.Ed
|
|
295
|
+
.Pp
|
|
296
|
+
Styles follow the universal
|
|
297
|
+
.Sy [id] ["title"]
|
|
298
|
+
pattern.
|
|
299
|
+
Properties are listed under
|
|
300
|
+
.Sx STYLE PROPERTIES
|
|
301
|
+
below.
|
|
302
|
+
.Ss symbol \(em custom named symbol
|
|
303
|
+
A
|
|
304
|
+
.Sy symbol
|
|
305
|
+
declares a custom symbol for use by
|
|
306
|
+
.Sy icon:
|
|
307
|
+
and
|
|
308
|
+
.Sy capacity-icon:
|
|
309
|
+
style properties.
|
|
310
|
+
Authors use the inline Unicode-literal form
|
|
311
|
+
.Pq Sy capacity-icon:"\(rs"
|
|
312
|
+
for one-off symbols; named
|
|
313
|
+
.Sy symbol
|
|
314
|
+
declarations are for reusable ones.
|
|
315
|
+
.Bd -literal -offset indent
|
|
316
|
+
symbol budget "Budget" unicode:"\(em" ascii:"$"
|
|
317
|
+
symbol fte unicode:"\eu{1F464}" ascii:"@"
|
|
318
|
+
symbol star unicode:"\(em"
|
|
319
|
+
.Ed
|
|
320
|
+
.Pp
|
|
321
|
+
Required:
|
|
322
|
+
.Sy unicode:"<string>"
|
|
323
|
+
\(em the Unicode character (literal or
|
|
324
|
+
.Sy \eu{...}
|
|
325
|
+
escape, may be a multi-codepoint grapheme cluster).
|
|
326
|
+
.Pp
|
|
327
|
+
Optional:
|
|
328
|
+
.Sy ascii:"<string>"
|
|
329
|
+
\(em short ASCII fallback for terminals lacking the glyph,
|
|
330
|
+
\(<= 3 ASCII characters; defaults to
|
|
331
|
+
.Sq \&?
|
|
332
|
+
when omitted.
|
|
333
|
+
.Pp
|
|
334
|
+
A
|
|
335
|
+
.Sy symbol
|
|
336
|
+
id must not shadow a built-in icon name
|
|
337
|
+
.Pq Sy none , Sy multiplier , Sy person , Sy people , Sy points , Sy time , Sy shield , Sy warning , Sy lock .
|
|
338
|
+
.Ss default \(em default property values per entity type
|
|
339
|
+
.Sy default <entity> <properties>
|
|
340
|
+
sets default property values for a given entity type.
|
|
341
|
+
One declaration per entity type per file:
|
|
342
|
+
.Bd -literal -offset indent
|
|
343
|
+
default item status:planned shadow:subtle
|
|
344
|
+
default label style:subtle corner-radius:full
|
|
345
|
+
default swimlane padding:sm spacing:none
|
|
346
|
+
default roadmap padding:md header-height:md font:sans
|
|
347
|
+
default milestone weight:bold
|
|
348
|
+
default footnote style:subtle shadow:subtle
|
|
349
|
+
default anchor style:subtle
|
|
350
|
+
default parallel bracket:none
|
|
351
|
+
default group padding:xs spacing:xs
|
|
352
|
+
.Ed
|
|
353
|
+
.Pp
|
|
354
|
+
Supported entity types:
|
|
355
|
+
.Sy item , label , swimlane , roadmap , parallel , group , milestone , footnote , anchor .
|
|
356
|
+
When an entity omits a property, the matching default applies;
|
|
357
|
+
explicit values on the entity always override defaults.
|
|
358
|
+
.Pp
|
|
359
|
+
Identity-defining, sizing, sequencing, reference, and prose
|
|
360
|
+
properties cannot be defaulted because they must be explicit per
|
|
361
|
+
entity.
|
|
362
|
+
Banned, by entity type:
|
|
363
|
+
.Bl -tag -width "default footnote"
|
|
364
|
+
.It Sy default item
|
|
365
|
+
.Sy size , duration , after , before , remaining , link , description , owner .
|
|
366
|
+
.It Sy default milestone
|
|
367
|
+
.Sy date , after , link , description .
|
|
368
|
+
.It Sy default anchor
|
|
369
|
+
.Sy date , link , description .
|
|
370
|
+
.It Sy default footnote
|
|
371
|
+
.Sy on , link , description .
|
|
372
|
+
.El
|
|
373
|
+
.Pp
|
|
374
|
+
Raw style properties
|
|
375
|
+
.Pq Sy bg , Sy fg , Sy text , Sy border , Sy shadow , ...
|
|
376
|
+
are allowed on
|
|
377
|
+
.Sy default
|
|
378
|
+
because
|
|
379
|
+
.Sy default
|
|
380
|
+
lives in
|
|
381
|
+
.Sy config ,
|
|
382
|
+
the presentation section.
|
|
383
|
+
The ban on raw style properties applies to roadmap-section
|
|
384
|
+
entities, not to
|
|
385
|
+
.Sy default
|
|
386
|
+
lines.
|
|
387
|
+
.Pp
|
|
388
|
+
.Sy capacity
|
|
389
|
+
is allowed on
|
|
390
|
+
.Sy default item
|
|
391
|
+
but
|
|
392
|
+
.Em not
|
|
393
|
+
on
|
|
394
|
+
.Sy default swimlane
|
|
395
|
+
\(em each lane's budget is intentionally explicit at its declaration
|
|
396
|
+
site.
|
|
397
|
+
.Sy utilization-warn-at: ,
|
|
398
|
+
.Sy utilization-over-at: ,
|
|
399
|
+
and
|
|
400
|
+
.Sy capacity-icon:
|
|
401
|
+
are allowed on both
|
|
402
|
+
.Sy default swimlane
|
|
403
|
+
and
|
|
404
|
+
.Sy default item
|
|
405
|
+
per the usual presentation-property rule.
|
|
406
|
+
.Ss scale \(em axis display
|
|
407
|
+
.Sy scale
|
|
408
|
+
configures the timeline axis.
|
|
409
|
+
Column width is set by
|
|
410
|
+
.Sy scale:<duration>
|
|
411
|
+
on the
|
|
412
|
+
.Sy roadmap
|
|
413
|
+
declaration; this block configures display:
|
|
414
|
+
.Bd -literal -offset indent
|
|
415
|
+
scale
|
|
416
|
+
name: sprints
|
|
417
|
+
label-every: 2
|
|
418
|
+
label: "Sprint {n}"
|
|
419
|
+
.Ed
|
|
420
|
+
.Bl -tag -width "label-every"
|
|
421
|
+
.It Sy name
|
|
422
|
+
Display label for the scale unit (e.g.
|
|
423
|
+
.Qq sprint ) .
|
|
424
|
+
Defaults to an auto-generated name based on the roadmap's
|
|
425
|
+
.Sy scale:
|
|
426
|
+
duration.
|
|
427
|
+
.It Sy label-every
|
|
428
|
+
Show an axis label every Nth column.
|
|
429
|
+
Defaults to the renderer's choice.
|
|
430
|
+
.It Sy label
|
|
431
|
+
Axis label format.
|
|
432
|
+
.Sq {n}
|
|
433
|
+
is the column index.
|
|
434
|
+
.El
|
|
435
|
+
.Pp
|
|
436
|
+
The
|
|
437
|
+
.Sy scale
|
|
438
|
+
config block is optional.
|
|
439
|
+
A file can declare
|
|
440
|
+
.Sy scale:2w
|
|
441
|
+
on its
|
|
442
|
+
.Sy roadmap
|
|
443
|
+
with no
|
|
444
|
+
.Sy scale
|
|
445
|
+
block and the renderer picks all display defaults.
|
|
446
|
+
.Ss calendar \(em day arithmetic
|
|
447
|
+
The
|
|
448
|
+
.Sy calendar:
|
|
449
|
+
property on
|
|
450
|
+
.Sy roadmap
|
|
451
|
+
selects day-arithmetic mode:
|
|
452
|
+
.Bl -tag -width "calendar:business"
|
|
453
|
+
.It Sy calendar:business Pq default
|
|
454
|
+
Engineering working-day arithmetic.
|
|
455
|
+
.Sy days-per-week:5 ,
|
|
456
|
+
.Sy days-per-month:22 ,
|
|
457
|
+
.Sy days-per-quarter:65 ,
|
|
458
|
+
.Sy days-per-year:260 .
|
|
459
|
+
.It Sy calendar:full
|
|
460
|
+
Calendar-day arithmetic with weekends.
|
|
461
|
+
.Sy days-per-week:7 ,
|
|
462
|
+
.Sy days-per-month:30 ,
|
|
463
|
+
.Sy days-per-quarter:90 ,
|
|
464
|
+
.Sy days-per-year:365 .
|
|
465
|
+
.It Sy calendar:custom
|
|
466
|
+
Author-supplied values via the
|
|
467
|
+
.Sy calendar
|
|
468
|
+
config block.
|
|
469
|
+
.El
|
|
470
|
+
.Pp
|
|
471
|
+
A
|
|
472
|
+
.Sy calendar
|
|
473
|
+
config block is only meaningful when
|
|
474
|
+
.Sy roadmap
|
|
475
|
+
declares
|
|
476
|
+
.Sy calendar:custom .
|
|
477
|
+
When custom, all four
|
|
478
|
+
.Sy days-per-*
|
|
479
|
+
fields are required:
|
|
480
|
+
.Bd -literal -offset indent
|
|
481
|
+
config
|
|
482
|
+
|
|
483
|
+
calendar
|
|
484
|
+
days-per-week: 6
|
|
485
|
+
days-per-month: 26
|
|
486
|
+
days-per-quarter: 78
|
|
487
|
+
days-per-year: 312
|
|
488
|
+
|
|
489
|
+
roadmap rotating-shift "Rotating Shift" calendar:custom
|
|
490
|
+
.Ed
|
|
491
|
+
.Pp
|
|
492
|
+
All four entries must be positive integers.
|
|
493
|
+
There is no partial form.
|
|
494
|
+
.Pp
|
|
495
|
+
Each
|
|
496
|
+
.Sy days-per-*
|
|
497
|
+
field is independently defined: a duration like
|
|
498
|
+
.Sy 1y
|
|
499
|
+
resolves to
|
|
500
|
+
.Sy days-per-year
|
|
501
|
+
directly, not by multiplying through months or weeks.
|
|
502
|
+
This is why business mode's
|
|
503
|
+
.Sy 1y
|
|
504
|
+
is
|
|
505
|
+
.Sy 260d ,
|
|
506
|
+
not
|
|
507
|
+
.Sy 12 \(mu 22d = 264d .
|
|
508
|
+
.Sh ROADMAP SECTION
|
|
509
|
+
The
|
|
510
|
+
.Sy roadmap
|
|
511
|
+
section marker is required and appears exactly once per file.
|
|
512
|
+
Roadmap keywords sit at the top level (not indented under the
|
|
513
|
+
marker) and form the content of the file.
|
|
514
|
+
.Pp
|
|
515
|
+
The
|
|
516
|
+
.Sy roadmap
|
|
517
|
+
declaration line itself accepts:
|
|
518
|
+
.Bd -literal -offset indent
|
|
519
|
+
roadmap platform-2026 "Platform 2026" \e
|
|
520
|
+
author:"Acme" \e
|
|
521
|
+
start:2026-01-06 \e
|
|
522
|
+
scale:2w \e
|
|
523
|
+
calendar:business \e
|
|
524
|
+
logo:"./brand/acme.svg" \e
|
|
525
|
+
logo-size:md
|
|
526
|
+
.Ed
|
|
527
|
+
.Bl -tag -width "calendar:"
|
|
528
|
+
.It Sy author:
|
|
529
|
+
Free-form string.
|
|
530
|
+
.It Sy start:
|
|
531
|
+
ISO date
|
|
532
|
+
.Pq Pa YYYY-MM-DD ,
|
|
533
|
+
the timeline baseline.
|
|
534
|
+
Required if any
|
|
535
|
+
.Sy anchor
|
|
536
|
+
or any dated
|
|
537
|
+
.Sy milestone
|
|
538
|
+
exists.
|
|
539
|
+
Every anchor date and dated milestone date must be on or after
|
|
540
|
+
.Sy start: .
|
|
541
|
+
.It Sy scale:
|
|
542
|
+
Raw duration literal for column width
|
|
543
|
+
.Pq Sy 2w , Sy 1q ;
|
|
544
|
+
defaults to
|
|
545
|
+
.Sy 1w .
|
|
546
|
+
.It Sy calendar:
|
|
547
|
+
.Sy business | full | custom .
|
|
548
|
+
Defaults to
|
|
549
|
+
.Sy business .
|
|
550
|
+
.It Sy logo:
|
|
551
|
+
Path to a logo file
|
|
552
|
+
.Pq Sy .svg , Sy .png , Sy .jpg / Sy .jpeg , Sy .webp ,
|
|
553
|
+
resolved relative to the
|
|
554
|
+
.Pa .nowline
|
|
555
|
+
file's directory.
|
|
556
|
+
Forward slashes on all platforms; only local paths are accepted.
|
|
557
|
+
Asset resolution happens at render time, not parse time \(em a file
|
|
558
|
+
referencing a missing logo is still a valid document.
|
|
559
|
+
.It Sy logo-size:
|
|
560
|
+
Size preset
|
|
561
|
+
.Pq Sy xs | sm | md | lg | xl ,
|
|
562
|
+
default
|
|
563
|
+
.Sy md .
|
|
564
|
+
.El
|
|
565
|
+
.Pp
|
|
566
|
+
Twelve roadmap-section keywords:
|
|
567
|
+
.Sy swimlane , item , parallel , group ,
|
|
568
|
+
.Sy person , team , anchor , label , size , status , milestone ,
|
|
569
|
+
.Sy footnote .
|
|
570
|
+
Each follows the universal
|
|
571
|
+
.Sy [id] ["title"] [key:value...]
|
|
572
|
+
pattern.
|
|
573
|
+
.Ss swimlane \(em group items by team / area / stream
|
|
574
|
+
.Bd -literal -offset indent
|
|
575
|
+
swimlane platform owner:platform capacity:5
|
|
576
|
+
item auth-refactor "Auth refactor" size:l after:kickoff
|
|
577
|
+
item platform-qa "Platform QA" size:s capacity:2
|
|
578
|
+
.Ed
|
|
579
|
+
.Pp
|
|
580
|
+
Items, parallels, and groups are indented beneath.
|
|
581
|
+
Properties:
|
|
582
|
+
.Bl -tag -width "utilization-over-at"
|
|
583
|
+
.It Sy owner:
|
|
584
|
+
Person or team id.
|
|
585
|
+
.It Sy capacity:
|
|
586
|
+
Per-timestep budget.
|
|
587
|
+
Integer or decimal only; no percent form.
|
|
588
|
+
.It Sy utilization-warn-at: , Sy utilization-over-at:
|
|
589
|
+
Thresholds for the lane utilization underline.
|
|
590
|
+
Each accepts a percent literal
|
|
591
|
+
.Pq Sy 80% ,
|
|
592
|
+
a positive decimal interpreted as a fraction
|
|
593
|
+
.Pq Sy 0.8 ,
|
|
594
|
+
or the bareword
|
|
595
|
+
.Sy none
|
|
596
|
+
to opt out of that color band.
|
|
597
|
+
Defaults
|
|
598
|
+
.Sy 80%
|
|
599
|
+
and
|
|
600
|
+
.Sy 100% .
|
|
601
|
+
When both numeric thresholds are set,
|
|
602
|
+
.Sy warn-at \(<= over-at .
|
|
603
|
+
.El
|
|
604
|
+
.Ss item \(em work item
|
|
605
|
+
Items live inside swimlanes (or
|
|
606
|
+
.Sy parallel /
|
|
607
|
+
.Sy group
|
|
608
|
+
blocks) and must declare at least one of
|
|
609
|
+
.Sy size:
|
|
610
|
+
or
|
|
611
|
+
.Sy duration: .
|
|
612
|
+
See
|
|
613
|
+
.Sx ITEM PROPERTIES
|
|
614
|
+
below.
|
|
615
|
+
.Bd -literal -offset indent
|
|
616
|
+
swimlane platform
|
|
617
|
+
item auth-refactor "Auth refactor" size:l status:done
|
|
618
|
+
item "Quick cleanup" size:s
|
|
619
|
+
item sso size:m
|
|
620
|
+
.Ed
|
|
621
|
+
.Ss parallel \(em parallel execution block
|
|
622
|
+
.Sy parallel
|
|
623
|
+
runs its children in parallel.
|
|
624
|
+
Children can be bare items or groups.
|
|
625
|
+
.Bd -literal -offset indent
|
|
626
|
+
swimlane platform
|
|
627
|
+
item auth "Auth refactor" size:l
|
|
628
|
+
parallel
|
|
629
|
+
item api-v2 "API v2" size:m
|
|
630
|
+
item sdk-update "SDK update" size:s
|
|
631
|
+
item integration "Integration" size:s
|
|
632
|
+
.Ed
|
|
633
|
+
.Pp
|
|
634
|
+
.Sy api-v2
|
|
635
|
+
and
|
|
636
|
+
.Sy sdk-update
|
|
637
|
+
start at the same time (after
|
|
638
|
+
.Sy auth
|
|
639
|
+
finishes).
|
|
640
|
+
When the
|
|
641
|
+
.Sy parallel
|
|
642
|
+
block ends, the next sibling
|
|
643
|
+
.Pq Sy integration
|
|
644
|
+
waits for all parallel children to complete (implicit join on
|
|
645
|
+
dedent).
|
|
646
|
+
A
|
|
647
|
+
.Sy parallel
|
|
648
|
+
block must contain at least 2 children; a single-child parallel
|
|
649
|
+
emits a warning.
|
|
650
|
+
.Ss group \(em sequential item bundle
|
|
651
|
+
.Sy group
|
|
652
|
+
bundles items into a named sequential track.
|
|
653
|
+
Inside a swimlane (outside a parallel block), the group is
|
|
654
|
+
sequential with respect to its siblings.
|
|
655
|
+
.Bd -literal -offset indent
|
|
656
|
+
swimlane platform
|
|
657
|
+
group api-work "API Work" labels:enterprise
|
|
658
|
+
item api-v2 "API v2" size:m
|
|
659
|
+
item api-docs "API docs" size:s
|
|
660
|
+
item deploy "Deploy" size:s
|
|
661
|
+
.Ed
|
|
662
|
+
.Pp
|
|
663
|
+
A
|
|
664
|
+
.Sy group
|
|
665
|
+
with
|
|
666
|
+
.Sy style: ,
|
|
667
|
+
.Sy labels: ,
|
|
668
|
+
or other visual properties renders with a visible bounding box
|
|
669
|
+
plus a small title chiclet.
|
|
670
|
+
A
|
|
671
|
+
.Sy group
|
|
672
|
+
with no styling is purely structural \(em it only governs
|
|
673
|
+
sequencing and inner row growth, with no visible artefact.
|
|
674
|
+
.Ss anchor \(em named date on the timeline
|
|
675
|
+
.Bd -literal -offset indent
|
|
676
|
+
anchor kickoff date:2026-01-06
|
|
677
|
+
anchor code-freeze "Code Freeze" date:2026-05-01
|
|
678
|
+
.Ed
|
|
679
|
+
.Pp
|
|
680
|
+
.Sy date:
|
|
681
|
+
is required.
|
|
682
|
+
Anchors are referenced by
|
|
683
|
+
.Sy after:
|
|
684
|
+
and
|
|
685
|
+
.Sy before:
|
|
686
|
+
on items, parallels, groups, and milestones to pin their position.
|
|
687
|
+
.Ss label \(em semantic tag / chip vocabulary
|
|
688
|
+
Labels live in the roadmap section so content and vocabulary live
|
|
689
|
+
together; visual defaults live in
|
|
690
|
+
.Sy config
|
|
691
|
+
via
|
|
692
|
+
.Sy default label
|
|
693
|
+
and referenced
|
|
694
|
+
.Sy style
|
|
695
|
+
blocks.
|
|
696
|
+
.Bd -literal -offset indent
|
|
697
|
+
label enterprise "Enterprise readiness" style:enterprise
|
|
698
|
+
label security "Security hardening" style:enterprise-red
|
|
699
|
+
label low-confidence style:risky-dotted
|
|
700
|
+
.Ed
|
|
701
|
+
.Pp
|
|
702
|
+
A
|
|
703
|
+
.Sy label
|
|
704
|
+
line accepts
|
|
705
|
+
.Sy style:id
|
|
706
|
+
plus universal properties
|
|
707
|
+
.Pq Sy labels: , Sy link: , description .
|
|
708
|
+
Raw style properties are
|
|
709
|
+
.Em not
|
|
710
|
+
allowed on a
|
|
711
|
+
.Sy label
|
|
712
|
+
line.
|
|
713
|
+
Labels used on items without a matching
|
|
714
|
+
.Sy label
|
|
715
|
+
declaration are valid; they render with chip defaults from
|
|
716
|
+
.Sy default label
|
|
717
|
+
or system defaults.
|
|
718
|
+
.Ss size \(em named effort budget
|
|
719
|
+
A
|
|
720
|
+
.Sy size
|
|
721
|
+
maps a named t-shirt size to a single-engineer effort budget.
|
|
722
|
+
.Bd -literal -offset indent
|
|
723
|
+
size xs "Extra Small" effort:0.5d
|
|
724
|
+
size s "Small" effort:3d
|
|
725
|
+
size m "Medium" effort:1w
|
|
726
|
+
size l "Large" effort:2w
|
|
727
|
+
size xl "Extra Large" effort:1m
|
|
728
|
+
.Ed
|
|
729
|
+
.Pp
|
|
730
|
+
.Sy effort:
|
|
731
|
+
is required and must be a positive raw duration literal
|
|
732
|
+
.Pq decimal-aware: Sy 0.5d , Sy 1.5w .
|
|
733
|
+
The id must not match the raw duration pattern
|
|
734
|
+
.Sy \&\ed+(\e.\ed+)?[dwmqy]
|
|
735
|
+
or be a bare
|
|
736
|
+
.Sy d , w , m , q , y
|
|
737
|
+
\(em this avoids ambiguity at the call site.
|
|
738
|
+
.Pp
|
|
739
|
+
On items, the on-bar size chip renders the size's optional
|
|
740
|
+
.Sy title
|
|
741
|
+
when provided, falling back to the id verbatim.
|
|
742
|
+
.Sy size m "M" effort:1w
|
|
743
|
+
renders
|
|
744
|
+
.Qq M ;
|
|
745
|
+
.Sy size m effort:1w
|
|
746
|
+
renders
|
|
747
|
+
.Qq m .
|
|
748
|
+
.Pp
|
|
749
|
+
.Sy size
|
|
750
|
+
declarations must precede any item that references them.
|
|
751
|
+
.Ss status \(em custom status value
|
|
752
|
+
.Bd -literal -offset indent
|
|
753
|
+
status awaiting-review "Awaiting Review"
|
|
754
|
+
status in-review "In Review"
|
|
755
|
+
status deferred "Deferred"
|
|
756
|
+
.Ed
|
|
757
|
+
.Pp
|
|
758
|
+
Extends the built-in set
|
|
759
|
+
.Po
|
|
760
|
+
.Sy planned ,
|
|
761
|
+
.Sy in-progress
|
|
762
|
+
.Pq alias Sy active ,
|
|
763
|
+
.Sy done
|
|
764
|
+
.Pq alias Sy completed ,
|
|
765
|
+
.Sy at-risk ,
|
|
766
|
+
.Sy blocked
|
|
767
|
+
.Pc .
|
|
768
|
+
The aliases canonicalize at the layout boundary; both spellings
|
|
769
|
+
are valid input.
|
|
770
|
+
.Pp
|
|
771
|
+
Custom statuses have no inherent semantics beyond what renderers
|
|
772
|
+
assign; the DSL only guarantees the value resolves and can carry
|
|
773
|
+
a display title.
|
|
774
|
+
Renderers may map custom statuses to visual treatments via
|
|
775
|
+
.Sy default item style:...
|
|
776
|
+
or entity-level
|
|
777
|
+
.Sy style:
|
|
778
|
+
overrides.
|
|
779
|
+
.Pp
|
|
780
|
+
.Sy status
|
|
781
|
+
declarations must precede any entity that references them.
|
|
782
|
+
.Ss milestone \(em achievement marker
|
|
783
|
+
.Bd -literal -offset indent
|
|
784
|
+
milestone v1-ga "v1 GA" date:2026-06-30
|
|
785
|
+
milestone beta "Beta" after:auth-refactor
|
|
786
|
+
milestone v1-ga "v1 GA" after:[core-api, audit-log]
|
|
787
|
+
milestone v1-ga "v1 GA" date:2026-06-30 after:[core-api, audit-log]
|
|
788
|
+
.Ed
|
|
789
|
+
.Pp
|
|
790
|
+
At least one of
|
|
791
|
+
.Sy date:
|
|
792
|
+
or
|
|
793
|
+
.Sy after:
|
|
794
|
+
is required.
|
|
795
|
+
With both, the
|
|
796
|
+
.Sy date:
|
|
797
|
+
is an intended target, not a hard cap; slippage (dependencies not
|
|
798
|
+
converging by the target date) is a rendering concern, not a
|
|
799
|
+
validation error.
|
|
800
|
+
.Ss footnote \(em attachable annotation
|
|
801
|
+
.Bd -literal -offset indent
|
|
802
|
+
footnote "Vendor dependency" on:audit-log
|
|
803
|
+
description "Blocked until vendor contract is signed."
|
|
804
|
+
|
|
805
|
+
footnote capacity-risk "Team capacity risk" on:[mobile, platform]
|
|
806
|
+
description "Both teams are understaffed through Q2."
|
|
807
|
+
.Ed
|
|
808
|
+
.Pp
|
|
809
|
+
.Sy on:
|
|
810
|
+
is required and references one or more identifiers (item,
|
|
811
|
+
swimlane, anchor, milestone, person, team).
|
|
812
|
+
Use bracket notation for multiples:
|
|
813
|
+
.Sy on:[id1, id2] .
|
|
814
|
+
Footnotes are numbered sequentially by document order; a
|
|
815
|
+
superscript number appears on every entity the footnote attaches
|
|
816
|
+
to.
|
|
817
|
+
.Ss person and team \(em organisational vocabulary
|
|
818
|
+
.Bd -literal -offset indent
|
|
819
|
+
person sam "Sam Chen" link:https://github.com/samchen
|
|
820
|
+
person jen "Jennifer Wu"
|
|
821
|
+
|
|
822
|
+
team engineering "Engineering"
|
|
823
|
+
team platform "Platform Team"
|
|
824
|
+
person sam
|
|
825
|
+
person jen
|
|
826
|
+
team mobile "Mobile Team"
|
|
827
|
+
.Ed
|
|
828
|
+
.Pp
|
|
829
|
+
A
|
|
830
|
+
.Sy person
|
|
831
|
+
may be declared at the roadmap top level or nested inside a
|
|
832
|
+
.Sy team .
|
|
833
|
+
.Bl -tag -width "person <id>"
|
|
834
|
+
.It Sy person <id>
|
|
835
|
+
Bare reference.
|
|
836
|
+
Inside a
|
|
837
|
+
.Sy team
|
|
838
|
+
it denotes membership.
|
|
839
|
+
At the roadmap top level it is a no-op (parser may emit a
|
|
840
|
+
warning).
|
|
841
|
+
.It Sy person <id> ["title"] [properties]
|
|
842
|
+
Declaration.
|
|
843
|
+
Creates the person.
|
|
844
|
+
If nested inside a
|
|
845
|
+
.Sy team ,
|
|
846
|
+
the declaration also establishes membership.
|
|
847
|
+
.El
|
|
848
|
+
.Pp
|
|
849
|
+
Person identifiers are global within the merged file scope
|
|
850
|
+
regardless of where they are declared.
|
|
851
|
+
A person may be declared at most once in the merged scope;
|
|
852
|
+
duplicate declarations are an error.
|
|
853
|
+
.Pp
|
|
854
|
+
.Sy team
|
|
855
|
+
nesting inside another
|
|
856
|
+
.Sy team
|
|
857
|
+
is always a declaration.
|
|
858
|
+
Teams cannot be referenced with a bare
|
|
859
|
+
.Sy team <id>
|
|
860
|
+
line.
|
|
861
|
+
.Pp
|
|
862
|
+
Both
|
|
863
|
+
.Sy person
|
|
864
|
+
and
|
|
865
|
+
.Sy team
|
|
866
|
+
support
|
|
867
|
+
.Sy link:
|
|
868
|
+
and the
|
|
869
|
+
.Sy description
|
|
870
|
+
sub-directive.
|
|
871
|
+
.Sh UNIVERSAL PROPERTIES
|
|
872
|
+
These properties are valid on every entity type: items, swimlanes,
|
|
873
|
+
parallel blocks, groups, milestones, anchors, persons, teams,
|
|
874
|
+
labels, sizes, statuses, footnotes.
|
|
875
|
+
.Bl -tag -width "description"
|
|
876
|
+
.It Sy labels:
|
|
877
|
+
List.
|
|
878
|
+
Tags for filtering and display.
|
|
879
|
+
.Sy labels:enterprise
|
|
880
|
+
or
|
|
881
|
+
.Sy labels:[enterprise, security] .
|
|
882
|
+
On an item, each label renders as an atomic chiclet inside the
|
|
883
|
+
bar.
|
|
884
|
+
.It Sy link:
|
|
885
|
+
Bare URL (no quotes).
|
|
886
|
+
One link per entity.
|
|
887
|
+
.It Sy style:
|
|
888
|
+
Identifier.
|
|
889
|
+
Single reference to a named style declared in
|
|
890
|
+
.Sy config .
|
|
891
|
+
This is the only visual property allowed on a roadmap-section
|
|
892
|
+
entity.
|
|
893
|
+
.It Sy description
|
|
894
|
+
Sub-directive.
|
|
895
|
+
Indented under the entity.
|
|
896
|
+
Longer explanatory text:
|
|
897
|
+
.Sy description "Details here" .
|
|
898
|
+
.El
|
|
899
|
+
.Pp
|
|
900
|
+
.Sy Content vs. rendering separation .
|
|
901
|
+
Entities in the roadmap section carry only semantic information
|
|
902
|
+
plus an optional single
|
|
903
|
+
.Sy style:id
|
|
904
|
+
reference.
|
|
905
|
+
Raw style properties
|
|
906
|
+
.Po
|
|
907
|
+
.Sy bg , Sy fg , Sy text , Sy border , Sy icon , Sy shadow ,
|
|
908
|
+
.Sy font , Sy weight , Sy italic , Sy text-size , Sy padding ,
|
|
909
|
+
.Sy spacing , Sy header-height , Sy corner-radius , Sy bracket ,
|
|
910
|
+
.Sy capacity-icon , Sy timeline-position , Sy minor-grid
|
|
911
|
+
.Pc
|
|
912
|
+
may only appear in
|
|
913
|
+
.Sy style
|
|
914
|
+
blocks and
|
|
915
|
+
.Sy default <entity>
|
|
916
|
+
lines \(em both of which live in
|
|
917
|
+
.Sy config .
|
|
918
|
+
.Sh ITEM PROPERTIES
|
|
919
|
+
.Sy status , owner , after ,
|
|
920
|
+
and
|
|
921
|
+
.Sy before
|
|
922
|
+
are also valid on swimlanes, parallel blocks, and groups.
|
|
923
|
+
The rest are item-only.
|
|
924
|
+
.Bl -tag -width "remaining"
|
|
925
|
+
.It Sy status:
|
|
926
|
+
Built-in:
|
|
927
|
+
.Sy planned ,
|
|
928
|
+
.Sy in-progress
|
|
929
|
+
.Pq alias Sy active ,
|
|
930
|
+
.Sy done
|
|
931
|
+
.Pq alias Sy completed ,
|
|
932
|
+
.Sy at-risk ,
|
|
933
|
+
.Sy blocked .
|
|
934
|
+
Custom:
|
|
935
|
+
.Sy status:awaiting-review
|
|
936
|
+
matching a
|
|
937
|
+
.Sy status
|
|
938
|
+
declaration.
|
|
939
|
+
.It Sy owner:
|
|
940
|
+
Person or team id.
|
|
941
|
+
Singular \(em one accountable owner.
|
|
942
|
+
.It Sy after:
|
|
943
|
+
Identifier or bracketed list.
|
|
944
|
+
The entity starts after the referenced entity finishes.
|
|
945
|
+
.Sy after:[a, b]
|
|
946
|
+
starts after the latest finisher.
|
|
947
|
+
Accepts item, milestone, anchor, parallel, or group ids.
|
|
948
|
+
.It Sy before:
|
|
949
|
+
Identifier or bracketed list.
|
|
950
|
+
The entity must finish before the referenced entity starts.
|
|
951
|
+
.Sy before:[a, b]
|
|
952
|
+
finishes before the earliest starter.
|
|
953
|
+
.It Sy size:
|
|
954
|
+
Size alias.
|
|
955
|
+
.Sy size:l
|
|
956
|
+
references a
|
|
957
|
+
.Sy size
|
|
958
|
+
declaration; the item's calendar duration is
|
|
959
|
+
.Sy effort \(di item_capacity
|
|
960
|
+
.Pq Sy capacity:
|
|
961
|
+
defaults to
|
|
962
|
+
.Sy 1
|
|
963
|
+
when absent.
|
|
964
|
+
Items only \(em not valid on
|
|
965
|
+
.Sy parallel
|
|
966
|
+
or
|
|
967
|
+
.Sy group .
|
|
968
|
+
.It Sy duration:
|
|
969
|
+
Raw duration literal only
|
|
970
|
+
.Pq Sy 2w , Sy 3m , Sy 0.5d ;
|
|
971
|
+
no alias names.
|
|
972
|
+
.Sy size:
|
|
973
|
+
is the alias mechanism.
|
|
974
|
+
When set alongside
|
|
975
|
+
.Sy size: ,
|
|
976
|
+
.Sy duration:
|
|
977
|
+
wins for bar width and meta-line driver (size chip omitted).
|
|
978
|
+
Items only.
|
|
979
|
+
.It Sy remaining:
|
|
980
|
+
Work remaining.
|
|
981
|
+
Two equivalent forms: percent
|
|
982
|
+
.Pq Sy remaining:30%
|
|
983
|
+
or single-eng effort literal
|
|
984
|
+
.Pq Sy remaining:1w , Sy remaining:0.5d .
|
|
985
|
+
A literal is normalized to a percent during layout.
|
|
986
|
+
Both forms render identically.
|
|
987
|
+
.Sy status:done
|
|
988
|
+
takes priority.
|
|
989
|
+
Items only.
|
|
990
|
+
.It Sy capacity:
|
|
991
|
+
Concurrent capacity consumed by this item while it runs.
|
|
992
|
+
Positive integer
|
|
993
|
+
.Pq Sy capacity:2 ,
|
|
994
|
+
decimal
|
|
995
|
+
.Pq Sy capacity:0.5 ,
|
|
996
|
+
or percent literal
|
|
997
|
+
.Pq Sy capacity:50%
|
|
998
|
+
which parses to a decimal.
|
|
999
|
+
Items only.
|
|
1000
|
+
.El
|
|
1001
|
+
.Pp
|
|
1002
|
+
.Sy Required properties .
|
|
1003
|
+
.Sy item
|
|
1004
|
+
declarations must include at least one of
|
|
1005
|
+
.Sy size:
|
|
1006
|
+
or
|
|
1007
|
+
.Sy duration: .
|
|
1008
|
+
.Sy anchor
|
|
1009
|
+
declarations require
|
|
1010
|
+
.Sy date: .
|
|
1011
|
+
.Sy milestone
|
|
1012
|
+
declarations require at least one of
|
|
1013
|
+
.Sy date:
|
|
1014
|
+
or
|
|
1015
|
+
.Sy after: .
|
|
1016
|
+
.Sy footnote
|
|
1017
|
+
declarations require
|
|
1018
|
+
.Sy on: .
|
|
1019
|
+
Omitting a required property is a validation error that names the
|
|
1020
|
+
entity by id or title.
|
|
1021
|
+
.Sh CAPACITY
|
|
1022
|
+
.Sy capacity:
|
|
1023
|
+
is an optional annotation that models per-timestep throughput.
|
|
1024
|
+
Both swimlanes and items may declare it, and the two annotations
|
|
1025
|
+
are fully independent \(em neither requires the other.
|
|
1026
|
+
.Bd -literal -offset indent
|
|
1027
|
+
swimlane platform capacity:5
|
|
1028
|
+
item auth size:l capacity:2
|
|
1029
|
+
parallel
|
|
1030
|
+
item api size:m capacity:2
|
|
1031
|
+
item sdk size:m capacity:1
|
|
1032
|
+
item qa size:s capacity:50%
|
|
1033
|
+
.Ed
|
|
1034
|
+
.Pp
|
|
1035
|
+
The unit is opaque to the DSL: authors decide whether
|
|
1036
|
+
.Sy 5
|
|
1037
|
+
means engineers, story points, FTE, hours, or any other measure
|
|
1038
|
+
.Pq same opacity contract as Sy size:l until a Sy size declaration gives it meaning .
|
|
1039
|
+
.Pp
|
|
1040
|
+
Where it can appear:
|
|
1041
|
+
.Bl -tag -width "swimlane"
|
|
1042
|
+
.It Sy swimlane
|
|
1043
|
+
Integer or decimal only (no percent form).
|
|
1044
|
+
The lane's per-timestep budget.
|
|
1045
|
+
.It Sy item
|
|
1046
|
+
Integer, decimal, or percent literal.
|
|
1047
|
+
The item's concurrent consumption.
|
|
1048
|
+
.It Sy parallel , Sy group
|
|
1049
|
+
Not valid \(em derived from children (sum at each timestep across
|
|
1050
|
+
parallel; pass-through for group).
|
|
1051
|
+
Same exclusion family as
|
|
1052
|
+
.Sy size , duration , remaining .
|
|
1053
|
+
.El
|
|
1054
|
+
.Pp
|
|
1055
|
+
Default capacity:
|
|
1056
|
+
.Bl -tag -width "Duration-literal items"
|
|
1057
|
+
.It Sy Sized items
|
|
1058
|
+
.Sy size:
|
|
1059
|
+
declared, no explicit
|
|
1060
|
+
.Sy capacity: \(em
|
|
1061
|
+
capacity defaults to
|
|
1062
|
+
.Sy 1
|
|
1063
|
+
in both duration derivation
|
|
1064
|
+
.Pq Sy duration = effort \(di 1 = effort
|
|
1065
|
+
and overload accounting.
|
|
1066
|
+
.It Sy Duration-literal items
|
|
1067
|
+
.Sy duration:
|
|
1068
|
+
declared, no
|
|
1069
|
+
.Sy size: ,
|
|
1070
|
+
no explicit
|
|
1071
|
+
.Sy capacity: \(em
|
|
1072
|
+
capacity stays unset and the item contributes
|
|
1073
|
+
.Sy 0
|
|
1074
|
+
to overload (uncounted).
|
|
1075
|
+
The literal duration is the bar width regardless.
|
|
1076
|
+
.It Sy Explicit Sy capacity:N
|
|
1077
|
+
Always wins for both purposes.
|
|
1078
|
+
.El
|
|
1079
|
+
.Pp
|
|
1080
|
+
Lifetime: capacity is constant for the item's full duration.
|
|
1081
|
+
No ramps in
|
|
1082
|
+
.Sy v1 .
|
|
1083
|
+
.Pp
|
|
1084
|
+
.Sy Utilization thresholds .
|
|
1085
|
+
Swimlanes that declare
|
|
1086
|
+
.Sy capacity:
|
|
1087
|
+
paint a tri-state utilization underline (green / yellow / red)
|
|
1088
|
+
along the bottom of the band based on the per-timestep load
|
|
1089
|
+
function
|
|
1090
|
+
.Sy f(x) = \(*S items[i].capacity for items active at x .
|
|
1091
|
+
.Bl -tag -width "utilization-over-at"
|
|
1092
|
+
.It Sy utilization-warn-at:N% Pq default Sy 80%
|
|
1093
|
+
At or above this fraction of
|
|
1094
|
+
.Sy capacity: ,
|
|
1095
|
+
the segment paints
|
|
1096
|
+
.Sy yellow .
|
|
1097
|
+
.It Sy utilization-over-at:N% Pq default Sy 100%
|
|
1098
|
+
At or above this fraction of
|
|
1099
|
+
.Sy capacity: ,
|
|
1100
|
+
the segment paints
|
|
1101
|
+
.Sy red .
|
|
1102
|
+
.El
|
|
1103
|
+
.Pp
|
|
1104
|
+
Below
|
|
1105
|
+
.Sy warn-at
|
|
1106
|
+
the segment paints
|
|
1107
|
+
.Sy green .
|
|
1108
|
+
Both thresholds accept the literal value
|
|
1109
|
+
.Sy none
|
|
1110
|
+
to opt out of that color band:
|
|
1111
|
+
.Sy utilization-warn-at:none
|
|
1112
|
+
collapses to a binary green/red indicator;
|
|
1113
|
+
.Sy utilization-over-at:none
|
|
1114
|
+
removes red entirely; setting both to
|
|
1115
|
+
.Sy none
|
|
1116
|
+
suppresses the underline outright.
|
|
1117
|
+
.Sh SIZING PRECEDENCE
|
|
1118
|
+
When an item declares both
|
|
1119
|
+
.Sy size:
|
|
1120
|
+
and
|
|
1121
|
+
.Sy duration: ,
|
|
1122
|
+
the explicit
|
|
1123
|
+
.Sy duration:
|
|
1124
|
+
literal wins for bar width and the meta line: the size chip is
|
|
1125
|
+
not shown (only the literal appears as the driver token).
|
|
1126
|
+
.Bl -column -offset indent "size:" "duration:" "capacity:" "Resulting duration"
|
|
1127
|
+
.It Sy size: Ta Sy duration: Ta Sy capacity: Ta Resulting duration
|
|
1128
|
+
.It l Ta \(em Ta \(em Ta size.l.effort \(di 1 (e.g. 2w)
|
|
1129
|
+
.It l Ta \(em Ta 2 Ta size.l.effort \(di 2 (e.g. 1w)
|
|
1130
|
+
.It l Ta 2w Ta 2 Ta 2w (literal wins; no chip)
|
|
1131
|
+
.It \(em Ta 2w Ta 2 Ta 2w (capacity does not divide a literal)
|
|
1132
|
+
.It \(em Ta \(em Ta \(em Ta validation error
|
|
1133
|
+
.El
|
|
1134
|
+
.Sh STYLE PROPERTIES
|
|
1135
|
+
Properties valid inside a
|
|
1136
|
+
.Sy style
|
|
1137
|
+
block (and on
|
|
1138
|
+
.Sy default <entity>
|
|
1139
|
+
lines):
|
|
1140
|
+
.Bl -tag -width "timeline-position"
|
|
1141
|
+
.It Sy bg
|
|
1142
|
+
Background/fill color or
|
|
1143
|
+
.Sy none .
|
|
1144
|
+
Named
|
|
1145
|
+
.Po
|
|
1146
|
+
.Sy red , blue , yellow , green , orange ,
|
|
1147
|
+
.Sy purple
|
|
1148
|
+
.Pq alias Sy violet ,
|
|
1149
|
+
.Sy gray
|
|
1150
|
+
.Pq alias Sy grey ,
|
|
1151
|
+
.Sy navy , white
|
|
1152
|
+
.Pc ,
|
|
1153
|
+
hex
|
|
1154
|
+
.Pq Sy #2563eb ,
|
|
1155
|
+
or
|
|
1156
|
+
.Sy none
|
|
1157
|
+
(transparent).
|
|
1158
|
+
.It Sy fg
|
|
1159
|
+
Border/outline color.
|
|
1160
|
+
Named, hex, or
|
|
1161
|
+
.Sy none
|
|
1162
|
+
(no border).
|
|
1163
|
+
.It Sy text
|
|
1164
|
+
Text color.
|
|
1165
|
+
Named, hex, or
|
|
1166
|
+
.Sy none
|
|
1167
|
+
(hides text).
|
|
1168
|
+
.It Sy border
|
|
1169
|
+
.Sy solid | dashed | dotted .
|
|
1170
|
+
.It Sy icon
|
|
1171
|
+
Identifier or string.
|
|
1172
|
+
Built-in identifiers
|
|
1173
|
+
.Po
|
|
1174
|
+
.Sy shield , warning , lock , plus the capacity-icon vocabulary
|
|
1175
|
+
.Pc ;
|
|
1176
|
+
custom: any identifier declared by a
|
|
1177
|
+
.Sy symbol
|
|
1178
|
+
declaration; inline: a double-quoted Unicode literal
|
|
1179
|
+
.Pq Sy "\(rs"
|
|
1180
|
+
\(em font-dependent.
|
|
1181
|
+
.It Sy shadow
|
|
1182
|
+
.Sy none Pq default | subtle | soft | hard .
|
|
1183
|
+
.It Sy font
|
|
1184
|
+
.Sy sans Pq default | serif | mono .
|
|
1185
|
+
.It Sy weight
|
|
1186
|
+
.Sy thin | light | normal Pq default | bold .
|
|
1187
|
+
.It Sy italic
|
|
1188
|
+
.Sy true | false Pq default .
|
|
1189
|
+
.It Sy text-size
|
|
1190
|
+
.Sy xs | sm | md Pq default | lg | xl .
|
|
1191
|
+
.It Sy padding
|
|
1192
|
+
.Sy none | xs | sm | md Pq default | lg | xl .
|
|
1193
|
+
.It Sy spacing
|
|
1194
|
+
.Sy none | xs | sm | md | lg | xl .
|
|
1195
|
+
Default varies by entity.
|
|
1196
|
+
.It Sy header-height
|
|
1197
|
+
.Sy none | xs | sm | md Pq default | lg | xl .
|
|
1198
|
+
Roadmap-only.
|
|
1199
|
+
.It Sy corner-radius
|
|
1200
|
+
.Sy none | xs | sm | md | lg | xl | full .
|
|
1201
|
+
.It Sy bracket
|
|
1202
|
+
.Sy none Pq default | solid | dashed .
|
|
1203
|
+
Parallel-only.
|
|
1204
|
+
.It Sy capacity-icon
|
|
1205
|
+
Glyph used as the suffix to capacity numbers.
|
|
1206
|
+
Built-in identifiers:
|
|
1207
|
+
.Sy none ,
|
|
1208
|
+
.Sy multiplier
|
|
1209
|
+
.Pq default \(em "\(mu" ,
|
|
1210
|
+
.Sy person ,
|
|
1211
|
+
.Sy people ,
|
|
1212
|
+
.Sy points
|
|
1213
|
+
.Pq "\(em" ,
|
|
1214
|
+
.Sy time
|
|
1215
|
+
.Pq "\(em" .
|
|
1216
|
+
Custom: any
|
|
1217
|
+
.Sy symbol
|
|
1218
|
+
id; inline: a double-quoted Unicode literal.
|
|
1219
|
+
.It Sy timeline-position
|
|
1220
|
+
.Sy top Pq default | bottom | both .
|
|
1221
|
+
Roadmap-only.
|
|
1222
|
+
.Sy both
|
|
1223
|
+
mirrors the date strip at the chart bottom.
|
|
1224
|
+
.It Sy minor-grid
|
|
1225
|
+
.Sy true | false Pq default .
|
|
1226
|
+
Roadmap-only.
|
|
1227
|
+
When
|
|
1228
|
+
.Sy true ,
|
|
1229
|
+
draws faint dotted grid lines at every tick boundary.
|
|
1230
|
+
.El
|
|
1231
|
+
.Pp
|
|
1232
|
+
Built-in icon names are rendered from a curated SVG library
|
|
1233
|
+
shipped with the renderer, not from Unicode emoji codepoints.
|
|
1234
|
+
This guarantees consistent visual output across every platform
|
|
1235
|
+
(web, CLI, exports).
|
|
1236
|
+
Authors who want platform-default emoji rendering use an inline
|
|
1237
|
+
Unicode literal instead of the named identifier.
|
|
1238
|
+
.Sh GRAMMAR
|
|
1239
|
+
.Ss Universal declaration pattern
|
|
1240
|
+
Every entity declaration follows the same shape:
|
|
1241
|
+
.Bd -literal -offset indent
|
|
1242
|
+
keyword [id] ["title"] [key:value ...]
|
|
1243
|
+
.Ed
|
|
1244
|
+
.Bl -tag -width "Identifier"
|
|
1245
|
+
.It Sy Identifier
|
|
1246
|
+
Unquoted, matches
|
|
1247
|
+
.Sy [a-zA-Z_][a-zA-Z0-9_-]* .
|
|
1248
|
+
Used for referencing.
|
|
1249
|
+
Optional \(em auto-generated from the title (kebab-cased) if
|
|
1250
|
+
omitted.
|
|
1251
|
+
.It Sy Title
|
|
1252
|
+
Double-quoted string.
|
|
1253
|
+
Human-readable display name.
|
|
1254
|
+
Optional.
|
|
1255
|
+
Always double-quoted, even single-word titles \(em the quote is
|
|
1256
|
+
how the parser distinguishes id from title.
|
|
1257
|
+
.El
|
|
1258
|
+
.Pp
|
|
1259
|
+
At least one of
|
|
1260
|
+
.Sy id
|
|
1261
|
+
or
|
|
1262
|
+
.Sy "title"
|
|
1263
|
+
must be present.
|
|
1264
|
+
Every other input is a keyed property using
|
|
1265
|
+
.Sy key:value .
|
|
1266
|
+
.Pp
|
|
1267
|
+
The
|
|
1268
|
+
.Sy nowline
|
|
1269
|
+
directive is the only construct without an id or title; every
|
|
1270
|
+
other declaration follows this pattern.
|
|
1271
|
+
.Ss Identifiers
|
|
1272
|
+
Identifiers match
|
|
1273
|
+
.Sy [a-zA-Z_][a-zA-Z0-9_-]* \(em
|
|
1274
|
+
letters, digits, underscores, and dashes, starting with a letter
|
|
1275
|
+
or underscore.
|
|
1276
|
+
They must be unique across the merged result (the file and all
|
|
1277
|
+
its includes); items, parallel blocks, groups, anchors, persons,
|
|
1278
|
+
teams, milestones, footnotes share one namespace.
|
|
1279
|
+
.Pp
|
|
1280
|
+
Idiomatic Nowline uses kebab-case but
|
|
1281
|
+
.Sy authRefactor ,
|
|
1282
|
+
.Sy auth_refactor ,
|
|
1283
|
+
and
|
|
1284
|
+
.Sy MED
|
|
1285
|
+
are equally valid.
|
|
1286
|
+
.Pp
|
|
1287
|
+
When omitted, the parser generates one by slugifying the title to
|
|
1288
|
+
kebab-case:
|
|
1289
|
+
.Qq Audit log v2
|
|
1290
|
+
becomes
|
|
1291
|
+
.Sy audit-log-v2 .
|
|
1292
|
+
.Ss Lists
|
|
1293
|
+
Any list-typed property accepts a single value without brackets or
|
|
1294
|
+
multiple values with bracket notation:
|
|
1295
|
+
.Bd -literal -offset indent
|
|
1296
|
+
labels:enterprise
|
|
1297
|
+
labels:[enterprise, security]
|
|
1298
|
+
.Ed
|
|
1299
|
+
.Pp
|
|
1300
|
+
No quotes around identifiers in lists.
|
|
1301
|
+
Comma-separated, optional spaces.
|
|
1302
|
+
.Ss Dependencies
|
|
1303
|
+
.Sy after:
|
|
1304
|
+
and
|
|
1305
|
+
.Sy before:
|
|
1306
|
+
each accept a single identifier or a bracketed list.
|
|
1307
|
+
References may target items, milestones, anchors, parallel
|
|
1308
|
+
blocks, or groups.
|
|
1309
|
+
.Bl -bullet -offset indent -compact
|
|
1310
|
+
.It
|
|
1311
|
+
.Sy after:id
|
|
1312
|
+
\(em this entity starts after the referenced entity finishes (or
|
|
1313
|
+
after the referenced anchor date).
|
|
1314
|
+
.It
|
|
1315
|
+
.Sy after:[id1, id2, ...]
|
|
1316
|
+
\(em starts after
|
|
1317
|
+
.Em all
|
|
1318
|
+
referenced entities finish (i.e. after the latest of them).
|
|
1319
|
+
.It
|
|
1320
|
+
.Sy before:id
|
|
1321
|
+
\(em this entity must finish before the referenced entity starts
|
|
1322
|
+
(or before the referenced anchor date).
|
|
1323
|
+
.It
|
|
1324
|
+
.Sy before:[id1, id2, ...]
|
|
1325
|
+
\(em finishes before the
|
|
1326
|
+
.Em earliest
|
|
1327
|
+
of the referenced entities starts.
|
|
1328
|
+
.El
|
|
1329
|
+
.Pp
|
|
1330
|
+
Circular dependencies across the full graph (including every
|
|
1331
|
+
element of list-form references) are a validation error.
|
|
1332
|
+
.Ss Line continuation
|
|
1333
|
+
A trailing
|
|
1334
|
+
.Sq \e
|
|
1335
|
+
means the next line continues the same declaration.
|
|
1336
|
+
Indentation on the continuation line is cosmetic.
|
|
1337
|
+
Only valid at the end of a property line \(em not inside strings
|
|
1338
|
+
or comments.
|
|
1339
|
+
Use
|
|
1340
|
+
.Sq \e\e
|
|
1341
|
+
for a literal backslash.
|
|
1342
|
+
.Bd -literal -offset indent
|
|
1343
|
+
item auth "Auth refactor" duration:2w status:in-progress \e
|
|
1344
|
+
owner:sam labels:[security,enterprise] \e
|
|
1345
|
+
link:https://github.com/acme/auth/issues/123 \e
|
|
1346
|
+
style:flagged
|
|
1347
|
+
.Ed
|
|
1348
|
+
.Ss Comments
|
|
1349
|
+
.Bd -literal -offset indent
|
|
1350
|
+
// This is a single-line comment
|
|
1351
|
+
|
|
1352
|
+
/* This is a
|
|
1353
|
+
multi-line comment */
|
|
1354
|
+
.Ed
|
|
1355
|
+
.Sh VALIDATION
|
|
1356
|
+
The parser produces clear error messages with file position and
|
|
1357
|
+
suggestions (fuzzy-match
|
|
1358
|
+
.Qq did you mean X?
|
|
1359
|
+
hints).
|
|
1360
|
+
Rules group as follows; full prose lives in
|
|
1361
|
+
.Pa specs/dsl.md .
|
|
1362
|
+
.Ss Structural
|
|
1363
|
+
.Bl -bullet -offset indent -compact
|
|
1364
|
+
.It
|
|
1365
|
+
Exactly one
|
|
1366
|
+
.Sy roadmap
|
|
1367
|
+
declaration per file (subject to
|
|
1368
|
+
.Sy include
|
|
1369
|
+
.Sy roadmap:
|
|
1370
|
+
mode).
|
|
1371
|
+
.It
|
|
1372
|
+
All identifiers are unique across the merged result.
|
|
1373
|
+
Parent wins on collision, with a warning.
|
|
1374
|
+
.It
|
|
1375
|
+
Every entity must have at least an identifier or a title (or
|
|
1376
|
+
both).
|
|
1377
|
+
.It
|
|
1378
|
+
File structure must follow the section order:
|
|
1379
|
+
.Sy nowline
|
|
1380
|
+
directive (optional, first non-comment line),
|
|
1381
|
+
.Sy include ,
|
|
1382
|
+
.Sy config ,
|
|
1383
|
+
.Sy roadmap .
|
|
1384
|
+
.It
|
|
1385
|
+
The
|
|
1386
|
+
.Sy nowline
|
|
1387
|
+
directive version must match
|
|
1388
|
+
.Sy v\&\ed+ .
|
|
1389
|
+
A version newer than the parser supports is an error identifying
|
|
1390
|
+
the required version.
|
|
1391
|
+
.It
|
|
1392
|
+
At least one swimlane is required in the merged result.
|
|
1393
|
+
.It
|
|
1394
|
+
Indentation must be consistent within a file: spaces
|
|
1395
|
+
.Em or
|
|
1396
|
+
tabs, not both.
|
|
1397
|
+
Mixed indentation is a parse error identifying the first offending
|
|
1398
|
+
line.
|
|
1399
|
+
.It
|
|
1400
|
+
.Sy label ,
|
|
1401
|
+
.Sy size ,
|
|
1402
|
+
and
|
|
1403
|
+
.Sy status
|
|
1404
|
+
declarations must appear in the roadmap section.
|
|
1405
|
+
Placing them before
|
|
1406
|
+
.Sy roadmap
|
|
1407
|
+
is an error.
|
|
1408
|
+
.El
|
|
1409
|
+
.Ss References
|
|
1410
|
+
.Bl -bullet -offset indent -compact
|
|
1411
|
+
.It
|
|
1412
|
+
All elements of
|
|
1413
|
+
.Sy after: ,
|
|
1414
|
+
.Sy before: ,
|
|
1415
|
+
and
|
|
1416
|
+
.Sy on:
|
|
1417
|
+
must resolve to declared identifiers within the merged scope.
|
|
1418
|
+
.It
|
|
1419
|
+
A
|
|
1420
|
+
.Sy size:
|
|
1421
|
+
or
|
|
1422
|
+
.Sy status:
|
|
1423
|
+
reference must resolve to a declaration that appears
|
|
1424
|
+
.Em earlier in the file
|
|
1425
|
+
(or in an earlier include).
|
|
1426
|
+
Forward references are an error.
|
|
1427
|
+
.It
|
|
1428
|
+
No circular dependencies in
|
|
1429
|
+
.Sy after / before
|
|
1430
|
+
chains.
|
|
1431
|
+
.El
|
|
1432
|
+
.Ss Values
|
|
1433
|
+
.Bl -bullet -offset indent -compact
|
|
1434
|
+
.It
|
|
1435
|
+
.Sy anchor date:
|
|
1436
|
+
and dated
|
|
1437
|
+
.Sy milestone date:
|
|
1438
|
+
values are valid ISO 8601 dates
|
|
1439
|
+
.Pq Pa YYYY-MM-DD , calendar-valid .
|
|
1440
|
+
.It
|
|
1441
|
+
.Sy duration:
|
|
1442
|
+
and
|
|
1443
|
+
.Sy scale:
|
|
1444
|
+
values match the raw duration pattern
|
|
1445
|
+
.Sy \&\ed+(\e.\ed+)?[dwmqy] .
|
|
1446
|
+
.It
|
|
1447
|
+
A
|
|
1448
|
+
.Sy size
|
|
1449
|
+
declaration's id must not match the raw duration pattern and must
|
|
1450
|
+
not be a bare
|
|
1451
|
+
.Sy d , w , m , q , y .
|
|
1452
|
+
.It
|
|
1453
|
+
Every
|
|
1454
|
+
.Sy size
|
|
1455
|
+
declaration must specify
|
|
1456
|
+
.Sy effort: ;
|
|
1457
|
+
the value must be a positive raw duration literal.
|
|
1458
|
+
.It
|
|
1459
|
+
.Sy capacity:
|
|
1460
|
+
on a
|
|
1461
|
+
.Sy swimlane
|
|
1462
|
+
must be a positive integer or decimal (no percent form).
|
|
1463
|
+
.Sy capacity:
|
|
1464
|
+
on an
|
|
1465
|
+
.Sy item
|
|
1466
|
+
must be a positive integer, decimal, or percent literal.
|
|
1467
|
+
.Sy capacity:
|
|
1468
|
+
is not valid on
|
|
1469
|
+
.Sy parallel
|
|
1470
|
+
or
|
|
1471
|
+
.Sy group .
|
|
1472
|
+
.It
|
|
1473
|
+
.Sy utilization-warn-at:
|
|
1474
|
+
and
|
|
1475
|
+
.Sy utilization-over-at:
|
|
1476
|
+
must each be a positive percent literal, a positive decimal
|
|
1477
|
+
fraction, or
|
|
1478
|
+
.Sy none .
|
|
1479
|
+
When both numeric thresholds are set,
|
|
1480
|
+
.Sy warn-at \(<= over-at .
|
|
1481
|
+
.It
|
|
1482
|
+
.Sy capacity-icon:
|
|
1483
|
+
value must be a built-in identifier
|
|
1484
|
+
.Po
|
|
1485
|
+
.Sy none , Sy multiplier , Sy person , Sy people , Sy points , Sy time
|
|
1486
|
+
.Pc ,
|
|
1487
|
+
an identifier matching a
|
|
1488
|
+
.Sy symbol
|
|
1489
|
+
declaration in scope, or a double-quoted Unicode literal.
|
|
1490
|
+
Same contract for
|
|
1491
|
+
.Sy icon: .
|
|
1492
|
+
.It
|
|
1493
|
+
.Sy remaining:
|
|
1494
|
+
is either a percentage
|
|
1495
|
+
.Pq Sy 0% \(en Sy 100%
|
|
1496
|
+
or a single-eng effort literal.
|
|
1497
|
+
When the literal exceeds total effort (computed percent
|
|
1498
|
+
.Sy > 100% ) ,
|
|
1499
|
+
the layout step emits a soft warning and clamps the painted bar
|
|
1500
|
+
to 100% remaining; rendering is never blocked.
|
|
1501
|
+
.El
|
|
1502
|
+
.Ss Calendar
|
|
1503
|
+
.Bl -bullet -offset indent -compact
|
|
1504
|
+
.It
|
|
1505
|
+
.Sy calendar:
|
|
1506
|
+
on
|
|
1507
|
+
.Sy roadmap
|
|
1508
|
+
must be one of
|
|
1509
|
+
.Sy business , full , custom .
|
|
1510
|
+
.It
|
|
1511
|
+
A
|
|
1512
|
+
.Sy calendar
|
|
1513
|
+
config block is only valid when the roadmap declares
|
|
1514
|
+
.Sy calendar:custom .
|
|
1515
|
+
.It
|
|
1516
|
+
When
|
|
1517
|
+
.Sy calendar:custom ,
|
|
1518
|
+
all four
|
|
1519
|
+
.Sy days-per-*
|
|
1520
|
+
entries are required and must be positive integers.
|
|
1521
|
+
.El
|
|
1522
|
+
.Ss Roadmap start property
|
|
1523
|
+
.Bl -bullet -offset indent -compact
|
|
1524
|
+
.It
|
|
1525
|
+
.Sy roadmap start:
|
|
1526
|
+
must be a valid ISO 8601 date.
|
|
1527
|
+
.It
|
|
1528
|
+
If a file contains any
|
|
1529
|
+
.Sy anchor
|
|
1530
|
+
or any dated
|
|
1531
|
+
.Sy milestone ,
|
|
1532
|
+
.Sy start:
|
|
1533
|
+
is required.
|
|
1534
|
+
.It
|
|
1535
|
+
Every anchor date and every dated milestone date must be on or
|
|
1536
|
+
after
|
|
1537
|
+
.Sy start: .
|
|
1538
|
+
.El
|
|
1539
|
+
.Ss Persons and teams
|
|
1540
|
+
.Bl -bullet -offset indent -compact
|
|
1541
|
+
.It
|
|
1542
|
+
A
|
|
1543
|
+
.Sy person
|
|
1544
|
+
may be declared at most once in the merged file scope.
|
|
1545
|
+
A declaration is identified by the presence of a title or any
|
|
1546
|
+
keyed property on the line.
|
|
1547
|
+
.It
|
|
1548
|
+
A bare
|
|
1549
|
+
.Sy person <id>
|
|
1550
|
+
inside a
|
|
1551
|
+
.Sy team
|
|
1552
|
+
denotes membership and is valid with or without a separate
|
|
1553
|
+
declaration.
|
|
1554
|
+
.It
|
|
1555
|
+
A bare
|
|
1556
|
+
.Sy person <id>
|
|
1557
|
+
at roadmap top level with no matching declaration anywhere is a
|
|
1558
|
+
no-op (parser may emit a warning).
|
|
1559
|
+
.El
|
|
1560
|
+
.Ss Includes
|
|
1561
|
+
.Bl -bullet -offset indent -compact
|
|
1562
|
+
.It
|
|
1563
|
+
.Sy include
|
|
1564
|
+
paths must resolve to an existing
|
|
1565
|
+
.Pa .nowline
|
|
1566
|
+
file relative to the including file's directory.
|
|
1567
|
+
.It
|
|
1568
|
+
No circular includes.
|
|
1569
|
+
.It
|
|
1570
|
+
.Sy include
|
|
1571
|
+
declarations appear before
|
|
1572
|
+
.Sy config
|
|
1573
|
+
and
|
|
1574
|
+
.Sy roadmap
|
|
1575
|
+
(after the
|
|
1576
|
+
.Sy nowline
|
|
1577
|
+
directive if present).
|
|
1578
|
+
.It
|
|
1579
|
+
Duplicate
|
|
1580
|
+
.Sy include
|
|
1581
|
+
of the same file in a single file is an error.
|
|
1582
|
+
.It
|
|
1583
|
+
.Sy config:
|
|
1584
|
+
must be
|
|
1585
|
+
.Sy merge , ignore , or isolate .
|
|
1586
|
+
.Sy roadmap:
|
|
1587
|
+
must be
|
|
1588
|
+
.Sy merge , ignore , or isolate .
|
|
1589
|
+
.It
|
|
1590
|
+
On
|
|
1591
|
+
.Sy config:isolate ,
|
|
1592
|
+
.Sy style:
|
|
1593
|
+
references within the isolated file must resolve within that
|
|
1594
|
+
file's own config.
|
|
1595
|
+
.It
|
|
1596
|
+
On
|
|
1597
|
+
.Sy roadmap:isolate ,
|
|
1598
|
+
the included file must contain a
|
|
1599
|
+
.Sy roadmap
|
|
1600
|
+
declaration.
|
|
1601
|
+
.It
|
|
1602
|
+
For any
|
|
1603
|
+
.Sy include
|
|
1604
|
+
whose
|
|
1605
|
+
.Sy roadmap:
|
|
1606
|
+
mode is not
|
|
1607
|
+
.Sy ignore ,
|
|
1608
|
+
parent and child must agree on
|
|
1609
|
+
.Sy start: \(em
|
|
1610
|
+
both absent or both present with identical values.
|
|
1611
|
+
A mismatch is an error reported on the parent's
|
|
1612
|
+
.Sy include
|
|
1613
|
+
line.
|
|
1614
|
+
.El
|
|
1615
|
+
.Ss Parallel and group
|
|
1616
|
+
.Bl -bullet -offset indent -compact
|
|
1617
|
+
.It
|
|
1618
|
+
.Sy parallel
|
|
1619
|
+
must contain at least 2 children.
|
|
1620
|
+
A single-child parallel emits a warning.
|
|
1621
|
+
.It
|
|
1622
|
+
.Sy group
|
|
1623
|
+
must contain at least 1 child.
|
|
1624
|
+
.It
|
|
1625
|
+
.Sy size , duration , remaining , capacity
|
|
1626
|
+
are not valid on
|
|
1627
|
+
.Sy parallel
|
|
1628
|
+
or
|
|
1629
|
+
.Sy group
|
|
1630
|
+
(computed from children).
|
|
1631
|
+
.It
|
|
1632
|
+
.Sy parallel
|
|
1633
|
+
is valid inside swimlane or group.
|
|
1634
|
+
.Pp
|
|
1635
|
+
.Sy group
|
|
1636
|
+
is valid inside swimlane, parallel, or group.
|
|
1637
|
+
.El
|
|
1638
|
+
.Ss Defaults
|
|
1639
|
+
.Bl -bullet -offset indent -compact
|
|
1640
|
+
.It
|
|
1641
|
+
The first positional argument after
|
|
1642
|
+
.Sy default
|
|
1643
|
+
must be one of:
|
|
1644
|
+
.Sy item , label , swimlane , roadmap , parallel , group ,
|
|
1645
|
+
.Sy milestone , footnote , anchor .
|
|
1646
|
+
.It
|
|
1647
|
+
Duplicate
|
|
1648
|
+
.Sy default <entity>
|
|
1649
|
+
declarations for the same entity type within a single file are
|
|
1650
|
+
an error.
|
|
1651
|
+
.It
|
|
1652
|
+
A
|
|
1653
|
+
.Sy default <entity>
|
|
1654
|
+
that sets a banned property
|
|
1655
|
+
.Pq see Sx CONFIG SECTION
|
|
1656
|
+
is an error.
|
|
1657
|
+
.El
|
|
1658
|
+
.Ss Symbols
|
|
1659
|
+
.Bl -bullet -offset indent -compact
|
|
1660
|
+
.It
|
|
1661
|
+
Every
|
|
1662
|
+
.Sy symbol
|
|
1663
|
+
declaration must specify a non-empty
|
|
1664
|
+
.Sy unicode:"<string>" .
|
|
1665
|
+
.It
|
|
1666
|
+
.Sy ascii: ,
|
|
1667
|
+
if present, must be a quoted string of length \(<= 3 ASCII
|
|
1668
|
+
characters.
|
|
1669
|
+
.It
|
|
1670
|
+
A
|
|
1671
|
+
.Sy symbol
|
|
1672
|
+
id must not shadow a built-in icon name.
|
|
1673
|
+
.It
|
|
1674
|
+
A
|
|
1675
|
+
.Sy symbol
|
|
1676
|
+
reference
|
|
1677
|
+
.Pq Sy icon:NAME or Sy capacity-icon:NAME
|
|
1678
|
+
must resolve to a built-in or an earlier
|
|
1679
|
+
.Sy symbol
|
|
1680
|
+
declaration.
|
|
1681
|
+
Forward references are an error.
|
|
1682
|
+
.El
|
|
1683
|
+
.Sh EXAMPLES
|
|
1684
|
+
A complete
|
|
1685
|
+
.Pa .nowline
|
|
1686
|
+
file exercising the major language features:
|
|
1687
|
+
.Bd -literal -offset indent
|
|
1688
|
+
nowline v1
|
|
1689
|
+
|
|
1690
|
+
include "shared/teams.nowline"
|
|
1691
|
+
|
|
1692
|
+
config
|
|
1693
|
+
|
|
1694
|
+
style enterprise "Enterprise readiness"
|
|
1695
|
+
bg: blue
|
|
1696
|
+
fg: navy
|
|
1697
|
+
text: white
|
|
1698
|
+
border: solid
|
|
1699
|
+
icon: shield
|
|
1700
|
+
|
|
1701
|
+
style risky
|
|
1702
|
+
border: dashed
|
|
1703
|
+
fg: orange
|
|
1704
|
+
|
|
1705
|
+
default item status:planned shadow:subtle
|
|
1706
|
+
default label style:subtle corner-radius:full
|
|
1707
|
+
default swimlane padding:sm spacing:none
|
|
1708
|
+
|
|
1709
|
+
roadmap platform-2026 "Platform 2026" \e
|
|
1710
|
+
author:"Acme Engineering" \e
|
|
1711
|
+
logo:"./brand/acme.svg" \e
|
|
1712
|
+
start:2026-01-06 scale:2w calendar:business
|
|
1713
|
+
|
|
1714
|
+
person sam "Sam Chen" link:https://github.com/samchen
|
|
1715
|
+
person jen "Jennifer Wu"
|
|
1716
|
+
|
|
1717
|
+
team engineering "Engineering"
|
|
1718
|
+
team platform "Platform Team"
|
|
1719
|
+
person sam
|
|
1720
|
+
person jen
|
|
1721
|
+
team mobile "Mobile Team"
|
|
1722
|
+
|
|
1723
|
+
anchor kickoff date:2026-01-06
|
|
1724
|
+
anchor code-freeze "Code Freeze" date:2026-05-01
|
|
1725
|
+
anchor ga-date "GA Date" date:2026-06-01
|
|
1726
|
+
|
|
1727
|
+
size xs "Extra Small" effort:1d
|
|
1728
|
+
size s "Small" effort:3d
|
|
1729
|
+
size m "Medium" effort:1w
|
|
1730
|
+
size l "Large" effort:2w
|
|
1731
|
+
size xl "Extra Large" effort:1m
|
|
1732
|
+
|
|
1733
|
+
status awaiting-review "Awaiting Review"
|
|
1734
|
+
|
|
1735
|
+
label enterprise "Enterprise readiness" style:enterprise
|
|
1736
|
+
label security "Security hardening" style:enterprise
|
|
1737
|
+
label low-confidence style:risky
|
|
1738
|
+
|
|
1739
|
+
swimlane platform owner:platform capacity:5
|
|
1740
|
+
item auth-refactor "Auth refactor" size:l after:kickoff \e
|
|
1741
|
+
status:done owner:sam labels:enterprise capacity:3 \e
|
|
1742
|
+
link:https://github.com/acme/auth/issues/123
|
|
1743
|
+
parallel after:auth-refactor
|
|
1744
|
+
group audit-track "Audit Track" labels:security
|
|
1745
|
+
item audit-log "Audit log v2" size:xl before:code-freeze \e
|
|
1746
|
+
remaining:30% labels:[enterprise, security] capacity:2
|
|
1747
|
+
description "Comprehensive audit trail for admin actions"
|
|
1748
|
+
item audit-ui "Audit UI" size:m capacity:1
|
|
1749
|
+
item sso "SSO plugins" size:m \e
|
|
1750
|
+
labels:[enterprise, low-confidence] capacity:50%
|
|
1751
|
+
item platform-qa "Platform QA" size:s capacity:2
|
|
1752
|
+
|
|
1753
|
+
swimlane mobile owner:mobile capacity:2
|
|
1754
|
+
item offline "Offline mode" size:l after:kickoff owner:jen \e
|
|
1755
|
+
status:at-risk remaining:60% capacity:3
|
|
1756
|
+
item push-v2 "Push notifications v2" size:m owner:mobile capacity:1
|
|
1757
|
+
|
|
1758
|
+
milestone beta "Beta" after:auth-refactor
|
|
1759
|
+
milestone v1-ga "v1 GA" after:[auth-refactor, audit-log]
|
|
1760
|
+
milestone ga-launch "GA launch" date:2026-06-01 \e
|
|
1761
|
+
after:[auth-refactor, audit-log]
|
|
1762
|
+
|
|
1763
|
+
footnote "Vendor dependency" on:audit-log
|
|
1764
|
+
description "Blocked until vendor contract is signed."
|
|
1765
|
+
footnote capacity-risk "Team capacity risk" on:[mobile, platform]
|
|
1766
|
+
description "Mobile team is down to 2 engineers through Q2."
|
|
1767
|
+
.Ed
|
|
1768
|
+
.Sh SEE ALSO
|
|
1769
|
+
.Xr nowline 1
|
|
1770
|
+
.Pq Sy man 1 nowline
|
|
1771
|
+
.Pp
|
|
1772
|
+
The
|
|
1773
|
+
.Sy specs/
|
|
1774
|
+
directory in the source repository documents the DSL grammar in
|
|
1775
|
+
prose
|
|
1776
|
+
.Pq Pa specs/dsl.md ,
|
|
1777
|
+
the layout / rendering pipeline
|
|
1778
|
+
.Pq Pa specs/rendering.md ,
|
|
1779
|
+
the localization model
|
|
1780
|
+
.Pq Pa specs/localization.md ,
|
|
1781
|
+
and OSS milestones
|
|
1782
|
+
.Pq Pa specs/milestones.md .
|
|
1783
|
+
.Sh AUTHORS
|
|
1784
|
+
.An Lolay Aq Mt packages@lolay.com
|