@rasensio/aidlc 0.1.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/README.md +251 -0
- package/capabilities/claude-code.yaml +9 -0
- package/capabilities/codex.yaml +8 -0
- package/capabilities/cursor.yaml +8 -0
- package/capabilities/kiro.yaml +9 -0
- package/capabilities/windsurf.yaml +8 -0
- package/ci/aidlc-gate.yml +100 -0
- package/dist/cli.d.ts +11 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +39 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/add-action.d.ts +83 -0
- package/dist/commands/add-action.d.ts.map +1 -0
- package/dist/commands/add-action.js +437 -0
- package/dist/commands/add-action.js.map +1 -0
- package/dist/commands/continue.d.ts +23 -0
- package/dist/commands/continue.d.ts.map +1 -0
- package/dist/commands/continue.js +238 -0
- package/dist/commands/continue.js.map +1 -0
- package/dist/commands/discover.d.ts +19 -0
- package/dist/commands/discover.d.ts.map +1 -0
- package/dist/commands/discover.js +85 -0
- package/dist/commands/discover.js.map +1 -0
- package/dist/commands/docs.d.ts +25 -0
- package/dist/commands/docs.d.ts.map +1 -0
- package/dist/commands/docs.js +282 -0
- package/dist/commands/docs.js.map +1 -0
- package/dist/commands/gate.d.ts +25 -0
- package/dist/commands/gate.d.ts.map +1 -0
- package/dist/commands/gate.js +168 -0
- package/dist/commands/gate.js.map +1 -0
- package/dist/commands/init.d.ts +24 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +187 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/review.d.ts +60 -0
- package/dist/commands/review.d.ts.map +1 -0
- package/dist/commands/review.js +264 -0
- package/dist/commands/review.js.map +1 -0
- package/dist/commands/setup.d.ts +24 -0
- package/dist/commands/setup.d.ts.map +1 -0
- package/dist/commands/setup.js +206 -0
- package/dist/commands/setup.js.map +1 -0
- package/dist/commands/start.d.ts +27 -0
- package/dist/commands/start.d.ts.map +1 -0
- package/dist/commands/start.js +243 -0
- package/dist/commands/start.js.map +1 -0
- package/dist/commands/status.d.ts +25 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +263 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/transition.d.ts +30 -0
- package/dist/commands/transition.d.ts.map +1 -0
- package/dist/commands/transition.js +353 -0
- package/dist/commands/transition.js.map +1 -0
- package/dist/compile/adapters/claude-code.d.ts +24 -0
- package/dist/compile/adapters/claude-code.d.ts.map +1 -0
- package/dist/compile/adapters/claude-code.js +271 -0
- package/dist/compile/adapters/claude-code.js.map +1 -0
- package/dist/compile/adapters/codex.d.ts +19 -0
- package/dist/compile/adapters/codex.d.ts.map +1 -0
- package/dist/compile/adapters/codex.js +157 -0
- package/dist/compile/adapters/codex.js.map +1 -0
- package/dist/compile/adapters/cursor.d.ts +21 -0
- package/dist/compile/adapters/cursor.d.ts.map +1 -0
- package/dist/compile/adapters/cursor.js +181 -0
- package/dist/compile/adapters/cursor.js.map +1 -0
- package/dist/compile/adapters/index.d.ts +16 -0
- package/dist/compile/adapters/index.d.ts.map +1 -0
- package/dist/compile/adapters/index.js +26 -0
- package/dist/compile/adapters/index.js.map +1 -0
- package/dist/compile/adapters/kiro.d.ts +24 -0
- package/dist/compile/adapters/kiro.d.ts.map +1 -0
- package/dist/compile/adapters/kiro.js +222 -0
- package/dist/compile/adapters/kiro.js.map +1 -0
- package/dist/compile/adapters/windsurf.d.ts +25 -0
- package/dist/compile/adapters/windsurf.d.ts.map +1 -0
- package/dist/compile/adapters/windsurf.js +242 -0
- package/dist/compile/adapters/windsurf.js.map +1 -0
- package/dist/compile/install-plan.d.ts +49 -0
- package/dist/compile/install-plan.d.ts.map +1 -0
- package/dist/compile/install-plan.js +112 -0
- package/dist/compile/install-plan.js.map +1 -0
- package/dist/compile/loaders.d.ts +81 -0
- package/dist/compile/loaders.d.ts.map +1 -0
- package/dist/compile/loaders.js +293 -0
- package/dist/compile/loaders.js.map +1 -0
- package/dist/compile/merger.d.ts +32 -0
- package/dist/compile/merger.d.ts.map +1 -0
- package/dist/compile/merger.js +60 -0
- package/dist/compile/merger.js.map +1 -0
- package/dist/core/gate.d.ts +36 -0
- package/dist/core/gate.d.ts.map +1 -0
- package/dist/core/gate.js +97 -0
- package/dist/core/gate.js.map +1 -0
- package/dist/core/index.d.ts +7 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +7 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/lifecycle.d.ts +89 -0
- package/dist/core/lifecycle.d.ts.map +1 -0
- package/dist/core/lifecycle.js +356 -0
- package/dist/core/lifecycle.js.map +1 -0
- package/dist/core/template-resolver.d.ts +56 -0
- package/dist/core/template-resolver.d.ts.map +1 -0
- package/dist/core/template-resolver.js +261 -0
- package/dist/core/template-resolver.js.map +1 -0
- package/dist/core/types.d.ts +527 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +8 -0
- package/dist/core/types.js.map +1 -0
- package/dist/discover/scanner.d.ts +58 -0
- package/dist/discover/scanner.d.ts.map +1 -0
- package/dist/discover/scanner.js +772 -0
- package/dist/discover/scanner.js.map +1 -0
- package/dist/events/event-bus.d.ts +53 -0
- package/dist/events/event-bus.d.ts.map +1 -0
- package/dist/events/event-bus.js +263 -0
- package/dist/events/event-bus.js.map +1 -0
- package/dist/events/plugin-hooks.d.ts +44 -0
- package/dist/events/plugin-hooks.d.ts.map +1 -0
- package/dist/events/plugin-hooks.js +225 -0
- package/dist/events/plugin-hooks.js.map +1 -0
- package/dist/orchestrator/budget-packer.d.ts +57 -0
- package/dist/orchestrator/budget-packer.d.ts.map +1 -0
- package/dist/orchestrator/budget-packer.js +70 -0
- package/dist/orchestrator/budget-packer.js.map +1 -0
- package/dist/orchestrator/config.d.ts +43 -0
- package/dist/orchestrator/config.d.ts.map +1 -0
- package/dist/orchestrator/config.js +109 -0
- package/dist/orchestrator/config.js.map +1 -0
- package/dist/orchestrator/endpoint-clients.d.ts +23 -0
- package/dist/orchestrator/endpoint-clients.d.ts.map +1 -0
- package/dist/orchestrator/endpoint-clients.js +129 -0
- package/dist/orchestrator/endpoint-clients.js.map +1 -0
- package/dist/orchestrator/orchestrator-loop.d.ts +93 -0
- package/dist/orchestrator/orchestrator-loop.d.ts.map +1 -0
- package/dist/orchestrator/orchestrator-loop.js +185 -0
- package/dist/orchestrator/orchestrator-loop.js.map +1 -0
- package/dist/security/confirmation.d.ts +90 -0
- package/dist/security/confirmation.d.ts.map +1 -0
- package/dist/security/confirmation.js +140 -0
- package/dist/security/confirmation.js.map +1 -0
- package/dist/setup/setup-compute.d.ts +54 -0
- package/dist/setup/setup-compute.d.ts.map +1 -0
- package/dist/setup/setup-compute.js +66 -0
- package/dist/setup/setup-compute.js.map +1 -0
- package/dist/state/snapshot-store.d.ts +79 -0
- package/dist/state/snapshot-store.d.ts.map +1 -0
- package/dist/state/snapshot-store.js +164 -0
- package/dist/state/snapshot-store.js.map +1 -0
- package/dist/state/state-recovery.d.ts +87 -0
- package/dist/state/state-recovery.d.ts.map +1 -0
- package/dist/state/state-recovery.js +274 -0
- package/dist/state/state-recovery.js.map +1 -0
- package/dist/state/transition-log.d.ts +40 -0
- package/dist/state/transition-log.d.ts.map +1 -0
- package/dist/state/transition-log.js +83 -0
- package/dist/state/transition-log.js.map +1 -0
- package/dist/state/yaml-helpers.d.ts +53 -0
- package/dist/state/yaml-helpers.d.ts.map +1 -0
- package/dist/state/yaml-helpers.js +110 -0
- package/dist/state/yaml-helpers.js.map +1 -0
- package/examples/.gitkeep +0 -0
- package/guidance/accessibility.md +67 -0
- package/guidance/api-conventions.md +124 -0
- package/guidance/index.yaml +7 -0
- package/guidance/secure-defaults.md +71 -0
- package/package.json +52 -0
- package/phases/.gitkeep +0 -0
- package/skills/00-overview.md +74 -0
- package/skills/10-ideation.md +45 -0
- package/skills/20-requirements.md +54 -0
- package/skills/30-design.md +57 -0
- package/skills/40-implementation.md +64 -0
- package/skills/50-testing.md +60 -0
- package/skills/60-deployment.md +63 -0
- package/skills/70-maintenance.md +56 -0
- package/skills/80-review.md +85 -0
- package/skills/81-continue.md +57 -0
- package/skills/82-add-action.md +71 -0
- package/templates/.gitkeep +0 -0
- package/templates/bugfix.yaml +14 -0
- package/templates/full-feature.yaml +44 -0
- package/templates/micro-task.yaml +11 -0
- package/templates/quick-feature.yaml +20 -0
- package/templates/spike.yaml +15 -0
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Gate evaluation with exit-code semantics for CI/CD integration.
|
|
3
|
+
*
|
|
4
|
+
* `evaluateGate()` checks whether a phase passes its gate:
|
|
5
|
+
* - Exit 0 (pass: true) iff phase status is 'complete'.
|
|
6
|
+
* - Otherwise, returns structured data naming missing artifacts and unsatisfied criteria.
|
|
7
|
+
*
|
|
8
|
+
* Requirements: 9.1, 9.6
|
|
9
|
+
*/
|
|
10
|
+
// ---------------------------------------------------------------------------
|
|
11
|
+
// Gate evaluation
|
|
12
|
+
// ---------------------------------------------------------------------------
|
|
13
|
+
/**
|
|
14
|
+
* Evaluate whether a phase passes its gate check.
|
|
15
|
+
*
|
|
16
|
+
* Exit 0 (pass: true) iff the phase status is 'complete'.
|
|
17
|
+
* Otherwise, returns structured data naming what's missing (Req 9.6).
|
|
18
|
+
*
|
|
19
|
+
* @param phaseName - Name of the phase to check.
|
|
20
|
+
* @param phaseStates - Map of phase name → PhaseState for the instance.
|
|
21
|
+
* @param template - The resolved workflow template defining required artifacts.
|
|
22
|
+
* @returns A GateCheckResult indicating pass/fail with structured details.
|
|
23
|
+
*/
|
|
24
|
+
export function evaluateGate(phaseName, phaseStates, template) {
|
|
25
|
+
const state = phaseStates.get(phaseName);
|
|
26
|
+
// Phase not found in state
|
|
27
|
+
if (!state) {
|
|
28
|
+
return {
|
|
29
|
+
pass: false,
|
|
30
|
+
phase: phaseName,
|
|
31
|
+
missingArtifacts: [],
|
|
32
|
+
unsatisfiedCriteria: ['phase not found in instance state'],
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
// Phase is complete — gate passes
|
|
36
|
+
if (state.status === 'complete') {
|
|
37
|
+
return {
|
|
38
|
+
pass: true,
|
|
39
|
+
phase: phaseName,
|
|
40
|
+
missingArtifacts: [],
|
|
41
|
+
unsatisfiedCriteria: [],
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
// Phase is not complete — gather structured details about what's missing
|
|
45
|
+
const missingArtifacts = getMissingArtifacts(phaseName, state, template);
|
|
46
|
+
const unsatisfiedCriteria = getUnsatisfiedCriteria(state);
|
|
47
|
+
return {
|
|
48
|
+
pass: false,
|
|
49
|
+
phase: phaseName,
|
|
50
|
+
missingArtifacts,
|
|
51
|
+
unsatisfiedCriteria,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
// ---------------------------------------------------------------------------
|
|
55
|
+
// Helpers
|
|
56
|
+
// ---------------------------------------------------------------------------
|
|
57
|
+
/**
|
|
58
|
+
* Determine which required artifacts from the template are not yet 'complete'
|
|
59
|
+
* in the phase state.
|
|
60
|
+
*/
|
|
61
|
+
function getMissingArtifacts(phaseName, state, template) {
|
|
62
|
+
// Find the template phase definition
|
|
63
|
+
const templatePhase = template.phases.find((p) => p.name === phaseName);
|
|
64
|
+
if (!templatePhase) {
|
|
65
|
+
// Phase exists in state but not in template — no required artifacts to check
|
|
66
|
+
return [];
|
|
67
|
+
}
|
|
68
|
+
// Build a set of artifact names that are already complete in state
|
|
69
|
+
const completedArtifacts = new Set(state.artifacts
|
|
70
|
+
.filter((a) => a.status === 'complete')
|
|
71
|
+
.map((a) => a.name));
|
|
72
|
+
// Find required artifacts that are not complete
|
|
73
|
+
return templatePhase.required_artifacts
|
|
74
|
+
.filter((decl) => !completedArtifacts.has(decl.name))
|
|
75
|
+
.map((decl) => decl.name);
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Describe unsatisfied criteria based on the current phase status.
|
|
79
|
+
*/
|
|
80
|
+
function getUnsatisfiedCriteria(state) {
|
|
81
|
+
const criteria = [];
|
|
82
|
+
switch (state.status) {
|
|
83
|
+
case 'pending':
|
|
84
|
+
criteria.push('phase has not been started (status: pending)');
|
|
85
|
+
break;
|
|
86
|
+
case 'in-progress':
|
|
87
|
+
criteria.push('phase is still in progress (status: in-progress)');
|
|
88
|
+
break;
|
|
89
|
+
case 'skipped':
|
|
90
|
+
criteria.push('phase was skipped (status: skipped)');
|
|
91
|
+
break;
|
|
92
|
+
default:
|
|
93
|
+
criteria.push(`phase status is "${state.status}" (expected: complete)`);
|
|
94
|
+
}
|
|
95
|
+
return criteria;
|
|
96
|
+
}
|
|
97
|
+
//# sourceMappingURL=gate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gate.js","sourceRoot":"","sources":["../../src/core/gate.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAsBH,8EAA8E;AAC9E,kBAAkB;AAClB,8EAA8E;AAE9E;;;;;;;;;;GAUG;AACH,MAAM,UAAU,YAAY,CAC1B,SAAiB,EACjB,WAAoC,EACpC,QAA0B;IAE1B,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IAEzC,2BAA2B;IAC3B,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO;YACL,IAAI,EAAE,KAAK;YACX,KAAK,EAAE,SAAS;YAChB,gBAAgB,EAAE,EAAE;YACpB,mBAAmB,EAAE,CAAC,mCAAmC,CAAC;SAC3D,CAAC;IACJ,CAAC;IAED,kCAAkC;IAClC,IAAI,KAAK,CAAC,MAAM,KAAK,UAAU,EAAE,CAAC;QAChC,OAAO;YACL,IAAI,EAAE,IAAI;YACV,KAAK,EAAE,SAAS;YAChB,gBAAgB,EAAE,EAAE;YACpB,mBAAmB,EAAE,EAAE;SACxB,CAAC;IACJ,CAAC;IAED,yEAAyE;IACzE,MAAM,gBAAgB,GAAG,mBAAmB,CAAC,SAAS,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC;IACzE,MAAM,mBAAmB,GAAG,sBAAsB,CAAC,KAAK,CAAC,CAAC;IAE1D,OAAO;QACL,IAAI,EAAE,KAAK;QACX,KAAK,EAAE,SAAS;QAChB,gBAAgB;QAChB,mBAAmB;KACpB,CAAC;AACJ,CAAC;AAED,8EAA8E;AAC9E,UAAU;AACV,8EAA8E;AAE9E;;;GAGG;AACH,SAAS,mBAAmB,CAC1B,SAAiB,EACjB,KAAiB,EACjB,QAA0B;IAE1B,qCAAqC;IACrC,MAAM,aAAa,GAAG,QAAQ,CAAC,MAAM,CAAC,IAAI,CACxC,CAAC,CAAgB,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,SAAS,CAC3C,CAAC;IAEF,IAAI,CAAC,aAAa,EAAE,CAAC;QACnB,6EAA6E;QAC7E,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,mEAAmE;IACnE,MAAM,kBAAkB,GAAG,IAAI,GAAG,CAChC,KAAK,CAAC,SAAS;SACZ,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,UAAU,CAAC;SACtC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CACtB,CAAC;IAEF,gDAAgD;IAChD,OAAO,aAAa,CAAC,kBAAkB;SACpC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,kBAAkB,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;SACpD,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC9B,CAAC;AAED;;GAEG;AACH,SAAS,sBAAsB,CAAC,KAAiB;IAC/C,MAAM,QAAQ,GAAa,EAAE,CAAC;IAE9B,QAAQ,KAAK,CAAC,MAAM,EAAE,CAAC;QACrB,KAAK,SAAS;YACZ,QAAQ,CAAC,IAAI,CAAC,8CAA8C,CAAC,CAAC;YAC9D,MAAM;QACR,KAAK,aAAa;YAChB,QAAQ,CAAC,IAAI,CAAC,kDAAkD,CAAC,CAAC;YAClE,MAAM;QACR,KAAK,SAAS;YACZ,QAAQ,CAAC,IAAI,CAAC,qCAAqC,CAAC,CAAC;YACrD,MAAM;QACR;YACE,QAAQ,CAAC,IAAI,CAAC,oBAAoB,KAAK,CAAC,MAAM,wBAAwB,CAAC,CAAC;IAC5E,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,wBAAwB,CAAC;AACvC,cAAc,WAAW,CAAC;AAC1B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,wBAAwB,CAAC;AACvC,cAAc,WAAW,CAAC;AAC1B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure lifecycle engine functions — completionPercent, isStalled, nextStep, evaluateTransition.
|
|
3
|
+
*
|
|
4
|
+
* These are stateless computations over typed state objects used for
|
|
5
|
+
* progress tracking, observability, continuation resolution, and gate evaluation.
|
|
6
|
+
* (Requirements 3.6, 6.6, 9.3, 11.2, 11.3, 24.6, 26.1, 26.5).
|
|
7
|
+
*/
|
|
8
|
+
import type { PhaseState, WorkflowTemplate, InstanceState, NextStep, FindingsIndex, TransitionResult } from './types.js';
|
|
9
|
+
/**
|
|
10
|
+
* Calculate completion percentage for a lifecycle instance.
|
|
11
|
+
*
|
|
12
|
+
* Integer 0-100, floor of: (completed required artifacts) / (total required artifacts)
|
|
13
|
+
* across all applicable phases (filtered by scope).
|
|
14
|
+
*
|
|
15
|
+
* Algorithm:
|
|
16
|
+
* 1. Get applicable phases from the template (accounting for scope via phasesForScope)
|
|
17
|
+
* 2. Count total required artifacts across all applicable phases
|
|
18
|
+
* 3. Count completed artifacts (status === 'complete') from phase states
|
|
19
|
+
* 4. Return Math.floor((completed / total) * 100), or 0 if total is 0
|
|
20
|
+
*
|
|
21
|
+
* @param phaseStates - Map of phase name to PhaseState for this instance.
|
|
22
|
+
* @param template - The resolved workflow template (no `extends`).
|
|
23
|
+
* @param scope - The cycle scope to determine applicable phases.
|
|
24
|
+
* @returns Integer 0-100 representing completion percentage.
|
|
25
|
+
*/
|
|
26
|
+
export declare function completionPercent(phaseStates: Map<string, PhaseState>, template: WorkflowTemplate, scope?: InstanceState['scope']): number;
|
|
27
|
+
/**
|
|
28
|
+
* Determine if an instance is stalled.
|
|
29
|
+
*
|
|
30
|
+
* Stalled = current phase has been active longer than thresholdDays
|
|
31
|
+
* AND completionPercent < 100%.
|
|
32
|
+
* Never stalled at 100% — a completed instance is never flagged regardless
|
|
33
|
+
* of how long its current phase has been active.
|
|
34
|
+
*
|
|
35
|
+
* @param state - The instance state (provides current_phase and scope).
|
|
36
|
+
* @param phaseStates - Map of phase name to PhaseState for this instance.
|
|
37
|
+
* @param template - The resolved workflow template.
|
|
38
|
+
* @param now - Current time for age calculation.
|
|
39
|
+
* @param thresholdDays - Number of days before a phase is considered stalled.
|
|
40
|
+
* @returns true if the instance is stalled, false otherwise.
|
|
41
|
+
*/
|
|
42
|
+
export declare function isStalled(state: InstanceState, phaseStates: Map<string, PhaseState>, template: WorkflowTemplate, now: Date, thresholdDays: number): boolean;
|
|
43
|
+
/**
|
|
44
|
+
* Continuation resolver — deterministic function of template and state.
|
|
45
|
+
*
|
|
46
|
+
* Returns the next action the instance should take:
|
|
47
|
+
* - `{ kind: 'artifact', phase, artifact }` — produce this artifact next
|
|
48
|
+
* - `{ kind: 'phase', phase }` — enter this phase next
|
|
49
|
+
* - `{ kind: 'complete' }` — all phases and artifacts are done
|
|
50
|
+
*
|
|
51
|
+
* Algorithm:
|
|
52
|
+
* 1. Get the resolved phases for the current scope from the template.
|
|
53
|
+
* 2. Find the current phase in the resolved list.
|
|
54
|
+
* 3. In the current phase, find the first required artifact with status !== 'complete'.
|
|
55
|
+
* → return `{ kind: 'artifact', phase: currentPhase, artifact: artifactName }`
|
|
56
|
+
* 4. If all required artifacts in the current phase are complete, find the next
|
|
57
|
+
* pending phase (status not 'complete' and not 'skipped').
|
|
58
|
+
* → return `{ kind: 'phase', phase: nextPhaseName }`
|
|
59
|
+
* 5. If no pending phases remain, return `{ kind: 'complete' }`.
|
|
60
|
+
*
|
|
61
|
+
* @param state - The current instance state.
|
|
62
|
+
* @param phaseStates - Map of phase name → PhaseState for all tracked phases.
|
|
63
|
+
* @param template - The fully resolved workflow template (no `extends`).
|
|
64
|
+
* @returns The next step the instance should take.
|
|
65
|
+
*/
|
|
66
|
+
export declare function nextStep(state: InstanceState, phaseStates: Map<string, PhaseState>, template: WorkflowTemplate): NextStep;
|
|
67
|
+
/**
|
|
68
|
+
* Gate chain — evaluates whether a phase transition is allowed.
|
|
69
|
+
* Returns Allowed or Blocked (with EVERY unsatisfied condition).
|
|
70
|
+
*
|
|
71
|
+
* Gate evaluation order:
|
|
72
|
+
* 1. Required artifacts of the current phase all "complete"
|
|
73
|
+
* 2. Review gate (if template configures one for this phase): no critical+open findings
|
|
74
|
+
* 3. Ownership guard: warn + require override if actor ≠ recorded owner
|
|
75
|
+
* 4. Deployment entry: every preceding required phase has recorded status "complete" (from state only)
|
|
76
|
+
* 5. Blocking actions (placeholder — currently no-op)
|
|
77
|
+
*
|
|
78
|
+
* A blocked attempt reports every unsatisfied condition (Req 4.4).
|
|
79
|
+
*
|
|
80
|
+
* @param state - Current instance state.
|
|
81
|
+
* @param phaseStates - Map of phase name → PhaseState for all phases in the instance.
|
|
82
|
+
* @param template - The resolved workflow template (no `extends`).
|
|
83
|
+
* @param actor - Identity of the user/agent attempting the transition.
|
|
84
|
+
* @param findings - Findings index keyed by artifact name.
|
|
85
|
+
* @param override - If true, suppresses the ownership violation.
|
|
86
|
+
* @returns TransitionResult — `{ allowed: true }` or `{ allowed: false, violations: [...] }`.
|
|
87
|
+
*/
|
|
88
|
+
export declare function evaluateTransition(state: InstanceState, phaseStates: Map<string, PhaseState>, template: WorkflowTemplate, actor: string, findings: FindingsIndex, override?: boolean): TransitionResult;
|
|
89
|
+
//# sourceMappingURL=lifecycle.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lifecycle.d.ts","sourceRoot":"","sources":["../../src/core/lifecycle.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EACV,UAAU,EACV,gBAAgB,EAChB,aAAa,EACb,QAAQ,EAER,aAAa,EACb,gBAAgB,EAEjB,MAAM,YAAY,CAAC;AAOpB;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,iBAAiB,CAC/B,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,EACpC,QAAQ,EAAE,gBAAgB,EAC1B,KAAK,CAAC,EAAE,aAAa,CAAC,OAAO,CAAC,GAC7B,MAAM,CA2BR;AAMD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,SAAS,CACvB,KAAK,EAAE,aAAa,EACpB,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,EACpC,QAAQ,EAAE,gBAAgB,EAC1B,GAAG,EAAE,IAAI,EACT,aAAa,EAAE,MAAM,GACpB,OAAO,CAeT;AAOD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,QAAQ,CACtB,KAAK,EAAE,aAAa,EACpB,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,EACpC,QAAQ,EAAE,gBAAgB,GACzB,QAAQ,CA+CV;AA8ED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,aAAa,EACpB,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,EACpC,QAAQ,EAAE,gBAAgB,EAC1B,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,aAAa,EACvB,QAAQ,CAAC,EAAE,OAAO,GACjB,gBAAgB,CAiClB"}
|
|
@@ -0,0 +1,356 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure lifecycle engine functions — completionPercent, isStalled, nextStep, evaluateTransition.
|
|
3
|
+
*
|
|
4
|
+
* These are stateless computations over typed state objects used for
|
|
5
|
+
* progress tracking, observability, continuation resolution, and gate evaluation.
|
|
6
|
+
* (Requirements 3.6, 6.6, 9.3, 11.2, 11.3, 24.6, 26.1, 26.5).
|
|
7
|
+
*/
|
|
8
|
+
import { phasesForScope } from './template-resolver.js';
|
|
9
|
+
// ---------------------------------------------------------------------------
|
|
10
|
+
// completionPercent (Req 11.2)
|
|
11
|
+
// ---------------------------------------------------------------------------
|
|
12
|
+
/**
|
|
13
|
+
* Calculate completion percentage for a lifecycle instance.
|
|
14
|
+
*
|
|
15
|
+
* Integer 0-100, floor of: (completed required artifacts) / (total required artifacts)
|
|
16
|
+
* across all applicable phases (filtered by scope).
|
|
17
|
+
*
|
|
18
|
+
* Algorithm:
|
|
19
|
+
* 1. Get applicable phases from the template (accounting for scope via phasesForScope)
|
|
20
|
+
* 2. Count total required artifacts across all applicable phases
|
|
21
|
+
* 3. Count completed artifacts (status === 'complete') from phase states
|
|
22
|
+
* 4. Return Math.floor((completed / total) * 100), or 0 if total is 0
|
|
23
|
+
*
|
|
24
|
+
* @param phaseStates - Map of phase name to PhaseState for this instance.
|
|
25
|
+
* @param template - The resolved workflow template (no `extends`).
|
|
26
|
+
* @param scope - The cycle scope to determine applicable phases.
|
|
27
|
+
* @returns Integer 0-100 representing completion percentage.
|
|
28
|
+
*/
|
|
29
|
+
export function completionPercent(phaseStates, template, scope) {
|
|
30
|
+
const effectiveScope = scope ?? template.scope;
|
|
31
|
+
const applicablePhases = phasesForScope(template, effectiveScope);
|
|
32
|
+
let totalRequired = 0;
|
|
33
|
+
let completedCount = 0;
|
|
34
|
+
for (const templatePhase of applicablePhases) {
|
|
35
|
+
totalRequired += templatePhase.required_artifacts.length;
|
|
36
|
+
const phaseState = phaseStates.get(templatePhase.name);
|
|
37
|
+
if (!phaseState)
|
|
38
|
+
continue;
|
|
39
|
+
for (const artifact of phaseState.artifacts) {
|
|
40
|
+
// Only count artifacts that are declared as required in the template
|
|
41
|
+
const isRequired = templatePhase.required_artifacts.some((ra) => ra.name === artifact.name);
|
|
42
|
+
if (isRequired && artifact.status === 'complete') {
|
|
43
|
+
completedCount++;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
if (totalRequired === 0)
|
|
48
|
+
return 0;
|
|
49
|
+
return Math.floor((completedCount / totalRequired) * 100);
|
|
50
|
+
}
|
|
51
|
+
// ---------------------------------------------------------------------------
|
|
52
|
+
// isStalled (Req 11.3)
|
|
53
|
+
// ---------------------------------------------------------------------------
|
|
54
|
+
/**
|
|
55
|
+
* Determine if an instance is stalled.
|
|
56
|
+
*
|
|
57
|
+
* Stalled = current phase has been active longer than thresholdDays
|
|
58
|
+
* AND completionPercent < 100%.
|
|
59
|
+
* Never stalled at 100% — a completed instance is never flagged regardless
|
|
60
|
+
* of how long its current phase has been active.
|
|
61
|
+
*
|
|
62
|
+
* @param state - The instance state (provides current_phase and scope).
|
|
63
|
+
* @param phaseStates - Map of phase name to PhaseState for this instance.
|
|
64
|
+
* @param template - The resolved workflow template.
|
|
65
|
+
* @param now - Current time for age calculation.
|
|
66
|
+
* @param thresholdDays - Number of days before a phase is considered stalled.
|
|
67
|
+
* @returns true if the instance is stalled, false otherwise.
|
|
68
|
+
*/
|
|
69
|
+
export function isStalled(state, phaseStates, template, now, thresholdDays) {
|
|
70
|
+
// Never stalled at 100% completion
|
|
71
|
+
const percent = completionPercent(phaseStates, template, state.scope);
|
|
72
|
+
if (percent >= 100)
|
|
73
|
+
return false;
|
|
74
|
+
// Find the current phase state
|
|
75
|
+
const currentPhaseState = phaseStates.get(state.current_phase);
|
|
76
|
+
if (!currentPhaseState || !currentPhaseState.entered_at)
|
|
77
|
+
return false;
|
|
78
|
+
// Calculate how long the phase has been active
|
|
79
|
+
const enteredAt = new Date(currentPhaseState.entered_at);
|
|
80
|
+
const elapsedMs = now.getTime() - enteredAt.getTime();
|
|
81
|
+
const elapsedDays = elapsedMs / (1000 * 60 * 60 * 24);
|
|
82
|
+
return elapsedDays > thresholdDays;
|
|
83
|
+
}
|
|
84
|
+
// ---------------------------------------------------------------------------
|
|
85
|
+
// nextStep — Continuation Resolver (Req 26.1, 26.5)
|
|
86
|
+
// ---------------------------------------------------------------------------
|
|
87
|
+
/**
|
|
88
|
+
* Continuation resolver — deterministic function of template and state.
|
|
89
|
+
*
|
|
90
|
+
* Returns the next action the instance should take:
|
|
91
|
+
* - `{ kind: 'artifact', phase, artifact }` — produce this artifact next
|
|
92
|
+
* - `{ kind: 'phase', phase }` — enter this phase next
|
|
93
|
+
* - `{ kind: 'complete' }` — all phases and artifacts are done
|
|
94
|
+
*
|
|
95
|
+
* Algorithm:
|
|
96
|
+
* 1. Get the resolved phases for the current scope from the template.
|
|
97
|
+
* 2. Find the current phase in the resolved list.
|
|
98
|
+
* 3. In the current phase, find the first required artifact with status !== 'complete'.
|
|
99
|
+
* → return `{ kind: 'artifact', phase: currentPhase, artifact: artifactName }`
|
|
100
|
+
* 4. If all required artifacts in the current phase are complete, find the next
|
|
101
|
+
* pending phase (status not 'complete' and not 'skipped').
|
|
102
|
+
* → return `{ kind: 'phase', phase: nextPhaseName }`
|
|
103
|
+
* 5. If no pending phases remain, return `{ kind: 'complete' }`.
|
|
104
|
+
*
|
|
105
|
+
* @param state - The current instance state.
|
|
106
|
+
* @param phaseStates - Map of phase name → PhaseState for all tracked phases.
|
|
107
|
+
* @param template - The fully resolved workflow template (no `extends`).
|
|
108
|
+
* @returns The next step the instance should take.
|
|
109
|
+
*/
|
|
110
|
+
export function nextStep(state, phaseStates, template) {
|
|
111
|
+
// Step 1: Get applicable phases for the current scope
|
|
112
|
+
const applicablePhases = phasesForScope(template, state.scope);
|
|
113
|
+
if (applicablePhases.length === 0) {
|
|
114
|
+
return { kind: 'complete' };
|
|
115
|
+
}
|
|
116
|
+
// Step 2: Find the current phase in the applicable phases list
|
|
117
|
+
const currentPhaseIndex = applicablePhases.findIndex((p) => p.name === state.current_phase);
|
|
118
|
+
// If current phase is found, check for incomplete artifacts in it
|
|
119
|
+
if (currentPhaseIndex !== -1) {
|
|
120
|
+
const currentTemplatePhase = applicablePhases[currentPhaseIndex];
|
|
121
|
+
const currentPhaseState = phaseStates.get(state.current_phase);
|
|
122
|
+
// Step 3: Find the first incomplete required artifact in the current phase
|
|
123
|
+
const incompleteArtifact = findFirstIncompleteArtifact(currentTemplatePhase, currentPhaseState);
|
|
124
|
+
if (incompleteArtifact !== null) {
|
|
125
|
+
return {
|
|
126
|
+
kind: 'artifact',
|
|
127
|
+
phase: state.current_phase,
|
|
128
|
+
artifact: incompleteArtifact,
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
// Step 4: All artifacts in current phase are complete (or current phase not found).
|
|
133
|
+
// Find the next pending phase that is not the current phase.
|
|
134
|
+
const nextPendingPhase = findNextPendingPhase(applicablePhases, phaseStates, state.current_phase);
|
|
135
|
+
if (nextPendingPhase !== null) {
|
|
136
|
+
return { kind: 'phase', phase: nextPendingPhase };
|
|
137
|
+
}
|
|
138
|
+
// Step 5: No pending phases remain — all done.
|
|
139
|
+
return { kind: 'complete' };
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Find the first required artifact in a template phase that is not yet complete.
|
|
143
|
+
*
|
|
144
|
+
* @returns The artifact name, or null if all required artifacts are complete.
|
|
145
|
+
*/
|
|
146
|
+
function findFirstIncompleteArtifact(templatePhase, phaseState) {
|
|
147
|
+
if (templatePhase.required_artifacts.length === 0) {
|
|
148
|
+
return null;
|
|
149
|
+
}
|
|
150
|
+
// Build a set of completed artifact names from the phase state
|
|
151
|
+
const completedArtifacts = new Set();
|
|
152
|
+
if (phaseState) {
|
|
153
|
+
for (const artifact of phaseState.artifacts) {
|
|
154
|
+
if (artifact.status === 'complete') {
|
|
155
|
+
completedArtifacts.add(artifact.name);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
// Find the first required artifact that is not complete
|
|
160
|
+
for (const decl of templatePhase.required_artifacts) {
|
|
161
|
+
if (!completedArtifacts.has(decl.name)) {
|
|
162
|
+
return decl.name;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
return null;
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Find the next phase that is not yet complete or skipped, excluding the
|
|
169
|
+
* current phase (since we already checked its artifacts).
|
|
170
|
+
*
|
|
171
|
+
* Iterates through applicable phases in order. A phase is "pending" if
|
|
172
|
+
* its phase state status is not 'complete' and not 'skipped', or if
|
|
173
|
+
* no phase state exists for it yet (implicitly pending).
|
|
174
|
+
*
|
|
175
|
+
* @param currentPhase - The current phase to exclude from results.
|
|
176
|
+
* @returns The name of the next pending phase, or null if all are done/skipped.
|
|
177
|
+
*/
|
|
178
|
+
function findNextPendingPhase(applicablePhases, phaseStates, currentPhase) {
|
|
179
|
+
for (const templatePhase of applicablePhases) {
|
|
180
|
+
// Skip the current phase — its artifacts are already handled
|
|
181
|
+
if (templatePhase.name === currentPhase) {
|
|
182
|
+
continue;
|
|
183
|
+
}
|
|
184
|
+
const ps = phaseStates.get(templatePhase.name);
|
|
185
|
+
// No phase state → phase hasn't started → it's pending
|
|
186
|
+
if (!ps) {
|
|
187
|
+
return templatePhase.name;
|
|
188
|
+
}
|
|
189
|
+
// Phase exists but is neither complete nor skipped → still pending
|
|
190
|
+
if (ps.status !== 'complete' && ps.status !== 'skipped') {
|
|
191
|
+
return templatePhase.name;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
return null;
|
|
195
|
+
}
|
|
196
|
+
// ---------------------------------------------------------------------------
|
|
197
|
+
// evaluateTransition (Req 3.6, 6.6, 9.3, 24.6)
|
|
198
|
+
// ---------------------------------------------------------------------------
|
|
199
|
+
/**
|
|
200
|
+
* Gate chain — evaluates whether a phase transition is allowed.
|
|
201
|
+
* Returns Allowed or Blocked (with EVERY unsatisfied condition).
|
|
202
|
+
*
|
|
203
|
+
* Gate evaluation order:
|
|
204
|
+
* 1. Required artifacts of the current phase all "complete"
|
|
205
|
+
* 2. Review gate (if template configures one for this phase): no critical+open findings
|
|
206
|
+
* 3. Ownership guard: warn + require override if actor ≠ recorded owner
|
|
207
|
+
* 4. Deployment entry: every preceding required phase has recorded status "complete" (from state only)
|
|
208
|
+
* 5. Blocking actions (placeholder — currently no-op)
|
|
209
|
+
*
|
|
210
|
+
* A blocked attempt reports every unsatisfied condition (Req 4.4).
|
|
211
|
+
*
|
|
212
|
+
* @param state - Current instance state.
|
|
213
|
+
* @param phaseStates - Map of phase name → PhaseState for all phases in the instance.
|
|
214
|
+
* @param template - The resolved workflow template (no `extends`).
|
|
215
|
+
* @param actor - Identity of the user/agent attempting the transition.
|
|
216
|
+
* @param findings - Findings index keyed by artifact name.
|
|
217
|
+
* @param override - If true, suppresses the ownership violation.
|
|
218
|
+
* @returns TransitionResult — `{ allowed: true }` or `{ allowed: false, violations: [...] }`.
|
|
219
|
+
*/
|
|
220
|
+
export function evaluateTransition(state, phaseStates, template, actor, findings, override) {
|
|
221
|
+
const violations = [];
|
|
222
|
+
// Find the current phase in the resolved template
|
|
223
|
+
const currentPhaseName = state.current_phase;
|
|
224
|
+
const applicablePhases = phasesForScope(template, state.scope);
|
|
225
|
+
const currentTemplatePhase = applicablePhases.find((p) => p.name === currentPhaseName);
|
|
226
|
+
// Gate 1: Required artifacts — all must have status 'complete'
|
|
227
|
+
if (currentTemplatePhase) {
|
|
228
|
+
const currentPhaseState = phaseStates.get(currentPhaseName);
|
|
229
|
+
checkRequiredArtifacts(currentTemplatePhase, currentPhaseState, violations);
|
|
230
|
+
}
|
|
231
|
+
// Gate 2: Review gate — if template configures adversarial-review for this phase
|
|
232
|
+
checkReviewGate(template, currentPhaseName, findings, violations);
|
|
233
|
+
// Gate 3: Ownership guard — actor must match phase owner (unless override)
|
|
234
|
+
checkOwnership(phaseStates, currentPhaseName, actor, override, violations);
|
|
235
|
+
// Gate 4: Deployment entry — all preceding required phases must be complete
|
|
236
|
+
checkDeploymentEntry(applicablePhases, currentPhaseName, phaseStates, violations);
|
|
237
|
+
// Gate 5: Blocking actions (placeholder — no implementation yet)
|
|
238
|
+
// Future: check enabled blocking actions and add violations if any fail.
|
|
239
|
+
if (violations.length === 0) {
|
|
240
|
+
return { allowed: true };
|
|
241
|
+
}
|
|
242
|
+
return { allowed: false, violations };
|
|
243
|
+
}
|
|
244
|
+
// ---------------------------------------------------------------------------
|
|
245
|
+
// Gate helpers
|
|
246
|
+
// ---------------------------------------------------------------------------
|
|
247
|
+
/**
|
|
248
|
+
* Check that all required artifacts in the current phase have status 'complete'.
|
|
249
|
+
*/
|
|
250
|
+
function checkRequiredArtifacts(templatePhase, phaseState, violations) {
|
|
251
|
+
if (!templatePhase.required_artifacts || templatePhase.required_artifacts.length === 0) {
|
|
252
|
+
return;
|
|
253
|
+
}
|
|
254
|
+
if (!phaseState) {
|
|
255
|
+
// Phase state doesn't exist — all artifacts are missing
|
|
256
|
+
for (const art of templatePhase.required_artifacts) {
|
|
257
|
+
violations.push({
|
|
258
|
+
gate: 'required-artifacts',
|
|
259
|
+
reason: `required artifact "${art.name}" is missing (no phase state)`,
|
|
260
|
+
});
|
|
261
|
+
}
|
|
262
|
+
return;
|
|
263
|
+
}
|
|
264
|
+
for (const requiredArt of templatePhase.required_artifacts) {
|
|
265
|
+
const tracked = phaseState.artifacts.find((a) => a.name === requiredArt.name);
|
|
266
|
+
if (!tracked || tracked.status !== 'complete') {
|
|
267
|
+
const status = tracked ? tracked.status : 'not-started';
|
|
268
|
+
violations.push({
|
|
269
|
+
gate: 'required-artifacts',
|
|
270
|
+
reason: `required artifact "${requiredArt.name}" is not complete (status: ${status})`,
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* If the template has an adversarial-review gate for the current phase,
|
|
277
|
+
* check that no finding with severity 'critical' and status 'open' exists.
|
|
278
|
+
*/
|
|
279
|
+
function checkReviewGate(template, currentPhaseName, findings, violations) {
|
|
280
|
+
const reviewGatePhases = template.gates?.['adversarial-review'];
|
|
281
|
+
if (!reviewGatePhases || !reviewGatePhases.includes(currentPhaseName)) {
|
|
282
|
+
return;
|
|
283
|
+
}
|
|
284
|
+
// Review gate is configured for this phase — check findings
|
|
285
|
+
const allFindings = Object.values(findings).flat();
|
|
286
|
+
// If no findings exist at all (no review has been done), block
|
|
287
|
+
if (allFindings.length === 0) {
|
|
288
|
+
violations.push({
|
|
289
|
+
gate: 'review-gate',
|
|
290
|
+
reason: `review gate requires a completed review for phase "${currentPhaseName}" but no findings exist`,
|
|
291
|
+
});
|
|
292
|
+
return;
|
|
293
|
+
}
|
|
294
|
+
// Block on any critical+open finding
|
|
295
|
+
const criticalOpen = allFindings.filter((f) => f.severity === 'critical' && f.status === 'open');
|
|
296
|
+
for (const finding of criticalOpen) {
|
|
297
|
+
violations.push({
|
|
298
|
+
gate: 'review-gate',
|
|
299
|
+
reason: `critical finding "${finding.id}" is still open: ${finding.title}`,
|
|
300
|
+
});
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
/**
|
|
304
|
+
* If phase ownership is set and actor ≠ owner, add an ownership violation
|
|
305
|
+
* (unless override is true).
|
|
306
|
+
*/
|
|
307
|
+
function checkOwnership(phaseStates, currentPhaseName, actor, override, violations) {
|
|
308
|
+
if (override) {
|
|
309
|
+
return;
|
|
310
|
+
}
|
|
311
|
+
const phaseState = phaseStates.get(currentPhaseName);
|
|
312
|
+
if (!phaseState || !phaseState.owner) {
|
|
313
|
+
return;
|
|
314
|
+
}
|
|
315
|
+
if (phaseState.owner !== actor) {
|
|
316
|
+
violations.push({
|
|
317
|
+
gate: 'ownership',
|
|
318
|
+
reason: `phase "${currentPhaseName}" is owned by "${phaseState.owner}" but transition attempted by "${actor}"; use override to proceed`,
|
|
319
|
+
});
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
/**
|
|
323
|
+
* If the next phase is 'deployment', verify that all preceding required phases
|
|
324
|
+
* have recorded status 'complete' or 'skipped' (from state only, not disk).
|
|
325
|
+
* The current phase is excluded from this check since its completion is
|
|
326
|
+
* validated by the required-artifacts gate.
|
|
327
|
+
*/
|
|
328
|
+
function checkDeploymentEntry(applicablePhases, currentPhaseName, phaseStates, violations) {
|
|
329
|
+
// Find the index of the current phase
|
|
330
|
+
const currentIdx = applicablePhases.findIndex((p) => p.name === currentPhaseName);
|
|
331
|
+
if (currentIdx === -1) {
|
|
332
|
+
return;
|
|
333
|
+
}
|
|
334
|
+
// Determine the next phase (the target of this transition)
|
|
335
|
+
const nextIdx = currentIdx + 1;
|
|
336
|
+
if (nextIdx >= applicablePhases.length) {
|
|
337
|
+
return;
|
|
338
|
+
}
|
|
339
|
+
const nextPhase = applicablePhases[nextIdx];
|
|
340
|
+
if (nextPhase.name !== 'deployment') {
|
|
341
|
+
return;
|
|
342
|
+
}
|
|
343
|
+
// Target is deployment — verify all preceding required phases (except current) are complete
|
|
344
|
+
for (let i = 0; i < currentIdx; i++) {
|
|
345
|
+
const phase = applicablePhases[i];
|
|
346
|
+
const ps = phaseStates.get(phase.name);
|
|
347
|
+
if (!ps || (ps.status !== 'complete' && ps.status !== 'skipped')) {
|
|
348
|
+
const status = ps ? ps.status : 'pending';
|
|
349
|
+
violations.push({
|
|
350
|
+
gate: 'deployment-entry',
|
|
351
|
+
reason: `phase "${phase.name}" must be complete before entering deployment (status: ${status})`,
|
|
352
|
+
});
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
//# sourceMappingURL=lifecycle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lifecycle.js","sourceRoot":"","sources":["../../src/core/lifecycle.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Template resolution — inheritance, cycle-scope phase applicability.
|
|
3
|
+
*
|
|
4
|
+
* - `resolveTemplate()` applies the full inheritance chain (remove/override/add).
|
|
5
|
+
* - `loadTemplates()` loads all template YAML files from a directory.
|
|
6
|
+
* - `phasesForScope()` filters phases by cycle scope.
|
|
7
|
+
*
|
|
8
|
+
* Requirements: 8.1, 8.5, 5.1, 5.2
|
|
9
|
+
*/
|
|
10
|
+
import type { WorkflowTemplate, TemplatePhase, CycleScope } from './types.js';
|
|
11
|
+
/**
|
|
12
|
+
* Error thrown when template resolution encounters a problem
|
|
13
|
+
* (cycle, missing parent, invalid insertion point).
|
|
14
|
+
*/
|
|
15
|
+
export declare class TemplateResolutionError extends Error {
|
|
16
|
+
constructor(message: string);
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Get the applicable phases for a given cycle scope.
|
|
20
|
+
*
|
|
21
|
+
* Filters the resolved template's phases to include only those whose name
|
|
22
|
+
* appears in the scope's allowed phase set. Custom (non-core) phase names
|
|
23
|
+
* pass through for all scopes (they are never filtered out by scope rules).
|
|
24
|
+
*
|
|
25
|
+
* @param resolvedTemplate - A fully resolved template (no `extends`).
|
|
26
|
+
* @param scope - The cycle scope to filter by.
|
|
27
|
+
* @returns The subset of template phases applicable to the given scope.
|
|
28
|
+
*/
|
|
29
|
+
export declare function phasesForScope(resolvedTemplate: WorkflowTemplate, scope: CycleScope): TemplatePhase[];
|
|
30
|
+
/**
|
|
31
|
+
* Resolve a template by applying its inheritance chain.
|
|
32
|
+
*
|
|
33
|
+
* Resolution algorithm:
|
|
34
|
+
* 1. If no `extends` → template is already resolved (return a copy with
|
|
35
|
+
* inheritance fields cleared).
|
|
36
|
+
* 2. Load parent template, resolve it recursively (cycle-detected).
|
|
37
|
+
* 3. Start with parent's resolved phases.
|
|
38
|
+
* 4. Apply `remove`: filter out listed phases.
|
|
39
|
+
* 5. Apply `override`: for each phase name in override map, merge fields.
|
|
40
|
+
* 6. Apply `add`: insert new phases at declared positions (before/after).
|
|
41
|
+
*
|
|
42
|
+
* @param template - The template to resolve.
|
|
43
|
+
* @param allTemplates - Map of all available templates by name.
|
|
44
|
+
* @returns A fully resolved WorkflowTemplate (no `extends`, all phases concrete).
|
|
45
|
+
* @throws {TemplateResolutionError} On circular inheritance or missing parent.
|
|
46
|
+
*/
|
|
47
|
+
export declare function resolveTemplate(template: WorkflowTemplate, allTemplates: Map<string, WorkflowTemplate>): WorkflowTemplate;
|
|
48
|
+
/**
|
|
49
|
+
* Load all templates from a directory. Each `.yaml` or `.yml` file is parsed
|
|
50
|
+
* as a WorkflowTemplate. Invalid files are skipped with a warning to stderr.
|
|
51
|
+
*
|
|
52
|
+
* @param templateDir - Path to the directory containing template YAML files.
|
|
53
|
+
* @returns A Map of template name → WorkflowTemplate.
|
|
54
|
+
*/
|
|
55
|
+
export declare function loadTemplates(templateDir: string): Map<string, WorkflowTemplate>;
|
|
56
|
+
//# sourceMappingURL=template-resolver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"template-resolver.d.ts","sourceRoot":"","sources":["../../src/core/template-resolver.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAKH,OAAO,KAAK,EACV,gBAAgB,EAChB,aAAa,EAGb,UAAU,EAEX,MAAM,YAAY,CAAC;AAMpB;;;GAGG;AACH,qBAAa,uBAAwB,SAAQ,KAAK;gBACpC,OAAO,EAAE,MAAM;CAI5B;AAwBD;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAC5B,gBAAgB,EAAE,gBAAgB,EAClC,KAAK,EAAE,UAAU,GAChB,aAAa,EAAE,CAUjB;AAMD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,gBAAgB,EAC1B,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,gBAAgB,CAAC,GAC1C,gBAAgB,CAElB;AA6ID;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,gBAAgB,CAAC,CA+BhF"}
|