@akagilnc/pi-workflow-roles 0.1.5303 → 0.1.5307
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/dist/acp-host/production-host.js +137 -163
- package/dist/analyst-ledger.js +16 -1
- package/dist/analyst-metric-families/acceptance-success-rework.js +16 -15
- package/dist/analyst-metric-families/b2-frame-buckets-actions.js +3 -8
- package/dist/analyst-metric-families/gate-cycles.js +2 -8
- package/dist/analyst-metric-families/leg-wall-clock.js +4 -13
- package/dist/analyst-metric-families/round-timeline.js +1 -4
- package/dist/analyst-model-groups.js +1 -7
- package/dist/analyst-page.js +4 -13
- package/dist/headless-host/production-host.js +137 -163
- package/dist/public-cli/main.js +137 -163
- package/package.json +1 -1
- package/src/analyst-ledger.ts +20 -1
- package/src/analyst-metric-families/acceptance-success-rework.ts +5 -15
- package/src/analyst-metric-families/b2-frame-buckets-actions.ts +3 -7
- package/src/analyst-metric-families/gate-cycles.ts +2 -8
- package/src/analyst-metric-families/leg-wall-clock.ts +4 -16
- package/src/analyst-metric-families/round-timeline.ts +1 -5
- package/src/analyst-model-groups.ts +1 -10
- package/src/analyst-page.ts +4 -16
|
@@ -2,9 +2,6 @@ import { extractStatus } from "./acceptance-success-rework.js";
|
|
|
2
2
|
function isRecord(value) {
|
|
3
3
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
4
4
|
}
|
|
5
|
-
function wallMsFromSpan(startedAt, endedAt) {
|
|
6
|
-
return Date.parse(endedAt) - Date.parse(startedAt);
|
|
7
|
-
}
|
|
8
5
|
function readClassCount(body) {
|
|
9
6
|
if (!isRecord(body.outcome))
|
|
10
7
|
return undefined;
|
|
@@ -44,7 +41,7 @@ function projectRunRow(facts) {
|
|
|
44
41
|
role: facts.role,
|
|
45
42
|
startedAt,
|
|
46
43
|
endedAt,
|
|
47
|
-
wallMs:
|
|
44
|
+
wallMs: facts.frameSpan.wallMs,
|
|
48
45
|
terminal: projectTerminal(facts),
|
|
49
46
|
};
|
|
50
47
|
}
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
*/
|
|
11
11
|
import { buildAcceptanceSuccessReworkSection } from "./analyst-metric-families/acceptance-success-rework.js";
|
|
12
12
|
import { medianNumber } from "./analyst-median.js";
|
|
13
|
+
import { sortUnreadable } from "./analyst-page.js";
|
|
13
14
|
/**
|
|
14
15
|
* Build the raw group key for one leg from its ordered-unique model sequence.
|
|
15
16
|
* Empty sequence → undefined (no inventable group; caller lists as typed vacancy).
|
|
@@ -33,13 +34,6 @@ function displayNameFor(rawGroupKey, combinationMapping) {
|
|
|
33
34
|
const aliased = combinationMapping[rawGroupKey];
|
|
34
35
|
return aliased === undefined ? rawGroupKey : aliased;
|
|
35
36
|
}
|
|
36
|
-
function sortUnreadable(unreadable) {
|
|
37
|
-
return [...unreadable].sort((a, b) => {
|
|
38
|
-
if (a.book !== b.book)
|
|
39
|
-
return a.book.localeCompare(b.book);
|
|
40
|
-
return a.runId.localeCompare(b.runId);
|
|
41
|
-
});
|
|
42
|
-
}
|
|
43
37
|
/**
|
|
44
38
|
* Legs with no usable session model identity cannot join any model group.
|
|
45
39
|
* Reuse the typed unreadable path (locatable missing-source) — not an empty-key group.
|
package/dist/analyst-page.js
CHANGED
|
@@ -10,6 +10,7 @@ import { createHash } from "node:crypto";
|
|
|
10
10
|
import { dirname, join } from "node:path";
|
|
11
11
|
import { writeFileAtomically } from "./atomic-write.js";
|
|
12
12
|
import { assertLedgerFileInsideHome, ensureRealDirectoryTree, physicalPathIdentity, } from "./activation-ledger-topology.js";
|
|
13
|
+
import { compareAnalystLegs, sumAnalystRunWallMs } from "./analyst-ledger.js";
|
|
13
14
|
import { loadAnalystIssueMetricFamilies } from "./analyst-metric-families.js";
|
|
14
15
|
import { composeAnalystMetricFamilySections } from "./analyst-metric-family.js";
|
|
15
16
|
export function analystIssuePageKey(address) {
|
|
@@ -35,15 +36,9 @@ export function analystIssuePageAddressFromPage(page) {
|
|
|
35
36
|
};
|
|
36
37
|
}
|
|
37
38
|
function sortLegs(legs) {
|
|
38
|
-
return [...legs].sort(
|
|
39
|
-
if (a.book !== b.book)
|
|
40
|
-
return a.book.localeCompare(b.book);
|
|
41
|
-
if (a.role !== b.role)
|
|
42
|
-
return a.role.localeCompare(b.role);
|
|
43
|
-
return a.runId.localeCompare(b.runId);
|
|
44
|
-
});
|
|
39
|
+
return [...legs].sort(compareAnalystLegs);
|
|
45
40
|
}
|
|
46
|
-
function sortUnreadable(unreadable) {
|
|
41
|
+
export function sortUnreadable(unreadable) {
|
|
47
42
|
return [...unreadable].sort((a, b) => {
|
|
48
43
|
if (a.book !== b.book)
|
|
49
44
|
return a.book.localeCompare(b.book);
|
|
@@ -95,19 +90,15 @@ export function computeAnalystMsPerKLines(totalElapsedMs, changedLines) {
|
|
|
95
90
|
value: totalElapsedMs / (changedLines.value / 1000),
|
|
96
91
|
};
|
|
97
92
|
}
|
|
98
|
-
function frameSpanWallMs(span) {
|
|
99
|
-
return Date.parse(span.endedAt) - Date.parse(span.startedAt);
|
|
100
|
-
}
|
|
101
93
|
/**
|
|
102
94
|
* Σ readable wall clocks + max end-frame across ALL runs (C1 efficiency / index).
|
|
103
95
|
* Unreadable runs never enter totalElapsedMs; their available lastFrameAt still
|
|
104
96
|
* competes for lastActivityAt (PRD ②: 全部 run 末帧之最大者).
|
|
105
97
|
*/
|
|
106
98
|
export function summarizeAnalystRunEfficiency(runs, unreadable = []) {
|
|
107
|
-
|
|
99
|
+
const totalElapsedMs = sumAnalystRunWallMs(runs);
|
|
108
100
|
let latestEndedAt;
|
|
109
101
|
for (const run of runs) {
|
|
110
|
-
totalElapsedMs += frameSpanWallMs(run.frameSpan);
|
|
111
102
|
const endedAt = run.frameSpan.endedAt;
|
|
112
103
|
if (latestEndedAt === undefined || endedAt > latestEndedAt) {
|
|
113
104
|
latestEndedAt = endedAt;
|
|
@@ -15958,11 +15958,21 @@ function admitFrameSpanFromRows(rows) {
|
|
|
15958
15958
|
}
|
|
15959
15959
|
return {
|
|
15960
15960
|
models,
|
|
15961
|
-
frameSpan: { startedAt: span.startedAt, endedAt: span.endedAt },
|
|
15961
|
+
frameSpan: { startedAt: span.startedAt, endedAt: span.endedAt, wallMs: endedMs - startedMs },
|
|
15962
15962
|
partialFirstFrameAt: { status: "present", at: span.startedAt },
|
|
15963
15963
|
partialLastFrameAt: { status: "present", at: span.endedAt }
|
|
15964
15964
|
};
|
|
15965
15965
|
}
|
|
15966
|
+
function sumAnalystRunWallMs(runs) {
|
|
15967
|
+
let total = 0;
|
|
15968
|
+
for (const run of runs) total += run.frameSpan.wallMs;
|
|
15969
|
+
return total;
|
|
15970
|
+
}
|
|
15971
|
+
function compareAnalystLegs(a, b) {
|
|
15972
|
+
if (a.book !== b.book) return a.book.localeCompare(b.book);
|
|
15973
|
+
if (a.role !== b.role) return a.role.localeCompare(b.role);
|
|
15974
|
+
return a.runId.localeCompare(b.runId);
|
|
15975
|
+
}
|
|
15966
15976
|
async function classifyScopedRun(input) {
|
|
15967
15977
|
const missingSources = [];
|
|
15968
15978
|
const reasons = [];
|
|
@@ -16243,9 +16253,6 @@ var init_analyst_ledger = __esm({
|
|
|
16243
16253
|
function isRecord13(value) {
|
|
16244
16254
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
16245
16255
|
}
|
|
16246
|
-
function wallMsFromSpan(span) {
|
|
16247
|
-
return Date.parse(span.endedAt) - Date.parse(span.startedAt);
|
|
16248
|
-
}
|
|
16249
16256
|
function findCollectorGroups(body) {
|
|
16250
16257
|
if (Array.isArray(body.groups)) return body.groups;
|
|
16251
16258
|
const receipt = body.receipt;
|
|
@@ -16354,7 +16361,7 @@ function projectLegs(runs) {
|
|
|
16354
16361
|
book: run.book,
|
|
16355
16362
|
role: run.role,
|
|
16356
16363
|
startedAt: run.frameSpan.startedAt,
|
|
16357
|
-
wallMs:
|
|
16364
|
+
wallMs: run.frameSpan.wallMs,
|
|
16358
16365
|
terminalLabel: mapped.terminalLabel,
|
|
16359
16366
|
accepted: mapped.accepted,
|
|
16360
16367
|
success: mapped.success,
|
|
@@ -16364,11 +16371,7 @@ function projectLegs(runs) {
|
|
|
16364
16371
|
rework: ordinal >= 2
|
|
16365
16372
|
});
|
|
16366
16373
|
}
|
|
16367
|
-
return legs.sort(
|
|
16368
|
-
if (a.book !== b.book) return a.book.localeCompare(b.book);
|
|
16369
|
-
if (a.role !== b.role) return a.role.localeCompare(b.role);
|
|
16370
|
-
return a.runId.localeCompare(b.runId);
|
|
16371
|
-
});
|
|
16374
|
+
return legs.sort(compareAnalystLegs);
|
|
16372
16375
|
}
|
|
16373
16376
|
function aggregateByRole(legs) {
|
|
16374
16377
|
const roles = [...new Set(legs.map((leg) => leg.role))].sort((a, b) => a.localeCompare(b));
|
|
@@ -16412,12 +16415,10 @@ function aggregateByRole(legs) {
|
|
|
16412
16415
|
};
|
|
16413
16416
|
});
|
|
16414
16417
|
}
|
|
16415
|
-
function reworkLens(legs) {
|
|
16418
|
+
function reworkLens(legs, totalWallMs) {
|
|
16416
16419
|
let reworkWallMs = 0;
|
|
16417
|
-
let totalWallMs = 0;
|
|
16418
16420
|
let reworkLegCount = 0;
|
|
16419
16421
|
for (const leg of legs) {
|
|
16420
|
-
totalWallMs += leg.wallMs;
|
|
16421
16422
|
if (leg.rework) {
|
|
16422
16423
|
reworkWallMs += leg.wallMs;
|
|
16423
16424
|
reworkLegCount += 1;
|
|
@@ -16438,13 +16439,14 @@ function buildAcceptanceSuccessReworkSection(runs) {
|
|
|
16438
16439
|
kind: "analyst-acceptance-success-rework",
|
|
16439
16440
|
legs,
|
|
16440
16441
|
byRole: aggregateByRole(legs),
|
|
16441
|
-
rework: reworkLens(legs)
|
|
16442
|
+
rework: reworkLens(legs, sumAnalystRunWallMs(runs))
|
|
16442
16443
|
};
|
|
16443
16444
|
}
|
|
16444
16445
|
var WORKER_ROLES, ACCEPTED_STATUS, SUCCESS_STATUS, acceptanceSuccessReworkFamily, acceptance_success_rework_default;
|
|
16445
16446
|
var init_acceptance_success_rework = __esm({
|
|
16446
16447
|
"src/analyst-metric-families/acceptance-success-rework.ts"() {
|
|
16447
16448
|
"use strict";
|
|
16449
|
+
init_analyst_ledger();
|
|
16448
16450
|
init_analyst_median();
|
|
16449
16451
|
init_packaged_role_registry();
|
|
16450
16452
|
WORKER_ROLES = /* @__PURE__ */ new Set(["coder", "fixer"]);
|
|
@@ -16477,117 +16479,6 @@ var init_acceptance_success_rework = __esm({
|
|
|
16477
16479
|
}
|
|
16478
16480
|
});
|
|
16479
16481
|
|
|
16480
|
-
// src/analyst-model-groups.ts
|
|
16481
|
-
function analystModelGroupKey(models) {
|
|
16482
|
-
if (models.length === 0) return void 0;
|
|
16483
|
-
if (models.length === 1) return models[0];
|
|
16484
|
-
return `mixed:${models.join("+")}`;
|
|
16485
|
-
}
|
|
16486
|
-
function rate(numerator, denominator) {
|
|
16487
|
-
if (denominator === 0) return void 0;
|
|
16488
|
-
return numerator / denominator;
|
|
16489
|
-
}
|
|
16490
|
-
function displayNameFor(rawGroupKey, combinationMapping) {
|
|
16491
|
-
if (combinationMapping === void 0) return rawGroupKey;
|
|
16492
|
-
const aliased = combinationMapping[rawGroupKey];
|
|
16493
|
-
return aliased === void 0 ? rawGroupKey : aliased;
|
|
16494
|
-
}
|
|
16495
|
-
function sortUnreadable(unreadable) {
|
|
16496
|
-
return [...unreadable].sort((a, b) => {
|
|
16497
|
-
if (a.book !== b.book) return a.book.localeCompare(b.book);
|
|
16498
|
-
return a.runId.localeCompare(b.runId);
|
|
16499
|
-
});
|
|
16500
|
-
}
|
|
16501
|
-
function modelIdentityAbsentEntry(run) {
|
|
16502
|
-
return {
|
|
16503
|
-
runId: run.runId,
|
|
16504
|
-
book: run.book,
|
|
16505
|
-
missingSources: ["session-model"],
|
|
16506
|
-
reason: "session has no usable model identity",
|
|
16507
|
-
firstFrameAt: { status: "present", at: run.frameSpan.startedAt },
|
|
16508
|
-
// Readable legs already admitted a full span — retain end edge for lastActivityAt.
|
|
16509
|
-
lastFrameAt: { status: "present", at: run.frameSpan.endedAt }
|
|
16510
|
-
};
|
|
16511
|
-
}
|
|
16512
|
-
function buildAnalystModelGroupsPage(input) {
|
|
16513
|
-
const groupedRuns = [];
|
|
16514
|
-
const modelAbsent = [];
|
|
16515
|
-
for (const run of input.runs) {
|
|
16516
|
-
const rawGroupKey = analystModelGroupKey(run.models);
|
|
16517
|
-
if (rawGroupKey === void 0) {
|
|
16518
|
-
modelAbsent.push(modelIdentityAbsentEntry(run));
|
|
16519
|
-
} else {
|
|
16520
|
-
groupedRuns.push({ run, rawGroupKey });
|
|
16521
|
-
}
|
|
16522
|
-
}
|
|
16523
|
-
const acceptance = buildAcceptanceSuccessReworkSection(
|
|
16524
|
-
groupedRuns.map(({ run }) => run)
|
|
16525
|
-
);
|
|
16526
|
-
const legByRunId = new Map(
|
|
16527
|
-
(acceptance?.legs ?? []).map((leg) => [leg.runId, leg])
|
|
16528
|
-
);
|
|
16529
|
-
const byRaw = /* @__PURE__ */ new Map();
|
|
16530
|
-
for (const { run, rawGroupKey } of groupedRuns) {
|
|
16531
|
-
const leg = legByRunId.get(run.runId);
|
|
16532
|
-
if (leg === void 0) {
|
|
16533
|
-
throw new Error(
|
|
16534
|
-
`analyst model-groups: missing acceptance projection for run ${run.runId}`
|
|
16535
|
-
);
|
|
16536
|
-
}
|
|
16537
|
-
let acc = byRaw.get(rawGroupKey);
|
|
16538
|
-
if (acc === void 0) {
|
|
16539
|
-
acc = {
|
|
16540
|
-
acceptedCount: 0,
|
|
16541
|
-
successCount: 0,
|
|
16542
|
-
successEligibleCount: 0,
|
|
16543
|
-
noReceiptCount: 0,
|
|
16544
|
-
walls: []
|
|
16545
|
-
};
|
|
16546
|
-
byRaw.set(rawGroupKey, acc);
|
|
16547
|
-
}
|
|
16548
|
-
if (leg.accepted) acc.acceptedCount += 1;
|
|
16549
|
-
if (leg.success) acc.successCount += 1;
|
|
16550
|
-
if (leg.successEligible) acc.successEligibleCount += 1;
|
|
16551
|
-
if (leg.noReceipt) acc.noReceiptCount += 1;
|
|
16552
|
-
acc.walls.push(leg.wallMs);
|
|
16553
|
-
}
|
|
16554
|
-
const rawKeys = [...byRaw.keys()].sort((a, b) => a.localeCompare(b));
|
|
16555
|
-
const groups = rawKeys.map((rawGroupKey) => {
|
|
16556
|
-
const acc = byRaw.get(rawGroupKey);
|
|
16557
|
-
const legCount = acc.walls.length;
|
|
16558
|
-
return {
|
|
16559
|
-
rawGroupKey,
|
|
16560
|
-
displayName: displayNameFor(rawGroupKey, input.combinationMapping),
|
|
16561
|
-
legCount,
|
|
16562
|
-
acceptedCount: acc.acceptedCount,
|
|
16563
|
-
acceptanceRate: rate(acc.acceptedCount, legCount),
|
|
16564
|
-
successCount: acc.successCount,
|
|
16565
|
-
successEligibleCount: acc.successEligibleCount,
|
|
16566
|
-
successRate: rate(acc.successCount, acc.successEligibleCount),
|
|
16567
|
-
noReceiptCount: acc.noReceiptCount,
|
|
16568
|
-
noReceiptRate: rate(acc.noReceiptCount, legCount),
|
|
16569
|
-
wallClockMedianMs: medianNumber(acc.walls)
|
|
16570
|
-
};
|
|
16571
|
-
});
|
|
16572
|
-
const unreadable = sortUnreadable([...input.unreadable, ...modelAbsent]);
|
|
16573
|
-
return {
|
|
16574
|
-
kind: "analyst-model-groups",
|
|
16575
|
-
mode: "model-groups",
|
|
16576
|
-
projectRoots: [...input.projectRoots].sort((a, b) => a.localeCompare(b)),
|
|
16577
|
-
groups,
|
|
16578
|
-
legCount: groupedRuns.length,
|
|
16579
|
-
unreadableCount: unreadable.length,
|
|
16580
|
-
unreadable
|
|
16581
|
-
};
|
|
16582
|
-
}
|
|
16583
|
-
var init_analyst_model_groups = __esm({
|
|
16584
|
-
"src/analyst-model-groups.ts"() {
|
|
16585
|
-
"use strict";
|
|
16586
|
-
init_acceptance_success_rework();
|
|
16587
|
-
init_analyst_median();
|
|
16588
|
-
}
|
|
16589
|
-
});
|
|
16590
|
-
|
|
16591
16482
|
// src/analyst-metric-families/b2-frame-buckets-actions.ts
|
|
16592
16483
|
function timestampMs(iso) {
|
|
16593
16484
|
const ms = Date.parse(iso);
|
|
@@ -16710,7 +16601,7 @@ function sortActionsDescending(actions) {
|
|
|
16710
16601
|
function computeAnalystB2RunMetrics(facts) {
|
|
16711
16602
|
const frameStartMs = timestampMs(facts.frameSpan.startedAt);
|
|
16712
16603
|
const frameEndMs = timestampMs(facts.frameSpan.endedAt);
|
|
16713
|
-
const wallMs =
|
|
16604
|
+
const wallMs = facts.frameSpan.wallMs;
|
|
16714
16605
|
const tools = clipToolsToFrame(closedTools(facts.toolIntervals), frameStartMs, frameEndMs);
|
|
16715
16606
|
const toolUnion = mergeUnion(tools);
|
|
16716
16607
|
const toolBucketMs = toolUnion.reduce(
|
|
@@ -16740,15 +16631,12 @@ var init_b2_frame_buckets_actions = __esm({
|
|
|
16740
16631
|
"src/analyst-metric-families/b2-frame-buckets-actions.ts"() {
|
|
16741
16632
|
"use strict";
|
|
16742
16633
|
init_analyst_median();
|
|
16634
|
+
init_analyst_ledger();
|
|
16743
16635
|
b2FrameBucketsActionsFamily = {
|
|
16744
16636
|
id: "b2-frame-buckets-actions",
|
|
16745
16637
|
contribute(input) {
|
|
16746
16638
|
if (input.runs.length === 0) return void 0;
|
|
16747
|
-
const runs = [...input.runs].map(computeAnalystB2RunMetrics).sort(
|
|
16748
|
-
if (a.book !== b.book) return a.book.localeCompare(b.book);
|
|
16749
|
-
if (a.role !== b.role) return a.role.localeCompare(b.role);
|
|
16750
|
-
return a.runId.localeCompare(b.runId);
|
|
16751
|
-
});
|
|
16639
|
+
const runs = [...input.runs].map(computeAnalystB2RunMetrics).sort(compareAnalystLegs);
|
|
16752
16640
|
const section = {
|
|
16753
16641
|
kind: "analyst-b2-frame-buckets-actions",
|
|
16754
16642
|
runs
|
|
@@ -16781,11 +16669,6 @@ function projectLeg(facts) {
|
|
|
16781
16669
|
rounds
|
|
16782
16670
|
};
|
|
16783
16671
|
}
|
|
16784
|
-
function compareLegs(a, b) {
|
|
16785
|
-
if (a.book !== b.book) return a.book.localeCompare(b.book);
|
|
16786
|
-
if (a.role !== b.role) return a.role.localeCompare(b.role);
|
|
16787
|
-
return a.runId.localeCompare(b.runId);
|
|
16788
|
-
}
|
|
16789
16672
|
function emptyAccum() {
|
|
16790
16673
|
return { rounds: 0, bounceCount: 0, passCount: 0, wallSum: 0 };
|
|
16791
16674
|
}
|
|
@@ -16821,11 +16704,12 @@ var gateCyclesFamily, gate_cycles_default;
|
|
|
16821
16704
|
var init_gate_cycles = __esm({
|
|
16822
16705
|
"src/analyst-metric-families/gate-cycles.ts"() {
|
|
16823
16706
|
"use strict";
|
|
16707
|
+
init_analyst_ledger();
|
|
16824
16708
|
gateCyclesFamily = {
|
|
16825
16709
|
id: "gate-cycles",
|
|
16826
16710
|
contribute(input) {
|
|
16827
16711
|
if (input.runs.length === 0) return void 0;
|
|
16828
|
-
const legs = input.runs.map(projectLeg).sort(
|
|
16712
|
+
const legs = input.runs.map(projectLeg).sort(compareAnalystLegs);
|
|
16829
16713
|
const section = {
|
|
16830
16714
|
kind: "analyst-gate-cycles",
|
|
16831
16715
|
legs,
|
|
@@ -16839,28 +16723,24 @@ var init_gate_cycles = __esm({
|
|
|
16839
16723
|
});
|
|
16840
16724
|
|
|
16841
16725
|
// src/analyst-metric-families/leg-wall-clock.ts
|
|
16842
|
-
function frameSpanWallMs(span) {
|
|
16843
|
-
return Date.parse(span.endedAt) - Date.parse(span.startedAt);
|
|
16844
|
-
}
|
|
16845
16726
|
function projectEntry(facts) {
|
|
16846
16727
|
return {
|
|
16847
16728
|
runId: facts.runId,
|
|
16848
16729
|
book: facts.book,
|
|
16849
16730
|
role: facts.role,
|
|
16850
|
-
wallMs:
|
|
16731
|
+
wallMs: facts.frameSpan.wallMs
|
|
16851
16732
|
};
|
|
16852
16733
|
}
|
|
16853
16734
|
function compareRankingDesc(a, b) {
|
|
16854
16735
|
if (b.wallMs !== a.wallMs) return b.wallMs - a.wallMs;
|
|
16855
|
-
|
|
16856
|
-
if (a.role !== b.role) return a.role.localeCompare(b.role);
|
|
16857
|
-
return a.runId.localeCompare(b.runId);
|
|
16736
|
+
return compareAnalystLegs(a, b);
|
|
16858
16737
|
}
|
|
16859
16738
|
var legWallClockFamily, leg_wall_clock_default;
|
|
16860
16739
|
var init_leg_wall_clock = __esm({
|
|
16861
16740
|
"src/analyst-metric-families/leg-wall-clock.ts"() {
|
|
16862
16741
|
"use strict";
|
|
16863
16742
|
init_analyst_median();
|
|
16743
|
+
init_analyst_ledger();
|
|
16864
16744
|
legWallClockFamily = {
|
|
16865
16745
|
id: "leg-wall-clock",
|
|
16866
16746
|
contribute(input) {
|
|
@@ -16873,13 +16753,11 @@ var init_leg_wall_clock = __esm({
|
|
|
16873
16753
|
if (medianWallMs === void 0) {
|
|
16874
16754
|
return void 0;
|
|
16875
16755
|
}
|
|
16876
|
-
let totalElapsedMs = 0;
|
|
16877
|
-
for (const wallMs of walls) totalElapsedMs += wallMs;
|
|
16878
16756
|
const section = {
|
|
16879
16757
|
kind: "analyst-leg-wall-clock",
|
|
16880
16758
|
ranking,
|
|
16881
16759
|
medianWallMs,
|
|
16882
|
-
totalElapsedMs
|
|
16760
|
+
totalElapsedMs: sumAnalystRunWallMs(input.runs)
|
|
16883
16761
|
};
|
|
16884
16762
|
return { legWallClock: section };
|
|
16885
16763
|
}
|
|
@@ -16892,9 +16770,6 @@ var init_leg_wall_clock = __esm({
|
|
|
16892
16770
|
function isRecord14(value) {
|
|
16893
16771
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
16894
16772
|
}
|
|
16895
|
-
function wallMsFromSpan2(startedAt, endedAt) {
|
|
16896
|
-
return Date.parse(endedAt) - Date.parse(startedAt);
|
|
16897
|
-
}
|
|
16898
16773
|
function readClassCount(body) {
|
|
16899
16774
|
if (!isRecord14(body.outcome)) return void 0;
|
|
16900
16775
|
if (!isRecord14(body.outcome.decisiveFacts)) return void 0;
|
|
@@ -16931,7 +16806,7 @@ function projectRunRow(facts) {
|
|
|
16931
16806
|
role: facts.role,
|
|
16932
16807
|
startedAt,
|
|
16933
16808
|
endedAt,
|
|
16934
|
-
wallMs:
|
|
16809
|
+
wallMs: facts.frameSpan.wallMs,
|
|
16935
16810
|
terminal: projectTerminal(facts)
|
|
16936
16811
|
};
|
|
16937
16812
|
}
|
|
@@ -17063,13 +16938,9 @@ function analystIssuePageAddressFromPage(page) {
|
|
|
17063
16938
|
};
|
|
17064
16939
|
}
|
|
17065
16940
|
function sortLegs(legs) {
|
|
17066
|
-
return [...legs].sort(
|
|
17067
|
-
if (a.book !== b.book) return a.book.localeCompare(b.book);
|
|
17068
|
-
if (a.role !== b.role) return a.role.localeCompare(b.role);
|
|
17069
|
-
return a.runId.localeCompare(b.runId);
|
|
17070
|
-
});
|
|
16941
|
+
return [...legs].sort(compareAnalystLegs);
|
|
17071
16942
|
}
|
|
17072
|
-
function
|
|
16943
|
+
function sortUnreadable(unreadable) {
|
|
17073
16944
|
return [...unreadable].sort((a, b) => {
|
|
17074
16945
|
if (a.book !== b.book) return a.book.localeCompare(b.book);
|
|
17075
16946
|
return a.runId.localeCompare(b.runId);
|
|
@@ -17105,14 +16976,10 @@ function computeAnalystMsPerKLines(totalElapsedMs, changedLines) {
|
|
|
17105
16976
|
value: totalElapsedMs / (changedLines.value / 1e3)
|
|
17106
16977
|
};
|
|
17107
16978
|
}
|
|
17108
|
-
function frameSpanWallMs2(span) {
|
|
17109
|
-
return Date.parse(span.endedAt) - Date.parse(span.startedAt);
|
|
17110
|
-
}
|
|
17111
16979
|
function summarizeAnalystRunEfficiency(runs, unreadable = []) {
|
|
17112
|
-
|
|
16980
|
+
const totalElapsedMs = sumAnalystRunWallMs(runs);
|
|
17113
16981
|
let latestEndedAt;
|
|
17114
16982
|
for (const run of runs) {
|
|
17115
|
-
totalElapsedMs += frameSpanWallMs2(run.frameSpan);
|
|
17116
16983
|
const endedAt = run.frameSpan.endedAt;
|
|
17117
16984
|
if (latestEndedAt === void 0 || endedAt > latestEndedAt) {
|
|
17118
16985
|
latestEndedAt = endedAt;
|
|
@@ -17137,7 +17004,7 @@ async function buildAnalystIssueMetricsPage(input) {
|
|
|
17137
17004
|
role: run.role
|
|
17138
17005
|
}))
|
|
17139
17006
|
);
|
|
17140
|
-
const unreadable =
|
|
17007
|
+
const unreadable = sortUnreadable(input.unreadable);
|
|
17141
17008
|
const scopeConflicts = sortScopeConflicts(input.scopeConflicts ?? []);
|
|
17142
17009
|
const projectRoot = physicalPathIdentity(input.projectRoot);
|
|
17143
17010
|
const { totalElapsedMs, lastActivityAt } = summarizeAnalystRunEfficiency(
|
|
@@ -17183,11 +17050,118 @@ var init_analyst_page = __esm({
|
|
|
17183
17050
|
"use strict";
|
|
17184
17051
|
init_atomic_write();
|
|
17185
17052
|
init_activation_ledger_topology();
|
|
17053
|
+
init_analyst_ledger();
|
|
17186
17054
|
init_analyst_metric_families();
|
|
17187
17055
|
init_analyst_metric_family();
|
|
17188
17056
|
}
|
|
17189
17057
|
});
|
|
17190
17058
|
|
|
17059
|
+
// src/analyst-model-groups.ts
|
|
17060
|
+
function analystModelGroupKey(models) {
|
|
17061
|
+
if (models.length === 0) return void 0;
|
|
17062
|
+
if (models.length === 1) return models[0];
|
|
17063
|
+
return `mixed:${models.join("+")}`;
|
|
17064
|
+
}
|
|
17065
|
+
function rate(numerator, denominator) {
|
|
17066
|
+
if (denominator === 0) return void 0;
|
|
17067
|
+
return numerator / denominator;
|
|
17068
|
+
}
|
|
17069
|
+
function displayNameFor(rawGroupKey, combinationMapping) {
|
|
17070
|
+
if (combinationMapping === void 0) return rawGroupKey;
|
|
17071
|
+
const aliased = combinationMapping[rawGroupKey];
|
|
17072
|
+
return aliased === void 0 ? rawGroupKey : aliased;
|
|
17073
|
+
}
|
|
17074
|
+
function modelIdentityAbsentEntry(run) {
|
|
17075
|
+
return {
|
|
17076
|
+
runId: run.runId,
|
|
17077
|
+
book: run.book,
|
|
17078
|
+
missingSources: ["session-model"],
|
|
17079
|
+
reason: "session has no usable model identity",
|
|
17080
|
+
firstFrameAt: { status: "present", at: run.frameSpan.startedAt },
|
|
17081
|
+
// Readable legs already admitted a full span — retain end edge for lastActivityAt.
|
|
17082
|
+
lastFrameAt: { status: "present", at: run.frameSpan.endedAt }
|
|
17083
|
+
};
|
|
17084
|
+
}
|
|
17085
|
+
function buildAnalystModelGroupsPage(input) {
|
|
17086
|
+
const groupedRuns = [];
|
|
17087
|
+
const modelAbsent = [];
|
|
17088
|
+
for (const run of input.runs) {
|
|
17089
|
+
const rawGroupKey = analystModelGroupKey(run.models);
|
|
17090
|
+
if (rawGroupKey === void 0) {
|
|
17091
|
+
modelAbsent.push(modelIdentityAbsentEntry(run));
|
|
17092
|
+
} else {
|
|
17093
|
+
groupedRuns.push({ run, rawGroupKey });
|
|
17094
|
+
}
|
|
17095
|
+
}
|
|
17096
|
+
const acceptance = buildAcceptanceSuccessReworkSection(
|
|
17097
|
+
groupedRuns.map(({ run }) => run)
|
|
17098
|
+
);
|
|
17099
|
+
const legByRunId = new Map(
|
|
17100
|
+
(acceptance?.legs ?? []).map((leg) => [leg.runId, leg])
|
|
17101
|
+
);
|
|
17102
|
+
const byRaw = /* @__PURE__ */ new Map();
|
|
17103
|
+
for (const { run, rawGroupKey } of groupedRuns) {
|
|
17104
|
+
const leg = legByRunId.get(run.runId);
|
|
17105
|
+
if (leg === void 0) {
|
|
17106
|
+
throw new Error(
|
|
17107
|
+
`analyst model-groups: missing acceptance projection for run ${run.runId}`
|
|
17108
|
+
);
|
|
17109
|
+
}
|
|
17110
|
+
let acc = byRaw.get(rawGroupKey);
|
|
17111
|
+
if (acc === void 0) {
|
|
17112
|
+
acc = {
|
|
17113
|
+
acceptedCount: 0,
|
|
17114
|
+
successCount: 0,
|
|
17115
|
+
successEligibleCount: 0,
|
|
17116
|
+
noReceiptCount: 0,
|
|
17117
|
+
walls: []
|
|
17118
|
+
};
|
|
17119
|
+
byRaw.set(rawGroupKey, acc);
|
|
17120
|
+
}
|
|
17121
|
+
if (leg.accepted) acc.acceptedCount += 1;
|
|
17122
|
+
if (leg.success) acc.successCount += 1;
|
|
17123
|
+
if (leg.successEligible) acc.successEligibleCount += 1;
|
|
17124
|
+
if (leg.noReceipt) acc.noReceiptCount += 1;
|
|
17125
|
+
acc.walls.push(leg.wallMs);
|
|
17126
|
+
}
|
|
17127
|
+
const rawKeys = [...byRaw.keys()].sort((a, b) => a.localeCompare(b));
|
|
17128
|
+
const groups = rawKeys.map((rawGroupKey) => {
|
|
17129
|
+
const acc = byRaw.get(rawGroupKey);
|
|
17130
|
+
const legCount = acc.walls.length;
|
|
17131
|
+
return {
|
|
17132
|
+
rawGroupKey,
|
|
17133
|
+
displayName: displayNameFor(rawGroupKey, input.combinationMapping),
|
|
17134
|
+
legCount,
|
|
17135
|
+
acceptedCount: acc.acceptedCount,
|
|
17136
|
+
acceptanceRate: rate(acc.acceptedCount, legCount),
|
|
17137
|
+
successCount: acc.successCount,
|
|
17138
|
+
successEligibleCount: acc.successEligibleCount,
|
|
17139
|
+
successRate: rate(acc.successCount, acc.successEligibleCount),
|
|
17140
|
+
noReceiptCount: acc.noReceiptCount,
|
|
17141
|
+
noReceiptRate: rate(acc.noReceiptCount, legCount),
|
|
17142
|
+
wallClockMedianMs: medianNumber(acc.walls)
|
|
17143
|
+
};
|
|
17144
|
+
});
|
|
17145
|
+
const unreadable = sortUnreadable([...input.unreadable, ...modelAbsent]);
|
|
17146
|
+
return {
|
|
17147
|
+
kind: "analyst-model-groups",
|
|
17148
|
+
mode: "model-groups",
|
|
17149
|
+
projectRoots: [...input.projectRoots].sort((a, b) => a.localeCompare(b)),
|
|
17150
|
+
groups,
|
|
17151
|
+
legCount: groupedRuns.length,
|
|
17152
|
+
unreadableCount: unreadable.length,
|
|
17153
|
+
unreadable
|
|
17154
|
+
};
|
|
17155
|
+
}
|
|
17156
|
+
var init_analyst_model_groups = __esm({
|
|
17157
|
+
"src/analyst-model-groups.ts"() {
|
|
17158
|
+
"use strict";
|
|
17159
|
+
init_acceptance_success_rework();
|
|
17160
|
+
init_analyst_median();
|
|
17161
|
+
init_analyst_page();
|
|
17162
|
+
}
|
|
17163
|
+
});
|
|
17164
|
+
|
|
17191
17165
|
// src/analyst-entry.ts
|
|
17192
17166
|
import { readFile as readFile20 } from "node:fs/promises";
|
|
17193
17167
|
import { Type as Type12 } from "typebox";
|