@akagilnc/pi-workflow-roles 0.1.1918 → 0.1.2004
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/evidence-child-executor.js +12 -6
- package/dist/package-contracts/reviewer-output.js +16 -0
- package/dist/public-cli/main.js +2520 -72
- package/dist/reviewer-construction.js +46 -6
- package/dist/reviewer-dispatch.js +64 -1
- package/dist/reviewer-execution-ledger.js +2 -1
- package/dist/reviewer-pinned-git.js +33 -0
- package/package.json +1 -1
- package/src/atomic-write.ts +26 -0
- package/src/evidence-child-executor.ts +13 -6
- package/src/ledger-session-read.ts +260 -0
- package/src/package-contracts/reviewer-output.ts +19 -0
- package/src/public-cli/cli.ts +24 -0
- package/src/public-cli/invocation.ts +398 -2
- package/src/public-cli/main.ts +21 -2
- package/src/public-cli/registry.ts +18 -1
- package/src/public-cli/reviewer-run.ts +12 -0
- package/src/public-cli/run-lifecycle.ts +22 -1
- package/src/public-cli/settlement.ts +17 -0
- package/src/public-cli/taishi-run.ts +235 -0
- package/src/reviewer-construction.ts +64 -7
- package/src/reviewer-dispatch.ts +81 -2
- package/src/reviewer-execution-ledger.ts +2 -1
- package/src/reviewer-pinned-git.ts +43 -0
- package/src/reviewer-role.ts +143 -132
- package/src/reviewer-settlement.ts +4 -0
- package/src/role-runtime.ts +186 -3
- package/src/run-terminal-artifacts.ts +231 -0
- package/src/taishi-cohort.ts +232 -0
- package/src/taishi-entry.ts +429 -0
- package/src/taishi-index.ts +269 -0
- package/src/taishi-ledger.ts +466 -0
- package/src/taishi-median.ts +15 -0
- package/src/taishi-metric-families/acceptance-success-rework.ts +346 -0
- package/src/taishi-metric-families/b2-frame-buckets-actions.ts +274 -0
- package/src/taishi-metric-families/leg-wall-clock.ts +90 -0
- package/src/taishi-metric-families/round-timeline.ts +201 -0
- package/src/taishi-metric-families.ts +36 -0
- package/src/taishi-metric-family.ts +41 -0
- package/src/taishi-model-groups.ts +198 -0
- package/src/taishi-page.ts +320 -0
- package/src/ticket-trajectory.ts +9 -62
package/dist/public-cli/main.js
CHANGED
|
@@ -147,6 +147,18 @@ function validateRuntimeReviewerReceipt(output) {
|
|
|
147
147
|
throw new Error("Successful Reviewer outcome lacks report");
|
|
148
148
|
if (status === "failed" && report !== void 0) throw new Error("Failed Reviewer outcome cannot bind a report");
|
|
149
149
|
}
|
|
150
|
+
const specDisposition = read(output, "specDisposition");
|
|
151
|
+
if (specDisposition === "launched") {
|
|
152
|
+
if (expectedAxes.length !== 2 || expectedAxes[0] !== "standards" || expectedAxes[1] !== "spec") {
|
|
153
|
+
throw new Error("Reviewer specDisposition launched requires Standards+Spec accepted legs");
|
|
154
|
+
}
|
|
155
|
+
} else if (specDisposition === "skipped-missing") {
|
|
156
|
+
if (expectedAxes.length !== 1 || expectedAxes[0] !== "standards") {
|
|
157
|
+
throw new Error("Reviewer specDisposition skipped-missing requires Standards-only accepted legs");
|
|
158
|
+
}
|
|
159
|
+
} else if (specDisposition !== void 0) {
|
|
160
|
+
throw new Error("Invalid Reviewer specDisposition");
|
|
161
|
+
}
|
|
150
162
|
}
|
|
151
163
|
return output;
|
|
152
164
|
}
|
|
@@ -14261,7 +14273,13 @@ function listHelpCapabilities() {
|
|
|
14261
14273
|
defaultPhase
|
|
14262
14274
|
};
|
|
14263
14275
|
});
|
|
14264
|
-
|
|
14276
|
+
const deterministic = PUBLIC_DETERMINISTIC_COMMANDS.map(
|
|
14277
|
+
(name) => ({
|
|
14278
|
+
kind: "deterministic",
|
|
14279
|
+
name
|
|
14280
|
+
})
|
|
14281
|
+
);
|
|
14282
|
+
return [...support, ...roles, ...deterministic];
|
|
14265
14283
|
}
|
|
14266
14284
|
function isPublicConfigurableSeat(value) {
|
|
14267
14285
|
return PUBLIC_CONFIGURABLE_SEATS.includes(value);
|
|
@@ -14269,7 +14287,7 @@ function isPublicConfigurableSeat(value) {
|
|
|
14269
14287
|
function isPublicCliSupportCommand(value) {
|
|
14270
14288
|
return PUBLIC_CLI_SUPPORT_COMMANDS.includes(value);
|
|
14271
14289
|
}
|
|
14272
|
-
var INTERNAL_ROLE_ENTRYPOINT_RELATIVE, PUBLIC_CALLABLE_ROLES, AUTOMATIC_NAVIGATOR_SEAT, PUBLIC_CONFIGURABLE_SEATS, PUBLIC_CLI_SUPPORT_COMMANDS, STARTUP_CANDIDATES;
|
|
14290
|
+
var INTERNAL_ROLE_ENTRYPOINT_RELATIVE, PUBLIC_CALLABLE_ROLES, AUTOMATIC_NAVIGATOR_SEAT, PUBLIC_CONFIGURABLE_SEATS, PUBLIC_CLI_SUPPORT_COMMANDS, STARTUP_CANDIDATES, PUBLIC_DETERMINISTIC_COMMANDS;
|
|
14273
14291
|
var init_registry2 = __esm({
|
|
14274
14292
|
"src/public-cli/registry.ts"() {
|
|
14275
14293
|
"use strict";
|
|
@@ -14323,6 +14341,7 @@ var init_registry2 = __esm({
|
|
|
14323
14341
|
{ provider: "xai", model: "grok-4.5", thinking: "high" }
|
|
14324
14342
|
]
|
|
14325
14343
|
};
|
|
14344
|
+
PUBLIC_DETERMINISTIC_COMMANDS = ["taishi"];
|
|
14326
14345
|
}
|
|
14327
14346
|
});
|
|
14328
14347
|
|
|
@@ -14755,6 +14774,26 @@ function ensureRealDirectoryTree(root, targetDir) {
|
|
|
14755
14774
|
);
|
|
14756
14775
|
}
|
|
14757
14776
|
}
|
|
14777
|
+
function assertLedgerFileInsideHome(ledgerPath, ledgerHome) {
|
|
14778
|
+
if (!isAbsolute(ledgerHome)) {
|
|
14779
|
+
throw new ActivationLedgerError(`activation ledger home must be absolute: ${ledgerHome}`);
|
|
14780
|
+
}
|
|
14781
|
+
const resolvedLedger = resolve(ledgerPath);
|
|
14782
|
+
try {
|
|
14783
|
+
if (!lstatSync2(resolvedLedger).isSymbolicLink()) return;
|
|
14784
|
+
throw new ActivationLedgerError(
|
|
14785
|
+
`activation ledger file is a symbolic link: ${resolvedLedger}`
|
|
14786
|
+
);
|
|
14787
|
+
} catch (error) {
|
|
14788
|
+
if (errnoCode(error) !== "ENOENT") {
|
|
14789
|
+
if (error instanceof ActivationLedgerError) throw error;
|
|
14790
|
+
throw new ActivationLedgerError(
|
|
14791
|
+
`activation ledger failed to stat ledger file (${resolvedLedger}): ${errorText(error)}`,
|
|
14792
|
+
{ cause: error }
|
|
14793
|
+
);
|
|
14794
|
+
}
|
|
14795
|
+
}
|
|
14796
|
+
}
|
|
14758
14797
|
var ActivationLedgerError;
|
|
14759
14798
|
var init_activation_ledger_topology = __esm({
|
|
14760
14799
|
"src/activation-ledger-topology.ts"() {
|
|
@@ -15464,6 +15503,17 @@ function requireOptionPath(flag, value) {
|
|
|
15464
15503
|
}
|
|
15465
15504
|
return value;
|
|
15466
15505
|
}
|
|
15506
|
+
function requireAuthorityRef(value) {
|
|
15507
|
+
if (value === void 0 || value.trim() === "") {
|
|
15508
|
+
throw new CliUsageError("--authority-ref requires a nonempty durable reference");
|
|
15509
|
+
}
|
|
15510
|
+
if (/\s/.test(value)) {
|
|
15511
|
+
throw new CliUsageError(
|
|
15512
|
+
"--authority-ref requires a durable reference, not inline Spec prose"
|
|
15513
|
+
);
|
|
15514
|
+
}
|
|
15515
|
+
return value;
|
|
15516
|
+
}
|
|
15467
15517
|
function parseJudgeArgv(args) {
|
|
15468
15518
|
const attachmentPaths = [];
|
|
15469
15519
|
let project;
|
|
@@ -16426,6 +16476,7 @@ function buildDoctorTransportPrompt(admitted) {
|
|
|
16426
16476
|
}
|
|
16427
16477
|
function parseReviewerArgv(args) {
|
|
16428
16478
|
const attachmentPaths = [];
|
|
16479
|
+
const authorityRefs = [];
|
|
16429
16480
|
let project;
|
|
16430
16481
|
let baseRevision;
|
|
16431
16482
|
const positional = [];
|
|
@@ -16452,6 +16503,14 @@ function parseReviewerArgv(args) {
|
|
|
16452
16503
|
baseRevision = requireOptionPath("--base", token.slice("--base=".length));
|
|
16453
16504
|
continue;
|
|
16454
16505
|
}
|
|
16506
|
+
if (token === "--authority-ref") {
|
|
16507
|
+
authorityRefs.push(requireAuthorityRef(tokens.shift()));
|
|
16508
|
+
continue;
|
|
16509
|
+
}
|
|
16510
|
+
if (token.startsWith("--authority-ref=")) {
|
|
16511
|
+
authorityRefs.push(requireAuthorityRef(token.slice("--authority-ref=".length)));
|
|
16512
|
+
continue;
|
|
16513
|
+
}
|
|
16455
16514
|
if (token.startsWith("-") && token !== "-") {
|
|
16456
16515
|
throw new CliUsageError(`unknown reviewer option: ${token}`);
|
|
16457
16516
|
}
|
|
@@ -16464,6 +16523,7 @@ function parseReviewerArgv(args) {
|
|
|
16464
16523
|
instruction: positional.join(" "),
|
|
16465
16524
|
attachmentPaths,
|
|
16466
16525
|
baseRevision,
|
|
16526
|
+
authorityRefs,
|
|
16467
16527
|
...project === void 0 ? {} : { project }
|
|
16468
16528
|
};
|
|
16469
16529
|
}
|
|
@@ -16474,6 +16534,9 @@ async function admitReviewerInvocation(options) {
|
|
|
16474
16534
|
if (options.baseRevision.trim() === "") {
|
|
16475
16535
|
throw new CliUsageError("--base requires a nonempty revision");
|
|
16476
16536
|
}
|
|
16537
|
+
const authorityRefs = Object.freeze(
|
|
16538
|
+
(options.authorityRefs ?? []).map((ref) => requireAuthorityRef(ref))
|
|
16539
|
+
);
|
|
16477
16540
|
const projectRoot = resolve4(options.project ?? options.cwd);
|
|
16478
16541
|
const runId = (options.createRunId ?? uuidv7)();
|
|
16479
16542
|
const { ledgerHome, bookKey, runDirectory, sessionDirectory, sessionFile } = roleRunSessionCoordinates({ cwd: projectRoot, runId, role: "reviewer", home: options.home });
|
|
@@ -16499,6 +16562,7 @@ async function admitReviewerInvocation(options) {
|
|
|
16499
16562
|
instruction,
|
|
16500
16563
|
instructionEmpty,
|
|
16501
16564
|
baseRevision: options.baseRevision,
|
|
16565
|
+
authorityRefs: [...authorityRefs],
|
|
16502
16566
|
attachments: attachments.map((a) => ({
|
|
16503
16567
|
provenancePath: a.provenancePath,
|
|
16504
16568
|
frozenPath: a.frozenPath,
|
|
@@ -16528,6 +16592,7 @@ async function admitReviewerInvocation(options) {
|
|
|
16528
16592
|
sessionFile,
|
|
16529
16593
|
admittedRequestPath,
|
|
16530
16594
|
baseRevision: options.baseRevision,
|
|
16595
|
+
authorityRefs,
|
|
16531
16596
|
...ticketFields
|
|
16532
16597
|
};
|
|
16533
16598
|
}
|
|
@@ -16731,7 +16796,260 @@ function buildMergerTransportPrompt(admitted) {
|
|
|
16731
16796
|
}
|
|
16732
16797
|
return lines.join("\n");
|
|
16733
16798
|
}
|
|
16734
|
-
|
|
16799
|
+
function parseTaishiTicketNumber(raw, flag = "--ticket") {
|
|
16800
|
+
const trimmed = raw.trim();
|
|
16801
|
+
if (!TAISHI_TICKET_NUMBER_PATTERN.test(trimmed)) {
|
|
16802
|
+
throw new CliUsageError(
|
|
16803
|
+
`taishi ${flag} must be a positive integer, got ${raw}`
|
|
16804
|
+
);
|
|
16805
|
+
}
|
|
16806
|
+
const value = Number(trimmed);
|
|
16807
|
+
if (!Number.isSafeInteger(value) || value < 1) {
|
|
16808
|
+
throw new CliUsageError(
|
|
16809
|
+
`taishi ${flag} must be a positive integer, got ${raw}`
|
|
16810
|
+
);
|
|
16811
|
+
}
|
|
16812
|
+
return value;
|
|
16813
|
+
}
|
|
16814
|
+
function parseTaishiIssueNumberList(raw, flag) {
|
|
16815
|
+
const trimmed = raw.trim();
|
|
16816
|
+
if (trimmed === "") {
|
|
16817
|
+
throw new CliUsageError(`${flag} requires a comma-separated positive integer list`);
|
|
16818
|
+
}
|
|
16819
|
+
const parts = trimmed.split(",").map((part) => part.trim());
|
|
16820
|
+
if (parts.some((part) => part === "")) {
|
|
16821
|
+
throw new CliUsageError(`${flag} requires a comma-separated positive integer list`);
|
|
16822
|
+
}
|
|
16823
|
+
return parts.map((part) => parseTaishiTicketNumber(part, flag));
|
|
16824
|
+
}
|
|
16825
|
+
function requireOptionValue(flag, value, what) {
|
|
16826
|
+
if (value === void 0 || value.trim() === "") {
|
|
16827
|
+
throw new CliUsageError(`${flag} requires ${what}`);
|
|
16828
|
+
}
|
|
16829
|
+
return value;
|
|
16830
|
+
}
|
|
16831
|
+
function parseTaishiArgv(args) {
|
|
16832
|
+
let query = "issue";
|
|
16833
|
+
let ticketRaw;
|
|
16834
|
+
const projectRoots = [];
|
|
16835
|
+
let groupALabel;
|
|
16836
|
+
let groupAIssuesRaw;
|
|
16837
|
+
let groupBLabel;
|
|
16838
|
+
let groupBIssuesRaw;
|
|
16839
|
+
let sweepToken = false;
|
|
16840
|
+
const attachmentPaths = [];
|
|
16841
|
+
const tokens = [...args];
|
|
16842
|
+
while (tokens.length > 0) {
|
|
16843
|
+
const token = tokens.shift();
|
|
16844
|
+
if (token === "--") {
|
|
16845
|
+
if (tokens.length > 0) {
|
|
16846
|
+
throw new CliUsageError(`unexpected taishi argument: ${tokens[0]}`);
|
|
16847
|
+
}
|
|
16848
|
+
break;
|
|
16849
|
+
}
|
|
16850
|
+
if (token === "--cohort") {
|
|
16851
|
+
if (query !== "issue") {
|
|
16852
|
+
throw new CliUsageError("taishi accepts only one of --cohort / --model-groups");
|
|
16853
|
+
}
|
|
16854
|
+
query = "cohort";
|
|
16855
|
+
continue;
|
|
16856
|
+
}
|
|
16857
|
+
if (token === "--model-groups") {
|
|
16858
|
+
if (query !== "issue") {
|
|
16859
|
+
throw new CliUsageError("taishi accepts only one of --cohort / --model-groups");
|
|
16860
|
+
}
|
|
16861
|
+
query = "model-groups";
|
|
16862
|
+
continue;
|
|
16863
|
+
}
|
|
16864
|
+
if (token === "--ticket") {
|
|
16865
|
+
const value = tokens.shift();
|
|
16866
|
+
if (value === void 0 || value.trim() === "") {
|
|
16867
|
+
throw new CliUsageError("taishi --ticket requires a positive integer");
|
|
16868
|
+
}
|
|
16869
|
+
ticketRaw = value;
|
|
16870
|
+
continue;
|
|
16871
|
+
}
|
|
16872
|
+
if (token.startsWith("--ticket=")) {
|
|
16873
|
+
ticketRaw = token.slice("--ticket=".length);
|
|
16874
|
+
if (ticketRaw.trim() === "") {
|
|
16875
|
+
throw new CliUsageError("taishi --ticket requires a positive integer");
|
|
16876
|
+
}
|
|
16877
|
+
continue;
|
|
16878
|
+
}
|
|
16879
|
+
if (token === "--project-root") {
|
|
16880
|
+
projectRoots.push(requireOptionPath("--project-root", tokens.shift()));
|
|
16881
|
+
continue;
|
|
16882
|
+
}
|
|
16883
|
+
if (token.startsWith("--project-root=")) {
|
|
16884
|
+
projectRoots.push(
|
|
16885
|
+
requireOptionPath("--project-root", token.slice("--project-root=".length))
|
|
16886
|
+
);
|
|
16887
|
+
continue;
|
|
16888
|
+
}
|
|
16889
|
+
if (token === "--group-a-label") {
|
|
16890
|
+
groupALabel = requireOptionValue("--group-a-label", tokens.shift(), "a label");
|
|
16891
|
+
continue;
|
|
16892
|
+
}
|
|
16893
|
+
if (token.startsWith("--group-a-label=")) {
|
|
16894
|
+
groupALabel = requireOptionValue(
|
|
16895
|
+
"--group-a-label",
|
|
16896
|
+
token.slice("--group-a-label=".length),
|
|
16897
|
+
"a label"
|
|
16898
|
+
);
|
|
16899
|
+
continue;
|
|
16900
|
+
}
|
|
16901
|
+
if (token === "--group-a-issues") {
|
|
16902
|
+
groupAIssuesRaw = requireOptionValue(
|
|
16903
|
+
"--group-a-issues",
|
|
16904
|
+
tokens.shift(),
|
|
16905
|
+
"a comma-separated positive integer list"
|
|
16906
|
+
);
|
|
16907
|
+
continue;
|
|
16908
|
+
}
|
|
16909
|
+
if (token.startsWith("--group-a-issues=")) {
|
|
16910
|
+
groupAIssuesRaw = requireOptionValue(
|
|
16911
|
+
"--group-a-issues",
|
|
16912
|
+
token.slice("--group-a-issues=".length),
|
|
16913
|
+
"a comma-separated positive integer list"
|
|
16914
|
+
);
|
|
16915
|
+
continue;
|
|
16916
|
+
}
|
|
16917
|
+
if (token === "--group-b-label") {
|
|
16918
|
+
groupBLabel = requireOptionValue("--group-b-label", tokens.shift(), "a label");
|
|
16919
|
+
continue;
|
|
16920
|
+
}
|
|
16921
|
+
if (token.startsWith("--group-b-label=")) {
|
|
16922
|
+
groupBLabel = requireOptionValue(
|
|
16923
|
+
"--group-b-label",
|
|
16924
|
+
token.slice("--group-b-label=".length),
|
|
16925
|
+
"a label"
|
|
16926
|
+
);
|
|
16927
|
+
continue;
|
|
16928
|
+
}
|
|
16929
|
+
if (token === "--group-b-issues") {
|
|
16930
|
+
groupBIssuesRaw = requireOptionValue(
|
|
16931
|
+
"--group-b-issues",
|
|
16932
|
+
tokens.shift(),
|
|
16933
|
+
"a comma-separated positive integer list"
|
|
16934
|
+
);
|
|
16935
|
+
continue;
|
|
16936
|
+
}
|
|
16937
|
+
if (token.startsWith("--group-b-issues=")) {
|
|
16938
|
+
groupBIssuesRaw = requireOptionValue(
|
|
16939
|
+
"--group-b-issues",
|
|
16940
|
+
token.slice("--group-b-issues=".length),
|
|
16941
|
+
"a comma-separated positive integer list"
|
|
16942
|
+
);
|
|
16943
|
+
continue;
|
|
16944
|
+
}
|
|
16945
|
+
if (token === "--attach") {
|
|
16946
|
+
attachmentPaths.push(requireOptionPath("--attach", tokens.shift()));
|
|
16947
|
+
continue;
|
|
16948
|
+
}
|
|
16949
|
+
if (token.startsWith("--attach=")) {
|
|
16950
|
+
attachmentPaths.push(
|
|
16951
|
+
requireOptionPath("--attach", token.slice("--attach=".length))
|
|
16952
|
+
);
|
|
16953
|
+
continue;
|
|
16954
|
+
}
|
|
16955
|
+
if (token.startsWith("-") && token !== "-") {
|
|
16956
|
+
throw new CliUsageError(`unknown taishi option: ${token}`);
|
|
16957
|
+
}
|
|
16958
|
+
if (token === "sweep") {
|
|
16959
|
+
if (sweepToken) {
|
|
16960
|
+
throw new CliUsageError("unexpected taishi argument: sweep");
|
|
16961
|
+
}
|
|
16962
|
+
sweepToken = true;
|
|
16963
|
+
continue;
|
|
16964
|
+
}
|
|
16965
|
+
throw new CliUsageError(`unexpected taishi argument: ${token}`);
|
|
16966
|
+
}
|
|
16967
|
+
const hasSweepFace = sweepToken || attachmentPaths.length > 0;
|
|
16968
|
+
const hasCohortFlags = groupALabel !== void 0 || groupAIssuesRaw !== void 0 || groupBLabel !== void 0 || groupBIssuesRaw !== void 0;
|
|
16969
|
+
if (query === "cohort") {
|
|
16970
|
+
if (groupALabel === void 0 || groupAIssuesRaw === void 0 || groupBLabel === void 0 || groupBIssuesRaw === void 0) {
|
|
16971
|
+
throw new CliUsageError(
|
|
16972
|
+
"usage: ak-role taishi --cohort --group-a-label <L> --group-a-issues <N[,N...]> --group-b-label <L> --group-b-issues <N[,N...]>"
|
|
16973
|
+
);
|
|
16974
|
+
}
|
|
16975
|
+
if (ticketRaw !== void 0 || projectRoots.length > 0) {
|
|
16976
|
+
throw new CliUsageError(
|
|
16977
|
+
"taishi --cohort does not accept --ticket or --project-root"
|
|
16978
|
+
);
|
|
16979
|
+
}
|
|
16980
|
+
if (hasSweepFace) {
|
|
16981
|
+
throw new CliUsageError(
|
|
16982
|
+
"taishi --cohort does not accept sweep --attach"
|
|
16983
|
+
);
|
|
16984
|
+
}
|
|
16985
|
+
return {
|
|
16986
|
+
query: "cohort",
|
|
16987
|
+
groups: [
|
|
16988
|
+
{
|
|
16989
|
+
groupLabel: groupALabel,
|
|
16990
|
+
issues: parseTaishiIssueNumberList(groupAIssuesRaw, "--group-a-issues")
|
|
16991
|
+
},
|
|
16992
|
+
{
|
|
16993
|
+
groupLabel: groupBLabel,
|
|
16994
|
+
issues: parseTaishiIssueNumberList(groupBIssuesRaw, "--group-b-issues")
|
|
16995
|
+
}
|
|
16996
|
+
]
|
|
16997
|
+
};
|
|
16998
|
+
}
|
|
16999
|
+
if (query === "model-groups") {
|
|
17000
|
+
if (projectRoots.length === 0) {
|
|
17001
|
+
throw new CliUsageError(
|
|
17002
|
+
"usage: ak-role taishi --model-groups --project-root <P> [--project-root <P> ...]"
|
|
17003
|
+
);
|
|
17004
|
+
}
|
|
17005
|
+
if (ticketRaw !== void 0) {
|
|
17006
|
+
throw new CliUsageError("taishi --model-groups does not accept --ticket");
|
|
17007
|
+
}
|
|
17008
|
+
if (hasCohortFlags) {
|
|
17009
|
+
throw new CliUsageError("taishi --model-groups does not accept cohort group flags");
|
|
17010
|
+
}
|
|
17011
|
+
if (hasSweepFace) {
|
|
17012
|
+
throw new CliUsageError(
|
|
17013
|
+
"taishi --model-groups does not accept sweep --attach"
|
|
17014
|
+
);
|
|
17015
|
+
}
|
|
17016
|
+
return {
|
|
17017
|
+
query: "model-groups",
|
|
17018
|
+
projectRoots
|
|
17019
|
+
};
|
|
17020
|
+
}
|
|
17021
|
+
if (hasCohortFlags) {
|
|
17022
|
+
throw new CliUsageError("taishi issue query does not accept cohort group flags");
|
|
17023
|
+
}
|
|
17024
|
+
if (hasSweepFace) {
|
|
17025
|
+
if (ticketRaw !== void 0 || projectRoots.length > 0) {
|
|
17026
|
+
throw new CliUsageError(
|
|
17027
|
+
"taishi sweep --attach cannot combine with --ticket or --project-root"
|
|
17028
|
+
);
|
|
17029
|
+
}
|
|
17030
|
+
return {
|
|
17031
|
+
query: "sweep",
|
|
17032
|
+
attachmentPaths
|
|
17033
|
+
};
|
|
17034
|
+
}
|
|
17035
|
+
if (projectRoots.length > 1) {
|
|
17036
|
+
throw new CliUsageError(
|
|
17037
|
+
"taishi issue query accepts at most one --project-root (use --model-groups for many)"
|
|
17038
|
+
);
|
|
17039
|
+
}
|
|
17040
|
+
const projectRoot = projectRoots[0];
|
|
17041
|
+
if (ticketRaw === void 0 && projectRoot === void 0) {
|
|
17042
|
+
throw new CliUsageError(
|
|
17043
|
+
"usage: ak-role taishi ((--ticket <N> | --project-root <P>) | [sweep] --attach <sweep.json> | --cohort ... | --model-groups ...)"
|
|
17044
|
+
);
|
|
17045
|
+
}
|
|
17046
|
+
return {
|
|
17047
|
+
query: "issue",
|
|
17048
|
+
...ticketRaw === void 0 ? {} : { ticket: parseTaishiTicketNumber(ticketRaw) },
|
|
17049
|
+
...projectRoot === void 0 ? {} : { projectRoot }
|
|
17050
|
+
};
|
|
17051
|
+
}
|
|
17052
|
+
var MergerEnvelopeDerivationError, DOCTOR_ISSUE_NUMBER_PATTERN, DOCTOR_CASE_RUNS_PATH_PATTERN, TAISHI_TICKET_NUMBER_PATTERN;
|
|
16735
17053
|
var init_invocation = __esm({
|
|
16736
17054
|
"src/public-cli/invocation.ts"() {
|
|
16737
17055
|
"use strict";
|
|
@@ -16758,6 +17076,7 @@ var init_invocation = __esm({
|
|
|
16758
17076
|
};
|
|
16759
17077
|
DOCTOR_ISSUE_NUMBER_PATTERN = /^[1-9]\d*$/;
|
|
16760
17078
|
DOCTOR_CASE_RUNS_PATH_PATTERN = /\/\.ak-roles\/books\/[^/]+\/issues\/([1-9]\d*)\/runs$/;
|
|
17079
|
+
TAISHI_TICKET_NUMBER_PATTERN = /^[1-9]\d*$/;
|
|
16761
17080
|
}
|
|
16762
17081
|
});
|
|
16763
17082
|
|
|
@@ -16804,7 +17123,7 @@ var init_reviewer_scope_prompt = __esm({
|
|
|
16804
17123
|
});
|
|
16805
17124
|
|
|
16806
17125
|
// src/reviewer-construction.ts
|
|
16807
|
-
var REVIEWER_CONSTRUCTION_RECIPE, REVIEWER_AXIS_OUTPUT_ADAPTER, REVIEWER_STANDARDS_CONCLUSION_KEYS, REVIEWER_STANDARDS_CONCLUSION_LABELS;
|
|
17126
|
+
var REVIEWER_CONSTRUCTION_RECIPE, REVIEWER_AXIS_OUTPUT_ADAPTER, REVIEWER_VERIFICATION_BOUNDARY, REVIEWER_STANDARDS_CONCLUSION_KEYS, REVIEWER_STANDARDS_CONCLUSION_LABELS;
|
|
16808
17127
|
var init_reviewer_construction = __esm({
|
|
16809
17128
|
"src/reviewer-construction.ts"() {
|
|
16810
17129
|
"use strict";
|
|
@@ -16821,6 +17140,14 @@ var init_reviewer_construction = __esm({
|
|
|
16821
17140
|
version: 1,
|
|
16822
17141
|
implementationSha256: sha256Hex("reviewer-axis-output:v1:single-axis-verbatim-report+standards-three-priorities")
|
|
16823
17142
|
});
|
|
17143
|
+
REVIEWER_VERIFICATION_BOUNDARY = [
|
|
17144
|
+
"Verification-Boundary: you may run focused product tests during this review turn when independent verification needs them.",
|
|
17145
|
+
"A full repository test suite is not forbidden, but do not re-run it every review round;",
|
|
17146
|
+
"prefer once at family wrap-up unless this review specifically requires a broader run.",
|
|
17147
|
+
"Slice and review work should not trigger frequent full-suite reruns.",
|
|
17148
|
+
"Independently discover test facts (including existing coder/fixer receipts and any tests you run);",
|
|
17149
|
+
"do not treat caller prose as the source of those facts."
|
|
17150
|
+
].join(" ");
|
|
16824
17151
|
REVIEWER_STANDARDS_CONCLUSION_KEYS = Object.freeze([
|
|
16825
17152
|
"constitutionality",
|
|
16826
17153
|
"minimum-necessary-test-cost",
|
|
@@ -16845,6 +17172,7 @@ var init_reviewer_dispatch = __esm({
|
|
|
16845
17172
|
init_reviewer_prompt_identity();
|
|
16846
17173
|
init_sha256();
|
|
16847
17174
|
init_reviewer_construction();
|
|
17175
|
+
init_reviewer_construction();
|
|
16848
17176
|
init_reviewer_preflight_error();
|
|
16849
17177
|
init_sha256();
|
|
16850
17178
|
init_reviewer_prompt_identity();
|
|
@@ -17640,6 +17968,7 @@ async function loadResumableRunRecord(home, runId) {
|
|
|
17640
17968
|
let prerequisitesPath;
|
|
17641
17969
|
let prerequisites;
|
|
17642
17970
|
let baseRevision;
|
|
17971
|
+
let authorityRefs;
|
|
17643
17972
|
let mergerInputPath;
|
|
17644
17973
|
let derived;
|
|
17645
17974
|
let correlationId;
|
|
@@ -17677,6 +18006,18 @@ async function loadResumableRunRecord(home, runId) {
|
|
|
17677
18006
|
if (typeof record4.baseRevision === "string" && record4.baseRevision.trim() !== "") {
|
|
17678
18007
|
baseRevision = record4.baseRevision;
|
|
17679
18008
|
}
|
|
18009
|
+
if (Array.isArray(record4.authorityRefs)) {
|
|
18010
|
+
authorityRefs = Object.freeze(
|
|
18011
|
+
record4.authorityRefs.map((ref) => {
|
|
18012
|
+
if (typeof ref !== "string") {
|
|
18013
|
+
throw new CliUsageError(
|
|
18014
|
+
"role run admitted authority refs must be durable reference strings"
|
|
18015
|
+
);
|
|
18016
|
+
}
|
|
18017
|
+
return requireAuthorityRef(ref);
|
|
18018
|
+
})
|
|
18019
|
+
);
|
|
18020
|
+
}
|
|
17680
18021
|
if (typeof record4.mergerInputPath === "string" && record4.mergerInputPath.trim() !== "") {
|
|
17681
18022
|
mergerInputPath = record4.mergerInputPath;
|
|
17682
18023
|
}
|
|
@@ -17696,9 +18037,11 @@ async function loadResumableRunRecord(home, runId) {
|
|
|
17696
18037
|
correlationId = fromAdmitted.correlationId;
|
|
17697
18038
|
ticketNumber = fromAdmitted.ticketNumber;
|
|
17698
18039
|
}
|
|
17699
|
-
} catch {
|
|
18040
|
+
} catch (error) {
|
|
18041
|
+
if (error instanceof CliUsageError) throw error;
|
|
17700
18042
|
throw new CliUsageError(
|
|
17701
|
-
`role run admitted request is unreadable: ${runId}
|
|
18043
|
+
`role run admitted request is unreadable: ${runId}`,
|
|
18044
|
+
{ cause: error }
|
|
17702
18045
|
);
|
|
17703
18046
|
}
|
|
17704
18047
|
if (correlationId === void 0 || ticketNumber === void 0) {
|
|
@@ -17735,6 +18078,7 @@ async function loadResumableRunRecord(home, runId) {
|
|
|
17735
18078
|
...prerequisitesPath === void 0 ? {} : { prerequisitesPath },
|
|
17736
18079
|
...prerequisites === void 0 ? {} : { prerequisites },
|
|
17737
18080
|
...baseRevision === void 0 ? {} : { baseRevision },
|
|
18081
|
+
...authorityRefs === void 0 ? {} : { authorityRefs },
|
|
17738
18082
|
...mergerInputPath === void 0 ? {} : { mergerInputPath },
|
|
17739
18083
|
...derived === void 0 ? {} : { derived },
|
|
17740
18084
|
...correlationId === void 0 ? {} : { correlationId },
|
|
@@ -17890,6 +18234,7 @@ async function loadResumableReviewerRun(home, runId) {
|
|
|
17890
18234
|
sessionFile: loaded.run.sessionFile,
|
|
17891
18235
|
admittedRequestPath: loaded.run.admittedRequestPath,
|
|
17892
18236
|
baseRevision,
|
|
18237
|
+
authorityRefs: Object.freeze([...loaded.admittedFields.authorityRefs ?? []]),
|
|
17893
18238
|
...restoredTicketFields(loaded.admittedFields)
|
|
17894
18239
|
};
|
|
17895
18240
|
return {
|
|
@@ -18093,8 +18438,9 @@ var init_evidence_child_executor = __esm({
|
|
|
18093
18438
|
"use strict";
|
|
18094
18439
|
init_compliance_transport();
|
|
18095
18440
|
init_package_owned_tool_idle();
|
|
18096
|
-
init_stream_idle_guard();
|
|
18097
18441
|
init_receipt_delivery_policy();
|
|
18442
|
+
init_reviewer_construction();
|
|
18443
|
+
init_stream_idle_guard();
|
|
18098
18444
|
init_upstream_error_testimony();
|
|
18099
18445
|
}
|
|
18100
18446
|
});
|
|
@@ -18670,6 +19016,11 @@ function formatFailureStderrDiagnostic(failure) {
|
|
|
18670
19016
|
function presentStructuralRejection(error, io) {
|
|
18671
19017
|
io.stderr(formatCliDiagnostic(error.message));
|
|
18672
19018
|
}
|
|
19019
|
+
function presentControlledFailure(failure, io) {
|
|
19020
|
+
io.stdout(`${JSON.stringify(failure, null, 2)}
|
|
19021
|
+
`);
|
|
19022
|
+
io.stderr(formatFailureStderrDiagnostic(failure));
|
|
19023
|
+
}
|
|
18673
19024
|
async function inspectJudgeSession(sessionFile) {
|
|
18674
19025
|
try {
|
|
18675
19026
|
await readFile9(sessionFile, "utf8");
|
|
@@ -19352,6 +19703,7 @@ function reviewerDecisiveFacts(output) {
|
|
|
19352
19703
|
const axes = reviewerAxes(outcomes.readable ? outcomes.value : void 0);
|
|
19353
19704
|
const reportAxes = reviewerAxes(reports.readable ? reports.value : void 0);
|
|
19354
19705
|
const acceptedBatch = safelyRead(candidate, "acceptedBatch");
|
|
19706
|
+
const specDisposition = safelyRead(candidate, "specDisposition");
|
|
19355
19707
|
const facts = {
|
|
19356
19708
|
axes,
|
|
19357
19709
|
reportAxes,
|
|
@@ -19359,6 +19711,9 @@ function reviewerDecisiveFacts(output) {
|
|
|
19359
19711
|
...auditNoReceiptDecisiveFact(candidate)
|
|
19360
19712
|
};
|
|
19361
19713
|
if (status.readable && typeof status.value === "string") facts.reviewerStatus = status.value;
|
|
19714
|
+
if (specDisposition.readable && (specDisposition.value === "launched" || specDisposition.value === "skipped-missing")) {
|
|
19715
|
+
facts.specDisposition = specDisposition.value;
|
|
19716
|
+
}
|
|
19362
19717
|
const diagnostic = safelyRead(candidate, "diagnostic");
|
|
19363
19718
|
if (status.readable && status.value === "refused" && diagnostic.readable) {
|
|
19364
19719
|
facts.diagnosticPresent = typeof diagnostic.value === "string" && diagnostic.value.trim().length > 0;
|
|
@@ -20649,6 +21004,7 @@ async function publishReviewerArtifacts(admitted, roleOutcome, sessionDirectory,
|
|
|
20649
21004
|
sessionFile: admitted.sessionFile,
|
|
20650
21005
|
admittedRequestPath: admitted.admittedRequestPath,
|
|
20651
21006
|
baseRevision: admitted.baseRevision,
|
|
21007
|
+
authorityRefs: [...admitted.authorityRefs],
|
|
20652
21008
|
...admitted.instructionEmpty ? {} : { callerProvenance: admitted.instruction },
|
|
20653
21009
|
attachments: admitted.attachments.map((a) => ({
|
|
20654
21010
|
provenancePath: a.provenancePath,
|
|
@@ -21315,7 +21671,7 @@ function buildCoderResumeActivationExtraArgs(admitted, options) {
|
|
|
21315
21671
|
RESUME_TRANSPORT_ENVELOPE
|
|
21316
21672
|
];
|
|
21317
21673
|
}
|
|
21318
|
-
async function
|
|
21674
|
+
async function presentControlledFailure2(admitted, failureInput, io) {
|
|
21319
21675
|
const hasThrown = Object.hasOwn(failureInput, "thrown");
|
|
21320
21676
|
const resumeObservation = await resolveControlledFailureResumeObservation({
|
|
21321
21677
|
runDirectory: admitted.runDirectory,
|
|
@@ -21371,7 +21727,7 @@ async function dispatchAdmittedCoder(input) {
|
|
|
21371
21727
|
env.credentials
|
|
21372
21728
|
);
|
|
21373
21729
|
if (missingCredential !== void 0) {
|
|
21374
|
-
return await
|
|
21730
|
+
return await presentControlledFailure2(
|
|
21375
21731
|
admitted,
|
|
21376
21732
|
missingCredential,
|
|
21377
21733
|
io
|
|
@@ -21402,7 +21758,7 @@ async function dispatchAdmittedCoder(input) {
|
|
|
21402
21758
|
...env.piRunner === void 0 ? {} : { runner: env.piRunner }
|
|
21403
21759
|
});
|
|
21404
21760
|
} catch (error) {
|
|
21405
|
-
return await
|
|
21761
|
+
return await presentControlledFailure2(
|
|
21406
21762
|
admitted,
|
|
21407
21763
|
{
|
|
21408
21764
|
timedOut: false,
|
|
@@ -21427,7 +21783,7 @@ async function dispatchAdmittedCoder(input) {
|
|
|
21427
21783
|
...methodProvenance === void 0 ? {} : { methodProvenance }
|
|
21428
21784
|
});
|
|
21429
21785
|
} catch (error) {
|
|
21430
|
-
return await
|
|
21786
|
+
return await presentControlledFailure2(
|
|
21431
21787
|
admitted,
|
|
21432
21788
|
{
|
|
21433
21789
|
timedOut: false,
|
|
@@ -21458,7 +21814,7 @@ async function dispatchAdmittedCoder(input) {
|
|
|
21458
21814
|
credential: credentialFailure,
|
|
21459
21815
|
runDirectory: admitted.runDirectory
|
|
21460
21816
|
});
|
|
21461
|
-
return await
|
|
21817
|
+
return await presentControlledFailure2(
|
|
21462
21818
|
admitted,
|
|
21463
21819
|
{
|
|
21464
21820
|
timedOut: result2.timedOut,
|
|
@@ -21513,7 +21869,7 @@ async function runPublicCoder(argv, env, io, parseCoderArgv2) {
|
|
|
21513
21869
|
methodProvenance = material.provenance;
|
|
21514
21870
|
} catch (error) {
|
|
21515
21871
|
await lease.release();
|
|
21516
|
-
return await
|
|
21872
|
+
return await presentControlledFailure2(
|
|
21517
21873
|
admitted,
|
|
21518
21874
|
{
|
|
21519
21875
|
timedOut: false,
|
|
@@ -21590,7 +21946,7 @@ async function runPublicCoderResume(argv, env, io) {
|
|
|
21590
21946
|
methodProvenance = material.provenance;
|
|
21591
21947
|
} catch (error) {
|
|
21592
21948
|
await lease.release();
|
|
21593
|
-
return await
|
|
21949
|
+
return await presentControlledFailure2(
|
|
21594
21950
|
admitted,
|
|
21595
21951
|
{
|
|
21596
21952
|
timedOut: false,
|
|
@@ -21673,7 +22029,7 @@ function buildCollectorActivationExtraArgs(admitted, options = {}) {
|
|
|
21673
22029
|
prompt
|
|
21674
22030
|
];
|
|
21675
22031
|
}
|
|
21676
|
-
async function
|
|
22032
|
+
async function presentControlledFailure3(admitted, failureInput, io) {
|
|
21677
22033
|
const hasThrown = Object.hasOwn(failureInput, "thrown");
|
|
21678
22034
|
const session = !hasThrown && !failureInput.timedOut && failureInput.knownFailure === void 0 && failureInput.knownCause === void 0 ? await inspectJudgeSession(admitted.sessionFile) : void 0;
|
|
21679
22035
|
const failure = classifyPostAdmissionFailure({
|
|
@@ -21704,7 +22060,7 @@ async function dispatchAdmittedCollector(input) {
|
|
|
21704
22060
|
env.credentials
|
|
21705
22061
|
);
|
|
21706
22062
|
if (missingCredential !== void 0) {
|
|
21707
|
-
return await
|
|
22063
|
+
return await presentControlledFailure3(
|
|
21708
22064
|
admitted,
|
|
21709
22065
|
missingCredential,
|
|
21710
22066
|
io
|
|
@@ -21735,7 +22091,7 @@ async function dispatchAdmittedCollector(input) {
|
|
|
21735
22091
|
...env.piRunner === void 0 ? {} : { runner: env.piRunner }
|
|
21736
22092
|
});
|
|
21737
22093
|
} catch (error) {
|
|
21738
|
-
return await
|
|
22094
|
+
return await presentControlledFailure3(
|
|
21739
22095
|
admitted,
|
|
21740
22096
|
{
|
|
21741
22097
|
timedOut: false,
|
|
@@ -21758,7 +22114,7 @@ async function dispatchAdmittedCollector(input) {
|
|
|
21758
22114
|
try {
|
|
21759
22115
|
lawful = await trySettleCollectorTerminalResult(admitted);
|
|
21760
22116
|
} catch (error) {
|
|
21761
|
-
return await
|
|
22117
|
+
return await presentControlledFailure3(
|
|
21762
22118
|
admitted,
|
|
21763
22119
|
{
|
|
21764
22120
|
timedOut: false,
|
|
@@ -21796,7 +22152,7 @@ async function dispatchAdmittedCollector(input) {
|
|
|
21796
22152
|
credential: credentialFailure,
|
|
21797
22153
|
runDirectory: admitted.runDirectory
|
|
21798
22154
|
});
|
|
21799
|
-
return await
|
|
22155
|
+
return await presentControlledFailure3(
|
|
21800
22156
|
admitted,
|
|
21801
22157
|
{
|
|
21802
22158
|
timedOut: result2.timedOut,
|
|
@@ -21907,7 +22263,7 @@ function buildDoctorActivationExtraArgs(admitted, options = {}) {
|
|
|
21907
22263
|
prompt
|
|
21908
22264
|
];
|
|
21909
22265
|
}
|
|
21910
|
-
async function
|
|
22266
|
+
async function presentControlledFailure4(admitted, failureInput, io) {
|
|
21911
22267
|
const hasThrown = Object.hasOwn(failureInput, "thrown");
|
|
21912
22268
|
const session = !hasThrown && !failureInput.timedOut && failureInput.knownFailure === void 0 ? await inspectJudgeSession(admitted.sessionFile) : void 0;
|
|
21913
22269
|
const failure = classifyPostAdmissionFailure({
|
|
@@ -21935,7 +22291,7 @@ async function dispatchAdmittedDoctor(input) {
|
|
|
21935
22291
|
env.credentials
|
|
21936
22292
|
);
|
|
21937
22293
|
if (missingCredential !== void 0) {
|
|
21938
|
-
return await
|
|
22294
|
+
return await presentControlledFailure4(
|
|
21939
22295
|
admitted,
|
|
21940
22296
|
missingCredential,
|
|
21941
22297
|
io
|
|
@@ -21965,7 +22321,7 @@ async function dispatchAdmittedDoctor(input) {
|
|
|
21965
22321
|
...env.piRunner === void 0 ? {} : { runner: env.piRunner }
|
|
21966
22322
|
});
|
|
21967
22323
|
} catch (error) {
|
|
21968
|
-
return await
|
|
22324
|
+
return await presentControlledFailure4(
|
|
21969
22325
|
admitted,
|
|
21970
22326
|
{
|
|
21971
22327
|
timedOut: false,
|
|
@@ -21988,7 +22344,7 @@ async function dispatchAdmittedDoctor(input) {
|
|
|
21988
22344
|
try {
|
|
21989
22345
|
lawful = await trySettleDoctorTerminalResult(admitted);
|
|
21990
22346
|
} catch (error) {
|
|
21991
|
-
return await
|
|
22347
|
+
return await presentControlledFailure4(
|
|
21992
22348
|
admitted,
|
|
21993
22349
|
{
|
|
21994
22350
|
timedOut: false,
|
|
@@ -22033,7 +22389,7 @@ async function dispatchAdmittedDoctor(input) {
|
|
|
22033
22389
|
credential: credentialFailure,
|
|
22034
22390
|
runDirectory: admitted.runDirectory
|
|
22035
22391
|
});
|
|
22036
|
-
return await
|
|
22392
|
+
return await presentControlledFailure4(
|
|
22037
22393
|
admitted,
|
|
22038
22394
|
{
|
|
22039
22395
|
timedOut: result2.timedOut,
|
|
@@ -22187,7 +22543,7 @@ function buildFixerResumeActivationExtraArgs(admitted, options) {
|
|
|
22187
22543
|
RESUME_TRANSPORT_ENVELOPE
|
|
22188
22544
|
];
|
|
22189
22545
|
}
|
|
22190
|
-
async function
|
|
22546
|
+
async function presentControlledFailure5(admitted, failureInput, io) {
|
|
22191
22547
|
const hasThrown = Object.hasOwn(failureInput, "thrown");
|
|
22192
22548
|
const resumeObservation = await resolveControlledFailureResumeObservation({
|
|
22193
22549
|
runDirectory: admitted.runDirectory,
|
|
@@ -22240,7 +22596,7 @@ async function dispatchAdmittedFixer(input) {
|
|
|
22240
22596
|
env.credentials
|
|
22241
22597
|
);
|
|
22242
22598
|
if (missingCredential !== void 0) {
|
|
22243
|
-
return await
|
|
22599
|
+
return await presentControlledFailure5(
|
|
22244
22600
|
admitted,
|
|
22245
22601
|
missingCredential,
|
|
22246
22602
|
io
|
|
@@ -22271,7 +22627,7 @@ async function dispatchAdmittedFixer(input) {
|
|
|
22271
22627
|
...env.piRunner === void 0 ? {} : { runner: env.piRunner }
|
|
22272
22628
|
});
|
|
22273
22629
|
} catch (error) {
|
|
22274
|
-
return await
|
|
22630
|
+
return await presentControlledFailure5(
|
|
22275
22631
|
admitted,
|
|
22276
22632
|
{
|
|
22277
22633
|
timedOut: false,
|
|
@@ -22301,7 +22657,7 @@ async function dispatchAdmittedFixer(input) {
|
|
|
22301
22657
|
)
|
|
22302
22658
|
});
|
|
22303
22659
|
} catch (error) {
|
|
22304
|
-
return await
|
|
22660
|
+
return await presentControlledFailure5(
|
|
22305
22661
|
admitted,
|
|
22306
22662
|
{
|
|
22307
22663
|
timedOut: false,
|
|
@@ -22346,7 +22702,7 @@ async function dispatchAdmittedFixer(input) {
|
|
|
22346
22702
|
credential: credentialFailure,
|
|
22347
22703
|
runDirectory: admitted.runDirectory
|
|
22348
22704
|
});
|
|
22349
|
-
return await
|
|
22705
|
+
return await presentControlledFailure5(
|
|
22350
22706
|
admitted,
|
|
22351
22707
|
{
|
|
22352
22708
|
timedOut: result2.timedOut,
|
|
@@ -22400,7 +22756,7 @@ async function runPublicFixer(argv, env, io, parseFixerArgv2) {
|
|
|
22400
22756
|
methodMaterial = await loadFixerMethodMaterial(env.packageRoot);
|
|
22401
22757
|
} catch (error) {
|
|
22402
22758
|
await lease.release();
|
|
22403
|
-
return await
|
|
22759
|
+
return await presentControlledFailure5(
|
|
22404
22760
|
admitted,
|
|
22405
22761
|
{
|
|
22406
22762
|
timedOut: false,
|
|
@@ -22470,7 +22826,7 @@ async function runPublicFixerResume(argv, env, io) {
|
|
|
22470
22826
|
methodMaterial = await loadFixerMethodMaterial(env.packageRoot);
|
|
22471
22827
|
} catch (error) {
|
|
22472
22828
|
await lease.release();
|
|
22473
|
-
return await
|
|
22829
|
+
return await presentControlledFailure5(
|
|
22474
22830
|
admitted,
|
|
22475
22831
|
{
|
|
22476
22832
|
timedOut: false,
|
|
@@ -22566,7 +22922,7 @@ function buildJudgeResumeActivationExtraArgs(admitted, options = {}) {
|
|
|
22566
22922
|
RESUME_TRANSPORT_ENVELOPE
|
|
22567
22923
|
];
|
|
22568
22924
|
}
|
|
22569
|
-
async function
|
|
22925
|
+
async function presentControlledFailure6(admitted, failureInput, io) {
|
|
22570
22926
|
const hasThrown = Object.hasOwn(failureInput, "thrown");
|
|
22571
22927
|
const resumeObservation = await resolveControlledFailureResumeObservation({
|
|
22572
22928
|
runDirectory: admitted.runDirectory,
|
|
@@ -22619,7 +22975,7 @@ async function dispatchAdmittedJudge(input) {
|
|
|
22619
22975
|
env.credentials
|
|
22620
22976
|
);
|
|
22621
22977
|
if (missingCredential !== void 0) {
|
|
22622
|
-
return await
|
|
22978
|
+
return await presentControlledFailure6(
|
|
22623
22979
|
admitted,
|
|
22624
22980
|
missingCredential,
|
|
22625
22981
|
io
|
|
@@ -22652,7 +23008,7 @@ async function dispatchAdmittedJudge(input) {
|
|
|
22652
23008
|
...env.piRunner === void 0 ? {} : { runner: env.piRunner }
|
|
22653
23009
|
});
|
|
22654
23010
|
} catch (error) {
|
|
22655
|
-
return await
|
|
23011
|
+
return await presentControlledFailure6(
|
|
22656
23012
|
admitted,
|
|
22657
23013
|
{
|
|
22658
23014
|
timedOut: false,
|
|
@@ -22675,7 +23031,7 @@ async function dispatchAdmittedJudge(input) {
|
|
|
22675
23031
|
try {
|
|
22676
23032
|
lawful = await trySettleJudgeTerminalResult(admitted);
|
|
22677
23033
|
} catch (error) {
|
|
22678
|
-
return await
|
|
23034
|
+
return await presentControlledFailure6(
|
|
22679
23035
|
admitted,
|
|
22680
23036
|
{
|
|
22681
23037
|
timedOut: false,
|
|
@@ -22720,7 +23076,7 @@ async function dispatchAdmittedJudge(input) {
|
|
|
22720
23076
|
credential: credentialFailure,
|
|
22721
23077
|
runDirectory: admitted.runDirectory
|
|
22722
23078
|
});
|
|
22723
|
-
return await
|
|
23079
|
+
return await presentControlledFailure6(
|
|
22724
23080
|
admitted,
|
|
22725
23081
|
{
|
|
22726
23082
|
timedOut: result2.timedOut,
|
|
@@ -22913,7 +23269,7 @@ function buildMergerResumeActivationExtraArgs(admitted, options) {
|
|
|
22913
23269
|
RESUME_TRANSPORT_ENVELOPE
|
|
22914
23270
|
];
|
|
22915
23271
|
}
|
|
22916
|
-
async function
|
|
23272
|
+
async function presentControlledFailure7(admitted, failureInput, io) {
|
|
22917
23273
|
const hasThrown = Object.hasOwn(failureInput, "thrown");
|
|
22918
23274
|
const resumeObservation = await resolveControlledFailureResumeObservation({
|
|
22919
23275
|
runDirectory: admitted.runDirectory,
|
|
@@ -22969,7 +23325,7 @@ async function dispatchAdmittedMerger(input) {
|
|
|
22969
23325
|
env.credentials
|
|
22970
23326
|
);
|
|
22971
23327
|
if (missingCredential !== void 0) {
|
|
22972
|
-
return await
|
|
23328
|
+
return await presentControlledFailure7(
|
|
22973
23329
|
admitted,
|
|
22974
23330
|
missingCredential,
|
|
22975
23331
|
io
|
|
@@ -23000,7 +23356,7 @@ async function dispatchAdmittedMerger(input) {
|
|
|
23000
23356
|
...env.piRunner === void 0 ? {} : { runner: env.piRunner }
|
|
23001
23357
|
});
|
|
23002
23358
|
} catch (error) {
|
|
23003
|
-
return await
|
|
23359
|
+
return await presentControlledFailure7(
|
|
23004
23360
|
admitted,
|
|
23005
23361
|
{
|
|
23006
23362
|
timedOut: false,
|
|
@@ -23030,7 +23386,7 @@ async function dispatchAdmittedMerger(input) {
|
|
|
23030
23386
|
)
|
|
23031
23387
|
});
|
|
23032
23388
|
} catch (error) {
|
|
23033
|
-
return await
|
|
23389
|
+
return await presentControlledFailure7(
|
|
23034
23390
|
admitted,
|
|
23035
23391
|
{
|
|
23036
23392
|
timedOut: false,
|
|
@@ -23061,7 +23417,7 @@ async function dispatchAdmittedMerger(input) {
|
|
|
23061
23417
|
credential: credentialFailure,
|
|
23062
23418
|
runDirectory: admitted.runDirectory
|
|
23063
23419
|
});
|
|
23064
|
-
return await
|
|
23420
|
+
return await presentControlledFailure7(
|
|
23065
23421
|
admitted,
|
|
23066
23422
|
{
|
|
23067
23423
|
timedOut: result2.timedOut,
|
|
@@ -23167,7 +23523,7 @@ async function runPublicMerger(argv, env, io, parseMergerArgv2) {
|
|
|
23167
23523
|
...env.createRunId === void 0 ? {} : { createRunId: env.createRunId }
|
|
23168
23524
|
});
|
|
23169
23525
|
await markRunAdmitted(shell);
|
|
23170
|
-
return await
|
|
23526
|
+
return await presentControlledFailure7(
|
|
23171
23527
|
shell,
|
|
23172
23528
|
{
|
|
23173
23529
|
timedOut: false,
|
|
@@ -23198,7 +23554,7 @@ async function runPublicMerger(argv, env, io, parseMergerArgv2) {
|
|
|
23198
23554
|
methodMaterial = await loadMergerMethodMaterial(env.packageRoot);
|
|
23199
23555
|
} catch (error) {
|
|
23200
23556
|
await lease.release();
|
|
23201
|
-
return await
|
|
23557
|
+
return await presentControlledFailure7(
|
|
23202
23558
|
admitted,
|
|
23203
23559
|
{
|
|
23204
23560
|
timedOut: false,
|
|
@@ -23269,7 +23625,7 @@ async function runPublicMergerResume(argv, env, io) {
|
|
|
23269
23625
|
methodMaterial = await loadMergerMethodMaterial(env.packageRoot);
|
|
23270
23626
|
} catch (error) {
|
|
23271
23627
|
await lease.release();
|
|
23272
|
-
return await
|
|
23628
|
+
return await presentControlledFailure7(
|
|
23273
23629
|
admitted,
|
|
23274
23630
|
{
|
|
23275
23631
|
timedOut: false,
|
|
@@ -23335,6 +23691,7 @@ function buildReviewerActivationExtraArgs(admitted, options) {
|
|
|
23335
23691
|
options.packageRoot,
|
|
23336
23692
|
"code-review"
|
|
23337
23693
|
);
|
|
23694
|
+
const authorityRefArgs = admitted.authorityRefs.length === 0 ? [] : ["--ak-review-authority-refs", JSON.stringify([...admitted.authorityRefs])];
|
|
23338
23695
|
return [
|
|
23339
23696
|
"--no-skills",
|
|
23340
23697
|
"--skill",
|
|
@@ -23351,6 +23708,7 @@ function buildReviewerActivationExtraArgs(admitted, options) {
|
|
|
23351
23708
|
"reviewer",
|
|
23352
23709
|
"--ak-review-base",
|
|
23353
23710
|
admitted.baseRevision,
|
|
23711
|
+
...authorityRefArgs,
|
|
23354
23712
|
"--mode",
|
|
23355
23713
|
"json",
|
|
23356
23714
|
...buildModelArgs7(options.model),
|
|
@@ -23362,6 +23720,7 @@ function buildReviewerResumeActivationExtraArgs(admitted, options) {
|
|
|
23362
23720
|
options.packageRoot,
|
|
23363
23721
|
"code-review"
|
|
23364
23722
|
);
|
|
23723
|
+
const authorityRefArgs = admitted.authorityRefs.length === 0 ? [] : ["--ak-review-authority-refs", JSON.stringify([...admitted.authorityRefs])];
|
|
23365
23724
|
return [
|
|
23366
23725
|
"--no-skills",
|
|
23367
23726
|
"--skill",
|
|
@@ -23378,13 +23737,14 @@ function buildReviewerResumeActivationExtraArgs(admitted, options) {
|
|
|
23378
23737
|
"reviewer",
|
|
23379
23738
|
"--ak-review-base",
|
|
23380
23739
|
admitted.baseRevision,
|
|
23740
|
+
...authorityRefArgs,
|
|
23381
23741
|
"--mode",
|
|
23382
23742
|
"json",
|
|
23383
23743
|
...buildModelArgs7(options.model),
|
|
23384
23744
|
RESUME_TRANSPORT_ENVELOPE
|
|
23385
23745
|
];
|
|
23386
23746
|
}
|
|
23387
|
-
async function
|
|
23747
|
+
async function presentControlledFailure8(admitted, failureInput, io) {
|
|
23388
23748
|
const hasThrown = Object.hasOwn(failureInput, "thrown");
|
|
23389
23749
|
const resumeObservation = await resolveControlledFailureResumeObservation({
|
|
23390
23750
|
runDirectory: admitted.runDirectory,
|
|
@@ -23437,7 +23797,7 @@ async function dispatchAdmittedReviewer(input) {
|
|
|
23437
23797
|
env.credentials
|
|
23438
23798
|
);
|
|
23439
23799
|
if (missingCredential !== void 0) {
|
|
23440
|
-
return await
|
|
23800
|
+
return await presentControlledFailure8(
|
|
23441
23801
|
admitted,
|
|
23442
23802
|
missingCredential,
|
|
23443
23803
|
io
|
|
@@ -23469,7 +23829,7 @@ async function dispatchAdmittedReviewer(input) {
|
|
|
23469
23829
|
...env.piRunner === void 0 ? {} : { runner: env.piRunner }
|
|
23470
23830
|
});
|
|
23471
23831
|
} catch (error) {
|
|
23472
|
-
return await
|
|
23832
|
+
return await presentControlledFailure8(
|
|
23473
23833
|
admitted,
|
|
23474
23834
|
{
|
|
23475
23835
|
timedOut: false,
|
|
@@ -23499,7 +23859,7 @@ async function dispatchAdmittedReviewer(input) {
|
|
|
23499
23859
|
)
|
|
23500
23860
|
});
|
|
23501
23861
|
} catch (error) {
|
|
23502
|
-
return await
|
|
23862
|
+
return await presentControlledFailure8(
|
|
23503
23863
|
admitted,
|
|
23504
23864
|
{
|
|
23505
23865
|
timedOut: false,
|
|
@@ -23544,7 +23904,7 @@ async function dispatchAdmittedReviewer(input) {
|
|
|
23544
23904
|
credential: credentialFailure,
|
|
23545
23905
|
runDirectory: admitted.runDirectory
|
|
23546
23906
|
});
|
|
23547
|
-
return await
|
|
23907
|
+
return await presentControlledFailure8(
|
|
23548
23908
|
admitted,
|
|
23549
23909
|
{
|
|
23550
23910
|
timedOut: result2.timedOut,
|
|
@@ -23571,6 +23931,7 @@ async function runPublicReviewer(argv, env, io, parseReviewerArgv2) {
|
|
|
23571
23931
|
instruction: parsed.instruction,
|
|
23572
23932
|
attachmentPaths: parsed.attachmentPaths,
|
|
23573
23933
|
baseRevision: parsed.baseRevision,
|
|
23934
|
+
authorityRefs: parsed.authorityRefs,
|
|
23574
23935
|
...parsed.project === void 0 ? {} : { project: parsed.project },
|
|
23575
23936
|
...env.createRunId === void 0 ? {} : { createRunId: env.createRunId }
|
|
23576
23937
|
});
|
|
@@ -23597,7 +23958,7 @@ async function runPublicReviewer(argv, env, io, parseReviewerArgv2) {
|
|
|
23597
23958
|
methodMaterial = await loadReviewerMethodMaterial(env.packageRoot);
|
|
23598
23959
|
} catch (error) {
|
|
23599
23960
|
await lease.release();
|
|
23600
|
-
return await
|
|
23961
|
+
return await presentControlledFailure8(
|
|
23601
23962
|
admitted,
|
|
23602
23963
|
{
|
|
23603
23964
|
timedOut: false,
|
|
@@ -23667,7 +24028,7 @@ async function runPublicReviewerResume(argv, env, io) {
|
|
|
23667
24028
|
methodMaterial = await loadReviewerMethodMaterial(env.packageRoot);
|
|
23668
24029
|
} catch (error) {
|
|
23669
24030
|
await lease.release();
|
|
23670
|
-
return await
|
|
24031
|
+
return await presentControlledFailure8(
|
|
23671
24032
|
admitted,
|
|
23672
24033
|
{
|
|
23673
24034
|
timedOut: false,
|
|
@@ -23709,22 +24070,2080 @@ var init_reviewer_run = __esm({
|
|
|
23709
24070
|
}
|
|
23710
24071
|
});
|
|
23711
24072
|
|
|
23712
|
-
// src/
|
|
23713
|
-
|
|
23714
|
-
|
|
23715
|
-
|
|
23716
|
-
|
|
23717
|
-
|
|
23718
|
-
|
|
23719
|
-
|
|
23720
|
-
|
|
23721
|
-
|
|
23722
|
-
|
|
23723
|
-
|
|
23724
|
-
|
|
23725
|
-
|
|
23726
|
-
|
|
23727
|
-
|
|
24073
|
+
// src/atomic-write.ts
|
|
24074
|
+
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
24075
|
+
import { rename, rm, writeFile as writeFile13 } from "node:fs/promises";
|
|
24076
|
+
import { dirname as dirname7, join as join18 } from "node:path";
|
|
24077
|
+
async function writeFileAtomically(destination, contents) {
|
|
24078
|
+
const parent = dirname7(destination);
|
|
24079
|
+
const temporary = join18(parent, `.atomic-write-${randomUUID2()}.tmp`);
|
|
24080
|
+
try {
|
|
24081
|
+
await writeFile13(temporary, contents);
|
|
24082
|
+
await rename(temporary, destination);
|
|
24083
|
+
} catch (error) {
|
|
24084
|
+
await rm(temporary, { force: true }).catch(() => void 0);
|
|
24085
|
+
throw error;
|
|
24086
|
+
}
|
|
24087
|
+
}
|
|
24088
|
+
var init_atomic_write = __esm({
|
|
24089
|
+
"src/atomic-write.ts"() {
|
|
24090
|
+
"use strict";
|
|
24091
|
+
}
|
|
24092
|
+
});
|
|
24093
|
+
|
|
24094
|
+
// src/taishi-index.ts
|
|
24095
|
+
import { open as open3, readFile as readFile10, unlink as unlink4 } from "node:fs/promises";
|
|
24096
|
+
import { dirname as dirname8, join as join19 } from "node:path";
|
|
24097
|
+
function sleep(ms) {
|
|
24098
|
+
return new Promise((resolve9) => {
|
|
24099
|
+
setTimeout(resolve9, ms);
|
|
24100
|
+
});
|
|
24101
|
+
}
|
|
24102
|
+
async function withTaishiLibraryIndexLock(ledgerHome, fn) {
|
|
24103
|
+
const indexPath = taishiLibraryIndexPath(ledgerHome);
|
|
24104
|
+
ensureRealDirectoryTree(ledgerHome, dirname8(indexPath));
|
|
24105
|
+
const lockPath = join19(dirname8(indexPath), LIBRARY_INDEX_LOCK_NAME);
|
|
24106
|
+
assertLedgerFileInsideHome(lockPath, ledgerHome);
|
|
24107
|
+
const startedAt = Date.now();
|
|
24108
|
+
while (true) {
|
|
24109
|
+
try {
|
|
24110
|
+
const handle = await open3(lockPath, "wx");
|
|
24111
|
+
try {
|
|
24112
|
+
await handle.writeFile(`${process.pid}
|
|
24113
|
+
`, "utf8");
|
|
24114
|
+
return await fn();
|
|
24115
|
+
} finally {
|
|
24116
|
+
await handle.close().catch(() => void 0);
|
|
24117
|
+
await unlink4(lockPath).catch(() => void 0);
|
|
24118
|
+
}
|
|
24119
|
+
} catch (error) {
|
|
24120
|
+
const code = error instanceof Error && "code" in error ? error.code : void 0;
|
|
24121
|
+
if (code !== "EEXIST") throw error;
|
|
24122
|
+
if (Date.now() - startedAt > LIBRARY_INDEX_LOCK_TIMEOUT_MS) {
|
|
24123
|
+
throw new Error(
|
|
24124
|
+
`taishi library-index lock timeout after ${LIBRARY_INDEX_LOCK_TIMEOUT_MS}ms: ${lockPath}`
|
|
24125
|
+
);
|
|
24126
|
+
}
|
|
24127
|
+
await sleep(LIBRARY_INDEX_LOCK_RETRY_MS);
|
|
24128
|
+
}
|
|
24129
|
+
}
|
|
24130
|
+
}
|
|
24131
|
+
function taishiLibraryIndexPath(ledgerHome) {
|
|
24132
|
+
return join19(ledgerHome, "taishi", "library-index.json");
|
|
24133
|
+
}
|
|
24134
|
+
function rowFromIssueMetricsPage(page) {
|
|
24135
|
+
return {
|
|
24136
|
+
projectRoot: page.projectRoot,
|
|
24137
|
+
// exactOptionalPropertyTypes: only materialize when page carries it.
|
|
24138
|
+
...page.issueNumber === void 0 ? {} : { issueNumber: page.issueNumber },
|
|
24139
|
+
totalElapsedMs: page.totalElapsedMs,
|
|
24140
|
+
changedLines: page.changedLines,
|
|
24141
|
+
msPerKLines: page.msPerKLines,
|
|
24142
|
+
lastActivityAt: page.lastActivityAt
|
|
24143
|
+
};
|
|
24144
|
+
}
|
|
24145
|
+
function sortRows(rows) {
|
|
24146
|
+
return [...rows].sort((a, b) => {
|
|
24147
|
+
const byRoot = a.projectRoot.localeCompare(b.projectRoot);
|
|
24148
|
+
if (byRoot !== 0) return byRoot;
|
|
24149
|
+
const aNum = a.issueNumber;
|
|
24150
|
+
const bNum = b.issueNumber;
|
|
24151
|
+
if (aNum === void 0 && bNum === void 0) return 0;
|
|
24152
|
+
if (aNum === void 0) return 1;
|
|
24153
|
+
if (bNum === void 0) return -1;
|
|
24154
|
+
return aNum - bNum;
|
|
24155
|
+
});
|
|
24156
|
+
}
|
|
24157
|
+
function buildTaishiLibraryIndexPage(rows) {
|
|
24158
|
+
return {
|
|
24159
|
+
kind: "taishi-library-index",
|
|
24160
|
+
rows: sortRows(rows)
|
|
24161
|
+
};
|
|
24162
|
+
}
|
|
24163
|
+
function findTaishiLibraryIndexRow(index, issueNumber) {
|
|
24164
|
+
if (index === void 0) return void 0;
|
|
24165
|
+
return index.rows.find((row) => row.issueNumber === issueNumber);
|
|
24166
|
+
}
|
|
24167
|
+
function upsertTaishiLibraryIndexRows(existing, upserts) {
|
|
24168
|
+
const byRoot = /* @__PURE__ */ new Map();
|
|
24169
|
+
const rootByIssue = /* @__PURE__ */ new Map();
|
|
24170
|
+
const ingest = (row) => {
|
|
24171
|
+
if (row.issueNumber !== void 0) {
|
|
24172
|
+
const priorRoot = rootByIssue.get(row.issueNumber);
|
|
24173
|
+
if (priorRoot !== void 0 && priorRoot !== row.projectRoot) {
|
|
24174
|
+
byRoot.delete(priorRoot);
|
|
24175
|
+
}
|
|
24176
|
+
}
|
|
24177
|
+
const prior = byRoot.get(row.projectRoot);
|
|
24178
|
+
if (prior !== void 0 && prior.issueNumber !== void 0 && prior.issueNumber !== row.issueNumber) {
|
|
24179
|
+
rootByIssue.delete(prior.issueNumber);
|
|
24180
|
+
}
|
|
24181
|
+
byRoot.set(row.projectRoot, row);
|
|
24182
|
+
if (row.issueNumber !== void 0) {
|
|
24183
|
+
rootByIssue.set(row.issueNumber, row.projectRoot);
|
|
24184
|
+
}
|
|
24185
|
+
};
|
|
24186
|
+
if (existing !== void 0) {
|
|
24187
|
+
for (const row of existing.rows) {
|
|
24188
|
+
ingest(row);
|
|
24189
|
+
}
|
|
24190
|
+
}
|
|
24191
|
+
for (const row of upserts) {
|
|
24192
|
+
ingest(row);
|
|
24193
|
+
}
|
|
24194
|
+
return buildTaishiLibraryIndexPage([...byRoot.values()]);
|
|
24195
|
+
}
|
|
24196
|
+
async function readTaishiLibraryIndexPage(ledgerHome) {
|
|
24197
|
+
const path = taishiLibraryIndexPath(ledgerHome);
|
|
24198
|
+
let raw;
|
|
24199
|
+
try {
|
|
24200
|
+
raw = await readFile10(path, "utf8");
|
|
24201
|
+
} catch (error) {
|
|
24202
|
+
if (error instanceof Error && "code" in error && (error.code === "ENOENT" || error.code === "ENOTDIR")) {
|
|
24203
|
+
return void 0;
|
|
24204
|
+
}
|
|
24205
|
+
throw error;
|
|
24206
|
+
}
|
|
24207
|
+
return JSON.parse(raw);
|
|
24208
|
+
}
|
|
24209
|
+
async function writeTaishiLibraryIndexPage(ledgerHome, page) {
|
|
24210
|
+
const path = taishiLibraryIndexPath(ledgerHome);
|
|
24211
|
+
ensureRealDirectoryTree(ledgerHome, dirname8(path));
|
|
24212
|
+
assertLedgerFileInsideHome(path, ledgerHome);
|
|
24213
|
+
await writeFileAtomically(path, `${JSON.stringify(page, null, 2)}
|
|
24214
|
+
`);
|
|
24215
|
+
return path;
|
|
24216
|
+
}
|
|
24217
|
+
async function mergeTaishiLibraryIndexRows(ledgerHome, upserts) {
|
|
24218
|
+
return withTaishiLibraryIndexLock(ledgerHome, async () => {
|
|
24219
|
+
const existing = await readTaishiLibraryIndexPage(ledgerHome);
|
|
24220
|
+
const index = upsertTaishiLibraryIndexRows(existing, upserts);
|
|
24221
|
+
const indexPath = await writeTaishiLibraryIndexPage(ledgerHome, index);
|
|
24222
|
+
return { index, indexPath };
|
|
24223
|
+
});
|
|
24224
|
+
}
|
|
24225
|
+
var LIBRARY_INDEX_LOCK_NAME, LIBRARY_INDEX_LOCK_TIMEOUT_MS, LIBRARY_INDEX_LOCK_RETRY_MS;
|
|
24226
|
+
var init_taishi_index = __esm({
|
|
24227
|
+
"src/taishi-index.ts"() {
|
|
24228
|
+
"use strict";
|
|
24229
|
+
init_atomic_write();
|
|
24230
|
+
init_activation_ledger_topology();
|
|
24231
|
+
LIBRARY_INDEX_LOCK_NAME = ".library-index.lock";
|
|
24232
|
+
LIBRARY_INDEX_LOCK_TIMEOUT_MS = 3e4;
|
|
24233
|
+
LIBRARY_INDEX_LOCK_RETRY_MS = 15;
|
|
24234
|
+
}
|
|
24235
|
+
});
|
|
24236
|
+
|
|
24237
|
+
// src/taishi-median.ts
|
|
24238
|
+
function medianNumber(values) {
|
|
24239
|
+
if (values.length === 0) return void 0;
|
|
24240
|
+
const sorted = [...values].sort((a, b) => a - b);
|
|
24241
|
+
const mid = Math.floor(sorted.length / 2);
|
|
24242
|
+
if (sorted.length % 2 === 1) {
|
|
24243
|
+
return sorted[mid];
|
|
24244
|
+
}
|
|
24245
|
+
return (sorted[mid - 1] + sorted[mid]) / 2;
|
|
24246
|
+
}
|
|
24247
|
+
var init_taishi_median = __esm({
|
|
24248
|
+
"src/taishi-median.ts"() {
|
|
24249
|
+
"use strict";
|
|
24250
|
+
}
|
|
24251
|
+
});
|
|
24252
|
+
|
|
24253
|
+
// src/taishi-cohort.ts
|
|
24254
|
+
function presentMetric(value) {
|
|
24255
|
+
return { status: "present", value };
|
|
24256
|
+
}
|
|
24257
|
+
function rateMetric(numerator, denominator) {
|
|
24258
|
+
if (denominator === 0) return ABSENT;
|
|
24259
|
+
return presentMetric(numerator / denominator);
|
|
24260
|
+
}
|
|
24261
|
+
function optionalMedian(values) {
|
|
24262
|
+
const median = medianNumber(values);
|
|
24263
|
+
return median === void 0 ? ABSENT : presentMetric(median);
|
|
24264
|
+
}
|
|
24265
|
+
function emptyRoleAccum() {
|
|
24266
|
+
return {
|
|
24267
|
+
convergenceRounds: [],
|
|
24268
|
+
firstPassLaneCount: 0,
|
|
24269
|
+
appearanceLaneCount: 0,
|
|
24270
|
+
successCount: 0,
|
|
24271
|
+
successEligibleCount: 0
|
|
24272
|
+
};
|
|
24273
|
+
}
|
|
24274
|
+
function absorbRole(accum, stats) {
|
|
24275
|
+
accum.convergenceRounds.push(...stats.convergenceRounds);
|
|
24276
|
+
accum.firstPassLaneCount += stats.firstPassLaneCount;
|
|
24277
|
+
accum.appearanceLaneCount += stats.appearanceLaneCount;
|
|
24278
|
+
accum.successCount += stats.successCount;
|
|
24279
|
+
accum.successEligibleCount += stats.successEligibleCount;
|
|
24280
|
+
}
|
|
24281
|
+
function finishRole(role, accum) {
|
|
24282
|
+
return {
|
|
24283
|
+
role,
|
|
24284
|
+
convergenceRounds: accum.convergenceRounds,
|
|
24285
|
+
convergenceRoundsMedian: optionalMedian(accum.convergenceRounds),
|
|
24286
|
+
firstPassRate: rateMetric(accum.firstPassLaneCount, accum.appearanceLaneCount),
|
|
24287
|
+
successRate: rateMetric(accum.successCount, accum.successEligibleCount)
|
|
24288
|
+
};
|
|
24289
|
+
}
|
|
24290
|
+
async function aggregateGroup(index, input, ensureIssuePage) {
|
|
24291
|
+
const issueEntries = [];
|
|
24292
|
+
const roleAccums = /* @__PURE__ */ new Map();
|
|
24293
|
+
let reworkWallMs = 0;
|
|
24294
|
+
let totalWallMs = 0;
|
|
24295
|
+
let hasReworkSample = false;
|
|
24296
|
+
const legWalls = [];
|
|
24297
|
+
for (const issueNumber of input.issues) {
|
|
24298
|
+
const row = findTaishiLibraryIndexRow(index, issueNumber);
|
|
24299
|
+
if (row === void 0) {
|
|
24300
|
+
issueEntries.push({ issueNumber, status: "absent" });
|
|
24301
|
+
continue;
|
|
24302
|
+
}
|
|
24303
|
+
const page = await ensureIssuePage({
|
|
24304
|
+
projectRoot: row.projectRoot,
|
|
24305
|
+
issueNumber
|
|
24306
|
+
});
|
|
24307
|
+
issueEntries.push({
|
|
24308
|
+
issueNumber,
|
|
24309
|
+
status: "present",
|
|
24310
|
+
projectRoot: row.projectRoot
|
|
24311
|
+
});
|
|
24312
|
+
const acceptance = page.acceptanceSuccessRework;
|
|
24313
|
+
if (acceptance !== void 0) {
|
|
24314
|
+
for (const roleStats of acceptance.byRole) {
|
|
24315
|
+
const accum = roleAccums.get(roleStats.role) ?? emptyRoleAccum();
|
|
24316
|
+
absorbRole(accum, roleStats);
|
|
24317
|
+
roleAccums.set(roleStats.role, accum);
|
|
24318
|
+
}
|
|
24319
|
+
reworkWallMs += acceptance.rework.reworkWallMs;
|
|
24320
|
+
totalWallMs += acceptance.rework.totalWallMs;
|
|
24321
|
+
hasReworkSample = true;
|
|
24322
|
+
}
|
|
24323
|
+
const legWallClock = page.legWallClock;
|
|
24324
|
+
if (legWallClock !== void 0) {
|
|
24325
|
+
for (const leg of legWallClock.ranking) {
|
|
24326
|
+
legWalls.push(leg.wallMs);
|
|
24327
|
+
}
|
|
24328
|
+
}
|
|
24329
|
+
}
|
|
24330
|
+
const byRole = [...roleAccums.keys()].sort((a, b) => a.localeCompare(b)).map((role) => finishRole(role, roleAccums.get(role)));
|
|
24331
|
+
return {
|
|
24332
|
+
groupLabel: input.groupLabel,
|
|
24333
|
+
issues: issueEntries,
|
|
24334
|
+
byRole,
|
|
24335
|
+
reworkRatio: hasReworkSample ? rateMetric(reworkWallMs, totalWallMs) : ABSENT,
|
|
24336
|
+
medianWallMs: optionalMedian(legWalls)
|
|
24337
|
+
};
|
|
24338
|
+
}
|
|
24339
|
+
async function runTaishiCohortMode(ledgerHome, input, ensureIssuePage) {
|
|
24340
|
+
const index = await readTaishiLibraryIndexPage(ledgerHome);
|
|
24341
|
+
const group0 = await aggregateGroup(index, input.groups[0], ensureIssuePage);
|
|
24342
|
+
const group1 = await aggregateGroup(index, input.groups[1], ensureIssuePage);
|
|
24343
|
+
return {
|
|
24344
|
+
mode: "cohort",
|
|
24345
|
+
groups: [group0, group1]
|
|
24346
|
+
};
|
|
24347
|
+
}
|
|
24348
|
+
var ABSENT;
|
|
24349
|
+
var init_taishi_cohort = __esm({
|
|
24350
|
+
"src/taishi-cohort.ts"() {
|
|
24351
|
+
"use strict";
|
|
24352
|
+
init_taishi_index();
|
|
24353
|
+
init_taishi_median();
|
|
24354
|
+
ABSENT = { status: "absent" };
|
|
24355
|
+
}
|
|
24356
|
+
});
|
|
24357
|
+
|
|
24358
|
+
// src/ledger-session-read.ts
|
|
24359
|
+
import { readFile as readFile11 } from "node:fs/promises";
|
|
24360
|
+
function isRecord6(value) {
|
|
24361
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
24362
|
+
}
|
|
24363
|
+
async function readLedgerSessionJsonl(path) {
|
|
24364
|
+
const text = await readFile11(path, "utf8");
|
|
24365
|
+
const lines = text.split("\n");
|
|
24366
|
+
const rows = [];
|
|
24367
|
+
for (let index = 0; index < lines.length; index += 1) {
|
|
24368
|
+
const line2 = lines[index];
|
|
24369
|
+
if (!line2.trim()) continue;
|
|
24370
|
+
let row;
|
|
24371
|
+
try {
|
|
24372
|
+
row = JSON.parse(line2);
|
|
24373
|
+
} catch (error) {
|
|
24374
|
+
if (!(error instanceof SyntaxError)) throw error;
|
|
24375
|
+
const completedByTerminator = index < lines.length - 1;
|
|
24376
|
+
if (completedByTerminator) {
|
|
24377
|
+
throw new LedgerSessionJsonlError(
|
|
24378
|
+
`malformed JSONL record in ${path} at line ${index + 1}: ${error.message}`,
|
|
24379
|
+
{ path, line: index + 1, prefixRows: rows }
|
|
24380
|
+
);
|
|
24381
|
+
}
|
|
24382
|
+
break;
|
|
24383
|
+
}
|
|
24384
|
+
if (!isRecord6(row)) {
|
|
24385
|
+
const kind = row === null ? "null" : Array.isArray(row) ? "array" : typeof row;
|
|
24386
|
+
throw new LedgerSessionJsonlError(
|
|
24387
|
+
`complete non-object JSONL record in ${path} at line ${index + 1}: expected object, got ${kind}`,
|
|
24388
|
+
{ path, line: index + 1, prefixRows: rows }
|
|
24389
|
+
);
|
|
24390
|
+
}
|
|
24391
|
+
rows.push(row);
|
|
24392
|
+
}
|
|
24393
|
+
return rows;
|
|
24394
|
+
}
|
|
24395
|
+
function extractSessionTimestampSpan(rows) {
|
|
24396
|
+
let startedAt;
|
|
24397
|
+
let endedAt;
|
|
24398
|
+
for (const row of rows) {
|
|
24399
|
+
if (typeof row.timestamp !== "string" || !row.timestamp) continue;
|
|
24400
|
+
if (startedAt === void 0) startedAt = row.timestamp;
|
|
24401
|
+
endedAt = row.timestamp;
|
|
24402
|
+
}
|
|
24403
|
+
return {
|
|
24404
|
+
...startedAt !== void 0 ? { startedAt } : {},
|
|
24405
|
+
...endedAt !== void 0 ? { endedAt } : {}
|
|
24406
|
+
};
|
|
24407
|
+
}
|
|
24408
|
+
function extractSessionModelSequence(rows) {
|
|
24409
|
+
const seen = /* @__PURE__ */ new Set();
|
|
24410
|
+
const ordered = [];
|
|
24411
|
+
const push = (raw) => {
|
|
24412
|
+
const model = raw.trim();
|
|
24413
|
+
if (model === "" || seen.has(model)) return;
|
|
24414
|
+
seen.add(model);
|
|
24415
|
+
ordered.push(model);
|
|
24416
|
+
};
|
|
24417
|
+
for (const row of rows) {
|
|
24418
|
+
if (row.type === "model_change" && typeof row.modelId === "string") {
|
|
24419
|
+
push(row.modelId);
|
|
24420
|
+
}
|
|
24421
|
+
const message = isRecord6(row.message) ? row.message : void 0;
|
|
24422
|
+
if (message?.role === "assistant" && typeof message.model === "string") {
|
|
24423
|
+
push(message.model);
|
|
24424
|
+
}
|
|
24425
|
+
}
|
|
24426
|
+
return ordered;
|
|
24427
|
+
}
|
|
24428
|
+
function bashCommandFirstLine(command) {
|
|
24429
|
+
const match = /^[^\r\n]*/.exec(command);
|
|
24430
|
+
return match?.[0] ?? "";
|
|
24431
|
+
}
|
|
24432
|
+
function extractSessionToolIntervals(rows) {
|
|
24433
|
+
const order = [];
|
|
24434
|
+
const openById = /* @__PURE__ */ new Map();
|
|
24435
|
+
for (const row of rows) {
|
|
24436
|
+
const rowTimestamp = typeof row.timestamp === "string" ? row.timestamp : void 0;
|
|
24437
|
+
const message = isRecord6(row.message) ? row.message : void 0;
|
|
24438
|
+
if (message?.role === "assistant" && Array.isArray(message.content)) {
|
|
24439
|
+
const callTimestamp = typeof message.timestamp === "string" && message.timestamp ? message.timestamp : rowTimestamp;
|
|
24440
|
+
for (const part of message.content) {
|
|
24441
|
+
if (!isRecord6(part) || part.type !== "toolCall") continue;
|
|
24442
|
+
if (typeof part.id !== "string" || part.id.length === 0) {
|
|
24443
|
+
throw new Error("toolCall frame missing string id");
|
|
24444
|
+
}
|
|
24445
|
+
if (typeof part.name !== "string" || part.name.length === 0) {
|
|
24446
|
+
throw new Error(`toolCall ${part.id} missing string name`);
|
|
24447
|
+
}
|
|
24448
|
+
if (callTimestamp === void 0 || callTimestamp.length === 0) {
|
|
24449
|
+
throw new Error(`toolCall ${part.id} missing timestamp`);
|
|
24450
|
+
}
|
|
24451
|
+
if (openById.has(part.id)) {
|
|
24452
|
+
throw new Error(`duplicate toolCall id ${part.id}`);
|
|
24453
|
+
}
|
|
24454
|
+
const args = isRecord6(part.arguments) ? part.arguments : void 0;
|
|
24455
|
+
const command = part.name === "bash" && args !== void 0 && typeof args.command === "string" ? bashCommandFirstLine(args.command) : void 0;
|
|
24456
|
+
const interval = {
|
|
24457
|
+
toolCallId: part.id,
|
|
24458
|
+
toolName: part.name,
|
|
24459
|
+
startedAt: callTimestamp,
|
|
24460
|
+
...command !== void 0 ? { command } : {}
|
|
24461
|
+
};
|
|
24462
|
+
order.push(interval);
|
|
24463
|
+
openById.set(part.id, interval);
|
|
24464
|
+
}
|
|
24465
|
+
}
|
|
24466
|
+
if (message?.role === "toolResult") {
|
|
24467
|
+
if (typeof message.toolCallId !== "string" || message.toolCallId.length === 0) {
|
|
24468
|
+
throw new Error("toolResult frame missing string toolCallId");
|
|
24469
|
+
}
|
|
24470
|
+
const resultTimestamp = typeof message.timestamp === "string" && message.timestamp ? message.timestamp : rowTimestamp;
|
|
24471
|
+
if (resultTimestamp === void 0 || resultTimestamp.length === 0) {
|
|
24472
|
+
throw new Error(`toolResult ${message.toolCallId} missing timestamp`);
|
|
24473
|
+
}
|
|
24474
|
+
const open4 = openById.get(message.toolCallId);
|
|
24475
|
+
if (open4 === void 0) {
|
|
24476
|
+
const toolName = typeof message.toolName === "string" && message.toolName.length > 0 ? message.toolName : "unknown";
|
|
24477
|
+
order.push({
|
|
24478
|
+
toolCallId: message.toolCallId,
|
|
24479
|
+
toolName,
|
|
24480
|
+
startedAt: resultTimestamp,
|
|
24481
|
+
endedAt: resultTimestamp
|
|
24482
|
+
});
|
|
24483
|
+
continue;
|
|
24484
|
+
}
|
|
24485
|
+
if (open4.endedAt !== void 0) {
|
|
24486
|
+
throw new Error(`duplicate toolResult for toolCallId ${message.toolCallId}`);
|
|
24487
|
+
}
|
|
24488
|
+
open4.endedAt = resultTimestamp;
|
|
24489
|
+
}
|
|
24490
|
+
}
|
|
24491
|
+
return order.map((interval) => {
|
|
24492
|
+
const base = {
|
|
24493
|
+
toolCallId: interval.toolCallId,
|
|
24494
|
+
toolName: interval.toolName,
|
|
24495
|
+
startedAt: interval.startedAt,
|
|
24496
|
+
...interval.command !== void 0 ? { command: interval.command } : {}
|
|
24497
|
+
};
|
|
24498
|
+
return interval.endedAt === void 0 ? base : { ...base, endedAt: interval.endedAt };
|
|
24499
|
+
});
|
|
24500
|
+
}
|
|
24501
|
+
var LedgerSessionJsonlError;
|
|
24502
|
+
var init_ledger_session_read = __esm({
|
|
24503
|
+
"src/ledger-session-read.ts"() {
|
|
24504
|
+
"use strict";
|
|
24505
|
+
LedgerSessionJsonlError = class extends Error {
|
|
24506
|
+
path;
|
|
24507
|
+
line;
|
|
24508
|
+
prefixRows;
|
|
24509
|
+
constructor(message, init) {
|
|
24510
|
+
super(message);
|
|
24511
|
+
this.name = "LedgerSessionJsonlError";
|
|
24512
|
+
this.path = init.path;
|
|
24513
|
+
this.line = init.line;
|
|
24514
|
+
this.prefixRows = init.prefixRows;
|
|
24515
|
+
}
|
|
24516
|
+
};
|
|
24517
|
+
}
|
|
24518
|
+
});
|
|
24519
|
+
|
|
24520
|
+
// src/run-terminal-artifacts.ts
|
|
24521
|
+
import { readdir as readdir4, readFile as readFile12 } from "node:fs/promises";
|
|
24522
|
+
import { basename as basename4, dirname as dirname9, join as join20 } from "node:path";
|
|
24523
|
+
function isMissingPathError3(error) {
|
|
24524
|
+
return error instanceof Error && "code" in error && (error.code === "ENOENT" || error.code === "ENOTDIR");
|
|
24525
|
+
}
|
|
24526
|
+
function errorText2(error) {
|
|
24527
|
+
return error instanceof Error ? error.message : String(error);
|
|
24528
|
+
}
|
|
24529
|
+
function isRecord7(value) {
|
|
24530
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
24531
|
+
}
|
|
24532
|
+
function readUsableTerminalArtifactBody(body) {
|
|
24533
|
+
if (body === null) {
|
|
24534
|
+
return { ok: false, reason: "terminal artifact JSON value is null" };
|
|
24535
|
+
}
|
|
24536
|
+
if (!isRecord7(body)) {
|
|
24537
|
+
return {
|
|
24538
|
+
ok: false,
|
|
24539
|
+
reason: `terminal artifact JSON value is not a typed object (${Array.isArray(body) ? "array" : typeof body})`
|
|
24540
|
+
};
|
|
24541
|
+
}
|
|
24542
|
+
if (typeof body.role !== "string" || body.role.trim() === "") {
|
|
24543
|
+
return {
|
|
24544
|
+
ok: false,
|
|
24545
|
+
reason: "terminal artifact missing nonblank producer-owned role field"
|
|
24546
|
+
};
|
|
24547
|
+
}
|
|
24548
|
+
return { ok: true, body };
|
|
24549
|
+
}
|
|
24550
|
+
async function readTerminalArtifactAtPath(path, file) {
|
|
24551
|
+
let raw;
|
|
24552
|
+
try {
|
|
24553
|
+
raw = await readFile12(path, "utf8");
|
|
24554
|
+
} catch (error) {
|
|
24555
|
+
if (isMissingPathError3(error)) return void 0;
|
|
24556
|
+
return {
|
|
24557
|
+
status: "unreadable",
|
|
24558
|
+
file,
|
|
24559
|
+
path,
|
|
24560
|
+
reason: errorText2(error)
|
|
24561
|
+
};
|
|
24562
|
+
}
|
|
24563
|
+
let parsed;
|
|
24564
|
+
try {
|
|
24565
|
+
parsed = JSON.parse(raw);
|
|
24566
|
+
} catch (error) {
|
|
24567
|
+
return {
|
|
24568
|
+
status: "unreadable",
|
|
24569
|
+
file,
|
|
24570
|
+
path,
|
|
24571
|
+
reason: error instanceof Error ? error.message : `terminal artifact JSON parse failed: ${String(error)}`
|
|
24572
|
+
};
|
|
24573
|
+
}
|
|
24574
|
+
const usable = readUsableTerminalArtifactBody(parsed);
|
|
24575
|
+
if (!usable.ok) {
|
|
24576
|
+
return {
|
|
24577
|
+
status: "unreadable",
|
|
24578
|
+
file,
|
|
24579
|
+
path,
|
|
24580
|
+
reason: usable.reason
|
|
24581
|
+
};
|
|
24582
|
+
}
|
|
24583
|
+
return { status: "present", file, path, body: usable.body };
|
|
24584
|
+
}
|
|
24585
|
+
async function listUniqueErrorFallbackPaths(directories) {
|
|
24586
|
+
const found = [];
|
|
24587
|
+
for (const dir of directories) {
|
|
24588
|
+
let names;
|
|
24589
|
+
try {
|
|
24590
|
+
names = await readdir4(dir);
|
|
24591
|
+
} catch (error) {
|
|
24592
|
+
if (isMissingPathError3(error)) continue;
|
|
24593
|
+
throw error;
|
|
24594
|
+
}
|
|
24595
|
+
for (const name of names.sort((a, b) => a.localeCompare(b))) {
|
|
24596
|
+
if (!UNIQUE_ERROR_FALLBACK_NAME.test(name)) continue;
|
|
24597
|
+
found.push(join20(dir, name));
|
|
24598
|
+
}
|
|
24599
|
+
}
|
|
24600
|
+
return found;
|
|
24601
|
+
}
|
|
24602
|
+
function runIdFromRunDirectory(runDirectory) {
|
|
24603
|
+
const name = basename4(runDirectory);
|
|
24604
|
+
const at = name.lastIndexOf("@");
|
|
24605
|
+
if (at <= 0 || at === name.length - 1) return void 0;
|
|
24606
|
+
return name.slice(0, at);
|
|
24607
|
+
}
|
|
24608
|
+
function presentUniqueFallbackBoundToRun(body, expectedRunId) {
|
|
24609
|
+
if (expectedRunId === void 0) return false;
|
|
24610
|
+
return typeof body.runId === "string" && body.runId === expectedRunId;
|
|
24611
|
+
}
|
|
24612
|
+
async function readRunTerminalArtifact(runDirectory) {
|
|
24613
|
+
const artifactsDir = join20(runDirectory, "artifacts");
|
|
24614
|
+
for (const file of RUN_TERMINAL_ARTIFACT_FILES) {
|
|
24615
|
+
const path = join20(artifactsDir, file);
|
|
24616
|
+
const read3 = await readTerminalArtifactAtPath(path, file);
|
|
24617
|
+
if (read3 !== void 0) return read3;
|
|
24618
|
+
}
|
|
24619
|
+
for (const relative3 of RUN_TERMINAL_ERROR_FALLBACK_RELATIVE_PATHS) {
|
|
24620
|
+
const path = join20(runDirectory, relative3);
|
|
24621
|
+
const read3 = await readTerminalArtifactAtPath(path, "error.json");
|
|
24622
|
+
if (read3 !== void 0) return read3;
|
|
24623
|
+
}
|
|
24624
|
+
for (const path of await listUniqueErrorFallbackPaths([artifactsDir, runDirectory])) {
|
|
24625
|
+
const read3 = await readTerminalArtifactAtPath(path, "error.json");
|
|
24626
|
+
if (read3 !== void 0) return read3;
|
|
24627
|
+
}
|
|
24628
|
+
const expectedRunId = runIdFromRunDirectory(runDirectory);
|
|
24629
|
+
for (const path of await listUniqueErrorFallbackPaths([dirname9(runDirectory)])) {
|
|
24630
|
+
const read3 = await readTerminalArtifactAtPath(path, "error.json");
|
|
24631
|
+
if (read3 === void 0) continue;
|
|
24632
|
+
if (read3.status === "present") {
|
|
24633
|
+
if (!presentUniqueFallbackBoundToRun(read3.body, expectedRunId)) continue;
|
|
24634
|
+
return read3;
|
|
24635
|
+
}
|
|
24636
|
+
}
|
|
24637
|
+
return { status: "absent" };
|
|
24638
|
+
}
|
|
24639
|
+
var RUN_TERMINAL_ARTIFACT_FILES, RUN_TERMINAL_ERROR_FALLBACK_RELATIVE_PATHS, UNIQUE_ERROR_FALLBACK_NAME;
|
|
24640
|
+
var init_run_terminal_artifacts = __esm({
|
|
24641
|
+
"src/run-terminal-artifacts.ts"() {
|
|
24642
|
+
"use strict";
|
|
24643
|
+
RUN_TERMINAL_ARTIFACT_FILES = [
|
|
24644
|
+
"report.json",
|
|
24645
|
+
"error.json",
|
|
24646
|
+
"audit-incomplete.json"
|
|
24647
|
+
];
|
|
24648
|
+
RUN_TERMINAL_ERROR_FALLBACK_RELATIVE_PATHS = [
|
|
24649
|
+
"artifacts/error.settlement.json",
|
|
24650
|
+
"error.settlement.json"
|
|
24651
|
+
];
|
|
24652
|
+
UNIQUE_ERROR_FALLBACK_NAME = /^error\.[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\.json$/i;
|
|
24653
|
+
}
|
|
24654
|
+
});
|
|
24655
|
+
|
|
24656
|
+
// src/taishi-ledger.ts
|
|
24657
|
+
import { readdir as readdir5, readFile as readFile13 } from "node:fs/promises";
|
|
24658
|
+
import { join as join21 } from "node:path";
|
|
24659
|
+
function isMissingPathError4(error) {
|
|
24660
|
+
return error instanceof Error && "code" in error && (error.code === "ENOENT" || error.code === "ENOTDIR");
|
|
24661
|
+
}
|
|
24662
|
+
function errorText3(error) {
|
|
24663
|
+
return error instanceof Error ? error.message : String(error);
|
|
24664
|
+
}
|
|
24665
|
+
function isRecord8(value) {
|
|
24666
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
24667
|
+
}
|
|
24668
|
+
async function readExistingRunLifecycleState(runDirectory) {
|
|
24669
|
+
try {
|
|
24670
|
+
const raw = JSON.parse(
|
|
24671
|
+
await readFile13(join21(runDirectory, "run-state.json"), "utf8")
|
|
24672
|
+
);
|
|
24673
|
+
if (!isRecord8(raw) || typeof raw.state !== "string") return void 0;
|
|
24674
|
+
return raw.state;
|
|
24675
|
+
} catch {
|
|
24676
|
+
return void 0;
|
|
24677
|
+
}
|
|
24678
|
+
}
|
|
24679
|
+
function parseRunDirectoryName(name) {
|
|
24680
|
+
const at = name.lastIndexOf("@");
|
|
24681
|
+
if (at <= 0 || at === name.length - 1) return void 0;
|
|
24682
|
+
return { runId: name.slice(0, at), role: name.slice(at + 1) };
|
|
24683
|
+
}
|
|
24684
|
+
async function readInvocationScopeFields(runDirectory) {
|
|
24685
|
+
let raw;
|
|
24686
|
+
try {
|
|
24687
|
+
raw = await readFile13(join21(runDirectory, "invocation.json"), "utf8");
|
|
24688
|
+
} catch (error) {
|
|
24689
|
+
if (isMissingPathError4(error)) return void 0;
|
|
24690
|
+
throw error;
|
|
24691
|
+
}
|
|
24692
|
+
const parsed = JSON.parse(raw);
|
|
24693
|
+
if (!isRecord8(parsed)) return void 0;
|
|
24694
|
+
if (typeof parsed.projectRoot !== "string" || parsed.projectRoot.trim() === "") {
|
|
24695
|
+
return void 0;
|
|
24696
|
+
}
|
|
24697
|
+
const projectRoot = parsed.projectRoot;
|
|
24698
|
+
if (typeof parsed.ticketNumber === "number" && Number.isInteger(parsed.ticketNumber) && parsed.ticketNumber >= 1) {
|
|
24699
|
+
return { projectRoot, ticketNumber: parsed.ticketNumber };
|
|
24700
|
+
}
|
|
24701
|
+
return { projectRoot };
|
|
24702
|
+
}
|
|
24703
|
+
function decideIssueScope(input) {
|
|
24704
|
+
const projectRootMatch = input.runProjectRootIdentity === input.scopeProjectRootIdentity;
|
|
24705
|
+
if (input.scopeTicketNumber !== void 0 && input.runTicketNumber !== void 0) {
|
|
24706
|
+
if (input.runTicketNumber === input.scopeTicketNumber) {
|
|
24707
|
+
return { inScope: true, conflict: !projectRootMatch };
|
|
24708
|
+
}
|
|
24709
|
+
return { inScope: false, conflict: false };
|
|
24710
|
+
}
|
|
24711
|
+
return { inScope: projectRootMatch, conflict: false };
|
|
24712
|
+
}
|
|
24713
|
+
async function resolveSessionFile(runDirectory) {
|
|
24714
|
+
try {
|
|
24715
|
+
const raw = await readFile13(join21(runDirectory, "invocation.json"), "utf8");
|
|
24716
|
+
const parsed = JSON.parse(raw);
|
|
24717
|
+
if (isRecord8(parsed) && typeof parsed.sessionFile === "string" && parsed.sessionFile.trim() !== "") {
|
|
24718
|
+
return parsed.sessionFile;
|
|
24719
|
+
}
|
|
24720
|
+
} catch (error) {
|
|
24721
|
+
if (!isMissingPathError4(error)) throw error;
|
|
24722
|
+
}
|
|
24723
|
+
return join21(runDirectory, "session", "session.jsonl");
|
|
24724
|
+
}
|
|
24725
|
+
async function classifyScopedRun(input) {
|
|
24726
|
+
const missingSources = [];
|
|
24727
|
+
const reasons = [];
|
|
24728
|
+
let frameSpan;
|
|
24729
|
+
let toolIntervals;
|
|
24730
|
+
let terminal;
|
|
24731
|
+
let models = [];
|
|
24732
|
+
let partialFirstFrameAt = { status: "absent" };
|
|
24733
|
+
let partialLastFrameAt = { status: "absent" };
|
|
24734
|
+
const sessionFile = await resolveSessionFile(input.runDirectory);
|
|
24735
|
+
let rows;
|
|
24736
|
+
try {
|
|
24737
|
+
rows = await readLedgerSessionJsonl(sessionFile);
|
|
24738
|
+
models = extractSessionModelSequence(rows);
|
|
24739
|
+
const span = extractSessionTimestampSpan(rows);
|
|
24740
|
+
if (span.startedAt === void 0 || span.endedAt === void 0) {
|
|
24741
|
+
missingSources.push("session-timeline");
|
|
24742
|
+
reasons.push("session timeline has no usable timestamps");
|
|
24743
|
+
if (span.startedAt !== void 0) {
|
|
24744
|
+
partialFirstFrameAt = { status: "present", at: span.startedAt };
|
|
24745
|
+
}
|
|
24746
|
+
if (span.endedAt !== void 0) {
|
|
24747
|
+
partialLastFrameAt = { status: "present", at: span.endedAt };
|
|
24748
|
+
}
|
|
24749
|
+
} else {
|
|
24750
|
+
const startedMs = Date.parse(span.startedAt);
|
|
24751
|
+
const endedMs = Date.parse(span.endedAt);
|
|
24752
|
+
if (!Number.isFinite(startedMs) || !Number.isFinite(endedMs)) {
|
|
24753
|
+
missingSources.push("session-timeline");
|
|
24754
|
+
reasons.push("session timeline timestamps are not parseable instants");
|
|
24755
|
+
partialFirstFrameAt = { status: "present", at: span.startedAt };
|
|
24756
|
+
partialLastFrameAt = { status: "present", at: span.endedAt };
|
|
24757
|
+
} else if (endedMs < startedMs) {
|
|
24758
|
+
missingSources.push("session-timeline");
|
|
24759
|
+
reasons.push("session timeline end is earlier than start");
|
|
24760
|
+
partialFirstFrameAt = { status: "present", at: span.startedAt };
|
|
24761
|
+
partialLastFrameAt = { status: "present", at: span.endedAt };
|
|
24762
|
+
} else {
|
|
24763
|
+
frameSpan = { startedAt: span.startedAt, endedAt: span.endedAt };
|
|
24764
|
+
}
|
|
24765
|
+
}
|
|
24766
|
+
} catch (error) {
|
|
24767
|
+
missingSources.push("session-timeline");
|
|
24768
|
+
reasons.push(errorText3(error));
|
|
24769
|
+
if (error instanceof LedgerSessionJsonlError) {
|
|
24770
|
+
const span = extractSessionTimestampSpan(error.prefixRows);
|
|
24771
|
+
if (span.startedAt !== void 0) {
|
|
24772
|
+
partialFirstFrameAt = { status: "present", at: span.startedAt };
|
|
24773
|
+
}
|
|
24774
|
+
if (span.endedAt !== void 0) {
|
|
24775
|
+
partialLastFrameAt = { status: "present", at: span.endedAt };
|
|
24776
|
+
}
|
|
24777
|
+
models = extractSessionModelSequence(error.prefixRows);
|
|
24778
|
+
}
|
|
24779
|
+
}
|
|
24780
|
+
if (rows !== void 0 && !missingSources.includes("session-timeline")) {
|
|
24781
|
+
try {
|
|
24782
|
+
toolIntervals = extractSessionToolIntervals(rows);
|
|
24783
|
+
} catch (error) {
|
|
24784
|
+
missingSources.push("tool-association");
|
|
24785
|
+
reasons.push(errorText3(error));
|
|
24786
|
+
}
|
|
24787
|
+
}
|
|
24788
|
+
try {
|
|
24789
|
+
const artifact = await readRunTerminalArtifact(input.runDirectory);
|
|
24790
|
+
if (artifact.status === "unreadable") {
|
|
24791
|
+
missingSources.push("terminal-artifact");
|
|
24792
|
+
reasons.push(`${artifact.file}: ${artifact.reason}`);
|
|
24793
|
+
} else if (artifact.status === "absent") {
|
|
24794
|
+
const lifecycle = await readExistingRunLifecycleState(input.runDirectory);
|
|
24795
|
+
if (lifecycle !== void 0 && LIVE_RUN_STATES.has(lifecycle)) {
|
|
24796
|
+
return { kind: "live" };
|
|
24797
|
+
}
|
|
24798
|
+
terminal = { status: "absent" };
|
|
24799
|
+
} else {
|
|
24800
|
+
terminal = {
|
|
24801
|
+
status: "present",
|
|
24802
|
+
file: artifact.file,
|
|
24803
|
+
body: artifact.body,
|
|
24804
|
+
role: artifact.body.role
|
|
24805
|
+
};
|
|
24806
|
+
}
|
|
24807
|
+
} catch (error) {
|
|
24808
|
+
missingSources.push("terminal-artifact");
|
|
24809
|
+
reasons.push(errorText3(error));
|
|
24810
|
+
}
|
|
24811
|
+
if (missingSources.length > 0) {
|
|
24812
|
+
const firstFrameAt = frameSpan !== void 0 ? { status: "present", at: frameSpan.startedAt } : partialFirstFrameAt;
|
|
24813
|
+
const lastFrameAt = frameSpan !== void 0 ? { status: "present", at: frameSpan.endedAt } : partialLastFrameAt;
|
|
24814
|
+
return {
|
|
24815
|
+
kind: "unreadable",
|
|
24816
|
+
entry: {
|
|
24817
|
+
runId: input.runId,
|
|
24818
|
+
book: input.book,
|
|
24819
|
+
missingSources,
|
|
24820
|
+
reason: reasons.join("; "),
|
|
24821
|
+
firstFrameAt,
|
|
24822
|
+
lastFrameAt
|
|
24823
|
+
}
|
|
24824
|
+
};
|
|
24825
|
+
}
|
|
24826
|
+
if (frameSpan === void 0 || toolIntervals === void 0 || terminal === void 0) {
|
|
24827
|
+
throw new Error(
|
|
24828
|
+
`classifyScopedRun internal invariant: missing retained facts for ${input.runId}`
|
|
24829
|
+
);
|
|
24830
|
+
}
|
|
24831
|
+
return {
|
|
24832
|
+
kind: "readable",
|
|
24833
|
+
facts: {
|
|
24834
|
+
runId: input.runId,
|
|
24835
|
+
book: input.book,
|
|
24836
|
+
role: input.role,
|
|
24837
|
+
frameSpan,
|
|
24838
|
+
toolIntervals,
|
|
24839
|
+
terminal,
|
|
24840
|
+
models
|
|
24841
|
+
}
|
|
24842
|
+
};
|
|
24843
|
+
}
|
|
24844
|
+
async function scanTaishiIssueRuns(input) {
|
|
24845
|
+
const ledgerHome = resolveActivationLedgerHome();
|
|
24846
|
+
const scopeIdentity = physicalPathIdentity(input.projectRoot);
|
|
24847
|
+
const scopeTicketNumber = input.ticketNumber;
|
|
24848
|
+
const booksRoot = join21(ledgerHome, "books");
|
|
24849
|
+
let bookNames;
|
|
24850
|
+
try {
|
|
24851
|
+
const entries = await readdir5(booksRoot, { withFileTypes: true });
|
|
24852
|
+
bookNames = entries.filter((e) => e.isDirectory()).map((e) => e.name).sort();
|
|
24853
|
+
} catch (error) {
|
|
24854
|
+
if (isMissingPathError4(error)) {
|
|
24855
|
+
return { runs: [], unreadable: [], scopeConflicts: [] };
|
|
24856
|
+
}
|
|
24857
|
+
throw error;
|
|
24858
|
+
}
|
|
24859
|
+
const runs = [];
|
|
24860
|
+
const unreadable = [];
|
|
24861
|
+
const scopeConflicts = [];
|
|
24862
|
+
for (const book of bookNames) {
|
|
24863
|
+
const runsDir = join21(booksRoot, book, "runs");
|
|
24864
|
+
let runNames;
|
|
24865
|
+
try {
|
|
24866
|
+
const entries = await readdir5(runsDir, { withFileTypes: true });
|
|
24867
|
+
runNames = entries.filter((e) => e.isDirectory()).map((e) => e.name).sort();
|
|
24868
|
+
} catch (error) {
|
|
24869
|
+
if (isMissingPathError4(error)) continue;
|
|
24870
|
+
throw error;
|
|
24871
|
+
}
|
|
24872
|
+
for (const runName of runNames) {
|
|
24873
|
+
const parsed = parseRunDirectoryName(runName);
|
|
24874
|
+
if (parsed === void 0) continue;
|
|
24875
|
+
const runDirectory = join21(runsDir, runName);
|
|
24876
|
+
let scopeFields;
|
|
24877
|
+
try {
|
|
24878
|
+
scopeFields = await readInvocationScopeFields(runDirectory);
|
|
24879
|
+
} catch (error) {
|
|
24880
|
+
if (error instanceof SyntaxError) continue;
|
|
24881
|
+
throw error;
|
|
24882
|
+
}
|
|
24883
|
+
if (scopeFields === void 0) continue;
|
|
24884
|
+
const runProjectRootIdentity = physicalPathIdentity(scopeFields.projectRoot);
|
|
24885
|
+
const decision = decideIssueScope({
|
|
24886
|
+
scopeProjectRootIdentity: scopeIdentity,
|
|
24887
|
+
scopeTicketNumber,
|
|
24888
|
+
runProjectRootIdentity,
|
|
24889
|
+
runTicketNumber: scopeFields.ticketNumber
|
|
24890
|
+
});
|
|
24891
|
+
if (!decision.inScope) continue;
|
|
24892
|
+
if (decision.conflict) {
|
|
24893
|
+
scopeConflicts.push({
|
|
24894
|
+
runId: parsed.runId,
|
|
24895
|
+
ticketNumber: scopeFields.ticketNumber,
|
|
24896
|
+
projectRoot: runProjectRootIdentity,
|
|
24897
|
+
fact: "typed-ticketNumber-over-projectRoot"
|
|
24898
|
+
});
|
|
24899
|
+
}
|
|
24900
|
+
const classified = await classifyScopedRun({
|
|
24901
|
+
book,
|
|
24902
|
+
runId: parsed.runId,
|
|
24903
|
+
role: parsed.role,
|
|
24904
|
+
runDirectory
|
|
24905
|
+
});
|
|
24906
|
+
if (classified.kind === "readable") runs.push(classified.facts);
|
|
24907
|
+
else if (classified.kind === "unreadable") unreadable.push(classified.entry);
|
|
24908
|
+
}
|
|
24909
|
+
}
|
|
24910
|
+
return {
|
|
24911
|
+
runs,
|
|
24912
|
+
unreadable,
|
|
24913
|
+
scopeConflicts
|
|
24914
|
+
};
|
|
24915
|
+
}
|
|
24916
|
+
var LIVE_RUN_STATES;
|
|
24917
|
+
var init_taishi_ledger = __esm({
|
|
24918
|
+
"src/taishi-ledger.ts"() {
|
|
24919
|
+
"use strict";
|
|
24920
|
+
init_activation_ledger_topology();
|
|
24921
|
+
init_ledger_session_read();
|
|
24922
|
+
init_run_terminal_artifacts();
|
|
24923
|
+
LIVE_RUN_STATES = /* @__PURE__ */ new Set(["admitted", "running", "resumable"]);
|
|
24924
|
+
}
|
|
24925
|
+
});
|
|
24926
|
+
|
|
24927
|
+
// src/taishi-metric-families/acceptance-success-rework.ts
|
|
24928
|
+
function isRecord9(value) {
|
|
24929
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
24930
|
+
}
|
|
24931
|
+
function wallMsFromSpan(span) {
|
|
24932
|
+
return Date.parse(span.endedAt) - Date.parse(span.startedAt);
|
|
24933
|
+
}
|
|
24934
|
+
function findCollectorGroups(body) {
|
|
24935
|
+
if (Array.isArray(body.groups)) return body.groups;
|
|
24936
|
+
const receipt = body.receipt;
|
|
24937
|
+
if (isRecord9(receipt) && Array.isArray(receipt.groups)) return receipt.groups;
|
|
24938
|
+
const outcome = body.outcome;
|
|
24939
|
+
if (isRecord9(outcome)) {
|
|
24940
|
+
const facts = outcome.decisiveFacts;
|
|
24941
|
+
if (isRecord9(facts) && Array.isArray(facts.groups)) return facts.groups;
|
|
24942
|
+
}
|
|
24943
|
+
return void 0;
|
|
24944
|
+
}
|
|
24945
|
+
function extractStatus(body) {
|
|
24946
|
+
const outcome = body.outcome;
|
|
24947
|
+
if (isRecord9(outcome) && typeof outcome.status === "string" && outcome.status.trim() !== "") {
|
|
24948
|
+
return outcome.status;
|
|
24949
|
+
}
|
|
24950
|
+
const receipt = body.receipt;
|
|
24951
|
+
if (isRecord9(receipt) && typeof receipt.status === "string" && receipt.status.trim() !== "") {
|
|
24952
|
+
return receipt.status;
|
|
24953
|
+
}
|
|
24954
|
+
if (typeof body.status === "string" && body.status.trim() !== "") {
|
|
24955
|
+
return body.status;
|
|
24956
|
+
}
|
|
24957
|
+
return void 0;
|
|
24958
|
+
}
|
|
24959
|
+
function mapTerminal(role, terminal) {
|
|
24960
|
+
if (terminal.status === "absent") {
|
|
24961
|
+
return {
|
|
24962
|
+
terminalLabel: "no-receipt",
|
|
24963
|
+
accepted: false,
|
|
24964
|
+
success: false,
|
|
24965
|
+
successEligible: false,
|
|
24966
|
+
noReceipt: true
|
|
24967
|
+
};
|
|
24968
|
+
}
|
|
24969
|
+
const body = terminal.body;
|
|
24970
|
+
if (role === "collector") {
|
|
24971
|
+
const groups = findCollectorGroups(body);
|
|
24972
|
+
if (Array.isArray(groups)) {
|
|
24973
|
+
return {
|
|
24974
|
+
terminalLabel: "groups",
|
|
24975
|
+
accepted: true,
|
|
24976
|
+
success: true,
|
|
24977
|
+
successEligible: true,
|
|
24978
|
+
noReceipt: false
|
|
24979
|
+
};
|
|
24980
|
+
}
|
|
24981
|
+
return {
|
|
24982
|
+
terminalLabel: "non-accepted",
|
|
24983
|
+
accepted: false,
|
|
24984
|
+
success: false,
|
|
24985
|
+
successEligible: false,
|
|
24986
|
+
noReceipt: false
|
|
24987
|
+
};
|
|
24988
|
+
}
|
|
24989
|
+
const status = extractStatus(body);
|
|
24990
|
+
if (status === void 0) {
|
|
24991
|
+
return {
|
|
24992
|
+
terminalLabel: "non-accepted",
|
|
24993
|
+
accepted: false,
|
|
24994
|
+
success: false,
|
|
24995
|
+
successEligible: false,
|
|
24996
|
+
noReceipt: false
|
|
24997
|
+
};
|
|
24998
|
+
}
|
|
24999
|
+
const acceptedSet = ACCEPTED_STATUS[role];
|
|
25000
|
+
if (acceptedSet === void 0 || !acceptedSet.has(status)) {
|
|
25001
|
+
return {
|
|
25002
|
+
terminalLabel: status,
|
|
25003
|
+
accepted: false,
|
|
25004
|
+
success: false,
|
|
25005
|
+
successEligible: false,
|
|
25006
|
+
noReceipt: false
|
|
25007
|
+
};
|
|
25008
|
+
}
|
|
25009
|
+
const plannedDuty = WORKER_ROLES.has(role) && status === "planned";
|
|
25010
|
+
const successSet = SUCCESS_STATUS[role] ?? /* @__PURE__ */ new Set();
|
|
25011
|
+
const success = !plannedDuty && successSet.has(status);
|
|
25012
|
+
const successEligible = !plannedDuty;
|
|
25013
|
+
return {
|
|
25014
|
+
terminalLabel: status,
|
|
25015
|
+
accepted: true,
|
|
25016
|
+
success,
|
|
25017
|
+
successEligible,
|
|
25018
|
+
noReceipt: false
|
|
25019
|
+
};
|
|
25020
|
+
}
|
|
25021
|
+
function projectLegs(runs) {
|
|
25022
|
+
const sorted = [...runs].sort((a, b) => {
|
|
25023
|
+
if (a.book !== b.book) return a.book.localeCompare(b.book);
|
|
25024
|
+
if (a.role !== b.role) return a.role.localeCompare(b.role);
|
|
25025
|
+
if (a.frameSpan.startedAt !== b.frameSpan.startedAt) {
|
|
25026
|
+
return a.frameSpan.startedAt.localeCompare(b.frameSpan.startedAt);
|
|
25027
|
+
}
|
|
25028
|
+
return a.runId.localeCompare(b.runId);
|
|
25029
|
+
});
|
|
25030
|
+
const ordinalByKey = /* @__PURE__ */ new Map();
|
|
25031
|
+
const legs = [];
|
|
25032
|
+
for (const run of sorted) {
|
|
25033
|
+
const key = `${run.book}\0${run.role}`;
|
|
25034
|
+
const ordinal = (ordinalByKey.get(key) ?? 0) + 1;
|
|
25035
|
+
ordinalByKey.set(key, ordinal);
|
|
25036
|
+
const mapped = mapTerminal(run.role, run.terminal);
|
|
25037
|
+
legs.push({
|
|
25038
|
+
runId: run.runId,
|
|
25039
|
+
book: run.book,
|
|
25040
|
+
role: run.role,
|
|
25041
|
+
startedAt: run.frameSpan.startedAt,
|
|
25042
|
+
wallMs: wallMsFromSpan(run.frameSpan),
|
|
25043
|
+
terminalLabel: mapped.terminalLabel,
|
|
25044
|
+
accepted: mapped.accepted,
|
|
25045
|
+
success: mapped.success,
|
|
25046
|
+
successEligible: mapped.successEligible,
|
|
25047
|
+
noReceipt: mapped.noReceipt,
|
|
25048
|
+
ordinalInLaneRole: ordinal,
|
|
25049
|
+
rework: ordinal >= 2
|
|
25050
|
+
});
|
|
25051
|
+
}
|
|
25052
|
+
return legs.sort((a, b) => {
|
|
25053
|
+
if (a.book !== b.book) return a.book.localeCompare(b.book);
|
|
25054
|
+
if (a.role !== b.role) return a.role.localeCompare(b.role);
|
|
25055
|
+
return a.runId.localeCompare(b.runId);
|
|
25056
|
+
});
|
|
25057
|
+
}
|
|
25058
|
+
function aggregateByRole(legs) {
|
|
25059
|
+
const roles = [...new Set(legs.map((leg) => leg.role))].sort((a, b) => a.localeCompare(b));
|
|
25060
|
+
return roles.map((role) => {
|
|
25061
|
+
const roleLegs = legs.filter((leg) => leg.role === role);
|
|
25062
|
+
const acceptedCount = roleLegs.filter((leg) => leg.accepted).length;
|
|
25063
|
+
const successEligibleCount = roleLegs.filter((leg) => leg.successEligible).length;
|
|
25064
|
+
const successCount = roleLegs.filter((leg) => leg.success).length;
|
|
25065
|
+
const noReceiptCount = roleLegs.filter((leg) => leg.noReceipt).length;
|
|
25066
|
+
const byBook = /* @__PURE__ */ new Map();
|
|
25067
|
+
for (const leg of roleLegs) {
|
|
25068
|
+
const list = byBook.get(leg.book) ?? [];
|
|
25069
|
+
list.push(leg);
|
|
25070
|
+
byBook.set(leg.book, list);
|
|
25071
|
+
}
|
|
25072
|
+
const books = [...byBook.keys()].sort((a, b) => a.localeCompare(b));
|
|
25073
|
+
const convergenceRounds = [];
|
|
25074
|
+
let firstPassLaneCount = 0;
|
|
25075
|
+
for (const book of books) {
|
|
25076
|
+
const laneLegs = [...byBook.get(book)].sort((a, b) => {
|
|
25077
|
+
if (a.startedAt !== b.startedAt) return a.startedAt.localeCompare(b.startedAt);
|
|
25078
|
+
return a.runId.localeCompare(b.runId);
|
|
25079
|
+
});
|
|
25080
|
+
convergenceRounds.push(laneLegs.length);
|
|
25081
|
+
const first = laneLegs[0];
|
|
25082
|
+
if (first.accepted) firstPassLaneCount += 1;
|
|
25083
|
+
}
|
|
25084
|
+
const appearanceLaneCount = books.length;
|
|
25085
|
+
return {
|
|
25086
|
+
role,
|
|
25087
|
+
acceptedCount,
|
|
25088
|
+
successEligibleCount,
|
|
25089
|
+
successCount,
|
|
25090
|
+
noReceiptCount,
|
|
25091
|
+
successRate: successEligibleCount === 0 ? void 0 : successCount / successEligibleCount,
|
|
25092
|
+
appearanceLaneCount,
|
|
25093
|
+
firstPassLaneCount,
|
|
25094
|
+
firstPassRate: appearanceLaneCount === 0 ? void 0 : firstPassLaneCount / appearanceLaneCount,
|
|
25095
|
+
convergenceRounds,
|
|
25096
|
+
convergenceRoundsMedian: medianNumber(convergenceRounds)
|
|
25097
|
+
};
|
|
25098
|
+
});
|
|
25099
|
+
}
|
|
25100
|
+
function reworkLens(legs) {
|
|
25101
|
+
let reworkWallMs = 0;
|
|
25102
|
+
let totalWallMs = 0;
|
|
25103
|
+
let reworkLegCount = 0;
|
|
25104
|
+
for (const leg of legs) {
|
|
25105
|
+
totalWallMs += leg.wallMs;
|
|
25106
|
+
if (leg.rework) {
|
|
25107
|
+
reworkWallMs += leg.wallMs;
|
|
25108
|
+
reworkLegCount += 1;
|
|
25109
|
+
}
|
|
25110
|
+
}
|
|
25111
|
+
return {
|
|
25112
|
+
reworkWallMs,
|
|
25113
|
+
totalWallMs,
|
|
25114
|
+
reworkRatio: totalWallMs === 0 ? void 0 : reworkWallMs / totalWallMs,
|
|
25115
|
+
reworkLegCount,
|
|
25116
|
+
totalLegCount: legs.length
|
|
25117
|
+
};
|
|
25118
|
+
}
|
|
25119
|
+
function buildAcceptanceSuccessReworkSection(runs) {
|
|
25120
|
+
if (runs.length === 0) return void 0;
|
|
25121
|
+
const legs = projectLegs(runs);
|
|
25122
|
+
return {
|
|
25123
|
+
kind: "taishi-acceptance-success-rework",
|
|
25124
|
+
legs,
|
|
25125
|
+
byRole: aggregateByRole(legs),
|
|
25126
|
+
rework: reworkLens(legs)
|
|
25127
|
+
};
|
|
25128
|
+
}
|
|
25129
|
+
var WORKER_ROLES, ACCEPTED_STATUS, SUCCESS_STATUS, acceptanceSuccessReworkFamily, acceptance_success_rework_default;
|
|
25130
|
+
var init_acceptance_success_rework = __esm({
|
|
25131
|
+
"src/taishi-metric-families/acceptance-success-rework.ts"() {
|
|
25132
|
+
"use strict";
|
|
25133
|
+
init_taishi_median();
|
|
25134
|
+
WORKER_ROLES = /* @__PURE__ */ new Set(["coder", "fixer"]);
|
|
25135
|
+
ACCEPTED_STATUS = {
|
|
25136
|
+
coder: /* @__PURE__ */ new Set(["completed", "refused", "partially_completed", "unfinished", "planned"]),
|
|
25137
|
+
fixer: /* @__PURE__ */ new Set(["completed", "refused", "partially_completed", "unfinished", "planned"]),
|
|
25138
|
+
judge: /* @__PURE__ */ new Set(["converged", "continue", "escalate"]),
|
|
25139
|
+
reviewer: /* @__PURE__ */ new Set(["completed", "refused"]),
|
|
25140
|
+
doctor: /* @__PURE__ */ new Set(["completed", "refused"]),
|
|
25141
|
+
merger: /* @__PURE__ */ new Set(["completed", "escalate"])
|
|
25142
|
+
};
|
|
25143
|
+
SUCCESS_STATUS = {
|
|
25144
|
+
coder: /* @__PURE__ */ new Set(["completed"]),
|
|
25145
|
+
fixer: /* @__PURE__ */ new Set(["completed"]),
|
|
25146
|
+
// Judge: producing any of the three verdicts completes the duty.
|
|
25147
|
+
judge: /* @__PURE__ */ new Set(["converged", "continue", "escalate"]),
|
|
25148
|
+
reviewer: /* @__PURE__ */ new Set(["completed"]),
|
|
25149
|
+
doctor: /* @__PURE__ */ new Set(["completed"]),
|
|
25150
|
+
merger: /* @__PURE__ */ new Set(["completed"])
|
|
25151
|
+
};
|
|
25152
|
+
acceptanceSuccessReworkFamily = {
|
|
25153
|
+
id: "acceptance-success-rework",
|
|
25154
|
+
contribute(input) {
|
|
25155
|
+
const section = buildAcceptanceSuccessReworkSection(input.runs);
|
|
25156
|
+
if (section === void 0) return void 0;
|
|
25157
|
+
return { acceptanceSuccessRework: section };
|
|
25158
|
+
}
|
|
25159
|
+
};
|
|
25160
|
+
acceptance_success_rework_default = acceptanceSuccessReworkFamily;
|
|
25161
|
+
}
|
|
25162
|
+
});
|
|
25163
|
+
|
|
25164
|
+
// src/taishi-model-groups.ts
|
|
25165
|
+
function taishiModelGroupKey(models) {
|
|
25166
|
+
if (models.length === 0) return void 0;
|
|
25167
|
+
if (models.length === 1) return models[0];
|
|
25168
|
+
return `mixed:${models.join("+")}`;
|
|
25169
|
+
}
|
|
25170
|
+
function rate(numerator, denominator) {
|
|
25171
|
+
if (denominator === 0) return void 0;
|
|
25172
|
+
return numerator / denominator;
|
|
25173
|
+
}
|
|
25174
|
+
function displayNameFor(rawGroupKey, combinationMapping) {
|
|
25175
|
+
if (combinationMapping === void 0) return rawGroupKey;
|
|
25176
|
+
const aliased = combinationMapping[rawGroupKey];
|
|
25177
|
+
return aliased === void 0 ? rawGroupKey : aliased;
|
|
25178
|
+
}
|
|
25179
|
+
function sortUnreadable(unreadable) {
|
|
25180
|
+
return [...unreadable].sort((a, b) => {
|
|
25181
|
+
if (a.book !== b.book) return a.book.localeCompare(b.book);
|
|
25182
|
+
return a.runId.localeCompare(b.runId);
|
|
25183
|
+
});
|
|
25184
|
+
}
|
|
25185
|
+
function modelIdentityAbsentEntry(run) {
|
|
25186
|
+
return {
|
|
25187
|
+
runId: run.runId,
|
|
25188
|
+
book: run.book,
|
|
25189
|
+
missingSources: ["session-model"],
|
|
25190
|
+
reason: "session has no usable model identity",
|
|
25191
|
+
firstFrameAt: { status: "present", at: run.frameSpan.startedAt },
|
|
25192
|
+
// Readable legs already admitted a full span — retain end edge for lastActivityAt.
|
|
25193
|
+
lastFrameAt: { status: "present", at: run.frameSpan.endedAt }
|
|
25194
|
+
};
|
|
25195
|
+
}
|
|
25196
|
+
function buildTaishiModelGroupsPage(input) {
|
|
25197
|
+
const groupedRuns = [];
|
|
25198
|
+
const modelAbsent = [];
|
|
25199
|
+
for (const run of input.runs) {
|
|
25200
|
+
const rawGroupKey = taishiModelGroupKey(run.models);
|
|
25201
|
+
if (rawGroupKey === void 0) {
|
|
25202
|
+
modelAbsent.push(modelIdentityAbsentEntry(run));
|
|
25203
|
+
} else {
|
|
25204
|
+
groupedRuns.push({ run, rawGroupKey });
|
|
25205
|
+
}
|
|
25206
|
+
}
|
|
25207
|
+
const acceptance = buildAcceptanceSuccessReworkSection(
|
|
25208
|
+
groupedRuns.map(({ run }) => run)
|
|
25209
|
+
);
|
|
25210
|
+
const legByRunId = new Map(
|
|
25211
|
+
(acceptance?.legs ?? []).map((leg) => [leg.runId, leg])
|
|
25212
|
+
);
|
|
25213
|
+
const byRaw = /* @__PURE__ */ new Map();
|
|
25214
|
+
for (const { run, rawGroupKey } of groupedRuns) {
|
|
25215
|
+
const leg = legByRunId.get(run.runId);
|
|
25216
|
+
if (leg === void 0) {
|
|
25217
|
+
throw new Error(
|
|
25218
|
+
`taishi model-groups: missing acceptance projection for run ${run.runId}`
|
|
25219
|
+
);
|
|
25220
|
+
}
|
|
25221
|
+
let acc = byRaw.get(rawGroupKey);
|
|
25222
|
+
if (acc === void 0) {
|
|
25223
|
+
acc = {
|
|
25224
|
+
acceptedCount: 0,
|
|
25225
|
+
successCount: 0,
|
|
25226
|
+
successEligibleCount: 0,
|
|
25227
|
+
noReceiptCount: 0,
|
|
25228
|
+
walls: []
|
|
25229
|
+
};
|
|
25230
|
+
byRaw.set(rawGroupKey, acc);
|
|
25231
|
+
}
|
|
25232
|
+
if (leg.accepted) acc.acceptedCount += 1;
|
|
25233
|
+
if (leg.success) acc.successCount += 1;
|
|
25234
|
+
if (leg.successEligible) acc.successEligibleCount += 1;
|
|
25235
|
+
if (leg.noReceipt) acc.noReceiptCount += 1;
|
|
25236
|
+
acc.walls.push(leg.wallMs);
|
|
25237
|
+
}
|
|
25238
|
+
const rawKeys = [...byRaw.keys()].sort((a, b) => a.localeCompare(b));
|
|
25239
|
+
const groups = rawKeys.map((rawGroupKey) => {
|
|
25240
|
+
const acc = byRaw.get(rawGroupKey);
|
|
25241
|
+
const legCount = acc.walls.length;
|
|
25242
|
+
return {
|
|
25243
|
+
rawGroupKey,
|
|
25244
|
+
displayName: displayNameFor(rawGroupKey, input.combinationMapping),
|
|
25245
|
+
legCount,
|
|
25246
|
+
acceptedCount: acc.acceptedCount,
|
|
25247
|
+
acceptanceRate: rate(acc.acceptedCount, legCount),
|
|
25248
|
+
successCount: acc.successCount,
|
|
25249
|
+
successEligibleCount: acc.successEligibleCount,
|
|
25250
|
+
successRate: rate(acc.successCount, acc.successEligibleCount),
|
|
25251
|
+
noReceiptCount: acc.noReceiptCount,
|
|
25252
|
+
noReceiptRate: rate(acc.noReceiptCount, legCount),
|
|
25253
|
+
wallClockMedianMs: medianNumber(acc.walls)
|
|
25254
|
+
};
|
|
25255
|
+
});
|
|
25256
|
+
const unreadable = sortUnreadable([...input.unreadable, ...modelAbsent]);
|
|
25257
|
+
return {
|
|
25258
|
+
kind: "taishi-model-groups",
|
|
25259
|
+
mode: "model-groups",
|
|
25260
|
+
projectRoots: [...input.projectRoots].sort((a, b) => a.localeCompare(b)),
|
|
25261
|
+
groups,
|
|
25262
|
+
legCount: groupedRuns.length,
|
|
25263
|
+
unreadableCount: unreadable.length,
|
|
25264
|
+
unreadable
|
|
25265
|
+
};
|
|
25266
|
+
}
|
|
25267
|
+
var init_taishi_model_groups = __esm({
|
|
25268
|
+
"src/taishi-model-groups.ts"() {
|
|
25269
|
+
"use strict";
|
|
25270
|
+
init_acceptance_success_rework();
|
|
25271
|
+
init_taishi_median();
|
|
25272
|
+
}
|
|
25273
|
+
});
|
|
25274
|
+
|
|
25275
|
+
// src/taishi-metric-families/b2-frame-buckets-actions.ts
|
|
25276
|
+
function timestampMs(iso) {
|
|
25277
|
+
const ms = Date.parse(iso);
|
|
25278
|
+
if (!Number.isFinite(ms)) {
|
|
25279
|
+
throw new Error(`unparseable timestamp: ${iso}`);
|
|
25280
|
+
}
|
|
25281
|
+
return ms;
|
|
25282
|
+
}
|
|
25283
|
+
function toIso(ms) {
|
|
25284
|
+
return new Date(ms).toISOString();
|
|
25285
|
+
}
|
|
25286
|
+
function closedTools(intervals) {
|
|
25287
|
+
const out = [];
|
|
25288
|
+
for (const interval of intervals) {
|
|
25289
|
+
if (interval.endedAt === void 0) continue;
|
|
25290
|
+
const startMs = timestampMs(interval.startedAt);
|
|
25291
|
+
const endMs = timestampMs(interval.endedAt);
|
|
25292
|
+
if (endMs <= startMs) continue;
|
|
25293
|
+
out.push({
|
|
25294
|
+
toolCallId: interval.toolCallId,
|
|
25295
|
+
toolName: interval.toolName,
|
|
25296
|
+
startedAt: interval.startedAt,
|
|
25297
|
+
endedAt: interval.endedAt,
|
|
25298
|
+
startMs,
|
|
25299
|
+
endMs,
|
|
25300
|
+
...interval.command !== void 0 ? { command: interval.command } : {}
|
|
25301
|
+
});
|
|
25302
|
+
}
|
|
25303
|
+
return out;
|
|
25304
|
+
}
|
|
25305
|
+
function clipToolsToFrame(tools, frameStartMs, frameEndMs) {
|
|
25306
|
+
if (frameEndMs <= frameStartMs) return [];
|
|
25307
|
+
const out = [];
|
|
25308
|
+
for (const tool2 of tools) {
|
|
25309
|
+
const startMs = Math.max(tool2.startMs, frameStartMs);
|
|
25310
|
+
const endMs = Math.min(tool2.endMs, frameEndMs);
|
|
25311
|
+
if (endMs <= startMs) continue;
|
|
25312
|
+
out.push({
|
|
25313
|
+
toolCallId: tool2.toolCallId,
|
|
25314
|
+
toolName: tool2.toolName,
|
|
25315
|
+
startMs,
|
|
25316
|
+
endMs,
|
|
25317
|
+
startedAt: startMs === tool2.startMs ? tool2.startedAt : toIso(startMs),
|
|
25318
|
+
endedAt: endMs === tool2.endMs ? tool2.endedAt : toIso(endMs),
|
|
25319
|
+
...tool2.command !== void 0 ? { command: tool2.command } : {}
|
|
25320
|
+
});
|
|
25321
|
+
}
|
|
25322
|
+
return out;
|
|
25323
|
+
}
|
|
25324
|
+
function mergeUnion(intervals) {
|
|
25325
|
+
if (intervals.length === 0) return [];
|
|
25326
|
+
const sorted = [...intervals].sort(
|
|
25327
|
+
(a, b) => a.startMs - b.startMs || a.endMs - b.endMs
|
|
25328
|
+
);
|
|
25329
|
+
const merged = [
|
|
25330
|
+
{ startMs: sorted[0].startMs, endMs: sorted[0].endMs }
|
|
25331
|
+
];
|
|
25332
|
+
for (let i = 1; i < sorted.length; i += 1) {
|
|
25333
|
+
const cur = sorted[i];
|
|
25334
|
+
const last = merged[merged.length - 1];
|
|
25335
|
+
if (cur.startMs <= last.endMs) {
|
|
25336
|
+
last.endMs = Math.max(last.endMs, cur.endMs);
|
|
25337
|
+
} else {
|
|
25338
|
+
merged.push({ startMs: cur.startMs, endMs: cur.endMs });
|
|
25339
|
+
}
|
|
25340
|
+
}
|
|
25341
|
+
return merged;
|
|
25342
|
+
}
|
|
25343
|
+
function modelMaximalIntervals(frameStartMs, frameEndMs, toolUnion) {
|
|
25344
|
+
if (frameEndMs <= frameStartMs) return [];
|
|
25345
|
+
const gaps = [];
|
|
25346
|
+
let cursor = frameStartMs;
|
|
25347
|
+
for (const interval of toolUnion) {
|
|
25348
|
+
if (interval.startMs > cursor) {
|
|
25349
|
+
gaps.push({ startMs: cursor, endMs: interval.startMs });
|
|
25350
|
+
}
|
|
25351
|
+
cursor = Math.max(cursor, interval.endMs);
|
|
25352
|
+
}
|
|
25353
|
+
if (cursor < frameEndMs) {
|
|
25354
|
+
gaps.push({ startMs: cursor, endMs: frameEndMs });
|
|
25355
|
+
}
|
|
25356
|
+
return gaps;
|
|
25357
|
+
}
|
|
25358
|
+
function toolAction(tool2) {
|
|
25359
|
+
const action = {
|
|
25360
|
+
kind: "tool",
|
|
25361
|
+
toolCallId: tool2.toolCallId,
|
|
25362
|
+
toolName: tool2.toolName,
|
|
25363
|
+
durationMs: tool2.endMs - tool2.startMs,
|
|
25364
|
+
startedAt: tool2.startedAt,
|
|
25365
|
+
endedAt: tool2.endedAt
|
|
25366
|
+
};
|
|
25367
|
+
if (tool2.toolName === "bash" && tool2.command !== void 0) {
|
|
25368
|
+
return {
|
|
25369
|
+
...action,
|
|
25370
|
+
commandSummary: tool2.command
|
|
25371
|
+
};
|
|
25372
|
+
}
|
|
25373
|
+
return action;
|
|
25374
|
+
}
|
|
25375
|
+
function modelAction(gap) {
|
|
25376
|
+
return {
|
|
25377
|
+
kind: "model",
|
|
25378
|
+
durationMs: gap.endMs - gap.startMs,
|
|
25379
|
+
startedAt: toIso(gap.startMs),
|
|
25380
|
+
endedAt: toIso(gap.endMs)
|
|
25381
|
+
};
|
|
25382
|
+
}
|
|
25383
|
+
function sortActionsDescending(actions) {
|
|
25384
|
+
return [...actions].sort((a, b) => {
|
|
25385
|
+
if (b.durationMs !== a.durationMs) return b.durationMs - a.durationMs;
|
|
25386
|
+
if (a.startedAt !== b.startedAt) return a.startedAt.localeCompare(b.startedAt);
|
|
25387
|
+
if (a.kind !== b.kind) return a.kind.localeCompare(b.kind);
|
|
25388
|
+
if (a.kind === "tool" && b.kind === "tool") {
|
|
25389
|
+
return a.toolCallId.localeCompare(b.toolCallId);
|
|
25390
|
+
}
|
|
25391
|
+
return 0;
|
|
25392
|
+
});
|
|
25393
|
+
}
|
|
25394
|
+
function computeTaishiB2RunMetrics(facts) {
|
|
25395
|
+
const frameStartMs = timestampMs(facts.frameSpan.startedAt);
|
|
25396
|
+
const frameEndMs = timestampMs(facts.frameSpan.endedAt);
|
|
25397
|
+
const wallMs = Math.max(0, frameEndMs - frameStartMs);
|
|
25398
|
+
const tools = clipToolsToFrame(closedTools(facts.toolIntervals), frameStartMs, frameEndMs);
|
|
25399
|
+
const toolUnion = mergeUnion(tools);
|
|
25400
|
+
const toolBucketMs = toolUnion.reduce(
|
|
25401
|
+
(sum, interval) => sum + (interval.endMs - interval.startMs),
|
|
25402
|
+
0
|
|
25403
|
+
);
|
|
25404
|
+
const modelBucketMs = wallMs - toolBucketMs;
|
|
25405
|
+
const modelGaps = modelMaximalIntervals(frameStartMs, frameEndMs, toolUnion);
|
|
25406
|
+
const actions = sortActionsDescending([
|
|
25407
|
+
...tools.map(toolAction),
|
|
25408
|
+
...modelGaps.map(modelAction)
|
|
25409
|
+
]);
|
|
25410
|
+
const actionDurationMedianMs = medianNumber(actions.map((action) => action.durationMs));
|
|
25411
|
+
return {
|
|
25412
|
+
runId: facts.runId,
|
|
25413
|
+
book: facts.book,
|
|
25414
|
+
role: facts.role,
|
|
25415
|
+
wallMs,
|
|
25416
|
+
toolBucketMs,
|
|
25417
|
+
modelBucketMs,
|
|
25418
|
+
actions,
|
|
25419
|
+
actionDurationMedianMs
|
|
25420
|
+
};
|
|
25421
|
+
}
|
|
25422
|
+
var b2FrameBucketsActionsFamily, b2_frame_buckets_actions_default;
|
|
25423
|
+
var init_b2_frame_buckets_actions = __esm({
|
|
25424
|
+
"src/taishi-metric-families/b2-frame-buckets-actions.ts"() {
|
|
25425
|
+
"use strict";
|
|
25426
|
+
init_taishi_median();
|
|
25427
|
+
b2FrameBucketsActionsFamily = {
|
|
25428
|
+
id: "b2-frame-buckets-actions",
|
|
25429
|
+
contribute(input) {
|
|
25430
|
+
if (input.runs.length === 0) return void 0;
|
|
25431
|
+
const runs = [...input.runs].map(computeTaishiB2RunMetrics).sort((a, b) => {
|
|
25432
|
+
if (a.book !== b.book) return a.book.localeCompare(b.book);
|
|
25433
|
+
if (a.role !== b.role) return a.role.localeCompare(b.role);
|
|
25434
|
+
return a.runId.localeCompare(b.runId);
|
|
25435
|
+
});
|
|
25436
|
+
const section = {
|
|
25437
|
+
kind: "taishi-b2-frame-buckets-actions",
|
|
25438
|
+
runs
|
|
25439
|
+
};
|
|
25440
|
+
return { b2FrameBucketsActions: section };
|
|
25441
|
+
}
|
|
25442
|
+
};
|
|
25443
|
+
b2_frame_buckets_actions_default = b2FrameBucketsActionsFamily;
|
|
25444
|
+
}
|
|
25445
|
+
});
|
|
25446
|
+
|
|
25447
|
+
// src/taishi-metric-families/leg-wall-clock.ts
|
|
25448
|
+
function frameSpanWallMs(span) {
|
|
25449
|
+
return Date.parse(span.endedAt) - Date.parse(span.startedAt);
|
|
25450
|
+
}
|
|
25451
|
+
function projectEntry(facts) {
|
|
25452
|
+
return {
|
|
25453
|
+
runId: facts.runId,
|
|
25454
|
+
book: facts.book,
|
|
25455
|
+
role: facts.role,
|
|
25456
|
+
wallMs: frameSpanWallMs(facts.frameSpan)
|
|
25457
|
+
};
|
|
25458
|
+
}
|
|
25459
|
+
function compareRankingDesc(a, b) {
|
|
25460
|
+
if (b.wallMs !== a.wallMs) return b.wallMs - a.wallMs;
|
|
25461
|
+
if (a.book !== b.book) return a.book.localeCompare(b.book);
|
|
25462
|
+
if (a.role !== b.role) return a.role.localeCompare(b.role);
|
|
25463
|
+
return a.runId.localeCompare(b.runId);
|
|
25464
|
+
}
|
|
25465
|
+
var legWallClockFamily, leg_wall_clock_default;
|
|
25466
|
+
var init_leg_wall_clock = __esm({
|
|
25467
|
+
"src/taishi-metric-families/leg-wall-clock.ts"() {
|
|
25468
|
+
"use strict";
|
|
25469
|
+
init_taishi_median();
|
|
25470
|
+
legWallClockFamily = {
|
|
25471
|
+
id: "leg-wall-clock",
|
|
25472
|
+
contribute(input) {
|
|
25473
|
+
if (input.runs.length === 0) {
|
|
25474
|
+
return void 0;
|
|
25475
|
+
}
|
|
25476
|
+
const ranking = input.runs.map(projectEntry).sort(compareRankingDesc);
|
|
25477
|
+
const walls = ranking.map((leg) => leg.wallMs);
|
|
25478
|
+
const medianWallMs = medianNumber(walls);
|
|
25479
|
+
if (medianWallMs === void 0) {
|
|
25480
|
+
return void 0;
|
|
25481
|
+
}
|
|
25482
|
+
let totalElapsedMs = 0;
|
|
25483
|
+
for (const wallMs of walls) totalElapsedMs += wallMs;
|
|
25484
|
+
const section = {
|
|
25485
|
+
kind: "taishi-leg-wall-clock",
|
|
25486
|
+
ranking,
|
|
25487
|
+
medianWallMs,
|
|
25488
|
+
totalElapsedMs
|
|
25489
|
+
};
|
|
25490
|
+
return { legWallClock: section };
|
|
25491
|
+
}
|
|
25492
|
+
};
|
|
25493
|
+
leg_wall_clock_default = legWallClockFamily;
|
|
25494
|
+
}
|
|
25495
|
+
});
|
|
25496
|
+
|
|
25497
|
+
// src/taishi-metric-families/round-timeline.ts
|
|
25498
|
+
function isRecord10(value) {
|
|
25499
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
25500
|
+
}
|
|
25501
|
+
function wallMsFromSpan2(startedAt, endedAt) {
|
|
25502
|
+
return Date.parse(endedAt) - Date.parse(startedAt);
|
|
25503
|
+
}
|
|
25504
|
+
function readOutcomeStatus(body) {
|
|
25505
|
+
if (!isRecord10(body.outcome)) return void 0;
|
|
25506
|
+
const status = body.outcome.status;
|
|
25507
|
+
if (typeof status !== "string" || status.trim() === "") return void 0;
|
|
25508
|
+
return status;
|
|
25509
|
+
}
|
|
25510
|
+
function readClassCount(body) {
|
|
25511
|
+
if (!isRecord10(body.outcome)) return void 0;
|
|
25512
|
+
if (!isRecord10(body.outcome.decisiveFacts)) return void 0;
|
|
25513
|
+
const classCount = body.outcome.decisiveFacts.classCount;
|
|
25514
|
+
if (typeof classCount !== "number" || !Number.isFinite(classCount)) {
|
|
25515
|
+
return void 0;
|
|
25516
|
+
}
|
|
25517
|
+
return classCount;
|
|
25518
|
+
}
|
|
25519
|
+
function projectTerminal(facts) {
|
|
25520
|
+
if (facts.terminal.status === "absent") {
|
|
25521
|
+
return { kind: "death", channel: "no-receipt" };
|
|
25522
|
+
}
|
|
25523
|
+
if (facts.terminal.file === "error.json") {
|
|
25524
|
+
return { kind: "death", channel: "error" };
|
|
25525
|
+
}
|
|
25526
|
+
if (facts.terminal.file === "audit-incomplete.json") {
|
|
25527
|
+
return { kind: "death", channel: "audit-incomplete" };
|
|
25528
|
+
}
|
|
25529
|
+
const status = readOutcomeStatus(facts.terminal.body);
|
|
25530
|
+
const classCount = readClassCount(facts.terminal.body);
|
|
25531
|
+
const receiptStatus = status ?? "unparsed";
|
|
25532
|
+
if (classCount === void 0) {
|
|
25533
|
+
return { kind: "receipt", status: receiptStatus };
|
|
25534
|
+
}
|
|
25535
|
+
return { kind: "receipt", status: receiptStatus, classCount };
|
|
25536
|
+
}
|
|
25537
|
+
function projectRunRow(facts) {
|
|
25538
|
+
const { startedAt, endedAt } = facts.frameSpan;
|
|
25539
|
+
return {
|
|
25540
|
+
kind: "run",
|
|
25541
|
+
runId: facts.runId,
|
|
25542
|
+
book: facts.book,
|
|
25543
|
+
role: facts.role,
|
|
25544
|
+
startedAt,
|
|
25545
|
+
endedAt,
|
|
25546
|
+
wallMs: wallMsFromSpan2(startedAt, endedAt),
|
|
25547
|
+
terminal: projectTerminal(facts)
|
|
25548
|
+
};
|
|
25549
|
+
}
|
|
25550
|
+
function projectUnreadableRow(entry) {
|
|
25551
|
+
return {
|
|
25552
|
+
kind: "unreadable",
|
|
25553
|
+
runId: entry.runId,
|
|
25554
|
+
book: entry.book,
|
|
25555
|
+
missingSources: entry.missingSources,
|
|
25556
|
+
reason: entry.reason,
|
|
25557
|
+
firstFrameAt: entry.firstFrameAt
|
|
25558
|
+
};
|
|
25559
|
+
}
|
|
25560
|
+
function rowSortStartedAt(row) {
|
|
25561
|
+
if (row.kind === "run") return row.startedAt;
|
|
25562
|
+
if (row.firstFrameAt.status === "present") return row.firstFrameAt.at;
|
|
25563
|
+
return void 0;
|
|
25564
|
+
}
|
|
25565
|
+
function compareRows(a, b) {
|
|
25566
|
+
const aStart = rowSortStartedAt(a);
|
|
25567
|
+
const bStart = rowSortStartedAt(b);
|
|
25568
|
+
if (aStart === void 0 && bStart === void 0) {
|
|
25569
|
+
return a.runId.localeCompare(b.runId);
|
|
25570
|
+
}
|
|
25571
|
+
if (aStart === void 0) return 1;
|
|
25572
|
+
if (bStart === void 0) return -1;
|
|
25573
|
+
if (aStart !== bStart) return aStart.localeCompare(bStart);
|
|
25574
|
+
return a.runId.localeCompare(b.runId);
|
|
25575
|
+
}
|
|
25576
|
+
function buildLanes(runs, unreadable) {
|
|
25577
|
+
const byLane = /* @__PURE__ */ new Map();
|
|
25578
|
+
const push = (lane, row) => {
|
|
25579
|
+
const list = byLane.get(lane);
|
|
25580
|
+
if (list === void 0) byLane.set(lane, [row]);
|
|
25581
|
+
else list.push(row);
|
|
25582
|
+
};
|
|
25583
|
+
for (const facts of runs) {
|
|
25584
|
+
push(facts.book, projectRunRow(facts));
|
|
25585
|
+
}
|
|
25586
|
+
for (const entry of unreadable) {
|
|
25587
|
+
push(entry.book, projectUnreadableRow(entry));
|
|
25588
|
+
}
|
|
25589
|
+
return [...byLane.keys()].sort((a, b) => a.localeCompare(b)).map((lane) => ({
|
|
25590
|
+
lane,
|
|
25591
|
+
rows: [...byLane.get(lane) ?? []].sort(compareRows)
|
|
25592
|
+
}));
|
|
25593
|
+
}
|
|
25594
|
+
var roundTimelineFamily, round_timeline_default;
|
|
25595
|
+
var init_round_timeline = __esm({
|
|
25596
|
+
"src/taishi-metric-families/round-timeline.ts"() {
|
|
25597
|
+
"use strict";
|
|
25598
|
+
roundTimelineFamily = {
|
|
25599
|
+
id: "round-timeline",
|
|
25600
|
+
contribute(input) {
|
|
25601
|
+
if (input.runs.length === 0 && input.unreadable.length === 0) {
|
|
25602
|
+
return void 0;
|
|
25603
|
+
}
|
|
25604
|
+
const section = {
|
|
25605
|
+
kind: "taishi-round-timeline",
|
|
25606
|
+
lanes: buildLanes(input.runs, input.unreadable)
|
|
25607
|
+
};
|
|
25608
|
+
return { roundTimeline: section };
|
|
25609
|
+
}
|
|
25610
|
+
};
|
|
25611
|
+
round_timeline_default = roundTimelineFamily;
|
|
25612
|
+
}
|
|
25613
|
+
});
|
|
25614
|
+
|
|
25615
|
+
// src/taishi-metric-families.ts
|
|
25616
|
+
async function loadTaishiIssueMetricFamilies() {
|
|
25617
|
+
return ISSUE_METRIC_FAMILIES;
|
|
25618
|
+
}
|
|
25619
|
+
var ISSUE_METRIC_FAMILIES;
|
|
25620
|
+
var init_taishi_metric_families = __esm({
|
|
25621
|
+
"src/taishi-metric-families.ts"() {
|
|
25622
|
+
"use strict";
|
|
25623
|
+
init_acceptance_success_rework();
|
|
25624
|
+
init_b2_frame_buckets_actions();
|
|
25625
|
+
init_leg_wall_clock();
|
|
25626
|
+
init_round_timeline();
|
|
25627
|
+
ISSUE_METRIC_FAMILIES = [
|
|
25628
|
+
acceptance_success_rework_default,
|
|
25629
|
+
b2_frame_buckets_actions_default,
|
|
25630
|
+
leg_wall_clock_default,
|
|
25631
|
+
round_timeline_default
|
|
25632
|
+
].sort((a, b) => a.id.localeCompare(b.id));
|
|
25633
|
+
}
|
|
25634
|
+
});
|
|
25635
|
+
|
|
25636
|
+
// src/taishi-metric-family.ts
|
|
25637
|
+
function composeTaishiMetricFamilySections(families, input) {
|
|
25638
|
+
const sections = {};
|
|
25639
|
+
for (const family of families) {
|
|
25640
|
+
const piece = family.contribute(input);
|
|
25641
|
+
if (piece === void 0) continue;
|
|
25642
|
+
Object.assign(sections, piece);
|
|
25643
|
+
}
|
|
25644
|
+
return sections;
|
|
25645
|
+
}
|
|
25646
|
+
var init_taishi_metric_family = __esm({
|
|
25647
|
+
"src/taishi-metric-family.ts"() {
|
|
25648
|
+
"use strict";
|
|
25649
|
+
}
|
|
25650
|
+
});
|
|
25651
|
+
|
|
25652
|
+
// src/taishi-page.ts
|
|
25653
|
+
import { createHash as createHash4 } from "node:crypto";
|
|
25654
|
+
import { dirname as dirname10, join as join22 } from "node:path";
|
|
25655
|
+
function taishiIssuePageKey(projectRoot) {
|
|
25656
|
+
const identity = physicalPathIdentity(projectRoot);
|
|
25657
|
+
return createHash4("sha256").update(identity).digest("hex").slice(0, 32);
|
|
25658
|
+
}
|
|
25659
|
+
function taishiIssuePagePath(ledgerHome, projectRoot) {
|
|
25660
|
+
return join22(ledgerHome, "taishi", "issues", `${taishiIssuePageKey(projectRoot)}.json`);
|
|
25661
|
+
}
|
|
25662
|
+
function sortLegs(legs) {
|
|
25663
|
+
return [...legs].sort((a, b) => {
|
|
25664
|
+
if (a.book !== b.book) return a.book.localeCompare(b.book);
|
|
25665
|
+
if (a.role !== b.role) return a.role.localeCompare(b.role);
|
|
25666
|
+
return a.runId.localeCompare(b.runId);
|
|
25667
|
+
});
|
|
25668
|
+
}
|
|
25669
|
+
function sortUnreadable2(unreadable) {
|
|
25670
|
+
return [...unreadable].sort((a, b) => {
|
|
25671
|
+
if (a.book !== b.book) return a.book.localeCompare(b.book);
|
|
25672
|
+
return a.runId.localeCompare(b.runId);
|
|
25673
|
+
});
|
|
25674
|
+
}
|
|
25675
|
+
function sortScopeConflicts(conflicts) {
|
|
25676
|
+
return [...conflicts].sort((a, b) => {
|
|
25677
|
+
const aRun = a.runId ?? "";
|
|
25678
|
+
const bRun = b.runId ?? "";
|
|
25679
|
+
if (aRun !== bRun) return aRun.localeCompare(bRun);
|
|
25680
|
+
return a.projectRoot.localeCompare(b.projectRoot);
|
|
25681
|
+
});
|
|
25682
|
+
}
|
|
25683
|
+
function assertTaishiChangedLinesInput(changedLines) {
|
|
25684
|
+
if (changedLines === void 0) return;
|
|
25685
|
+
if (typeof changedLines !== "number" || !Number.isFinite(changedLines) || changedLines < 0) {
|
|
25686
|
+
throw new Error(
|
|
25687
|
+
`taishi changedLines must be a finite non-negative number, got ${String(changedLines)}`
|
|
25688
|
+
);
|
|
25689
|
+
}
|
|
25690
|
+
}
|
|
25691
|
+
function normalizeTaishiChangedLines(changedLines) {
|
|
25692
|
+
assertTaishiChangedLinesInput(changedLines);
|
|
25693
|
+
if (changedLines === void 0 || changedLines === 0) {
|
|
25694
|
+
return { status: "absent" };
|
|
25695
|
+
}
|
|
25696
|
+
return { status: "present", value: changedLines };
|
|
25697
|
+
}
|
|
25698
|
+
function computeTaishiMsPerKLines(totalElapsedMs, changedLines) {
|
|
25699
|
+
if (changedLines.status === "absent") return { status: "absent" };
|
|
25700
|
+
return {
|
|
25701
|
+
status: "present",
|
|
25702
|
+
value: totalElapsedMs / (changedLines.value / 1e3)
|
|
25703
|
+
};
|
|
25704
|
+
}
|
|
25705
|
+
function frameSpanWallMs2(span) {
|
|
25706
|
+
return Date.parse(span.endedAt) - Date.parse(span.startedAt);
|
|
25707
|
+
}
|
|
25708
|
+
function summarizeTaishiRunEfficiency(runs, unreadable = []) {
|
|
25709
|
+
let totalElapsedMs = 0;
|
|
25710
|
+
let latestEndedAt;
|
|
25711
|
+
for (const run of runs) {
|
|
25712
|
+
totalElapsedMs += frameSpanWallMs2(run.frameSpan);
|
|
25713
|
+
const endedAt = run.frameSpan.endedAt;
|
|
25714
|
+
if (latestEndedAt === void 0 || endedAt > latestEndedAt) {
|
|
25715
|
+
latestEndedAt = endedAt;
|
|
25716
|
+
}
|
|
25717
|
+
}
|
|
25718
|
+
for (const entry of unreadable) {
|
|
25719
|
+
if (entry.lastFrameAt.status !== "present") continue;
|
|
25720
|
+
const endedAt = entry.lastFrameAt.at;
|
|
25721
|
+
if (latestEndedAt === void 0 || endedAt > latestEndedAt) {
|
|
25722
|
+
latestEndedAt = endedAt;
|
|
25723
|
+
}
|
|
25724
|
+
}
|
|
25725
|
+
const lastActivityAt = latestEndedAt === void 0 ? { status: "absent" } : { status: "present", at: latestEndedAt };
|
|
25726
|
+
return { totalElapsedMs, lastActivityAt };
|
|
25727
|
+
}
|
|
25728
|
+
async function buildTaishiIssueMetricsPage(input) {
|
|
25729
|
+
const families = await loadTaishiIssueMetricFamilies();
|
|
25730
|
+
const legs = sortLegs(
|
|
25731
|
+
input.runs.map((run) => ({
|
|
25732
|
+
runId: run.runId,
|
|
25733
|
+
book: run.book,
|
|
25734
|
+
role: run.role
|
|
25735
|
+
}))
|
|
25736
|
+
);
|
|
25737
|
+
const unreadable = sortUnreadable2(input.unreadable);
|
|
25738
|
+
const scopeConflicts = sortScopeConflicts(input.scopeConflicts ?? []);
|
|
25739
|
+
const projectRoot = physicalPathIdentity(input.projectRoot);
|
|
25740
|
+
const { totalElapsedMs, lastActivityAt } = summarizeTaishiRunEfficiency(
|
|
25741
|
+
input.runs,
|
|
25742
|
+
unreadable
|
|
25743
|
+
);
|
|
25744
|
+
const changedLines = normalizeTaishiChangedLines(input.changedLines);
|
|
25745
|
+
const msPerKLines = computeTaishiMsPerKLines(totalElapsedMs, changedLines);
|
|
25746
|
+
const envelope = {
|
|
25747
|
+
kind: "taishi-issue-metrics",
|
|
25748
|
+
mode: "issue",
|
|
25749
|
+
projectRoot,
|
|
25750
|
+
// exactOptionalPropertyTypes: only materialize when caller supplied it.
|
|
25751
|
+
...input.issueNumber === void 0 ? {} : { issueNumber: input.issueNumber },
|
|
25752
|
+
legs,
|
|
25753
|
+
unreadable,
|
|
25754
|
+
unreadableCount: unreadable.length,
|
|
25755
|
+
scopeConflicts,
|
|
25756
|
+
totalElapsedMs,
|
|
25757
|
+
changedLines,
|
|
25758
|
+
msPerKLines,
|
|
25759
|
+
lastActivityAt
|
|
25760
|
+
};
|
|
25761
|
+
const sections = composeTaishiMetricFamilySections(families, {
|
|
25762
|
+
projectRoot,
|
|
25763
|
+
runs: input.runs,
|
|
25764
|
+
unreadable
|
|
25765
|
+
});
|
|
25766
|
+
return { ...envelope, ...sections };
|
|
25767
|
+
}
|
|
25768
|
+
async function writeTaishiIssueMetricsPage(ledgerHome, page) {
|
|
25769
|
+
const path = taishiIssuePagePath(ledgerHome, page.projectRoot);
|
|
25770
|
+
ensureRealDirectoryTree(ledgerHome, dirname10(path));
|
|
25771
|
+
assertLedgerFileInsideHome(path, ledgerHome);
|
|
25772
|
+
await writeFileAtomically(path, `${JSON.stringify(page, null, 2)}
|
|
25773
|
+
`);
|
|
25774
|
+
return path;
|
|
25775
|
+
}
|
|
25776
|
+
var init_taishi_page = __esm({
|
|
25777
|
+
"src/taishi-page.ts"() {
|
|
25778
|
+
"use strict";
|
|
25779
|
+
init_atomic_write();
|
|
25780
|
+
init_activation_ledger_topology();
|
|
25781
|
+
init_taishi_metric_families();
|
|
25782
|
+
init_taishi_metric_family();
|
|
25783
|
+
}
|
|
25784
|
+
});
|
|
25785
|
+
|
|
25786
|
+
// src/taishi-entry.ts
|
|
25787
|
+
import { readFile as readFile14 } from "node:fs/promises";
|
|
25788
|
+
function isMissingPathError5(error) {
|
|
25789
|
+
return error instanceof Error && "code" in error && (error.code === "ENOENT" || error.code === "ENOTDIR");
|
|
25790
|
+
}
|
|
25791
|
+
function cachedPageMatchesRequestedScope(page, input) {
|
|
25792
|
+
const requestedTicket = input.ticketNumber ?? input.issueNumber;
|
|
25793
|
+
if (requestedTicket === void 0) {
|
|
25794
|
+
return page.issueNumber === void 0;
|
|
25795
|
+
}
|
|
25796
|
+
return page.issueNumber === requestedTicket;
|
|
25797
|
+
}
|
|
25798
|
+
async function readOrComputeTaishiIssuePage(input) {
|
|
25799
|
+
const ledgerHome = resolveActivationLedgerHome();
|
|
25800
|
+
const projectRoot = physicalPathIdentity(input.projectRoot);
|
|
25801
|
+
const pagePath = taishiIssuePagePath(ledgerHome, projectRoot);
|
|
25802
|
+
try {
|
|
25803
|
+
const raw = await readFile14(pagePath, "utf8");
|
|
25804
|
+
const page = JSON.parse(raw);
|
|
25805
|
+
if (cachedPageMatchesRequestedScope(page, input)) {
|
|
25806
|
+
return { mode: "issue", page, pagePath };
|
|
25807
|
+
}
|
|
25808
|
+
} catch (error) {
|
|
25809
|
+
if (!isMissingPathError5(error)) {
|
|
25810
|
+
throw new TaishiIssueComputeError({
|
|
25811
|
+
projectRoot,
|
|
25812
|
+
...input.issueNumber === void 0 ? {} : { issueNumber: input.issueNumber },
|
|
25813
|
+
cause: error
|
|
25814
|
+
});
|
|
25815
|
+
}
|
|
25816
|
+
}
|
|
25817
|
+
try {
|
|
25818
|
+
return await runTaishiIssueMode(input);
|
|
25819
|
+
} catch (error) {
|
|
25820
|
+
if (error instanceof TaishiIssueComputeError) throw error;
|
|
25821
|
+
throw new TaishiIssueComputeError({
|
|
25822
|
+
projectRoot,
|
|
25823
|
+
...input.issueNumber === void 0 ? {} : { issueNumber: input.issueNumber },
|
|
25824
|
+
cause: error
|
|
25825
|
+
});
|
|
25826
|
+
}
|
|
25827
|
+
}
|
|
25828
|
+
async function runTaishiIssueMode(input, precomputedScan) {
|
|
25829
|
+
assertTaishiChangedLinesInput(input.changedLines);
|
|
25830
|
+
const ledgerHome = resolveActivationLedgerHome();
|
|
25831
|
+
const projectRoot = input.projectRoot;
|
|
25832
|
+
const ticketNumber = "ticketNumber" in input ? input.ticketNumber : void 0;
|
|
25833
|
+
const scan = precomputedScan ?? (ticketNumber === void 0 ? await scanTaishiIssueRuns({ projectRoot }) : await scanTaishiIssueRuns({ projectRoot, ticketNumber }));
|
|
25834
|
+
const issueNumber = "issueNumber" in input ? input.issueNumber : void 0;
|
|
25835
|
+
const conflictingProjectRoot = "conflictingProjectRoot" in input ? input.conflictingProjectRoot : void 0;
|
|
25836
|
+
const scopeConflicts = [...scan.scopeConflicts];
|
|
25837
|
+
if (conflictingProjectRoot !== void 0 && ticketNumber !== void 0) {
|
|
25838
|
+
const losingRoot = physicalPathIdentity(conflictingProjectRoot);
|
|
25839
|
+
const winningRoot = physicalPathIdentity(projectRoot);
|
|
25840
|
+
if (losingRoot !== winningRoot) {
|
|
25841
|
+
scopeConflicts.push({
|
|
25842
|
+
ticketNumber,
|
|
25843
|
+
projectRoot: losingRoot,
|
|
25844
|
+
fact: "typed-ticketNumber-over-projectRoot"
|
|
25845
|
+
});
|
|
25846
|
+
}
|
|
25847
|
+
}
|
|
25848
|
+
const page = await buildTaishiIssueMetricsPage({
|
|
25849
|
+
projectRoot,
|
|
25850
|
+
runs: scan.runs,
|
|
25851
|
+
unreadable: scan.unreadable,
|
|
25852
|
+
scopeConflicts,
|
|
25853
|
+
...input.changedLines === void 0 ? {} : { changedLines: input.changedLines },
|
|
25854
|
+
...issueNumber === void 0 ? {} : { issueNumber }
|
|
25855
|
+
});
|
|
25856
|
+
const pagePath = await writeTaishiIssueMetricsPage(ledgerHome, page);
|
|
25857
|
+
if (issueNumber !== void 0) {
|
|
25858
|
+
await mergeTaishiLibraryIndexRows(ledgerHome, [
|
|
25859
|
+
rowFromIssueMetricsPage(page)
|
|
25860
|
+
]);
|
|
25861
|
+
}
|
|
25862
|
+
return { mode: "issue", page, pagePath };
|
|
25863
|
+
}
|
|
25864
|
+
async function runTaishiSweepMode(input) {
|
|
25865
|
+
const ledgerHome = resolveActivationLedgerHome();
|
|
25866
|
+
const issuePages = [];
|
|
25867
|
+
for (const entry of input.mergedPullRequests) {
|
|
25868
|
+
issuePages.push(await runTaishiIssueMode(entry));
|
|
25869
|
+
}
|
|
25870
|
+
const upserts = issuePages.map((result2) => rowFromIssueMetricsPage(result2.page));
|
|
25871
|
+
const { index, indexPath } = await mergeTaishiLibraryIndexRows(ledgerHome, upserts);
|
|
25872
|
+
return { mode: "sweep", issuePages, index, indexPath };
|
|
25873
|
+
}
|
|
25874
|
+
async function runTaishiModelGroupsMode(input) {
|
|
25875
|
+
const ledgerHome = resolveActivationLedgerHome();
|
|
25876
|
+
const runs = [];
|
|
25877
|
+
const unreadable = [];
|
|
25878
|
+
const seen = /* @__PURE__ */ new Set();
|
|
25879
|
+
const projectRoots = [];
|
|
25880
|
+
for (const root of input.projectRoots) {
|
|
25881
|
+
const identity = physicalPathIdentity(root);
|
|
25882
|
+
if (seen.has(identity)) continue;
|
|
25883
|
+
seen.add(identity);
|
|
25884
|
+
projectRoots.push(identity);
|
|
25885
|
+
}
|
|
25886
|
+
for (const projectRoot of projectRoots) {
|
|
25887
|
+
const scan = await scanTaishiIssueRuns({ projectRoot });
|
|
25888
|
+
runs.push(...scan.runs);
|
|
25889
|
+
unreadable.push(...scan.unreadable);
|
|
25890
|
+
const pagePath = taishiIssuePagePath(ledgerHome, projectRoot);
|
|
25891
|
+
try {
|
|
25892
|
+
const raw = await readFile14(pagePath, "utf8");
|
|
25893
|
+
JSON.parse(raw);
|
|
25894
|
+
} catch (error) {
|
|
25895
|
+
if (!isMissingPathError5(error)) {
|
|
25896
|
+
throw new TaishiIssueComputeError({ projectRoot, cause: error });
|
|
25897
|
+
}
|
|
25898
|
+
try {
|
|
25899
|
+
await runTaishiIssueMode({ mode: "issue", projectRoot }, scan);
|
|
25900
|
+
} catch (computeError) {
|
|
25901
|
+
if (computeError instanceof TaishiIssueComputeError) throw computeError;
|
|
25902
|
+
throw new TaishiIssueComputeError({ projectRoot, cause: computeError });
|
|
25903
|
+
}
|
|
25904
|
+
}
|
|
25905
|
+
}
|
|
25906
|
+
const page = input.combinationMapping === void 0 ? buildTaishiModelGroupsPage({ projectRoots, runs, unreadable }) : buildTaishiModelGroupsPage({
|
|
25907
|
+
projectRoots,
|
|
25908
|
+
runs,
|
|
25909
|
+
unreadable,
|
|
25910
|
+
combinationMapping: input.combinationMapping
|
|
25911
|
+
});
|
|
25912
|
+
return { mode: "model-groups", page };
|
|
25913
|
+
}
|
|
25914
|
+
async function runTaishi(input) {
|
|
25915
|
+
if (input.mode === "sweep") {
|
|
25916
|
+
return runTaishiSweepMode(input);
|
|
25917
|
+
}
|
|
25918
|
+
if (input.mode === "cohort") {
|
|
25919
|
+
const ledgerHome = resolveActivationLedgerHome();
|
|
25920
|
+
return runTaishiCohortMode(ledgerHome, input, async ({ projectRoot, issueNumber }) => {
|
|
25921
|
+
const ensured = await readOrComputeTaishiIssuePage({
|
|
25922
|
+
mode: "issue",
|
|
25923
|
+
projectRoot,
|
|
25924
|
+
issueNumber
|
|
25925
|
+
});
|
|
25926
|
+
return ensured.page;
|
|
25927
|
+
});
|
|
25928
|
+
}
|
|
25929
|
+
if (input.mode === "model-groups") {
|
|
25930
|
+
return runTaishiModelGroupsMode(input);
|
|
25931
|
+
}
|
|
25932
|
+
return runTaishiIssueMode(input);
|
|
25933
|
+
}
|
|
25934
|
+
var TaishiIssueComputeError, taishiSweepModeInputSchema;
|
|
25935
|
+
var init_taishi_entry = __esm({
|
|
25936
|
+
"src/taishi-entry.ts"() {
|
|
25937
|
+
"use strict";
|
|
25938
|
+
init_build();
|
|
25939
|
+
init_activation_ledger_topology();
|
|
25940
|
+
init_taishi_cohort();
|
|
25941
|
+
init_taishi_ledger();
|
|
25942
|
+
init_taishi_index();
|
|
25943
|
+
init_taishi_model_groups();
|
|
25944
|
+
init_taishi_page();
|
|
25945
|
+
TaishiIssueComputeError = class extends Error {
|
|
25946
|
+
code = "taishi-issue-compute-failed";
|
|
25947
|
+
projectRoot;
|
|
25948
|
+
issueNumber;
|
|
25949
|
+
constructor(input) {
|
|
25950
|
+
const root = physicalPathIdentity(input.projectRoot);
|
|
25951
|
+
const causeText = input.cause instanceof Error ? input.cause.message || input.cause.name : String(input.cause);
|
|
25952
|
+
const issueFace = input.issueNumber === void 0 ? `projectRoot ${root}` : `issue ${input.issueNumber} (projectRoot ${root})`;
|
|
25953
|
+
super(`taishi compute failed for ${issueFace}: ${causeText}`, {
|
|
25954
|
+
cause: input.cause
|
|
25955
|
+
});
|
|
25956
|
+
this.name = "TaishiIssueComputeError";
|
|
25957
|
+
this.projectRoot = root;
|
|
25958
|
+
if (input.issueNumber !== void 0) {
|
|
25959
|
+
this.issueNumber = input.issueNumber;
|
|
25960
|
+
}
|
|
25961
|
+
}
|
|
25962
|
+
};
|
|
25963
|
+
taishiSweepModeInputSchema = typebox_exports.Object(
|
|
25964
|
+
{
|
|
25965
|
+
mode: typebox_exports.Literal("sweep"),
|
|
25966
|
+
mergedPullRequests: typebox_exports.Array(
|
|
25967
|
+
typebox_exports.Object(
|
|
25968
|
+
{
|
|
25969
|
+
projectRoot: typebox_exports.String(),
|
|
25970
|
+
/** 排除后改动行数 — omit or 0 → typed 空缺; finite ≥ 0 only. */
|
|
25971
|
+
changedLines: typebox_exports.Optional(
|
|
25972
|
+
typebox_exports.Number({ minimum: 0, maximum: Number.MAX_VALUE })
|
|
25973
|
+
)
|
|
25974
|
+
},
|
|
25975
|
+
{ additionalProperties: false }
|
|
25976
|
+
)
|
|
25977
|
+
)
|
|
25978
|
+
},
|
|
25979
|
+
{ additionalProperties: false }
|
|
25980
|
+
);
|
|
25981
|
+
}
|
|
25982
|
+
});
|
|
25983
|
+
|
|
25984
|
+
// src/public-cli/taishi-run.ts
|
|
25985
|
+
import { readFile as readFile15 } from "node:fs/promises";
|
|
25986
|
+
import { isAbsolute as isAbsolute5, resolve as resolve8 } from "node:path";
|
|
25987
|
+
async function buildTaishiIssueModeInputFromPublicArgv(parsed, ledgerHome) {
|
|
25988
|
+
const ticket = parsed.ticket;
|
|
25989
|
+
const directRoot = parsed.projectRoot;
|
|
25990
|
+
if (ticket === void 0) {
|
|
25991
|
+
return {
|
|
25992
|
+
mode: "issue",
|
|
25993
|
+
projectRoot: directRoot
|
|
25994
|
+
};
|
|
25995
|
+
}
|
|
25996
|
+
const index = await readTaishiLibraryIndexPage(ledgerHome);
|
|
25997
|
+
const row = findTaishiLibraryIndexRow(index, ticket);
|
|
25998
|
+
let projectRoot;
|
|
25999
|
+
if (row !== void 0) {
|
|
26000
|
+
projectRoot = row.projectRoot;
|
|
26001
|
+
} else if (directRoot !== void 0) {
|
|
26002
|
+
projectRoot = directRoot;
|
|
26003
|
+
} else {
|
|
26004
|
+
throw new CliUsageError(
|
|
26005
|
+
`taishi library index has no row for ticket ${ticket}`
|
|
26006
|
+
);
|
|
26007
|
+
}
|
|
26008
|
+
const dualParamConflict = row !== void 0 && directRoot !== void 0 && physicalPathIdentity(directRoot) !== physicalPathIdentity(projectRoot);
|
|
26009
|
+
return {
|
|
26010
|
+
mode: "issue",
|
|
26011
|
+
projectRoot,
|
|
26012
|
+
ticketNumber: ticket,
|
|
26013
|
+
issueNumber: ticket,
|
|
26014
|
+
...dualParamConflict ? { conflictingProjectRoot: directRoot } : {}
|
|
26015
|
+
};
|
|
26016
|
+
}
|
|
26017
|
+
function parseTaishiSweepModeInputFromJsonValue(value) {
|
|
26018
|
+
if (!value_exports.Check(taishiSweepModeInputSchema, value)) {
|
|
26019
|
+
throw new CliUsageError(
|
|
26020
|
+
"taishi sweep attachment must match TaishiSweepModeInput"
|
|
26021
|
+
);
|
|
26022
|
+
}
|
|
26023
|
+
return value;
|
|
26024
|
+
}
|
|
26025
|
+
async function buildTaishiSweepModeInputFromAttachmentPaths(attachmentPaths) {
|
|
26026
|
+
if (attachmentPaths.length !== 1) {
|
|
26027
|
+
throw new CliUsageError(
|
|
26028
|
+
"taishi sweep requires exactly one --attach typed JSON attachment"
|
|
26029
|
+
);
|
|
26030
|
+
}
|
|
26031
|
+
const sourcePath = attachmentPaths[0];
|
|
26032
|
+
const absolute = isAbsolute5(sourcePath) ? sourcePath : resolve8(sourcePath);
|
|
26033
|
+
let bytes;
|
|
26034
|
+
try {
|
|
26035
|
+
bytes = await readFile15(absolute);
|
|
26036
|
+
} catch (error) {
|
|
26037
|
+
throw new CliUsageError(
|
|
26038
|
+
`taishi sweep attachment is not a readable regular file: ${sourcePath}`,
|
|
26039
|
+
{ cause: error }
|
|
26040
|
+
);
|
|
26041
|
+
}
|
|
26042
|
+
let text;
|
|
26043
|
+
try {
|
|
26044
|
+
text = exactUtf8(bytes, "taishi sweep attachment");
|
|
26045
|
+
} catch (error) {
|
|
26046
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
26047
|
+
throw new CliUsageError(detail, { cause: error });
|
|
26048
|
+
}
|
|
26049
|
+
let parsed;
|
|
26050
|
+
try {
|
|
26051
|
+
parsed = JSON.parse(text);
|
|
26052
|
+
} catch (error) {
|
|
26053
|
+
throw new CliUsageError(
|
|
26054
|
+
"taishi sweep attachment is not valid JSON",
|
|
26055
|
+
{ cause: error }
|
|
26056
|
+
);
|
|
26057
|
+
}
|
|
26058
|
+
return parseTaishiSweepModeInputFromJsonValue(parsed);
|
|
26059
|
+
}
|
|
26060
|
+
async function runPublicTaishi(argv, _env, io, parseTaishiArgv2) {
|
|
26061
|
+
try {
|
|
26062
|
+
const parsed = parseTaishiArgv2(argv);
|
|
26063
|
+
const ledgerHome = resolveActivationLedgerHome();
|
|
26064
|
+
if (parsed.query === "sweep") {
|
|
26065
|
+
const input2 = await buildTaishiSweepModeInputFromAttachmentPaths(
|
|
26066
|
+
parsed.attachmentPaths
|
|
26067
|
+
);
|
|
26068
|
+
const result3 = await runTaishi(input2);
|
|
26069
|
+
io.stdout(`${JSON.stringify(result3, null, 2)}
|
|
26070
|
+
`);
|
|
26071
|
+
return { exitCode: 0 };
|
|
26072
|
+
}
|
|
26073
|
+
if (parsed.query === "cohort") {
|
|
26074
|
+
const result3 = await runTaishi({
|
|
26075
|
+
mode: "cohort",
|
|
26076
|
+
groups: parsed.groups
|
|
26077
|
+
});
|
|
26078
|
+
io.stdout(`${JSON.stringify(result3, null, 2)}
|
|
26079
|
+
`);
|
|
26080
|
+
return { exitCode: 0 };
|
|
26081
|
+
}
|
|
26082
|
+
if (parsed.query === "model-groups") {
|
|
26083
|
+
const result3 = await runTaishi({
|
|
26084
|
+
mode: "model-groups",
|
|
26085
|
+
projectRoots: parsed.projectRoots
|
|
26086
|
+
});
|
|
26087
|
+
io.stdout(`${JSON.stringify(result3, null, 2)}
|
|
26088
|
+
`);
|
|
26089
|
+
return { exitCode: 0 };
|
|
26090
|
+
}
|
|
26091
|
+
const input = await buildTaishiIssueModeInputFromPublicArgv(parsed, ledgerHome);
|
|
26092
|
+
const result2 = await readOrComputeTaishiIssuePage(input);
|
|
26093
|
+
io.stdout(`${JSON.stringify(result2, null, 2)}
|
|
26094
|
+
`);
|
|
26095
|
+
return { exitCode: 0 };
|
|
26096
|
+
} catch (error) {
|
|
26097
|
+
if (error instanceof CliUsageError) {
|
|
26098
|
+
presentStructuralRejection(error, io);
|
|
26099
|
+
return { exitCode: 2 };
|
|
26100
|
+
}
|
|
26101
|
+
if (error instanceof TaishiIssueComputeError) {
|
|
26102
|
+
const code = errnoCode(error.cause);
|
|
26103
|
+
presentControlledFailure({
|
|
26104
|
+
cause: "output",
|
|
26105
|
+
diagnostic: error.message,
|
|
26106
|
+
...code === void 0 ? {} : { identity: { code } },
|
|
26107
|
+
details: {
|
|
26108
|
+
code: error.code,
|
|
26109
|
+
projectRoot: error.projectRoot,
|
|
26110
|
+
...error.issueNumber === void 0 ? {} : { issueNumber: error.issueNumber }
|
|
26111
|
+
}
|
|
26112
|
+
}, io);
|
|
26113
|
+
return { exitCode: 1 };
|
|
26114
|
+
}
|
|
26115
|
+
throw error;
|
|
26116
|
+
}
|
|
26117
|
+
}
|
|
26118
|
+
var init_taishi_run = __esm({
|
|
26119
|
+
"src/public-cli/taishi-run.ts"() {
|
|
26120
|
+
"use strict";
|
|
26121
|
+
init_value2();
|
|
26122
|
+
init_activation_ledger_topology();
|
|
26123
|
+
init_exact_utf8();
|
|
26124
|
+
init_taishi_index();
|
|
26125
|
+
init_taishi_entry();
|
|
26126
|
+
init_cli_errors();
|
|
26127
|
+
init_settlement();
|
|
26128
|
+
}
|
|
26129
|
+
});
|
|
26130
|
+
|
|
26131
|
+
// src/public-cli/cli.ts
|
|
26132
|
+
var cli_exports = {};
|
|
26133
|
+
__export(cli_exports, {
|
|
26134
|
+
CliUsageError: () => CliUsageError,
|
|
26135
|
+
PUBLIC_ROLE_ARGV: () => PUBLIC_ROLE_ARGV,
|
|
26136
|
+
buildExplicitInternalActivationArgs: () => buildExplicitInternalActivationArgs,
|
|
26137
|
+
helpDocument: () => helpDocument,
|
|
26138
|
+
resolveInternalRoleEntrypoint: () => resolveInternalRoleEntrypoint,
|
|
26139
|
+
runAkRole: () => runAkRole
|
|
26140
|
+
});
|
|
26141
|
+
import { realpath as realpath5 } from "node:fs/promises";
|
|
26142
|
+
import { homedir as homedir3 } from "node:os";
|
|
26143
|
+
import { join as join23 } from "node:path";
|
|
26144
|
+
function takePublicGlobalFlag(argv, index) {
|
|
26145
|
+
const token = argv[index];
|
|
26146
|
+
if (token === void 0) return void 0;
|
|
23728
26147
|
if (token === "--help" || token === "-h") {
|
|
23729
26148
|
return { flag: "help", consume: 1 };
|
|
23730
26149
|
}
|
|
@@ -23772,7 +26191,7 @@ function resolveHome(env) {
|
|
|
23772
26191
|
return env.home ?? process.env.HOME ?? homedir3();
|
|
23773
26192
|
}
|
|
23774
26193
|
function resolveAgentDir(env, home) {
|
|
23775
|
-
return env.agentDir ?? process.env.PI_CODING_AGENT_DIR ??
|
|
26194
|
+
return env.agentDir ?? process.env.PI_CODING_AGENT_DIR ?? join23(home, ".pi", "agent");
|
|
23776
26195
|
}
|
|
23777
26196
|
function parseThinking(value) {
|
|
23778
26197
|
if (!THINKING_LEVELS2.has(value)) {
|
|
@@ -23858,6 +26277,12 @@ function renderHelp() {
|
|
|
23858
26277
|
lines.push(` ${cap.name} \u2014 ${phaseText}`);
|
|
23859
26278
|
}
|
|
23860
26279
|
}
|
|
26280
|
+
lines.push("", "Deterministic commands:");
|
|
26281
|
+
for (const cap of doc.capabilities) {
|
|
26282
|
+
if (cap.kind === "deterministic") {
|
|
26283
|
+
lines.push(` ${cap.name}`);
|
|
26284
|
+
}
|
|
26285
|
+
}
|
|
23861
26286
|
lines.push(
|
|
23862
26287
|
"",
|
|
23863
26288
|
"Global options: --model provider/model --thinking level",
|
|
@@ -23955,6 +26380,9 @@ async function runAkRole(argv, env) {
|
|
|
23955
26380
|
}
|
|
23956
26381
|
if (match.kind === "support") {
|
|
23957
26382
|
io.stdout(`command ${match.name} kind support
|
|
26383
|
+
`);
|
|
26384
|
+
} else if (match.kind === "deterministic") {
|
|
26385
|
+
io.stdout(`command ${match.name} kind deterministic
|
|
23958
26386
|
`);
|
|
23959
26387
|
} else {
|
|
23960
26388
|
io.stdout(
|
|
@@ -24358,6 +26786,15 @@ async function runAkRole(argv, env) {
|
|
|
24358
26786
|
...result2.terminal === void 0 ? {} : { terminal: result2.terminal }
|
|
24359
26787
|
};
|
|
24360
26788
|
}
|
|
26789
|
+
if (parsed.command === "taishi") {
|
|
26790
|
+
const result2 = await runPublicTaishi(
|
|
26791
|
+
parsed.args,
|
|
26792
|
+
{ home },
|
|
26793
|
+
io,
|
|
26794
|
+
PUBLIC_ROLE_ARGV.taishi.parse
|
|
26795
|
+
);
|
|
26796
|
+
return { exitCode: result2.exitCode };
|
|
26797
|
+
}
|
|
24361
26798
|
throw new CliUsageError(`unknown command: ${parsed.command}`);
|
|
24362
26799
|
} catch (error) {
|
|
24363
26800
|
if (error instanceof CliUsageError) {
|
|
@@ -24388,6 +26825,7 @@ var init_cli = __esm({
|
|
|
24388
26825
|
init_judge_run();
|
|
24389
26826
|
init_merger_run();
|
|
24390
26827
|
init_reviewer_run();
|
|
26828
|
+
init_taishi_run();
|
|
24391
26829
|
init_run_lifecycle();
|
|
24392
26830
|
init_registry2();
|
|
24393
26831
|
init_settlement();
|
|
@@ -24400,7 +26838,9 @@ var init_cli = __esm({
|
|
|
24400
26838
|
collector: { parse: parseCollectorArgv },
|
|
24401
26839
|
doctor: { parse: parseDoctorArgv },
|
|
24402
26840
|
merger: { parse: parseMergerArgv },
|
|
24403
|
-
reviewer: { parse: parseReviewerArgv }
|
|
26841
|
+
reviewer: { parse: parseReviewerArgv },
|
|
26842
|
+
/** Deterministic analysis seat (#336) — argv parse only; no LLM admission. */
|
|
26843
|
+
taishi: { parse: parseTaishiArgv }
|
|
24404
26844
|
};
|
|
24405
26845
|
THINKING_LEVELS2 = /* @__PURE__ */ new Set([
|
|
24406
26846
|
"off",
|
|
@@ -24415,7 +26855,8 @@ var init_cli = __esm({
|
|
|
24415
26855
|
});
|
|
24416
26856
|
|
|
24417
26857
|
// src/public-cli/main.ts
|
|
24418
|
-
import {
|
|
26858
|
+
import { existsSync as existsSync2 } from "node:fs";
|
|
26859
|
+
import { dirname as dirname11, join as join24 } from "node:path";
|
|
24419
26860
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
24420
26861
|
|
|
24421
26862
|
// src/public-cli/host-pi-runtime.ts
|
|
@@ -24502,8 +26943,15 @@ function linkPackage(packageRoot2, name, targetDir) {
|
|
|
24502
26943
|
}
|
|
24503
26944
|
|
|
24504
26945
|
// src/public-cli/main.ts
|
|
24505
|
-
var here =
|
|
24506
|
-
|
|
26946
|
+
var here = dirname11(fileURLToPath2(import.meta.url));
|
|
26947
|
+
function resolvePackageRoot(binDir) {
|
|
26948
|
+
const canonical = join24(binDir, "..", "..");
|
|
26949
|
+
if (existsSync2(join24(canonical, "package.json"))) {
|
|
26950
|
+
return canonical;
|
|
26951
|
+
}
|
|
26952
|
+
return binDir;
|
|
26953
|
+
}
|
|
26954
|
+
var packageRoot = resolvePackageRoot(here);
|
|
24507
26955
|
ensureHostPiRuntimeResolvable(packageRoot);
|
|
24508
26956
|
var { runAkRole: runAkRole2 } = await Promise.resolve().then(() => (init_cli(), cli_exports));
|
|
24509
26957
|
var result = await runAkRole2(process.argv.slice(2), { packageRoot });
|