@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
|
@@ -15559,11 +15559,21 @@ function admitFrameSpanFromRows(rows) {
|
|
|
15559
15559
|
}
|
|
15560
15560
|
return {
|
|
15561
15561
|
models,
|
|
15562
|
-
frameSpan: { startedAt: span.startedAt, endedAt: span.endedAt },
|
|
15562
|
+
frameSpan: { startedAt: span.startedAt, endedAt: span.endedAt, wallMs: endedMs - startedMs },
|
|
15563
15563
|
partialFirstFrameAt: { status: "present", at: span.startedAt },
|
|
15564
15564
|
partialLastFrameAt: { status: "present", at: span.endedAt }
|
|
15565
15565
|
};
|
|
15566
15566
|
}
|
|
15567
|
+
function sumAnalystRunWallMs(runs) {
|
|
15568
|
+
let total = 0;
|
|
15569
|
+
for (const run of runs) total += run.frameSpan.wallMs;
|
|
15570
|
+
return total;
|
|
15571
|
+
}
|
|
15572
|
+
function compareAnalystLegs(a, b) {
|
|
15573
|
+
if (a.book !== b.book) return a.book.localeCompare(b.book);
|
|
15574
|
+
if (a.role !== b.role) return a.role.localeCompare(b.role);
|
|
15575
|
+
return a.runId.localeCompare(b.runId);
|
|
15576
|
+
}
|
|
15567
15577
|
async function classifyScopedRun(input) {
|
|
15568
15578
|
const missingSources = [];
|
|
15569
15579
|
const reasons = [];
|
|
@@ -15844,9 +15854,6 @@ var init_analyst_ledger = __esm({
|
|
|
15844
15854
|
function isRecord13(value) {
|
|
15845
15855
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
15846
15856
|
}
|
|
15847
|
-
function wallMsFromSpan(span) {
|
|
15848
|
-
return Date.parse(span.endedAt) - Date.parse(span.startedAt);
|
|
15849
|
-
}
|
|
15850
15857
|
function findCollectorGroups(body) {
|
|
15851
15858
|
if (Array.isArray(body.groups)) return body.groups;
|
|
15852
15859
|
const receipt = body.receipt;
|
|
@@ -15955,7 +15962,7 @@ function projectLegs(runs) {
|
|
|
15955
15962
|
book: run.book,
|
|
15956
15963
|
role: run.role,
|
|
15957
15964
|
startedAt: run.frameSpan.startedAt,
|
|
15958
|
-
wallMs:
|
|
15965
|
+
wallMs: run.frameSpan.wallMs,
|
|
15959
15966
|
terminalLabel: mapped.terminalLabel,
|
|
15960
15967
|
accepted: mapped.accepted,
|
|
15961
15968
|
success: mapped.success,
|
|
@@ -15965,11 +15972,7 @@ function projectLegs(runs) {
|
|
|
15965
15972
|
rework: ordinal >= 2
|
|
15966
15973
|
});
|
|
15967
15974
|
}
|
|
15968
|
-
return legs.sort(
|
|
15969
|
-
if (a.book !== b.book) return a.book.localeCompare(b.book);
|
|
15970
|
-
if (a.role !== b.role) return a.role.localeCompare(b.role);
|
|
15971
|
-
return a.runId.localeCompare(b.runId);
|
|
15972
|
-
});
|
|
15975
|
+
return legs.sort(compareAnalystLegs);
|
|
15973
15976
|
}
|
|
15974
15977
|
function aggregateByRole(legs) {
|
|
15975
15978
|
const roles = [...new Set(legs.map((leg) => leg.role))].sort((a, b) => a.localeCompare(b));
|
|
@@ -16013,12 +16016,10 @@ function aggregateByRole(legs) {
|
|
|
16013
16016
|
};
|
|
16014
16017
|
});
|
|
16015
16018
|
}
|
|
16016
|
-
function reworkLens(legs) {
|
|
16019
|
+
function reworkLens(legs, totalWallMs) {
|
|
16017
16020
|
let reworkWallMs = 0;
|
|
16018
|
-
let totalWallMs = 0;
|
|
16019
16021
|
let reworkLegCount = 0;
|
|
16020
16022
|
for (const leg of legs) {
|
|
16021
|
-
totalWallMs += leg.wallMs;
|
|
16022
16023
|
if (leg.rework) {
|
|
16023
16024
|
reworkWallMs += leg.wallMs;
|
|
16024
16025
|
reworkLegCount += 1;
|
|
@@ -16039,13 +16040,14 @@ function buildAcceptanceSuccessReworkSection(runs) {
|
|
|
16039
16040
|
kind: "analyst-acceptance-success-rework",
|
|
16040
16041
|
legs,
|
|
16041
16042
|
byRole: aggregateByRole(legs),
|
|
16042
|
-
rework: reworkLens(legs)
|
|
16043
|
+
rework: reworkLens(legs, sumAnalystRunWallMs(runs))
|
|
16043
16044
|
};
|
|
16044
16045
|
}
|
|
16045
16046
|
var WORKER_ROLES, ACCEPTED_STATUS, SUCCESS_STATUS, acceptanceSuccessReworkFamily, acceptance_success_rework_default;
|
|
16046
16047
|
var init_acceptance_success_rework = __esm({
|
|
16047
16048
|
"src/analyst-metric-families/acceptance-success-rework.ts"() {
|
|
16048
16049
|
"use strict";
|
|
16050
|
+
init_analyst_ledger();
|
|
16049
16051
|
init_analyst_median();
|
|
16050
16052
|
init_packaged_role_registry();
|
|
16051
16053
|
WORKER_ROLES = /* @__PURE__ */ new Set(["coder", "fixer"]);
|
|
@@ -16078,117 +16080,6 @@ var init_acceptance_success_rework = __esm({
|
|
|
16078
16080
|
}
|
|
16079
16081
|
});
|
|
16080
16082
|
|
|
16081
|
-
// src/analyst-model-groups.ts
|
|
16082
|
-
function analystModelGroupKey(models) {
|
|
16083
|
-
if (models.length === 0) return void 0;
|
|
16084
|
-
if (models.length === 1) return models[0];
|
|
16085
|
-
return `mixed:${models.join("+")}`;
|
|
16086
|
-
}
|
|
16087
|
-
function rate(numerator, denominator) {
|
|
16088
|
-
if (denominator === 0) return void 0;
|
|
16089
|
-
return numerator / denominator;
|
|
16090
|
-
}
|
|
16091
|
-
function displayNameFor(rawGroupKey, combinationMapping) {
|
|
16092
|
-
if (combinationMapping === void 0) return rawGroupKey;
|
|
16093
|
-
const aliased = combinationMapping[rawGroupKey];
|
|
16094
|
-
return aliased === void 0 ? rawGroupKey : aliased;
|
|
16095
|
-
}
|
|
16096
|
-
function sortUnreadable(unreadable) {
|
|
16097
|
-
return [...unreadable].sort((a, b) => {
|
|
16098
|
-
if (a.book !== b.book) return a.book.localeCompare(b.book);
|
|
16099
|
-
return a.runId.localeCompare(b.runId);
|
|
16100
|
-
});
|
|
16101
|
-
}
|
|
16102
|
-
function modelIdentityAbsentEntry(run) {
|
|
16103
|
-
return {
|
|
16104
|
-
runId: run.runId,
|
|
16105
|
-
book: run.book,
|
|
16106
|
-
missingSources: ["session-model"],
|
|
16107
|
-
reason: "session has no usable model identity",
|
|
16108
|
-
firstFrameAt: { status: "present", at: run.frameSpan.startedAt },
|
|
16109
|
-
// Readable legs already admitted a full span — retain end edge for lastActivityAt.
|
|
16110
|
-
lastFrameAt: { status: "present", at: run.frameSpan.endedAt }
|
|
16111
|
-
};
|
|
16112
|
-
}
|
|
16113
|
-
function buildAnalystModelGroupsPage(input) {
|
|
16114
|
-
const groupedRuns = [];
|
|
16115
|
-
const modelAbsent = [];
|
|
16116
|
-
for (const run of input.runs) {
|
|
16117
|
-
const rawGroupKey = analystModelGroupKey(run.models);
|
|
16118
|
-
if (rawGroupKey === void 0) {
|
|
16119
|
-
modelAbsent.push(modelIdentityAbsentEntry(run));
|
|
16120
|
-
} else {
|
|
16121
|
-
groupedRuns.push({ run, rawGroupKey });
|
|
16122
|
-
}
|
|
16123
|
-
}
|
|
16124
|
-
const acceptance = buildAcceptanceSuccessReworkSection(
|
|
16125
|
-
groupedRuns.map(({ run }) => run)
|
|
16126
|
-
);
|
|
16127
|
-
const legByRunId = new Map(
|
|
16128
|
-
(acceptance?.legs ?? []).map((leg) => [leg.runId, leg])
|
|
16129
|
-
);
|
|
16130
|
-
const byRaw = /* @__PURE__ */ new Map();
|
|
16131
|
-
for (const { run, rawGroupKey } of groupedRuns) {
|
|
16132
|
-
const leg = legByRunId.get(run.runId);
|
|
16133
|
-
if (leg === void 0) {
|
|
16134
|
-
throw new Error(
|
|
16135
|
-
`analyst model-groups: missing acceptance projection for run ${run.runId}`
|
|
16136
|
-
);
|
|
16137
|
-
}
|
|
16138
|
-
let acc = byRaw.get(rawGroupKey);
|
|
16139
|
-
if (acc === void 0) {
|
|
16140
|
-
acc = {
|
|
16141
|
-
acceptedCount: 0,
|
|
16142
|
-
successCount: 0,
|
|
16143
|
-
successEligibleCount: 0,
|
|
16144
|
-
noReceiptCount: 0,
|
|
16145
|
-
walls: []
|
|
16146
|
-
};
|
|
16147
|
-
byRaw.set(rawGroupKey, acc);
|
|
16148
|
-
}
|
|
16149
|
-
if (leg.accepted) acc.acceptedCount += 1;
|
|
16150
|
-
if (leg.success) acc.successCount += 1;
|
|
16151
|
-
if (leg.successEligible) acc.successEligibleCount += 1;
|
|
16152
|
-
if (leg.noReceipt) acc.noReceiptCount += 1;
|
|
16153
|
-
acc.walls.push(leg.wallMs);
|
|
16154
|
-
}
|
|
16155
|
-
const rawKeys = [...byRaw.keys()].sort((a, b) => a.localeCompare(b));
|
|
16156
|
-
const groups = rawKeys.map((rawGroupKey) => {
|
|
16157
|
-
const acc = byRaw.get(rawGroupKey);
|
|
16158
|
-
const legCount = acc.walls.length;
|
|
16159
|
-
return {
|
|
16160
|
-
rawGroupKey,
|
|
16161
|
-
displayName: displayNameFor(rawGroupKey, input.combinationMapping),
|
|
16162
|
-
legCount,
|
|
16163
|
-
acceptedCount: acc.acceptedCount,
|
|
16164
|
-
acceptanceRate: rate(acc.acceptedCount, legCount),
|
|
16165
|
-
successCount: acc.successCount,
|
|
16166
|
-
successEligibleCount: acc.successEligibleCount,
|
|
16167
|
-
successRate: rate(acc.successCount, acc.successEligibleCount),
|
|
16168
|
-
noReceiptCount: acc.noReceiptCount,
|
|
16169
|
-
noReceiptRate: rate(acc.noReceiptCount, legCount),
|
|
16170
|
-
wallClockMedianMs: medianNumber(acc.walls)
|
|
16171
|
-
};
|
|
16172
|
-
});
|
|
16173
|
-
const unreadable = sortUnreadable([...input.unreadable, ...modelAbsent]);
|
|
16174
|
-
return {
|
|
16175
|
-
kind: "analyst-model-groups",
|
|
16176
|
-
mode: "model-groups",
|
|
16177
|
-
projectRoots: [...input.projectRoots].sort((a, b) => a.localeCompare(b)),
|
|
16178
|
-
groups,
|
|
16179
|
-
legCount: groupedRuns.length,
|
|
16180
|
-
unreadableCount: unreadable.length,
|
|
16181
|
-
unreadable
|
|
16182
|
-
};
|
|
16183
|
-
}
|
|
16184
|
-
var init_analyst_model_groups = __esm({
|
|
16185
|
-
"src/analyst-model-groups.ts"() {
|
|
16186
|
-
"use strict";
|
|
16187
|
-
init_acceptance_success_rework();
|
|
16188
|
-
init_analyst_median();
|
|
16189
|
-
}
|
|
16190
|
-
});
|
|
16191
|
-
|
|
16192
16083
|
// src/analyst-metric-families/b2-frame-buckets-actions.ts
|
|
16193
16084
|
function timestampMs(iso) {
|
|
16194
16085
|
const ms = Date.parse(iso);
|
|
@@ -16311,7 +16202,7 @@ function sortActionsDescending(actions) {
|
|
|
16311
16202
|
function computeAnalystB2RunMetrics(facts) {
|
|
16312
16203
|
const frameStartMs = timestampMs(facts.frameSpan.startedAt);
|
|
16313
16204
|
const frameEndMs = timestampMs(facts.frameSpan.endedAt);
|
|
16314
|
-
const wallMs =
|
|
16205
|
+
const wallMs = facts.frameSpan.wallMs;
|
|
16315
16206
|
const tools = clipToolsToFrame(closedTools(facts.toolIntervals), frameStartMs, frameEndMs);
|
|
16316
16207
|
const toolUnion = mergeUnion(tools);
|
|
16317
16208
|
const toolBucketMs = toolUnion.reduce(
|
|
@@ -16341,15 +16232,12 @@ var init_b2_frame_buckets_actions = __esm({
|
|
|
16341
16232
|
"src/analyst-metric-families/b2-frame-buckets-actions.ts"() {
|
|
16342
16233
|
"use strict";
|
|
16343
16234
|
init_analyst_median();
|
|
16235
|
+
init_analyst_ledger();
|
|
16344
16236
|
b2FrameBucketsActionsFamily = {
|
|
16345
16237
|
id: "b2-frame-buckets-actions",
|
|
16346
16238
|
contribute(input) {
|
|
16347
16239
|
if (input.runs.length === 0) return void 0;
|
|
16348
|
-
const runs = [...input.runs].map(computeAnalystB2RunMetrics).sort(
|
|
16349
|
-
if (a.book !== b.book) return a.book.localeCompare(b.book);
|
|
16350
|
-
if (a.role !== b.role) return a.role.localeCompare(b.role);
|
|
16351
|
-
return a.runId.localeCompare(b.runId);
|
|
16352
|
-
});
|
|
16240
|
+
const runs = [...input.runs].map(computeAnalystB2RunMetrics).sort(compareAnalystLegs);
|
|
16353
16241
|
const section = {
|
|
16354
16242
|
kind: "analyst-b2-frame-buckets-actions",
|
|
16355
16243
|
runs
|
|
@@ -16382,11 +16270,6 @@ function projectLeg(facts) {
|
|
|
16382
16270
|
rounds
|
|
16383
16271
|
};
|
|
16384
16272
|
}
|
|
16385
|
-
function compareLegs(a, b) {
|
|
16386
|
-
if (a.book !== b.book) return a.book.localeCompare(b.book);
|
|
16387
|
-
if (a.role !== b.role) return a.role.localeCompare(b.role);
|
|
16388
|
-
return a.runId.localeCompare(b.runId);
|
|
16389
|
-
}
|
|
16390
16273
|
function emptyAccum() {
|
|
16391
16274
|
return { rounds: 0, bounceCount: 0, passCount: 0, wallSum: 0 };
|
|
16392
16275
|
}
|
|
@@ -16422,11 +16305,12 @@ var gateCyclesFamily, gate_cycles_default;
|
|
|
16422
16305
|
var init_gate_cycles = __esm({
|
|
16423
16306
|
"src/analyst-metric-families/gate-cycles.ts"() {
|
|
16424
16307
|
"use strict";
|
|
16308
|
+
init_analyst_ledger();
|
|
16425
16309
|
gateCyclesFamily = {
|
|
16426
16310
|
id: "gate-cycles",
|
|
16427
16311
|
contribute(input) {
|
|
16428
16312
|
if (input.runs.length === 0) return void 0;
|
|
16429
|
-
const legs = input.runs.map(projectLeg).sort(
|
|
16313
|
+
const legs = input.runs.map(projectLeg).sort(compareAnalystLegs);
|
|
16430
16314
|
const section = {
|
|
16431
16315
|
kind: "analyst-gate-cycles",
|
|
16432
16316
|
legs,
|
|
@@ -16440,28 +16324,24 @@ var init_gate_cycles = __esm({
|
|
|
16440
16324
|
});
|
|
16441
16325
|
|
|
16442
16326
|
// src/analyst-metric-families/leg-wall-clock.ts
|
|
16443
|
-
function frameSpanWallMs(span) {
|
|
16444
|
-
return Date.parse(span.endedAt) - Date.parse(span.startedAt);
|
|
16445
|
-
}
|
|
16446
16327
|
function projectEntry(facts) {
|
|
16447
16328
|
return {
|
|
16448
16329
|
runId: facts.runId,
|
|
16449
16330
|
book: facts.book,
|
|
16450
16331
|
role: facts.role,
|
|
16451
|
-
wallMs:
|
|
16332
|
+
wallMs: facts.frameSpan.wallMs
|
|
16452
16333
|
};
|
|
16453
16334
|
}
|
|
16454
16335
|
function compareRankingDesc(a, b) {
|
|
16455
16336
|
if (b.wallMs !== a.wallMs) return b.wallMs - a.wallMs;
|
|
16456
|
-
|
|
16457
|
-
if (a.role !== b.role) return a.role.localeCompare(b.role);
|
|
16458
|
-
return a.runId.localeCompare(b.runId);
|
|
16337
|
+
return compareAnalystLegs(a, b);
|
|
16459
16338
|
}
|
|
16460
16339
|
var legWallClockFamily, leg_wall_clock_default;
|
|
16461
16340
|
var init_leg_wall_clock = __esm({
|
|
16462
16341
|
"src/analyst-metric-families/leg-wall-clock.ts"() {
|
|
16463
16342
|
"use strict";
|
|
16464
16343
|
init_analyst_median();
|
|
16344
|
+
init_analyst_ledger();
|
|
16465
16345
|
legWallClockFamily = {
|
|
16466
16346
|
id: "leg-wall-clock",
|
|
16467
16347
|
contribute(input) {
|
|
@@ -16474,13 +16354,11 @@ var init_leg_wall_clock = __esm({
|
|
|
16474
16354
|
if (medianWallMs === void 0) {
|
|
16475
16355
|
return void 0;
|
|
16476
16356
|
}
|
|
16477
|
-
let totalElapsedMs = 0;
|
|
16478
|
-
for (const wallMs of walls) totalElapsedMs += wallMs;
|
|
16479
16357
|
const section = {
|
|
16480
16358
|
kind: "analyst-leg-wall-clock",
|
|
16481
16359
|
ranking,
|
|
16482
16360
|
medianWallMs,
|
|
16483
|
-
totalElapsedMs
|
|
16361
|
+
totalElapsedMs: sumAnalystRunWallMs(input.runs)
|
|
16484
16362
|
};
|
|
16485
16363
|
return { legWallClock: section };
|
|
16486
16364
|
}
|
|
@@ -16493,9 +16371,6 @@ var init_leg_wall_clock = __esm({
|
|
|
16493
16371
|
function isRecord14(value) {
|
|
16494
16372
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
16495
16373
|
}
|
|
16496
|
-
function wallMsFromSpan2(startedAt, endedAt) {
|
|
16497
|
-
return Date.parse(endedAt) - Date.parse(startedAt);
|
|
16498
|
-
}
|
|
16499
16374
|
function readClassCount(body) {
|
|
16500
16375
|
if (!isRecord14(body.outcome)) return void 0;
|
|
16501
16376
|
if (!isRecord14(body.outcome.decisiveFacts)) return void 0;
|
|
@@ -16532,7 +16407,7 @@ function projectRunRow(facts) {
|
|
|
16532
16407
|
role: facts.role,
|
|
16533
16408
|
startedAt,
|
|
16534
16409
|
endedAt,
|
|
16535
|
-
wallMs:
|
|
16410
|
+
wallMs: facts.frameSpan.wallMs,
|
|
16536
16411
|
terminal: projectTerminal(facts)
|
|
16537
16412
|
};
|
|
16538
16413
|
}
|
|
@@ -16664,13 +16539,9 @@ function analystIssuePageAddressFromPage(page) {
|
|
|
16664
16539
|
};
|
|
16665
16540
|
}
|
|
16666
16541
|
function sortLegs(legs) {
|
|
16667
|
-
return [...legs].sort(
|
|
16668
|
-
if (a.book !== b.book) return a.book.localeCompare(b.book);
|
|
16669
|
-
if (a.role !== b.role) return a.role.localeCompare(b.role);
|
|
16670
|
-
return a.runId.localeCompare(b.runId);
|
|
16671
|
-
});
|
|
16542
|
+
return [...legs].sort(compareAnalystLegs);
|
|
16672
16543
|
}
|
|
16673
|
-
function
|
|
16544
|
+
function sortUnreadable(unreadable) {
|
|
16674
16545
|
return [...unreadable].sort((a, b) => {
|
|
16675
16546
|
if (a.book !== b.book) return a.book.localeCompare(b.book);
|
|
16676
16547
|
return a.runId.localeCompare(b.runId);
|
|
@@ -16706,14 +16577,10 @@ function computeAnalystMsPerKLines(totalElapsedMs, changedLines) {
|
|
|
16706
16577
|
value: totalElapsedMs / (changedLines.value / 1e3)
|
|
16707
16578
|
};
|
|
16708
16579
|
}
|
|
16709
|
-
function frameSpanWallMs2(span) {
|
|
16710
|
-
return Date.parse(span.endedAt) - Date.parse(span.startedAt);
|
|
16711
|
-
}
|
|
16712
16580
|
function summarizeAnalystRunEfficiency(runs, unreadable = []) {
|
|
16713
|
-
|
|
16581
|
+
const totalElapsedMs = sumAnalystRunWallMs(runs);
|
|
16714
16582
|
let latestEndedAt;
|
|
16715
16583
|
for (const run of runs) {
|
|
16716
|
-
totalElapsedMs += frameSpanWallMs2(run.frameSpan);
|
|
16717
16584
|
const endedAt = run.frameSpan.endedAt;
|
|
16718
16585
|
if (latestEndedAt === void 0 || endedAt > latestEndedAt) {
|
|
16719
16586
|
latestEndedAt = endedAt;
|
|
@@ -16738,7 +16605,7 @@ async function buildAnalystIssueMetricsPage(input) {
|
|
|
16738
16605
|
role: run.role
|
|
16739
16606
|
}))
|
|
16740
16607
|
);
|
|
16741
|
-
const unreadable =
|
|
16608
|
+
const unreadable = sortUnreadable(input.unreadable);
|
|
16742
16609
|
const scopeConflicts = sortScopeConflicts(input.scopeConflicts ?? []);
|
|
16743
16610
|
const projectRoot = physicalPathIdentity(input.projectRoot);
|
|
16744
16611
|
const { totalElapsedMs, lastActivityAt } = summarizeAnalystRunEfficiency(
|
|
@@ -16784,11 +16651,118 @@ var init_analyst_page = __esm({
|
|
|
16784
16651
|
"use strict";
|
|
16785
16652
|
init_atomic_write();
|
|
16786
16653
|
init_activation_ledger_topology();
|
|
16654
|
+
init_analyst_ledger();
|
|
16787
16655
|
init_analyst_metric_families();
|
|
16788
16656
|
init_analyst_metric_family();
|
|
16789
16657
|
}
|
|
16790
16658
|
});
|
|
16791
16659
|
|
|
16660
|
+
// src/analyst-model-groups.ts
|
|
16661
|
+
function analystModelGroupKey(models) {
|
|
16662
|
+
if (models.length === 0) return void 0;
|
|
16663
|
+
if (models.length === 1) return models[0];
|
|
16664
|
+
return `mixed:${models.join("+")}`;
|
|
16665
|
+
}
|
|
16666
|
+
function rate(numerator, denominator) {
|
|
16667
|
+
if (denominator === 0) return void 0;
|
|
16668
|
+
return numerator / denominator;
|
|
16669
|
+
}
|
|
16670
|
+
function displayNameFor(rawGroupKey, combinationMapping) {
|
|
16671
|
+
if (combinationMapping === void 0) return rawGroupKey;
|
|
16672
|
+
const aliased = combinationMapping[rawGroupKey];
|
|
16673
|
+
return aliased === void 0 ? rawGroupKey : aliased;
|
|
16674
|
+
}
|
|
16675
|
+
function modelIdentityAbsentEntry(run) {
|
|
16676
|
+
return {
|
|
16677
|
+
runId: run.runId,
|
|
16678
|
+
book: run.book,
|
|
16679
|
+
missingSources: ["session-model"],
|
|
16680
|
+
reason: "session has no usable model identity",
|
|
16681
|
+
firstFrameAt: { status: "present", at: run.frameSpan.startedAt },
|
|
16682
|
+
// Readable legs already admitted a full span — retain end edge for lastActivityAt.
|
|
16683
|
+
lastFrameAt: { status: "present", at: run.frameSpan.endedAt }
|
|
16684
|
+
};
|
|
16685
|
+
}
|
|
16686
|
+
function buildAnalystModelGroupsPage(input) {
|
|
16687
|
+
const groupedRuns = [];
|
|
16688
|
+
const modelAbsent = [];
|
|
16689
|
+
for (const run of input.runs) {
|
|
16690
|
+
const rawGroupKey = analystModelGroupKey(run.models);
|
|
16691
|
+
if (rawGroupKey === void 0) {
|
|
16692
|
+
modelAbsent.push(modelIdentityAbsentEntry(run));
|
|
16693
|
+
} else {
|
|
16694
|
+
groupedRuns.push({ run, rawGroupKey });
|
|
16695
|
+
}
|
|
16696
|
+
}
|
|
16697
|
+
const acceptance = buildAcceptanceSuccessReworkSection(
|
|
16698
|
+
groupedRuns.map(({ run }) => run)
|
|
16699
|
+
);
|
|
16700
|
+
const legByRunId = new Map(
|
|
16701
|
+
(acceptance?.legs ?? []).map((leg) => [leg.runId, leg])
|
|
16702
|
+
);
|
|
16703
|
+
const byRaw = /* @__PURE__ */ new Map();
|
|
16704
|
+
for (const { run, rawGroupKey } of groupedRuns) {
|
|
16705
|
+
const leg = legByRunId.get(run.runId);
|
|
16706
|
+
if (leg === void 0) {
|
|
16707
|
+
throw new Error(
|
|
16708
|
+
`analyst model-groups: missing acceptance projection for run ${run.runId}`
|
|
16709
|
+
);
|
|
16710
|
+
}
|
|
16711
|
+
let acc = byRaw.get(rawGroupKey);
|
|
16712
|
+
if (acc === void 0) {
|
|
16713
|
+
acc = {
|
|
16714
|
+
acceptedCount: 0,
|
|
16715
|
+
successCount: 0,
|
|
16716
|
+
successEligibleCount: 0,
|
|
16717
|
+
noReceiptCount: 0,
|
|
16718
|
+
walls: []
|
|
16719
|
+
};
|
|
16720
|
+
byRaw.set(rawGroupKey, acc);
|
|
16721
|
+
}
|
|
16722
|
+
if (leg.accepted) acc.acceptedCount += 1;
|
|
16723
|
+
if (leg.success) acc.successCount += 1;
|
|
16724
|
+
if (leg.successEligible) acc.successEligibleCount += 1;
|
|
16725
|
+
if (leg.noReceipt) acc.noReceiptCount += 1;
|
|
16726
|
+
acc.walls.push(leg.wallMs);
|
|
16727
|
+
}
|
|
16728
|
+
const rawKeys = [...byRaw.keys()].sort((a, b) => a.localeCompare(b));
|
|
16729
|
+
const groups = rawKeys.map((rawGroupKey) => {
|
|
16730
|
+
const acc = byRaw.get(rawGroupKey);
|
|
16731
|
+
const legCount = acc.walls.length;
|
|
16732
|
+
return {
|
|
16733
|
+
rawGroupKey,
|
|
16734
|
+
displayName: displayNameFor(rawGroupKey, input.combinationMapping),
|
|
16735
|
+
legCount,
|
|
16736
|
+
acceptedCount: acc.acceptedCount,
|
|
16737
|
+
acceptanceRate: rate(acc.acceptedCount, legCount),
|
|
16738
|
+
successCount: acc.successCount,
|
|
16739
|
+
successEligibleCount: acc.successEligibleCount,
|
|
16740
|
+
successRate: rate(acc.successCount, acc.successEligibleCount),
|
|
16741
|
+
noReceiptCount: acc.noReceiptCount,
|
|
16742
|
+
noReceiptRate: rate(acc.noReceiptCount, legCount),
|
|
16743
|
+
wallClockMedianMs: medianNumber(acc.walls)
|
|
16744
|
+
};
|
|
16745
|
+
});
|
|
16746
|
+
const unreadable = sortUnreadable([...input.unreadable, ...modelAbsent]);
|
|
16747
|
+
return {
|
|
16748
|
+
kind: "analyst-model-groups",
|
|
16749
|
+
mode: "model-groups",
|
|
16750
|
+
projectRoots: [...input.projectRoots].sort((a, b) => a.localeCompare(b)),
|
|
16751
|
+
groups,
|
|
16752
|
+
legCount: groupedRuns.length,
|
|
16753
|
+
unreadableCount: unreadable.length,
|
|
16754
|
+
unreadable
|
|
16755
|
+
};
|
|
16756
|
+
}
|
|
16757
|
+
var init_analyst_model_groups = __esm({
|
|
16758
|
+
"src/analyst-model-groups.ts"() {
|
|
16759
|
+
"use strict";
|
|
16760
|
+
init_acceptance_success_rework();
|
|
16761
|
+
init_analyst_median();
|
|
16762
|
+
init_analyst_page();
|
|
16763
|
+
}
|
|
16764
|
+
});
|
|
16765
|
+
|
|
16792
16766
|
// src/analyst-entry.ts
|
|
16793
16767
|
import { readFile as readFile19 } from "node:fs/promises";
|
|
16794
16768
|
import { Type as Type11 } from "typebox";
|
package/dist/analyst-ledger.js
CHANGED
|
@@ -212,11 +212,26 @@ function admitFrameSpanFromRows(rows) {
|
|
|
212
212
|
}
|
|
213
213
|
return {
|
|
214
214
|
models,
|
|
215
|
-
frameSpan: { startedAt: span.startedAt, endedAt: span.endedAt },
|
|
215
|
+
frameSpan: { startedAt: span.startedAt, endedAt: span.endedAt, wallMs: endedMs - startedMs },
|
|
216
216
|
partialFirstFrameAt: { status: "present", at: span.startedAt },
|
|
217
217
|
partialLastFrameAt: { status: "present", at: span.endedAt },
|
|
218
218
|
};
|
|
219
219
|
}
|
|
220
|
+
/** Total wall clock for exactly the readable runs supplied by the caller. */
|
|
221
|
+
export function sumAnalystRunWallMs(runs) {
|
|
222
|
+
let total = 0;
|
|
223
|
+
for (const run of runs)
|
|
224
|
+
total += run.frameSpan.wallMs;
|
|
225
|
+
return total;
|
|
226
|
+
}
|
|
227
|
+
/** Shared identity order for readable legs and their page/metric projections. */
|
|
228
|
+
export function compareAnalystLegs(a, b) {
|
|
229
|
+
if (a.book !== b.book)
|
|
230
|
+
return a.book.localeCompare(b.book);
|
|
231
|
+
if (a.role !== b.role)
|
|
232
|
+
return a.role.localeCompare(b.role);
|
|
233
|
+
return a.runId.localeCompare(b.runId);
|
|
234
|
+
}
|
|
220
235
|
async function classifyScopedRun(input) {
|
|
221
236
|
const missingSources = [];
|
|
222
237
|
const reasons = [];
|
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* B3 metric family: acceptance terminal mapping, rework lens, first-pass / success rates.
|
|
3
|
+
*
|
|
4
|
+
* Consumes only A2 typed per-run facts (frame span + terminal face). Drop-in
|
|
5
|
+
* registration via analyst-metric-families/ discovery — no shared skeleton edits.
|
|
6
|
+
*
|
|
7
|
+
* Denominator contract (PRD #298 + ticket #327 票面补正):
|
|
8
|
+
* - first-pass rate den = appearance lanes (no-receipt first call stays in den)
|
|
9
|
+
* - success rate den = success-eligible accepted legs (no-receipt out; planned out)
|
|
10
|
+
* - planned = plan-duty acceptance; never success numerator or denominator
|
|
11
|
+
*/
|
|
12
|
+
import { compareAnalystLegs, sumAnalystRunWallMs } from "../analyst-ledger.js";
|
|
1
13
|
import { medianNumber } from "../analyst-median.js";
|
|
2
14
|
import { packagedAnalystTerminal } from "../packaged-role-registry.js";
|
|
3
15
|
const WORKER_ROLES = new Set(["coder", "fixer"]);
|
|
@@ -23,9 +35,6 @@ const SUCCESS_STATUS = {
|
|
|
23
35
|
function isRecord(value) {
|
|
24
36
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
25
37
|
}
|
|
26
|
-
function wallMsFromSpan(span) {
|
|
27
|
-
return Date.parse(span.endedAt) - Date.parse(span.startedAt);
|
|
28
|
-
}
|
|
29
38
|
/** Locate collector groups array: receipt.groups or top-level groups. */
|
|
30
39
|
function findCollectorGroups(body) {
|
|
31
40
|
if (Array.isArray(body.groups))
|
|
@@ -143,7 +152,7 @@ function projectLegs(runs) {
|
|
|
143
152
|
book: run.book,
|
|
144
153
|
role: run.role,
|
|
145
154
|
startedAt: run.frameSpan.startedAt,
|
|
146
|
-
wallMs:
|
|
155
|
+
wallMs: run.frameSpan.wallMs,
|
|
147
156
|
terminalLabel: mapped.terminalLabel,
|
|
148
157
|
accepted: mapped.accepted,
|
|
149
158
|
success: mapped.success,
|
|
@@ -154,13 +163,7 @@ function projectLegs(runs) {
|
|
|
154
163
|
});
|
|
155
164
|
}
|
|
156
165
|
// Stable page order: book, role, runId (match A1 leg sort).
|
|
157
|
-
return legs.sort(
|
|
158
|
-
if (a.book !== b.book)
|
|
159
|
-
return a.book.localeCompare(b.book);
|
|
160
|
-
if (a.role !== b.role)
|
|
161
|
-
return a.role.localeCompare(b.role);
|
|
162
|
-
return a.runId.localeCompare(b.runId);
|
|
163
|
-
});
|
|
166
|
+
return legs.sort(compareAnalystLegs);
|
|
164
167
|
}
|
|
165
168
|
function aggregateByRole(legs) {
|
|
166
169
|
const roles = [...new Set(legs.map((leg) => leg.role))].sort((a, b) => a.localeCompare(b));
|
|
@@ -207,12 +210,10 @@ function aggregateByRole(legs) {
|
|
|
207
210
|
};
|
|
208
211
|
});
|
|
209
212
|
}
|
|
210
|
-
function reworkLens(legs) {
|
|
213
|
+
function reworkLens(legs, totalWallMs) {
|
|
211
214
|
let reworkWallMs = 0;
|
|
212
|
-
let totalWallMs = 0;
|
|
213
215
|
let reworkLegCount = 0;
|
|
214
216
|
for (const leg of legs) {
|
|
215
|
-
totalWallMs += leg.wallMs;
|
|
216
217
|
if (leg.rework) {
|
|
217
218
|
reworkWallMs += leg.wallMs;
|
|
218
219
|
reworkLegCount += 1;
|
|
@@ -234,7 +235,7 @@ export function buildAcceptanceSuccessReworkSection(runs) {
|
|
|
234
235
|
kind: "analyst-acceptance-success-rework",
|
|
235
236
|
legs,
|
|
236
237
|
byRole: aggregateByRole(legs),
|
|
237
|
-
rework: reworkLens(legs),
|
|
238
|
+
rework: reworkLens(legs, sumAnalystRunWallMs(runs)),
|
|
238
239
|
};
|
|
239
240
|
}
|
|
240
241
|
const acceptanceSuccessReworkFamily = {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { medianNumber } from "../analyst-median.js";
|
|
2
|
+
import { compareAnalystLegs } from "../analyst-ledger.js";
|
|
2
3
|
function timestampMs(iso) {
|
|
3
4
|
const ms = Date.parse(iso);
|
|
4
5
|
if (!Number.isFinite(ms)) {
|
|
@@ -141,7 +142,7 @@ function sortActionsDescending(actions) {
|
|
|
141
142
|
export function computeAnalystB2RunMetrics(facts) {
|
|
142
143
|
const frameStartMs = timestampMs(facts.frameSpan.startedAt);
|
|
143
144
|
const frameEndMs = timestampMs(facts.frameSpan.endedAt);
|
|
144
|
-
const wallMs =
|
|
145
|
+
const wallMs = facts.frameSpan.wallMs;
|
|
145
146
|
// Single frame-bounded core: clip → union once → bucket/complement/actions.
|
|
146
147
|
const tools = clipToolsToFrame(closedTools(facts.toolIntervals), frameStartMs, frameEndMs);
|
|
147
148
|
const toolUnion = mergeUnion(tools);
|
|
@@ -172,13 +173,7 @@ const b2FrameBucketsActionsFamily = {
|
|
|
172
173
|
return undefined;
|
|
173
174
|
const runs = [...input.runs]
|
|
174
175
|
.map(computeAnalystB2RunMetrics)
|
|
175
|
-
.sort(
|
|
176
|
-
if (a.book !== b.book)
|
|
177
|
-
return a.book.localeCompare(b.book);
|
|
178
|
-
if (a.role !== b.role)
|
|
179
|
-
return a.role.localeCompare(b.role);
|
|
180
|
-
return a.runId.localeCompare(b.runId);
|
|
181
|
-
});
|
|
176
|
+
.sort(compareAnalystLegs);
|
|
182
177
|
const section = {
|
|
183
178
|
kind: "analyst-b2-frame-buckets-actions",
|
|
184
179
|
runs,
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { compareAnalystLegs } from "../analyst-ledger.js";
|
|
1
2
|
function projectRound(round) {
|
|
2
3
|
return {
|
|
3
4
|
roundIndex: round.roundIndex,
|
|
@@ -18,13 +19,6 @@ function projectLeg(facts) {
|
|
|
18
19
|
rounds,
|
|
19
20
|
};
|
|
20
21
|
}
|
|
21
|
-
function compareLegs(a, b) {
|
|
22
|
-
if (a.book !== b.book)
|
|
23
|
-
return a.book.localeCompare(b.book);
|
|
24
|
-
if (a.role !== b.role)
|
|
25
|
-
return a.role.localeCompare(b.role);
|
|
26
|
-
return a.runId.localeCompare(b.runId);
|
|
27
|
-
}
|
|
28
22
|
function emptyAccum() {
|
|
29
23
|
return { rounds: 0, bounceCount: 0, passCount: 0, wallSum: 0 };
|
|
30
24
|
}
|
|
@@ -65,7 +59,7 @@ const gateCyclesFamily = {
|
|
|
65
59
|
contribute(input) {
|
|
66
60
|
if (input.runs.length === 0)
|
|
67
61
|
return undefined;
|
|
68
|
-
const legs = input.runs.map(projectLeg).sort(
|
|
62
|
+
const legs = input.runs.map(projectLeg).sort(compareAnalystLegs);
|
|
69
63
|
const section = {
|
|
70
64
|
kind: "analyst-gate-cycles",
|
|
71
65
|
legs,
|
|
@@ -6,25 +6,19 @@
|
|
|
6
6
|
* Registers by file drop under analyst-metric-families/ (A2 discovery).
|
|
7
7
|
*/
|
|
8
8
|
import { medianNumber } from "../analyst-median.js";
|
|
9
|
-
|
|
10
|
-
return Date.parse(span.endedAt) - Date.parse(span.startedAt);
|
|
11
|
-
}
|
|
9
|
+
import { compareAnalystLegs, sumAnalystRunWallMs } from "../analyst-ledger.js";
|
|
12
10
|
function projectEntry(facts) {
|
|
13
11
|
return {
|
|
14
12
|
runId: facts.runId,
|
|
15
13
|
book: facts.book,
|
|
16
14
|
role: facts.role,
|
|
17
|
-
wallMs:
|
|
15
|
+
wallMs: facts.frameSpan.wallMs,
|
|
18
16
|
};
|
|
19
17
|
}
|
|
20
18
|
function compareRankingDesc(a, b) {
|
|
21
19
|
if (b.wallMs !== a.wallMs)
|
|
22
20
|
return b.wallMs - a.wallMs;
|
|
23
|
-
|
|
24
|
-
return a.book.localeCompare(b.book);
|
|
25
|
-
if (a.role !== b.role)
|
|
26
|
-
return a.role.localeCompare(b.role);
|
|
27
|
-
return a.runId.localeCompare(b.runId);
|
|
21
|
+
return compareAnalystLegs(a, b);
|
|
28
22
|
}
|
|
29
23
|
/** Discovered by analyst-metric-families loader (default export). */
|
|
30
24
|
const legWallClockFamily = {
|
|
@@ -41,14 +35,11 @@ const legWallClockFamily = {
|
|
|
41
35
|
if (medianWallMs === undefined) {
|
|
42
36
|
return undefined;
|
|
43
37
|
}
|
|
44
|
-
let totalElapsedMs = 0;
|
|
45
|
-
for (const wallMs of walls)
|
|
46
|
-
totalElapsedMs += wallMs;
|
|
47
38
|
const section = {
|
|
48
39
|
kind: "analyst-leg-wall-clock",
|
|
49
40
|
ranking,
|
|
50
41
|
medianWallMs,
|
|
51
|
-
totalElapsedMs,
|
|
42
|
+
totalElapsedMs: sumAnalystRunWallMs(input.runs),
|
|
52
43
|
};
|
|
53
44
|
return { legWallClock: section };
|
|
54
45
|
},
|