1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
/// Work subcommands for unified GitHub/YAML workflow
/// CRUD: Create (add), Read (list/status), Update (edit/start/complete), Delete (delete)
#[derive(Debug, Clone, Subcommand)]
pub enum WorkCommands {
/// Add a new work ticket (CREATE)
#[command(visible_aliases = &["new", "create", "a"])]
Add {
/// Ticket title (required)
title: String,
/// Description (optional)
#[arg(short, long)]
description: Option<String>,
/// Priority level
#[arg(short, long, value_enum, default_value = "medium")]
priority: WorkPriority,
/// Tags (comma-separated)
#[arg(short, long)]
tags: Option<String>,
/// Project path (default: current directory)
#[arg(long)]
path: Option<PathBuf>,
/// Also create GitHub issue
#[arg(long)]
github: bool,
},
/// List all work tickets (READ)
#[command(visible_aliases = &["ls", "l"])]
List {
/// Filter by status
#[arg(short, long)]
status: Option<String>,
/// Filter by priority
#[arg(long)]
priority: Option<WorkPriority>,
/// Show only count
#[arg(long)]
count: bool,
/// Project path (default: current directory)
#[arg(short, long)]
path: Option<PathBuf>,
},
/// Edit an existing ticket (UPDATE)
#[command(visible_aliases = &["update", "e"])]
Edit {
/// Ticket ID to edit
id: String,
/// New title
#[arg(short, long)]
title: Option<String>,
/// New description
#[arg(short, long)]
description: Option<String>,
/// New priority
#[arg(long)]
priority: Option<WorkPriority>,
/// New status
#[arg(short, long)]
status: Option<String>,
/// New tags (comma-separated, replaces existing)
#[arg(long)]
tags: Option<String>,
/// Project path (default: current directory)
#[arg(short, long)]
path: Option<PathBuf>,
},
/// Delete a work ticket (DELETE)
#[command(visible_aliases = &["rm", "remove", "del"])]
Delete {
/// Ticket ID to delete
id: String,
/// Skip confirmation prompt
#[arg(short, long)]
force: bool,
/// Project path (default: current directory)
#[arg(short, long)]
path: Option<PathBuf>,
},
/// Show unified quality annotations for a ticket
#[command(visible_aliases = &["ann", "quality", "metrics"])]
Annotate {
/// Ticket ID to annotate
id: String,
/// Project path (default: current directory)
#[arg(short, long)]
path: Option<PathBuf>,
/// Output format
#[arg(short, long, value_enum, default_value = "text")]
format: AnnotateOutputFormat,
/// Include churn analysis (slower)
#[arg(long)]
with_churn: bool,
/// Days for churn analysis
#[arg(long, default_value = "30")]
churn_days: u32,
},
/// Start work on a GitHub issue or YAML ticket
#[command(visible_aliases = &["begin", "s"])]
Start {
/// Issue number (e.g., "8", "42") or YAML ticket ID (e.g., "PERF-001")
id: String,
/// Create specification file (docs/specifications/NNN-name.md)
#[arg(long)]
with_spec: bool,
/// Create as epic with subtasks
#[arg(long)]
epic: bool,
/// Project path (default: current directory)
#[arg(short, long)]
path: Option<PathBuf>,
/// Force create GitHub issue for YAML ticket
#[arg(long)]
create_github: bool,
/// DbC contract profile override (universal, rust, pmat)
#[arg(long)]
profile: Option<String>,
/// Exclude specific DbC claims (comma-separated, e.g. "ensure.coverage,ensure.supply_chain")
#[arg(long, value_delimiter = ',')]
without: Option<Vec<String>>,
/// Iteration number for subcontracting (inherits postconditions from prior iteration)
#[arg(long, default_value = "1")]
iteration: u32,
/// Bind this ticket to a provable-contracts equation (Component 27).
/// Format: `<contract>/<equation>`, e.g. `rope-kernel-v1/rope`.
/// Repeatable for cross-kernel work items.
#[arg(long, value_name = "CONTRACT/EQUATION")]
implements: Vec<String>,
},
/// Continue work on existing issue/ticket
#[command(visible_aliases = &["cont", "c", "resume"])]
Continue {
/// Issue number or ticket ID
id: String,
/// Project path (default: current directory)
#[arg(short, long)]
path: Option<PathBuf>,
},
/// Run invariant checkpoint (DbC ยง4.2)
#[command(visible_aliases = &["ck", "cp"])]
Checkpoint {
/// Issue number or ticket ID
id: String,
/// Project path (default: current directory)
#[arg(short, long)]
path: Option<PathBuf>,
},
/// Complete work on issue/ticket
#[command(visible_aliases = &["done", "finish", "f"])]
Complete {
/// Issue number or ticket ID
id: String,
/// Skip quality gates (not recommended, falsification still runs)
#[arg(long)]
skip_quality: bool,
/// Override specific falsification claims (requires --ticket)
/// Use claim names like: coverage, complexity, file-size, github-sync
#[arg(long, value_delimiter = ',')]
override_claims: Option<Vec<String>>,
/// Ticket ID for override accountability (MANDATORY with --override-claims)
/// Must reference a valid debt ticket (e.g., DEBT-COV-20240115)
#[arg(long)]
ticket: Option<String>,
/// Project path (default: current directory)
#[arg(short, long)]
path: Option<PathBuf>,
},
/// Run falsification tests without completing the work item
#[command(visible_alias = "test-claims")]
Falsify {
/// Issue number or ticket ID
id: String,
/// Override specific falsification claims (requires --ticket)
#[arg(long, value_delimiter = ',')]
override_claims: Option<Vec<String>>,
/// Ticket ID for override accountability (MANDATORY with --override-claims)
#[arg(long)]
ticket: Option<String>,
/// Project path (default: current directory)
#[arg(short, long)]
path: Option<PathBuf>,
},
/// Show work status
#[command(visible_aliases = &["st", "stat"])]
Status {
/// Issue number or ticket ID (default: all)
id: Option<String>,
/// Project path (default: current directory)
#[arg(short, long)]
path: Option<PathBuf>,
/// Show only active items
#[arg(long)]
active: bool,
},
/// Synchronize GitHub and YAML
#[command(visible_aliases = &["sy"])]
Sync {
/// Sync direction
#[arg(long, value_enum, default_value = "full")]
direction: SyncDirection,
/// Project path (default: current directory)
#[arg(short, long)]
path: Option<PathBuf>,
/// Dry run (show what would be synced)
#[arg(long)]
dry_run: bool,
},
/// Initialize roadmap and hooks
#[command(visible_aliases = &["setup", "ini"])]
Init {
/// GitHub repository (owner/repo)
#[arg(long)]
github_repo: Option<String>,
/// Disable GitHub integration
#[arg(long)]
no_github: bool,
/// Project path (default: current directory)
#[arg(short, long)]
path: Option<PathBuf>,
},
/// Validate roadmap.yaml syntax and content (Part B: UX Improvements)
#[command(visible_aliases = &["check", "lint", "v"])]
Validate {
/// Project path (default: current directory)
#[arg(short, long)]
path: Option<PathBuf>,
/// Show verbose output with suggestions
#[arg(long)]
verbose: bool,
/// Fix issues automatically where possible
#[arg(long)]
fix: bool,
},
/// Auto-fix common roadmap.yaml issues (Part B: UX Improvements)
#[command(visible_aliases = &["fix", "m"])]
Migrate {
/// Project path (default: current directory)
#[arg(short, long)]
path: Option<PathBuf>,
/// Dry run (show what would be changed)
#[arg(long)]
dry_run: bool,
/// Create backup before migration
#[arg(long, default_value = "true")]
backup: bool,
},
/// List all valid status values with descriptions
#[command(visible_aliases = &["values", "statuses"])]
ListStatuses,
/// Score a work contract (DBC spec 5-dimension quality + lint)
#[command(visible_aliases = &["sc", "quality-score"])]
Score {
/// Work item ID
id: String,
/// Minimum score threshold (0.0-1.0, default: 0.0)
#[arg(long, default_value = "0.0")]
min_score: f64,
/// Project path (default: current directory)
#[arg(short, long)]
path: Option<PathBuf>,
/// Output format (text, json, or sarif)
#[arg(short, long, default_value = "text")]
format: String,
},
/// Aggregate quality score across all work contracts (DBC spec ยง14.6)
#[command(visible_aliases = &["cbs", "portfolio"])]
CodebaseScore {
/// Project path (default: current directory)
#[arg(short, long)]
path: Option<PathBuf>,
/// Output format (text or json)
#[arg(short, long, default_value = "text")]
format: String,
},
}