ex-workflow 0.2.0-stage → 0.4.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 (87) hide show
  1. package/CHANGELOG.md +20 -1
  2. package/README.md +54 -12
  3. package/dist/adapters/index.cjs +1 -1
  4. package/dist/adapters/index.mjs +1 -1
  5. package/dist/chunk-36M6OVUJ.mjs +2 -0
  6. package/dist/chunk-36M6OVUJ.mjs.map +1 -0
  7. package/dist/{chunk-472WEDPJ.cjs → chunk-7KF5K3L7.cjs} +2 -2
  8. package/dist/{chunk-472WEDPJ.cjs.map → chunk-7KF5K3L7.cjs.map} +1 -1
  9. package/dist/chunk-CWBH7H52.cjs +2 -0
  10. package/dist/chunk-CWBH7H52.cjs.map +1 -0
  11. package/dist/chunk-DXC2RSN5.cjs +3 -0
  12. package/dist/chunk-DXC2RSN5.cjs.map +1 -0
  13. package/dist/{chunk-XSXHEEJX.mjs → chunk-GATJZYTB.mjs} +2 -2
  14. package/dist/{chunk-XSXHEEJX.mjs.map → chunk-GATJZYTB.mjs.map} +1 -1
  15. package/dist/chunk-GFH2FEZH.mjs +2 -0
  16. package/dist/chunk-GFH2FEZH.mjs.map +1 -0
  17. package/dist/{chunk-DBR24RTX.cjs → chunk-HHC5EZ54.cjs} +2 -2
  18. package/dist/{chunk-DBR24RTX.cjs.map → chunk-HHC5EZ54.cjs.map} +1 -1
  19. package/dist/chunk-KSKEFYY7.cjs +2 -0
  20. package/dist/chunk-KSKEFYY7.cjs.map +1 -0
  21. package/dist/chunk-KUUIAKEJ.cjs +2 -0
  22. package/dist/chunk-KUUIAKEJ.cjs.map +1 -0
  23. package/dist/{chunk-IBRC36PE.mjs → chunk-L2ZN6HEL.mjs} +2 -2
  24. package/dist/{chunk-IBRC36PE.mjs.map → chunk-L2ZN6HEL.mjs.map} +1 -1
  25. package/dist/chunk-NDORREWR.mjs +2 -0
  26. package/dist/chunk-NDORREWR.mjs.map +1 -0
  27. package/dist/{chunk-VN2UYV2O.mjs → chunk-NZ2DIDOD.mjs} +2 -2
  28. package/dist/{chunk-VN2UYV2O.mjs.map → chunk-NZ2DIDOD.mjs.map} +1 -1
  29. package/dist/chunk-OHSQ52DW.mjs +6 -0
  30. package/dist/chunk-OHSQ52DW.mjs.map +1 -0
  31. package/dist/chunk-RSKZVOYC.cjs +6 -0
  32. package/dist/chunk-RSKZVOYC.cjs.map +1 -0
  33. package/dist/chunk-S22CPYXJ.mjs +3 -0
  34. package/dist/chunk-S22CPYXJ.mjs.map +1 -0
  35. package/dist/chunk-SHAPFMVP.mjs +2 -0
  36. package/dist/chunk-SHAPFMVP.mjs.map +1 -0
  37. package/dist/chunk-SJRRQZ3R.cjs +2 -0
  38. package/dist/chunk-SJRRQZ3R.cjs.map +1 -0
  39. package/dist/{chunk-D4HNETUL.cjs → chunk-UM5X2JHB.cjs} +2 -2
  40. package/dist/{chunk-D4HNETUL.cjs.map → chunk-UM5X2JHB.cjs.map} +1 -1
  41. package/dist/cli/bin.cjs +1 -1
  42. package/dist/cli/bin.cjs.map +1 -1
  43. package/dist/cli/bin.mjs +1 -1
  44. package/dist/cli/bin.mjs.map +1 -1
  45. package/dist/cli/index.cjs +1 -1
  46. package/dist/cli/index.mjs +1 -1
  47. package/dist/index.cjs +1 -1
  48. package/dist/index.cjs.map +1 -1
  49. package/dist/index.d.cts +8 -8
  50. package/dist/index.d.ts +8 -8
  51. package/dist/index.mjs +1 -1
  52. package/dist/index.mjs.map +1 -1
  53. package/dist/kanban/index.cjs +1 -1
  54. package/dist/kanban/index.mjs +1 -1
  55. package/dist/schema/index.cjs +2 -0
  56. package/dist/schema/index.cjs.map +1 -0
  57. package/dist/schema/index.d.cts +57 -0
  58. package/dist/schema/index.d.ts +57 -0
  59. package/dist/schema/index.mjs +2 -0
  60. package/dist/schema/index.mjs.map +1 -0
  61. package/dist/scrum/index.cjs +1 -1
  62. package/dist/scrum/index.mjs +1 -1
  63. package/dist/types.d.cts +38 -2
  64. package/dist/types.d.ts +38 -2
  65. package/dist/waterfall/index.cjs +2 -0
  66. package/dist/waterfall/index.cjs.map +1 -0
  67. package/dist/waterfall/index.d.cts +148 -0
  68. package/dist/waterfall/index.d.ts +148 -0
  69. package/dist/waterfall/index.mjs +2 -0
  70. package/dist/waterfall/index.mjs.map +1 -0
  71. package/package.json +31 -2
  72. package/dist/chunk-6R3YFUUV.cjs +0 -6
  73. package/dist/chunk-6R3YFUUV.cjs.map +0 -1
  74. package/dist/chunk-JDVE7DQR.cjs +0 -2
  75. package/dist/chunk-JDVE7DQR.cjs.map +0 -1
  76. package/dist/chunk-NQU5TH3A.mjs +0 -2
  77. package/dist/chunk-NQU5TH3A.mjs.map +0 -1
  78. package/dist/chunk-NRAPI3GV.cjs +0 -2
  79. package/dist/chunk-NRAPI3GV.cjs.map +0 -1
  80. package/dist/chunk-PD5FBDN7.mjs +0 -2
  81. package/dist/chunk-PD5FBDN7.mjs.map +0 -1
  82. package/dist/chunk-QDT35LXB.cjs +0 -2
  83. package/dist/chunk-QDT35LXB.cjs.map +0 -1
  84. package/dist/chunk-VGD4V5BA.mjs +0 -6
  85. package/dist/chunk-VGD4V5BA.mjs.map +0 -1
  86. package/dist/chunk-YJNDBKIG.mjs +0 -2
  87. package/dist/chunk-YJNDBKIG.mjs.map +0 -1
