ex-workflow 0.0.0-stage → 0.2.0-stage

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.
Files changed (84) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/LICENSE +21 -0
  3. package/README.md +153 -2
  4. package/dist/adapters/index.cjs +2 -0
  5. package/dist/adapters/index.cjs.map +1 -0
  6. package/dist/adapters/index.d.cts +17 -0
  7. package/dist/adapters/index.d.ts +17 -0
  8. package/dist/adapters/index.mjs +2 -0
  9. package/dist/adapters/index.mjs.map +1 -0
  10. package/dist/chunk-2FRRD6A3.mjs +2 -0
  11. package/dist/chunk-2FRRD6A3.mjs.map +1 -0
  12. package/dist/chunk-472WEDPJ.cjs +2 -0
  13. package/dist/chunk-472WEDPJ.cjs.map +1 -0
  14. package/dist/chunk-6R3YFUUV.cjs +6 -0
  15. package/dist/chunk-6R3YFUUV.cjs.map +1 -0
  16. package/dist/chunk-D4HNETUL.cjs +2 -0
  17. package/dist/chunk-D4HNETUL.cjs.map +1 -0
  18. package/dist/chunk-DBR24RTX.cjs +2 -0
  19. package/dist/chunk-DBR24RTX.cjs.map +1 -0
  20. package/dist/chunk-IBRC36PE.mjs +2 -0
  21. package/dist/chunk-IBRC36PE.mjs.map +1 -0
  22. package/dist/chunk-JDVE7DQR.cjs +2 -0
  23. package/dist/chunk-JDVE7DQR.cjs.map +1 -0
  24. package/dist/chunk-KIQOUUEZ.mjs +2 -0
  25. package/dist/chunk-KIQOUUEZ.mjs.map +1 -0
  26. package/dist/chunk-NQU5TH3A.mjs +2 -0
  27. package/dist/chunk-NQU5TH3A.mjs.map +1 -0
  28. package/dist/chunk-NRAPI3GV.cjs +2 -0
  29. package/dist/chunk-NRAPI3GV.cjs.map +1 -0
  30. package/dist/chunk-PD5FBDN7.mjs +2 -0
  31. package/dist/chunk-PD5FBDN7.mjs.map +1 -0
  32. package/dist/chunk-PO2SPQJP.cjs +2 -0
  33. package/dist/chunk-PO2SPQJP.cjs.map +1 -0
  34. package/dist/chunk-QDT35LXB.cjs +2 -0
  35. package/dist/chunk-QDT35LXB.cjs.map +1 -0
  36. package/dist/chunk-S3BXVHO7.cjs +2 -0
  37. package/dist/chunk-S3BXVHO7.cjs.map +1 -0
  38. package/dist/chunk-VGD4V5BA.mjs +6 -0
  39. package/dist/chunk-VGD4V5BA.mjs.map +1 -0
  40. package/dist/chunk-VN2UYV2O.mjs +2 -0
  41. package/dist/chunk-VN2UYV2O.mjs.map +1 -0
  42. package/dist/chunk-XSXHEEJX.mjs +2 -0
  43. package/dist/chunk-XSXHEEJX.mjs.map +1 -0
  44. package/dist/chunk-YJNDBKIG.mjs +2 -0
  45. package/dist/chunk-YJNDBKIG.mjs.map +1 -0
  46. package/dist/cli/bin.cjs +5 -0
  47. package/dist/cli/bin.cjs.map +1 -0
  48. package/dist/cli/bin.d.cts +1 -0
  49. package/dist/cli/bin.d.ts +1 -0
  50. package/dist/cli/bin.mjs +5 -0
  51. package/dist/cli/bin.mjs.map +1 -0
  52. package/dist/cli/index.cjs +2 -0
  53. package/dist/cli/index.cjs.map +1 -0
  54. package/dist/cli/index.d.cts +13 -0
  55. package/dist/cli/index.d.ts +13 -0
  56. package/dist/cli/index.mjs +2 -0
  57. package/dist/cli/index.mjs.map +1 -0
  58. package/dist/index.cjs +2 -0
  59. package/dist/index.cjs.map +1 -0
  60. package/dist/index.d.cts +134 -0
  61. package/dist/index.d.ts +134 -0
  62. package/dist/index.mjs +2 -0
  63. package/dist/index.mjs.map +1 -0
  64. package/dist/kanban/index.cjs +2 -0
  65. package/dist/kanban/index.cjs.map +1 -0
  66. package/dist/kanban/index.d.cts +225 -0
  67. package/dist/kanban/index.d.ts +225 -0
  68. package/dist/kanban/index.mjs +2 -0
  69. package/dist/kanban/index.mjs.map +1 -0
  70. package/dist/roles-BLBRKhUZ.d.ts +14 -0
  71. package/dist/roles-aneKYJ3Z.d.cts +14 -0
  72. package/dist/scrum/index.cjs +2 -0
  73. package/dist/scrum/index.cjs.map +1 -0
  74. package/dist/scrum/index.d.cts +59 -0
  75. package/dist/scrum/index.d.ts +59 -0
  76. package/dist/scrum/index.mjs +2 -0
  77. package/dist/scrum/index.mjs.map +1 -0
  78. package/dist/types.cjs +2 -0
  79. package/dist/types.cjs.map +1 -0
  80. package/dist/types.d.cts +330 -0
  81. package/dist/types.d.ts +330 -0
  82. package/dist/types.mjs +2 -0
  83. package/dist/types.mjs.map +1 -0
  84. package/package.json +146 -4
