@dailephd/my-dev-kit-lab 0.6.2 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +26 -0
- package/README.md +11 -8
- package/benchmarks/contracts/context-window-scaling-cases.json +220 -0
- package/benchmarks/projects/context-window-scaling-fixed-ts/README.md +14 -0
- package/benchmarks/projects/context-window-scaling-fixed-ts/src/filler/tier-1/carrier-depot-catalog-01.ts +302 -0
- package/benchmarks/projects/context-window-scaling-fixed-ts/src/filler/tier-1/course-module-catalog-06.ts +302 -0
- package/benchmarks/projects/context-window-scaling-fixed-ts/src/filler/tier-1/library-shelf-catalog-07.ts +302 -0
- package/benchmarks/projects/context-window-scaling-fixed-ts/src/filler/tier-1/sensor-station-catalog-05.ts +302 -0
- package/benchmarks/projects/context-window-scaling-fixed-ts/src/filler/tier-1/staff-rota-catalog-03.ts +302 -0
- package/benchmarks/projects/context-window-scaling-fixed-ts/src/filler/tier-1/supplier-contract-catalog-02.ts +302 -0
- package/benchmarks/projects/context-window-scaling-fixed-ts/src/filler/tier-1/vehicle-route-catalog-04.ts +302 -0
- package/benchmarks/projects/context-window-scaling-fixed-ts/src/filler/tier-2/archive-box-catalog-12.ts +302 -0
- package/benchmarks/projects/context-window-scaling-fixed-ts/src/filler/tier-2/clinic-ward-catalog-08.ts +302 -0
- package/benchmarks/projects/context-window-scaling-fixed-ts/src/filler/tier-2/greenhouse-bay-catalog-13.ts +302 -0
- package/benchmarks/projects/context-window-scaling-fixed-ts/src/filler/tier-2/harbor-berth-catalog-10.ts +302 -0
- package/benchmarks/projects/context-window-scaling-fixed-ts/src/filler/tier-2/kitchen-section-catalog-15.ts +302 -0
- package/benchmarks/projects/context-window-scaling-fixed-ts/src/filler/tier-2/market-stall-catalog-09.ts +302 -0
- package/benchmarks/projects/context-window-scaling-fixed-ts/src/filler/tier-2/station-platform-catalog-14.ts +302 -0
- package/benchmarks/projects/context-window-scaling-fixed-ts/src/filler/tier-2/workshop-bench-catalog-11.ts +302 -0
- package/benchmarks/projects/context-window-scaling-fixed-ts/src/filler/tier-3/archive-box-catalog-28.ts +302 -0
- package/benchmarks/projects/context-window-scaling-fixed-ts/src/filler/tier-3/carrier-depot-catalog-17.ts +302 -0
- package/benchmarks/projects/context-window-scaling-fixed-ts/src/filler/tier-3/clinic-ward-catalog-24.ts +302 -0
- package/benchmarks/projects/context-window-scaling-fixed-ts/src/filler/tier-3/course-module-catalog-22.ts +302 -0
- package/benchmarks/projects/context-window-scaling-fixed-ts/src/filler/tier-3/greenhouse-bay-catalog-29.ts +302 -0
- package/benchmarks/projects/context-window-scaling-fixed-ts/src/filler/tier-3/harbor-berth-catalog-26.ts +302 -0
- package/benchmarks/projects/context-window-scaling-fixed-ts/src/filler/tier-3/kitchen-section-catalog-31.ts +302 -0
- package/benchmarks/projects/context-window-scaling-fixed-ts/src/filler/tier-3/library-shelf-catalog-23.ts +302 -0
- package/benchmarks/projects/context-window-scaling-fixed-ts/src/filler/tier-3/market-stall-catalog-25.ts +302 -0
- package/benchmarks/projects/context-window-scaling-fixed-ts/src/filler/tier-3/sensor-station-catalog-21.ts +302 -0
- package/benchmarks/projects/context-window-scaling-fixed-ts/src/filler/tier-3/staff-rota-catalog-19.ts +302 -0
- package/benchmarks/projects/context-window-scaling-fixed-ts/src/filler/tier-3/station-platform-catalog-30.ts +302 -0
- package/benchmarks/projects/context-window-scaling-fixed-ts/src/filler/tier-3/supplier-contract-catalog-18.ts +302 -0
- package/benchmarks/projects/context-window-scaling-fixed-ts/src/filler/tier-3/vehicle-route-catalog-20.ts +302 -0
- package/benchmarks/projects/context-window-scaling-fixed-ts/src/filler/tier-3/warehouse-zone-catalog-16.ts +302 -0
- package/benchmarks/projects/context-window-scaling-fixed-ts/src/filler/tier-3/workshop-bench-catalog-27.ts +302 -0
- package/benchmarks/projects/context-window-scaling-fixed-ts/src/filler/tier-4/archive-box-catalog-44.ts +302 -0
- package/benchmarks/projects/context-window-scaling-fixed-ts/src/filler/tier-4/carrier-depot-catalog-33.ts +302 -0
- package/benchmarks/projects/context-window-scaling-fixed-ts/src/filler/tier-4/carrier-depot-catalog-49.ts +302 -0
- package/benchmarks/projects/context-window-scaling-fixed-ts/src/filler/tier-4/clinic-ward-catalog-40.ts +302 -0
- package/benchmarks/projects/context-window-scaling-fixed-ts/src/filler/tier-4/clinic-ward-catalog-56.ts +302 -0
- package/benchmarks/projects/context-window-scaling-fixed-ts/src/filler/tier-4/course-module-catalog-38.ts +302 -0
- package/benchmarks/projects/context-window-scaling-fixed-ts/src/filler/tier-4/course-module-catalog-54.ts +302 -0
- package/benchmarks/projects/context-window-scaling-fixed-ts/src/filler/tier-4/greenhouse-bay-catalog-45.ts +302 -0
- package/benchmarks/projects/context-window-scaling-fixed-ts/src/filler/tier-4/harbor-berth-catalog-42.ts +302 -0
- package/benchmarks/projects/context-window-scaling-fixed-ts/src/filler/tier-4/harbor-berth-catalog-58.ts +302 -0
- package/benchmarks/projects/context-window-scaling-fixed-ts/src/filler/tier-4/kitchen-section-catalog-47.ts +302 -0
- package/benchmarks/projects/context-window-scaling-fixed-ts/src/filler/tier-4/library-shelf-catalog-39.ts +302 -0
- package/benchmarks/projects/context-window-scaling-fixed-ts/src/filler/tier-4/library-shelf-catalog-55.ts +302 -0
- package/benchmarks/projects/context-window-scaling-fixed-ts/src/filler/tier-4/market-stall-catalog-41.ts +302 -0
- package/benchmarks/projects/context-window-scaling-fixed-ts/src/filler/tier-4/market-stall-catalog-57.ts +302 -0
- package/benchmarks/projects/context-window-scaling-fixed-ts/src/filler/tier-4/sensor-station-catalog-37.ts +302 -0
- package/benchmarks/projects/context-window-scaling-fixed-ts/src/filler/tier-4/sensor-station-catalog-53.ts +302 -0
- package/benchmarks/projects/context-window-scaling-fixed-ts/src/filler/tier-4/staff-rota-catalog-35.ts +302 -0
- package/benchmarks/projects/context-window-scaling-fixed-ts/src/filler/tier-4/staff-rota-catalog-51.ts +302 -0
- package/benchmarks/projects/context-window-scaling-fixed-ts/src/filler/tier-4/station-platform-catalog-46.ts +302 -0
- package/benchmarks/projects/context-window-scaling-fixed-ts/src/filler/tier-4/supplier-contract-catalog-34.ts +302 -0
- package/benchmarks/projects/context-window-scaling-fixed-ts/src/filler/tier-4/supplier-contract-catalog-50.ts +302 -0
- package/benchmarks/projects/context-window-scaling-fixed-ts/src/filler/tier-4/vehicle-route-catalog-36.ts +302 -0
- package/benchmarks/projects/context-window-scaling-fixed-ts/src/filler/tier-4/vehicle-route-catalog-52.ts +302 -0
- package/benchmarks/projects/context-window-scaling-fixed-ts/src/filler/tier-4/warehouse-zone-catalog-32.ts +302 -0
- package/benchmarks/projects/context-window-scaling-fixed-ts/src/filler/tier-4/warehouse-zone-catalog-48.ts +302 -0
- package/benchmarks/projects/context-window-scaling-fixed-ts/src/filler/tier-4/workshop-bench-catalog-43.ts +302 -0
- package/benchmarks/projects/context-window-scaling-fixed-ts/src/tasks/auditRedaction.ts +25 -0
- package/benchmarks/projects/context-window-scaling-fixed-ts/src/tasks/inventoryReservation.ts +26 -0
- package/benchmarks/projects/context-window-scaling-fixed-ts/src/tasks/invoiceTotals.ts +25 -0
- package/benchmarks/projects/context-window-scaling-fixed-ts/src/tasks/shippingQuote.ts +32 -0
- package/benchmarks/projects/context-window-scaling-fixed-ts/tests/tasks/auditRedaction.test.ts +17 -0
- package/benchmarks/projects/context-window-scaling-fixed-ts/tests/tasks/inventoryReservation.test.ts +19 -0
- package/benchmarks/projects/context-window-scaling-fixed-ts/tests/tasks/invoiceTotals.test.ts +14 -0
- package/benchmarks/projects/context-window-scaling-fixed-ts/tests/tasks/shippingQuote.test.ts +19 -0
- package/dist/src/cli/help.js +27 -10
- package/dist/src/commands/runExperimentDescribeCommand.js +5 -2
- package/dist/src/commands/runExperimentRunCommand.js +64 -8
- package/dist/src/evaluation/benchmarkMetadata.js +5 -1
- package/dist/src/evaluation/parseAgentAnswer.js +172 -24
- package/dist/src/evaluation/runMyDevKitRetrieval.js +120 -7
- package/dist/src/experiments/defaultRegistry.js +2 -0
- package/dist/src/experiments/plugins/contextWindowScaling/cliBudgets.js +31 -0
- package/dist/src/experiments/plugins/contextWindowScaling/config.js +84 -0
- package/dist/src/experiments/plugins/contextWindowScaling/contextBudget.js +43 -0
- package/dist/src/experiments/plugins/contextWindowScaling/evaluation.js +36 -0
- package/dist/src/experiments/plugins/contextWindowScaling/execution.js +187 -0
- package/dist/src/experiments/plugins/contextWindowScaling/executionArtifact.js +15 -0
- package/dist/src/experiments/plugins/contextWindowScaling/executionArtifactReader.js +186 -0
- package/dist/src/experiments/plugins/contextWindowScaling/index.js +14 -0
- package/dist/src/experiments/plugins/contextWindowScaling/metadata.js +12 -0
- package/dist/src/experiments/plugins/contextWindowScaling/metrics.js +149 -0
- package/dist/src/experiments/plugins/contextWindowScaling/plugin.js +185 -0
- package/dist/src/experiments/plugins/contextWindowScaling/projectProfile.js +51 -0
- package/dist/src/experiments/plugins/contextWindowScaling/relevantFiles.js +76 -0
- package/dist/src/experiments/plugins/contextWindowScaling/successEvidence.js +60 -0
- package/dist/src/experiments/plugins/contextWindowScaling/types.js +1 -0
- package/dist/src/experiments/plugins/incrementalChangeStaleness/comparisonV2.js +49 -0
- package/dist/src/experiments/plugins/incrementalChangeStaleness/config.js +5 -4
- package/dist/src/experiments/plugins/incrementalChangeStaleness/disposableTarget.js +20 -2
- package/dist/src/experiments/plugins/incrementalChangeStaleness/execution.js +42 -16
- package/dist/src/experiments/plugins/incrementalChangeStaleness/executionArtifact.js +4 -4
- package/dist/src/experiments/plugins/incrementalChangeStaleness/executionArtifactV2.js +289 -0
- package/dist/src/experiments/plugins/incrementalChangeStaleness/executionV2.js +195 -0
- package/dist/src/experiments/plugins/incrementalChangeStaleness/indexClone.js +76 -0
- package/dist/src/experiments/plugins/incrementalChangeStaleness/lifecycle.js +64 -32
- package/dist/src/experiments/plugins/incrementalChangeStaleness/lifecyclePolicy.js +6 -4
- package/dist/src/experiments/plugins/incrementalChangeStaleness/lifecyclePolicyV2.js +78 -0
- package/dist/src/experiments/plugins/incrementalChangeStaleness/lifecycleV2.js +298 -0
- package/dist/src/experiments/plugins/incrementalChangeStaleness/plugin.js +213 -12
- package/dist/src/experiments/plugins/incrementalChangeStaleness/treatmentSessionV2.js +5 -0
- package/dist/src/experiments/plugins/index.js +1 -0
- package/dist/src/experiments/plugins/warmIndexReuse/agentEvaluation.js +1 -1
- package/dist/src/experiments/plugins/warmIndexReuse/warmIndexSession.js +3 -1
- package/dist/src/mobile/android/advancedSecurity/candidateEvidence.js +9 -2
- package/dist/src/mobile/android/advancedSecurity/redaction.js +19 -10
- package/dist/src/mobile/android/advancedSecurity/secretCandidates/analyzeSecretCandidates.js +12 -2
- package/dist/src/mobile/android/advancedSecurity/signingConfiguration/analyzeSigningConfiguration.js +1 -1
- package/dist/src/mobile/android/advancedSecurity/signingConfiguration/extractSigningConfigurations.js +7 -7
- package/dist/src/plots/buildContextWindowScalingPlotData.js +96 -0
- package/dist/src/plots/index.js +1 -0
- package/dist/src/plots/writePlotArtifacts.js +12 -3
- package/dist/src/report/experiments/buildContextWindowScalingReport.js +84 -0
- package/dist/src/report/experiments/buildIncrementalChangeStalenessPluginReport.js +33 -0
- package/dist/src/report/experiments/buildIncrementalChangeStalenessReport.js +1 -1
- package/dist/src/report/experiments/buildIncrementalChangeStalenessReportV2.js +80 -0
- package/dist/src/report/experiments/buildPluginExperimentReport.js +24 -4
- package/dist/src/report/experiments/contextWindowScalingReportModel.js +3 -0
- package/dist/src/report/experiments/incrementalChangeStalenessReportModelV2.js +3 -0
- package/dist/src/report/experiments/incrementalChangeStalenessReportRowsV2.js +146 -0
- package/dist/src/report/experiments/index.js +7 -0
- package/dist/src/report/experiments/renderContextWindowScalingHtml.js +99 -0
- package/dist/src/report/experiments/renderContextWindowScalingText.js +108 -0
- package/dist/src/report/experiments/renderIncrementalChangeStalenessHtml.js +4 -0
- package/dist/src/report/experiments/renderIncrementalChangeStalenessHtmlV2.js +111 -0
- package/dist/src/report/experiments/renderIncrementalChangeStalenessTextV2.js +96 -0
- package/dist/src/report/experiments/renderPluginExperimentReportHtml.js +3 -0
- package/dist/src/report/experiments/renderPluginExperimentReportText.js +14 -0
- package/dist/src/securityValidation/staticScans/codeql.js +8 -8
- package/docs/METRICS.md +58 -0
- package/examples/tutorial-browser/prepare.mjs +13 -13
- package/examples/tutorial-browser/server.mjs +13 -13
- package/package.json +1 -1
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { CONTEXT_WINDOW_SCALING_PLUGIN_ID } from "../../experiments/plugins/contextWindowScaling/metadata.js";
|
|
2
|
+
import { CONTEXT_WINDOW_SCALING_REPORT_SCHEMA_VERSION, MAX_REPORT_OMITTED_RELEVANT_FILES, } from "./contextWindowScalingReportModel.js";
|
|
3
|
+
/** Fixed wording; the report states observed evidence only and never ranks treatments. */
|
|
4
|
+
export const CONTEXT_WINDOW_SCALING_INTERPRETATION = [
|
|
5
|
+
"Estimated context tokens use the Lab deterministic heuristic (characters divided by four, rounded up); they are not provider billing telemetry or a provider model tokenizer result.",
|
|
6
|
+
"The configured budgets are experiment budgets, not claims about actual provider model context-window limits.",
|
|
7
|
+
"context-too-large is an expected measurement state under a budget and is not an operational execution failure.",
|
|
8
|
+
"When a context is too large for a budget, evaluation did not occur, so correctness is unavailable; unavailable correctness is not zero and is excluded from mean correctness.",
|
|
9
|
+
"Success combines context fit with the existing deterministic correctness pass evidence: success is true only when the context fits and correctness passes.",
|
|
10
|
+
"context-too-large is an available, not-successful outcome for the applicable budget and remains in the success-rate denominator.",
|
|
11
|
+
"Operational or evidence-unavailable cells are excluded from the success-rate denominator and are counted separately.",
|
|
12
|
+
"Omitted relevant files are benchmark-expected files that were not observed in the treatment's context provenance.",
|
|
13
|
+
"Omitted relevant files are not full retrieval precision or recall; no precision, recall, or irrelevant-context measure is calculated.",
|
|
14
|
+
"The deterministic fake-agent correctness path is context-independent in the current harness: correctness tests the existing answer-key and evaluation pipeline, not semantic model sensitivity to different context content.",
|
|
15
|
+
"Utilization is estimated context tokens divided by the budget, is not capped at 100 percent, and may exceed 100 for a context that is too large.",
|
|
16
|
+
"No composite score, winner, or ranking is calculated; the treatments are reported side by side.",
|
|
17
|
+
];
|
|
18
|
+
/**
|
|
19
|
+
* Presents the aggregate and cell evidence already calculated on the run. It performs no fit,
|
|
20
|
+
* success, correctness, or utilization calculation of its own.
|
|
21
|
+
*/
|
|
22
|
+
export function buildContextWindowScalingReport(run) {
|
|
23
|
+
if (run.pluginId !== CONTEXT_WINDOW_SCALING_PLUGIN_ID)
|
|
24
|
+
return null;
|
|
25
|
+
const candidate = run;
|
|
26
|
+
const evidence = candidate.executionEvidence;
|
|
27
|
+
const aggregate = candidate.aggregate;
|
|
28
|
+
if (!evidence || !aggregate) {
|
|
29
|
+
throw new Error("Invalid context-window-scaling report source: execution evidence and aggregate are required.");
|
|
30
|
+
}
|
|
31
|
+
if (aggregate.caseTreatmentContextSummaries.length !== evidence.length * aggregate.treatments.length) {
|
|
32
|
+
throw new Error("Invalid context-window-scaling report source: aggregate and execution evidence are inconsistent.");
|
|
33
|
+
}
|
|
34
|
+
const caseTreatmentContexts = aggregate.caseTreatmentContextSummaries.map((summary) => {
|
|
35
|
+
const relevant = summary.relevantFileEvidence;
|
|
36
|
+
return {
|
|
37
|
+
caseId: summary.caseId,
|
|
38
|
+
caseName: summary.caseName,
|
|
39
|
+
variantId: summary.variantId,
|
|
40
|
+
contextStatus: summary.contextStatus,
|
|
41
|
+
characterCount: summary.characterCount,
|
|
42
|
+
estimatedTokens: summary.estimatedTokens,
|
|
43
|
+
tokenCountMethod: summary.tokenCountMethod,
|
|
44
|
+
observedFileCount: summary.observedFileCount,
|
|
45
|
+
relevantFileStatus: relevant.status,
|
|
46
|
+
expectedRelevantFileCount: relevant.expectedRelevantFileCount,
|
|
47
|
+
observedExpectedFileCount: relevant.observedExpectedFileCount,
|
|
48
|
+
omittedRelevantFileCount: relevant.omittedRelevantFileCount,
|
|
49
|
+
omittedRelevantFiles: boundedList(relevant.omittedRelevantFiles),
|
|
50
|
+
relevantFileReason: relevant.reason,
|
|
51
|
+
};
|
|
52
|
+
});
|
|
53
|
+
const caseBudgetCells = evidence.flatMap((caseEvidence) => caseEvidence.treatments.flatMap((treatment) => treatment.budgetCells.map((cell) => ({
|
|
54
|
+
caseId: caseEvidence.caseId,
|
|
55
|
+
variantId: treatment.variantId,
|
|
56
|
+
contextEstimatedTokens: treatment.context.estimatedTokens,
|
|
57
|
+
...structuredClone(cell),
|
|
58
|
+
}))));
|
|
59
|
+
return {
|
|
60
|
+
schemaVersion: CONTEXT_WINDOW_SCALING_REPORT_SCHEMA_VERSION,
|
|
61
|
+
budgets: [...aggregate.budgets],
|
|
62
|
+
treatments: [...aggregate.treatments],
|
|
63
|
+
tokenCountMethod: firstTokenCountMethod(aggregate.caseTreatmentContextSummaries.map((summary) => summary.tokenCountMethod)),
|
|
64
|
+
runSummary: { ...aggregate.runSummary },
|
|
65
|
+
budgetTreatmentSummaries: aggregate.budgetTreatmentSummaries.map((summary) => ({ ...summary })),
|
|
66
|
+
caseTreatmentContexts,
|
|
67
|
+
caseBudgetCells,
|
|
68
|
+
relevantFileSummary: { ...aggregate.relevantFileSummary },
|
|
69
|
+
interpretation: [...CONTEXT_WINDOW_SCALING_INTERPRETATION],
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
function boundedList(items) {
|
|
73
|
+
const displayed = items.slice(0, MAX_REPORT_OMITTED_RELEVANT_FILES);
|
|
74
|
+
return {
|
|
75
|
+
totalCount: items.length,
|
|
76
|
+
displayedCount: displayed.length,
|
|
77
|
+
omittedCount: items.length - displayed.length,
|
|
78
|
+
truncated: items.length > displayed.length,
|
|
79
|
+
items: [...displayed],
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
function firstTokenCountMethod(methods) {
|
|
83
|
+
return methods.find((method) => method !== null) ?? null;
|
|
84
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
// Dispatches the incremental-change-staleness plugin report by the persisted execution artifact's
|
|
2
|
+
// schemaVersion: V1 artifacts keep the released V1 report semantics untouched (the V1 builder is called
|
|
3
|
+
// as-is), V2 artifacts select the four-treatment V2 model. Historical V1 evidence is never converted.
|
|
4
|
+
import { readFileSync } from "node:fs";
|
|
5
|
+
import { INCREMENTAL_CHANGE_STALENESS_EXECUTION_SCHEMA_VERSION } from "../../experiments/plugins/incrementalChangeStaleness/executionArtifact.js";
|
|
6
|
+
import { INCREMENTAL_CHANGE_STALENESS_EXECUTION_SCHEMA_VERSION_V2 } from "../../experiments/plugins/incrementalChangeStaleness/executionArtifactV2.js";
|
|
7
|
+
import { INCREMENTAL_CHANGE_STALENESS_PLUGIN_ID } from "../../experiments/plugins/incrementalChangeStaleness/plugin.js";
|
|
8
|
+
import { buildIncrementalChangeStalenessReport, readArtifactPath } from "./buildIncrementalChangeStalenessReport.js";
|
|
9
|
+
import { buildIncrementalChangeStalenessReportV2FromArtifact } from "./buildIncrementalChangeStalenessReportV2.js";
|
|
10
|
+
export function buildIncrementalChangeStalenessPluginReport(run) {
|
|
11
|
+
if (run.pluginId !== INCREMENTAL_CHANGE_STALENESS_PLUGIN_ID)
|
|
12
|
+
return null;
|
|
13
|
+
const artifactPath = readArtifactPath(run);
|
|
14
|
+
if (!artifactPath)
|
|
15
|
+
return buildIncrementalChangeStalenessReport(run); // throws the established missing-path error
|
|
16
|
+
let schemaVersion;
|
|
17
|
+
let parsed;
|
|
18
|
+
try {
|
|
19
|
+
parsed = JSON.parse(readFileSync(artifactPath, "utf8"));
|
|
20
|
+
schemaVersion = parsed?.schemaVersion;
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
// Unreadable or malformed: the V1 builder owns the established, explicit error messages.
|
|
24
|
+
return buildIncrementalChangeStalenessReport(run);
|
|
25
|
+
}
|
|
26
|
+
if (schemaVersion === INCREMENTAL_CHANGE_STALENESS_EXECUTION_SCHEMA_VERSION_V2) {
|
|
27
|
+
return buildIncrementalChangeStalenessReportV2FromArtifact(parsed);
|
|
28
|
+
}
|
|
29
|
+
if (schemaVersion === INCREMENTAL_CHANGE_STALENESS_EXECUTION_SCHEMA_VERSION) {
|
|
30
|
+
return buildIncrementalChangeStalenessReport(run);
|
|
31
|
+
}
|
|
32
|
+
throw new Error(`Invalid incremental-change-staleness report source: unsupported execution artifact schema version ${String(schemaVersion)}.`);
|
|
33
|
+
}
|
|
@@ -74,7 +74,7 @@ function toReportScenario(record) {
|
|
|
74
74
|
comparison: { ...record.comparison, reasonCodes: [...record.comparison.reasonCodes] }
|
|
75
75
|
};
|
|
76
76
|
}
|
|
77
|
-
function readArtifactPath(run) {
|
|
77
|
+
export function readArtifactPath(run) {
|
|
78
78
|
const fromMetadata = run.metadata?.executionArtifactPath;
|
|
79
79
|
if (typeof fromMetadata === "string" && fromMetadata)
|
|
80
80
|
return fromMetadata;
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
// v0.6.3 -- projects the persisted V2 incremental-change-staleness execution artifact into the V2 report
|
|
2
|
+
// model. A deterministic projection only: no retrieval, fake-agent evaluation, correctness scoring,
|
|
3
|
+
// affected-neighborhood assessment, freshness assessment, refresh-realization or classification
|
|
4
|
+
// recomputation, and no source/index/benchmark reads. The only integrity check is the artifact's own
|
|
5
|
+
// contradiction validator, so a hand-edited or corrupted artifact is rejected rather than presented.
|
|
6
|
+
import { validateIncrementalChangeStalenessScenarioRecordV2 } from "../../experiments/plugins/incrementalChangeStaleness/executionArtifactV2.js";
|
|
7
|
+
import { INCREMENTAL_CHANGE_STALENESS_V2_TREATMENT_IDS } from "../../experiments/plugins/incrementalChangeStaleness/disposableTarget.js";
|
|
8
|
+
import { INCREMENTAL_CHANGE_STALENESS_REPORT_SCHEMA_VERSION_V2 } from "./incrementalChangeStalenessReportModelV2.js";
|
|
9
|
+
// Frozen V2 wording. Every point must appear in report.txt and report.html.
|
|
10
|
+
export const LIMITATIONS_V2 = [
|
|
11
|
+
"Results are scoped to the executed deterministic benchmark scenarios and the configured upstream my-dev-kit tool.",
|
|
12
|
+
"Full refresh is a comparison reference, not an asserted optimal strategy.",
|
|
13
|
+
"A partial treatment that falls back to a full rebuild is not evidence about the requested partial-refresh behavior.",
|
|
14
|
+
"\"no-observed-regression-relative-to-full\" means only that the executed scenario did not show a regression under the frozen correctness and required-file evidence dimensions. It does not prove general equivalence or safety, and does not show that full refresh is unnecessary.",
|
|
15
|
+
"Required-file evidence is a bounded answer-key file-presence check, not retrieval precision/recall.",
|
|
16
|
+
"Correctness remains deterministic fake-agent/harness evidence in v0.6.3.",
|
|
17
|
+
"Lab affected-neighborhood evidence (changed baseline neighborhood relative to the task) is distinct from upstream refresh execution evidence (what my-dev-kit actually refreshed).",
|
|
18
|
+
"\"reindexRecommendation\" remains observational evidence; it did not select or trigger any treatment.",
|
|
19
|
+
"\"changedSymbolCount\" does not mean source-level symbol-diff proof; it retains the released v0.6.1 baseline-symbol-identity definition.",
|
|
20
|
+
"The experiment does not use graph-diff."
|
|
21
|
+
];
|
|
22
|
+
/** Fixed neutral wording per partial-refresh reference classification. Presentation only. */
|
|
23
|
+
export const PARTIAL_REFERENCE_CLASSIFICATION_EXPLANATIONS = {
|
|
24
|
+
"observed-regression-relative-to-full": "The persisted comparison observed at least one regression relative to the full-refresh reference under the frozen evidence dimensions: correctness and/or required-file presence.",
|
|
25
|
+
"no-observed-regression-relative-to-full": "This executed scenario did not show a regression relative to the full-refresh reference under the frozen correctness and required-file evidence dimensions. This does not establish general equivalence or safety, and does not imply that full refresh is unnecessary.",
|
|
26
|
+
inconclusive: "Available persisted evidence was insufficient to determine whether a regression relative to the full-refresh reference occurred. Inconclusive is not the same as no regression.",
|
|
27
|
+
"not-comparable-as-partial-refresh": "The requested partial-refresh treatment fell back to a full rebuild, so this run does not provide evidence about the requested partial-refresh behavior."
|
|
28
|
+
};
|
|
29
|
+
/** Presentation order and labels; identity is always resolved by treatment id, never by array position. */
|
|
30
|
+
export const TREATMENT_PRESENTATION = [
|
|
31
|
+
{ id: "stale-index", label: "No Refresh" },
|
|
32
|
+
{ id: "changed-files-refresh", label: "Changed-Files Refresh" },
|
|
33
|
+
{ id: "affected-neighborhood-refresh", label: "Affected-Neighborhood Refresh" },
|
|
34
|
+
{ id: "full-refresh", label: "Full Refresh" }
|
|
35
|
+
];
|
|
36
|
+
export const COMPARISON_PRESENTATION = [
|
|
37
|
+
{ candidate: "stale-index", label: "No Refresh vs Full Refresh" },
|
|
38
|
+
{ candidate: "changed-files-refresh", label: "Changed-Files Refresh vs Full Refresh" },
|
|
39
|
+
{ candidate: "affected-neighborhood-refresh", label: "Affected-Neighborhood Refresh vs Full Refresh" }
|
|
40
|
+
];
|
|
41
|
+
export function findReportTreatment(scenario, treatmentId) {
|
|
42
|
+
return scenario.treatments.find((treatment) => treatment.treatmentId === treatmentId) ?? null;
|
|
43
|
+
}
|
|
44
|
+
export function findReportComparison(scenario, candidateTreatmentId) {
|
|
45
|
+
return scenario.referenceComparisons.find((comparison) => comparison.candidateTreatmentId === candidateTreatmentId && comparison.referenceTreatmentId === "full-refresh") ?? null;
|
|
46
|
+
}
|
|
47
|
+
export function buildIncrementalChangeStalenessReportV2FromArtifact(artifact) {
|
|
48
|
+
for (const scenario of artifact.scenarios)
|
|
49
|
+
validateIncrementalChangeStalenessScenarioRecordV2(scenario);
|
|
50
|
+
return {
|
|
51
|
+
schemaVersion: INCREMENTAL_CHANGE_STALENESS_REPORT_SCHEMA_VERSION_V2,
|
|
52
|
+
pluginId: artifact.pluginId,
|
|
53
|
+
summary: { ...artifact.summary },
|
|
54
|
+
scenarios: artifact.scenarios.map(toReportScenario),
|
|
55
|
+
limitations: [...LIMITATIONS_V2]
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
function toReportScenario(record) {
|
|
59
|
+
return {
|
|
60
|
+
scenarioId: record.scenarioId,
|
|
61
|
+
category: record.category,
|
|
62
|
+
benchmarkProjectId: record.benchmarkProjectId,
|
|
63
|
+
baseCaseId: record.baseCaseId,
|
|
64
|
+
status: record.status,
|
|
65
|
+
failureReason: record.failureReason,
|
|
66
|
+
query: record.query,
|
|
67
|
+
answerPolicy: record.answerPolicy,
|
|
68
|
+
expectedFiles: [...record.expectedFiles],
|
|
69
|
+
expectedSymbols: [...record.expectedSymbols],
|
|
70
|
+
lifecycle: record.lifecycle ? structuredClone(record.lifecycle) : null,
|
|
71
|
+
// Persisted order is preserved; consumers resolve identity by id (see findReportTreatment/findReportComparison).
|
|
72
|
+
treatments: record.treatments.map((treatment) => structuredClone(treatment)),
|
|
73
|
+
referenceComparisons: record.referenceComparisons.map((comparison) => structuredClone(comparison))
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
/** Kept for callers that need the fixed id list without importing the plugin layer. */
|
|
77
|
+
export const REPORT_TREATMENT_IDS = INCREMENTAL_CHANGE_STALENESS_V2_TREATMENT_IDS;
|
|
78
|
+
export function isV2ReportSection(section) {
|
|
79
|
+
return section !== null && section.schemaVersion === INCREMENTAL_CHANGE_STALENESS_REPORT_SCHEMA_VERSION_V2;
|
|
80
|
+
}
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
2
|
import { buildContextStrategyComparisonV043Report } from "./buildContextStrategyComparisonV043Report.js";
|
|
3
3
|
import { buildWarmIndexReuseReport } from "./buildWarmIndexReuseReport.js";
|
|
4
|
-
import {
|
|
4
|
+
import { buildIncrementalChangeStalenessPluginReport } from "./buildIncrementalChangeStalenessPluginReport.js";
|
|
5
|
+
import { buildContextWindowScalingReport } from "./buildContextWindowScalingReport.js";
|
|
6
|
+
// Bulk context-window-scaling evidence is presented by the typed report section; the complete
|
|
7
|
+
// evidence stays in context-window-scaling-execution.json.
|
|
8
|
+
const CONTEXT_WINDOW_SCALING_BULK_KEYS = ["executionEvidence", "aggregate"];
|
|
5
9
|
const V043_BULK_ARRAY_KEYS = [
|
|
6
10
|
"v043StageContextExecutions",
|
|
7
11
|
"v043StageContextEvaluations",
|
|
@@ -12,11 +16,17 @@ export function buildPluginExperimentReport(args) {
|
|
|
12
16
|
const allOutcomes = args.run.cases.flatMap((experimentCase) => experimentCase.outcomes);
|
|
13
17
|
const contextStrategyComparisonV043 = buildContextStrategyComparisonV043Report(args.run);
|
|
14
18
|
const warmIndexReuse = buildWarmIndexReuseReport(args.run);
|
|
15
|
-
const incrementalChangeStaleness =
|
|
19
|
+
const incrementalChangeStaleness = buildIncrementalChangeStalenessPluginReport(args.run);
|
|
20
|
+
const contextWindowScaling = buildContextWindowScalingReport(args.run);
|
|
16
21
|
const rawRun = { ...args.run, artifacts: relativizeArtifacts(args.run.artifacts, outputRoot) };
|
|
17
22
|
for (const key of V043_BULK_ARRAY_KEYS) {
|
|
18
23
|
delete rawRun[key];
|
|
19
24
|
}
|
|
25
|
+
if (contextWindowScaling) {
|
|
26
|
+
for (const key of CONTEXT_WINDOW_SCALING_BULK_KEYS) {
|
|
27
|
+
delete rawRun[key];
|
|
28
|
+
}
|
|
29
|
+
}
|
|
20
30
|
return {
|
|
21
31
|
metadata: {
|
|
22
32
|
generatedAt: args.generatedAt ?? new Date().toISOString(),
|
|
@@ -42,8 +52,9 @@ export function buildPluginExperimentReport(args) {
|
|
|
42
52
|
findings: buildFindings(args.run),
|
|
43
53
|
warmIndexReuse,
|
|
44
54
|
incrementalChangeStaleness,
|
|
55
|
+
contextWindowScaling,
|
|
45
56
|
contextStrategyComparisonV043,
|
|
46
|
-
interpretation: buildInterpretation(args.run, contextStrategyComparisonV043, warmIndexReuse),
|
|
57
|
+
interpretation: buildInterpretation(args.run, contextStrategyComparisonV043, warmIndexReuse, contextWindowScaling),
|
|
47
58
|
rawRun,
|
|
48
59
|
};
|
|
49
60
|
}
|
|
@@ -122,7 +133,16 @@ function affectedNeighborhoodSentence(report) {
|
|
|
122
133
|
`reindex recommendations were recommended=${summary.recommendedReindexCount}, not-indicated=${summary.notIndicatedReindexCount}, unknown=${summary.unknownReindexRecommendationCount}. ` +
|
|
123
134
|
"Affected-neighborhood evidence uses a one-hop baseline graph around confirmed changed indexed files/symbols. It is observational and does not alter retrieval or execution status.");
|
|
124
135
|
}
|
|
125
|
-
function buildInterpretation(run, contextStrategyComparisonV043, warmIndexReuse) {
|
|
136
|
+
function buildInterpretation(run, contextStrategyComparisonV043, warmIndexReuse, contextWindowScaling) {
|
|
137
|
+
if (contextWindowScaling) {
|
|
138
|
+
const summary = contextWindowScaling.runSummary;
|
|
139
|
+
return {
|
|
140
|
+
summary: `Context-window-scaling evidence covers ${summary.caseCount} case${summary.caseCount === 1 ? "" : "s"}, ${summary.treatmentCount} treatments, and ${summary.budgetCount} budget${summary.budgetCount === 1 ? "" : "s"} ` +
|
|
141
|
+
`(${summary.totalBudgetCellCount} budget cells): ${summary.evaluatedBudgetCellCount} evaluated, ${summary.contextTooLargeCellCount} context-too-large, ${summary.contextUnavailableCellCount} with unavailable context. ` +
|
|
142
|
+
"Context-too-large is an expected measurement state, not an execution failure. The treatments are reported side by side and are not ranked.",
|
|
143
|
+
recommendedNextStep: "Review the budget summary, per-case context sizes, and per-case budget matrix; unavailable correctness and success evidence are excluded from the rates and are never treated as zero.",
|
|
144
|
+
};
|
|
145
|
+
}
|
|
126
146
|
if (run.pluginId === "warm-index-reuse" && warmIndexReuse) {
|
|
127
147
|
const summary = warmIndexReuse.summary;
|
|
128
148
|
const campaign = warmIndexReuse.agentCampaign;
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
// v0.6.3 -- plugin-specific presentation model for the four-treatment V2 execution artifact. Types only:
|
|
2
|
+
// projection lives in buildIncrementalChangeStalenessReportV2.ts, rendering in the text/HTML renderers.
|
|
3
|
+
export const INCREMENTAL_CHANGE_STALENESS_REPORT_SCHEMA_VERSION_V2 = "my-dev-kit-lab-incremental-change-staleness-report-v2";
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
// v0.6.3 -- shared semantic content for the V2 text and HTML renderers, so both present exactly the same
|
|
2
|
+
// persisted facts. Formatting only: no classification, arithmetic, or recomputation. Unavailable evidence
|
|
3
|
+
// is written as words ("unavailable", "not applicable"), never as zero.
|
|
4
|
+
import { STALE_RISK_CLASSIFICATION_EXPLANATIONS } from "./buildIncrementalChangeStalenessReport.js";
|
|
5
|
+
import { COMPARISON_PRESENTATION, PARTIAL_REFERENCE_CLASSIFICATION_EXPLANATIONS, TREATMENT_PRESENTATION, findReportComparison, findReportTreatment } from "./buildIncrementalChangeStalenessReportV2.js";
|
|
6
|
+
import { REINDEX_RECOMMENDATION_EXPLANATIONS } from "./buildWarmIndexReuseReport.js";
|
|
7
|
+
export function display(value, missing = "unavailable") {
|
|
8
|
+
return value === null || value === undefined ? missing : String(value);
|
|
9
|
+
}
|
|
10
|
+
export function treatmentBlock(scenario, treatmentId, label) {
|
|
11
|
+
const treatment = findReportTreatment(scenario, treatmentId);
|
|
12
|
+
if (!treatment) {
|
|
13
|
+
return { label, available: false, rows: [], fallbackStatement: null, refreshRows: [], forcedNeighborSample: null, filesRead: [], requiredFiles: [], observedFiles: [], missingFiles: [] };
|
|
14
|
+
}
|
|
15
|
+
const retrieval = treatment.retrieval;
|
|
16
|
+
const correctness = treatment.fakeAgent?.correctness;
|
|
17
|
+
const refresh = treatment.refreshExecution;
|
|
18
|
+
const rows = [
|
|
19
|
+
["Treatment status", treatment.status],
|
|
20
|
+
["Treatment intent", treatment.treatmentIntent],
|
|
21
|
+
["Failure reason", display(treatment.failureReason, "not applicable")],
|
|
22
|
+
["Active index phase", treatment.activeIndexPhase],
|
|
23
|
+
["Baseline freshness", treatment.baselineFreshness.status],
|
|
24
|
+
["Refreshed freshness", display(treatment.refreshedFreshness?.status, "not applicable")],
|
|
25
|
+
["Retrieval status", retrieval.status],
|
|
26
|
+
["Context characters", retrieval.status === "not-run" ? "unavailable" : String(retrieval.totalChars)],
|
|
27
|
+
["Estimated context tokens", retrieval.status === "not-run" ? "unavailable" : String(retrieval.totalEstimatedTokens)],
|
|
28
|
+
["Retrieval duration (ms)", retrieval.status === "not-run" ? "unavailable" : String(retrieval.durationMs)],
|
|
29
|
+
["Fake-agent status", display(treatment.fakeAgent?.status, "not run")],
|
|
30
|
+
["Correctness score", correctness && correctness.available && correctness.score !== null ? String(correctness.score) : "unavailable"],
|
|
31
|
+
["Required-file evidence", treatment.requiredFileEvidence.status],
|
|
32
|
+
["Required-file reason", display(treatment.requiredFileEvidence.reason, "not applicable")],
|
|
33
|
+
["Affected-neighborhood relationship", treatment.affectedNeighborhood.relationship],
|
|
34
|
+
["Reindex recommendation (observational)", treatment.affectedNeighborhood.reindexRecommendation]
|
|
35
|
+
];
|
|
36
|
+
const refreshRows = [
|
|
37
|
+
["Refresh kind", refresh.kind],
|
|
38
|
+
["Refresh realization", refresh.realization]
|
|
39
|
+
];
|
|
40
|
+
let fallbackStatement = null;
|
|
41
|
+
let forcedNeighborSample = null;
|
|
42
|
+
if (refresh.kind === "incremental") {
|
|
43
|
+
const upstream = refresh.incrementalRefresh;
|
|
44
|
+
refreshRows.push(["Requested scope", upstream.requestedScope], ["Applied scope", upstream.appliedScope], ["Selection status", upstream.selectionStatus], ["Fallback reason", display(upstream.fallbackReason, "not applicable")], ["Fresh extraction files", String(upstream.freshExtractionFileCount)], ["Reused files", String(upstream.reusedFileCount)], ["Forced-neighbor reanalysis files", String(upstream.forcedNeighborReanalysisFileCount)], ["Upstream seed files", display(upstream.seedFileCount, "not recorded")], ["Upstream seed symbols", display(upstream.seedSymbolCount, "not recorded")], ["Upstream affected nodes", display(upstream.affectedNodeCount, "not recorded")], ["Upstream affected edges", display(upstream.affectedEdgeCount, "not recorded")]);
|
|
45
|
+
forcedNeighborSample = [...upstream.forcedNeighborSample];
|
|
46
|
+
if (refresh.realization === "FALLBACK_FULL") {
|
|
47
|
+
fallbackStatement = `FALLBACK_FULL: requested ${upstream.requestedScope}, applied ${upstream.appliedScope}, selection status ${upstream.selectionStatus}, reason ${display(upstream.fallbackReason, "not recorded")}. The requested partial refresh was not applied; a full rebuild produced this index.`;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
refreshRows.push(["Upstream incremental refresh evidence", "not applicable"]);
|
|
52
|
+
}
|
|
53
|
+
return {
|
|
54
|
+
label,
|
|
55
|
+
available: true,
|
|
56
|
+
rows,
|
|
57
|
+
fallbackStatement,
|
|
58
|
+
refreshRows,
|
|
59
|
+
forcedNeighborSample,
|
|
60
|
+
filesRead: [...retrieval.filesRead],
|
|
61
|
+
requiredFiles: [...treatment.requiredFileEvidence.requiredFiles],
|
|
62
|
+
observedFiles: [...treatment.requiredFileEvidence.observedFiles],
|
|
63
|
+
missingFiles: [...treatment.requiredFileEvidence.missingFiles]
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
export function comparisonBlock(scenario, presentation) {
|
|
67
|
+
const comparison = findReportComparison(scenario, presentation.candidate);
|
|
68
|
+
if (!comparison)
|
|
69
|
+
return { label: presentation.label, available: false, rows: [], reasonCodes: [], explanation: "" };
|
|
70
|
+
if (comparison.kind === "stale-risk") {
|
|
71
|
+
const value = comparison.comparison;
|
|
72
|
+
return {
|
|
73
|
+
label: presentation.label,
|
|
74
|
+
available: true,
|
|
75
|
+
rows: [
|
|
76
|
+
["Correctness relation", value.correctnessRelation],
|
|
77
|
+
["Required-file evidence relation", value.requiredFileEvidenceRelation],
|
|
78
|
+
["Stale-risk classification", value.staleRiskClassification]
|
|
79
|
+
],
|
|
80
|
+
reasonCodes: [...value.reasonCodes],
|
|
81
|
+
explanation: STALE_RISK_CLASSIFICATION_EXPLANATIONS[value.staleRiskClassification]
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
return {
|
|
85
|
+
label: presentation.label,
|
|
86
|
+
available: true,
|
|
87
|
+
rows: [
|
|
88
|
+
["Refresh realization", display(comparison.refreshRealization, "not recorded")],
|
|
89
|
+
["Candidate correctness relation", comparison.correctnessRelation],
|
|
90
|
+
["Candidate required-file relation", comparison.requiredFileEvidenceRelation],
|
|
91
|
+
["Reference classification", comparison.classification]
|
|
92
|
+
],
|
|
93
|
+
reasonCodes: [...comparison.reasonCodes],
|
|
94
|
+
explanation: PARTIAL_REFERENCE_CLASSIFICATION_EXPLANATIONS[comparison.classification]
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
export const TREATMENT_PRESENTATION_ORDER = TREATMENT_PRESENTATION;
|
|
98
|
+
export const COMPARISON_PRESENTATION_ORDER = COMPARISON_PRESENTATION;
|
|
99
|
+
/**
|
|
100
|
+
* Baseline affected-neighborhood evidence is symmetric by construction of the execution; the report
|
|
101
|
+
* presents it once only when the persisted relationship and recommendation agree, and otherwise says so.
|
|
102
|
+
*/
|
|
103
|
+
export function affectedNeighborhoodSummary(scenario) {
|
|
104
|
+
const assessments = TREATMENT_PRESENTATION.map((entry) => findReportTreatment(scenario, entry.id)?.affectedNeighborhood ?? null).filter((assessment) => assessment !== null);
|
|
105
|
+
if (assessments.length === 0)
|
|
106
|
+
return { state: "none" };
|
|
107
|
+
const first = assessments[0];
|
|
108
|
+
if (assessments.some((a) => a.relationship !== first.relationship || a.reindexRecommendation !== first.reindexRecommendation))
|
|
109
|
+
return { state: "inconsistent" };
|
|
110
|
+
const number = (value) => display(value);
|
|
111
|
+
return {
|
|
112
|
+
state: "ok",
|
|
113
|
+
rows: [
|
|
114
|
+
["Relationship", first.relationship],
|
|
115
|
+
["Reindex recommendation (observational)", first.reindexRecommendation],
|
|
116
|
+
["Changed indexed files", number(first.changedFileCount)],
|
|
117
|
+
["Changed baseline symbols", number(first.changedSymbolCount)],
|
|
118
|
+
["Affected graph nodes", number(first.affectedNodeCount)],
|
|
119
|
+
["Affected graph edges", number(first.affectedEdgeCount)],
|
|
120
|
+
["Task-overlap nodes", number(first.taskOverlapCount)],
|
|
121
|
+
["Task-overlap percent", number(first.taskOverlapPercent)]
|
|
122
|
+
],
|
|
123
|
+
explanation: REINDEX_RECOMMENDATION_EXPLANATIONS[first.reindexRecommendation]
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
export const EVIDENCE_FAMILY_NOTE = "Lab affected-neighborhood evidence describes the baseline graph neighborhood implicated by the controlled change. Upstream refresh evidence describes what my-dev-kit actually refreshed. They are different evidence families.";
|
|
127
|
+
export const SCENARIO_SUMMARY_ROWS = (summary) => [
|
|
128
|
+
["Scenarios", String(summary.scenarioCount)],
|
|
129
|
+
["Ready", String(summary.readyScenarioCount)],
|
|
130
|
+
["Failed", String(summary.failedScenarioCount)],
|
|
131
|
+
["No refresh: observed stale regression", String(summary.staleObservedRegressionCount)],
|
|
132
|
+
["No refresh: no observed stale regression", String(summary.staleNoObservedRegressionCount)],
|
|
133
|
+
["No refresh: inconclusive", String(summary.staleInconclusiveCount)],
|
|
134
|
+
["Changed-files: applied partial", String(summary.changedFilesAppliedPartialCount)],
|
|
135
|
+
["Changed-files: fallback to full", String(summary.changedFilesFallbackFullCount)],
|
|
136
|
+
["Affected-neighborhood: applied partial", String(summary.affectedNeighborhoodAppliedPartialCount)],
|
|
137
|
+
["Affected-neighborhood: fallback to full", String(summary.affectedNeighborhoodFallbackFullCount)],
|
|
138
|
+
["Changed-files: observed regression relative to full", String(summary.changedFilesObservedRegressionRelativeToFullCount)],
|
|
139
|
+
["Changed-files: no observed regression relative to full", String(summary.changedFilesNoObservedRegressionRelativeToFullCount)],
|
|
140
|
+
["Changed-files: inconclusive", String(summary.changedFilesInconclusiveCount)],
|
|
141
|
+
["Changed-files: not comparable as partial refresh", String(summary.changedFilesNotComparableCount)],
|
|
142
|
+
["Affected-neighborhood: observed regression relative to full", String(summary.affectedNeighborhoodObservedRegressionRelativeToFullCount)],
|
|
143
|
+
["Affected-neighborhood: no observed regression relative to full", String(summary.affectedNeighborhoodNoObservedRegressionRelativeToFullCount)],
|
|
144
|
+
["Affected-neighborhood: inconclusive", String(summary.affectedNeighborhoodInconclusiveCount)],
|
|
145
|
+
["Affected-neighborhood: not comparable as partial refresh", String(summary.affectedNeighborhoodNotComparableCount)]
|
|
146
|
+
];
|
|
@@ -15,5 +15,12 @@ export { renderContextIntegrityJsonReport } from "./renderContextIntegrityJsonRe
|
|
|
15
15
|
export { renderContextIntegrityText } from "./renderContextIntegrityText.js";
|
|
16
16
|
export { renderContextIntegrityHtml } from "./renderContextIntegrityHtml.js";
|
|
17
17
|
export * from "./incrementalChangeStalenessReportModel.js";
|
|
18
|
+
export * from "./incrementalChangeStalenessReportModelV2.js";
|
|
19
|
+
export { buildIncrementalChangeStalenessPluginReport } from "./buildIncrementalChangeStalenessPluginReport.js";
|
|
20
|
+
export { buildIncrementalChangeStalenessReportV2FromArtifact, findReportTreatment, findReportComparison, LIMITATIONS_V2 } from "./buildIncrementalChangeStalenessReportV2.js";
|
|
18
21
|
export { buildIncrementalChangeStalenessReport, STALE_RISK_CLASSIFICATION_EXPLANATIONS } from "./buildIncrementalChangeStalenessReport.js";
|
|
19
22
|
export { renderIncrementalChangeStalenessHtml } from "./renderIncrementalChangeStalenessHtml.js";
|
|
23
|
+
export * from "./contextWindowScalingReportModel.js";
|
|
24
|
+
export { buildContextWindowScalingReport, CONTEXT_WINDOW_SCALING_INTERPRETATION } from "./buildContextWindowScalingReport.js";
|
|
25
|
+
export { renderContextWindowScalingHtml } from "./renderContextWindowScalingHtml.js";
|
|
26
|
+
export { renderContextWindowScalingTextLines } from "./renderContextWindowScalingText.js";
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { formatContextWindowScalingCount, formatContextWindowScalingPercent, formatContextWindowScalingScore, } from "./renderContextWindowScalingText.js";
|
|
2
|
+
export function renderContextWindowScalingHtml(section) {
|
|
3
|
+
if (section === null) {
|
|
4
|
+
return `<section>
|
|
5
|
+
<h2>Context Window Scaling</h2>
|
|
6
|
+
<p>Not applicable to this plugin.</p>
|
|
7
|
+
</section>`;
|
|
8
|
+
}
|
|
9
|
+
const summary = section.runSummary;
|
|
10
|
+
return `<section>
|
|
11
|
+
<h2>Context Window Scaling</h2>
|
|
12
|
+
${table(["Field", "Value"], [
|
|
13
|
+
["Schema", section.schemaVersion],
|
|
14
|
+
["Budgets (estimated context tokens)", section.budgets.join(", ")],
|
|
15
|
+
["Treatments", section.treatments.join(", ")],
|
|
16
|
+
["Token count method", section.tokenCountMethod ?? "unavailable"],
|
|
17
|
+
...Object.entries(summary).map(([label, value]) => [label, String(value)]),
|
|
18
|
+
])}
|
|
19
|
+
<h3>Budget Summary</h3>
|
|
20
|
+
${table(["Budget", "Treatment", "Cells", "Fits", "Too large", "Context unavailable", "Success", "Not successful", "Success unavailable", "Success rate", "Correctness available", "Mean correctness", "Mean utilization", "Min utilization", "Max utilization"], section.budgetTreatmentSummaries.map((s) => [
|
|
21
|
+
String(s.contextBudgetTokens),
|
|
22
|
+
s.variantId,
|
|
23
|
+
String(s.totalCellCount),
|
|
24
|
+
String(s.fitCount),
|
|
25
|
+
String(s.contextTooLargeCount),
|
|
26
|
+
String(s.contextUnavailableCount),
|
|
27
|
+
String(s.successfulCellCount),
|
|
28
|
+
String(s.notSuccessfulCellCount),
|
|
29
|
+
String(s.successEvidenceUnavailableCount),
|
|
30
|
+
formatContextWindowScalingPercent(s.successRatePercent),
|
|
31
|
+
String(s.correctnessAvailableCount),
|
|
32
|
+
formatContextWindowScalingScore(s.meanCorrectnessScore),
|
|
33
|
+
formatContextWindowScalingPercent(s.meanContextBudgetUtilizationPercent),
|
|
34
|
+
formatContextWindowScalingPercent(s.minContextBudgetUtilizationPercent),
|
|
35
|
+
formatContextWindowScalingPercent(s.maxContextBudgetUtilizationPercent),
|
|
36
|
+
]))}
|
|
37
|
+
<h3>Case Context Evidence</h3>
|
|
38
|
+
<p class="muted">Context does not vary by budget, so there is one row per case and treatment.</p>
|
|
39
|
+
${table(["Case", "Treatment", "Context", "Characters", "Estimated tokens", "Token method", "Observed files", "Relevant-file evidence", "Expected relevant files", "Observed expected files", "Omitted relevant files"], section.caseTreatmentContexts.map((c) => [
|
|
40
|
+
c.caseId,
|
|
41
|
+
c.variantId,
|
|
42
|
+
c.contextStatus,
|
|
43
|
+
formatContextWindowScalingCount(c.characterCount),
|
|
44
|
+
formatContextWindowScalingCount(c.estimatedTokens),
|
|
45
|
+
c.tokenCountMethod ?? "unavailable",
|
|
46
|
+
formatContextWindowScalingCount(c.observedFileCount),
|
|
47
|
+
c.relevantFileStatus,
|
|
48
|
+
String(c.expectedRelevantFileCount),
|
|
49
|
+
formatContextWindowScalingCount(c.observedExpectedFileCount),
|
|
50
|
+
formatContextWindowScalingCount(c.omittedRelevantFileCount),
|
|
51
|
+
]))}
|
|
52
|
+
<h3>Omitted Relevant Files</h3>
|
|
53
|
+
<p class="muted">Benchmark-expected files not observed in the treatment context. Not retrieval precision or recall.</p>
|
|
54
|
+
${table(["Evidence available", "Unavailable", "Not applicable", "Total omitted"], [[
|
|
55
|
+
String(section.relevantFileSummary.relevantFileEvidenceAvailableCount),
|
|
56
|
+
String(section.relevantFileSummary.relevantFileEvidenceUnavailableCount),
|
|
57
|
+
String(section.relevantFileSummary.relevantFileEvidenceNotApplicableCount),
|
|
58
|
+
String(section.relevantFileSummary.totalOmittedRelevantFileCount),
|
|
59
|
+
]])}
|
|
60
|
+
${section.caseTreatmentContexts
|
|
61
|
+
.filter((c) => c.relevantFileStatus === "available" && (c.omittedRelevantFileCount ?? 0) > 0)
|
|
62
|
+
.map((c) => `<p><code>${escapeHtml(c.caseId)}</code> / ${escapeHtml(c.variantId)}: omitted ${c.omittedRelevantFiles.totalCount}; displayed ${c.omittedRelevantFiles.displayedCount} of ${c.omittedRelevantFiles.totalCount}; omitted from display ${c.omittedRelevantFiles.omittedCount}; truncated ${c.omittedRelevantFiles.truncated ? "yes" : "no"}</p>${list(c.omittedRelevantFiles.items)}`)
|
|
63
|
+
.join("\n ")}
|
|
64
|
+
<h3>Per-Case Budget Matrix</h3>
|
|
65
|
+
${table(["Case", "Treatment", "Budget", "Estimated context tokens", "Fit", "Utilization", "Evaluation", "Correctness", "Correctness score", "Correctness pass", "Success evidence", "Success", "Success reason"], section.caseBudgetCells.map((cell) => [
|
|
66
|
+
cell.caseId,
|
|
67
|
+
cell.variantId,
|
|
68
|
+
String(cell.contextBudgetTokens),
|
|
69
|
+
formatContextWindowScalingCount(cell.contextEstimatedTokens),
|
|
70
|
+
cell.contextFitStatus,
|
|
71
|
+
formatContextWindowScalingPercent(cell.contextBudgetUtilizationPercent),
|
|
72
|
+
cell.evaluationStatus,
|
|
73
|
+
cell.correctness.availability,
|
|
74
|
+
formatContextWindowScalingScore(cell.correctness.score),
|
|
75
|
+
cell.correctness.pass === null ? "unavailable" : String(cell.correctness.pass),
|
|
76
|
+
cell.successEvidence.status,
|
|
77
|
+
cell.successEvidence.success === null ? "unavailable" : String(cell.successEvidence.success),
|
|
78
|
+
cell.successEvidence.reason,
|
|
79
|
+
]))}
|
|
80
|
+
<h3>Interpretation And Limitations</h3>
|
|
81
|
+
${list(section.interpretation)}
|
|
82
|
+
</section>`;
|
|
83
|
+
}
|
|
84
|
+
function list(items) {
|
|
85
|
+
return `<ul>${items.map((item) => `<li>${escapeHtml(item)}</li>`).join("")}</ul>`;
|
|
86
|
+
}
|
|
87
|
+
function table(headers, rows) {
|
|
88
|
+
return `<table><thead><tr>${headers.map((header) => `<th>${escapeHtml(header)}</th>`).join("")}</tr></thead><tbody>${rows
|
|
89
|
+
.map((row) => `<tr>${row.map((cell) => `<td>${escapeHtml(cell)}</td>`).join("")}</tr>`)
|
|
90
|
+
.join("")}</tbody></table>`;
|
|
91
|
+
}
|
|
92
|
+
function escapeHtml(value) {
|
|
93
|
+
return String(value ?? "")
|
|
94
|
+
.replaceAll("&", "&")
|
|
95
|
+
.replaceAll("<", "<")
|
|
96
|
+
.replaceAll(">", ">")
|
|
97
|
+
.replaceAll('"', """)
|
|
98
|
+
.replaceAll("'", "'");
|
|
99
|
+
}
|