@@ -0,0 +1,2 @@
1
+ 'use strict';var chunkKSKEFYY7_cjs=require('../chunk-KSKEFYY7.cjs');require('../chunk-CWBH7H52.cjs'),require('../chunk-SJRRQZ3R.cjs'),require('../chunk-S3BXVHO7.cjs');Object.defineProperty(exports,"CHANGE_GATE",{enumerable:true,get:function(){return chunkKSKEFYY7_cjs.e}});Object.defineProperty(exports,"DEFAULT_DELIVERABLES",{enumerable:true,get:function(){return chunkKSKEFYY7_cjs.b}});Object.defineProperty(exports,"DEFAULT_DELIVER_BY",{enumerable:true,get:function(){return chunkKSKEFYY7_cjs.c}});Object.defineProperty(exports,"DEFAULT_PHASE_IDS",{enumerable:true,get:function(){return chunkKSKEFYY7_cjs.a}});Object.defineProperty(exports,"DONE",{enumerable:true,get:function(){return chunkKSKEFYY7_cjs.k}});Object.defineProperty(exports,"GATE_ID",{enumerable:true,get:function(){return chunkKSKEFYY7_cjs.d}});Object.defineProperty(exports,"REVIEW",{enumerable:true,get:function(){return chunkKSKEFYY7_cjs.j}});Object.defineProperty(exports,"WATERFALL_VOCABULARY",{enumerable:true,get:function(){return chunkKSKEFYY7_cjs.K}});Object.defineProperty(exports,"WORK",{enumerable:true,get:function(){return chunkKSKEFYY7_cjs.i}});Object.defineProperty(exports,"approveChange",{enumerable:true,get:function(){return chunkKSKEFYY7_cjs.z}});Object.defineProperty(exports,"baselinePhase",{enumerable:true,get:function(){return chunkKSKEFYY7_cjs.x}});Object.defineProperty(exports,"configOf",{enumerable:true,get:function(){return chunkKSKEFYY7_cjs.g}});Object.defineProperty(exports,"currentPhase",{enumerable:true,get:function(){return chunkKSKEFYY7_cjs.s}});Object.defineProperty(exports,"defaultPhases",{enumerable:true,get:function(){return chunkKSKEFYY7_cjs.f}});Object.defineProperty(exports,"deliverRoleFor",{enumerable:true,get:function(){return chunkKSKEFYY7_cjs.L}});Object.defineProperty(exports,"getPhase",{enumerable:true,get:function(){return chunkKSKEFYY7_cjs.o}});Object.defineProperty(exports,"isFrozen",{enumerable:true,get:function(){return chunkKSKEFYY7_cjs.t}});Object.defineProperty(exports,"itemsInPhase",{enumerable:true,get:function(){return chunkKSKEFYY7_cjs.q}});Object.defineProperty(exports,"lastToPhase",{enumerable:true,get:function(){return chunkKSKEFYY7_cjs.w}});Object.defineProperty(exports,"missingDeliverables",{enumerable:true,get:function(){return chunkKSKEFYY7_cjs.v}});Object.defineProperty(exports,"missingTraces",{enumerable:true,get:function(){return chunkKSKEFYY7_cjs.C}});Object.defineProperty(exports,"openPhase",{enumerable:true,get:function(){return chunkKSKEFYY7_cjs.r}});Object.defineProperty(exports,"phaseIndex",{enumerable:true,get:function(){return chunkKSKEFYY7_cjs.n}});Object.defineProperty(exports,"phaseOf",{enumerable:true,get:function(){return chunkKSKEFYY7_cjs.p}});Object.defineProperty(exports,"phaseReport",{enumerable:true,get:function(){return chunkKSKEFYY7_cjs.M}});Object.defineProperty(exports,"phasesOf",{enumerable:true,get:function(){return chunkKSKEFYY7_cjs.l}});Object.defineProperty(exports,"producedKinds",{enumerable:true,get:function(){return chunkKSKEFYY7_cjs.u}});Object.defineProperty(exports,"rejectChange",{enumerable:true,get:function(){return chunkKSKEFYY7_cjs.A}});Object.defineProperty(exports,"reopenPhases",{enumerable:true,get:function(){return chunkKSKEFYY7_cjs.y}});Object.defineProperty(exports,"traceabilityMatrix",{enumerable:true,get:function(){return chunkKSKEFYY7_cjs.B}});Object.defineProperty(exports,"validateWaterfallConfig",{enumerable:true,get:function(){return chunkKSKEFYY7_cjs.h}});Object.defineProperty(exports,"wantPhase",{enumerable:true,get:function(){return chunkKSKEFYY7_cjs.D}});Object.defineProperty(exports,"waterfall",{enumerable:true,get:function(){return chunkKSKEFYY7_cjs.N}});Object.defineProperty(exports,"waterfallAfterDecide",{enumerable:true,get:function(){return chunkKSKEFYY7_cjs.F}});Object.defineProperty(exports,"waterfallCeremonies",{enumerable:true,get:function(){return chunkKSKEFYY7_cjs.E}});Object.defineProperty(exports,"waterfallMetrics",{enumerable:true,get:function(){return chunkKSKEFYY7_cjs.G}});Object.defineProperty(exports,"waterfallRoles",{enumerable:true,get:function(){return chunkKSKEFYY7_cjs.H}});Object.defineProperty(exports,"waterfallRules",{enumerable:true,get:function(){return chunkKSKEFYY7_cjs.I}});Object.defineProperty(exports,"waterfallStages",{enumerable:true,get:function(){return chunkKSKEFYY7_cjs.J}});Object.defineProperty(exports,"withPhases",{enumerable:true,get:function(){return chunkKSKEFYY7_cjs.m}});//# sourceMappingURL=index.cjs.map
2
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"index.cjs"}
@@ -0,0 +1,148 @@
1
+ import { Gate, Budget, GateRequirement, WorkflowState, Phase, WorkItem, Stage, Role, Rule, CeremonyInput, PendingHuman, Methodology, Ceremony, CoreTerm } from '../types.cjs';
2
+
3
+ interface WaterfallPhaseConfig {
4
+ id: string;
5
+ name: string;
6
+ deliverables: string[];
7
+ gate: Gate;
8
+ budget?: Budget;
9
+ /** role id that delivers this phase's items; default: the first role with "deliver" */
10
+ deliverBy?: string;
11
+ }
12
+ interface WaterfallConfig {
13
+ phases: WaterfallPhaseConfig[];
14
+ changeControl: {
15
+ requiresImpactAnalysis: boolean;
16
+ approvers: GateRequirement[];
17
+ };
18
+ /** phase ids: every item of `from` must trace to an item of each `to` phase before that phase's gate */
19
+ traceability: {
20
+ from: string;
21
+ to: string[];
22
+ };
23
+ humanGates: "all" | string[];
24
+ }
25
+ declare const DEFAULT_PHASE_IDS: readonly string[];
26
+ declare const DEFAULT_DELIVERABLES: Record<string, string[]>;
27
+ declare const DEFAULT_DELIVER_BY: Record<string, string>;
28
+ declare const GATE_ID: (id: string) => string;
29
+ declare const CHANGE_GATE = "change-control";
30
+ declare function defaultPhases(): WaterfallPhaseConfig[];
31
+ declare function configOf(state: WorkflowState): WaterfallConfig;
32
+ declare function validateWaterfallConfig(raw: unknown): WaterfallConfig;
33
+
34
+ declare const WORK = "work";
35
+ declare const REVIEW = "review";
36
+ declare const DONE = "done";
37
+ /** state.phases, or the config phases as pending (before the first ceremony touches them). */
38
+ declare function phasesOf(state: WorkflowState): Phase[];
39
+ declare function withPhases(state: WorkflowState, phases: Phase[]): WorkflowState;
40
+ declare function phaseIndex(state: WorkflowState, id: string): number;
41
+ declare function getPhase(state: WorkflowState, id: string): Phase;
42
+ /** The item's phase, inherited from its parent chain (questions, follow-ups, retro items). */
43
+ declare function phaseOf(state: WorkflowState, item: WorkItem): string | undefined;
44
+ declare function itemsInPhase(state: WorkflowState, phaseId: string): WorkItem[];
45
+ declare function openPhase(state: WorkflowState): Phase | undefined;
46
+ /** First phase in order that is not baselined: the one to kick off (or the open one). */
47
+ declare function currentPhase(state: WorkflowState): Phase | undefined;
48
+ declare function isFrozen(state: WorkflowState, item: WorkItem): boolean;
49
+ declare function producedKinds(state: WorkflowState, phase: Phase): Set<string>;
50
+ /** Deliverables (and gate evidence kinds) still missing, in declaration order. */
51
+ declare function missingDeliverables(state: WorkflowState, phase: Phase, extra?: string[]): string[];
52
+ /** The traceability `to` phase that comes last in phase order (where the matrix must be complete). */
53
+ declare function lastToPhase(state: WorkflowState): string | undefined;
54
+
55
+ /** Every phase's items share the same three steps; the phase is the unit of governance. */
56
+ declare function waterfallStages(_config: WaterfallConfig): Stage[];
57
+
58
+ /** Order matters: the first role with "deliver" is the fallback deliverer for phases without deliverBy. */
59
+ declare function waterfallRoles(config: WaterfallConfig): Role[];
60
+
61
+ declare function waterfallRules(): Rule[];
62
+
63
+ interface WaterfallMetrics {
64
+ phaseCompletion: Record<string, number>;
65
+ budgetPlanned: Record<string, number>;
66
+ budgetSpent: Record<string, number>;
67
+ scheduleVariance: Record<string, number>;
68
+ requirementCoverage: number;
69
+ requirementsTraced: number;
70
+ requirementsTotal: number;
71
+ defectsPerPhase: Record<string, number>;
72
+ changeRequests: number;
73
+ changesApproved: number;
74
+ changesRejected: number;
75
+ changeApprovalRate: number;
76
+ reworkWeight: number;
77
+ phasesReopened: number;
78
+ }
79
+ /** Phase metrics replayed from events alone (membership from item.added, spend from item.completed). */
80
+ declare function waterfallMetrics(state: WorkflowState): WaterfallMetrics;
81
+
82
+ declare function approveChange(state: WorkflowState, changeId: string, by: string, note: string, now: string): WorkflowState;
83
+ declare function rejectChange(state: WorkflowState, changeId: string, by: string, note: string, now: string): WorkflowState;
84
+
85
+ /** input.phase as an existing phase. */
86
+ declare function wantPhase(state: WorkflowState, input: CeremonyInput, ceremony: string): Phase;
87
+
88
+ declare function waterfallCeremonies(methodology: () => Methodology): Record<string, Ceremony>;
89
+ /** decide() hook: a phase gate's human decision baselines the phase or records the failure. */
90
+ declare function waterfallAfterDecide(state: WorkflowState, entry: PendingHuman, decision: "approve" | "reject", by: string, note: string, now: string): WorkflowState;
91
+
92
+ interface TraceRow {
93
+ item: string;
94
+ /** to-phase id → ids of linked items in that phase */
95
+ links: Record<string, string[]>;
96
+ }
97
+ interface TraceabilityMatrix {
98
+ from: string;
99
+ to: string[];
100
+ rows: TraceRow[];
101
+ missing: Array<{
102
+ item: string;
103
+ phases: string[];
104
+ }>;
105
+ coverage: {
106
+ traced: number;
107
+ total: number;
108
+ };
109
+ }
110
+ declare function traceabilityMatrix(state: WorkflowState): TraceabilityMatrix;
111
+ /** Ids of `from` items with no link into `toPhase`. */
112
+ declare function missingTraces(state: WorkflowState, toPhase: string): string[];
113
+
114
+ /** Pass the phase gate: freeze its items, record the baseline, close its iteration. */
115
+ declare function baselinePhase(state: WorkflowState, phaseId: string, approvedBy: string[], now: string): WorkflowState;
116
+ interface ReopenResult {
117
+ state: WorkflowState;
118
+ reopened: string[];
119
+ suspended: string | null;
120
+ }
121
+ /** Change-control approval: reopen the listed baselined phases; a later open phase is suspended until they are re-baselined. */
122
+ declare function reopenPhases(state: WorkflowState, ids: string[], now: string): ReopenResult;
123
+
124
+ declare const WATERFALL_VOCABULARY: Record<CoreTerm, string>;
125
+ /** The role that delivers the item's phase (config deliverBy); undefined = the planner's default deliverer. */
126
+ declare function deliverRoleFor(state: WorkflowState, item: WorkItem): string | undefined;
127
+ interface PhaseReportRow {
128
+ id: string;
129
+ name: string;
130
+ status: string;
131
+ items: number;
132
+ done: number;
133
+ missingDeliverables: string[];
134
+ readyForGate: boolean;
135
+ }
136
+ interface PhaseReport {
137
+ phases: PhaseReportRow[];
138
+ current: string | null;
139
+ open: string | null;
140
+ pendingGates: Array<{
141
+ pending: string;
142
+ gate: string;
143
+ }>;
144
+ }
145
+ declare function phaseReport(state: WorkflowState): PhaseReport;
146
+ declare function waterfall(): Methodology<WaterfallConfig>;
147
+
148
+ export { CHANGE_GATE, DEFAULT_DELIVERABLES, DEFAULT_DELIVER_BY, DEFAULT_PHASE_IDS, DONE, GATE_ID, type PhaseReport, type PhaseReportRow, REVIEW, type ReopenResult, type TraceRow, type TraceabilityMatrix, WATERFALL_VOCABULARY, WORK, type WaterfallConfig, type WaterfallMetrics, type WaterfallPhaseConfig, approveChange, baselinePhase, configOf, currentPhase, defaultPhases, deliverRoleFor, getPhase, isFrozen, itemsInPhase, lastToPhase, missingDeliverables, missingTraces, openPhase, phaseIndex, phaseOf, phaseReport, phasesOf, producedKinds, rejectChange, reopenPhases, traceabilityMatrix, validateWaterfallConfig, wantPhase, waterfall, waterfallAfterDecide, waterfallCeremonies, waterfallMetrics, waterfallRoles, waterfallRules, waterfallStages, withPhases };
@@ -0,0 +1,148 @@
1
+ import { Gate, Budget, GateRequirement, WorkflowState, Phase, WorkItem, Stage, Role, Rule, CeremonyInput, PendingHuman, Methodology, Ceremony, CoreTerm } from '../types.js';
2
+
3
+ interface WaterfallPhaseConfig {
4
+ id: string;
5
+ name: string;
6
+ deliverables: string[];
7
+ gate: Gate;
8
+ budget?: Budget;
9
+ /** role id that delivers this phase's items; default: the first role with "deliver" */
10
+ deliverBy?: string;
11
+ }
12
+ interface WaterfallConfig {
13
+ phases: WaterfallPhaseConfig[];
14
+ changeControl: {
15
+ requiresImpactAnalysis: boolean;
16
+ approvers: GateRequirement[];
17
+ };
18
+ /** phase ids: every item of `from` must trace to an item of each `to` phase before that phase's gate */
19
+ traceability: {
20
+ from: string;
21
+ to: string[];
22
+ };
23
+ humanGates: "all" | string[];
24
+ }
25
+ declare const DEFAULT_PHASE_IDS: readonly string[];
26
+ declare const DEFAULT_DELIVERABLES: Record<string, string[]>;
27
+ declare const DEFAULT_DELIVER_BY: Record<string, string>;
28
+ declare const GATE_ID: (id: string) => string;
29
+ declare const CHANGE_GATE = "change-control";
30
+ declare function defaultPhases(): WaterfallPhaseConfig[];
31
+ declare function configOf(state: WorkflowState): WaterfallConfig;
32
+ declare function validateWaterfallConfig(raw: unknown): WaterfallConfig;
33
+
34
+ declare const WORK = "work";
35
+ declare const REVIEW = "review";
36
+ declare const DONE = "done";
37
+ /** state.phases, or the config phases as pending (before the first ceremony touches them). */
38
+ declare function phasesOf(state: WorkflowState): Phase[];
39
+ declare function withPhases(state: WorkflowState, phases: Phase[]): WorkflowState;
40
+ declare function phaseIndex(state: WorkflowState, id: string): number;
41
+ declare function getPhase(state: WorkflowState, id: string): Phase;
42
+ /** The item's phase, inherited from its parent chain (questions, follow-ups, retro items). */
43
+ declare function phaseOf(state: WorkflowState, item: WorkItem): string | undefined;
44
+ declare function itemsInPhase(state: WorkflowState, phaseId: string): WorkItem[];
45
+ declare function openPhase(state: WorkflowState): Phase | undefined;
46
+ /** First phase in order that is not baselined: the one to kick off (or the open one). */
47
+ declare function currentPhase(state: WorkflowState): Phase | undefined;
48
+ declare function isFrozen(state: WorkflowState, item: WorkItem): boolean;
49
+ declare function producedKinds(state: WorkflowState, phase: Phase): Set<string>;
50
+ /** Deliverables (and gate evidence kinds) still missing, in declaration order. */
51
+ declare function missingDeliverables(state: WorkflowState, phase: Phase, extra?: string[]): string[];
52
+ /** The traceability `to` phase that comes last in phase order (where the matrix must be complete). */
53
+ declare function lastToPhase(state: WorkflowState): string | undefined;
54
+
55
+ /** Every phase's items share the same three steps; the phase is the unit of governance. */
56
+ declare function waterfallStages(_config: WaterfallConfig): Stage[];
57
+
58
+ /** Order matters: the first role with "deliver" is the fallback deliverer for phases without deliverBy. */
59
+ declare function waterfallRoles(config: WaterfallConfig): Role[];
60
+
61
+ declare function waterfallRules(): Rule[];
62
+
63
+ interface WaterfallMetrics {
64
+ phaseCompletion: Record<string, number>;
65
+ budgetPlanned: Record<string, number>;
66
+ budgetSpent: Record<string, number>;
67
+ scheduleVariance: Record<string, number>;
68
+ requirementCoverage: number;
69
+ requirementsTraced: number;
70
+ requirementsTotal: number;
71
+ defectsPerPhase: Record<string, number>;
72
+ changeRequests: number;
73
+ changesApproved: number;
74
+ changesRejected: number;
75
+ changeApprovalRate: number;
76
+ reworkWeight: number;
77
+ phasesReopened: number;
78
+ }
79
+ /** Phase metrics replayed from events alone (membership from item.added, spend from item.completed). */
80
+ declare function waterfallMetrics(state: WorkflowState): WaterfallMetrics;
81
+
82
+ declare function approveChange(state: WorkflowState, changeId: string, by: string, note: string, now: string): WorkflowState;
83
+ declare function rejectChange(state: WorkflowState, changeId: string, by: string, note: string, now: string): WorkflowState;
84
+
85
+ /** input.phase as an existing phase. */
86
+ declare function wantPhase(state: WorkflowState, input: CeremonyInput, ceremony: string): Phase;
87
+
88
+ declare function waterfallCeremonies(methodology: () => Methodology): Record<string, Ceremony>;
89
+ /** decide() hook: a phase gate's human decision baselines the phase or records the failure. */
90
+ declare function waterfallAfterDecide(state: WorkflowState, entry: PendingHuman, decision: "approve" | "reject", by: string, note: string, now: string): WorkflowState;
91
+
92
+ interface TraceRow {
93
+ item: string;
94
+ /** to-phase id → ids of linked items in that phase */
95
+ links: Record<string, string[]>;
96
+ }
97
+ interface TraceabilityMatrix {
98
+ from: string;
99
+ to: string[];
100
+ rows: TraceRow[];
101
+ missing: Array<{
102
+ item: string;
103
+ phases: string[];
104
+ }>;
105
+ coverage: {
106
+ traced: number;
107
+ total: number;
108
+ };
109
+ }
110
+ declare function traceabilityMatrix(state: WorkflowState): TraceabilityMatrix;
111
+ /** Ids of `from` items with no link into `toPhase`. */
112
+ declare function missingTraces(state: WorkflowState, toPhase: string): string[];
113
+
114
+ /** Pass the phase gate: freeze its items, record the baseline, close its iteration. */
115
+ declare function baselinePhase(state: WorkflowState, phaseId: string, approvedBy: string[], now: string): WorkflowState;
116
+ interface ReopenResult {
117
+ state: WorkflowState;
118
+ reopened: string[];
119
+ suspended: string | null;
120
+ }
121
+ /** Change-control approval: reopen the listed baselined phases; a later open phase is suspended until they are re-baselined. */
122
+ declare function reopenPhases(state: WorkflowState, ids: string[], now: string): ReopenResult;
123
+
124
+ declare const WATERFALL_VOCABULARY: Record<CoreTerm, string>;
125
+ /** The role that delivers the item's phase (config deliverBy); undefined = the planner's default deliverer. */
126
+ declare function deliverRoleFor(state: WorkflowState, item: WorkItem): string | undefined;
127
+ interface PhaseReportRow {
128
+ id: string;
129
+ name: string;
130
+ status: string;
131
+ items: number;
132
+ done: number;
133
+ missingDeliverables: string[];
134
+ readyForGate: boolean;
135
+ }
136
+ interface PhaseReport {
137
+ phases: PhaseReportRow[];
138
+ current: string | null;
139
+ open: string | null;
140
+ pendingGates: Array<{
141
+ pending: string;
142
+ gate: string;
143
+ }>;
144
+ }
145
+ declare function phaseReport(state: WorkflowState): PhaseReport;
146
+ declare function waterfall(): Methodology<WaterfallConfig>;
147
+
148
+ export { CHANGE_GATE, DEFAULT_DELIVERABLES, DEFAULT_DELIVER_BY, DEFAULT_PHASE_IDS, DONE, GATE_ID, type PhaseReport, type PhaseReportRow, REVIEW, type ReopenResult, type TraceRow, type TraceabilityMatrix, WATERFALL_VOCABULARY, WORK, type WaterfallConfig, type WaterfallMetrics, type WaterfallPhaseConfig, approveChange, baselinePhase, configOf, currentPhase, defaultPhases, deliverRoleFor, getPhase, isFrozen, itemsInPhase, lastToPhase, missingDeliverables, missingTraces, openPhase, phaseIndex, phaseOf, phaseReport, phasesOf, producedKinds, rejectChange, reopenPhases, traceabilityMatrix, validateWaterfallConfig, wantPhase, waterfall, waterfallAfterDecide, waterfallCeremonies, waterfallMetrics, waterfallRoles, waterfallRules, waterfallStages, withPhases };
@@ -0,0 +1,2 @@
1
+ export{e as CHANGE_GATE,b as DEFAULT_DELIVERABLES,c as DEFAULT_DELIVER_BY,a as DEFAULT_PHASE_IDS,k as DONE,d as GATE_ID,j as REVIEW,K as WATERFALL_VOCABULARY,i as WORK,z as approveChange,x as baselinePhase,g as configOf,s as currentPhase,f as defaultPhases,L as deliverRoleFor,o as getPhase,t as isFrozen,q as itemsInPhase,w as lastToPhase,v as missingDeliverables,C as missingTraces,r as openPhase,n as phaseIndex,p as phaseOf,M as phaseReport,l as phasesOf,u as producedKinds,A as rejectChange,y as reopenPhases,B as traceabilityMatrix,h as validateWaterfallConfig,D as wantPhase,N as waterfall,F as waterfallAfterDecide,E as waterfallCeremonies,G as waterfallMetrics,H as waterfallRoles,I as waterfallRules,J as waterfallStages,m as withPhases}from'../chunk-NDORREWR.mjs';import'../chunk-GFH2FEZH.mjs';import'../chunk-SHAPFMVP.mjs';import'../chunk-2FRRD6A3.mjs';//# sourceMappingURL=index.mjs.map
2
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"index.mjs"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ex-workflow",
3
- "version": "0.2.0-stage",
3
+ "version": "0.4.0-stage",
4
4
  "description": "Methodology engine for AI teams: Scrum, Kanban and Waterfall as data-driven state machines on top of ex-flow",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -61,6 +61,16 @@
