@jterrats/open-orchestra 0.2.1 → 0.3.1

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.
@@ -0,0 +1,386 @@
1
+ import { existsSync } from "node:fs";
2
+ import { appendFile, readFile } from "node:fs/promises";
3
+ import path from "node:path";
4
+ import { ensureDir, resolveWorkflowPath } from "./fs-utils.js";
5
+ import { appendEvent, readEvents, writeArtifact } from "./workspace.js";
6
+ import { addTask, createHandoff, updateTask } from "./workflow-services.js";
7
+ import { SIZING_LABELS } from "./types.js";
8
+ // Phase graph: ordered list of [phase-id, role-id, summary]
9
+ export const AUTONOMOUS_PHASE_SEQUENCE = [
10
+ {
11
+ phase: "pm",
12
+ role: "product_manager",
13
+ summary: "Product framing, prioritization, and success metrics",
14
+ },
15
+ {
16
+ phase: "po",
17
+ role: "product_owner",
18
+ summary: "Backlog refinement, story sizing, and acceptance criteria",
19
+ },
20
+ {
21
+ phase: "architect",
22
+ role: "architect",
23
+ summary: "Technical tasking, design decisions, and size estimation",
24
+ },
25
+ {
26
+ phase: "developer",
27
+ role: "developer",
28
+ summary: "Implementation against acceptance criteria",
29
+ },
30
+ {
31
+ phase: "qa",
32
+ role: "qa",
33
+ summary: "Verification against acceptance criteria and edge cases",
34
+ },
35
+ {
36
+ phase: "release",
37
+ role: "release_manager",
38
+ summary: "Release candidate validation and PR creation",
39
+ },
40
+ ];
41
+ // Gate transitions that require human approval in 'phase' mode
42
+ const PHASE_GATES = new Set(["po→architect", "qa→release"]);
43
+ export const AUTONOMOUS_RUNS_FILE = "workflow-runs.jsonl";
44
+ export function autonomousRunsPath(root) {
45
+ return resolveWorkflowPath(root, AUTONOMOUS_RUNS_FILE);
46
+ }
47
+ export async function checkArchitectSizing(root, taskId) {
48
+ const events = await readEvents(root);
49
+ for (const event of events) {
50
+ if (event.type === "DECISION_RECORDED" &&
51
+ event.taskId === taskId &&
52
+ event.actor === "architect") {
53
+ const sizing = event.metadata.sizing;
54
+ if (typeof sizing === "string" &&
55
+ SIZING_LABELS.includes(sizing)) {
56
+ const points = typeof event.metadata.points === "number"
57
+ ? event.metadata.points
58
+ : undefined;
59
+ return {
60
+ found: true,
61
+ sizing: sizing,
62
+ ...(points !== undefined ? { points } : {}),
63
+ };
64
+ }
65
+ }
66
+ }
67
+ return { found: false };
68
+ }
69
+ export async function createAutonomousRun(root, opts) {
70
+ const now = new Date().toISOString();
71
+ const run = {
72
+ id: `wfrun-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`,
73
+ taskId: opts.taskId,
74
+ gates: opts.gates,
75
+ maxIterations: opts.maxIterations,
76
+ qaIterations: 0,
77
+ phases: [],
78
+ status: "running",
79
+ createdAt: now,
80
+ updatedAt: now,
81
+ };
82
+ await persistRun(root, run);
83
+ await appendEvent(root, {
84
+ type: "AUTONOMOUS_RUN_STARTED",
85
+ taskId: opts.taskId,
86
+ actor: "parent",
87
+ summary: `Autonomous workflow started [gates=${opts.gates}]`,
88
+ metadata: {
89
+ runId: run.id,
90
+ gates: opts.gates,
91
+ maxIterations: opts.maxIterations,
92
+ },
93
+ });
94
+ return run;
95
+ }
96
+ export async function readAutonomousRun(root, id) {
97
+ const file = autonomousRunsPath(root);
98
+ if (!existsSync(file))
99
+ return undefined;
100
+ const lines = (await readFile(file, "utf8"))
101
+ .trim()
102
+ .split("\n")
103
+ .filter(Boolean);
104
+ const latest = new Map();
105
+ for (const line of lines) {
106
+ const r = JSON.parse(line);
107
+ latest.set(r.id, r);
108
+ }
109
+ return latest.get(id);
110
+ }
111
+ export async function listAutonomousRuns(root) {
112
+ const file = autonomousRunsPath(root);
113
+ if (!existsSync(file))
114
+ return [];
115
+ const lines = (await readFile(file, "utf8"))
116
+ .trim()
117
+ .split("\n")
118
+ .filter(Boolean);
119
+ const latest = new Map();
120
+ for (const line of lines) {
121
+ const r = JSON.parse(line);
122
+ latest.set(r.id, r);
123
+ }
124
+ return [...latest.values()];
125
+ }
126
+ export async function initPhase(root, run, phaseIndex, retryContext) {
127
+ const def = AUTONOMOUS_PHASE_SEQUENCE[phaseIndex];
128
+ if (!def)
129
+ throw new Error(`invalid phase index: ${phaseIndex}`);
130
+ const now = new Date().toISOString();
131
+ // Use a run-scoped suffix so multiple runs on the same task don't collide.
132
+ // Short run suffix (last 6 chars of id) keeps IDs readable.
133
+ const runSuffix = run.id.slice(-6);
134
+ const iteration = run.phases.filter((p) => p.phase === def.phase).length;
135
+ const phaseTaskId = iteration === 0
136
+ ? `${run.taskId}-${def.phase}-${runSuffix}`
137
+ : `${run.taskId}-${def.phase}-${runSuffix}-retry${iteration}`;
138
+ // Dependency on the previous phase task in this same run
139
+ const prevDef = phaseIndex > 0 ? AUTONOMOUS_PHASE_SEQUENCE[phaseIndex - 1] : undefined;
140
+ const prevPhaseTaskId = prevDef
141
+ ? `${run.taskId}-${prevDef.phase}-${runSuffix}`
142
+ : undefined;
143
+ await addTask({
144
+ id: phaseTaskId,
145
+ title: `[${def.phase.toUpperCase()}] ${run.taskId}${iteration > 0 ? ` (retry ${iteration})` : ""}`,
146
+ ownerRole: def.role,
147
+ dependencies: prevPhaseTaskId ? [prevPhaseTaskId] : [],
148
+ ...(retryContext ? { blockedReason: retryContext } : {}),
149
+ }, root);
150
+ const phase = {
151
+ phase: def.phase,
152
+ role: def.role,
153
+ status: "running",
154
+ taskId: phaseTaskId,
155
+ startedAt: now,
156
+ ...(retryContext ? { notes: retryContext } : {}),
157
+ };
158
+ return phase;
159
+ }
160
+ export async function closePhase(root, run, phaseIndex, outcome) {
161
+ let resolvedOutcome = outcome;
162
+ const now = new Date().toISOString();
163
+ const def = AUTONOMOUS_PHASE_SEQUENCE[phaseIndex];
164
+ const nextDef = AUTONOMOUS_PHASE_SEQUENCE[phaseIndex + 1];
165
+ if (!def)
166
+ throw new Error(`invalid phase index: ${phaseIndex}`);
167
+ const phase = run.phases.find((p) => p.phase === def.phase);
168
+ if (!phase)
169
+ throw new Error(`phase not found in run: ${def.phase}`);
170
+ let handoffArtifact;
171
+ let reviewArtifact;
172
+ if (outcome.kind === "done" && nextDef) {
173
+ // Create handoff to next phase
174
+ const handoffResult = await createHandoff({
175
+ task: run.taskId,
176
+ from: def.role,
177
+ to: nextDef.role,
178
+ changed: `Phase ${def.phase} completed`,
179
+ behavior: def.summary,
180
+ tests: "See phase task evidence",
181
+ commands: "See phase task evidence",
182
+ status: "ready_for_review",
183
+ }, root);
184
+ handoffArtifact = handoffResult.artifact;
185
+ // Gate check
186
+ const transitionKey = `${def.phase}→${nextDef.phase}`;
187
+ const needsGate = run.gates === "all" ||
188
+ (run.gates === "phase" && PHASE_GATES.has(transitionKey));
189
+ if (needsGate) {
190
+ const reviewResult = await createGateReview(root, run, def, nextDef, transitionKey);
191
+ reviewArtifact = reviewResult.artifact;
192
+ resolvedOutcome = {
193
+ kind: "gate_pause",
194
+ reviewArtifact: reviewResult.artifact,
195
+ };
196
+ }
197
+ }
198
+ const updatedPhase = {
199
+ ...phase,
200
+ status: outcomeToPhaseStatus(resolvedOutcome),
201
+ ...(handoffArtifact !== undefined ? { handoffArtifact } : {}),
202
+ ...(reviewArtifact !== undefined ? { reviewArtifact } : {}),
203
+ notes: resolvedOutcome.kind !== "gate_pause"
204
+ ? resolvedOutcome.notes
205
+ : `Gate pause — review pending`,
206
+ completedAt: now,
207
+ };
208
+ const updatedPhases = run.phases.map((p) => p.phase === def.phase ? updatedPhase : p);
209
+ const allDone = resolvedOutcome.kind === "done" &&
210
+ !nextDef &&
211
+ updatedPhases.every((p) => p.status === "done");
212
+ const updatedRun = {
213
+ ...run,
214
+ phases: updatedPhases,
215
+ qaIterations: def.phase === "qa" && resolvedOutcome.kind === "qa_fail"
216
+ ? run.qaIterations + 1
217
+ : run.qaIterations,
218
+ status: resolvedOutcome.kind === "gate_pause"
219
+ ? "paused"
220
+ : allDone
221
+ ? "done"
222
+ : "running",
223
+ updatedAt: now,
224
+ };
225
+ await persistRun(root, updatedRun);
226
+ if (resolvedOutcome.kind === "gate_pause") {
227
+ await appendEvent(root, {
228
+ type: "AUTONOMOUS_GATE_PAUSED",
229
+ taskId: run.taskId,
230
+ actor: def.role,
231
+ summary: `Gate pause at ${def.phase}→${nextDef?.phase ?? "end"}`,
232
+ metadata: { runId: run.id, phase: def.phase, reviewArtifact },
233
+ });
234
+ }
235
+ else if (resolvedOutcome.kind === "done") {
236
+ await appendEvent(root, {
237
+ type: "AUTONOMOUS_PHASE_DONE",
238
+ taskId: run.taskId,
239
+ actor: def.role,
240
+ summary: `Phase ${def.phase} completed`,
241
+ metadata: { runId: run.id, phase: def.phase, handoffArtifact },
242
+ });
243
+ await updateTask({ id: phase.taskId, status: "done" }, root);
244
+ }
245
+ return {
246
+ run: updatedRun,
247
+ ...(handoffArtifact !== undefined ? { handoffArtifact } : {}),
248
+ ...(reviewArtifact !== undefined ? { reviewArtifact } : {}),
249
+ };
250
+ }
251
+ export async function markRunFailed(root, run, reason) {
252
+ const now = new Date().toISOString();
253
+ const updated = { ...run, status: "failed", updatedAt: now };
254
+ await persistRun(root, updated);
255
+ await appendEvent(root, {
256
+ type: "AUTONOMOUS_RUN_FAILED",
257
+ taskId: run.taskId,
258
+ actor: "parent",
259
+ summary: reason,
260
+ metadata: { runId: run.id },
261
+ });
262
+ // Cancel any phase sub-tasks still in a non-terminal state
263
+ for (const phase of run.phases) {
264
+ if (phase.status === "running" || phase.status === "pending") {
265
+ await updateTask({ id: phase.taskId, status: "canceled" }, root).catch(() => undefined);
266
+ }
267
+ }
268
+ return updated;
269
+ }
270
+ export async function markRunDone(root, run) {
271
+ const now = new Date().toISOString();
272
+ const updated = { ...run, status: "done", updatedAt: now };
273
+ await persistRun(root, updated);
274
+ await appendEvent(root, {
275
+ type: "AUTONOMOUS_RUN_DONE",
276
+ taskId: run.taskId,
277
+ actor: "parent",
278
+ summary: `Autonomous workflow complete`,
279
+ metadata: { runId: run.id },
280
+ });
281
+ return updated;
282
+ }
283
+ // Returns the phase index to resume from, or -1 if run is already done.
284
+ export function resumePhaseIndex(run) {
285
+ for (let i = 0; i < AUTONOMOUS_PHASE_SEQUENCE.length; i++) {
286
+ const def = AUTONOMOUS_PHASE_SEQUENCE[i];
287
+ const phase = run.phases.find((p) => p.phase === def.phase);
288
+ // No record yet, or actively running/pending → start here
289
+ if (!phase || phase.status === "running" || phase.status === "pending")
290
+ return i;
291
+ if (phase.status === "qa_failed")
292
+ return i; // retry qa
293
+ if (phase.status === "awaiting_clarification")
294
+ return i; // resume same phase
295
+ // done or gate_paused (gate already approved on previous resume) → scan forward
296
+ if (phase.status === "done" || phase.status === "gate_paused")
297
+ continue;
298
+ }
299
+ return -1; // all phases accounted for
300
+ }
301
+ // Suspends a phase awaiting clarification (does not advance phase sequence).
302
+ export async function suspendPhaseForClarification(root, run, phaseIndex) {
303
+ const def = AUTONOMOUS_PHASE_SEQUENCE[phaseIndex];
304
+ if (!def)
305
+ throw new Error(`invalid phase index: ${phaseIndex}`);
306
+ const phase = run.phases.find((p) => p.phase === def.phase);
307
+ if (!phase)
308
+ throw new Error(`phase not found in run: ${def.phase}`);
309
+ const updatedPhases = run.phases.map((p) => p.phase === def.phase
310
+ ? { ...p, status: "awaiting_clarification" }
311
+ : p);
312
+ const updated = {
313
+ ...run,
314
+ phases: updatedPhases,
315
+ status: "paused",
316
+ updatedAt: new Date().toISOString(),
317
+ };
318
+ await persistRun(root, updated);
319
+ return updated;
320
+ }
321
+ // Resumes a phase from awaiting_clarification back to running.
322
+ export async function resumePhaseFromClarification(root, run, phaseIndex) {
323
+ const def = AUTONOMOUS_PHASE_SEQUENCE[phaseIndex];
324
+ if (!def)
325
+ throw new Error(`invalid phase index: ${phaseIndex}`);
326
+ const phase = run.phases.find((p) => p.phase === def.phase);
327
+ if (!phase)
328
+ throw new Error(`phase not found in run: ${def.phase}`);
329
+ if (phase.status !== "awaiting_clarification") {
330
+ throw new Error(`phase ${def.phase} is not awaiting clarification (status: ${phase.status})`);
331
+ }
332
+ const updatedPhases = run.phases.map((p) => p.phase === def.phase ? { ...p, status: "running" } : p);
333
+ const updated = {
334
+ ...run,
335
+ phases: updatedPhases,
336
+ status: "running",
337
+ updatedAt: new Date().toISOString(),
338
+ };
339
+ await persistRun(root, updated);
340
+ return updated;
341
+ }
342
+ // --- helpers ---
343
+ async function createGateReview(root, run, from, to, transitionKey) {
344
+ const fileName = `${run.taskId}-gate-${transitionKey.replace("→", "-to-")}-${Date.now()}.md`;
345
+ const content = [
346
+ `# Gate Review: ${transitionKey}`,
347
+ "",
348
+ `- Run: ${run.id}`,
349
+ `- Task: ${run.taskId}`,
350
+ `- Transition: ${from.phase} → ${to.phase}`,
351
+ `- From role: ${from.role}`,
352
+ `- To role: ${to.role}`,
353
+ "",
354
+ "## Checklist",
355
+ `- [ ] ${from.summary}`,
356
+ `- [ ] Acceptance criteria verified`,
357
+ `- [ ] No open blockers`,
358
+ "",
359
+ "## Approval",
360
+ `Approve: orchestra workflow run --task ${run.taskId} --resume ${run.id}`,
361
+ "",
362
+ ].join("\n");
363
+ const artifact = await writeArtifact(root, "approvals", fileName, content);
364
+ await appendEvent(root, {
365
+ type: "AUTONOMOUS_GATE_REQUESTED",
366
+ taskId: run.taskId,
367
+ actor: from.role,
368
+ summary: `Gate review requested: ${transitionKey}`,
369
+ artifacts: [artifact],
370
+ metadata: { runId: run.id, transitionKey },
371
+ });
372
+ return { artifact };
373
+ }
374
+ function outcomeToPhaseStatus(outcome) {
375
+ if (outcome.kind === "done")
376
+ return "done";
377
+ if (outcome.kind === "gate_pause")
378
+ return "gate_paused";
379
+ return "qa_failed";
380
+ }
381
+ async function persistRun(root, run) {
382
+ const file = autonomousRunsPath(root);
383
+ await ensureDir(path.dirname(file));
384
+ await appendFile(file, `${JSON.stringify(run)}\n`, "utf8");
385
+ }
386
+ //# sourceMappingURL=autonomous-workflow.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"autonomous-workflow.js","sourceRoot":"","sources":["../src/autonomous-workflow.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import type { BenchmarkResult, BenchmarkSummary, EstimateInput, EstimateRecord } from "./types.js";
2
+ export declare const ESTIMATES_FILE = "estimates.jsonl";
3
+ export declare function estimatesPath(root: string): string;
4
+ export declare function recordEstimate(root: string, input: EstimateInput): Promise<EstimateRecord>;
5
+ export declare function readEstimate(root: string, taskId: string): Promise<EstimateRecord | undefined>;
6
+ export declare function listEstimates(root: string): Promise<EstimateRecord[]>;
7
+ export declare function computeBenchmark(root: string, taskId: string): Promise<BenchmarkResult>;
8
+ export declare function summarizeBenchmark(root: string): Promise<BenchmarkSummary>;
@@ -0,0 +1,193 @@
1
+ import { existsSync } from "node:fs";
2
+ import { appendFile, readFile } from "node:fs/promises";
3
+ import path from "node:path";
4
+ import { ensureDir, resolveWorkflowPath } from "./fs-utils.js";
5
+ import { appendEvent, readEvents } from "./workspace.js";
6
+ import { listAutonomousRuns } from "./autonomous-workflow.js";
7
+ export const ESTIMATES_FILE = "estimates.jsonl";
8
+ export function estimatesPath(root) {
9
+ return resolveWorkflowPath(root, ESTIMATES_FILE);
10
+ }
11
+ export async function recordEstimate(root, input) {
12
+ const now = new Date().toISOString();
13
+ const record = {
14
+ id: `est-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`,
15
+ taskId: input.taskId,
16
+ sizingLabel: input.sizingLabel,
17
+ soloEstimateDays: input.soloEstimateDays,
18
+ aiUnguidedEstimateDays: input.aiUnguidedEstimateDays,
19
+ confidence: input.confidence,
20
+ declaredBy: input.declaredBy,
21
+ declaredAt: now,
22
+ };
23
+ const file = estimatesPath(root);
24
+ await ensureDir(path.dirname(file));
25
+ await appendFile(file, `${JSON.stringify(record)}\n`, "utf8");
26
+ await appendEvent(root, {
27
+ type: "ESTIMATE_RECORDED",
28
+ taskId: input.taskId,
29
+ actor: input.declaredBy,
30
+ summary: `Estimate recorded: solo=${input.soloEstimateDays}d AI=${input.aiUnguidedEstimateDays}d sizing=${input.sizingLabel}`,
31
+ metadata: {
32
+ estimateId: record.id,
33
+ sizingLabel: input.sizingLabel,
34
+ soloEstimateDays: input.soloEstimateDays,
35
+ aiUnguidedEstimateDays: input.aiUnguidedEstimateDays,
36
+ confidence: input.confidence,
37
+ },
38
+ });
39
+ return record;
40
+ }
41
+ export async function readEstimate(root, taskId) {
42
+ const file = estimatesPath(root);
43
+ if (!existsSync(file))
44
+ return undefined;
45
+ const lines = (await readFile(file, "utf8"))
46
+ .trim()
47
+ .split("\n")
48
+ .filter(Boolean);
49
+ const latest = new Map();
50
+ for (const line of lines) {
51
+ const r = JSON.parse(line);
52
+ latest.set(r.taskId, r);
53
+ }
54
+ return latest.get(taskId);
55
+ }
56
+ export async function listEstimates(root) {
57
+ const file = estimatesPath(root);
58
+ if (!existsSync(file))
59
+ return [];
60
+ const lines = (await readFile(file, "utf8"))
61
+ .trim()
62
+ .split("\n")
63
+ .filter(Boolean);
64
+ const latest = new Map();
65
+ for (const line of lines) {
66
+ const r = JSON.parse(line);
67
+ latest.set(r.taskId, r);
68
+ }
69
+ return [...latest.values()];
70
+ }
71
+ export async function computeBenchmark(root, taskId) {
72
+ const estimate = await readEstimate(root, taskId);
73
+ if (!estimate)
74
+ throw new Error(`no estimate found for task ${taskId}`);
75
+ const runs = await listAutonomousRuns(root);
76
+ const taskRun = runs.find((r) => r.taskId === taskId && r.status === "done");
77
+ const quality = await computeQualitySignals(root, taskId);
78
+ if (!taskRun) {
79
+ return {
80
+ taskId,
81
+ sizingLabel: estimate.sizingLabel,
82
+ soloEstimateDays: estimate.soloEstimateDays,
83
+ aiUnguidedEstimateDays: estimate.aiUnguidedEstimateDays,
84
+ actualDays: null,
85
+ vsSoloPct: null,
86
+ vsAiUnguidedPct: null,
87
+ qaIterations: 0,
88
+ quality,
89
+ status: "pending",
90
+ };
91
+ }
92
+ // Compute actual cycle time from first phase start to release phase completion
93
+ const startedPhase = taskRun.phases[0];
94
+ const releasedPhase = taskRun.phases.find((p) => p.phase === "release");
95
+ const startedAt = startedPhase?.startedAt
96
+ ? new Date(startedPhase.startedAt).getTime()
97
+ : null;
98
+ const completedAt = releasedPhase?.completedAt
99
+ ? new Date(releasedPhase.completedAt).getTime()
100
+ : null;
101
+ const actualDays = startedAt !== null && completedAt !== null
102
+ ? Math.round(((completedAt - startedAt) / (1000 * 60 * 60 * 24)) * 100) /
103
+ 100
104
+ : null;
105
+ const vsSoloPct = actualDays !== null
106
+ ? Math.round(((actualDays - estimate.soloEstimateDays) /
107
+ estimate.soloEstimateDays) *
108
+ 100)
109
+ : null;
110
+ const vsAiUnguidedPct = actualDays !== null
111
+ ? Math.round(((actualDays - estimate.aiUnguidedEstimateDays) /
112
+ estimate.aiUnguidedEstimateDays) *
113
+ 100)
114
+ : null;
115
+ return {
116
+ taskId,
117
+ sizingLabel: estimate.sizingLabel,
118
+ soloEstimateDays: estimate.soloEstimateDays,
119
+ aiUnguidedEstimateDays: estimate.aiUnguidedEstimateDays,
120
+ actualDays,
121
+ vsSoloPct,
122
+ vsAiUnguidedPct,
123
+ qaIterations: taskRun.qaIterations,
124
+ quality,
125
+ status: "complete",
126
+ };
127
+ }
128
+ async function computeQualitySignals(root, taskId) {
129
+ const events = await readEvents(root);
130
+ const taskEvents = events.filter((e) => e.taskId === taskId);
131
+ const reviews = taskEvents.filter((e) => e.type === "REVIEW_RECORDED");
132
+ const blockingReviews = reviews.filter((e) => e.metadata.result === "block" ||
133
+ e.metadata.severity === "critical" ||
134
+ e.metadata.severity === "high").length;
135
+ const evidenceCount = taskEvents.filter((e) => e.type === "EVIDENCE_ADDED").length;
136
+ const gateBlockCount = taskEvents.filter((e) => e.type === "GATE_BLOCKED").length;
137
+ const lessonCount = taskEvents.filter((e) => e.type === "LESSON_RECORDED").length;
138
+ const provenanceEvents = taskEvents.filter((e) => e.type === "MODEL_PROVENANCE_RECORDED");
139
+ const totalInputTokens = provenanceEvents.reduce((sum, e) => sum +
140
+ (typeof e.metadata.inputTokens === "number" ? e.metadata.inputTokens : 0), 0);
141
+ const totalOutputTokens = provenanceEvents.reduce((sum, e) => sum +
142
+ (typeof e.metadata.outputTokens === "number"
143
+ ? e.metadata.outputTokens
144
+ : 0), 0);
145
+ const estimatedCostUsd = provenanceEvents.reduce((sum, e) => sum +
146
+ (typeof e.metadata.estimatedCostUsd === "number"
147
+ ? e.metadata.estimatedCostUsd
148
+ : 0), 0);
149
+ return {
150
+ reviewCount: reviews.length,
151
+ blockingReviews,
152
+ evidenceCount,
153
+ gateBlockCount,
154
+ lessonCount,
155
+ totalInputTokens,
156
+ totalOutputTokens,
157
+ estimatedCostUsd: Math.round(estimatedCostUsd * 10000) / 10000,
158
+ };
159
+ }
160
+ export async function summarizeBenchmark(root) {
161
+ const estimates = await listEstimates(root);
162
+ const stories = [];
163
+ for (const est of estimates) {
164
+ try {
165
+ const result = await computeBenchmark(root, est.taskId);
166
+ stories.push(result);
167
+ }
168
+ catch {
169
+ // skip tasks where computation fails
170
+ }
171
+ }
172
+ // Sort by sizing label order
173
+ const sizeOrder = {
174
+ xs: 0,
175
+ s: 1,
176
+ m: 2,
177
+ l: 3,
178
+ xl: 4,
179
+ };
180
+ stories.sort((a, b) => sizeOrder[a.sizingLabel] - sizeOrder[b.sizingLabel]);
181
+ const withActuals = stories.filter((s) => s.actualDays !== null);
182
+ const totalWithActuals = withActuals.length;
183
+ const avgVsSoloPct = totalWithActuals > 0
184
+ ? Math.round(withActuals.reduce((sum, s) => sum + (s.vsSoloPct ?? 0), 0) /
185
+ totalWithActuals)
186
+ : null;
187
+ const avgVsAiUnguidedPct = totalWithActuals > 0
188
+ ? Math.round(withActuals.reduce((sum, s) => sum + (s.vsAiUnguidedPct ?? 0), 0) /
189
+ totalWithActuals)
190
+ : null;
191
+ return { stories, totalWithActuals, avgVsSoloPct, avgVsAiUnguidedPct };
192
+ }
193
+ //# sourceMappingURL=benchmark.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"benchmark.js","sourceRoot":"","sources":["../src/benchmark.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { BurndownSeries } from "./types.js";
2
+ export declare function computeSprintBurndown(root: string, sprintTaskIds: string[]): Promise<BurndownSeries>;
3
+ export declare function renderBurndownAscii(series: BurndownSeries): string;