@lumenflow/initiatives 4.20.2 → 4.22.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.
@@ -17,13 +17,15 @@
17
17
  * @see {@link packages/@lumenflow/cli/src/lib/initiative-yaml.ts} - Initiative loading
18
18
  * @see {@link packages/@lumenflow/cli/src/lib/dependency-graph.ts} - Dependency graph utilities
19
19
  */
20
- export type { CheckpointOptions, CheckpointModeResult, AutoCheckpointResult, SkippedWUEntry, DeferredWUEntry, ExecutionPlan, ProgressStats, BottleneckWU, WaveManifestWU, WaveManifest, CheckpointWaveResult, DependencyFilterResult, LockPolicy, LaneConfig, LockPolicyOptions, LaneAvailabilityResult, } from './orchestrator/types.js';
20
+ export type { CheckpointOptions, CheckpointModeResult, AutoCheckpointResult, SkippedWUEntry, DeferredWUEntry, ExecutionPlan, ProgressStats, BottleneckWU, WaveManifestWU, WaveManifest, CheckpointWaveResult, DependencyFilterResult, LockPolicy, LaneConfig, LockPolicyOptions, LaneAvailabilityResult, HandoffFormat, HandoffReceipt, OrchestrationArtifactBundle, OrchestrationExecutionState, OrchestrationActionType, WuExecutionEvidence, OrchestrationNextAction, ReconciledInitiativeWU, InitiativeExecutionSummary, } from './orchestrator/types.js';
21
21
  export { LOG_PREFIX } from './orchestrator/shared.js';
22
22
  export { buildExecutionPlan, buildExecutionPlanAsync, buildExecutionPlanWithLockPolicy, } from './orchestrator/execution-planning.js';
23
23
  export { CHECKPOINT_AUTO_THRESHOLDS, filterByDependencyStamps, shouldAutoEnableCheckpoint, shouldAutoEnableCheckpointAsync, resolveCheckpointMode, resolveCheckpointModeAsync, validateCheckpointFlags, buildCheckpointWave, } from './orchestrator/checkpoint.js';
24
+ export { isXmlCapableClient, renderHandoffArtifact, writeCheckpointArtifacts, writeExecutionPlanArtifacts, } from './orchestrator/artifacts.js';
24
25
  export { formatExecutionPlan, generateSpawnCommands, calculateProgress, formatProgress, getBottleneckWUs, formatCheckpointOutput, generateEmbeddedSpawnPrompt, formatTaskInvocationWithEmbeddedSpawn, formatExecutionPlanWithEmbeddedSpawns, } from './orchestrator/formatting.js';
25
26
  export { getManifestWUStatus, isWUActuallySpawned, getSpawnCandidatesWithYAMLCheck, } from './orchestrator/spawn-status.js';
26
27
  export { getLockPolicyForLane, getLaneAvailability } from './orchestrator/lane-policy.js';
28
+ export { reconcileInitiativeExecution } from './orchestrator/reconciliation.js';
27
29
  export { loadInitiativeWUs, loadMultipleInitiatives } from './orchestrator/initiative-loading.js';
28
30
  export { analyseScopeShape, formatScopeAdvisory, SCOPE_ADVISORY_THRESHOLDS, type ScopeAdvisory, type ScopeAdvisoryResult, type ScopeAdvisoryType, type ScopeAdvisorySeverity, } from './orchestrator/scope-advisory.js';
29
31
  //# sourceMappingURL=initiative-orchestrator.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"initiative-orchestrator.d.ts","sourceRoot":"","sources":["../src/initiative-orchestrator.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;;;GAkBG;AAGH,YAAY,EACV,iBAAiB,EACjB,oBAAoB,EACpB,oBAAoB,EACpB,cAAc,EACd,eAAe,EACf,aAAa,EACb,aAAa,EACb,YAAY,EACZ,cAAc,EACd,YAAY,EACZ,oBAAoB,EACpB,sBAAsB,EACtB,UAAU,EACV,UAAU,EACV,iBAAiB,EACjB,sBAAsB,GACvB,MAAM,yBAAyB,CAAC;AAGjC,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAGtD,OAAO,EACL,kBAAkB,EAClB,uBAAuB,EACvB,gCAAgC,GACjC,MAAM,sCAAsC,CAAC;AAG9C,OAAO,EACL,0BAA0B,EAC1B,wBAAwB,EACxB,0BAA0B,EAC1B,+BAA+B,EAC/B,qBAAqB,EACrB,0BAA0B,EAC1B,uBAAuB,EACvB,mBAAmB,GACpB,MAAM,8BAA8B,CAAC;AAGtC,OAAO,EACL,mBAAmB,EACnB,qBAAqB,EACrB,iBAAiB,EACjB,cAAc,EACd,gBAAgB,EAChB,sBAAsB,EACtB,2BAA2B,EAC3B,qCAAqC,EACrC,qCAAqC,GACtC,MAAM,8BAA8B,CAAC;AAGtC,OAAO,EACL,mBAAmB,EACnB,mBAAmB,EACnB,+BAA+B,GAChC,MAAM,gCAAgC,CAAC;AAGxC,OAAO,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AAG1F,OAAO,EAAE,iBAAiB,EAAE,uBAAuB,EAAE,MAAM,sCAAsC,CAAC;AAGlG,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,yBAAyB,EACzB,KAAK,aAAa,EAClB,KAAK,mBAAmB,EACxB,KAAK,iBAAiB,EACtB,KAAK,qBAAqB,GAC3B,MAAM,kCAAkC,CAAC"}