61
61
  "default": "./dist/kanban/index.cjs"
62
62
  }
63
63
  },
64
+ "./waterfall": {
65
+ "import": {
66
+ "types": "./dist/waterfall/index.d.ts",
67
+ "default": "./dist/waterfall/index.mjs"
68
+ },
69
+ "require": {
70
+ "types": "./dist/waterfall/index.d.cts",
71
+ "default": "./dist/waterfall/index.cjs"
72
+ }
73
+ },
64
74
  "./adapters": {
65
75
  "import": {
66
76
  "types": "./dist/adapters/index.d.ts",
@@ -81,6 +91,16 @@
81
91
  "default": "./dist/cli/index.cjs"
82
92
  }
83
93
  },
94
+ "./schema": {
95
+ "import": {
96
+ "types": "./dist/schema/index.d.ts",
97
+ "default": "./dist/schema/index.mjs"
98
+ },
99
+ "require": {
100
+ "types": "./dist/schema/index.d.cts",
101
+ "default": "./dist/schema/index.cjs"
102
+ }
103
+ },
84
104
  "./types": {
85
105
  "import": {
86
106
  "types": "./dist/types.d.ts",
@@ -100,6 +120,12 @@
100
120
  "kanban": [
101
121
  "dist/kanban/index.d.ts"
102
122
  ],
123
+ "waterfall": [
124
+ "dist/waterfall/index.d.ts"
125
+ ],
126
+ "schema": [
127
+ "dist/schema/index.d.ts"
128
+ ],
103
129
  "adapters": [
104
130
  "dist/adapters/index.d.ts"
105
131
  ],
@@ -127,7 +153,9 @@
127
153
  "typecheck": "tsc --noEmit",
128
154
  "size": "node scripts/size.mjs",
129
155
  "check:dist": "node scripts/check-dist.mjs && node scripts/check-exports.mjs",
130
- "ci": "pnpm format:check && pnpm lint && pnpm typecheck && pnpm test && pnpm minify && pnpm check:dist && pnpm size",
156
+ "schema:gen": "node scripts/gen-schema.mjs",
157
+ "schema:check": "node scripts/gen-schema.mjs --check",
158
+ "ci": "pnpm format:check && pnpm lint && pnpm typecheck && pnpm schema:check && pnpm test && pnpm minify && pnpm check:dist && pnpm size",
131
159
  "clean": "node -e \"require('fs').rmSync('dist',{recursive:true,force:true})\"",
132
160
  "prepublishOnly": "pnpm run ci",
133
161
  "prepare": "husky"
@@ -141,6 +169,7 @@
141
169
  "husky": "^9.1.7",
142
170
  "oxfmt": "^0.45.0",
143
171
  "oxlint": "^1.19.0",
172
+ "ts-json-schema-generator": "^2.9.0",
144
173
  "tsup": "^8.5.1",
145
174
  "tsx": "^4.20.6",
146
175
  "typescript": "^5.9.3"
@@ -1,6 +0,0 @@
1
- 'use strict';var chunkS3BXVHO7_cjs=require('./chunk-S3BXVHO7.cjs'),promises=require('fs/promises'),crypto=require('crypto'),n=require('path');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var n__default=/*#__PURE__*/_interopDefault(n);var c=".workflow";function y(t){return n__default.default.join(t,c,"state.json")}async function g(t,e){let i=`${t}.tmp-${process.pid}-${crypto.randomBytes(4).toString("hex")}`;try{await promises.mkdir(n__default.default.dirname(t),{recursive:!0}),await promises.writeFile(i,e,"utf8"),await promises.rename(i,t);}catch(r){await promises.unlink(i).catch(()=>{}),chunkS3BXVHO7_cjs.b("invalid-input",`cannot write ${t}: ${r.message}`,"check the directory exists and is writable");}}async function E(t,e,i={}){let{retries:r=40,intervalMs:d=50,staleMs:m=6e4}=i,a=n__default.default.join(t,c,"state.lock");await promises.mkdir(n__default.default.dirname(a),{recursive:true});let u=false;for(let f=0;!u;f++)try{let s=await promises.open(a,"wx");await s.writeFile(`${process.pid} ${new Date().toISOString()}
2
- `),await s.close(),u=!0;}catch(s){if(s.code!=="EEXIST")throw s;if(await promises.stat(a).then(w=>Date.now()-w.mtimeMs,()=>0)>m){await promises.unlink(a).catch(()=>{});continue}f>=r&&chunkS3BXVHO7_cjs.b("invalid-input","another exwf command holds .workflow/state.lock","retry, or delete the file if no exwf process is running"),await new Promise(w=>setTimeout(w,d));}try{return await e()}finally{await promises.unlink(a).catch(()=>{});}}async function D(t,e){await g(y(t),JSON.stringify(e,null,2)+`
3
- `);}async function M(t){let e=y(t),i;try{i=await promises.readFile(e,"utf8");}catch{chunkS3BXVHO7_cjs.b("invalid-input",`no workflow state at ${e}`,"run `exwf init <scrum|kanban|waterfall> --config <file>` in this directory first");}let r;try{r=JSON.parse(i);}catch(f){chunkS3BXVHO7_cjs.b("invalid-input",`${e} is not valid JSON: ${f.message}`,"restore it from git or re-run exwf init");}(typeof r!="object"||r===null||Array.isArray(r))&&chunkS3BXVHO7_cjs.b("invalid-input",`${e} does not contain a workflow state object`,"restore it from git or re-run exwf init");let d=r;d.version!==1&&chunkS3BXVHO7_cjs.b("state-version",`${e} has schema version ${String(d.version)}; this ex-workflow reads version 1`,"upgrade ex-workflow, or run the migration this version documents in its changelog");let m=n__default.default.join(t,c,"roles"),a=[];try{a=(await promises.readdir(m)).filter(f=>f.endsWith(".json"));}catch{}let u={...d.roles};for(let f of a){let s=n__default.default.join(m,f),l;try{l=JSON.parse(await promises.readFile(s,"utf8"));}catch(w){chunkS3BXVHO7_cjs.b("invalid-input",`role manifest ${s} is not valid JSON: ${w.message}`,"fix or delete that manifest");}(typeof l!="object"||l===null||typeof l.id!="string")&&chunkS3BXVHO7_cjs.b("invalid-input",`role manifest ${s} is not an object with a string id`,"a role manifest needs at least an id"),u[l.id]||(u[l.id]=l);}return {...d,roles:u}}function k(t,e){return n__default.default.resolve(e).startsWith(n__default.default.resolve(t,c)+n__default.default.sep)||chunkS3BXVHO7_cjs.b("invalid-input",`${e} resolves outside ${c}/`,"use a plain item id (letters, digits, - _ .)"),e}async function R(t,e){let i=k(t,n__default.default.join(t,c,"briefs",`${e.item.id}.json`));return await g(i,JSON.stringify(e,null,2)+`
4
- `),i}async function T(t,e,i){let r=k(t,n__default.default.join(t,c,"handoffs",`${e.item}-${i}.json`));return await g(r,JSON.stringify(e,null,2)+`
5
- `),r}exports.a=c;exports.b=y;exports.c=E;exports.d=D;exports.e=M;exports.f=R;exports.g=T;//# sourceMappingURL=chunk-6R3YFUUV.cjs.map
6
- //# sourceMappingURL=chunk-6R3YFUUV.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/adapters/file.ts"],"names":["WORKFLOW_DIR","statePath","root","path","writeAtomic","file","content","tmp","randomBytes","mkdir","writeFile","rename","e","unlink","fail","withStateLock","fn","opts","retries","intervalMs","staleMs","lock","held","attempt","fh","open","stat","st","resolve","saveState","state","loadState","raw","readFile","parsed","rolesDir","manifests","readdir","roles","manifestPath","role","inWorkflowDir","saveBrief","brief","saveHandoff","handoff","seq"],"mappings":"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","file":"chunk-6R3YFUUV.cjs","sourcesContent":["import { mkdir, open, readFile, readdir, rename, stat, unlink, writeFile } from \"node:fs/promises\";\nimport { randomBytes } from \"node:crypto\";\nimport path from \"node:path\";\nimport { fail } from \"../errors.ts\";\nimport type { Brief, Handoff, Role, WorkflowState } from \"../types.ts\";\n\nexport const WORKFLOW_DIR = \".workflow\";\n\nexport function statePath(root: string): string {\n return path.join(root, WORKFLOW_DIR, \"state.json\");\n}\n\nasync function writeAtomic(file: string, content: string): Promise<void> {\n const tmp = `${file}.tmp-${process.pid}-${randomBytes(4).toString(\"hex\")}`;\n try {\n await mkdir(path.dirname(file), { recursive: true });\n await writeFile(tmp, content, \"utf8\");\n await rename(tmp, file);\n } catch (e) {\n // best effort: remove the temp file if it was created; ignore failure\n await unlink(tmp).catch(() => undefined);\n fail(\n \"invalid-input\",\n `cannot write ${file}: ${(e as Error).message}`,\n \"check the directory exists and is writable\",\n );\n }\n}\n\nexport interface LockOptions {\n retries?: number;\n intervalMs?: number;\n staleMs?: number;\n}\n\n/** Run `fn` while holding `.workflow/state.lock`, so concurrent exwf commands cannot lose each other's updates. */\nexport async function withStateLock<T>(\n root: string,\n fn: () => Promise<T>,\n opts: LockOptions = {},\n): Promise<T> {\n const { retries = 40, intervalMs = 50, staleMs = 60_000 } = opts;\n const lock = path.join(root, WORKFLOW_DIR, \"state.lock\");\n await mkdir(path.dirname(lock), { recursive: true });\n let held = false;\n for (let attempt = 0; !held; attempt++) {\n try {\n const fh = await open(lock, \"wx\");\n await fh.writeFile(`${process.pid} ${new Date().toISOString()}\\n`);\n await fh.close();\n held = true;\n } catch (e) {\n if ((e as NodeJS.ErrnoException).code !== \"EEXIST\") throw e;\n const age = await stat(lock).then(\n (st) => Date.now() - st.mtimeMs,\n () => 0,\n );\n if (age > staleMs) {\n await unlink(lock).catch(() => undefined);\n continue;\n }\n if (attempt >= retries)\n fail(\n \"invalid-input\",\n \"another exwf command holds .workflow/state.lock\",\n \"retry, or delete the file if no exwf process is running\",\n );\n await new Promise((resolve) => setTimeout(resolve, intervalMs));\n }\n }\n try {\n return await fn();\n } finally {\n await unlink(lock).catch(() => undefined);\n }\n}\n\nexport async function saveState(root: string, state: WorkflowState): Promise<void> {\n await writeAtomic(statePath(root), JSON.stringify(state, null, 2) + \"\\n\");\n}\n\nexport async function loadState(root: string): Promise<WorkflowState> {\n const file = statePath(root);\n let raw: string;\n try {\n raw = await readFile(file, \"utf8\");\n } catch {\n fail(\n \"invalid-input\",\n `no workflow state at ${file}`,\n \"run `exwf init <scrum|kanban|waterfall> --config <file>` in this directory first\",\n );\n }\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch (e) {\n fail(\n \"invalid-input\",\n `${file} is not valid JSON: ${(e as Error).message}`,\n \"restore it from git or re-run exwf init\",\n );\n }\n if (typeof parsed !== \"object\" || parsed === null || Array.isArray(parsed)) {\n fail(\n \"invalid-input\",\n `${file} does not contain a workflow state object`,\n \"restore it from git or re-run exwf init\",\n );\n }\n const state = parsed as WorkflowState;\n if (state.version !== 1)\n fail(\n \"state-version\",\n `${file} has schema version ${String(state.version)}; this ex-workflow reads version 1`,\n \"upgrade ex-workflow, or run the migration this version documents in its changelog\",\n );\n const rolesDir = path.join(root, WORKFLOW_DIR, \"roles\");\n let manifests: string[] = [];\n try {\n manifests = (await readdir(rolesDir)).filter((f) => f.endsWith(\".json\"));\n } catch {\n /* no extra roles */\n }\n const roles = { ...state.roles };\n for (const f of manifests) {\n const manifestPath = path.join(rolesDir, f);\n let role: Role;\n try {\n role = JSON.parse(await readFile(manifestPath, \"utf8\")) as Role;\n } catch (e) {\n fail(\n \"invalid-input\",\n `role manifest ${manifestPath} is not valid JSON: ${(e as Error).message}`,\n \"fix or delete that manifest\",\n );\n }\n if (typeof role !== \"object\" || role === null || typeof role.id !== \"string\") {\n fail(\n \"invalid-input\",\n `role manifest ${manifestPath} is not an object with a string id`,\n \"a role manifest needs at least an id\",\n );\n }\n if (!roles[role.id]) roles[role.id] = role;\n }\n return { ...state, roles };\n}\n\nfunction inWorkflowDir(root: string, file: string): string {\n if (!path.resolve(file).startsWith(path.resolve(root, WORKFLOW_DIR) + path.sep))\n fail(\n \"invalid-input\",\n `${file} resolves outside ${WORKFLOW_DIR}/`,\n \"use a plain item id (letters, digits, - _ .)\",\n );\n return file;\n}\n\nexport async function saveBrief(root: string, brief: Brief): Promise<string> {\n const file = inWorkflowDir(\n root,\n path.join(root, WORKFLOW_DIR, \"briefs\", `${brief.item.id}.json`),\n );\n await writeAtomic(file, JSON.stringify(brief, null, 2) + \"\\n\");\n return file;\n}\n\nexport async function saveHandoff(root: string, handoff: Handoff, seq: number): Promise<string> {\n const file = inWorkflowDir(\n root,\n path.join(root, WORKFLOW_DIR, \"handoffs\", `${handoff.item}-${seq}.json`),\n );\n await writeAtomic(file, JSON.stringify(handoff, null, 2) + \"\\n\");\n return file;\n}\n"]}
@@ -1,2 +0,0 @@
1
- 'use strict';var chunkS3BXVHO7_cjs=require('./chunk-S3BXVHO7.cjs');function k(t){return t??new Date().toISOString()}function C(t){let e=new Set;for(let n of t.stages)e.has(n.id)&&chunkS3BXVHO7_cjs.b("config-invalid",`duplicate stage id "${n.id}"`,"give every stage a unique id"),e.add(n.id);let o={};for(let n of t.roles)chunkS3BXVHO7_cjs.c(n.id,"role id"),Object.hasOwn(o,n.id)&&chunkS3BXVHO7_cjs.b("duplicate-role",`duplicate role id "${n.id}"`,"give every role a unique id"),o[n.id]=n;let i=k(t.now);return {version:1,methodology:t.methodology,config:t.config,items:{},stages:t.stages,roles:o,iterations:[],events:[{seq:1,at:i,type:"state.created",by:"system",payload:{methodology:t.methodology}}],accounting:[],pending:[],lessons:[],agreements:[]}}function g(t,e,o,i,n){let r={seq:(t.events[t.events.length-1]?.seq??0)+1,at:k(n),type:e,by:o,payload:i};return {...t,events:[...t.events,r]}}function te(t,e){for(let o=t.events.length-1;o>=0;o--){let i=t.events[o];if(e===void 0||i.type===e)return i}}function j(t,e){return Object.hasOwn(t.roles,e)?t.roles[e]:void 0}var H=new Set(["in_progress","review","blocked"]);function re(t,e,o,i){chunkS3BXVHO7_cjs.c(e.id,"role id"),j(t,e.id)&&chunkS3BXVHO7_cjs.b("duplicate-role",`role "${e.id}" already exists`,`use a different id or retireRole("${e.id}") first`);let n={...t,roles:{...t.roles,[e.id]:e}};return g(n,"role.registered",o,{role:e.id,capabilities:e.capabilities},i)}function se(t,e,o,i){j(t,e)||chunkS3BXVHO7_cjs.b("unknown-role",`role "${e}" does not exist`,`registered roles: ${Object.keys(t.roles).join(", ")||"(none)"}`);let n=Object.values(t.items).filter(r=>r.role===e&&H.has(r.status)).map(r=>r.id);n.length&&chunkS3BXVHO7_cjs.b("role-has-open-items",`role "${e}" still holds ${n.length} open item(s)`,`complete or reassign ${n.join(", ")} before retiring the role`,{items:n});let s={...t.roles};return delete s[e],g({...t,roles:s},"role.retired",o,{role:e},i)}function x(t,e){return t.capabilities.includes(e)}function O(t,e){return Object.values(t.roles).filter(o=>x(o,e))}function w(t,e,o,i){return Object.values(t.roles).filter(n=>n.id!==i&&n.canApprove.includes(e)&&(o===void 0||n.capabilities.includes(o))).map(n=>n.id)}function ae(t,e){return O(t,"approve-gate").filter(o=>o.canApprove.includes(e))}function q(t,e,o){for(let i of e)O(t,i).length===0&&chunkS3BXVHO7_cjs.b("missing-capability",`no registered role has capability "${i}"`,`register a role whose capabilities include "${i}" (registerRole) before init`);for(let i of o){let n=O(t,i);n.length>1&&chunkS3BXVHO7_cjs.b("exclusive-capability",`capability "${i}" must belong to exactly one role but is held by ${n.map(s=>s.id).join(", ")}`,`remove "${i}" from all but one role`);}}function P(t,e){return e.length===0?[]:Object.values(t.roles).filter(o=>e.every(i=>x(o,i)))}function G(t,e,...o){if(e==="human")return true;let i=j(t,e);return !!i&&o.some(n=>x(i,n))}function le(t,e,...o){if(!G(t,e,...o)){let i=Object.values(t.roles).filter(n=>o.some(s=>x(n,s))).map(n=>n.id);chunkS3BXVHO7_cjs.b("missing-capability",`"${e}" lacks capability ${o.map(n=>`"${n}"`).join(" or ")}`,`run this as one of: human${i.map(n=>`, ${n}`).join("")}`);}}function I(t,e){let o=t.stages.find(i=>i.id===e);return o||chunkS3BXVHO7_cjs.b("unknown-stage",`stage "${e}" does not exist`,`stages are: ${t.stages.map(i=>i.id).join(" \u2192 ")}`),o}function D(t,e){let o=t.stages.findIndex(i=>i.id===e);return o<0&&I(t,e),t.stages[o+1]}function K(t,e){return t.stages[t.stages.length-1]?.id===e}function v(t,e){return {...t,items:{...t.items,[e.id]:e}}}function J(t,e,o){return v(t,o(h(t,e)))}function L(t,e,o){return J(t,e,i=>{let n={...i};for(let s of o)delete n[s];return n})}function h(t,e){let o=Object.hasOwn(t.items,e)?t.items[e]:void 0;return o||chunkS3BXVHO7_cjs.b("unknown-item",`item "${e}" does not exist`,`add it with addItem first; known items: ${Object.keys(t.items).join(", ")||"(none)"}`,{items:[e]}),o}function $(t,e,o){let i=e.filter(n=>!Object.hasOwn(t.items,n));i.length&&chunkS3BXVHO7_cjs.b("unknown-item",`${o} refers to unknown item(s) ${i.join(", ")}`,"add those items first or remove the reference",{items:i});}function ue(t,e,o,i){chunkS3BXVHO7_cjs.c(e.id,"item id"),Object.hasOwn(t.items,e.id)&&chunkS3BXVHO7_cjs.b("duplicate-item",`item "${e.id}" already exists`,"use editItem to change it, or pick a new id",{items:[e.id]});let n=t.stages[0];n||chunkS3BXVHO7_cjs.b("config-invalid","state has no stages","create the state with at least one stage");let s=e.stage??n.id;I(t,s),$(t,e.dependsOn??[],`item "${e.id}".dependsOn`),e.affects&&$(t,e.affects,`item "${e.id}".affects`),e.parent!==void 0&&$(t,[e.parent],`item "${e.id}".parent`),e.role!==void 0&&!Object.hasOwn(t.roles,e.role)&&chunkS3BXVHO7_cjs.b("unknown-role",`role "${e.role}" does not exist`,`registered roles: ${Object.keys(t.roles).join(", ")}`);let{stage:r,...a}=e,l={type:"task",acceptance:[],dependsOn:[],...a,id:e.id,title:e.title,stage:s,status:"todo",evidence:[],blockers:[],transitions:[]},c=v(t,l);return g(c,"item.added",o,{id:l.id,type:l.type,stage:l.stage,weight:l.weight??null,priority:l.priority??null},i)}function ge(t,e,o,i,n){let s=h(t,e);o.dependsOn&&$(t,o.dependsOn,`item "${e}".dependsOn`),o.affects&&$(t,o.affects,`item "${e}".affects`),o.parent!==void 0&&$(t,[o.parent],`item "${e}".parent`),o.role!==void 0&&!Object.hasOwn(t.roles,o.role)&&chunkS3BXVHO7_cjs.b("unknown-role",`role "${o.role}" does not exist`,`registered roles: ${Object.keys(t.roles).join(", ")}`);let r=Object.keys(o).filter(c=>JSON.stringify(o[c])!==JSON.stringify(s[c]));r.length===0&&chunkS3BXVHO7_cjs.b("no-op",`editItem("${e}") changes nothing`,"pass at least one field with a different value",{items:[e]});let a={...s};for(let c of r)a[c]=o[c];let l=v(t,a);return g(l,"item.edited",i,{id:e,changed:r},n)}function S(t,e,o,i,n){let s=h(t,e),r=o.stage??s.stage;I(t,r),(s.status==="done"||s.status==="dropped")&&chunkS3BXVHO7_cjs.b("invalid-transition",`item "${e}" is ${s.status} and cannot move`,"create a new item (or a change-request) instead of reopening a finished one",{items:[e]}),r===s.stage&&o.status===s.status&&chunkS3BXVHO7_cjs.b("no-op",`item "${e}" is already ${s.status} in "${r}"`,"choose a different stage or status",{items:[e]});let a=k(n),l={...s,stage:r,status:o.status,transitions:[...s.transitions,{from:{stage:s.stage,status:s.status},to:{stage:r,status:o.status},at:a,by:i}]},c=v(t,l);return g(c,"item.transition",i,{id:e,from:{stage:s.stage,status:s.status},to:{stage:r,status:o.status}},a)}function pe(t,e,o,i){let n=h(t,e),s=k(i),r={...n,evidence:[...n.evidence,{...o,at:s}]},a=v(t,r);return g(a,"item.evidence",o.by,{id:e,kind:o.kind,ref:o.ref},s)}function V(t,e,o,i,n,s){let r=h(t,e),a=k(s),l=`${e}-b${r.blockers.length+1}`,c=r.status==="blocked"?null:{from:{stage:r.stage,status:r.status},to:{stage:r.stage,status:"blocked"},at:a,by:n},f={...r,status:"blocked",blockers:[...r.blockers,{id:l,reason:o,owner:i,raisedAt:a}],transitions:c?[...r.transitions,c]:r.transitions},u=v(t,f);return g(u,"blocker.raised",n,{id:e,blocker:l,reason:o,owner:i,transition:c&&{from:c.from,to:c.to}},a)}function E(t,e){for(let o=t.transitions.length-1;o>=0;o--){let i=t.transitions[o];if(i.to.status===e)return i}}function me(t,e,o,i,n){let s=h(t,e),r=s.blockers.findIndex(m=>m.id===o&&!m.clearedAt);r<0&&chunkS3BXVHO7_cjs.b("invalid-input",`item "${e}" has no open blocker "${o}"`,`open blockers: ${s.blockers.filter(m=>!m.clearedAt).map(m=>m.id).join(", ")||"(none)"}`,{items:[e]});let a=k(n),l=s.blockers.map((m,F)=>F===r?{...m,clearedAt:a}:m),c=l.some(m=>!m.clearedAt),f=E(s,"blocked")?.from.status??"todo",u=s.stage,p=f,W=false;f==="in_progress"?(p="todo",u=E(s,"in_progress")?.from.stage??s.stage):f==="awaiting_human"&&(p=I(t,s.stage).review?"review":"todo",W=true);let{role:Z,...T}=s,b=c?null:{from:{stage:s.stage,status:"blocked"},to:{stage:u,status:p},at:a,by:i},N={...W&&!c?T:s,blockers:l,stage:c?s.stage:u,status:c?"blocked":p,transitions:b?[...s.transitions,b]:s.transitions},B=v(t,N);return g(B,"blocker.cleared",i,{id:e,blocker:o,transition:b&&{from:b.from,to:b.to}},a)}function R(t,e){return L(t,e,["role"])}function M(t,e,o,i,n){let s=h(t,e),r=D(t,s.stage);if(!r)return S(t,e,{status:"done"},o,n);if(K(t,r.id))return S(t,e,{stage:r.id,status:"done"},o,n);let a=i||r.review===true?"review":"todo";return R(S(t,e,{stage:r.id,status:a},o,n),e)}function z(t,e,o){let i=[],n=(s,r,a)=>i.push({rule:s,severity:"error",item:e.id,message:r,fix:a});for(let s of o)switch(s.kind){case "evidence":e.evidence.some(r=>r.kind===s.evidenceKind)||n("policy:evidence",`item "${e.id}" has no evidence of kind "${s.evidenceKind}"`,`attach evidence { kind: "${s.evidenceKind}" } via addEvidence or in the handoff.produced`);break;case "acceptance-written":e.acceptance.length===0&&n("policy:acceptance-written",`item "${e.id}" has no acceptance criteria`,"editItem with a non-empty acceptance[] (needs define-acceptance)");break;case "estimate-present":e.weight===void 0&&n("policy:estimate-present",`item "${e.id}" has no weight`,"editItem with a weight (story points)");break;case "no-open-blockers":{let r=e.blockers.filter(a=>!a.clearedAt);r.length&&n("policy:no-open-blockers",`item "${e.id}" has ${r.length} open blocker(s)`,`clearBlocker ${r.map(a=>a.id).join(", ")}`);break}case "dependencies-done":{let r=e.dependsOn.filter(a=>t.items[a]?.status!=="done");r.length&&n("policy:dependencies-done",`item "${e.id}" depends on unfinished ${r.join(", ")}`,`finish ${r.join(", ")} first`);break}case "custom":e.evidence.some(r=>r.kind===`policy:${s.id}`)||n(`policy:custom:${s.id}`,`item "${e.id}" has not satisfied "${s.description}"`,`attach evidence { kind: "policy:${s.id}" } when it is satisfied`);break}return i}function we(t,e,o,i){let n=z(t,e,o);n.length&&chunkS3BXVHO7_cjs.b("policy-unmet",`item "${e.id}" cannot ${i}: ${n.length} polic${n.length===1?"y":"ies"} unmet`,n.map(s=>s.fix).join("; "),{items:[e.id]});}function Q(t,e){let o=new Map(t.stages.map((n,s)=>[n.id,s])),i=o.get(e.stage);if(i!==void 0)for(let n=e.transitions.length-1;n>=0;n--){let s=e.transitions[n],r=o.get(s.from.stage);if(s.to.status==="in_progress"&&r!==void 0&&r<i)return s}}function A(t,e){let o=Q(t,e);if(o)return o.by;for(let i=e.transitions.length-1;i>=0;i--){let n=e.transitions[i];if(n.to.status==="in_progress")return n.by}}function U(t,e,o,i){let n=[];for(let r of o.evidence)e.evidence.some(a=>a.kind===r)||n.push({rule:"gate:evidence",severity:"error",item:e.id,message:`gate "${o.id}" needs evidence "${r}" on item "${e.id}"`,fix:`attach evidence { kind: "${r}" } before approving`});if(n.length)return {outcome:"fail",violations:n};let s=false;for(let r of o.requires){if(r==="human"){i!=="human"&&(s=true);continue}if(!w(t,o.id,r.capability).includes(i)){n.push({rule:"gate:capability",severity:"error",item:e.id,message:`"${i}" may not approve gate "${o.id}" (needs capability "${r.capability}" and canApprove "${o.id}")`,fix:`approve as one of: ${w(t,o.id,r.capability).join(", ")||"(no role qualifies; register one)"}`});continue}let l=A(t,e);if(l!==void 0&&l===i){let c=w(t,o.id,r.capability,i);n.push({rule:"conflict-of-interest",severity:"error",item:e.id,message:`role "${i}" did the work on "${e.id}" and may not approve it`,fix:`approve as a different role: ${c.join(", ")||"(register another approver)"}`});}}return n.length?{outcome:"fail",violations:n}:s?{outcome:"human"}:{outcome:"pass"}}function be(t,e,o){let i=k(o),n=`p${t.events.filter(a=>a.type==="pending.raised").length+1}`,s={...e,id:n,raisedAt:i},r={...t,pending:[...t.pending,s]};return e.item&&h(r,e.item).status!=="awaiting_human"&&(r=S(r,e.item,{status:"awaiting_human"},"system",i)),g(r,"pending.raised","system",{id:n,kind:e.kind,item:e.item??null,gate:e.gate??null},i)}function xe(t,e,o,i,n,s){o!=="approve"&&o!=="reject"&&chunkS3BXVHO7_cjs.b("invalid-input",`decision must be "approve" or "reject" (got ${JSON.stringify(o)})`,"pass approve or reject");let r=t.pending.find(u=>u.id===e);r||chunkS3BXVHO7_cjs.b("unknown-pending",`no pending decision "${e}"`,`open decisions: ${t.pending.map(u=>u.id).join(", ")||"(none)"}`);let a=r.kind==="gate"&&r.item?h(t,r.item):void 0,l=a&&(t.stages.find(u=>r.gate!==void 0&&u.gate?.id===r.gate)?.gate??t.stages.find(u=>u.id===a.stage)?.gate);a&&l&&i!=="human"&&(l.requires.includes("human")?void 0:U(t,a,l,i))?.outcome!=="pass"&&chunkS3BXVHO7_cjs.b("gate-unmet",`"${i}" may not decide gate "${l.id}" on "${a.id}"`,`decide as one of: human${l.requires.flatMap(p=>p==="human"?[]:w(t,l.id,p.capability)).map(p=>`, ${p}`).join("")}`,{items:[a.id],rule:"gate"});let c=k(s),f={...t,pending:t.pending.filter(u=>u.id!==e)};if(f=g(f,"pending.decided",i,{id:e,decision:o,note:n,item:r.item??null,gate:r.gate??null},c),a){let u=a.id,p=r.gate??l?.id??null;if(o==="approve")f=M(f,u,i,false,c),f=g(f,"gate.passed",i,{item:u,gate:p},c);else {let W=l?.onFail??{action:"block"};W.action==="return-to"?f=R(S(f,u,{stage:W.stage,status:"todo"},i,c),u):f=V(f,u,`gate "${p??"?"}" rejected: ${n||"no reason given"}`,i,i,c),f=g(f,"gate.failed",i,{item:u,gate:p,note:n},c);}}return f}function _(t){return [{id:"separation-lost",severity:"warning",check(i,n){return n.type!=="init"&&n.type!=="role.register"?[]:P(i,t.requiredCapabilities).map(s=>({rule:"separation-lost",severity:"warning",message:`role "${s.id}" holds every required capability (${t.requiredCapabilities.join(", ")}); no separation of duties`,fix:"fine for a solo operator; otherwise split capabilities across roles"}))}},{id:"conflict-of-interest",severity:"error",check(i,n){if(n.type!=="complete")return [];let s=n.payload?.handoff;if(!s)return [];let r=s.verdict??"done";if(r!=="done"&&r!=="needs-review")return [];let a=i.items[s.item];if(!a)return [];let l=i.stages.find(f=>f.id===a.stage)?.gate;if(!l||!l.requires.some(f=>f!=="human"))return [];if(A(i,a)!==s.role)return [];let c=w(i,l.id,void 0,s.role);return [{rule:"conflict-of-interest",severity:"error",item:a.id,message:`role "${s.role}" authored "${a.id}" and may not pass gate "${l.id}" on it`,fix:`hand the gate to another approver: ${c.join(", ")||"(register one)"}`}]}}]}function X(t,e,o){let i=[];for(let n of [..._(e),...e.rules])i.push(...n.check(t,o));return i}function Y(t,e,o,i){let n=X(t,e,o),s=n.filter(r=>r.severity==="error");return s.length&&chunkS3BXVHO7_cjs.b("rule-violation",`${o.type} violates ${s.map(r=>r.rule).join(", ")}: ${s.map(r=>r.message).join("; ")}`,s.map(r=>r.fix).join("; "),{rule:s[0].rule,items:s.map(r=>r.item).filter(r=>!!r)}),{state:i(t),warnings:n.filter(r=>r.severity==="warning")}}function Ee(t){let e=t.methodology,o=e.validateConfig(t.config),i=t.stages??e.defaultStages(o),n=t.roles??e.defaultRoles(o),s=t.now!==void 0?{methodology:e.name,config:o,stages:i,roles:n,now:t.now}:{methodology:e.name,config:o,stages:i,roles:n},r=C(s);return q(r,e.requiredCapabilities,e.exclusiveCapabilities),Y(r,e,{type:"init",by:t.by??"system"},a=>a)}exports.A=me;exports.B=R;exports.C=M;exports.D=z;exports.E=we;exports.F=Q;exports.G=A;exports.H=U;exports.I=be;exports.J=xe;exports.K=_;exports.L=X;exports.M=Y;exports.N=Ee;exports.a=k;exports.b=C;exports.c=g;exports.d=te;exports.e=j;exports.f=re;exports.g=se;exports.h=x;exports.i=O;exports.j=w;exports.k=ae;exports.l=q;exports.m=P;exports.n=G;exports.o=le;exports.p=I;exports.q=D;exports.r=K;exports.s=J;exports.t=L;exports.u=h;exports.v=ue;exports.w=ge;exports.x=S;exports.y=pe;exports.z=V;//# sourceMappingURL=chunk-JDVE7DQR.cjs.map
2
- //# sourceMappingURL=chunk-JDVE7DQR.cjs.map