@@ -0,0 +1,330 @@
1
+ type ItemType = "epic" | "story" | "task" | "bug" | "change-request" | "deliverable" | "question";
2
+ type ItemStatus = "todo" | "in_progress" | "blocked" | "review" | "awaiting_human" | "done" | "dropped";
3
+ type ClassOfService = "expedite" | "fixed-date" | "standard" | "intangible";
4
+ interface Evidence {
5
+ kind: string;
6
+ ref: string;
7
+ by: string;
8
+ at: string;
9
+ }
10
+ interface Blocker {
11
+ id: string;
12
+ reason: string;
13
+ owner: string;
14
+ raisedAt: string;
15
+ clearedAt?: string;
16
+ }
17
+ interface Transition {
18
+ from: {
19
+ stage: string;
20
+ status: ItemStatus;
21
+ };
22
+ to: {
23
+ stage: string;
24
+ status: ItemStatus;
25
+ };
26
+ at: string;
27
+ by: string;
28
+ }
29
+ interface WorkItem {
30
+ id: string;
31
+ type: ItemType;
32
+ title: string;
33
+ description?: string;
34
+ dependsOn: string[];
35
+ priority?: number;
36
+ weight?: number;
37
+ deadline?: string;
38
+ classOfService?: ClassOfService;
39
+ stage: string;
40
+ status: ItemStatus;
41
+ role?: string;
42
+ parent?: string;
43
+ acceptance: string[];
44
+ evidence: Evidence[];
45
+ blockers: Blocker[];
46
+ transitions: Transition[];
47
+ iteration?: string;
48
+ traces?: string[];
49
+ tags?: string[];
50
+ /** bug / change-request: ids of items whose finished work this invalidates */
51
+ affects?: string[];
52
+ }
53
+ /** Fields a caller supplies to addItem; the rest are defaulted. */
54
+ type NewItem = Pick<WorkItem, "id" | "title"> & Partial<Omit<WorkItem, "id" | "title" | "stage" | "status" | "evidence" | "blockers" | "transitions">> & {
55
+ stage?: string;
56
+ };
57
+ type Policy = {
58
+ kind: "evidence";
59
+ evidenceKind: string;
60
+ } | {
61
+ kind: "acceptance-written";
62
+ } | {
63
+ kind: "estimate-present";
64
+ } | {
65
+ kind: "no-open-blockers";
66
+ } | {
67
+ kind: "dependencies-done";
68
+ } | {
69
+ kind: "custom";
70
+ id: string;
71
+ description: string;
72
+ };
73
+ type GateRequirement = "human" | {
74
+ capability: string;
75
+ };
76
+ interface Gate {
77
+ id: string;
78
+ requires: GateRequirement[];
79
+ evidence: string[];
80
+ onFail: {
81
+ action: "block";
82
+ } | {
83
+ action: "return-to";
84
+ stage: string;
85
+ };
86
+ }
87
+ interface Stage {
88
+ id: string;
89
+ name: string;
90
+ wipLimit?: number;
91
+ entryPolicy: Policy[];
92
+ exitPolicy: Policy[];
93
+ gate?: Gate;
94
+ commitmentPoint?: boolean;
95
+ deliveryPoint?: boolean;
96
+ /** Items entering this stage wait for a reviewer (status "review") instead of "todo". */
97
+ review?: boolean;
98
+ }
99
+ interface Budget {
100
+ tokens?: number;
101
+ turns?: number;
102
+ wallclockMs?: number;
103
+ }
104
+ interface Iteration {
105
+ id: string;
106
+ goal: string;
107
+ budget: Budget;
108
+ spent: Required<Budget>;
109
+ startedAt: string;
110
+ endedAt?: string;
111
+ committed: string[];
112
+ carryover: string[];
113
+ outcome?: "completed" | "cancelled";
114
+ /** Budget is exhausted; in-flight items may finish, nothing new is dispatched. */
115
+ closing?: boolean;
116
+ }
117
+ type ModelTier = "small" | "medium" | "large";
118
+ type Capability = "order-backlog" | "define-acceptance" | "facilitate" | "deliver" | "review" | "verify" | "approve-gate" | "manage-flow" | "control-change" | "escalate";
119
+ interface Role {
120
+ id: string;
121
+ name: string;
122
+ modelTier: ModelTier;
123
+ resourceClass?: string;
124
+ maxConcurrent?: number;
125
+ capabilities: Capability[];
126
+ canApprove: string[];
127
+ inputs: string[];
128
+ outputs: string[];
129
+ do_not: string[];
130
+ constraints?: string[];
131
+ }
132
+ type Verdict = "done" | "blocked" | "needs-review" | "rework" | "escalate";
133
+ interface Handoff {
134
+ item: string;
135
+ role: string;
136
+ produced: Array<{
137
+ kind: string;
138
+ ref: string;
139
+ }>;
140
+ notes: string;
141
+ do_not: string[];
142
+ open_questions: string[];
143
+ verdict?: Verdict;
144
+ /** new work discovered while doing this item; lands in the FIRST stage (backlog), never in the iteration */
145
+ follow_ups?: NewItem[];
146
+ /** raised by the worker the moment it happens, e.g. "spec was vague here" */
147
+ lessons?: Array<{
148
+ text: string;
149
+ scope: Lesson["scope"];
150
+ }>;
151
+ }
152
+ interface Accounting {
153
+ item: string;
154
+ role: string;
155
+ model: string;
156
+ tokensIn: number;
157
+ tokensOut: number;
158
+ durationMs: number;
159
+ startedAt: string;
160
+ endedAt: string;
161
+ }
162
+ interface Event {
163
+ seq: number;
164
+ at: string;
165
+ type: string;
166
+ by: string;
167
+ payload: unknown;
168
+ }
169
+ interface PendingHuman {
170
+ id: string;
171
+ kind: "gate" | "decision";
172
+ item?: string;
173
+ gate?: string;
174
+ question: string;
175
+ raisedAt: string;
176
+ }
177
+ type LessonChange = {
178
+ kind: "agreement";
179
+ text: string;
180
+ } | {
181
+ kind: "dod";
182
+ policy: Policy;
183
+ } | {
184
+ kind: "backlog";
185
+ item: NewItem;
186
+ } | {
187
+ kind: "skill";
188
+ note: string;
189
+ };
190
+ interface Lesson {
191
+ id: string;
192
+ at: string;
193
+ text: string;
194
+ scope: "policy" | "skill" | "memory" | "spec" | "review";
195
+ status: "raised" | "adopted" | "dismissed";
196
+ from?: string;
197
+ item?: string;
198
+ suggestedChange?: LessonChange;
199
+ }
200
+ interface Phase {
201
+ id: string;
202
+ name: string;
203
+ deliverables: string[];
204
+ gate: Gate;
205
+ status: "pending" | "open" | "baselined" | "reopened";
206
+ }
207
+ interface Baseline {
208
+ phase: string;
209
+ version: number;
210
+ at: string;
211
+ approvedBy: string[];
212
+ itemSnapshot: Record<string, WorkItem>;
213
+ }
214
+ type MethodologyName = "scrum" | "kanban" | "waterfall";
215
+ interface WorkflowState {
216
+ version: 1;
217
+ methodology: MethodologyName;
218
+ config: unknown;
219
+ items: Record<string, WorkItem>;
220
+ stages: Stage[];
221
+ roles: Record<string, Role>;
222
+ iterations: Iteration[];
223
+ phases?: Phase[];
224
+ baseline?: Baseline;
225
+ events: Event[];
226
+ accounting: Accounting[];
227
+ pending: PendingHuman[];
228
+ lessons: Lesson[];
229
+ /** adopted working agreements; synthesizeBrief appends them to invariants */
230
+ agreements: string[];
231
+ }
232
+ interface Action {
233
+ type: string;
234
+ by: string;
235
+ payload?: unknown;
236
+ }
237
+ interface Violation {
238
+ rule: string;
239
+ severity: "error" | "warning";
240
+ item?: string;
241
+ message: string;
242
+ fix: string;
243
+ }
244
+ interface Rule {
245
+ id: string;
246
+ severity: "error" | "warning";
247
+ check(state: WorkflowState, action: Action): Violation[];
248
+ }
249
+ interface ApplyResult {
250
+ state: WorkflowState;
251
+ warnings: Violation[];
252
+ }
253
+ interface Brief {
254
+ item: WorkItem;
255
+ role: Role;
256
+ modelTier: ModelTier;
257
+ invariants: string[];
258
+ do_not: string[];
259
+ acceptance: string[];
260
+ upstream: Array<{
261
+ item: string;
262
+ produced: Handoff["produced"];
263
+ notes: string;
264
+ }>;
265
+ /** earlier completions of THIS item (rework feedback) */
266
+ priorHandoffs: Array<{
267
+ role: string;
268
+ verdict: Verdict;
269
+ notes: string;
270
+ produced: Handoff["produced"];
271
+ at: string;
272
+ }>;
273
+ /** open bug/change-request items whose `affects` touches this item or its dependsOn */
274
+ relatedBugs: Array<{
275
+ id: string;
276
+ title: string;
277
+ affects: string[];
278
+ }>;
279
+ budgetRemaining: Budget;
280
+ gateAhead?: Gate;
281
+ }
282
+ type CoreTerm = "backlog" | "item" | "stage" | "iteration" | "increment" | "ceremony" | "gate";
283
+ type CeremonyInput = {
284
+ by: string;
285
+ now?: string;
286
+ } & Record<string, unknown>;
287
+ type Ceremony = (state: WorkflowState, input: CeremonyInput) => ApplyResult;
288
+ interface PlannerOptions {
289
+ schedulerMode: "level" | "throughput";
290
+ /** Stage a todo item is pulled into when dispatched; a function decides per item; omitted/undefined = stay in its current stage. */
291
+ dispatchStage?: string | ((item: WorkItem) => string | undefined);
292
+ concurrencyCap?: number;
293
+ fairnessPolicy?: "none" | "aging";
294
+ maxDeferralRounds?: number;
295
+ deadlineStrategy?: "earliest-first" | "latest-first";
296
+ weightStrategy?: "higher-first" | "lower-first";
297
+ /** Priority the planner orders by; defaults to item.priority. */
298
+ priorityOf?(item: WorkItem): number | undefined;
299
+ /** Orders items of equal priority (after deadline/weight strategies); e.g. class of service, then age. */
300
+ tieBreaker?(a: WorkItem, b: WorkItem): number;
301
+ /** Statuses that occupy a stage's wipLimit slot; default ["in_progress"]. */
302
+ wipCounts?: ItemStatus[];
303
+ /** Per-item replacement for the target stage's wipLimit (e.g. an expedite bypass); undefined = no limit. */
304
+ wipLimitOf?(stage: Stage, item: WorkItem): number | undefined;
305
+ }
306
+ interface Methodology<C = unknown> {
307
+ name: MethodologyName;
308
+ vocabulary: Record<CoreTerm, string>;
309
+ validateConfig(config: unknown): C;
310
+ defaultStages(config: C): Stage[];
311
+ defaultRoles(config: C): Role[];
312
+ requiredCapabilities: Capability[];
313
+ exclusiveCapabilities: Capability[];
314
+ plannerOptions(state: WorkflowState): PlannerOptions;
315
+ candidates(state: WorkflowState): WorkItem[];
316
+ invariants(state: WorkflowState, item: WorkItem): string[];
317
+ ceremonies: Record<string, Ceremony>;
318
+ rules: Rule[];
319
+ metrics(state: WorkflowState): Record<string, number | number[] | Record<string, number>>;
320
+ humanDefaults: {
321
+ gates: "all" | "none" | string[];
322
+ };
323
+ /** Called after complete(); lets the methodology react (e.g. close a sprint when the budget is gone). */
324
+ afterComplete?(state: WorkflowState, itemId: string, now: string): WorkflowState;
325
+ /** Methodology-specific status for hosts (e.g. cadences due); printed by `exwf status`. */
326
+ report?(state: WorkflowState): Record<string, unknown>;
327
+ }
328
+ type ErrorCode = "unknown-item" | "duplicate-item" | "unknown-role" | "duplicate-role" | "unknown-stage" | "missing-capability" | "exclusive-capability" | "role-has-open-items" | "invalid-transition" | "policy-unmet" | "gate-unmet" | "conflict-of-interest" | "handoff-invalid" | "accounting-invalid" | "rule-violation" | "planner-error" | "no-op" | "unknown-pending" | "unknown-ceremony" | "state-version" | "config-invalid" | "budget-exhausted" | "invalid-input";
329
+
330
+ export type { Accounting, Action, ApplyResult, Baseline, Blocker, Brief, Budget, Capability, Ceremony, CeremonyInput, ClassOfService, CoreTerm, ErrorCode, Event, Evidence, Gate, GateRequirement, Handoff, ItemStatus, ItemType, Iteration, Lesson, LessonChange, Methodology, MethodologyName, ModelTier, NewItem, PendingHuman, Phase, PlannerOptions, Policy, Role, Rule, Stage, Transition, Verdict, Violation, WorkItem, WorkflowState };
@@ -0,0 +1,330 @@
1
+ type ItemType = "epic" | "story" | "task" | "bug" | "change-request" | "deliverable" | "question";
2
+ type ItemStatus = "todo" | "in_progress" | "blocked" | "review" | "awaiting_human" | "done" | "dropped";
3
+ type ClassOfService = "expedite" | "fixed-date" | "standard" | "intangible";
4
+ interface Evidence {
5
+ kind: string;
6
+ ref: string;
7
+ by: string;
8
+ at: string;
9
+ }
10
+ interface Blocker {
11
+ id: string;
12
+ reason: string;
13
+ owner: string;
14
+ raisedAt: string;
15
+ clearedAt?: string;
16
+ }
17
+ interface Transition {
18
+ from: {
19
+ stage: string;
20
+ status: ItemStatus;
21
+ };
22
+ to: {
23
+ stage: string;
24
+ status: ItemStatus;
25
+ };
26
+ at: string;
27
+ by: string;
28
+ }
29
+ interface WorkItem {
30
+ id: string;
31
+ type: ItemType;
32
+ title: string;
33
+ description?: string;
34
+ dependsOn: string[];
35
+ priority?: number;
36
+ weight?: number;
37
+ deadline?: string;
38
+ classOfService?: ClassOfService;
39
+ stage: string;
40
+ status: ItemStatus;
41
+ role?: string;
42
+ parent?: string;
43
+ acceptance: string[];
44
+ evidence: Evidence[];
45
+ blockers: Blocker[];
46
+ transitions: Transition[];
47
+ iteration?: string;
48
+ traces?: string[];
49
+ tags?: string[];
50
+ /** bug / change-request: ids of items whose finished work this invalidates */
51
+ affects?: string[];
52
+ }
53
+ /** Fields a caller supplies to addItem; the rest are defaulted. */
54
+ type NewItem = Pick<WorkItem, "id" | "title"> & Partial<Omit<WorkItem, "id" | "title" | "stage" | "status" | "evidence" | "blockers" | "transitions">> & {
55
+ stage?: string;
56
+ };
57
+ type Policy = {
58
+ kind: "evidence";
59
+ evidenceKind: string;
60
+ } | {
61
+ kind: "acceptance-written";
62
+ } | {
63
+ kind: "estimate-present";
64
+ } | {
65
+ kind: "no-open-blockers";
66
+ } | {
67
+ kind: "dependencies-done";
68
+ } | {
69
+ kind: "custom";
70
+ id: string;
71
+ description: string;
72
+ };
73
+ type GateRequirement = "human" | {
74
+ capability: string;
75
+ };
76
+ interface Gate {
77
+ id: string;
78
+ requires: GateRequirement[];
79
+ evidence: string[];
80
+ onFail: {
81
+ action: "block";
82
+ } | {
83
+ action: "return-to";
84
+ stage: string;
85
+ };
86
+ }
87
+ interface Stage {
88
+ id: string;
89
+ name: string;
90
+ wipLimit?: number;
91
+ entryPolicy: Policy[];
92
+ exitPolicy: Policy[];
93
+ gate?: Gate;
94
+ commitmentPoint?: boolean;
95
+ deliveryPoint?: boolean;
96
+ /** Items entering this stage wait for a reviewer (status "review") instead of "todo". */
97
+ review?: boolean;
98
+ }
99
+ interface Budget {
100
+ tokens?: number;
101
+ turns?: number;
102
+ wallclockMs?: number;
103
+ }
104
+ interface Iteration {
105
+ id: string;
106
+ goal: string;
107
+ budget: Budget;
108
+ spent: Required<Budget>;
109
+ startedAt: string;
110
+ endedAt?: string;
111
+ committed: string[];
112
+ carryover: string[];
113
+ outcome?: "completed" | "cancelled";
114
+ /** Budget is exhausted; in-flight items may finish, nothing new is dispatched. */
115
+ closing?: boolean;
116
+ }
117
+ type ModelTier = "small" | "medium" | "large";
118
+ type Capability = "order-backlog" | "define-acceptance" | "facilitate" | "deliver" | "review" | "verify" | "approve-gate" | "manage-flow" | "control-change" | "escalate";
119
+ interface Role {
120
+ id: string;
121
+ name: string;
122
+ modelTier: ModelTier;
123
+ resourceClass?: string;
124
+ maxConcurrent?: number;
125
+ capabilities: Capability[];
126
+ canApprove: string[];
127
+ inputs: string[];
128
+ outputs: string[];
129
+ do_not: string[];
130
+ constraints?: string[];
131
+ }
132
+ type Verdict = "done" | "blocked" | "needs-review" | "rework" | "escalate";
133
+ interface Handoff {
134
+ item: string;
135
+ role: string;
136
+ produced: Array<{
137
+ kind: string;
138
+ ref: string;
139
+ }>;
140
+ notes: string;
141
+ do_not: string[];
142
+ open_questions: string[];
143
+ verdict?: Verdict;
144
+ /** new work discovered while doing this item; lands in the FIRST stage (backlog), never in the iteration */
145
+ follow_ups?: NewItem[];
146
+ /** raised by the worker the moment it happens, e.g. "spec was vague here" */
147
+ lessons?: Array<{
148
+ text: string;
149
+ scope: Lesson["scope"];
150
+ }>;
151
+ }
152
+ interface Accounting {
153
+ item: string;
154
+ role: string;
155
+ model: string;
156
+ tokensIn: number;
157
+ tokensOut: number;
158
+ durationMs: number;
159
+ startedAt: string;
160
+ endedAt: string;
161
+ }
162
+ interface Event {
163
+ seq: number;
164
+ at: string;
165
+ type: string;
166
+ by: string;
167
+ payload: unknown;
168
+ }
169
+ interface PendingHuman {
170
+ id: string;
171
+ kind: "gate" | "decision";
172
+ item?: string;
173
+ gate?: string;
174
+ question: string;
175
+ raisedAt: string;
176
+ }
177
+ type LessonChange = {
178
+ kind: "agreement";
179
+ text: string;
180
+ } | {
181
+ kind: "dod";
182
+ policy: Policy;
183
+ } | {
184
+ kind: "backlog";
185
+ item: NewItem;
186
+ } | {
187
+ kind: "skill";
188
+ note: string;
189
+ };
190
+ interface Lesson {
191
+ id: string;
192
+ at: string;
193
+ text: string;
194
+ scope: "policy" | "skill" | "memory" | "spec" | "review";
195
+ status: "raised" | "adopted" | "dismissed";
196
+ from?: string;
197
+ item?: string;
198
+ suggestedChange?: LessonChange;
199
+ }
200
+ interface Phase {
201
+ id: string;
202
+ name: string;
203
+ deliverables: string[];
204
+ gate: Gate;
205
+ status: "pending" | "open" | "baselined" | "reopened";
206
+ }
207
+ interface Baseline {
208
+ phase: string;
209
+ version: number;
210
+ at: string;
211
+ approvedBy: string[];
212
+ itemSnapshot: Record<string, WorkItem>;
213
+ }
214
+ type MethodologyName = "scrum" | "kanban" | "waterfall";
215
+ interface WorkflowState {
216
+ version: 1;
217
+ methodology: MethodologyName;
218
+ config: unknown;
219
+ items: Record<string, WorkItem>;
220
+ stages: Stage[];
221
+ roles: Record<string, Role>;
222
+ iterations: Iteration[];
223
+ phases?: Phase[];
224
+ baseline?: Baseline;
225
+ events: Event[];
226
+ accounting: Accounting[];
227
+ pending: PendingHuman[];
228
+ lessons: Lesson[];
229
+ /** adopted working agreements; synthesizeBrief appends them to invariants */
230
+ agreements: string[];
231
+ }
232
+ interface Action {
233
+ type: string;
234
+ by: string;
235
+ payload?: unknown;
236
+ }
237
+ interface Violation {
238
+ rule: string;
239
+ severity: "error" | "warning";
240
+ item?: string;
241
+ message: string;
242
+ fix: string;
243
+ }
244
+ interface Rule {
245
+ id: string;
246
+ severity: "error" | "warning";
247
+ check(state: WorkflowState, action: Action): Violation[];
248
+ }
249
+ interface ApplyResult {
250
+ state: WorkflowState;
251
+ warnings: Violation[];
252
+ }
253
+ interface Brief {
254
+ item: WorkItem;
255
+ role: Role;
256
+ modelTier: ModelTier;
257
+ invariants: string[];
258
+ do_not: string[];
259
+ acceptance: string[];
260
+ upstream: Array<{
261
+ item: string;
262
+ produced: Handoff["produced"];
263
+ notes: string;
264
+ }>;
265
+ /** earlier completions of THIS item (rework feedback) */
266
+ priorHandoffs: Array<{
267
+ role: string;
268
+ verdict: Verdict;
269
+ notes: string;
270
+ produced: Handoff["produced"];
271
+ at: string;
272
+ }>;
273
+ /** open bug/change-request items whose `affects` touches this item or its dependsOn */
274
+ relatedBugs: Array<{
275
+ id: string;
276
+ title: string;
277
+ affects: string[];
278
+ }>;
279
+ budgetRemaining: Budget;
280
+ gateAhead?: Gate;
281
+ }
282
+ type CoreTerm = "backlog" | "item" | "stage" | "iteration" | "increment" | "ceremony" | "gate";
283
+ type CeremonyInput = {
284
+ by: string;
285
+ now?: string;
286
+ } & Record<string, unknown>;
287
+ type Ceremony = (state: WorkflowState, input: CeremonyInput) => ApplyResult;
288
+ interface PlannerOptions {
289
+ schedulerMode: "level" | "throughput";
290
+ /** Stage a todo item is pulled into when dispatched; a function decides per item; omitted/undefined = stay in its current stage. */
291
+ dispatchStage?: string | ((item: WorkItem) => string | undefined);
292
+ concurrencyCap?: number;
293
+ fairnessPolicy?: "none" | "aging";
294
+ maxDeferralRounds?: number;
295
+ deadlineStrategy?: "earliest-first" | "latest-first";
296
+ weightStrategy?: "higher-first" | "lower-first";
297
+ /** Priority the planner orders by; defaults to item.priority. */
298
+ priorityOf?(item: WorkItem): number | undefined;
299
+ /** Orders items of equal priority (after deadline/weight strategies); e.g. class of service, then age. */
300
+ tieBreaker?(a: WorkItem, b: WorkItem): number;
301
+ /** Statuses that occupy a stage's wipLimit slot; default ["in_progress"]. */
302
+ wipCounts?: ItemStatus[];
303
+ /** Per-item replacement for the target stage's wipLimit (e.g. an expedite bypass); undefined = no limit. */
304
+ wipLimitOf?(stage: Stage, item: WorkItem): number | undefined;
305
+ }
306
+ interface Methodology<C = unknown> {
307
+ name: MethodologyName;
308
+ vocabulary: Record<CoreTerm, string>;
309
+ validateConfig(config: unknown): C;
310
+ defaultStages(config: C): Stage[];
311
+ defaultRoles(config: C): Role[];
312
+ requiredCapabilities: Capability[];
313
+ exclusiveCapabilities: Capability[];
314
+ plannerOptions(state: WorkflowState): PlannerOptions;
315
+ candidates(state: WorkflowState): WorkItem[];
316
+ invariants(state: WorkflowState, item: WorkItem): string[];
317
+ ceremonies: Record<string, Ceremony>;
318
+ rules: Rule[];
319
+ metrics(state: WorkflowState): Record<string, number | number[] | Record<string, number>>;
320
+ humanDefaults: {
321
+ gates: "all" | "none" | string[];
322
+ };
323
+ /** Called after complete(); lets the methodology react (e.g. close a sprint when the budget is gone). */
324
+ afterComplete?(state: WorkflowState, itemId: string, now: string): WorkflowState;
325
+ /** Methodology-specific status for hosts (e.g. cadences due); printed by `exwf status`. */
326
+ report?(state: WorkflowState): Record<string, unknown>;
327
+ }
328
+ type ErrorCode = "unknown-item" | "duplicate-item" | "unknown-role" | "duplicate-role" | "unknown-stage" | "missing-capability" | "exclusive-capability" | "role-has-open-items" | "invalid-transition" | "policy-unmet" | "gate-unmet" | "conflict-of-interest" | "handoff-invalid" | "accounting-invalid" | "rule-violation" | "planner-error" | "no-op" | "unknown-pending" | "unknown-ceremony" | "state-version" | "config-invalid" | "budget-exhausted" | "invalid-input";
329
+
330
+ export type { Accounting, Action, ApplyResult, Baseline, Blocker, Brief, Budget, Capability, Ceremony, CeremonyInput, ClassOfService, CoreTerm, ErrorCode, Event, Evidence, Gate, GateRequirement, Handoff, ItemStatus, ItemType, Iteration, Lesson, LessonChange, Methodology, MethodologyName, ModelTier, NewItem, PendingHuman, Phase, PlannerOptions, Policy, Role, Rule, Stage, Transition, Verdict, Violation, WorkItem, WorkflowState };
package/dist/types.mjs ADDED
@@ -0,0 +1,2 @@
1
+ import'./chunk-KIQOUUEZ.mjs';//# sourceMappingURL=types.mjs.map
2
+ //# sourceMappingURL=types.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"types.mjs"}