1
+ {"version":3,"file":"initiative-orchestrator.d.ts","sourceRoot":"","sources":["../src/initiative-orchestrator.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;;;GAkBG;AAGH,YAAY,EACV,iBAAiB,EACjB,oBAAoB,EACpB,oBAAoB,EACpB,cAAc,EACd,eAAe,EACf,aAAa,EACb,aAAa,EACb,YAAY,EACZ,cAAc,EACd,YAAY,EACZ,oBAAoB,EACpB,sBAAsB,EACtB,UAAU,EACV,UAAU,EACV,iBAAiB,EACjB,sBAAsB,EACtB,aAAa,EACb,cAAc,EACd,2BAA2B,EAC3B,2BAA2B,EAC3B,uBAAuB,EACvB,mBAAmB,EACnB,uBAAuB,EACvB,sBAAsB,EACtB,0BAA0B,GAC3B,MAAM,yBAAyB,CAAC;AAGjC,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAGtD,OAAO,EACL,kBAAkB,EAClB,uBAAuB,EACvB,gCAAgC,GACjC,MAAM,sCAAsC,CAAC;AAG9C,OAAO,EACL,0BAA0B,EAC1B,wBAAwB,EACxB,0BAA0B,EAC1B,+BAA+B,EAC/B,qBAAqB,EACrB,0BAA0B,EAC1B,uBAAuB,EACvB,mBAAmB,GACpB,MAAM,8BAA8B,CAAC;AAGtC,OAAO,EACL,kBAAkB,EAClB,qBAAqB,EACrB,wBAAwB,EACxB,2BAA2B,GAC5B,MAAM,6BAA6B,CAAC;AAGrC,OAAO,EACL,mBAAmB,EACnB,qBAAqB,EACrB,iBAAiB,EACjB,cAAc,EACd,gBAAgB,EAChB,sBAAsB,EACtB,2BAA2B,EAC3B,qCAAqC,EACrC,qCAAqC,GACtC,MAAM,8BAA8B,CAAC;AAGtC,OAAO,EACL,mBAAmB,EACnB,mBAAmB,EACnB,+BAA+B,GAChC,MAAM,gCAAgC,CAAC;AAGxC,OAAO,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AAG1F,OAAO,EAAE,4BAA4B,EAAE,MAAM,kCAAkC,CAAC;AAGhF,OAAO,EAAE,iBAAiB,EAAE,uBAAuB,EAAE,MAAM,sCAAsC,CAAC;AAGlG,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,yBAAyB,EACzB,KAAK,aAAa,EAClB,KAAK,mBAAmB,EACxB,KAAK,iBAAiB,EACtB,KAAK,qBAAqB,GAC3B,MAAM,kCAAkC,CAAC"}
@@ -6,12 +6,16 @@ export { LOG_PREFIX } from './orchestrator/shared.js';
6
6
  export { buildExecutionPlan, buildExecutionPlanAsync, buildExecutionPlanWithLockPolicy, } from './orchestrator/execution-planning.js';
7
7
  // ── Checkpoint ────────────────────────────────────────────────────────────────
8
8
  export { CHECKPOINT_AUTO_THRESHOLDS, filterByDependencyStamps, shouldAutoEnableCheckpoint, shouldAutoEnableCheckpointAsync, resolveCheckpointMode, resolveCheckpointModeAsync, validateCheckpointFlags, buildCheckpointWave, } from './orchestrator/checkpoint.js';
9
+ // ── Durable artifacts ────────────────────────────────────────────────────────
10
+ export { isXmlCapableClient, renderHandoffArtifact, writeCheckpointArtifacts, writeExecutionPlanArtifacts, } from './orchestrator/artifacts.js';
9
11
  // ── Formatting ────────────────────────────────────────────────────────────────
10
12
  export { formatExecutionPlan, generateSpawnCommands, calculateProgress, formatProgress, getBottleneckWUs, formatCheckpointOutput, generateEmbeddedSpawnPrompt, formatTaskInvocationWithEmbeddedSpawn, formatExecutionPlanWithEmbeddedSpawns, } from './orchestrator/formatting.js';
11
13
  // ── Spawn status ──────────────────────────────────────────────────────────────
12
14
  export { getManifestWUStatus, isWUActuallySpawned, getSpawnCandidatesWithYAMLCheck, } from './orchestrator/spawn-status.js';
13
15
  // ── Lane policy ───────────────────────────────────────────────────────────────
14
16
  export { getLockPolicyForLane, getLaneAvailability } from './orchestrator/lane-policy.js';
17
+ // ── Reconciliation / advancement ─────────────────────────────────────────────
18
+ export { reconcileInitiativeExecution } from './orchestrator/reconciliation.js';
15
19
  // ── Initiative loading ────────────────────────────────────────────────────────
16
20
  export { loadInitiativeWUs, loadMultipleInitiatives } from './orchestrator/initiative-loading.js';
17
21
  // ── Scope advisory (WU-2142/WU-2155) ────────────────────────────────────────
@@ -1 +1 @@
1
- {"version":3,"file":"initiative-orchestrator.js","sourceRoot":"","sources":["../src/initiative-orchestrator.ts"],"names":[],"mappings":"AAAA,iCAAiC;AACjC,yCAAyC;AA0CzC,iFAAiF;AACjF,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAEtD,iFAAiF;AACjF,OAAO,EACL,kBAAkB,EAClB,uBAAuB,EACvB,gCAAgC,GACjC,MAAM,sCAAsC,CAAC;AAE9C,iFAAiF;AACjF,OAAO,EACL,0BAA0B,EAC1B,wBAAwB,EACxB,0BAA0B,EAC1B,+BAA+B,EAC/B,qBAAqB,EACrB,0BAA0B,EAC1B,uBAAuB,EACvB,mBAAmB,GACpB,MAAM,8BAA8B,CAAC;AAEtC,iFAAiF;AACjF,OAAO,EACL,mBAAmB,EACnB,qBAAqB,EACrB,iBAAiB,EACjB,cAAc,EACd,gBAAgB,EAChB,sBAAsB,EACtB,2BAA2B,EAC3B,qCAAqC,EACrC,qCAAqC,GACtC,MAAM,8BAA8B,CAAC;AAEtC,iFAAiF;AACjF,OAAO,EACL,mBAAmB,EACnB,mBAAmB,EACnB,+BAA+B,GAChC,MAAM,gCAAgC,CAAC;AAExC,iFAAiF;AACjF,OAAO,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AAE1F,iFAAiF;AACjF,OAAO,EAAE,iBAAiB,EAAE,uBAAuB,EAAE,MAAM,sCAAsC,CAAC;AAElG,+EAA+E;AAC/E,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,yBAAyB,GAK1B,MAAM,kCAAkC,CAAC"}
1
+ {"version":3,"file":"initiative-orchestrator.js","sourceRoot":"","sources":["../src/initiative-orchestrator.ts"],"names":[],"mappings":"AAAA,iCAAiC;AACjC,yCAAyC;AAmDzC,iFAAiF;AACjF,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAEtD,iFAAiF;AACjF,OAAO,EACL,kBAAkB,EAClB,uBAAuB,EACvB,gCAAgC,GACjC,MAAM,sCAAsC,CAAC;AAE9C,iFAAiF;AACjF,OAAO,EACL,0BAA0B,EAC1B,wBAAwB,EACxB,0BAA0B,EAC1B,+BAA+B,EAC/B,qBAAqB,EACrB,0BAA0B,EAC1B,uBAAuB,EACvB,mBAAmB,GACpB,MAAM,8BAA8B,CAAC;AAEtC,gFAAgF;AAChF,OAAO,EACL,kBAAkB,EAClB,qBAAqB,EACrB,wBAAwB,EACxB,2BAA2B,GAC5B,MAAM,6BAA6B,CAAC;AAErC,iFAAiF;AACjF,OAAO,EACL,mBAAmB,EACnB,qBAAqB,EACrB,iBAAiB,EACjB,cAAc,EACd,gBAAgB,EAChB,sBAAsB,EACtB,2BAA2B,EAC3B,qCAAqC,EACrC,qCAAqC,GACtC,MAAM,8BAA8B,CAAC;AAEtC,iFAAiF;AACjF,OAAO,EACL,mBAAmB,EACnB,mBAAmB,EACnB,+BAA+B,GAChC,MAAM,gCAAgC,CAAC;AAExC,iFAAiF;AACjF,OAAO,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AAE1F,gFAAgF;AAChF,OAAO,EAAE,4BAA4B,EAAE,MAAM,kCAAkC,CAAC;AAEhF,iFAAiF;AACjF,OAAO,EAAE,iBAAiB,EAAE,uBAAuB,EAAE,MAAM,sCAAsC,CAAC;AAElG,+EAA+E;AAC/E,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,yBAAyB,GAK1B,MAAM,kCAAkC,CAAC"}
@@ -0,0 +1,17 @@
1
+ import type { WUEntry } from '../initiative-yaml.js';
2
+ import type { CheckpointOptions, ExecutionPlan, HandoffFormat, OrchestrationArtifactBundle } from './types.js';
3
+ interface RenderedHandoffArtifact {
4
+ content: string;
5
+ extension: string;
6
+ format: HandoffFormat;
7
+ }
8
+ interface HandoffWU {
9
+ id: string;
10
+ doc: WUEntry['doc'];
11
+ }
12
+ export declare function isXmlCapableClient(clientName?: string): boolean;
13
+ export declare function renderHandoffArtifact(wu: HandoffWU, clientName?: string): RenderedHandoffArtifact;
14
+ export declare function writeExecutionPlanArtifacts(initId: string, allWUs: WUEntry[], plan: ExecutionPlan, options?: CheckpointOptions): OrchestrationArtifactBundle;
15
+ export declare function writeCheckpointArtifacts(initId: string, allWUs: WUEntry[], selectedWUs: WUEntry[], options?: CheckpointOptions): OrchestrationArtifactBundle;
16
+ export {};
17
+ //# sourceMappingURL=artifacts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"artifacts.d.ts","sourceRoot":"","sources":["../../src/orchestrator/artifacts.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,KAAK,EACV,iBAAiB,EACjB,aAAa,EACb,aAAa,EAEb,2BAA2B,EAC5B,MAAM,YAAY,CAAC;AAgBpB,UAAU,uBAAuB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,aAAa,CAAC;CACvB;AAOD,UAAU,SAAS;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;CACrB;AAQD,wBAAgB,kBAAkB,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAE/D;AAED,wBAAgB,qBAAqB,CAAC,EAAE,EAAE,SAAS,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,uBAAuB,CAiBjG;AAED,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,OAAO,EAAE,EACjB,IAAI,EAAE,aAAa,EACnB,OAAO,GAAE,iBAAsB,GAC9B,2BAA2B,CAG7B;AAED,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,OAAO,EAAE,EACjB,WAAW,EAAE,OAAO,EAAE,EACtB,OAAO,GAAE,iBAAsB,GAC9B,2BAA2B,CAO7B"}
@@ -0,0 +1,248 @@
1
+ // Copyright (c) 2026 Hellmai Ltd
2
+ // SPDX-License-Identifier: AGPL-3.0-only
3
+ /**
4
+ * Durable artifact writing for initiative orchestration.
5
+ *
6
+ * WU-2617: Persist plan/launch/status artifacts and per-WU handoff receipts so
7
+ * orchestration can distinguish dependency waves from repeated launch attempts.
8
+ *
9
+ * @module orchestrator/artifacts
10
+ */
11
+ import { existsSync, mkdirSync, readdirSync, writeFileSync } from 'node:fs';
12
+ import { join } from 'node:path';
13
+ import { getAllDependencies, ORCHESTRATION_ARTIFACT_DIR, WAVE_MANIFEST_DIR } from './shared.js';
14
+ import { generateCodexPrompt, generateTaskInvocation } from '@lumenflow/core/wu-spawn';
15
+ import { SpawnStrategyFactory } from '@lumenflow/core/spawn-strategy';
16
+ const XML_CAPABLE_CLIENTS = new Set(['claude-code', 'claude']);
17
+ const ATTEMPT_PREFIX = 'attempt-';
18
+ const HANDOFFS_DIRNAME = 'handoffs';
19
+ const PLAN_FILENAME = 'plan.json';
20
+ const LAUNCH_FILENAME = 'launch.json';
21
+ const STATUS_FILENAME = 'status.json';
22
+ const MARKDOWN_EXTENSION = 'md';
23
+ const XML_EXTENSION = 'xml';
24
+ const FALLBACK_LOGICAL_WAVE = 0;
25
+ const FALLBACK_ATTEMPT = -1;
26
+ export function isXmlCapableClient(clientName) {
27
+ return clientName !== undefined && XML_CAPABLE_CLIENTS.has(clientName.toLowerCase());
28
+ }
29
+ export function renderHandoffArtifact(wu, clientName) {
30
+ const resolvedClient = clientName || 'generic';
31
+ const strategy = SpawnStrategyFactory.create(resolvedClient);
32
+ if (isXmlCapableClient(resolvedClient)) {
33
+ return {
34
+ content: generateTaskInvocation(wu.doc, wu.id, strategy),
35
+ extension: XML_EXTENSION,
36
+ format: 'xml',
37
+ };
38
+ }
39
+ return {
40
+ content: generateCodexPrompt(wu.doc, wu.id, strategy),
41
+ extension: MARKDOWN_EXTENSION,
42
+ format: 'markdown',
43
+ };
44
+ }
45
+ export function writeExecutionPlanArtifacts(initId, allWUs, plan, options = {}) {
46
+ const waveGroups = plan.waves.map((wus, plannedWave) => ({ plannedWave, wus }));
47
+ return writeOrchestrationAttemptArtifacts(initId, allWUs, waveGroups, options);
48
+ }
49
+ export function writeCheckpointArtifacts(initId, allWUs, selectedWUs, options = {}) {
50
+ return writeOrchestrationAttemptArtifacts(initId, allWUs, [{ plannedWave: 0, wus: selectedWUs }], options);
51
+ }
52
+ function writeOrchestrationAttemptArtifacts(initId, allWUs, waveGroups, options = {}) {
53
+ const { clientName, dryRun = false } = options;
54
+ const executionSummary = options.executionSummary;
55
+ const launchAttempt = getNextLaunchAttempt(initId);
56
+ const artifactDir = join(ORCHESTRATION_ARTIFACT_DIR, initId, `${ATTEMPT_PREFIX}${launchAttempt}`);
57
+ const planPath = join(artifactDir, PLAN_FILENAME);
58
+ const launchPath = join(artifactDir, LAUNCH_FILENAME);
59
+ const statusPath = join(artifactDir, STATUS_FILENAME);
60
+ const handoffDir = join(artifactDir, HANDOFFS_DIRNAME);
61
+ const createdAt = new Date().toISOString();
62
+ const logicalWaveMap = calculateLogicalWaveMap(allWUs);
63
+ const launchableWUs = flattenWaveGroups(waveGroups, logicalWaveMap);
64
+ const logicalWaves = Array.from(new Set(launchableWUs.map((entry) => entry.logicalWave))).sort((left, right) => left - right);
65
+ const handoffReceipts = launchableWUs.map((entry) => createHandoffReceipt(entry, launchAttempt, handoffDir, clientName, createdAt, dryRun));
66
+ if (!dryRun) {
67
+ mkdirSync(handoffDir, { recursive: true });
68
+ for (let index = 0; index < handoffReceipts.length; index++) {
69
+ const receipt = handoffReceipts[index];
70
+ const launchableWU = launchableWUs[index];
71
+ const rendered = renderHandoffArtifact(launchableWU.wu, clientName);
72
+ writeFileSync(receipt.handoff_artifact_path, rendered.content, 'utf8');
73
+ }
74
+ const planData = {
75
+ initiative: initId,
76
+ created_at: createdAt,
77
+ launch_attempt: launchAttempt,
78
+ logical_waves: logicalWaves,
79
+ waves: waveGroups.map((group) => {
80
+ const groupEntries = launchableWUs.filter((entry) => entry.plannedWave === group.plannedWave);
81
+ const groupLogicalWaves = Array.from(new Set(groupEntries.map((entry) => entry.logicalWave))).sort((left, right) => left - right);
82
+ return {
83
+ planned_wave: group.plannedWave,
84
+ logical_wave: groupLogicalWaves[0] ?? FALLBACK_LOGICAL_WAVE,
85
+ logical_waves: groupLogicalWaves,
86
+ wus: groupEntries.map((entry) => ({
87
+ id: entry.wu.id,
88
+ lane: entry.wu.doc.lane,
89
+ logical_wave: entry.logicalWave,
90
+ })),
91
+ };
92
+ }),
93
+ };
94
+ const launchData = {
95
+ initiative: initId,
96
+ created_at: createdAt,
97
+ launch_attempt: launchAttempt,
98
+ logical_waves: logicalWaves,
99
+ handoffs: handoffReceipts,
100
+ };
101
+ const statusData = {
102
+ initiative: initId,
103
+ created_at: createdAt,
104
+ launch_attempt: launchAttempt,
105
+ logical_waves: logicalWaves,
106
+ actual_launch_confirmed: false,
107
+ treat_handoff_as_completed: false,
108
+ available_capacity: executionSummary?.availableCapacity ?? null,
109
+ max_active_workers: executionSummary?.maxActiveWorkers ?? null,
110
+ blocked_by_integrity: executionSummary?.blockedByIntegrity ?? false,
111
+ next_safe_actions: executionSummary?.nextSafeActions.map((action) => ({
112
+ type: action.type,
113
+ wu_id: action.wuId,
114
+ reason: action.reason,
115
+ logical_wave: action.logicalWave,
116
+ })) ?? [],
117
+ wus: allWUs.map((wu) => {
118
+ const summaryEntry = executionSummary?.wus.find((entry) => entry.wuId === wu.id);
119
+ const launchableEntry = launchableWUs.find((entry) => entry.wu.id === wu.id);
120
+ const handoffState = handoffReceipts.find((receipt) => receipt.wu_id === wu.id);
121
+ return {
122
+ wu_id: wu.id,
123
+ lane: wu.doc.lane,
124
+ logical_wave: summaryEntry?.logicalWave ?? launchableEntry?.logicalWave ?? FALLBACK_LOGICAL_WAVE,
125
+ orchestration_state: launchableEntry || handoffState ? 'handoff_emitted' : (summaryEntry?.state ?? 'ready'),
126
+ yaml_status: wu.doc.status ?? 'unknown',
127
+ };
128
+ }),
129
+ };
130
+ writeFileSync(planPath, JSON.stringify(planData, null, 2), 'utf8');
131
+ writeFileSync(launchPath, JSON.stringify(launchData, null, 2), 'utf8');
132
+ writeFileSync(statusPath, JSON.stringify(statusData, null, 2), 'utf8');
133
+ }
134
+ return {
135
+ artifactDir,
136
+ planPath,
137
+ launchPath,
138
+ statusPath,
139
+ logicalWaves,
140
+ launchAttempt,
141
+ handoffReceipts,
142
+ };
143
+ }
144
+ function flattenWaveGroups(waveGroups, logicalWaveMap) {
145
+ return waveGroups.flatMap((group) => group.wus.map((wu) => ({
146
+ logicalWave: logicalWaveMap.get(wu.id) ?? FALLBACK_LOGICAL_WAVE,
147
+ plannedWave: group.plannedWave,
148
+ wu,
149
+ })));
150
+ }
151
+ function createHandoffReceipt(entry, launchAttempt, handoffDir, clientName, emittedAt, dryRun) {
152
+ const rendered = renderHandoffArtifact(entry.wu, clientName);
153
+ const handoffArtifactPath = join(handoffDir, `${entry.wu.id}.${rendered.extension}`);
154
+ if (!dryRun && !existsSync(handoffDir)) {
155
+ mkdirSync(handoffDir, { recursive: true });
156
+ }
157
+ return {
158
+ wu_id: entry.wu.id,
159
+ lane: entry.wu.doc.lane,
160
+ logical_wave: entry.logicalWave,
161
+ launch_attempt: launchAttempt,
162
+ handoff_artifact_path: handoffArtifactPath,
163
+ handoff_format: rendered.format,
164
+ orchestration_state: 'handoff_emitted',
165
+ emitted_at: emittedAt,
166
+ };
167
+ }
168
+ function calculateLogicalWaveMap(wus) {
169
+ const logicalWaveMap = new Map();
170
+ const allWuIds = new Set(wus.map((wu) => wu.id));
171
+ const adjacency = new Map();
172
+ const inDegree = new Map();
173
+ for (const wu of wus) {
174
+ adjacency.set(wu.id, []);
175
+ inDegree.set(wu.id, 0);
176
+ }
177
+ for (const wu of wus) {
178
+ const internalDeps = getAllDependencies(wu.doc).filter((depId) => allWuIds.has(depId));
179
+ inDegree.set(wu.id, internalDeps.length);
180
+ for (const depId of internalDeps) {
181
+ const dependants = adjacency.get(depId);
182
+ if (dependants) {
183
+ dependants.push(wu.id);
184
+ }
185
+ }
186
+ }
187
+ const queue = Array.from(inDegree.entries())
188
+ .filter(([, degree]) => degree === 0)
189
+ .map(([wuId]) => wuId)
190
+ .sort();
191
+ for (const wuId of queue) {
192
+ logicalWaveMap.set(wuId, FALLBACK_LOGICAL_WAVE);
193
+ }
194
+ while (queue.length > 0) {
195
+ const currentId = queue.shift();
196
+ if (!currentId) {
197
+ continue;
198
+ }
199
+ const currentWave = logicalWaveMap.get(currentId) ?? FALLBACK_LOGICAL_WAVE;
200
+ const dependants = adjacency.get(currentId) ?? [];
201
+ for (const dependantId of dependants) {
202
+ const nextWave = currentWave + 1;
203
+ logicalWaveMap.set(dependantId, Math.max(logicalWaveMap.get(dependantId) ?? 0, nextWave));
204
+ const remainingDegree = (inDegree.get(dependantId) ?? 1) - 1;
205
+ inDegree.set(dependantId, remainingDegree);
206
+ if (remainingDegree === 0) {
207
+ queue.push(dependantId);
208
+ queue.sort();
209
+ }
210
+ }
211
+ }
212
+ for (const wu of wus) {
213
+ if (!logicalWaveMap.has(wu.id)) {
214
+ logicalWaveMap.set(wu.id, FALLBACK_LOGICAL_WAVE);
215
+ }
216
+ }
217
+ return logicalWaveMap;
218
+ }
219
+ function getNextLaunchAttempt(initId) {
220
+ const attemptDirsPath = join(ORCHESTRATION_ARTIFACT_DIR, initId);
221
+ const legacyPattern = new RegExp(`^${initId}-wave-(\\d+)\\.json$`);
222
+ let maxAttempt = FALLBACK_ATTEMPT;
223
+ if (existsSync(attemptDirsPath)) {
224
+ for (const entry of readdirSync(attemptDirsPath, { withFileTypes: true })) {
225
+ if (!entry.isDirectory() || !entry.name.startsWith(ATTEMPT_PREFIX)) {
226
+ continue;
227
+ }
228
+ const parsed = Number.parseInt(entry.name.slice(ATTEMPT_PREFIX.length), 10);
229
+ if (!Number.isNaN(parsed)) {
230
+ maxAttempt = Math.max(maxAttempt, parsed);
231
+ }
232
+ }
233
+ }
234
+ if (existsSync(WAVE_MANIFEST_DIR)) {
235
+ for (const file of readdirSync(WAVE_MANIFEST_DIR)) {
236
+ const match = file.match(legacyPattern);
237
+ if (!match) {
238
+ continue;
239
+ }
240
+ const parsed = Number.parseInt(match[1] ?? '', 10);
241
+ if (!Number.isNaN(parsed)) {
242
+ maxAttempt = Math.max(maxAttempt, parsed);
243
+ }
244
+ }
245
+ }
246
+ return maxAttempt + 1;
247
+ }
248
+ //# sourceMappingURL=artifacts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"artifacts.js","sourceRoot":"","sources":["../../src/orchestrator/artifacts.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"checkpoint.d.ts","sourceRoot":"","sources":["../../src/orchestrator/checkpoint.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAErD,OAAO,KAAK,EACV,iBAAiB,EACjB,oBAAoB,EACpB,oBAAoB,EACpB,oBAAoB,EAEpB,sBAAsB,EACvB,MAAM,YAAY,CAAC;AAWpB;;;;;;;GAOG;AACH,eAAO,MAAM,0BAA0B;IACrC,6EAA6E;;IAE7E,uEAAuE;;CAExE,CAAC;AAEF;;;;;;;;;GASG;AACH,wBAAgB,wBAAwB,CAAC,UAAU,EAAE,OAAO,EAAE,GAAG,sBAAsB,CAqCtF;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,0BAA0B,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,oBAAoB,CA6C/E;AAED;;;;;GAKG;AACH,wBAAsB,+BAA+B,CACnD,GAAG,EAAE,OAAO,EAAE,GACb,OAAO,CAAC,oBAAoB,CAAC,CA6C/B;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,iBAAiB,EAC1B,GAAG,EAAE,OAAO,EAAE,GACb,oBAAoB,CAqCtB;AAED;;;;;;GAMG;AACH,wBAAsB,0BAA0B,CAC9C,OAAO,EAAE,iBAAiB,EAC1B,GAAG,EAAE,OAAO,EAAE,GACb,OAAO,CAAC,oBAAoB,CAAC,CAqC/B;AAED;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,iBAAiB,GAAG,IAAI,CAmBxE;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,iBAAsB,GAC9B,oBAAoB,GAAG,IAAI,CA2F7B"}
1
+ {"version":3,"file":"checkpoint.d.ts","sourceRoot":"","sources":["../../src/orchestrator/checkpoint.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAErD,OAAO,KAAK,EACV,iBAAiB,EACjB,oBAAoB,EACpB,oBAAoB,EACpB,oBAAoB,EAEpB,sBAAsB,EACvB,MAAM,YAAY,CAAC;AAapB;;;;;;;GAOG;AACH,eAAO,MAAM,0BAA0B;IACrC,6EAA6E;;IAE7E,uEAAuE;;CAExE,CAAC;AAEF;;;;;;;;;GASG;AACH,wBAAgB,wBAAwB,CAAC,UAAU,EAAE,OAAO,EAAE,GAAG,sBAAsB,CAqCtF;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,0BAA0B,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,oBAAoB,CA6C/E;AAED;;;;;GAKG;AACH,wBAAsB,+BAA+B,CACnD,GAAG,EAAE,OAAO,EAAE,GACb,OAAO,CAAC,oBAAoB,CAAC,CA6C/B;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,iBAAiB,EAC1B,GAAG,EAAE,OAAO,EAAE,GACb,oBAAoB,CAqCtB;AAED;;;;;;GAMG;AACH,wBAAsB,0BAA0B,CAC9C,OAAO,EAAE,iBAAiB,EAC1B,GAAG,EAAE,OAAO,EAAE,GACb,OAAO,CAAC,oBAAoB,CAAC,CAqC/B;AAED;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,iBAAiB,GAAG,IAAI,CAmBxE;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,iBAAsB,GAC9B,oBAAoB,GAAG,IAAI,CAoP7B"}
@@ -13,6 +13,8 @@ import { join } from 'node:path';
13
13
  import { findInitiative, getInitiativeWUs } from '../initiative-yaml.js';
14
14
  import { WAVE_MANIFEST_DIR, hasStamp, getAllDependencies } from './shared.js';
15
15
  import { buildExecutionPlan, buildExecutionPlanAsync } from './execution-planning.js';
16
+ import { writeCheckpointArtifacts } from './artifacts.js';
17
+ import { reconcileInitiativeExecution } from './reconciliation.js';
16
18
  import { createError, ErrorCodes } from '@lumenflow/core/error-handler';
17
19
  import { WU_STATUS } from '@lumenflow/core/wu-constants';
18
20
  /**
@@ -302,7 +304,7 @@ export function validateCheckpointFlags(options) {
302
304
  * Wave data or null if all WUs complete
303
305
  */
304
306
  export function buildCheckpointWave(initRef, options = {}) {
305
- const { dryRun = false } = options;
307
+ const { dryRun = false, clientName, executionEvidence = [], maxActiveWorkers, blockOnIntegrity = true, } = options;
306
308
  // Load initiative and WUs
307
309
  const initData = findInitiative(initRef);
308
310
  if (!initData) {
@@ -310,6 +312,18 @@ export function buildCheckpointWave(initRef, options = {}) {
310
312
  }
311
313
  const initId = initData.id;
312
314
  const wus = getInitiativeWUs(initRef);
315
+ const stampAwareEvidence = wus.map((wu) => {
316
+ const existing = executionEvidence.find((entry) => entry.wuId === wu.id);
317
+ return {
318
+ wuId: wu.id,
319
+ stampPresent: hasStamp(wu.id),
320
+ ...existing,
321
+ };
322
+ });
323
+ const executionSummary = reconcileInitiativeExecution(wus, stampAwareEvidence, {
324
+ maxActiveWorkers,
325
+ blockOnIntegrity,
326
+ });
313
327
  // Filter to spawn candidates:
314
328
  // 1. status: ready only (from YAML - authoritative)
315
329
  // 2. No stamp exists (idempotency)
@@ -322,9 +336,48 @@ export function buildCheckpointWave(initRef, options = {}) {
322
336
  }
323
337
  return true;
324
338
  });
325
- // If no ready candidates, all work is done
326
339
  if (readyCandidates.length === 0) {
327
- return null;
340
+ const unfinishedActions = executionSummary.nextSafeActions.filter((action) => action.type !== 'launch');
341
+ const hasIncompleteExecution = executionSummary.wus.some((wu) => wu.state !== 'done');
342
+ if (!hasIncompleteExecution) {
343
+ return null;
344
+ }
345
+ return {
346
+ initiative: initId,
347
+ wave: -1,
348
+ wus: [],
349
+ manifestPath: null,
350
+ artifactDir: '',
351
+ planPath: '',
352
+ launchPath: '',
353
+ statusPath: '',
354
+ waitingMessage: 'No ready WUs can launch yet. Finish or recover in-flight work first.',
355
+ logicalWaves: [],
356
+ launchAttempt: -1,
357
+ handoffReceipts: [],
358
+ availableCapacity: executionSummary.availableCapacity,
359
+ nextSafeActions: unfinishedActions,
360
+ executionSummary,
361
+ };
362
+ }
363
+ if (executionSummary.blockedByIntegrity) {
364
+ return {
365
+ initiative: initId,
366
+ wave: -1,
367
+ wus: [],
368
+ manifestPath: null,
369
+ artifactDir: '',
370
+ planPath: '',
371
+ launchPath: '',
372
+ statusPath: '',
373
+ waitingMessage: 'Unsafe to advance while orchestration integrity issues remain.',
374
+ logicalWaves: [],
375
+ launchAttempt: -1,
376
+ handoffReceipts: [],
377
+ availableCapacity: executionSummary.availableCapacity,
378
+ nextSafeActions: executionSummary.nextSafeActions,
379
+ executionSummary,
380
+ };
328
381
  }
329
382
  // WU-2040: Filter by dependency stamps (wait-for-completion pattern)
330
383
  const depResult = filterByDependencyStamps(readyCandidates);
@@ -335,34 +388,111 @@ export function buildCheckpointWave(initRef, options = {}) {
335
388
  wave: -1,
336
389
  wus: [],
337
390
  manifestPath: null,
391
+ artifactDir: '',
392
+ planPath: '',
393
+ launchPath: '',
394
+ statusPath: '',
338
395
  blockedBy: depResult.blockingDeps,
339
396
  waitingMessage: depResult.waitingMessage,
397
+ logicalWaves: [],
398
+ launchAttempt: -1,
399
+ handoffReceipts: [],
400
+ availableCapacity: executionSummary.availableCapacity,
401
+ nextSafeActions: executionSummary.nextSafeActions,
402
+ executionSummary,
403
+ };
404
+ }
405
+ const launchableIds = new Set(executionSummary.launchableWuIds);
406
+ const launchableCandidates = depResult.spawnable.filter((wu) => launchableIds.has(wu.id));
407
+ if (launchableCandidates.length === 0) {
408
+ return {
409
+ initiative: initId,
410
+ wave: -1,
411
+ wus: [],
412
+ manifestPath: null,
413
+ artifactDir: '',
414
+ planPath: '',
415
+ launchPath: '',
416
+ statusPath: '',
417
+ waitingMessage: executionSummary.nextSafeActions.length > 0
418
+ ? 'No WUs can launch yet. Follow the next safe actions before advancing.'
419
+ : 'No WUs are currently eligible to launch.',
420
+ logicalWaves: [],
421
+ launchAttempt: -1,
422
+ handoffReceipts: [],
423
+ availableCapacity: executionSummary.availableCapacity,
424
+ nextSafeActions: executionSummary.nextSafeActions,
425
+ executionSummary,
340
426
  };
341
427
  }
428
+ const capacityLimit = executionSummary.availableCapacity === null
429
+ ? Number.POSITIVE_INFINITY
430
+ : executionSummary.availableCapacity;
342
431
  // Apply lane WIP=1 constraint: max one WU per lane per wave
343
432
  const selectedWUs = [];
344
433
  const usedLanes = new Set();
345
434
  for (const wu of depResult.spawnable) {
435
+ if (!launchableIds.has(wu.id)) {
436
+ continue;
437
+ }
438
+ if (selectedWUs.length >= capacityLimit) {
439
+ break;
440
+ }
346
441
  const lane = wu.doc.lane;
347
442
  if (!usedLanes.has(lane)) {
348
443
  selectedWUs.push(wu);
349
444
  usedLanes.add(lane);
350
445
  }
351
446
  }
352
- // Determine wave number
353
- const waveNum = getNextWaveNumber(initId);
354
- // Build manifest
447
+ if (selectedWUs.length === 0) {
448
+ return {
449
+ initiative: initId,
450
+ wave: -1,
451
+ wus: [],
452
+ manifestPath: null,
453
+ artifactDir: '',
454
+ planPath: '',
455
+ launchPath: '',
456
+ statusPath: '',
457
+ waitingMessage: 'No WUs fit the remaining capacity or lane limits in this launch.',
458
+ logicalWaves: [],
459
+ launchAttempt: -1,
460
+ handoffReceipts: [],
461
+ availableCapacity: executionSummary.availableCapacity,
462
+ nextSafeActions: executionSummary.nextSafeActions,
463
+ executionSummary,
464
+ };
465
+ }
466
+ const artifactBundle = writeCheckpointArtifacts(initId, wus, selectedWUs, {
467
+ clientName,
468
+ dryRun,
469
+ executionSummary,
470
+ });
471
+ const waveNum = artifactBundle.launchAttempt;
472
+ // Build compatibility manifest
355
473
  const manifest = {
356
474
  initiative: initId,
357
475
  wave: waveNum,
476
+ launch_attempt: artifactBundle.launchAttempt,
477
+ logical_waves: artifactBundle.logicalWaves,
358
478
  created_at: new Date().toISOString(),
359
- wus: selectedWUs.map((wu) => ({
360
- id: wu.id,
361
- lane: wu.doc.lane,
362
- status: MANIFEST_WU_STATUS,
363
- })),
479
+ wus: selectedWUs.map((wu) => {
480
+ const receipt = artifactBundle.handoffReceipts.find((entry) => entry.wu_id === wu.id);
481
+ return {
482
+ id: wu.id,
483
+ lane: wu.doc.lane,
484
+ status: MANIFEST_WU_STATUS,
485
+ logical_wave: receipt?.logical_wave,
486
+ handoff_artifact_path: receipt?.handoff_artifact_path,
487
+ handoff_format: receipt?.handoff_format,
488
+ };
489
+ }),
364
490
  lane_validation: 'pass',
365
491
  done_criteria: 'All stamps exist in .lumenflow/stamps/',
492
+ artifact_dir: artifactBundle.artifactDir,
493
+ plan_path: artifactBundle.planPath,
494
+ launch_path: artifactBundle.launchPath,
495
+ status_path: artifactBundle.statusPath,
366
496
  };
367
497
  // WU-2277: Skip file creation in dry-run mode
368
498
  const manifestPath = join(WAVE_MANIFEST_DIR, `${initId}-wave-${waveNum}.json`);
@@ -379,6 +509,16 @@ export function buildCheckpointWave(initRef, options = {}) {
379
509
  wave: waveNum,
380
510
  wus: manifest.wus,
381
511
  manifestPath,
512
+ artifactDir: artifactBundle.artifactDir,
513
+ planPath: artifactBundle.planPath,
514
+ launchPath: artifactBundle.launchPath,
515
+ statusPath: artifactBundle.statusPath,
516
+ logicalWaves: artifactBundle.logicalWaves,
517
+ launchAttempt: artifactBundle.launchAttempt,
518
+ handoffReceipts: artifactBundle.handoffReceipts,
519
+ availableCapacity: executionSummary.availableCapacity,
520
+ nextSafeActions: executionSummary.nextSafeActions,
521
+ executionSummary,
382
522
  };
383
523
  }
384
524
  // ── Internal helpers ──────────────────────────────────────────────────────────
@@ -429,18 +569,4 @@ function _getSpawnedWUIds(initId) {
429
569
  }
430
570
  return spawnedIds;
431
571
  }
432
- /**
433
- * Determine the next wave number for an initiative.
434
- *
435
- * @param {string} initId - Initiative ID
436
- * @returns {number} Next wave number (0-indexed)
437
- */
438
- function getNextWaveNumber(initId) {
439
- const manifests = getExistingWaveManifests(initId);
440
- if (manifests.length === 0) {
441
- return 0;
442
- }
443
- const maxWave = Math.max(...manifests.map((m) => m.wave));
444
- return maxWave + 1;
445
- }
446
572
  //# sourceMappingURL=checkpoint.js.map